44 void Foam::conformationSurfaces::hasBoundedVolume
46 List<volumeType>& referenceVolumeTypes
50 label totalTriangles = 0;
54 const searchableSurface& surface(allGeometry_[surfaces_[
s]]);
58 surface.hasVolumeType()
60 normalVolumeTypes_[regionOffset_[
s]]
67 List<volumeType> vTypes
73 surface.getVolumeType(pts, vTypes);
75 referenceVolumeTypes[
s] = vTypes[0];
77 Info<<
" is " << referenceVolumeTypes[
s].str()
78 <<
" surface " << surface.name()
82 if (isA<triSurface>(surface))
84 const triSurface& triSurf = refCast<const triSurface>(surface);
88 Info<<
" Checking " << surface.name() <<
endl;
92 Info<<
" Index = " << surfaces_[
s] <<
endl;
93 Info<<
" Offset = " << regionOffset_[
s] <<
endl;
95 for (
const labelledTri&
f : triSurf)
97 const label
patchID =
f.region() + regionOffset_[
s];
106 sum +=
f.areaNormal(surfPts);
113 Info<<
" has " << nBaffles <<
" baffles out of "
114 << triSurf.size() <<
" triangles" <<
nl;
116 totalTriangles += triSurf.size();
120 Info<<
" Sum of all the surface normals (if near zero, surface is"
121 <<
" probably closed):" <<
nl
122 <<
" Note: Does not include baffle surfaces in calculation" <<
nl
123 <<
" Sum = " <<
sum/(totalTriangles + SMALL) <<
nl
124 <<
" mag(Sum) = " <<
mag(
sum)/(totalTriangles + SMALL)
129 void Foam::conformationSurfaces::readFeatures
132 const dictionary& featureDict,
133 const word& surfaceName,
137 const word featureMethod =
138 featureDict.getOrDefault<word>(
"featureMethod",
"none");
140 if (featureMethod ==
"extendedFeatureEdgeMesh")
144 featureDict.get<fileName>(
"extendedFeatureEdgeMesh")
147 Info<<
" features: " << feMeshName <<
endl;
152 new extendedFeatureEdgeMesh
157 runTime_.time().constant(),
158 "extendedFeatureEdgeMesh",
168 else if (featureMethod ==
"extractFeatures")
170 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
172 Info<<
" features: " << surface.name()
173 <<
" of type " << surface.type()
174 <<
", id: " << featureIndex <<
endl;
176 autoPtr<searchableSurfaceFeatures> ssFeatures
181 if (ssFeatures().hasFeatures())
186 ssFeatures().features()
194 << surface.name() <<
" of type "
195 << surface.type() <<
" does not have features"
199 else if (featureMethod ==
"none")
206 <<
"No valid featureMethod found for surface " << surfaceName
207 <<
nl <<
"Use \"extendedFeatureEdgeMesh\" "
208 <<
"or \"extractFeatures\"."
213 void Foam::conformationSurfaces::readFeatures
215 const dictionary& featureDict,
216 const word& surfaceName,
220 const word featureMethod =
221 featureDict.getOrDefault<word>(
"featureMethod",
"none");
223 if (featureMethod ==
"extendedFeatureEdgeMesh")
227 featureDict.get<fileName>(
"extendedFeatureEdgeMesh")
230 Info<<
" features: " << feMeshName <<
", id: " << featureIndex
236 new extendedFeatureEdgeMesh
241 runTime_.time().constant(),
242 "extendedFeatureEdgeMesh",
252 else if (featureMethod ==
"none")
259 <<
"No valid featureMethod found for surface " << surfaceName
260 <<
nl <<
"Use \"extendedFeatureEdgeMesh\" "
261 <<
"or \"extractFeatures\"."
269 Foam::conformationSurfaces::conformationSurfaces
273 const searchableSurfaces& allGeometry,
274 const dictionary& surfaceConformationDict
278 allGeometry_(allGeometry),
280 locationInMesh_(surfaceConformationDict.
get<
point>(
"locationInMesh")),
282 allGeometryToSurfaces_(),
283 normalVolumeTypes_(),
289 referenceVolumeTypes_()
291 const dictionary& surfacesDict
293 surfaceConformationDict.subDict(
"geometryToConformTo")
296 const dictionary& additionalFeaturesDict
298 surfaceConformationDict.subDict(
"additionalFeatures")
307 for (
const word& geomName : allGeometry_.names())
309 if (surfacesDict.found(geomName))
315 const label nAddFeat = additionalFeaturesDict.size();
317 Info<<
nl <<
"Reading geometryToConformTo" <<
endl;
319 allGeometryToSurfaces_.setSize(allGeometry_.size(), -1);
321 normalVolumeTypes_.setSize(surfI);
322 surfaces_.setSize(surfI);
323 surfZones_.setSize(surfI);
326 features_.setSize(surfI + nAddFeat);
330 regionOffset_.setSize(surfI, 0);
332 PtrList<dictionary> globalPatchInfo(surfI);
333 List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
334 List<sideVolumeType> globalVolumeTypes(surfI);
335 List<Map<sideVolumeType>> regionVolumeTypes(surfI);
340 forAll(allGeometry_.names(), geomI)
342 const word& geomName = allGeometry_.names()[geomI];
344 const entry* ePtr = surfacesDict.findEntry(geomName,
keyType::REGEX);
348 const dictionary&
dict = ePtr->dict();
349 unmatchedKeys.
erase(ePtr->keyword());
351 surfaces_[surfI] = geomI;
353 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
365 allGeometry_.regionNames()[surfaces_[surfI]]
370 allGeometryToSurfaces_[surfaces_[surfI]] = surfI;
375 allGeometry_.regionNames()[surfaces_[surfI]];
379 globalVolumeTypes[surfI] =
391 if (!globalVolumeTypes[surfI])
393 if (!surface.hasVolumeType())
396 <<
"Non-baffle surface "
398 <<
" does not allow inside/outside queries."
399 <<
" This usually is an error." <<
endl;
421 const wordList& rNames = surface.regions();
425 const dictionary& regionsDict =
dict.
subDict(
"regions");
436 const dictionary& regionDict = regionsDict.subDict
441 if (regionDict.found(
"patchInfo"))
443 regionPatchInfo[surfI].insert
446 regionDict.subDict(
"patchInfo").clone()
450 regionVolumeTypes[surfI].insert
455 regionDict.getOrDefault<word>
458 extendedFeatureEdgeMesh::
461 globalVolumeTypes[surfI]
467 readFeatures(regionDict,
regionName, featureI);
477 if (unmatchedKeys.size() > 0)
480 <<
"Not all entries in conformationSurfaces dictionary were used."
481 <<
" The following entries were not used : "
482 << unmatchedKeys.sortedToc()
492 regionOffset_[surfI] = nRegions;
494 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
495 nRegions += surface.regions().size();
499 patchInfo_.setSize(nRegions);
500 normalVolumeTypes_.setSize(nRegions);
504 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
506 label nRegions = surface.regions().size();
509 for (label i = 0; i < nRegions; i++)
511 label globalRegionI = regionOffset_[surfI] + i;
512 normalVolumeTypes_[globalRegionI] = globalVolumeTypes[surfI];
513 if (globalPatchInfo.set(surfI))
518 globalPatchInfo[surfI].clone()
525 label globalRegionI = regionOffset_[surfI] + iter.key();
527 normalVolumeTypes_[globalRegionI] =
528 regionVolumeTypes[surfI][iter.key()];
531 const Map<autoPtr<dictionary>>& localInfo = regionPatchInfo[surfI];
534 label globalRegionI = regionOffset_[surfI] + iter.key();
536 patchInfo_.set(globalRegionI, iter()().clone());
542 if (!additionalFeaturesDict.empty())
544 Info<<
nl <<
"Reading additionalFeatures" <<
endl;
547 for (
const entry& dEntry : additionalFeaturesDict)
549 const word& featureName = dEntry.keyword();
550 const dictionary& featureSubDict = dEntry.dict();
554 readFeatures(featureSubDict, featureName, featureI);
558 features_.setSize(featureI);
560 globalBounds_ = treeBoundBox
569 vector newSpan = 1
e-4*globalBounds_.span();
571 globalBounds_.min() -= newSpan;
572 globalBounds_.max() += newSpan;
578 referenceVolumeTypes_.setSize
585 <<
"Testing for locationInMesh " << locationInMesh_ <<
endl;
587 hasBoundedVolume(referenceVolumeTypes_);
591 Info<<
"Names = " << allGeometry_.names() <<
endl;
592 Info<<
"Surfaces = " << surfaces_ <<
endl;
593 Info<<
"AllGeom to Surfaces = " << allGeometryToSurfaces_ <<
endl;
594 Info<<
"Volume types = " << normalVolumeTypes_ <<
endl;
595 Info<<
"Patch names = " << patchNames_ <<
endl;
596 Info<<
"Region Offset = " << regionOffset_ <<
endl;
600 Info<< features_[fI].name() <<
endl;
612 if (allGeometry_[surfaces_[
s]].
overlaps(bb))
633 const point& samplePt
651 const point& samplePt
663 const bool testForInside
666 List<List<volumeType>> surfaceVolumeTests
679 const searchableSurface& surface(allGeometry_[surfaces_[
s]]);
681 const label regionI = regionOffset_[
s];
685 surface.getVolumeType(samplePts, surfaceVolumeTests[
s]);
694 Field<bool> insideOutsidePoint(samplePts.size(), testForInside);
699 List<pointIndexHit> hitInfo;
718 insideOutsidePoint[i] =
false;
725 const label regionI = regionOffset_[
s];
732 const searchableSurface& surface(allGeometry_[surfaces_[
s]]);
736 !surface.hasVolumeType()
742 List<pointIndexHit> info;
744 surface.findNearest(
sample, nearestDistSqr, info);
749 info[0].rawPoint() - samplePts[i]
755 findSurfaceNearestIntersection
758 info[0].rawPoint() - 1
e-3*
mag(hitDir)*hitDir,
763 if (surfHit.hit() && hitSurface != surfaces_[
s])
773 normalVolumeTypes_[regionI]
777 insideOutsidePoint[i] = !testForInside;
785 normalVolumeTypes_[regionI]
789 insideOutsidePoint[i] = !testForInside;
796 return insideOutsidePoint;
806 return wellInOutSide(samplePts, testDistSqr,
true);
812 const point& samplePt,
826 return wellInOutSide(samplePts, testDistSqr,
false);
832 const point& samplePt,
847 List<pointIndexHit> hitInfo;
859 return hitInfo[0].hit();
872 List<pointIndexHit> hitInfo;
884 surfHit = hitInfo[0];
892 hitSurface = surfaces_[hitSurfaces[0]];
901 List<pointIndexHit>& surfHit,
906 List<List<pointIndexHit>> hitInfo;
918 surfHit = hitInfo[0];
920 hitSurface.setSize(hitSurfaces[0].size());
922 forAll(hitSurfaces[0], surfI)
928 hitSurface[surfI] = surfaces_[hitSurfaces[0][surfI]];
942 List<pointIndexHit> hitInfoStart;
944 List<pointIndexHit> hitInfoEnd;
958 surfHit = hitInfoStart[0];
966 hitSurface = surfaces_[hitSurfacesStart[0]];
974 scalar nearestDistSqr,
980 List<pointIndexHit> surfaceHits;
992 surfHit = surfaceHits[0];
1000 hitSurface = surfaces_[hitSurfaces[0]];
1009 List<pointIndexHit>& surfaceHits,
1025 if (surfaceHits[i].hit())
1031 hitSurfaces[i] = surfaces_[hitSurfaces[i]];
1040 scalar nearestDistSqr,
1046 scalar minDistSqr = nearestDistSqr;
1051 features_[testI].nearestFeaturePoint
1071 scalar nearestDistSqr,
1079 List<pointIndexHit> edgeHits;
1090 edgeHit = edgeHits[0];
1091 featureHit = featuresHit[0];
1099 List<pointIndexHit>& edgeHits,
1104 featuresHit.setSize(
samples.size());
1106 edgeHits.setSize(
samples.size());
1110 List<pointIndexHit> hitInfo(
samples.size());
1114 features_[testI].nearestFeatureEdge
1124 if (hitInfo[pointi].hit())
1126 minDistSqr[pointi] =
magSqr
1128 hitInfo[pointi].hitPoint()
1131 edgeHits[pointi] = hitInfo[pointi];
1132 featuresHit[pointi] = testI;
1142 scalar nearestDistSqr,
1143 List<pointIndexHit>& edgeHits,
1144 List<label>& featuresHit
1158 features_[testI].nearestFeatureEdgeByType
1168 if (hitInfo[typeI].hit())
1170 minDistSqr[typeI] =
magSqr(hitInfo[typeI].hitPoint() -
sample);
1171 edgeHits[typeI] = hitInfo[typeI];
1172 featuresHit[typeI] = testI;
1182 const scalar searchRadiusSqr,
1183 List<List<pointIndexHit>>& edgeHitsByFeature,
1184 List<label>& featuresHit
1197 features_[testI].allNearestFeatureEdges
1204 bool anyHit =
false;
1207 if (hitInfo[hitI].hit())
1215 edgeHitsByFeature.append(hitInfo);
1216 featuresHit.append(testI);
1224 OFstream ftStr(runTime_.time().path()/prefix +
"_allFeatures.obj");
1226 Pout<<
nl <<
"Writing all features to " << ftStr.name() <<
endl;
1232 const extendedFeatureEdgeMesh& fEM(features_[i]);
1236 ftStr <<
"g " << fEM.name() <<
endl;
1240 const edge&
e = eds[j];
1244 ftStr <<
"l " << verti-1 <<
' ' << verti <<
endl;
1259 findSurfaceAnyIntersection(ptA, ptB, surfHit, hitSurface);
1261 return getPatchID(hitSurface, surfHit);
1270 findSurfaceNearest(pt,
sqr(GREAT), surfHit, hitSurface);
1272 return getPatchID(hitSurface, surfHit);
1278 const label hitSurface,
1289 allGeometry_[hitSurface].getRegion
1291 List<pointIndexHit>(1, surfHit),
1297 + regionOffset_[allGeometryToSurfaces_[hitSurface]];
1306 const label hitSurface,
1310 const label
patchID = getPatchID(hitSurface, surfHit);
1317 return normalVolumeTypes_[
patchID];
1323 const label hitSurface,
1324 const List<pointIndexHit>& surfHit,
1328 allGeometry_[hitSurface].getNormal(surfHit, normal);
1330 const label
patchID = regionOffset_[allGeometryToSurfaces_[hitSurface]];