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:
parent
61be8c6972
commit
05ea032f3d
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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 = ⁢
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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<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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
/*! @} */
|
||||
|
@ -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 = ⁢
|
||||
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();
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user