Skip to content

Commit

Permalink
[Topology] Add function in BaseMeshTopology to compute all topology c…
Browse files Browse the repository at this point in the history
…ontainers (sofa-framework#3368)

* [Topology] rename method initTpology into initContainers and provide access to it from BaseMeshTopology

* [MultiThreading] Replace call to getter to init topology by call to initContainers

* Fix MeshTopology initContainer

* REname initContainers into computeCrossElementBuffers

* restore comment

* Fix compilation

* Update MeshTopology.cpp

* Update MeshTopology.cpp

* Update applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp

Co-authored-by: Hugo <[email protected]>

* Update MeshTopology, Keep method ComputeCorssElementBuffer to be call only if needed. Not called at init

* Update MeshTopology.h

* Update MeshTopology.cpp

* Update MeshTopology.h

---------

Co-authored-by: Hugo <[email protected]>
  • Loading branch information
epernod and hugtalbot authored Jan 8, 2025
1 parent 292f5bc commit 7b3729f
Show file tree
Hide file tree
Showing 15 changed files with 106 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -524,7 +525,6 @@ MeshTopology::MeshTopology()

void MeshTopology::init()
{

BaseMeshTopology::init();

const auto hexahedra = sofa::helper::getReadAccessor(d_seqHexahedra);
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -576,6 +580,7 @@ void MeshTopology::init()
nbPoints = n;
}


if(edges.empty() )
{
if(d_seqEdges.getParent() != nullptr )
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -348,6 +351,7 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public core:
Data<SeqTetrahedra> d_seqTetrahedra; ///< List of tetrahedron indices
Data<SeqHexahedra> d_seqHexahedra; ///< List of hexahedron indices
Data<SeqUV> d_seqUVs; ///< List of uv coordinates
Data<bool> d_computeAllBuffers; ///< Option to call method computeCrossElementBuffers. False by default

protected:
Size nbPoints;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <sofa/helper/io/MeshTopologyLoader.h>
#include <sofa/helper/system/FileRepository.h>
#include <sofa/core/objectmodel/BaseNode.h>

namespace sofa::core::topology
{

Expand Down
3 changes: 3 additions & 0 deletions Sofa/framework/Core/src/sofa/core/topology/BaseMeshTopology.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

Expand Down

0 comments on commit 7b3729f

Please sign in to comment.