112 for (label i = 1; i < splitPoints.
size(); i++)
137 else if (
f[fp2] ==
e[1])
152 for (label i = splitPoints.
size()-1; i > 0; --i)
180 <<
"Edge " <<
e <<
" not part of triangle " <<
f 199 static bool insertSorted
208 if (sortedVerts.
found(vertI))
211 <<
" which is already in list of sorted vertices " 215 if (weight <= 0 || weight >= 1)
218 <<
" with illegal weight " << weight
219 <<
" into list of sorted vertices " 224 label insertI = sortedVerts.
size();
226 forAll(sortedVerts, sortedI)
228 scalar w = sortedWeights[sortedI];
230 if (
mag(w - weight) < SMALL)
233 <<
"Trying to insert weight " << weight <<
" which is close to" 234 <<
" existing weight " << w <<
" in " << sortedWeights
247 label sz = sortedWeights.
size();
255 for (label i = sz-1; i >= insertI; --i)
257 sortedWeights[i+1] = sortedWeights[i];
258 sortedVerts[i+1] = sortedVerts[i];
260 sortedWeights[insertI] = weight;
261 sortedVerts[insertI] = vertI;
272 const scalar minQuality,
296 e.line(localPoints).nearestDist
298 localPoints[opposite0]
306 ||
f.tri(surf.
points()).quality() < minQuality
333 static void markCollapsedFaces
337 const scalar minQuality,
352 label facei = eFaces[i];
354 bool isCandidate = isSliver(surf, minLen, minQuality, facei, edgeI);
359 if (faceToEdge[facei] != -1)
362 <<
"Cannot collapse face " << facei <<
" since " 363 <<
" is marked to be collapsed both to edge " 364 << faceToEdge[facei] <<
" and " << edgeI
368 faceToEdge[facei] = edgeI;
377 static void markRegion
386 if (faceToEdge[facei] == -1 || collapseRegion[facei] != -1)
389 <<
"Problem : crossed into uncollapsed/regionized face" 393 collapseRegion[facei] = regionI;
401 label edgeI = fEdges[fEdgeI];
407 label nbrFacei = eFaces[i];
409 if (faceToEdge[nbrFacei] != -1)
411 if (collapseRegion[nbrFacei] == -1)
422 else if (collapseRegion[nbrFacei] != regionI)
425 <<
"Edge:" << edgeI <<
" between face " << facei
426 <<
" with region " << regionI
427 <<
" and face " << nbrFacei
428 <<
" with region " << collapseRegion[nbrFacei]
439 static label markRegions
450 if (collapseRegion[facei] == -1 && faceToEdge[facei] != -1)
456 markRegion(surf, faceToEdge, regionI++, facei, collapseRegion);
467 static label edgeType
477 bool usesUncollapsed =
false;
478 label usesRegion = -1;
482 label facei = eFaces[i];
484 label region = collapseRegion[facei];
488 usesUncollapsed =
true;
490 else if (usesRegion == -1)
494 else if (usesRegion != region)
506 if (usesRegion == -1)
519 if (usesRegion == -1)
548 label regionI = edgeType(surf, collapseRegion, edgeI);
557 labelList& regionVerts = outsideVerts[regionI];
564 if (!regionVerts.
found(v))
566 label sz = regionVerts.
size();
587 scalar maxDist = -GREAT;
592 label v0 = outsideVerts[i];
594 for (label j = i+1; j < outsideVerts.
size(); j++)
596 label v1 = outsideVerts[j];
598 scalar d =
mag(localPoints[v0] - localPoints[v1]);
614 static void projectNonSpanPoints
628 label v = outsideVerts[i];
630 if (v != spanPair[0] && v != spanPair[1])
646 scalar w = pHit.
point().dist(
p0) / p1.dist(
p0);
648 insertSorted(v, w, sortedVertices, sortedWeights);
655 static void getSplitVerts
669 const label sz = orderedVerts.
size();
671 if (
e[0] == spanPoints[0])
675 if (
e[1] == spanPoints[1])
678 splitVerts = orderedVerts;
679 splitWeights = orderedWeights;
684 label i1 = orderedVerts.
find(
e[1]);
689 else if (
e[0] == spanPoints[1])
693 if (
e[1] == spanPoints[0])
696 splitVerts = orderedVerts;
698 splitWeights = orderedWeights;
705 label i1 = orderedVerts.
find(
e[1]);
712 else if (
e[1] == spanPoints[0])
718 label i0 = orderedVerts.
find(
e[0]);
724 else if (
e[1] == spanPoints[1])
728 label i0 = orderedVerts.
find(
e[0]);
734 label i0 = orderedVerts.
find(
e[0]);
735 label i1 = orderedVerts.
find(
e[1]);
737 if (i0 == -1 || i1 == -1)
740 <<
"Did not find edge in projected vertices." <<
nl 741 <<
"region:" << regionI <<
nl 742 <<
"spanPoints:" << spanPoints
749 <<
"orderedVerts:" << orderedVerts <<
nl 773 const scalar minQuality
776 label nTotalSplit = 0;
789 markCollapsedFaces(surf, minLen, minQuality, faceToEdge);
798 label nRegions = markRegions(surf, faceToEdge, collapseRegion);
806 getOutsideVerts(surf, collapseRegion, nRegions)
814 forAll(spanPoints, regionI)
816 spanPoints[regionI] = getSpanPoints(surf, outsideVerts[regionI]);
827 outsideVerts[regionI],
829 orderedVertices[regionI],
830 orderedWeights[regionI]
870 const edge&
e = edges[edgeI];
873 label regionI = edgeType(surf, collapseRegion, edgeI);
879 else if (regionI == -1)
897 orderedVertices[regionI],
898 orderedWeights[regionI],
905 if (splitVerts.
size())
928 label facei = eFaces[i];
930 if (!faceHandled[facei] && faceToEdge[facei] == -1)
941 faceHandled[facei] =
true;
951 forAll(faceHandled, facei)
953 if (!faceHandled[facei] && faceToEdge[facei] == -1)
955 newTris.append(localFaces[facei]);
959 Info<<
"collapseBase : collapsing " << nSplit
960 <<
" triangles by splitting their base edge." 963 nTotalSplit += nSplit;
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
void size(const label n)
Older name for setAddressableSize.
label collapseBase(triSurface &surf, const scalar minLen, const scalar minQuality)
Keep collapsing all triangles whose height is < minLen or quality < minQ.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool found(const T &val, label pos=0) const
Same as contains()
Routines collapse sliver triangles by splitting the base edge.
#define forAll(list, i)
Loop across all elements in list.
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
bool hit() const noexcept
Is there a hit.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
A List obtained as a section of another List.
const geometricSurfacePatchList & patches() const noexcept
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
line< point, const point & > linePointRef
A line using referred points.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
const labelListList & edgeFaces() const
Return edge-face addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
void reverse(UList< T > &list, const label n)
Reverse the first n elements of the list.
A triFace with additional (region) index.
Describes the interaction of a object and a (templated) point. It carries the info of a successful hi...
const Field< point_type > & points() const noexcept
Return reference to global points.
void append(const T &val)
Copy append an element to the end of this list.
errorManip< error > abort(error &err)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
T & last()
Access last element of the list, position [size()-1].
#define WarningInFunction
Report a warning using Foam::Warning.
scalar distance() const noexcept
Return distance to hit.
const point_type & point() const noexcept
Return the point, no checks.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const labelListList & faceEdges() const
Return face-edge addressing.
Triangulated surface description with patch information.
const volScalarField & p0