6 #include <unordered_map>
15 void ConnecRemv::disp()
17 cout <<
"connrmv: ki " << keepind <<
" | tobj " << typeobj <<
" | rmvind ";
18 DisplayVector(rmvind);
23 void SpawnAtVertex(
snake &snakein,
int indVert)
26 int subVert, nVert, nEdge, nSurf, nVolu;
28 vector<int> edgeInds, surfInds, voluInds;
29 vector<int> edgeSubs, surfSubs, voluSubs;
32 unordered_multimap<int, int> hashEdgeInds, hashVoluInds, hashSurfInds;
34 is3D = snakein.snakemesh()->volus.size() > 0;
36 subVert = snakein.snakemesh()->verts.find(indVert);
38 edgeInds = snakein.snakemesh()->verts(subVert)->edgeind;
39 edgeSubs = snakein.snakemesh()->edges.find_list(edgeInds);
40 surfInds = ConcatenateVectorField(snakein.snakemesh()->edges, &edge::surfind, edgeSubs);
44 surfSubs = snakein.snakemesh()->surfs.find_list(surfInds);
45 voluInds = ConcatenateVectorField(snakein.snakemesh()->surfs, &surf::voluind, surfSubs);
50 voluSubs = snakein.snakemesh()->volus.find_list(voluInds);
54 voluSubs = snakein.snakemesh()->volus.find_list(voluInds);
58 nVert = edgeInds.size();
59 nEdge = surfInds.size();
60 nSurf = voluInds.size();
63 newsnake.Init(snakein.snakemesh(), nVert, nEdge, nSurf, nVolu);
64 newsnake.VertIsIn(indVert);
66 SpawnAtVertexVert(newsnake, nVert, indVert, subVert, surfInds, edgeInds, edgeSubs, hashSurfInds);
68 SpawnAtVertexEdge(newsnake, nEdge, surfInds, edgeInds, voluInds, surfSubs, hashEdgeInds, hashVoluInds);
72 SpawnAtVertexSurf3D(newsnake, nSurf, surfInds, voluInds, voluSubs, hashSurfInds);
74 SpawnAtVertexVolu(newsnake, nSurf);
78 SpawnAtVertexSurf2D(newsnake, nEdge, voluInds);
81 snakein.SetMaxIndexNM();
83 snakein.MakeCompatible_inplace(newsnake);
86 snakein.Concatenate(newsnake);
89 void SpawnAtVertexVert(
snake &newsnake,
int nVert,
int indVert,
int subVert,
const vector<int> &surfInds,
90 const vector<int> &edgeInds,
const vector<int> &edgeSubs,
91 unordered_multimap<int, int> &hashSurfInds)
94 vector<int> edgeSubsTemp;
96 newsnake.snakeconn.verts.PopulateIndices();
97 newsnake.snaxs.PopulateIndices();
98 for (ii = 0; ii < nVert; ++ii)
101 jj = int(newsnake.snakemesh()->edges(edgeSubs[ii])->vertind[0] == indVert);
102 newsnake.snaxs[ii].set(newsnake.snaxs(ii)->index, 0.0, 0.5, indVert,
103 newsnake.snakemesh()->edges(edgeSubs[ii])->vertind[jj], edgeInds[ii], 0, -1);
105 edgeSubsTemp = FindSubList(newsnake.snakemesh()->edges(edgeSubs[ii])->surfind, surfInds, hashSurfInds);
106 newsnake.snakeconn.verts[ii].edgeind = edgeSubsTemp;
107 newsnake.snakeconn.verts[ii].coord = newsnake.snakemesh()->verts(subVert)->coord;
109 newsnake.snakeconn.verts.ChangeIndices(0, 1, 0, 0);
112 void SpawnAtVertexEdge(
snake &newsnake,
int nEdge,
const vector<int> &surfInds,
const vector<int> &edgeInds,
113 const vector<int> &voluInds,
const vector<int> &surfSubs,
114 unordered_multimap<int, int> &hashEdgeInds, unordered_multimap<int, int> &hashVoluInds)
117 vector<int> surfSubsTemp, vertSubsTemp;
119 newsnake.snakeconn.edges.PopulateIndices();
120 newsnake.snaxedges.PopulateIndices();
122 for (ii = 0; ii < nEdge; ++ii)
124 newsnake.snaxedges[ii].surfind = surfInds[ii];
125 if (newsnake.Check3D())
127 surfSubsTemp = FindSubList(newsnake.snakemesh()->surfs(surfSubs[ii])->voluind, voluInds, hashVoluInds);
128 newsnake.snakeconn.edges[ii].surfind = surfSubsTemp;
129 for (jj = 0; jj < int(surfSubsTemp.size()); ++jj)
131 newsnake.snakeconn.edges[ii].surfind[jj]++;
136 vertSubsTemp = FindSubList(newsnake.snakemesh()->surfs(surfSubs[ii])->edgeind, edgeInds, hashEdgeInds);
138 for (jj = 0; jj < int(vertSubsTemp.size()); ++jj)
140 if (vertSubsTemp[jj] >= 0)
142 newsnake.snakeconn.edges[ii].vertind[kk] = vertSubsTemp[jj];
148 newsnake.snakeconn.edges.ChangeIndices(1, 0, 0, 0);
149 if (!newsnake.Check3D())
151 for (ii = 0; ii < nEdge; ++ii)
153 newsnake.snakeconn.edges[ii].surfind.assign(2, 0);
154 newsnake.snakeconn.edges[ii].surfind[0] = 1;
155 newsnake.snakeconn.edges[ii].surfind[1] = 0;
159 void SpawnAtVertexSurf3D(
snake &newsnake,
int nSurf,
const vector<int> &surfInds,
const vector<int> &voluInds,
160 const vector<int> &voluSubs, unordered_multimap<int, int> &hashSurfInds)
163 vector<int> surfSubsTemp;
165 newsnake.snakeconn.surfs.PopulateIndices();
166 newsnake.snaxsurfs.PopulateIndices();
167 for (ii = 0; ii < nSurf; ++ii)
169 newsnake.snaxsurfs[ii].voluind = voluInds[ii];
170 newsnake.snakeconn.surfs[ii].voluind[0] = 1;
173 surfSubsTemp = FindSubList(newsnake.snakemesh()->volus(voluSubs[ii])->surfind, surfInds, hashSurfInds);
176 for (jj = 0; jj < int(surfSubsTemp.size()); ++jj)
178 if (surfSubsTemp[jj] >= 0)
180 newsnake.snakeconn.surfs[ii].edgeind.push_back(surfSubsTemp[jj]);
184 newsnake.snakeconn.surfs.ChangeIndices(0, 1, 0, 0);
187 void SpawnAtVertexSurf2D(
snake &newsnake,
int nEdge,
const vector<int> &voluInds)
192 newsnake.snakeconn.surfs.PopulateIndices();
193 newsnake.snaxsurfs.PopulateIndices();
195 newsnake.snaxsurfs[ii].voluind = voluInds[ii];
196 newsnake.snakeconn.surfs[ii].voluind[0] = 0;
198 for (jj = 0; jj < int(nEdge); ++jj)
200 newsnake.snakeconn.surfs[ii].edgeind.push_back(jj + 1);
206 void SpawnAtVertexVolu(
snake &newsnake,
int nSurf)
210 newsnake.snakeconn.volus.PopulateIndices();
211 newsnake.snakeconn.volus[0].surfind.reserve(nSurf);
212 for (ii = 0; ii < nSurf; ++ii)
214 newsnake.snakeconn.volus[0].surfind.push_back(ii + 1);
220 void MergeAllContactVertices(
snake &fullsnake, vector<int> &isImpact)
223 int ii, jj, nImpacts;
224 vector<int> snaxToRemove, vertSameSub, subVelTo0;
225 vector<bool> isImpactDone;
228 nImpacts = isImpact.size() / 2;
229 impactInd.vec.reserve(nImpacts);
230 impactTarg.vec.reserve(nImpacts);
231 snaxToRemove.reserve(nImpacts);
232 isImpactDone.assign(nImpacts,
false);
234 for (ii = 0; ii < int(isImpact.size()); ii = ii + 2)
236 impactInd.vec.push_back(isImpact[ii]);
238 for (ii = 1; ii < int(isImpact.size()); ii = ii + 2)
240 impactTarg.vec.push_back(isImpact[ii]);
242 impactInd.GenerateHash();
243 impactTarg.GenerateHash();
245 for (ii = 0; ii < nImpacts; ++ii)
247 if (!isImpactDone[ii])
249 isImpactDone[ii] =
true;
250 if (impactTarg.vec[ii] > 0)
252 fullsnake.snakeconn.SwitchIndex(1, impactInd.vec[ii], impactTarg.vec[ii]);
253 subVelTo0.push_back(fullsnake.snaxs.find(impactTarg.vec[ii]));
255 snaxToRemove.push_back(impactInd.vec[ii]);
256 vertSameSub = ReturnDataEqualRange(impactTarg.vec[ii], impactInd.hashTable);
258 for (jj = 0; jj < int(vertSameSub.size()); jj++)
260 isImpactDone[vertSameSub[jj]] =
true;
262 vertSameSub = ReturnDataEqualRange(impactTarg.vec[ii], impactTarg.hashTable);
263 for (jj = 0; jj < int(vertSameSub.size()); jj++)
265 isImpactDone[vertSameSub[jj]] =
true;
270 for (ii = 0; ii < int(subVelTo0.size()); ii++)
272 fullsnake.snaxs[subVelTo0[ii]].v = 0.0;
274 fullsnake.snaxs.remove(snaxToRemove);
275 fullsnake.snakeconn.verts.remove(snaxToRemove);
278 void SpawnArrivedSnaxels(
snake &fullsnake,
const vector<int> &isImpact)
280 snake fwdSnake, bwdSnake;
283 fwdSnake.Init(fullsnake.snakemesh(), 0, 0, 0, 0);
284 bwdSnake.Init(fullsnake.snakemesh(), 0, 0, 0, 0);
288 vertNoSpawn.vec.push_back(0);
289 vertNoSpawn.GenerateHash();
290 SpawnArrivedSnaxelsDir(fullsnake, bwdSnake, isImpact, -1, vertNoSpawn);
291 SpawnArrivedSnaxelsDir(fullsnake, fwdSnake, isImpact, -2, vertNoSpawn);
306 fullsnake.SetMaxIndexNM();
307 fullsnake.MakeCompatible_inplace(bwdSnake);
309 fullsnake.Concatenate(bwdSnake);
311 fullsnake.SetMaxIndexNM();
312 fullsnake.MakeCompatible_inplace(fwdSnake);
314 fullsnake.Concatenate(fwdSnake);
316 fullsnake.PrepareForUse();
319 void SpawnArrivedSnaxelsDir(
snake &fullsnake,
snake &partSnake,
const vector<int> &isImpact,
int dir,
322 int nVert, nEdge, nSurf, nVolu, ii, jj, kk;
324 vector<int> vertSpawn, subList;
325 int snax::*mp = NULL;
335 mp = &snax::fromvert;
343 cerr <<
"Error: Direction of arrived snaxel is invalid " << endl;
344 cerr <<
" in function:" << __PRETTY_FUNCTION__ << endl;
347 isReady = fullsnake.snaxs.checkready();
349 for (ii = 0; ii < int(isImpact.size()); ii = ii + 2)
351 if (isImpact[ii + 1] == dir)
353 jj = fullsnake.snaxs.find(isImpact[ii]);
354 if (!fullsnake.snakemesh()->verts.isearch(fullsnake.snaxs(jj)->*mp)->isBorder)
356 jj = fullsnake.snaxs.find(isImpact[ii]);
357 vertSpawn.push_back(fullsnake.snaxs(jj)->*mp);
359 nVert = nVert + fullsnake.snakemesh()->verts.isearch(fullsnake.snaxs(jj)->*mp)->edgeind.size();
361 subList = fullsnake.snakemesh()->edges.find_list(
362 fullsnake.snakemesh()->verts.isearch(fullsnake.snaxs(jj)->*mp)->edgeind);
364 for (kk = 0; kk < int(subList.size()); kk++)
366 nEdge = nEdge + fullsnake.snakemesh()->edges(subList[kk])->surfind.size();
371 fullsnake.snaxs[jj].isfreeze = 1;
374 fullsnake.snaxs.ForceArrayReady();
381 partSnake.reserve(nVert, nEdge, nSurf, nVolu);
390 kk = int(vertSpawn.size());
392 for (ii = 0; ii < kk; ++ii)
394 if (vertNoSpawn.find(vertSpawn[ii]) == -1)
396 SpawnAtVertex(partSnake, vertSpawn[ii]);
402 vertNoSpawn.vec.insert(vertNoSpawn.vec.end(), vertSpawn.begin(), vertSpawn.end());
403 vertNoSpawn.GenerateHash();
407 void dispconnrmv(vector<ConnecRemv> conn)
409 for (
int i = 0; i < int(conn.size()); ++i)
415 void SnaxEdgeConnecDetection(
snake &snakein, vector<ConnecRemv> &connecEdit)
417 int ii, snaxSub1, snaxSub2, nSnaxEdge;
419 nSnaxEdge = snakein.snaxedges.size();
421 tempConnec.typeobj = 1;
422 tempConnec2.typeobj = 2;
424 for (ii = 0; ii < nSnaxEdge; ++ii)
426 if (snakein.snakeconn.edges(ii)->vertind.size() > 0)
428 snaxSub1 = snakein.snaxs.find(snakein.snakeconn.edges(ii)->vertind[0]);
429 snaxSub2 = snakein.snaxs.find(snakein.snakeconn.edges(ii)->vertind[1]);
430 if (snaxSub1 == -1 && snaxSub2 == -1)
436 cout <<
"SnaxEdgeConnecDetection invalid edge 2 snaxel inexistant:";
437 snakein.snakeconn.edges(ii)->disp();
439 else if (snaxSub1 == -1)
441 cout <<
"SnaxEdgeConnecDetection invalid edge 1(1) snaxel inexistant:";
442 snakein.snakeconn.edges(ii)->disp();
444 else if (snaxSub2 == -1)
446 cout <<
"SnaxEdgeConnecDetection invalid edge 1(2) snaxel inexistant:";
447 snakein.snakeconn.edges(ii)->disp();
449 else if (snakein.snaxs(snaxSub1)->edgeind == snakein.snaxs(snaxSub2)->edgeind)
451 if (snaxSub1 != snaxSub2)
453 tempConnec.rmvind.clear();
454 tempConnec.keepind = snakein.snaxs(snaxSub1)->index;
455 tempConnec.rmvind.push_back(snakein.snaxs(snaxSub2)->index);
456 connecEdit.push_back(tempConnec);
458 tempConnec2.rmvind.clear();
459 tempConnec2.keepind = snakein.snaxedges(ii)->index;
460 tempConnec2.rmvind.push_back(snakein.snaxedges(ii)->index);
461 connecEdit.push_back(tempConnec2);
473 void SnaxNoConnecDetection(
const mesh &snakeconn, vector<ConnecRemv> &connecEdit)
477 nSnax = snakeconn.verts.size();
479 tempConnec.typeobj = 1;
481 for (ii = 0; ii < nSnax; ++ii)
483 if (snakeconn.verts(ii)->edgeind.size() == 0)
485 tempConnec.rmvind.clear();
486 tempConnec.keepind = snakeconn.verts(ii)->index;
487 tempConnec.rmvind.push_back(snakeconn.verts(ii)->index);
489 connecEdit.push_back(tempConnec);
494 void MergeCleanSnake(
snake &fullsnake, vector<int> &isImpact)
502 fullsnake.SnaxImpactDetection(isImpact);
503 fullsnake.PrepareForUse();
510 fullsnake.SnaxImpactDetection(isImpact);
511 nI = isImpact.size() / 2;
512 for (ii = 0; ii < nI; ++ii)
515 temp.push_back(isImpact[ii * 2]);
516 temp.push_back(isImpact[ii * 2 + 1]);
517 if (temp[0] >= 0 && temp[1] >= 0)
519 MergeAllContactVertices(fullsnake, temp);
520 CleanupSnakeConnec(fullsnake);
521 fullsnake.PrepareForUse();
534 fullsnake.PrepareForUse();
537 void CleanupSnakeConnec(
snake &snakein)
539 vector<ConnecRemv> connecEdit;
541 vector<int> indRmvVert, indRmvEdge, indRmvSurf, indRmvVolu, indDelSurf;
543 int ii, jj, kk, nEdgeConn, nSurfConn, nEdgeSurfConn, nVertConn, nSnaxConn, nEdgeSameSurfConn, nAboveN;
546 bool flag, iterFlag, contFlag;
552 auto itVert = indRmvVert.begin();
553 auto itEdge = indRmvEdge.begin();
554 auto itSurf = indRmvSurf.begin();
555 auto itVolu = indRmvVolu.begin();
557 snakein.snakeconn.TightenConnectivity();
558 snakein.HashParent();
560 if (snakein.Check3D())
562 snakein.snakeconn.TestConnectivityBiDir(__PRETTY_FUNCTION__);
573 indDelEdge.vec.clear();
575 snakein.PrepareForUse(
false);
576 itVert = indRmvVert.begin();
577 itEdge = indRmvEdge.begin();
578 itSurf = indRmvSurf.begin();
579 itVolu = indRmvVolu.begin();
583 SnaxNoConnecDetection(snakein.snakeconn, connecEdit);
585 nSnaxConn = int(connecEdit.size());
588 SnaxEdgeConnecDetection(snakein, connecEdit);
589 nVertConn = int(connecEdit.size());
591 for (ii = nSnaxConn; ii < nVertConn; ++ii)
593 if (connecEdit[ii].typeobj == 1)
596 snakein.snakeconn.SwitchIndex(connecEdit[ii].typeobj, connecEdit[ii].rmvind[0], connecEdit[ii].keepind,
597 connecEdit[ii].scopeind);
599 for (jj = ii + 1; jj < nVertConn; ++jj)
601 if (connecEdit[jj].typeobj == 1)
603 if (connecEdit[jj].keepind != connecEdit[jj].rmvind[0] &&
604 (connecEdit[jj].rmvind[0] == connecEdit[ii].rmvind[0] ||
605 connecEdit[jj].rmvind[0] == connecEdit[ii].keepind ||
606 connecEdit[jj].keepind == connecEdit[ii].rmvind[0] ||
607 connecEdit[jj].keepind == connecEdit[ii].keepind))
609 connecEdit[jj].keepind = connecEdit[ii].keepind;
610 connecEdit[jj].rmvind[0] = connecEdit[ii].rmvind[0];
614 connecEdit[jj + 1].keepind = connecEdit[ii + 1].keepind;
615 connecEdit[jj + 1].rmvind[0] = -1;
626 for (ii = nSnaxConn; ii < nVertConn; ++ii)
628 if (connecEdit[ii].typeobj == 2)
630 if (connecEdit[ii].rmvind[0] > 0)
632 snakein.snakeconn.RemoveIndex(2, connecEdit[ii].rmvind[0]);
633 snakein.snaxedges.DeHashParent(snakein.snaxedges.find(connecEdit[ii].rmvind[0]));
637 connecEdit[ii].rmvind[0] = connecEdit[ii].keepind;
644 jj = snakein.snakeconn.edges.size();
645 for (ii = 0; ii < jj; ++ii)
647 if (snakein.snakeconn.edges(ii)->vertind.size() > 1 &&
648 (snakein.snakeconn.edges(ii)->vertind[0] == snakein.snakeconn.edges(ii)->vertind[1]))
651 snakein.snakeconn.RemoveIndex(2, snakein.snakeconn.edges(ii)->index);
652 snakein.snaxedges.DeHashParent(snakein.snaxedges.find(snakein.snakeconn.edges(ii)->index));
653 tempConnec.typeobj = 2;
654 tempConnec.keepind = snakein.snakeconn.edges(ii)->index;
655 tempConnec.rmvind.clear();
656 tempConnec.rmvind.push_back(tempConnec.keepind);
657 connecEdit.push_back(tempConnec);
660 nVertConn = int(connecEdit.size());
664 IdentifyMergEdgeSameSurfConnec(snakein, connecEdit);
665 nEdgeSameSurfConn = int(connecEdit.size());
666 for (ii = nVertConn; ii < nEdgeSameSurfConn; ++ii)
668 for (jj = 0; jj < int(connecEdit[ii].rmvind.size()); ++jj)
670 snakein.snakeconn.SwitchIndex(connecEdit[ii].typeobj, connecEdit[ii].rmvind[jj], connecEdit[ii].keepind,
671 connecEdit[ii].scopeind);
672 if (connecEdit[ii].typeobj == 2)
674 snakein.snaxedges.DeHashParent(snakein.snaxedges.find(connecEdit[ii].rmvind[jj]));
689 IdentifyMergEdgeConnec(snakein, connecEdit);
690 nEdgeConn = int(connecEdit.size());
691 iterFlag = int(nEdgeConn) > 0;
692 if (contFlag || iterFlag)
694 for (ii = nEdgeSameSurfConn; ii < nEdgeConn; ++ii)
696 for (jj = 0; jj < int(connecEdit[ii].rmvind.size()); ++jj)
698 snakein.snakeconn.SwitchIndex(connecEdit[ii].typeobj, connecEdit[ii].rmvind[jj],
699 connecEdit[ii].keepind, connecEdit[ii].scopeind);
702 SnaxNoConnecDetection(snakein.snakeconn, connecEdit);
703 nEdgeConn = int(connecEdit.size());
705 if (snakein.Check3D())
707 IdentifyMergSurfConnec(snakein, connecEdit);
709 nSurfConn = int(connecEdit.size());
710 for (ii = nEdgeConn; ii < nSurfConn; ++ii)
712 for (jj = 0; jj < int(connecEdit[ii].rmvind.size()); ++jj)
714 snakein.snakeconn.SwitchIndex(connecEdit[ii].typeobj, connecEdit[ii].rmvind[jj],
715 connecEdit[ii].keepind, connecEdit[ii].scopeind);
721 for (ii = 0; ii < nEdgeConn; ++ii)
723 if (connecEdit[ii].typeobj == 2)
725 indRmvEdge.insert(itEdge, connecEdit[ii].rmvind.begin(), connecEdit[ii].rmvind.end());
726 itEdge = indRmvEdge.end();
728 else if (connecEdit[ii].typeobj == 3)
730 cerr <<
"Should not be here " << endl;
732 else if (connecEdit[ii].typeobj == 5 || connecEdit[ii].typeobj == 1)
734 indRmvVert.insert(itVert, connecEdit[ii].rmvind.begin(), connecEdit[ii].rmvind.end());
735 itVert = indRmvVert.end();
744 if (snakein.Check3D())
746 ModifyMergVoluConnec(snakein, connecEdit, indRmvVert);
751 ModifyMergSurf2DConnec(snakein, connecEdit);
754 nEdgeSurfConn = int(connecEdit.size());
755 for (ii = nEdgeConn; ii < nEdgeSurfConn; ++ii)
757 if (connecEdit[ii].typeobj == 3)
759 indRmvSurf.insert(itSurf, connecEdit[ii].rmvind.begin(), connecEdit[ii].rmvind.end());
760 itSurf = indRmvSurf.end();
762 else if (connecEdit[ii].typeobj == 4)
764 indRmvVolu.insert(itVolu, connecEdit[ii].rmvind.begin(), connecEdit[ii].rmvind.end());
765 itVolu = indRmvVolu.end();
767 else if (connecEdit[ii].typeobj == 2)
769 cerr <<
"Should not be Here " << endl;
771 else if (connecEdit[ii].typeobj == 5)
773 cerr <<
"Should not be Here " << endl;
784 indDelEdge.vec.reserve(nEdgeConn);
785 for (ii = 0; ii < nEdgeConn; ++ii)
787 if (connecEdit[ii].typeobj == 2)
789 if (snakein.snakeconn.edges.isearch(connecEdit[ii].keepind)->vertind[0] ==
790 snakein.snakeconn.edges.isearch(connecEdit[ii].keepind)->vertind[1])
792 indDelEdge.vec.push_back(connecEdit[ii].keepind);
796 indDelEdge.GenerateHash();
798 kk = indDelEdge.vec.size();
799 for (ii = 0; ii < kk; ++ii)
801 snakein.snakeconn.RemoveIndex(2, indDelEdge.vec[ii]);
804 kk = int(snakein.snakeconn.surfs.size());
805 indDelSurf.reserve(nEdgeSurfConn - nEdgeConn);
806 for (ii = 0; ii < kk; ++ii)
808 flag = int(snakein.snakeconn.surfs(ii)->edgeind.size()) == 0;
811 indDelSurf.push_back(snakein.snakeconn.surfs(ii)->index);
815 kk = indDelSurf.size();
816 for (ii = 0; ii < kk; ++ii)
818 snakein.snakeconn.RemoveIndex(3, indDelSurf[ii]);
820 kk = connecEdit.size();
821 SnaxNoConnecDetection(snakein.snakeconn, connecEdit);
822 nEdgeSurfConn = connecEdit.size();
823 itVert = indRmvVert.end();
824 for (ii = kk; ii < nEdgeSurfConn; ++ii)
826 if (connecEdit[ii].typeobj == 5 || connecEdit[ii].typeobj == 1)
828 indRmvVert.insert(itVert, connecEdit[ii].rmvind.begin(), connecEdit[ii].rmvind.end());
829 itVert = indRmvVert.end();
836 indRmvSurf.insert(indRmvSurf.end(), indDelSurf.begin(), indDelSurf.end());
840 indRmvEdge.insert(indRmvEdge.end(), indDelEdge.vec.begin(), indDelEdge.vec.end());
849 snakein.snakeconn.TightenConnectivity();
852 for (ii = 0; ii < int(indRmvVert.size()); ii++)
858 if (snakein.snakemesh()
859 ->edges.isearch(snakein.snaxs.isearch(indRmvVert[ii])->edgeind)
860 ->surfind.size() == snakein.snakeconn.verts.isearch(indRmvVert[ii])->edgeind.size())
864 cout << endl <<
"displaying vertices about to be removed by nAboveN cond:" << endl;
867 snakein.snakeconn.verts.isearch(indRmvVert[ii])->disp();
868 indRmvVert.erase(indRmvVert.begin() + ii);
875 CheckSnakeRemovalsEdge(snakein, indRmvEdge);
877 snakein.snakeconn.surfs.remove(indRmvSurf);
878 snakein.snakeconn.edges.remove(indRmvEdge);
879 snakein.snakeconn.verts.remove(indRmvVert);
880 snakein.snakeconn.volus.remove(indRmvVolu);
881 snakein.snaxs.remove(indRmvVert);
882 snakein.snaxedges.remove(indRmvEdge);
883 snakein.snaxsurfs.remove(indRmvSurf);
885 snakein.snakeconn.TightenConnectivity();
886 snakein.HashArrayNM();
890 if (snakein.Check3D())
892 ii = snakein.snakeconn.TestConnectivityBiDir(__PRETTY_FUNCTION__,
false);
895 dispconnrmv(connecEdit);
901 iterFlag = int(connecEdit.size()) > 0;
915 snakein.HashArrayNM();
916 snakein.CheckConnectivity();
917 snakein.OrderEdges();
918 snakein.ForceCloseContainers();
919 snakein.snakeconn.TightenConnectivity();
921 if (snakein.Check3D())
923 snakein.snakeconn.TestConnectivityBiDir(__PRETTY_FUNCTION__);
928 snakein.PrepareForUse();
939 void IdentifyMergEdgeSameSurfConnec(
const snake &snakein, vector<ConnecRemv> &connecEdit)
941 vector<bool> isObjDone;
943 vector<int> tempSub, tempSub2, tempSub3, tempCount, tempCount2;
947 int nSnaxEdge, ii, jj, nParent, stepCheck, nSurf, nTemp;
949 if (snakein.Check3D())
952 nSnaxEdge = snakein.snaxedges.size();
955 isObjDone.reserve(nSnaxEdge);
957 isObjDone.assign(nSnaxEdge,
false);
958 for (ii = 0; ii < nSnaxEdge; ++ii)
962 if (snakein.snaxedges.memberIsHashParent(ii))
964 nParent = snakein.snaxedges.countparent(snakein.snaxedges(ii)->KeyParent());
967 nSurf = int(snakein.snakeconn.edges(ii)->surfind.size());
971 IndentifyEdgeSameSurf(snakein, ii, stepCheck, tempSub, tempSub2, tempSub3, tempIndHash2,
972 edge2Surf, tempCount2);
974 nTemp = tempSub2.size();
975 for (jj = 0; jj < nTemp; ++jj)
977 isAnyDone = isAnyDone || isObjDone[tempSub2[jj]];
979 if (stepCheck < nSurf && !isAnyDone)
981 IdentifyMergeEdgeGeneral(snakein, isObjDone, connecEdit, tempConnec, tempConnec2, tempSub2,
982 tempSub3, tempCount, tempIndHash);
987 isObjDone[ii] =
true;
993 void IndentifyEdgeSameSurf(
const snake &snakein,
int currSub,
int &stepCheck, vector<int> &tempSub,
1002 snakein.snaxedges.findsiblings(snakein.snaxedges(currSub)->KeyParent(), tempSub);
1003 edge2Surf.vec.clear();
1004 tempIndHash.vec = ConcatenateVectorField(snakein.snakeconn.edges, &edge::surfind, tempSub);
1006 for (ii = 0; ii < int(tempSub.size()); ++ii)
1008 for (jj = 0; jj < int(snakein.snakeconn.edges(tempSub[ii])->surfind.size()); ++jj)
1010 edge2Surf.vec.push_back(ii);
1016 tempIndHash.GenerateHash();
1017 edge2Surf.GenerateHash();
1018 tempCount = tempIndHash.count(snakein.snakeconn.edges(currSub)->surfind);
1019 tempCount.push_back(0);
1023 nTemp = tempCount.size() - 1;
1025 while (tempCount[stepCheck] < 2 && stepCheck <= nTemp)
1030 if (stepCheck < nTemp)
1032 tempSub3 = tempIndHash.findall(snakein.snakeconn.edges(currSub)->surfind[stepCheck]);
1034 for (ii = 0; ii < int(tempSub3.size()); ++ii)
1036 tempSub2.push_back(tempSub[edge2Surf.vec[tempSub3[ii]]]);
1041 void IdentifyMergEdgeConnec(
const snake &snakein, vector<ConnecRemv> &connecEdit)
1043 vector<bool> isObjDone;
1044 vector<int> tempSub, tempSub2, tempCount;
1047 int nSnaxEdge, ii, nParent;
1051 nSnaxEdge = snakein.snaxedges.size();
1054 isObjDone.reserve(nSnaxEdge);
1056 isObjDone.assign(nSnaxEdge,
false);
1057 for (ii = 0; ii < nSnaxEdge; ++ii)
1061 nParent = snakein.snaxedges.countparent(snakein.snaxedges(ii)->KeyParent());
1064 snakein.snaxedges.findsiblings(snakein.snaxedges(ii)->KeyParent(), tempSub);
1065 IdentifyMergeEdgeGeneral(snakein, isObjDone, connecEdit, tempConnec, tempConnec2, tempSub, tempSub2,
1066 tempCount, tempIndHash);
1068 isObjDone[ii] =
true;
1073 void IdentifyMergeEdgeGeneral(
const snake &snakein, vector<bool> &isObjDone, vector<ConnecRemv> &connecEdit,
1077 int jj, jjStart, nTemp;
1080 tempIndHash.vec.clear();
1082 tempIndHash.vec = ConcatenateVectorField(snakein.snakeconn.edges, &edge::vertind, tempSub);
1083 tempIndHash.GenerateHash();
1084 tempCount = tempIndHash.count(tempIndHash.vec);
1085 tempCount.push_back(0);
1086 nTemp = tempCount.size() - 1;
1088 tempConnec2.scopeind.clear();
1089 for (jj = 0; jj < int(tempSub.size()); ++jj)
1091 tempConnec2.scopeind.push_back(snakein.snaxedges(tempSub[jj])->index);
1095 while (tempCount[jjStart] != 1 && jjStart < nTemp)
1099 while (jjStart < nTemp)
1101 IdentifyMergeEdgeGeneralChain(snakein, isObjDone, connecEdit, tempConnec, tempConnec2, tempSub, tempSub2,
1102 tempCount, tempIndHash, jjStart);
1105 while (tempCount[jjStart] != 1 && jjStart < nTemp)
1113 while (tempCount[jjStart] != 2 && jjStart < nTemp)
1117 while (jjStart < nTemp)
1119 IdentifyMergeEdgeGeneralChain(snakein, isObjDone, connecEdit, tempConnec, tempConnec2, tempSub, tempSub2,
1120 tempCount, tempIndHash, jjStart);
1125 while (tempCount[jjStart] != 2 && jjStart < nTemp)
1132 void IdentifyMergeEdgeGeneralChain(
const snake &snakein, vector<bool> &isObjDone, vector<ConnecRemv> &connecEdit,
1138 bool flagMoved, flag3;
1140 tempConnec.rmvind.clear();
1141 tempConnec2.rmvind.clear();
1142 tempConnec.typeobj = 2;
1143 tempConnec2.typeobj = 5;
1145 tempCount[jjStart] = 0;
1146 tempConnec.keepind = snakein.snaxedges(tempSub[jjStart / 2])->index;
1147 isObjDone[tempSub[jjStart / 2]] =
true;
1149 jjNext = jj + (1 - ((jj % 2) * 2));
1151 while (tempCount[jjNext] > 1)
1156 if (tempCount[jjNext] > 2)
1159 DisplayVector(tempCount);
1160 DisplayVector(tempIndHash.vec);
1162 for (
int i = 0; i < int(tempSub.size()); ++i)
1164 snakein.snakeconn.edges(tempSub[i])->disp();
1166 for (
int i = 0; i < int(tempSub.size()); ++i)
1168 snakein.snaxedges(tempSub[i])->disp();
1170 for (
int i = 0; i < int(tempIndHash.vec.size()); ++i)
1172 snakein.snakeconn.verts.isearch(tempIndHash.vec[i])->disp();
1174 for (
int i = 0; i < int(tempIndHash.vec.size()); ++i)
1176 snakein.snaxs.isearch(tempIndHash.vec[i])->disp();
1179 cerr <<
"Error: Algorithm not conceived for this case " << endl;
1180 cerr <<
" snake has more than 2 edges connected to the same snaxel "
1181 "inside the same surface "
1183 cerr <<
" in function:" << __PRETTY_FUNCTION__ << endl;
1187 flag3 = tempCount[jjNext] == 3;
1190 tempConnec2.rmvind.push_back(tempIndHash.vec[jjNext]);
1193 tempCount[jjNext] = 0;
1194 tempSub2 = tempIndHash.findall(tempIndHash.vec[jjNext]);
1198 while (jj < 4 && tempSub2[jj] == jjNext)
1205 while ((tempSub2[jj] == jjNext || tempCount[tempSub2[jj]] < 3) && jj < 4)
1209 tempCount[tempSub2[jj]] = 1;
1210 while ((tempSub2[jj] == jjNext || tempCount[tempSub2[jj]] < 3) && jj < 4)
1219 cerr <<
"Error: Algorithm not conceived for this case " << endl;
1220 cerr <<
" jj>3 Unsafe read has happened " << endl;
1221 cerr <<
" in function:" << __PRETTY_FUNCTION__ << endl;
1228 tempConnec.rmvind.push_back(snakein.snaxedges(tempSub[jj / 2])->index);
1229 isObjDone[tempSub[jj / 2]] =
true;
1231 jjNext = jj + (1 - ((jj % 2) * 2));
1233 tempConnec2.keepind = tempIndHash.vec[jjNext];
1236 connecEdit.push_back(tempConnec);
1237 connecEdit.push_back(tempConnec2);
1241 void IdentifyMergSurfConnec(
const snake &snakein, vector<ConnecRemv> &connecEdit)
1243 vector<bool> isObjDone;
1244 vector<int> tempSub, tempSub2, tempCount;
1247 int nSnaxSurf, ii, nParent;
1251 nSnaxSurf = snakein.snaxsurfs.size();
1254 isObjDone.reserve(nSnaxSurf);
1256 isObjDone.assign(nSnaxSurf,
false);
1257 for (ii = 0; ii < nSnaxSurf; ++ii)
1261 nParent = snakein.snaxsurfs.countparent(snakein.snaxsurfs(ii)->KeyParent());
1265 snakein.snaxsurfs.findsiblings(snakein.snaxsurfs(ii)->KeyParent(), tempSub);
1266 IdentifyMergeSurfGeneral(snakein, isObjDone, connecEdit, tempConnec, tempSub, tempSub2, tempCount,
1267 edge2Surf, tempIndHash);
1269 isObjDone[ii] =
true;
1274 void IdentifyMergeSurfGeneral(
const snake &snakein, vector<bool> &isObjDone, vector<ConnecRemv> &connecEdit,
1275 ConnecRemv &tempConnec, vector<int> &tempSub, vector<int> &tempSub2,
1280 int ii, jj, jjStart, nTemp;
1282 edge2Surf.vec.clear();
1283 tempIndHash.vec = ConcatenateVectorField(snakein.snakeconn.surfs, &surf::edgeind, tempSub);
1285 for (ii = 0; ii < int(tempSub.size()); ++ii)
1287 for (jj = 0; jj < int(snakein.snakeconn.surfs(tempSub[ii])->edgeind.size()); ++jj)
1289 edge2Surf.vec.push_back(ii);
1295 tempIndHash.GenerateHash();
1296 edge2Surf.GenerateHash();
1297 tempCount = tempIndHash.count(tempIndHash.vec);
1298 tempCount.push_back(0);
1301 nTemp = tempCount.size() - 1;
1304 while (tempCount[jjStart] <= 1 && jjStart < nTemp)
1311 if (jjStart < nTemp)
1316 tempConnec.rmvind.clear();
1318 tempSub2 = tempIndHash.findall(tempIndHash.vec[jjStart]);
1320 tempConnec.typeobj = 3;
1321 isObjDone[tempSub[edge2Surf.vec[jjStart]]] =
true;
1322 tempConnec.keepind = snakein.snakeconn.surfs(tempSub[edge2Surf.vec[jjStart]])->index;
1325 tempCount[jjStart] = 0;
1327 IdentifyMergeSurfRecursive(snakein, isObjDone, tempCount, edge2Surf, tempIndHash, tempConnec, tempSub,
1329 if (tempConnec.rmvind.size() > 0)
1331 sort(tempConnec.rmvind);
1332 unique(tempConnec.rmvind);
1333 connecEdit.push_back(tempConnec);
1339 while (tempCount[jjStart] <= 1 && jjStart < nTemp)
1343 }
while (jjStart < nTemp);
1351 void IdentifyMergeSurfRecursive(
const snake &snakein, vector<bool> &isObjDone, vector<int> &tempCount,
1353 ConnecRemv &tempConnec,
const vector<int> &tempSub,
const vector<int> &tempSub2,
1359 vector<int> tempSurf, tempRecur;
1361 for (ii = 0; ii < int(tempSub2.size()); ++ii)
1363 if (tempSub2[ii] != excludeSub)
1365 if (!isObjDone[tempSub[edge2Surf.vec[tempSub2[ii]]]])
1367 tempConnec.rmvind.push_back(snakein.snakeconn.surfs(tempSub[edge2Surf.vec[tempSub2[ii]]])->index);
1369 isObjDone[tempSub[edge2Surf.vec[tempSub2[ii]]]] =
true;
1370 tempCount[tempSub2[ii]] = 0;
1373 tempSurf = edge2Surf.findall(edge2Surf.vec[tempSub2[ii]]);
1376 for (jj = 0; jj < int(tempSurf.size()); ++jj)
1378 if (tempCount[tempSurf[jj]] > 1)
1381 tempCount[tempSurf[jj]] = 0;
1382 tempRecur = tempIndHash.findall(tempIndHash.vec[tempSurf[jj]]);
1383 IdentifyMergeSurfRecursive(snakein, isObjDone, tempCount, edge2Surf, tempIndHash, tempConnec,
1384 tempSub, tempRecur, tempSurf[jj]);
1392 void ModifyMergVoluConnec(
snake &snakein, vector<ConnecRemv> &connecEdit,
const vector<int> &indRmvVert)
1394 vector<int> tempSub, tempSub2;
1398 for (ii = 0; ii < int(indRmvVert.size()); ++ii)
1401 tempSub = snakein.snakeconn.edges.find_list(snakein.snakeconn.verts.isearch(indRmvVert[ii])->edgeind);
1403 tempSub2 = ConcatenateVectorField(snakein.snakeconn.edges, &edge::surfind, tempSub);
1404 tempSub = ConcatenateVectorField(snakein.snakeconn.surfs, &surf::voluind,
1405 snakein.snakeconn.surfs.find_list(tempSub2));
1410 if (
int(tempSub.size()) > 1)
1412 tempConnec.typeobj = 4;
1414 if (tempSub[kk] == 0)
1418 if (
int(tempSub.size()) > (kk + 1))
1420 tempConnec.keepind = tempSub[kk];
1421 tempConnec.rmvind.clear();
1422 for (jj = kk + 1; jj < int(tempSub.size()); ++jj)
1424 if (tempSub[jj] > 0)
1426 tempConnec.rmvind.push_back(tempSub[jj]);
1429 if (
int(tempConnec.rmvind.size()) > 0)
1431 for (jj = 0; jj < int(tempConnec.rmvind.size()); jj++)
1433 snakein.snakeconn.SwitchIndex(tempConnec.typeobj, tempConnec.rmvind[jj], tempConnec.keepind,
1434 tempConnec.scopeind);
1436 connecEdit.push_back(tempConnec);
1443 void ModifyMergSurf2DConnec(
snake &snakein, vector<ConnecRemv> &connecEdit)
1450 int ii, jj, ni, nj, nAbove0;
1453 tempConnec.typeobj = 3;
1455 ni = snakein.snakeconn.edges.size();
1457 for (ii = 0; ii < ni; ++ii)
1459 nj = snakein.snakeconn.edges(ii)->surfind.size();
1463 for (jj = 0; jj < nj; ++jj)
1465 nAbove0 += (snakein.snakeconn.edges(ii)->surfind[jj] > 0);
1470 tempConnec.keepind = -1;
1471 tempConnec.rmvind.clear();
1473 for (jj = 0; jj < nj; ++jj)
1477 tempConnec.keepind = snakein.snakeconn.edges(ii)->surfind[jj];
1479 else if (snakein.snakeconn.edges(ii)->surfind[jj] != 0 &&
1480 snakein.snakeconn.edges(ii)->surfind[jj] != tempConnec.keepind)
1482 tempConnec.rmvind.push_back(snakein.snakeconn.edges(ii)->surfind[jj]);
1484 nAbove0 += (snakein.snakeconn.edges(ii)->surfind[jj] > 0);
1487 for (jj = 0; jj < int(tempConnec.rmvind.size()); jj++)
1489 snakein.snakeconn.SwitchIndex(tempConnec.typeobj, tempConnec.rmvind[jj], tempConnec.keepind,
1490 tempConnec.scopeind);
1494 connecEdit.push_back(tempConnec);
1504 #pragma GCC diagnostic push
1505 #pragma GCC diagnostic ignored "-Wunused-parameter"
1506 void CheckSnakeRemovalsVert(
const snake &snakein,
const vector<int> &indRmvVert)
1512 void CheckSnakeRemovalsEdge(
const snake &snakein,
const vector<int> &indRmvEdge)
1517 int ii, jj, kk, ni, nj, ne, sub;
1518 bool cond1vert, cond1surf;
1519 ni = indRmvEdge.size();
1521 for (ii = 0; ii < ni; ++ii)
1523 sub = snakein.snakeconn.edges.find(indRmvEdge[ii]);
1527 nj = snakein.snakeconn.edges(sub)->vertind.size();
1531 kk = snakein.snakeconn.edges(sub)->vertind[jj];
1532 for (jj = 0; jj < nj; ++jj)
1534 cond1vert = kk != snakein.snakeconn.edges(sub)->vertind[jj];
1546 nj = snakein.snakeconn.edges(sub)->surfind.size();
1550 kk = snakein.snakeconn.edges(sub)->surfind[jj];
1551 for (jj = 0; jj < nj; ++jj)
1553 cond1surf = kk != snakein.snakeconn.edges(sub)->surfind[jj];
1561 if (!(cond1surf || cond1vert))
1567 snakein.snakeconn.edges(sub)->disptree(snakein.snakeconn, 2);
1569 <<
"Edge was marked for deletion but is connected"
1570 <<
" to more than 1 Surface and edge." << endl;
1590 cerr << endl <<
"There were " << ne <<
" Edge deletion errors:";
1591 cerr << endl << __PRETTY_FUNCTION__ << endl;
1594 void CheckSnakeRemovalsSurf(
const snake &snakein,
const vector<int> &indRmvSurf)
1600 void CheckSnakeRemovalsVolu(
const snake &snakein,
const vector<int> &indRmvVolu)
1606 #pragma GCC diagnostic pop
Class containing the information needed to trim objects from a mesh.
Provides all the mesh tools used for the generation of 3D grids and geometries.
Provides the core restricted surface snake container.
Functions needed to evolve the r-surface snake.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.