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 "meshOctree.H"
30 #include "demandDrivenData.H"
31 #include "helperFunctions.H"
34 // #define DEBUGSearch
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 void meshOctree::findNearestSurfacePoint
47 label& nearestTriangle,
55 const label cLabel = findLeafContainingVertex(p);
59 sizeVec.x() = sizeVec.y() = sizeVec.z() = searchRange_;
63 const scalar s = 0.75 * leaves_[cLabel]->size(rootBox_);
64 sizeVec.x() = sizeVec.y() = sizeVec.z() = s;
67 //- find nearest surface vertex to the point p
70 DynList<const meshOctreeCube*, 256> neighbours;
76 const boundBox bb(p - sizeVec, p + sizeVec);
79 findLeavesContainedInBox(bb, neighbours);
81 //- find nearest projection
82 forAll(neighbours, neiI)
84 if( !neighbours[neiI]->hasContainedElements() )
88 neighbours[neiI]->slotPtr()->containedTriangles_;
89 const constRow el = ct[neighbours[neiI]->containedElements()];
93 help::nearestPointOnTheTriangle(el[tI], surface_, p);
95 const scalar dSq = Foam::magSqr(p0 - p);
100 nearestTriangle = el[tI];
101 region = surface_[el[tI]].region();
110 } while( !found && (iterationI++ < 100) );
113 forAll(surface_, triI)
115 const point pp = help::nearestPointOnTheTriangle(triI, surface_, p);
117 if( distSq - magSqr(pp - p) > SMALL )
118 Pout << "Point " << p << " current nearest " << nearest
119 << " closer point " << pp << endl;
123 if( (!found || (region < 0)) && !Pstream::parRun() )
125 Warning << "Could not find a boundary region for vertex " << p << endl;
126 Warning << "Found " << found << " and region " << region << endl;
130 void meshOctree::findNearestSurfacePointInRegion
134 label& nearestTriangle,
139 const label cLabel = findLeafContainingVertex(p);
143 sizeVec.x() = sizeVec.y() = sizeVec.z() = searchRange_;
147 const scalar s = 0.75 * leaves_[cLabel]->size(rootBox_);
148 sizeVec.x() = sizeVec.y() = sizeVec.z() = s;
151 //- find nearest surface vertex to the point p
154 DynList<const meshOctreeCube*, 256> neighbours;
155 nearestTriangle = -1;
161 const boundBox bb(p - sizeVec, p + sizeVec);
164 findLeavesContainedInBox(bb, neighbours);
166 //- find nearest projection
167 forAll(neighbours, neiI)
169 if( !neighbours[neiI]->hasContainedElements() )
173 neighbours[neiI]->slotPtr()->containedTriangles_;
175 ct[neighbours[neiI]->containedElements()];
178 if( surface_[el[tI]].region() != region )
182 help::nearestPointOnTheTriangle(el[tI], surface_, p);
184 const scalar dSq = Foam::magSqr(p0 - p);
189 nearestTriangle = el[tI];
198 } while( !found && (iterationI++ < 5) );
200 if( (!found || (region < 0)) && !Pstream::parRun() )
201 Warning << "Could not find a boundary region for vertex " << p << endl;
204 bool meshOctree::findNearestEdgePoint
210 const DynList<label>& regions
213 //- find the estimate for the searching range
214 const label cLabel = findLeafContainingVertex(p);
218 sizeVec.x() = sizeVec.y() = sizeVec.z() = searchRange_;
222 const scalar s = 0.75 * leaves_[cLabel]->size(rootBox_);
223 sizeVec.x() = sizeVec.y() = sizeVec.z() = s;
226 DynList<const meshOctreeCube*, 256> neighbours;
228 const pointField& sPoints = surface_.points();
229 const edgeLongList& edges = surface_.edges();
230 const VRWGraph& edgeFaces = surface_.edgeFacets();
233 bool foundAnEdge(false);
239 // Info << "Finding nearest point for " << p << " size vec " << sizeVec << endl;
243 const boundBox bb(p - sizeVec, p + sizeVec);
246 findLeavesContainedInBox(bb, neighbours);
248 // Info << "Iteration " << iterationI << " nu found boxes "
249 // << neighbours.size() << endl;
251 forAll(neighbours, neiI)
253 if( !neighbours[neiI]->hasContainedEdges() )
256 const VRWGraph& containedEdges =
257 neighbours[neiI]->slotPtr()->containedEdges_;
259 containedEdges[neighbours[neiI]->containedEdges()];
261 // Info << "Number of contained edges in box "
262 // << neighbours[neiI]->cubeLabel()
263 // << " are " << ce.size() << endl;
267 const label edgeI = ce[eI];
269 //- find if the edge is in correct patches
270 bool correctPatches(true);
272 forAllRow(edgeFaces, edgeI, efI)
274 const label facetI = edgeFaces(edgeI, efI);
276 if( !regions.contains(surface_[facetI].region()) )
278 correctPatches = false;
283 if( !correctPatches )
286 const edge& e = edges[edgeI];
287 const point& sp = sPoints[e.start()];
288 const point& ep = sPoints[e.end()];
289 const point np = help::nearestPointOnTheEdgeExact(sp, ep, p);
290 const scalar dSq = Foam::magSqr(np - p);
296 nearestEdge = ce[eI];
305 } while( !foundAnEdge && (++iterationI < 3) );
310 bool meshOctree::findNearestPointToEdge
315 const FixedList<point, 2>& edgePoints,
316 const FixedList<label, 2>& edgePointRegions
319 const point c = 0.5 * (edgePoints[0] + edgePoints[1]);
320 const scalar dst = mag(edgePoints[0] - edgePoints[1]);
321 vector sizeVec(dst, dst, dst);
323 boundBox bb(c - 0.75 * sizeVec, c + 0.75 * sizeVec);
325 DynList<const meshOctreeCube*, 256> leavesInBox;
326 findLeavesContainedInBox(bb, leavesInBox);
328 const VRWGraph& edgeFaces = surface_.edgeFacets();
329 const pointField& points = surface_.points();
330 const edgeLongList& surfaceEdges = surface_.edges();
337 forAll(leavesInBox, leafI)
339 if( !leavesInBox[leafI]->hasContainedEdges() )
342 const VRWGraph& containedEdges =
343 leavesInBox[leafI]->slotPtr()->containedEdges_;
344 const constRow edges =
345 containedEdges[leavesInBox[leafI]->containedEdges()];
349 const constRow ef = edgeFaces[edges[eI]];
355 (surface_[ef[0]].region() == edgePointRegions[0]) &&
356 (surface_[ef[1]].region() == edgePointRegions[1])
359 (surface_[ef[1]].region() == edgePointRegions[0]) &&
360 (surface_[ef[0]].region() == edgePointRegions[1])
364 const edge& edg = surfaceEdges[edges[eI]];
366 point nearestOnEdge, nearestOnLine;
368 help::nearestEdgePointToTheLine
379 if( magSqr(nearestOnEdge - nearestOnLine) < distSq )
381 nearest = nearestOnEdge;
382 nearestEdge = edges[eI];
383 distSq = magSqr(nearestOnEdge - nearestOnLine);
394 bool meshOctree::findNearestCorner
400 const DynList<label>& patches
405 const label cLabel = findLeafContainingVertex(p);
409 sizeVec.x() = sizeVec.y() = sizeVec.z() = searchRange_;
413 const scalar s = 0.75 * leaves_[cLabel]->size(rootBox_);
414 sizeVec.x() = sizeVec.y() = sizeVec.z() = s;
417 //- find nearest surface vertex to the point p
420 DynList<const meshOctreeCube*, 256> neighbours;
422 const pointField& points = surface_.points();
423 const VRWGraph& pEdges = surface_.pointEdges();
424 const VRWGraph& eFacets = surface_.edgeFacets();
431 const boundBox bb(p - sizeVec, p + sizeVec);
434 findLeavesContainedInBox(bb, neighbours);
435 labelHashSet checkedPoint;
437 //- find nearest projection
438 forAll(neighbours, neiI)
440 if( !neighbours[neiI]->hasContainedElements() )
444 neighbours[neiI]->slotPtr()->containedTriangles_;
445 const constRow el = ct[neighbours[neiI]->containedElements()];
448 const labelledTri& tri = surface_[el[tI]];
452 const label spI = tri[pI];
454 if( checkedPoint.found(spI) )
457 checkedPoint.insert(spI);
459 DynList<label> nodePatches;
462 forAllRow(pEdges, spI, i)
464 const label eI = pEdges(spI, i);
466 if( eFacets.sizeOfRow(eI) != 2 )
470 surface_[eFacets(eI, 0)].region() !=
471 surface_[eFacets(eI, 1)].region()
474 //- found an edge attached to this vertex
476 nodePatches.appendIfNotIn
478 surface_[eFacets(eI, 0)].region()
480 nodePatches.appendIfNotIn
482 surface_[eFacets(eI, 1)].region()
489 //- check if all required patches
490 //- are present at this corner
494 if( nodePatches.contains(patches[i]) )
498 if( nEdges >= patches.size() )
500 //- all patches are present, check the distance
501 const scalar dSq = Foam::magSqr(points[spI] - p);
507 nearest = points[spI];
519 } while( !found && (iterationI++ < 3) );
524 bool meshOctree::findNearestPointToPatches
529 const DynList<label>& patches,
533 if( patches.size() == 0 )
541 point newP(vector::zero);
542 forAll(patches, patchI)
546 this->findNearestSurfacePointInRegion
558 newP /= patches.size();
559 distSq = magSqr(newP - p);
561 if( Foam::magSqr(newP - nearest) < tol * distSq )
570 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
572 } // End namespace Foam
574 // ************************************************************************* //