1 #include <iostream>
2 #include <string>
3 #include <map>
4 // -------------------- OpenMesh
5 #include <OpenMesh/Core/IO/MeshIO.hh>
6 #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
7 #include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
8 // -------------------- little helper
9 #include "generate_cube.hh"
10 #include "stats.hh"
11 #include "fill_props.hh"
12 
13 // ----------------------------------------------------------------------------
14 
15 // Set to 1 to use an PolyMesh type.
16 #define UsePolyMesh 1
17 
18 // ----------------------------------------------------------------------------
19 
20 using namespace OpenMesh;
21 
22 // ----------------------------------------------------------------------------
23 
24 typedef TriMesh_ArrayKernelT<>  TriMesh;
25 typedef PolyMesh_ArrayKernelT<> PolyMesh;
26 
27 #if UsePolyMesh
28 typedef PolyMesh Mesh;
29 #else
30 typedef TriMesh Mesh;
31 #endif
32 
33 // ----------------------------------------------------------------------------
34 
35 #ifndef DOXY_IGNORE_THIS
36 
37 struct MyData
38 {
39   int             ival;
40   double          dval;
41   bool            bval;
42   OpenMesh::Vec4f vec4fval;
43 
MyDataMyData44   MyData()
45     : ival(0), dval(0.0), bval(false)
46   { }
47 
MyDataMyData48   MyData( const MyData& _cpy )
49     : ival(_cpy.ival), dval(_cpy.dval), bval(_cpy.bval),
50       vec4fval(_cpy.vec4fval)
51   { }
52 
53 
54   // ---------- assignment
55 
operator =MyData56   MyData& operator = (const MyData& _rhs)
57   {
58     ival = _rhs.ival;
59     dval = _rhs.dval;
60     bval = _rhs.bval;
61     vec4fval = _rhs.vec4fval;
62     return *this;
63   }
64 
operator =MyData65   MyData& operator = (int    _rhs) { ival = _rhs; return *this; }
operator =MyData66   MyData& operator = (double _rhs) { dval = _rhs; return *this; }
operator =MyData67   MyData& operator = (bool   _rhs) { bval = _rhs; return *this; }
operator =MyData68   MyData& operator = (const OpenMesh::Vec4f& _rhs)
69   { vec4fval = _rhs; return *this; }
70 
71 
72   // ---------- comparison
73 
operator ==MyData74   bool operator == (const MyData& _rhs) const
75   {
76     return ival == _rhs.ival
77       &&   dval == _rhs.dval
78       &&   bval == _rhs.bval
79       &&   vec4fval == _rhs.vec4fval;
80   }
81 
operator !=MyData82   bool operator != (const MyData& _rhs) const { return !(*this == _rhs); }
83 
84 };
85 
86 #endif
87 
88 
89 // ----------------------------------------------------------------------------
90 
91 typedef std::map< std::string, unsigned int > MyMap;
92 
93 
94 // ----------------------------------------------------------------------------
95 
96 #ifndef DOXY_IGNORE_THIS
97 
98 namespace OpenMesh {
99   namespace IO {
100 
101     // support persistence for struct MyData
102 
103     template <> struct binary<MyData>
104     {
105       typedef MyData value_type;
106 
107       static const bool is_streamable = true;
108 
109       // return binary size of the value
110 
size_ofOpenMesh::IO::binary111       static size_t size_of(void)
112       {
113         return sizeof(int)+sizeof(double)+sizeof(bool)+sizeof(OpenMesh::Vec4f);
114       }
115 
size_ofOpenMesh::IO::binary116       static size_t size_of(const value_type&)
117       {
118         return size_of();
119       }
120 
storeOpenMesh::IO::binary121       static size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
122       {
123         size_t bytes;
124         bytes  = IO::store( _os, _v.ival, _swap );
125         bytes += IO::store( _os, _v.dval, _swap );
126         bytes += IO::store( _os, _v.bval, _swap );
127         bytes += IO::store( _os, _v.vec4fval, _swap );
128         return _os.good() ? bytes : 0;
129       }
130 
restoreOpenMesh::IO::binary131       static size_t restore( std::istream& _is, value_type& _v, bool _swap=false)
132       {
133         size_t bytes;
134         bytes  = IO::restore( _is, _v.ival, _swap );
135         bytes += IO::restore( _is, _v.dval, _swap );
136         bytes += IO::restore( _is, _v.bval, _swap );
137         bytes += IO::restore( _is, _v.vec4fval, _swap );
138         return _is.good() ? bytes : 0;
139       }
140     };
141 
142 
143     template <> struct binary< MyMap >
144     {
145       typedef MyMap value_type;
146 
147       static const bool is_streamable = true;
148 
149       // return generic binary size of self, if known
size_ofOpenMesh::IO::binary150       static size_t size_of(void) { return UnknownSize; }
151 
152       // return binary size of the value
size_ofOpenMesh::IO::binary153       static size_t size_of(const value_type& _v)
154       {
155         if (_v.empty())
156           return sizeof(unsigned int);
157 
158         value_type::const_iterator it = _v.begin();
159         unsigned int   N     = _v.size();
160         size_t         bytes = IO::size_of(N);
161 
162         for(;it!=_v.end(); ++it)
163         {
164           bytes += IO::size_of( it->first );
165           bytes += IO::size_of( it->second );
166         }
167         return bytes;
168       }
169 
170       static
storeOpenMesh::IO::binary171       size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
172       {
173         size_t   bytes = 0;
174         unsigned int N = _v.size();
175 
176         value_type::const_iterator it = _v.begin();
177 
178         bytes += IO::store( _os, N, _swap );
179 
180         for (; it != _v.end() && _os.good(); ++it)
181         {
182           bytes += IO::store( _os, it->first, _swap );
183           bytes += IO::store( _os, it->second, _swap );
184         }
185         return _os.good() ? bytes : 0;
186       }
187 
188       static
restoreOpenMesh::IO::binary189       size_t restore( std::istream& _is, value_type& _v, bool _swap=false)
190       {
191         size_t   bytes = 0;
192         unsigned int N = 0;
193 
194         _v.clear();
195 
196         bytes += IO::restore( _is, N, _swap );
197 
198         std::string key;
199         size_t      val;
200 
201         for (size_t i=0; i<N && _is.good(); ++i)
202         {
203           bytes += IO::restore( _is, key, _swap );
204           bytes += IO::restore( _is, val, _swap );
205           _v[key] = val;
206         }
207         return _is.good() ? bytes : 0;
208       }
209     };
210 
211   }
212 }
213 
214 #endif
215 
216 
217 // ----------------------------------------------------------------------------
218 
main(void)219 int main(void)
220 {
221   //
222   Mesh mesh;
223 
224 
225   // generate a geometry
226   generate_cube<Mesh>(mesh);
227 
228 
229   // should display 8 vertices, 18/12 edges, 12/6 faces (Tri/Poly)
230   mesh_stats(mesh);
231 
232 
233   // print out information about properties
234   mesh_property_stats(mesh);
235 
236 
237   std::cout << "Define some custom properties..\n";
238 
239   OpenMesh::VPropHandleT<float>       vprop_float;
240   OpenMesh::EPropHandleT<bool>        eprop_bool;
241   OpenMesh::FPropHandleT<std::string> fprop_string;
242   OpenMesh::HPropHandleT<MyData>      hprop_mydata;
243   OpenMesh::MPropHandleT<MyMap>       mprop_map;
244 
245   std::cout << ".. and registrate them at the mesh object.\n";
246 
247   mesh.add_property(vprop_float,  "vprop_float");
248   mesh.add_property(eprop_bool,   "eprop_bool");
249   mesh.add_property(fprop_string, "fprop_string");
250   mesh.add_property(hprop_mydata, "hprop_mydata");
251   mesh.add_property(mprop_map,    "mprop_map");
252 
253 
254   mesh_property_stats(mesh);
255 
256 
257   std::cout << "Now let's fill the props..\n";
258 
259   fill_props(mesh, vprop_float);
260   fill_props(mesh, eprop_bool);
261   fill_props(mesh, fprop_string);
262   fill_props(mesh, hprop_mydata);
263   fill_props(mesh, mprop_map);
264 
265 
266   std::cout << "Check props..\n";
267 #define CHK_PROP( PH ) \
268   std::cout << "  " << #PH << " " \
269             << (fill_props(mesh, PH, true)?"ok\n":"error\n")
270 
271   CHK_PROP(vprop_float);
272   CHK_PROP(eprop_bool);
273   CHK_PROP(fprop_string);
274   CHK_PROP(hprop_mydata);
275   CHK_PROP(mprop_map);
276 #undef CHK_PROP
277 
278 
279   std::cout << "Set persistent flag..\n";
280 #define SET_PERS( PH ) \
281     mesh.property(PH).set_persistent(true); \
282     std::cout << "  " << #PH << " " \
283               << (mesh.property(PH).persistent()?"ok\n":"failed!\n")
284 
285   mesh.property(vprop_float).set_persistent(true);
286   std::cout << "  vprop_float "
287             << (mesh.property(vprop_float).persistent()?"ok\n":"failed!\n");
288 
289   SET_PERS( eprop_bool );
290   SET_PERS( fprop_string );
291   SET_PERS( hprop_mydata );
292   mesh.mproperty(mprop_map).set_persistent(true);
293   std::cout << "  mprop_map "
294             << (mesh.mproperty(mprop_map).persistent()?"ok\n":"failed!\n");
295 
296 
297   std::cout << "Write mesh..";
298   if (IO::write_mesh( mesh, "persistence-check.om" ))
299     std::cout << "  ok\n";
300   else
301   {
302     std::cout << "  failed\n";
303     return 1;
304   }
305 
306 
307   std::cout << "Clear mesh\n";
308   mesh.clear();
309   mesh_stats(mesh, "  ");
310 
311 
312   std::cout << "Read back mesh..";
313   try
314   {
315     if (IO::read_mesh( mesh, "persistence-check.om" ))
316       std::cout << "  ok\n";
317     else
318     {
319       std::cout << "  failed!\n";
320       return 1;
321     }
322     mesh_stats(mesh, "  ");
323   }
324   catch( std::exception &x )
325   {
326     std::cerr << x.what() << std::endl;
327     return 1;
328   }
329 
330 
331   std::cout << "Check props..\n";
332 #define CHK_PROP( PH ) \
333   std::cout << "  " << #PH << " " \
334             << (fill_props(mesh, PH, true)?"ok\n":"error\n")
335   CHK_PROP(vprop_float);
336   CHK_PROP(eprop_bool);
337   CHK_PROP(fprop_string);
338   CHK_PROP(hprop_mydata);
339   CHK_PROP(mprop_map);
340 #undef CHK_PROP
341 
342   return 0;
343 }
344 
345 // end of file
346 // ============================================================================
347