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.
This commit is contained in:
Hugues Delorme 2016-06-14 16:42:22 +02:00
parent 61be8c6972
commit 05ea032f3d
9 changed files with 261 additions and 301 deletions

View File

@ -181,14 +181,14 @@ static void stl_write(
static void stl_mesh_write(const char* filepath, gmio_stl_format format) static void stl_mesh_write(const char* filepath, gmio_stl_format format)
{ {
const gmio_stl_occmesh_iterator occ_itmesh(stlMesh); const gmio_stl_mesh_occmesh mesh(stlMesh);
stl_write(filepath, format, gmio_stl_occmesh(occ_itmesh)); stl_write(filepath, format, mesh);
} }
static void stl_brep_write(const char* filepath, gmio_stl_format format) static void stl_brep_write(const char* filepath, gmio_stl_format format)
{ {
const gmio_stl_occshape_iterator occ_itshape(BmkBRep::inputShape); const gmio_stl_mesh_occshape mesh(BmkBRep::inputShape);
stl_write(filepath, format, gmio_stl_occmesh(occ_itshape)); stl_write(filepath, format, mesh);
} }
static void stla_mesh_write(const void* filepath) static void stla_mesh_write(const void* filepath)

View File

@ -26,9 +26,7 @@ int main(int argc, char** argv)
Handle_StlMesh_Mesh occmesh = new StlMesh_Mesh; Handle_StlMesh_Mesh occmesh = new StlMesh_Mesh;
// Initialize the OpenCascade StlMesh_Mesh here // Initialize the OpenCascade StlMesh_Mesh here
// ... // ...
const gmio_stl_mesh_occmesh mesh(occmesh);
const gmio_stl_occmesh_iterator occmesh_it(occmesh);
const gmio_stl_mesh mesh = gmio_stl_occmesh(occmesh_it);
// Write binary STL(little-endian), using default options(NULL) // Write binary STL(little-endian), using default options(NULL)
error = gmio_stl_write_file( error = gmio_stl_write_file(

View File

@ -18,64 +18,80 @@
#include "stl_occ_utils.h" #include "stl_occ_utils.h"
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx> #include <TopLoc_Location.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Face.hxx> #include <TopoDS_Face.hxx>
gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occshape_iterator& it) gmio_stl_mesh_occshape::gmio_stl_mesh_occshape()
{
gmio_stl_mesh mesh = {};
mesh.cookie = &it;
if (it.shape() != NULL) {
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();
}
}
//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) : m_shape(NULL)
{ {
this->reset_face(); this->init_C_members();
} }
gmio_stl_occshape_iterator::gmio_stl_occshape_iterator(const TopoDS_Shape& shape) gmio_stl_mesh_occshape::gmio_stl_mesh_occshape(const TopoDS_Shape& shape)
: m_shape(&shape), : m_shape(&shape)
m_expl(shape, TopAbs_FACE)
{ {
if (m_expl.More()) { this->init_C_members();
this->cache_face(TopoDS::Face(m_expl.Current()));
} // Count facets and triangles
else { std::size_t face_count = 0;
this->reset_face(); for (TopExp_Explorer expl(shape, TopAbs_FACE); expl.More(); expl.Next()) {
TopLoc_Location loc;
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();
} }
} }
void gmio_stl_occshape_iterator::get_triangle( // Fill face and triangle datas
const void *cookie, uint32_t /*tri_id*/, gmio_stl_triangle *tri) 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));
}
}
}
}
// static
void gmio_stl_mesh_occshape::get_triangle(
const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri)
{ {
void* wcookie = const_cast<void*>(cookie); const gmio_stl_mesh_occshape* it =
gmio_stl_occshape_iterator* it = static_cast<const gmio_stl_mesh_occshape*>(cookie);
static_cast<gmio_stl_occshape_iterator*>(wcookie);
const bool reversed = it->m_face_is_reversed; const struct triangle_data* tridata = &it->m_vec_triangle_data.at(tri_id);
const gp_Trsf& trsf = it->m_face_trsf; const struct face_data* facedata = tridata->ptr_face_data;
const TColgp_Array1OfPnt* nodes = it->m_face_nodes; 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 int n1, n2, n3; // Node index
const Poly_Triangle& curr_tri = const Poly_Triangle* occtri = tridata->ptr_triangle;
it->m_face_triangles->Value(it->m_face_tri_id); occtri->Get(n1, n2, n3);
curr_tri.Get(n1, n2, n3);
gp_Pnt p1 = nodes->Value(n1); gp_Pnt p1 = nodes->Value(n1);
gp_Pnt p2 = nodes->Value(reversed ? n3 : n2); gp_Pnt p2 = nodes->Value(reversed ? n3 : n2);
gp_Pnt p3 = nodes->Value(reversed ? n2 : n3); 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->v2, p2.XYZ());
gmio_stl_occ_copy_xyz(&tri->v3, p3.XYZ()); gmio_stl_occ_copy_xyz(&tri->v3, p3.XYZ());
gmio_stl_triangle_compute_normal(tri); 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; this->cookie = this;
if (m_face_tri_id > m_face_last_tri_id) { this->func_get_triangle = &gmio_stl_mesh_occshape::get_triangle;
m_expl.Next(); this->triangle_count = 0;
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;
} }

View File

@ -39,59 +39,51 @@
#include "support_global.h" #include "support_global.h"
#include "../gmio_stl/stl_mesh.h" #include "../gmio_stl/stl_mesh.h"
#include <vector>
#include <Poly_Triangulation.hxx> #include <Poly_Triangulation.hxx>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
class TopoDS_Face; class TopoDS_Face;
struct gmio_stl_occshape_iterator; /*! Provides access to all the internal triangles of OpenCascade's
* \c TopoDS_Shape
/*! Returns a gmio_stl_mesh mapped to the OpenCascade mesh in iterator \p it
* *
* The mesh's cookie will point to \c &it so the lifescope of the corresponding * gmio_stl_mesh_occshape iterates efficiently over the triangles of all
* object must be at least as long as the returned gmio_stl_mesh. * sub <tt>TopoDS_Faces</tt>(internal \c Poly_Triangulation objects).
* *
* Example of use: * Example of use:
* \code{.cpp} * \code{.cpp}
* const TopoDS_Shape occshape = ...; * const TopoDS_Shape occshape = ...;
* const gmio_stl_occshape_iterator it(occshape); * const gmio_stl_mesh_occshape mesh(occshape);
* const gmio_stl_mesh mesh = gmio_stl_occmesh(it); * gmio_stl_write_file(stl_format, filepath, &occmesh, &options);
* gmio_stl_write_file(stl_format, filepath, &mesh, &options);
* \endcode * \endcode
*/ */
gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occshape_iterator& it); struct gmio_stl_mesh_occshape : public gmio_stl_mesh
/*! 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
{ {
gmio_stl_occshape_iterator(); gmio_stl_mesh_occshape();
explicit gmio_stl_occshape_iterator(const TopoDS_Shape& shape); explicit gmio_stl_mesh_occshape(const TopoDS_Shape& shape);
inline const TopoDS_Shape* shape() const { return m_shape; } inline const TopoDS_Shape* shape() const { return m_shape; }
private: private:
friend gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occshape_iterator&);
static void get_triangle( static void get_triangle(
const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri);
bool move_to_next_tri(); void init_C_members();
void reset_face();
void cache_face(const TopoDS_Face& face);
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<face_data> m_vec_face_data;
std::vector<triangle_data> m_vec_triangle_data;
const TopoDS_Shape* m_shape; 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 */ #endif /* GMIO_SUPPORT_STL_OCC_BREP_H */

View File

@ -25,13 +25,6 @@
namespace internal { namespace internal {
/* Common */
static StlMesh_Mesh* occMeshPtr(const Handle_StlMesh_Mesh& mesh)
{
return mesh.operator->();
}
static void occmesh_add_triangle( static void occmesh_add_triangle(
void* cookie, uint32_t tri_id, const gmio_stl_triangle* tri) void* cookie, uint32_t tri_id, const gmio_stl_triangle* tri)
{ {
@ -50,17 +43,6 @@ static void occmesh_add_triangle(
} // namespace internal } // namespace internal
gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator& it)
{
gmio_stl_mesh mesh = {};
mesh.cookie = &it;
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 gmio_stl_occmesh_creator(StlMesh_Mesh* mesh)
{ {
gmio_stl_mesh_creator creator = {}; 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) 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) const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri)
{ {
void* wcookie = const_cast<void*>(cookie); const gmio_stl_mesh_occmesh* it =
gmio_stl_occmesh_iterator* it = static_cast<const gmio_stl_mesh_occmesh*>(cookie);
static_cast<gmio_stl_occmesh_iterator*>(wcookie);
if (it->move_to_next_tri(tri_id)) { const StlMesh_MeshTriangle* occ_tri;
const int dom_tri_id = tri_id - it->m_domain_first_tri_id + 1; const TColgp_SequenceOfXYZ* occ_vertices;
const Handle_StlMesh_MeshTriangle& occTri = if (it->m_mesh_domain_count > 1) {
it->m_domain_triangles->Value(dom_tri_id); 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; int iv1, iv2, iv3;
double nx, ny, nz; double nx, ny, nz;
occTri->GetVertexAndOrientation(iv1, iv2, iv3, 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->n, nx, ny, nz);
gmio_stl_occ_copy_xyz(&tri->v1, occ_vertices->Value(iv1));
const TColgp_SequenceOfXYZ* vertices = it->m_domain_vertices; gmio_stl_occ_copy_xyz(&tri->v2, occ_vertices->Value(iv2));
gmio_stl_occ_copy_xyz(&tri->v1, vertices->Value(iv1)); gmio_stl_occ_copy_xyz(&tri->v3, occ_vertices->Value(iv3));
gmio_stl_occ_copy_xyz(&tri->v2, vertices->Value(iv2));
gmio_stl_occ_copy_xyz(&tri->v3, vertices->Value(iv3));
}
} }
void gmio_stl_occmesh_iterator::init(const StlMesh_Mesh* mesh) void gmio_stl_mesh_occmesh::init_cache()
{ {
m_mesh = mesh; if (m_mesh == NULL)
m_domain_id = 0; return;
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);
}
void gmio_stl_occmesh_iterator::cache_domain(int dom_id) // Count triangles
{ m_mesh_domain_count = m_mesh != NULL ? m_mesh->NbDomains() : 0;
m_domain_id = dom_id; for (int dom_id = 1; dom_id <= m_mesh_domain_count; ++dom_id)
m_domain_triangles = &m_mesh->Triangles(dom_id); this->triangle_count += m_mesh->NbTriangles(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;
}
bool gmio_stl_occmesh_iterator::move_to_next_tri(uint32_t tri_id) if (m_mesh_domain_count > 1) {
{ // Fill vector of triangle data
if (tri_id > m_domain_last_tri_id) { m_vec_triangle_data.reserve(this->triangle_count);
if (m_domain_id < m_domain_count) { for (int dom_id = 1; dom_id <= m_mesh_domain_count; ++dom_id) {
++m_domain_id; const StlMesh_SequenceOfMeshTriangle& seq_triangles =
this->cache_domain(m_domain_id); m_mesh->Triangles(dom_id);
return true; 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);
}
} }

View File

@ -40,27 +40,54 @@
#include "../gmio_stl/stl_mesh.h" #include "../gmio_stl/stl_mesh.h"
#include "../gmio_stl/stl_mesh_creator.h" #include "../gmio_stl/stl_mesh_creator.h"
#include <vector>
#include <StlMesh_Mesh.hxx> #include <StlMesh_Mesh.hxx>
#include <StlMesh_MeshTriangle.hxx> #include <StlMesh_MeshTriangle.hxx>
#include <StlMesh_SequenceOfMeshTriangle.hxx>
#include <TColgp_SequenceOfXYZ.hxx> #include <TColgp_SequenceOfXYZ.hxx>
struct gmio_stl_occmesh_iterator; /*! Provides access to all the triangles of OpenCascade's \c StlMesh_Mesh
/*! Returns a gmio_stl_mesh mapped to the OpenCascade mesh in iterator \p it
* *
* The mesh's cookie will point to \c &it so the lifescope of the corresponding * gmio_stl_mesh_occmesh iterates efficiently over the triangles of all
* object must be at least as long as the returned gmio_stl_mesh. * domains.
* *
* Example of use: * Example of use:
* \code{.cpp} * \code{.cpp}
* Handle_StlMesh_Mesh occmesh = ...; * const Handle_StlMesh_Mesh occmesh = ...;
* const gmio_stl_occmesh_iterator it(occmesh); * const gmio_stl_mesh_occmesh mesh(occmesh);
* const gmio_stl_mesh mesh = gmio_stl_occmesh(it);
* gmio_stl_write_file(stl_format, filepath, &mesh, &options); * gmio_stl_write_file(stl_format, filepath, &mesh, &options);
* \endcode * \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<triangle_data> 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 /*! Returns a gmio_stl_mesh_creator that will build a new domain in a
* StlMesh_Mesh object * 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); 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 */ #endif /* GMIO_SUPPORT_STL_OCC_MESH_H */
/*! @} */ /*! @} */

View File

@ -18,59 +18,71 @@
#include "stl_occ_utils.h" #include "stl_occ_utils.h"
#include <MeshVS_DataSource.hxx> #include <MeshVS_DataSource.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <TColStd_PackedMapOfInteger.hxx> #include <TColStd_PackedMapOfInteger.hxx>
#include <cstddef> #include <cstddef>
gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_datasource_iterator& it) gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs()
{
gmio_stl_mesh mesh = {};
mesh.cookie = &it;
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()
: m_data_src(NULL), : m_data_src(NULL),
m_element_coords(1, 1) 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) this->init_C_members();
m_element_it.Initialize(m_data_src->GetAllElements());
} }
gmio_stl_occmesh_datasource_iterator::gmio_stl_occmesh_datasource_iterator( gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs(const MeshVS_DataSource *ds)
const Handle_MeshVS_DataSource &hnd) : 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_data_src(hnd.operator->()),
m_element_coords(1, 9) m_element_coords(1, 9)
{ {
if (m_data_src != NULL) this->init_C_members();
m_element_it.Initialize(m_data_src->GetAllElements()); this->init_cache();
} }
void gmio_stl_occmesh_datasource_iterator::get_triangle( void gmio_stl_mesh_occmeshvs::init_C_members()
const void *cookie, uint32_t /*tri_id*/, gmio_stl_triangle *tri)
{ {
void* wcookie = const_cast<void*>(cookie); this->cookie = this;
gmio_stl_occmesh_datasource_iterator* it = this->func_get_triangle = &gmio_stl_mesh_occmeshvs::get_triangle;
static_cast<gmio_stl_occmesh_datasource_iterator*>(wcookie); 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<const gmio_stl_mesh_occmeshvs*>(cookie);
const MeshVS_DataSource* data_src = it->data_src(); 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; TColStd_Array1OfReal& element_coords = it->m_element_coords;
int node_count; int node_count;
MeshVS_EntityType entity_type; MeshVS_EntityType entity_type;
const Standard_Boolean get_geom_ok = const Standard_Boolean get_geom_ok =
data_src->GetGeom( data_src->GetGeom(
curr_element_key, element_key,
Standard_True, // Is element Standard_True, // Is element
element_coords, element_coords,
node_count, node_count,
@ -83,8 +95,7 @@ void gmio_stl_occmesh_datasource_iterator::get_triangle(
out_coords_ptr[i] = static_cast<float>(in_coords_array.Value(i + 1)); out_coords_ptr[i] = static_cast<float>(in_coords_array.Value(i + 1));
// Copy normal coords // Copy normal coords
double nx, ny, nz; 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); gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz);
} }
it->m_element_it.Next();
} }

View File

@ -39,51 +39,42 @@
#include "support_global.h" #include "support_global.h"
#include "../gmio_stl/stl_mesh.h" #include "../gmio_stl/stl_mesh.h"
#include <vector>
#include <MeshVS_DataSource.hxx> #include <MeshVS_DataSource.hxx>
#include <TColStd_Array1OfReal.hxx> #include <TColStd_Array1OfReal.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
struct gmio_stl_occmesh_datasource_iterator; /*! Provides access to all the triangles of OpenCascade's \c MeshVS_DataSource
/*! Returns a gmio_stl_mesh mapped to the OpenCascade mesh data-source in
* iterator \p it
* *
* The mesh's cookie will point to \c &it so the lifescope of the corresponding * gmio_stl_mesh_occmeshvs iterates efficiently over the elements of a
* object must be at least as long as the returned gmio_stl_mesh. * \c MeshVS_DataSource object.\n
* Each element should be of type \c MeshVS_ET_Face and made of 3 nodes.
* *
* Example of use: * Example of use:
* \code{.cpp} * \code{.cpp}
* Handle_MeshVS_Mesh mesh = ...; * Handle_MeshVS_Mesh occmeshvs = ...;
* const gmio_stl_occmesh_datasource_iterator it(mesh->GetDataSource()); * const gmio_stl_mesh_occmeshvs mesh(occmeshvs);
* const gmio_stl_mesh mesh = gmio_stl_occmesh(it);
* gmio_stl_write_file(stl_format, filepath, &mesh, &options); * gmio_stl_write_file(stl_format, filepath, &mesh, &options);
* \endcode * \endcode
*/ */
gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_datasource_iterator& it); struct gmio_stl_mesh_occmeshvs : public gmio_stl_mesh
/*! 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
{ {
gmio_stl_occmesh_datasource_iterator(); gmio_stl_mesh_occmeshvs();
explicit gmio_stl_occmesh_datasource_iterator(const MeshVS_DataSource* ds); explicit gmio_stl_mesh_occmeshvs(const MeshVS_DataSource* ds);
explicit gmio_stl_occmesh_datasource_iterator(const Handle_MeshVS_DataSource& hnd); explicit gmio_stl_mesh_occmeshvs(const Handle_MeshVS_DataSource& hnd);
inline const MeshVS_DataSource* data_src() const { return m_data_src; } inline const MeshVS_DataSource* data_src() const { return m_data_src; }
private: private:
friend gmio_stl_mesh gmio_stl_occmesh(
const gmio_stl_occmesh_datasource_iterator&);
static void get_triangle( static void get_triangle(
const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri);
void init_C_members();
void init_cache();
const MeshVS_DataSource* m_data_src; const MeshVS_DataSource* m_data_src;
TColStd_MapIteratorOfPackedMapOfInteger m_element_it; std::vector<int> m_vec_element_key;
TColStd_Array1OfReal m_element_coords; mutable TColStd_Array1OfReal m_element_coords;
}; };
#endif /* GMIO_SUPPORT_STL_OCC_MESHVS_H */ #endif /* GMIO_SUPPORT_STL_OCC_MESHVS_H */

View File

@ -1,6 +1,7 @@
#ifndef TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile #ifndef TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile
#define TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile #define TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile
#include <Standard_TypeDef.hxx>
class TColStd_PackedMapOfInteger; class TColStd_PackedMapOfInteger;
class TColStd_MapIteratorOfPackedMapOfInteger class TColStd_MapIteratorOfPackedMapOfInteger
@ -12,6 +13,7 @@ public:
void Reset() {} void Reset() {}
int Key() const { return 0; } int Key() const { return 0; }
void Next() {} void Next() {}
Standard_Boolean More() const { return Standard_False; }
}; };
#endif #endif