From 05ea032f3d0a6adfb5f0c0945682657d450b9717 Mon Sep 17 00:00:00 2001 From: Hugues Delorme Date: Tue, 14 Jun 2016 16:42:22 +0200 Subject: [PATCH] gmio_support: refactor gmio_stl_mesh OCC support Make use of gmio_support for OpenCascade less error-prone and easier to maintain. Ugly const_cast<> have also been eradicated. --- benchmarks/benchmark_opencascade/main.cpp | 8 +- examples/occstl_write_file.cpp | 4 +- src/gmio_support/stl_occ_brep.cpp | 149 ++++++++---------- src/gmio_support/stl_occ_brep.h | 56 +++---- src/gmio_support/stl_occ_mesh.cpp | 144 ++++++++--------- src/gmio_support/stl_occ_mesh.h | 79 +++++----- src/gmio_support/stl_occ_meshvs.cpp | 77 +++++---- src/gmio_support/stl_occ_meshvs.h | 43 ++--- ...ColStd_MapIteratorOfPackedMapOfInteger.hxx | 2 + 9 files changed, 261 insertions(+), 301 deletions(-) diff --git a/benchmarks/benchmark_opencascade/main.cpp b/benchmarks/benchmark_opencascade/main.cpp index 8945551..324755a 100644 --- a/benchmarks/benchmark_opencascade/main.cpp +++ b/benchmarks/benchmark_opencascade/main.cpp @@ -181,14 +181,14 @@ static void stl_write( static void stl_mesh_write(const char* filepath, gmio_stl_format format) { - const gmio_stl_occmesh_iterator occ_itmesh(stlMesh); - stl_write(filepath, format, gmio_stl_occmesh(occ_itmesh)); + const gmio_stl_mesh_occmesh mesh(stlMesh); + stl_write(filepath, format, mesh); } static void stl_brep_write(const char* filepath, gmio_stl_format format) { - const gmio_stl_occshape_iterator occ_itshape(BmkBRep::inputShape); - stl_write(filepath, format, gmio_stl_occmesh(occ_itshape)); + const gmio_stl_mesh_occshape mesh(BmkBRep::inputShape); + stl_write(filepath, format, mesh); } static void stla_mesh_write(const void* filepath) diff --git a/examples/occstl_write_file.cpp b/examples/occstl_write_file.cpp index cb49764..0938174 100644 --- a/examples/occstl_write_file.cpp +++ b/examples/occstl_write_file.cpp @@ -26,9 +26,7 @@ int main(int argc, char** argv) Handle_StlMesh_Mesh occmesh = new StlMesh_Mesh; // Initialize the OpenCascade StlMesh_Mesh here // ... - - const gmio_stl_occmesh_iterator occmesh_it(occmesh); - const gmio_stl_mesh mesh = gmio_stl_occmesh(occmesh_it); + const gmio_stl_mesh_occmesh mesh(occmesh); // Write binary STL(little-endian), using default options(NULL) error = gmio_stl_write_file( diff --git a/src/gmio_support/stl_occ_brep.cpp b/src/gmio_support/stl_occ_brep.cpp index bbde45d..a0482c1 100644 --- a/src/gmio_support/stl_occ_brep.cpp +++ b/src/gmio_support/stl_occ_brep.cpp @@ -18,64 +18,80 @@ #include "stl_occ_utils.h" #include +#include #include #include #include -gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occshape_iterator& it) +gmio_stl_mesh_occshape::gmio_stl_mesh_occshape() + : m_shape(NULL) { - gmio_stl_mesh mesh = {}; - mesh.cookie = ⁢ + this->init_C_members(); +} - if (it.shape() != NULL) { +gmio_stl_mesh_occshape::gmio_stl_mesh_occshape(const TopoDS_Shape& shape) + : m_shape(&shape) +{ + this->init_C_members(); + + // Count facets and triangles + std::size_t face_count = 0; + for (TopExp_Explorer expl(shape, TopAbs_FACE); expl.More(); expl.Next()) { TopLoc_Location loc; - const TopoDS_Shape& sh = *it.shape(); - for (TopExp_Explorer expl(sh, TopAbs_FACE); expl.More(); expl.Next()) { - const Handle_Poly_Triangulation& poly = - BRep_Tool::Triangulation(TopoDS::Face(expl.Current()), loc); - if (!poly.IsNull()) - mesh.triangle_count += poly->NbTriangles(); + const Handle_Poly_Triangulation& hnd_face_poly = + BRep_Tool::Triangulation(TopoDS::Face(expl.Current()), loc); + if (!hnd_face_poly.IsNull()) { + ++face_count; + this->triangle_count += hnd_face_poly->NbTriangles(); } } - //mesh.func_get_triangle = internal::occshape_get_triangle; - mesh.func_get_triangle = &gmio_stl_occshape_iterator::get_triangle; - return mesh; -} - - -gmio_stl_occshape_iterator::gmio_stl_occshape_iterator() - : m_shape(NULL) -{ - this->reset_face(); -} - -gmio_stl_occshape_iterator::gmio_stl_occshape_iterator(const TopoDS_Shape& shape) - : m_shape(&shape), - m_expl(shape, TopAbs_FACE) -{ - if (m_expl.More()) { - this->cache_face(TopoDS::Face(m_expl.Current())); - } - else { - this->reset_face(); + // Fill face and triangle datas + m_vec_face_data.reserve(face_count); + m_vec_triangle_data.reserve(this->triangle_count); + for (TopExp_Explorer expl(shape, TopAbs_FACE); expl.More(); expl.Next()) { + const TopoDS_Face& topoface = TopoDS::Face(expl.Current()); + TopLoc_Location loc; + const Handle_Poly_Triangulation& hnd_face_poly = + BRep_Tool::Triangulation(topoface, loc); + if (!hnd_face_poly.IsNull()) { + { // Add next face_data + struct face_data facedata; + facedata.trsf = loc.Transformation(); + facedata.is_reversed = (topoface.Orientation() == TopAbs_REVERSED); + if (facedata.trsf.IsNegative()) + facedata.is_reversed = !facedata.is_reversed; + facedata.ptr_nodes = &hnd_face_poly->Nodes(); + m_vec_face_data.push_back(std::move(facedata)); + } + const struct face_data& last_facedata = m_vec_face_data.back(); + // Add triangle_datas + const Poly_Array1OfTriangle& vec_face_tri = hnd_face_poly->Triangles(); + for (int i = vec_face_tri.Lower(); i <= vec_face_tri.Upper(); ++i) { + struct triangle_data tridata; + tridata.ptr_triangle = &vec_face_tri.Value(i); + tridata.ptr_face_data = &last_facedata; + m_vec_triangle_data.push_back(std::move(tridata)); + } + } } } -void gmio_stl_occshape_iterator::get_triangle( - const void *cookie, uint32_t /*tri_id*/, gmio_stl_triangle *tri) +// static +void gmio_stl_mesh_occshape::get_triangle( + const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri) { - void* wcookie = const_cast(cookie); - gmio_stl_occshape_iterator* it = - static_cast(wcookie); + const gmio_stl_mesh_occshape* it = + static_cast(cookie); - const bool reversed = it->m_face_is_reversed; - const gp_Trsf& trsf = it->m_face_trsf; - const TColgp_Array1OfPnt* nodes = it->m_face_nodes; + const struct triangle_data* tridata = &it->m_vec_triangle_data.at(tri_id); + const struct face_data* facedata = tridata->ptr_face_data; + const bool reversed = facedata->is_reversed; + const gp_Trsf& trsf = facedata->trsf; + const TColgp_Array1OfPnt* nodes = facedata->ptr_nodes; int n1, n2, n3; // Node index - const Poly_Triangle& curr_tri = - it->m_face_triangles->Value(it->m_face_tri_id); - curr_tri.Get(n1, n2, n3); + const Poly_Triangle* occtri = tridata->ptr_triangle; + occtri->Get(n1, n2, n3); gp_Pnt p1 = nodes->Value(n1); gp_Pnt p2 = nodes->Value(reversed ? n3 : n2); gp_Pnt p3 = nodes->Value(reversed ? n2 : n3); @@ -88,52 +104,11 @@ void gmio_stl_occshape_iterator::get_triangle( gmio_stl_occ_copy_xyz(&tri->v2, p2.XYZ()); gmio_stl_occ_copy_xyz(&tri->v3, p3.XYZ()); gmio_stl_triangle_compute_normal(tri); - it->move_to_next_tri(); } -bool gmio_stl_occshape_iterator::move_to_next_tri() +void gmio_stl_mesh_occshape::init_C_members() { - ++m_face_tri_id; - if (m_face_tri_id > m_face_last_tri_id) { - m_expl.Next(); - if (m_expl.More()) { - this->cache_face(TopoDS::Face(m_expl.Current())); - return true; - } - return false; - } - return true; -} - -void gmio_stl_occshape_iterator::reset_face() -{ - m_face_poly = NULL; - m_face_nodes = NULL; - m_face_triangles = NULL; - if (m_face_trsf.Form() != gp_Identity) - m_face_trsf = gp_Trsf(); - m_face_is_reversed = false; - m_face_tri_id = 0; - m_face_last_tri_id = 0; -} - -void gmio_stl_occshape_iterator::cache_face(const TopoDS_Face& face) -{ - TopLoc_Location loc; - const Handle_Poly_Triangulation& hnd_face_poly = - BRep_Tool::Triangulation(face, loc); - m_face_trsf = loc.Transformation(); - m_face_poly = - !hnd_face_poly.IsNull() ? hnd_face_poly.operator->() : NULL; - m_face_nodes = - m_face_poly != NULL ? &m_face_poly->Nodes() : NULL; - m_face_triangles = - m_face_poly != NULL ? &m_face_poly->Triangles() : NULL; - m_face_is_reversed = face.Orientation() == TopAbs_REVERSED; - if (m_face_trsf.IsNegative()) - m_face_is_reversed = !m_face_is_reversed; - m_face_tri_id = - m_face_triangles != NULL ? m_face_triangles->Lower() : -1; - m_face_last_tri_id = - m_face_triangles != NULL ? m_face_triangles->Upper() : -1; + this->cookie = this; + this->func_get_triangle = &gmio_stl_mesh_occshape::get_triangle; + this->triangle_count = 0; } diff --git a/src/gmio_support/stl_occ_brep.h b/src/gmio_support/stl_occ_brep.h index 2b834a6..ff0d10a 100644 --- a/src/gmio_support/stl_occ_brep.h +++ b/src/gmio_support/stl_occ_brep.h @@ -39,59 +39,51 @@ #include "support_global.h" #include "../gmio_stl/stl_mesh.h" +#include + #include #include -#include class TopoDS_Face; -struct gmio_stl_occshape_iterator; - -/*! Returns a gmio_stl_mesh mapped to the OpenCascade mesh in iterator \p it +/*! Provides access to all the internal triangles of OpenCascade's + * \c TopoDS_Shape * - * The mesh's cookie will point to \c &it so the lifescope of the corresponding - * object must be at least as long as the returned gmio_stl_mesh. + * gmio_stl_mesh_occshape iterates efficiently over the triangles of all + * sub TopoDS_Faces(internal \c Poly_Triangulation objects). * * Example of use: * \code{.cpp} * const TopoDS_Shape occshape = ...; - * const gmio_stl_occshape_iterator it(occshape); - * const gmio_stl_mesh mesh = gmio_stl_occmesh(it); - * gmio_stl_write_file(stl_format, filepath, &mesh, &options); + * const gmio_stl_mesh_occshape mesh(occshape); + * gmio_stl_write_file(stl_format, filepath, &occmesh, &options); * \endcode */ -gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occshape_iterator& it); - - -/*! Forward iterator over the triangles of OpenCascade's TopoDS_Shape - * - * It is used to iterate over the triangles of all triangulated sub faces(the - * Poly_Triangulation object). - */ -struct gmio_stl_occshape_iterator +struct gmio_stl_mesh_occshape : public gmio_stl_mesh { - gmio_stl_occshape_iterator(); - explicit gmio_stl_occshape_iterator(const TopoDS_Shape& shape); + gmio_stl_mesh_occshape(); + explicit gmio_stl_mesh_occshape(const TopoDS_Shape& shape); inline const TopoDS_Shape* shape() const { return m_shape; } private: - friend gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occshape_iterator&); static void get_triangle( const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); - bool move_to_next_tri(); - void reset_face(); - void cache_face(const TopoDS_Face& face); + void init_C_members(); + struct face_data { + gp_Trsf trsf; + bool is_reversed; + const TColgp_Array1OfPnt* ptr_nodes; + }; + struct triangle_data { + const Poly_Triangle* ptr_triangle; + const face_data* ptr_face_data; + }; + + std::vector m_vec_face_data; + std::vector m_vec_triangle_data; const TopoDS_Shape* m_shape; - TopExp_Explorer m_expl; - const Poly_Triangulation* m_face_poly; - const TColgp_Array1OfPnt* m_face_nodes; - const Poly_Array1OfTriangle* m_face_triangles; - gp_Trsf m_face_trsf; - bool m_face_is_reversed; - int m_face_tri_id; - int m_face_last_tri_id; }; #endif /* GMIO_SUPPORT_STL_OCC_BREP_H */ diff --git a/src/gmio_support/stl_occ_mesh.cpp b/src/gmio_support/stl_occ_mesh.cpp index c1b649d..e9ccaf8 100644 --- a/src/gmio_support/stl_occ_mesh.cpp +++ b/src/gmio_support/stl_occ_mesh.cpp @@ -25,13 +25,6 @@ namespace internal { -/* Common */ - -static StlMesh_Mesh* occMeshPtr(const Handle_StlMesh_Mesh& mesh) -{ - return mesh.operator->(); -} - static void occmesh_add_triangle( void* cookie, uint32_t tri_id, const gmio_stl_triangle* tri) { @@ -50,17 +43,6 @@ static void occmesh_add_triangle( } // namespace internal -gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator& it) -{ - gmio_stl_mesh mesh = {}; - mesh.cookie = ⁢ - const int domain_count = it.mesh() != NULL ? it.mesh()->NbDomains() : 0; - for (int dom_id = 1; dom_id <= domain_count; ++dom_id) - mesh.triangle_count += it.mesh()->NbTriangles(dom_id); - mesh.func_get_triangle = gmio_stl_occmesh_iterator::get_triangle; - return mesh; -} - gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh) { gmio_stl_mesh_creator creator = {}; @@ -71,82 +53,96 @@ gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh) gmio_stl_mesh_creator gmio_stl_occmesh_creator(const Handle_StlMesh_Mesh &hnd) { - return gmio_stl_occmesh_creator(internal::occMeshPtr(hnd)); + return gmio_stl_occmesh_creator(hnd.operator->()); } -gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator() +gmio_stl_mesh_occmesh::gmio_stl_mesh_occmesh() + : m_mesh(NULL), + m_mesh_domain_count(0), + m_seq_triangle(NULL), + m_seq_vertex(NULL) { - this->init(NULL); + this->init_C_members(); } -gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator(const StlMesh_Mesh *mesh) +gmio_stl_mesh_occmesh::gmio_stl_mesh_occmesh(const StlMesh_Mesh *mesh) + : m_mesh(mesh) { - this->init(mesh); + this->init_C_members(); + this->init_cache(); } -gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator(const Handle_StlMesh_Mesh &hnd) +gmio_stl_mesh_occmesh::gmio_stl_mesh_occmesh(const Handle_StlMesh_Mesh &hnd) + : m_mesh(hnd.operator->()) { - this->init(internal::occMeshPtr(hnd)); + this->init_C_members(); + this->init_cache(); } -void gmio_stl_occmesh_iterator::get_triangle( +void gmio_stl_mesh_occmesh::init_C_members() +{ + this->cookie = this; + this->func_get_triangle = &gmio_stl_mesh_occmesh::get_triangle; + this->triangle_count = 0; +} + +void gmio_stl_mesh_occmesh::get_triangle( const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri) { - void* wcookie = const_cast(cookie); - gmio_stl_occmesh_iterator* it = - static_cast(wcookie); + const gmio_stl_mesh_occmesh* it = + static_cast(cookie); - if (it->move_to_next_tri(tri_id)) { - const int dom_tri_id = tri_id - it->m_domain_first_tri_id + 1; - const Handle_StlMesh_MeshTriangle& occTri = - it->m_domain_triangles->Value(dom_tri_id); - - int iv1, iv2, iv3; - double nx, ny, nz; - occTri->GetVertexAndOrientation(iv1, iv2, iv3, nx, ny, nz); - gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); - - const TColgp_SequenceOfXYZ* vertices = it->m_domain_vertices; - gmio_stl_occ_copy_xyz(&tri->v1, vertices->Value(iv1)); - gmio_stl_occ_copy_xyz(&tri->v2, vertices->Value(iv2)); - gmio_stl_occ_copy_xyz(&tri->v3, vertices->Value(iv3)); + const StlMesh_MeshTriangle* occ_tri; + const TColgp_SequenceOfXYZ* occ_vertices; + if (it->m_mesh_domain_count > 1) { + const triangle_data& tridata = it->m_vec_triangle_data.at(tri_id); + occ_tri = tridata.ptr_triangle; + occ_vertices = tridata.ptr_vec_vertices; } + else { + occ_tri = it->m_seq_triangle->Value(tri_id + 1).operator->(); + occ_vertices = it->m_seq_vertex; + } + + int iv1, iv2, iv3; + double nx, ny, nz; + occ_tri->GetVertexAndOrientation(iv1, iv2, iv3, nx, ny, nz); + gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); + gmio_stl_occ_copy_xyz(&tri->v1, occ_vertices->Value(iv1)); + gmio_stl_occ_copy_xyz(&tri->v2, occ_vertices->Value(iv2)); + gmio_stl_occ_copy_xyz(&tri->v3, occ_vertices->Value(iv3)); } -void gmio_stl_occmesh_iterator::init(const StlMesh_Mesh* mesh) +void gmio_stl_mesh_occmesh::init_cache() { - m_mesh = mesh; - m_domain_id = 0; - m_domain_count = m_mesh != NULL ? m_mesh->NbDomains() : 0; - m_domain_triangles = NULL; - m_domain_vertices = NULL; - m_domain_first_tri_id = 0; - m_domain_last_tri_id = 0; - if (m_domain_count > 0) - this->cache_domain(1); -} + if (m_mesh == NULL) + return; -void gmio_stl_occmesh_iterator::cache_domain(int dom_id) -{ - m_domain_id = dom_id; - m_domain_triangles = &m_mesh->Triangles(dom_id); - m_domain_vertices = &m_mesh->Vertices(dom_id); - const int dom_tricnt = m_domain_triangles->Length(); - m_domain_first_tri_id = - dom_tricnt > 0 ? m_domain_last_tri_id : m_domain_first_tri_id; - m_domain_last_tri_id += - dom_tricnt > 0 ? dom_tricnt - 1 : 0; -} + // Count triangles + m_mesh_domain_count = m_mesh != NULL ? m_mesh->NbDomains() : 0; + for (int dom_id = 1; dom_id <= m_mesh_domain_count; ++dom_id) + this->triangle_count += m_mesh->NbTriangles(dom_id); -bool gmio_stl_occmesh_iterator::move_to_next_tri(uint32_t tri_id) -{ - if (tri_id > m_domain_last_tri_id) { - if (m_domain_id < m_domain_count) { - ++m_domain_id; - this->cache_domain(m_domain_id); - return true; + if (m_mesh_domain_count > 1) { + // Fill vector of triangle data + m_vec_triangle_data.reserve(this->triangle_count); + for (int dom_id = 1; dom_id <= m_mesh_domain_count; ++dom_id) { + const StlMesh_SequenceOfMeshTriangle& seq_triangles = + m_mesh->Triangles(dom_id); + const TColgp_SequenceOfXYZ& seq_vertices = + m_mesh->Vertices(dom_id); + for (int tri_id = 1; tri_id <= seq_triangles.Length(); ++tri_id) { + const Handle_StlMesh_MeshTriangle& hnd_occtri = + seq_triangles.Value(tri_id); + struct triangle_data tridata; + tridata.ptr_triangle = hnd_occtri.operator->(); + tridata.ptr_vec_vertices = &seq_vertices; + m_vec_triangle_data.push_back(std::move(tridata)); + } } - return false; } - return true; + else { + m_seq_triangle = &m_mesh->Triangles(1); + m_seq_vertex = &m_mesh->Vertices(1); + } } diff --git a/src/gmio_support/stl_occ_mesh.h b/src/gmio_support/stl_occ_mesh.h index decd1c0..56344f0 100644 --- a/src/gmio_support/stl_occ_mesh.h +++ b/src/gmio_support/stl_occ_mesh.h @@ -40,27 +40,54 @@ #include "../gmio_stl/stl_mesh.h" #include "../gmio_stl/stl_mesh_creator.h" +#include + #include #include -#include #include -struct gmio_stl_occmesh_iterator; - -/*! Returns a gmio_stl_mesh mapped to the OpenCascade mesh in iterator \p it +/*! Provides access to all the triangles of OpenCascade's \c StlMesh_Mesh * - * The mesh's cookie will point to \c &it so the lifescope of the corresponding - * object must be at least as long as the returned gmio_stl_mesh. + * gmio_stl_mesh_occmesh iterates efficiently over the triangles of all + * domains. * * Example of use: * \code{.cpp} - * Handle_StlMesh_Mesh occmesh = ...; - * const gmio_stl_occmesh_iterator it(occmesh); - * const gmio_stl_mesh mesh = gmio_stl_occmesh(it); + * const Handle_StlMesh_Mesh occmesh = ...; + * const gmio_stl_mesh_occmesh mesh(occmesh); * gmio_stl_write_file(stl_format, filepath, &mesh, &options); * \endcode */ -gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator& it); +struct gmio_stl_mesh_occmesh : public gmio_stl_mesh +{ + gmio_stl_mesh_occmesh(); + explicit gmio_stl_mesh_occmesh(const StlMesh_Mesh* mesh); + explicit gmio_stl_mesh_occmesh(const Handle_StlMesh_Mesh& hnd); + + inline const StlMesh_Mesh* mesh() const { return m_mesh; } + +private: + static void get_triangle( + const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); + + void init_C_members(); + void init_cache(); + + struct triangle_data + { + const StlMesh_MeshTriangle* ptr_triangle; + const TColgp_SequenceOfXYZ* ptr_vec_vertices; + }; + + const StlMesh_Mesh* m_mesh; + int m_mesh_domain_count; + + // Data to be used when mesh domain_count > 1 + std::vector m_vec_triangle_data; + // Data to be used when mesh domain_count == 1 + const StlMesh_SequenceOfMeshTriangle* m_seq_triangle; + const TColgp_SequenceOfXYZ* m_seq_vertex; +}; /*! Returns a gmio_stl_mesh_creator that will build a new domain in a * StlMesh_Mesh object @@ -76,37 +103,5 @@ gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh); */ gmio_stl_mesh_creator gmio_stl_occmesh_creator(const Handle_StlMesh_Mesh& hnd); - -/*! Forward iterator over the triangles of OpenCascade's StlMesh_Mesh - * - * It is used internally to iterate over the triangles of all domains within - * a StlMesh_Mesh object. - */ -struct gmio_stl_occmesh_iterator -{ - gmio_stl_occmesh_iterator(); - explicit gmio_stl_occmesh_iterator(const StlMesh_Mesh* mesh); - explicit gmio_stl_occmesh_iterator(const Handle_StlMesh_Mesh& hnd); - - inline const StlMesh_Mesh* mesh() const { return m_mesh; } - -private: - friend gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator&); - static void get_triangle( - const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); - - bool move_to_next_tri(uint32_t tri_id); - void init(const StlMesh_Mesh* mesh); - void cache_domain(int dom_id); - - const StlMesh_Mesh* m_mesh; - int m_domain_count; - int m_domain_id; - const StlMesh_SequenceOfMeshTriangle* m_domain_triangles; - const TColgp_SequenceOfXYZ* m_domain_vertices; - uint32_t m_domain_first_tri_id; - uint32_t m_domain_last_tri_id; -}; - #endif /* GMIO_SUPPORT_STL_OCC_MESH_H */ /*! @} */ diff --git a/src/gmio_support/stl_occ_meshvs.cpp b/src/gmio_support/stl_occ_meshvs.cpp index ae43014..e8081f0 100644 --- a/src/gmio_support/stl_occ_meshvs.cpp +++ b/src/gmio_support/stl_occ_meshvs.cpp @@ -18,59 +18,71 @@ #include "stl_occ_utils.h" #include +#include #include #include -gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_datasource_iterator& it) -{ - gmio_stl_mesh mesh = {}; - mesh.cookie = ⁢ - mesh.triangle_count = - it.data_src() != NULL ? - it.data_src()->GetAllElements().Extent() : 0; - mesh.func_get_triangle = gmio_stl_occmesh_datasource_iterator::get_triangle; - return mesh; -} - -gmio_stl_occmesh_datasource_iterator::gmio_stl_occmesh_datasource_iterator() +gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs() : m_data_src(NULL), m_element_coords(1, 1) -{ } - -gmio_stl_occmesh_datasource_iterator::gmio_stl_occmesh_datasource_iterator( - const MeshVS_DataSource *data_src) - : m_data_src(data_src), - m_element_coords(1, 9) { - if (m_data_src != NULL) - m_element_it.Initialize(m_data_src->GetAllElements()); + this->init_C_members(); } -gmio_stl_occmesh_datasource_iterator::gmio_stl_occmesh_datasource_iterator( - const Handle_MeshVS_DataSource &hnd) +gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs(const MeshVS_DataSource *ds) + : m_data_src(ds), + m_element_coords(1, 9) +{ + this->init_C_members(); + this->init_cache(); +} + +gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs(const Handle_MeshVS_DataSource &hnd) : m_data_src(hnd.operator->()), m_element_coords(1, 9) { - if (m_data_src != NULL) - m_element_it.Initialize(m_data_src->GetAllElements()); + this->init_C_members(); + this->init_cache(); } -void gmio_stl_occmesh_datasource_iterator::get_triangle( - const void *cookie, uint32_t /*tri_id*/, gmio_stl_triangle *tri) +void gmio_stl_mesh_occmeshvs::init_C_members() { - void* wcookie = const_cast(cookie); - gmio_stl_occmesh_datasource_iterator* it = - static_cast(wcookie); + this->cookie = this; + this->func_get_triangle = &gmio_stl_mesh_occmeshvs::get_triangle; + this->triangle_count = 0; +} + +void gmio_stl_mesh_occmeshvs::init_cache() +{ + if (m_data_src == NULL) + return; + + this->triangle_count = m_data_src->GetAllElements().Extent(); + m_vec_element_key.reserve(this->triangle_count); + + TColStd_MapIteratorOfPackedMapOfInteger element_it; + element_it.Initialize(m_data_src->GetAllElements()); + while (element_it.More()) { + m_vec_element_key.push_back(element_it.Key()); + element_it.Next(); + } +} + +void gmio_stl_mesh_occmeshvs::get_triangle( + const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri) +{ + const gmio_stl_mesh_occmeshvs* it = + static_cast(cookie); const MeshVS_DataSource* data_src = it->data_src(); - const int curr_element_key = it->m_element_it.Key(); + const int element_key = it->m_vec_element_key.at(tri_id); TColStd_Array1OfReal& element_coords = it->m_element_coords; int node_count; MeshVS_EntityType entity_type; const Standard_Boolean get_geom_ok = data_src->GetGeom( - curr_element_key, + element_key, Standard_True, // Is element element_coords, node_count, @@ -83,8 +95,7 @@ void gmio_stl_occmesh_datasource_iterator::get_triangle( out_coords_ptr[i] = static_cast(in_coords_array.Value(i + 1)); // Copy normal coords double nx, ny, nz; - data_src->GetNormal(curr_element_key, 3, nx, ny, nz); + data_src->GetNormal(element_key, 3, nx, ny, nz); gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); } - it->m_element_it.Next(); } diff --git a/src/gmio_support/stl_occ_meshvs.h b/src/gmio_support/stl_occ_meshvs.h index 5e7e3fc..fe7b1ff 100644 --- a/src/gmio_support/stl_occ_meshvs.h +++ b/src/gmio_support/stl_occ_meshvs.h @@ -39,51 +39,42 @@ #include "support_global.h" #include "../gmio_stl/stl_mesh.h" +#include + #include #include -#include -struct gmio_stl_occmesh_datasource_iterator; - -/*! Returns a gmio_stl_mesh mapped to the OpenCascade mesh data-source in - * iterator \p it +/*! Provides access to all the triangles of OpenCascade's \c MeshVS_DataSource * - * The mesh's cookie will point to \c &it so the lifescope of the corresponding - * object must be at least as long as the returned gmio_stl_mesh. + * gmio_stl_mesh_occmeshvs iterates efficiently over the elements of a + * \c MeshVS_DataSource object.\n + * Each element should be of type \c MeshVS_ET_Face and made of 3 nodes. * * Example of use: * \code{.cpp} - * Handle_MeshVS_Mesh mesh = ...; - * const gmio_stl_occmesh_datasource_iterator it(mesh->GetDataSource()); - * const gmio_stl_mesh mesh = gmio_stl_occmesh(it); + * Handle_MeshVS_Mesh occmeshvs = ...; + * const gmio_stl_mesh_occmeshvs mesh(occmeshvs); * gmio_stl_write_file(stl_format, filepath, &mesh, &options); * \endcode */ -gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_datasource_iterator& it); - -/*! Forward iterator over the triangles of OpenCascade's MeshVS_DataSource - * - * It is used to iterate efficiently over the elements of a MeshVS_DataSource - * object.\n - * Each element should be of type MeshVS_ET_Face and made of 3 nodes. - */ -struct gmio_stl_occmesh_datasource_iterator +struct gmio_stl_mesh_occmeshvs : public gmio_stl_mesh { - gmio_stl_occmesh_datasource_iterator(); - explicit gmio_stl_occmesh_datasource_iterator(const MeshVS_DataSource* ds); - explicit gmio_stl_occmesh_datasource_iterator(const Handle_MeshVS_DataSource& hnd); + gmio_stl_mesh_occmeshvs(); + explicit gmio_stl_mesh_occmeshvs(const MeshVS_DataSource* ds); + explicit gmio_stl_mesh_occmeshvs(const Handle_MeshVS_DataSource& hnd); inline const MeshVS_DataSource* data_src() const { return m_data_src; } private: - friend gmio_stl_mesh gmio_stl_occmesh( - const gmio_stl_occmesh_datasource_iterator&); static void get_triangle( const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); + void init_C_members(); + void init_cache(); + const MeshVS_DataSource* m_data_src; - TColStd_MapIteratorOfPackedMapOfInteger m_element_it; - TColStd_Array1OfReal m_element_coords; + std::vector m_vec_element_key; + mutable TColStd_Array1OfReal m_element_coords; }; #endif /* GMIO_SUPPORT_STL_OCC_MESHVS_H */ diff --git a/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx b/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx index 0a6caa7..8772943 100644 --- a/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx +++ b/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx @@ -1,6 +1,7 @@ #ifndef TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile #define TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile +#include class TColStd_PackedMapOfInteger; class TColStd_MapIteratorOfPackedMapOfInteger @@ -12,6 +13,7 @@ public: void Reset() {} int Key() const { return 0; } void Next() {} + Standard_Boolean More() const { return Standard_False; } }; #endif