diff --git a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp index 5ae461075e0..d41efbaed97 100644 --- a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp +++ b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp @@ -492,6 +492,7 @@ MeshTopology::MeshTopology() , d_seqTetrahedra(initData(&d_seqTetrahedra, "tetrahedra", "List of tetrahedron indices")) , d_seqHexahedra(initData(&d_seqHexahedra, "hexahedra", "List of hexahedron indices")) , d_seqUVs(initData(&d_seqUVs, "uv", "List of uv coordinates")) + , d_computeAllBuffers(initData(&d_computeAllBuffers, false, "computeAllBuffers", "Option to compute all crossed topology buffers at init. False by default")) , nbPoints(0) , validTetrahedra(false), validHexahedra(false) , revision(0) @@ -524,7 +525,6 @@ MeshTopology::MeshTopology() void MeshTopology::init() { - BaseMeshTopology::init(); const auto hexahedra = sofa::helper::getReadAccessor(d_seqHexahedra); @@ -533,7 +533,6 @@ void MeshTopology::init() const auto triangles = sofa::helper::getReadAccessor(d_seqTriangles); const auto edges = sofa::helper::getReadAccessor(d_seqEdges); - // looking for upper topology if (!hexahedra.empty()) m_upperElementType = geometry::ElementType::HEXAHEDRON; @@ -548,6 +547,11 @@ void MeshTopology::init() else m_upperElementType = sofa::geometry::ElementType::POINT; + // If true, will compute all crossed element buffers such as triangleAroundEdges, EdgesIntriangle, etc. + if (d_computeAllBuffers.getValue()) + { + computeCrossElementBuffers(); + } // compute the number of points, if the topology is charged from the scene or if it was loaded from a MeshLoader without any points data. if (nbPoints==0) @@ -576,6 +580,7 @@ void MeshTopology::init() nbPoints = n; } + if(edges.empty() ) { if(d_seqEdges.getParent() != nullptr ) @@ -608,6 +613,72 @@ void MeshTopology::init() } } +void MeshTopology::computeCrossElementBuffers() +{ + const auto hexahedra = sofa::helper::getReadAccessor(d_seqHexahedra); + const auto tetrahedra = sofa::helper::getReadAccessor(d_seqTetrahedra); + const auto quads = sofa::helper::getReadAccessor(d_seqQuads); + const auto triangles = sofa::helper::getReadAccessor(d_seqTriangles); + const auto edges = sofa::helper::getReadAccessor(d_seqEdges); + + if (!hexahedra.empty()) // Create hexahedron cross element buffers. + { + createHexahedraAroundVertexArray(); + + if (!quads.empty()) + { + createQuadsInHexahedronArray(); + createHexahedraAroundQuadArray(); + } + + if (!edges.empty()) + { + createEdgesInHexahedronArray(); + createHexahedraAroundEdgeArray(); + } + } + if (!tetrahedra.empty()) // Create tetrahedron cross element buffers. + { + createTetrahedraAroundVertexArray(); + + if (!triangles.empty()) + { + createTrianglesInTetrahedronArray(); + createTetrahedraAroundTriangleArray(); + } + + if (!edges.empty()) + { + createEdgesInTetrahedronArray(); + createTetrahedraAroundEdgeArray(); + } + } + if (!quads.empty()) // Create triangle cross element buffers. + { + createQuadsAroundVertexArray(); + + if (!edges.empty()) + { + createEdgesInQuadArray(); + createQuadsAroundEdgeArray(); + } + } + if (!triangles.empty()) // Create triangle cross element buffers. + { + createTrianglesAroundVertexArray(); + + if (!edges.empty()) + { + createEdgesInTriangleArray(); + createTrianglesAroundEdgeArray(); + } + } + if (!edges.empty()) + { + createEdgesAroundVertexArray(); + } +} + void MeshTopology::clear() { nbPoints = 0; diff --git a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h index d4b0d37e717..4d79f8cff17 100644 --- a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h +++ b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h @@ -86,6 +86,9 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public core: public: void init() override; + /// Method called by component Init method. Will create all the topology buffers + void computeCrossElementBuffers() override; + Size getNbPoints() const override; void setNbPoints(Size n) override; @@ -348,6 +351,7 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public core: Data d_seqTetrahedra; ///< List of tetrahedron indices Data d_seqHexahedra; ///< List of hexahedron indices Data d_seqUVs; ///< List of uv coordinates + Data d_computeAllBuffers; ///< Option to call method computeCrossElementBuffers. False by default protected: Size nbPoints; diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp index 15ddadbc529..4e212ff7696 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp @@ -77,10 +77,10 @@ void EdgeSetTopologyContainer::init() // only init if edges are present at init. if (!m_edge.empty()) - initTopology(); + computeCrossElementBuffers(); } -void EdgeSetTopologyContainer::initTopology() +void EdgeSetTopologyContainer::computeCrossElementBuffers() { // force computation of neighborhood elements createEdgesAroundVertexArray(); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.h index 2cf809bbe3a..ee9d4404c18 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.h @@ -100,7 +100,7 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API EdgeSetTopologyContainer : p /// Dynamic Topology API /// @{ /// Method called by component Init method. Will create all the topology neighborhood buffers. - void initTopology(); + void computeCrossElementBuffers() override; /** \brief Checks if the topology is coherent * diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.cpp index b8fb2b1c268..554a87f9352 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.cpp @@ -83,12 +83,12 @@ void HexahedronSetTopologyContainer::init() } if (!m_hexahedron.empty()) - initTopology(); + computeCrossElementBuffers(); } -void HexahedronSetTopologyContainer::initTopology() +void HexahedronSetTopologyContainer::computeCrossElementBuffers() { - QuadSetTopologyContainer::initTopology(); + QuadSetTopologyContainer::computeCrossElementBuffers(); // Create tetrahedron cross element buffers. createQuadsInHexahedronArray(); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.h index 65238e957a2..9bb8f012910 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetTopologyContainer.h @@ -222,8 +222,8 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API HexahedronSetTopologyContain /// Dynamic Topology API /// @{ - /// Method called by component Init method. Will create all the topology neighborhood buffers and call @see TriangleSetTopologyContainer::initTopology() - void initTopology(); + /// Method called by component Init method. Will create all the topology neighboorhood buffers and call @see QuadSetTopologyContainer::computeCrossElementBuffers() + void computeCrossElementBuffers() override; /** \brief Checks if the topology is coherent * diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.cpp index b9434772f7f..d861dfc5ea2 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.cpp @@ -72,13 +72,13 @@ void QuadSetTopologyContainer::init() // only init if triangles are present at init. if (!m_quads.empty()) - initTopology(); + computeCrossElementBuffers(); } -void QuadSetTopologyContainer::initTopology() +void QuadSetTopologyContainer::computeCrossElementBuffers() { // Force creation of Edge Neighborhood buffers. - EdgeSetTopologyContainer::initTopology(); + EdgeSetTopologyContainer::computeCrossElementBuffers(); // Create triangle cross element buffers. createEdgesInQuadArray(); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.h index 54a78981e3a..58efedcc105 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetTopologyContainer.h @@ -144,8 +144,8 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API QuadSetTopologyContainer : p /// Dynamic Topology API /// @{ - /// Method called by component Init method. Will create all the topology neighborhood buffers and call @see EdgeSetTopologyContainer::initTopology() - void initTopology(); + /// Method called by component Init method. Will create all the topology neighboorhood buffers and call @see EdgeSetTopologyContainer::computeCrossElementBuffers() + void computeCrossElementBuffers() override; /** \brief Checks if the topology is coherent * diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.cpp index d8fbe58adcd..5ad91e53519 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.cpp @@ -79,12 +79,12 @@ void TetrahedronSetTopologyContainer::init() } if (!m_tetrahedron.empty()) - initTopology(); + computeCrossElementBuffers(); } -void TetrahedronSetTopologyContainer::initTopology() +void TetrahedronSetTopologyContainer::computeCrossElementBuffers() { - TriangleSetTopologyContainer::initTopology(); + TriangleSetTopologyContainer::computeCrossElementBuffers(); // Create tetrahedron cross element buffers. createTrianglesInTetrahedronArray(); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.h index 089d3e6f7f2..2376324fbb2 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.h @@ -193,8 +193,8 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API TetrahedronSetTopologyContai /// Dynamic Topology API /// @{ - /// Method called by component Init method. Will create all the topology neighborhood buffers and call @see TriangleSetTopologyContainer::initTopology() - void initTopology(); + /// Method called by component Init method. Will create all the topology neighboorhood buffers and call @see TriangleSetTopologyContainer::computeCrossElementBuffers() + void computeCrossElementBuffers() override; /** \brief Checks if the topology is coherent * diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp index cfc69119e8c..577727a1c01 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp @@ -73,13 +73,13 @@ void TriangleSetTopologyContainer::init() // only init if triangles are present at init. if (!m_triangle.empty()) - initTopology(); + computeCrossElementBuffers(); } -void TriangleSetTopologyContainer::initTopology() +void TriangleSetTopologyContainer::computeCrossElementBuffers() { // Force creation of Edge Neighborhood buffers. - EdgeSetTopologyContainer::initTopology(); + EdgeSetTopologyContainer::computeCrossElementBuffers(); // Create triangle cross element buffers. createEdgesInTriangleArray(); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.h index 8c41f4a5ecd..ba0bfa3c8f9 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.h @@ -151,8 +151,8 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API TriangleSetTopologyContainer /// Dynamic Topology API /// @{ - /// Method called by component Init method. Will create all the topology neighborhood buffers and call @see EdgeSetTopologyContainer::initTopology() - void initTopology(); + /// Method called by component Init method. Will create all the topology neighboorhood buffers and call @see EdgeSetTopologyContainer::computeCrossElementBuffers() + void computeCrossElementBuffers() override; /** \brief Checks if the topology is coherent * diff --git a/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.cpp b/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.cpp index f1fbc45235f..7eb1494c17d 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.cpp +++ b/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.cpp @@ -23,7 +23,6 @@ #include #include #include - namespace sofa::core::topology { diff --git a/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.h b/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.h index 2a5348f3eb3..b8b36581ab4 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.h +++ b/Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.h @@ -85,6 +85,9 @@ class SOFA_CORE_API BaseMeshTopology : public core::topology::Topology public: void init() override; + /// Method to be overriden by child class to create all the topology buffers + virtual void computeCrossElementBuffers() {} + /// Load the topology from a file. /// /// The default implementation supports the following formats: obj, gmsh, mesh (custom simple text file), xs3 (deprecated description of mass-springs networks). diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp b/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp index db0659a8504..3c1a0a06af7 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp @@ -132,22 +132,10 @@ void ParallelBVHNarrowPhase::initializeTopology(sofa::core::topology::BaseMeshTo auto insertionIt = m_initializedTopology.insert(topology); if (insertionIt.second) { - // The following calls force the creation of some topology arrays before the concurrent computing. - // Those arrays cannot be created on the fly, in a concurrent environment, + // We need to make sure all topology buffers are well created. + // Those arrays cannot be created on the fly later, in a concurrent environment, // due to possible race conditions. - // Depending on the scene graph, it is possible that those calls are not enough. - if (topology->getNbPoints()) - { - topology->getTrianglesAroundVertex(0); - } - if (topology->getNbTriangles()) - { - topology->getEdgesInTriangle(0); - } - if (topology->getNbEdges()) - { - topology->getTrianglesAroundEdge(0); - } + topology->computeCrossElementBuffers(); } }