1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
26 University of Massachusetts Amherst
28 \*---------------------------------------------------------------------------*/
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 // Compute clip-planes
36 inline void triIntersection::computeClipPlanes()
39 tNorm_ = (clipTri_[1] - clipTri_[0]) ^ (clipTri_[2] - clipTri_[0]);
42 tNorm_ /= mag(tNorm_) + VSMALL;
45 clipPlanes_[0].first() = ((clipTri_[1] - clipTri_[0]) ^ tNorm_);
46 clipPlanes_[1].first() = ((clipTri_[2] - clipTri_[1]) ^ tNorm_);
47 clipPlanes_[2].first() = ((clipTri_[0] - clipTri_[2]) ^ tNorm_);
50 clipPlanes_[0].first() /= mag(clipPlanes_[0].first()) + VSMALL;
51 clipPlanes_[1].first() /= mag(clipPlanes_[1].first()) + VSMALL;
52 clipPlanes_[2].first() /= mag(clipPlanes_[2].first()) + VSMALL;
54 // Determine plane constants
55 clipPlanes_[0].second() = (clipTri_[0] & clipPlanes_[0].first());
56 clipPlanes_[1].second() = (clipTri_[1] & clipPlanes_[1].first());
57 clipPlanes_[2].second() = (clipTri_[2] & clipPlanes_[2].first());
61 // Split and decompose
62 inline void triIntersection::splitAndDecompose
64 const label triPlaneIndex,
65 FixedList<point, 3>& tri,
66 DynamicList<FixedList<point, 3> >& decompTris
69 FixedList<scalar, 3> C;
70 FixedList<vector, 3> tmpTri;
71 FixedList<label, 3> pos, neg, zero;
72 label i = 0, nPos = 0, nNeg = 0, nZero = 0;
74 // Fetch reference to plane
75 const hPlane& triPlane = clipPlanes_[triPlaneIndex];
77 for (i = 0; i < 3; ++i)
79 // Compute distance to plane
80 C[i] = (tri[i] & triPlane.first()) - triPlane.second();
104 decompTris.append(tri);
108 // Triangle is split by plane. Determine how it is split and how to
109 // decompose the negative-side portion into triangles (3 cases).
110 scalar w0, w1, invCDiff;
116 for (i = 0; i < nPos; ++i)
118 invCDiff = (1.0 / (C[pos[i]] - C[neg[0]]));
120 w0 = -C[neg[0]] * invCDiff;
121 w1 = +C[pos[i]] * invCDiff;
123 tri[pos[i]] = (w0 * tri[pos[i]]) + (w1 * tri[neg[0]]);
126 decompTris.append(tri);
134 for (i = 0; i < nNeg; ++i)
136 invCDiff = (1.0 / (C[pos[0]] - C[neg[i]]));
138 w0 = -C[neg[i]] * invCDiff;
139 w1 = +C[pos[0]] * invCDiff;
141 intp[i] = (w0 * tri[pos[0]]) + (w1 * tri[neg[i]]);
144 tri[pos[0]] = intp[0];
146 decompTris.append(tri);
149 tmpTri[1] = tri[neg[1]];
152 decompTris.append(tmpTri);
157 invCDiff = (1.0 / (C[pos[0]] - C[neg[0]]));
159 w0 = -C[neg[0]] * invCDiff;
160 w1 = +C[pos[0]] * invCDiff;
162 tri[pos[0]] = (w0 * tri[pos[0]]) + (w1 * tri[neg[0]]);
164 decompTris.append(tri);
170 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
172 inline triIntersection::triIntersection(const FixedList<point, 3>& clipTri)
178 // Pre-compute clipping planes
183 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
185 inline triIntersection::~triIntersection()
189 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
191 // Evaluate for intersections
192 inline bool triIntersection::evaluate(const FixedList<point, 3>& subjectTri)
198 // Project subject triangle to clipping triangle plane
199 FixedList<point, 3> sTP(subjectTri);
201 for (label i = 0; i < 3; i++)
203 // Relative to zeroth face-point
204 sTP[i] -= clipTri_[0];
207 sTP[i] = clipTri_[0] + (sTP[i] - (sTP[i] & tNorm_)*tNorm_);
210 // Add initial triangle to list
211 allTris_.append(sTP);
213 // Clip second triangle against planes of clipping triangle
214 for (label i = 0; i < 3; i++)
216 forAll(allTris_, triI)
218 splitAndDecompose(i, allTris_[triI], inside_);
221 // Prep for next clipping plane
226 return (allTris_.size() > 0);
230 // Return intersections
231 inline const DynamicList<FixedList<point, 3> >&
232 triIntersection::getIntersection() const
238 //- Evaluate and return area / centroid
239 inline void triIntersection::getAreaAndCentre
246 centre = vector::zero;
248 forAll(allTris_, triI)
250 const FixedList<point, 3>& t = allTris_[triI];
252 // Calculate area (no check for orientation)
253 scalar tA = Foam::mag(0.5 * ((t[1] - t[0]) ^ (t[2] - t[0])));
255 // Calculate centroid
256 vector tC = (1.0 / 3.0) * (t[0] + t[1] + t[2]);
262 centre /= area + VSMALL;
268 // ************************************************************************* //