61 #include <OpenMesh/Core/Utils/Endian.hh>
62 #include <OpenMesh/Core/IO/OMFormat.hh>
63 #include <OpenMesh/Core/IO/reader/OMReader.hh>
85 _OMReader_::_OMReader_()
104 std::ifstream ifs(_filename.c_str(), std::ios::binary);
110 ifs.unsetf(std::ios::skipws);
112 if (!ifs.is_open() || !ifs.good()) {
113 omerr() <<
"[OMReader] : cannot not open file " << _filename << std::endl;
118 bool result =
read(ifs, _bi, _opt);
123 _opt = _opt & fileOptions_;
141 omerr() <<
"[OMReader] : cannot read from stream " << std::endl;
146 bool result = read_binary(_is, _bi, _opt);
151 _opt = _opt & fileOptions_;
169 bool _OMReader_::read_binary(std::istream& _is,
BaseImporter& _bi, Options& _opt)
const
176 bytes_ += restore(_is, header_, swap);
180 bytes_ += restore(_is, chunk_header_, swap);
186 if (chunk_header_.name_) {
187 OMFormat::Chunk::PropertyName pn;
188 bytes_ += restore(_is, property_name_, swap);
193 switch (chunk_header_.entity_) {
194 case OMFormat::Chunk::Entity_Vertex:
195 if (!read_binary_vertex_chunk(_is, _bi, _opt, swap))
198 case OMFormat::Chunk::Entity_Face:
199 if (!read_binary_face_chunk(_is, _bi, _opt, swap))
202 case OMFormat::Chunk::Entity_Edge:
203 if (!read_binary_edge_chunk(_is, _bi, _opt, swap))
206 case OMFormat::Chunk::Entity_Halfedge:
207 if (!read_binary_halfedge_chunk(_is, _bi, _opt, swap))
210 case OMFormat::Chunk::Entity_Mesh:
211 if (!read_binary_mesh_chunk(_is, _bi, _opt, swap))
232 std::ifstream ifile(_filename.c_str());
243 std::vector<char> evt;
247 while (evt.size() < 4)
248 evt.push_back(static_cast<char>(_is.get()));
251 std::vector<char>::reverse_iterator it = evt.rbegin();
252 while (it != evt.rend())
256 OMFormat::Header *hdr = (OMFormat::Header*) &evt[0];
259 if (hdr->magic_[0] !=
'O' || hdr->magic_[1] !=
'M')
263 switch (hdr->mesh_) {
273 return supports(hdr->version_);
278 bool _OMReader_::supports(
const OMFormat::uint8 )
const
286 bool _OMReader_::read_binary_vertex_chunk(std::istream &_is,
BaseImporter &_bi, Options &_opt,
bool _swap)
const
288 using OMFormat::Chunk;
290 assert( chunk_header_.entity_ == Chunk::Entity_Vertex);
296 OMFormat::Chunk::PropertyName custom_prop;
299 switch (chunk_header_.type_) {
300 case Chunk::Type_Pos:
301 assert( OMFormat::dimensions(chunk_header_) ==
size_t(OpenMesh::Vec3f::dim()));
303 for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
304 bytes_ += vector_restore(_is, v3f, _swap);
309 case Chunk::Type_Normal:
310 assert( OMFormat::dimensions(chunk_header_) ==
size_t(OpenMesh::Vec3f::dim()));
313 for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
314 bytes_ += vector_restore(_is, v3f, _swap);
315 if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal())
316 _bi.set_normal(VertexHandle(
int(vidx)), v3f);
320 case Chunk::Type_Texcoord:
321 assert( OMFormat::dimensions(chunk_header_) ==
size_t(OpenMesh::Vec2f::dim()));
324 for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
325 bytes_ += vector_restore(_is, v2f, _swap);
326 if (fileOptions_.vertex_has_texcoord() && _opt.vertex_has_texcoord())
327 _bi.set_texcoord(VertexHandle(
int(vidx)), v2f);
331 case Chunk::Type_Color:
333 assert( OMFormat::dimensions(chunk_header_) == 3);
337 for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
338 bytes_ += vector_restore(_is, v3uc, _swap);
339 if (fileOptions_.vertex_has_color() && _opt.vertex_has_color())
340 _bi.set_color(VertexHandle(
int(vidx)), v3uc);
344 case Chunk::Type_Custom:
346 bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap);
348 vidx = header_.n_vertices_;
354 omerr() <<
"Unknown chunk type ignored!\n";
355 size_t size_of = header_.n_vertices_ * OMFormat::vector_size(chunk_header_);
362 return vidx == header_.n_vertices_;
368 bool _OMReader_::read_binary_face_chunk(std::istream &_is,
BaseImporter &_bi, Options &_opt,
bool _swap)
const
370 using OMFormat::Chunk;
372 assert( chunk_header_.entity_ == Chunk::Entity_Face);
378 switch (chunk_header_.type_) {
379 case Chunk::Type_Topology: {
380 BaseImporter::VHandles vhandles;
384 switch (header_.mesh_) {
393 for (; fidx < header_.n_faces_; ++fidx) {
394 if (header_.mesh_ ==
'P')
395 bytes_ += restore(_is, nV, Chunk::Integer_16, _swap);
398 for (
size_t j = 0; j < nV; ++j) {
399 bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap);
401 vhandles.push_back(VertexHandle(
int(vidx)));
404 _bi.add_face(vhandles);
409 case Chunk::Type_Normal:
410 assert( OMFormat::dimensions(chunk_header_) ==
size_t(OpenMesh::Vec3f::dim()));
413 for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
414 bytes_ += vector_restore(_is, v3f, _swap);
415 if( fileOptions_.face_has_normal() && _opt.face_has_normal())
416 _bi.set_normal(FaceHandle(
int(fidx)), v3f);
420 case Chunk::Type_Color:
422 assert( OMFormat::dimensions(chunk_header_) == 3);
425 for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
426 bytes_ += vector_restore(_is, v3uc, _swap);
427 if( fileOptions_.face_has_color() && _opt.face_has_color())
428 _bi.set_color(FaceHandle(
int(fidx)), v3uc);
432 case Chunk::Type_Custom:
434 bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_fprop(property_name_), header_.n_faces_, _swap);
436 fidx = header_.n_faces_;
442 omerr() <<
"Unknown chunk type ignore!\n";
443 size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
448 return fidx == header_.n_faces_;
454 bool _OMReader_::read_binary_edge_chunk(std::istream &_is,
BaseImporter &_bi, Options &,
bool _swap)
const
456 using OMFormat::Chunk;
458 assert( chunk_header_.entity_ == Chunk::Entity_Edge);
462 switch (chunk_header_.type_) {
463 case Chunk::Type_Custom:
465 bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_eprop(property_name_), header_.n_edges_, _swap);
471 size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
482 bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is,
BaseImporter &_bi, Options &,
bool _swap)
const
484 using OMFormat::Chunk;
486 assert( chunk_header_.entity_ == Chunk::Entity_Halfedge);
490 switch (chunk_header_.type_) {
491 case Chunk::Type_Custom:
493 bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap);
498 omerr() <<
"Unknown chunk type ignored!\n";
499 size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
510 bool _OMReader_::read_binary_mesh_chunk(std::istream &_is,
BaseImporter &_bi, Options & ,
bool _swap)
const
512 using OMFormat::Chunk;
514 assert( chunk_header_.entity_ == Chunk::Entity_Mesh);
518 switch (chunk_header_.type_) {
519 case Chunk::Type_Custom:
521 bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_mprop(property_name_), 1, _swap);
527 size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
539 size_t _OMReader_::restore_binary_custom_data(std::istream& _is, BaseProperty* _bp,
size_t _n_elem,
bool _swap)
const
541 assert( !_bp || (_bp->name() == property_name_));
543 using OMFormat::Chunk;
546 Chunk::esize_t block_size;
547 Chunk::PropertyName custom_prop;
549 bytes += restore(_is, block_size, OMFormat::Chunk::Integer_32, _swap);
552 size_t n_bytes = _bp->size_of(_n_elem);
556 #if defined(OM_DEBUG)
558 bytes += (b=_bp->restore( _is, _swap ));
560 bytes += _bp->restore(_is, _swap);
563 #if defined(OM_DEBUG)
564 assert( block_size == b );
567 assert( block_size == _bp->size_of());
571 omerr() <<
"Warning! Property " << _bp->name() <<
" not loaded: " <<
"Mismatching data sizes!n";
576 _is.ignore(block_size);
Has (r) / store (w) vertex normals.
bool register_module(BaseReader *_bl)
virtual bool can_u_read(const std::string &_filename) const
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...
Has (r) / store (w) face normals.
Has (r) / store (w) face colors.
_OMReader_ __OMReaderInstance
Declare the single entity of the OM reader.
Has (r) / store (w) texture coordinates.
Set options for reader/writer modules.
static Type local()
Return endian type of host system.
big endian (Motorola's 68x family, DEC Alpha, MIPS)
size_t size_of(const T &_v)
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt)
Swap byte order in binary mode.
Has (r) / store (w) vertex colors.
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
_IOManager_ & IOManager()
virtual bool can_u_read(const std::string &_filename) const
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...