Developer Documentation

OMWriter.cc
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openmesh.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenMesh. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 * ========================================================================= */
41
42
43
44
45 //== INCLUDES =================================================================
46
47 #include <OpenMesh/Core/System/config.h>
48 // -------------------- STL
49 #if defined( OM_CC_MIPS )
50 #include <time.h>
51 #include <string.h>
52 #else
53 #include <ctime>
54 #include <cstring>
55 #endif
56
57 #include <fstream>
58 #include <vector>
59
60 // -------------------- OpenMesh
61 #include <OpenMesh/Core/IO/OMFormat.hh>
62 #include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
63 #include <OpenMesh/Core/IO/writer/OMWriter.hh>
64
65 //=== NAMESPACES ==============================================================
66
67
68 namespace OpenMesh {
69 namespace IO {
70
71
72 //=== INSTANCIATE =============================================================
73
74
75 // register the OMLoader singleton with MeshLoader
76 _OMWriter_ __OMWriterInstance;
77 _OMWriter_& OMWriter() { return __OMWriterInstance; }
78
79
80 //=== IMPLEMENTATION ==========================================================
81
82
83 const OMFormat::uchar _OMWriter_::magic_[3] = "OM";
84 const OMFormat::uint8 _OMWriter_::version_ = OMFormat::mk_version(2,0);
85
86
87 _OMWriter_::
88 _OMWriter_()
89 {
90 IOManager().register_module(this);
91 }
92
93
94 bool
95 _OMWriter_::write(const std::string& _filename, BaseExporter& _be,
96 Options _opt, std::streamsize /*_precision*/) const
97 {
98 // check whether exporter can give us an OpenMesh BaseKernel
99 if (!_be.kernel()) return false;
100
101
102 // check for om extension in filename, we can only handle OM
103 if (_filename.rfind(".om") == std::string::npos)
104 return false;
105
106 _opt += Options::Binary; // only binary format supported
107
108 std::ofstream ofs(_filename.c_str(), std::ios::binary);
109
110 // check if file is open
111 if (!ofs.is_open())
112 {
113 omerr() << "[OMWriter] : cannot open file " << _filename << std::endl;
114 return false;
115 }
116
117 // call stream save method
118 bool rc = write(ofs, _be, _opt);
119
120 // close filestream
121 ofs.close();
122
123 // return success/failure notice
124 return rc;
125 }
126
127
128 //-----------------------------------------------------------------------------
129
130 bool
131 _OMWriter_::write(std::ostream& _os, BaseExporter& _be, Options _opt, std::streamsize /*_precision*/) const
132 {
133 // std::clog << "[OMWriter]::write( stream )\n";
134
135 // check exporter features
136 if ( !check( _be, _opt ) )
137 {
138 omerr() << "[OMWriter]: exporter does not support wanted feature!\n";
139 return false;
140 }
141
142 // Maybe an ascii version will be implemented in the future.
143 // For now, support only a binary format
144 if ( !_opt.check( Options::Binary ) )
145 _opt += Options::Binary;
146
147 // Ignore LSB/MSB bit. Always store in LSB (little endian)
148 _opt += Options::LSB;
149 _opt -= Options::MSB;
150
151 return write_binary(_os, _be, _opt);
152 }
153
154
155 //-----------------------------------------------------------------------------
156
157
158 #ifndef DOXY_IGNORE_THIS
159 template <typename T> struct Enabler
160 {
161 explicit Enabler( T& obj ) : obj_(obj)
162 {}
163
164 ~Enabler() { obj_.enable(); }
165
166 T& obj_;
167 };
168 #endif
169
170
171 bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
172 Options _opt) const
173 {
174 #ifndef DOXY_IGNORE_THIS
175 Enabler<mostream> enabler(omlog());
176 #endif
177
178 size_t bytes = 0;
179
180 bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB);
181
182 unsigned int i, nV, nF;
183 Vec3f v;
184 Vec2f t;
185
186 // -------------------- write header
187 OMFormat::Header header;
188
189 header.magic_[0] = 'O';
190 header.magic_[1] = 'M';
191 header.mesh_ = _be.is_triangle_mesh() ? 'T' : 'P';
192 header.version_ = version_;
193 header.n_vertices_ = int(_be.n_vertices());
194 header.n_faces_ = int(_be.n_faces());
195 header.n_edges_ = int(_be.n_edges());
196
197 bytes += store( _os, header, swap );
198
199 // ---------------------------------------- write chunks
200
201 OMFormat::Chunk::Header chunk_header;
202
203
204 // -------------------- write vertex data
205
206 // ---------- write vertex position
207 if (_be.n_vertices())
208 {
209 v = _be.point(VertexHandle(0));
210 chunk_header.reserved_ = 0;
211 chunk_header.name_ = false;
212 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
213 chunk_header.type_ = OMFormat::Chunk::Type_Pos;
214 chunk_header.signed_ = OMFormat::is_signed(v[0]);
215 chunk_header.float_ = OMFormat::is_float(v[0]);
216 chunk_header.dim_ = OMFormat::dim(v);
217 chunk_header.bits_ = OMFormat::bits(v[0]);
218
219 bytes += store( _os, chunk_header, swap );
220 for (i=0, nV=header.n_vertices_; i<nV; ++i)
221 bytes += vector_store( _os, _be.point(VertexHandle(i)), swap );
222 }
223
224
225 // ---------- write vertex normal
226 if (_be.n_vertices() && _opt.check( Options::VertexNormal ))
227 {
228 Vec3f n = _be.normal(VertexHandle(0));
229
230 chunk_header.name_ = false;
231 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
232 chunk_header.type_ = OMFormat::Chunk::Type_Normal;
233 chunk_header.signed_ = OMFormat::is_signed(n[0]);
234 chunk_header.float_ = OMFormat::is_float(n[0]);
235 chunk_header.dim_ = OMFormat::dim(n);
236 chunk_header.bits_ = OMFormat::bits(n[0]);
237
238 bytes += store( _os, chunk_header, swap );
239 for (i=0, nV=header.n_vertices_; i<nV; ++i)
240 bytes += vector_store( _os, _be.normal(VertexHandle(i)), swap );
241 }
242
243 // ---------- write vertex color
244 if (_be.n_vertices() && _opt.check( Options::VertexColor ) && _be.has_vertex_colors() )
245 {
246 Vec3uc c = _be.color(VertexHandle(0));
247
248 chunk_header.name_ = false;
249 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
250 chunk_header.type_ = OMFormat::Chunk::Type_Color;
251 chunk_header.signed_ = OMFormat::is_signed( c[0] );
252 chunk_header.float_ = OMFormat::is_float( c[0] );
253 chunk_header.dim_ = OMFormat::dim( c );
254 chunk_header.bits_ = OMFormat::bits( c[0] );
255
256 bytes += store( _os, chunk_header, swap );
257 for (i=0, nV=header.n_vertices_; i<nV; ++i)
258 bytes += vector_store( _os, _be.color(VertexHandle(i)), swap );
259 }
260
261 // ---------- write vertex texture coords
262 if (_be.n_vertices() && _opt.check(Options::VertexTexCoord)) {
263
264 t = _be.texcoord(VertexHandle(0));
265
266 chunk_header.name_ = false;
267 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
268 chunk_header.type_ = OMFormat::Chunk::Type_Texcoord;
269 chunk_header.signed_ = OMFormat::is_signed(t[0]);
270 chunk_header.float_ = OMFormat::is_float(t[0]);
271 chunk_header.dim_ = OMFormat::dim(t);
272 chunk_header.bits_ = OMFormat::bits(t[0]);
273
274 // std::clog << chunk_header << std::endl;
275 bytes += store(_os, chunk_header, swap);
276
277 for (i = 0, nV = header.n_vertices_; i < nV; ++i)
278 bytes += vector_store(_os, _be.texcoord(VertexHandle(i)), swap);
279
280 }
281
282 // ---------- wirte halfedge data
283 if (_be.n_edges())
284 {
285 chunk_header.reserved_ = 0;
286 chunk_header.name_ = false;
287 chunk_header.entity_ = OMFormat::Chunk::Entity_Halfedge;
288 chunk_header.type_ = OMFormat::Chunk::Type_Topology;
289 chunk_header.signed_ = true;
290 chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think?
291 chunk_header.dim_ = OMFormat::Chunk::Dim_3D;
292 chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness
293
294 bytes += store( _os, chunk_header, swap );
295 auto nE=header.n_edges_*2;
296 for (i=0; i<nE; ++i)
297 {
298 auto next_id = _be.get_next_halfedge_id(HalfedgeHandle(static_cast<int>(i)));
299 auto to_vertex_id = _be.get_to_vertex_id(HalfedgeHandle(static_cast<int>(i)));
300 auto face_id = _be.get_face_id(HalfedgeHandle(static_cast<int>(i)));
301
302 bytes += store( _os, next_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
303 bytes += store( _os, to_vertex_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
304 bytes += store( _os, face_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
305 }
306 }
307
308 // ---------- write vertex topology (outgoing halfedge)
309 if (_be.n_vertices())
310 {
311 chunk_header.reserved_ = 0;
312 chunk_header.name_ = false;
313 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
314 chunk_header.type_ = OMFormat::Chunk::Type_Topology;
315 chunk_header.signed_ = true;
316 chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think?
317 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
318 chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness
319
320 bytes += store( _os, chunk_header, swap );
321 for (i=0, nV=header.n_vertices_; i<nV; ++i)
322 bytes += store( _os, _be.get_halfedge_id(VertexHandle(i)), OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
323 }
324
325
326 // -------------------- write face data
327
328 // ---------- write topology
329 {
330 chunk_header.name_ = false;
331 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
332 chunk_header.type_ = OMFormat::Chunk::Type_Topology;
333 chunk_header.signed_ = true;
334 chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think?
335 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
336 chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness
337
338 bytes += store( _os, chunk_header, swap );
339
340 for (i=0, nF=header.n_faces_; i<nF; ++i)
341 {
342 auto size = OMFormat::Chunk::Integer_Size(chunk_header.bits_);
343 bytes += store( _os, _be.get_halfedge_id(FaceHandle(i)), size, swap);
344 }
345 }
346
347 // ---------- write face normals
348
349 if (_be.n_faces() && _be.has_face_normals() && _opt.check(Options::FaceNormal) )
350 {
351 #define NEW_STYLE 0
352 #if NEW_STYLE
353 const BaseProperty *bp = _be.kernel()._get_fprop("f:normals");
354
355 if (bp)
356 {
357 #endif
358 Vec3f n = _be.normal(FaceHandle(0));
359
360 chunk_header.name_ = false;
361 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
362 chunk_header.type_ = OMFormat::Chunk::Type_Normal;
363 chunk_header.signed_ = OMFormat::is_signed(n[0]);
364 chunk_header.float_ = OMFormat::is_float(n[0]);
365 chunk_header.dim_ = OMFormat::dim(n);
366 chunk_header.bits_ = OMFormat::bits(n[0]);
367
368 bytes += store( _os, chunk_header, swap );
369 #if !NEW_STYLE
370 for (i=0, nF=header.n_faces_; i<nF; ++i)
371 bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap );
372 #else
373 bytes += bp->store(_os, swap );
374 }
375 else
376 return false;
377 #endif
378 #undef NEW_STYLE
379 }
380
381
382 // ---------- write face color
383
384 if (_be.n_faces() && _be.has_face_colors() && _opt.check( Options::FaceColor ))
385 {
386 #define NEW_STYLE 0
387 #if NEW_STYLE
388 const BaseProperty *bp = _be.kernel()._get_fprop("f:colors");
389
390 if (bp)
391 {
392 #endif
393 Vec3uc c;
394
395 chunk_header.name_ = false;
396 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
397 chunk_header.type_ = OMFormat::Chunk::Type_Color;
398 chunk_header.signed_ = OMFormat::is_signed( c[0] );
399 chunk_header.float_ = OMFormat::is_float( c[0] );
400 chunk_header.dim_ = OMFormat::dim( c );
401 chunk_header.bits_ = OMFormat::bits( c[0] );
402
403 bytes += store( _os, chunk_header, swap );
404 #if !NEW_STYLE
405 for (i=0, nF=header.n_faces_; i<nF; ++i)
406 bytes += vector_store( _os, _be.color(FaceHandle(i)), swap );
407 #else
408 bytes += bp->store(_os, swap);
409 }
410 else
411 return false;
412 #endif
413 }
414
415 // ---------- write vertex status
416 if (_be.n_vertices() && _be.has_vertex_status() && _opt.check(Options::Status))
417 {
418 auto s = _be.status(VertexHandle(0));
419 chunk_header.name_ = false;
420 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
421 chunk_header.type_ = OMFormat::Chunk::Type_Status;
422 chunk_header.signed_ = false;
423 chunk_header.float_ = false;
424 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
425 chunk_header.bits_ = OMFormat::bits(s);
426
427 // std::clog << chunk_header << std::endl;
428 bytes += store(_os, chunk_header, swap);
429
430 for (i = 0, nV = header.n_vertices_; i < nV; ++i)
431 bytes += store(_os, _be.status(VertexHandle(i)), swap);
432 }
433
434 // ---------- write edge status
435 if (_be.n_edges() && _be.has_edge_status() && _opt.check(Options::Status))
436 {
437 auto s = _be.status(EdgeHandle(0));
438 chunk_header.name_ = false;
439 chunk_header.entity_ = OMFormat::Chunk::Entity_Edge;
440 chunk_header.type_ = OMFormat::Chunk::Type_Status;
441 chunk_header.signed_ = false;
442 chunk_header.float_ = false;
443 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
444 chunk_header.bits_ = OMFormat::bits(s);
445
446 // std::clog << chunk_header << std::endl;
447 bytes += store(_os, chunk_header, swap);
448
449 for (i = 0, nV = header.n_edges_; i < nV; ++i)
450 bytes += store(_os, _be.status(EdgeHandle(i)), swap);
451 }
452
453 // ---------- write halfedge status
454 if (_be.n_edges() && _be.has_halfedge_status() && _opt.check(Options::Status))
455 {
456 auto s = _be.status(HalfedgeHandle(0));
457 chunk_header.name_ = false;
458 chunk_header.entity_ = OMFormat::Chunk::Entity_Halfedge;
459 chunk_header.type_ = OMFormat::Chunk::Type_Status;
460 chunk_header.signed_ = false;
461 chunk_header.float_ = false;
462 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
463 chunk_header.bits_ = OMFormat::bits(s);
464
465 // std::clog << chunk_header << std::endl;
466 bytes += store(_os, chunk_header, swap);
467
468 for (i = 0, nV = header.n_edges_ * 2; i < nV; ++i)
469 bytes += store(_os, _be.status(HalfedgeHandle(i)), swap);
470 }
471
472 // ---------- write face status
473 if (_be.n_faces() && _be.has_face_status() && _opt.check(Options::Status))
474 {
475 auto s = _be.status(FaceHandle(0));
476 chunk_header.name_ = false;
477 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
478 chunk_header.type_ = OMFormat::Chunk::Type_Status;
479 chunk_header.signed_ = false;
480 chunk_header.float_ = false;
481 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
482 chunk_header.bits_ = OMFormat::bits(s);
483
484 // std::clog << chunk_header << std::endl;
485 bytes += store(_os, chunk_header, swap);
486
487 for (i = 0, nV = header.n_faces_; i < nV; ++i)
488 bytes += store(_os, _be.status(FaceHandle(i)), swap);
489 }
490
491 // -------------------- write custom properties
492
493
494 BaseKernel::const_prop_iterator prop;
495
496 for (prop = _be.kernel()->vprops_begin();
497 prop != _be.kernel()->vprops_end(); ++prop)
498 {
499 if ( !*prop ) continue;
500 if ( (*prop)->name()[1]==':') continue;
501 bytes += store_binary_custom_chunk(_os, **prop,
502 OMFormat::Chunk::Entity_Vertex, swap );
503 }
504 for (prop = _be.kernel()->fprops_begin();
505 prop != _be.kernel()->fprops_end(); ++prop)
506 {
507 if ( !*prop ) continue;
508 if ( (*prop)->name()[1]==':') continue;
509 bytes += store_binary_custom_chunk(_os, **prop,
510 OMFormat::Chunk::Entity_Face, swap );
511 }
512 for (prop = _be.kernel()->eprops_begin();
513 prop != _be.kernel()->eprops_end(); ++prop)
514 {
515 if ( !*prop ) continue;
516 if ( (*prop)->name()[1]==':') continue;
517 bytes += store_binary_custom_chunk(_os, **prop,
518 OMFormat::Chunk::Entity_Edge, swap );
519 }
520 for (prop = _be.kernel()->hprops_begin();
521 prop != _be.kernel()->hprops_end(); ++prop)
522 {
523 if ( !*prop ) continue;
524 if ( (*prop)->name()[1]==':') continue;
525 bytes += store_binary_custom_chunk(_os, **prop,
526 OMFormat::Chunk::Entity_Halfedge, swap );
527 }
528 for (prop = _be.kernel()->mprops_begin();
529 prop != _be.kernel()->mprops_end(); ++prop)
530 {
531 if ( !*prop ) continue;
532 if ( (*prop)->name()[1]==':') continue;
533 bytes += store_binary_custom_chunk(_os, **prop,
534 OMFormat::Chunk::Entity_Mesh, swap );
535 }
536
537 memset(&chunk_header, 0, sizeof(chunk_header));
538 chunk_header.name_ = false;
539 chunk_header.entity_ = OMFormat::Chunk::Entity_Sentinel;
540 bytes += store(_os, chunk_header, swap);
541
542 std::clog << "#bytes written: " << bytes << std::endl;
543
544 return true;
545 }
546
547 // ----------------------------------------------------------------------------
548
549 size_t _OMWriter_::store_binary_custom_chunk(std::ostream& _os,
550 const BaseProperty& _bp,
551 OMFormat::Chunk::Entity _entity,
552 bool _swap) const
553 {
554 //omlog() << "Custom Property " << OMFormat::as_string(_entity) << " property ["
555 // << _bp.name() << "]" << std::endl;
556
557 // Don't store if
558 // 1. it is not persistent
559 // 2. it's name is empty
560 if ( !_bp.persistent() || _bp.name().empty() )
561 {
562 //omlog() << " skipped\n";
563 return 0;
564 }
565
566 size_t bytes = 0;
567
568 OMFormat::Chunk::esize_t element_size = OMFormat::Chunk::esize_t(_bp.element_size());
569 OMFormat::Chunk::Header chdr;
570
571 // set header
572 chdr.name_ = true;
573 chdr.entity_ = _entity;
574 chdr.type_ = OMFormat::Chunk::Type_Custom;
575 chdr.signed_ = 0;
576 chdr.float_ = 0;
577 chdr.dim_ = OMFormat::Chunk::Dim_1D; // ignored
578 chdr.bits_ = element_size;
579
580
581 // write custom chunk
582
583 // 1. chunk header
584 bytes += store( _os, chdr, _swap );
585
586 // 2. property name
587 bytes += store( _os, OMFormat::Chunk::PropertyName(_bp.name()), _swap );
588
589 // 3. block size
590 bytes += store( _os, _bp.size_of(), OMFormat::Chunk::Integer_32, _swap );
591 //omlog() << " n_bytes = " << _bp.size_of() << std::endl;
592
593 // 4. data
594 {
595 size_t b;
596 bytes += ( b=_bp.store( _os, _swap ) );
597 //omlog() << " b = " << b << std::endl;
598 assert( b == _bp.size_of() );
599 }
600 return bytes;
601 }
602
603 // ----------------------------------------------------------------------------
604
605 size_t _OMWriter_::binary_size(BaseExporter& /* _be */, Options /* _opt */) const
606 {
607 // std::clog << "[OMWriter]: binary_size()" << std::endl;
608 size_t bytes = sizeof( OMFormat::Header );
609
610 // !!!TODO!!!
611
612 return bytes;
613 }
614
615 //=============================================================================
616 } // namespace IO
617 } // namespace OpenMesh
618 //=============================================================================
OpenMesh::IO::Options::Swap
Swap byte order in binary mode.
Definition: Options.hh:103
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:134
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:141
OpenMesh::IO::_OMWriter_::binary_size
size_t binary_size(BaseExporter &_be, Options _opt) const override
Returns expected size of file if binary format is supported else 0.
Definition: OMWriter.cc:605
OpenMesh::IO::Options::MSB
Assume big endian byte ordering.
Definition: Options.hh:101
OpenMesh::IO::_OMWriter_
Definition: OMWriter.hh:91
OpenMesh::IO::Options::VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
OpenMesh::IO::Options::FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:109
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:127
config.h
OpenMesh::BaseProperty::store
virtual size_t store(std::ostream &_ostr, bool _swap) const =0
Store self as one binary block.
OpenMesh::VectorT< float, 3 >
OpenMesh::BaseProperty
Definition: BaseProperty.hh:60
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:120
OpenMesh::IO::_IOManager_::register_module
bool register_module(BaseReader *_bl)
Definition: IOManager.hh:217
OpenMesh::BaseProperty::persistent
bool persistent(void) const
Returns true if the persistent flag is enabled else false.
Definition: BaseProperty.hh:130
OpenMesh
Definition: MeshItems.hh:59
OpenMesh::BaseProperty::size_of
virtual size_t size_of() const
Return size of property in bytes.
Definition: BaseProperty.hh:143
OpenMesh::IO::__OMWriterInstance
_OMWriter_ __OMWriterInstance
Declare the single entity of the OM writer.
Definition: OMWriter.cc:76
OpenMesh::BaseProperty::element_size
virtual size_t element_size() const =0
Size of one element in bytes or UnknownSize if not known.
OpenMesh::IO::BaseExporter
Definition: BaseExporter.hh:84
OpenMesh::BaseProperty::name
const std::string & name() const
Return the name of the property.
Definition: BaseProperty.hh:120
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:90
OpenMesh::IO::Options::Status
Has (r) / store (w) status properties.
Definition: Options.hh:114
OpenMesh::IO::_OMWriter_::write
bool write(std::ostream &, BaseExporter &, Options, std::streamsize _precision=6) const override
Definition: OMWriter.cc:131
OpenMesh::IO::Options::VertexNormal
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
OpenMesh::IO::IOManager
_IOManager_ & IOManager()
Definition: IOManager.cc:72
OpenMesh::IO::Options::FaceNormal
Has (r) / store (w) face normals.
Definition: Options.hh:108
OpenMesh::Endian::MSB
big endian (Motorola&#39;s 68x family, DEC Alpha, MIPS)
Definition: Endian.hh:79
OpenMesh::IO::Options::Binary
Set binary mode for r/w.
Definition: Options.hh:100
OpenMesh::IO::_OMWriter_::_OMWriter_
_OMWriter_()
Constructor.
Definition: OMWriter.cc:88
OpenMesh::IO::Options::LSB
Assume little endian byte ordering.
Definition: Options.hh:102
OpenMesh::IO::Options::VertexTexCoord
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
OpenMesh::Endian::local
static Type local()
Return endian type of host system.
Definition: Endian.hh:83