Loading...
Searching...
No Matches
dynamicIndexedOctree.H
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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27Class
28 Foam::dynamicIndexedOctree
29
30Description
31 Non-pointer based hierarchical recursive searching.
32 Storage is dynamic, so elements can be deleted.
33
34SourceFiles
35 dynamicIndexedOctree.C
36
37\*---------------------------------------------------------------------------*/
38
39#ifndef Foam_dynamicIndexedOctree_H
40#define Foam_dynamicIndexedOctree_H
41
42#include "indexedOctree.H"
43#include "DynamicList.H"
44
45// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46
47namespace Foam
49
50// Forward Declarations
51template<class Type> class dynamicIndexedOctree;
52template<class Type>
54
55
56/*---------------------------------------------------------------------------*\
57 Class dynamicIndexedOctreeBase Declaration
58\*---------------------------------------------------------------------------*/
59
60//- Template invariant parts for dynamicIndexedOctree
61// Same type of node bookkeeping as indexedOctree
63:
65{
66public:
67
68 //- Document that we are using the same types of node
70
71 //- Runtime type information
72 ClassName("dynamicIndexedOctree");
73
75 // Constructors
76
77 //- Default construct
78 dynamicIndexedOctreeBase() = default;
79};
80
81
82/*---------------------------------------------------------------------------*\
83 Class dynamicIndexedOctree Declaration
84\*---------------------------------------------------------------------------*/
85
86template<class Type>
88:
90{
91 // Private Data
92
93 //- Underlying shapes for geometric queries.
94 const Type shapes_;
95
96 const treeBoundBox bb_;
97
98 const label maxLevels_;
99
100 //- Current number of levels in the tree.
101 label nLevelsMax_;
102
103 const scalar maxLeafRatio_;
104
105 const label minSize_;
106
107 const scalar maxDuplicity_;
108
109 //- List of all nodes
110 DynamicList<node> nodes_;
111
112 //- List of all contents (referenced by those nodes that are contents)
114
115 //- Per node per octant whether is fully inside/outside/mixed.
116 mutable PackedList<2> nodeTypes_;
117
118
119 // Private Member Functions
120
121 // Construction
122
123 //- Split list of indices into 8 bins
124 // according to where they are in relation to mid.
125 void divide
126 (
127 const labelUList& indices,
128 const treeBoundBox& bb,
129 FixedList<DynamicList<label>, 8>& dividedIndices
130 ) const;
131
132 //- Subdivide the contents node at position contentI.
133 // Appends to contents.
134 node divide
135 (
136 const treeBoundBox& bb,
137 label contentIndex,
138 const label parentNodeIndex,
139 const label octantToBeDivided
140 );
141
142 // Recursively call the divide function
143 void recursiveSubDivision
144 (
145 const treeBoundBox& subBb,
146 const label contentI,
147 const label parentIndex,
148 const label octant,
149 label& nLevels
150 );
151
152 //- Determine inside/outside per node (mixed if cannot be
153 // determined). Only valid for closed shapes.
154 volumeType calcVolumeType(const label nodeI) const;
155
156 //- Search cached volume type.
157 volumeType getVolumeType(const label nodeI, const point&) const;
158
159
160 // Query
161
162 //- Find nearest point to line.
163 void findNearest
164 (
165 const label nodeI,
166 const linePointRef& ln,
167
168 treeBoundBox& tightest,
169 label& nearestShapeI,
170 point& linePoint,
171 point& nearestPoint
172 ) const;
173
174 //- Return bbox of octant
175 treeBoundBox subBbox
176 (
177 const label parentNodeI,
178 const direction octant
179 ) const;
180
181 //- Helper: take a point on/close to face of bb and push it
182 // inside or outside of bb.
183 static point pushPoint
184 (
185 const treeBoundBox&,
186 const point&,
187 const bool pushInside
188 );
189
190 //- Helper: take a point on face of bb and push it
191 // inside or outside of bb.
192 static point pushPoint
193 (
194 const treeBoundBox&,
195 const direction,
196 const point&,
197 const bool pushInside
198 );
199
200 //- Helper: take point on face(s) of bb and push it away from
201 // edges of face. If pt is not on a face does nothing.
202 static point pushPointIntoFace
203 (
204 const treeBoundBox& bb,
205 const vector& dir, // end-start
206 const point& pt
207 );
208
209 //- Walk to parent of node+octant.
210 // Return false if top of tree reached.
211 bool walkToParent
212 (
213 const label nodeI,
214 const direction octant,
215
216 label& parentNodeI,
217 label& parentOctant
218 ) const;
219
220 //- Walk tree to neighbouring node. Return false if edge of tree
221 // hit.
222 bool walkToNeighbour
223 (
224 const point& facePoint,
225 const direction faceID, // direction to walk in
226 label& nodeI,
227 direction& octant
228 ) const;
229
230 //- Debug: return verbose the bounding box faces
231 static word faceString(const direction faceID);
232
233 //- Traverse a node. If intersects a triangle return first
234 // intersection point.
235 // findAny=true : return any intersection
236 // findAny=false: return nearest (to start) intersection
237 void traverseNode
238 (
239 const bool findAny,
240 const point& treeStart,
241 const vector& treeVec,
242
243 const point& start,
244 const point& end,
245 const label nodeI,
246 const direction octantI,
247
248 pointIndexHit& hitInfo,
249 direction& faceID
250 ) const;
251
252 //- Find any or nearest intersection
253 pointIndexHit findLine
254 (
255 const bool findAny,
256 const point& treeStart,
257 const point& treeEnd,
258 const label startNodeI,
259 const direction startOctantI,
260 const bool verbose = false
261 ) const;
262
263 //- Find any or nearest intersection of line between start and end.
264 pointIndexHit findLine
265 (
266 const bool findAny,
267 const point& start,
268 const point& end
269 ) const;
270
271 //- Find elements intersecting box
272 // Store all results in elements (if non-null), or early exit
273 bool findBox
274 (
275 const label nodeI,
276 const treeBoundBox& searchBox,
277 labelHashSet* elements
278 ) const;
279
280 //- Find elements intersecting sphere.
281 // Store all results in elements (if non-null), or early exit
282 bool findSphere
283 (
284 const label nodeI,
285 const point& centre,
286 const scalar radiusSqr,
287 labelHashSet* elements
288 ) const;
289
290
291 template<class CompareOp>
292 static void findNear
293 (
294 const scalar nearDist,
295 const bool okOrder,
296 const dynamicIndexedOctree<Type>& tree1,
297 const labelBits index1,
298 const treeBoundBox& bb1,
299 const dynamicIndexedOctree<Type>& tree2,
300 const labelBits index2,
301 const treeBoundBox& bb2,
302 CompareOp& cop
303 );
304
305
306 // Other
307
308 //- Count number of elements on this and sublevels
309 label countElements(const labelBits index) const;
310
311 //- Write node treeBoundBoxes in OBJ format
312 void writeOBJ
313 (
314 const label nodeI,
315 Ostream& os,
316 label& vertIndex,
317 const bool leavesOnly,
318 const bool writeLinesOnly = false
319 ) const;
320
321 //- Dump node+octant to an obj file
322 void writeOBJ(const label nodeI, const direction octant) const;
323
324
325public:
326
327 // Constructors
328
329 //- Construct from shapes
331 (
332 const Type& shapes,
333 const treeBoundBox& bb,
334 const label maxLevels, // maximum number of levels
335 const scalar maxLeafRatio, // how many elements per leaf
336 const scalar maxDuplicity // in how many leaves is a shape on
337 // average
338 );
339
340 //- Clone
342 {
344 }
345
346
347 // Member Functions
348
349 // Access
350
351 //- Reference to shape
352 const Type& shapes() const noexcept { return shapes_; }
353
354 //- List of all nodes
355 const List<node>& nodes() const noexcept { return nodes_; }
356
357 //- List of all contents
358 //- (referenced by those nodes that are contents)
359 const DynamicList<DynamicList<label>>& contents() const noexcept
360 {
361 return contents_;
362 }
363
364 //- Per node, per octant whether is fully inside/outside/mixed.
365 PackedList<2>& nodeTypes() const noexcept
366 {
367 return nodeTypes_;
368 }
369
370 //- Top bounding box
371 const treeBoundBox& bb() const
372 {
373 if (nodes_.empty())
374 {
375 return treeBoundBox::null();
376 }
377 return nodes_[0].bb_;
378 }
379
380
381 // Queries
382
383 //- Calculate nearest point on nearest shape.
384 // Returns
385 // - bool : any point found nearer than nearestDistSqr
386 // - label: index in shapes
387 // - point: actual nearest point found
388 pointIndexHit findNearest
389 (
390 const point& sample,
391 const scalar nearestDistSqr
392 ) const;
393
394 //- Low level: calculate nearest starting from subnode.
395 void findNearest
396 (
397 const label nodeI,
398 const point&,
399
400 scalar& nearestDistSqr,
401 label& nearestShapeI,
402 point& nearestPoint
403 ) const;
404
405 //- Find nearest to line.
406 // Returns
407 // - bool : any point found?
408 // - label: index in shapes
409 // - point: actual nearest point found
410 // sets:
411 // - linePoint : corresponding nearest point on line
412 pointIndexHit findNearest
413 (
414 const linePointRef& ln,
415 treeBoundBox& tightest,
416 point& linePoint
417 ) const;
418
419 //- Find nearest intersection of line between start and end.
420 pointIndexHit findLine
421 (
422 const point& start,
423 const point& end
424 ) const;
425
426 //- Find any intersection of line between start and end.
429 const point& start,
430 const point& end
431 ) const;
432
433 //- True if any shapes overlap the bounding box
434 bool overlaps(const treeBoundBox& bb) const;
435
436 //- Find indices of all shapes inside or overlapping
437 //- a bounding box (i.e. all shapes not outside box)
438 // \returns the indices (in no particular order)
439 labelList findBox
440 (
441 const treeBoundBox& bb
442 ) const;
443
444 //- Find indices of all shapes inside or overlapping
445 //- a bounding box (i.e. all shapes not outside box)
446 // \returns the number of elements found
447 label findBox
448 (
449 const treeBoundBox& bb,
450 labelHashSet& elements
451 ) const;
452
453 //- True if any shapes overlap the bounding sphere
454 bool overlaps
455 (
456 const point& centre,
457 const scalar radiusSqr
458 ) const;
459
460 //- Find indices of all shapes inside or overlapping
461 //- a bounding sphere (i.e. all shapes not outside a sphere)
462 // \returns the indices (in no particular order)
463 labelList findSphere
464 (
465 const point& centre,
466 const scalar radiusSqr
467 ) const;
468
469 //- Find indices of all shapes inside or overlapping
470 //- a bounding sphere (i.e. all shapes not outside sphere)
471 // \returns the number of elements found
472 label findSphere
473 (
474 const point& centre,
475 const scalar radiusSqr,
476 labelHashSet& elements
477 ) const;
478
479
480 //- Find deepest node (as parent+octant) containing point. Starts
481 // off from starting index in nodes_ (use 0 to start from top)
482 // Use getNode and getOctant to extract info, or call findIndices.
483 labelBits findNode(const label nodeI, const point&) const;
484
485 //- Find shape containing point. Only implemented for certain
486 // shapes.
487 label findInside(const point&) const;
488
489 //- Find the shape indices that occupy the result of findNode
490 const labelList& findIndices(const point&) const;
491
492 //- Determine type (inside/outside/mixed) for point. unknown if
493 // cannot be determined (e.g. non-manifold surface)
494 volumeType getVolumeType(const point&) const;
495
496 //- Helper function to return the side. Returns outside if
497 // outsideNormal&vec >= 0, inside otherwise
498 static volumeType getSide
499 (
500 const vector& outsideNormal,
501 const vector& vec
502 );
503
504 //- Find near pairs and apply CompareOp to them.
505 // tree2 can be *this or different tree.
506 template<class CompareOp>
507 void findNear
508 (
509 const scalar nearDist,
510 const dynamicIndexedOctree<Type>& tree2,
511 CompareOp& cop
512 ) const;
513
514
515 // Edit
516
517 //- Insert a new object into the tree.
518 bool insert(label startIndex, label endIndex);
519
520 bool insertIndex
521 (
522 const label nodIndex,
523 const label index,
524 label& nLevels
525 );
526
527 //- Remove an object from the tree.
528 bool remove(const label index);
529
530 label removeIndex(const label nodIndex, const label index);
531
532
533 // Write
534
535 //- Write all tree boxes as OBJ format
536 void writeOBJ(Ostream& os) const;
537
538 //- Print tree. Either print all indices (printContent = true) or
539 // just size of contents nodes.
540 void print
541 (
543 const bool printContents,
544 const label
545 ) const;
546
547 bool write(Ostream& os) const;
548
549 void writeTreeInfo() const;
550
551
552 // IOstream Operators
553
554 friend Ostream& operator<< <Type>
555 (
556 Ostream&,
558 );
559};
560
561
562// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
563
564} // End namespace Foam
565
566// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
567
568#ifdef NoRepository
569 #include "dynamicIndexedOctree.C"
570#endif
571
572// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
573
574#endif
575
576// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
A 1D vector of objects of type <T> with a fixed length <N>.
Definition FixedList.H:73
Minimal example by using system/controlDict.functions:
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition PackedList.H:146
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
ClassName("dynamicIndexedOctree")
Runtime type information.
dynamicIndexedOctreeBase()=default
Default construct.
indexedOctreeBase::node node
Document that we are using the same types of node.
Non-pointer based hierarchical recursive searching. Storage is dynamic, so elements can be deleted.
label findInside(const point &) const
Find shape containing point. Only implemented for certain.
const List< node > & nodes() const noexcept
List of all nodes.
const labelList & findIndices(const point &) const
Find the shape indices that occupy the result of findNode.
const Type & shapes() const noexcept
Reference to shape.
const treeBoundBox & bb() const
Top bounding box.
label removeIndex(const label nodIndex, const label index)
bool overlaps(const treeBoundBox &bb) const
True if any shapes overlap the bounding box.
autoPtr< dynamicIndexedOctree< Type > > clone() const
Clone.
void print(prefixOSstream &, const bool printContents, const label) const
Print tree. Either print all indices (printContent = true) or.
static volumeType getSide(const vector &outsideNormal, const vector &vec)
Helper function to return the side. Returns outside if.
dynamicIndexedOctree(const Type &shapes, const treeBoundBox &bb, const label maxLevels, const scalar maxLeafRatio, const scalar maxDuplicity)
Construct from shapes.
bool remove(const label index)
Remove an object from the tree.
labelBits findNode(const label nodeI, const point &) const
Find deepest node (as parent+octant) containing point. Starts.
PackedList< 2 > & nodeTypes() const noexcept
Per node, per octant whether is fully inside/outside/mixed.
const DynamicList< DynamicList< label > > & contents() const noexcept
List of all contents (referenced by those nodes that are contents).
bool insertIndex(const label nodIndex, const label index, label &nLevels)
pointIndexHit findLineAny(const point &start, const point &end) const
Find any intersection of line between start and end.
Tree node. Has up pointer and down pointers.
indexedOctreeBase()=default
Default construct.
A 29bits (or 61bits) integer label with 3bits direction (eg, octant) packed into single label.
Definition labelBits.H:49
Version of OSstream that prints a prefix on each line.
Standard boundBox with extra functionality for use in octree.
static const treeBoundBox & null() noexcept
The null treeBoundBox is the same as an inverted box.
An enumeration wrapper for classification of a location as being inside/outside of a volume.
Definition volumeType.H:56
A class for handling words, derived from Foam::string.
Definition word.H:66
#define ClassName(TypeNameString)
Add typeName information from argument TypeNameString to a class.
Definition className.H:74
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< label > labelList
A List of labels.
Definition List.H:62
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
label facePoint(const int facei, const block &block, const label i, const label j)
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
line< point, const point & > linePointRef
A line using referred points.
Definition line.H:66
uint8_t direction
Definition direction.H:49
vector point
Point is a vector.
Definition point.H:37
const direction noexcept
Definition scalarImpl.H:265
Vector< scalar > vector
Definition vector.H:57
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
UList< label > labelUList
A UList of labels.
Definition UList.H:75
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition POSIX.C:1239
runTime write()
nonInt insert("surfaceSum(((S|magSf)*S)")