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 "meshOctreeAddressing.H"
29 #include "demandDrivenData.H"
30 #include "IOdictionary.H"
31 #include "helperFunctions.H"
33 #include "meshOctreeModifier.H"
35 // #define DEBUGSearch
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 void meshOctreeAddressing::clearOut()
44 clearNodeAddressing();
48 clearParallelAddressing();
51 void meshOctreeAddressing::clearNodeAddressing()
54 deleteDemandDrivenData(octreePointsPtr_);
55 deleteDemandDrivenData(nodeLabelsPtr_);
56 deleteDemandDrivenData(nodeLeavesPtr_);
58 deleteDemandDrivenData(nodeTypePtr_);
61 void meshOctreeAddressing::clearBoxTypes()
63 deleteDemandDrivenData(boxTypePtr_);
66 void meshOctreeAddressing::clearOctreeFaces()
68 deleteDemandDrivenData(octreeFacesPtr_);
69 deleteDemandDrivenData(octreeFacesOwnersPtr_);
70 deleteDemandDrivenData(octreeFacesNeighboursPtr_);
73 void meshOctreeAddressing::clearAddressing()
75 deleteDemandDrivenData(leafFacesPtr_);
76 deleteDemandDrivenData(nodeFacesPtr_);
77 deleteDemandDrivenData(leafLeavesPtr_);
78 deleteDemandDrivenData(octreeEdgesPtr_);
79 deleteDemandDrivenData(edgeLeavesPtr_);
80 deleteDemandDrivenData(leafEdgesPtr_);
81 deleteDemandDrivenData(nodeEdgesPtr_);
82 deleteDemandDrivenData(faceEdgesPtr_);
83 deleteDemandDrivenData(edgeFacesPtr_);
86 void meshOctreeAddressing::clearParallelAddressing()
88 deleteDemandDrivenData(globalPointLabelPtr_);
89 deleteDemandDrivenData(globalPointToLocalPtr_);
90 deleteDemandDrivenData(pointProcsPtr_);
91 deleteDemandDrivenData(globalFaceLabelPtr_);
92 deleteDemandDrivenData(globalFaceToLocalPtr_);
93 deleteDemandDrivenData(faceProcsPtr_);
94 deleteDemandDrivenData(globalLeafLabelPtr_);
95 deleteDemandDrivenData(globalLeafToLocalPtr_);
96 deleteDemandDrivenData(leafAtProcsPtr_);
99 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
101 // Construct from octree and IOdictionary
102 meshOctreeAddressing::meshOctreeAddressing
104 const meshOctree& mo,
105 const dictionary& dict,
111 useDATABoxes_(useDATABoxes),
113 octreePointsPtr_(NULL),
114 nodeLabelsPtr_(NULL),
115 nodeLeavesPtr_(NULL),
118 octreeFacesPtr_(NULL),
119 octreeFacesOwnersPtr_(NULL),
120 octreeFacesNeighboursPtr_(NULL),
123 leafLeavesPtr_(NULL),
124 octreeEdgesPtr_(NULL),
125 edgeLeavesPtr_(NULL),
130 globalPointLabelPtr_(NULL),
131 globalPointToLocalPtr_(NULL),
132 pointProcsPtr_(NULL),
133 globalFaceLabelPtr_(NULL),
134 globalFaceToLocalPtr_(NULL),
136 globalLeafLabelPtr_(NULL),
137 globalLeafToLocalPtr_(NULL),
138 leafAtProcsPtr_(NULL)
140 if( !useDATABoxes && dict.found("keepCellsIntersectingBoundary") )
142 useDATABoxes_ = readBool(dict.lookup("keepCellsIntersectingBoundary"));
145 if( dict.found("nonManifoldMeshing") )
147 const bool nonManifoldMesh
149 readBool(dict.lookup("nonManifoldMeshing"))
152 if( nonManifoldMesh )
153 useDATABoxes_ = true;
156 if( Pstream::parRun() )
158 meshOctreeModifier om(const_cast<meshOctree&>(octree_));
159 om.addLayerFromNeighbouringProcessors();
162 //- check for glued regions
166 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
168 meshOctreeAddressing::~meshOctreeAddressing()
173 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
175 bool meshOctreeAddressing::isIntersectedFace(const label fI) const
177 const labelLongList& owner = octreeFaceOwner();
178 const labelLongList& neighbour = octreeFaceNeighbour();
180 if( neighbour[fI] < 0 )
183 Map<label> nAppearances;
184 DynList<label> triangles;
185 octree_.containedTriangles(owner[fI], triangles);
186 forAll(triangles, triI)
188 if( nAppearances.found(triangles[triI]) )
190 ++nAppearances[triangles[triI]];
194 nAppearances.insert(triangles[triI], 1);
199 octree_.containedTriangles(neighbour[fI], triangles);
200 forAll(triangles, triI)
202 if( nAppearances.found(triangles[triI]) )
204 ++nAppearances[triangles[triI]];
208 nAppearances.insert(triangles[triI], 1);
212 forAllConstIter(Map<label>, nAppearances, iter)
218 octree_.returnLeaf(owner[fI]).level() ==
219 octree_.returnLeaf(neighbour[fI]).level()
223 //- check intersection by geometric testing
224 const triSurf& surf = octree_.surface();
225 const pointField& points = this->octreePoints();
226 const VRWGraph& faces = this->octreeFaces();
228 face f(faces.sizeOfRow(fI));
230 f[pI] = faces(fI, pI);
233 help::doFaceAndTriangleIntersect
248 bool meshOctreeAddressing::isIntersectedEdge(const label eI) const
250 const VRWGraph& edgeCubes = this->edgeLeaves();
252 Map<label> nAppearances;
253 DynList<label> triangles;
254 bool sameLevel(true);
256 forAllRow(edgeCubes, eI, i)
258 const label leafI = edgeCubes(eI, i);
259 if( !octree_.hasContainedTriangles(leafI) )
264 octree_.returnLeaf(leafI).level() !=
265 octree_.returnLeaf(edgeCubes(eI, 0)).level()
270 octree_.containedTriangles(leafI, triangles);
271 forAll(triangles, triI)
273 if( nAppearances.found(triangles[triI]) )
275 ++nAppearances[triangles[triI]];
279 nAppearances.insert(triangles[triI], 1);
284 forAllConstIter(Map<label>, nAppearances, iter)
286 if( iter() == edgeCubes.sizeOfRow(eI) )
291 //- check for geometric intersection
292 const LongList<edge>& edges = this->octreeEdges();
293 const pointField& points = this->octreePoints();
294 point intersection(vector::zero);
297 help::triLineIntersection
301 points[edges[eI].start()],
302 points[edges[eI].end()],
313 void meshOctreeAddressing::edgeIntersections
316 DynList<point>& intersections
319 intersections.clear();
321 const LongList<edge>& edges = this->octreeEdges();
322 const pointField& points = this->octreePoints();
323 const VRWGraph& edgeCubes = this->edgeLeaves();
325 SMALL * mag(points[edges[eI].start()] - points[edges[eI].end()]);
327 Map<label> nAppearances;
328 DynList<label> triangles;
330 forAllRow(edgeCubes, eI, i)
332 const label leafI = edgeCubes(eI, i);
333 if( !octree_.hasContainedTriangles(leafI) )
337 octree_.containedTriangles(leafI, triangles);
338 forAll(triangles, triI)
340 if( nAppearances.found(triangles[triI]) )
342 ++nAppearances[triangles[triI]];
346 nAppearances.insert(triangles[triI], 1);
351 point intersection(vector::zero);
353 forAllConstIter(Map<label>, nAppearances, iter)
355 if( iter() == edgeCubes.sizeOfRow(eI) )
357 //- check for geometric intersection
358 const bool intersectionExists =
359 help::triLineIntersection
363 points[edges[eI].start()],
364 points[edges[eI].end()],
368 if( intersectionExists )
371 forAll(intersections, i)
372 if( mag(intersections[i] - intersection) <= tol )
376 intersections.append(intersection);
382 void meshOctreeAddressing::cubesAroundEdge
386 FixedList<label, 4>& edgeCubes
389 const VRWGraph& nl = this->nodeLabels();
390 const label nodeI = nl(leafI, meshOctreeCubeCoordinates::edgeNodes_[eI][0]);
391 const FRWGraph<label, 8>& pLeaves = this->nodeLeaves();
395 case 0: case 1: case 2: case 3:
397 edgeCubes[0] = pLeaves(nodeI, 1);
398 edgeCubes[1] = pLeaves(nodeI, 3);
399 edgeCubes[2] = pLeaves(nodeI, 5);
400 edgeCubes[3] = pLeaves(nodeI, 7);
402 case 4: case 5: case 6: case 7:
404 edgeCubes[0] = pLeaves(nodeI, 2);
405 edgeCubes[1] = pLeaves(nodeI, 3);
406 edgeCubes[2] = pLeaves(nodeI, 6);
407 edgeCubes[3] = pLeaves(nodeI, 7);
409 case 8: case 9: case 10: case 11:
411 edgeCubes[0] = pLeaves(nodeI, 4);
412 edgeCubes[1] = pLeaves(nodeI, 5);
413 edgeCubes[2] = pLeaves(nodeI, 6);
414 edgeCubes[3] = pLeaves(nodeI, 7);
420 "void tetMeshExtractorOctree::cubesAroundEdge(const label,"
421 "const direction, FixedList<label, 4>&)"
422 ) << "Invalid edge specified!!" << abort(FatalError);
427 label meshOctreeAddressing::findEdgeCentre
433 if( octree_.isQuadtree() && eI >= 8 )
436 const meshOctreeCubeBasic& oc = octree_.returnLeaf(leafI);
437 const VRWGraph& nl = this->nodeLabels();
438 const label nodeI = nl(leafI, meshOctreeCubeCoordinates::edgeNodes_[eI][0]);
439 const FRWGraph<label, 8>& pLeaves = this->nodeLeaves();
441 const direction level = oc.level();
446 case 0: case 1: case 2: case 3:
450 case 4: case 5: case 6: case 7:
454 case 8: case 9: case 10: case 11:
462 "label meshOctreeAddressing::findEdgeCentre"
463 "(const label leafI, const direction eI) const"
464 ) << "Invalid edge specified!!" << abort(FatalError);
468 for(label i=0;i<4;++i)
470 const label fNode = meshOctreeCubeCoordinates::faceNodes_[fI][i];
472 if( pLeaves(nodeI, fNode) < 0 )
475 const label leafJ = pLeaves(nodeI, fNode);
476 if( octree_.returnLeaf(leafJ).level() > level )
478 const label shift = (i+2)%4;
479 return nl(leafJ, meshOctreeCubeCoordinates::faceNodes_[fI][shift]);
486 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
488 } // End namespace Foam
490 // ************************************************************************* //