diff --git a/src/gmio_support/stl_occ.cpp b/src/gmio_support/stl_occ.cpp index 7af9cfc..9bfc305 100644 --- a/src/gmio_support/stl_occ.cpp +++ b/src/gmio_support/stl_occ.cpp @@ -21,6 +21,12 @@ #include #include +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +# include +# include +# include +#endif // !GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE + namespace internal { /* Common */ @@ -47,11 +53,17 @@ static void occmesh_add_triangle( } static inline void gmio_stl_occ_copy_xyz( - gmio_vec3f* stl_coords, const gp_XYZ& coords) + gmio_vec3f* vec, double x, double y, double z) { - stl_coords->x = static_cast(coords.X()); - stl_coords->y = static_cast(coords.Y()); - stl_coords->z = static_cast(coords.Z()); + vec->x = static_cast(x); + vec->y = static_cast(y); + vec->z = static_cast(z); +} + +static inline void gmio_stl_occ_copy_xyz( + gmio_vec3f* vec, const gp_XYZ& coords) +{ + gmio_stl_occ_copy_xyz(vec, coords.X(), coords.Y(), coords.Z()); } static void occmesh_get_triangle( @@ -62,35 +74,78 @@ static void occmesh_get_triangle( static_cast(wcookie); if (it->move_to_next_tri(tri_id)) { + int iv1, iv2, iv3; + double nx, ny, nz; 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_vec3f& n = tri->n; - n.x = static_cast(xN); - n.y = static_cast(yN); - n.z = static_cast(zN); + occTri->GetVertexAndOrientation(iv1, iv2, iv3, nx, ny, nz); + gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); 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)); + 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)); } } +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +static void occmesh_datasource_get_triangle( + const void* cookie, uint32_t /*tri_id*/, gmio_stl_triangle* tri) +{ + void* wcookie = const_cast(cookie); + gmio_stl_occmesh_datasource_iterator* it = + static_cast(wcookie); + const MeshVS_DataSource* data_src = it->data_src(); + + int node_count; + MeshVS_EntityType entity_type; + const Standard_Boolean get_geom_ok = + data_src->GetGeom( + it->current_element_key(), + Standard_True, // Is element + it->cached_element_coords(), + node_count, + entity_type); + if (get_geom_ok && node_count == 3) { + // Copy vertex coords + const TColStd_Array1OfReal& in_coords_array = it->cached_element_coords(); + float* out_coords_ptr = &tri->v1.x; + for (int i = 0; i < 9; ++i) + out_coords_ptr[i] = static_cast(in_coords_array.Value(i + 1)); + // Copy normal coords + double nx, ny, nz; + data_src->GetNormal(it->current_element_key(), 3, nx, ny, nz); + gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); + } + it->move_to_next_tri(); +} +#endif // !GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE + } // 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()->NbDomains(); + 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 = internal::occmesh_get_triangle; return mesh; } +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +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 = internal::occmesh_datasource_get_triangle; + return mesh; +} +#endif // !GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE + gmio_stl_mesh_creator gmio_stl_occmesh_creator(StlMesh_Mesh* mesh) { gmio_stl_mesh_creator creator = {}; @@ -156,3 +211,28 @@ bool gmio_stl_occmesh_iterator::move_to_next_tri(uint32_t tri_id) } return true; } + +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +gmio_stl_occmesh_datasource_iterator::gmio_stl_occmesh_datasource_iterator() + : 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()); +} + +gmio_stl_occmesh_datasource_iterator::gmio_stl_occmesh_datasource_iterator( + 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()); +} +#endif /* GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE */ diff --git a/src/gmio_support/stl_occ.h b/src/gmio_support/stl_occ.h index 6b051d8..105fd35 100644 --- a/src/gmio_support/stl_occ.h +++ b/src/gmio_support/stl_occ.h @@ -38,6 +38,13 @@ class StlMesh_Mesh; class Handle_StlMesh_MeshTriangle; class TColgp_SequenceOfXYZ; +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +# include +# include +class Handle_MeshVS_DataSource; +class MeshVS_DataSource; +#endif // !GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE + /*! Forward iterator over the triangles of OpenCascade's StlMesh_Mesh * * It is used to iterate efficiently over the triangles of all domains within @@ -83,6 +90,47 @@ private: */ gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_iterator& it); +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +/*! 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. + * + * You don't have to use API of this class, it's intended to gmio_stl_mesh() + */ +struct gmio_stl_occmesh_datasource_iterator +{ + gmio_stl_occmesh_datasource_iterator(); + gmio_stl_occmesh_datasource_iterator(const MeshVS_DataSource* data_src); + gmio_stl_occmesh_datasource_iterator(const Handle_MeshVS_DataSource& hnd); + + inline void move_to_next_tri(); + inline int current_element_key() const; + inline TColStd_Array1OfReal& cached_element_coords(); + inline const MeshVS_DataSource* data_src() const; + +private: + const MeshVS_DataSource* m_data_src; + TColStd_MapIteratorOfPackedMapOfInteger m_element_it; + TColStd_Array1OfReal m_element_coords; +}; + +/*! Returns a gmio_stl_mesh mapped to the OCC mesh data-source in iterator \p it + * + * 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_MeshVS_Mesh mesh = ...; + * const gmio_stl_occmesh_datasource_iterator it(mesh->GetDataSource()); + * const gmio_stl_mesh mesh = gmio_stl_occmesh(it); + * gmio_stl_write_file(stl_format, filepath, &mesh, &options); + * \endcode + */ +gmio_stl_mesh gmio_stl_occmesh(const gmio_stl_occmesh_datasource_iterator& it); +#endif // !GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE + /*! Returns a gmio_stl_mesh_creator that will build a new domain in a * StlMesh_Mesh object * @@ -118,6 +166,20 @@ const TColgp_SequenceOfXYZ &gmio_stl_occmesh_iterator::domain_vertices() const const StlMesh_Mesh *gmio_stl_occmesh_iterator::mesh() const { return m_mesh; } +#ifndef GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE +void gmio_stl_occmesh_datasource_iterator::move_to_next_tri() +{ m_element_it.Next(); } + +int gmio_stl_occmesh_datasource_iterator::current_element_key() const +{ return m_element_it.Key(); } + +TColStd_Array1OfReal& gmio_stl_occmesh_datasource_iterator::cached_element_coords() +{ return m_element_coords; } + +const MeshVS_DataSource* gmio_stl_occmesh_datasource_iterator::data_src() const +{ return m_data_src; } +#endif /* GMIO_SUPPORT_STL_OCC_NO_MESHVS_DATASOURCE */ + #endif /* !DOXYGEN */ #endif /* GMIO_SUPPORT_STL_OCC_H */ diff --git a/tests/fake_support/CMakeLists.txt b/tests/fake_support/CMakeLists.txt index 1cd1d05..7e9fd98 100644 --- a/tests/fake_support/CMakeLists.txt +++ b/tests/fake_support/CMakeLists.txt @@ -18,11 +18,17 @@ add_executable( EXCLUDE_FROM_ALL main.cpp opencascade/gp_XYZ.hxx + opencascade/Handle_MeshVS_DataSource.hxx opencascade/Handle_StlMesh_Mesh.hxx opencascade/Handle_StlMesh_MeshTriangle.hxx + opencascade/MeshVS_DataSource.hxx + opencascade/Standard_TypeDef.hxx opencascade/StlMesh_Mesh.hxx opencascade/StlMesh_MeshTriangle.hxx opencascade/StlMesh_SequenceOfMeshTriangle.hxx + opencascade/TColStd_Array1OfReal.hxx + opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx + opencascade/TColStd_PackedMapOfInteger.hxx opencascade/TColgp_SequenceOfXYZ.hxx qt/QtCore/QFile qt/QtCore/QIODevice diff --git a/tests/fake_support/opencascade/Handle_MeshVS_DataSource.hxx b/tests/fake_support/opencascade/Handle_MeshVS_DataSource.hxx new file mode 100644 index 0000000..773b669 --- /dev/null +++ b/tests/fake_support/opencascade/Handle_MeshVS_DataSource.hxx @@ -0,0 +1,20 @@ +#ifndef _Handle_MeshVS_DataSource_HeaderFile +#define _Handle_MeshVS_DataSource_HeaderFile + +class MeshVS_DataSource; + +class Handle_MeshVS_DataSource +{ +public: + Handle_MeshVS_DataSource() {} + Handle_MeshVS_DataSource(const Handle_MeshVS_DataSource&) {} + Handle_MeshVS_DataSource(const MeshVS_DataSource*) {} + + MeshVS_DataSource* operator->() const + { return 0; } + + Handle_MeshVS_DataSource& operator=(const MeshVS_DataSource*) + { return *this; } +}; + +#endif // _Handle_MeshVS_DataSource_HeaderFile diff --git a/tests/fake_support/opencascade/MeshVS_DataSource.hxx b/tests/fake_support/opencascade/MeshVS_DataSource.hxx new file mode 100644 index 0000000..deabbd6 --- /dev/null +++ b/tests/fake_support/opencascade/MeshVS_DataSource.hxx @@ -0,0 +1,44 @@ +#ifndef _MeshVS_DataSource_HeaderFile +#define _MeshVS_DataSource_HeaderFile + +#include "Standard_TypeDef.hxx" + +class TColStd_Array1OfReal; +class TColStd_PackedMapOfInteger; + +typedef enum +{ + MeshVS_ET_NONE = 0x00, + MeshVS_ET_Node = 0x01, + MeshVS_ET_0D = 0x02, + MeshVS_ET_Link = 0x04, + MeshVS_ET_Face = 0x08, + MeshVS_ET_Volume = 0x10, + + MeshVS_ET_Element = MeshVS_ET_0D | MeshVS_ET_Link | MeshVS_ET_Face | MeshVS_ET_Volume, + MeshVS_ET_All = MeshVS_ET_Element | MeshVS_ET_Node + +} MeshVS_EntityType; + +class MeshVS_DataSource +{ +public: + virtual Standard_Boolean GetGeom(const int, const Standard_Boolean, TColStd_Array1OfReal&, int&, MeshVS_EntityType&) const = 0; + virtual Standard_Boolean GetGeomType(const int, const Standard_Boolean, MeshVS_EntityType&) const = 0; + virtual const TColStd_PackedMapOfInteger& GetAllNodes() const = 0; + virtual const TColStd_PackedMapOfInteger& GetAllElements() const = 0; + + virtual Standard_Boolean GetNormal(const int, const int, double&, double&, double&) const + { return 0; } + + virtual Standard_Boolean GetNodeNormal(const int, const int, double&, double&, double&) const + { return 0; } + + virtual void GetAllGroups (TColStd_PackedMapOfInteger&) const + { } + + virtual Standard_Boolean GetGroup (const int, MeshVS_EntityType&, TColStd_PackedMapOfInteger&) const + { return 0; } +}; + +#endif // _MeshVS_DataSource_HeaderFile diff --git a/tests/fake_support/opencascade/Standard_TypeDef.hxx b/tests/fake_support/opencascade/Standard_TypeDef.hxx new file mode 100644 index 0000000..b46acca --- /dev/null +++ b/tests/fake_support/opencascade/Standard_TypeDef.hxx @@ -0,0 +1,23 @@ +#ifndef _Standard_TypeDef_HeaderFile +#define _Standard_TypeDef_HeaderFile + +typedef int Standard_Integer; +typedef double Standard_Real; +typedef unsigned int Standard_Boolean; +typedef float Standard_ShortReal; +typedef char Standard_Character; +typedef short Standard_ExtCharacter; +typedef unsigned char Standard_Byte; +typedef void* Standard_Address; + +typedef const char* Standard_CString; +typedef const short* Standard_ExtString; + +#ifndef Standard_False +# define Standard_False (Standard_Boolean)0 +#endif +#ifndef Standard_True +# define Standard_True (Standard_Boolean)1 +#endif + +#endif // _Standard_TypeDef_HeaderFile diff --git a/tests/fake_support/opencascade/TColStd_Array1OfReal.hxx b/tests/fake_support/opencascade/TColStd_Array1OfReal.hxx new file mode 100644 index 0000000..e6788dd --- /dev/null +++ b/tests/fake_support/opencascade/TColStd_Array1OfReal.hxx @@ -0,0 +1,34 @@ +#ifndef _TColStd_Array1OfReal_HeaderFile +#define _TColStd_Array1OfReal_HeaderFile + +class TColStd_Array1OfReal +{ +public: + TColStd_Array1OfReal(const int, const int) {} + + int Length() const { return 0; } + int Lower() const { return 1; } + int Upper() const { return 1; } + + void SetValue (const int, const double&) {} + + const double& Value(const int) const + { + static const double v = 0; + return v; + } + + const double& operator()(const int Index) const + { return Value(Index); } + + double& ChangeValue(const int) + { + static double v = 0; + return v; + } + + double& operator()(const int Index) + { return ChangeValue(Index); } +}; + +#endif // _TColStd_Array1OfReal_HeaderFile diff --git a/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx b/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx new file mode 100644 index 0000000..0a6caa7 --- /dev/null +++ b/tests/fake_support/opencascade/TColStd_MapIteratorOfPackedMapOfInteger.hxx @@ -0,0 +1,17 @@ +#ifndef TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile +#define TColStd_MapIteratorOfPackedMapOfInteger_HeaderFile + +class TColStd_PackedMapOfInteger; + +class TColStd_MapIteratorOfPackedMapOfInteger +{ +public: + TColStd_MapIteratorOfPackedMapOfInteger() {} + TColStd_MapIteratorOfPackedMapOfInteger(const TColStd_PackedMapOfInteger&) {} + void Initialize(const TColStd_PackedMapOfInteger&) {} + void Reset() {} + int Key() const { return 0; } + void Next() {} +}; + +#endif diff --git a/tests/fake_support/opencascade/TColStd_PackedMapOfInteger.hxx b/tests/fake_support/opencascade/TColStd_PackedMapOfInteger.hxx new file mode 100644 index 0000000..3cd43f9 --- /dev/null +++ b/tests/fake_support/opencascade/TColStd_PackedMapOfInteger.hxx @@ -0,0 +1,26 @@ +#ifndef TColStd_PackedMapOfInteger_HeaderFile +#define TColStd_PackedMapOfInteger_HeaderFile + +#include "Standard_TypeDef.hxx" + +class TColStd_PackedMapOfInteger +{ +public: + TColStd_PackedMapOfInteger(const int /*NbBuckets*/ = 1) {} + TColStd_PackedMapOfInteger(const TColStd_PackedMapOfInteger&) {} + ~TColStd_PackedMapOfInteger() {} + + TColStd_PackedMapOfInteger& operator=(const TColStd_PackedMapOfInteger&) {} + void ReSize(const int) {} + void Clear() {} + + Standard_Boolean Add(const int) { return Standard_False; } + Standard_Boolean Contains(const int) const { return Standard_False; } + Standard_Boolean Remove(const int) { return Standard_False; } + + int NbBuckets() const { return 0; } + int Extent() const { return 0; } + int IsEmpty() const { return 1; } +}; + +#endif