diff --git a/scenes/TopologyBenchmarks/Benchmark_01_TriangleCut_plane.scn.qglviewer.view b/scenes/TopologyBenchmarks/Benchmark_01_TriangleCut_plane.scn.qglviewer.view
new file mode 100644
index 0000000..77a09d8
--- /dev/null
+++ b/scenes/TopologyBenchmarks/Benchmark_01_TriangleCut_plane.scn.qglviewer.view
@@ -0,0 +1,2 @@
+-4.56984 18.0925 3.09767
+-0.707107 -2.08167e-17 4.93754e-18 0.707107
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-01_simpleCut.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-01_simpleCut.scn
new file mode 100644
index 0000000..dbb5fd1
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-01_simpleCut.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-01_simpleCut.scn.qglviewer.view b/scenes/TopologyBenchmarks/TriangleCut_benchmark-01_simpleCut.scn.qglviewer.view
new file mode 100644
index 0000000..3f9098d
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-01_simpleCut.scn.qglviewer.view
@@ -0,0 +1,2 @@
+-0.849029 25.627 1.51729
+-0.707107 2.01511e-19 -2.01511e-19 0.707107
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-02_snapping.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-02_snapping.scn
new file mode 100644
index 0000000..5cb5e93
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-02_snapping.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-02_snapping.scn.qglviewer.view b/scenes/TopologyBenchmarks/TriangleCut_benchmark-02_snapping.scn.qglviewer.view
new file mode 100644
index 0000000..03eca3c
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-02_snapping.scn.qglviewer.view
@@ -0,0 +1,2 @@
+1.26184e-17 22.1391 2.62308e-15
+-0.707107 2.01511e-19 -2.01511e-19 0.707107
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-03_snapping.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-03_snapping.scn
new file mode 100644
index 0000000..731a0cb
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-03_snapping.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-03_snapping.scn.qglviewer.view b/scenes/TopologyBenchmarks/TriangleCut_benchmark-03_snapping.scn.qglviewer.view
new file mode 100644
index 0000000..088c644
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-03_snapping.scn.qglviewer.view
@@ -0,0 +1,2 @@
+-0.740008 44.5146 -4.62505
+-0.707107 6.93889e-18 1.14281e-17 0.707107
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-04_snappingStartEdge.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-04_snappingStartEdge.scn
new file mode 100644
index 0000000..0101993
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-04_snappingStartEdge.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-04_snappingStartEdge.scn.qglviewer.view b/scenes/TopologyBenchmarks/TriangleCut_benchmark-04_snappingStartEdge.scn.qglviewer.view
new file mode 100644
index 0000000..16f7386
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-04_snappingStartEdge.scn.qglviewer.view
@@ -0,0 +1,2 @@
+0.462173 28.4812 3.73835
+-0.707107 7.38134e-18 -7.38134e-18 0.707107
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-05_snappingEdgeInside.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-05_snappingEdgeInside.scn
new file mode 100644
index 0000000..da75859
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-05_snappingEdgeInside.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-06_snappingPointOutside.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-06_snappingPointOutside.scn
new file mode 100644
index 0000000..329e1af
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-06_snappingPointOutside.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-06_snappingPointOutside.scn.qglviewer.view b/scenes/TopologyBenchmarks/TriangleCut_benchmark-06_snappingPointOutside.scn.qglviewer.view
new file mode 100644
index 0000000..a1dd874
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-06_snappingPointOutside.scn.qglviewer.view
@@ -0,0 +1,2 @@
+1.69345e-12 31.945 2.05747e-13
+-0.707107 -2.84464e-18 6.93889e-18 0.707107
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-07_snappingPointInside.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-07_snappingPointInside.scn
new file mode 100644
index 0000000..6a53a73
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-07_snappingPointInside.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenes/TopologyBenchmarks/TriangleCut_benchmark-08_snappingDebug.scn b/scenes/TopologyBenchmarks/TriangleCut_benchmark-08_snappingDebug.scn
new file mode 100644
index 0000000..1eefb4b
--- /dev/null
+++ b/scenes/TopologyBenchmarks/TriangleCut_benchmark-08_snappingDebug.scn
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Tearing/Controllers/TriangleCuttingController.h b/src/Tearing/Controllers/TriangleCuttingController.h
index 1927dcd..957249d 100644
--- a/src/Tearing/Controllers/TriangleCuttingController.h
+++ b/src/Tearing/Controllers/TriangleCuttingController.h
@@ -78,6 +78,7 @@ class TEARING_API TriangleCuttingController : public core::behavior::BaseControl
void processSubdividers();
void processCut();
+ void processCutNew();
void clearBuffers();
public:
@@ -85,6 +86,8 @@ class TEARING_API TriangleCuttingController : public core::behavior::BaseControl
Data < sofa::type::vector< TriangleID > > d_triangleIds;
Data < unsigned int > d_triAID;
Data < unsigned int > d_triBID;
+ Data < Vec3 > d_triACoefs;
+ Data < Vec3 > d_triBCoefs;
/// Bool to perform a cut at the current timestep
Data d_performCut;
@@ -107,6 +110,9 @@ class TEARING_API TriangleCuttingController : public core::behavior::BaseControl
type::vector< TriangleSubdivider*> m_subviders;
type::vector< std::shared_ptr > m_pointsToAdd;
+
+ type::vector m_addTriangles;
+ type::vector m_removedTriangles;
};
diff --git a/src/Tearing/Controllers/TriangleCuttingController.inl b/src/Tearing/Controllers/TriangleCuttingController.inl
index bf26d7c..d062628 100644
--- a/src/Tearing/Controllers/TriangleCuttingController.inl
+++ b/src/Tearing/Controllers/TriangleCuttingController.inl
@@ -43,6 +43,8 @@ TriangleCuttingController::TriangleCuttingController()
, d_triangleIds(initData(&d_triangleIds, "triangleIds", "Triangles Ids to subdivide"))
, d_triAID(initData(&d_triAID, (unsigned int)(0), "triAID", "id triangle1"))
, d_triBID(initData(&d_triBID, (unsigned int)(0), "triBID", "id triangle2"))
+ , d_triACoefs(initData(&d_triACoefs, Vec3(0.3333, 0.3333, 0.3333), "triACoefs", "(default=[0.3333, 0.3333, 0.3333])"))
+ , d_triBCoefs(initData(&d_triBCoefs, Vec3(0.3333, 0.3333, 0.3333), "triBCoefs", "(default=[0.3333, 0.3333, 0.3333])"))
, d_performCut(initData(&d_performCut, false, "performCut", "to activate cut at the current timestep"))
, d_cutPointA(initData(&d_cutPointA, Vec3(0.0, 0.0, 0.0), "cutPointA", "(default=[0, 0, 0])"))
, d_cutPointB(initData(&d_cutPointB, Vec3(0.0, 0.0, 0.0), "cutPointB", "(default=[0, 0, 0])"))
@@ -382,20 +384,27 @@ void TriangleCuttingController::processSubdividers()
// 1. Add all new points and duplicate point from snapped points
type::vector < type::vector > _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)
+ 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);
}
}
size_t nbrP = _ancestors.size();
+ std::cout << "processSubdividers: nbrP: " << nbrP << std::endl;
// 2. resize the point buffer in the topology
// warn for the creation of all the points registered to be created
@@ -408,15 +417,29 @@ void TriangleCuttingController::processSubdividers()
_baryCoefs.clear();
for (auto triSub : m_subviders)
{
+ std::cout << "-- trianglesToRemove: " << triSub->getTriangleIdToSplit() << std::endl;
const type::vector& TTAS = triSub->getTrianglesToAdd();
for (auto TTA : TTAS)
{
trianglesToAdd.push_back(TTA->m_triangle);
+ std::cout << "trianglesToAdd: " << TTA->m_triangle << std::endl;
_ancestors.push_back(TTA->m_ancestors);
_baryCoefs.push_back(TTA->m_coefs);
}
trianglesToRemove.push_back(triSub->getTriangleIdToSplit());
+ std::cout << "--------------" << std::endl;
}
+
+ for (auto tri : m_addTriangles)
+ {
+ trianglesToAdd.push_back(tri);
+ }
+
+ for (auto triId : m_removedTriangles)
+ {
+ trianglesToRemove.push_back(triId);
+ }
+
std::cout << "Nbr trianglesToAdd: " << trianglesToAdd.size() << std::endl;
m_topoModifier->addTriangles(trianglesToAdd, _ancestors, _baryCoefs);
std::cout << "Nbr trianglesToRemove: " << trianglesToRemove.size() << std::endl;
@@ -428,105 +451,370 @@ void TriangleCuttingController::processSubdividers()
}
+template
+void TriangleCuttingController::processCutNew()
+{
+ std::cout << "TriangleCuttingController::processCutNew()" << std::endl;
+
+ // Get triangle to subdivide information
+ const auto& triangles = m_topoContainer->getTriangles();
+ type::fixed_array< Topology::TriangleID, 2> triIds = { d_triAID.getValue() , d_triBID.getValue() };
+ type::fixed_array< Topology::Triangle, 2> theTris = { triangles[triIds[0]], triangles[triIds[1]] };
+ type::fixed_array < Vec3, 2> _coefsTris = { d_triACoefs.getValue(), d_triBCoefs.getValue() };
+
+ // Get points coordinates
+ sofa::helper::ReadAccessor x = m_state->read(sofa::core::ConstVecCoordId::position())->getValue();
+
+ const Coord pA = x[theTris[0][0]] * _coefsTris[0][0] + x[theTris[0][1]] * _coefsTris[0][1] + x[theTris[0][2]] * _coefsTris[0][2];
+ const Coord pB = x[theTris[1][0]] * _coefsTris[1][0] + x[theTris[1][1]] * _coefsTris[1][1] + x[theTris[1][2]] * _coefsTris[1][2];
+ Vec3 ptA = Vec3(pA[0], pA[1], pA[2]);
+ Vec3 ptB = Vec3(pB[0], pB[1], pB[2]);
+
+ d_cutPointA.setValue(ptA);
+ d_cutPointB.setValue(ptB);
+
+ SReal snapThreshold = 0.8;
+ SReal snapThresholdBorder = 0.8;
+
+ m_pointsToAdd = m_geometryAlgorithms->computeIncisionPath(ptA, ptB, triIds[0], triIds[1], snapThreshold, snapThresholdBorder);
+ std::cout << "m_pointsToAdd: " << m_pointsToAdd.size() << std::endl;
+
+ if (d_performCut.getValue())
+ m_geometryAlgorithms->InciseAlongPath(ptA, ptB, triIds[0], triIds[1], m_pointsToAdd);
+
+ std::cout << "TriangleCuttingController::processCutNew() out" << std::endl;
+}
+
+
template
void TriangleCuttingController::processCut()
{
std::cout << "TriangleCuttingController::processCut()" << std::endl;
-
+
auto nbrPoints = Topology::PointID(this->m_topoContainer->getNbPoints());
const auto& triangles = m_topoContainer->getTriangles();
const auto& edges = m_topoContainer->getEdges();
const auto& triAEdges = m_topoContainer->getTrianglesAroundEdgeArray();
+ const auto& edgesInTri = m_topoContainer->getEdgesInTriangleArray();
// Get triangle to subdivide information
type::fixed_array< Topology::TriangleID, 2> triIds = { d_triAID.getValue() , d_triBID.getValue() };
type::fixed_array< Topology::Triangle, 2> theTris = { triangles[triIds[0]], triangles[triIds[1]] };
-
+ type::fixed_array < Vec3, 2> _coefsTris = { d_triACoefs.getValue(), d_triBCoefs.getValue() };
+
// Get points coordinates
sofa::helper::ReadAccessor x = m_state->read(sofa::core::ConstVecCoordId::position())->getValue();
- const Coord pA = (x[theTris[0][0]] + x[theTris[0][1]] + x[theTris[0][2]]) / 3;
- const Coord pB = (x[theTris[1][0]] + x[theTris[1][1]] + x[theTris[1][2]]) / 3;
+ const Coord pA = x[theTris[0][0]] * _coefsTris[0][0] + x[theTris[0][1]] * _coefsTris[0][1] + x[theTris[0][2]] * _coefsTris[0][2];
+ const Coord pB = x[theTris[1][0]] * _coefsTris[1][0] + x[theTris[1][1]] * _coefsTris[1][1] + x[theTris[1][2]] * _coefsTris[1][2];
Vec3 ptA = Vec3(pA[0], pA[1], pA[2]);
Vec3 ptB = Vec3(pB[0], pB[1], pB[2]);
d_cutPointA.setValue(ptA);
d_cutPointB.setValue(ptB);
+ // Move that directly inside the subdividers
+ const sofa::type::Vec3 AB = x[theTris[0][1]] - x[theTris[0][0]];
+ const sofa::type::Vec3 AC = x[theTris[0][2]] - x[theTris[0][0]];
+ const sofa::type::Vec3 triNorm = AB.cross(AC);
+ const sofa::type::Vec3 cutPath = ptB - ptA;
+
sofa::type::vector< TriangleID > triangles_list;
sofa::type::vector< EdgeID > edges_list;
sofa::type::vector< Real > coords_list;
- //m_geometryAlgorithms->computeIntersectedPointsList2(ptA, ptB, triIds[0], triIds[1], triangles_list, edges_list, coords_list);
+
+ std::cout << "ptA: " << ptA << std::endl;
+ std::cout << "ptB: " << ptB << std::endl;
+ m_geometryAlgorithms->computeSegmentTriangulationIntersections(ptA, ptB, triIds[0], triIds[1], triangles_list, edges_list, coords_list);
+
+ std::cout << "triangles_list: " << triangles_list << std::endl;
+ std::cout << "edges_list: " << edges_list << std::endl;
+ std::cout << "coords_list: " << coords_list << std::endl;
- std::map < TriangleID, std::vector> > PTA_map;
// create map to store point to be added
- //for (auto triId : triangles_list)
- //{
- // auto tSplit = new TriangleToSplit(triId, triangles[triId]);
- // TTS_map[triId] = tSplit;
- //}
+ std::map < TriangleID, std::vector > > PTA_map;
+ std::map < Topology::PointID, Topology::PointID> cloneMap;
+ SReal snapThreshold = 0.8;
+ SReal snapThresholdBorder = 0.8;
+
+ // create points To add from start/end triangles -> TODO see snap possibility later
+ // if coef > threshold snap to this point and update PTA and path. Do we need to duplicate point?
+ // else if coef < 0.1 -> need to snap with edge. compute intersection in the other direction to find point on edge. Or just substract half coef
+
+ // check snapping at first point
+ type::fixed_array< PointID, 2> snapV = { InvalidID , InvalidID };
+ type::fixed_array< PointID, 2> snapE = { InvalidID , InvalidID };
- // create points To add
for (unsigned int i = 0; i < 2; ++i)
{
- type::vector _coefs;
- type::vector _ancestors;
-
for (unsigned int j = 0; j < 3; ++j)
{
- _ancestors.push_back(theTris[i][j]);
- _coefs.push_back(0.3333);
+ if (_coefsTris[i][j] > snapThresholdBorder) // snap to point at start
+ {
+ 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];
+ }
+ }
+ }
+
+ std::cout << "nbrPoints0: " << nbrPoints << std::endl;
+ for (unsigned int i = 0; i < 2; ++i)
+ {
+ if (snapV[i] != InvalidID)
+ {
+ // snap Vertex is prioritary
+ 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 _coefs = { 0.0, 0.0, 0.0 };
+ _coefs[snapId] = 1.0;
+ type::vector _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 PTA = std::make_shared(uniqID, vId, _ancestors, _coefs, snapThresholdBorder);
+ m_pointsToAdd.push_back(PTA);
+
+ // add to the map for later retrieving
+ std::vector >& 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;
}
- std::cout << "triIds[i]: " << triIds[i] << std::endl;
- std::cout << "theTris[i]: " << theTris[i] << std::endl;
- Topology::PointID uniqID = getUniqueId(theTris[i][0], theTris[i][1]) + theTris[i][2];
+ else if (snapE[i] != InvalidID)
+ {
+ PointID snapId = snapE[i];
+ Topology::EdgeID edgeId = edgesInTri[triIds[i]][(snapId + 3) % 3];
+ const Topology::Edge& edge = edges[edgeId];
+
+
+ type::Vec2 newCoefs;
+ //newCoefs[snapEFirst] = 0.0;
+
+ std::cout << "theTris[0]: " << theTris[i] << std::endl;
+ std::cout << "_coefsTris[0]: " << _coefsTris[i] << std::endl;
+ std::cout << "edge: " << edge << std::endl;
+ //std::cout << "newCoefs: " << newCoefs << std::endl;
+ std::cout << "snapId: " << snapId << std::endl;
+
+ std::cout << "edge[0]: " << edge[0] << std::endl;
+ std::cout << "theTris[i][(snapId + 1) % 3]: " << theTris[i][(snapId + 1) % 3] << std::endl;
+ if (edge[0] == theTris[i][(snapId + 1) % 3])
+ {
+ newCoefs[0] = _coefsTris[i][(snapId + 1) % 3];
+ newCoefs[1] = _coefsTris[i][(snapId + 2) % 3];
+ }
+ else
+ {
+ newCoefs[0] = _coefsTris[i][(snapId + 2) % 3];
+ newCoefs[1] = _coefsTris[i][(snapId + 1) % 3];
+
+ }
+ std::cout << "newCoefs: " << newCoefs << std::endl;
+ SReal sum = newCoefs[0] + newCoefs[1];
+ newCoefs[0] = newCoefs[0] / sum;
+ newCoefs[1] = newCoefs[1] / sum;
+
+ std::cout << "newCoefs: " << newCoefs << std::endl;
+
+ type::vector _ancestors = { edge[0], edge[1] };
+ type::vector _coefs = { newCoefs[0], newCoefs[1] };
+ std::cout << "_ancestors: " << _ancestors << std::endl;
+ std::cout << "_coefs: " << _coefs << std::endl;
+
+ Topology::PointID uniqID = getUniqueId(_ancestors[0], _ancestors[1]);
+ std::shared_ptr PTA = std::make_shared(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
+ {
+ PTA->updatePointIDForDuplication();
+ std::vector >& PTAs = PTA_map[triIds[i]];
+ PTAs.push_back(PTA);
+ nbrPoints = nbrPoints + 2;
+ }
+ else // we don't duplicate the point as it would mess up the adjacent triangle
+ {
+ for (auto triId : triAEdge)
+ {
+ std::vector >& PTAs = PTA_map[triId];
+ PTAs.push_back(PTA);
+ }
+ nbrPoints++;
+ }
+
+ if (i == 0 && edges_list[0] == edgeId) // start snapped with already first interesected edge. Will remove the duplicated occurence.
+ {
+ edges_list.erase(edges_list.begin());
+ coords_list.erase(coords_list.begin());
+ }
+ else if (i == 1 && edges_list.back() == edgeId)
+ {
+ edges_list.pop_back();
+ coords_list.pop_back();
+ }
+
+ continue;
+ }
+
+
+ type::vector _coefs = { _coefsTris[i][0], _coefsTris[i][1], _coefsTris[i][2] };
+ type::vector _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 PTA = std::make_shared(uniqID, nbrPoints, _ancestors, _coefs);
+ PTA->printValue();
PTA->m_ancestorType = sofa::geometry::ElementType::TRIANGLE;
m_pointsToAdd.push_back(PTA);
+
+
nbrPoints++;
+ // add to the map for later retrieving
std::vector >& PTAs = PTA_map[triIds[i]];
- //if (tSplit == nullptr) {
- // std::cout << "TTS_map not found" << std::endl;
- // return;
- //}
PTAs.push_back(PTA);
- //tSplit->m_points.push_back(PTA);
+
+ std::cout << "nbrPoints1: " << nbrPoints << std::endl;
+ }
+
+ // ProcessUpdate all coef due to the snapping
+ std::set psnap;
+ for (unsigned int i = 0; i < edges_list.size(); ++i)
+ {
+ const Topology::Edge& edge = edges[edges_list[i]];
+ if (coords_list[i] > snapThreshold)
+ psnap.insert(edge[0]);
+ else if (1.0 - coords_list[i] > snapThreshold)
+ psnap.insert(edge[1]);
}
for (unsigned int i = 0; i < edges_list.size(); ++i)
{
- type::vector _coefs;
- type::vector _ancestors;
-
const Topology::Edge& edge = edges[edges_list[i]];
- _ancestors.push_back(edge[0]);
- _ancestors.push_back(edge[1]);
- _coefs.push_back(coords_list[i]); // use them as weights if W == 1 -> point is on vertex.
- _coefs.push_back(1.0 - coords_list[i]);
+ if (psnap.find(edge[0]) != psnap.end())
+ coords_list[i] = 1.0;
+ else if (psnap.find(edge[1]) != psnap.end())
+ coords_list[i] = 0.0;
+ }
- Topology::PointID uniqID = getUniqueId(_ancestors[0], _ancestors[1]);
- std::shared_ptr PTA = std::make_shared(uniqID, nbrPoints, _ancestors, _coefs);
- PTA->m_ancestorType = sofa::geometry::ElementType::EDGE;
- PTA->m_idClone = nbrPoints + 1;
- m_pointsToAdd.push_back(PTA);
- nbrPoints = nbrPoints + 2;
+ // create PointToAdd from edges
+ for (unsigned int i = 0; i < edges_list.size(); ++i)
+ {
+ const Topology::Edge& edge = edges[edges_list[i]];
+ type::vector _coefs = { coords_list[i], 1.0 - coords_list[i] };
+ type::vector _ancestors = { edge[0], edge[1] };
+
+ Topology::PointID uniqID = getUniqueId(edge[0], edge[1]);
+ std::shared_ptr PTA = std::make_shared(uniqID, nbrPoints, _ancestors, _coefs, snapThreshold);
+ bool snapped = true; PTA->updatePointIDForDuplication();
+ PTA->printValue();
+ if (snapped)
+ {
+ auto itM = cloneMap.find(PTA->m_idPoint);
+ if (itM == cloneMap.end())
+ {
+ cloneMap[PTA->m_idPoint] = PTA->m_idClone;
+ m_pointsToAdd.push_back(PTA);
+ nbrPoints++;
+ }
+ else {
+ PTA = m_pointsToAdd.back();
+ }
+ }
+ else
+ {
+ m_pointsToAdd.push_back(PTA);
+ nbrPoints = nbrPoints +2;
+ }
const auto& triAEdge = triAEdges[edges_list[i]];
for (auto triId : triAEdge)
- {
- //TriangleToSplit* tSplit = TTS_map[triId];
- //tSplit->m_points.push_back(PTA);
+ {
std::vector >& PTAs = PTA_map[triId];
PTAs.push_back(PTA);
}
}
-
- for (unsigned int i = 0; i < triangles_list.size(); ++i)
+ // Create subdividers and add PTA
+ for (auto itM : PTA_map)
{
- TriangleID triId = triangles_list[i];
- std::vector >& PTAs = PTA_map[triId];
- //TriangleToSplit* tSplit = TTS_map[triId];
+ TriangleID triId = itM.first;
+
+
+ //for (unsigned int i = 0; i < triangles_list.size(); ++i)
+ //{
+ // TriangleID triId = triangles_list[i];
+ // auto itM = PTA_map.find(triId);
+ // if (itM == PTA_map.end())
+ // {
+ // // TriangleSubdivider has been removed due to snapping
+ // continue;
+ // }
+
+ std::vector >& PTAs = itM.second;
+
const Topology::Triangle& theTri = triangles[triId];
TriangleSubdivider* subdivider = new TriangleSubdivider(triId, theTri);
sofa::type::fixed_array points = { x[theTri[0]], x[theTri[1]], x[theTri[2]] };
@@ -539,74 +827,72 @@ void TriangleCuttingController::processCut()
}
- // split path here
+ //std::cout << "m_pointsToAdd: " << m_pointsToAdd.size() << std::endl;
+ //for (auto ptA : m_pointsToAdd)
+ //{
+ // std::cout << ptA->m_uniqueID << " | ancestors: " << ptA->m_ancestors << " | " << ptA->m_coefs << std::endl;
+ //}
+
+
+
+
// create the list of new triangles around the inside path
- std::map < Topology::PointID, type::vector > TTA_map;
- std::map < Topology::PointID, Topology::PointID> cloneMap;
for (auto triSub : m_subviders)
{
- const type::vector& TTAS = triSub->getTrianglesToAdd();
- const type::vector>& PTAS = triSub->getPointsToAdd();
- for (unsigned int i = 0; i < TTAS.size(); ++i)
+ triSub->cutTriangles(ptA, ptB, triNorm);
+ }
+
+ // need to split snapped point in existing triangles
+ m_addTriangles.clear();
+ m_removedTriangles.clear();
+ for (auto itM : cloneMap)
+ {
+ std::cout << "need to update triangles arount v: " << itM.first << " -> " << itM.second << std::endl;
+ const auto& triAV = m_topoContainer->getTrianglesAroundVertex(itM.first);
+ for (TriangleID triId : triAV)
{
- Topology::Triangle newTri = TTAS[i]->m_triangle;
- for (unsigned int j = 0; j < PTAS.size(); ++j)
+ bool found = false;
+ for (auto triSub : m_subviders)
{
- if (PTAS[j]->m_ancestorType == sofa::geometry::ElementType::TRIANGLE)
- continue;
-
- Topology::PointID idNewPoint = PTAS[j]->m_idPoint;
- cloneMap[idNewPoint] = PTAS[j]->m_idClone;
- for (unsigned int k = 0; k < 3; ++k)
+ if (triSub->getTriangleIdToSplit() == triId) // already in subdivider
{
- if (newTri[k] == idNewPoint)
- {
- type::vector tris = TTA_map[idNewPoint];
- tris.push_back(TTAS[i]);
- TTA_map[idNewPoint] = tris;
- break;
- }
+ found = true;
+ break;
}
}
- }
- }
- const sofa::type::Vec3 AB = x[theTris[0][1]] - x[theTris[0][0]];
- const sofa::type::Vec3 AC = x[theTris[0][2]] - x[theTris[0][0]];
- const sofa::type::Vec3 triNorm = AB.cross(AC);
- const sofa::type::Vec3 cutPath = ptB - ptA;
+ if (found)
+ continue;
- for (auto it = TTA_map.begin(); it != TTA_map.end(); ++it)
- {
- const type::vector& TTAS = it->second;
- Topology::PointID idClone = cloneMap[it->first];
- for (unsigned int i = 0; i < TTAS.size(); ++i)
- {
- TriangleToAdd* TTA = TTAS[i];
+ Triangle tri = triangles[triId];
+ sofa::type::Vec3 _gravityCenter = (x[tri[0]] + x[tri[1]] + x[tri[2]]) / 3;
- const sofa::type::fixed_array& triCoords = TTA->m_triCoords;
- sofa::type::Vec3 m_gravityCenter = (triCoords[0] + triCoords[1] + triCoords[2]) / 3;
- sofa::type::Vec3 triCutNorm = cutPath.cross(m_gravityCenter - ptA);
+ sofa::type::Vec3 triCutNorm = cutPath.cross(_gravityCenter - ptA);
SReal dotValue = triCutNorm * triNorm;
if (dotValue < 0)
{
- TTA->isUp = false;
- for (unsigned int j = 0; j < 3; ++j)
+ for (unsigned int k = 0; k < 3; ++k)
{
- if (TTA->m_triangle[j] == it->first)
- TTA->m_triangle[j] = idClone;
- }
+ if (tri[k] == itM.first)
+ {
+ tri[k] = itM.second;
+ break;
+ }
+ }
+
+ std::cout << "add Tri: " << tri << " to replace triId: " << triId << std::endl;
+ m_addTriangles.push_back(tri);
+ m_removedTriangles.push_back(triId);
}
- else
- TTA->isUp = true;
}
+
}
- std::cout << "triangles_list: " << triangles_list << std::endl;
- std::cout << "edges_list: " << edges_list << std::endl;
- std::cout << "coords_list: " << coords_list << std::endl;
+ // split path here
+ if (!d_performCut.getValue())
+ return;
processSubdividers();
}
@@ -626,6 +912,10 @@ void TriangleCuttingController::handleEvent(sofa::core::objectmodel::
{
processCut();
}
+ else if (ev->getKey() == 'G')
+ {
+ processCutNew();
+ }
}
}
@@ -639,47 +929,52 @@ void TriangleCuttingController::draw(const core::visual::VisualParams
if (!d_drawDebugCut.getValue())
return;
+ const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle();
+
sofa::type::RGBAColor colorL = sofa::type::RGBAColor::red();
vparams->drawTool()->drawLine(d_cutPointA.getValue(), d_cutPointB.getValue(), colorL);
- std::vector spheresUp, spheresDown;// , float radius, const type::RGBAColor& color
- std::vector pointsUp, pointsDown;
- int cpt = 0;
- for (auto triSub : m_subviders)
+ sofa::helper::ReadAccessor x = m_state->read(sofa::core::ConstVecCoordId::position())->getValue();
+
+ std::vector points;
+ for (auto ptA : m_pointsToAdd)
{
- if (cpt == 20000)
- break;
-
- const type::vector& TTAS = triSub->getTrianglesToAdd();
- const type::vector>& PTAS = triSub->getPointsToAdd();
- for (unsigned int i = 0; i < TTAS.size(); ++i)
+ sofa::type::Vec3 vecG = sofa::type::Vec3(0.0, 0.0, 0.0);
+ sofa::Size nbr = ptA->m_ancestors.size();
+ for (int i = 0; i < nbr; ++i)
{
- TriangleToAdd* TTA = TTAS[i];
- sofa::type::fixed_array triCoords = TTA->m_triCoords;
- sofa::type::Vec3 vecG = (triCoords[0] + triCoords[1] + triCoords[2]) / 3;;
- if (TTA->isUp)
- {
- pointsUp.push_back(triCoords[0]);
- pointsUp.push_back(triCoords[1]);
- pointsUp.push_back(triCoords[2]);
- spheresUp.push_back(vecG);
- }
- else
- {
- pointsDown.push_back(triCoords[0]);
- pointsDown.push_back(triCoords[1]);
- pointsDown.push_back(triCoords[2]);
- spheresDown.push_back(vecG);
- }
+
+ vecG += x[ptA->m_ancestors[i]] * ptA->m_coefs[i];
}
-
- cpt++;
+ points.push_back(vecG);
}
+ vparams->drawTool()->drawSpheres(points, 0.1, sofa::type::RGBAColor::red());
+
+ //std::vector pointsUp, pointsDown;
+ //for (auto triSub : m_subviders)
+ //{
+ // const type::vector& TTAS = triSub->getTrianglesToAdd();
+ // for (unsigned int i = 0; i < TTAS.size(); ++i)
+ // {
+ // TriangleToAdd* TTA = TTAS[i];
+ // sofa::type::fixed_array triCoords = TTA->m_triCoords;
+ // if (TTA->isUp)
+ // {
+ // pointsUp.push_back(triCoords[0]);
+ // pointsUp.push_back(triCoords[1]);
+ // pointsUp.push_back(triCoords[2]);
+ // }
+ // else
+ // {
+ // pointsDown.push_back(triCoords[0]);
+ // pointsDown.push_back(triCoords[1]);
+ // pointsDown.push_back(triCoords[2]);
+ // }
+ // }
+ //}
- vparams->drawTool()->drawTriangles(pointsUp, sofa::type::RGBAColor::red());
- vparams->drawTool()->drawTriangles(pointsDown, sofa::type::RGBAColor::green());
- vparams->drawTool()->drawSpheres(spheresUp, 0.01, sofa::type::RGBAColor::red());
- vparams->drawTool()->drawSpheres(spheresDown, 0.01, sofa::type::RGBAColor::green());
+ //vparams->drawTool()->drawTriangles(pointsUp, sofa::type::RGBAColor::red());
+ //vparams->drawTool()->drawTriangles(pointsDown, sofa::type::RGBAColor::green());
}