1 #define _USE_MATH_DEFINES
19 namespace rsvsorder = rsvs3d::constants::ordering;
20 namespace rsvslogic = rsvs3d::logicals;
24 double &coordvec::operator[](
int a)
28 if ((unsigned_int(a) >= 3) | (0 > a))
36 double coordvec::operator()(
int a)
const
40 if ((unsigned_int(a) >= 3) | (0 > a))
48 void coordvec::swap(vector<double> &vecin)
50 if (
int(vecin.size()) != 3)
53 "vector other than 3 long");
55 this->elems.swap(vecin);
56 this->isuptodate =
false;
58 void coordvec::swap(
coordvec &coordin)
60 this->elems.swap(coordin.elems);
62 auto temp = this->norm;
63 this->norm = coordin.norm;
67 auto temp = this->isuptodate;
68 this->isuptodate = coordin.isuptodate;
69 coordin.isuptodate = temp;
73 void coordvec::flipsign()
75 for (
int ii = 0; ii < 3; ++ii)
77 this->elems[ii] = -this->elems[ii];
84 unitCoordVec.Normalize();
85 return (unitCoordVec);
87 double coordvec::Normalize()
89 double oldNorm = this->GetNorm();
91 for (
int ii = 0; ii < 3; ++ii)
93 this->elems[ii] = this->elems[ii] / oldNorm;
99 double coordvec::Unit(
const int a)
const
102 if ((unsigned_int(a) >= 3) | (0 > a))
109 cerr <<
"Warning: NORM of coordvec potentially obsolete " << endl;
110 cerr <<
" in coordvec::Unit(const int a) const" << endl;
111 cerr <<
" To avoid this message perform read operations"
112 " on coordvec using the () operator"
115 return (elems[a] / norm);
118 double coordvec::GetNorm()
127 double coordvec::GetNorm()
const
137 double coordvec::CalcNorm()
139 norm = sqrt(pow(elems[0], 2) + pow(elems[1], 2) + pow(elems[2], 2));
144 void coordvec::PrepareForUse()
149 void coordvec::assign(
double a,
double b,
double c)
157 void coordvec::disp()
const
159 cout <<
"coordvec [" << elems[0] <<
"," << elems[1] <<
"," << elems[2] <<
"] norm " << norm <<
" utd " << isuptodate
165 void coordvec::max(
const vector<double> &vecin)
167 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
168 for (
int ii = 0; ii < n; ++ii)
170 elems[ii] = elems[ii] >= vecin[ii] ? elems[ii] : vecin[ii];
172 this->isuptodate = 0;
174 void coordvec::min(
const vector<double> &vecin)
176 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
177 for (
int ii = 0; ii < n; ++ii)
179 elems[ii] = elems[ii] <= vecin[ii] ? elems[ii] : vecin[ii];
181 this->isuptodate = 0;
184 void coordvec::add(
const vector<double> &vecin)
186 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
187 for (
int ii = 0; ii < n; ++ii)
189 elems[ii] = elems[ii] + vecin[ii];
191 this->isuptodate = 0;
193 void coordvec::substract(
const vector<double> &vecin)
195 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
196 for (
int ii = 0; ii < n; ++ii)
198 elems[ii] = elems[ii] - vecin[ii];
200 this->isuptodate = 0;
202 void coordvec::substractfrom(
const vector<double> &vecin)
204 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
205 for (
int ii = 0; ii < n; ++ii)
207 elems[ii] = vecin[ii] - elems[ii];
209 this->isuptodate = 0;
211 void coordvec::div(
const vector<double> &vecin)
213 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
214 for (
int ii = 0; ii < n; ++ii)
216 elems[ii] = elems[ii] / vecin[ii];
218 this->isuptodate = 0;
220 void coordvec::mult(
const vector<double> &vecin)
222 int n = int(elems.size() <= vecin.size() ? elems.size() : vecin.size());
223 for (
int ii = 0; ii < n; ++ii)
225 elems[ii] = elems[ii] * vecin[ii];
227 this->isuptodate = 0;
230 void coordvec::div(
double scalin)
232 this->mult(1.0 / scalin);
234 void coordvec::mult(
double scalin)
236 int n = int(elems.size());
237 for (
int ii = 0; ii < n; ++ii)
239 elems[ii] = elems[ii] * scalin;
241 this->norm = scalin * this->norm;
244 vector<double> coordvec::cross(
const std::vector<double> &vecin)
const
246 vector<double> retVec;
247 retVec.assign(3, 0.0);
249 for (
int ii = 3; ii < 6; ii++)
251 retVec[ii % 3] = elems[(ii + 1) % 3] * vecin[(ii + 2) % 3] - elems[(ii - 1) % 3] * vecin[(ii - 2) % 3];
256 double coordvec::dot(
const std::vector<double> &vecin)
const
260 for (
int ii = 0; ii < 3; ii++)
262 retVec += elems[ii] * vecin[ii];
266 double coordvec::angle(
const coordvec &coordin)
const
268 double angle = acos(this->dot(coordin.usedata()) / (coordin.GetNorm() * this->GetNorm()));
269 if (!isfinite(angle))
299 diffVerts.substractfrom(vert2);
300 diffVerts.CalcNorm();
313 void DiffPointsFromCentre(
const vector<double> ¢re,
const vector<double> &vert1,
const vector<double> &vert2,
318 diffVert1.substractfrom(vert1);
319 diffVert2.substractfrom(vert2);
320 diffVert1.CalcNorm();
321 diffVert2.CalcNorm();
333 void PlaneNormal(
const vector<double> &planeVert1,
const vector<double> &planeVert2,
const vector<double> &planeVert3,
337 normal = temp1.cross(normal.usedata());
356 double angle = temp1.angle(normal);
357 normal = temp1.cross(normal.usedata());
373 double Angle3Points(
const vector<double> ¢re,
const vector<double> &planeVert2,
const vector<double> &planeVert3,
377 double angle = temp1.angle(normal);
401 const vector<double> &planeVert3,
const vector<double> &testVertex,
coordvec &temp1,
404 double planeDistance = 0.0;
405 if (testVertex.size() != 3)
410 PlaneNormal(planeVert1, planeVert2, planeVert3, temp2, temp1);
412 planeDistance = temp2.dot(testVertex) - temp2.dot(planeVert1);
414 return planeDistance;
439 const vector<double> &planeVert3,
const vector<double> &testVertices,
442 if (testVertices.size() % 3 != 0)
447 std::vector<double> planeDistances, testVertex;
448 size_t nPts = testVertices.size() / 3;
449 planeDistances.assign(nPts, 0.0);
452 return planeDistances;
454 testVertex.assign(3, 0.0);
455 testVertex.assign(testVertices.begin(), testVertices.begin() + 3);
456 planeDistances[0] =
VertexDistanceToPlane(planeVert1, planeVert2, planeVert3, testVertex, temp1, temp2);
457 auto planePosition = temp2.dot(planeVert1);
458 for (
size_t i = 1; i < nPts; ++i)
460 testVertex.assign(testVertices.begin() + 3 * i, testVertices.begin() + 3 * i);
461 planeDistances[i] = temp2.dot(testVertex) - planePosition;
464 return planeDistances;
468 const vector<double> &planeVert3,
const vector<double> &testVertex)
475 const vector<double> &planeVert3,
const vector<double> &testVertices)
498 if (testVertices.size() % sizeVert != 0)
504 vector<int> vertVolumeIndices;
505 size_t nPts = testVertices.size() / sizeVert;
506 vector<double> tempCoord;
507 vertVolumeIndices.assign(nPts, -1);
508 #ifdef RSVS_DIAGNOSTIC_RESOLVED
510 <<
" Number of volumes explored before final "
512 << this->volus.size() << endl;
517 tempCoord.assign(testVertices.begin(), testVertices.begin() + 3);
518 bool needFlip = meshhelp::VertexInVolume(*
this, tempCoord) == 0;
519 for (
size_t i = 0; i < nPts; ++i)
521 tempCoord.assign(testVertices.begin() + i * sizeVert, testVertices.begin() + (i * sizeVert + 3));
522 vertVolumeIndices[i] = meshhelp::VertexInVolume(*
this, tempCoord, needFlip);
524 #ifdef RSVS_DIAGNOSTIC_RESOLVED
527 return vertVolumeIndices;
530 double PlanesDotProduct(
const vector<double> &planeVert1,
const vector<double> &planeVert2,
531 const vector<double> &planeVert3,
const vector<double> &planeVert4,
532 const vector<double> &planeVert5,
const vector<double> &planeVert6,
bool normalize)
536 PlaneNormal(planeVert1, planeVert2, planeVert3, normal1, temp);
537 PlaneNormal(planeVert4, planeVert5, planeVert6, normal2, temp);
543 return normal1.dot(normal2.usedata());
560 this->PseudoCentroid(meshin, coord);
577 double edgeLength = 0.0;
578 double surfLength = 0.0;
579 coord.assign(0, 0, 0);
580 n = int(this->edgeind.size());
581 for (ii = 0; ii < n; ++ii)
583 meshin.edges.isearch(this->edgeind[ii])->GeometricProperties(&meshin, edgeCentre, edgeLength);
584 edgeCentre.mult(edgeLength);
585 coord.add(edgeCentre.usedata());
586 surfLength += edgeLength;
588 if (rsvs3d::utils::IsAproxEqual(surfLength, 0.0))
592 meshin.edges.isearch(this->edgeind[0])->GeometricProperties(&meshin, coord, edgeLength);
597 coord.div(surfLength);
613 double surfLength, voluLength;
614 coordVolu.assign(0, 0, 0);
617 for (
auto surfInd : this->surfind)
619 surfLength = meshin.surfs.isearch(surfInd)->PseudoCentroid(meshin, coordSurf);
620 coordSurf.mult(surfLength);
621 coordVolu.add(coordSurf.usedata());
622 voluLength += surfLength;
624 if (rsvs3d::utils::IsAproxEqual(voluLength, 0.0))
626 int n = this->surfind.size();
629 surfLength = meshin.surfs.isearch(this->surfind[0])->PseudoCentroid(meshin, coordVolu);
634 coordVolu.div(voluLength);
657 if (vecPts.size() == 0)
660 "vector of points.");
663 coordvec planeCurr, planePrev, temp;
665 double totalNormalAngle = 0.0;
667 double totalTangentAngle = 0.0;
669 int count = vecPts.size();
671 bool flagInit =
true;
672 normal.assign(0.0, 0.0, 0.0);
675 return totalTangentAngle;
678 while (flagInit && iStart < count)
681 if (rsvs3d::utils::IsAproxEqual(planePrev.GetNorm(), 0.0) || !isfinite(planePrev.GetNorm()) ||
682 !isfinite(currAngle))
693 std::cerr << std::endl;
694 DisplayVector(centre);
695 for (
int i = 0; i < count; ++i)
697 std::cerr << std::endl;
698 DisplayVector(*vecPts[i]);
701 " surrounding the centre vertex was degenerate (all the same).");
703 planePrev.Normalize();
704 for (
int i = iStart; i < count; ++i)
706 currAngle =
PlaneNormalAndAngle(centre, *vecPts[i], *vecPts[(i + 1) % count], planeCurr, temp);
708 if (rsvs3d::utils::IsAproxEqual(planeCurr.GetNorm(), 0.0) || !isfinite(planeCurr.GetNorm()) ||
709 !isfinite(currAngle))
711 planeCurr.assign(1, 1, 1);
712 planeCurr.CalcNorm();
715 planeCurr.Normalize();
716 totalNormalAngle += currAngle;
717 planeCurr.mult(currAngle);
718 normal.add(planeCurr.usedata());
719 planeCurr.Normalize();
720 totalTangentAngle += planeCurr.angle(planePrev);
721 planePrev.swap(planeCurr);
722 if (!isfinite(totalTangentAngle) || !isfinite(totalNormalAngle))
724 std::cerr << std::endl;
725 DisplayVector(planePrev.usedata());
726 DisplayVector(planeCurr.usedata());
727 std::cerr << totalTangentAngle <<
" " << totalNormalAngle << std::endl;
728 DisplayVector(centre);
729 DisplayVector(*vecPts[i]);
730 DisplayVector(*vecPts[(i + 1) % count]);
734 normal.div(totalNormalAngle);
735 return totalTangentAngle;
749 std::tuple<coordvec, double> returnTup;
750 get<1>(returnTup) =
VertexNormal(centre, vecPts, get<0>(returnTup));
778 bool innerComparison)
780 RSVS3D_ARGCHECK(voluind.size() == 2,
"4th argument voluind must be size 2");
781 RSVS3D_ARGCHECK(voluind[0] ^ voluind[1],
"4th argument must have one 0 and "
782 "one non zero element.");
784 auto pairOrder = OrderMatchLists(orderedList, elm1, elm2);
785 int isSameOrder = -pairOrder.first;
789 int flipMultiplier = 0;
790 if ((voluind[1] == 0) && (isSameOrder == -1))
794 else if ((voluind[0] == 0) && (isSameOrder == 1))
798 else if ((voluind[1] == 0) && (isSameOrder == 1))
802 else if ((voluind[0] == 0) && (isSameOrder == -1))
806 if (flipMultiplier == 0)
809 strerr <<
"Flip multiplier was not set in the cases." << std::endl
810 <<
" isSameOrder " << isSameOrder <<
"pairOrder (2)" << pairOrder.second << std::endl;
815 flipMultiplier = -flipMultiplier;
817 return flipMultiplier;
822 std::vector<int> edgeIndOut;
823 auto retVal = this->SurroundingCoords(meshin, neighCoord, isOrdered, &edgeIndOut);
825 if (retVal != rsvs3d::constants::__success)
827 normalVec.assign(0.0, 0.0, 0.0);
828 return rsvs3d::constants::__failure;
837 normalVec.assign(0.0, 0.0, 0.0);
838 return rsvs3d::constants::__failure;
840 normalVec.Normalize();
841 if (edgeIndOut.size() > 2)
843 int surfInd = meshin->
SurfFromEdges(edgeIndOut[0], edgeIndOut[1]);
844 if (rsvslogic::__isfound(surfInd) && meshin->surfs.isearch(surfInd)->IsOrdered())
847 edgeIndOut[1], meshin->surfs.isearch(surfInd)->voluind,
true);
851 normalVec.flipsign();
860 return rsvs3d::constants::__success;
868 auto retVal = this->Normal(meshin, neighCoord, normalVec);
870 if (retVal != rsvs3d::constants::__success)
872 normalVec.assign(0.0, 0.0, 0.0);
881 int meshdependence::AddParent(
mesh *meshin)
885 parentmesh.push_back(meshin);
886 parentconn.push_back(temp);
887 return (parentmesh.size());
889 int meshdependence::AddChild(
mesh *meshin)
893 childmesh.push_back(meshin);
894 return (childmesh.size());
896 void meshdependence::RemoveChild(
mesh *meshin)
898 for (
int i = 0; i < int(childmesh.size()); ++i)
900 if (meshin == childmesh[i])
902 childmesh.erase(childmesh.begin() + i);
906 void meshdependence::RemoveParent(
mesh *meshin)
908 for (
int i = 0; i < int(parentmesh.size()); ++i)
910 if (meshin == parentmesh[i])
912 parentmesh.erase(parentmesh.begin() + i);
916 nParents = parentmesh.size();
919 void meshdependence::AddParent(
mesh *meshin, vector<int> &parentind)
931 if (parentind.size() != elemind.size())
940 parentmesh.push_back(meshin);
941 parentconn.push_back(temp);
942 nParents = parentmesh.size();
945 void mesh::RemoveFromFamily()
949 for (jj = 0; jj < int(meshtree.parentmesh.size()); jj++)
951 meshtree.parentmesh[jj]->meshtree.RemoveChild(
this);
953 for (jj = 0; jj < int(meshtree.childmesh.size()); jj++)
955 meshtree.childmesh[jj]->meshtree.RemoveParent(
this);
959 void mesh::AddChild(
mesh *meshin)
961 meshtree.AddChild(meshin);
962 meshin->meshtree.AddParent(
this);
964 void mesh::AddParent(
mesh *meshin)
966 meshtree.AddParent(meshin);
967 meshin->meshtree.AddChild(
this);
970 void mesh::AddChild(
mesh *meshin, vector<int> &parentind)
976 meshtree.AddChild(meshin);
977 meshin->meshtree.AddParent(
this, parentind);
979 void mesh::AddParent(
mesh *meshin, vector<int> &parentind)
985 meshtree.AddParent(meshin, parentind);
986 meshin->meshtree.AddChild(
this);
989 void mesh::SetMeshDepElm()
993 meshtree.elemind.clear();
997 meshtree.elemind.reserve(verts.size());
998 for (ii = 0; ii < int(verts.size()); ii++)
1000 meshtree.elemind.push_back(verts(ii)->index);
1004 meshtree.elemind.reserve(edges.size());
1005 for (ii = 0; ii < int(edges.size()); ii++)
1007 meshtree.elemind.push_back(edges(ii)->index);
1011 meshtree.elemind.reserve(surfs.size());
1012 for (ii = 0; ii < int(surfs.size()); ii++)
1014 meshtree.elemind.push_back(surfs(ii)->index);
1018 meshtree.elemind.reserve(volus.size());
1019 for (ii = 0; ii < int(volus.size()); ii++)
1021 meshtree.elemind.push_back(volus(ii)->index);
1025 meshDepIsSet =
true;
1028 void mesh::ReturnParentMap(vector<int> &currind, vector<int> &parentpos, vector<pair<int, int>> &parentcases,
1029 vector<double> &voluVals)
const
1031 size_t ii, ni, jj, nj, nElm, nParCases;
1032 pair<int, int> tempPair;
1036 parentcases.clear();
1039 ni = meshtree.nParents;
1040 nj = meshtree.elemind.size();
1041 nElm = meshtree.elemind.size();
1043 currind.reserve(nElm * meshtree.nParents);
1044 parentpos.reserve(nElm * meshtree.nParents);
1045 voluVals.reserve(nElm * meshtree.nParents);
1046 parentcases.reserve(this->CountVoluParent());
1048 for (ii = 0; ii < ni; ++ii)
1051 nj = meshtree.parentmesh[ii]->volus.size();
1052 tempPair.first = ii;
1053 for (jj = 0; jj < nj; ++jj)
1055 tempPair.second = meshtree.parentmesh[ii]->volus(jj)->index;
1056 parentcases.push_back(tempPair);
1057 voluVals.push_back(meshtree.parentmesh[ii]->volus(jj)->volume * meshtree.parentmesh[ii]->volus(jj)->target);
1059 for (jj = 0; jj < nElm; ++jj)
1061 currind.push_back(meshtree.elemind[jj]);
1062 parentpos.push_back(meshtree.parentmesh[ii]->volus.find(meshtree.parentconn[ii][jj]) + nParCases);
1068 void mesh::MapVolu2Parent(
const vector<double> &fillIn,
const vector<pair<int, int>> &parentcases,
double volu::*mp)
1070 int ii, ni, sub, sub2;
1072 ni = parentcases.size();
1076 for (ii = 0; ii < ni; ii++)
1078 sub2 = this->meshtree.parentmesh[parentcases[ii].first]->volus.isHash;
1079 sub = this->meshtree.parentmesh[parentcases[ii].first]->volus.find(parentcases[ii].second);
1082 this->meshtree.parentmesh[parentcases[ii].first]->volus[sub].*mp = fillIn[ii];
1086 this->meshtree.parentmesh[parentcases[ii].first]->volus.isHash = sub2;
1090 void mesh::MapVolu2Self(
const vector<double> &fillIn,
const vector<int> &elms,
double volu::*mp)
1096 for (ii = 0; ii < ni; ii++)
1098 volus[volus.find(elms[ii])].*mp = fillIn[ii];
1104 void mesh::MaintainLineage()
1111 int mesh::CountParents()
const
1113 return (meshtree.parentmesh.size());
1115 int mesh::SurfInParent(
int surfind)
const
1119 int ii = surfs.find(surfind);
1120 bool isParentSurf =
false;
1123 kk1 = volus.find(surfs(ii)->voluind[0]);
1124 kk2 = volus.find(surfs(ii)->voluind[1]);
1125 while (!isParentSurf && jj < meshtree.nParents - 1)
1128 if ((kk1 != -1) ^ (kk2 != -1))
1130 isParentSurf =
true;
1134 isParentSurf = meshtree.parentconn[jj][kk1] != meshtree.parentconn[jj][kk2];
1148 void mesh::SurfInParent(vector<int> &listInParent)
const
1150 int ii, nSurf = surfs.size();
1151 listInParent.clear();
1152 for (ii = 0; ii < nSurf; ++ii)
1154 if (SurfInParent(surfs(ii)->index) >= 0)
1156 listInParent.push_back((ii));
1161 void mesh::SurfValuesofParents(
int elmInd, vector<double> &vals,
int volType)
const
1185 this->SurfValuesofParents(elmInd, vals, mp);
1188 void mesh::SurfValuesofParents(
int elmInd, vector<double> &vals,
double surf::*mp)
const
1197 sub = surfs.find(elmInd);
1198 for (ii = 0; ii < meshtree.nParents; ++ii)
1200 vals.push_back(meshtree.parentmesh[ii]->surfs.isearch(meshtree.parentconn[ii][sub])->*mp);
1204 void mesh::VoluValuesofParents(
int elmInd, vector<double> &vals,
int volType)
const
1229 this->VoluValuesofParents(elmInd, vals, mp);
1232 void mesh::VoluValuesofParents(
int elmInd, vector<double> &vals,
double volu::*mp)
const
1241 sub = volus.find(elmInd);
1242 for (ii = 0; ii < meshtree.nParents; ++ii)
1244 vals.push_back(meshtree.parentmesh[ii]->volus.isearch(meshtree.parentconn[ii][sub])->*mp);
1248 void mesh::ElmOnParentBound(vector<int> &listInParent, vector<int> &voluInd,
bool isBorderBound,
bool outerVolume)
const
1250 if (this->WhatDim() == 3)
1252 this->SurfOnParentBound(listInParent, voluInd, isBorderBound, outerVolume);
1254 else if (this->WhatDim() == 2)
1256 this->EdgeOnParentBound(listInParent, voluInd, isBorderBound, outerVolume);
1260 void mesh::SurfOnParentBound(vector<int> &listInParent, vector<int> &voluInd,
bool isBorderBound,
1261 bool outerVolume)
const
1266 int ii, jj, boundVolume, nSurf = surfs.size();
1268 vector<double> vals0, vals1;
1269 listInParent.clear();
1280 vals0.reserve(meshtree.nParents);
1281 vals1.reserve(meshtree.nParents);
1283 voluInd.reserve(volus.size());
1285 for (ii = 0; ii < nSurf; ++ii)
1288 if (surfs(ii)->voluind[0] == 0 || surfs(ii)->voluind[1] == 0)
1290 isOnBound = isBorderBound;
1291 if (isOnBound && (surfs(ii)->voluind[0] != 0))
1293 voluInd.push_back(surfs(ii)->voluind[0]);
1295 if (isOnBound && (surfs(ii)->voluind[1] != 0))
1297 voluInd.push_back(surfs(ii)->voluind[1]);
1300 else if (SurfInParent(surfs(ii)->index) >= 0)
1303 this->VoluValuesofParents(surfs(ii)->voluind[0], vals0, &volu::target);
1304 this->VoluValuesofParents(surfs(ii)->voluind[1], vals1, &volu::target);
1308 while (!isOnBound && jj < meshtree.nParents)
1313 isOnBound = (fabs(vals0[jj] - boundVolume) < __DBL_EPSILON__) ^
1314 (fabs(vals1[jj] - boundVolume) < __DBL_EPSILON__);
1320 if ((fabs(vals1[jj - 1] - boundVolume) < __DBL_EPSILON__))
1322 voluInd.push_back(surfs(ii)->voluind[1]);
1324 else if ((fabs(vals0[jj - 1] - boundVolume) < __DBL_EPSILON__))
1326 voluInd.push_back(surfs(ii)->voluind[0]);
1334 listInParent.push_back(surfs(ii)->index);
1339 void mesh::EdgeOnParentBound(vector<int> &listInParent, vector<int> &surfInd,
bool isBorderBound,
1340 bool outerVolume)
const
1345 int ii, jj, boundVolume, nSurf = edges.size();
1347 vector<double> vals0, vals1;
1348 listInParent.clear();
1359 vals0.reserve(meshtree.nParents);
1360 vals1.reserve(meshtree.nParents);
1362 surfInd.reserve(surfs.size());
1364 for (ii = 0; ii < nSurf; ++ii)
1367 if (edges(ii)->surfind[0] == 0 || edges(ii)->surfind[1] == 0)
1369 isOnBound = isBorderBound;
1370 if (isOnBound && (edges(ii)->surfind[0] != 0))
1372 surfInd.push_back(edges(ii)->surfind[0]);
1374 if (isOnBound && (edges(ii)->surfind[1] != 0))
1376 surfInd.push_back(edges(ii)->surfind[1]);
1379 else if (SurfInParent(edges(ii)->index) >= 0)
1382 this->SurfValuesofParents(edges(ii)->surfind[0], vals0, &surf::target);
1383 this->SurfValuesofParents(edges(ii)->surfind[1], vals1, &surf::target);
1387 while (!isOnBound && jj < meshtree.nParents)
1389 isOnBound = (vals0[jj] != vals1[jj]) && ((vals0[jj] == boundVolume) || (vals1[jj] == boundVolume));
1393 if (isOnBound && (vals1[jj - 1] == boundVolume))
1395 surfInd.push_back(edges(ii)->surfind[1]);
1396 if (boundVolume == 1.0 && surfs.isearch(surfInd.back())->isBorder)
1401 if (isOnBound && (vals0[jj - 1] == boundVolume))
1403 surfInd.push_back(edges(ii)->surfind[0]);
1404 if (boundVolume == 1.0 && surfs.isearch(surfInd.back())->isBorder)
1414 listInParent.push_back(edges(ii)->index);
1419 int mesh::CountVoluParent()
const
1422 for (
int i = 0; i < int(meshtree.parentmesh.size()); ++i)
1424 n += meshtree.parentmesh[i]->volus.size();
1429 int mesh::ParentElementIndex(
int childElmInd,
int parentInd)
const
1434 if (parentInd >=
int(this->meshtree.parentconn.size()) || parentInd < 0)
1437 " of mesh parents");
1439 if (this->WhatDim() == 3)
1441 return (this->meshtree.parentconn[parentInd][this->volus.find(childElmInd)]);
1443 else if (this->WhatDim() == 2)
1445 return (this->meshtree.parentconn[parentInd][this->surfs.find(childElmInd)]);
1450 " 3 not supported yet");
1459 centre.assign(0, 0, 0);
1461 sub = meshin->verts.find(vertind[0]);
1462 centre.substract(meshin->verts(sub)->coord);
1463 centre.add(meshin->verts.isearch(vertind[1])->coord);
1464 length = centre.CalcNorm();
1465 centre.add(meshin->verts(sub)->coord);
1466 centre.add(meshin->verts(sub)->coord);
1479 double lengthSquared = 0.0;
1481 for (
int i = 0; i < meshin.WhatDim(); ++i)
1483 lengthSquared += pow(
1484 meshin.verts.isearch(this->vertind[0])->coord[i] - meshin.verts.isearch(this->vertind[1])->coord[i], 2.0);
1487 return lengthSquared;
1498 if (rsvs3d::constants::__issetlength(this->length))
1500 return this->length;
1502 return sqrt(this->LengthSquared(meshin));
1516 if (rsvs3d::constants::__issetlength(this->length))
1518 return fabs(this->length) < fabs(eps);
1520 return this->LengthSquared(meshin) < pow(eps, 2.0);
1524 void volu::disp()
const
1527 cout <<
"volu : index " << index <<
" | fill " << fill <<
", " << target <<
", " << error <<
" | isBorder "
1528 << isBorder <<
" | surfind " << surfind.size() <<
":";
1529 if (surfind.size() < 30)
1531 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1533 cout <<
" " << surfind[i];
1539 void surf::disp()
const
1542 cout <<
"surf : index " << index <<
" | fill " << fill <<
", " << target <<
", " <<
error <<
" | isBorder "
1543 << isBorder <<
" | voluind " << voluind.size() <<
":";
1544 for (i = 0; unsigned_int(i) < voluind.size(); i++)
1546 cout <<
" " << voluind[i];
1548 cout <<
" | edgeind " << edgeind.size() <<
":";
1549 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1551 cout <<
" " << edgeind[i];
1556 void edge::disp()
const
1559 cout <<
"edge : index " << index <<
" | isBorder " << isBorder <<
" | vertind " << vertind.size() <<
":";
1560 for (i = 0; unsigned_int(i) < vertind.size(); i++)
1562 cout <<
" " << vertind[i];
1564 cout <<
" | surfind " << surfind.size() <<
":";
1565 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1567 cout <<
" " << surfind[i];
1572 void vert::disp()
const
1575 cout <<
"vert : index " << index <<
" | isBorder " << isBorder <<
" | edgeind " << edgeind.size() <<
":";
1576 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1578 cout <<
" " << edgeind[i];
1580 cout <<
" | coord " << coord.size() <<
":";
1581 for (i = 0; unsigned_int(i) < coord.size(); i++)
1583 cout <<
" " << coord[i];
1590 void volu::disptree(
const mesh &meshin,
int n)
const
1593 for (i = 0; i < n; i++)
1598 if (n > 0 && surfind.size() < 8)
1600 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1602 meshin.surfs.isearch(surfind[i])->disptree(meshin, n - 1);
1607 void surf::disptree(
const mesh &meshin,
int n)
const
1610 for (i = 0; i < n; i++)
1617 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1619 meshin.edges.isearch(edgeind[i])->disptree(meshin, n - 1);
1621 for (i = 0; unsigned_int(i) < voluind.size(); i++)
1625 meshin.volus.isearch(voluind[i])->disptree(meshin, n - 1);
1631 void edge::disptree(
const mesh &meshin,
int n)
const
1634 for (i = 0; i < n; i++)
1641 for (i = 0; unsigned_int(i) < vertind.size(); i++)
1643 meshin.verts.isearch(vertind[i])->disptree(meshin, n - 1);
1645 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1647 meshin.surfs.isearch(surfind[i])->disptree(meshin, n - 1);
1652 void vert::disptree(
const mesh &meshin,
int n)
const
1655 for (i = 0; i < n; i++)
1662 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1664 meshin.edges.isearch(edgeind[i])->disptree(meshin, n - 1);
1669 double volu::value(
const mesh &meshin)
const
1672 double valMult = this->surfind.size() > 0 ? 1.0 / double(this->surfind.size()) : 0.0;
1673 for (
auto vi : this->surfind)
1675 val += meshin.surfs.isearch(vi)->value(meshin);
1677 return val * valMult;
1680 double surf::value(
const mesh &meshin)
const
1683 double valMult = this->edgeind.size() > 0 ? 1.0 / double(this->edgeind.size()) : 0.0;
1684 for (
auto vi : this->edgeind)
1686 val += meshin.edges.isearch(vi)->value(meshin);
1688 return val * valMult;
1691 double edge::value(
const mesh &meshin)
const
1694 double valMult = this->vertind.size() > 0 ? 1.0 / double(this->vertind.size()) : 0.0;
1695 for (
auto vi : this->vertind)
1697 val += meshin.verts.isearch(vi)->value(meshin);
1699 return val * valMult;
1702 #pragma GCC diagnostic push
1703 #pragma GCC diagnostic ignored "-Wunused-parameter"
1704 double vert::value(
const mesh &meshin)
const
1707 for (
int j = 0; j < 3; ++j)
1709 val += this->coord[j] * pow(10.0,
double(j));
1713 #pragma GCC diagnostic pop
1715 bool mesh::CompareVerts(
const vert &in1,
const vert &in2)
const
1717 return in1.value(*
this) < in2.value(*
this);
1720 bool mesh::CompareEdges(
const edge &in1,
const edge &in2)
const
1722 return in1.value(*
this) < in2.value(*
this);
1725 bool mesh::CompareSurfs(
const surf &in1,
const surf &in2)
const
1727 return in1.value(*
this) < in2.value(*
this);
1730 bool mesh::CompareVolus(
const volu &in1,
const volu &in2)
const
1732 return in1.value(*
this) < in2.value(*
this);
1736 void volu::write(FILE *fid)
const
1740 fprintf(fid,
"%i %.16lf %.16lf %.16lf %i ", index, fill, target, error,
int(isBorder));
1741 fprintf(fid,
"%i ",
int(surfind.size()));
1742 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1744 fprintf(fid,
"%i ", surfind[i]);
1749 void surf::write(FILE *fid)
const
1753 fprintf(fid,
"%i %.16lf %.16lf %.16lf %i ", index, fill, target, error,
int(isBorder));
1754 fprintf(fid,
"%i ",
int(voluind.size()));
1755 for (i = 0; unsigned_int(i) < voluind.size(); i++)
1757 fprintf(fid,
"%i ", voluind[i]);
1759 fprintf(fid,
"%i ",
int(edgeind.size()));
1760 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1762 fprintf(fid,
"%i ", edgeind[i]);
1767 void edge::write(FILE *fid)
const
1771 fprintf(fid,
"%i %i ", index,
int(isBorder));
1772 fprintf(fid,
"%i ",
int(vertind.size()));
1773 for (i = 0; unsigned_int(i) < vertind.size(); i++)
1775 fprintf(fid,
"%i ", vertind[i]);
1777 fprintf(fid,
"%i ",
int(surfind.size()));
1778 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1780 fprintf(fid,
"%i ", surfind[i]);
1785 void vert::write(FILE *fid)
const
1789 fprintf(fid,
"%i %i ", index,
int(isBorder));
1790 fprintf(fid,
"%i ",
int(edgeind.size()));
1791 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1793 fprintf(fid,
"%i ", edgeind[i]);
1795 fprintf(fid,
"%i ",
int(coord.size()));
1796 for (i = 0; unsigned_int(i) < coord.size(); i++)
1798 fprintf(fid,
"%.16lf ", coord[i]);
1803 void volu::read(FILE *fid)
1807 fscanf(fid,
"%i %lf %lf %lf %i ", &index, &fill, &target, &error, &i);
1809 fscanf(fid,
"%i ", &n);
1810 surfind.assign(n, 0);
1811 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1813 fscanf(fid,
"%i ", &surfind[i]);
1817 void surf::read(FILE *fid)
1821 fscanf(fid,
"%i %lf %lf %lf %i ", &index, &fill, &target, &error, &i);
1823 fscanf(fid,
"%i ", &n);
1824 voluind.assign(n, 0);
1825 for (i = 0; unsigned_int(i) < voluind.size(); i++)
1827 fscanf(fid,
"%i ", &voluind[i]);
1829 fscanf(fid,
"%i ", &n);
1830 edgeind.assign(n, 0);
1831 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1833 fscanf(fid,
"%i ", &edgeind[i]);
1837 void edge::read(FILE *fid)
1841 fscanf(fid,
"%i %i ", &index, &i);
1843 fscanf(fid,
"%i ", &n);
1844 vertind.assign(n, 0);
1845 for (i = 0; unsigned_int(i) < vertind.size(); i++)
1847 fscanf(fid,
"%i ", &vertind[i]);
1849 fscanf(fid,
"%i ", &n);
1850 surfind.assign(n, 0);
1851 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1853 fscanf(fid,
"%i ", &surfind[i]);
1857 void vert::read(FILE *fid)
1861 fscanf(fid,
"%i %i ", &index, &i);
1863 fscanf(fid,
"%i ", &n);
1864 edgeind.assign(n, 0);
1865 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1867 fscanf(fid,
"%i ", &edgeind[i]);
1869 fscanf(fid,
"%i ", &n);
1871 for (i = 0; unsigned_int(i) < coord.size(); i++)
1873 fscanf(fid,
"%lf ", &coord[i]);
1877 std::vector<int> vert::elmind(
const mesh &meshin,
int dimOveride)
const
1879 std::vector<int> elmind;
1881 int dim = meshin.WhatDim();
1887 for (
auto edgeInd : this->edgeind)
1889 for (
auto surfInd : meshin.edges.isearch(edgeInd)->surfind)
1891 for (
auto voluInd : meshin.surfs.isearch(surfInd)->voluind)
1893 elmind.push_back(voluInd);
1899 for (
auto edgeInd : this->edgeind)
1901 for (
auto surfInd : meshin.edges.isearch(edgeInd)->surfind)
1903 elmind.push_back(surfInd);
1921 std::vector<int> vertind;
1922 vertind.reserve(30);
1923 for (
auto surfInd : this->surfind)
1925 for (
auto edgeInd : meshin.surfs.isearch(surfInd)->edgeind)
1927 for (
auto vertInd : meshin.edges.isearch(edgeInd)->vertind)
1929 vertind.push_back(vertInd);
1937 std::vector<int> surf::vertind(
const mesh &meshin)
const
1939 std::vector<int> vertind;
1940 vertind.reserve(30);
1942 for (
auto edgeInd : this->edgeind)
1944 for (
auto vertInd : meshin.edges.isearch(edgeInd)->vertind)
1946 vertind.push_back(vertInd);
1955 #pragma GCC diagnostic push
1956 #pragma GCC diagnostic ignored "-Wunused-parameter"
1957 void volu::ChangeIndices(
int nVert,
int nEdge,
int nSurf,
int nVolu)
1961 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1963 surfind[i] = (surfind[i] > 0) ? (surfind[i] + nSurf) : surfind[i];
1966 void surf::ChangeIndices(
int nVert,
int nEdge,
int nSurf,
int nVolu)
1970 for (i = 0; unsigned_int(i) < voluind.size(); i++)
1972 voluind[i] = (voluind[i] > 0) ? (voluind[i] + nVolu) : voluind[i];
1975 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
1977 edgeind[i] = edgeind[i] + nEdge;
1980 void edge::ChangeIndices(
int nVert,
int nEdge,
int nSurf,
int nVolu)
1984 for (i = 0; unsigned_int(i) < vertind.size(); i++)
1986 vertind[i] = vertind[i] + nVert;
1989 for (i = 0; unsigned_int(i) < surfind.size(); i++)
1991 surfind[i] = (surfind[i] > 0) ? (surfind[i] + nSurf) : surfind[i];
1994 void vert::ChangeIndices(
int nVert,
int nEdge,
int nSurf,
int nVolu)
1998 for (i = 0; unsigned_int(i) < edgeind.size(); i++)
2000 edgeind[i] = edgeind[i] + nEdge;
2003 void mesh::TightenConnectivity()
2005 verts.TightenConnectivity();
2006 surfs.TightenConnectivity();
2007 edges.TightenConnectivity();
2008 volus.TightenConnectivity();
2009 this->facesAreOriented =
false;
2012 void mesh::SwitchIndex(
int typeInd,
int oldInd,
int newInd,
const vector<int> &scopeInd)
2019 int ii, jj, kk, newSub, oldSub;
2020 vector<int> subList;
2022 bool is3DMesh = volus.size() > 0;
2026 newSub = verts.find(newInd);
2027 oldSub = verts.find(oldInd);
2028 subList = edges.find_list(verts[oldSub].edgeind);
2029 for (ii = 0; ii < int(subList.size()); ++ii)
2031 jj = edges(subList[ii])->vertind[1] == oldInd;
2032 edges[subList[ii]].vertind[jj] = newInd;
2034 verts[newSub].edgeind.push_back(edges[subList[ii]].index);
2035 for (jj = 0; jj < int(verts(oldSub)->edgeind.size()); ++jj)
2037 if (verts(oldSub)->edgeind[jj] == edges[subList[ii]].index)
2039 verts[oldSub].edgeind.erase(verts[oldSub].edgeind.begin() + jj);
2044 sort(verts[newSub].edgeind);
2045 unique(verts[newSub].edgeind);
2046 if (meshDepIsSet && meshDim == 0)
2048 meshtree.elemind[oldSub] = newInd;
2054 else if (typeInd == 2)
2056 newSub = edges.find(newInd);
2057 oldSub = edges.find(oldInd);
2058 subList = verts.find_list(edges(edges.find(oldInd))->vertind);
2059 for (ii = 0; ii < int(subList.size()); ++ii)
2061 for (jj = 0; jj < int(verts(subList[ii])->edgeind.size()); ++jj)
2063 if (verts(subList[ii])->edgeind[jj] == oldInd)
2065 verts[subList[ii]].edgeind[jj] = newInd;
2070 subList = surfs.find_list(edges(edges.find(oldInd))->surfind);
2071 for (ii = 0; ii < int(subList.size()); ++ii)
2073 if (subList[ii] != -1 || is3DMesh)
2075 for (jj = 0; jj < int(surfs(subList[ii])->edgeind.size()); ++jj)
2077 if (surfs(subList[ii])->edgeind[jj] == oldInd)
2079 surfs[subList[ii]].edgeind[jj] = newInd;
2080 edges[newSub].surfind.push_back(surfs[subList[ii]].index);
2081 surfs[subList[ii]].isordered =
false;
2087 if (meshDepIsSet && meshDim == 1)
2089 meshtree.elemind[oldSub] = newInd;
2099 else if (typeInd == 3)
2101 newSub = surfs.find(newInd);
2102 oldSub = surfs.find(oldInd);
2103 subList = edges.find_list(surfs(surfs.find(oldInd))->edgeind);
2104 for (ii = 0; ii < int(subList.size()); ++ii)
2106 for (jj = 0; jj < int(edges(subList[ii])->surfind.size()); ++jj)
2108 if (edges(subList[ii])->surfind[jj] == oldInd)
2110 edges[subList[ii]].surfind[jj] = newInd;
2111 surfs[newSub].edgeind.push_back(edges[subList[ii]].index);
2117 subList = volus.find_list(surfs(surfs.find(oldInd))->voluind);
2118 for (ii = 0; ii < int(subList.size()); ++ii)
2120 if (subList[ii] != -1)
2122 for (jj = 0; jj < int(volus(subList[ii])->surfind.size()); ++jj)
2124 if (volus(subList[ii])->surfind[jj] == oldInd)
2126 volus[subList[ii]].surfind[jj] = newInd;
2127 surfs[newSub].voluind.push_back(volus[subList[ii]].index);
2133 if (meshDepIsSet && meshDim == 2)
2138 meshtree.elemind[oldSub] = newInd;
2141 surfs[newSub].isordered =
false;
2149 else if (typeInd == 4)
2151 newSub = volus.find(newInd);
2152 oldSub = volus.find(oldInd);
2153 subList = surfs.find_list(volus[volus.find(oldInd)].surfind);
2154 for (ii = 0; ii < int(subList.size()); ++ii)
2156 for (jj = 0; jj < int(surfs(subList[ii])->voluind.size()); ++jj)
2158 if (surfs[subList[ii]].voluind[jj] == oldInd)
2160 surfs[subList[ii]].voluind[jj] = newInd;
2162 volus[newSub].surfind.push_back(surfs[subList[ii]].index);
2166 if (meshDepIsSet && meshDim == 3)
2171 meshtree.elemind[oldSub] = newInd;
2179 else if (typeInd == 5)
2182 newSub = verts.find(newInd);
2183 oldSub = verts.find(oldInd);
2185 subList = edges.find_list(scopeInd);
2186 tempSub.vec = edges.find_list(verts(oldSub)->edgeind);
2187 tempSub.GenerateHash();
2188 for (ii = 0; ii < int(subList.size()); ++ii)
2190 if (tempSub.find(subList[ii]) != -1)
2192 for (jj = 0; jj < int(edges(subList[ii])->vertind.size()); ++jj)
2194 if (edges(subList[ii])->vertind[jj] == oldInd)
2196 edges[subList[ii]].vertind[jj] = newInd;
2197 verts[newSub].edgeind.push_back(edges[subList[ii]].index);
2198 for (kk = 0; kk < int(verts(oldSub)->edgeind.size()); ++kk)
2200 if (verts(oldSub)->edgeind[kk] == edges[subList[ii]].index)
2202 verts[oldSub].edgeind.erase(verts[oldSub].edgeind.begin() + kk);
2210 if (meshDepIsSet && meshDim == 0)
2212 meshtree.elemind[oldSub] = newInd;
2219 else if (typeInd == 6)
2222 newSub = surfs.find(newInd);
2223 oldSub = surfs.find(oldInd);
2225 subList = edges.find_list(scopeInd);
2226 for (ii = 0; ii < int(subList.size()); ++ii)
2228 for (jj = 0; jj < int(edges(subList[ii])->surfind.size()); ++jj)
2230 if (edges(subList[ii])->surfind[jj] == oldInd)
2232 edges[subList[ii]].surfind[jj] = newInd;
2233 surfs[newSub].edgeind.push_back(edges[subList[ii]].index);
2234 for (kk = 0; kk < int(surfs(oldSub)->edgeind.size()); ++kk)
2236 if (surfs(oldSub)->edgeind[kk] == edges[subList[ii]].index)
2238 surfs[oldSub].edgeind.erase(surfs[oldSub].edgeind.begin() + kk);
2245 for (ii = 0; ii < int(surfs(newSub)->voluind.size()); ii++)
2247 if (surfs(newSub)->voluind[ii] > 0)
2249 volus.elems[volus.find(surfs(newSub)->voluind[ii])].surfind.push_back(newInd);
2252 if (meshDepIsSet && meshDim == 2)
2254 meshtree.elemind[oldSub] = newInd;
2261 else if (typeInd == 7)
2264 newSub = volus.find(newInd);
2265 oldSub = volus.find(oldInd);
2267 subList = surfs.find_list(scopeInd);
2268 for (ii = 0; ii < int(subList.size()); ++ii)
2270 for (jj = 0; jj < int(surfs(subList[ii])->voluind.size()); ++jj)
2272 if (surfs(subList[ii])->voluind[jj] == oldInd)
2274 surfs[subList[ii]].voluind[jj] = newInd;
2275 volus[newSub].surfind.push_back(surfs[subList[ii]].index);
2276 for (kk = 0; kk < int(volus(oldSub)->surfind.size()); ++kk)
2278 if (volus(oldSub)->surfind[kk] == surfs[subList[ii]].index)
2280 volus[oldSub].surfind.erase(volus[oldSub].surfind.begin() + kk);
2288 if (meshDepIsSet && meshDim == 3)
2290 meshtree.elemind[oldSub] = newInd;
2299 cerr <<
"Error unknown type " << typeInd
2300 <<
" of object for "
2303 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
2308 void mesh::RemoveIndex(
int typeInd,
int oldInd)
2311 vector<int> subList;
2315 sub = verts.find(oldInd);
2316 subList = edges.find_list(verts(sub)->edgeind);
2317 for (ii = 0; ii < int(subList.size()); ++ii)
2319 for (jj = 0; jj < int(edges(subList[ii])->vertind.size()); ++jj)
2321 if (edges(subList[ii])->vertind[jj] == oldInd)
2323 edges[subList[ii]].vertind.erase(edges[subList[ii]].vertind.begin() + jj);
2333 else if (typeInd == 2)
2335 sub = edges.find(oldInd);
2336 subList = verts.find_list(edges(sub)->vertind);
2337 for (ii = 0; ii < int(subList.size()); ++ii)
2339 for (jj = 0; jj < int(verts(subList[ii])->edgeind.size()); ++jj)
2341 if (verts(subList[ii])->edgeind[jj] == oldInd)
2343 verts[subList[ii]].edgeind.erase(verts[subList[ii]].edgeind.begin() + jj);
2349 subList = surfs.find_list(edges(sub)->surfind);
2350 for (ii = 0; ii < int(subList.size()); ++ii)
2352 if (subList[ii] != -1)
2354 for (jj = 0; jj < int(surfs(subList[ii])->edgeind.size()); ++jj)
2356 if (surfs(subList[ii])->edgeind[jj] == oldInd)
2358 surfs[subList[ii]].edgeind.erase(surfs[subList[ii]].edgeind.begin() + jj);
2359 surfs[subList[ii]].isordered =
false;
2365 edges[sub].vertind.clear();
2366 edges[sub].surfind.clear();
2375 else if (typeInd == 3)
2377 sub = surfs.find(oldInd);
2379 subList = edges.find_list(surfs(sub)->edgeind);
2380 for (ii = 0; ii < int(subList.size()); ++ii)
2382 for (jj = 0; jj < int(edges(subList[ii])->surfind.size()); ++jj)
2384 if (edges(subList[ii])->surfind[jj] == oldInd)
2386 edges[subList[ii]].surfind.erase(edges[subList[ii]].surfind.begin() + jj);
2392 subList = volus.find_list(surfs(sub)->voluind);
2393 for (ii = 0; ii < int(subList.size()); ++ii)
2395 if (subList[ii] != -1)
2397 for (jj = 0; jj < int(volus(subList[ii])->surfind.size()); ++jj)
2399 if (volus(subList[ii])->surfind[jj] == oldInd)
2401 volus[subList[ii]].surfind.erase(volus[subList[ii]].surfind.begin() + jj);
2408 surfs[sub].edgeind.clear();
2409 surfs[sub].voluind.clear();
2417 else if (typeInd == 4)
2419 sub = volus.find(oldInd);
2421 subList = surfs.find_list(volus(sub)->surfind);
2422 for (ii = 0; ii < int(subList.size()); ++ii)
2424 for (jj = 0; jj < int(surfs(subList[ii])->voluind.size()); ++jj)
2426 if (surfs(subList[ii])->voluind[jj] == oldInd)
2428 surfs[subList[ii]].voluind.erase(surfs[subList[ii]].voluind.begin() + jj);
2429 if (surfs[subList[ii]].voluind.size() < 2)
2431 surfs[subList[ii]].voluind.push_back(0);
2438 volus[sub].surfind.clear();
2444 else if (typeInd == 5)
2447 RSVS3D_ERROR(
"Not implemented: Cannot modify vertex in scoped mode.");
2451 cerr <<
"Error unknown type of object for index switching" << endl;
2452 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
2457 int mesh::TestConnectivity(
const char *strRoot)
const
2459 int ii, jj, kk, kk2, errCount, errTot;
2460 vector<int> testSub;
2464 kk = int(verts.size());
2465 for (ii = 0; ii < kk; ++ii)
2467 if (verts(ii)->edgeind.size() == 0)
2470 cerr <<
" Test Connectivity Error :" << errCount <<
" vertex " << verts(ii)->index
2471 <<
" Has empty connectivity list ";
2476 #ifdef RSVS_DIAGNOSTIC
2477 if (verts(ii)->edgeind.size() == 2)
2480 cerr <<
" Test Connectivity Error :" << errCount <<
" vertex " << verts(ii)->index
2481 <<
" Has connectivity "
2482 "list of length 2 ";
2483 DisplayVector(verts(ii)->edgeind);
2487 testSub = edges.find_list(verts(ii)->edgeind);
2488 kk2 = testSub.size();
2489 for (jj = 0; jj < kk2; ++jj)
2491 if (testSub[jj] < 0 && verts(ii)->edgeind[jj] != 0)
2494 cerr <<
" Test Connectivity Error :" << errCount <<
" vertex " << verts(ii)->index
2495 <<
" makes unknown reference to edge " << verts(ii)->edgeind[jj] <<
" list: ";
2496 DisplayVector(verts(ii)->edgeind);
2504 cerr <<
"Test Connectivity vertex (edgeind) Errors :" << errCount << endl;
2509 kk = int(edges.size());
2510 for (ii = 0; ii < kk; ++ii)
2512 testSub = verts.find_list(edges(ii)->vertind);
2513 kk2 = testSub.size();
2514 for (jj = 0; jj < kk2; ++jj)
2516 if (testSub[jj] < 0 && edges(ii)->vertind[jj] != 0)
2519 cerr <<
" Test Connectivity Error :" << errCount <<
" edge " << edges(ii)->index
2520 <<
" makes unknown reference to vertex " << edges(ii)->vertind[jj] <<
" list: ";
2521 DisplayVector(edges(ii)->vertind);
2528 cerr <<
"Test Connectivity edges (vertind) Errors :" << errCount << endl;
2533 for (ii = 0; ii < kk; ++ii)
2535 testSub = surfs.find_list(edges(ii)->surfind);
2536 kk2 = testSub.size();
2537 for (jj = 0; jj < kk2; ++jj)
2539 if (testSub[jj] < 0 && edges(ii)->surfind[jj] != 0)
2542 cerr <<
" Test Connectivity Error :" << errCount <<
" edge " << edges(ii)->index
2543 <<
" makes unknown reference to surface " << edges(ii)->surfind[jj] << endl;
2549 cerr <<
"Test Connectivity edges (surfind) Errors :" << errCount << endl;
2554 kk = int(surfs.size());
2555 for (ii = 0; ii < kk; ++ii)
2557 testSub = edges.find_list(surfs(ii)->edgeind);
2558 kk2 = testSub.size();
2559 for (jj = 0; jj < kk2; ++jj)
2561 if (testSub[jj] < 0)
2564 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index
2565 <<
" makes unknown reference to edge " << surfs(ii)->edgeind[jj] << endl;
2568 if (
int(testSub.size()) == 0)
2571 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index <<
" has empty edgeind "
2577 cerr <<
"Test Connectivity surfs (edgeind) Errors :" << errCount << endl;
2582 kk = int(surfs.size());
2583 for (ii = 0; ii < kk; ++ii)
2585 testSub = volus.find_list(surfs(ii)->voluind);
2586 kk2 = testSub.size();
2587 for (jj = 0; jj < kk2; ++jj)
2589 if (testSub[jj] < 0 && surfs(ii)->voluind[jj] != 0)
2592 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index
2593 <<
" makes unknown reference to volu " << surfs(ii)->voluind[jj] << endl;
2599 cerr <<
"Test Connectivity surfs (voluind) Errors :" << errCount << endl;
2604 kk = int(volus.size());
2605 for (ii = 0; ii < kk; ++ii)
2607 testSub = surfs.find_list(volus(ii)->surfind);
2608 kk2 = testSub.size();
2609 for (jj = 0; jj < kk2; ++jj)
2611 if (testSub[jj] < 0 && volus(ii)->surfind[jj] != 0)
2614 cerr <<
" Test Connectivity Error :" << errCount <<
" volu " << volus(ii)->index
2615 <<
" makes unknown reference to surface " << volus(ii)->surfind[jj] << endl;
2621 cerr <<
"Test Connectivity volus (surfind) Errors :" << errCount << endl;
2627 <<
" Total errors were detected in the connectivity "
2635 int mesh::TestConnectivityBiDir(
const char *strRoot,
bool emptyIsErr)
const
2637 int ii, jj, ll, ll2, kk, kk2, errCount, errTot, errCountBiDir, errTotBiDir;
2639 vector<int> testSub;
2645 kk = int(verts.size());
2646 for (ii = 0; ii < kk; ++ii)
2648 if (emptyIsErr && verts(ii)->edgeind.size() == 0)
2651 cerr <<
" Test Connectivity Error :" << errCount <<
" vertex " << verts(ii)->index
2652 <<
" Has empty connectivity list ";
2657 testSub = edges.find_list(verts(ii)->edgeind);
2658 kk2 = testSub.size();
2659 for (jj = 0; jj < kk2; ++jj)
2661 if (testSub[jj] < 0 && verts(ii)->edgeind[jj] != 0)
2664 cerr <<
" Test Connectivity Error :" << errCount <<
" vertex " << verts(ii)->index
2665 <<
" makes unknown reference to edge " << verts(ii)->edgeind[jj] <<
" list: ";
2666 DisplayVector(verts(ii)->edgeind);
2669 else if (verts(ii)->edgeind[jj] != 0)
2671 ll2 = edges(testSub[jj])->vertind.size();
2673 for (ll = 0; ll < ll2; ll++)
2675 flag = flag || (edges(testSub[jj])->vertind[ll] == verts(ii)->index);
2680 cerr <<
" Test Connectivity Error :" << errCountBiDir <<
" vertex " << verts(ii)->index
2681 <<
" makes uni-directional reference to edge " << verts(ii)->edgeind[jj] <<
" list: ";
2682 DisplayVector(verts(ii)->edgeind);
2683 cout <<
" list (edge.vertind): ";
2684 DisplayVector(edges(jj)->vertind);
2693 cerr <<
"Test Connectivity vertex (edgeind) Errors :" << errCount << endl;
2695 if (errCountBiDir > 0)
2697 cerr <<
"Test Connectivity vertex (edgeind) uni-directional Errors :" << errCountBiDir << endl;
2701 errTotBiDir += errCountBiDir;
2704 kk = int(edges.size());
2705 for (ii = 0; ii < kk; ++ii)
2707 testSub = verts.find_list(edges(ii)->vertind);
2708 kk2 = testSub.size();
2709 if (emptyIsErr && testSub.size() != 2)
2712 cerr <<
" Test Connectivity Error :" << errCount <<
" edge " << edges(ii)->index
2713 <<
" has vertind of length " << testSub.size() <<
" list (edge::vertind): ";
2714 DisplayVector(edges(ii)->vertind);
2717 for (jj = 0; jj < kk2; ++jj)
2719 if (testSub[jj] < 0 && edges(ii)->vertind[jj] != 0)
2722 cerr <<
" Test Connectivity Error :" << errCount <<
" edge " << edges(ii)->index
2723 <<
" makes unknown reference to vertex " << edges(ii)->vertind[jj] <<
" list: ";
2724 DisplayVector(edges(ii)->vertind);
2727 else if (edges(ii)->vertind[jj] != 0)
2729 ll2 = verts(testSub[jj])->edgeind.size();
2731 for (ll = 0; ll < ll2; ll++)
2733 flag = flag || (verts(testSub[jj])->edgeind[ll] == edges(ii)->index);
2738 cerr <<
" Test Connectivity Error :" << errCountBiDir <<
" edge " << edges(ii)->index
2739 <<
" makes uni-directional reference to vertex " << edges(ii)->vertind[jj] <<
" list: ";
2740 DisplayVector(edges(ii)->vertind);
2741 cout <<
" list (vert.edgeind): ";
2742 DisplayVector(verts(jj)->edgeind);
2750 cerr <<
"Test Connectivity edges (vertind) Errors :" << errCount << endl;
2752 if (errCountBiDir > 0)
2754 cerr <<
"Test Connectivity edges (vertind) uni-directional Errors :" << errCountBiDir << endl;
2758 errTotBiDir += errCountBiDir;
2761 for (ii = 0; ii < kk; ++ii)
2763 testSub = surfs.find_list(edges(ii)->surfind);
2764 kk2 = testSub.size();
2765 for (jj = 0; jj < kk2; ++jj)
2767 if (testSub[jj] < 0 && edges(ii)->surfind[jj] != 0)
2770 cerr <<
" Test Connectivity Error :" << errCount <<
" edge " << edges(ii)->index
2771 <<
" makes unknown reference to surface " << edges(ii)->surfind[jj] << endl;
2773 else if (edges(ii)->surfind[jj] != 0)
2775 ll2 = surfs(testSub[jj])->edgeind.size();
2777 for (ll = 0; ll < ll2; ll++)
2779 flag = flag || (surfs(testSub[jj])->edgeind[ll] == edges(ii)->index);
2784 cerr <<
" Test Connectivity Error :" << errCountBiDir <<
" edge " << edges(ii)->index
2785 <<
" makes uni-directional reference to surface " << edges(ii)->surfind[jj] <<
" list: ";
2786 DisplayVector(edges(ii)->surfind);
2787 cout <<
" list (surf.edgeind): ";
2788 DisplayVector(surfs(jj)->edgeind);
2796 cerr <<
"Test Connectivity edges (surfind) Errors :" << errCount << endl;
2798 if (errCountBiDir > 0)
2800 cerr <<
"Test Connectivity edges (surfind) uni-directional Errors :" << errCountBiDir << endl;
2804 errTotBiDir += errCountBiDir;
2807 kk = int(surfs.size());
2808 for (ii = 0; ii < kk; ++ii)
2810 testSub = edges.find_list(surfs(ii)->edgeind);
2811 kk2 = testSub.size();
2812 if (
int(testSub.size()) == 0)
2815 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index <<
" has empty edgeind "
2818 for (jj = 0; jj < kk2; ++jj)
2820 if (testSub[jj] < 0)
2823 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index
2824 <<
" makes unknown reference to edge " << surfs(ii)->edgeind[jj] << endl;
2826 else if (surfs(ii)->edgeind[jj] != 0)
2828 ll2 = edges(testSub[jj])->surfind.size();
2830 for (ll = 0; ll < ll2; ll++)
2832 flag = flag || (edges(testSub[jj])->surfind[ll] == surfs(ii)->index);
2837 cerr <<
" Test Connectivity Error :" << errCountBiDir <<
" surf " << surfs(ii)->index
2838 <<
" makes uni-directional reference to edge " << surfs(ii)->edgeind[jj] <<
" list: ";
2839 DisplayVector(surfs(ii)->edgeind);
2840 cout <<
" list (edge.surfind): ";
2841 DisplayVector(edges(jj)->surfind);
2849 cerr <<
"Test Connectivity surfs (edgeind) Errors :" << errCount << endl;
2851 if (errCountBiDir > 0)
2853 cerr <<
"Test Connectivity surfs (edgeind) uni-directional Errors :" << errCountBiDir << endl;
2857 errTotBiDir += errCountBiDir;
2860 kk = int(surfs.size());
2861 for (ii = 0; ii < kk; ++ii)
2863 testSub = volus.find_list(surfs(ii)->voluind);
2864 kk2 = testSub.size();
2865 if (this->WhatDim() > 2 && emptyIsErr && kk2 != 2)
2868 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index
2869 <<
" has voluind of length " << kk2 <<
" list (surf::voluind): ";
2870 DisplayVector(surfs(ii)->voluind);
2873 for (jj = 0; jj < kk2; ++jj)
2875 if (testSub[jj] < 0 && surfs(ii)->voluind[jj] != 0)
2878 cerr <<
" Test Connectivity Error :" << errCount <<
" surf " << surfs(ii)->index
2879 <<
" makes unknown reference to volu " << surfs(ii)->voluind[jj] << endl;
2881 else if (surfs(ii)->voluind[jj] != 0)
2883 ll2 = volus(testSub[jj])->surfind.size();
2885 for (ll = 0; ll < ll2; ll++)
2887 flag = flag || (volus(testSub[jj])->surfind[ll] == surfs(ii)->index);
2892 cerr <<
" Test Connectivity Error :" << errCountBiDir <<
" surf " << surfs(ii)->index
2893 <<
" makes uni-directional reference to volume " << surfs(ii)->voluind[jj] <<
" list: ";
2894 DisplayVector(surfs(ii)->voluind);
2895 cout <<
" list (volu.surfind): ";
2896 DisplayVector(volus(jj)->surfind);
2904 cerr <<
"Test Connectivity surfs (voluind) Errors :" << errCount << endl;
2906 if (errCountBiDir > 0)
2908 cerr <<
"Test Connectivity surfs (voluind) uni-directional Errors :" << errCountBiDir << endl;
2912 errTotBiDir += errCountBiDir;
2915 kk = int(volus.size());
2916 for (ii = 0; ii < kk; ++ii)
2918 testSub = surfs.find_list(volus(ii)->surfind);
2919 kk2 = testSub.size();
2920 for (jj = 0; jj < kk2; ++jj)
2922 if (testSub[jj] < 0 && volus(ii)->surfind[jj] != 0)
2925 cerr <<
" Test Connectivity Error :" << errCount <<
" volu " << volus(ii)->index
2926 <<
" makes unknown reference to surface " << volus(ii)->surfind[jj] << endl;
2928 else if (volus(ii)->surfind[jj] != 0)
2930 ll2 = surfs(testSub[jj])->voluind.size();
2932 for (ll = 0; ll < ll2; ll++)
2934 flag = flag || (surfs(testSub[jj])->voluind[ll] == volus(ii)->index);
2939 cerr <<
" Test Connectivity Error :" << errCountBiDir <<
" volu " << volus(ii)->index
2940 <<
" makes uni-directional reference to surface " << volus(ii)->surfind[jj] <<
" list: ";
2941 DisplayVector(volus(ii)->surfind);
2942 cout <<
" list (surfs.voluind): ";
2943 DisplayVector(surfs(testSub[jj])->voluind);
2951 cerr <<
"Test Connectivity volus (surfind) Errors :" << errCount << endl;
2953 if (errCountBiDir > 0)
2955 cerr <<
"Test Connectivity volus (surfind) uni-directional Errors :" << errCountBiDir << endl;
2958 errTotBiDir += errCountBiDir;
2962 <<
" Total errors were detected in the "
2963 "connectivity list in: "
2967 if (errTotBiDir > 0)
2970 <<
" Total errors were detected in "
2971 "the bi-directionality of the connectivity list in: "
2978 #pragma GCC diagnostic pop
2980 void mesh::HashArray()
2987 void mesh::SetMaxIndex()
2989 verts.SetMaxIndex();
2990 edges.SetMaxIndex();
2991 surfs.SetMaxIndex();
2992 volus.SetMaxIndex();
2994 void mesh::SetLastIndex()
2996 verts.SetLastIndex();
2997 edges.SetLastIndex();
2998 surfs.SetLastIndex();
2999 volus.SetLastIndex();
3002 void mesh::ArraysAreHashed()
3004 this->verts.isHash = 1;
3005 this->edges.isHash = 1;
3006 this->surfs.isHash = 1;
3007 this->volus.isHash = 1;
3009 void mesh::SetEdgeLengths()
3011 int nEdges = int(this->edges.size());
3012 bool setEdgeLengths =
true;
3013 for (
int ii = 0; ii < nEdges; ++ii)
3015 if (!rsvs3d::constants::__issetlength(this->edges(ii)->GetLength(
false)))
3022 this->edges.elems[ii].SetLength(*
this);
3026 this->edgesLengthsAreSet = setEdgeLengths;
3028 void mesh::PrepareForUse(
bool needOrder)
3030 verts.isInMesh =
true;
3031 edges.isInMesh =
true;
3032 surfs.isInMesh =
true;
3033 volus.isInMesh =
true;
3038 if (volus.size() == 0)
3041 if (surfs.size() == 0)
3044 if (edges.size() == 0)
3052 verts.PrepareForUse();
3053 edges.PrepareForUse();
3054 surfs.PrepareForUse();
3055 volus.PrepareForUse();
3069 verts.ForceArrayReady();
3070 edges.ForceArrayReady();
3071 surfs.ForceArrayReady();
3072 volus.ForceArrayReady();
3073 if (!this->edgesLengthsAreSet)
3077 this->SetEdgeLengths();
3079 catch (exception
const &ex)
3082 "be due to a call to mesh::PrepareForUse before edges[].vertind"
3083 " has been set, use mesh::HashArray instead if");
3087 void mesh::InvalidateEdgeLength(
int iEdge)
3089 if (!this->edges.isHash)
3091 this->edges.HashArray();
3093 int eSub = this->edges.find(iEdge);
3094 this->edges.elems[eSub].InvalidateLength();
3095 this->edgesLengthsAreSet =
false;
3098 void mesh::GetMaxIndex(
int *nVert,
int *nEdge,
int *nSurf,
int *nVolu)
const
3100 *nVert = verts.GetMaxIndex();
3101 *nEdge = edges.GetMaxIndex();
3102 *nSurf = surfs.GetMaxIndex();
3103 *nVolu = volus.GetMaxIndex();
3105 void mesh::disp()
const
3112 void mesh::read(FILE *fid)
3119 verts.isInMesh =
true;
3120 edges.isInMesh =
true;
3121 surfs.isInMesh =
true;
3122 volus.isInMesh =
true;
3124 void mesh::write(FILE *fid)
const
3132 int mesh::read(
const char *str)
3136 fid = fopen(str,
"r");
3144 cout <<
"File " << str <<
"Could not be opened to read" << endl;
3149 int mesh::write(
const char *str)
const
3152 fid = fopen(str,
"w");
3160 cout <<
"File " << str <<
"Could not be opened to write" << endl;
3165 bool mesh::isready()
const
3167 bool readyforuse =
true;
3168 readyforuse = readyforuse & verts.isready();
3169 readyforuse = readyforuse & edges.isready();
3170 readyforuse = readyforuse & surfs.isready();
3171 readyforuse = readyforuse & volus.isready();
3173 return (readyforuse);
3176 void mesh::displight()
const
3178 cout <<
"mesh: vert " << verts.size();
3179 cout <<
"; edges " << edges.size();
3180 cout <<
"; surfs " << surfs.size();
3181 cout <<
"; volus " << volus.size() << endl;
3183 void mesh::size(
int &nVe,
int &nE,
int &nS,
int &nVo)
const
3185 nVe = this->verts.size();
3186 nE = this->edges.size();
3187 nS = this->surfs.size();
3188 nVo = this->volus.size();
3191 void mesh::Init(
int nVe,
int nE,
int nS,
int nVo)
3193 borderIsSet =
false;
3200 verts.isInMesh =
true;
3201 edges.isInMesh =
true;
3202 surfs.isInMesh =
true;
3203 volus.isInMesh =
true;
3205 #ifdef TEST_ARRAYSTRUCTURES
3206 cout <<
"Mesh Correctly Assigned!" << endl;
3210 void mesh::reserve(
int nVe,
int nE,
int nS,
int nVo)
3217 verts.isInMesh =
true;
3218 edges.isInMesh =
true;
3219 surfs.isInMesh =
true;
3220 volus.isInMesh =
true;
3223 void mesh::MakeCompatible_inplace(
mesh &other)
const
3228 int nVert, nEdge, nSurf, nVolu;
3231 this->GetMaxIndex(&nVert, &nEdge, &nSurf, &nVolu);
3232 other.ChangeIndices(nVert, nEdge, nSurf, nVolu);
3235 void mesh::ChangeIndices(
int nVert,
int nEdge,
int nSurf,
int nVolu)
3237 volus.ChangeIndices(nVert, nEdge, nSurf, nVolu);
3238 edges.ChangeIndices(nVert, nEdge, nSurf, nVolu);
3239 surfs.ChangeIndices(nVert, nEdge, nSurf, nVolu);
3240 verts.ChangeIndices(nVert, nEdge, nSurf, nVolu);
3243 mesh mesh::MakeCompatible(
mesh other)
const
3245 MakeCompatible_inplace(other);
3249 void mesh::Concatenate(
const mesh &other)
3251 this->volus.Concatenate(other.volus);
3252 this->edges.Concatenate(other.edges);
3253 this->verts.Concatenate(other.verts);
3254 this->surfs.Concatenate(other.surfs);
3257 void mesh::PopulateIndices()
3259 volus.PopulateIndices();
3260 edges.PopulateIndices();
3261 verts.PopulateIndices();
3262 surfs.PopulateIndices();
3263 meshDepIsSet =
false;
3285 #pragma GCC diagnostic push
3286 #pragma GCC diagnostic ignored "-Wunused-parameter"
3287 int OrderEdgeList(vector<int> &edgeind,
const mesh &meshin,
bool warn,
bool errout,
const vector<int> *edgeIndOrigPtr,
3290 unordered_multimap<int, int> vert2Edge;
3291 vector<bool> isDone;
3292 vector<int> edgeIndOrig;
3293 int vertCurr, edgeCurr, ii, jj, endsExpl = 0;
3295 if (edgeind.size() <= 0)
3297 return (rsvsorder::ordered);
3300 if (edgeIndOrigPtr == NULL)
3305 edgeIndOrig = edgeind;
3306 edgeIndOrigPtr = &edgeIndOrig;
3309 isDone.assign(edgeIndOrigPtr->size(),
false);
3310 auto edgeSub = meshin.edges.find_list(edgeind);
3311 auto edge2Vert = ConcatenateVectorField(meshin.edges, &edge::vertind, edgeSub);
3313 HashVector(edge2Vert, vert2Edge);
3315 vertCurr = edge2Vert[0];
3316 edgeCurr = edgeind[0];
3318 auto it = vert2Edge.end();
3319 for (ii = 1; ii < int(edgeind.size()); ++ii)
3321 auto range = vert2Edge.equal_range(vertCurr);
3322 if (vert2Edge.count(vertCurr) == 1)
3334 cerr <<
" in :" << __PRETTY_FUNCTION__;
3335 cerr <<
" - edgeind is not closed (single vertex " << vertCurr <<
")" << endl;
3344 vertCurr = edge2Vert[1];
3345 edgeCurr = edgeind[0];
3346 range = vert2Edge.equal_range(vertCurr);
3351 return rsvsorder::open * ii;
3355 if (range.first == vert2Edge.end())
3357 surfin->disptree(meshin, 0);
3359 cerr << ii <<
" vert " << vertCurr <<
" ";
3360 DisplayVector(edge2Vert);
3361 DisplayVector(edgeind);
3362 meshin.verts.isearch(vertCurr)->disp();
3363 cout << it->second <<
" " << 1 / 2 << 2 / 3 << endl;
3364 cerr <<
"Error in :" << __PRETTY_FUNCTION__ << endl;
3366 "range in OrderEdges");
3368 #ifdef RSVS_DIAGNOSTIC
3369 if (vert2Edge.count(vertCurr) != 2)
3371 cerr <<
"DIAGNOSTIC in " << __PRETTY_FUNCTION__ << endl;
3372 cerr <<
" current vertex " << vertCurr <<
" appears " << vert2Edge.count(vertCurr)
3373 <<
" in the surf::edgeind ...->vertind" << endl;
3377 jj = (*edgeIndOrigPtr)[(range.first->second) / 2] == edgeCurr;
3384 if (!isDone[(it->second) / 2])
3386 isDone[(it->second) / 2] =
true;
3387 edgeCurr = (*edgeIndOrigPtr)[(it->second) / 2];
3390 jj = edge2Vert[((it->second) / 2) * 2] == vertCurr;
3391 vertCurr = edge2Vert[((it->second) / 2) * 2 + jj];
3392 edgeind[ii] = edgeCurr;
3396 return rsvsorder::open * ii;
3400 #ifdef RSVS_DIAGNOSTIC_FIXED
3401 cerr <<
"DIAGNOSTIC in " << __PRETTY_FUNCTION__
3402 <<
" surface about to be truncated, if "
3403 "this should not be the case"
3404 " this can be due to duplicates in the edgeind list"
3406 cerr <<
"edgeind : ";
3407 DisplayVector(edgeind);
3408 cerr << endl <<
"edgeIndOrig : ";
3409 DisplayVector((*edgeIndOrigPtr));
3410 cerr << endl <<
"Original connectivity setup:" << endl;
3411 auto temp = edgeind;
3412 edgeind = (*edgeIndOrigPtr);
3413 surfin->disptree(meshin, 1);
3417 edgeind.erase(edgeind.begin() + ii, edgeind.end());
3419 #ifdef RSVS_DIAGNOSTIC_FIXED
3420 cerr << endl <<
"New connectivity setup:" << endl;
3421 surfin->disptree(meshin, 1);
3424 return rsvsorder::truncated;
3428 return rsvsorder::ordered;
3430 #pragma GCC diagnostic pop
3449 int OrderList(vector<int> &edgeind,
const vector<int> &edge2Vert,
bool warn,
bool errout,
3450 const vector<int> *edgeIndOrigPtr)
3452 unordered_multimap<int, int> vert2Edge;
3453 vector<bool> isDone;
3454 vector<int> edgeIndOrig;
3455 int vertCurr, edgeCurr, ii, jj, endsExpl = 0;
3457 if (edgeind.size() <= 0)
3459 return (rsvsorder::ordered);
3462 if (edgeIndOrigPtr == NULL)
3467 edgeIndOrig = edgeind;
3468 edgeIndOrigPtr = &edgeIndOrig;
3471 isDone.assign(edgeIndOrigPtr->size(),
false);
3473 HashVector(edge2Vert, vert2Edge);
3475 vertCurr = edge2Vert[0];
3476 edgeCurr = edgeind[0];
3478 auto it = vert2Edge.end();
3479 for (ii = 1; ii < int(edgeind.size()); ++ii)
3481 auto range = vert2Edge.equal_range(vertCurr);
3482 if (vert2Edge.count(vertCurr) == 1)
3494 cerr <<
" in :" << __PRETTY_FUNCTION__;
3495 cerr <<
" - edgeind is not closed (single vertex " << vertCurr <<
")" << endl;
3504 vertCurr = edge2Vert[1];
3505 edgeCurr = edgeind[0];
3506 range = vert2Edge.equal_range(vertCurr);
3511 return rsvsorder::open * ii;
3515 if (range.first == vert2Edge.end())
3517 cerr << ii <<
" vert " << vertCurr <<
" ";
3518 DisplayVector(edge2Vert);
3519 DisplayVector(edgeind);
3520 cout << it->second <<
" " << 1 / 2 << 2 / 3 << endl;
3521 cerr <<
"Error in :" << __PRETTY_FUNCTION__ << endl;
3523 "range in OrderEdges");
3525 #ifdef RSVS_DIAGNOSTIC
3526 if (vert2Edge.count(vertCurr) != 2)
3528 cerr <<
"DIAGNOSTIC in " << __PRETTY_FUNCTION__ << endl;
3529 cerr <<
" current vertex " << vertCurr <<
" appears " << vert2Edge.count(vertCurr)
3530 <<
" in the surf::edgeind ...->vertind" << endl;
3534 jj = (*edgeIndOrigPtr)[(range.first->second) / 2] == edgeCurr;
3541 if (!isDone[(it->second) / 2])
3543 isDone[(it->second) / 2] =
true;
3544 edgeCurr = (*edgeIndOrigPtr)[(it->second) / 2];
3547 jj = edge2Vert[((it->second) / 2) * 2] == vertCurr;
3548 vertCurr = edge2Vert[((it->second) / 2) * 2 + jj];
3549 edgeind[ii] = edgeCurr;
3553 return rsvsorder::open * ii;
3557 edgeind.erase(edgeind.begin() + ii, edgeind.end());
3558 return rsvsorder::truncated;
3562 return rsvsorder::ordered;
3565 int vert::OrderEdges(
const mesh *meshin, std::vector<int> &edgeIndOut)
const
3568 vector<int> edge2Vert;
3570 if (&edgeIndOut != &(this->edgeind))
3572 edgeIndOut = this->edgeind;
3576 if (edgeIndOut.size() < 2)
3578 return rsvs3d::constants::ordering::error;
3580 vector<int> edgeIndOrig = edgeIndOut;
3582 edge2Vert.reserve(edgeIndOut.size() * 2);
3583 for (
auto iEdge : edgeIndOut)
3585 auto edgeC = meshin->edges.isearch(iEdge);
3586 if (edgeC->surfind.size() != 2)
3588 return rsvs3d::constants::ordering::error;
3590 edge2Vert.push_back(edgeC->surfind[0]);
3591 edge2Vert.push_back(edgeC->surfind[1]);
3594 retVal =
OrderList(edgeIndOut, edge2Vert,
false,
false, &edgeIndOrig);
3596 if (retVal != rsvs3d::constants::ordering::ordered)
3598 edgeIndOut = edgeIndOrig;
3604 std::pair<std::vector<int>,
int> vert::OrderEdges(
const mesh *meshin)
const
3606 std::pair<std::vector<int>,
int> output;
3607 vector<int> &edgeIndOut = output.first;
3609 auto retVal = this->OrderEdges(meshin, edgeIndOut);
3611 return {edgeIndOut, retVal};
3614 int vert::OrderEdges(
const mesh *meshin)
3616 return this->OrderEdges(meshin, this->edgeind);
3619 int vert::SurroundingCoords(
const mesh *meshin,
grid::coordlist &coordout,
bool isOrdered,
3620 std::vector<int> *edgeIndOutPtr)
const
3623 std::vector<int> edgeIndModif;
3625 const std::vector<int> *edgeIndInPtr = &(this->edgeind);
3630 auto retOrder = this->OrderEdges(meshin, edgeIndModif);
3631 if (!rsvs3d::constants::ordering::__isordered(retOrder))
3633 return rsvs3d::constants::__failure;
3635 edgeIndInPtr = &edgeIndModif;
3640 auto &edgeIndOut = *edgeIndInPtr;
3642 int nEdges = edgeIndOut.size();
3643 for (
int i = 0; i < nEdges; ++i)
3646 coordout.push_back(&(meshin->verts.isearch(iVert)->coord));
3649 if (edgeIndOutPtr != NULL)
3653 edgeIndModif.swap(*edgeIndOutPtr);
3657 *edgeIndOutPtr = this->edgeind;
3660 return rsvs3d::constants::__success;
3663 int surf::OrderEdges(
mesh *meshin)
3665 vector<int> edgeIndOrig;
3666 vector<bool> isDone;
3670 isTruncated =
false;
3675 this->isordered =
false;
3676 return (newSurfInd);
3678 if (edgeind.size() <= 0)
3680 this->isordered =
true;
3681 return (newSurfInd);
3684 sort(this->edgeind);
3685 unique(this->edgeind);
3686 edgeIndOrig = this->edgeind;
3688 int retFlag =
OrderEdgeList(this->edgeind, *meshin,
true,
true, &edgeIndOrig,
this);
3690 isTruncated = retFlag == rsvsorder::truncated;
3695 this->isordered =
true;
3696 return (newSurfInd);
3699 if ((meshin->surfs.capacity() - meshin->surfs.size()) == 0)
3703 #ifdef RSVS_DIAGNOSTIC_FIXED
3704 cerr <<
"DIAGNOSTIC in " << __PRETTY_FUNCTION__ <<
" reallocation necessary." << endl;
3706 this->edgeind = edgeIndOrig;
3707 this->isordered =
false;
3708 meshin->surfs.reserve(meshin->surfs.capacity() + meshin->surfs.capacity() / 2);
3710 return (newSurfInd);
3713 newSurfInd = this->SplitSurface(*meshin, edgeIndOrig);
3715 this->isordered =
true;
3716 return (newSurfInd);
3719 int surf::SplitSurface(
mesh &meshin,
const vector<int> &fullEdgeInd)
3723 vector<int> newSurfedgeind;
3724 surf newSurf = *
this;
3725 meshin.surfs.SetMaxIndex();
3726 newSurf.index = meshin.surfs.GetMaxIndex() + 1;
3729 newSurf.edgeind.clear();
3732 for (
auto allInd : fullEdgeInd)
3735 for (
auto currInd : this->edgeind)
3737 flag = currInd == allInd;
3745 newSurf.edgeind.push_back(allInd);
3749 if ((newSurf.edgeind.size() != (fullEdgeInd.size() - this->edgeind.size())) || newSurf.edgeind.size() == 0 ||
3750 this->edgeind.size() == 0)
3752 cerr <<
"Error in: " << __PRETTY_FUNCTION__ << endl;
3753 cerr <<
" New surface edgeind is not of the correct size:" << endl
3754 <<
" newSurf.edgeind (" << newSurf.edgeind.size() <<
") != fullEdgeInd (" << fullEdgeInd.size()
3755 <<
")-this::edgeind(" << this->edgeind.size() <<
")" << endl;
3757 "surface is incorrect.");
3760 #ifdef RSVS_DIAGNOSTIC_FIXED
3761 DisplayVector(this->edgeind);
3762 DisplayVector(newSurf.edgeind);
3765 meshin.surfs.push_back(newSurf);
3767 auto prevHash = meshin.surfs.isHash;
3768 meshin.surfs.isHash = 1;
3769 meshin.SwitchIndex(6, this->index, newSurf.index, newSurf.edgeind);
3771 if (this->edgeind.size() == 0)
3774 "surf::SplitSurface process");
3777 meshin.surfs[meshin.surfs.size() - 1].OrderEdges(&meshin);
3779 meshin.surfs.isHash = prevHash;
3780 prevHash = meshin.volus.isHash;
3781 if (meshin.WhatDim() > 2)
3784 if (this->voluind.size() < 2)
3786 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
3787 cerr <<
" voluind is of size " << this->voluind.size() << endl;
3791 for (
int i = 0; i < 2; ++i)
3793 kk = meshin.volus.find(voluind[i]);
3796 meshin.volus[kk].surfind.push_back(newSurf.index);
3798 meshin.volus.isHash = prevHash;
3801 newSurfInd = newSurf.index;
3802 #ifdef RSVS_DIAGNOSTIC_FIXED
3803 cerr <<
" Succesful surface split " << this->index <<
" | " << newSurfInd << endl;
3805 return (newSurfInd);
3808 void surf::OrderedVerts(
const mesh *meshin, vector<int> &vertList)
const
3810 int jj, n, actVert, edgeCurr;
3811 int verts[2], vertsPast[2];
3813 n = int(edgeind.size());
3815 vertList.reserve(n);
3817 edgeCurr = meshin->edges.find(edgeind[n - 1]);
3818 verts[0] = (meshin->edges(edgeCurr)->vertind[0]);
3819 verts[1] = (meshin->edges(edgeCurr)->vertind[1]);
3820 vertsPast[0] = verts[0];
3821 vertsPast[1] = verts[1];
3823 for (jj = 0; jj < int(n); ++jj)
3825 edgeCurr = meshin->edges.find(edgeind[jj]);
3827 verts[0] = (meshin->edges(edgeCurr)->vertind[0]);
3828 verts[1] = (meshin->edges(edgeCurr)->vertind[1]);
3830 if ((verts[0] == vertsPast[0]) || (verts[1] == vertsPast[0]))
3835 else if ((verts[0] == vertsPast[1]) || (verts[1] == vertsPast[1]))
3844 cerr <<
"Error: Surface is not ordered " << endl;
3845 cerr <<
" in " << __PRETTY_FUNCTION__ << endl;
3850 vertList.push_back(vertsPast[actVert]);
3851 vertsPast[0] = verts[0];
3852 vertsPast[1] = verts[1];
3855 vector<int> surf::OrderedVerts(
const mesh *meshin)
const
3857 vector<int> vertList;
3858 this->OrderedVerts(meshin, vertList);
3862 void surf::FlipVolus()
3865 interm = voluind[0];
3866 voluind[0] = voluind[1];
3867 voluind[1] = interm;
3870 bool edge::vertconneq(
const edge &other)
const
3872 return (this->vertind[0] == other.vertind[0] && this->vertind[1] == other.vertind[1]) ||
3873 (this->vertind[1] == other.vertind[0] && this->vertind[0] == other.vertind[1]);
3876 bool surf::edgeconneq(
const surf &other,
bool recurse)
const
3891 int count = this->edgeind.size();
3892 int count2 = other.edgeind.size();
3894 for (
int i = 0; i < count; ++i)
3897 for (
int j = 0; j < count2; ++j)
3899 temp = temp || (this->edgeind[i] == other.edgeind[j]);
3909 return out && other.edgeconneq(*
this,
false);
3917 vector<int> mesh::OrderEdges()
3921 vector<int> newSurfPairs;
3923 if (surfs.size() > 0)
3925 auto origSurf = surfs(0);
3926 auto capPrev = surfs.capacity();
3927 bool pntrFlag, capFlag;
3932 origSurf = surfs(0);
3933 capPrev = surfs.capacity();
3934 for (ii = 0; ii < surfs.size(); ++ii)
3936 if (!surfs(ii)->isready(
true))
3938 newInd = surfs.elems[ii].OrderEdges(
this);
3941 newSurfPairs.push_back(surfs(ii)->index);
3942 newSurfPairs.push_back(newInd);
3947 pntrFlag = (origSurf != surfs(0));
3948 capFlag = (capPrev != surfs.capacity());
3949 }
while (pntrFlag || capFlag);
3951 for (ii = 0; ii < surfs.size(); ++ii)
3953 if (!surfs(ii)->isready(
true))
3956 " is not ordered.");
3961 return (newSurfPairs);
3964 void mesh::GetOffBorderVert(vector<int> &vertInd, vector<int> &voluInd,
int outerVolume)
3981 this->GetOffBorderVert(vertInd, voluInd, outerVolume);
3984 void mesh::GetOffBorderVert(vector<int> &vertInd, vector<int> &voluInd,
int outerVolume)
const
3986 if (this->WhatDim() == 3)
3988 this->GetOffBorderVert3D(vertInd, voluInd, outerVolume);
3990 else if (this->WhatDim() == 2)
3992 this->GetOffBorderVert2D(vertInd, voluInd, outerVolume);
3996 void mesh::GetOffBorderVert3D(vector<int> &vertInd, vector<int> &voluInd,
int outerVolume)
const
4009 vector<double> vals;
4010 bool voluOnBoundary;
4015 vertInd.reserve(nj);
4017 voluInd.reserve(ni);
4019 for (ii = 0; ii < ni; ++ii)
4021 voluOnBoundary = volus(ii)->isBorder;
4024 if (outerVolume == 0)
4026 this->VoluValuesofParents(volus(ii)->index, vals, &volu::target);
4027 voluOnBoundary =
false;
4029 while (!voluOnBoundary && jj < meshtree.nParents)
4031 voluOnBoundary = fabs(vals[jj] - 1.0) < __DBL_EPSILON__;
4035 else if (outerVolume == 1)
4037 this->VoluValuesofParents(volus(ii)->index, vals, &volu::target);
4038 voluOnBoundary =
false;
4040 while (!voluOnBoundary && jj < meshtree.nParents)
4042 voluOnBoundary = fabs(vals[jj]) > __DBL_EPSILON__;
4046 else if (outerVolume != -1)
4055 voluInd.push_back(volus(ii)->index);
4057 for (
auto surfAct : volus(ii)->surfind)
4059 for (
auto edgeAct : surfs.isearch(surfAct)->edgeind)
4061 for (
auto vertAct : edges.isearch(edgeAct)->vertind)
4063 if (!verts.isearch(vertAct)->isBorder)
4065 vertInd.push_back(vertAct);
4074 void mesh::GetOffBorderVert2D(vector<int> &vertInd, vector<int> &surfind,
int outerVolume)
const
4086 int ii, ni, jj, nj, kk, nk, vertTemp, edgeSub, surfSub;
4087 vector<double> vals;
4093 vertInd.reserve(nj);
4095 surfind.reserve(ni);
4097 for (ii = 0; ii < ni; ++ii)
4099 surfCond = surfs(ii)->isBorder;
4102 if (outerVolume == 0)
4104 this->SurfValuesofParents(surfs(ii)->index, vals, &surf::target);
4107 while (!surfCond && jj < meshtree.nParents)
4109 surfCond = vals[jj] == 1.0;
4113 else if (outerVolume == 1)
4115 this->SurfValuesofParents(surfs(ii)->index, vals, &surf::target);
4118 while (!surfCond && jj < meshtree.nParents)
4120 surfCond = vals[jj] > 0.0;
4124 else if (outerVolume != -1)
4127 "outerVolume -1,0, or 1");
4134 if (outerVolume == 0)
4136 nj = surfs(ii)->edgeind.size();
4137 for (jj = 0; jj < nj; ++jj)
4139 surfSub = edges.find(surfs(ii)->edgeind[jj]);
4140 for (kk = 0; kk < 2; ++kk)
4142 if (edges(surfSub)->surfind[kk] != 0)
4144 if (!(surfs.isearch(edges(surfSub)->surfind[kk])->isBorder))
4146 surfind.push_back(edges(surfSub)->surfind[kk]);
4154 surfind.push_back(surfs(ii)->index);
4157 nj = surfs(surfSub)->edgeind.size();
4158 for (jj = 0; jj < nj; ++jj)
4160 edgeSub = edges.find(surfs(surfSub)->edgeind[jj]);
4161 nk = edges(edgeSub)->vertind.size();
4162 for (kk = 0; kk < nk; ++kk)
4164 vertTemp = edges(edgeSub)->vertind[kk];
4165 if (!verts.isearch(vertTemp)->isBorder)
4167 vertInd.push_back(vertTemp);
4175 void mesh::SetBorders()
4178 if (
int(volus.size()) > 0)
4181 for (ii = 0; ii < surfs.size(); ++ii)
4184 nT = surfs(ii)->voluind.size();
4185 surfs[ii].isBorder =
false;
4186 while (jj < nT && !surfs(ii)->isBorder)
4188 surfs[ii].isBorder = surfs[ii].voluind[jj] == 0;
4192 surfs.ForceArrayReady();
4195 for (ii = 0; ii < volus.size(); ++ii)
4198 nT = volus(ii)->surfind.size();
4199 volus[ii].isBorder =
false;
4200 while (jj < nT && !volus(ii)->isBorder)
4202 volus[ii].isBorder = surfs(surfs.find(volus[ii].surfind[jj]))->isBorder;
4206 volus.ForceArrayReady();
4209 for (ii = 0; ii < edges.size(); ++ii)
4212 nT = edges(ii)->surfind.size();
4213 edges[ii].isBorder =
false;
4214 while (jj < nT && !edges(ii)->isBorder)
4216 edges[ii].isBorder = surfs(surfs.find(edges[ii].surfind[jj]))->isBorder;
4220 edges.ForceArrayReady();
4224 for (ii = 0; ii < edges.size(); ++ii)
4227 nT = edges(ii)->surfind.size();
4228 edges[ii].isBorder =
false;
4229 while (jj < nT && !edges(ii)->isBorder)
4231 edges[ii].isBorder = (edges[ii].surfind[jj] == 0);
4235 edges.ForceArrayReady();
4237 for (ii = 0; ii < surfs.size(); ++ii)
4240 nT = surfs(ii)->edgeind.size();
4241 surfs[ii].isBorder =
false;
4242 while (jj < nT && !surfs(ii)->isBorder)
4244 surfs[ii].isBorder = edges(edges.find(surfs[ii].edgeind[jj]))->isBorder;
4248 surfs.ForceArrayReady();
4252 for (ii = 0; ii < verts.size(); ++ii)
4255 nT = verts(ii)->edgeind.size();
4256 verts[ii].isBorder =
false;
4257 while (jj < nT && !verts(ii)->isBorder)
4259 verts[ii].isBorder = edges(edges.find(verts[ii].edgeind[jj]))->isBorder;
4263 verts.ForceArrayReady();
4265 if (
int(volus.size()) > 0)
4269 int nVolu = volus.size();
4270 for (ii = 0; ii < nVolu; ++ii)
4272 if (!volus(ii)->isBorder)
4274 for (
auto surfAct : volus(ii)->surfind)
4276 for (
auto edgeAct : surfs.isearch(surfAct)->edgeind)
4278 for (
auto vertAct : edges.isearch(edgeAct)->vertind)
4280 if (verts.isearch(vertAct)->isBorder)
4282 volus[ii].isBorder =
true;
4286 if (volus[ii].isBorder)
4291 if (volus[ii].isBorder)
4298 volus.ForceArrayReady();
4304 int nSurf = surfs.size();
4305 for (ii = 0; ii < nSurf; ++ii)
4307 if (!surfs(ii)->isBorder)
4309 for (
auto edgeAct : surfs(ii)->edgeind)
4311 for (
auto vertAct : edges.isearch(edgeAct)->vertind)
4313 if (verts.isearch(vertAct)->isBorder)
4315 surfs[ii].isBorder =
true;
4319 if (surfs[ii].isBorder)
4326 surfs.ForceArrayReady();
4331 void mesh::ForceCloseContainers()
4333 int ii, jj, iEdge, iSurf, kk;
4334 int nVert, nEdge, nSurf, nBlocks;
4335 bool is3DMesh = volus.size() > 0;
4336 vector<int> vertBlock;
4337 vector<bool> surfsIsDone;
4340 nBlocks = this->ConnectedVertex(vertBlock);
4341 surfsIsDone.assign(surfs.size(),
false);
4342 nVert = verts.size();
4346 volus.elems.clear();
4347 volus.Init(nBlocks);
4348 volus.PopulateIndices();
4350 for (ii = 0; ii < nVert; ii++)
4352 nEdge = verts(ii)->edgeind.size();
4353 for (jj = 0; jj < nEdge; ++jj)
4355 iEdge = edges.find(verts(ii)->edgeind[jj]);
4357 if (vertBlock[verts.find(edges(iEdge)->vertind[0])] != vertBlock[verts.find(edges(iEdge)->vertind[1])])
4360 <<
"An edge has connections "
4363 cerr << __PRETTY_FUNCTION__ << endl;
4366 nSurf = edges(iEdge)->surfind.size();
4367 for (kk = 0; kk < nSurf; ++kk)
4369 iSurf = surfs.find(edges(iEdge)->surfind[kk]);
4370 if (surfsIsDone[iSurf])
4373 if (surfs.elems[iSurf].voluind[0] != vertBlock[ii])
4376 <<
"Surf voluind assignement "
4377 "performed twice during:"
4379 cerr << __PRETTY_FUNCTION__ << endl;
4383 volus.elems[volus.find(vertBlock[ii])].surfind.push_back(edges(iEdge)->surfind[kk]);
4384 surfs.elems[iSurf].voluind.clear();
4385 surfs.elems[iSurf].voluind.push_back(vertBlock[ii]);
4386 surfs.elems[iSurf].voluind.push_back(0);
4387 surfsIsDone[iSurf] =
true;
4395 surfs.elems.clear();
4396 surfs.Init(nBlocks);
4397 surfs.PopulateIndices();
4400 for (ii = 0; ii < nVert; ii++)
4402 nEdge = verts(ii)->edgeind.size();
4403 for (jj = 0; jj < nEdge; ++jj)
4405 iEdge = edges.find(verts(ii)->edgeind[jj]);
4406 surfs.elems[surfs.find(vertBlock[ii])].edgeind.push_back(verts(ii)->edgeind[jj]);
4407 edges.elems[iEdge].surfind.clear();
4408 edges.elems[iEdge].surfind.push_back(vertBlock[ii]);
4409 edges.elems[iEdge].surfind.push_back(0);
4414 verts.ForceArrayReady();
4415 surfs.ForceArrayReady();
4416 edges.ForceArrayReady();
4417 volus.ForceArrayReady();
4427 std::vector<bool> isSnaxDone;
4428 std::vector<int> sameSnaxs, rmvInds;
4429 int nSnax, countJ, countRep;
4431 nSnax = closeVert.vec.size();
4432 if (!closeVert.isHash)
4434 closeVert.GenerateHash();
4436 rmvInds.reserve(nSnax);
4437 isSnaxDone.assign(nSnax,
false);
4441 for (
int i = 0; i < nSnax; ++i)
4443 if ((!isSnaxDone[i]) && (closeVert.vec[i] != -1))
4446 sameSnaxs = closeVert.findall(closeVert.vec[i]);
4447 countJ = sameSnaxs.size();
4448 for (
int j = 1; j < countJ; ++j)
4450 this->SwitchIndex(1, this->verts(sameSnaxs[j])->index, this->verts(sameSnaxs[0])->index);
4452 rmvInds.push_back(this->verts(sameSnaxs[j])->index);
4453 isSnaxDone[sameSnaxs[j]] =
true;
4455 isSnaxDone[sameSnaxs[0]] =
true;
4459 isSnaxDone[i] =
true;
4463 if (rmvInds.size() > 0 && delVerts)
4467 this->verts.remove(rmvInds);
4468 this->verts.PrepareForUse();
4473 void mesh::RemoveSingularConnectors(
const std::vector<int> &rmvVertInds,
bool voidError)
4488 std::vector<int> rmvInds, rmvInds2;
4490 int count, countRep;
4492 if (rmvVertInds.size() > 0)
4494 rmvInds = rmvVertInds;
4498 this->verts.remove(rmvInds);
4499 this->verts.PrepareForUse();
4501 std::cout <<
"Number of removed vertices " << rmvInds.size() << std::endl;
4507 count = this->edges.size();
4509 for (
int i = 0; i < count; ++i)
4511 if (this->edges(i)->vertind[0] == this->edges(i)->vertind[1])
4513 this->RemoveIndex(2, this->edges(i)->index);
4514 rmvInds.push_back(this->edges(i)->index);
4519 std::cout <<
"Number of removed edges " << countRep << std::endl;
4523 this->edges.remove(rmvInds);
4524 this->edges.PrepareForUse();
4528 count = this->surfs.size();
4531 for (
int i = 0; i < count; ++i)
4533 nEdgeSurf = this->surfs(i)->edgeind.size();
4536 bool edgeConnEq = this->edges.isearch(this->surfs(i)->edgeind[0])
4537 ->vertconneq(*(this->edges.isearch(this->surfs(i)->edgeind[1])));
4538 if (edgeConnEq && (this->surfs(i)->edgeind[1] != this->surfs(i)->edgeind[0]))
4540 rmvInds2.push_back(this->surfs(i)->edgeind[1]);
4541 this->SwitchIndex(2, this->surfs(i)->edgeind[1], this->surfs(i)->edgeind[0]);
4546 this->RemoveIndex(3, this->surfs(i)->index);
4547 rmvInds.push_back(this->surfs(i)->index);
4552 std::cout <<
"Number of removed surfs " << countRep << std::endl;
4556 this->surfs.remove(rmvInds);
4557 this->surfs.PrepareForUse();
4562 std::cout <<
"Number of removed edges (duplicates) " << rmvInds2.size() << std::endl;
4564 this->edges.remove(rmvInds2);
4565 this->edges.PrepareForUse();
4569 count = this->volus.size();
4572 for (
int i = 0; i < count; ++i)
4574 nEdgeSurf = this->volus(i)->surfind.size();
4577 bool surfConnEq = this->surfs.isearch(this->volus(i)->surfind[0])
4578 ->edgeconneq(*(this->surfs.isearch(this->volus(i)->surfind[1])));
4581 if ((this->volus(i)->surfind[0] != this->volus(i)->surfind[1]) && surfConnEq)
4583 rmvInds2.push_back(this->volus(i)->surfind[1]);
4584 this->SwitchIndex(3, this->volus(i)->surfind[1], this->volus(i)->surfind[0]);
4587 else if (nEdgeSurf == 3 && voidError)
4593 "unwanted Void creation");
4597 this->RemoveIndex(4, this->volus(i)->index);
4598 rmvInds.push_back(this->volus(i)->index);
4603 std::cout <<
"Number of removed volus " << countRep << std::endl;
4607 this->volus.remove(rmvInds);
4608 this->volus.PrepareForUse();
4613 std::cout <<
"Number of removed surfs (duplicates) " << rmvInds2.size() << std::endl;
4615 this->surfs.remove(rmvInds2);
4616 this->surfs.PrepareForUse();
4635 int nVertExplored, nVerts, nBlocks, nCurr, nEdgesCurr, ii, jj, kk;
4636 vector<bool> vertStatus;
4638 vector<int> currQueue, nextQueue;
4641 nVerts = verts.size();
4645 vertStatus.assign(nVerts,
false);
4647 if (
int(vertBlock.size()) == 0)
4652 vertBlock.assign(nVerts, 0);
4654 else if (
int(vertBlock.size()) == nVerts)
4658 for (
int i = 0; i < nVerts; ++i)
4660 if (vertBlock[i] != 0)
4662 vertStatus[i] =
true;
4671 cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
": " << endl
4672 <<
"vertBlock should be empty or the size of mesh.verts";
4675 currQueue.reserve(nVerts / 2);
4676 nextQueue.reserve(nVerts / 2);
4679 while (nVertExplored < nVerts)
4682 if (currQueue.size() < 1)
4685 while (ii < nVerts && vertStatus[ii])
4691 cerr <<
"Error starting point for loop not found despite "
4692 "max number of vertex not reached"
4694 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
4697 currQueue.push_back(ii);
4701 nCurr = currQueue.size();
4702 for (ii = 0; ii < nCurr; ++ii)
4704 if (!vertStatus[currQueue[ii]])
4706 vertBlock[currQueue[ii]] = nBlocks;
4707 nEdgesCurr = verts(currQueue[ii])->edgeind.size();
4708 for (jj = 0; jj < nEdgesCurr; ++jj)
4710 kk = int(edges.isearch(verts(currQueue[ii])->edgeind[jj])->vertind[0] ==
4711 verts(currQueue[ii])->index);
4712 nextQueue.push_back(verts.find(edges.isearch(verts(currQueue[ii])->edgeind[jj])->vertind[kk]));
4714 if (verts.find(edges.isearch(verts(currQueue[ii])->edgeind[jj])->vertind[kk]) == -1)
4716 cerr <<
"Edge index: " << verts(currQueue[ii])->edgeind[jj]
4717 <<
" vertex index:" << edges.isearch(verts(currQueue[ii])->edgeind[jj])->vertind[kk]
4719 cerr <<
"Edge connected to non existant vertex" << endl;
4720 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
4725 vertStatus[currQueue[ii]] =
true;
4732 currQueue.swap(nextQueue);
4737 int mesh::ConnectedVolumes(vector<int> &voluBlock,
const vector<bool> &boundaryFaces)
const
4744 int nVoluExplored, nVolus, nSurfs, nBlocks, nCurr, nSurfsCurr, ii, jj, kk;
4745 vector<bool> volStatus;
4747 vector<int> currQueue, nextQueue;
4748 bool boundConstrAct =
false;
4750 nVolus = volus.size();
4751 nSurfs = surfs.size();
4755 volStatus.assign(nVolus,
false);
4757 if (
int(voluBlock.size()) == 0)
4762 voluBlock.assign(nVolus, 0);
4764 else if (
int(voluBlock.size()) == nVolus)
4768 for (
int i = 0; i < nVolus; ++i)
4770 if (voluBlock[i] != 0)
4772 volStatus[i] =
true;
4781 cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
": " << endl
4782 <<
"voluBlock should be empty or the size of mesh.volus";
4785 if (boundaryFaces.size() == 0)
4787 boundConstrAct =
false;
4789 else if (
int(boundaryFaces.size()) == nSurfs)
4791 boundConstrAct =
true;
4795 cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
": " << endl
4796 <<
"boundaryFaces should be empty or the size of mesh.surfs";
4799 currQueue.reserve(nVolus / 2);
4800 nextQueue.reserve(nVolus / 2);
4803 while (nVoluExplored < nVolus)
4806 if (currQueue.size() < 1)
4809 while (ii < nVolus && volStatus[ii])
4815 cerr <<
"Error starting point for loop not found despite"
4816 " max number of volume not reached"
4818 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
4821 currQueue.push_back(ii);
4825 nCurr = currQueue.size();
4826 for (ii = 0; ii < nCurr; ++ii)
4828 if (volStatus[currQueue[ii]])
4833 voluBlock[currQueue[ii]] = nBlocks;
4834 nSurfsCurr = volus(currQueue[ii])->surfind.size();
4835 for (jj = 0; jj < nSurfsCurr; ++jj)
4837 int sTempInd = surfs.find(volus(currQueue[ii])->surfind[jj]);
4838 if (boundConstrAct && boundaryFaces[sTempInd])
4843 kk = int(surfs(sTempInd)->voluind[0] == volus(currQueue[ii])->index);
4844 if (surfs(sTempInd)->voluind[kk] == 0)
4849 nextQueue.push_back(volus.find(surfs(sTempInd)->voluind[kk]));
4851 if (volus.find(surfs(sTempInd)->voluind[kk]) == -1)
4853 cerr <<
"Surf index: " << volus(currQueue[ii])->surfind[jj]
4854 <<
" volume index:" << surfs(sTempInd)->voluind[kk] << endl;
4855 cerr <<
"Surf connected to non existant volume" << endl;
4856 cerr <<
"Error in " << __PRETTY_FUNCTION__ << endl;
4861 volStatus[currQueue[ii]] =
true;
4867 currQueue.swap(nextQueue);
4872 coordvec mesh::CalcCentreVolu(
int ind)
const
4883 a = volus.find(ind);
4884 ni = volus(a)->surfind.size();
4885 for (ii = 0; ii < ni; ++ii)
4887 cSurf = surfs.find(volus(a)->surfind[ii]);
4888 nj = surfs(cSurf)->edgeind.size();
4889 for (jj = 0; jj < nj; ++jj)
4891 temp.assign(0, 0, 0);
4892 temp.add(verts.isearch(edges.isearch(surfs(cSurf)->edgeind[jj])->vertind[0])->coord);
4893 temp.substract(verts.isearch(edges.isearch(surfs(cSurf)->edgeind[jj])->vertind[1])->coord);
4895 edgeLength = temp.CalcNorm();
4896 voluLength += edgeLength;
4898 temp.add(verts.isearch(edges.isearch(surfs(cSurf)->edgeind[jj])->vertind[1])->coord);
4899 temp.add(verts.isearch(edges.isearch(surfs(cSurf)->edgeind[jj])->vertind[1])->coord);
4900 temp.mult(edgeLength);
4902 ret.add(temp.usedata());
4905 ret.div(voluLength);
4909 coordvec mesh::CalcPseudoNormalSurf(
int ind)
const
4915 vector<int> vertList;
4919 cSurf = surfs.find(ind);
4920 surfs(cSurf)->OrderedVerts(
this, vertList);
4922 nj = vertList.size();
4923 ret.assign(0, 0, 0);
4924 for (jj = 0; jj < nj; ++jj)
4926 temp1.assign(0, 0, 0);
4927 temp2.assign(0, 0, 0);
4928 temp1.add(verts.isearch(vertList[(jj + 1) % nj])->coord);
4929 temp2.add(verts.isearch(vertList[(jj + nj - 1) % nj])->coord);
4930 temp1.substract(verts.isearch(vertList[jj])->coord);
4931 temp2.substract(verts.isearch(vertList[jj])->coord);
4933 temp3 = temp1.cross(temp2.usedata());
4935 edgeLength = temp3.CalcNorm();
4936 voluLength += edgeLength;
4938 ret.add(temp3.usedata());
4941 ret.div(voluLength);
4950 if (this->WhatDim() == 3)
4952 this->OrientSurfaceVolume();
4954 else if (this->WhatDim() == 2)
4956 this->OrientEdgeSurface();
4964 void mesh::OrientEdgeSurface()
4966 cerr <<
"Warning: not coded yet in " << __PRETTY_FUNCTION__ << endl;
4969 void mesh::OrientSurfaceVolume()
4977 int nBlocks, ii, jj, ni, nj, kk;
4978 vector<int> surfOrient;
4979 vector<bool> isFlip;
4983 nBlocks = OrientRelativeSurfaceVolume(surfOrient);
4984 isFlip.assign(nBlocks,
false);
4989 for (ii = 1; ii <= nBlocks; ii++)
4992 nj = surfOrient.size();
4996 while (jj < nj && ii != abs(surfOrient[jj]))
5005 <<
"Warning: Cell orientations could not "
5007 cerr <<
" in " << __PRETTY_FUNCTION__;
5010 kk = surfs(jj)->voluind[0] == 0;
5011 centreVolu = CalcCentreVolu(surfs(jj)->voluind[kk]);
5012 normalVec = CalcPseudoNormalSurf(surfs(jj)->index);
5014 centreVolu.substractfrom(verts.isearch(edges.isearch(surfs(jj)->edgeind[0])->vertind[0])->coord);
5015 dotProd = centreVolu.dot(normalVec.usedata());
5016 }
while (!isfinite(dotProd) || (fabs(dotProd) < numeric_limits<double>::epsilon()));
5018 isFlip[ii - 1] = (((dotProd < 0.0) && (kk == 0)) || ((dotProd > 0.0) && (kk == 1)));
5020 ni = surfOrient.size();
5021 for (ii = 0; ii < ni; ++ii)
5023 if (isFlip[abs(surfOrient[ii]) - 1])
5025 surfs.elems[ii].FlipVolus();
5028 this->facesAreOriented =
true;
5031 int mesh::OrientRelativeSurfaceVolume(vector<int> &surfOrient)
5033 int nSurfExplored, nSurfs, nBlocks, nCurr, currEdge, testSurf, relOrient;
5034 int ii, jj, kk, nj, nk;
5035 vector<bool> surfStatus;
5036 vector<vector<int>> orderVert;
5037 bool isConnec, t0, t1, t3, t4, isFlip;
5039 vector<int> currQueue, nextQueue, emptVert;
5042 nSurfs = surfs.size();
5044 surfStatus.assign(nSurfs,
false);
5045 surfOrient.assign(nSurfs, 0);
5046 currQueue.reserve(nSurfs / 2);
5047 nextQueue.reserve(nSurfs / 2);
5048 orderVert.reserve(nSurfs);
5052 emptVert.assign(6, 0);
5053 for (ii = 0; ii < nSurfs; ii++)
5055 orderVert.push_back(emptVert);
5056 surfs(ii)->OrderedVerts(
this, orderVert[ii]);
5074 while (nSurfExplored < nSurfs)
5078 if (currQueue.size() < 1)
5081 while (ii < nSurfs && surfStatus[ii])
5097 currQueue.push_back(ii);
5099 surfStatus[ii] =
true;
5101 surfOrient[ii] = nBlocks;
5104 nCurr = currQueue.size();
5105 for (ii = 0; ii < nCurr; ++ii)
5107 nj = surfs(currQueue[ii])->edgeind.size();
5108 for (jj = 0; jj < nj; ++jj)
5110 currEdge = edges.find(surfs(currQueue[ii])->edgeind[jj]);
5111 nk = edges(currEdge)->surfind.size();
5112 for (kk = 0; kk < nk; ++kk)
5115 testSurf = surfs.find(edges(currEdge)->surfind[kk]);
5116 t0 = (surfs(testSurf)->voluind[0] == surfs(currQueue[ii])->voluind[0] ||
5117 surfs(testSurf)->voluind[1] == surfs(currQueue[ii])->voluind[0]) &&
5118 (surfs(currQueue[ii])->voluind[0] != 0);
5120 t1 = (surfs(testSurf)->voluind[0] == surfs(currQueue[ii])->voluind[1] ||
5121 surfs(testSurf)->voluind[1] == surfs(currQueue[ii])->voluind[1]) &&
5122 (surfs(currQueue[ii])->voluind[1] != 0);
5124 isConnec = (edges(currEdge)->surfind[kk] != surfs(currQueue[ii])->index) && (t0 || t1) &&
5125 (!surfStatus[testSurf]);
5130 relOrient = OrderMatchLists(orderVert[currQueue[ii]], orderVert[testSurf],
5131 edges(currEdge)->vertind[0], edges(currEdge)->vertind[1]);
5133 nextQueue.push_back(testSurf);
5135 surfStatus[testSurf] =
true;
5136 surfOrient[testSurf] = -1 * relOrient * surfOrient[currQueue[ii]];
5139 t3 = (surfs(testSurf)->voluind[0] == surfs(currQueue[ii])->voluind[0]);
5140 t4 = (surfs(testSurf)->voluind[1] == surfs(currQueue[ii])->voluind[1]);
5141 isFlip = ((relOrient == -1) && ((t0 && !t3) || (t1 && !t4))) ||
5142 ((relOrient == 1) && ((t0 && t3) || (t1 && t4)));
5145 surfs.elems[testSurf].FlipVolus();
5153 currQueue.swap(nextQueue);
5160 grid::limits domain;
5161 for (
int i = 0; i < 3; ++i)
5163 domain[i] = {0.0, 1.0};
5165 return this->Scale(domain);
5182 grid::limits currDomain = this->BoundingBox();
5185 for (
int i = 0; i < 3; ++i)
5189 transformation[i][2] = (domain[i][1] - domain[i][0]) / (currDomain[i][1] - currDomain[i][0]);
5191 if (!isfinite(transformation[i][2]))
5198 this->LinearTransform(transformation);
5209 int nVerts = int(this->verts.size());
5211 for (
int ii = 0; ii < nVerts; ++ii)
5213 for (
int jj = 0; jj < 3; ++jj)
5215 this->verts.elems[ii].coord[jj] =
5216 transform[jj][0] + ((this->verts(ii)->coord[jj] - transform[jj][1]) * transform[jj][2]);
5240 for (
mesh *famMember : this->meshtree.*mp)
5242 famMember->LinearTransform(transform);
5243 famMember->_LinearTransformGeneration(transform, mp);
5247 grid::limits mesh::BoundingBox()
const
5249 int nVerts = this->verts.size();
5250 grid::limits currDomain;
5251 for (
int i = 0; i < 3; ++i)
5253 currDomain[i] = {std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity()};
5255 for (
int ii = 0; ii < nVerts; ++ii)
5257 for (
int jj = 0; jj < 3; ++jj)
5260 currDomain[jj][0] <= this->verts(ii)->coord[jj] ? currDomain[jj][0] : this->verts(ii)->coord[jj];
5262 currDomain[jj][1] >= this->verts(ii)->coord[jj] ? currDomain[jj][1] : this->verts(ii)->coord[jj];
5265 return (currDomain);
5268 void mesh::ReturnBoundingBox(std::array<double, 3> &lowerB, std::array<double, 3> &upperB)
const
5270 grid::limits currDomain = this->BoundingBox();
5271 for (
int i = 0; i < 3; ++i)
5273 lowerB[i] = currDomain[i][0];
5274 upperB[i] = currDomain[i][1];
5278 void mesh::LoadTargetFill(
const std::string &fileName)
5280 vector<double> fillVals;
5285 file.open(fileName);
5288 if (this->WhatDim() == 3)
5290 nElms = this->volus.size();
5292 else if (this->WhatDim() == 2)
5294 nElms = this->surfs.size();
5301 fillVals.reserve(nElms);
5303 while (!file.eof() && count < nElms)
5306 fillVals.push_back(ft);
5309 cout <<
"fill loaded : ";
5310 DisplayVector(fillVals);
5312 if (this->WhatDim() == 3)
5314 for (
int i = 0; i < nElms; ++i)
5316 this->volus[i].target = fillVals[i % count];
5319 else if (this->WhatDim() == 2)
5321 for (
int i = 0; i < nElms; ++i)
5323 this->surfs[i].target = fillVals[i % count];
5326 this->PrepareForUse();
5384 std::vector<int> vertOutInd;
5386 bool flagErr1, flagErr2;
5388 std::vector<bool> vertOut;
5389 std::vector<bool> edgeOut;
5390 std::vector<int> edgeBound;
5391 std::vector<bool> surfOut;
5392 std::vector<int> surfBound;
5393 std::vector<bool> voluOut;
5394 std::vector<int> voluBound;
5396 int vertSize, edgeSize, edgeSize2, surfSize, surfSize2, voluSize, voluSize2, count, countPrev;
5398 vertSize = this->verts.size();
5399 edgeSize = this->edges.size();
5400 surfSize = this->surfs.size();
5401 voluSize = this->volus.size();
5402 vertOut.assign(vertSize,
false);
5403 edgeBound.reserve(edgeSize);
5404 surfBound.reserve(surfSize);
5405 voluBound.reserve(voluSize);
5407 meshAdd.Init(0, 0, 0, 0);
5410 for (
int i = 0; i < vertSize; ++i)
5412 for (
int j = 0; j < 3; ++j)
5414 if (this->verts(i)->coord[j] > ub[j] || this->verts(i)->coord[j] < lb[j])
5421 for (
int i = 0; i < edgeSize; ++i)
5423 if (vertOut[this->verts.find(this->edges(i)->vertind[0])] ^
5424 vertOut[this->verts.find(this->edges(i)->vertind[1])])
5426 edgeBound.push_back(this->edges(i)->index);
5429 count = edgeBound.size();
5430 auto tempVec = this->edges.find_list(edgeBound);
5431 surfBound = ConcatenateVectorField(this->edges, &edge::surfind, tempVec);
5435 tempVec = this->surfs.find_list(surfBound);
5436 voluBound = ConcatenateVectorField(this->surfs, &surf::voluind, tempVec);
5439 if (voluBound.size() && voluBound[0] == 0)
5441 voluBound[0] = voluBound.back();
5442 voluBound.pop_back();
5445 meshAdd.Init(edgeBound.size(), edgeBound.size() + surfBound.size(), surfBound.size() + voluBound.size(),
5450 meshAdd.PopulateIndices();
5451 this->MakeCompatible_inplace(meshAdd);
5453 this->Concatenate(meshAdd);
5464 count = edgeBound.size();
5465 tempVec = this->edges.find_list(edgeBound);
5466 for (
int i = 0; i < count; ++i)
5469 auto tempInd = this->edges[i + edgeSize].index;
5470 this->edges[i + edgeSize] = this->edges[tempVec[i]];
5471 this->edges[i + edgeSize].index = tempInd;
5472 for (
auto temp : this->surfs.find_list(this->edges[i + edgeSize].surfind))
5474 this->surfs[temp].edgeind.push_back(tempInd);
5477 int iIn = 0, iOut = 0, subIn, subOut;
5478 iOut += !vertOut[this->verts.find(this->edges[tempVec[i]].vertind[0])];
5479 iIn += vertOut[this->verts.find(this->edges[tempVec[i]].vertind[0])];
5481 if (!(vertOut[this->verts.find(this->edges[tempVec[i]].vertind[0])] ^
5482 vertOut[this->verts.find(this->edges[tempVec[i]].vertind[1])]))
5485 " one outer vertex, this is not the case.");
5487 flagErr1 = vertOut[this->verts.find(this->edges[tempVec[i]].vertind[iIn])];
5488 flagErr2 = !vertOut[this->verts.find(this->edges[tempVec[i]].vertind[iOut])];
5489 if (flagErr1 && flagErr2)
5502 subIn = this->verts.find(this->edges[tempVec[i]].vertind[iIn]);
5503 subOut = this->verts.find(this->edges[tempVec[i]].vertind[iOut]);
5504 meshhelp::PlaceBorderVertex(this->verts[subIn].coord, this->verts[subOut].coord, lb, ub,
5505 this->verts[i + vertSize].coord);
5507 int count2 = this->verts[subOut].edgeind.size();
5508 for (
int j = 0; j < count2; ++j)
5510 if (this->verts[subOut].edgeind[j] == this->edges[tempVec[i]].index)
5512 this->verts[subOut].edgeind[j] = this->edges[i + edgeSize].index;
5516 this->edges[i + edgeSize].vertind[iIn] = this->verts[i + vertSize].index;
5517 this->edges[tempVec[i]].vertind[iOut] = this->verts[i + vertSize].index;
5518 this->verts[i + vertSize].edgeind.push_back(this->edges[tempVec[i]].index);
5519 this->verts[i + vertSize].edgeind.push_back(this->edges[i + edgeSize].index);
5520 vertOut.push_back(
false);
5521 this->ArraysAreHashed();
5523 this->verts.HashArray();
5524 this->edges.HashArray();
5525 edgeSize2 = edgeSize + count;
5526 edgeOut.assign(edgeSize2,
false);
5527 for (
int i = 0; i < edgeSize2; ++i)
5529 edgeOut[i] = vertOut[this->verts.find(this->edges(i)->vertind[0])] ||
5530 vertOut[this->verts.find(this->edges(i)->vertind[1])];
5540 count = surfBound.size();
5542 tempVec = this->surfs.find_list(surfBound);
5544 for (
int i = countPrev; i < count; ++i)
5547 auto tempInd = this->surfs[i + surfSize].index;
5548 this->surfs[i + surfSize] = this->surfs[tempVec[i]];
5549 this->surfs[i + surfSize].index = tempInd;
5551 meshhelp::SplitBorderSurfaceEdgeind(*
this, edgeOut, this->surfs[tempVec[i]].edgeind,
5552 this->surfs[i + surfSize].edgeind);
5555 this->edges[edgeSize2 + i].vertind = meshhelp::FindVertInFromEdgeOut(
5556 *
this, vertOut, this->surfs(i + surfSize)->edgeind, this->surfs(tempVec[i])->edgeind);
5558 if (this->edges[edgeSize2 + i].vertind.size() > 2)
5560 this->ArraysAreHashed();
5561 meshhelp::HandleMultiSurfaceSplit(*
this, this->surfs.elems[tempVec[i]].edgeind,
5562 this->surfs.elems[surfSize + i].edgeind,
5563 this->edges.elems[edgeSize2 + i].vertind);
5564 surfBound.push_back(this->surfs(tempVec[i])->index);
5567 this->ArraysAreHashed();
5568 this->SwitchIndex(6, this->surfs(tempVec[i])->index, this->surfs(i + surfSize)->index,
5569 this->surfs(i + surfSize)->edgeind);
5571 this->edges[edgeSize2 + i].surfind.push_back(this->surfs[i + surfSize].index);
5572 this->edges[edgeSize2 + i].surfind.push_back(this->surfs[tempVec[i]].index);
5573 this->surfs[i + surfSize].edgeind.push_back(this->edges[edgeSize2 + i].index);
5574 this->surfs[tempVec[i]].edgeind.push_back(this->edges[edgeSize2 + i].index);
5576 int count2 = this->edges[edgeSize2 + i].vertind.size();
5577 for (
int j = 0; j < count2; ++j)
5579 this->verts.elems[this->verts.find(this->edges[edgeSize2 + i].vertind[j])].edgeind.push_back(
5580 this->edges[edgeSize2 + i].index);
5582 edgeOut.push_back(
false);
5583 this->ArraysAreHashed();
5588 count = surfBound.size();
5589 if (count != countPrev)
5591 meshAdd.Init(0, count - countPrev, count - countPrev, 0);
5592 meshAdd.PopulateIndices();
5593 this->SetMaxIndex();
5594 meshAdd.SetMaxIndex();
5595 this->MakeCompatible_inplace(meshAdd);
5596 this->Concatenate(meshAdd);
5599 }
while (count != countPrev);
5600 this->verts.HashArray();
5601 this->edges.HashArray();
5602 this->surfs.HashArray();
5603 surfSize2 = surfSize + count;
5604 surfOut.assign(surfSize2,
false);
5605 for (
int i = 0; i < surfSize2; ++i)
5607 int count2 = this->surfs(i)->edgeind.size();
5608 for (
int j = 0; j < count2; ++j)
5610 surfOut[i] = surfOut[i] || edgeOut[this->edges.find(this->surfs(i)->edgeind[j])];
5617 count = voluBound.size();
5619 tempVec = this->volus.find_list(voluBound);
5620 for (
int i = 0; i < count; ++i)
5623 auto tempInd = this->volus[i + voluSize].index;
5624 this->volus[i + voluSize] = this->volus[tempVec[i]];
5625 this->volus[i + voluSize].index = tempInd;
5628 meshhelp::SplitBorderVolumeSurfind(*
this, surfOut, this->volus[tempVec[i]].surfind,
5629 this->volus[i + voluSize].surfind);
5631 this->ArraysAreHashed();
5632 this->SwitchIndex(7, this->volus(tempVec[i])->index, this->volus(i + voluSize)->index,
5633 this->volus(i + voluSize)->surfind);
5636 this->surfs[surfSize2 + i].edgeind =
5637 meshhelp::FindEdgeInFromSurfOut(*
this, edgeOut, this->volus(i + voluSize)->surfind);
5639 this->surfs[surfSize2 + i].voluind[0] = this->volus[i + voluSize].index;
5640 this->surfs[surfSize2 + i].voluind[1] = this->volus[tempVec[i]].index;
5641 this->volus[tempVec[i]].surfind.push_back(this->surfs[surfSize2 + i].index);
5642 this->volus[i + voluSize].surfind.push_back(this->surfs[surfSize2 + i].index);
5644 int count2 = this->surfs(surfSize2 + i)->edgeind.size();
5645 this->ArraysAreHashed();
5646 for (
int j = 0; j < count2; ++j)
5648 this->edges.elems[this->edges.find(this->surfs[surfSize2 + i].edgeind[j])].surfind.push_back(
5649 this->surfs[surfSize2 + i].index);
5651 surfOut.push_back(
false);
5652 this->ArraysAreHashed();
5655 voluSize2 = voluSize + count;
5656 voluOut.assign(voluSize2,
false);
5657 for (
int i = 0; i < voluSize2; ++i)
5659 for (
auto temp : this->volus(i)->surfind)
5661 voluOut[i] = voluOut[i] || surfOut[this->surfs.find(temp)];
5665 this->TightenConnectivity();
5666 this->TestConnectivityBiDir(__PRETTY_FUNCTION__);
5667 this->PrepareForUse();
5668 vertOutInd.reserve(this->verts.size());
5669 count = this->verts.size();
5670 for (
int i = 0; i < count; ++i)
5674 vertOutInd.push_back(this->verts(i)->index);
5678 return (vertOutInd);
5681 void mesh::Crop(vector<int> indList,
int indType)
5705 if (indType > 4 || indType < 1)
5708 " vertex (indType=1), edge (2), surf (3), volu (4)");
5711 std::vector<int> vertDel, edgeDel, surfDel, voluDel;
5718 else if (indType == i++)
5722 else if (indType == i++)
5726 else if (indType == i++)
5734 auto vertSub = this->verts.find_list(vertDel);
5735 edgeDel = ConcatenateVectorField(this->verts, &vert::edgeind, vertSub);
5736 [[gnu::fallthrough]];
5739 auto edgeSub = this->edges.find_list(edgeDel);
5740 surfDel = ConcatenateVectorField(this->edges, &edge::surfind, edgeSub);
5741 [[gnu::fallthrough]];
5744 auto surfSub = this->surfs.find_list(surfDel);
5745 voluDel = ConcatenateVectorField(this->surfs, &surf::voluind, surfSub);
5753 int count = voluDel.size();
5756 if (voluDel[0] == 0)
5758 voluDel.erase(voluDel.begin());
5761 for (
int i = 0; i < count; ++i)
5763 this->RemoveIndex(4, voluDel[i]);
5767 count = this->surfs.size();
5768 for (
int i = 0; i < count; ++i)
5770 if (this->surfs(i)->voluind.size() == 0)
5772 surfDel.push_back(this->surfs(i)->index);
5774 else if (this->surfs(i)->voluind.size() == 1)
5776 this->surfs[i].voluind.push_back(0);
5779 this->ArraysAreHashed();
5782 count = surfDel.size();
5783 for (
int i = 0; i < count; ++i)
5785 this->RemoveIndex(3, surfDel[i]);
5788 count = this->edges.size();
5789 for (
int i = 0; i < count; ++i)
5791 if (this->edges(i)->surfind.size() == 0)
5793 edgeDel.push_back(this->edges(i)->index);
5798 count = edgeDel.size();
5799 for (
int i = 0; i < count; ++i)
5801 this->RemoveIndex(2, edgeDel[i]);
5804 count = this->verts.size();
5805 for (
int i = 0; i < count; ++i)
5807 if (this->verts(i)->edgeind.size() == 0)
5809 vertDel.push_back(this->verts(i)->index);
5814 count = vertDel.size();
5815 for (
int i = 0; i < count; ++i)
5817 this->RemoveIndex(1, vertDel[i]);
5820 this->verts.remove(vertDel);
5821 this->edges.remove(edgeDel);
5822 this->surfs.remove(surfDel);
5823 this->volus.remove(voluDel);
5825 this->PrepareForUse();
5826 this->RemoveSingularConnectors();
5827 this->PrepareForUse();
5830 void mesh::CropAtBoundary(
const vector<double> &lb,
const vector<double> &ub)
5838 auto vecDel = this->AddBoundary(lb, ub);
5839 this->Crop(vecDel, 1);
5842 int mesh::EdgeFromVerts(
int v1,
int v2)
const
5844 int vExp = this->verts.isearch(v1)->edgeind.size() < this->verts.isearch(v2)->edgeind.size() ? v1 : v2;
5845 auto &el = this->verts.isearch(vExp)->edgeind;
5847 int retEdge = rsvs3d::constants::__notfound;
5851 auto &vinds = this->edges.isearch(e)->vertind;
5852 if ((vinds[0] == v1 && vinds[1] == v2) || (vinds[1] == v1 && vinds[0] == v2))
5874 bool e1Smaller = this->edges.isearch(e1)->surfind.size() < this->edges.isearch(e2)->surfind.size();
5875 int eExp = e1Smaller ? e1 : e2;
5876 int eNoExp = !e1Smaller ? e1 : e2;
5877 auto &sl = this->edges.isearch(eExp)->surfind;
5879 int retSurf = rsvs3d::constants::__notfound;
5880 bool prevFind =
false;
5883 auto &einds = this->surfs.isearch(s)->edgeind;
5884 for (
auto e : einds)
5890 if (repetitionBehaviour == 1)
5892 return rsvs3d::constants::__notfound;
5896 stringstream errstr;
5897 errstr <<
"Two or more surfaces connect edges e1 (" << e1 <<
") and e2 (" << e2 <<
")";
5903 if (repetitionBehaviour == 0)
5928 auto &edgeVerts = this->edges.isearch(e)->vertind;
5930 return edgeVerts[int(edgeVerts[0] == v)];
5932 void mesh::VerticesVector(
int v1,
int v2,
coordvec &vec)
const
5934 vec = this->verts.isearch(v2)->coord;
5935 vec.substract(this->verts.isearch(v1)->coord);
5937 void mesh::EdgeVector(
int edgeIndex,
coordvec &vec)
const
5939 auto e = this->edges.isearch(edgeIndex);
5940 int smallV = int(e->vertind[0] > e->vertind[1]);
5941 this->VerticesVector(e->vertind[smallV], e->vertind[abs(smallV - 1)], vec);
5944 int mesh::OrderVertexEdges(
int vertIndex)
5946 return this->verts.elems[this->verts.find(vertIndex)].OrderEdges(
this);
5949 void mesh::ReOrder()
5952 auto compareVerts = [&](
const vert &i1,
const vert &i2) ->
bool {
return (this->CompareVerts(i1, i2)); };
5953 auto compareEdges = [&](
const edge &i1,
const edge &i2) ->
bool {
return (this->CompareEdges(i1, i2)); };
5954 auto compareSurfs = [&](
const surf &i1,
const surf &i2) ->
bool {
return (this->CompareSurfs(i1, i2)); };
5955 auto compareVolus = [&](
const volu &i1,
const volu &i2) ->
bool {
return (this->CompareVolus(i1, i2)); };
5958 sort(this->verts.elems.begin(), this->verts.elems.end(), compareVerts);
5959 this->verts.HashArray();
5960 sort(this->edges.elems.begin(), this->edges.elems.end(), compareEdges);
5961 this->edges.HashArray();
5962 sort(this->surfs.elems.begin(), this->surfs.elems.end(), compareSurfs);
5963 this->surfs.HashArray();
5964 sort(this->volus.elems.begin(), this->volus.elems.end(), compareVolus);
5965 this->volus.HashArray();
5972 int nVerts = this->verts.size();
5973 for (
int i = 0; i < nVerts; ++i)
5975 for (
auto &ei : this->verts[i].edgeind)
5977 ei = this->edges.find(ei,
true) + 1;
5982 int nEdges = this->edges.size();
5983 for (
int i = 0; i < nEdges; ++i)
5985 for (
auto &ei : this->edges[i].surfind)
5987 ei = this->surfs.find(ei,
true) + 1;
5989 for (
auto &ei : this->edges[i].vertind)
5991 ei = this->verts.find(ei,
true) + 1;
5996 int nSurfs = this->surfs.size();
5997 for (
int i = 0; i < nSurfs; ++i)
5999 for (
auto &ei : this->surfs[i].voluind)
6001 ei = this->volus.find(ei,
true) + 1;
6003 for (
auto &ei : this->surfs[i].edgeind)
6005 ei = this->edges.find(ei,
true) + 1;
6010 int nVolus = this->volus.size();
6011 for (
int i = 0; i < nVolus; ++i)
6013 this->volus[i].index = i + 1;
6014 for (
auto &ei : this->volus[i].surfind)
6016 ei = this->surfs.find(ei,
true) + 1;
6021 nVerts = this->verts.size();
6022 for (
int i = 0; i < nVerts; ++i)
6024 this->verts[i].index = i + 1;
6027 nEdges = this->edges.size();
6028 for (
int i = 0; i < nEdges; ++i)
6030 this->edges[i].index = i + 1;
6033 nSurfs = this->surfs.size();
6034 for (
int i = 0; i < nSurfs; ++i)
6036 this->surfs[i].index = i + 1;
6039 nVolus = this->volus.size();
6040 for (
int i = 0; i < nVolus; ++i)
6042 this->volus[i].index = i + 1;
6046 this->PrepareForUse();
6048 this->TestConnectivityBiDir();
6052 std::pair<int, int> OrderMatchLists(
const vector<int> &vec1,
int p1,
int p2)
6056 int n = vec1.size();
6057 for (
int ii = 0; ii < n; ++ii)
6064 else if (vec1[ii] == p2)
6081 int OrderMatchLists_old(
const vector<int> &vec1,
const vector<int> &vec2,
int p1,
int p2)
6086 int ii, n, ord1, ord2, retVal, kk;
6091 for (ii = 0; ii < n; ++ii)
6098 else if (vec1[ii] == p2)
6115 DisplayVector(vec1);
6116 DisplayVector(vec2);
6117 cerr << endl <<
"p " << p1 <<
"," << p2 << endl;
6118 cerr <<
"Error : indices were not found in lists " << endl;
6119 cerr <<
" p1 and/or p2 did not appear in vec " << endl;
6120 cerr <<
" in " << __PRETTY_FUNCTION__ << endl;
6127 for (ii = 0; ii < n; ++ii)
6134 else if (vec2[ii] == p2)
6151 DisplayVector(vec1);
6152 DisplayVector(vec2);
6153 cerr << endl <<
"p " << p1 <<
"," << p2 << endl;
6154 cerr <<
"Error : indices were not found in lists " << endl;
6155 cerr <<
" p1 and/or p2 did not appear in vec " << endl;
6156 cerr <<
" in " << __PRETTY_FUNCTION__ << endl;
6160 retVal = (ord1 == ord2) * 2 - 1;
6165 int OrderMatchLists(
const vector<int> &vec1,
const vector<int> &vec2,
int p1,
int p2)
6170 int ord1, ord2, retVal, kk;
6172 auto pair1 = OrderMatchLists(vec1, p1, p2);
6178 DisplayVector(vec1);
6179 DisplayVector(vec2);
6180 cerr << endl <<
"p " << p1 <<
"," << p2 << endl;
6181 cerr <<
"Error : indices were not found in lists " << endl;
6182 cerr <<
" p1 and/or p2 did not appear in vec " << endl;
6183 cerr <<
" in " << __PRETTY_FUNCTION__ << endl;
6187 auto pair2 = OrderMatchLists(vec2, p1, p2);
6193 DisplayVector(vec1);
6194 DisplayVector(vec2);
6195 cerr << endl <<
"p " << p1 <<
"," << p2 << endl;
6196 cerr <<
"Error : indices were not found in lists " << endl;
6197 cerr <<
" p1 and/or p2 did not appear in vec " << endl;
6198 cerr <<
" in " << __PRETTY_FUNCTION__ << endl;
6202 retVal = (ord1 == ord2) * 2 - 1;
6204 int retValOld = OrderMatchLists_old(vec1, vec2, p1, p2);
6205 if (retVal != retValOld)
6208 DisplayVector(vec1);
6209 DisplayVector(vec2);
6210 cerr << endl <<
"p " << p1 <<
"," << p2 << endl;
6211 cerr << endl <<
"retVal (new,old): " << retVal <<
"," << retValOld << endl;
6218 void ConnVertFromConnEdge(
const mesh &meshin,
const vector<int> &edgeind, vector<int> &vertind)
6224 nEdge = int(edgeind.size());
6225 if (vertind.size() > 0)
6229 vertind.reserve(nEdge);
6232 flag = (meshin.edges.isearch(edgeind[kk])->vertind[ll] == meshin.edges.isearch(edgeind[kk + 1])->vertind[0]) |
6233 (meshin.edges.isearch(edgeind[kk])->vertind[ll] == meshin.edges.isearch(edgeind[kk + 1])->vertind[1]);
6236 ll = ((ll + 1) % 2);
6238 for (kk = 0; kk < nEdge; ++kk)
6240 vertind.push_back(meshin.edges.isearch(edgeind[kk])->vertind[ll]);
6242 if (kk < (nEdge - 1))
6245 (meshin.edges.isearch(edgeind[kk])->vertind[0] == meshin.edges.isearch(edgeind[kk + 1])->vertind[ll]) |
6246 (meshin.edges.isearch(edgeind[kk])->vertind[1] == meshin.edges.isearch(edgeind[kk + 1])->vertind[ll]);
6247 ll = ((ll + 1) % 2) * (flag) + ll * (!flag);
6267 std::vector<int> vertDel;
6270 nVerts = meshin.verts.size();
6271 for (
int i = 0; i < nVerts; ++i)
6273 for (
int j = 0; j < 3; ++j)
6275 if (meshin.verts(i)->coord[j] > ub[j] || meshin.verts(i)->coord[j] < lb[j])
6277 vertDel.push_back(meshin.verts(i)->index);
6282 meshin.Crop(vertDel, 1);
6297 if ((vecPts.size() % nProp) != 0)
6299 std::cerr <<
"Error in: " << __PRETTY_FUNCTION__ << std::endl;
6302 int nPts = vecPts.size() / nProp;
6303 meshpts.Init(nPts, 0, 0, 0);
6304 meshpts.PopulateIndices();
6305 for (
int i = 0; i < nPts; ++i)
6307 for (
int j = 0; j < 3; ++j)
6309 meshpts.verts[i].coord[j] = vecPts[i * nProp + j];
6312 meshpts.verts.PrepareForUse();
6321 void PlaceBorderVertex(
const std::vector<double> &coordIn,
const std::vector<double> &coordOut,
6322 const std::vector<double> &lb,
const std::vector<double> &ub, std::vector<double> &coordTarg)
6324 for (
int i = 0; i < 3; ++i)
6326 coordTarg[i] = coordIn[i] - coordOut[i];
6329 double lStep = meshhelp::ProjectRay(3, vector<vector<double>>({lb, ub}), coordTarg, coordIn, 0.0);
6332 if (lStep > +0.0 || lStep < -1.001)
6334 cout <<
"Error in: " << __PRETTY_FUNCTION__ << endl <<
" coordIn : ";
6335 DisplayVector(coordIn);
6336 cout <<
" coordOut : ";
6337 DisplayVector(coordOut);
6338 cout <<
" coordTarg : ";
6339 DisplayVector(coordTarg);
6340 cout << endl <<
"lStep : " << lStep << endl;
6342 " and 1 for it to lie on the original edge.");
6346 for (
int i = 0; i < 3; ++i)
6348 coordTarg[i] = coordTarg[i] * lStep + coordIn[i];
6352 void SplitBorderSurfaceEdgeind(
const mesh &meshin,
const std::vector<bool> &edgeOut, std::vector<int> &vecconnIn,
6353 std::vector<int> &vecconnOut)
6363 int count = vecconnIn.size();
6364 auto temp = meshin.edges.find_list(vecconnIn,
true);
6366 for (
int i = 0; i < count; ++i)
6370 std::cerr <<
"Error in : " << __PRETTY_FUNCTION__ << std::endl;
6374 if (edgeOut[temp[i]])
6376 vecconnOut.push_back(meshin.edges(temp[i])->index);
6380 vecconnIn.push_back(meshin.edges(temp[i])->index);
6396 void HandleMultiSurfaceSplit(
mesh &meshin, vector<int> &edgeindOld, vector<int> &edgeindNew, vector<int> &vertindNew)
6400 auto edgeOrig = edgeindNew;
6401 int outFlag =
OrderEdgeList(edgeindNew, meshin,
false,
false, &edgeOrig);
6403 if (outFlag != rsvsorder::truncated)
6405 edgeindNew.erase(edgeindNew.begin() - outFlag, edgeindNew.end());
6407 for (
auto edgeIndAll : edgeOrig)
6410 for (
auto edgeindOut : edgeindNew)
6412 if (edgeIndAll == edgeindOut)
6420 edgeindOld.push_back(edgeIndAll);
6426 "negative to indicate an open surface");
6428 std::array<int, 2> inds;
6430 int nVertExtra = vertindNew.size();
6431 for (
auto edgei : edgeindNew)
6433 int temp = meshin.edges.find(edgei);
6434 for (
int j = 0; j < 2; ++j)
6436 for (
int l = 0; l < nVertExtra; ++l)
6438 if (vertindNew[l] == meshin.edges(temp)->vertind[j])
6454 vertindNew = {vertindNew[inds[0]], vertindNew[inds[1]]};
6457 void SplitBorderVolumeSurfind(
const mesh &meshin,
const std::vector<bool> &edgeOut, std::vector<int> &vecconnIn,
6458 std::vector<int> &vecconnOut)
6468 int count = vecconnIn.size();
6469 auto temp = meshin.surfs.find_list(vecconnIn,
true);
6471 for (
int i = 0; i < count; ++i)
6475 std::cerr <<
"Error in : " << __PRETTY_FUNCTION__ << std::endl;
6479 if (edgeOut[temp[i]])
6481 vecconnOut.push_back(meshin.surfs(temp[i])->index);
6485 vecconnIn.push_back(meshin.surfs(temp[i])->index);
6490 std::vector<int> FindVertInFromEdgeOut(
const mesh &meshin,
const std::vector<bool> &vertOut,
6491 const std::vector<int> &edgeList,
const std::vector<int> &edgeListCheck)
6500 std::vector<int> vertList;
6501 int count = edgeList.size();
6502 for (
int i = 0; i < count; ++i)
6504 for (
int j = 0; j < 2; ++j)
6506 int temp = meshin.edges.isearch(edgeList[i])->vertind[j];
6507 if (!vertOut[meshin.verts.find(temp)])
6509 vertList.push_back(temp);
6515 if (vertList.size() != 2)
6518 std::vector<int> vertListTemp = {};
6519 vertList.swap(vertListTemp);
6521 for (
auto k : edgeListCheck)
6523 for (
auto i : meshin.edges.isearch(k)->vertind)
6525 for (
int j : vertListTemp)
6529 vertList.push_back(i);
6541 std::vector<int> FindEdgeInFromSurfOut(
const mesh &meshin,
const std::vector<bool> &edgeOut, std::vector<int> surfList)
6549 std::vector<int> edgeList;
6550 int count = surfList.size();
6551 for (
int i = 0; i < count; ++i)
6553 for (
auto temp : meshin.surfs.isearch(surfList[i])->edgeind)
6555 if (!edgeOut[meshin.edges.find(temp)])
6557 edgeList.push_back(temp);
6576 int Get3PointsInSurface(
const mesh &meshin,
int surfCurr, std::array<int, 3> &surfacePoints)
6578 int surfacePointsIdentified = 0;
6579 for (
auto edgeCurr : meshin.surfs.isearch(surfCurr)->edgeind)
6581 if (meshin.edges.isearch(edgeCurr)->IsLength0(meshin))
6585 if (surfacePointsIdentified == 0)
6587 surfacePoints[0] = meshin.edges.isearch(edgeCurr)->vertind[0];
6588 surfacePoints[1] = meshin.edges.isearch(edgeCurr)->vertind[1];
6589 surfacePointsIdentified = 2;
6593 for (
auto vertCurr : meshin.edges.isearch(edgeCurr)->vertind)
6595 if (vertCurr != surfacePoints[0] && vertCurr != surfacePoints[1] &&
6596 !(meshhelp::IsVerticesDistance0(meshin, {vertCurr, surfacePoints[0]})) &&
6597 !(meshhelp::IsVerticesDistance0(meshin, {vertCurr, surfacePoints[1]})))
6599 surfacePoints[2] = vertCurr;
6600 surfacePointsIdentified++;
6605 if (surfacePointsIdentified == 3)
6610 return surfacePointsIdentified;
6613 int VertexInVolume(
const mesh &meshin,
const vector<double> testCoord,
bool needFlip)
6625 if (meshin.volus.size() == 0)
6630 std::array<int, 3> surfacePoints = {0, 0, 0};
6631 bool isInCandidate =
false, candidateIsValid;
6632 int volumeCandidate = 0;
6633 int pointInVolu, alternateVolume, nVolusExplored = 0, nVolus;
6634 double distToPlane, multiplierDist;
6635 multiplierDist = needFlip ? -1.0 : 1.0;
6636 nVolus = meshin.volus.size();
6637 volumeCandidate = meshin.volus(0)->index;
6641 isInCandidate =
true;
6642 candidateIsValid =
false;
6644 for (
auto surfCurr : meshin.volus.isearch(volumeCandidate)->surfind)
6648 if (!meshin.surfs.isearch(surfCurr)->isready(
true))
6651 "ordered. Run meshin.OrderEdges() before calling");
6653 if (meshin.surfs.isearch(surfCurr)->edgeind.size() < 3)
6656 strErr =
"Surface " + to_string(surfCurr) +
" has less than 3 edges.";
6663 int surfacePointsIdentified = Get3PointsInSurface(meshin, surfCurr, surfacePoints);
6664 if (surfacePointsIdentified != 3)
6669 int jj = meshin.surfs.isearch(surfCurr)->voluind[0] == volumeCandidate;
6670 alternateVolume = meshin.surfs.isearch(surfCurr)->voluind[jj];
6674 candidateIsValid =
true;
6676 meshin.verts.isearch(surfacePoints[1])->coord,
6677 meshin.verts.isearch(surfacePoints[2])->coord, testCoord, temp1, temp2);
6678 if (fabs(distToPlane) < __DBL_EPSILON__)
6682 pointInVolu = meshin.surfs.isearch(surfCurr)->voluind[int((distToPlane * multiplierDist) > 0)];
6683 if (pointInVolu == 0)
6685 volumeCandidate = pointInVolu;
6688 else if (pointInVolu != volumeCandidate)
6690 isInCandidate =
false;
6691 volumeCandidate = pointInVolu;
6695 if (!candidateIsValid && isInCandidate)
6697 isInCandidate =
false;
6698 volumeCandidate = alternateVolume;
6701 }
while (!isInCandidate && nVolusExplored < nVolus);
6707 #ifdef RSVS_DIAGNOSTIC_RESOLVED
6708 cout << nVolusExplored <<
" ";
6710 return volumeCandidate;
6713 double VerticesDistanceSquared(
const mesh &meshin,
const vector<int> &vertind)
6715 double lengthSquared = 0.0;
6717 for (
int i = 0; i < meshin.WhatDim(); ++i)
6720 pow(meshin.verts.isearch(vertind[0])->coord[i] - meshin.verts.isearch(vertind[1])->coord[i], 2.0);
6723 return lengthSquared;
6725 double VerticesDistance(
const mesh &meshin,
const vector<int> &vertind)
6727 return sqrt(VerticesDistanceSquared(meshin, vertind));
6729 bool IsVerticesDistance0(
const mesh &meshin,
const vector<int> &vertind,
double eps)
6731 return VerticesDistanceSquared(meshin, vertind) < pow(eps, 2.0);
Handles the use and norm of a vector for which the norm and the unit value might be needed.
Class for an edge object in a mesh.
double Length(const mesh &meshin) const
Calculate the edge length.
double LengthSquared(const mesh &meshin) const
Calculate squared edge length.
bool IsLength0(const mesh &meshin, double eps=__DBL_EPSILON__) const
Returns.
void GeometricProperties(const mesh *meshin, coordvec ¢re, double &length) const
Math operations in mesh.
std::vector< int > AddBoundary(const std::vector< double > &lb, const std::vector< double > &ub)
Adds boundaries alond max and min xyz planes.
void LinearTransform(const grid::transformation &transform)
Applies a linear transformation to the points on a grid.
void LinearTransformFamily(const grid::transformation &transform)
Applies a linear transform to child and parent meshes.
void _LinearTransformGeneration(const grid::transformation &transform, std::vector< mesh * > meshdependence::*mp)
Applies reccursively linear transforms to a tree of meshes.
std::vector< int > VertexInVolume(const std::vector< double > testVertices, int sizeVert=3) const
Finds for each vertex, the volume object containing it.
int VertFromVertEdge(int v, int e) const
Returns the vertex in edges.isearch(e)->vertind which does not match v.
int ConnectedVertex(std::vector< int > &vertBlock) const
Return in a vector for each vertex a block number which it is part of.
int SurfFromEdges(int e1, int e2, int repetitionBehaviour=-1) const
Returns the index of the surface connecting two edges.
void OrientFaces()
Orients either surfaces or edges depending on the dimensionality of the object.
Class for connecting meshes.
std::vector< mesh * > parentmesh
Vector of pointers to the mesh which are coarser (parents).
std::vector< mesh * > childmesh
Vector of pointers to the mesh which are finer (children).
Class for surface object in a mesh.
coordvec PseudoCentroid(const mesh &meshin) const
Calculates the length weighted pseudo-centroid of a surface.
Class for a vertex in a mesh.
Class for volume cell objects in a mesh.
std::vector< int > vertind(const mesh &meshin) const
Get all the vertices a volume is connected to.
coordvec PseudoCentroid(const mesh &meshin) const
Calculates the length weighted pseudo-centroid of a volume.
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.
std::tuple< coordvec, double > VertexNormal(const std::vector< double > ¢re, const grid::coordlist &vecPts)
Calculates the vertex normal weighted by surface angle partitions.
mesh Points2Mesh(const std::vector< double > &vecPts, int nProp=3)
Takes in a set of points and returns a mesh of points ready for voronisation.
double PlaneNormalAndAngle(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &normal, coordvec &temp1)
Calculates a plane's normal vector.
void PlaneNormal(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &normal, coordvec &temp1)
Calculates a plane's normal vector.
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.
void DiffPoints(const std::vector< double > &vert1, const std::vector< double > &vert2, coordvec &diffVerts)
Computes vector between vertices to then compute angles and plane normals.
std::array< std::array< double, 3 >, 3 > transformation
Defines a linear transformation to the mesh where for each dimension: {new minimum,...
std::vector< double > VerticesDistanceToPlane(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, const std::vector< double > &testVertices, coordvec &temp1, coordvec &temp2)
Calculates the distance from a set of vertices to a plane.
int OrderEdgeList(std::vector< int > &edgeind, const mesh &meshin, bool warn=true, bool errout=true, const std::vector< int > *edgeIndOrigPtr=NULL, const surf *surfin=NULL)
Orders a list of edge to be connected.
int OrderList(std::vector< int > &edgeind, const std::vector< int > &edge2Vert, bool warn=true, bool errout=true, const std::vector< int > *edgeIndOrigPtr=NULL)
Orders a list of elements defined by pairs of indices.
void CropMeshGreedy(mesh &meshin, const std::vector< double > &lb, const std::vector< double > &ub)
Crops a mesh to only the elements inside the cropBox.
void DiffPointsFromCentre(const std::vector< double > ¢re, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &normal, coordvec &temp1)
Computes vector between vertices to then compute angles and plane normals.
double VertexDistanceToPlane(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, const std::vector< double > &testVertex, coordvec &temp1, coordvec &temp2)
Calculates the distance from a vertex to a plane.
int NormalShouldFlip(const std::vector< int > orderedList, int elm1, int elm2, const std::vector< int > &voluind, bool innerComparison)
Answers if a normal should be flipped to point towards the outside of a volume.
int sign(T val)
Returns the sign of a type comparable to 0.
void error(const char *message="", const char *caller="", const char *file="", int line=0, bool throwError=true)
Custom error function.
Provides various utility functions for the RSVS operation.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_LOGIC(M)
Throw a logic_error.
#define RSVS3D_ERROR_NOTHROW(M)
Generic rsvs warning.
void CheckFStream(const T &file, const char *callerID, const std::string &fileName)
Checks a file stream.
#define RSVS3D_ERROR(M)
Throw generic rsvs errors.
#define RSVS3D_ERROR_RANGE(M)
Throw a range_error.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.