Bayeux  3.4.1
Core Foundation library for SuperNEMO
stl_tools.h
Go to the documentation of this file.
1 /* Author(s): Francois Mauger <mauger@lpccaen.in2p3.fr>
3  * Creation date: 2012-09-23
4  * Last modified: 2013-06-11
5  *
6  * License:
7  *
8  * Description:
9  *
10  * STL (STereoLithography) tools for STL ASCII formatted file import.
11  *
12  * Based on :
13  *
14  * http://en.wikipedia.org/wiki/STL_%28file_format%29
15  * http://www.ennex.com/~fabbers/StL.asp
16  *
17  * History:
18  *
19  */
20 
21 #ifndef GEOMTOOLS_STL_TOOLS_H
22 #define GEOMTOOLS_STL_TOOLS_H 1
23 
24 // Standard library:
25 #include <iostream>
26 #include <vector>
27 #include <string>
28 
29 // Third party:
30 // - Boost:
31 // Ignore unused parameter warning from transiently included
32 // qi/real.hpp
33 #ifdef __clang__
34 #pragma clang diagnostic push
35 #pragma clang diagnostic ignored "-Wunused-parameter"
36 #endif
37 #include <boost/spirit/include/qi.hpp>
38 #ifdef __clang__
39 #pragma clang diagnostic pop
40 #endif
41 
42 #include <boost/spirit/include/phoenix_core.hpp>
43 #include <boost/spirit/include/phoenix_operator.hpp>
44 #include <boost/spirit/include/phoenix_object.hpp>
45 #include <boost/spirit/include/phoenix_fusion.hpp>
46 #include <boost/spirit/include/phoenix_stl.hpp>
47 #include <boost/fusion/include/adapt_struct.hpp>
48 
49 namespace geomtools {
50 
52  namespace stl {
53 
54  /*******************
55  * STL vertex *
56  *******************/
57 
59  struct vertex
60  {
61  double x, y, z;
62 
64  vertex();
65 
66  friend std::ostream & operator<<(std::ostream & out_,
67  const vertex & vtx_);
68 
69  friend bool operator== (const vertex & vtx1_,
70  const vertex & vtx2_);
71 
72  friend bool operator< (const vertex & vtx1_,
73  const vertex & vtx2_);
74 
75  };
76 
77 
78  /*******************
79  * STL facet *
80  *******************/
81 
83  struct facet
84  {
85  double nx, ny, nz;
86  std::vector<vertex> vertices;
87 
89  facet();
90 
91  friend std::ostream & operator<<(std::ostream & out_,
92  const facet & fct_);
93 
94  };
95 
96 
97  /*******************
98  * STL solid *
99  *******************/
100 
102  struct solid
103  {
104  std::string name;
105  std::vector<facet> facets;
106  std::string dummy_name;
107 
109  solid();
110 
111  friend std::ostream & operator<<( std::ostream & out_, const solid & sld_);
112 
113  };
114 
115  } // end of namespace stl
116 
117 } // end of namespace geomtools
118 
119 
120 /****************************
121  * Boost/Fusion interface *
122  ****************************/
123 
124 BOOST_FUSION_ADAPT_STRUCT(geomtools::stl::vertex,
125  (double, x)
126  (double, y)
127  (double, z)
128  )
129 
130 BOOST_FUSION_ADAPT_STRUCT(geomtools::stl::facet,
131  (double, nx)
132  (double, ny)
133  (double, nz)
134  (std::vector<geomtools::stl::vertex>,vertices)
135  )
136 
137 BOOST_FUSION_ADAPT_STRUCT(geomtools::stl::solid,
138  (std::string, name)
139  (std::vector<geomtools::stl::facet>,facets)
140  (std::string, dummy_name)
141  )
142 
143 namespace geomtools {
144 
145  namespace stl {
146 
147 
148  /****************************
149  * Boost/Spirit parsers *
150  ****************************/
151 
152  template <typename Iterator>
153  struct vertex_parser :
154  boost::spirit::qi::grammar<Iterator,
155  vertex(),
156  boost::spirit::qi::ascii::space_type>
157  {
158  vertex_parser () : vertex_parser::base_type(start)
159  {
160  start %=
161  boost::spirit::qi::lit("vertex")
162  > boost::spirit::qi::double_
163  > boost::spirit::qi::double_
164  > boost::spirit::qi::double_
165  ;
166  return;
167  }
168 
169  // Attributes:
170  boost::spirit::qi::rule<Iterator,
171  vertex(),
172  boost::spirit::qi::ascii::space_type> start;
173 
174  };
175 
176  template <typename Iterator>
177  struct facet_parser : boost::spirit::qi::grammar<Iterator,
178  facet(),
179  boost::spirit::qi::locals<std::string>,
180  boost::spirit::qi::ascii::space_type>
181  {
182  facet_parser () : facet_parser::base_type(facet_grammar, "geomtools::stl::facet_grammar")
183  {
184 
185  facet_grammar %=
186  boost::spirit::qi::lit("facet")
187  > boost::spirit::qi::lit("normal")
188  > boost::spirit::qi::double_
189  > boost::spirit::qi::double_
190  > boost::spirit::qi::double_
191  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank] > boost::spirit::qi::eol]
192  > boost::spirit::qi::lit("outer")
193  > boost::spirit::qi::lit("loop")
194  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank] > boost::spirit::qi::eol]
195 
196 
197  > boost::spirit::qi::repeat(3)[vertex_grammar
198  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank]
199  > boost::spirit::qi::eol]
200  ]
201 
202  > boost::spirit::qi::lit("endloop")
203  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank] > boost::spirit::qi::eol]
204  > boost::spirit::qi::lit("endfacet")
205  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank] > boost::spirit::qi::eol]
206  ;
207 
208  facet_grammar.name("geomtools::stl::facet_grammar");
209  vertex_grammar.name("geomtools::stl::vertex_grammar");
210 
211  boost::spirit::qi::on_error<boost::spirit::qi::fail>
212  (
213  facet_grammar
214  , std::cerr
215  << boost::phoenix::val("Error! Expecting ")
216  << boost::spirit::qi::_4
217  << boost::phoenix::val(" here: \"")
218  << boost::phoenix::construct<std::string>(boost::spirit::qi::_3,
219  boost::spirit::qi::_2)
220  << boost::phoenix::val("\"")
221  << std::endl
222  );
223 
224  return;
225  }
226 
227  // Attributes:
228  geomtools::stl::vertex_parser<Iterator> vertex_grammar;
229  boost::spirit::qi::rule<Iterator,
230  facet(),
231  boost::spirit::qi::locals<std::string>,
232  boost::spirit::qi::ascii::space_type> facet_grammar;
233 
234  };
235 
236 
237 
238  template <typename Iterator>
239  struct solid_parser : boost::spirit::qi::grammar<Iterator,
240  solid(),
241  boost::spirit::qi::locals<std::string>,
242  boost::spirit::qi::ascii::space_type>
243  {
244  solid_parser () : solid_parser::base_type(solid_grammar, "geomtools::stl:solid_grammar")
245  {
246 
247  name_grammar %=
248  boost::spirit::qi::lexeme[ boost::spirit::qi::alpha >> *boost::spirit::qi::alnum]
249  ;
250 
251  solid_grammar %=
252  boost::spirit::qi::lit("solid")
253  > name_grammar
254  > boost::spirit::qi::omit[ boost::spirit::qi::lexeme[ *(boost::spirit::qi::char_ - boost::spirit::qi::eol) ]]
255 
256  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank] > boost::spirit::qi::eol]
257  > boost::spirit::qi::repeat(4, boost::spirit::qi::inf)[facet_grammar]
258  > boost::spirit::qi::lit("endsolid")
259  > name_grammar
260  > boost::spirit::qi::omit[boost::spirit::qi::lexeme[ *(boost::spirit::qi::char_ - boost::spirit::qi::eol) ]]
261  > boost::spirit::qi::no_skip[boost::spirit::qi::omit[*boost::spirit::qi::blank] > boost::spirit::qi::eol]
262  ;
263 
264  solid_grammar.name("geomtools::stl::solid_grammar");
265  facet_grammar.name("geomtools::stl::solid::facet_grammar");
266  name_grammar.name("geomtools::stl::solid::name_grammar");
267 
268  boost::spirit::qi::on_error<boost::spirit::qi::fail>
269  (
270  solid_grammar
271  , std::cerr
272  << boost::phoenix::val("Error! Expecting ")
273  << boost::spirit::qi::_4
274  << boost::phoenix::val(" here: \"")
275  << boost::phoenix::construct<std::string>(boost::spirit::qi::_3, boost::spirit::qi::_2)
276  << boost::phoenix::val("\"")
277  << std::endl
278  );
279 
280  return;
281  }
282 
283  // Attributes:
284  boost::spirit:: qi::rule<Iterator, std::string(), boost::spirit::qi::ascii::space_type> name_grammar;
285  geomtools::stl::facet_parser<Iterator> facet_grammar;
286  boost::spirit::qi::rule<Iterator,
287  solid(),
288  boost::spirit::qi::locals<std::string>,
289  boost::spirit::qi::ascii::space_type> solid_grammar;
290 
291  };
292 
293  } // end of namespace stl
294 
295 } // end of namespace geomtools
296 
297 
298 namespace geomtools {
299 
300  class tessellated_solid;
301 
302  namespace stl {
303 
304 
305  /*************************
306  * STL solid converter *
307  *************************/
308 
310 
312  class stl_to_geomtools_converter
313  {
314  public:
315 
316  bool is_debug () const;
317 
318  void set_debug (bool);
319 
320  bool is_check_normal () const;
321 
322  void set_check_normal (bool);
323 
324  bool is_fix_attempt () const;
325 
326  void set_fix_attempt (bool);
327 
328  bool is_lock_ts () const;
329 
330  void set_lock_ts (bool d_);
331 
332  double get_length_unit () const;
333 
334  void set_length_unit (double u_);
335 
337  stl_to_geomtools_converter ();
338 
339  int convert (const solid & solid_, tessellated_solid & ts_);
340 
341  static void fix_broken_facets (tessellated_solid & ts_, bool verbose_ = true);
342 
343  private:
344 
345  bool _debug_;
346  bool _check_normal_;
347  bool _fix_attempt_;
348  bool _lock_ts_;
349  double _length_unit_;
350 
351  };
352 
353  } // end of namespace stl
354 
355 } // end of namespace geomtools
356 
357 #endif // GEOMTOOLS_STL_TOOLS_H
358 
359 /*
360 ** Local Variables: --
361 ** mode: c++ --
362 ** c-file-style: "gnu" --
363 ** tab-width: 2 --
364 ** End: --
365 */
double z
Definition: stl_tools.h:61
double nx
Definition: stl_tools.h:85
friend std::ostream & operator<<(std::ostream &out_, const vertex &vtx_)
vertex()
Default constructor.
A STL facet.
Definition: stl_tools.h:83
friend bool operator<(const vertex &vtx1_, const vertex &vtx2_)
double ny
Definition: stl_tools.h:85
std::string dummy_name
Dummy name.
Definition: stl_tools.h:106
A STL solid.
Definition: stl_tools.h:102
double x
Definition: stl_tools.h:61
double nz
Coordinates of the normal to the facet.
Definition: stl_tools.h:85
friend bool operator==(const vertex &vtx1_, const vertex &vtx2_)
double y
Definition: stl_tools.h:61
friend std::ostream & operator<<(std::ostream &out_, const facet &fct_)
facet()
Default constructor.
friend std::ostream & operator<<(std::ostream &out_, const solid &sld_)
std::vector< facet > facets
Array of facets.
Definition: stl_tools.h:105
std::string name
Name of the solid.
Definition: stl_tools.h:104
solid()
Default constructor.
std::vector< vertex > vertices
Array of vertices.
Definition: stl_tools.h:86
A STL vertex.
Definition: stl_tools.h:59
Top-level namespace of the Bayeux/geomtools module library.
Definition: electromagnetic_field_manager.h:39