gmio_support: iterate on all StlMesh_Mesh's domains

This commit is contained in:
Hugues Delorme 2016-02-18 18:20:23 +01:00
parent 9cf0ac13df
commit 706fc26b0e
6 changed files with 152 additions and 96 deletions

View File

@ -61,7 +61,7 @@ static void stl_read(const void* filepath)
stlMesh = new StlMesh_Mesh; stlMesh = new StlMesh_Mesh;
const int error = gmio_stl_read_file( const int error = gmio_stl_read_file(
static_cast<const char*>(filepath), static_cast<const char*>(filepath),
gmio_stl_hnd_occmesh_creator(stlMesh), gmio_stl_occmesh_creator(stlMesh),
NULL); NULL);
if (error != GMIO_ERROR_OK) if (error != GMIO_ERROR_OK)
printf("gmio error: 0x%X\n", error); printf("gmio error: 0x%X\n", error);
@ -69,7 +69,6 @@ static void stl_read(const void* filepath)
static void stl_write(const char* filepath, gmio_stl_format format) static void stl_write(const char* filepath, gmio_stl_format format)
{ {
const gmio_occ_stl_mesh_domain occ_mesh_domain(stlMesh);
gmio_stl_write_options options = {}; gmio_stl_write_options options = {};
options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE; options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE;
options.stla_float32_prec = 7; options.stla_float32_prec = 7;
@ -77,7 +76,7 @@ static void stl_write(const char* filepath, gmio_stl_format format)
gmio_stl_write_file( gmio_stl_write_file(
format, format,
static_cast<const char*>(filepath), static_cast<const char*>(filepath),
gmio_stl_occmesh(&occ_mesh_domain), gmio_stl_occmesh(stlMesh),
&options); &options);
if (error != GMIO_ERROR_OK) if (error != GMIO_ERROR_OK)
printf("gmio error: 0x%X\n", error); printf("gmio error: 0x%X\n", error);

View File

@ -31,7 +31,7 @@ static StlMesh_Mesh* occMeshPtr(const Handle_StlMesh_Mesh& mesh)
} }
static void occmesh_add_triangle( static void occmesh_add_triangle(
void* cookie, uint32_t tri_id, const struct gmio_stl_triangle* tri) void* cookie, uint32_t tri_id, const gmio_stl_triangle* tri)
{ {
StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie); StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie);
if (tri_id == 0) if (tri_id == 0)
@ -46,94 +46,113 @@ static void occmesh_add_triangle(
n.x, n.y, n.z); n.x, n.y, n.z);
} }
static void occmesh_get_triangle( static inline void gmio_stl_occ_copy_xyz(
const void* cookie, uint32_t tri_id, struct gmio_stl_triangle* tri) gmio_stl_coords* stl_coords, const gp_XYZ& coords)
{ {
const struct gmio_occ_stl_mesh_domain* mesh_domain = stl_coords->x = static_cast<float>(coords.X());
static_cast<const struct gmio_occ_stl_mesh_domain*>(cookie); stl_coords->y = static_cast<float>(coords.Y());
const Handle_StlMesh_MeshTriangle& occTri = stl_coords->z = static_cast<float>(coords.Z());
mesh_domain->triangles()->Value(tri_id + 1); }
int idV1;
int idV2; static void occmesh_get_triangle(
int idV3; const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri)
double xN; {
double yN; void* wcookie = const_cast<void*>(cookie);
double zN; gmio_stl_occmesh_iterator* it =
static_cast<gmio_stl_occmesh_iterator*>(wcookie);
if (it->move_to_next_tri(tri_id)) {
const Handle_StlMesh_MeshTriangle& occTri = it->domain_tri(tri_id);
int idV1, idV2, idV3;
double xN, yN, zN;
occTri->GetVertexAndOrientation(idV1, idV2, idV3, xN, yN, zN); occTri->GetVertexAndOrientation(idV1, idV2, idV3, xN, yN, zN);
gmio_stl_coords& n = tri->n; gmio_stl_coords& n = tri->n;
n.x = static_cast<float>(xN); n.x = static_cast<float>(xN);
n.y = static_cast<float>(yN); n.y = static_cast<float>(yN);
n.z = static_cast<float>(zN); n.z = static_cast<float>(zN);
const TColgp_SequenceOfXYZ& vertices = *mesh_domain->vertices(); const TColgp_SequenceOfXYZ& vertices = it->domain_vertices();
const gp_XYZ& coordsV1 = vertices.Value(idV1); gmio_stl_occ_copy_xyz(&tri->v1, vertices.Value(idV1));
gmio_stl_coords& v1 = tri->v1; gmio_stl_occ_copy_xyz(&tri->v2, vertices.Value(idV2));
v1.x = static_cast<float>(coordsV1.X()); gmio_stl_occ_copy_xyz(&tri->v3, vertices.Value(idV3));
v1.y = static_cast<float>(coordsV1.Y()); }
v1.z = static_cast<float>(coordsV1.Z());
const gp_XYZ& coordsV2 = vertices.Value(idV2);
gmio_stl_coords& v2 = tri->v2;
v2.x = static_cast<float>(coordsV2.X());
v2.y = static_cast<float>(coordsV2.Y());
v2.z = static_cast<float>(coordsV2.Z());
const gp_XYZ& coordsV3 = vertices.Value(idV3);
gmio_stl_coords& v3 = tri->v3;
v3.x = static_cast<float>(coordsV3.X());
v3.y = static_cast<float>(coordsV3.Y());
v3.z = static_cast<float>(coordsV3.Z());
} }
} // namespace internal } // namespace internal
struct gmio_stl_mesh gmio_stl_occmesh(const struct gmio_occ_stl_mesh_domain* mesh_domain) gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator& it)
{ {
struct gmio_stl_mesh mesh = {0}; gmio_stl_mesh mesh = {};
mesh.cookie = mesh_domain; mesh.cookie = &it;
if (mesh_domain != NULL && mesh_domain->mesh() != NULL) { const int domain_count = it.mesh()->NbDomains();
mesh.triangle_count = for (int dom_id = 1; dom_id <= domain_count; ++dom_id)
mesh_domain->mesh()->NbTriangles(mesh_domain->domain_id()); mesh.triangle_count += it.mesh()->NbTriangles(dom_id);
}
mesh.func_get_triangle = internal::occmesh_get_triangle; mesh.func_get_triangle = internal::occmesh_get_triangle;
return mesh; return mesh;
} }
struct gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh) gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh)
{ {
struct gmio_stl_mesh_creator creator = {0}; gmio_stl_mesh_creator creator = {};
creator.cookie = mesh; creator.cookie = mesh;
creator.func_add_triangle = internal::occmesh_add_triangle; creator.func_add_triangle = internal::occmesh_add_triangle;
return creator; return creator;
} }
struct gmio_stl_mesh_creator gmio_stl_hnd_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(internal::occMeshPtr(hnd));
} }
gmio_occ_stl_mesh_domain::gmio_occ_stl_mesh_domain() gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator()
: m_mesh(NULL),
m_domain_id(0),
m_triangles(NULL),
m_vertices(NULL)
{ {
this->init(NULL);
} }
gmio_occ_stl_mesh_domain::gmio_occ_stl_mesh_domain( gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator(const StlMesh_Mesh *mesh)
const StlMesh_Mesh *msh, int dom_id)
: m_mesh(msh),
m_domain_id(dom_id),
m_triangles(&msh->Triangles(dom_id)),
m_vertices(&msh->Vertices(dom_id))
{ {
this->init(mesh);
} }
gmio_occ_stl_mesh_domain::gmio_occ_stl_mesh_domain( gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator(const Handle_StlMesh_Mesh &hnd)
const Handle_StlMesh_Mesh &hnd, int dom_id)
: m_mesh(internal::occMeshPtr(hnd)),
m_domain_id(dom_id),
m_triangles(&m_mesh->Triangles(dom_id)),
m_vertices(&m_mesh->Vertices(dom_id))
{ {
this->init(internal::occMeshPtr(hnd));
}
void gmio_stl_occmesh_iterator::init(const StlMesh_Mesh* mesh)
{
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);
}
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;
}
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;
}
return false;
}
return true;
} }

View File

@ -31,39 +31,70 @@
#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 <StlMesh_SequenceOfMeshTriangle.hxx>
class Handle_StlMesh_Mesh; class Handle_StlMesh_Mesh;
class StlMesh_Mesh; class StlMesh_Mesh;
class StlMesh_SequenceOfMeshTriangle; class Handle_StlMesh_MeshTriangle;
class TColgp_SequenceOfXYZ; class TColgp_SequenceOfXYZ;
/*! Domain in a OpenCascade \c StlMesh_Mesh object /*! Forward iterator over the triangles of OpenCascade's StlMesh_Mesh
* *
* The domain is indicated with its index within the STL mesh * It is used to iterate efficiently over the triangles of all domains within
* a StlMesh_Mesh object.
*
* You don't have to use API of this class, it's intended to gmio_stl_mesh()
*/ */
struct GMIO_LIBSUPPORT_EXPORT gmio_occ_stl_mesh_domain struct GMIO_LIBSUPPORT_EXPORT gmio_stl_occmesh_iterator
{ {
gmio_occ_stl_mesh_domain(); gmio_stl_occmesh_iterator();
gmio_occ_stl_mesh_domain(const StlMesh_Mesh* mesh, int dom_id = 1); gmio_stl_occmesh_iterator(const StlMesh_Mesh* mesh);
gmio_occ_stl_mesh_domain(const Handle_StlMesh_Mesh& hnd, int dom_id = 1); gmio_stl_occmesh_iterator(const Handle_StlMesh_Mesh& hnd);
bool move_to_next_tri(uint32_t tri_id);
inline const Handle_StlMesh_MeshTriangle& domain_tri(uint32_t tri_id) const;
inline const TColgp_SequenceOfXYZ& domain_vertices() const;
inline const StlMesh_Mesh* mesh() const; inline const StlMesh_Mesh* mesh() const;
inline int domain_id() const;
inline const StlMesh_SequenceOfMeshTriangle* triangles() const;
inline const TColgp_SequenceOfXYZ* vertices() const;
private: private:
void init(const StlMesh_Mesh* mesh);
void cache_domain(int dom_id);
const StlMesh_Mesh* m_mesh; const StlMesh_Mesh* m_mesh;
int m_domain_count;
int m_domain_id; int m_domain_id;
const StlMesh_SequenceOfMeshTriangle* m_triangles; const StlMesh_SequenceOfMeshTriangle* m_domain_triangles;
const TColgp_SequenceOfXYZ* m_vertices; const TColgp_SequenceOfXYZ* m_domain_vertices;
uint32_t m_domain_first_tri_id;
uint32_t m_domain_last_tri_id;
}; };
/*! Returns a gmio_stl_mesh mapped to domain in StlMesh_Mesh /*! Returns a gmio_stl_mesh mapped to the OCC mesh in iterator \p it
* *
* The mesh's cookie will point to \p mesh_domain * The mesh's cookie will point to \c &it so the lifescope of the corresponding
* object must be at least as longer as the returned gmio_stl_mesh.
* Example of use:
* \code
* Handle_StlMesh_Mesh occmesh = ...;
* gmio_stl_write_file(
* stl_format,
* filepath,
* gmio_stl_occmesh(occmesh), // Implicit temporary iterator
* &options);
* \endcode
*
* Dangerous use:
* \code
* Handle_StlMesh_Mesh occmesh = ...;
* const gmio_stl_mesh mesh =
* gmio_stl_occmesh(gmio_stl_occmesh_iterator(occmesh));
* // At this point the iterator object is destroyed, mesh.cookie points to
* // some garbage. The following line may cause a crash.
* gmio_stl_write_file(stl_format, filepath, mesh, &options);
* \endcode
*/ */
GMIO_LIBSUPPORT_EXPORT GMIO_LIBSUPPORT_EXPORT
struct gmio_stl_mesh gmio_stl_occmesh(const struct gmio_occ_stl_mesh_domain* mesh_domain); gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator& it);
/*! 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
@ -71,7 +102,7 @@ struct gmio_stl_mesh gmio_stl_occmesh(const struct gmio_occ_stl_mesh_domain* mes
* The creator's cookie will point \p mesh * The creator's cookie will point \p mesh
*/ */
GMIO_LIBSUPPORT_EXPORT GMIO_LIBSUPPORT_EXPORT
struct gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh); gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh);
/*! Same as gmio_stl_occmesh_creator(StlMesh_Mesh*) but takes a handle /*! Same as gmio_stl_occmesh_creator(StlMesh_Mesh*) but takes a handle
* *
@ -79,25 +110,26 @@ struct gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh);
* handle \p hnd * handle \p hnd
*/ */
GMIO_LIBSUPPORT_EXPORT GMIO_LIBSUPPORT_EXPORT
struct gmio_stl_mesh_creator gmio_stl_hnd_occmesh_creator(const Handle_StlMesh_Mesh& hnd); gmio_stl_mesh_creator gmio_stl_occmesh_creator(const Handle_StlMesh_Mesh& hnd);
// -- /*
// -- Implementation * Implementation
// -- */
const StlMesh_Mesh* gmio_occ_stl_mesh_domain::mesh() const const Handle_StlMesh_MeshTriangle&
gmio_stl_occmesh_iterator::domain_tri(uint32_t tri_id) const
{
const int dom_tri_id = tri_id - m_domain_first_tri_id + 1;
return m_domain_triangles->Value(dom_tri_id);
}
const TColgp_SequenceOfXYZ &gmio_stl_occmesh_iterator::domain_vertices() const
{ return *m_domain_vertices; }
const StlMesh_Mesh *gmio_stl_occmesh_iterator::mesh() const
{ return m_mesh; } { return m_mesh; }
int gmio_occ_stl_mesh_domain::domain_id() const
{ return m_domain_id; }
const StlMesh_SequenceOfMeshTriangle* gmio_occ_stl_mesh_domain::triangles() const
{ return m_triangles; }
const TColgp_SequenceOfXYZ* gmio_occ_stl_mesh_domain::vertices() const
{ return m_vertices; }
#endif /* GMIO_SUPPORT_STL_OCC_H */ #endif /* GMIO_SUPPORT_STL_OCC_H */
/*! @} */ /*! @} */

View File

@ -11,7 +11,7 @@ int main()
{ {
// OpenCascade // OpenCascade
Handle_StlMesh_Mesh stlMesh; Handle_StlMesh_Mesh stlMesh;
gmio_stl_hnd_occmesh_creator(stlMesh); gmio_stl_occmesh_creator(stlMesh);
// Qt // Qt
QFile file; QFile file;

View File

@ -23,7 +23,10 @@ public:
const double /*X*/, const double /*Y*/, const double /*Z*/) const double /*X*/, const double /*Y*/, const double /*Z*/)
{ return -1; } { return -1; }
virtual int NbTriangles(const int DomainIndex) const virtual int NbTriangles(const int /*DomainIndex*/) const
{ return 0; }
virtual int NbDomains() const
{ return 0; } { return 0; }
virtual const StlMesh_SequenceOfMeshTriangle& Triangles( virtual const StlMesh_SequenceOfMeshTriangle& Triangles(

View File

@ -11,6 +11,9 @@ public:
static Handle_StlMesh_MeshTriangle meshTri; static Handle_StlMesh_MeshTriangle meshTri;
return meshTri; return meshTri;
} }
int Length() const
{ return 0; }
}; };
#endif // _StlMesh_SequenceOfMeshTriangle_HeaderFile #endif // _StlMesh_SequenceOfMeshTriangle_HeaderFile