32 const Foam::scalar Foam::faceTriangulation::edgeRelTol = 1
e-6;
45 return i ? i-1 : size-1;
62 point thisPt = points[f[i]];
63 point nextPt = points[f[f.fcIndex(i)]];
65 vector vec(nextPt - thisPt);
66 vec /=
mag(vec) + VSMALL;
76 void Foam::faceTriangulation::calcHalfAngle
86 scalar cos =
max(-1,
min(1, e0 & e1));
88 scalar sin = (e0 ^ e1) & normal;
90 if (sin < -ROOTVSMALL)
110 const point& rayOrigin,
121 const vector y = normal ^ rayDir;
123 posOnEdge = plane(rayOrigin, y).normalIntersect(p1, (p2-p1));
126 if ((posOnEdge < 0) || (posOnEdge > 1))
133 point intersectPt = p1 + posOnEdge * (p2 - p1);
135 if (((intersectPt - rayOrigin) & rayDir) < 0)
143 result.setPoint(intersectPt);
144 result.setDistance(
mag(intersectPt - rayOrigin));
153 bool Foam::faceTriangulation::triangleContainsPoint
166 if ((area01Pt > 0) && (area12Pt > 0) && (area20Pt > 0))
170 else if ((area01Pt < 0) && (area12Pt < 0) && (area20Pt < 0))
184 void Foam::faceTriangulation::findDiagonal
190 const label startIndex,
195 const point& startPt = points[f[startIndex]];
198 const vector& rightE = edges[right(f.size(), startIndex)];
199 const vector leftE = -edges[left(f.size(), startIndex)];
202 scalar cosHalfAngle = GREAT;
203 scalar sinHalfAngle = GREAT;
204 calcHalfAngle(normal, rightE, leftE, cosHalfAngle, sinHalfAngle);
208 + sinHalfAngle*(normal ^ rightE)
212 rayDir /=
mag(rayDir) + VSMALL;
219 label faceVertI = f.fcIndex(startIndex);
223 scalar minPosOnEdge = GREAT;
225 for (
label i = 0; i < f.size() - 2; i++)
234 points[f[faceVertI]],
235 points[f[f.fcIndex(faceVertI)]],
239 if (inter.hit() && inter.distance() < minInter.distance())
242 minIndex = faceVertI;
243 minPosOnEdge = posOnEdge;
246 faceVertI = f.fcIndex(faceVertI);
261 const label leftIndex = minIndex;
262 const label rightIndex = f.fcIndex(minIndex);
268 if (
mag(minPosOnEdge) < edgeRelTol && f.fcIndex(startIndex) != leftIndex)
277 mag(minPosOnEdge - 1) < edgeRelTol
278 && f.fcIndex(rightIndex) != startIndex
291 const point& leftPt = points[f[leftIndex]];
292 const point& rightPt = points[f[rightIndex]];
295 scalar maxCos = -GREAT;
298 faceVertI = f.fcIndex(f.fcIndex(startIndex));
299 for (
label i = 0; i < f.size() - 3; i++)
301 const point& pt = points[f[faceVertI]];
305 (faceVertI == leftIndex)
306 || (faceVertI == rightIndex)
307 || (triangleContainsPoint(normal, startPt, leftPt, rightPt, pt))
312 vector edgePt0 = pt - startPt;
313 edgePt0 /=
mag(edgePt0);
315 scalar cos = rayDir & edgePt0;
319 minIndex = faceVertI;
322 faceVertI = f.fcIndex(faceVertI);
331 if (f.fcIndex(startIndex) != leftIndex)
358 const label size = f.size();
360 scalar minCos = GREAT;
365 const vector& rightEdge = edges[right(size, fp)];
366 const vector leftEdge = -edges[left(size, fp)];
368 if (((rightEdge ^ leftEdge) & normal) < ROOTVSMALL)
370 scalar cos = rightEdge & leftEdge;
386 const vector& rightEdge = edges[right(size, fp)];
387 const vector leftEdge = -edges[left(size, fp)];
389 scalar cos = rightEdge & leftEdge;
406 bool Foam::faceTriangulation::split
415 const label size = f.size();
421 "split(const bool, const pointField&, const face&" 422 ", const vector&, label&)" 423 ) <<
"Illegal face:" << f
424 <<
" with points " << UIndirectList<point>(
points,
f)()
444 tmp<vectorField> tedges(calcEdges(f, points));
447 label startIndex = findStart(f, edges, normal);
466 if (index1 != -1 && index2 != -1)
473 startIndex = f.fcIndex(startIndex);
476 if (index1 == -1 || index2 == -1)
483 scalar maxCos = -GREAT;
487 const vector& rightEdge = edges[right(size, fp)];
488 const vector leftEdge = -edges[left(size, fp)];
490 scalar cos = rightEdge & leftEdge;
500 "split(const bool, const pointField&, const face&" 501 ", const vector&, label&)" 502 ) <<
"Cannot find valid diagonal on face " << f
503 <<
" with points " << UIndirectList<point>(
points,
f)()
505 <<
"Returning naive triangulation starting from " 506 << f[maxIndex] <<
" which might not be correct for a" 507 <<
" concave or warped face" <<
endl;
510 label fp = f.fcIndex(maxIndex);
512 for (
label i = 0; i < size-2; i++)
514 label nextFp = f.fcIndex(fp);
517 tri[0] = f[maxIndex];
530 "split(const bool, const pointField&, const face&" 531 ", const vector&, label&)" 532 ) <<
"Cannot find valid diagonal on face " << f
533 <<
" with points " << UIndirectList<point>(
points,
f)()
535 <<
"Returning empty triFaceList" <<
endl;
550 diff = index2 - index1;
555 diff = index2 + size - index1;
558 label nPoints1 = diff + 1;
559 label nPoints2 = size - diff + 1;
561 if (nPoints1 == size || nPoints2 == size)
565 "split(const bool, const pointField&, const face&" 566 ", const vector&, label&)" 567 ) <<
"Illegal split of face:" << f
568 <<
" with points " << UIndirectList<point>(
points,
f)()
569 <<
" at indices " << index1 <<
" and " << index2
575 face face1(nPoints1);
577 label faceVertI = index1;
578 for (
int i = 0; i < nPoints1; i++)
580 face1[i] = f[faceVertI];
581 faceVertI = f.fcIndex(faceVertI);
585 face face2(nPoints2);
588 for (
int i = 0; i < nPoints2; i++)
590 face2[i] = f[faceVertI];
591 faceVertI = f.fcIndex(faceVertI);
601 split(fallBack, points, face1, normal, triI)
602 && split(fallBack, points, face2, normal, triI);
631 avgNormal /=
mag(avgNormal) + VSMALL;
635 bool valid = split(fallBack, points, f, avgNormal, triI);
657 bool valid = split(fallBack, points, f, n, triI);
dimensionedScalar sqrt(const dimensionedScalar &ds)
const pointField & points
vector point
Point is a vector.
dimensioned< scalar > mag(const dimensioned< Type > &)
faceTriangulation()
Construct null.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
void size(const label)
Override size to be inconsistent with allocated storage.
vectorField pointField
pointField is a vectorField.
PointHit< point > pointHit
triangle< point, const point & > triPointRef
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
A face is a list of labels corresponding to mesh vertices.
T & operator[](const label)
Return element of UList.
void setSize(const label)
Reset size of List.
Ostream & endl(Ostream &os)
Add newline and flush stream.
#define WarningIn(functionName)
Report a warning using Foam::Warning.
const dimensionedScalar e
Elementary charge.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
dimensionedScalar cos(const dimensionedScalar &ds)
errorManip< error > abort(error &err)
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
vector normal(const pointField &) const
Vector normal; magnitude is equal to area of face.
Vector< scalar > vector
A scalar version of the templated Vector.
List< triFace > triFaceList
list of triFaces
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
A class for managing temporary objects.