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-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Class
27 Foam::dynamicIndexedOctree
28
29Description
30 Non-pointer based hierarchical recursive searching.
31 Storage is dynamic, so elements can be deleted.
32
33SourceFiles
34 dynamicIndexedOctree.C
35
36\*---------------------------------------------------------------------------*/
37
38#ifndef dynamicIndexedOctree_H
39#define dynamicIndexedOctree_H
40
41#include "treeBoundBox.H"
42#include "pointIndexHit.H"
43#include "FixedList.H"
44#include "Ostream.H"
45#include "HashSet.H"
46#include "labelBits.H"
47#include "PackedList.H"
48#include "volumeType.H"
49
50// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51
52namespace Foam
53{
56
57// Forward declaration of classes
58template<class Type> class dynamicIndexedOctree;
60template<class Type> Ostream& operator<<
61(
62 Ostream&,
64);
65
66class Istream;
67
68
69/*---------------------------------------------------------------------------*\
70 Class dynamicIndexedOctreeName Declaration
71\*---------------------------------------------------------------------------*/
74
75
76/*---------------------------------------------------------------------------*\
77 Class dynamicIndexedOctree Declaration
78\*---------------------------------------------------------------------------*/
79
80template<class Type>
82:
83 public dynamicIndexedOctreeName
84{
85public:
86
87 // Data types
88
89 //- Tree node. Has up pointer and down pointers.
90 class node
91 {
92 public:
93
94 //- Bounding box of this node
96
97 //- Parent node (index into nodes_ of tree)
98 label parent_;
99
100 //- IDs of the 8 nodes on all sides of the mid point
103 friend Ostream& operator<< (Ostream& os, const node& n)
104 {
105 return os << n.bb_ << token::SPACE
106 << n.parent_ << token::SPACE << n.subNodes_;
107 }
109 friend Istream& operator>> (Istream& is, node& n)
110 {
111 return is >> n.bb_ >> n.parent_ >> n.subNodes_;
112 }
114 friend bool operator==(const node& a, const node& b)
115 {
116 return
117 a.bb_ == b.bb_
118 && a.parent_ == b.parent_
119 && a.subNodes_ == b.subNodes_;
120 }
122 friend bool operator!=(const node& a, const node& b)
123 {
124 return !(a == b);
125 }
126 };
127
128
129private:
130
131 // Static data
132
133 //- Relative perturbation tolerance. Determines when point is
134 // considered to be close to face/edge of bb of node.
135 // The tolerance is relative to the bounding box of the smallest
136 // node.
137 static scalar perturbTol_;
138
139
140 // Private data
141
142 //- Underlying shapes for geometric queries.
143 const Type shapes_;
144
145 const treeBoundBox bb_;
146
147 const label maxLevels_;
148
149 //- Current number of levels in the tree.
150 label nLevelsMax_;
151
152 const scalar maxLeafRatio_;
153
154 const label minSize_;
155
156 const scalar maxDuplicity_;
157
158 //- List of all nodes
159 DynamicList<node> nodes_;
160
161 //- List of all contents (referenced by those nodes that are contents)
162 contentListList contents_;
163
164 //- Per node per octant whether is fully inside/outside/mixed.
165 mutable PackedList<2> nodeTypes_;
166
167 // Private Member Functions
168
169 //- Helper: does bb intersect a sphere around sample? Or is any
170 // corner point of bb closer than nearestDistSqr to sample.
171 // (bb is implicitly provided as parent bb + octant)
172 static bool overlaps
173 (
174 const treeBoundBox& parentBb,
175 const direction octant,
176 const scalar nearestDistSqr,
177 const point& sample
178 );
179
180 // Construction
181
182 //- Split list of indices into 8 bins
183 // according to where they are in relation to mid.
184 void divide
185 (
186 const autoPtr<DynamicList<label>>& indices,
187 const treeBoundBox& bb,
188 contentListList& result
189 ) const;
190
191 //- Subdivide the contents node at position contentI.
192 // Appends to contents.
193 node divide
194 (
195 const treeBoundBox& bb,
196 const label contentI,
197 const label parentNodeIndex,
198 const label octantToBeDivided
199 );
200
201 // Recursively call the divide function
202 void recursiveSubDivision
203 (
204 const treeBoundBox& subBb,
205 const label contentI,
206 const label parentIndex,
207 const label octant,
208 label& nLevels
209 );
210
211 //- Determine inside/outside per node (mixed if cannot be
212 // determined). Only valid for closed shapes.
213 volumeType calcVolumeType(const label nodeI) const;
214
215 //- Search cached volume type.
216 volumeType getVolumeType(const label nodeI, const point&) const;
217
218
219 // Query
220
221 //- Find nearest point to line.
222 void findNearest
223 (
224 const label nodeI,
225 const linePointRef& ln,
226
227 treeBoundBox& tightest,
228 label& nearestShapeI,
229 point& linePoint,
230 point& nearestPoint
231 ) const;
232
233 //- Return bbox of octant
234 treeBoundBox subBbox
235 (
236 const label parentNodeI,
237 const direction octant
238 ) const;
239
240 //- Helper: take a point on/close to face of bb and push it
241 // inside or outside of bb.
242 static point pushPoint
243 (
244 const treeBoundBox&,
245 const point&,
246 const bool pushInside
247 );
248
249 //- Helper: take a point on face of bb and push it
250 // inside or outside of bb.
251 static point pushPoint
252 (
253 const treeBoundBox&,
254 const direction,
255 const point&,
256 const bool pushInside
257 );
258
259 //- Helper: take point on face(s) of bb and push it away from
260 // edges of face. If pt is not on a face does nothing.
261 static point pushPointIntoFace
262 (
263 const treeBoundBox& bb,
264 const vector& dir, // end-start
265 const point& pt
266 );
267
268 //- Walk to parent of node+octant.
269 // Return false if top of tree reached.
270 bool walkToParent
271 (
272 const label nodeI,
273 const direction octant,
274
275 label& parentNodeI,
276 label& parentOctant
277 ) const;
278
279 //- Walk tree to neighbouring node. Return false if edge of tree
280 // hit.
281 bool walkToNeighbour
282 (
283 const point& facePoint,
284 const direction faceID, // direction to walk in
285 label& nodeI,
286 direction& octant
287 ) const;
288
289 //- Debug: return verbose the bounding box faces
290 static word faceString(const direction faceID);
291
292 //- Traverse a node. If intersects a triangle return first
293 // intersection point.
294 // findAny=true : return any intersection
295 // findAny=false: return nearest (to start) intersection
296 void traverseNode
297 (
298 const bool findAny,
299 const point& treeStart,
300 const vector& treeVec,
301
302 const point& start,
303 const point& end,
304 const label nodeI,
305 const direction octantI,
306
307 pointIndexHit& hitInfo,
308 direction& faceID
309 ) const;
310
311 //- Find any or nearest intersection
312 pointIndexHit findLine
313 (
314 const bool findAny,
315 const point& treeStart,
316 const point& treeEnd,
317 const label startNodeI,
318 const direction startOctantI,
319 const bool verbose = false
320 ) const;
321
322 //- Find any or nearest intersection of line between start and end.
323 pointIndexHit findLine
324 (
325 const bool findAny,
326 const point& start,
327 const point& end
328 ) const;
329
330 //- Find all elements intersecting box.
331 void findBox
332 (
333 const label nodeI,
334 const treeBoundBox& searchBox,
335 labelHashSet& elements
336 ) const;
337
338
339 //- Find all elements intersecting sphere.
340 void findSphere
341 (
342 const label nodeI,
343 const point& centre,
344 const scalar radiusSqr,
345 labelHashSet& elements
346 ) const;
347
348
349 template<class CompareOp>
350 static void findNear
351 (
352 const scalar nearDist,
353 const bool okOrder,
354 const dynamicIndexedOctree<Type>& tree1,
355 const labelBits index1,
356 const treeBoundBox& bb1,
357 const dynamicIndexedOctree<Type>& tree2,
358 const labelBits index2,
359 const treeBoundBox& bb2,
360 CompareOp& cop
361 );
362
363
364 // Other
365
366 //- Count number of elements on this and sublevels
367 label countElements(const labelBits index) const;
368
369 //- Dump node+octant to an obj file
370 void writeOBJ(const label nodeI, const direction octant) const;
371
372 //- From index into contents_ to subNodes_ entry
373 static labelBits contentPlusOctant
374 (
375 const label i,
376 const direction octant
377 )
378 {
379 return labelBits(-i - 1, octant);
380 }
381
382 //- From index into nodes_ to subNodes_ entry
383 static labelBits nodePlusOctant
384 (
385 const label i,
386 const direction octant
387 )
388 {
389 return labelBits(i + 1, octant);
390 }
391
392 //- From empty to subNodes_ entry
393 static labelBits emptyPlusOctant
394 (
395 const direction octant
396 )
397 {
398 return labelBits(0, octant);
399 }
400
401public:
402
403 //- Get the perturbation tolerance
404 static scalar& perturbTol();
405
406
407 // Constructors
408
409 //- Construct from shapes
411 (
412 const Type& shapes,
413 const treeBoundBox& bb,
414 const label maxLevels, // maximum number of levels
415 const scalar maxLeafRatio, // how many elements per leaf
416 const scalar maxDuplicity // in how many leaves is a shape on
417 // average
418 );
419
420 //- Clone
422 {
424 }
425
426
427 // Member Functions
428
429 // Access
430
431 //- Reference to shape
432 const Type& shapes() const
433 {
434 return shapes_;
435 }
436
437 //- List of all nodes
438 const List<node>& nodes() const
439 {
440 return nodes_;
441 }
442
443 //- List of all contents (referenced by those nodes that are
444 // contents)
445 const contentListList& contents() const
446 {
447 return contents_;
448 }
449
450 //- Top bounding box
451 const treeBoundBox& bb() const
452 {
453 if (nodes_.empty())
454 {
456 << "Tree is empty" << abort(FatalError);
457 }
458 return nodes_[0].bb_;
459 }
460
461
462 // Conversions for entries in subNodes_.
464 static bool isContent(const labelBits i)
465 {
466 return i.val() < 0;
467 }
469 static bool isEmpty(const labelBits i)
470 {
471 return i.val() == 0;
472 }
474 static bool isNode(const labelBits i)
475 {
476 return i.val() > 0;
477 }
479 static label getContent(const labelBits i)
480 {
481 if (!isContent(i))
482 {
484 << abort(FatalError);
485 }
486 return -i.val()-1;
487 }
489 static label getNode(const labelBits i)
490 {
491 if (!isNode(i))
492 {
494 << abort(FatalError);
495 }
496 return i.val() - 1;
497 }
499 static direction getOctant(const labelBits i)
500 {
501 return i.bits();
502 }
503
504
505 // Queries
506
507 //- Calculate nearest point on nearest shape.
508 // Returns
509 // - bool : any point found nearer than nearestDistSqr
510 // - label: index in shapes
511 // - point: actual nearest point found
512 pointIndexHit findNearest
513 (
514 const point& sample,
515 const scalar nearestDistSqr
516 ) const;
517
518 //- Low level: calculate nearest starting from subnode.
519 void findNearest
520 (
521 const label nodeI,
522 const point&,
523
524 scalar& nearestDistSqr,
525 label& nearestShapeI,
526 point& nearestPoint
527 ) const;
528
529 //- Find nearest to line.
530 // Returns
531 // - bool : any point found?
532 // - label: index in shapes
533 // - point: actual nearest point found
534 // sets:
535 // - linePoint : corresponding nearest point on line
536 pointIndexHit findNearest
537 (
538 const linePointRef& ln,
539 treeBoundBox& tightest,
540 point& linePoint
541 ) const;
542
543 //- Find nearest intersection of line between start and end.
544 pointIndexHit findLine
545 (
546 const point& start,
547 const point& end
548 ) const;
549
550 //- Find any intersection of line between start and end.
552 (
553 const point& start,
554 const point& end
555 ) const;
556
557 //- Find (in no particular order) indices of all shapes inside or
558 // overlapping bounding box (i.e. all shapes not outside box)
559 labelList findBox(const treeBoundBox& bb) const;
560
561 //- Find (in no particular order) indices of all shapes inside or
562 // overlapping a bounding sphere (i.e. all shapes not outside
563 // sphere)
564 labelList findSphere
565 (
566 const point& centre,
567 const scalar radiusSqr
568 ) const;
569
570 //- Find deepest node (as parent+octant) containing point. Starts
571 // off from starting index in nodes_ (use 0 to start from top)
572 // Use getNode and getOctant to extract info, or call findIndices.
573 labelBits findNode(const label nodeI, const point&) const;
574
575 //- Find shape containing point. Only implemented for certain
576 // shapes.
577 label findInside(const point&) const;
578
579 //- Find the shape indices that occupy the result of findNode
580 const labelList& findIndices(const point&) const;
581
582 //- Determine type (inside/outside/mixed) for point. unknown if
583 // cannot be determined (e.g. non-manifold surface)
584 volumeType getVolumeType(const point&) const;
585
586 //- Helper function to return the side. Returns outside if
587 // outsideNormal&vec >= 0, inside otherwise
588 static volumeType getSide
589 (
590 const vector& outsideNormal,
591 const vector& vec
592 );
593
594 //- Helper: does bb intersect a sphere around sample? Or is any
595 // corner point of bb closer than nearestDistSqr to sample.
596 static bool overlaps
597 (
598 const point& bbMin,
599 const point& bbMax,
600 const scalar nearestDistSqr,
601 const point& sample
602 );
603
604 //- Find near pairs and apply CompareOp to them.
605 // tree2 can be *this or different tree.
606 template<class CompareOp>
607 void findNear
608 (
609 const scalar nearDist,
610 const dynamicIndexedOctree<Type>& tree2,
611 CompareOp& cop
612 ) const;
613
614
615 // Edit
616
617 //- Insert a new object into the tree.
618 bool insert(label startIndex, label endIndex);
619
620 bool insertIndex
621 (
622 const label nodIndex,
623 const label index,
624 label& nLevels
625 );
626
627 //- Remove an object from the tree.
628 bool remove(const label index);
629
630 label removeIndex(const label nodIndex, const label index);
631
632
633 // Write
634
635 //- Print tree. Either print all indices (printContent = true) or
636 // just size of contents nodes.
637 void print
638 (
640 const bool printContents,
641 const label
642 ) const;
643
644 bool write(Ostream& os) const;
645
646 void writeTreeInfo() const;
647
648
649 // IOstream Operators
651 friend Ostream& operator<< <Type>
652 (
653 Ostream&,
655 );
656};
657
658
659// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
660
661} // End namespace Foam
662
663// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
664
665#ifdef NoRepository
666 #include "dynamicIndexedOctree.C"
667#endif
668
669// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
670
671#endif
672
673// ************************************************************************* //
label n
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: FixedList.H:81
Minimal example by using system/controlDict.functions:
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:129
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:66
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
Tree node. Has up pointer and down pointers.
friend Ostream & operator<<(Ostream &os, const node &n)
FixedList< labelBits, 8 > subNodes_
IDs of the 8 nodes on all sides of the mid point.
label parent_
Parent node (index into nodes_ of tree)
friend bool operator!=(const node &a, const node &b)
friend Istream & operator>>(Istream &is, node &n)
treeBoundBox bb_
Bounding box of this node.
friend bool operator==(const node &a, const node &b)
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.
static bool isEmpty(const labelBits i)
const labelList & findIndices(const point &) const
Find the shape indices that occupy the result of findNode.
static label getNode(const labelBits i)
static direction getOctant(const labelBits i)
static scalar & perturbTol()
Get the perturbation tolerance.
static bool isContent(const labelBits i)
static label getContent(const labelBits i)
const treeBoundBox & bb() const
Top bounding box.
label removeIndex(const label nodIndex, const label index)
const contentListList & contents() const
List of all contents (referenced by those nodes that are.
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.
const List< node > & nodes() const
List of all nodes.
bool insert(label startIndex, label endIndex)
Insert a new object into the tree.
const Type & shapes() const
Reference to shape.
labelBits findNode(const label nodeI, const point &) const
Find deepest node (as parent+octant) containing point. Starts.
static bool isNode(const labelBits i)
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.
A 29bits label and 3bits direction packed into single label.
Definition: labelBits.H:54
label val() const
Definition: labelBits.H:99
direction bits() const
Definition: labelBits.H:104
A line primitive.
Definition: line.H:68
Version of OSstream that prints a prefix on each line.
@ SPACE
Space [isspace].
Definition: token.H:125
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:89
An enumeration wrapper for classification of a location as being inside/outside of a volume.
Definition: volumeType.H:61
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define TemplateName(TemplateNameString)
Add typeName information from argument TypeNameString to a.
Definition: className.H:79
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.
label facePoint(const int facei, const block &block, const label i, const label j)
DynamicList< autoPtr< DynamicList< label > > > contentListList
errorManip< error > abort(error &err)
Definition: errorManip.H:144
uint8_t direction
Definition: direction.H:56
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
error FatalError
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition: MSwindows.C:933
runTime write()
volScalarField & b
Definition: createFields.H:27