diff --git a/src/OpenMesh/Core/IO/exporter/BaseExporter.hh b/src/OpenMesh/Core/IO/exporter/BaseExporter.hh index 2c93e19c..bbd2b9e9 100644 --- a/src/OpenMesh/Core/IO/exporter/BaseExporter.hh +++ b/src/OpenMesh/Core/IO/exporter/BaseExporter.hh @@ -104,6 +104,7 @@ public: virtual Vec4f colorAf(VertexHandle _vh) const = 0; virtual Vec2f texcoord(VertexHandle _vh) const = 0; virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0; + virtual OpenMesh::Attributes::StatusInfo status(VertexHandle _vh) const = 0; // get face data @@ -111,13 +112,6 @@ public: get_vhandles(FaceHandle _fh, std::vector& _vhandles) const=0; - // information needed for a halfedge based data structure such as OpenMesh - virtual int get_halfedge_id(VertexHandle _vh) = 0; - virtual int get_halfedge_id(FaceHandle _vh) = 0; - virtual int get_next_halfedge_id(HalfedgeHandle _heh) = 0; - virtual int get_to_vertex_id(HalfedgeHandle _heh) = 0; - virtual int get_face_id(HalfedgeHandle _heh) = 0; - /// /// \brief getHeh returns the HalfEdgeHandle that belongs to the face /// specified by _fh and has a toVertexHandle that corresponds to _vh. @@ -135,6 +129,7 @@ public: virtual Vec4ui colorAi(FaceHandle _fh) const = 0; virtual Vec3f colorf(FaceHandle _fh) const = 0; virtual Vec4f colorAf(FaceHandle _fh) const = 0; + virtual OpenMesh::Attributes::StatusInfo status(FaceHandle _fh) const = 0; // get edge data virtual Vec3uc color(EdgeHandle _eh) const = 0; @@ -143,6 +138,15 @@ public: virtual Vec4ui colorAi(EdgeHandle _eh) const = 0; virtual Vec3f colorf(EdgeHandle _eh) const = 0; virtual Vec4f colorAf(EdgeHandle _eh) const = 0; + virtual OpenMesh::Attributes::StatusInfo status(EdgeHandle _eh) const = 0; + + // get halfedge data + virtual int get_halfedge_id(VertexHandle _vh) = 0; + virtual int get_halfedge_id(FaceHandle _vh) = 0; + virtual int get_next_halfedge_id(HalfedgeHandle _heh) = 0; + virtual int get_to_vertex_id(HalfedgeHandle _heh) = 0; + virtual int get_face_id(HalfedgeHandle _heh) = 0; + virtual OpenMesh::Attributes::StatusInfo status(HalfedgeHandle _heh) const = 0; // get reference to base kernel virtual const BaseKernel* kernel() { return 0; } diff --git a/src/OpenMesh/Core/IO/exporter/ExporterT.hh b/src/OpenMesh/Core/IO/exporter/ExporterT.hh index 0ea30e6e..84313d2f 100644 --- a/src/OpenMesh/Core/IO/exporter/ExporterT.hh +++ b/src/OpenMesh/Core/IO/exporter/ExporterT.hh @@ -171,6 +171,13 @@ public: : Vec2f(0.0f, 0.0f)); } + OpenMesh::Attributes::StatusInfo status(VertexHandle _vh) const + { + if (mesh_.has_vertex_status()) + return mesh_.status(_vh); + return OpenMesh::Attributes::StatusInfo(); + } + // get edge data Vec3uc color(EdgeHandle _eh) const @@ -215,21 +222,15 @@ public: : Vec4f(0, 0, 0, 0)); } - // get face data - - unsigned int get_vhandles(FaceHandle _fh, - std::vector& _vhandles) const + OpenMesh::Attributes::StatusInfo status(EdgeHandle _eh) const { - unsigned int count(0); - _vhandles.clear(); - for (typename Mesh::CFVIter fv_it=mesh_.cfv_iter(_fh); fv_it.is_valid(); ++fv_it) - { - _vhandles.push_back(*fv_it); - ++count; - } - return count; + if (mesh_.has_edge_status()) + return mesh_.status(_eh); + return OpenMesh::Attributes::StatusInfo(); } + // get halfedge data + int get_halfedge_id(VertexHandle _vh) override { return mesh_.halfedge_handle(_vh).idx(); @@ -255,6 +256,28 @@ public: return mesh_.face_handle(_heh).idx(); } + OpenMesh::Attributes::StatusInfo status(HalfedgeHandle _heh) const + { + if (mesh_.has_halfedge_status()) + return mesh_.status(_heh); + return OpenMesh::Attributes::StatusInfo(); + } + + // get face data + + unsigned int get_vhandles(FaceHandle _fh, + std::vector& _vhandles) const + { + unsigned int count(0); + _vhandles.clear(); + for (typename Mesh::CFVIter fv_it=mesh_.cfv_iter(_fh); fv_it.is_valid(); ++fv_it) + { + _vhandles.push_back(*fv_it); + ++count; + } + return count; + } + unsigned int get_face_texcoords(std::vector& _hehandles) const { unsigned int count(0); @@ -329,6 +352,13 @@ public: : Vec4f(0, 0, 0, 0)); } + OpenMesh::Attributes::StatusInfo status(FaceHandle _fh) const + { + if (mesh_.has_face_status()) + return mesh_.status(_fh); + return OpenMesh::Attributes::StatusInfo(); + } + virtual const BaseKernel* kernel() { return &mesh_; } diff --git a/src/OpenMesh/Core/IO/importer/BaseImporter.hh b/src/OpenMesh/Core/IO/importer/BaseImporter.hh index c1331e7d..46630a5b 100644 --- a/src/OpenMesh/Core/IO/importer/BaseImporter.hh +++ b/src/OpenMesh/Core/IO/importer/BaseImporter.hh @@ -142,6 +142,9 @@ public: // set vertex texture coordinate virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0; + // set vertex status + virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // set next halfedge handle virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) = 0; @@ -157,6 +160,9 @@ public: // set 3d vertex texture coordinate virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) = 0; + // set halfedge status + virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // set edge color virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0; @@ -169,6 +175,9 @@ public: // set edge color virtual void set_color(EdgeHandle _eh, const Vec4f& _color) = 0; + // set edge status + virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // set face normal virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0; @@ -184,6 +193,9 @@ public: // set face color virtual void set_color(FaceHandle _fh, const Vec4f& _color) = 0; + // set face status + virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) = 0; + // Store a property in the mesh mapping from an int to a texture file // Use set_face_texindex to set the index for each face virtual void add_texture_information( int _id , std::string _name ) = 0; diff --git a/src/OpenMesh/Core/IO/importer/ImporterT.hh b/src/OpenMesh/Core/IO/importer/ImporterT.hh index 48744a36..d95e1cbe 100644 --- a/src/OpenMesh/Core/IO/importer/ImporterT.hh +++ b/src/OpenMesh/Core/IO/importer/ImporterT.hh @@ -257,6 +257,13 @@ public: mesh_.set_texcoord2D(_vh, vector_cast(_texcoord)); } + virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) + { + if (!mesh_.has_vertex_status()) + mesh_.request_vertex_status(); + mesh_.status(_vh) = _status; + } + virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) override { mesh_.set_next_halfedge_handle(_heh, _next); @@ -286,6 +293,12 @@ public: mesh_.set_texcoord3D(_heh, vector_cast(_texcoord)); } + virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) + { + if (!mesh_.has_halfedge_status()) + mesh_.request_halfedge_status(); + mesh_.status(_heh) = _status; + } // edge attributes @@ -313,6 +326,13 @@ public: mesh_.set_color(_eh, color_cast(_color)); } + virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) + { + if (!mesh_.has_edge_status()) + mesh_.request_edge_status(); + mesh_.status(_eh) = _status; + } + // face attributes virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) @@ -345,6 +365,13 @@ public: mesh_.set_color(_fh, color_cast(_color)); } + virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) + { + if (!mesh_.has_face_status()) + mesh_.request_face_status(); + mesh_.status(_fh) = _status; + } + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) { // get first halfedge handle diff --git a/src/OpenMesh/Core/IO/reader/OMReader.cc b/src/OpenMesh/Core/IO/reader/OMReader.cc index 00af3f73..8a22d607 100644 --- a/src/OpenMesh/Core/IO/reader/OMReader.cc +++ b/src/OpenMesh/Core/IO/reader/OMReader.cc @@ -294,6 +294,7 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, OpenMesh::Vec3f v3f; OpenMesh::Vec2f v2f; OpenMesh::Vec3uc v3uc; // rgb + OpenMesh::Attributes::StatusInfo status; OMFormat::Chunk::PropertyName custom_prop; @@ -343,6 +344,20 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, } break; + case Chunk::Type_Status: + { + assert( OMFormat::dimensions(chunk_header_) == 1); + + fileOptions_ += Options::Status; + + for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { + bytes_ += restore(_is, status, _swap); + if (fileOptions_.vertex_has_status() && _opt.vertex_has_status()) + _bi.set_status(VertexHandle(int(vidx)), status); + } + break; + } + case Chunk::Type_Custom: bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap); @@ -389,6 +404,7 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op size_t fidx = 0; OpenMesh::Vec3f v3f; // normal OpenMesh::Vec3uc v3uc; // rgb + OpenMesh::Attributes::StatusInfo status; switch (chunk_header_.type_) { case Chunk::Type_Topology: @@ -459,6 +475,19 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op _bi.set_color(FaceHandle(int(fidx)), v3uc); } break; + case Chunk::Type_Status: + { + assert( OMFormat::dimensions(chunk_header_) == 1); + + fileOptions_ += Options::Status; + + for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) { + bytes_ += restore(_is, status, _swap); + if (fileOptions_.face_has_status() && _opt.face_has_status()) + _bi.set_status(FaceHandle(int(fidx)), status); + } + break; + } case Chunk::Type_Custom: diff --git a/src/OpenMesh/Core/IO/writer/OMWriter.cc b/src/OpenMesh/Core/IO/writer/OMWriter.cc index cc12d73d..721a25a1 100644 --- a/src/OpenMesh/Core/IO/writer/OMWriter.cc +++ b/src/OpenMesh/Core/IO/writer/OMWriter.cc @@ -420,53 +420,77 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be, // ---------- write vertex status if (_be.n_vertices() && _be.has_vertex_status() && _opt.check(Options::Status)) { - //store status as costum property because that already works - auto prop = _be.kernel()->_get_vprop("v:status"); - assert(prop != nullptr); - bool persistent = prop->persistent(); - const_cast(prop)->set_persistent(true); - bytes += store_binary_custom_chunk(_os, *prop, - OMFormat::Chunk::Entity_Vertex, swap ); - const_cast(prop)->set_persistent(persistent); + auto s = _be.status(VertexHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_vertices_; i < nV; ++i) + bytes += store(_os, _be.status(VertexHandle(i)), swap); } // ---------- write edge status if (_be.n_edges() && _be.has_edge_status() && _opt.check(Options::Status)) { - //store status as costum property because that already works - auto prop = _be.kernel()->_get_eprop("e:status"); - assert(prop != nullptr); - bool persistent = prop->persistent(); - const_cast(prop)->set_persistent(true); - bytes += store_binary_custom_chunk(_os, *prop, - OMFormat::Chunk::Entity_Edge, swap ); - const_cast(prop)->set_persistent(persistent); + auto s = _be.status(EdgeHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_edges_; i < nV; ++i) + bytes += store(_os, _be.status(EdgeHandle(i)), swap); } // ---------- write halfedge status if (_be.n_edges() && _be.has_halfedge_status() && _opt.check(Options::Status)) { - //store status as costum property because that already works - auto prop = _be.kernel()->_get_hprop("h:status"); - assert(prop != nullptr); - bool persistent = prop->persistent(); - const_cast(prop)->set_persistent(true); - bytes += store_binary_custom_chunk(_os, *prop, - OMFormat::Chunk::Entity_Halfedge, swap ); - const_cast(prop)->set_persistent(persistent); + auto s = _be.status(HalfedgeHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_edges_ * 2; i < nV; ++i) + bytes += store(_os, _be.status(HalfedgeHandle(i)), swap); } // ---------- write face status if (_be.n_faces() && _be.has_face_status() && _opt.check(Options::Status)) { - //store status as costum property because that already works - auto prop = _be.kernel()->_get_fprop("f:status"); - assert(prop != nullptr); - bool persistent = prop->persistent(); - const_cast(prop)->set_persistent(true); - bytes += store_binary_custom_chunk(_os, *prop, - OMFormat::Chunk::Entity_Face, swap ); - const_cast(prop)->set_persistent(persistent); + auto s = _be.status(FaceHandle(0)); + chunk_header.name_ = false; + chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex; + chunk_header.type_ = OMFormat::Chunk::Type_Status; + chunk_header.signed_ = false; + chunk_header.float_ = false; + chunk_header.dim_ = OMFormat::Chunk::Dim_1D; + chunk_header.bits_ = OMFormat::bits(s); + + // std::clog << chunk_header << std::endl; + bytes += store(_os, chunk_header, swap); + + for (i = 0, nV = header.n_faces_; i < nV; ++i) + bytes += store(_os, _be.status(FaceHandle(i)), swap); } // -------------------- write custom properties