Skip to content

Commit

Permalink
[Topology] Backup work to snap vertex at start/end
Browse files Browse the repository at this point in the history
  • Loading branch information
epernod committed Jan 8, 2025
1 parent 79fd94f commit ee6b5d8
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" ?>
<Node name="root" dt="0.03" showBoundingTree="0" gravity="0 -0.1 0">
<Node name="RequiredPlugins">
<RequiredPlugin name="Sofa.Component.Collision.Detection.Algorithm"/> <!-- Needed to use components [BVHNarrowPhase, BruteForceBroadPhase, CollisionPipeline] -->
<RequiredPlugin name="Sofa.Component.Collision.Detection.Intersection"/> <!-- Needed to use components [MinProximityIntersection] -->
<RequiredPlugin name="Sofa.Component.Collision.Geometry"/> <!-- Needed to use components [PointCollisionModel, SphereCollisionModel, TriangleCollisionModel] -->
<RequiredPlugin name="Sofa.Component.Collision.Response.Contact"/> <!-- Needed to use components [DefaultContactManager] -->
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedConstraint] -->
<RequiredPlugin name="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin name="Sofa.Component.IO.Mesh"/> <!-- Needed to use components [MeshOBJLoader] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [IdentityMapping] -->
<RequiredPlugin name="Sofa.Component.Mapping.NonLinear"/> <!-- Needed to use components [RigidMapping] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass, UniformMass] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.SceneUtility"/> <!-- Needed to use components [InfoComponent] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [TetrahedralCorotationalFEMForceField] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms, TetrahedronSetTopologyContainer, TetrahedronSetTopologyModifier, TriangleSetGeometryAlgorithms, TriangleSetTopologyContainer, TriangleSetTopologyModifier] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin name="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2TetraTopologicalMapping, Tetra2TriangleTopologicalMapping] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.Spring"/> <!-- Needed to use components [TriangularBendingSprings] -->
<RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> <!-- Needed to use components [OglModel] -->
<RequiredPlugin name="Tearing" />
</Node>

<VisualStyle displayFlags="hideCollisionModels showVisual showBehaviorModels showWireframe" />

<DefaultAnimationLoop />
<DefaultVisualManagerLoop />
<CollisionPipeline verbose="0" />
<BruteForceBroadPhase/>
<BVHNarrowPhase/>
<CollisionResponse response="PenalityContactForceField" />
<MinProximityIntersection name="Proximity" alarmDistance="1.0" contactDistance="0.1" />

<Node name="FixedPlane" >
<EulerImplicitSolver name="cg_odesolver" />
<CGLinearSolver iterations="40" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MeshOBJLoader name="loader" filename="./mesh/plane_128_triangles.obj" scale3d="10 10 10" />
<MechanicalObject name="CoarseMesh" position="@loader.position" template="Vec3d" />
<TriangleSetTopologyContainer triangles="@loader.triangles" name="Ttopo" />
<TriangleSetTopologyModifier name="Modifier" />
<TriangleSetGeometryAlgorithms template="Vec3d" name="GeomAlgo" drawEdges="1" showIndicesScale="0.04" showTriangleIndices="1" showEdgeIndices="1" showPointIndices="1"/>
<DiagonalMass template="Vec3d,Vec3d" name="default5" massDensity="0.1" />
<BoxROI template="Vec3d" name="box_roi1" box="-20.1 -1 -20.1 -19.9 1 20.1 19.9 -1 -20.1 20.1 1 20.1" drawBoxes="1"/>
<FixedProjectiveConstraint template="Vec3d" name="fixedConstraint1" indices="@box_roi1.indices"/>
<TriangularFEMForceField template="Vec3d" name="FEM" method="large" poissonRatio="0.45" youngModulus="600" />
<TriangleCollisionModel name="default7" selfCollision="true" />
<TriangleCuttingController name="TriCtrl" triAID="55" triBID="68" triACoefs="0.05 0.10 0.85" triBCoefs="0.07 0.86 0.07" drawDebugCut="1" performCut="1"/>
<Node name="visu">
<OglModel name="Visual" texcoords="@../loader.texcoords" texturename="textures/colorMap.png"/>
<IdentityMapping input="@.." output="@." />
</Node>
</Node>

</Node>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1.69345e-12 31.945 2.05747e-13
-0.707107 -2.84464e-18 6.93889e-18 0.707107
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" ?>
<Node name="root" dt="0.03" showBoundingTree="0" gravity="0 -0.1 0">
<Node name="RequiredPlugins">
<RequiredPlugin name="Sofa.Component.Collision.Detection.Algorithm"/> <!-- Needed to use components [BVHNarrowPhase, BruteForceBroadPhase, CollisionPipeline] -->
<RequiredPlugin name="Sofa.Component.Collision.Detection.Intersection"/> <!-- Needed to use components [MinProximityIntersection] -->
<RequiredPlugin name="Sofa.Component.Collision.Geometry"/> <!-- Needed to use components [PointCollisionModel, SphereCollisionModel, TriangleCollisionModel] -->
<RequiredPlugin name="Sofa.Component.Collision.Response.Contact"/> <!-- Needed to use components [DefaultContactManager] -->
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedConstraint] -->
<RequiredPlugin name="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin name="Sofa.Component.IO.Mesh"/> <!-- Needed to use components [MeshOBJLoader] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [IdentityMapping] -->
<RequiredPlugin name="Sofa.Component.Mapping.NonLinear"/> <!-- Needed to use components [RigidMapping] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass, UniformMass] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.SceneUtility"/> <!-- Needed to use components [InfoComponent] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [TetrahedralCorotationalFEMForceField] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms, TetrahedronSetTopologyContainer, TetrahedronSetTopologyModifier, TriangleSetGeometryAlgorithms, TriangleSetTopologyContainer, TriangleSetTopologyModifier] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin name="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2TetraTopologicalMapping, Tetra2TriangleTopologicalMapping] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.Spring"/> <!-- Needed to use components [TriangularBendingSprings] -->
<RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> <!-- Needed to use components [OglModel] -->
<RequiredPlugin name="Tearing" />
</Node>

<VisualStyle displayFlags="hideCollisionModels showVisual showBehaviorModels showWireframe" />

<DefaultAnimationLoop />
<DefaultVisualManagerLoop />
<CollisionPipeline verbose="0" />
<BruteForceBroadPhase/>
<BVHNarrowPhase/>
<CollisionResponse response="PenalityContactForceField" />
<MinProximityIntersection name="Proximity" alarmDistance="1.0" contactDistance="0.1" />

<Node name="FixedPlane" >
<EulerImplicitSolver name="cg_odesolver" />
<CGLinearSolver iterations="40" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MeshOBJLoader name="loader" filename="./mesh/plane_128_triangles.obj" scale3d="10 10 10" />
<MechanicalObject name="CoarseMesh" position="@loader.position" template="Vec3d" />
<TriangleSetTopologyContainer triangles="@loader.triangles" name="Ttopo" />
<TriangleSetTopologyModifier name="Modifier" />
<TriangleSetGeometryAlgorithms template="Vec3d" name="GeomAlgo" drawEdges="1" showIndicesScale="0.04" showTriangleIndices="1" showEdgeIndices="1" showPointIndices="1"/>
<DiagonalMass template="Vec3d,Vec3d" name="default5" massDensity="0.1" />
<BoxROI template="Vec3d" name="box_roi1" box="-20.1 -1 -20.1 -19.9 1 20.1 19.9 -1 -20.1 20.1 1 20.1" drawBoxes="1"/>
<FixedProjectiveConstraint template="Vec3d" name="fixedConstraint1" indices="@box_roi1.indices"/>
<TriangularFEMForceField template="Vec3d" name="FEM" method="large" poissonRatio="0.45" youngModulus="600" />
<TriangleCollisionModel name="default7" selfCollision="true" />
<TriangleCuttingController name="TriCtrl" triAID="55" triBID="68" triACoefs="0.05 0.10 0.85" triBCoefs=" 0.07 0.07 0.86" drawDebugCut="1" performCut="0"/>
<Node name="visu">
<OglModel name="Visual" texcoords="@../loader.texcoords" texturename="textures/colorMap.png"/>
<IdentityMapping input="@.." output="@." />
</Node>
</Node>

</Node>
104 changes: 90 additions & 14 deletions src/Tearing/Controllers/TriangleCuttingController.inl
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,20 @@ void TriangleCuttingController<DataTypes>::processSubdividers()
// 1. Add all new points and duplicate point from snapped points
type::vector < type::vector<SReal> > _baryCoefs;
type::vector < type::vector< Topology::PointID > >_ancestors;
auto nbrPoints = Topology::PointID(this->m_topoContainer->getNbPoints());

for (auto ptA : m_pointsToAdd)
{
_ancestors.push_back(ptA->m_ancestors);
_baryCoefs.push_back(ptA->m_coefs);
if (ptA->m_idPoint >= nbrPoints)
{
std::cout << ptA->m_idPoint << " | " << nbrPoints << std::endl;
_ancestors.push_back(ptA->m_ancestors);
_baryCoefs.push_back(ptA->m_coefs);
}

if (ptA->m_idClone != sofa::InvalidID && ptA->m_idLocalSnap == sofa::InvalidID)
if (ptA->m_idClone != sofa::InvalidID /*&& ptA->m_idLocalSnap == sofa::InvalidID*/) // check here to solve snapping: ptA->m_idClone >= nbrPoints
{
std::cout << ptA->m_idClone << " clone | " << nbrPoints << std::endl;
_ancestors.push_back(ptA->m_ancestors);
_baryCoefs.push_back(ptA->m_coefs);
}
Expand All @@ -411,6 +417,7 @@ void TriangleCuttingController<DataTypes>::processSubdividers()
_baryCoefs.clear();
for (auto triSub : m_subviders)
{
std::cout << "-- trianglesToRemove: " << triSub->getTriangleIdToSplit() << std::endl;
const type::vector<TriangleToAdd*>& TTAS = triSub->getTrianglesToAdd();
for (auto TTA : TTAS)
{
Expand All @@ -420,7 +427,7 @@ void TriangleCuttingController<DataTypes>::processSubdividers()
_baryCoefs.push_back(TTA->m_coefs);
}
trianglesToRemove.push_back(triSub->getTriangleIdToSplit());
std::cout << "-- trianglesToRemove: " << triSub->getTriangleIdToSplit() << std::endl;
std::cout << "--------------" << std::endl;
}

for (auto tri : m_addTriangles)
Expand Down Expand Up @@ -508,30 +515,94 @@ void TriangleCuttingController<DataTypes>::processCut()
{
if (_coefsTris[i][j] > snapThresholdBorder) // snap to point at start
{
snapV[i] = theTris[i][j];
if ( i==0)
std::cout << "Snap at Start: " << snapV[i] << std::endl;
else
std::cout << "Snap at End: " << snapV[i] << std::endl;
snapV[i] = j;
}

if (_coefsTris[i][j] < (1_sreal - snapThresholdBorder)) // otherwise snap to edge at start
{
snapE[i] = j;// edgesInTri[triIds[0]][(i + 3) % 3];
if (i == 0)
std::cout << "Snap Edge at Start: " << snapE[i] << " -> " << edgesInTri[triIds[i]][(j + 3) % 3] << std::endl;
else
std::cout << "Snap Edge at End: " << snapE[i] << " -> " << edgesInTri[triIds[i]][(j + 3) % 3] << std::endl;
}
}
}

std::cout << "nbrPoints0: " << nbrPoints << std::endl;
for (unsigned int i = 0; i < 2; ++i)
{
if (snapV[i] != InvalidID)
{
// snap Vertex is prioritary
std::cout << "Snap needed here: " << snapV[i] << std::endl;
PointID snapId = snapV[i];
PointID vId = theTris[i][snapId];

std::cout << "Snap needed here: " << vId << std::endl;


Topology::EdgeID edgeId = edgesInTri[triIds[i]][(snapId + 3) % 3];

std::cout << "theTris: " << theTris[i] << std::endl;
std::cout << "_coefsTris: " << _coefsTris[i] << std::endl;
std::cout << "snapId: " << snapId << std::endl;
std::cout << "edgeId: " << edgeId << std::endl;

if (i == 0 && edgeId != edges_list[0]) // id on next intersected edge
{
const Topology::Edge& edge = edges[edges_list[0]];
if (edge[0] == vId)
coords_list[0] = 1.0;
else
coords_list[0] = 0.0;

continue;
}
else if (i == 1 && edgeId != edges_list.back())
{
const Topology::Edge& edge = edges[edges_list.back()];
if (edge[0] == vId)
coords_list.back() = 1.0;
else
coords_list.back() = 0.0;

continue;
}

// point to snap is opposite to interesected edge. We just divid the full triangle
type::vector<SReal> _coefs = { 0.0, 0.0, 0.0 };
_coefs[snapId] = 1.0;
type::vector<Topology::PointID> _ancestors = { theTris[i][0] , theTris[i][1], theTris[i][2] };
Topology::PointID uniqID = getUniqueId(theTris[i][0], theTris[i][1], theTris[i][2]);

std::shared_ptr<PointToAdd> PTA = std::make_shared<PointToAdd>(uniqID, vId, _ancestors, _coefs, snapThresholdBorder);
m_pointsToAdd.push_back(PTA);

// add to the map for later retrieving
std::vector<std::shared_ptr<PointToAdd> >& PTAs = PTA_map[triIds[i]];
PTAs.push_back(PTA);


int nextTriId = -1;
if (i == 0) // start
{
nextTriId = m_geometryAlgorithms->getTriangleInDirection(vId, -cutPath);
}
else
{
nextTriId = m_geometryAlgorithms->getTriangleInDirection(vId, cutPath);
}
std::cout << "nextTriId: " << nextTriId << std::endl;
if (nextTriId != -1 ) // nothing to do, no subdivision as there are triangles all around
{
PTA->printValue();
continue;
}
else
{
PTA->m_idPoint = nbrPoints;
PTA->updatePointIDForDuplication();
cloneMap[vId] = PTA->m_idClone;
nbrPoints++;
PTA->printValue();
}

continue;
}
else if (snapE[i] != InvalidID)
Expand Down Expand Up @@ -579,6 +650,7 @@ void TriangleCuttingController<DataTypes>::processCut()
std::shared_ptr<PointToAdd> PTA = std::make_shared<PointToAdd>(uniqID, nbrPoints, _ancestors, _coefs);
m_pointsToAdd.push_back(PTA);
PTA->printValue();

// add to the map for later retrieving
const auto& triAEdge = triAEdges[edgeId];
if (triAEdge.size() == 1) // at border of the mesh, we duplicate it
Expand Down Expand Up @@ -618,6 +690,7 @@ void TriangleCuttingController<DataTypes>::processCut()
Topology::PointID uniqID = getUniqueId(theTris[i][0], theTris[i][1], theTris[i][2]);

std::shared_ptr<PointToAdd> PTA = std::make_shared<PointToAdd>(uniqID, nbrPoints, _ancestors, _coefs);
PTA->printValue();
PTA->m_ancestorType = sofa::geometry::ElementType::TRIANGLE;
m_pointsToAdd.push_back(PTA);

Expand All @@ -627,6 +700,8 @@ void TriangleCuttingController<DataTypes>::processCut()
// add to the map for later retrieving
std::vector<std::shared_ptr<PointToAdd> >& PTAs = PTA_map[triIds[i]];
PTAs.push_back(PTA);

std::cout << "nbrPoints1: " << nbrPoints << std::endl;
}

// ProcessUpdate all coef due to the snapping
Expand Down Expand Up @@ -659,6 +734,7 @@ void TriangleCuttingController<DataTypes>::processCut()
Topology::PointID uniqID = getUniqueId(edge[0], edge[1]);
std::shared_ptr<PointToAdd> PTA = std::make_shared<PointToAdd>(uniqID, nbrPoints, _ancestors, _coefs, snapThreshold);
bool snapped = PTA->updatePointIDForDuplication();
PTA->printValue();
if (snapped)
{
auto itM = cloneMap.find(PTA->m_idPoint);
Expand Down

0 comments on commit ee6b5d8

Please sign in to comment.