36 void Foam::shortEdgeFilter2D::addRegion
39 DynamicList<label>& bPointRegions
42 if (bPointRegions.empty())
44 bPointRegions.append(regionI);
46 else if (
findIndex(bPointRegions, regionI) == -1)
48 bPointRegions.append(regionI);
53 void Foam::shortEdgeFilter2D::assignBoundaryPointRegions
55 List<DynamicList<label>>& boundaryPointRegions
60 const edge& e = iter.key();
61 const label& regionI = iter();
63 const label startI = e.start();
64 const label endI = e.end();
66 addRegion(regionI, boundaryPointRegions[startI]);
67 addRegion(regionI, boundaryPointRegions[endI]);
72 void Foam::shortEdgeFilter2D::updateEdgeRegionMap
74 const MeshedSurface<face>& surfMesh,
75 const List<DynamicList<label>>& boundaryPtRegions,
77 EdgeMap<label>& mapEdgesRegion,
81 EdgeMap<label> newMapEdgesRegion(mapEdgesRegion.size());
83 const edgeList& edges = surfMesh.edges();
84 const labelList& meshPoints = surfMesh.meshPoints();
86 patchSizes.
setSize(patchNames_.size(), 0);
91 if (surfMesh.isInternalEdge(edgeI))
96 const edge& e = edges[edgeI];
98 const label startI = meshPoints[e[0]];
99 const label endI = meshPoints[e[1]];
103 const DynamicList<label> startPtRegions =
104 boundaryPtRegions[surfPtToBoundaryPt[startI]];
105 const DynamicList<label> endPtRegions =
106 boundaryPtRegions[surfPtToBoundaryPt[endI]];
108 if (startPtRegions.size() > 1 && endPtRegions.size() > 1)
110 region = startPtRegions[0];
113 <<
"Both points in edge are in different regions." 114 <<
" Assigning edge to region " << region
117 else if (startPtRegions.size() > 1 || endPtRegions.size() > 1)
121 startPtRegions.size() > 1
128 startPtRegions[0] == endPtRegions[0]
129 && startPtRegions[0] != -1
132 region = startPtRegions[0];
137 newMapEdgesRegion.insert(e, region);
138 patchSizes[region]++;
142 mapEdgesRegion.transfer(newMapEdgesRegion);
148 Foam::shortEdgeFilter2D::shortEdgeFilter2D
151 const dictionary& dict
156 edgeAttachedToBoundaryFactor_
158 dict.lookupOrDefault<scalar>(
"edgeAttachedToBoundaryFactor", 2.0)
181 points[ip] = cv2Dmesh.
toPoint3D(points2D[ip]);
186 OFstream str(
"indirectPatchEdges.obj");
189 Info<<
"Writing indirectPatchEdges to " << str.name() <<
endl;
193 const edge& e = iter.key();
209 Info<<
"Meshed surface stats before edge filtering :" <<
endl;
210 ms_.writeStats(
Info);
216 ms_.write(
"MeshedSurface_preFilter.obj");
234 const edgeList& edges = ms_.edges();
235 const faceList& faces = ms_.faces();
236 const labelList& meshPoints = ms_.meshPoints();
237 const labelList& boundaryPoints = ms_.boundaryPoints();
240 label nPointsToRemove = 0;
242 labelList pointsToRemove(ms_.points().size(), -1);
245 labelList newFaceVertexCount(faces.size(), -1);
248 newFaceVertexCount[facei] = faces[facei].size();
253 List<DynamicList<label>> boundaryPointRegions
258 assignBoundaryPointRegions(boundaryPointRegions);
262 Info<<
" Marking edges attached to boundaries." <<
endl;
263 boolList edgeAttachedToBoundary(edges.size(),
false);
266 const edge& e = edges[edgeI];
267 const label startVertex = e.start();
268 const label endVertex = e.end();
270 forAll(boundaryPoints, bPoint)
274 boundaryPoints[bPoint] == startVertex
275 || boundaryPoints[bPoint] == endVertex
278 edgeAttachedToBoundary[edgeI] =
true;
285 const edge& e = edges[edgeI];
288 const label startVertex = e.start();
289 const label endVertex = e.end();
294 points[meshPoints[startVertex]]
295 - points[meshPoints[endVertex]]
298 if (edgeAttachedToBoundary[edgeI])
300 edgeLength *= edgeAttachedToBoundaryFactor_;
303 scalar shortEdgeFilterValue = 0.0;
305 const labelList& psEdges = ms_.pointEdges()[startVertex];
306 const labelList& peEdges = ms_.pointEdges()[endVertex];
310 const edge& psE = edges[psEdges[psEdgeI]];
311 if (edgeI != psEdges[psEdgeI])
313 shortEdgeFilterValue +=
316 points[meshPoints[psE.start()]]
317 - points[meshPoints[psE.end()]]
324 const edge& peE = edges[peEdges[peEdgeI]];
325 if (edgeI != peEdges[peEdgeI])
327 shortEdgeFilterValue +=
330 points[meshPoints[peE.start()]]
331 - points[meshPoints[peE.end()]]
336 shortEdgeFilterValue *=
337 shortEdgeFilterFactor_
338 /(psEdges.size() + peEdges.size() - 2);
340 edge lookupInPatchEdge
342 meshPoints[startVertex],
343 meshPoints[endVertex]
348 edgeLength < shortEdgeFilterValue
349 || indirectPatchEdge_.found(lookupInPatchEdge)
352 bool flagDegenerateFace =
false;
353 const labelList& pFaces = ms_.pointFaces()[startVertex];
357 const face& f = ms_.localFaces()[pFaces[pFacei]];
361 if (f[fp] == endVertex)
364 if (newFaceVertexCount[pFaces[pFacei]] < 4)
366 flagDegenerateFace =
true;
370 newFaceVertexCount[pFaces[pFacei]]--;
377 if (newFaceVertexCount[pFaces[pFacei]] < 3)
379 flagDegenerateFace =
true;
388 pointsToRemove[meshPoints[startVertex]] == -1
389 && pointsToRemove[meshPoints[endVertex]] == -1
390 && !flagDegenerateFace
393 const DynamicList<label>& startVertexRegions =
394 boundaryPointRegions[meshPoints[startVertex]];
395 const DynamicList<label>& endVertexRegions =
396 boundaryPointRegions[meshPoints[endVertex]];
398 if (startVertexRegions.size() && endVertexRegions.size())
400 if (startVertexRegions.size() > 1)
402 pointsToRemove[meshPoints[endVertex]] =
403 meshPoints[startVertex];
407 pointsToRemove[meshPoints[startVertex]] =
408 meshPoints[endVertex];
411 else if (startVertexRegions.size())
413 pointsToRemove[meshPoints[endVertex]] =
414 meshPoints[startVertex];
418 pointsToRemove[meshPoints[startVertex]] =
419 meshPoints[endVertex];
427 label totalNewPoints = points.size() - nPointsToRemove;
430 labelList newPointNumbers(points.size(), -1);
431 label numberRemoved = 0;
434 labelList newPtToOldPt(totalNewPoints, -1);
439 if (pointsToRemove[pointi] == -1)
441 newPoints[pointi - numberRemoved] = points[pointi];
442 newPointNumbers[pointi] = pointi - numberRemoved;
443 newPtToOldPt[pointi - numberRemoved] = pointi;
456 label newFaceSize = 0;
461 const face& f = faces[facei];
464 newFace.setSize(f.size());
469 label pointi = f[fp];
471 if (pointsToRemove[pointi] == -1)
473 newFace[newFaceSize++] = newPointNumbers[pointi];
477 label newPointi = pointsToRemove[pointi];
482 f.nextLabel(fp) != newPointi
487 label totalChain = 0;
488 for (
label nChain = 0; nChain <= totalChain; ++nChain)
490 if (newPointNumbers[pChain] != -1)
492 newFace[newFaceSize++] = newPointNumbers[pChain];
493 newPointNumbers[pointi] = newPointNumbers[pChain];
494 maxChain =
max(totalChain, maxChain);
499 <<
"Point " << pChain
500 <<
" marked for deletion as well as point " 502 <<
" Incrementing maxChain by 1 from " 503 << totalChain <<
" to " << totalChain + 1
507 pChain = pointsToRemove[pChain];
512 if (newPointNumbers[newPointi] != -1)
514 newPointNumbers[pointi] = newPointNumbers[
newPointi];
520 newFace.setSize(newFaceSize);
522 if (newFace.size() > 2)
524 newFaces[newFacei++] = face(newFace);
529 <<
"Only " << newFace.size() <<
" in face " << facei
534 newFaces.setSize(newFacei);
536 MeshedSurface<face> fMesh
546 boundaryPointRegions,
552 forAll(newPointNumbers, pointi)
554 if (newPointNumbers[pointi] == -1)
557 << pointi <<
" will be deleted and " << newPointNumbers[pointi]
558 <<
", so it will not be replaced. " 559 <<
"This will cause edges to be deleted." <<
endl;
567 Info<<
" Maximum number of chained collapses = " << maxChain <<
endl;
576 os <<
"Short Edge Filtering Information:" <<
nl 577 <<
" shortEdgeFilterFactor: " << shortEdgeFilterFactor_ <<
nl 578 <<
" edgeAttachedToBoundaryFactor: " << edgeAttachedToBoundaryFactor_
583 os <<
" Patch " << patchNames_[
patchi]
587 os <<
" There are " << mapEdgesRegion_.size()
588 <<
" boundary edges." <<
endl;
590 os <<
" Mesh Info:" <<
nl 591 <<
" Points: " << ms_.nPoints() <<
nl 592 <<
" Faces: " << ms_.size() <<
nl 593 <<
" Edges: " << ms_.nEdges() <<
nl 594 <<
" Internal: " << ms_.nInternalEdges() <<
nl 595 <<
" External: " << ms_.nEdges() - ms_.nInternalEdges()
~shortEdgeFilter2D()
Destructor.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Ostream & endl(Ostream &os)
Add newline and flush stream.
point toPoint3D(const point2D &) const
Xfer< T > xferCopy(const T &)
Construct by copying the contents of the arg.
List< bool > boolList
Bool container classes.
vectorField pointField
pointField is a vectorField.
stressControl lookup("compactNormalStress") >> compactNormalStress
void calcDual(point2DField &dualPoints, faceList &dualFaces, wordList &patchNames, labelList &patchSizes, EdgeMap< label > &mapEdgesRegion, EdgeMap< label > &indirectPatchEdge) const
Calculates dual points (circumcentres of tets) and faces.
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
List< label > labelList
A List of labels.
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
vector2DField point2DField
point2DField is a vector2DField.
List< word > wordList
A List of words.
void setSize(const label)
Reset size of List.
#define WarningInFunction
Report a warning using Foam::Warning.
dimensioned< scalar > mag(const dimensioned< Type > &)
Conformal-Voronoi 2D automatic mesher with grid or read initial points and point position relaxation ...
void writeInfo(Ostream &os)