diff --git a/benchmarks/benchmark_opencascade/CMakeLists.txt b/benchmarks/benchmark_opencascade/CMakeLists.txt index a74008b..155ee81 100644 --- a/benchmarks/benchmark_opencascade/CMakeLists.txt +++ b/benchmarks/benchmark_opencascade/CMakeLists.txt @@ -54,6 +54,7 @@ add_executable( main.cpp ${CMAKE_SOURCE_DIR}/src/gmio_support/stl_occ_brep.cpp ${CMAKE_SOURCE_DIR}/src/gmio_support/stl_occ_mesh.cpp + ${CMAKE_SOURCE_DIR}/src/gmio_support/stl_occ_polytri.cpp ${COMMONS_FILES}) if(GMIO_TARGET_ARCH_BIT_SIZE EQUAL 64) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86029e4..66504eb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,13 +80,15 @@ install(FILES gmio_support/stream_qt.h DESTINATION include/gmio_support) install(FILES gmio_support/stream_qt.cpp DESTINATION src/gmio_support) # OpenCASCADE support -install(FILES gmio_support/stl_occ_brep.h DESTINATION include/gmio_support) -install(FILES gmio_support/stl_occ_mesh.h DESTINATION include/gmio_support) -install(FILES gmio_support/stl_occ_meshvs.h DESTINATION include/gmio_support) -install(FILES gmio_support/stl_occ_brep.cpp DESTINATION src/gmio_support) -install(FILES gmio_support/stl_occ_mesh.cpp DESTINATION src/gmio_support) -install(FILES gmio_support/stl_occ_meshvs.cpp DESTINATION src/gmio_support) -install(FILES gmio_support/stl_occ_utils.h DESTINATION src/gmio_support) +install(FILES gmio_support/stl_occ_brep.h DESTINATION include/gmio_support) +install(FILES gmio_support/stl_occ_mesh.h DESTINATION include/gmio_support) +install(FILES gmio_support/stl_occ_meshvs.h DESTINATION include/gmio_support) +install(FILES gmio_support/stl_occ_polytri.h DESTINATION include/gmio_support) +install(FILES gmio_support/stl_occ_brep.cpp DESTINATION src/gmio_support) +install(FILES gmio_support/stl_occ_mesh.cpp DESTINATION src/gmio_support) +install(FILES gmio_support/stl_occ_meshvs.cpp DESTINATION src/gmio_support) +install(FILES gmio_support/stl_occ_polytri.cpp DESTINATION src/gmio_support) +install(FILES gmio_support/stl_occ_utils.h DESTINATION src/gmio_support) # zlib if(GMIO_USE_BUNDLED_ZLIB) diff --git a/src/gmio_support/stl_occ_brep.cpp b/src/gmio_support/stl_occ_brep.cpp index 81bbf28..20f4313 100644 --- a/src/gmio_support/stl_occ_brep.cpp +++ b/src/gmio_support/stl_occ_brep.cpp @@ -28,15 +28,19 @@ ****************************************************************************/ #include - #include "stl_occ_utils.h" +#include #include #include #include #include #include +// ----------------------------------------------------------------------------- +// gmio_stl_mesh_occshape +// ----------------------------------------------------------------------------- + gmio_stl_mesh_occshape::gmio_stl_mesh_occshape() : m_shape(NULL) { @@ -128,3 +132,26 @@ void gmio_stl_mesh_occshape::init_C_members() this->func_get_triangle = &gmio_stl_mesh_occshape::get_triangle; this->triangle_count = 0; } + +// ----------------------------------------------------------------------------- +// gmio_stl_mesh_creator_occshape +// ----------------------------------------------------------------------------- + +gmio_stl_mesh_creator_occshape::gmio_stl_mesh_creator_occshape() +{ + this->cookie = this; + this->m_func_end_solid_occpolytri = this->func_end_solid; + this->func_end_solid = &gmio_stl_mesh_creator_occshape::end_solid; +} + +void gmio_stl_mesh_creator_occshape::end_solid(void* cookie) +{ + gmio_stl_mesh_creator_occshape* creator = + static_cast(cookie); + creator->m_func_end_solid_occpolytri(cookie); + if (!creator->polytri().IsNull()) { + Handle_BRep_TFace face = new BRep_TFace; + face->Triangulation(creator->polytri()); + creator->m_shape.TShape(face); + } +} diff --git a/src/gmio_support/stl_occ_brep.h b/src/gmio_support/stl_occ_brep.h index 9609e17..ccaa6bf 100644 --- a/src/gmio_support/stl_occ_brep.h +++ b/src/gmio_support/stl_occ_brep.h @@ -28,11 +28,12 @@ ****************************************************************************/ /*! \file stl_occ_brep.h - * STL support of OpenCascade's TopoDS_Shape + * STL support of OpenCascade's \c TopoDS_Shape * - * To use this header the source file + * To use this header the source files * $INSTALL/src/gmio_support/stl_occ_brep.cpp\n - * needs to be built in the target project(\c $INSTALL is the root directory + * $INSTALL/src/gmio_support/stl_occ_polytri.cpp\n + * need to be built in the target project(\c $INSTALL is the root directory * where is installed gmio) * * Of course this requires the includepath and libpath to point to OpenCascade, @@ -50,16 +51,14 @@ #pragma once #include "support_global.h" +#include "stl_occ_polytri.h" #include "../gmio_stl/stl_mesh.h" -#include - #include #include -class TopoDS_Face; +#include -/*! Provides access to all the internal triangles of OpenCascade's - * \c TopoDS_Shape +/*! Provides access to the internal triangles of an OpenCascade \c TopoDS_Shape * * gmio_stl_mesh_occshape iterates efficiently over the triangles of all * sub TopoDS_Faces(internal \c Poly_Triangulation objects). @@ -76,7 +75,7 @@ struct gmio_stl_mesh_occshape : public gmio_stl_mesh gmio_stl_mesh_occshape(); explicit gmio_stl_mesh_occshape(const TopoDS_Shape& shape); - inline const TopoDS_Shape* shape() const { return m_shape; } + const TopoDS_Shape* shape() const { return m_shape; } private: static void get_triangle( @@ -99,4 +98,26 @@ private: const TopoDS_Shape* m_shape; }; +/*! Provides creation of an OpenCascade \c TopoDS_Shape containing no + * geometrical surfaces but only a \c Poly_Triangulation structure + * + * Example of use: + * \code{.cpp} + * gmio_stl_mesh_creator_occshape meshcreator; + * gmio_stl_read_file(filepath, &meshcreator, &options); + * const TopoDS_Shape shape = meshcreator.shape(); + * \endcode + */ +struct gmio_stl_mesh_creator_occshape : public gmio_stl_mesh_creator_occpolytri +{ +public: + gmio_stl_mesh_creator_occshape(); + TopoDS_Shape& shape() { return m_shape; } + +private: + static void end_solid(void* cookie); + void (*m_func_end_solid_occpolytri)(void* cookie); + TopoDS_Shape m_shape; +}; + /*! @} */ diff --git a/src/gmio_support/stl_occ_mesh.cpp b/src/gmio_support/stl_occ_mesh.cpp index 54da8e2..226693f 100644 --- a/src/gmio_support/stl_occ_mesh.cpp +++ b/src/gmio_support/stl_occ_mesh.cpp @@ -44,56 +44,26 @@ // ----------------------------------------------------------------------------- gmio_stl_mesh_occmesh::gmio_stl_mesh_occmesh() - : m_mesh(NULL) { - this->init_C_members(); -} - -gmio_stl_mesh_occmesh::gmio_stl_mesh_occmesh(const StlMesh_Mesh *mesh) - : m_mesh(mesh) -{ - this->init_C_members(); - this->init_cache(); + this->init(); } gmio_stl_mesh_occmesh::gmio_stl_mesh_occmesh(const Handle_StlMesh_Mesh &hnd) - : m_mesh(hnd.operator->()) + : m_mesh(hnd) { - this->init_C_members(); - this->init_cache(); + this->init(); } -void gmio_stl_mesh_occmesh::init_C_members() +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) -{ - const gmio_stl_mesh_occmesh* it = - static_cast(cookie); - const triangle_data& tridata = it->m_vec_triangle_data.at(tri_id); - const std::vector& vec_coords = tridata.ptr_domain->vec_coords; - - int iv1, iv2, iv3; - double nx, ny, nz; - tridata.ptr_triangle->GetVertexAndOrientation(iv1, iv2, iv3, nx, ny, nz); - gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); - gmio_stl_occ_copy_xyz(&tri->v1, *vec_coords.at(iv1 - 1)); - gmio_stl_occ_copy_xyz(&tri->v2, *vec_coords.at(iv2 - 1)); - gmio_stl_occ_copy_xyz(&tri->v3, *vec_coords.at(iv3 - 1)); -} - -void gmio_stl_mesh_occmesh::init_cache() -{ // Count triangles - const int domain_count = m_mesh != NULL ? m_mesh->NbDomains() : 0; + const int domain_count = !m_mesh.IsNull() ? m_mesh->NbDomains() : 0; for (int dom_id = 1; dom_id <= domain_count; ++dom_id) this->triangle_count += m_mesh->NbTriangles(dom_id); - // Fill vector of triangle data m_vec_domain_data.resize(domain_count); m_vec_triangle_data.resize(this->triangle_count); @@ -128,33 +98,41 @@ void gmio_stl_mesh_occmesh::init_cache() } } +void gmio_stl_mesh_occmesh::get_triangle( + const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri) +{ + const gmio_stl_mesh_occmesh* mesh = + static_cast(cookie); + const triangle_data& tridata = mesh->m_vec_triangle_data.at(tri_id); + const std::vector& vec_coords = tridata.ptr_domain->vec_coords; + + int iv1, iv2, iv3; + double nx, ny, nz; + tridata.ptr_triangle->GetVertexAndOrientation(iv1, iv2, iv3, nx, ny, nz); + gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); + gmio_stl_occ_copy_xyz(&tri->v1, *vec_coords.at(iv1 - 1)); + gmio_stl_occ_copy_xyz(&tri->v2, *vec_coords.at(iv2 - 1)); + gmio_stl_occ_copy_xyz(&tri->v3, *vec_coords.at(iv3 - 1)); +} + // ----------------------------------------------------------------------------- // gmio_stl_mesh_creator_occmesh // ----------------------------------------------------------------------------- gmio_stl_mesh_creator_occmesh::gmio_stl_mesh_creator_occmesh() - : m_mesh(NULL), - m_filter(Precision::Confusion()), + : m_filter(Precision::Confusion()), m_inspector(Precision::Confusion()) { - this->init_C_members(); -} - -gmio_stl_mesh_creator_occmesh::gmio_stl_mesh_creator_occmesh(StlMesh_Mesh *mesh) - : m_mesh(mesh), - m_filter(Precision::Confusion()), - m_inspector(Precision::Confusion()) -{ - this->init_C_members(); + this->init(); } gmio_stl_mesh_creator_occmesh::gmio_stl_mesh_creator_occmesh( - const Handle_StlMesh_Mesh &hnd) - : m_mesh(hnd.operator->()), + const Handle_StlMesh_Mesh& hnd) + : m_mesh(hnd), m_filter(Precision::Confusion()), m_inspector(Precision::Confusion()) { - this->init_C_members(); + this->init(); } void gmio_stl_mesh_creator_occmesh::begin_solid( @@ -179,7 +157,7 @@ void gmio_stl_mesh_creator_occmesh::add_triangle( } -void gmio_stl_mesh_creator_occmesh::init_C_members() +void gmio_stl_mesh_creator_occmesh::init() { this->cookie = this; this->func_begin_solid = &gmio_stl_mesh_creator_occmesh::begin_solid; @@ -189,23 +167,11 @@ void gmio_stl_mesh_creator_occmesh::init_C_members() int gmio_stl_mesh_creator_occmesh::add_unique_vertex(const gmio_vec3f& v) { - //-------------------------------------------------------------------------- - // Code excerpted from OpenCascade v7.0.0 - // File: RWStl/RWStl.cxx - // Function: "static int AddVertex(...)" lines 38..61 - //-------------------------------------------------------------------------- const gp_XYZ pnt(v.x, v.y, v.z); - m_inspector.SetCurrent(pnt); - const gp_XYZ min_pnt = m_inspector.Shift(pnt, -Precision::Confusion()); - const gp_XYZ max_pnt = m_inspector.Shift(pnt, +Precision::Confusion()); - m_filter.Inspect(min_pnt, max_pnt, m_inspector); - if (!m_inspector.ResInd().IsEmpty()) { - const int index = m_inspector.ResInd().First(); // There should be only one - m_inspector.ClearResList(); - return index; - } - const int index = m_mesh->AddVertex(pnt.X(), pnt.Y(), pnt.Z()); - m_filter.Add(index, pnt); - m_inspector.Add(pnt); + int index = gmio_occ_find_vertex_index(pnt, &m_filter, &m_inspector); + if (index != -1) + return index; + index = m_mesh->AddVertex(pnt.X(), pnt.Y(), pnt.Z()); + gmio_occ_add_vertex_index(pnt, index, &m_filter, &m_inspector); return index; } diff --git a/src/gmio_support/stl_occ_mesh.h b/src/gmio_support/stl_occ_mesh.h index ddd7342..015d158 100644 --- a/src/gmio_support/stl_occ_mesh.h +++ b/src/gmio_support/stl_occ_mesh.h @@ -28,7 +28,7 @@ ****************************************************************************/ /*! \file stl_occ_mesh.h - * STL support of OpenCascade's StlMesh_Mesh + * STL support of OpenCascade's \c StlMesh_Mesh * * To use this header the source file * $INSTALL/src/gmio_support/stl_occ_mesh.cpp\n @@ -53,15 +53,14 @@ #include "../gmio_stl/stl_mesh.h" #include "../gmio_stl/stl_mesh_creator.h" -#include - #include #include #include #include #include +#include -/*! Provides access to all the triangles of OpenCascade's \c StlMesh_Mesh +/*! Provides access to all the triangles of an OpenCascade \c StlMesh_Mesh * * gmio_stl_mesh_occmesh iterates efficiently over the triangles of all * domains. @@ -76,17 +75,15 @@ 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; } + const Handle_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(); + void init(); struct domain_data { std::vector vec_coords; @@ -97,12 +94,12 @@ private: const domain_data* ptr_domain; }; - const StlMesh_Mesh* m_mesh; + Handle_StlMesh_Mesh m_mesh; std::vector m_vec_domain_data; std::vector m_vec_triangle_data; }; -/*! Provides creation of a new domain within an StlMesh_Mesh object +/*! Provides creation of a new domain within an OpenCascade \c StlMesh_Mesh * * gmio_stl_mesh_creator::func_add_triangle() calls * StlMesh_Mesh::AddVertex() only for new unique vertices, ie. they @@ -122,10 +119,9 @@ private: struct gmio_stl_mesh_creator_occmesh : public gmio_stl_mesh_creator { gmio_stl_mesh_creator_occmesh(); - explicit gmio_stl_mesh_creator_occmesh(StlMesh_Mesh* mesh); explicit gmio_stl_mesh_creator_occmesh(const Handle_StlMesh_Mesh& hnd); - inline StlMesh_Mesh* mesh() const { return m_mesh; } + const Handle_StlMesh_Mesh& mesh() const { return m_mesh; } private: static void begin_solid( @@ -133,10 +129,10 @@ private: static void add_triangle( void* cookie, uint32_t tri_id, const gmio_stl_triangle* tri); - void init_C_members(); + void init(); int add_unique_vertex(const gmio_vec3f& v); - StlMesh_Mesh* m_mesh; + Handle_StlMesh_Mesh m_mesh; BRepBuilderAPI_CellFilter m_filter; BRepBuilderAPI_VertexInspector m_inspector; }; diff --git a/src/gmio_support/stl_occ_meshvs.cpp b/src/gmio_support/stl_occ_meshvs.cpp index 17020c7..08371f0 100644 --- a/src/gmio_support/stl_occ_meshvs.cpp +++ b/src/gmio_support/stl_occ_meshvs.cpp @@ -28,74 +28,57 @@ ****************************************************************************/ #include - #include "stl_occ_utils.h" #include #include #include - #include gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs() - : m_data_src(NULL), - m_element_coords(1, 1) + : m_element_coords(1, 1) { - this->init_C_members(); -} - -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(); + this->init(); } gmio_stl_mesh_occmeshvs::gmio_stl_mesh_occmeshvs(const Handle_MeshVS_DataSource &hnd) - : m_data_src(hnd.operator->()), + : m_data_src(hnd), m_element_coords(1, 9) { - this->init_C_members(); - this->init_cache(); + this->init(); } -void gmio_stl_mesh_occmeshvs::init_C_members() +void gmio_stl_mesh_occmeshvs::init() { + // C members 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(); + this->triangle_count = + !m_data_src.IsNull() ? m_data_src->GetAllElements().Extent() : 0; + // Cache + if (this->triangle_count != 0) { + 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 = + const gmio_stl_mesh_occmeshvs* mesh = static_cast(cookie); - const MeshVS_DataSource* data_src = it->data_src(); - const int element_key = it->m_vec_element_key.at(tri_id); - TColStd_Array1OfReal& element_coords = it->m_element_coords; + const int element_key = mesh->m_vec_element_key.at(tri_id); + TColStd_Array1OfReal& element_coords = mesh->m_element_coords; int node_count; MeshVS_EntityType entity_type; const Standard_Boolean get_geom_ok = - data_src->GetGeom( + mesh->m_data_src->GetGeom( element_key, Standard_True, // Is element element_coords, @@ -109,7 +92,7 @@ void gmio_stl_mesh_occmeshvs::get_triangle( out_coords_ptr[i] = static_cast(in_coords_array.Value(i + 1)); // Copy normal coords double nx, ny, nz; - data_src->GetNormal(element_key, 3, nx, ny, nz); + mesh->m_data_src->GetNormal(element_key, 3, nx, ny, nz); gmio_stl_occ_copy_xyz(&tri->n, nx, ny, nz); } } diff --git a/src/gmio_support/stl_occ_meshvs.h b/src/gmio_support/stl_occ_meshvs.h index 7f52908..b3e3ea9 100644 --- a/src/gmio_support/stl_occ_meshvs.h +++ b/src/gmio_support/stl_occ_meshvs.h @@ -28,7 +28,7 @@ ****************************************************************************/ /*! \file stl_occ_meshvs.h - * STL support of OpenCascade's MeshVS_DataSource + * STL support of OpenCascade's \c MeshVS_DataSource * * To use this header the source file * $INSTALL/src/gmio_support/stl_occ_meshvs.cpp\n @@ -52,12 +52,11 @@ #include "support_global.h" #include "../gmio_stl/stl_mesh.h" -#include - #include #include +#include -/*! Provides access to all the triangles of OpenCascade's \c MeshVS_DataSource +/*! Provides access to all the triangles of an OpenCascade \c MeshVS_DataSource * * gmio_stl_mesh_occmeshvs iterates efficiently over the elements of a * \c MeshVS_DataSource object.\n @@ -73,19 +72,17 @@ struct gmio_stl_mesh_occmeshvs : public gmio_stl_mesh { 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; } + const Handle_MeshVS_DataSource& data_src() const { return m_data_src; } private: static void get_triangle( const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); - void init_C_members(); - void init_cache(); + void init(); - const MeshVS_DataSource* m_data_src; + Handle_MeshVS_DataSource m_data_src; std::vector m_vec_element_key; mutable TColStd_Array1OfReal m_element_coords; }; diff --git a/src/gmio_support/stl_occ_polytri.cpp b/src/gmio_support/stl_occ_polytri.cpp new file mode 100644 index 0000000..dd6267e --- /dev/null +++ b/src/gmio_support/stl_occ_polytri.cpp @@ -0,0 +1,183 @@ +/**************************************************************************** +** Copyright (c) 2017, Fougue Ltd. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. Redistributions in binary form must reproduce the above +** copyright notice, this list of conditions and the following +** disclaimer in the documentation and/or other materials provided +** with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************/ + +#include +#include "stl_occ_utils.h" + +#include +#include +#include +#include + +// ----------------------------------------------------------------------------- +// gmio_stl_mesh_occpolytri +// ----------------------------------------------------------------------------- + +gmio_stl_mesh_occpolytri::gmio_stl_mesh_occpolytri() +{ + this->init(); +} + +gmio_stl_mesh_occpolytri::gmio_stl_mesh_occpolytri( + const Handle_Poly_Triangulation& hnd) + : m_polytri(hnd) +{ + this->init(); +} + +void gmio_stl_mesh_occpolytri::init() +{ + const bool polytri_not_null = !m_polytri.IsNull(); + // C members + this->cookie = this; + this->func_get_triangle = &gmio_stl_mesh_occpolytri::get_triangle; + this->triangle_count = polytri_not_null ? m_polytri->NbTriangles() : 0; + // Cache + m_polytri_vec_node = polytri_not_null ? &m_polytri->Nodes() : NULL; + m_polytri_vec_triangle = polytri_not_null ? &m_polytri->Triangles() : NULL; + m_polytri_has_normals = + polytri_not_null ? + (m_polytri->HasNormals() == Standard_True) : + false; + m_polytri_vec_normal = m_polytri_has_normals ? &m_polytri->Normals() : NULL; +} + +void gmio_stl_mesh_occpolytri::get_triangle( + const void *cookie, uint32_t tri_id, gmio_stl_triangle *tri) +{ + const gmio_stl_mesh_occpolytri* mesh = + static_cast(cookie); + const TColgp_Array1OfPnt& vec_node = *mesh->m_polytri_vec_node; + const Poly_Array1OfTriangle& vec_triangle = *mesh->m_polytri_vec_triangle; + int n1, n2, n3; // Node index + vec_triangle.Value(tri_id + vec_triangle.Lower()).Get(n1, n2, n3); + const gp_Pnt& p1 = vec_node.Value(n1); + const gp_Pnt& p2 = vec_node.Value(n2); + const gp_Pnt& p3 = vec_node.Value(n3); + gmio_stl_occ_copy_xyz(&tri->v1, p1.XYZ()); + gmio_stl_occ_copy_xyz(&tri->v2, p2.XYZ()); + gmio_stl_occ_copy_xyz(&tri->v3, p3.XYZ()); + if (mesh->m_polytri_has_normals) { + const TShort_Array1OfShortReal& vec_normal = *mesh->m_polytri_vec_normal; + // Take the normal at the first triangle node + const int id_start_coord = n1*3 + vec_normal.Lower(); + std::memcpy(&tri->n, + &vec_normal.Value(id_start_coord), + 3*sizeof(float)); + } + else { + gmio_stl_triangle_compute_normal(tri); + } +} + +// ----------------------------------------------------------------------------- +// gmio_stl_mesh_creator_occpolytri +// ----------------------------------------------------------------------------- + +gmio_stl_mesh_creator_occpolytri::gmio_stl_mesh_creator_occpolytri() + : m_filter(Precision::Confusion()), + m_inspector(Precision::Confusion()) +{ + this->cookie = this; + this->func_begin_solid = &gmio_stl_mesh_creator_occpolytri::begin_solid; + this->func_add_triangle = &gmio_stl_mesh_creator_occpolytri::add_triangle; + this->func_end_solid = &gmio_stl_mesh_creator_occpolytri::end_solid; +} + +void gmio_stl_mesh_creator_occpolytri::begin_solid( + void* cookie, const gmio_stl_mesh_creator_infos* infos) +{ + gmio_stl_mesh_creator_occpolytri* creator = + static_cast(cookie); + uint32_t tricount = 0; + if (infos->format == GMIO_STL_FORMAT_ASCII) + tricount = static_cast(infos->stla_stream_size / 200u); + else if (infos->format & GMIO_STL_FORMAT_TAG_BINARY) + tricount = infos->stlb_triangle_count; + if (tricount > 0) { + creator->m_vec_node.reserve(3 * tricount); + creator->m_vec_normal.reserve(3 * tricount); + creator->m_vec_triangle.reserve(tricount); + } +} + +void gmio_stl_mesh_creator_occpolytri::add_triangle( + void *cookie, uint32_t /*tri_id*/, const gmio_stl_triangle *tri) +{ + gmio_stl_mesh_creator_occpolytri* creator = + static_cast(cookie); + const gmio_vec3f& n = tri->n; + const int id_v1 = creator->add_unique_vertex(tri->v1, n); + const int id_v2 = creator->add_unique_vertex(tri->v2, n); + const int id_v3 = creator->add_unique_vertex(tri->v3, n); + creator->m_vec_triangle.emplace_back(id_v1, id_v2, id_v3); +} + +void gmio_stl_mesh_creator_occpolytri::end_solid(void *cookie) +{ + gmio_stl_mesh_creator_occpolytri* creator = + static_cast(cookie); + creator->m_polytri = + new Poly_Triangulation( + static_cast(creator->m_vec_node.size()), + static_cast(creator->m_vec_triangle.size()), + Standard_False); // False->No UVNodes + // Copy nodes + TColgp_Array1OfPnt* nodes = &creator->m_polytri->ChangeNodes(); + std::memcpy(&nodes->ChangeValue(nodes->Lower()), + creator->m_vec_node.data(), + creator->m_vec_node.size() * sizeof(gp_XYZ)); + // Copy normals + Handle_TShort_HArray1OfShortReal normals = + new TShort_HArray1OfShortReal( + 1, static_cast(3 * creator->m_vec_node.size())); + std::memcpy(&normals->ChangeValue(normals->Lower()), + creator->m_vec_normal.data(), + creator->m_vec_normal.size() * sizeof(gmio_vec3f)); + creator->m_polytri->SetNormals(normals); + // Copy triangles + Poly_Array1OfTriangle* triangles = &creator->m_polytri->ChangeTriangles(); + std::memcpy(&triangles->ChangeValue(triangles->Lower()), + creator->m_vec_triangle.data(), + creator->m_vec_triangle.size() * sizeof(Poly_Triangle)); +} + +int gmio_stl_mesh_creator_occpolytri::add_unique_vertex( + const gmio_vec3f& v, const gmio_vec3f& n) +{ + const gp_XYZ pnt(v.x, v.y, v.z); + int index = gmio_occ_find_vertex_index(pnt, &m_filter, &m_inspector); + if (index != -1) + return index; + m_vec_node.push_back(pnt); + m_vec_normal.push_back(n); + index = static_cast(m_vec_node.size()); // Note: lowerbound = 1 + gmio_occ_add_vertex_index(pnt, index, &m_filter, &m_inspector); + return index; +} diff --git a/src/gmio_support/stl_occ_polytri.h b/src/gmio_support/stl_occ_polytri.h new file mode 100644 index 0000000..f6aa6d1 --- /dev/null +++ b/src/gmio_support/stl_occ_polytri.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** Copyright (c) 2017, Fougue Ltd. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. Redistributions in binary form must reproduce the above +** copyright notice, this list of conditions and the following +** disclaimer in the documentation and/or other materials provided +** with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************/ + +/*! \file stl_occ_polytri.h + * STL support of OpenCascade's \c Poly_Triangulation + * + * To use this header the source file + * $INSTALL/src/gmio_support/stl_occ_polytri.cpp\n + * needs to be built in the target project(\c $INSTALL is the root directory + * where is installed gmio) + * + * Of course this requires the includepath and libpath to point to OpenCascade, + * the import libraries likely needed are:\n + * TKernel TKMath TKTopAlgo + * + * \addtogroup gmio_support + * @{ + */ + +#ifndef __cplusplus +# error C++ compiler required +#endif + +#pragma once + +#include "support_global.h" +#include "../gmio_stl/stl_mesh.h" +#include "../gmio_stl/stl_mesh_creator.h" + +#include +#include +#include +#include +#include + +/*! Provides access to the triangles of an OpenCascade \c Poly_Triangulation + * + * Example of use: + * \code{.cpp} + * const Handle_Poly_Triangulation occpolytri = ...; + * const gmio_stl_mesh_occpolytri mesh(occpolytri); + * gmio_stl_write_file(stl_format, filepath, &occmesh, &options); + * \endcode + */ +struct gmio_stl_mesh_occpolytri : public gmio_stl_mesh +{ + gmio_stl_mesh_occpolytri(); + explicit gmio_stl_mesh_occpolytri(const Handle_Poly_Triangulation& hnd); + + const Handle_Poly_Triangulation& polytri() const { return m_polytri; } + +private: + static void get_triangle( + const void* cookie, uint32_t tri_id, gmio_stl_triangle* tri); + void init(); + + Handle_Poly_Triangulation m_polytri; + const TColgp_Array1OfPnt* m_polytri_vec_node; + const Poly_Array1OfTriangle* m_polytri_vec_triangle; + bool m_polytri_has_normals; + const TShort_Array1OfShortReal* m_polytri_vec_normal; +}; + +/*! Provides creation of an OpenCascade \c Poly_Triangulation + * + * Example of use: + * \code{.cpp} + * gmio_stl_mesh_creator_occpolytri meshcreator; + * gmio_stl_read_file(filepath, &meshcreator, &options); + * Handle_Poly_Triangulation occpolytri = meshcreator.polytri(); + * \endcode + */ +struct gmio_stl_mesh_creator_occpolytri : public gmio_stl_mesh_creator +{ +public: + gmio_stl_mesh_creator_occpolytri(); + const Handle_Poly_Triangulation& polytri() const { return m_polytri; } + +private: + static void begin_solid( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos); + static void add_triangle( + void* cookie, uint32_t tri_id, const gmio_stl_triangle* tri); + static void end_solid(void* cookie); + + int add_unique_vertex(const gmio_vec3f& v, const gmio_vec3f& n); + + Handle_Poly_Triangulation m_polytri; + BRepBuilderAPI_CellFilter m_filter; + BRepBuilderAPI_VertexInspector m_inspector; + std::vector m_vec_node; + std::vector m_vec_normal; + std::vector m_vec_triangle; +}; + +/*! @} */ diff --git a/src/gmio_support/stl_occ_utils.h b/src/gmio_support/stl_occ_utils.h index 0f1c932..3b20f23 100644 --- a/src/gmio_support/stl_occ_utils.h +++ b/src/gmio_support/stl_occ_utils.h @@ -38,20 +38,77 @@ #include #include + #include +#include +#include +#include GMIO_INLINE void gmio_stl_occ_copy_xyz( - gmio_vec3f* vec, double x, double y, double z) + gmio_vec3f* vec, double x, double y, double z); + +GMIO_INLINE void gmio_stl_occ_copy_xyz( + gmio_vec3f* vec, const gp_XYZ& coords); + +GMIO_INLINE int gmio_occ_find_vertex_index( + const gp_XYZ& coords, + BRepBuilderAPI_CellFilter* filter, + BRepBuilderAPI_VertexInspector* inspector); + +GMIO_INLINE void gmio_occ_add_vertex_index( + const gp_XYZ& coords, + int index, + BRepBuilderAPI_CellFilter* filter, + BRepBuilderAPI_VertexInspector* inspector); + + + +/* + * Implementation + */ + +void gmio_stl_occ_copy_xyz(gmio_vec3f* vec, double x, double y, double z) { vec->x = static_cast(x); vec->y = static_cast(y); vec->z = static_cast(z); } -GMIO_INLINE void gmio_stl_occ_copy_xyz( - gmio_vec3f* vec, const gp_XYZ& coords) +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()); } +int gmio_occ_find_vertex_index( + const gp_XYZ& coords, + BRepBuilderAPI_CellFilter* filter, + BRepBuilderAPI_VertexInspector* inspector) +{ + //-------------------------------------------------------------------------- + // Code excerpted from OpenCascade v7.0.0 + // File: RWStl/RWStl.cxx + // Function: "static int AddVertex(...)" lines 38..61 + //-------------------------------------------------------------------------- + inspector->SetCurrent(coords); + const gp_XYZ min_pnt = inspector->Shift(coords, -Precision::Confusion()); + const gp_XYZ max_pnt = inspector->Shift(coords, +Precision::Confusion()); + filter->Inspect(min_pnt, max_pnt, *inspector); + if (!inspector->ResInd().IsEmpty()) { + const int index = inspector->ResInd().First(); // There should be only one + inspector->ClearResList(); + return index; + } + return -1; +} + +void gmio_occ_add_vertex_index( + const gp_XYZ& coords, + int index, + BRepBuilderAPI_CellFilter* filter, + BRepBuilderAPI_VertexInspector* inspector) +{ + filter->Add(index, coords); + inspector->Add(coords); +} + /*! @} */ diff --git a/src/gmio_support/support_global.h b/src/gmio_support/support_global.h index 03177c7..18a3e80 100644 --- a/src/gmio_support/support_global.h +++ b/src/gmio_support/support_global.h @@ -53,12 +53,21 @@ * * * TopoDS_Shape - * no + * yes1 * yes * stl_occ_brep.h * + * + * Poly_Triangulation + * yes + * yes + * stl_occ_polytri.h + * * * + * 1 The resulting \c TopoDS_Shape object has no geometrical surface + * but only a \c Poly_Triangulation structure containing all the triangles. + * * \n * * @@ -96,12 +105,13 @@ /* * OpenCascade support : - * | | STL | - * | | import | export | - * |-------------------|--------|--------| - * | StlMesh_Mesh | yes | yes | - * | MeshVS_DataSource | no | yes | - * | TopoDS_Shape | no | yes | + * | | STL | + * | | import | export | + * |--------------------|--------|--------| + * | StlMesh_Mesh | yes | yes | + * | MeshVS_DataSource | no | yes | + * | TopoDS_Shape | yes | yes | + * | Poly_Triangulation | yes | yes | * * I/O stream support : * | | read | write | diff --git a/tests/fake_support/CMakeLists.txt b/tests/fake_support/CMakeLists.txt index 198d550..6dd8b2e 100644 --- a/tests/fake_support/CMakeLists.txt +++ b/tests/fake_support/CMakeLists.txt @@ -39,9 +39,10 @@ add_executable( qt/QtCore/QIODevice qt/QtCore/QString qt/QtCore/QtGlobal + ../../src/gmio_support/stl_occ_brep.cpp ../../src/gmio_support/stl_occ_mesh.cpp ../../src/gmio_support/stl_occ_meshvs.cpp - ../../src/gmio_support/stl_occ_brep.cpp + ../../src/gmio_support/stl_occ_polytri.cpp ../../src/gmio_support/stream_qt.cpp) target_link_libraries(fake_support gmio_static) include_directories( diff --git a/tests/fake_support/opencascade/BRepBuilderAPI_CellFilter.hxx b/tests/fake_support/opencascade/BRepBuilderAPI_CellFilter.hxx index a112635..a90520d 100644 --- a/tests/fake_support/opencascade/BRepBuilderAPI_CellFilter.hxx +++ b/tests/fake_support/opencascade/BRepBuilderAPI_CellFilter.hxx @@ -2,7 +2,7 @@ #define _BRepBuilderAPI_CellFilter_HeaderFile class BRepBuilderAPI_VertexInspector; -class gp_Pnt; +class gp_XYZ; class BRepBuilderAPI_CellFilter { @@ -10,12 +10,12 @@ public: BRepBuilderAPI_CellFilter(double /*cellSize*/) {} void Inspect( - const gp_Pnt& /*min_pnt*/, - const gp_Pnt& /*max_pnt*/, + const gp_XYZ& /*min_pnt*/, + const gp_XYZ& /*max_pnt*/, BRepBuilderAPI_VertexInspector& /*inspector*/) {} - void Add(int /*target*/, const gp_Pnt& /*pnt*/) {} + void Add(int /*target*/, const gp_XYZ& /*pnt*/) {} }; #endif diff --git a/tests/fake_support/opencascade/BRep_TFace.hxx b/tests/fake_support/opencascade/BRep_TFace.hxx new file mode 100644 index 0000000..fb6caad --- /dev/null +++ b/tests/fake_support/opencascade/BRep_TFace.hxx @@ -0,0 +1,25 @@ +#ifndef _BRep_TFace_HeaderFile +#define _BRep_TFace_HeaderFile + +#include +#include + +class BRep_TFace : public TopoDS_TShape +{ +public: + BRep_TFace() {} + + const Handle_Poly_Triangulation& Triangulation() const + { return myTriangulation; } + + void Triangulation (const Handle_Poly_Triangulation& other) + { myTriangulation = other; } + +private: + Handle_Poly_Triangulation myTriangulation; +}; + +#include +typedef opencascade::handle Handle_BRep_TFace; + +#endif // _BRep_TFace_HeaderFile diff --git a/tests/fake_support/opencascade/MeshVS_DataSource.hxx b/tests/fake_support/opencascade/MeshVS_DataSource.hxx index a5ee445..ef762a6 100644 --- a/tests/fake_support/opencascade/MeshVS_DataSource.hxx +++ b/tests/fake_support/opencascade/MeshVS_DataSource.hxx @@ -40,7 +40,7 @@ public: { return 0; } }; -#include "generic_handle.h" -typedef FakeOcc::GenericHandle Handle_MeshVS_DataSource; +#include +typedef opencascade::handle Handle_MeshVS_DataSource; #endif // _MeshVS_DataSource_HeaderFile diff --git a/tests/fake_support/opencascade/NCollection_DefineArray1.hxx b/tests/fake_support/opencascade/NCollection_DefineArray1.hxx new file mode 100644 index 0000000..2b2ef62 --- /dev/null +++ b/tests/fake_support/opencascade/NCollection_DefineArray1.hxx @@ -0,0 +1,47 @@ +// Created on: 2002-04-15 +// Created by: Alexander Kartomin (akm) +// Copyright (c) 2002-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// Automatically created from NCollection_Array1.hxx by GAWK +// Purpose: The class Array2 represents unidimensional arrays +// of fixed size known at run time. +// The range of the index is user defined. +// An array1 can be constructed with a "C array". +// This functionality is useful to call methods expecting +// an Array1. It allows to carry the bounds inside the arrays. +// Examples: Item tab[100]; // An example with a C array +// Array1OfItem ttab (tab[0],1,100); +// Array1OfItem tttab (ttab(10),10,20); // a slice of ttab +// If you want to reindex an array from 1 to Length do : +// Array1 tab1(tab(tab.Lower()),1,tab.Length()); +// Warning: Programs client of such a class must be independant +// of the range of the first element. Then, a C++ for +// loop must be written like this +// for (i = A.Lower(); i <= A.Upper(); i++) +// Changes: In comparison to TCollection the flag isAllocated was +// renamed into myDeletable (alike in the Array2). For naming +// compatibility the method IsAllocated remained in class along +// with IsDeletable. + +#ifndef NCollection_DefineArray1_HeaderFile +#define NCollection_DefineArray1_HeaderFile + +#include + +// *********************************************** Template for Array1 class + +#define DEFINE_ARRAY1(_ClassName_, _BaseCollection_, TheItemType) \ +typedef NCollection_Array1 _ClassName_; + +#endif diff --git a/tests/fake_support/opencascade/NCollection_DefineHArray1.hxx b/tests/fake_support/opencascade/NCollection_DefineHArray1.hxx new file mode 100644 index 0000000..cc83dd5 --- /dev/null +++ b/tests/fake_support/opencascade/NCollection_DefineHArray1.hxx @@ -0,0 +1,38 @@ +// Created on: 2002-04-29 +// Created by: Alexander KARTOMIN (akm) +// Copyright (c) 2002-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// Automatically created from NCollection_HArray1.hxx by GAWK + +#ifndef NCollection_DefineHArray1_HeaderFile +#define NCollection_DefineHArray1_HeaderFile + +#include + +// Declaration of Array1 class managed by Handle + +#define DEFINE_HARRAY1(HClassName, _Array1Type_) \ +class HClassName : public _Array1Type_ { \ + public: \ + HClassName (int theLower, int theUpper) : \ + _Array1Type_ (theLower,theUpper) {} \ + HClassName (int theLower, int theUpper, \ + const _Array1Type_::value_type& theValue) : \ + _Array1Type_ (theLower,theUpper) { Init (theValue); } \ + HClassName (const _Array1Type_& theOther) : _Array1Type_(theOther) {} \ + const _Array1Type_& Array1 () const { return *this; } \ + _Array1Type_& ChangeArray1 () { return *this; } \ +}; \ + +#endif diff --git a/tests/fake_support/opencascade/Poly_Triangle.hxx b/tests/fake_support/opencascade/Poly_Triangle.hxx index 3b977f3..646cc63 100644 --- a/tests/fake_support/opencascade/Poly_Triangle.hxx +++ b/tests/fake_support/opencascade/Poly_Triangle.hxx @@ -7,7 +7,11 @@ class Poly_Triangle { public: Poly_Triangle() {} - void Get(Standard_Integer&, Standard_Integer&, Standard_Integer&) const {} + Poly_Triangle(int, int, int) {} + void Get(int&, int&, int&) const {} + void Set(int, int, int) {} +private: + int myNodes[3]; }; #endif // _Poly_Triangle_HeaderFile diff --git a/tests/fake_support/opencascade/Poly_Triangulation.hxx b/tests/fake_support/opencascade/Poly_Triangulation.hxx index 970aeb2..93e9b07 100644 --- a/tests/fake_support/opencascade/Poly_Triangulation.hxx +++ b/tests/fake_support/opencascade/Poly_Triangulation.hxx @@ -2,22 +2,36 @@ #define _Poly_Triangulation_HeaderFile #include -#include #include +#include +#include class Poly_Triangulation { public: - const TColgp_Array1OfPnt& Nodes() const { return myNodes; } - const Poly_Array1OfTriangle& Triangles() const { return myTriangles; } - Standard_Integer NbTriangles() const { return 0; } + Poly_Triangulation(int nbNodes, int nbTriangles, Standard_Boolean /*UVNodes*/) + : myNodes(1, nbNodes), + myTriangles(1, nbTriangles) + {} + + const TColgp_Array1OfPnt& Nodes() const { return myNodes; } + TColgp_Array1OfPnt& ChangeNodes() { return myNodes; } + const Poly_Array1OfTriangle& Triangles() const { return myTriangles; } + Poly_Array1OfTriangle& ChangeTriangles() { return myTriangles; } + Standard_Integer NbTriangles() const { return 0; } + + void SetNormals(const Handle_TShort_HArray1OfShortReal&) {} + const TShort_Array1OfShortReal& Normals() const { return myNormals->Array1(); } + TShort_Array1OfShortReal& ChangeNormals() { return myNormals->ChangeArray1(); } + Standard_Boolean HasNormals() const { return !myNormals.IsNull(); } private: - TColgp_Array1OfPnt myNodes; - Poly_Array1OfTriangle myTriangles; + TColgp_Array1OfPnt myNodes; + Poly_Array1OfTriangle myTriangles; + Handle_TShort_HArray1OfShortReal myNormals; }; -#include "generic_handle.h" -typedef FakeOcc::GenericHandle Handle_Poly_Triangulation; +#include +typedef opencascade::handle Handle_Poly_Triangulation; #endif // _Poly_Triangulation_HeaderFile diff --git a/tests/fake_support/opencascade/Standard_Handle.hxx b/tests/fake_support/opencascade/Standard_Handle.hxx new file mode 100644 index 0000000..daf87dc --- /dev/null +++ b/tests/fake_support/opencascade/Standard_Handle.hxx @@ -0,0 +1,245 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#pragma once + +#include + +class Standard_Transient; + +namespace opencascade { + +//! Trait yielding true if class T1 is base of T2 but not the same +template +struct is_base_but_not_same : std::is_base_of {}; + +//! Explicit specialization of is_base_of trait to workaround the +//! requirement of type to be complete when T1 and T2 are the same. +template +struct is_base_but_not_same ::value>::type> : std::false_type {}; + +template +class handle +{ +public: + typedef T element_type; + +public: + handle() {} + handle(const T*) {} + handle(const handle&) {} + handle(handle&&) {} + ~handle() {} + + void Nullify() {} + bool IsNull() const { return true; } + void reset(T*) {} + + handle& operator=(const handle&) { return *this; } + handle& operator=(const T*) { return *this; } + handle& operator= (handle&&) { return *this; } + + const T* get() const { return 0; } + T* get() { return 0; } + T* operator->() const { return 0; } + T& operator* () { return *get(); } + const T& operator*() const { return *get(); } + + template bool operator==(const handle&) const { return false; } + template bool operator==(const T2*) const { return false; } + template friend bool operator==(const T2*, const handle&) { return false; } + template bool operator!=(const handle&) const { return false; } + template bool operator!=(const T2*) const { return false; } + template friend bool operator!=(const T2*, const handle&) { return false; } + template bool operator<(const handle&) const { return false; } + + template + static typename std::enable_if::value, handle>::type + DownCast (const handle& theObject) + { return handle (dynamic_cast(const_cast(theObject.get()))); } + + template + static typename std::enable_if::value, handle>::type + DownCast (const T2* thePtr) + { return handle (dynamic_cast(const_cast(thePtr))); } + + //! For compatibility, define down casting operator from non-base type, as deprecated + template + static handle DownCast (const handle& theObject, typename std::enable_if::value, void*>::type = 0) + { return handle (dynamic_cast(const_cast(theObject.get()))); } + + //! For compatibility, define down casting operator from non-base type, as deprecated + template + static handle DownCast (const T2* thePtr, typename std::enable_if::value, void*>::type = 0) + { return handle (dynamic_cast(const_cast(thePtr))); } + +#if (defined(__clang__)) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300) || \ + (defined(_MSC_VER) && _MSC_VER >= 1800) || \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) + + //! Conversion to bool for use in conditional expressions + explicit operator bool () const { return entity != nullptr; } + +#else /* fallback version for compilers not supporting explicit conversion operators (VC10, VC11, GCC below 4.5) */ + + //! Conversion to bool-compatible type for use in conditional expressions + operator Standard_Transient* handle::* () const + { + return entity ? &handle::entity : 0; + } + +#endif + + // Support of conversions to handle of base type: + // - copy and move constructors and assignment operators if OCCT_HANDLE_NOCAST is defined + // - operators of upcast to const reference to base type otherwise +#if (defined(__clang__)) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1206) || \ + (defined(_MSC_VER) && _MSC_VER >= 1800) || \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) + +#ifdef OCCT_HANDLE_NOCAST + + //! Generalized copy constructor. + //! Constructs handle holding entity of base type (T) from the one which holds entity of derived type (T2). + template ::value>::type> + handle (const handle& theHandle) : + entity(theHandle.entity) + { + BeginScope(); + } + + //! Generalized move constructor + template ::value>::type> + handle (handle&& theHandle) + : entity(theHandle.entity) + { + theHandle.entity = 0; + } + + //! Generalized assignment operator + template ::value>::type> + handle operator = (const handle& theHandle) + { + Assign (theHandle.entity); + return *this; + } + + //! Generalized move operator + template ::value>::type> + handle& operator= (handle&& theHandle) + { + std::swap (this->entity, theHandle.entity); + return *this; + } + +#else + + //! Upcast to const reference to base type. + template ::value>::type> + operator const handle& () const + { + return reinterpret_cast&>(*this); + } + + //! Upcast to non-const reference to base type. + //! NB: this cast can be dangerous, but required for legacy code; see #26377 + template ::value>::type> + operator handle& () + { + return reinterpret_cast&>(*this); + } + +#endif /* OCCT_HANDLE_NOCAST */ + +#else /* fallback version for compilers not supporting default arguments of function templates (VC10, VC11, GCC below 4.3) */ + +#ifdef OCCT_HANDLE_NOCAST + + //! Generalized copy constructor. + //! Constructs handle holding entity of base type (T) from the one which holds entity of derived type (T2). + template + handle (const handle& theHandle, typename std::enable_if ::value>::type* = nullptr) : + entity(theHandle.entity) + { + BeginScope(); + } + + //! Generalized move constructor + template + handle (handle&& theHandle, typename std::enable_if ::value>::type* = nullptr) + : entity(theHandle.entity) + { + theHandle.entity = 0; + } + + //! Generalized assignment operator. + template + handle operator = (const handle& theHandle) + { + std::enable_if ::value, void*>::type aTypeCheckHelperVar; + (void)aTypeCheckHelperVar; + Assign (theHandle.entity); + return *this; + } + + //! Generalized move operator + template + handle& operator= (handle&& theHandle) + { + std::enable_if ::value, void*>::type aTypeCheckHelperVar; + (void)aTypeCheckHelperVar; + std::swap (this->entity, theHandle.entity); + return *this; + } + +#else + + //! Upcast to const reference to base type. + //! NB: this implementation will cause ambiguity errors on calls to overloaded + //! functions accepting handles to different types, since compatibility is + //! checked in the cast code rather than ensured by SFINAE (possible with C++11) + template + operator const handle& () const + { + // error "type is not a member of enable_if" will be generated if T2 is not sub-type of T + // (handle is being cast to const& to handle of non-base type) + return reinterpret_cast::value, const handle&>::type>(*this); + } + + //! Upcast to non-const reference to base type. + //! NB: this cast can be dangerous, but required for legacy code; see #26377 + template + Standard_DEPRECATED("Passing non-const reference to handle of base type in function is unsafe; use variable of exact type") + operator handle& () + { + // error "type is not a member of enable_if" will be generated if T2 is not sub-type of T + // (handle is being cast to const& to handle of non-base type) + return reinterpret_cast::value, handle&>::type>(*this); + } + +#endif /* OCCT_HANDLE_NOCAST */ + +#endif /* compiler switch */ + +private: + void Assign (Standard_Transient*) {} + void BeginScope() {} + void EndScope() {} + + template friend class handle; + +private: + Standard_Transient* entity; +}; + +} // namespace opencascade diff --git a/tests/fake_support/opencascade/Standard_Transient.hxx b/tests/fake_support/opencascade/Standard_Transient.hxx new file mode 100644 index 0000000..34bc0cd --- /dev/null +++ b/tests/fake_support/opencascade/Standard_Transient.hxx @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +class Standard_Type; + +class Standard_Transient +{ +public: + Standard_Transient() : count(0) {} + Standard_Transient (const Standard_Transient&) : count(0) {} + Standard_Transient& operator= (const Standard_Transient&) { return *this; } + virtual ~Standard_Transient() {} + virtual void Delete() const {} + + typedef void base_type; + + static const char* get_type_name () { return "Standard_Transient"; } + + static const opencascade::handle& get_type_descriptor() + { static opencascade::handle d; return d; } + + virtual const opencascade::handle& DynamicType() const + { static opencascade::handle dt; return dt; } + + Standard_Boolean IsInstance(const opencascade::handle&) const + { return Standard_False; } + + Standard_Boolean IsInstance(const Standard_CString) const + { return Standard_False; } + + Standard_Boolean IsKind(const opencascade::handle&) const + { return Standard_False; } + + Standard_Boolean IsKind(const Standard_CString) const + { return Standard_False; } + + Standard_Transient* This() const + { return const_cast (this); } + + Standard_Integer GetRefCount() const { return count; } + void IncrementRefCounter() const { ++count; } + Standard_Integer DecrementRefCounter() const { return --count; } + +private: + mutable volatile Standard_Integer count; +}; + +//! Definition of Handle_Standard_Transient as typedef for compatibility +typedef opencascade::handle Handle_Standard_Transient; diff --git a/tests/fake_support/opencascade/Standard_Type.hxx b/tests/fake_support/opencascade/Standard_Type.hxx new file mode 100644 index 0000000..ef34616 --- /dev/null +++ b/tests/fake_support/opencascade/Standard_Type.hxx @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +class Standard_Type : public Standard_Transient +{ +public: + Standard_CString SystemName() const { return mySystemName; } + Standard_CString Name() const { return myName; } + std::size_t Size() const { return mySize; } + +private: + Standard_CString mySystemName; + Standard_CString myName; + std::size_t mySize; +}; + diff --git a/tests/fake_support/opencascade/StlMesh_Mesh.hxx b/tests/fake_support/opencascade/StlMesh_Mesh.hxx index a78b9d8..0c22680 100644 --- a/tests/fake_support/opencascade/StlMesh_Mesh.hxx +++ b/tests/fake_support/opencascade/StlMesh_Mesh.hxx @@ -44,7 +44,7 @@ public: } }; -#include "generic_handle.h" -typedef FakeOcc::GenericHandle Handle_StlMesh_Mesh; +#include +typedef opencascade::handle Handle_StlMesh_Mesh; #endif // _StlMesh_Mesh_HeaderFile diff --git a/tests/fake_support/opencascade/StlMesh_MeshTriangle.hxx b/tests/fake_support/opencascade/StlMesh_MeshTriangle.hxx index 756e405..7e70f85 100644 --- a/tests/fake_support/opencascade/StlMesh_MeshTriangle.hxx +++ b/tests/fake_support/opencascade/StlMesh_MeshTriangle.hxx @@ -10,7 +10,7 @@ public: { } }; -#include "generic_handle.h" -typedef FakeOcc::GenericHandle Handle_StlMesh_MeshTriangle; +#include +typedef opencascade::handle Handle_StlMesh_MeshTriangle; #endif // _StlMesh_MeshTriangle_HeaderFile diff --git a/tests/fake_support/opencascade/TShort_Array1OfShortReal.hxx b/tests/fake_support/opencascade/TShort_Array1OfShortReal.hxx new file mode 100644 index 0000000..b04f3ca --- /dev/null +++ b/tests/fake_support/opencascade/TShort_Array1OfShortReal.hxx @@ -0,0 +1,23 @@ +// Copyright (c) 1998-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef TShort_Array1OfShortReal_HeaderFile +#define TShort_Array1OfShortReal_HeaderFile + +#include +#include + +typedef NCollection_Array1 TShort_Array1OfShortReal; + +#endif diff --git a/tests/fake_support/opencascade/TShort_HArray1OfShortReal.hxx b/tests/fake_support/opencascade/TShort_HArray1OfShortReal.hxx new file mode 100644 index 0000000..267560b --- /dev/null +++ b/tests/fake_support/opencascade/TShort_HArray1OfShortReal.hxx @@ -0,0 +1,26 @@ +// Copyright (c) 1998-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef TShort_HArray1OfShortReal_HeaderFile +#define TShort_HArray1OfShortReal_HeaderFile + +#include +#include + +DEFINE_HARRAY1(TShort_HArray1OfShortReal, TShort_Array1OfShortReal) + +#include +typedef opencascade::handle Handle_TShort_HArray1OfShortReal; + +#endif diff --git a/tests/fake_support/opencascade/TopoDS_Shape.hxx b/tests/fake_support/opencascade/TopoDS_Shape.hxx index b17082c..be99781 100644 --- a/tests/fake_support/opencascade/TopoDS_Shape.hxx +++ b/tests/fake_support/opencascade/TopoDS_Shape.hxx @@ -2,6 +2,7 @@ #define _TopoDS_Shape_HeaderFile #include +#include enum TopAbs_Orientation { @@ -31,7 +32,11 @@ public: Standard_Boolean IsNull() const { return Standard_True; } TopAbs_Orientation Orientation() const { return myOrient; } + const Handle_TopoDS_TShape& TShape() const { return myTShape; } + void TShape(const Handle_TopoDS_TShape& other) { myTShape = other; } + private: + Handle_TopoDS_TShape myTShape; TopAbs_Orientation myOrient; }; diff --git a/tests/fake_support/opencascade/TopoDS_TShape.hxx b/tests/fake_support/opencascade/TopoDS_TShape.hxx new file mode 100644 index 0000000..6e2f4d6 --- /dev/null +++ b/tests/fake_support/opencascade/TopoDS_TShape.hxx @@ -0,0 +1,10 @@ +#ifndef _TopoDS_TShape_HeaderFile +#define _TopoDS_TShape_HeaderFile + +class TopoDS_TShape +{ }; + +#include +typedef opencascade::handle Handle_TopoDS_TShape; + +#endif // _TopoDS_TShape_HeaderFile
I/O stream support