1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh 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 cfMesh is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
29 #include "meshOctreeCubeCoordinates.H"
30 #include "helperFunctions.H"
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 const label meshOctreeCubeCoordinates::edgeNodes_[12][2] =
44 //- edges in x-direction
49 //- edges in y-direction
54 //- edges in z-direction
61 const label meshOctreeCubeCoordinates::faceNodes_[6][4] =
71 const label meshOctreeCubeCoordinates::nodeFaces_[8][3] =
83 const label meshOctreeCubeCoordinates::faceEdges_[6][4] =
93 const label meshOctreeCubeCoordinates::edgeFaces_[12][2] =
109 const label meshOctreeCubeCoordinates::oppositeFace_[6] = {1, 0, 3, 2, 5, 4};
111 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
113 void meshOctreeCubeCoordinates::vertices
115 const boundBox& rootBox,
116 FixedList<point, 8>& vrt
119 const vector tol = SMALL * (rootBox.max() - rootBox.min());
122 cubeBox(rootBox, min_, max_);
126 vrt[0] = point(min_.x(), min_.y(), min_.z());
127 vrt[1] = point(max_.x(), min_.y(), min_.z());
128 vrt[2] = point(min_.x(), max_.y(), min_.z());
129 vrt[3] = point(max_.x(), max_.y(), min_.z());
130 vrt[4] = point(min_.x(), min_.y(), max_.z());
131 vrt[5] = point(max_.x(), min_.y(), max_.z());
132 vrt[6] = point(min_.x(), max_.y(), max_.z());
133 vrt[7] = point(max_.x(), max_.y(), max_.z());
136 void meshOctreeCubeCoordinates::edgeVertices
138 const boundBox& rootBox,
139 FixedList<FixedList<point, 2>, 12>& e
142 FixedList<point, 8> vertices;
143 this->vertices(rootBox, vertices);
145 for(label i=0;i<12;++i)
147 e[i][0] = vertices[edgeNodes_[i][0]];
148 e[i][1] = vertices[edgeNodes_[i][1]];
152 bool meshOctreeCubeCoordinates::intersectsTriangle
154 const triSurf& surface,
155 const boundBox& rootBox,
159 const pointField& points = surface.points();
160 const labelledTri& ltri = surface[tI];
162 const vector tol = SMALL * (rootBox.max() - rootBox.min());
164 //- calculate the bound box of the octree cube
166 cubeBox(rootBox, cBox.min(), cBox.max());
170 //- calculate the bounding box of the triangle
172 tBox.min() = tBox.max() = points[ltri[0]];
174 for(label pI=1;pI<3;++pI)
176 tBox.max() = Foam::max(points[ltri[pI]], tBox.max());
177 tBox.min() = Foam::min(points[ltri[pI]], tBox.min());
183 return cBox.overlaps(tBox);
186 bool meshOctreeCubeCoordinates::intersectsTriangleExact
188 const triSurf& surface,
189 const boundBox& rootBox,
193 if( !intersectsTriangle(surface, rootBox, tI) )
196 const vector tol = SMALL * (rootBox.max() - rootBox.min());
198 const pointField& points = surface.points();
199 const labelledTri& ltri = surface[tI];
201 //- check if any of the vertices is in the cube
203 if( isVertexInside(rootBox, points[ltri[pI]]) )
206 //- check if any edges of the triangle intersect the cube
208 cubeBox(rootBox, bb.min(), bb.max());
212 for(label eI=0;eI<3;++eI)
214 const edge edg(ltri[eI], ltri[(eI+1)%3]);
215 const point& s = points[edg.start()];
216 const point& e = points[edg.end()];
218 if( help::boundBoxLineIntersection(s, e, bb) )
222 //- check if any cube edges intersects the triangle
223 FixedList<FixedList<point, 2>, 12> e;
224 this->edgeVertices(rootBox, e);
229 help::triLineIntersection
243 bool meshOctreeCubeCoordinates::isVertexInside
245 const boundBox& rootBox,
249 const vector tol = SMALL * (rootBox.max() - rootBox.min());
252 cubeBox(rootBox, min, max);
257 ((p.x() - max.x()) > 0.0) ||
258 ((p.y() - max.y()) > 0.0) ||
259 ((p.z() - max.z()) > 0.0) ||
260 ((p.x() - min.x()) < 0.0) ||
261 ((p.y() - min.y()) < 0.0) ||
262 ((p.z() - min.z()) < 0.0)
269 bool meshOctreeCubeCoordinates::isPositionInside
271 const meshOctreeCubeCoordinates& cc
275 Info << "Checking cube " << *this << endl;
276 Info << "level " << short(l) << " x: " << px
277 << " y: " << py << " z:" << pz << endl;
280 if( cc.level() >= this->level() )
282 const direction diff = cc.level() - this->level();
283 meshOctreeCubeCoordinates reducedLevel =
284 cc.reduceLevelBy(diff);
287 Info << "diff " << label(diff) << endl;
288 Info << "Divider " << divider << endl;
289 Info << "Coordinates at level are " << reducedLevel << endl;
292 if( reducedLevel == *this )
299 "bool meshOctreeCubeCoordinates::isPositionInside"
300 "(const label px,const label py,"
301 "const label pz,const direction l)"
302 ) << "Cannot find exact position of finer cube" << exit(FatalError);
308 bool meshOctreeCubeCoordinates::intersectsLine
310 const boundBox& rootBox,
315 const scalar tol = SMALL * (rootBox.max().x() - rootBox.min().x());
318 cubeBox(rootBox, min, max);
320 //- check if the cube contains start point or end point
321 min -= vector(tol,tol,tol);
322 max += vector(tol,tol,tol);
324 //- check for intersections of line with the cube faces
325 const vector v(e - s);
329 if( mag(v.x()) > tol )
332 t = (min.x() - s.x()) / v.x();
335 (t > -tol) && (t < (1.0+tol)) &&
336 (i.y() - min.y() > -tol) &&
337 (i.y() - max.y() < tol) &&
338 (i.z() - min.z() > -tol) &&
339 (i.z() - max.z() < tol)
344 t = (max.x() - s.x()) / v.x();
347 (t > -tol) && (t < (1.0+tol)) &&
348 (i.y() - min.y() > -tol) &&
349 (i.y() - max.y() < tol) &&
350 (i.z() - min.z() > -tol) &&
351 (i.z() - max.z() < tol)
356 if( mag(v.y()) > tol)
359 t = (min.y() - s.y()) / v.y();
362 (t > -tol) && (t < (1.0+tol)) &&
363 (i.x() - min.x() > -tol) &&
364 (i.x() - max.x() < tol) &&
365 (i.z() - min.z() > -tol) &&
366 (i.z() - max.z() < tol)
371 t = (max.y() - s.y()) / v.y();
374 (t > -tol) && (t < (1.0+tol)) &&
375 (i.x() - min.x() > -tol) &&
376 (i.x() - max.x() < tol) &&
377 (i.z() - min.z() > -tol) &&
378 (i.z() - max.z() < tol)
383 if( mag(v.z()) > tol )
386 t = (min.z() - s.z()) / v.z();
389 (t > -tol) && (t < (1.0+tol)) &&
390 (i.x() - min.x() > -tol) &&
391 (i.x() - max.x() < tol) &&
392 (i.y() - min.y() > -tol) &&
393 (i.y() - max.y() < tol)
398 t = (max.z() - s.z()) / v.z();
401 (t > -tol) && (t < (1.0+tol)) &&
402 (i.x() - min.x() > -tol) &&
403 (i.x() - max.x() < tol) &&
404 (i.y() - min.y() > -tol) &&
405 (i.y() - max.y() < tol)
410 if( isVertexInside(rootBox, s) )
416 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
418 } // End namespace Foam
420 // ************************************************************************* //