triangle.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "triangle.H"
29 #include "plane.H"
30 
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 
33 template<class Point, class PointRef>
34 template<class AboveOp, class BelowOp>
36 (
37  const plane& pln,
38  const triPoints& tri,
39  AboveOp& aboveOp,
40  BelowOp& belowOp
41 )
42 {
43  // distance to cutting plane
44  FixedList<scalar, 3> d;
45 
46  // determine how many of the points are above the cutting plane
47  label nPos = 0;
48  label posI = -1;
49  label negI = -1;
50  forAll(tri, i)
51  {
52  d[i] = pln.signedDistance(tri[i]);
53 
54  if (d[i] > 0)
55  {
56  nPos++;
57  posI = i;
58  }
59  else
60  {
61  negI = i;
62  }
63  }
64 
65  if (nPos == 3)
66  {
67  aboveOp(tri);
68  }
69  else if (nPos == 2)
70  {
71  // point under the plane
72  label i0 = negI;
73 
74  // indices of remaining points
75  label i1 = d.fcIndex(i0);
76  label i2 = d.fcIndex(i1);
77 
78  // determine the two intersection points
79  point p01 = planeIntersection(d, tri, i0, i1);
80  point p02 = planeIntersection(d, tri, i0, i2);
81 
82  aboveOp(triPoints(tri[i1], tri[i2], p02));
83  aboveOp(triPoints(tri[i1], p02, p01));
84  belowOp(triPoints(tri[i0], p01, p02));
85  }
86  else if (nPos == 1)
87  {
88  // point above the plane
89  label i0 = posI;
90 
91  // indices of remaining points
92  label i1 = d.fcIndex(i0);
93  label i2 = d.fcIndex(i1);
94 
95  // determine the two intersection points
96  point p01 = planeIntersection(d, tri, i0, i1);
97  point p02 = planeIntersection(d, tri, i0, i2);
98 
99  belowOp(triPoints(tri[i1], tri[i2], p02));
100  belowOp(triPoints(tri[i1], p02, p01));
101  aboveOp(triPoints(tri[i0], p01, p02));
102  }
103  else
104  {
105  // All below
106  belowOp(tri);
107  }
108 }
109 
110 
111 template<class Point, class PointRef>
112 template<class AboveOp, class BelowOp>
114 (
115  const plane& pl,
116  AboveOp& aboveOp,
117  BelowOp& belowOp
118 ) const
119 {
120  triSliceWithPlane(pl, triPoints(a_, b_, c_), aboveOp, belowOp);
121 }
122 
123 
124 template<class Point, class PointRef>
125 template<class InsideOp, class OutsideOp>
127 (
128  const vector& n,
129  const triangle<Point, PointRef>& tgt,
130  InsideOp& insideOp,
131  OutsideOp& outsideOp
132 ) const
133 {
134  // There are two possibilities with this algorithm - we either cut
135  // the outside triangles with all the edges or not (and keep them
136  // as disconnected triangles). In the first case
137  // we cannot do any evaluation short cut so we've chosen not to re-cut
138  // the outside triangles.
139 
140 
141  triIntersectionList insideTrisA;
142  label nInsideA = 0;
143  storeOp insideOpA(insideTrisA, nInsideA);
144 
145  triIntersectionList outsideTrisA;
146  label nOutsideA = 0;
147  storeOp outsideOpA(outsideTrisA, nOutsideA);
148 
149 
150  const triPoints thisTri(a_, b_, c_);
151 
152 
153  // Cut original triangle with tgt edge 0.
154  // From *this to insideTrisA, outsideTrisA.
155  {
156  scalar s = Foam::mag(tgt.b() - tgt.a());
157  const plane pl0(tgt.a(), tgt.b(), tgt.b() + s*n);
158  triSliceWithPlane(pl0, thisTri, insideOpA, outsideOpA);
159  }
160 
161  // Shortcut if nothing cut
162 
163  if (insideOpA.nTris_ == 0)
164  {
165  outsideOp(thisTri);
166  return;
167  }
168 
169  if (outsideOpA.nTris_ == 0)
170  {
171  insideOp(thisTri);
172  return;
173  }
174 
175 
176  // Cut all triangles with edge 1.
177  // From insideTrisA to insideTrisB, outsideTrisA
178 
179  triIntersectionList insideTrisB;
180  label nInsideB = 0;
181  storeOp insideOpB(insideTrisB, nInsideB);
182 
183  //triIntersectionList outsideTrisB;
184  //label nOutsideB = 0;
185  //storeOp outsideOpB(outsideTrisB, nOutsideB);
186 
187  {
188  scalar s = Foam::mag(tgt.c() - tgt.b());
189  const plane pl0(tgt.b(), tgt.c(), tgt.c() + s*n);
190 
191  for (label i = 0; i < insideOpA.nTris_; i++)
192  {
193  const triPoints& tri = insideOpA.tris_[i];
194  triSliceWithPlane(pl0, tri, insideOpB, outsideOpA);
195  }
196 
199  //for (label i = 0; i < outsideOpA.nTris_; i++)
200  //{
201  // const triPoints& tri = outsideOpA.tris_[i];
202  // triSliceWithPlane(pl0, tri, outsideOpB, outsideOpB);
203  //}
204  }
205 
206 
207  // Cut all triangles with edge 2.
208  // From insideTrisB to insideTrisA, outsideTrisA
209  {
210  scalar s = Foam::mag(tgt.a() - tgt.c());
211  const plane pl0(tgt.c(), tgt.a(), tgt.a() + s*n);
212 
213  insideOpA.nTris_ = 0;
214  //outsideOpA.nTris_ = 0;
215  for (label i = 0; i < insideOpB.nTris_; i++)
216  {
217  const triPoints& tri = insideOpB.tris_[i];
218  triSliceWithPlane(pl0, tri, insideOpA, outsideOpA);
219  }
220 
223  //for (label i = 0; i < outsideOpB.nTris_; i++)
224  //{
225  // const triPoints& tri = outsideOpB.tris_[i];
226  // triSliceWithPlane(pl0, tri, outsideOpA, outsideOpA);
227  //}
228  }
229 
230  // Transfer from A to argument
231  for (label i = 0; i < insideOpA.nTris_; i++)
232  {
233  insideOp(insideOpA.tris_[i]);
234  }
235 
236  for (label i = 0; i < outsideOpA.nTris_; i++)
237  {
238  outsideOp(outsideOpA.tris_[i]);
239  }
240 }
241 
242 
243 // ************************************************************************* //
A triangle primitive used to calculate face normals and swept volumes. Uses referred points...
Definition: triangle.H:217
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void sliceWithPlane(const plane &pln, AboveOp &aboveOp, BelowOp &belowOp) const
Decompose triangle into triangles above and below plane.
Definition: triangle.C:107
const Point & a() const noexcept
The first vertex.
Definition: triangle.H:371
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
Definition: plane.H:90
const Point & c() const noexcept
The third vertex.
Definition: triangle.H:381
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
const Point & b() const noexcept
The second vertex.
Definition: triangle.H:376
Triangle point storage. Default constructable (triangle is not)
Definition: triangle.H:74
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
void triangleOverlap(const vector &n, const triangle< Point, PointRef > &tri, InsideOp &insideOp, OutsideOp &outsideOp) const
Decompose triangle into triangles inside and outside.
Definition: triangle.C:120
vector point
Point is a vector.
Definition: point.H:37
label n
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))