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);
151 const dictionary& dict
154 shortEdgeFilterFactor_(dict.
lookup<scalar>(
"shortEdgeFilterFactor")),
155 edgeAttachedToBoundaryFactor_
157 dict.lookupOrDefault<scalar>(
"edgeAttachedToBoundaryFactor", 2.0)
180 points[ip] = cv2Dmesh.
toPoint3D(points2D[ip]);
185 OFstream str(
"indirectPatchEdges.obj");
188 Info<<
"Writing indirectPatchEdges to " << str.name() <<
endl;
192 const edge& e = iter.key();
206 ms_ = MeshedSurface<face>(move(points), move(faces));
208 Info<<
"Meshed surface stats before edge filtering :" <<
endl;
209 ms_.writeStats(
Info);
215 ms_.write(
"MeshedSurface_preFilter.obj");
233 const edgeList& edges = ms_.edges();
234 const faceList& faces = ms_.faces();
235 const labelList& meshPoints = ms_.meshPoints();
236 const labelList& boundaryPoints = ms_.boundaryPoints();
239 label nPointsToRemove = 0;
241 labelList pointsToRemove(ms_.points().size(), -1);
244 labelList newFaceVertexCount(faces.size(), -1);
247 newFaceVertexCount[facei] = faces[facei].size();
252 List<DynamicList<label>> boundaryPointRegions
257 assignBoundaryPointRegions(boundaryPointRegions);
261 Info<<
" Marking edges attached to boundaries." <<
endl;
262 boolList edgeAttachedToBoundary(edges.size(),
false);
265 const edge& e = edges[edgeI];
266 const label startVertex = e.start();
267 const label endVertex = e.end();
269 forAll(boundaryPoints, bPoint)
273 boundaryPoints[bPoint] == startVertex
274 || boundaryPoints[bPoint] == endVertex
277 edgeAttachedToBoundary[edgeI] =
true;
284 const edge& e = edges[edgeI];
287 const label startVertex = e.start();
288 const label endVertex = e.end();
293 points[meshPoints[startVertex]]
294 - points[meshPoints[endVertex]]
297 if (edgeAttachedToBoundary[edgeI])
299 edgeLength *= edgeAttachedToBoundaryFactor_;
302 scalar shortEdgeFilterValue = 0.0;
304 const labelList& psEdges = ms_.pointEdges()[startVertex];
305 const labelList& peEdges = ms_.pointEdges()[endVertex];
309 const edge& psE = edges[psEdges[psEdgeI]];
310 if (edgeI != psEdges[psEdgeI])
312 shortEdgeFilterValue +=
315 points[meshPoints[psE.start()]]
316 - points[meshPoints[psE.end()]]
323 const edge& peE = edges[peEdges[peEdgeI]];
324 if (edgeI != peEdges[peEdgeI])
326 shortEdgeFilterValue +=
329 points[meshPoints[peE.start()]]
330 - points[meshPoints[peE.end()]]
335 shortEdgeFilterValue *=
336 shortEdgeFilterFactor_
337 /(psEdges.size() + peEdges.size() - 2);
339 edge lookupInPatchEdge
341 meshPoints[startVertex],
342 meshPoints[endVertex]
347 edgeLength < shortEdgeFilterValue
348 || indirectPatchEdge_.found(lookupInPatchEdge)
351 bool flagDegenerateFace =
false;
352 const labelList& pFaces = ms_.pointFaces()[startVertex];
356 const face& f = ms_.localFaces()[pFaces[pFacei]];
360 if (f[fp] == endVertex)
363 if (newFaceVertexCount[pFaces[pFacei]] < 4)
365 flagDegenerateFace =
true;
369 newFaceVertexCount[pFaces[pFacei]]--;
376 if (newFaceVertexCount[pFaces[pFacei]] < 3)
378 flagDegenerateFace =
true;
387 pointsToRemove[meshPoints[startVertex]] == -1
388 && pointsToRemove[meshPoints[endVertex]] == -1
389 && !flagDegenerateFace
392 const DynamicList<label>& startVertexRegions =
393 boundaryPointRegions[meshPoints[startVertex]];
394 const DynamicList<label>& endVertexRegions =
395 boundaryPointRegions[meshPoints[endVertex]];
397 if (startVertexRegions.size() && endVertexRegions.size())
399 if (startVertexRegions.size() > 1)
401 pointsToRemove[meshPoints[endVertex]] =
402 meshPoints[startVertex];
406 pointsToRemove[meshPoints[startVertex]] =
407 meshPoints[endVertex];
410 else if (startVertexRegions.size())
412 pointsToRemove[meshPoints[endVertex]] =
413 meshPoints[startVertex];
417 pointsToRemove[meshPoints[startVertex]] =
418 meshPoints[endVertex];
426 label totalNewPoints = points.size() - nPointsToRemove;
429 labelList newPointNumbers(points.size(), -1);
430 label numberRemoved = 0;
433 labelList newPtToOldPt(totalNewPoints, -1);
438 if (pointsToRemove[pointi] == -1)
440 newPoints[pointi - numberRemoved] = points[pointi];
441 newPointNumbers[pointi] = pointi - numberRemoved;
442 newPtToOldPt[pointi - numberRemoved] = pointi;
455 label newFaceSize = 0;
460 const face& f = faces[facei];
463 newFace.setSize(f.size());
468 label pointi = f[fp];
470 if (pointsToRemove[pointi] == -1)
472 newFace[newFaceSize++] = newPointNumbers[pointi];
476 label newPointi = pointsToRemove[pointi];
481 f.nextLabel(fp) != newPointi
486 label totalChain = 0;
487 for (
label nChain = 0; nChain <= totalChain; ++nChain)
489 if (newPointNumbers[pChain] != -1)
491 newFace[newFaceSize++] = newPointNumbers[pChain];
492 newPointNumbers[pointi] = newPointNumbers[pChain];
493 maxChain =
max(totalChain, maxChain);
498 <<
"Point " << pChain
499 <<
" marked for deletion as well as point " 501 <<
" Incrementing maxChain by 1 from " 502 << totalChain <<
" to " << totalChain + 1
506 pChain = pointsToRemove[pChain];
511 if (newPointNumbers[newPointi] != -1)
513 newPointNumbers[pointi] = newPointNumbers[
newPointi];
519 newFace.setSize(newFaceSize);
521 if (newFace.size() > 2)
523 newFaces[newFacei++] = face(newFace);
528 <<
"Only " << newFace.size() <<
" in face " << facei
533 newFaces.setSize(newFacei);
535 MeshedSurface<face> fMesh
545 boundaryPointRegions,
551 forAll(newPointNumbers, pointi)
553 if (newPointNumbers[pointi] == -1)
556 << pointi <<
" will be deleted and " << newPointNumbers[pointi]
557 <<
", so it will not be replaced. " 558 <<
"This will cause edges to be deleted." <<
endl;
566 Info<<
" Maximum number of chained collapses = " << maxChain <<
endl;
575 os <<
"Short Edge Filtering Information:" <<
nl 576 <<
" shortEdgeFilterFactor: " << shortEdgeFilterFactor_ <<
nl 577 <<
" edgeAttachedToBoundaryFactor: " << edgeAttachedToBoundaryFactor_
582 os <<
" Patch " << patchNames_[
patchi]
586 os <<
" There are " << mapEdgesRegion_.size()
587 <<
" boundary edges." <<
endl;
589 os <<
" Mesh Info:" <<
nl 590 <<
" Points: " << ms_.nPoints() <<
nl 591 <<
" Faces: " << ms_.size() <<
nl 592 <<
" Edges: " << ms_.nEdges() <<
nl 593 <<
" Internal: " << ms_.nInternalEdges() <<
nl 594 <<
" External: " << ms_.nEdges() - ms_.nInternalEdges()
~shortEdgeFilter2D()
Destructor.
#define forAll(list, i)
Loop across all elements in list.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
FvWallInfoData< WallInfo, label > 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)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Ostream & endl(Ostream &os)
Add newline and flush stream.
point toPoint3D(const point2D &) const
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
shortEdgeFilter2D(const CV2D &cv2Dmesh, const dictionary &dict)
List< bool > boolList
Bool container classes.
vectorField pointField
pointField is a vectorField.
stressControl lookup("compactNormalStress") >> compactNormalStress
List< label > labelList
A List of labels.
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.
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence 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)