STYLE: sampleDict comment
[OpenFOAM-1.6.x.git] / src / meshTools / indexedOctree / indexedOctree.H
blobe0ef759222295400eefe791f90e70ffaeb7eb6e4
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Class
26     Foam::indexedOctree
28 Description
29     Non-pointer based hierarchical recursive searching
31 SourceFiles
32     indexedOctree.C
34 \*---------------------------------------------------------------------------*/
36 #ifndef indexedOctree_H
37 #define indexedOctree_H
39 #include "treeBoundBox.H"
40 #include "pointIndexHit.H"
41 #include "FixedList.H"
42 #include "Ostream.H"
43 #include "HashSet.H"
44 #include "labelBits.H"
45 #include "PackedList.H"
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 namespace Foam
52 // Forward declaration of classes
53 template<class Type> class indexedOctree;
54 template<class Type> Ostream& operator<<(Ostream&, const indexedOctree<Type>&);
55 class Istream;
58 /*---------------------------------------------------------------------------*\
59                         Class indexedOctreeName Declaration
60 \*---------------------------------------------------------------------------*/
62 TemplateName(indexedOctree);
65 /*---------------------------------------------------------------------------*\
66                            Class indexedOctree Declaration
67 \*---------------------------------------------------------------------------*/
69 template <class Type>
70 class indexedOctree
72     public indexedOctreeName
74 public:
76     // Data types
78         //- volume types
79         enum volumeType
80         {
81             UNKNOWN = 0,
82             MIXED = 1,
83             INSIDE = 2,
84             OUTSIDE = 3
85         };
88     // Tree node. Has up pointer and down pointers.
90         class node
91         {
92         public:
94             //- Bounding box of this node
95             treeBoundBox bb_;
97             //- parent node (index into nodes_ of tree)
98             label parent_;
100             //- IDs of the 8 nodes on all sides of the mid point
101             FixedList<labelBits, 8> subNodes_;
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         };
129 private:
131     // Static data
133         //- Relative peturbation 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_;
140     // Private data
142         //- Underlying shapes for geometric queries.
143         const Type shapes_;
145         //- List of all nodes
146         List<node> nodes_;
148         //- List of all contents (referenced by those nodes that are contents)
149         labelListList contents_;
151         //- Per node per octant whether is fully inside/outside/mixed.
152         mutable PackedList<2> nodeTypes_;
154     // Private Member Functions
156         //- Helper: does bb intersect a sphere around sample? Or is any
157         //  corner point of bb closer than nearestDistSqr to sample.
158         //  (bb is implicitly provided as parent bb + octant)
159         static bool overlaps
160         (
161             const treeBoundBox& parentBb,
162             const direction octant,
163             const scalar nearestDistSqr,
164             const point& sample
165         );
167         // Construction
169             //- Split list of indices into 8 bins according to where they are in
170             //  relation to mid.
171             void divide
172             (
173                 const labelList& indices,
174                 const treeBoundBox& bb,
175                 labelListList& result
176             ) const;
178             //- Subdivide the contents node at position contentI. Appends to
179             //  contents.
180             node divide
181             (
182                 const treeBoundBox& bb,
183                 DynamicList<labelList>& contents,
184                 const label contentI
185             ) const;
187             //- Split any contents node with more than minSize elements.
188             void splitNodes
189             (
190                 const label minSize,
191                 DynamicList<node>& nodes,
192                 DynamicList<labelList>& contents
193             ) const;
195             static label compactContents
196             (
197                 DynamicList<node>& nodes,
198                 DynamicList<labelList>& contents,
199                 const label compactLevel,
200                 const label nodeI,
201                 const label level,
202                 List<labelList>& compactedContents,
203                 label& compactI
204             );
206             //- Determine inside/outside per node (mixed if cannot be
207             //  determined). Only valid for closed shapes.
208             volumeType calcVolumeType(const label nodeI) const;
210             //- Search cached volume type.
211             volumeType getVolumeType(const label nodeI, const point&) const;
214         // Query
216             //- Find nearest point to line.
217             void findNearest
218             (
219                 const label nodeI,
220                 const linePointRef& ln,
222                 treeBoundBox& tightest,
223                 label& nearestShapeI,
224                 point& linePoint,
225                 point& nearestPoint
226             ) const;
228             //- Return bbox of octant
229             treeBoundBox subBbox
230             (
231                 const label parentNodeI,
232                 const direction octant
233             ) const;
235             //- Helper: take a point on/close to face of bb and push it
236             //  inside or outside of bb.
237             static point pushPoint
238             (
239                 const treeBoundBox&,
240                 const point&,
241                 const bool pushInside
242             );
244             //- Helper: take a point on face of bb and push it
245             //  inside or outside of bb.
246             static point pushPoint
247             (
248                 const treeBoundBox&,
249                 const direction,
250                 const point&,
251                 const bool pushInside
252             );
254             //- Helper: take point on face(s) of bb and push it away from
255             //  edges of face.
256             static point pushPointIntoFace
257             (
258                 const treeBoundBox& bb,
259                 const vector& dir,          // end-start
260                 const point& pt
261             );
263             ////- Push point on multiple faces away from any corner/edge.
264             //static void checkMultipleFaces
265             //(
266             //    const treeBoundBox& bb,
267             //    const vector& dir,          // end-start
268             //    pointIndexHit& faceHitInfo,
269             //    direction& faceID
270             //);
272             //- Walk to parent of node+octant.
273             bool walkToParent
274             (
275                 const label nodeI,
276                 const direction octant,
278                 label& parentNodeI,
279                 label& parentOctant
280             ) const;
282             //- Walk tree to neighbouring node. Return false if edge of tree
283             //  hit.
284             bool walkToNeighbour
285             (
286                 const point& facePoint,
287                 const direction faceID,         // direction to walk in
288                 label& nodeI,
289                 direction& octant
290             ) const;
292             //- Debug: return verbose the bounding box faces
293             static word faceString(const direction faceID);
295             //- Traverse a node. If intersects a triangle return first
296             // intersection point.
297             // findAny=true : return any intersection
298             // findAny=false: return nearest (to start) intersection
299             void traverseNode
300             (
301                 const bool findAny,
302                 const point& treeStart,
303                 const vector& treeVec,
305                 const point& start,
306                 const point& end,
307                 const label nodeI,
308                 const direction octantI,
310                 pointIndexHit& hitInfo,
311                 direction& faceID
312             ) const;
314             //- Find any or nearest intersection
315             pointIndexHit findLine
316             (
317                 const bool findAny,
318                 const point& treeStart,
319                 const point& treeEnd,
320                 const label startNodeI,
321                 const direction startOctantI,
322                 const bool verbose = false
323             ) const;
325             //- Find any or nearest intersection of line between start and end.
326             pointIndexHit findLine
327             (
328                 const bool findAny,
329                 const point& start,
330                 const point& end
331             ) const;
333             //- Find all elements intersecting box.
334             void findBox
335             (
336                 const label nodeI,
337                 const treeBoundBox& searchBox,
338                 labelHashSet& elements
339             ) const;
341         // Other
343             //- Count number of elements on this and sublevels
344             label countElements(const labelBits index) const;
346             //- Dump node+octant to an obj file
347             void writeOBJ(const label nodeI, const direction octant) const;
349             //- From index into contents_ to subNodes_ entry
350             static labelBits contentPlusOctant
351             (
352                 const label i,
353                 const direction octant
354             )
355             {
356                 return labelBits(-i - 1, octant);
357             }
359             //- From index into nodes_ to subNodes_ entry
360             static labelBits nodePlusOctant
361             (
362                 const label i,
363                 const direction octant
364             )
365             {
366                 return labelBits(i + 1, octant);
367             }
369             //- From empty to subNodes_ entry
370             static labelBits emptyPlusOctant
371             (
372                 const direction octant
373             )
374             {
375                 return labelBits(0, octant);
376             }
378 public:
380         //- Get the perturbation tolerance
381         static scalar& perturbTol();
384     // Constructors
386         //- Construct null
387         indexedOctree(const Type& shapes);
389         //- Construct from components
390         indexedOctree
391         (
392             const Type& shapes,
393             const List<node>& nodes,
394             const labelListList& contents
395         );
397         //- Construct from shapes
398         indexedOctree
399         (
400             const Type& shapes,
401             const treeBoundBox& bb,
402             const label maxLevels,          // maximum number of levels
403             const scalar maxLeafRatio,      // how many elements per leaf
404             const scalar maxDuplicity       // in how many leaves is a shape on
405                                             // average
406         );
408         //- Construct from Istream
409         indexedOctree(const Type& shapes, Istream& is);
411         //- Clone
412         autoPtr<indexedOctree<Type> > clone() const
413         {
414             return autoPtr<indexedOctree<Type> >
415             (
416                 new indexedOctree<Type>(*this)
417             );
418         }
420     // Member Functions
422         // Access
424             //- Reference to shape
425             const Type& shapes() const
426             {
427                 return shapes_;
428             }
430             //- List of all nodes
431             const List<node>& nodes() const
432             {
433                 return nodes_;
434             }
436             //- List of all contents (referenced by those nodes that are
437             //  contents)
438             const labelListList& contents() const
439             {
440                 return contents_;
441             }
443             //- Top bounding box
444             const treeBoundBox& bb() const
445             {
446                 if (nodes_.empty())
447                 {
448                     FatalErrorIn("indexedOctree<Type>::bb() const")
449                         << "Tree is empty" << abort(FatalError);
450                 }
451                 return nodes_[0].bb_;
452             }
455         // Conversions for entries in subNodes_.
457             static bool isContent(const labelBits i)
458             {
459                 return i.val() < 0;
460             }
462             static bool isEmpty(const labelBits i)
463             {
464                 return i.val() == 0;
465             }
467             static bool isNode(const labelBits i)
468             {
469                 return i.val() > 0;
470             }
472             static label getContent(const labelBits i)
473             {
474                 if (!isContent(i))
475                 {
476                     FatalErrorIn("getContent(const label)")
477                         << abort(FatalError);
478                 }
479                 return -i.val()-1;
480             }
482             static label getNode(const labelBits i)
483             {
484                 if (!isNode(i))
485                 {
486                     FatalErrorIn("getNode(const label)")
487                         << abort(FatalError);
488                 }
489                 return i.val() - 1;
490             }
492             static direction getOctant(const labelBits i)
493             {
494                 return i.bits();
495             }
498         // Queries
500             //- Calculate nearest point on nearest shape. Returns
501             //  - bool : any point found nearer than nearestDistSqr
502             //  - label: index in shapes
503             //  - point: actual nearest point found
504             pointIndexHit findNearest
505             (
506                 const point& sample,
507                 const scalar nearestDistSqr
508             ) const;
510             //- Low level: calculate nearest starting from subnode.
511             void findNearest
512             (
513                 const label nodeI,
514                 const point&,
516                 scalar& nearestDistSqr,
517                 label& nearestShapeI,
518                 point& nearestPoint
519             ) const;
521             //- Find nearest to line. Returns
522             //  - bool : any point found?
523             //  - label: index in shapes
524             //  - point: actual nearest point found
525             //  sets:
526             //  - linePoint : corresponding nearest point on line
527             pointIndexHit findNearest
528             (
529                 const linePointRef& ln,
530                 treeBoundBox& tightest,
531                 point& linePoint
532             ) const;
534             //- Find nearest intersection of line between start and end.
535             pointIndexHit findLine
536             (
537                 const point& start,
538                 const point& end
539             ) const;
541             //- Find any intersection of line between start and end.
542             pointIndexHit findLineAny
543             (
544                 const point& start,
545                 const point& end
546             ) const;
548             //- Find (in no particular order) indices of all shapes inside or
549             //  overlapping bounding box (i.e. all shapes not outside box)
550             labelList findBox(const treeBoundBox& bb) const;
552             //- Find deepest node (as parent+octant) containing point. Starts
553             //  off from starting index in nodes_ (use 0 to start from top)
554             //  Use getNode, getOctant to extract info.
555             labelBits findNode(const label nodeI, const point&) const;
557             //- Determine type (inside/outside/mixed) for point. unknown if
558             //  cannot be determined (e.g. non-manifold surface)
559             volumeType getVolumeType(const point&) const;
561             //- Helper function to return the side. Returns outside if
562             //  outsideNormal&vec >= 0, inside otherwise
563             static volumeType getSide
564             (
565                 const vector& outsideNormal,
566                 const vector& vec
567             );
569             //- Helper: does bb intersect a sphere around sample? Or is any
570             //  corner point of bb closer than nearestDistSqr to sample.
571             static bool overlaps
572             (
573                 const point& bbMin,
574                 const point& bbMax,
575                 const scalar nearestDistSqr,
576                 const point& sample
577             );
580         // Write
582             //- Print tree. Either print all indices (printContent = true) or
583             //  just size of contents nodes.
584             void print
585             (
586                 prefixOSstream&,
587                 const bool printContents,
588                 const label
589             ) const;
591             bool write(Ostream& os) const;
593     // IOstream Operators
595         friend Ostream& operator<< <Type>(Ostream&, const indexedOctree<Type>&);
600 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
602 } // End namespace Foam
604 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
606 #ifdef NoRepository
607 #   include "indexedOctree.C"
608 #endif
610 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
612 #endif
614 // ************************************************************************* //