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         value_type::key_type key;
198         value_type::mapped_type  val;
199 
200         for (size_t i=0; i<N && _is.good(); ++i)
201         {
202           bytes += IO::restore( _is, key, _swap );
203           bytes += IO::restore( _is, val, _swap );
204           _v[key] = val;
205         }
206         return _is.good() ? bytes : 0;
207       }
208     };
209 
210   }
211 }
212 
213 #endif
214 
215 
216 // ----------------------------------------------------------------------------
217 
main(void)218 int main(void)
219 {
220   //
221   Mesh mesh;
222 
223 
224   // generate a geometry
225   generate_cube<Mesh>(mesh);
226 
227 
228   // should display 8 vertices, 18/12 edges, 12/6 faces (Tri/Poly)
229   mesh_stats(mesh);
230 
231 
232   // print out information about properties
233   mesh_property_stats(mesh);
234 
235 
236   std::cout << "Define some custom properties..\n";
237 
238   OpenMesh::VPropHandleT<float>       vprop_float;
239   OpenMesh::EPropHandleT<bool>        eprop_bool;
240   OpenMesh::FPropHandleT<std::string> fprop_string;
241   OpenMesh::HPropHandleT<MyData>      hprop_mydata;
242   OpenMesh::MPropHandleT<MyMap>       mprop_map;
243 
244   std::cout << ".. and registrate them at the mesh object.\n";
245 
246   mesh.add_property(vprop_float,  "vprop_float");
247   mesh.add_property(eprop_bool,   "eprop_bool");
248   mesh.add_property(fprop_string, "fprop_string");
249   mesh.add_property(hprop_mydata, "hprop_mydata");
250   mesh.add_property(mprop_map,    "mprop_map");
251 
252 
253   mesh_property_stats(mesh);
254 
255 
256   std::cout << "Now let's fill the props..\n";
257 
258   fill_props(mesh, vprop_float);
259   fill_props(mesh, eprop_bool);
260   fill_props(mesh, fprop_string);
261   fill_props(mesh, hprop_mydata);
262   fill_props(mesh, mprop_map);
263 
264 
265   std::cout << "Check props..\n";
266 #define CHK_PROP( PH ) \
267   std::cout << "  " << #PH << " " \
268             << (fill_props(mesh, PH, true)?"ok\n":"error\n")
269 
270   CHK_PROP(vprop_float);
271   CHK_PROP(eprop_bool);
272   CHK_PROP(fprop_string);
273   CHK_PROP(hprop_mydata);
274   CHK_PROP(mprop_map);
275 #undef CHK_PROP
276 
277 
278   std::cout << "Set persistent flag..\n";
279 #define SET_PERS( PH ) \
280     mesh.property(PH).set_persistent(true); \
281     std::cout << "  " << #PH << " " \
282               << (mesh.property(PH).persistent()?"ok\n":"failed!\n")
283 
284   mesh.property(vprop_float).set_persistent(true);
285   std::cout << "  vprop_float "
286             << (mesh.property(vprop_float).persistent()?"ok\n":"failed!\n");
287 
288   SET_PERS( eprop_bool );
289   SET_PERS( fprop_string );
290   SET_PERS( hprop_mydata );
291   mesh.mproperty(mprop_map).set_persistent(true);
292   std::cout << "  mprop_map "
293             << (mesh.mproperty(mprop_map).persistent()?"ok\n":"failed!\n");
294 
295 
296   std::cout << "Write mesh..";
297   if (IO::write_mesh( mesh, "persistence-check.om" ))
298     std::cout << "  ok\n";
299   else
300   {
301     std::cout << "  failed\n";
302     return 1;
303   }
304 
305 
306   std::cout << "Clear mesh\n";
307   mesh.clear();
308   mesh_stats(mesh, "  ");
309 
310 
311   std::cout << "Read back mesh..";
312   try
313   {
314     if (IO::read_mesh( mesh, "persistence-check.om" ))
315       std::cout << "  ok\n";
316     else
317     {
318       std::cout << "  failed!\n";
319       return 1;
320     }
321     mesh_stats(mesh, "  ");
322   }
323   catch( std::exception &x )
324   {
325     std::cerr << x.what() << std::endl;
326     return 1;
327   }
328 
329 
330   std::cout << "Check props..\n";
331 #define CHK_PROP( PH ) \
332   std::cout << "  " << #PH << " " \
333             << (fill_props(mesh, PH, true)?"ok\n":"error\n")
334   CHK_PROP(vprop_float);
335   CHK_PROP(eprop_bool);
336   CHK_PROP(fprop_string);
337   CHK_PROP(hprop_mydata);
338   CHK_PROP(mprop_map);
339 #undef CHK_PROP
340 
341   return 0;
342 }
343 
344 // end of file
345 // ============================================================================
346