54 #if defined( OM_CC_MIPS ) 66 #include <OpenMesh/Core/IO/OMFormat.hh> 67 #include <OpenMesh/Core/IO/exporter/BaseExporter.hh> 68 #include <OpenMesh/Core/IO/writer/OMWriter.hh> 88 const OMFormat::uchar _OMWriter_::magic_[3] =
"OM";
89 const OMFormat::uint8 _OMWriter_::version_ = OMFormat::mk_version(1,2);
101 Options _opt, std::streamsize )
const 104 if (!_be.kernel())
return false;
108 if (_filename.rfind(
".om") == std::string::npos)
113 std::ofstream ofs(_filename.c_str(), std::ios::binary);
118 omerr() <<
"[OMWriter] : cannot open file " << _filename << std::endl;
123 bool rc =
write(ofs, _be, _opt);
141 if ( !check( _be, _opt ) )
143 omerr() <<
"[OMWriter]: exporter does not support wanted feature!\n";
156 return write_binary(_os, _be, _opt);
163 #ifndef DOXY_IGNORE_THIS 164 template <
typename T>
struct Enabler
166 Enabler( T& obj ) : obj_(obj)
169 ~Enabler() { obj_.enable(); }
176 bool _OMWriter_::write_binary(std::ostream& _os,
BaseExporter& _be,
179 #ifndef DOXY_IGNORE_THIS 180 Enabler<mostream> enabler(omlog());
187 unsigned int i, nV, nF;
190 std::vector<VertexHandle> vhandles;
194 OMFormat::Header header;
196 header.magic_[0] =
'O';
197 header.magic_[1] =
'M';
198 header.mesh_ = _be.is_triangle_mesh() ?
'T' :
'P';
199 header.version_ = version_;
200 header.n_vertices_ = int(_be.n_vertices());
201 header.n_faces_ = int(_be.n_faces());
202 header.n_edges_ = int(_be.n_edges());
204 bytes += store( _os, header, swap );
208 OMFormat::Chunk::Header chunk_header;
214 if (_be.n_vertices())
217 chunk_header.reserved_ = 0;
218 chunk_header.name_ =
false;
219 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
220 chunk_header.type_ = OMFormat::Chunk::Type_Pos;
221 chunk_header.signed_ = OMFormat::is_signed(v[0]);
222 chunk_header.float_ = OMFormat::is_float(v[0]);
223 chunk_header.dim_ = OMFormat::dim(v);
224 chunk_header.bits_ = OMFormat::bits(v[0]);
226 bytes += store( _os, chunk_header, swap );
227 for (i=0, nV=header.n_vertices_; i<nV; ++i)
228 bytes += vector_store( _os, _be.point(
VertexHandle(i)), swap );
237 chunk_header.name_ =
false;
238 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
239 chunk_header.type_ = OMFormat::Chunk::Type_Normal;
240 chunk_header.signed_ = OMFormat::is_signed(n[0]);
241 chunk_header.float_ = OMFormat::is_float(n[0]);
242 chunk_header.dim_ = OMFormat::dim(n);
243 chunk_header.bits_ = OMFormat::bits(n[0]);
245 bytes += store( _os, chunk_header, swap );
246 for (i=0, nV=header.n_vertices_; i<nV; ++i)
247 bytes += vector_store( _os, _be.normal(
VertexHandle(i)), swap );
255 chunk_header.name_ =
false;
256 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
257 chunk_header.type_ = OMFormat::Chunk::Type_Color;
258 chunk_header.signed_ = OMFormat::is_signed( c[0] );
259 chunk_header.float_ = OMFormat::is_float( c[0] );
260 chunk_header.dim_ = OMFormat::dim( c );
261 chunk_header.bits_ = OMFormat::bits( c[0] );
263 bytes += store( _os, chunk_header, swap );
264 for (i=0, nV=header.n_vertices_; i<nV; ++i)
265 bytes += vector_store( _os, _be.color(
VertexHandle(i)), swap );
273 chunk_header.name_ =
false;
274 chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
275 chunk_header.type_ = OMFormat::Chunk::Type_Texcoord;
276 chunk_header.signed_ = OMFormat::is_signed(t[0]);
277 chunk_header.float_ = OMFormat::is_float(t[0]);
278 chunk_header.dim_ = OMFormat::dim(t);
279 chunk_header.bits_ = OMFormat::bits(t[0]);
282 bytes += store(_os, chunk_header, swap);
284 for (i = 0, nV = header.n_vertices_; i < nV; ++i)
285 bytes += vector_store(_os, _be.texcoord(
VertexHandle(i)), swap);
293 chunk_header.name_ =
false;
294 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
295 chunk_header.type_ = OMFormat::Chunk::Type_Topology;
296 chunk_header.signed_ = 0;
297 chunk_header.float_ = 0;
298 chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
299 chunk_header.bits_ = OMFormat::needed_bits(_be.n_vertices());
301 bytes += store( _os, chunk_header, swap );
303 for (i=0, nF=header.n_faces_; i<nF; ++i)
305 nV = _be.get_vhandles(
FaceHandle(i), vhandles);
306 if ( header.mesh_ ==
'P' )
307 bytes += store( _os, vhandles.size(), OMFormat::Chunk::Integer_16, swap );
309 for (
size_t j=0; j < vhandles.size(); ++j)
311 using namespace OMFormat;
312 using namespace GenProg;
314 bytes += store( _os, vhandles[j].idx(), Chunk::Integer_Size(chunk_header.bits_), swap );
325 const BaseProperty *bp = _be.kernel()._get_fprop(
"f:normals");
332 chunk_header.name_ =
false;
333 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
334 chunk_header.type_ = OMFormat::Chunk::Type_Normal;
335 chunk_header.signed_ = OMFormat::is_signed(n[0]);
336 chunk_header.float_ = OMFormat::is_float(n[0]);
337 chunk_header.dim_ = OMFormat::dim(n);
338 chunk_header.bits_ = OMFormat::bits(n[0]);
340 bytes += store( _os, chunk_header, swap );
342 for (i=0, nF=header.n_faces_; i<nF; ++i)
343 bytes += vector_store( _os, _be.normal(
FaceHandle(i)), swap );
345 bytes += bp->
store(_os, swap );
360 const BaseProperty *bp = _be.kernel()._get_fprop(
"f:colors");
367 chunk_header.name_ =
false;
368 chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
369 chunk_header.type_ = OMFormat::Chunk::Type_Color;
370 chunk_header.signed_ = OMFormat::is_signed( c[0] );
371 chunk_header.float_ = OMFormat::is_float( c[0] );
372 chunk_header.dim_ = OMFormat::dim( c );
373 chunk_header.bits_ = OMFormat::bits( c[0] );
375 bytes += store( _os, chunk_header, swap );
377 for (i=0, nF=header.n_faces_; i<nF; ++i)
378 bytes += vector_store( _os, _be.color(
FaceHandle(i)), swap );
380 bytes += bp->
store(_os, swap);
390 BaseKernel::const_prop_iterator prop;
392 for (prop = _be.kernel()->vprops_begin();
393 prop != _be.kernel()->vprops_end(); ++prop)
395 if ( !*prop )
continue;
396 if ( (*prop)->name()[1]==
':')
continue;
397 bytes += store_binary_custom_chunk(_os, **prop,
398 OMFormat::Chunk::Entity_Vertex, swap );
400 for (prop = _be.kernel()->fprops_begin();
401 prop != _be.kernel()->fprops_end(); ++prop)
403 if ( !*prop )
continue;
404 if ( (*prop)->name()[1]==
':')
continue;
405 bytes += store_binary_custom_chunk(_os, **prop,
406 OMFormat::Chunk::Entity_Face, swap );
408 for (prop = _be.kernel()->eprops_begin();
409 prop != _be.kernel()->eprops_end(); ++prop)
411 if ( !*prop )
continue;
412 if ( (*prop)->name()[1]==
':')
continue;
413 bytes += store_binary_custom_chunk(_os, **prop,
414 OMFormat::Chunk::Entity_Edge, swap );
416 for (prop = _be.kernel()->hprops_begin();
417 prop != _be.kernel()->hprops_end(); ++prop)
419 if ( !*prop )
continue;
420 if ( (*prop)->name()[1]==
':')
continue;
421 bytes += store_binary_custom_chunk(_os, **prop,
422 OMFormat::Chunk::Entity_Halfedge, swap );
424 for (prop = _be.kernel()->mprops_begin();
425 prop != _be.kernel()->mprops_end(); ++prop)
427 if ( !*prop )
continue;
428 if ( (*prop)->name()[1]==
':')
continue;
429 bytes += store_binary_custom_chunk(_os, **prop,
430 OMFormat::Chunk::Entity_Mesh, swap );
433 std::clog <<
"#bytes written: " << bytes << std::endl;
440 size_t _OMWriter_::store_binary_custom_chunk(std::ostream& _os,
442 OMFormat::Chunk::Entity _entity,
459 OMFormat::Chunk::esize_t element_size = OMFormat::Chunk::esize_t(_bp.
element_size());
460 OMFormat::Chunk::Header chdr;
464 chdr.entity_ = _entity;
465 chdr.type_ = OMFormat::Chunk::Type_Custom;
468 chdr.dim_ = OMFormat::Chunk::Dim_1D;
469 chdr.bits_ = element_size;
475 bytes += store( _os, chdr, _swap );
478 bytes += store( _os, OMFormat::Chunk::PropertyName(_bp.
name()), _swap );
481 bytes += store( _os, _bp.
size_of(), OMFormat::Chunk::Integer_32, _swap );
487 bytes += ( b=_bp.
store( _os, _swap ) );
499 size_t bytes =
sizeof( OMFormat::Header );
Assume little endian byte ordering.
Has (r) / store (w) texture coordinates.
big endian (Motorola's 68x family, DEC Alpha, MIPS)
Has (r) / store (w) vertex normals.
bool persistent(void) const
Returns true if the persistent flag is enabled else false.
Has (r) / store (w) face normals.
virtual size_t size_of() const
Return size of property in bytes.
_OMWriter_ __OMWriterInstance
Declare the single entity of the OM writer.
virtual size_t element_size() const =0
Size of one element in bytes or UnknownSize if not known.
bool write(std::ostream &, BaseExporter &, Options, std::streamsize _precision=6) const
Set options for reader/writer modules.
Handle for a vertex entity.
const std::string & name() const
Return the name of the property.
bool register_module(BaseReader *_bl)
Swap byte order in binary mode.
virtual size_t store(std::ostream &_ostr, bool _swap) const =0
Store self as one binary block.
Handle for a face entity.
Has (r) / store (w) face colors.
Has (r) / store (w) vertex colors.
Assume big endian byte ordering.
static Type local()
Return endian type of host system.
_IOManager_ & IOManager()
size_t binary_size(BaseExporter &_be, Options _opt) const
Returns expected size of file if binary format is supported else 0.