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;
const int error = gmio_stl_read_file(
static_cast<const char*>(filepath),
gmio_stl_hnd_occmesh_creator(stlMesh),
gmio_stl_occmesh_creator(stlMesh),
NULL);
if (error != GMIO_ERROR_OK)
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)
{
const gmio_occ_stl_mesh_domain occ_mesh_domain(stlMesh);
gmio_stl_write_options options = {};
options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE;
options.stla_float32_prec = 7;
@ -77,7 +76,7 @@ static void stl_write(const char* filepath, gmio_stl_format format)
gmio_stl_write_file(
format,
static_cast<const char*>(filepath),
gmio_stl_occmesh(&occ_mesh_domain),
gmio_stl_occmesh(stlMesh),
&options);
if (error != GMIO_ERROR_OK)
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(
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);
if (tri_id == 0)
@ -46,94 +46,113 @@ static void occmesh_add_triangle(
n.x, n.y, n.z);
}
static void occmesh_get_triangle(
const void* cookie, uint32_t tri_id, struct gmio_stl_triangle* tri)
static inline void gmio_stl_occ_copy_xyz(
gmio_stl_coords* stl_coords, const gp_XYZ& coords)
{
const struct gmio_occ_stl_mesh_domain* mesh_domain =
static_cast<const struct gmio_occ_stl_mesh_domain*>(cookie);
const Handle_StlMesh_MeshTriangle& occTri =
mesh_domain->triangles()->Value(tri_id + 1);
int idV1;
int idV2;
int idV3;
double xN;
double yN;
double zN;
occTri->GetVertexAndOrientation(idV1, idV2, idV3, xN, yN, zN);
gmio_stl_coords& n = tri->n;
n.x = static_cast<float>(xN);
n.y = static_cast<float>(yN);
n.z = static_cast<float>(zN);
stl_coords->x = static_cast<float>(coords.X());
stl_coords->y = static_cast<float>(coords.Y());
stl_coords->z = static_cast<float>(coords.Z());
}
const TColgp_SequenceOfXYZ& vertices = *mesh_domain->vertices();
const gp_XYZ& coordsV1 = vertices.Value(idV1);
gmio_stl_coords& v1 = tri->v1;
v1.x = static_cast<float>(coordsV1.X());
v1.y = static_cast<float>(coordsV1.Y());
v1.z = static_cast<float>(coordsV1.Z());
static void 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 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());
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);
gmio_stl_coords& n = tri->n;
n.x = static_cast<float>(xN);
n.y = static_cast<float>(yN);
n.z = static_cast<float>(zN);
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());
const TColgp_SequenceOfXYZ& vertices = it->domain_vertices();
gmio_stl_occ_copy_xyz(&tri->v1, vertices.Value(idV1));
gmio_stl_occ_copy_xyz(&tri->v2, vertices.Value(idV2));
gmio_stl_occ_copy_xyz(&tri->v3, vertices.Value(idV3));
}
}
} // 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};
mesh.cookie = mesh_domain;
if (mesh_domain != NULL && mesh_domain->mesh() != NULL) {
mesh.triangle_count =
mesh_domain->mesh()->NbTriangles(mesh_domain->domain_id());
}
gmio_stl_mesh mesh = {};
mesh.cookie = &it;
const int domain_count = it.mesh()->NbDomains();
for (int dom_id = 1; dom_id <= domain_count; ++dom_id)
mesh.triangle_count += it.mesh()->NbTriangles(dom_id);
mesh.func_get_triangle = internal::occmesh_get_triangle;
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.func_add_triangle = internal::occmesh_add_triangle;
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));
}
gmio_occ_stl_mesh_domain::gmio_occ_stl_mesh_domain()
: m_mesh(NULL),
m_domain_id(0),
m_triangles(NULL),
m_vertices(NULL)
gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator()
{
this->init(NULL);
}
gmio_occ_stl_mesh_domain::gmio_occ_stl_mesh_domain(
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))
gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator(const StlMesh_Mesh *mesh)
{
this->init(mesh);
}
gmio_occ_stl_mesh_domain::gmio_occ_stl_mesh_domain(
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))
gmio_stl_occmesh_iterator::gmio_stl_occmesh_iterator(const Handle_StlMesh_Mesh &hnd)
{
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_creator.h"
#include <StlMesh_SequenceOfMeshTriangle.hxx>
class Handle_StlMesh_Mesh;
class StlMesh_Mesh;
class StlMesh_SequenceOfMeshTriangle;
class Handle_StlMesh_MeshTriangle;
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_occ_stl_mesh_domain(const StlMesh_Mesh* mesh, int dom_id = 1);
gmio_occ_stl_mesh_domain(const Handle_StlMesh_Mesh& hnd, int dom_id = 1);
gmio_stl_occmesh_iterator();
gmio_stl_occmesh_iterator(const StlMesh_Mesh* mesh);
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 int domain_id() const;
inline const StlMesh_SequenceOfMeshTriangle* triangles() const;
inline const TColgp_SequenceOfXYZ* vertices() const;
private:
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_triangles;
const TColgp_SequenceOfXYZ* m_vertices;
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;
};
/*! 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
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
* 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
*/
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
*
@ -79,25 +110,26 @@ struct gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh);
* handle \p hnd
*/
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; }
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 */
/*! @} */

View File

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

View File

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

View File

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