59 x.setSize(sz+
y.size());
71 bool Foam::snappySnapDriver::isFeaturePoint
73 const scalar featureCos,
75 const bitSet& isFeatureEdge,
81 const labelList& pEdges = pp.pointEdges()[pointi];
87 if (isFeatureEdge[pEdges[i]])
91 for (
label j = i+1; j < pEdges.size(); j++)
93 if (isFeatureEdge[pEdges[j]])
95 const edge& ei = edges[pEdges[i]];
96 const edge& ej = edges[pEdges[j]];
103 scalar viMag =
mag(vi);
106 scalar vjMag =
mag(vj);
112 && ((vi/viMag & vj/vjMag) < featureCos)
132 void Foam::snappySnapDriver::smoothAndConstrain
134 const bitSet& isPatchMasterEdge,
137 const List<pointConstraint>& constraints,
141 const fvMesh&
mesh = meshRefiner_.mesh();
143 for (
label avgIter = 0; avgIter < 20; avgIter++)
164 forAll(pointEdges, pointi)
166 const labelList& pEdges = pointEdges[pointi];
168 label nConstraints = constraints[pointi].first();
170 if (nConstraints <= 1)
174 label edgei = pEdges[i];
176 if (isPatchMasterEdge[edgei])
178 label nbrPointi = edges[edgei].otherVertex(pointi);
179 if (constraints[nbrPointi].first() >= nConstraints)
181 dispSum[pointi] += disp[nbrPointi];
209 forAll(constraints, pointi)
211 if (dispCount[pointi] > 0)
216 *(disp[pointi] + dispSum[pointi]/dispCount[pointi]);
223 void Foam::snappySnapDriver::calcNearestFace
234 const fvMesh&
mesh = meshRefiner_.mesh();
235 const refinementSurfaces& surfaces = meshRefiner_.surfaces();
238 faceDisp.setSize(pp.size());
240 faceSurfaceNormal.setSize(pp.size());
241 faceSurfaceNormal =
Zero;
242 faceSurfaceGlobalRegion.setSize(pp.size());
243 faceSurfaceGlobalRegion = -1;
260 const PtrList<surfaceZonesInfo>& surfZones = surfaces.surfZones();
264 label zoneSurfi = zonedSurfaces[i];
266 const word& faceZoneName = surfZones[zoneSurfi].faceZoneName();
273 <<
"Problem. Cannot find zone " << faceZoneName
277 const bitSet isZonedFace(
mesh.
nFaces(), fZone);
279 DynamicList<label> ppFaces(fZone.size());
280 DynamicList<label> meshFaces(fZone.size());
281 forAll(pp.addressing(), i)
283 if (isZonedFace[pp.addressing()[i]])
285 snapSurf[i] = zoneSurfi;
287 meshFaces.append(pp.addressing()[i]);
299 IndirectList<face>(
mesh.
faces(), meshFaces),
304 List<pointIndexHit> hitInfo;
308 surfaces.findNearestRegion
321 if (hitInfo[hiti].hit())
323 label facei = ppFaces[hiti];
324 faceDisp[facei] = hitInfo[hiti].hitPoint() - fc[hiti];
325 faceSurfaceNormal[facei] = hitNormal[hiti];
326 faceSurfaceGlobalRegion[facei] = surfaces.globalRegion
334 static label nWarn = 0;
339 <<
"Did not find surface near face centre " << fc[hiti]
345 <<
"Reached warning limit " << nWarn
346 <<
". Suppressing further warnings." <<
endl;
358 DynamicList<label> ppFaces(pp.size());
359 DynamicList<label> meshFaces(pp.size());
360 forAll(pp.addressing(), i)
362 if (snapSurf[i] == -1)
365 meshFaces.append(pp.addressing()[i]);
375 IndirectList<face>(
mesh.
faces(), meshFaces),
380 List<pointIndexHit> hitInfo;
384 surfaces.findNearestRegion
397 if (hitInfo[hiti].hit())
399 label facei = ppFaces[hiti];
400 faceDisp[facei] = hitInfo[hiti].hitPoint() - fc[hiti];
401 faceSurfaceNormal[facei] = hitNormal[hiti];
402 faceSurfaceGlobalRegion[facei] = surfaces.globalRegion
410 static label nWarn = 0;
415 <<
"Did not find surface near face centre " << fc[hiti]
422 <<
"Reached warning limit " << nWarn
423 <<
". Suppressing further warnings." <<
endl;
470 void Foam::snappySnapDriver::calcNearestFacePointProperties
477 const labelList& faceSurfaceGlobalRegion,
479 List<List<point>>& pointFaceSurfNormals,
480 List<List<point>>& pointFaceDisp,
481 List<List<point>>& pointFaceCentres,
482 List<labelList>& pointFacePatchID
485 const fvMesh&
mesh = meshRefiner_.mesh();
494 pointFaceSurfNormals.setSize(pp.nPoints());
495 pointFaceDisp.setSize(pp.nPoints());
496 pointFaceCentres.setSize(pp.nPoints());
497 pointFacePatchID.setSize(pp.nPoints());
500 forAll(pp.pointFaces(), pointi)
509 if (isMasterFace[facei] && faceSurfaceGlobalRegion[facei] != -1)
516 List<point>& pNormals = pointFaceSurfNormals[pointi];
517 pNormals.setSize(nFaces);
518 List<point>& pDisp = pointFaceDisp[pointi];
519 pDisp.setSize(nFaces);
520 List<point>& pFc = pointFaceCentres[pointi];
522 labelList& pFid = pointFacePatchID[pointi];
529 label globalRegioni = faceSurfaceGlobalRegion[facei];
531 if (isMasterFace[facei] && globalRegioni != -1)
533 pNormals[nFaces] = faceSurfaceNormal[facei];
534 pDisp[nFaces] = faceDisp[facei];
535 pFc[nFaces] = pp.faceCentres()[facei];
536 pFid[nFaces] = globalToMasterPatch_[globalRegioni];
557 const polyPatch& pp = pbm[patchi];
559 if (pp.coupled() || isA<emptyPolyPatch>(pp))
563 label meshFacei = pp.start()+i;
570 forAll(pp.addressing(), i)
572 label meshFacei = pp.addressing()[i];
589 bitSet isBoundaryPoint(pp.nPoints());
596 const edge&
e = edges[edgei];
597 const labelList& eFaces = edgeFaces[edgei];
599 if (eFaces.size() == 1)
602 isBoundaryPoint.
set(
e[0]);
603 isBoundaryPoint.set(
e[1]);
605 else if (eFaces.size() == 2 && bafflePair[eFaces[0]] == eFaces[1])
608 isBoundaryPoint.set(
e[0]);
609 isBoundaryPoint.set(
e[1]);
616 forAll(pp.meshPoints(), pointi)
618 meshToPatchPoint[pp.meshPoints()[pointi]] = pointi;
632 label pointi = meshToPatchPoint[
f[fp]];
634 if (pointi != -1 && isBoundaryPoint.test(pointi))
636 List<point>& pNormals = pointFaceSurfNormals[pointi];
637 List<point>& pDisp = pointFaceDisp[pointi];
638 List<point>& pFc = pointFaceCentres[pointi];
639 labelList& pFid = pointFacePatchID[pointi];
644 pNormals.append(fn/
mag(fn));
658 pointFaceSurfNormals,
659 listPlusEqOp<point>(),
668 listPlusEqOp<point>(),
677 listPlusEqOp<point>(),
679 mapDistribute::transformPosition()
686 listPlusEqOp<label>(),
694 forAll(pointFaceDisp, pointi)
696 List<point>& pNormals = pointFaceSurfNormals[pointi];
697 List<point>& pDisp = pointFaceDisp[pointi];
698 List<point>& pFc = pointFaceCentres[pointi];
699 labelList& pFid = pointFacePatchID[pointi];
703 pNormals = List<point>(pNormals, visitOrder);
704 pDisp = List<point>(pDisp, visitOrder);
705 pFc = List<point>(pFc, visitOrder);
714 void Foam::snappySnapDriver::correctAttraction
716 const DynamicList<point>& surfacePoints,
717 const DynamicList<label>& surfaceCounts,
726 scalar tang = ((pt-edgePt)&edgeNormal);
730 if (order[0] < order[1])
734 vector attractD = surfacePoints[order[0]]-edgePt;
736 scalar tang2 = (attractD&edgeNormal);
738 attractD -= tang2*edgeNormal;
740 scalar magAttractD =
mag(attractD);
741 scalar fraction = magAttractD/(magAttractD+
mag(edgeOffset));
745 + ((1.0-fraction)*tang2 + fraction*tang)*edgeNormal;
746 edgeOffset = linePt-pt;
755 const List<point>& faceCentres
761 label patch0 = patchIDs[0];
763 for (
label i = 1; i < patchIDs.size(); i++)
765 if (patchIDs[i] != patch0)
777 const scalar featureCos,
779 const DynamicList<vector>& surfaceNormals
786 scalar cosAngle = (
n&surfaceNormals[j]);
790 (cosAngle >= featureCos)
791 || (cosAngle < (-1+0.001))
812 const DynamicList<vector>& surfaceNormals,
816 if (patchIDs.empty())
822 label patch0 = patchIDs[0];
824 for (
label i = 1; i < patchIDs.size(); i++)
826 if (patchIDs[i] != patch0)
840 if (surfaceNormals.size() == 1)
848 labelList normalToPatch(surfaceNormals.size(), -1);
849 forAll(faceToNormalBin, i)
851 if (faceToNormalBin[i] != -1)
853 label&
patch = normalToPatch[faceToNormalBin[i]];
859 else if (
patch == -2)
863 else if (
patch != patchIDs[i])
871 forAll(normalToPatch, normali)
873 if (normalToPatch[normali] == -2)
888 void Foam::snappySnapDriver::writeStats
891 const bitSet& isPatchMasterPoint,
892 const List<pointConstraint>& patchConstraints
895 label nMasterPoints = 0;
900 forAll(patchConstraints, pointi)
902 if (isPatchMasterPoint[pointi])
906 if (patchConstraints[pointi].first() == 1)
910 else if (patchConstraints[pointi].first() == 2)
914 else if (patchConstraints[pointi].first() == 3)
921 reduce(nMasterPoints, sumOp<label>());
922 reduce(nPlanar, sumOp<label>());
923 reduce(nEdge, sumOp<label>());
924 reduce(nPoint, sumOp<label>());
925 Info<<
"total master points :" << nMasterPoints
926 <<
" of which attracted to :" <<
nl
927 <<
" feature point : " << nPoint <<
nl
928 <<
" feature edge : " << nEdge <<
nl
929 <<
" nearest surface : " << nPlanar <<
nl
930 <<
" rest : " << nMasterPoints-nPoint-nEdge-nPlanar
936 void Foam::snappySnapDriver::featureAttractionUsingReconstruction
939 const scalar featureCos,
946 const List<List<point>>& pointFaceSurfNormals,
947 const List<List<point>>& pointFaceDisp,
948 const List<List<point>>& pointFaceCentres,
951 DynamicList<point>& surfacePoints,
952 DynamicList<vector>& surfaceNormals,
956 pointConstraint& patchConstraint
959 patchAttraction =
Zero;
960 patchConstraint = pointConstraint();
962 const List<point>& pfSurfNormals = pointFaceSurfNormals[pointi];
963 const List<point>& pfDisp = pointFaceDisp[pointi];
964 const List<point>& pfCentres = pointFaceCentres[pointi];
974 surfacePoints.clear();
975 surfaceNormals.clear();
978 faceToNormalBin.setSize(pfDisp.size());
979 faceToNormalBin = -1;
983 const point& fc = pfCentres[i];
984 const vector& fSNormal = pfSurfNormals[i];
985 const vector& fDisp = pfDisp[i];
988 if (
magSqr(fDisp) <
sqr(snapDist[pointi]) &&
mag(fSNormal) > VSMALL)
990 const point pt = fc + fDisp;
993 faceToNormalBin[i] = findNormal
1000 if (faceToNormalBin[i] != -1)
1008 if (surfacePoints.size() <= 1)
1010 surfacePoints.append(pt);
1011 faceToNormalBin[i] = surfaceNormals.size();
1012 surfaceNormals.append(fSNormal);
1014 else if (surfacePoints.size() == 2)
1016 plane pl0(surfacePoints[0], surfaceNormals[0]);
1017 plane pl1(surfacePoints[1], surfaceNormals[1]);
1018 plane::ray r(pl0.planeIntersect(pl1));
1019 vector featureNormal = r.dir() /
mag(r.dir());
1021 if (
mag(fSNormal&featureNormal) >= 0.001)
1024 surfacePoints.append(pt);
1025 faceToNormalBin[i] = surfaceNormals.size();
1026 surfaceNormals.append(fSNormal);
1029 else if (surfacePoints.size() == 3)
1033 plane pl0(surfacePoints[0], surfaceNormals[0]);
1034 plane pl1(surfacePoints[1], surfaceNormals[1]);
1035 plane pl2(surfacePoints[2], surfaceNormals[2]);
1036 point p012(pl0.planePlaneIntersect(pl1, pl2));
1038 plane::ray r(pl0.planeIntersect(pl1));
1039 vector featureNormal = r.dir() /
mag(r.dir());
1040 if (
mag(fSNormal&featureNormal) >= 0.001)
1042 plane pl3(pt, fSNormal);
1043 point p013(pl0.planePlaneIntersect(pl1, pl3));
1045 if (
mag(p012-p013) > snapDist[pointi])
1048 surfacePoints.append(pt);
1049 faceToNormalBin[i] = surfaceNormals.
size();
1050 surfaceNormals.append(fSNormal);
1059 const point& pt = pp.localPoints()[pointi];
1062 if (surfaceNormals.size() == 1)
1066 ((surfacePoints[0]-pt) & surfaceNormals[0])
1075 patchAttraction = d;
1078 patchConstraint.applyConstraint(surfaceNormals[0]);
1080 else if (surfaceNormals.size() == 2)
1082 plane pl0(surfacePoints[0], surfaceNormals[0]);
1083 plane pl1(surfacePoints[1], surfaceNormals[1]);
1084 plane::ray r(pl0.planeIntersect(pl1));
1088 vector d = r.refPoint()-pt;
1097 patchAttraction = d;
1100 patchConstraint.applyConstraint(surfaceNormals[0]);
1101 patchConstraint.applyConstraint(surfaceNormals[1]);
1103 else if (surfaceNormals.size() == 3)
1106 plane pl0(surfacePoints[0], surfaceNormals[0]);
1107 plane pl1(surfacePoints[1], surfaceNormals[1]);
1108 plane pl2(surfacePoints[2], surfaceNormals[2]);
1109 point cornerPt(pl0.planePlaneIntersect(pl1, pl2));
1110 vector d = cornerPt - pt;
1118 patchAttraction = d;
1121 patchConstraint.applyConstraint(surfaceNormals[0]);
1122 patchConstraint.applyConstraint(surfaceNormals[1]);
1123 patchConstraint.applyConstraint(surfaceNormals[2]);
1129 void Foam::snappySnapDriver::featureAttractionUsingReconstruction
1132 const scalar featureCos,
1138 const List<List<point>>& pointFaceSurfNormals,
1139 const List<List<point>>& pointFaceDisp,
1140 const List<List<point>>& pointFaceCentres,
1144 List<pointConstraint>& patchConstraints
1147 autoPtr<OBJstream> feStr;
1148 autoPtr<OBJstream> fpStr;
1155 meshRefiner_.mesh().time().path()
1156 /
"implicitFeatureEdge_" +
name(iter) +
".obj"
1159 Info<<
"Dumping implicit feature-edge direction to "
1160 << feStr().name() <<
endl;
1166 meshRefiner_.mesh().time().path()
1167 /
"implicitFeaturePoint_" +
name(iter) +
".obj"
1170 Info<<
"Dumping implicit feature-point direction to "
1171 << fpStr().name() <<
endl;
1175 DynamicList<point> surfacePoints(4);
1176 DynamicList<vector> surfaceNormals(4);
1179 forAll(pp.localPoints(), pointi)
1182 pointConstraint constraint;
1184 featureAttractionUsingReconstruction
1195 pointFaceSurfNormals,
1210 (constraint.first() > patchConstraints[pointi].first())
1212 (constraint.first() == patchConstraints[pointi].first())
1213 && (
magSqr(attraction) <
magSqr(patchAttraction[pointi]))
1217 patchAttraction[pointi] = attraction;
1218 patchConstraints[pointi] = constraint;
1220 const point& pt = pp.localPoints()[pointi];
1222 if (patchConstraints[pointi].first() == 2 && feStr.valid())
1224 feStr().write(
linePointRef(pt, pt+patchAttraction[pointi]));
1226 else if (patchConstraints[pointi].first() == 3 && fpStr.valid())
1228 fpStr().write(
linePointRef(pt, pt+patchAttraction[pointi]));
1235 void Foam::snappySnapDriver::stringFeatureEdges
1238 const scalar featureCos,
1244 const List<pointConstraint>& rawPatchConstraints,
1247 List<pointConstraint>& patchConstraints
1277 forAll(pointEdges, pointi)
1279 if (patchConstraints[pointi].first() == 2)
1281 const point& pt = pp.localPoints()[pointi];
1282 const labelList& pEdges = pointEdges[pointi];
1283 const vector& featVec = patchConstraints[pointi].second();
1287 bool hasPos =
false;
1288 bool hasNeg =
false;
1292 const edge&
e = pp.edges()[pEdges[pEdgei]];
1293 label nbrPointi =
e.otherVertex(pointi);
1295 if (patchConstraints[nbrPointi].first() > 1)
1297 const point& nbrPt = pp.localPoints()[nbrPointi];
1298 const point featPt =
1299 nbrPt + patchAttraction[nbrPointi];
1300 const scalar cosAngle = (featVec & (featPt-pt));
1313 if (!hasPos || !hasNeg)
1319 label bestPosPointi = -1;
1320 scalar minPosDistSqr = GREAT;
1321 label bestNegPointi = -1;
1322 scalar minNegDistSqr = GREAT;
1326 const edge&
e = pp.edges()[pEdges[pEdgei]];
1327 label nbrPointi =
e.otherVertex(pointi);
1331 patchConstraints[nbrPointi].first() <= 1
1332 && rawPatchConstraints[nbrPointi].first() > 1
1335 const vector& nbrFeatVec =
1336 rawPatchConstraints[pointi].second();
1338 if (
mag(featVec&nbrFeatVec) > featureCos)
1345 rawPatchAttraction[nbrPointi]
1348 const point featPt =
1349 pp.localPoints()[nbrPointi]
1350 + rawPatchAttraction[nbrPointi];
1351 const scalar cosAngle =
1352 (featVec & (featPt-pt));
1356 if (!hasPos && d2 < minPosDistSqr)
1359 bestPosPointi = nbrPointi;
1364 if (!hasNeg && d2 < minNegDistSqr)
1367 bestNegPointi = nbrPointi;
1374 if (bestPosPointi != -1)
1384 patchAttraction[bestPosPointi] =
1385 0.5*rawPatchAttraction[bestPosPointi];
1386 patchConstraints[bestPosPointi] =
1387 rawPatchConstraints[bestPosPointi];
1391 if (bestNegPointi != -1)
1401 patchAttraction[bestNegPointi] =
1402 0.5*rawPatchAttraction[bestNegPointi];
1403 patchConstraints[bestNegPointi] =
1404 rawPatchConstraints[bestNegPointi];
1413 reduce(nChanged, sumOp<label>());
1414 Info<<
"Stringing feature edges : changed " << nChanged <<
" points"
1424 void Foam::snappySnapDriver::releasePointsNextToMultiPatch
1427 const scalar featureCos,
1432 const List<List<point>>& pointFaceCentres,
1436 const List<pointConstraint>& rawPatchConstraints,
1439 List<pointConstraint>& patchConstraints
1442 autoPtr<OBJstream> multiPatchStr;
1449 meshRefiner_.mesh().time().path()
1450 /
"multiPatch_" +
name(iter) +
".obj"
1453 Info<<
"Dumping removed constraints due to same-face"
1454 <<
" multi-patch points to "
1455 << multiPatchStr().name() <<
endl;
1460 bitSet isMultiPatchPoint(pp.size());
1462 forAll(pointFacePatchID, pointi)
1466 pp.localPoints()[pointi],
1467 pointFacePatchID[pointi],
1468 pointFaceCentres[pointi]
1470 isMultiPatchPoint.set(pointi, multiPatchPt.hit());
1474 forAll(isMultiPatchPoint, pointi)
1476 if (isMultiPatchPoint.test(pointi))
1480 patchConstraints[pointi].first() <= 1
1481 && rawPatchConstraints[pointi].first() > 1
1484 patchAttraction[pointi] = rawPatchAttraction[pointi];
1485 patchConstraints[pointi] = rawPatchConstraints[pointi];
1504 forAll(pp.localFaces(), facei)
1506 const face&
f = pp.localFaces()[facei];
1508 label nMultiPatchPoints = 0;
1514 isMultiPatchPoint.test(pointi)
1515 && patchConstraints[pointi].first() > 1
1518 ++nMultiPatchPoints;
1522 if (nMultiPatchPoints > 0)
1529 !isMultiPatchPoint.test(pointi)
1530 && patchConstraints[pointi].first() > 1
1536 patchAttraction[pointi] =
Zero;
1537 patchConstraints[pointi] = pointConstraint();
1540 if (multiPatchStr.valid())
1542 multiPatchStr().write(pp.localPoints()[pointi]);
1549 reduce(nChanged, sumOp<label>());
1550 Info<<
"Removing constraints near multi-patch points : changed "
1551 << nChanged <<
" points" <<
endl;
1559 const List<pointConstraint>& patchConstraints,
1563 const face&
f = pp.localFaces()[facei];
1571 for (
label startFp = 0; startFp <
f.size()-2; startFp++)
1573 label minFp =
f.rcIndex(startFp);
1577 label endFp =
f.fcIndex(
f.fcIndex(startFp));
1578 endFp <
f.size() && endFp != minFp;
1584 patchConstraints[
f[startFp]].first() >= 2
1585 && patchConstraints[
f[endFp]].first() >= 2
1588 attractIndices =
labelPair(startFp, endFp);
1594 return attractIndices;
1598 bool Foam::snappySnapDriver::isSplitAlignedWithFeature
1600 const scalar featureCos,
1602 const pointConstraint& pc0,
1604 const pointConstraint& pc1
1608 scalar magD =
mag(d);
1621 if (pc0.first() == 2 &&
mag(d & pc0.second()) > featureCos)
1625 else if (pc1.first() == 2 &&
mag(d & pc1.second()) > featureCos)
1638 bool Foam::snappySnapDriver::isConcave
1644 const scalar concaveCos
1648 scalar magN0 =
mag(n0);
1657 scalar d = (
c1-c0)&n0;
1668 scalar magN1 =
mag(n1);
1676 if ((n0&n1) < concaveCos)
1690 const scalar featureCos,
1691 const scalar concaveCos,
1692 const scalar minAreaRatio,
1695 const List<pointConstraint>& patchConstraints,
1701 DynamicField<point>& points1
1704 const face& localF = pp.localFaces()[facei];
1708 if (localF.size() >= 4)
1710 const pointField& localPts = pp.localPoints();
1748 for (
label startFp = 0; startFp < localF.size()-2; startFp++)
1750 label minFp = localF.rcIndex(startFp);
1754 label endFp = localF.fcIndex(localF.fcIndex(startFp));
1755 endFp < localF.size() && endFp != minFp;
1759 label startPti = localF[startFp];
1760 label endPti = localF[endFp];
1762 const pointConstraint& startPc = patchConstraints[startPti];
1763 const pointConstraint& endPc = patchConstraints[endPti];
1765 if (startPc.first() >= 2 && endPc.first() >= 2)
1767 if (startPc.first() == 2 || endPc.first() == 2)
1772 point start = localPts[startPti]+patchAttr[startPti];
1773 point end = localPts[endPti]+patchAttr[endPti];
1777 !isSplitAlignedWithFeature
1803 f0.setSize(endFp-startFp+1);
1805 for (
label fp = startFp; fp <= endFp; fp++)
1807 f0[i0++] = localF[fp];
1811 const face compact0(
identity(f0.size()));
1813 points0.append(localPts[f0[0]] + patchAttr[f0[0]]);
1814 for (
label fp=1; fp < f0.size()-1; fp++)
1821 localPts[f0.last()] + patchAttr[f0.last()]
1827 f1.setSize(localF.size()+2-f0.size());
1833 fp = localF.fcIndex(fp)
1836 f1[i1++] = localF[fp];
1838 f1[i1++] = localF[startFp];
1842 const face compact1(
identity(f1.size()));
1844 points1.append(localPts[f1[0]] + patchAttr[f1[0]]);
1845 for (
label fp=1; fp < f1.size()-1; fp++)
1848 points1.append(localPts[
pi] + nearestAttr[
pi]);
1852 localPts[f1.last()] + patchAttr[f1.last()]
1866 compact1.centre(points1),
1867 compact1.areaNormal(points1),
1887 const scalar area0 = f0.mag(localPts);
1888 const scalar area1 = f1.mag(localPts);
1892 area0/area1 >= minAreaRatio
1893 && area1/area0 >= minAreaRatio
1896 attractIndices =
labelPair(startFp, endFp);
1903 return attractIndices;
1907 void Foam::snappySnapDriver::splitDiagonals
1909 const scalar featureCos,
1910 const scalar concaveCos,
1911 const scalar minAreaRatio,
1918 List<pointConstraint>& patchConstraints,
1919 DynamicList<label>& splitFaces,
1920 DynamicList<labelPair>& splits
1923 const labelList& bFaces = pp.addressing();
1926 splitFaces.setCapacity(bFaces.size());
1928 splits.setCapacity(bFaces.size());
1932 DynamicField<point> facePoints0;
1933 DynamicField<point> facePoints1;
1939 findDiagonalAttraction
1960 splitFaces.append(bFaces[facei]);
1961 splits.append(
split);
1963 const face&
f = pp.localFaces()[facei];
1973 && patchConstraints[
f[fp]].first() >= 2
1976 patchConstraints[
f[fp]] = pointConstraint
1978 Tuple2<label, vector>
1981 nearestNormal[
f[fp]]
1984 patchAttraction[
f[fp]] = nearestAttraction[
f[fp]];
1992 void Foam::snappySnapDriver::avoidDiagonalAttraction
1995 const scalar featureCos,
2000 List<pointConstraint>& patchConstraints
2003 forAll(pp.localFaces(), facei)
2005 const face&
f = pp.localFaces()[facei];
2015 if (
diag[0] != -1 &&
diag[1] != -1)
2021 pp.localPoints()[i0]+patchAttraction[i0];
2024 pp.localPoints()[i1]+patchAttraction[i1];
2025 const point mid = 0.5*(pt0+pt1);
2027 const scalar cosAngle =
mag
2029 patchConstraints[i0].second()
2030 & patchConstraints[i1].second()
2039 if (cosAngle > featureCos)
2045 scalar minDistSqr = GREAT;
2049 if (patchConstraints[pointi].first() <= 1)
2051 const point& pt = pp.localPoints()[pointi];
2052 scalar distSqr =
magSqr(mid-pt);
2053 if (distSqr < minDistSqr)
2061 label minPointi =
f[minFp];
2062 patchAttraction[minPointi] =
2063 mid-pp.localPoints()[minPointi];
2064 patchConstraints[minPointi] = patchConstraints[
f[
diag[0]]];
2090 Foam::snappySnapDriver::findNearFeatureEdge
2092 const bool isRegionEdge,
2097 const point& estimatedPt,
2099 List<List<DynamicList<point>>>& edgeAttractors,
2100 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2102 List<pointConstraint>& patchConstraints
2105 const refinementFeatures& features = meshRefiner_.features();
2108 List<pointIndexHit> nearEdgeInfo;
2113 features.findNearestRegionEdge
2124 features.findNearestEdge
2135 label feati = nearEdgeFeat[0];
2141 edgeAttractors[feati][
nearInfo.index()].append
2145 pointConstraint
c(Tuple2<label, vector>(2, nearNormal[0]));
2146 edgeConstraints[feati][
nearInfo.index()].append(
c);
2149 patchAttraction[pointi] =
nearInfo.hitPoint()-pp.localPoints()[pointi];
2150 patchConstraints[pointi] =
c;
2152 return Tuple2<label, pointIndexHit>(feati,
nearInfo);
2157 Foam::snappySnapDriver::findNearFeaturePoint
2159 const bool isRegionPoint,
2164 const point& estimatedPt,
2167 List<labelList>& pointAttractor,
2168 List<List<pointConstraint>>& pointConstraints,
2170 List<List<DynamicList<point>>>& edgeAttractors,
2171 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2174 List<pointConstraint>& patchConstraints
2177 const refinementFeatures& features = meshRefiner_.features();
2183 features.findNearestPoint
2191 label feati = nearFeat[0];
2195 const point& pt = pp.localPoints()[pointi];
2199 scalar distSqr =
magSqr(featPt-pt);
2202 label oldPointi = pointAttractor[feati][featPointi];
2204 if (oldPointi != -1)
2207 if (distSqr >=
magSqr(featPt-pp.localPoints()[oldPointi]))
2216 pointAttractor[feati][featPointi] = pointi;
2217 pointConstraints[feati][featPointi].first() = 3;
2218 pointConstraints[feati][featPointi].second() =
Zero;
2221 patchAttraction[pointi] = featPt-pt;
2222 patchConstraints[pointi] = pointConstraints[feati][featPointi];
2225 patchAttraction[oldPointi] =
Zero;
2226 patchConstraints[oldPointi] = pointConstraint();
2235 pp.localPoints()[oldPointi],
2247 pointAttractor[feati][featPointi] = pointi;
2248 pointConstraints[feati][featPointi].first() = 3;
2249 pointConstraints[feati][featPointi].second() =
Zero;
2252 patchAttraction[pointi] = featPt-pt;
2253 patchConstraints[pointi] = pointConstraints[feati][featPointi];
2257 return Tuple2<label, pointIndexHit>(feati,
nearInfo[0]);
2263 void Foam::snappySnapDriver::determineFeatures
2266 const scalar featureCos,
2267 const bool multiRegionFeatureSnap,
2273 const List<List<point>>& pointFaceSurfNormals,
2274 const List<List<point>>& pointFaceDisp,
2275 const List<List<point>>& pointFaceCentres,
2279 List<labelList>& pointAttractor,
2280 List<List<pointConstraint>>& pointConstraints,
2282 List<List<DynamicList<point>>>& edgeAttractors,
2283 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2286 List<pointConstraint>& patchConstraints
2289 autoPtr<OBJstream> featureEdgeStr;
2290 autoPtr<OBJstream> missedEdgeStr;
2291 autoPtr<OBJstream> featurePointStr;
2292 autoPtr<OBJstream> missedMP0Str;
2293 autoPtr<OBJstream> missedMP1Str;
2297 featureEdgeStr.reset
2301 meshRefiner_.mesh().time().path()
2302 /
"featureEdge_" +
name(iter) +
".obj"
2305 Info<<
"Dumping feature-edge sampling to "
2306 << featureEdgeStr().name() <<
endl;
2312 meshRefiner_.mesh().time().path()
2313 /
"missedFeatureEdge_" +
name(iter) +
".obj"
2316 Info<<
"Dumping feature-edges that are too far away to "
2317 << missedEdgeStr().name() <<
endl;
2319 featurePointStr.reset
2323 meshRefiner_.mesh().time().path()
2324 /
"featurePoint_" +
name(iter) +
".obj"
2327 Info<<
"Dumping feature-point sampling to "
2328 << featurePointStr().name() <<
endl;
2334 meshRefiner_.mesh().time().path()
2335 /
"missedFeatureEdgeFromMPEdge_" +
name(iter) +
".obj"
2338 Info<<
"Dumping region-edges that are too far away to "
2339 << missedMP0Str().name() <<
endl;
2345 meshRefiner_.mesh().time().path()
2346 /
"missedFeatureEdgeFromMPPoint_" +
name(iter) +
".obj"
2349 Info<<
"Dumping region-points that are too far away to "
2350 << missedMP1Str().name() <<
endl;
2354 DynamicList<point> surfacePoints(4);
2355 DynamicList<vector> surfaceNormals(4);
2358 forAll(pp.localPoints(), pointi)
2360 const point& pt = pp.localPoints()[pointi];
2372 pointConstraint constraint;
2374 featureAttractionUsingReconstruction
2385 pointFaceSurfNormals,
2430 (constraint.first() > patchConstraints[pointi].first())
2432 (constraint.first() == patchConstraints[pointi].first())
2433 && (
magSqr(attraction) <
magSqr(patchAttraction[pointi]))
2437 patchAttraction[pointi] = attraction;
2438 patchConstraints[pointi] = constraint;
2441 if (patchConstraints[pointi].first() == 1)
2444 if (multiRegionFeatureSnap)
2446 const point estimatedPt(pt + nearestDisp[pointi]);
2452 pointFacePatchID[pointi],
2458 if (multiPatchPt.hit())
2463 Tuple2<label, pointIndexHit>
nearInfo =
2470 multiPatchPt.hitPoint(),
2483 if (featureEdgeStr.valid())
2485 featureEdgeStr().write
2493 if (missedEdgeStr.valid())
2495 missedEdgeStr().write
2504 else if (patchConstraints[pointi].first() == 2)
2509 const point estimatedPt(pt + patchAttraction[pointi]);
2514 bool hasSnapped =
false;
2515 if (multiRegionFeatureSnap)
2522 pointFacePatchID[pointi],
2527 if (multiPatchPt.hit())
2529 if (multiPatchPt.index() == 0)
2551 missedMP0Str.valid()
2555 missedMP0Str().write
2620 missedMP1Str.valid()
2624 missedMP1Str().write
2662 patchConstraints[pointi].first() == 3
2663 && featurePointStr.valid()
2666 featurePointStr().write
2673 patchConstraints[pointi].first() == 2
2674 && featureEdgeStr.valid()
2677 featureEdgeStr().write
2685 if (missedEdgeStr.valid())
2687 missedEdgeStr().write
2694 else if (patchConstraints[pointi].first() == 3)
2697 const point estimatedPt(pt + patchAttraction[pointi]);
2701 if (multiRegionFeatureSnap)
2708 pointFacePatchID[pointi],
2713 if (multiPatchPt.hit())
2781 if (info.hit() && featurePointStr.valid())
2783 featurePointStr().write
2805 void Foam::snappySnapDriver::determineBaffleFeatures
2808 const bool baffleFeaturePoints,
2809 const scalar featureCos,
2815 List<labelList>& pointAttractor,
2816 List<List<pointConstraint>>& pointConstraints,
2818 List<List<DynamicList<point>>>& edgeAttractors,
2819 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2822 List<pointConstraint>& patchConstraints
2825 const fvMesh&
mesh = meshRefiner_.mesh();
2826 const refinementFeatures& features = meshRefiner_.features();
2829 List<List<point>> edgeFaceNormals(pp.nEdges());
2832 forAll(pp.edgeFaces(), edgei)
2834 const labelList& eFaces = pp.edgeFaces()[edgei];
2835 List<point>& eFc = edgeFaceNormals[edgei];
2839 label facei = eFaces[i];
2840 eFc[i] = pp.faceNormals()[facei];
2855 listPlusEqOp<point>(),
2867 autoPtr<OBJstream> baffleEdgeStr;
2874 meshRefiner_.mesh().time().path()
2875 /
"baffleEdge_" +
name(iter) +
".obj"
2878 Info<<
nl <<
"Dumping baffle-edges to "
2879 << baffleEdgeStr().name() <<
endl;
2884 bitSet isBaffleEdge(pp.nEdges());
2885 label nBaffleEdges = 0;
2890 labelList pointStatus(pp.nPoints(), -1);
2892 forAll(edgeFaceNormals, edgei)
2894 const List<point>& efn = edgeFaceNormals[edgei];
2896 if (efn.size() == 2 && (efn[0]&efn[1]) < baffleFeatureCos)
2898 isBaffleEdge.set(edgei);
2900 const edge&
e = pp.edges()[edgei];
2901 pointStatus[
e[0]] = 0;
2902 pointStatus[
e[1]] = 0;
2904 if (baffleEdgeStr.valid())
2906 const point&
p0 = pp.localPoints()[
e[0]];
2907 const point& p1 = pp.localPoints()[
e[1]];
2913 reduce(nBaffleEdges, sumOp<label>());
2915 Info<<
"Detected " << nBaffleEdges
2916 <<
" baffle edges out of "
2918 <<
" edges." <<
endl;
2943 label nBafflePoints = 0;
2944 forAll(pointStatus, pointi)
2946 if (pointStatus[pointi] != -1)
2951 reduce(nBafflePoints, sumOp<label>());
2954 label nPointAttract = 0;
2955 label nEdgeAttract = 0;
2957 forAll(pointStatus, pointi)
2959 const point& pt = pp.localPoints()[pointi];
2961 if (pointStatus[pointi] == 0)
2965 Tuple2<label, pointIndexHit>
nearInfo = findNearFeatureEdge
2988 if (baffleFeaturePoints)
3018 else if (pointStatus[pointi] == 1)
3022 features.findNearestPoint
3030 label feati = nearFeat[0];
3038 scalar distSqr =
magSqr(featPt-pt);
3041 label oldPointi = pointAttractor[feati][featPointi];
3048 <
magSqr(featPt-pp.localPoints()[oldPointi])
3052 pointAttractor[feati][featPointi] = pointi;
3053 pointConstraints[feati][featPointi].first() = 3;
3054 pointConstraints[feati][featPointi].second() =
Zero;
3057 patchAttraction[pointi] = featPt-pt;
3058 patchConstraints[pointi] =
3059 pointConstraints[feati][featPointi];
3061 if (oldPointi != -1)
3072 pp.localPoints()[oldPointi],
3097 Tuple2<label, pointIndexHit>
nearInfo = findNearFeatureEdge
3119 reduce(nPointAttract, sumOp<label>());
3120 reduce(nEdgeAttract, sumOp<label>());
3122 Info<<
"Baffle points : " << nBafflePoints
3123 <<
" of which attracted to :" <<
nl
3124 <<
" feature point : " << nPointAttract <<
nl
3125 <<
" feature edge : " << nEdgeAttract <<
nl
3126 <<
" rest : " << nBafflePoints-nPointAttract-nEdgeAttract
3132 void Foam::snappySnapDriver::reverseAttractMeshPoints
3140 const List<labelList>& pointAttractor,
3141 const List<List<pointConstraint>>& pointConstraints,
3143 const List<List<DynamicList<point>>>& edgeAttractors,
3144 const List<List<DynamicList<pointConstraint>>>& edgeConstraints,
3147 const List<pointConstraint>& rawPatchConstraints,
3151 List<pointConstraint>& patchConstraints
3154 const refinementFeatures& features = meshRefiner_.features();
3162 treeBoundBox bb(pp.localPoints());
3170 bb.min() -=
point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
3171 bb.max() +=
point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
3175 DynamicList<label> attractPoints(pp.nPoints());
3177 const fvMesh&
mesh = meshRefiner_.mesh();
3179 boolList isFeatureEdgeOrPoint(pp.nPoints(),
false);
3181 forAll(rawPatchConstraints, pointi)
3183 if (rawPatchConstraints[pointi].first() >= 2)
3185 isFeatureEdgeOrPoint[pointi] =
true;
3191 <<
" mesh points out of "
3193 <<
" for reverse attraction." <<
endl;
3201 isFeatureEdgeOrPoint,
3206 for (
label nGrow = 0; nGrow < 1; nGrow++)
3208 boolList newIsFeatureEdgeOrPoint(isFeatureEdgeOrPoint);
3210 forAll(pp.localFaces(), facei)
3212 const face&
f = pp.localFaces()[facei];
3216 if (isFeatureEdgeOrPoint[
f[fp]])
3221 newIsFeatureEdgeOrPoint[
f[fp]] =
true;
3228 isFeatureEdgeOrPoint = newIsFeatureEdgeOrPoint;
3234 isFeatureEdgeOrPoint,
3242 forAll(isFeatureEdgeOrPoint, pointi)
3244 if (isFeatureEdgeOrPoint[pointi])
3246 attractPoints.append(pointi);
3252 <<
" mesh points out of "
3254 <<
" for reverse attraction." <<
endl;
3258 indexedOctree<treeDataPoint> ppTree
3260 treeDataPoint(pp.localPoints(), attractPoints),
3268 patchAttraction.setSize(pp.nPoints());
3269 patchAttraction =
Zero;
3270 patchConstraints.setSize(pp.nPoints());
3271 patchConstraints = pointConstraint();
3273 forAll(edgeAttractors, feati)
3275 const List<DynamicList<point>>& edgeAttr = edgeAttractors[feati];
3276 const List<DynamicList<pointConstraint>>& edgeConstr =
3277 edgeConstraints[feati];
3279 forAll(edgeAttr, featEdgei)
3281 const DynamicList<point>& attr = edgeAttr[featEdgei];
3285 const point& featPt = attr[i];
3295 ppTree.shapes().pointLabels()[
nearInfo.index()];
3296 const point attraction = featPt-pp.localPoints()[pointi];
3302 patchConstraints[pointi].first() <= 1
3303 ||
magSqr(attraction) <
magSqr(patchAttraction[pointi])
3306 patchAttraction[pointi] = attraction;
3307 patchConstraints[pointi] = edgeConstr[featEdgei][i];
3312 static label nWarn = 0;
3317 <<
"Did not find pp point near " << featPt
3323 <<
"Reached warning limit " << nWarn
3324 <<
". Suppressing further warnings." <<
endl;
3343 forAll(pointAttractor, feati)
3345 const labelList& pointAttr = pointAttractor[feati];
3346 const List<pointConstraint>& pointConstr = pointConstraints[feati];
3348 forAll(pointAttr, featPointi)
3350 if (pointAttr[featPointi] != -1)
3352 const point& featPt = features[feati].points()
3367 ppTree.shapes().pointLabels()[
nearInfo.index()];
3369 const point& pt = pp.localPoints()[pointi];
3370 const point attraction = featPt-pt;
3375 if (patchConstraints[pointi].first() <= 1)
3377 patchAttraction[pointi] = attraction;
3378 patchConstraints[pointi] = pointConstr[featPointi];
3380 else if (patchConstraints[pointi].first() == 2)
3382 patchAttraction[pointi] = attraction;
3383 patchConstraints[pointi] = pointConstr[featPointi];
3385 else if (patchConstraints[pointi].first() == 3)
3391 <
magSqr(patchAttraction[pointi])
3394 patchAttraction[pointi] = attraction;
3395 patchConstraints[pointi] =
3396 pointConstr[featPointi];
3406 void Foam::snappySnapDriver::featureAttractionUsingFeatureEdges
3409 const bool multiRegionFeatureSnap,
3411 const bool detectBaffles,
3412 const bool baffleFeaturePoints,
3414 const bool releasePoints,
3415 const bool stringFeatures,
3416 const bool avoidDiagonal,
3418 const scalar featureCos,
3425 const List<List<point>>& pointFaceSurfNormals,
3426 const List<List<point>>& pointFaceDisp,
3427 const List<List<point>>& pointFaceCentres,
3431 List<pointConstraint>& patchConstraints
3434 const refinementFeatures& features = meshRefiner_.features();
3435 const fvMesh&
mesh = meshRefiner_.mesh();
3437 const bitSet isPatchMasterPoint
3452 List<List<DynamicList<point>>> edgeAttractors(features.size());
3453 List<List<DynamicList<pointConstraint>>> edgeConstraints
3459 label nFeatEdges = features[feati].edges().size();
3460 edgeAttractors[feati].setSize(nFeatEdges);
3461 edgeConstraints[feati].setSize(nFeatEdges);
3467 List<labelList> pointAttractor(features.size());
3468 List<List<pointConstraint>> pointConstraints(features.size());
3471 label nFeatPoints = features[feati].points().size();
3472 pointAttractor[feati].setSize(nFeatPoints, -1);
3473 pointConstraints[feati].setSize(nFeatPoints);
3478 List<pointConstraint> rawPatchConstraints(pp.nPoints());
3484 multiRegionFeatureSnap,
3490 pointFaceSurfNormals,
3509 Info<<
"Raw geometric feature analysis : ";
3510 writeStats(pp, isPatchMasterPoint, rawPatchConstraints);
3526 determineBaffleFeatures
3529 baffleFeaturePoints,
3550 Info<<
"After baffle feature analysis : ";
3551 writeStats(pp, isPatchMasterPoint, rawPatchConstraints);
3559 reverseAttractMeshPoints
3575 rawPatchConstraints,
3585 Info<<
"Reverse attract feature analysis : ";
3586 writeStats(pp, isPatchMasterPoint, patchConstraints);
3592 OBJstream featureEdgeStr
3594 meshRefiner_.mesh().time().path()
3595 /
"edgeAttractors_" +
name(iter) +
".obj"
3597 Info<<
"Dumping feature-edge attraction to "
3598 << featureEdgeStr.name() <<
endl;
3600 OBJstream featurePointStr
3602 meshRefiner_.mesh().time().path()
3603 /
"pointAttractors_" +
name(iter) +
".obj"
3605 Info<<
"Dumping feature-point attraction to "
3606 << featurePointStr.name() <<
endl;
3608 forAll(patchConstraints, pointi)
3610 const point& pt = pp.localPoints()[pointi];
3611 const vector& attr = patchAttraction[pointi];
3613 if (patchConstraints[pointi].first() == 2)
3617 else if (patchConstraints[pointi].first() == 3)
3631 releasePointsNextToMultiPatch
3643 rawPatchConstraints,
3666 rawPatchConstraints,
3679 avoidDiagonalAttraction
3694 meshRefiner_.mesh().time().path()
3695 /
"patchAttraction_" +
name(iter) +
".obj",
3697 pp.localPoints() + patchAttraction
3704 void Foam::snappySnapDriver::preventFaceSqueeze
3707 const scalar featureCos,
3714 List<pointConstraint>& patchConstraints
3717 autoPtr<OBJstream> strPtr;
3724 meshRefiner_.mesh().time().path()
3725 /
"faceSqueeze_" +
name(iter) +
".obj"
3728 Info<<
"Dumping faceSqueeze corrections to "
3729 << strPtr().name() <<
endl;
3734 forAll(pp.localFaces(), facei)
3736 const face&
f = pp.localFaces()[facei];
3738 if (
f.size() !=
points.size())
3741 singleF.setSize(
f.size());
3742 for (
label i = 0; i <
f.size(); i++)
3747 label nConstraints = 0;
3751 const point& pt = pp.localPoints()[pointi];
3753 if (patchConstraints[pointi].first() > 1)
3755 points[fp] = pt + patchAttraction[pointi];
3764 if (nConstraints ==
f.size())
3775 const point& pt = pp.localPoints()[
f[fp]];
3776 const point& nextPt = pp.localPoints()[
f.nextLabel(fp)];
3787 label pointi =
f.prevLabel(maxFp);
3791 const point& pt = pp.localPoints()[pointi];
3798 patchAttraction[pointi] = nearestAttraction[pointi];
3811 scalar oldArea =
f.mag(pp.localPoints());
3812 scalar newArea = singleF.mag(
points);
3813 if (newArea < 0.1*oldArea)
3820 scalar
s =
magSqr(patchAttraction[
f[fp]]);
3831 patchAttraction[pointi] *= 0.5;
3842 const snapParameters& snapParams,
3843 const bool alignMeshEdges,
3845 const scalar featureCos,
3846 const scalar featureAttract,
3850 motionSmoother& meshMover,
3852 List<pointConstraint>& patchConstraints,
3854 DynamicList<label>& splitFaces,
3855 DynamicList<labelPair>& splits
3865 const Switch implicitFeatureAttraction = snapParams.implicitFeatureSnap();
3866 const Switch explicitFeatureAttraction = snapParams.explicitFeatureSnap();
3867 const Switch multiRegionFeatureSnap = snapParams.multiRegionFeatureSnap();
3869 Info<<
"Overriding displacement on features :" <<
nl
3870 <<
" implicit features : " << implicitFeatureAttraction <<
nl
3871 <<
" explicit features : " << explicitFeatureAttraction <<
nl
3872 <<
" multi-patch features : " << multiRegionFeatureSnap <<
nl
3876 const pointField& localPoints = pp.localPoints();
3877 const fvMesh&
mesh = meshRefiner_.mesh();
3881 const bitSet isPatchMasterPoint
3894 List<List<point>> pointFaceSurfNormals;
3895 List<List<point>> pointFaceDisp;
3896 List<List<point>> pointFaceCentres;
3897 List<labelList> pointFacePatchID;
3903 forAll(pp.localFaces(), facei)
3905 const face&
f = pp.localFaces()[facei];
3908 faceSnapDist[facei] =
max(faceSnapDist[facei], snapDist[
f[fp]]);
3920 labelList faceSurfaceGlobalRegion(pp.size(), -1);
3930 faceSurfaceGlobalRegion
3940 calcNearestFacePointProperties
3947 faceSurfaceGlobalRegion,
3949 pointFaceSurfNormals,
3968 patchAttraction.setSize(localPoints.size());
3969 patchAttraction =
Zero;
3971 patchConstraints.setSize(localPoints.size());
3972 patchConstraints = pointConstraint();
3974 if (implicitFeatureAttraction)
3979 featureAttractionUsingReconstruction
3988 pointFaceSurfNormals,
3998 if (explicitFeatureAttraction)
4001 bool releasePoints =
false;
4002 bool stringFeatures =
false;
4003 bool avoidDiagonal =
false;
4006 releasePoints = snapParams.releasePoints();
4007 stringFeatures = snapParams.stringFeatures();
4008 avoidDiagonal = snapParams.avoidDiagonal();
4018 featureAttractionUsingFeatureEdges
4021 multiRegionFeatureSnap,
4023 snapParams.detectBaffles(),
4024 snapParams.baffleFeaturePoints(),
4038 pointFaceSurfNormals,
4048 if (!alignMeshEdges)
4052 degToRad(snapParams.concaveAngle())
4054 const scalar minAreaRatio = snapParams.minAreaRatio();
4056 Info<<
"Experimental: introducing face splits to avoid rotating"
4057 <<
" mesh edges. Splitting faces when" <<
nl
4058 <<
indent <<
"- angle not concave by more than "
4059 << snapParams.concaveAngle() <<
" degrees" <<
nl
4060 <<
indent <<
"- resulting triangles of similar area "
4061 <<
" (ratio within " << minAreaRatio <<
")" <<
nl
4082 Info<<
"Diagonal attraction feature correction : ";
4083 writeStats(pp, isPatchMasterPoint, patchConstraints);
4115 <<
" avg:" << avgPatchDisp <<
endl
4116 <<
" feature : max:" <<
gMaxMagSqr(patchAttraction)
4117 <<
" avg:" << avgPatchAttr <<
endl;
4131 forAll(patchConstraints, pointi)
4133 if (patchConstraints[pointi].first() > 1)
4136 (1.0-featureAttract)*patchDisp[pointi]
4137 + featureAttract*patchAttraction[pointi];
4145 Info<<
"Feature analysis : ";
4146 writeStats(pp, isPatchMasterPoint, patchConstraints);
4161 if (featureAttract < 1-0.001)
4168 const bitSet isPatchMasterEdge
4200 tangPatchDisp -= (pointNormals & patchDisp) * pointNormals;
4211 tangPatchDisp += (pointNormals & patchDisp) * pointNormals;
4218 /
"tangPatchDispConstrained_" +
name(iter) +
".obj",
4220 pp.localPoints() + tangPatchDisp
4225 (1.0-featureAttract)*smoothedPatchDisp
4226 + featureAttract*tangPatchDisp;
4230 const scalar
relax = featureAttract;
4241 minMagSqrEqOp<point>(),
4242 vector(GREAT, GREAT, GREAT)