1 #define _USE_MATH_DEFINES
15 void FlattenBoundaryFaces(
mesh &meshin)
22 vector<int> subList, vertList;
23 std::array<bool, 3> isFlat;
28 nSurf = meshin.surfs.size();
29 subList.reserve(nSurf);
31 triangleRSVS.stattri.clear();
32 triangleRSVS.trivert.clear();
33 triangleRSVS.PrepareForUse();
36 for (
int i = 0; i < nSurf; ++i)
38 if (meshin.surfs(i)->isBorder && meshin.surfs(i)->edgeind.size() > 3)
40 meshin.surfs(i)->OrderedVerts(&meshin, vertList);
41 vertList = meshin.verts.find_list(vertList);
44 int count = vertList.size();
45 for (
int j = 1; j < count; ++j)
47 for (
int k = 0; k < 3; ++k)
49 isFlat[k] = isFlat[k] &&
50 (fabs(meshin.verts(vertList[j])->coord[k] - meshin.verts(vertList[0])->coord[k]) < tol);
53 if (!(isFlat[0] || isFlat[1] || isFlat[2]))
60 if (subList.size() > 0)
62 TriangulateContainer(meshin, triangleRSVS, 1, subList);
63 triangleRSVS.meshDep = &meshin;
65 triangleRSVS.PrepareForUse();
66 triangleRSVS.CalcTriVertPos();
67 triangleRSVS.PrepareForUse();
69 auto newSurfs = ConcatenateVectorField(meshin.surfs, &surf::edgeind, subList);
72 MeshTriangulation(meshout, meshin, triangleRSVS.stattri, triangleRSVS.trivert);
74 meshin.PrepareForUse();
76 meshin.TightenConnectivity();
82 void TriangulateAllFaces(
mesh &meshin)
89 nSurf = meshin.surfs.size();
90 subList.reserve(nSurf);
92 triangleRSVS.stattri.clear();
93 triangleRSVS.trivert.clear();
94 triangleRSVS.PrepareForUse();
96 TriangulateContainer(meshin, triangleRSVS, 1, {});
97 triangleRSVS.meshDep = &meshin;
99 triangleRSVS.PrepareForUse();
100 triangleRSVS.CalcTriVertPos();
101 triangleRSVS.PrepareForUse();
103 auto newSurfs = ConcatenateVectorField(meshin.surfs, &surf::edgeind, subList);
106 MeshTriangulation(meshout, meshin, triangleRSVS.stattri, triangleRSVS.trivert);
108 meshin.PrepareForUse();
110 meshin.TightenConnectivity();
127 int ii, cntII, jj, cntJJ, kk, cntKK, ll;
128 auto &vols = snakein.snakeconn.volus;
129 std::vector<bool> vertExplored;
130 std::vector<int> holeInds;
131 int vertAct, holeInd = -1;
133 vertExplored.assign(snakein.isMeshVertIn.size(),
false);
141 cntII = snakein.snakeconn.volus.size();
142 holeInds.reserve(cntII);
143 for (ii = 0; ii < cntII; ++ii)
145 cntJJ = vols(ii)->surfind.size();
146 for (jj = 0; jj < cntJJ; ++jj)
149 snakein.snakeconn.edges.find_list(snakein.snakeconn.surfs.isearch(vols(ii)->surfind[jj])->edgeind);
150 cntKK = surfEdgeind.size();
151 for (kk = 0; kk < cntKK; ++kk)
153 for (ll = 0; ll < 2; ++ll)
155 vertAct = snakein.snaxs.isearch(snakein.snakeconn.edges(surfEdgeind[kk])->vertind[ll])->fromvert;
156 holeInd = FindVertexHole(vertAct, *(snakein.snakemesh()), snakein.isMeshVertIn, uncertainVert,
175 holeInds.push_back(holeInd);
177 std::cout << std::endl << holeInd << std::endl;
202 std::vector<int> holeIndices;
208 meshtemp = snakein.snakeconn;
212 auto groupedVertices = GroupCloseSnaxels(snakein, distanceTol);
213 meshtemp.MergeGroupedVertices(groupedVertices);
214 meshtemp.RemoveSingularConnectors();
216 meshtemp.PrepareForUse();
217 meshtemp.TestConnectivityBiDir(__PRETTY_FUNCTION__);
218 meshtemp.TightenConnectivity();
219 meshtemp.OrderEdges();
224 triRSVS.stattri.clear();
225 triRSVS.trivert.clear();
226 triRSVS.PrepareForUse();
227 TriangulateMesh(meshtemp, triRSVS);
229 triRSVS.PrepareForUse();
230 triRSVS.CalcTriVertPos();
231 MeshTriangulation(meshgeom, meshtemp, triRSVS.stattri, triRSVS.trivert);
232 meshgeom.PrepareForUse();
234 meshgeom.TightenConnectivity();
235 meshgeom.OrderEdges();
238 holeIndices = FindHolesInSnake(snakein, groupedVertices);
239 nHoles = holeIndices.size();
241 holeCoords.assign(nHoles * 3, 0.0);
243 for (
int i = 0; i < nHoles; ++i)
245 for (
int j = 0; j < 3; ++j)
247 holeCoords[i * 3 + j] = snakein.snakemesh()->verts.isearch(holeIndices[i])->coord[j];
258 std::vector<int> sameSnaxs, rmvInds;
261 nSnax = snakein.snaxs.size();
262 closeVert.vec.assign(nSnax, -1);
268 for (
int i = 0; i < nSnax; ++i)
270 if ((snakein.snaxs(i)->d < distTol))
272 closeVert.vec[i] = snakein.snaxs(i)->fromvert;
274 else if (((1 - snakein.snaxs(i)->d) < distTol))
276 closeVert.vec[i] = snakein.snaxs(i)->tovert;
280 closeVert.GenerateHash();
284 void TestVertClose(
int vertIndIn, std::vector<bool> &isSnaxDone,
const mesh &meshin,
double distTol,
285 std::vector<int> &sameEdges)
291 if (!isSnaxDone[vertIndIn])
293 isSnaxDone[vertIndIn] =
true;
294 for (
auto eInd : meshin.verts(vertIndIn)->edgeind)
297 for (
int i = 0; i < 3; ++i)
299 d += pow((meshin.verts.isearch(meshin.edges.isearch(eInd)->vertind[0])->coord[i] -
300 meshin.verts.isearch(meshin.edges.isearch(eInd)->vertind[1])->coord[i]),
305 sameEdges.push_back(eInd);
306 for (
int i = 0; i < 2; ++i)
308 nextvertIndIn = meshin.verts.find(meshin.edges.isearch(eInd)->vertind[i]);
309 TestVertClose(nextvertIndIn, isSnaxDone, meshin, distTol, sameEdges);
321 std::vector<bool> isSnaxDone, isEdgeDone;
323 std::vector<int> sameEdges, rmvInds;
324 int nSnax, nEdge, nGroup = 1;
326 distTol = distTol * distTol;
327 nSnax = meshin.verts.size();
328 nEdge = meshin.edges.size();
329 closeVert.vec.assign(nSnax, -1);
330 isSnaxDone.assign(nSnax,
false);
331 isEdgeDone.assign(nEdge,
false);
332 sameEdges.reserve(10);
338 for (
int i = 0; i < nSnax; ++i)
341 TestVertClose(i, isSnaxDone, meshin, distTol, sameEdges);
343 if (sameEdges.size() > 0)
345 for (
auto eInd : sameEdges)
347 closeVert.vec[meshin.verts.find(meshin.edges.isearch(eInd)->vertind[0])] = nGroup;
351 closeVert.vec[meshin.verts.find(meshin.edges.isearch(eInd)->vertind[1])] = nGroup;
363 closeVert.GenerateHash();
367 int FindVertexHole(
int vertInd,
const mesh &meshin,
const std::vector<bool> &vertIn,
380 std::vector<int> currVertList, nextEdgeList;
382 int ii, cntII, jj, cntJJ, vertPos, vertFound;
384 currVertList.reserve(20);
385 nextEdgeList.reserve(20);
386 currVertList.push_back(vertInd);
388 while (currVertList.size() > 0)
390 nextEdgeList.clear();
391 cntII = currVertList.size();
392 for (ii = 0; ii < cntII; ++ii)
394 vertPos = meshin.verts.find(currVertList[ii]);
395 if (!vertExplored[vertPos] && vertIn[vertPos])
397 vertExplored[vertPos] =
true;
398 vertFound = uncertainVert.find(currVertList[ii]);
402 returnInd = currVertList[ii];
404 currVertList.clear();
410 cntJJ = meshin.verts(vertPos)->edgeind.size();
411 for (jj = 0; jj < cntJJ; ++jj)
413 nextEdgeList.push_back(meshin.verts(vertPos)->edgeind[jj]);
421 currVertList.clear();
422 if (nextEdgeList.size() > 0)
424 currVertList = ConcatenateVectorField(meshin.edges, &edge::vertind, nextEdgeList);
432 double DomInter(
double x,
double y1,
double y2)
435 return x * (y2 - y1) + y1;
438 mesh BuildDomain(
const std::array<double, 3> &lowerB,
const std::array<double, 3> &upperB,
double tolInner)
449 if (lowerB.size() != 3 || upperB.size() != 3)
451 std::cerr <<
"Error in " << __PRETTY_FUNCTION__
452 <<
" vectors must be"
458 std::array<int, 3> dimGrid = {1, 1, 1};
459 BuildBlockGrid(dimGrid, cube);
461 count = cube.verts.size();
462 for (
int i = 0; i < count; ++i)
464 for (
int j = 0; j < 3; ++j)
466 cube.verts[i].coord[j] =
467 (cube.verts[i].coord[j] * ((upperB[j] + tolInner) - (lowerB[j] - tolInner))) + (lowerB[j] - tolInner);
513 const std::array<double, 3> &innerLowerB,
const std::array<double, 3> &innerUpperB,
int nSteps,
514 std::vector<int> &vertPerSubDomain)
516 mesh meshdomain, meshtemp;
518 std::array<std::array<double, 2>, 3> scaleDom;
523 meshdomain.Init(0, 0, 0, 0);
524 meshdomain.PrepareForUse();
530 vertPerSubDomain.clear();
531 meshdomain = BuildDomain(innerLowerB, innerUpperB, 0.1);
532 meshdomain.PrepareForUse();
533 meshtemp = meshdomain;
534 meshtemp.PrepareForUse();
535 vertPerSubDomain.push_back(meshtemp.verts.size());
537 for (
int i = 1; i < nSteps; ++i)
539 x = double(i) / double(nSteps - 1);
540 for (
int j = 0; j < 3; ++j)
542 scaleDom[j] = {DomInter(x, innerLowerB[j], outerLowerB[j]), DomInter(x, innerUpperB[j], outerUpperB[j])};
545 meshtemp.Scale(scaleDom);
546 meshtemp.PrepareForUse();
547 meshdomain.MakeCompatible_inplace(meshtemp);
548 meshdomain.Concatenate(meshtemp);
549 meshdomain.PrepareForUse();
551 vertPerSubDomain.push_back(meshtemp.verts.size());
569 double surfaceAngle = 0.0;
570 auto getcoord = [&](
int indexVert) ->
const std::vector<double> {
return meshin.verts.isearch(indexVert)->coord; };
573 for (
auto surfind : surfInds)
575 if (meshin.surfs.isearch(surfind)->voluind[0] != 0 && meshin.surfs.isearch(surfind)->voluind[1] != 0)
581 std::array<std::array<int, 3>, 2> surfPoints;
582 for (
int i = 0; i < 2; ++i)
584 int nPts = meshhelp::Get3PointsInSurface(meshin, surfInds[i], surfPoints[i]);
591 bool surfOrientSame =
592 (meshin.surfs.isearch(surfInds[0])->voluind[0] == 0 &&
593 (meshin.surfs.isearch(surfInds[0])->voluind[0] == meshin.surfs.isearch(surfInds[1])->voluind[0])) ||
594 (meshin.surfs.isearch(surfInds[0])->voluind[1] == 0 &&
595 (meshin.surfs.isearch(surfInds[0])->voluind[1] == meshin.surfs.isearch(surfInds[1])->voluind[1]));
597 surfaceAngle = PlanesDotProduct(getcoord(surfPoints[0][0]), getcoord(surfPoints[0][1]), getcoord(surfPoints[0][2]),
598 getcoord(surfPoints[1][0]), getcoord(surfPoints[1][1 + surfOrientSame]),
599 getcoord(surfPoints[1][2 - surfOrientSame]),
true);
601 return (2.0 - (surfaceAngle + 1.0)) / 2.0;
614 std::vector<double> edgeCurvatures;
615 int nEdges = meshin.edges.size();
616 edgeCurvatures.assign(nEdges, 0);
617 for (
int i = 0; i < nEdges; ++i)
619 int nSurfsEdge = meshin.edges(i)->surfind.size();
620 for (
int j = 0; j < nSurfsEdge; ++j)
622 for (
int k = j + 1; k < nSurfsEdge; ++k)
625 PseudoSurfaceAngle(meshin, {meshin.edges(i)->surfind[j], meshin.edges(i)->surfind[k]});
630 return edgeCurvatures;
643 std::vector<double> vertCurvatures, edgeCurvatures;
644 int nVerts = meshin.verts.size();
645 int nEdges = meshin.edges.size();
647 vertCurvatures.assign(nVerts, 0);
656 for (
int i = 0; i < nEdges; ++i)
658 edgeCurvatures[i] = 0.0;
659 for (
auto vertInd : meshin.edges(i)->vertind)
662 vertCurvatures[meshin.verts.find(vertInd)] / meshin.verts.isearch(vertInd)->edgeind.size();
664 edgeCurvatures[i] = edgeCurvatures[i] / 2;
667 for (
int i = 0; i < nVerts; ++i)
669 for (
auto edgeInd : meshin.verts(i)->edgeind)
671 vertCurvatures[i] += edgeCurvatures[meshin.edges.find(edgeInd)];
675 vertCurvatures[i] = vertCurvatures[i] / 2;
679 }
while (nSteps < smoothingSteps);
681 return vertCurvatures;
693 std::vector<double> vertEdgeLength;
694 int nVerts = meshin.verts.size();
695 vertEdgeLength.assign(nVerts, 0);
699 for (
int i = 0; i < nVerts; ++i)
701 vertEdgeLength[i] = INFINITY;
702 for (
auto edgeInd : meshin.verts(i)->edgeind)
704 double testLength = edgeLength[meshin.edges.find(edgeInd)];
705 vertEdgeLength[i] = testLength < vertEdgeLength[i] ? testLength : vertEdgeLength[i];
708 return vertEdgeLength;
720 std::vector<double> vertEdgeLength;
721 int nVerts = meshin.verts.size();
722 vertEdgeLength.assign(nVerts, 0);
726 for (
int i = 0; i < nVerts; ++i)
728 vertEdgeLength[i] = -INFINITY;
729 for (
auto edgeInd : meshin.verts(i)->edgeind)
731 double testLength = edgeLength[meshin.edges.find(edgeInd)];
732 vertEdgeLength[i] = testLength > vertEdgeLength[i] ? testLength : vertEdgeLength[i];
735 return vertEdgeLength;
747 std::vector<double> vertEdgeLength;
748 int nVerts = meshin.verts.size();
750 vertEdgeLength.assign(nVerts, 0);
753 for (
int i = 0; i < nVerts; ++i)
755 vertEdgeLength[i] = INFINITY;
756 for (
auto edgeInd : meshin.verts(i)->edgeind)
758 double testLength = edgeLength[meshin.edges.find(edgeInd)];
759 vertEdgeLength[i] += testLength;
761 vertEdgeLength[i] = vertEdgeLength[i] / meshin.verts(i)->edgeind.size();
763 return vertEdgeLength;
775 std::vector<double> edgeLength;
776 int nEdges = meshin.edges.size();
777 edgeLength.assign(nEdges, 0);
779 for (
int i = 0; i < nEdges; ++i)
781 edgeLength[i] = meshin.edges(i)->Length(meshin);
796 std::vector<double> vecPts;
800 nVolu = meshin.volus.size();
801 vecPts.assign(nVolu * 3, 0.0);
803 for (
int i = 0; i < nVolu; ++i)
806 for (
auto surfInd : meshin.volus(i)->surfind)
808 for (
auto edgeInd : meshin.surfs.isearch(surfInd)->edgeind)
810 for (
auto vertInd : meshin.edges.isearch(edgeInd)->vertind)
812 for (
int j = 0; j < 3; ++j)
814 vecPts[i * 3 + j] += meshin.verts.isearch(vertInd)->coord[j];
820 for (
int j = 0; j < 3; ++j)
822 vecPts[i * 3 + j] = vecPts[i * 3 + j] / double(nPtsPerVolu);
839 std::vector<double> vecPts;
842 nVolu = meshin.volus.size();
843 vecPts.assign(nVolu * 3, 0.0);
845 for (
int i = 0; i < nVolu; ++i)
847 auto voluCoord = meshin.volus(i)->PseudoCentroid(meshin);
848 for (
int j = 0; j < 3; ++j)
850 vecPts[i * 3 + j] = voluCoord[j];
876 size_t nVolu = meshin.volus.size();
878 auto multcentre = [&](
size_t pos) ->
double {
return double(pos + 1) / double(nLayers + 1); };
879 auto multvert = [&](
size_t pos) ->
double {
return double(nLayers - pos) / double(nLayers + 1); };
881 vecPts.reserve(nVolu * 3 * (8 *
size_t(nLayers) + 1));
882 for (
size_t i = 0; i < nVolu; ++i)
884 auto voluVerts = meshin.verts.find_list(meshin.volus(i)->vertind(meshin));
886 for (
auto vertSub : voluVerts)
888 for (
size_t j = 0; j < size_t(nLayers); ++j)
890 for (
size_t k = 0; k < 3; ++k)
892 vecPts.push_back(vecPts[i * 3 + k] * multcentre(j) + meshin.verts(vertSub)->coord[k] * multvert(j));
910 std::vector<double> vecPts;
913 nSurf = meshin.surfs.size();
914 vecPts.assign(nSurf * 3, 0.0);
916 for (
int i = 0; i < nSurf; ++i)
918 auto surfCoord = meshin.surfs(i)->PseudoCentroid(meshin);
919 for (
int j = 0; j < 3; ++j)
921 vecPts[i * 3 + j] = surfCoord[j];
947 size_t nSurfs = meshin.surfs.size();
949 auto multcentre = [&](
size_t pos) ->
double {
return double(pos + 1) / double(nLayers + 1); };
950 auto multvert = [&](
size_t pos) ->
double {
return double(nLayers - pos) / double(nLayers + 1); };
952 vecPts.reserve(nSurfs * 3 * (8 *
size_t(nLayers) + 1));
953 for (
size_t i = 0; i < nSurfs; ++i)
955 auto tempEdge = meshin.edges.find_list(meshin.surfs(i)->edgeind);
956 auto surfInd = ConcatenateVectorField(meshin.edges, &edge::vertind, tempEdge);
957 auto surfVerts = meshin.verts.find_list(surfInd);
959 for (
auto vertSub : surfVerts)
961 for (
size_t j = 0; j < size_t(nLayers); ++j)
963 for (
size_t k = 0; k < 3; ++k)
965 vecPts.push_back(vecPts[i * 3 + k] * multcentre(j) + meshin.verts(vertSub)->coord[k] * multvert(j));
973 double CotanLaplacianWeight(
const vector<double> ¢re,
const vector<double> &p_im1,
const vector<double> &p_i,
976 double w_centrei = 0.0;
978 double angle_im1 =
Angle3Points(p_im1, centre, p_i, temp1, temp2);
979 double angle_ip1 =
Angle3Points(p_ip1, centre, p_i, temp1, temp2);
980 auto cot = [&](
double x) ->
double {
return tan(M_PI_2 - x); };
982 w_centrei = 0.5 * (cot(angle_im1) + cot(angle_ip1));
987 int VertexLaplacianVector(
const mesh &meshin,
const vert *vertsmooth,
coordvec &lapVec,
bool isOrdered)
991 double totalCotan = 0.0;
995 std::vector<int> edgeIndModif;
996 const std::vector<int> *edgeIndOutPtr = &(vertsmooth->edgeind);
999 auto retOrder = vertsmooth->OrderEdges(&meshin, edgeIndModif);
1000 if (!rsvs3d::constants::ordering::__isordered(retOrder))
1002 return rsvs3d::constants::__failure;
1004 edgeIndOutPtr = &edgeIndModif;
1008 auto &edgindOrdered = *edgeIndOutPtr;
1010 lapVec.assign(0.0, 0.0, 0.0);
1012 int nVerts = edgindOrdered.size();
1015 return rsvs3d::constants::__failure;
1019 for (
int i = 0; i < nVerts; ++i)
1021 int connVert = meshin.
VertFromVertEdge(vertsmooth->index, edgindOrdered[i]);
1022 int connVert_m1 = meshin.
VertFromVertEdge(vertsmooth->index, edgindOrdered[(i - 1 + nVerts) % nVerts]);
1023 int connVert_p1 = meshin.
VertFromVertEdge(vertsmooth->index, edgindOrdered[(i + 1) % nVerts]);
1024 tempPos = meshin.verts.isearch(connVert)->coord;
1026 double currCotan = CotanLaplacianWeight(vertsmooth->coord, meshin.verts.isearch(connVert_m1)->coord,
1027 meshin.verts.isearch(connVert)->coord,
1028 meshin.verts.isearch(connVert_p1)->coord, temp1, temp2);
1030 if (!isfinite(currCotan))
1032 return rsvs3d::constants::__failure;
1034 tempPos.mult(currCotan);
1035 totalCotan += currCotan;
1036 lapVec.add(tempPos.usedata());
1039 lapVec.div(totalCotan);
1040 lapVec.substract(vertsmooth->coord);
1041 if (rsvs3d::utils::IsAproxEqual(lapVec.GetNorm(), 0.0))
1043 lapVec.assign(0.0, 0.0, 0.0);
1045 return rsvs3d::constants::__success;
1048 coordvec VertexLaplacianVector(
const mesh &meshin,
int vertIndex)
1051 VertexLaplacianVector(meshin, meshin.verts.isearch(vertIndex), lapVec);
1073 a = lineVec.dot(lineVec.usedata());
1074 b = 2 * lineVec.dot(offset.usedata());
1075 c = offset.dot(offset.usedata()) - (sphereRadius * sphereRadius);
1077 double det = b * b - (4 * a * c);
1078 double inva = 1.0 / (2.0 * a);
1081 return {-INFINITY, INFINITY};
1083 if (rsvs3d::utils::IsAproxEqual(det, 0.0))
1085 double sol = -b * inva;
1089 return {(-b - det) * inva, (-b + det) * inva};
1093 const coordvec &sphereCentre,
double sphereRadius)
1097 offset.substract(sphereCentre.usedata());
1101 std::vector<double> MeshUnitNormals(
const mesh &meshin)
1103 std::vector<double> coords;
1104 int nVert = meshin.verts.size();
1105 coords.reserve(nVert * 3);
1110 for (
int i = 0; i < nVert; ++i)
1112 meshin.verts(i)->Normal(&meshin, neighCoord, normal);
1114 for (
int j = 0; j < 3; ++j)
1116 coords.push_back(normal(j));
1122 std::vector<double> MeshLaplacians(
const mesh &meshin)
1124 std::vector<double> coords;
1125 int nVert = meshin.verts.size();
1126 coords.reserve(nVert * 3);
1131 for (
int i = 0; i < nVert; ++i)
1133 VertexLaplacianVector(meshin, meshin.verts(i), lapVec);
1135 for (
int j = 0; j < 3; ++j)
1137 coords.push_back(lapVec(j));
Handles the use and norm of a vector for which the norm and the unit value might be needed.
int VertFromVertEdge(int v, int e) const
Returns the vertex in edges.isearch(e)->vertind which does not match v.
Class for a vertex in a mesh.
std::vector< const std::vector< double > * > coordlist
Defines a list of coordinates.
double Angle3Points(const std::vector< double > ¢re, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &vec1, coordvec &vec2)
Calculates a plane's normal vector.
Tools for the mathematical processing of meshes.
std::vector< double > CalculateEdgeCurvature(const mesh &meshin)
Calculates the angles between the surfaces connected at an edge.
std::vector< double > CalculateVertexCurvature(const mesh &meshin, int smoothingSteps)
Calculates the vertex curvature.
std::array< double, 2 > IntersectLineSphere(const coordvec &lineVec, const coordvec &offset, double sphereRadius)
Calculates the parametric position along a line at which it intersects a sphere.
std::vector< double > CalculateEdgeLengths(const mesh &meshin)
Calculates the edge lengths.
std::vector< double > SurfaceCentroids(const mesh &meshin)
Generate a vector of coordinates of points at the surfaces pseudo centroid.
mesh BuildCutCellDomain(const std::array< double, 3 > &outerLowerB, const std::array< double, 3 > &outerUpperB, const std::array< double, 3 > &innerLowerB, const std::array< double, 3 > &innerUpperB, int nSteps, std::vector< int > &vertPerSubDomain)
Builds a series of domains with different edge properties controlling the interpolation of the metric...
std::vector< double > CalculateVertexMinEdgeLength(const mesh &meshin)
Calculates the vertex minimum edge length.
std::vector< double > VolumeInternalLayers(const mesh &meshin, int nLayers)
Returns points on edges between volume pseudo centroid and vertices.
std::vector< double > CalculateVertexMeanEdgeLength(const mesh &meshin)
Calculates the vertex mean edge length.
std::vector< double > SurfaceInternalLayers(const mesh &meshin, int nLayers)
Returns points on edges between surface pseudo centroid and vertices.
std::vector< double > VolumeCentroids(const mesh &meshin)
Generate a vector of coordinates of points at the volume pseudo centroid.
double PseudoSurfaceAngle(const mesh &meshin, const std::array< int, 2 > &surfInds)
Calculates the pseudo surface angle.
std::vector< double > CalculateVertexMaxEdgeLength(const mesh &meshin)
Calculates the vertex maximum edge length.
std::vector< double > CoordInVolume(const mesh &meshin)
Generate a vector of coordinates of points probably inside volumes.
void PrepareSnakeForCFD(const snake &snakein, double distanceTol, mesh &meshgeom, std::vector< double > &holeCoords)
Prepares the snake to be used for CFD, removes duplicate points and triangulates it.
Provides various utility functions for the RSVS operation.
Provides a triangulation for snake and meshes.
Generation of cartesian grids.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.