rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
triangulate.cpp
1 
2 #include "triangulate.hpp"
3 
4 #include <cmath>
5 #include <cstdlib>
6 #include <iostream>
7 
8 #include "RSVScalc.hpp"
9 #include "RSVSmath.hpp"
10 #include "arraystructures.hpp"
11 #include "mesh.hpp"
12 #include "rsvsutils.hpp"
13 #include "snake.hpp"
14 #include "warning.hpp"
15 
16 using namespace std;
17 using namespace rsvs3d::constants;
18 
19 void CalculateSnakeVel(snake &snakein)
20 {
21  int ii = 0;
22 
23  for (ii = 0; ii < int(snakein.snaxs.size()); ++ii)
24  {
25  if (snakein.snaxs(ii)->isfreeze == 1)
26  {
27  snakein.snaxs[ii].v = (0.5 - snakein.snaxs[ii].d) * 0.3;
28  snakein.snaxs[ii].isfreeze = 0;
29  }
30  // snakein.snaxs[ii].v=(double(rand()%1001)/1000.0+0.5)*snakein.snaxs[ii].v;
31  snakein.snaxs[ii].v = (0.4 * (double(rand() % 1001) / 1000.0) + 0.8) * snakein.snaxs[ii].v;
32  }
33 }
34 
35 void CalculateSnakeVelRand(snake &snakein)
36 {
37  int ii = 0;
38 
39  for (ii = 0; ii < int(snakein.snaxs.size()); ++ii)
40  {
41  if (snakein.snaxs(ii)->isfreeze == 1)
42  {
43  snakein.snaxs[ii].v = (0.5 - snakein.snaxs[ii].d) * 0.3;
44  snakein.snaxs[ii].isfreeze = 0;
45  }
46  snakein.snaxs[ii].v = (double(rand() % 1001) / 1000.0 + 0.5) * snakein.snaxs[ii].v;
47  // snakein.snaxs[ii].v=(0.4*(double(rand()%1001)/1000.0)+0.8)*snakein.snaxs[ii].v;
48  }
49 }
50 
51 void CalculateSnakeVelUnit(snake &snakein)
52 {
53  int ii = 0;
54 
55  for (ii = 0; ii < int(snakein.snaxs.size()); ++ii)
56  {
57  if (snakein.snaxs(ii)->isfreeze == 1)
58  {
59  snakein.snaxs[ii].v = 0;
60  snakein.snaxs[ii].isfreeze = 0;
61  }
62  else
63  {
64  snakein.snaxs[ii].v = 1;
65  }
66  }
67 }
68 
69 void CalculateSnakeVelUnitReflect(snake &snakein)
70 {
71  int ii = 0;
72 
73  for (ii = 0; ii < int(snakein.snaxs.size()); ++ii)
74  {
75  if (snakein.snaxs(ii)->isfreeze == 1)
76  {
77  snakein.snaxs[ii].v = -0.2 * snakein.snaxs[ii].v;
78  snakein.snaxs[ii].isfreeze = 0;
79  }
80  else
81  {
82  snakein.snaxs[ii].v = 1 * snakein.snaxs[ii].v;
83  }
84  }
85 }
86 
87 void CalculateSnakeVelFast(snake &snakein)
88 {
89  int ii = 0;
90 
91  for (ii = 0; ii < int(snakein.snaxs.size()); ++ii)
92  {
93  if (snakein.snaxs(ii)->isfreeze == 1)
94  {
95  snakein.snaxs[ii].v = 0; //(0.5-snakein.snaxs[ii].d)*0.3;
96  snakein.snaxs[ii].isfreeze = 0;
97  }
98  // snakein.snaxs[ii].v=(double(rand()%1001)/1000.0+0.5)*snakein.snaxs[ii].v;
99  snakein.snaxs[ii].v = 4; //(0.4*(double(rand()%1001)/1000.0)+0.8)*snakein.snaxs[ii].v;
100  }
101 }
102 
103 void CalculateNoNanSnakeVel(snake &snakein, double deltaStep)
104 {
105  int ii = 0, ll = 0;
106 
107  for (ii = 0; ii < int(snakein.snaxs.size()); ++ii)
108  {
109  // if (snakein.snaxs(ii)->isfreeze==1){
110  // snakein.snaxs[ii].v=0;
111  // snakein.snaxs[ii].isfreeze=0;
112  // }
113  // snakein.snaxs[ii].v=(double(rand()%1001)/1000.0+0.5)*snakein.snaxs[ii].v;
114  if (!isfinite(snakein.snaxs[ii].v))
115  {
116  snakein.snaxs[ii].v = (0.5 - snakein.snaxs[ii].d) * deltaStep;
117  ++ll;
118  }
119  }
120  if (ll > 0)
121  {
122  cerr << endl << ll << " velocities were not finite." << endl;
123  }
124 }
125 
126 void TriangulateMesh(mesh &meshin, triangulation &triangleRSVS)
127 {
128  // build the list of valid surfaces
129  vector<int> subList;
130  int nSurf;
131 
132  nSurf = meshin.surfs.size();
133  subList.reserve(nSurf);
134 
135  meshin.SurfInParent(subList);
136 
137  TriangulateContainer(meshin, triangleRSVS, meshtypes::mesh, subList);
138  triangleRSVS.meshDep = &meshin;
139 }
140 
141 void TriangulateSnake(snake &snakein, triangulation &triangleRSVS)
142 {
143  TriangulateContainer(snakein.snakeconn, triangleRSVS, meshtypes::snake);
144  triangleRSVS.snakeDep = &snakein;
145 }
146 
147 void MaintainTriangulateSnake(triangulation &triangleRSVS)
148 {
149  vector<int> surfReTriangulate;
150  int ii, n;
151 
152  if (triangleRSVS.snakeDep != NULL)
153  {
154  triangleRSVS.snakeDep->snakeconn.surfs.ReturnModifInd(surfReTriangulate);
155  surfReTriangulate = triangleRSVS.snakeDep->snakeconn.surfs.find_list(surfReTriangulate);
156  triangleRSVS.CleanDynaTri();
157  triangleRSVS.trivert.SetMaxIndex();
158  if (surfReTriangulate.size() > 0)
159  {
160  TriangulateContainer(triangleRSVS.snakeDep->snakeconn, triangleRSVS, meshtypes::snake, surfReTriangulate);
161  }
162 
163  BuildTriSurfGridSnakeIntersect(triangleRSVS);
164  surfReTriangulate.clear();
165  TriangulateContainer(triangleRSVS.snakeDep->snakeconn, triangleRSVS, meshtypes::triangulation,
166  surfReTriangulate);
167 
168  n = triangleRSVS.trivert.size();
169  // Still need to recompute coordinates
170  for (ii = 0; ii < n; ++ii)
171  {
172  triangleRSVS.CalcTriVertPosDyna(ii);
173  }
174 
175  triangleRSVS.snakeDep->snakeconn.surfs.SetNoModif();
176  triangleRSVS.snakeDep->snakeconn.edges.SetNoModif();
177  triangleRSVS.SetConnectivity();
178  }
179  triangleRSVS.PrepareForUse();
180  if (triangleRSVS.snakeDep != NULL)
181  {
182  triangleRSVS.SetActiveStaticTri();
183  }
184 }
185 
186 void TriangulateContainer(const mesh &meshin, triangulation &triangleRSVS, const int typeMesh,
187  const vector<int> &subList)
188 {
189  int ii, n, nTriS, nTriE, maxIndVert, maxIndTriangle;
190  triarray triangulation::*mp = NULL;
191 
192  if (typeMesh == meshtypes::mesh)
193  {
194  mp = &triangulation::stattri;
195  }
196  else if (typeMesh == meshtypes::snake)
197  {
198  mp = &triangulation::dynatri;
199  }
200  else if (typeMesh == meshtypes::triangulation)
201  {
202  mp = &triangulation::intertri;
203  }
204  else
205  {
206  RSVS3D_ERROR_ARGUMENT("Invalid type of mesh, typeMesh [1,2,3]");
207  }
208 
209  maxIndVert = triangleRSVS.trivert.GetMaxIndex();
210  maxIndTriangle = int((triangleRSVS.*mp).GetMaxIndex());
211 
212  nTriS = int((triangleRSVS.*mp).size());
213  if (int(subList.size()) == 0)
214  { // if there is no list of surfaces to triangulate
215 
216  if (typeMesh != meshtypes::triangulation)
217  {
218  n = meshin.surfs.size();
219  for (ii = 0; ii < n; ++ii)
220  {
221  TriangulateSurface(*(meshin.surfs(ii)), meshin, triangleRSVS.*mp, triangleRSVS.trivert, typeMesh,
222  maxIndVert + ii + 1);
223  }
224  }
225  else
226  { // trisurf triangulation
227  n = triangleRSVS.trisurf.size();
228  for (ii = 0; ii < n; ++ii)
229  {
230  TriangulateTriSurface(*(triangleRSVS.trisurf(ii)), triangleRSVS.*mp, triangleRSVS.trivert, typeMesh,
231  maxIndVert + ii + 1);
232  }
233  }
234  }
235  else
236  { // if there is a list of specific surfaces to triangulate
237  n = subList.size();
238  if (typeMesh != meshtypes::triangulation)
239  {
240  for (ii = 0; ii < n; ++ii)
241  {
242  TriangulateSurface(*(meshin.surfs(subList[ii])), meshin, triangleRSVS.*mp, triangleRSVS.trivert,
243  typeMesh, maxIndVert + ii + 1);
244  }
245  }
246  else
247  { // trisurf triangulation
248  for (ii = 0; ii < n; ++ii)
249  {
250  TriangulateTriSurface(*(triangleRSVS.trisurf(subList[ii])), triangleRSVS.*mp, triangleRSVS.trivert,
251  typeMesh, maxIndVert + ii + 1);
252  }
253  }
254  }
255  nTriE = int((triangleRSVS.*mp).size());
256  for (ii = 0; ii < (nTriE - nTriS); ++ii)
257  {
258  (triangleRSVS.*mp)[nTriS + ii].index = ii + maxIndTriangle + 1;
259  }
260 }
261 
262 void TriangulateSurface(const surf &surfin, const mesh &meshin, triarray &triangul, tripointarray &trivert,
263  const int typeMesh, int trivertMaxInd)
264 {
265  // Generates the triangulation parts
266  // typeMesh=1 is a static mesh, type 2 is a dynamic one (snake)
267 
268  int ii, n;
269  coordvec edgeCentre;
270  // double surfLength,edgeLength;
271  trianglepoint surfCentre;
272  triangle triangleEdge;
273  vector<int> orderVert;
274  int nextInd = triangul.GetMaxIndex();
275 
276  // Loop around edges calculating centre and length of each edge
277  // surfLength=0;
278  // edgeLength=0;
279  n = int(surfin.edgeind.size());
280  surfin.OrderedVerts(&meshin, orderVert);
281  triangleEdge.SetPointType(typeMesh, typeMesh, meshtypes::triangulation);
282  triangleEdge.pointind[2] = trivertMaxInd + 1;
283  triangleEdge.parentsurf = surfin.index;
284  // Wrong needs to be always onto the base grid
285  if (typeMesh != meshtypes::snake)
286  {
287  triangleEdge.connec.celltarg = surfin.voluind;
288  triangleEdge.connec.constrinfluence = {-1.0, 1.0};
289  }
290  else
291  {
292  // Need to map onto snakemesh()
293  // Do it outside in triangulate snake?
294  triangleEdge.connec.celltarg = {};
295  triangleEdge.connec.constrinfluence = {};
296  }
297 
298  if (n < 3)
299  {
300  RSVS3D_ERROR_ARGUMENT("cannot build triangle less than 3 points");
301  }
302  else if (n > 3)
303  {
304  for (ii = 0; ii < n; ++ii)
305  {
306  // meshin.edges.isearch(surfin.edgeind[ii])->
307  // GeometricProperties(&meshin,edgeCentre,edgeLength);
308  // edgeCentre.mult(edgeLength);
309  // surfCentre.coord.add(edgeCentre.usedata());
310  // surfLength+=edgeLength;
311 
312  // triangleEdge.pointind[0]=meshin.edges.isearch(surfin.edgeind[ii])->vertind[0];
313  // triangleEdge.pointind[1]=meshin.edges.isearch(surfin.edgeind[ii])->vertind[1];
314  triangleEdge.index = ++nextInd;
315  triangleEdge.pointind[0] = orderVert[ii];
316  triangleEdge.pointind[1] = orderVert[(ii + 1) % n];
317  triangul.push_back(triangleEdge);
318  }
319 
320  // surfCentre.coord.div(surfLength);
321  surfCentre.index = trivertMaxInd + 1;
322  surfCentre.parentsurf = surfin.index;
323  surfCentre.parentType = typeMesh;
324  if (typeMesh == meshtypes::snake)
325  {
326  surfCentre.nInfluences = n;
327  }
328  trivert.push_back(surfCentre);
329  }
330  else
331  {
332  triangleEdge.SetPointType(typeMesh, typeMesh, typeMesh);
333  triangleEdge.index = ++nextInd;
334  triangleEdge.pointind = orderVert;
335  triangleEdge.parentsurf = surfin.index;
336  triangul.push_back(triangleEdge);
337  }
338 }
339 
340 void TriangulateTriSurface(const trianglesurf &surfin, triarray &triangul, tripointarray &trivert, const int typeMesh,
341  int trivertMaxInd)
342 {
343  // Generates the triangulation parts
344  // typeMesh=1 is a static mesh, type 2 is a dynamic one (snake)
345 
346  int ii, n, kk;
347  coordvec edgeCentre;
348  trianglepoint surfCentre;
349  triangle triangleEdge;
350  int nextInd = triangul.GetMaxIndex();
351 
352  // Loop around edges calculating centre and length of each edge
353 
354  n = int(surfin.indvert.size());
355 
356  triangleEdge.SetPointType(typeMesh, typeMesh, meshtypes::triangulation);
357  triangleEdge.pointind[2] = trivertMaxInd + 1;
358  triangleEdge.parentsurf = surfin.index;
359 
360  // Probably fine
361  triangleEdge.connec.celltarg = surfin.voluind;
362  triangleEdge.connec.constrinfluence = {-1.0, 1.0};
363  kk = 0;
364  if (n < 3)
365  {
366  RSVS3D_ERROR_ARGUMENT("cannot build triangle less than 3 points");
367  }
368  else if (n > 3)
369  {
370  for (ii = 0; ii < n; ++ii)
371  {
372  triangleEdge.SetPointType(surfin.typevert[ii], surfin.typevert[(ii + 1) % n], meshtypes::triangulation);
373 
374  triangleEdge.index = ++nextInd;
375 
376  triangleEdge.pointind[0] = surfin.indvert[ii];
377  triangleEdge.pointind[1] = surfin.indvert[(ii + 1) % n];
378  triangul.push_back(triangleEdge);
379  kk += (surfin.typevert[ii] == meshtypes::snake);
380  }
381 
382  surfCentre.index = trivertMaxInd + 1;
383  surfCentre.parentsurf = surfin.index;
384  surfCentre.parentType = typeMesh;
385  if (typeMesh == meshtypes::snake)
386  {
387  surfCentre.nInfluences = kk;
388  }
389  trivert.push_back(surfCentre);
390  }
391  else if (n == 3)
392  {
393  triangleEdge.SetPointType(surfin.typevert[0], surfin.typevert[1], surfin.typevert[2]);
394 
395  triangleEdge.index = ++nextInd;
396  triangleEdge.pointind = surfin.indvert;
397  triangleEdge.parentsurf = surfin.index;
398  triangul.push_back(triangleEdge);
399  }
400 }
401 
402 void SurfaceCentroid_fun2(coordvec &coord, const surf &surfin, const mesh &meshin)
403 {
404  int ii, n;
405  coordvec edgeCentre;
406  double edgeLength, surfLength = 0;
407  coord.assign(0, 0, 0);
408  n = int(surfin.edgeind.size());
409  for (ii = 0; ii < n; ++ii)
410  {
411  meshin.edges.isearch(surfin.edgeind[ii])->GeometricProperties(&meshin, edgeCentre, edgeLength);
412  edgeCentre.mult(edgeLength);
413  coord.add(edgeCentre.usedata());
414  surfLength += edgeLength;
415  }
416 
417  coord.div(surfLength);
418 }
419 
420 void SnakeSurfaceCentroid_fun(coordvec &coord, const surf &surfin, const mesh &meshin)
421 {
422  SurfCentroid tempCalc;
423  ArrayVec<double> tempCoord, jac, hes;
424 
425  coord.assign(0, 0, 0);
426 
427  tempCalc = SurfaceCentroid_SnakeSurf(surfin, meshin);
428 
429  tempCalc.Calc();
430 
431  tempCalc.ReturnDat(tempCoord, jac, hes);
432  coord.assign(tempCoord[0][0], tempCoord[1][0], tempCoord[2][0]);
433 }
434 
435 SurfCentroid SurfaceCentroid_SnakeSurf(const surf &surfin, const mesh &meshin)
436 {
437  int ii, n;
438  vector<int> vertind;
439  grid::coordlist veccoord;
440  SurfCentroid tempCalc;
441 
442  n = int(surfin.edgeind.size());
443 
444  veccoord.reserve(n);
445  ConnVertFromConnEdge(meshin, surfin.edgeind, vertind);
446 
447  for (ii = 0; ii < n; ++ii)
448  {
449  veccoord.push_back(&(meshin.verts.isearch(vertind[ii])->coord));
450  }
451  if (n == 3)
452  {
453  RSVS3D_ERROR_ARGUMENT("Invalid surface nEdges == 3");
454  veccoord.push_back(&(meshin.verts.isearch(vertind[0])->coord));
455  }
456 
457  tempCalc.assign(veccoord);
458  return (tempCalc);
459 }
460 
461 void HybridSurfaceCentroid_fun(coordvec &coord, const trianglesurf &surfin, const mesh &meshin, const mesh &snakeconn)
462 {
463  SurfCentroid tempCalc;
464  ArrayVec<double> tempCoord, jac, hes;
465 
466  coord.assign(0, 0, 0);
467 
468  tempCalc = SurfaceCentroid_TriangleSurf(surfin, meshin, snakeconn);
469 
470  tempCalc.Calc();
471 
472  tempCalc.ReturnDat(tempCoord, jac, hes);
473  coord.assign(tempCoord[0][0], tempCoord[1][0], tempCoord[2][0]);
474 }
475 
476 SurfCentroid SurfaceCentroid_TriangleSurf(const trianglesurf &surfin, const mesh &meshin, const mesh &snakeconn)
477 {
478  int ii, n;
479 
480  grid::coordlist veccoord;
481  SurfCentroid tempCalc;
482  ArrayVec<double> tempCoord, jac, hes;
483 
484  n = surfin.indvert.size();
485  for (ii = 0; ii < n; ++ii)
486  {
487  if (surfin.typevert[ii] == meshtypes::mesh)
488  {
489  veccoord.push_back(&(meshin.verts.isearch(surfin.indvert[ii])->coord));
490  }
491  else if (surfin.typevert[ii] == meshtypes::snake)
492  {
493  veccoord.push_back(&(snakeconn.verts.isearch(surfin.indvert[ii])->coord));
494  }
495  }
496  if (n == 3)
497  {
498  ii = 0;
499  if (surfin.typevert[ii] == meshtypes::mesh)
500  {
501  veccoord.push_back(&(meshin.verts.isearch(surfin.indvert[ii])->coord));
502  }
503  else if (surfin.typevert[ii] == meshtypes::snake)
504  {
505  veccoord.push_back(&(snakeconn.verts.isearch(surfin.indvert[ii])->coord));
506  }
507  }
508 
509  tempCalc.assign(veccoord);
510  return tempCalc;
511 }
512 
513 mesh TriarrayToMesh(const triangulation &triangul, const triarray &triin)
514 {
515  mesh meshout;
516  int ii, ni, jj, kk;
517  int nVe, nE, nSurf, nVolu;
518  std::vector<int> voluInds;
519  RSVScalc calcObj;
520 
521  calcObj.PrepTriangulationCalc(triangul);
522  nSurf = triin.size();
523  nVe = nSurf * 3;
524  nE = nSurf * 3;
525 
526  ni = nSurf;
527  // Build list of unique voluIndices
528  for (ii = 0; ii < ni; ++ii)
529  {
530  voluInds.push_back(triin(ii)->connec.celltarg[0]);
531  voluInds.push_back(triin(ii)->connec.celltarg[1]);
532  }
533  sort(voluInds);
534  unique(voluInds);
535  nVolu = calcObj.numConstr();
536  // Prepare new mesh container
537  meshout.Init(nVe, nE, nSurf, nVolu);
538  meshout.PopulateIndices();
539  meshout.volus.HashArray();
540  meshout.HashArray();
541 
542  for (ii = 0; ii < nSurf; ++ii)
543  {
544  // cout << endl;
545  meshout.surfs[ii].edgeind = {ii * 3 + 1, ii * 3 + 2, ii * 3 + 3};
546  meshout.surfs[ii].voluind.clear();
547  for (jj = 0; jj < int(triin(ii)->connec.celltarg.size()); jj++)
548  {
549  for (auto x : calcObj.constrMap.findall(triin(ii)->connec.celltarg[jj]))
550  {
551  meshout.surfs[ii].voluind.push_back(x + 1);
552  // cout << x+1 << " " ;
553  }
554  }
555  if (meshout.surfs[ii].voluind.size() == 1)
556  {
557  meshout.surfs[ii].voluind.push_back(0);
558  }
559  if (rsvs3d::utils::IsAproxEqual(triin(ii)->connec.constrinfluence[0], 1.0))
560  {
561  kk = meshout.surfs[ii].voluind[0];
562  meshout.surfs[ii].voluind[0] = meshout.surfs[ii].voluind[1];
563  meshout.surfs[ii].voluind[1] = kk;
564  }
565  // DisplayVector(meshout.surfs[ii].voluind);
566  for (jj = 0; jj < int(meshout.surfs[ii].voluind.size()); jj++)
567  {
568  kk = meshout.volus.find(meshout.surfs[ii].voluind[jj], true);
569  if (kk >= 0)
570  {
571  meshout.volus[kk].surfind.push_back(ii + 1);
572  }
573  else if (meshout.surfs[ii].voluind[jj] != 0)
574  {
575  std::cerr << " w " << kk << " " << meshout.surfs[ii].voluind[jj] << " "
576  << triin(ii)->connec.celltarg[jj];
577  // meshout.volus[meshout.surfs[ii].voluind[jj]-1].surfind.push_back(ii+1);
578  }
579  }
580 
581  for (jj = 0; jj < 3; jj++)
582  {
583  meshout.edges[ii * 3 + jj].surfind = {meshout.surfs(ii)->index};
584  meshout.edges[ii * 3 + jj].vertind = {ii * 3 + 1 + jj, ii * 3 + 1 + ((jj + 1) % 3)};
585  if (triin(ii)->pointtype[jj] == meshtypes::mesh)
586  {
587  meshout.verts[ii * 3 + jj].coord = triangul.meshDep->verts.isearch(triin(ii)->pointind[jj])->coord;
588  }
589  else if (triin(ii)->pointtype[jj] == meshtypes::snake)
590  {
591  meshout.verts[ii * 3 + jj].coord =
592  triangul.snakeDep->snakeconn.verts.isearch(triin(ii)->pointind[jj])->coord;
593  }
594  else if (triin(ii)->pointtype[jj] == meshtypes::triangulation)
595  {
596  meshout.verts[ii * 3 + jj].coord = triangul.trivert.isearch(triin(ii)->pointind[jj])->coord.usedata();
597  }
598  meshout.verts[ii * 3 + jj].edgeind = {ii * 3 + 1 + jj, ii * 3 + 1 + ((jj + 3 - 1) % 3)};
599  }
600  }
601  meshout.PrepareForUse();
602 
603  return (meshout);
604 }
605 
606 void MeshTriangulation(mesh &meshout, const mesh &meshin, triarray &triangul, tripointarray &trivert)
607 {
608  // Adds a triarray and corresponding
609  int ii, jj, kk, ll, n, nSub, subSurf, nSurfInd, mm;
610  int nNewVert, nNewEdge, nNewSurf, maxIndVert, maxIndEdge, maxIndSurf, vertSub;
611  vector<bool> isTriDone;
612  vector<int> tempSub, tempType, tempVert, tempEdge;
613  mesh tempMesh;
614  vert buildVert;
615  edge buildEdge;
616  surf buildSurf;
617  bool flag;
618  ConnecRemv tempConnec, tempConnec2;
619  vector<ConnecRemv> conn;
620 
621  meshout = meshin;
622 
623  meshout.PrepareForUse();
624  triangul.PrepareForUse();
625  trivert.PrepareForUse();
626  meshout.SetMaxIndex();
627 
628  n = int(triangul.size());
629  isTriDone.assign(n, false);
630 
631  nNewVert = 0;
632  nNewEdge = 0;
633  nNewSurf = 0;
634  maxIndVert = meshout.verts.GetMaxIndex();
635  maxIndEdge = meshout.edges.GetMaxIndex();
636  maxIndSurf = meshout.surfs.GetMaxIndex();
637  // cout << " " << maxIndVert << " " << maxIndEdge << " " << maxIndSurf <<
638  // endl;
639 
640  buildEdge.vertind.assign(2, 0);
641  buildEdge.surfind.assign(2, 0);
642 
643  for (ii = 0; ii < n; ++ii)
644  {
645  if (!isTriDone[ii])
646  {
647  tempType = triangul(ii)->pointtype;
648  sort(tempType);
649  unique(tempType);
650  if (int(tempType.size()) > 1)
651  {
652  triangul.findsiblings(triangul(ii)->KeyParent(), tempSub);
653  nSub = tempSub.size();
654  // cout << " " << nSub ;
655  for (jj = 0; jj < nSub; ++jj)
656  {
657  isTriDone[tempSub[jj]] = true;
658  }
659 
660  subSurf = meshin.surfs.find(triangul(ii)->KeyParent());
661  tempVert = ConcatenateVectorField(meshin.edges, &edge::vertind,
662  meshin.edges.find_list(meshin.surfs(subSurf)->edgeind));
663  sort(tempVert);
664  unique(tempVert);
665 
666  tempEdge = meshin.edges.find_list(meshin.surfs(subSurf)->edgeind);
667  // Build nSub edges
668  // 1 vertex
669  // nSub-1 surfaces
670 
671  // Add the vertex
672  for (jj = 0; jj < 3; ++jj)
673  {
674  if (triangul(ii)->pointtype[jj] == meshtypes::triangulation)
675  {
676  buildVert.index = maxIndVert + nNewVert + 1;
677  nNewVert++;
678  buildVert.coord = trivert.isearch(triangul(ii)->pointind[jj])->coord.usedata();
679  buildVert.edgeind.clear();
680  for (kk = 0; kk < int(tempVert.size()); ++kk)
681  {
682  buildVert.edgeind.push_back(maxIndEdge + nNewEdge + 1 + kk);
683  }
684  tempMesh.verts.push_back(buildVert);
685  break;
686  }
687  }
688  // Add the edges
689  ll = 0;
690  kk = 0;
691  flag = (meshin.edges(tempEdge[kk])->vertind[ll] == meshin.edges(tempEdge[kk + 1])->vertind[0]) |
692  (meshin.edges(tempEdge[kk])->vertind[ll] == meshin.edges(tempEdge[kk + 1])->vertind[1]);
693  if (!flag)
694  {
695  ll = ((ll + 1) % 2);
696  }
697 
698  nSub = int(tempEdge.size());
699  for (kk = 0; kk < nSub; ++kk)
700  {
701  buildEdge.index = (maxIndEdge + nNewEdge + 1 + kk);
702  buildEdge.vertind[0] = buildVert.index;
703  buildEdge.vertind[1] = meshin.edges(tempEdge[kk])->vertind[ll];
704  vertSub = meshin.verts.find(meshin.edges(tempEdge[kk])->vertind[ll]);
705  meshout.verts[vertSub].edgeind.push_back(maxIndEdge + nNewEdge + 1 + kk);
706 
707  buildEdge.surfind[0] =
708  (kk == 0) * (meshin.surfs(subSurf)->index) + (kk != 0) * (maxIndSurf + nNewSurf + kk);
709  buildEdge.surfind[1] = (kk == (nSub - 1)) * (meshin.surfs(subSurf)->index) +
710  (kk != (nSub - 1)) * (maxIndSurf + nNewSurf + kk + 1);
711 
712  tempMesh.edges.push_back(buildEdge);
713 
714  if (kk == 0)
715  {
716  meshout.surfs[subSurf].edgeind.clear();
717  meshout.surfs[subSurf].edgeind.push_back(maxIndEdge + nNewEdge + 1);
718  meshout.surfs[subSurf].edgeind.push_back(maxIndEdge + nNewEdge + nSub);
719  meshout.surfs[subSurf].edgeind.push_back(meshin.edges(tempEdge[kk])->index);
720  }
721  else
722  {
723  buildSurf = *(meshin.surfs(subSurf));
724  buildSurf.index = maxIndSurf + nNewSurf + kk;
725  buildSurf.edgeind.clear();
726  buildSurf.edgeind.push_back(maxIndEdge + nNewEdge + kk);
727  buildSurf.edgeind.push_back(maxIndEdge + nNewEdge + kk + 1);
728  buildSurf.edgeind.push_back(meshin.edges(tempEdge[kk])->index);
729 
730  tempMesh.surfs.push_back(buildSurf);
731 
732  nSurfInd = meshout.edges[tempEdge[kk]].surfind.size();
733  for (mm = 0; mm < nSurfInd; ++mm)
734  {
735  if (meshout.edges[tempEdge[kk]].surfind[mm] == meshin.surfs(subSurf)->index)
736  {
737  meshout.edges[tempEdge[kk]].surfind[mm] = maxIndSurf + nNewSurf + kk;
738  }
739  }
740  nSurfInd = buildSurf.voluind.size();
741  for (mm = 0; mm < nSurfInd; ++mm)
742  {
743  if (buildSurf.voluind[mm] != 0)
744  {
745  meshout.volus[meshin.volus.find(buildSurf.voluind[mm])].surfind.push_back(
746  buildSurf.index);
747  }
748  }
749  }
750 
751  if (kk < int(tempEdge.size() - 1))
752  {
753  flag = (meshin.edges(tempEdge[kk])->vertind[0] == meshin.edges(tempEdge[kk + 1])->vertind[ll]) |
754  (meshin.edges(tempEdge[kk])->vertind[1] == meshin.edges(tempEdge[kk + 1])->vertind[ll]);
755  ll = ((ll + 1) % 2) * (flag) + ll * (!flag);
756  }
757  }
758  nNewEdge = nNewEdge + nSub;
759  nNewSurf = nNewSurf + nSub - 1;
760  }
761  isTriDone[ii] = true;
762  }
763  }
764 
765  meshout.Concatenate(tempMesh);
766  meshout.PrepareForUse();
767  // meshout.TestConnectivityBiDir(__PRETTY_FUNCTION__);
768 }
769 
770 bool FollowSnaxEdgeConnection(int actSnax, int actSurf, int followSnaxEdge, const snake &snakeRSVS,
771  vector<bool> &isSnaxEdgeDone, int &returnIndex)
772 {
773  // Snaxel Operation:
774  // *- follow appropriate connection* < HERE
775  // - reverse onto edge
776  // -if its the final snaxel on the edge -> Go to Vertex
777  // - else find the correct snaxel -> Has it been explored?
778  // - No: got to snaxel
779  // - Yes: finish
780  int snaxSub, snaxedgeSub, ii, kk, nE;
781  bool flagIter, isRepeat;
782  // Build edge index sets to intersect
783 
784  snaxSub = snakeRSVS.snakeconn.verts.find(actSnax);
785  nE = snakeRSVS.snakeconn.verts(snaxSub)->edgeind.size();
786  // Define snaxel edge to follow
787  ii = 0;
788  isRepeat = 0;
789  if (followSnaxEdge == 0)
790  {
791  followSnaxEdge = 0;
792  flagIter = false;
793  }
794  else
795  {
796  flagIter = true;
797  }
798 
799  while (ii < nE && !flagIter)
800  {
801  followSnaxEdge = snakeRSVS.snakeconn.verts(snaxSub)->edgeind[ii];
802  flagIter = snakeRSVS.snaxedges.isearch(followSnaxEdge)->surfind == actSurf;
803  ii++;
804  }
805 
806  if (!flagIter)
807  {
808  cerr << "Error : Cannot build grid/snake intersection a suitable edge in "
809  "the surface"
810  << endl;
811  cerr << " was not found." << endl;
812  cerr << "Error in " << __PRETTY_FUNCTION__ << endl;
813  RSVS3D_ERROR_ARGUMENT("edge not found in surface");
814  }
815 
816  snaxedgeSub = snakeRSVS.snaxedges.find(followSnaxEdge);
817 
818  isRepeat = (isSnaxEdgeDone[snaxedgeSub]);
819  isSnaxEdgeDone[snaxedgeSub] = true;
820  // Find the snaxel to look from
821  kk = 1;
822  kk = snakeRSVS.snakeconn.edges(snaxedgeSub)->vertind[kk] != actSnax;
823 
824  actSnax = snakeRSVS.snakeconn.edges(snaxedgeSub)->vertind[kk];
825  returnIndex = actSnax;
826  return (isRepeat);
827 }
828 
829 int FollowSnaxelDirection(int actSnax, const snake &snakeRSVS, int &returnIndex, int &returnType, int &actEdge)
830 {
831  /*
832  - reverse onto edge
833  -if its the final snaxel on the edge -> Go to Vertex
834  - else find the correct snaxel -> Has it been explored?
835  - No: got to snaxel
836  - Yes: finish
837  returnType 0 (unassigned) 1 (vertex) 2 ()
838  */
839 
840  bool dirSnax; // 0 reverse, 1 forward;
841  int snaxSub, nSib;
842  int ii;
843  int currSnaxOrd, nextSnaxOrd, nextSnaxPos, testOrder;
844  vector<int> snaxSiblings;
845 
846  snaxSub = snakeRSVS.snaxs.find(actSnax);
847  dirSnax = snakeRSVS.snaxs(snaxSub)->fromvert < snakeRSVS.snaxs(snaxSub)->tovert;
848 
849  snakeRSVS.snaxs.findsiblings(snakeRSVS.snaxs(snaxSub)->edgeind, snaxSiblings);
850  actEdge = snakeRSVS.snaxs(snaxSub)->edgeind;
851  nSib = snaxSiblings.size();
852  if (nSib == 1)
853  { // if there is a single snaxel return only that one
854  returnType = 1;
855  returnIndex = snakeRSVS.snaxs(snaxSub)->fromvert;
856  }
857  else
858  {
859  currSnaxOrd = snakeRSVS.snaxs(snaxSub)->orderedge;
860  nextSnaxOrd = 0;
861  nextSnaxPos = -1;
862 
863  if (dirSnax)
864  {
865  for (ii = 0; ii < nSib; ++ii)
866  {
867  testOrder = snakeRSVS.snaxs(snaxSiblings[ii])->orderedge;
868 
869  if (testOrder < currSnaxOrd && (testOrder > nextSnaxOrd || nextSnaxPos == -1))
870  {
871  nextSnaxPos = ii;
872  nextSnaxOrd = testOrder;
873  }
874  }
875  }
876  else
877  {
878  for (ii = 0; ii < nSib; ++ii)
879  {
880  testOrder = snakeRSVS.snaxs(snaxSiblings[ii])->orderedge;
881 
882  if (testOrder > currSnaxOrd && (testOrder < nextSnaxOrd || nextSnaxPos == -1))
883  {
884  nextSnaxPos = ii;
885  nextSnaxOrd = testOrder;
886  }
887  }
888  }
889  if (nextSnaxPos == -1)
890  {
891  returnType = 1;
892  returnIndex = snakeRSVS.snaxs(snaxSub)->fromvert;
893  }
894  else
895  {
896  returnType = 2;
897  returnIndex = snakeRSVS.snaxs(snaxSiblings[nextSnaxPos])->index;
898  }
899  }
900  return (0);
901 }
902 
903 int FollowVertexConnection(int actVert, int prevEdge, const HashedVector<int, int> &edgeSurfInd,
904  const HashedVector<int, int> &vertSurfInd, const snake &snakeRSVS, const mesh &meshRSVS,
905  int &returnIndex, int &returnType, int &nextEdge)
906 {
907  // Vertex Operation
908  // - Find next edge
909  // - if there is a snaxel on that edge
910  // -> Goto the first snaxel.
911  // -> else go to the other vertex.
912  vector<int> tempVert, snaxTemp;
913  int ii, jj, kk, nSnax, currOrd, currSnax;
914  bool isDir;
915 
916  tempVert = vertSurfInd.findall(actVert);
917 
918  if (tempVert.size() != 2)
919  {
920  RSVS3D_ERROR_ARGUMENT("Edge and Vertex list out of surface are broken");
921  }
922 
923  jj = 1;
924  jj = edgeSurfInd.vec[tempVert[jj] / 2] != prevEdge;
925  nextEdge = edgeSurfInd.vec[tempVert[jj] / 2];
926 
927  snakeRSVS.snaxs.findsiblings(nextEdge, snaxTemp);
928  nSnax = snaxTemp.size();
929  if (nSnax == 0)
930  {
931  returnType = 1;
932  returnIndex = vertSurfInd.vec[tempVert[jj] + 1 - ((tempVert[jj] % 2) * 2)];
933  }
934  else if (nSnax == 1)
935  {
936  returnType = 2;
937  returnIndex = snakeRSVS.snaxs(snaxTemp[0])->index;
938  }
939  else
940  {
941  kk = tempVert[jj] % 2;
942 
943  isDir = meshRSVS.edges.isearch(nextEdge)->vertind[kk] < actVert;
944  currOrd = snakeRSVS.snaxs(snaxTemp[0])->orderedge;
945  currSnax = snakeRSVS.snaxs(snaxTemp[0])->index;
946  if (isDir)
947  {
948  for (ii = 1; ii < nSnax; ++ii)
949  {
950  if (snakeRSVS.snaxs(snaxTemp[ii])->orderedge > currOrd)
951  {
952  currOrd = snakeRSVS.snaxs(snaxTemp[ii])->orderedge;
953  currSnax = snakeRSVS.snaxs(snaxTemp[0])->index;
954  }
955  }
956  }
957  else
958  {
959  for (ii = 1; ii < nSnax; ++ii)
960  {
961  if (snakeRSVS.snaxs(snaxTemp[ii])->orderedge < currOrd)
962  {
963  currOrd = snakeRSVS.snaxs(snaxTemp[ii])->orderedge;
964  currSnax = snakeRSVS.snaxs(snaxTemp[0])->index;
965  }
966  }
967  }
968 
969  returnType = 2;
970  returnIndex = currSnax;
971  }
972 
973  return (0);
974 }
975 
976 void BuildTriSurfGridSnakeIntersect(triangulation &triangleRSVS)
977 {
978  /*
979  Builds inter triangulation
980  */
981  vector<bool> isSnaxEdgeDone;
982  int ii, n2, nVert, nSnax;
983  int actIndex, actSurf, actEdge, actSurfSub, maxNEdge, isFlip;
984  int returnType, returnIndex, returnEdge, actType;
985  bool flagDone;
986  HashedVector<int, int> hashedEdgeInd, vertSurfList;
987  vector<int> edgeSub, pseudoEdgeInd;
988  trianglesurf newTrisSurf;
989 
990  n2 = triangleRSVS.snakeDep->snaxedges.size();
991  isSnaxEdgeDone.assign(n2, false);
992  pseudoEdgeInd.assign(4, 0);
993  triangleRSVS.trisurf.clear();
994  newTrisSurf.index = 0;
995  for (ii = 0; ii < n2; ii++)
996  {
997  if (!isSnaxEdgeDone[ii])
998  {
999  actIndex = 0;
1000  actEdge = triangleRSVS.snakeDep->snaxedges(ii)->index;
1001  actSurf = triangleRSVS.snakeDep->snaxedges(ii)->surfind;
1002  actSurfSub = triangleRSVS.meshDep->surfs.find(actSurf);
1003  // change this to make sure that this appears in 2 parents
1004  // if(actSurfSub>=0){
1005  if (triangleRSVS.meshDep->SurfInParent(actSurf) >= 0)
1006  {
1007  newTrisSurf.parentsurfmesh = actSurf;
1008  newTrisSurf.indvert.clear();
1009  newTrisSurf.typevert.clear();
1010  newTrisSurf.indvert.reserve(8);
1011  newTrisSurf.typevert.reserve(8);
1012  newTrisSurf.index++;
1013 
1014  hashedEdgeInd.vec = triangleRSVS.meshDep->surfs(actSurfSub)->edgeind;
1015  edgeSub = triangleRSVS.meshDep->edges.find_list(hashedEdgeInd.vec);
1016  hashedEdgeInd.GenerateHash();
1017  vertSurfList.vec = ConcatenateVectorField(triangleRSVS.meshDep->edges, &edge::vertind, edgeSub);
1018  vertSurfList.GenerateHash();
1019 
1020  actIndex = triangleRSVS.snakeDep->snakeconn.edges(ii)->vertind[0];
1021  actType = 2;
1022  flagDone = false;
1023  nVert = 0;
1024  nSnax = 0;
1025  maxNEdge = hashedEdgeInd.vec.size();
1026  // Prepare edge lists and vertlists
1027  while (!flagDone && nVert < maxNEdge + 2)
1028  {
1029  if (actType == meshtypes::mesh)
1030  { // Type vert
1031  newTrisSurf.indvert.push_back(actIndex);
1032  newTrisSurf.typevert.push_back(actType);
1033  FollowVertexConnection(actIndex, actEdge, hashedEdgeInd, vertSurfList, *(triangleRSVS.snakeDep),
1034  *(triangleRSVS.meshDep), returnIndex, returnType, returnEdge);
1035  pseudoEdgeInd[1] = actEdge;
1036  pseudoEdgeInd[2] = returnEdge;
1037  actEdge = returnEdge;
1038  actType = returnType;
1039  actIndex = returnIndex;
1040  nVert++;
1041  }
1042  else if (actType == meshtypes::snake)
1043  { // Snaxel operations
1044  flagDone = FollowSnaxEdgeConnection(actIndex, actSurf, actEdge, *(triangleRSVS.snakeDep),
1045  isSnaxEdgeDone, returnIndex);
1046  nSnax++;
1047  if (!flagDone)
1048  {
1049  newTrisSurf.indvert.push_back(actIndex);
1050  newTrisSurf.typevert.push_back(actType);
1051  nSnax++;
1052  actIndex = returnIndex;
1053 
1054  newTrisSurf.indvert.push_back(actIndex);
1055  newTrisSurf.typevert.push_back(actType);
1056  returnIndex = -1;
1057  returnType = -1;
1058  FollowSnaxelDirection(actIndex, *(triangleRSVS.snakeDep), returnIndex, returnType, actEdge);
1059  actType = returnType;
1060  actIndex = returnIndex;
1061  }
1062  else if (nVert == 0)
1063  { // Define the direction of the trisurf if
1064  // no vertex was explored
1065  pseudoEdgeInd[1] = triangleRSVS.snakeDep->snaxs.isearch(actIndex)->edgeind;
1066  FollowVertexConnection(triangleRSVS.snakeDep->snaxs.isearch(actIndex)->tovert,
1067  pseudoEdgeInd[1], hashedEdgeInd, vertSurfList,
1068  *(triangleRSVS.snakeDep), *(triangleRSVS.meshDep), returnIndex,
1069  returnType, returnEdge);
1070  pseudoEdgeInd[2] = returnEdge;
1071  }
1072  }
1073  if (actType == meshtypes::snake)
1074  {
1075  actEdge = 0;
1076  }
1077  // cout << endl << "nVert= "<< nVert << " nSnax=" << nSnax ;
1078  if (nVert > maxNEdge)
1079  {
1080  cout << "Error";
1081  }
1082  }
1083 
1084  newTrisSurf.voluind = triangleRSVS.meshDep->surfs(actSurfSub)->voluind;
1085  isFlip = OrderMatchLists(pseudoEdgeInd, triangleRSVS.meshDep->surfs(actSurfSub)->edgeind,
1086  pseudoEdgeInd[1], pseudoEdgeInd[2]);
1087  if (isFlip == -1)
1088  {
1089  isFlip = newTrisSurf.voluind[0];
1090  newTrisSurf.voluind[0] = newTrisSurf.voluind[1];
1091  newTrisSurf.voluind[1] = isFlip;
1092  }
1093  triangleRSVS.trisurf.push_back(newTrisSurf);
1094  }
1095  isSnaxEdgeDone[ii] = true;
1096  }
1097  }
1098 
1099  // Snaxel Operation:
1100  // - follow appropriate connection
1101  // - reverse onto edge
1102  // -if its the final snaxel on the edge -> Go to Vertex
1103  // - else find the correct snaxel -> Has it been explored?
1104  // - No: got to snaxel
1105  // - Yes: finish
1106 
1107  // Vertex Operation
1108  // - Find next edge
1109  // - if there is a snaxel on that edge
1110  // -> Goto the first snaxel.
1111  // -> else go to the other vertex.
1112 }
1113 
1114 // Triangulation class Methods
1115 
1116 void triangulation::disp() const
1117 {
1118  cout << "This is a triangulation object" << endl;
1119 }
1120 void triangulation::PrepareForUse()
1121 {
1122  stattri.PrepareForUse();
1123  dynatri.PrepareForUse();
1124  intertri.PrepareForUse();
1125  trivert.PrepareForUse();
1126  trisurf.PrepareForUse();
1127 }
1128 
1129 void triangulation::CleanDynaTri()
1130 {
1131  vector<int> triDel, pDEl;
1132  int ii, jj, n, n2;
1133 
1134  n = dynatri.size();
1135  // remove the triangles of which the surface is gone or modif
1136  for (ii = 0; ii < n; ++ii)
1137  {
1138  if (snakeDep->snakeconn.surfs.find(dynatri(ii)->KeyParent()) == __notfound)
1139  {
1140  triDel.push_back(dynatri(ii)->index);
1141  }
1142  else if (snakeDep->snakeconn.surfs.isearch(dynatri(ii)->KeyParent())->returnIsModif())
1143  {
1144  triDel.push_back(dynatri(ii)->index);
1145  }
1146  }
1147  n = triDel.size();
1148  // Remove the surface centroid points that were in the removed triangles
1149  for (ii = 0; ii < n; ++ii)
1150  {
1151  n2 = 3; // dynatri.isearch(triDel[ii])->pointtype.size();
1152  for (jj = 0; jj < n2; ++jj)
1153  {
1154  if (dynatri.isearch(triDel[ii])->pointtype[jj] == meshtypes::triangulation)
1155  {
1156  pDEl.push_back(dynatri.isearch(triDel[ii])->pointind[jj]);
1157  }
1158  }
1159  }
1160 
1161  n = trivert.size();
1162  // Remove the surface centroid points that are in the intertri
1163  for (ii = 0; ii < n; ++ii)
1164  {
1165  if (trivert(ii)->parentType == meshtypes::triangulation)
1166  {
1167  pDEl.push_back(trivert(ii)->index);
1168  }
1169  }
1170 
1171  dynatri.remove(triDel);
1172  trivert.remove(pDEl);
1173  intertri.clear();
1174  trisurf.clear();
1175 
1176  PrepareForUse();
1177 }
1178 void triangulation::CalcTriVertPos()
1179 {
1180  int ii, n;
1181  n = trivert.size();
1182  for (ii = 0; ii < n; ++ii)
1183  {
1184  CalcTriVertPos(ii);
1185  }
1186 }
1187 void triangulation::CalcTriVertPos(int ii)
1188 {
1189  if (trivert(ii)->parentType == meshtypes::mesh)
1190  {
1191  SnakeSurfaceCentroid_fun(trivert[ii].coord, *(meshDep->surfs.isearch(trivert(ii)->parentsurf)), *meshDep);
1192  }
1193  else if (trivert(ii)->parentType == meshtypes::snake)
1194  {
1195  SnakeSurfaceCentroid_fun(trivert[ii].coord, *(snakeDep->snakeconn.surfs.isearch(trivert(ii)->parentsurf)),
1196  snakeDep->snakeconn);
1197  }
1198  else if (trivert(ii)->parentType == meshtypes::triangulation)
1199  {
1200  HybridSurfaceCentroid_fun(trivert[ii].coord, *(trisurf.isearch(trivert(ii)->parentsurf)), *(meshDep),
1201  snakeDep->snakeconn);
1202  }
1203 }
1204 void triangulation::CalcTriVertPosDyna()
1205 {
1206  int ii, n;
1207  n = trivert.size();
1208  for (ii = 0; ii < n; ++ii)
1209  {
1210  CalcTriVertPosDyna(ii);
1211  }
1212 }
1213 void triangulation::CalcTriVertPosDyna(int ii)
1214 {
1215  if (trivert(ii)->parentType == meshtypes::snake)
1216  {
1217  SnakeSurfaceCentroid_fun(trivert[ii].coord, *(snakeDep->snakeconn.surfs.isearch(trivert(ii)->parentsurf)),
1218  snakeDep->snakeconn);
1219  }
1220  else if (trivert(ii)->parentType == meshtypes::triangulation)
1221  {
1222  HybridSurfaceCentroid_fun(trivert[ii].coord, *(trisurf.isearch(trivert(ii)->parentsurf)), *(meshDep),
1223  snakeDep->snakeconn);
1224  }
1225 }
1226 void triangulation::SetActiveStaticTri()
1227 {
1228  vector<int> subList;
1229  vector<bool> isObjDone;
1230  int ii, ni, jj, nj;
1231  // Look through all statri if
1232  acttri.clear();
1233  ni = stattri.size();
1234  isObjDone.assign(ni, false);
1235  // trisurf.HashParent();
1236  for (ii = 0; ii < ni; ++ii)
1237  {
1238  if (!isObjDone[ii])
1239  {
1240  stattri.findsiblings(stattri(ii)->KeyParent(), subList);
1241  if (trisurf.findparent(stattri(ii)->KeyParent()) == __notfound)
1242  {
1243  nj = stattri(ii)->pointtype.size();
1244  for (jj = 0; jj < nj; ++jj)
1245  {
1246  if (stattri(ii)->pointtype[jj] == meshtypes::mesh)
1247  {
1248  break;
1249  }
1250  }
1251  if (jj == nj)
1252  {
1253  RSVS3D_ERROR_ARGUMENT("Static triangulation failed to "
1254  "return a mesh vertex");
1255  }
1256  if (snakeDep->isMeshVertIn[meshDep->verts.find(stattri(ii)->pointind[jj])])
1257  {
1258  nj = subList.size();
1259  for (jj = 0; jj < nj; ++jj)
1260  {
1261  acttri.push_back(stattri(subList[jj])->index);
1262  }
1263  }
1264  }
1265  nj = subList.size();
1266  for (jj = 0; jj < nj; ++jj)
1267  {
1268  isObjDone[subList[jj]] = true;
1269  }
1270  }
1271  }
1272 }
1273 
1274 void triangulation::SetConnectivity()
1275 {
1276  int ii, ni;
1277  ni = stattri.size();
1278  for (ii = 0; ii < ni; ++ii)
1279  {
1280  if (stattri(ii)->connec.celltarg.size() == 0)
1281  {
1282  this->SetConnectivityStat(ii);
1283  }
1284  }
1285 
1286  ni = intertri.size();
1287  for (ii = 0; ii < ni; ++ii)
1288  {
1289  // if(intertri(ii)->connec.celltarg.size()==0){
1290  this->SetConnectivityInter(ii);
1291  // }
1292  }
1293  ni = dynatri.size();
1294  for (ii = 0; ii < ni; ++ii)
1295  {
1296  if (dynatri(ii)->connec.celltarg.size() == 0)
1297  {
1298  this->SetConnectivityDyna(ii);
1299  }
1300  }
1301 }
1302 
1303 void triangulation::SetConnectivityInter(int ii)
1304 {
1305  int prevHash = this->intertri.isHash;
1306  this->intertri[ii].connec.celltarg = this->trisurf.isearch(this->intertri(ii)->parentsurf)->voluind;
1307  this->intertri[ii].connec.constrinfluence = {-1.0, 1.0};
1308  this->intertri.isHash = prevHash;
1309 }
1310 void triangulation::SetConnectivityStat(int ii)
1311 {
1312  int prevHash = stattri.isHash;
1313  stattri[ii].connec.celltarg = meshDep->surfs.isearch(stattri(ii)->parentsurf)->voluind;
1314  stattri[ii].connec.constrinfluence = {-1.0, 1.0};
1315  stattri.isHash = prevHash;
1316 }
1317 void triangulation::SetConnectivityDyna(int ii)
1318 {
1319  // Set the tri.connec of snake surfaces
1320  // Look at the tri surface, find the side which points in
1321  // if it is jj=0 influence is -1 if jj=1 influence is 1
1322  //
1323  int voluStore, jj, prevHash;
1324 
1325  voluStore = snakeDep->snaxsurfs.isearch(dynatri(ii)->parentsurf)->voluind;
1326  jj = 0;
1327  jj = (snakeDep->snakeconn.surfs.isearch(dynatri(ii)->parentsurf)->voluind[jj] == 0);
1328 
1329  prevHash = dynatri.isHash;
1330  dynatri[ii].connec.celltarg.clear();
1331  dynatri[ii].connec.constrinfluence.clear();
1332  dynatri[ii].connec.celltarg.push_back(voluStore);
1333  dynatri[ii].connec.constrinfluence.push_back(float(-1 + 2 * jj));
1334  dynatri.isHash = prevHash;
1335 }
1336 
1342 {
1343  this->stattri.clear();
1344  this->dynatri.clear();
1345  this->intertri.clear();
1346  this->trivert.clear();
1347  this->trisurf.clear();
1348  this->acttri.clear();
1349 }
1350 #pragma GCC diagnostic push
1351 #pragma GCC diagnostic ignored "-Wunused-parameter"
1352 void triangle::disp() const
1353 {
1354 }
1355 void triangle::ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu)
1356 {
1357 }
1358 void triangle::read(FILE *fid)
1359 {
1360 }
1361 void triangle::write(FILE *fid) const
1362 {
1363 }
1364 
1365 void trianglepoint::disp() const
1366 {
1367 }
1368 void trianglepoint::ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu)
1369 {
1370 }
1371 void trianglepoint::ChangeIndicesSnakeMesh(int nVert, int nEdge, int nSurf, int nVolu)
1372 {
1373 }
1374 void trianglepoint::read(FILE *fid)
1375 {
1376 }
1377 void trianglepoint::write(FILE *fid) const
1378 {
1379 }
1380 
1381 void trianglesurf::disp() const
1382 {
1383  cout << "trianglesurf " << index << " parent " << parentsurfmesh << endl;
1384  cout << "indvert: ";
1385  DisplayVector(indvert);
1386  cout << endl;
1387  cout << "typevert: ";
1388  DisplayVector(typevert);
1389  cout << endl;
1390 }
1391 void trianglesurf::ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu)
1392 {
1393 }
1394 void trianglesurf::ChangeIndicesSnakeMesh(int nVert, int nEdge, int nSurf, int nVolu)
1395 {
1396 }
1397 void trianglesurf::read(FILE *fid)
1398 {
1399 }
1400 void trianglesurf::write(FILE *fid) const
1401 {
1402 }
1403 #pragma GCC diagnostic pop
Provides the infrastructure for calculation of the RSVS equations.
Performs Volume and Area calculations for the RSVS process.
Provide std::vector container with hashed index mapping.
Class containing the information needed to trim objects from a mesh.
Definition: mesh.hpp:514
Class to handle the RSVS calculation.
Definition: RSVScalc.hpp:130
void PrepTriangulationCalc(const triangulation &triRSVS)
Groups actions needed before the calculation of triangular quantities.
Definition: RSVScalc.cpp:35
HashedMap< int, int, int > constrMap
maps snakemesh() volu onto constr
Definition: RSVScalc.hpp:204
int numConstr() const
Getter for the number of constraints.
Definition: RSVScalc.hpp:455
Handles the use and norm of a vector for which the norm and the unit value might be needed.
Definition: mesh.hpp:114
Class for an edge object in a mesh.
Definition: mesh.hpp:353
Class for mesh handling.
Definition: mesh.hpp:592
Definition: snake.hpp:83
Class for surface object in a mesh.
Definition: mesh.hpp:267
void clear()
Clears the contents of the triangulation making sure we can restart the process.
Class for a vertex in a mesh.
Definition: mesh.hpp:448
Provides all the mesh tools used for the generation of 3D grids and geometries.
std::vector< const std::vector< double > * > coordlist
Defines a list of coordinates.
Definition: mesh.hpp:87
Provides various utility functions for the RSVS operation.
Provides the core restricted surface snake container.
Provides a triangulation for snake and meshes.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.
Definition: warning.hpp:148