39 void Foam::shortEdgeFilter2D::addRegion
42 DynamicList<label>& bPointRegions
45 if (bPointRegions.empty())
47 bPointRegions.append(regionI);
49 else if (!bPointRegions.found(regionI))
51 bPointRegions.append(regionI);
56 void Foam::shortEdgeFilter2D::assignBoundaryPointRegions
58 List<DynamicList<label>>& boundaryPointRegions
63 const edge&
e = iter.key();
64 const label& regionI = iter();
66 const label startI =
e.start();
67 const label endI =
e.end();
69 addRegion(regionI, boundaryPointRegions[startI]);
70 addRegion(regionI, boundaryPointRegions[endI]);
75 void Foam::shortEdgeFilter2D::updateEdgeRegionMap
77 const MeshedSurface<face>& surfMesh,
78 const List<DynamicList<label>>& boundaryPtRegions,
80 EdgeMap<label>& mapEdgesRegion,
84 EdgeMap<label> newMapEdgesRegion(mapEdgesRegion.size());
86 const edgeList& edges = surfMesh.edges();
87 const labelList& meshPoints = surfMesh.meshPoints();
89 patchSizes.
setSize(patchNames_.size(), 0);
94 if (surfMesh.isInternalEdge(edgeI))
99 const edge&
e = edges[edgeI];
101 const label startI = meshPoints[
e[0]];
102 const label endI = meshPoints[
e[1]];
106 const DynamicList<label> startPtRegions =
107 boundaryPtRegions[surfPtToBoundaryPt[startI]];
108 const DynamicList<label> endPtRegions =
109 boundaryPtRegions[surfPtToBoundaryPt[endI]];
111 if (startPtRegions.size() > 1 && endPtRegions.size() > 1)
113 region = startPtRegions[0];
116 <<
"Both points in edge are in different regions."
117 <<
" Assigning edge to region " << region
120 else if (startPtRegions.size() > 1 || endPtRegions.size() > 1)
124 startPtRegions.size() > 1
131 startPtRegions[0] == endPtRegions[0]
132 && startPtRegions[0] != -1
135 region = startPtRegions[0];
140 newMapEdgesRegion.insert(
e, region);
141 patchSizes[region]++;
145 mapEdgesRegion.transfer(newMapEdgesRegion);
151 Foam::shortEdgeFilter2D::shortEdgeFilter2D
154 const dictionary&
dict
158 shortEdgeFilterFactor_(
dict.get<scalar>(
"shortEdgeFilterFactor")),
159 edgeAttachedToBoundaryFactor_
161 dict.getOrDefault<scalar>(
"edgeAttachedToBoundaryFactor", 2.0)
189 OFstream str(
"indirectPatchEdges.obj");
192 Info<<
"Writing indirectPatchEdges to " << str.name() <<
endl;
196 const edge&
e = iter.key();
210 ms_ = MeshedSurface<face>(std::move(
points), std::move(faces));
212 Info<<
"Meshed surface stats before edge filtering :" <<
endl;
213 ms_.writeStats(
Info);
219 ms_.write(
"MeshedSurface_preFilter.obj");
236 const edgeList& edges = ms_.edges();
237 const faceList& faces = ms_.surfFaces();
238 const labelList& meshPoints = ms_.meshPoints();
239 const labelList& boundaryPoints = ms_.boundaryPoints();
242 label nPointsToRemove = 0;
244 labelList pointsToRemove(ms_.points().size(), -1);
247 labelList newFaceVertexCount(faces.size(), -1);
250 newFaceVertexCount[facei] = faces[facei].size();
255 List<DynamicList<label>> boundaryPointRegions
260 assignBoundaryPointRegions(boundaryPointRegions);
264 Info<<
" Marking edges attached to boundaries." <<
endl;
265 boolList edgeAttachedToBoundary(edges.size(),
false);
268 const edge&
e = edges[edgeI];
269 const label startVertex =
e.start();
270 const label endVertex =
e.end();
272 forAll(boundaryPoints, bPoint)
276 boundaryPoints[bPoint] == startVertex
277 || boundaryPoints[bPoint] == endVertex
280 edgeAttachedToBoundary[edgeI] =
true;
287 const edge&
e = edges[edgeI];
290 const label startVertex =
e.start();
291 const label endVertex =
e.end();
296 points[meshPoints[startVertex]]
297 -
points[meshPoints[endVertex]]
300 if (edgeAttachedToBoundary[edgeI])
302 edgeLength *= edgeAttachedToBoundaryFactor_;
305 scalar shortEdgeFilterValue = 0.0;
307 const labelList& psEdges = ms_.pointEdges()[startVertex];
308 const labelList& peEdges = ms_.pointEdges()[endVertex];
312 const edge& psE = edges[psEdges[psEdgeI]];
313 if (edgeI != psEdges[psEdgeI])
315 shortEdgeFilterValue +=
318 points[meshPoints[psE.start()]]
319 -
points[meshPoints[psE.end()]]
326 const edge& peE = edges[peEdges[peEdgeI]];
327 if (edgeI != peEdges[peEdgeI])
329 shortEdgeFilterValue +=
332 points[meshPoints[peE.start()]]
333 -
points[meshPoints[peE.end()]]
338 shortEdgeFilterValue *=
339 shortEdgeFilterFactor_
340 /(psEdges.size() + peEdges.size() - 2);
342 edge lookupInPatchEdge
344 meshPoints[startVertex],
345 meshPoints[endVertex]
350 edgeLength < shortEdgeFilterValue
351 || indirectPatchEdge_.found(lookupInPatchEdge)
354 bool flagDegenerateFace =
false;
359 const face&
f = ms_.localFaces()[
pFaces[pFacei]];
363 if (
f[fp] == endVertex)
366 if (newFaceVertexCount[
pFaces[pFacei]] < 4)
368 flagDegenerateFace =
true;
372 newFaceVertexCount[
pFaces[pFacei]]--;
379 if (newFaceVertexCount[
pFaces[pFacei]] < 3)
381 flagDegenerateFace =
true;
390 pointsToRemove[meshPoints[startVertex]] == -1
391 && pointsToRemove[meshPoints[endVertex]] == -1
392 && !flagDegenerateFace
395 const DynamicList<label>& startVertexRegions =
396 boundaryPointRegions[meshPoints[startVertex]];
397 const DynamicList<label>& endVertexRegions =
398 boundaryPointRegions[meshPoints[endVertex]];
400 if (startVertexRegions.size() && endVertexRegions.size())
402 if (startVertexRegions.size() > 1)
404 pointsToRemove[meshPoints[endVertex]] =
405 meshPoints[startVertex];
409 pointsToRemove[meshPoints[startVertex]] =
410 meshPoints[endVertex];
413 else if (startVertexRegions.size())
415 pointsToRemove[meshPoints[endVertex]] =
416 meshPoints[startVertex];
420 pointsToRemove[meshPoints[startVertex]] =
421 meshPoints[endVertex];
429 label totalNewPoints =
points.size() - nPointsToRemove;
433 label numberRemoved = 0;
436 labelList newPtToOldPt(totalNewPoints, -1);
441 if (pointsToRemove[pointi] == -1)
443 newPoints[pointi - numberRemoved] =
points[pointi];
444 newPointNumbers[pointi] = pointi - numberRemoved;
445 newPtToOldPt[pointi - numberRemoved] = pointi;
458 label newFaceSize = 0;
463 const face&
f = faces[facei];
466 newFace.setSize(
f.size());
471 label pointi =
f[fp];
473 if (pointsToRemove[pointi] == -1)
475 newFace[newFaceSize++] = newPointNumbers[pointi];
479 label
newPointi = pointsToRemove[pointi];
489 label totalChain = 0;
490 for (label nChain = 0; nChain <= totalChain; ++nChain)
492 if (newPointNumbers[pChain] != -1)
494 newFace[newFaceSize++] = newPointNumbers[pChain];
495 newPointNumbers[pointi] = newPointNumbers[pChain];
496 maxChain =
max(totalChain, maxChain);
501 <<
"Point " << pChain
502 <<
" marked for deletion as well as point "
504 <<
" Incrementing maxChain by 1 from "
505 << totalChain <<
" to " << totalChain + 1
509 pChain = pointsToRemove[pChain];
516 newPointNumbers[pointi] = newPointNumbers[
newPointi];
522 newFace.setSize(newFaceSize);
524 if (newFace.size() > 2)
526 newFaces[newFacei++] = face(newFace);
531 <<
"Only " << newFace.size() <<
" in face " << facei
536 newFaces.setSize(newFacei);
538 MeshedSurface<face> fMesh(std::move(newPoints), std::move(newFaces));
543 boundaryPointRegions,
549 forAll(newPointNumbers, pointi)
551 if (newPointNumbers[pointi] == -1)
554 << pointi <<
" will be deleted and " << newPointNumbers[pointi]
555 <<
", so it will not be replaced. "
556 <<
"This will cause edges to be deleted." <<
endl;
564 Info<<
" Maximum number of chained collapses = " << maxChain <<
endl;
573 os <<
"Short Edge Filtering Information:" <<
nl
574 <<
" shortEdgeFilterFactor: " << shortEdgeFilterFactor_ <<
nl
575 <<
" edgeAttachedToBoundaryFactor: " << edgeAttachedToBoundaryFactor_
578 forAll(patchNames_, patchi)
580 os <<
" Patch " << patchNames_[patchi]
581 <<
", size " << patchSizes_[patchi] <<
endl;
584 os <<
" There are " << mapEdgesRegion_.size()
585 <<
" boundary edges." <<
endl;
587 os <<
" Mesh Info:" <<
nl
588 <<
" Points: " << ms_.nPoints() <<
nl
589 <<
" Faces: " << ms_.size() <<
nl
590 <<
" Edges: " << ms_.nEdges() <<
nl
591 <<
" Internal: " << ms_.nInternalEdges() <<
nl
592 <<
" External: " << ms_.nEdges() - ms_.nInternalEdges()