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
279 allGeometry_(allGeometry),
281 locationInMesh_(surfaceConformationDict.get<
point>(
"locationInMesh")),
283 allGeometryToSurfaces_(),
284 normalVolumeTypes_(),
290 referenceVolumeTypes_(0)
292 const dictionary& surfacesDict
294 surfaceConformationDict.subDict(
"geometryToConformTo")
297 const dictionary& additionalFeaturesDict
299 surfaceConformationDict.subDict(
"additionalFeatures")
308 for (
const word& geomName : allGeometry_.names())
310 if (surfacesDict.found(geomName))
316 const label nAddFeat = additionalFeaturesDict.size();
318 Info<<
nl <<
"Reading geometryToConformTo" <<
endl;
320 allGeometryToSurfaces_.setSize(allGeometry_.size(), -1);
322 normalVolumeTypes_.setSize(surfI);
323 surfaces_.setSize(surfI);
324 surfZones_.setSize(surfI);
327 features_.setSize(surfI + nAddFeat);
331 regionOffset_.setSize(surfI, 0);
333 PtrList<dictionary> globalPatchInfo(surfI);
334 List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
335 List<sideVolumeType> globalVolumeTypes(surfI);
336 List<Map<sideVolumeType>> regionVolumeTypes(surfI);
341 forAll(allGeometry_.names(), geomI)
343 const word& geomName = allGeometry_.names()[geomI];
345 const entry* ePtr = surfacesDict.findEntry(geomName,
keyType::REGEX);
349 const dictionary&
dict = ePtr->dict();
350 unmatchedKeys.
erase(ePtr->keyword());
352 surfaces_[surfI] = geomI;
354 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
366 allGeometry_.regionNames()[surfaces_[surfI]]
371 allGeometryToSurfaces_[surfaces_[surfI]] = surfI;
376 allGeometry_.regionNames()[surfaces_[surfI]];
378 patchNames_.
append(regionNames);
380 globalVolumeTypes[surfI] =
392 if (!globalVolumeTypes[surfI])
394 if (!surface.hasVolumeType())
397 <<
"Non-baffle surface "
399 <<
" does not allow inside/outside queries."
400 <<
" This usually is an error." <<
endl;
422 const wordList& rNames = surface.regions();
426 const dictionary& regionsDict =
dict.
subDict(
"regions");
437 const dictionary& regionDict = regionsDict.subDict
442 if (regionDict.found(
"patchInfo"))
444 regionPatchInfo[surfI].insert
447 regionDict.subDict(
"patchInfo").clone()
451 regionVolumeTypes[surfI].insert
456 regionDict.getOrDefault<word>
459 extendedFeatureEdgeMesh::
462 globalVolumeTypes[surfI]
468 readFeatures(regionDict,
regionName, featureI);
478 if (unmatchedKeys.size() > 0)
481 <<
"Not all entries in conformationSurfaces dictionary were used."
482 <<
" The following entries were not used : "
483 << unmatchedKeys.sortedToc()
493 regionOffset_[surfI] = nRegions;
495 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
496 nRegions += surface.regions().size();
500 patchInfo_.setSize(nRegions);
501 normalVolumeTypes_.setSize(nRegions);
505 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
507 label nRegions = surface.regions().size();
510 for (label i = 0; i < nRegions; i++)
512 label globalRegionI = regionOffset_[surfI] + i;
513 normalVolumeTypes_[globalRegionI] = globalVolumeTypes[surfI];
514 if (globalPatchInfo.set(surfI))
519 globalPatchInfo[surfI].clone()
526 label globalRegionI = regionOffset_[surfI] + iter.key();
528 normalVolumeTypes_[globalRegionI] =
529 regionVolumeTypes[surfI][iter.key()];
532 const Map<autoPtr<dictionary>>& localInfo = regionPatchInfo[surfI];
535 label globalRegionI = regionOffset_[surfI] + iter.key();
537 patchInfo_.set(globalRegionI, iter()().clone());
543 if (!additionalFeaturesDict.empty())
545 Info<<
nl <<
"Reading additionalFeatures" <<
endl;
548 for (
const entry& dEntry : additionalFeaturesDict)
550 const word& featureName = dEntry.keyword();
551 const dictionary& featureSubDict = dEntry.dict();
555 readFeatures(featureSubDict, featureName, featureI);
559 features_.setSize(featureI);
561 globalBounds_ = treeBoundBox
570 vector newSpan = 1
e-4*globalBounds_.span();
572 globalBounds_.min() -= newSpan;
573 globalBounds_.max() += newSpan;
579 referenceVolumeTypes_.setSize
586 <<
"Testing for locationInMesh " << locationInMesh_ <<
endl;
588 hasBoundedVolume(referenceVolumeTypes_);
592 Info<<
"Names = " << allGeometry_.names() <<
endl;
593 Info<<
"Surfaces = " << surfaces_ <<
endl;
594 Info<<
"AllGeom to Surfaces = " << allGeometryToSurfaces_ <<
endl;
595 Info<<
"Volume types = " << normalVolumeTypes_ <<
endl;
596 Info<<
"Patch names = " << patchNames_ <<
endl;
597 Info<<
"Region Offset = " << regionOffset_ <<
endl;
601 Info<< features_[fI].name() <<
endl;
613 if (allGeometry_[surfaces_[
s]].
overlaps(bb))
634 const point& samplePt
652 const point& samplePt
664 const bool testForInside
667 List<List<volumeType>> surfaceVolumeTests
680 const searchableSurface& surface(allGeometry_[surfaces_[
s]]);
682 const label regionI = regionOffset_[
s];
686 surface.getVolumeType(samplePts, surfaceVolumeTests[
s]);
695 Field<bool> insideOutsidePoint(samplePts.size(), testForInside);
700 List<pointIndexHit> hitInfo;
719 insideOutsidePoint[i] =
false;
726 const label regionI = regionOffset_[
s];
733 const searchableSurface& surface(allGeometry_[surfaces_[
s]]);
737 !surface.hasVolumeType()
743 List<pointIndexHit> info;
745 surface.findNearest(sample, nearestDistSqr, info);
750 info[0].rawPoint() - samplePts[i]
756 findSurfaceNearestIntersection
759 info[0].rawPoint() - 1
e-3*
mag(hitDir)*hitDir,
764 if (surfHit.hit() && hitSurface != surfaces_[
s])
774 normalVolumeTypes_[regionI]
778 insideOutsidePoint[i] = !testForInside;
786 normalVolumeTypes_[regionI]
790 insideOutsidePoint[i] = !testForInside;
797 return insideOutsidePoint;
807 return wellInOutSide(samplePts, testDistSqr,
true);
813 const point& samplePt,
827 return wellInOutSide(samplePts, testDistSqr,
false);
833 const point& samplePt,
848 List<pointIndexHit> hitInfo;
860 return hitInfo[0].hit();
873 List<pointIndexHit> hitInfo;
885 surfHit = hitInfo[0];
893 hitSurface = surfaces_[hitSurfaces[0]];
902 List<pointIndexHit>& surfHit,
907 List<List<pointIndexHit>> hitInfo;
919 surfHit = hitInfo[0];
921 hitSurface.setSize(hitSurfaces[0].size());
923 forAll(hitSurfaces[0], surfI)
929 hitSurface[surfI] = surfaces_[hitSurfaces[0][surfI]];
943 List<pointIndexHit> hitInfoStart;
945 List<pointIndexHit> hitInfoEnd;
959 surfHit = hitInfoStart[0];
967 hitSurface = surfaces_[hitSurfacesStart[0]];
975 scalar nearestDistSqr,
981 List<pointIndexHit> surfaceHits;
993 surfHit = surfaceHits[0];
1001 hitSurface = surfaces_[hitSurfaces[0]];
1010 List<pointIndexHit>& surfaceHits,
1026 if (surfaceHits[i].hit())
1032 hitSurfaces[i] = surfaces_[hitSurfaces[i]];
1040 const point& sample,
1041 scalar nearestDistSqr,
1047 scalar minDistSqr = nearestDistSqr;
1052 features_[testI].nearestFeaturePoint
1061 minDistSqr =
magSqr(hitInfo.hitPoint()- sample);
1071 const point& sample,
1072 scalar nearestDistSqr,
1080 List<pointIndexHit> edgeHits;
1091 edgeHit = edgeHits[0];
1092 featureHit = featuresHit[0];
1100 List<pointIndexHit>& edgeHits,
1105 featuresHit.setSize(
samples.size());
1107 edgeHits.setSize(
samples.size());
1111 List<pointIndexHit> hitInfo(
samples.size());
1115 features_[testI].nearestFeatureEdge
1125 if (hitInfo[pointi].hit())
1127 minDistSqr[pointi] =
magSqr
1129 hitInfo[pointi].hitPoint()
1132 edgeHits[pointi] = hitInfo[pointi];
1133 featuresHit[pointi] = testI;
1142 const point& sample,
1143 scalar nearestDistSqr,
1144 List<pointIndexHit>& edgeHits,
1145 List<label>& featuresHit
1159 features_[testI].nearestFeatureEdgeByType
1169 if (hitInfo[typeI].hit())
1171 minDistSqr[typeI] =
magSqr(hitInfo[typeI].hitPoint() - sample);
1172 edgeHits[typeI] = hitInfo[typeI];
1173 featuresHit[typeI] = testI;
1182 const point& sample,
1183 const scalar searchRadiusSqr,
1184 List<List<pointIndexHit>>& edgeHitsByFeature,
1185 List<label>& featuresHit
1198 features_[testI].allNearestFeatureEdges
1205 bool anyHit =
false;
1208 if (hitInfo[hitI].hit())
1216 edgeHitsByFeature.append(hitInfo);
1217 featuresHit.append(testI);
1225 OFstream ftStr(runTime_.time().path()/prefix +
"_allFeatures.obj");
1227 Pout<<
nl <<
"Writing all features to " << ftStr.name() <<
endl;
1233 const extendedFeatureEdgeMesh& fEM(features_[i]);
1237 ftStr <<
"g " << fEM.name() <<
endl;
1241 const edge&
e = eds[j];
1245 ftStr <<
"l " << verti-1 <<
' ' << verti <<
endl;
1260 findSurfaceAnyIntersection(ptA, ptB, surfHit, hitSurface);
1262 return getPatchID(hitSurface, surfHit);
1271 findSurfaceNearest(pt,
sqr(GREAT), surfHit, hitSurface);
1273 return getPatchID(hitSurface, surfHit);
1279 const label hitSurface,
1290 allGeometry_[hitSurface].getRegion
1292 List<pointIndexHit>(1, surfHit),
1298 + regionOffset_[allGeometryToSurfaces_[hitSurface]];
1307 const label hitSurface,
1311 const label
patchID = getPatchID(hitSurface, surfHit);
1318 return normalVolumeTypes_[
patchID];
1324 const label hitSurface,
1325 const List<pointIndexHit>& surfHit,
1329 allGeometry_[hitSurface].getNormal(surfHit, normal);
1331 const label
patchID = regionOffset_[allGeometryToSurfaces_[hitSurface]];