BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OpenFOAM / algorithms / indexedOctree / indexedOctree.H
blob6c74ca704e33ffd4766bfbaa8c443c077125fa79
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM 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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 Class
25     Foam::indexedOctree
27 Description
28     Non-pointer based hierarchical recursive searching
30 SourceFiles
31     indexedOctree.C
33 \*---------------------------------------------------------------------------*/
35 #ifndef indexedOctree_H
36 #define indexedOctree_H
38 #include "treeBoundBox.H"
39 #include "pointIndexHit.H"
40 #include "FixedList.H"
41 #include "Ostream.H"
42 #include "HashSet.H"
43 #include "labelBits.H"
44 #include "PackedList.H"
46 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 namespace Foam
51 // Forward declaration of classes
52 template<class Type> class indexedOctree;
53 template<class Type> Ostream& operator<<(Ostream&, const indexedOctree<Type>&);
54 class Istream;
57 /*---------------------------------------------------------------------------*\
58                         Class indexedOctreeName Declaration
59 \*---------------------------------------------------------------------------*/
61 TemplateName(indexedOctree);
64 /*---------------------------------------------------------------------------*\
65                            Class indexedOctree Declaration
66 \*---------------------------------------------------------------------------*/
68 template <class Type>
69 class indexedOctree
71     public indexedOctreeName
73 public:
75     // Data types
77         //- volume types
78         enum volumeType
79         {
80             UNKNOWN = 0,
81             MIXED = 1,
82             INSIDE = 2,
83             OUTSIDE = 3
84         };
87         //- Tree node. Has up pointer and down pointers.
88         class node
89         {
90         public:
92             //- Bounding box of this node
93             treeBoundBox bb_;
95             //- parent node (index into nodes_ of tree)
96             label parent_;
98             //- IDs of the 8 nodes on all sides of the mid point
99             FixedList<labelBits, 8> subNodes_;
101             friend Ostream& operator<< (Ostream& os, const node& n)
102             {
103                 return os << n.bb_ << token::SPACE
104                     << n.parent_ << token::SPACE << n.subNodes_;
105             }
107             friend Istream& operator>> (Istream& is, node& n)
108             {
109                 return is >> n.bb_ >> n.parent_ >> n.subNodes_;
110             }
112             friend bool operator==(const node& a, const node& b)
113             {
114                 return
115                     a.bb_ == b.bb_
116                  && a.parent_ == b.parent_
117                  && a.subNodes_ == b.subNodes_;
118             }
120             friend bool operator!=(const node& a, const node& b)
121             {
122                 return !(a == b);
123             }
124         };
127 private:
129     // Static data
131         //- Relative peturbation tolerance. Determines when point is
132         //  considered to be close to face/edge of bb of node.
133         //  The tolerance is relative to the bounding box of the smallest
134         //  node.
135         static scalar perturbTol_;
138     // Private data
140         //- Underlying shapes for geometric queries.
141         const Type shapes_;
143         //- List of all nodes
144         List<node> nodes_;
146         //- List of all contents (referenced by those nodes that are contents)
147         labelListList contents_;
149         //- Per node per octant whether is fully inside/outside/mixed.
150         mutable PackedList<2> nodeTypes_;
152     // Private Member Functions
154         //- Helper: does bb intersect a sphere around sample? Or is any
155         //  corner point of bb closer than nearestDistSqr to sample.
156         //  (bb is implicitly provided as parent bb + octant)
157         static bool overlaps
158         (
159             const treeBoundBox& parentBb,
160             const direction octant,
161             const scalar nearestDistSqr,
162             const point& sample
163         );
165         // Construction
167             //- Split list of indices into 8 bins
168             //  according to where they are in relation to mid.
169             void divide
170             (
171                 const labelList& indices,
172                 const treeBoundBox& bb,
173                 labelListList& result
174             ) const;
176             //- Subdivide the contents node at position contentI.
177             //  Appends to contents.
178             node divide
179             (
180                 const treeBoundBox& bb,
181                 DynamicList<labelList>& contents,
182                 const label contentI
183             ) const;
185             //- Split any contents node with more than minSize elements.
186             void splitNodes
187             (
188                 const label minSize,
189                 DynamicList<node>& nodes,
190                 DynamicList<labelList>& contents
191             ) const;
193             static label compactContents
194             (
195                 DynamicList<node>& nodes,
196                 DynamicList<labelList>& contents,
197                 const label compactLevel,
198                 const label nodeI,
199                 const label level,
200                 List<labelList>& compactedContents,
201                 label& compactI
202             );
204             //- Determine inside/outside per node (mixed if cannot be
205             //  determined). Only valid for closed shapes.
206             volumeType calcVolumeType(const label nodeI) const;
208             //- Search cached volume type.
209             volumeType getVolumeType(const label nodeI, const point&) const;
212         // Query
214             //- Find nearest point to line.
215             void findNearest
216             (
217                 const label nodeI,
218                 const linePointRef& ln,
220                 treeBoundBox& tightest,
221                 label& nearestShapeI,
222                 point& linePoint,
223                 point& nearestPoint
224             ) const;
226             //- Return bbox of octant
227             treeBoundBox subBbox
228             (
229                 const label parentNodeI,
230                 const direction octant
231             ) const;
233             //- Helper: take a point on/close to face of bb and push it
234             //  inside or outside of bb.
235             static point pushPoint
236             (
237                 const treeBoundBox&,
238                 const point&,
239                 const bool pushInside
240             );
242             //- Helper: take a point on face of bb and push it
243             //  inside or outside of bb.
244             static point pushPoint
245             (
246                 const treeBoundBox&,
247                 const direction,
248                 const point&,
249                 const bool pushInside
250             );
252             //- Helper: take point on face(s) of bb and push it away from
253             //  edges of face.
254             static point pushPointIntoFace
255             (
256                 const treeBoundBox& bb,
257                 const vector& dir,          // end-start
258                 const point& pt
259             );
261             ////- Push point on multiple faces away from any corner/edge.
262             //static void checkMultipleFaces
263             //(
264             //    const treeBoundBox& bb,
265             //    const vector& dir,          // end-start
266             //    pointIndexHit& faceHitInfo,
267             //    direction& faceID
268             //);
270             //- Walk to parent of node+octant.
271             bool walkToParent
272             (
273                 const label nodeI,
274                 const direction octant,
276                 label& parentNodeI,
277                 label& parentOctant
278             ) const;
280             //- Walk tree to neighbouring node. Return false if edge of tree
281             //  hit.
282             bool walkToNeighbour
283             (
284                 const point& facePoint,
285                 const direction faceID,         // direction to walk in
286                 label& nodeI,
287                 direction& octant
288             ) const;
290             //- Debug: return verbose the bounding box faces
291             static word faceString(const direction faceID);
293             //- Traverse a node. If intersects a triangle return first
294             // intersection point.
295             // findAny=true : return any intersection
296             // findAny=false: return nearest (to start) intersection
297             void traverseNode
298             (
299                 const bool findAny,
300                 const point& treeStart,
301                 const vector& treeVec,
303                 const point& start,
304                 const point& end,
305                 const label nodeI,
306                 const direction octantI,
308                 pointIndexHit& hitInfo,
309                 direction& faceID
310             ) const;
312             //- Find any or nearest intersection
313             pointIndexHit findLine
314             (
315                 const bool findAny,
316                 const point& treeStart,
317                 const point& treeEnd,
318                 const label startNodeI,
319                 const direction startOctantI,
320                 const bool verbose = false
321             ) const;
323             //- Find any or nearest intersection of line between start and end.
324             pointIndexHit findLine
325             (
326                 const bool findAny,
327                 const point& start,
328                 const point& end
329             ) const;
331             //- Find all elements intersecting box.
332             void findBox
333             (
334                 const label nodeI,
335                 const treeBoundBox& searchBox,
336                 labelHashSet& elements
337             ) const;
340             template <class CompareOp>
341             static void findNear
342             (
343                 const scalar nearDist,
344                 const bool okOrder,
345                 const indexedOctree<Type>& tree1,
346                 const labelBits index1,
347                 const treeBoundBox& bb1,
348                 const indexedOctree<Type>& tree2,
349                 const labelBits index2,
350                 const treeBoundBox& bb2,
351                 CompareOp& cop
352             );
355         // Other
357             //- Count number of elements on this and sublevels
358             label countElements(const labelBits index) const;
360             //- Dump node+octant to an obj file
361             void writeOBJ(const label nodeI, const direction octant) const;
363             //- From index into contents_ to subNodes_ entry
364             static labelBits contentPlusOctant
365             (
366                 const label i,
367                 const direction octant
368             )
369             {
370                 return labelBits(-i - 1, octant);
371             }
373             //- From index into nodes_ to subNodes_ entry
374             static labelBits nodePlusOctant
375             (
376                 const label i,
377                 const direction octant
378             )
379             {
380                 return labelBits(i + 1, octant);
381             }
383             //- From empty to subNodes_ entry
384             static labelBits emptyPlusOctant
385             (
386                 const direction octant
387             )
388             {
389                 return labelBits(0, octant);
390             }
392 public:
394         //- Get the perturbation tolerance
395         static scalar& perturbTol();
398     // Constructors
400         //- Construct null
401         indexedOctree(const Type& shapes);
403         //- Construct from components
404         indexedOctree
405         (
406             const Type& shapes,
407             const List<node>& nodes,
408             const labelListList& contents
409         );
411         //- Construct from shapes
412         indexedOctree
413         (
414             const Type& shapes,
415             const treeBoundBox& bb,
416             const label maxLevels,          // maximum number of levels
417             const scalar maxLeafRatio,      // how many elements per leaf
418             const scalar maxDuplicity       // in how many leaves is a shape on
419                                             // average
420         );
422         //- Construct from Istream
423         indexedOctree(const Type& shapes, Istream& is);
425         //- Clone
426         autoPtr<indexedOctree<Type> > clone() const
427         {
428             return autoPtr<indexedOctree<Type> >
429             (
430                 new indexedOctree<Type>(*this)
431             );
432         }
434     // Member Functions
436         // Access
438             //- Reference to shape
439             const Type& shapes() const
440             {
441                 return shapes_;
442             }
444             //- List of all nodes
445             const List<node>& nodes() const
446             {
447                 return nodes_;
448             }
450             //- List of all contents (referenced by those nodes that are
451             //  contents)
452             const labelListList& contents() const
453             {
454                 return contents_;
455             }
457             //- Top bounding box
458             const treeBoundBox& bb() const
459             {
460                 if (nodes_.empty())
461                 {
462                     FatalErrorIn("indexedOctree<Type>::bb() const")
463                         << "Tree is empty" << abort(FatalError);
464                 }
465                 return nodes_[0].bb_;
466             }
469         // Conversions for entries in subNodes_.
471             static bool isContent(const labelBits i)
472             {
473                 return i.val() < 0;
474             }
476             static bool isEmpty(const labelBits i)
477             {
478                 return i.val() == 0;
479             }
481             static bool isNode(const labelBits i)
482             {
483                 return i.val() > 0;
484             }
486             static label getContent(const labelBits i)
487             {
488                 if (!isContent(i))
489                 {
490                     FatalErrorIn("getContent(const label)")
491                         << abort(FatalError);
492                 }
493                 return -i.val()-1;
494             }
496             static label getNode(const labelBits i)
497             {
498                 if (!isNode(i))
499                 {
500                     FatalErrorIn("getNode(const label)")
501                         << abort(FatalError);
502                 }
503                 return i.val() - 1;
504             }
506             static direction getOctant(const labelBits i)
507             {
508                 return i.bits();
509             }
512         // Queries
514             //- Calculate nearest point on nearest shape.
515             //  Returns
516             //  - bool : any point found nearer than nearestDistSqr
517             //  - label: index in shapes
518             //  - point: actual nearest point found
519             pointIndexHit findNearest
520             (
521                 const point& sample,
522                 const scalar nearestDistSqr
523             ) const;
525             //- Low level: calculate nearest starting from subnode.
526             void findNearest
527             (
528                 const label nodeI,
529                 const point&,
531                 scalar& nearestDistSqr,
532                 label& nearestShapeI,
533                 point& nearestPoint
534             ) const;
536             //- Find nearest to line.
537             //  Returns
538             //  - bool : any point found?
539             //  - label: index in shapes
540             //  - point: actual nearest point found
541             //  sets:
542             //  - linePoint : corresponding nearest point on line
543             pointIndexHit findNearest
544             (
545                 const linePointRef& ln,
546                 treeBoundBox& tightest,
547                 point& linePoint
548             ) const;
550             //- Find nearest intersection of line between start and end.
551             pointIndexHit findLine
552             (
553                 const point& start,
554                 const point& end
555             ) const;
557             //- Find any intersection of line between start and end.
558             pointIndexHit findLineAny
559             (
560                 const point& start,
561                 const point& end
562             ) const;
564             //- Find (in no particular order) indices of all shapes inside or
565             //  overlapping bounding box (i.e. all shapes not outside box)
566             labelList findBox(const treeBoundBox& bb) const;
568             //- Find deepest node (as parent+octant) containing point. Starts
569             //  off from starting index in nodes_ (use 0 to start from top)
570             //  Use getNode and getOctant to extract info, or call findIndices.
571             labelBits findNode(const label nodeI, const point&) const;
573             //- Find shape containing point. Only implemented for certain
574             //  shapes.
575             label findInside(const point&) const;
577             //- Find the shape indices that occupy the result of findNode
578             const labelList& findIndices(const point&) const;
580             //- Determine type (inside/outside/mixed) for point. unknown if
581             //  cannot be determined (e.g. non-manifold surface)
582             volumeType getVolumeType(const point&) const;
584             //- Helper function to return the side. Returns outside if
585             //  outsideNormal&vec >= 0, inside otherwise
586             static volumeType getSide
587             (
588                 const vector& outsideNormal,
589                 const vector& vec
590             );
592             //- Helper: does bb intersect a sphere around sample? Or is any
593             //  corner point of bb closer than nearestDistSqr to sample.
594             static bool overlaps
595             (
596                 const point& bbMin,
597                 const point& bbMax,
598                 const scalar nearestDistSqr,
599                 const point& sample
600             );
602             //- Find near pairs and apply CompareOp to them.
603             //  tree2 can be *this or different tree.
604             template <class CompareOp>
605             void findNear
606             (
607                 const scalar nearDist,
608                 const indexedOctree<Type>& tree2,
609                 CompareOp& cop
610             ) const;
613         // Write
615             //- Print tree. Either print all indices (printContent = true) or
616             //  just size of contents nodes.
617             void print
618             (
619                 prefixOSstream&,
620                 const bool printContents,
621                 const label
622             ) const;
624             bool write(Ostream& os) const;
627     // IOstream Operators
629         friend Ostream& operator<< <Type>(Ostream&, const indexedOctree<Type>&);
633 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
635 } // End namespace Foam
637 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
639 #ifdef NoRepository
640 #   include "indexedOctree.C"
641 #endif
643 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
645 #endif
647 // ************************************************************************* //