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)
{
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)

View File

@ -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(

View File

@ -18,64 +18,80 @@
#include "stl_occ_utils.h"
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.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()
: m_shape(NULL)
{
gmio_stl_mesh mesh = {};
mesh.cookie = &it;
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<void*>(cookie);
gmio_stl_occshape_iterator* it =
static_cast<gmio_stl_occshape_iterator*>(wcookie);
const gmio_stl_mesh_occshape* it =
static_cast<const gmio_stl_mesh_occshape*>(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;
}

View File

@ -39,59 +39,51 @@
#include "support_global.h"
#include "../gmio_stl/stl_mesh.h"
#include <vector>
#include <Poly_Triangulation.hxx>
#include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
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 <tt>TopoDS_Faces</tt>(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<face_data> m_vec_face_data;
std::vector<triangle_data> 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 */

View File

@ -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 = &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 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<void*>(cookie);
gmio_stl_occmesh_iterator* it =
static_cast<gmio_stl_occmesh_iterator*>(wcookie);
const gmio_stl_mesh_occmesh* it =
static_cast<const gmio_stl_mesh_occmesh*>(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);
}
}

View File

@ -40,27 +40,54 @@
#include "../gmio_stl/stl_mesh.h"
#include "../gmio_stl/stl_mesh_creator.h"
#include <vector>
#include <StlMesh_Mesh.hxx>
#include <StlMesh_MeshTriangle.hxx>
#include <StlMesh_SequenceOfMeshTriangle.hxx>
#include <TColgp_SequenceOfXYZ.hxx>
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<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
* 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 */
/*! @} */

View File

@ -18,59 +18,71 @@
#include "stl_occ_utils.h"
#include <MeshVS_DataSource.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <cstddef>
gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_datasource_iterator& it)
{
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()
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<void*>(cookie);
gmio_stl_occmesh_datasource_iterator* it =
static_cast<gmio_stl_occmesh_datasource_iterator*>(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<const gmio_stl_mesh_occmeshvs*>(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<float>(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();
}

View File

@ -39,51 +39,42 @@
#include "support_global.h"
#include "../gmio_stl/stl_mesh.h"
#include <vector>
#include <MeshVS_DataSource.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
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<int> m_vec_element_key;
mutable TColStd_Array1OfReal m_element_coords;
};
#endif /* GMIO_SUPPORT_STL_OCC_MESHVS_H */

View File

@ -1,6 +1,7 @@
#ifndef TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile
#define TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile
#include <Standard_TypeDef.hxx>
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