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 \*---------------------------------------------------------------------------*/
28 #include "findCellsIntersectingSurface.H"
29 #include "polyMeshGen.H"
30 #include "polyMeshGenAddressing.H"
33 #include "helperFunctions.H"
34 #include "meshOctree.H"
35 #include "meshOctreeCreator.H"
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 void findCellsIntersectingSurface::generateOctree(const triSurf& surf)
51 octreePtr_ = new meshOctree(surf);
53 meshOctreeCreator(*octreePtr_).createOctreeWithRefinedBoundary(15, 15);
56 void findCellsIntersectingSurface::findIntersectedCells()
58 const pointFieldPMG& points = mesh_.points();
59 const faceListPMG& faces = mesh_.faces();
60 const cellListPMG& cells = mesh_.cells();
61 const labelList& owner = mesh_.owner();
63 const vectorField& faceCentres = mesh_.addressingData().faceCentres();
64 const vectorField& cellCentres = mesh_.addressingData().cellCentres();
66 meshOctreeModifier octreeModifier(*octreePtr_);
67 const LongList<meshOctreeCube*>& leaves = octreeModifier.leavesAccess();
69 intersectedCells_.setSize(cells.size());
70 facetsIntersectingCell_.setSize(cells.size());
72 const triSurf& surf = octreePtr_->surface();
73 const VRWGraph& pointFacets = surf.pointFacets();
74 const pointField& sp = surf.points();
77 # pragma omp parallel for schedule(dynamic, 40)
81 bool intersected(false);
83 const cell& c = cells[cellI];
85 //- find the bounding box of the cell
86 boundBox bb(cellCentres[cellI], cellCentres[cellI]);
90 const face& f = faces[c[fI]];
94 bb.min() = Foam::min(bb.min(), points[f[pI]]);
95 bb.max() = Foam::max(bb.max(), points[f[pI]]);
99 const vector spanCorr = 0.01 * bb.span();
100 bb.max() += spanCorr;
101 bb.min() -= spanCorr;
103 //- find surface triangles within the bounding box
104 DynList<label> leavesInBox;
105 octreePtr_->findLeavesContainedInBox(bb, leavesInBox);
106 labelHashSet triangles;
107 forAll(leavesInBox, boxI)
109 const meshOctreeCube& oc = *leaves[leavesInBox[boxI]];
111 if( oc.hasContainedElements() )
113 const meshOctreeSlot& slot = *oc.slotPtr();
114 const label ceI = oc.containedElements();
116 forAllRow(slot.containedTriangles_, ceI, tI)
117 triangles.insert(slot.containedTriangles_(ceI, tI));
121 //- remove triangles which do not intersect the bounding box
122 labelHashSet reasonableCandidates;
124 forAllConstIter(labelHashSet, triangles, tIter)
126 const labelledTri& tri = surf[tIter.key()];
128 boundBox obb(sp[tri[0]], sp[tri[0]]);
129 for(label i=1;i<3;++i)
131 const point& v = sp[tri[i]];
132 obb.min() = Foam::min(obb.min(), v);
133 obb.max() = Foam::max(obb.max(), v);
136 const vector spanTriCorr = SMALL * obb.span();
137 obb.min() -= spanTriCorr;
138 obb.max() += spanTriCorr;
140 if( obb.overlaps(bb) )
141 reasonableCandidates.insert(tIter.key());
144 triangles.transfer(reasonableCandidates);
146 //- check if any of the surface vertices is contained within the cell
147 labelHashSet nodes, facetsInCell;
148 forAllConstIter(labelHashSet, triangles, tIter)
150 const labelledTri& tri = surf[tIter.key()];
153 nodes.insert(tri[i]);
156 //- check which surface nodes are within the cell
157 forAllConstIter(labelHashSet, nodes, nIter)
159 const point& p = sp[nIter.key()];
161 if( !bb.contains(p) )
164 bool foundIntersection(false);
167 const face& f = faces[c[fI]];
169 if( owner[c[fI]] == cellI )
173 tetrahedron<point, point> tet
176 points[f.prevLabel(pI)],
181 if( help::pointInTetrahedron(p, tet) )
184 forAllRow(pointFacets, nIter.key(), ptI)
188 pointFacets(nIter.key(), ptI)
192 foundIntersection = true;
197 if( foundIntersection )
204 tetrahedron<point, point> tet
207 points[f.nextLabel(pI)],
212 if( help::pointInTetrahedron(p, tet) )
215 forAllRow(pointFacets, nIter.key(), ptI)
219 pointFacets(nIter.key(), ptI)
223 foundIntersection = true;
228 if( foundIntersection )
234 //- check if any triangle in the surface mesh
235 //- intersects any of the cell's faces
236 forAllConstIter(labelHashSet, triangles, tIter)
238 if( facetsInCell.found(tIter.key()) )
243 const face& f = faces[c[fI]];
245 const bool intersect =
246 help::doFaceAndTriangleIntersect
257 facetsInCell.insert(tIter.key());
263 //- store the results for this cell
264 intersectedCells_[cellI] = intersected;
268 # pragma omp critical
271 facetsIntersectingCell_.setRow(cellI, facetsInCell.toc());
277 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
279 findCellsIntersectingSurface::findCellsIntersectingSurface
282 const meshOctree& octree
286 octreePtr_(const_cast<meshOctree*>(&octree)),
287 octreeGenerated_(false),
289 facetsIntersectingCell_()
291 findIntersectedCells();
294 findCellsIntersectingSurface::findCellsIntersectingSurface
297 const triSurf& surface
302 octreeGenerated_(true),
304 facetsIntersectingCell_()
306 generateOctree(surface);
308 findIntersectedCells();
311 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
313 findCellsIntersectingSurface::~findCellsIntersectingSurface()
315 if( octreeGenerated_ )
316 deleteDemandDrivenData(octreePtr_);
319 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
321 const boolList& findCellsIntersectingSurface::intersectedCells() const
323 return intersectedCells_;
326 const VRWGraph& findCellsIntersectingSurface::facetsIntersectingCells() const
328 return facetsIntersectingCell_;
331 void findCellsIntersectingSurface::addIntersectedCellsToSubset
333 const word subsetName
336 const label setId = mesh_.addCellSubset(subsetName);
338 forAll(intersectedCells_, cellI)
339 if( intersectedCells_[cellI] )
340 mesh_.addCellToSubset(setId, cellI);
343 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
345 } // End namespace Foam
347 // ************************************************************************* //