00001 /*---------------------------------------------------------------------------*\ 00002 ========= | 00003 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox 00004 \\ / O peration | 00005 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. 00006 \\/ M anipulation | 00007 ------------------------------------------------------------------------------- 00008 License 00009 This file is part of OpenFOAM. 00010 00011 OpenFOAM is free software: you can redistribute it and/or modify it 00012 under the terms of the GNU General Public License as published by 00013 the Free Software Foundation, either version 3 of the License, or 00014 (at your option) any later version. 00015 00016 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00018 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00019 for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. 00023 00024 Class 00025 Foam::octree 00026 00027 Description 00028 Octree, templated on type of shapes it refers to. 00029 00030 Uses the octreeData class, which is a list of 1D, 2D or 3D shapes. 00031 Various implementations of octreeData which know about cell&meshes, 00032 patches&meshes and points. 00033 00034 The octree can be used to 00035 - find the "nearest" shape to a point 00036 - find the shape which contains a point (only sensible for 3D shapes) 00037 - find intersections of line with shapes 00038 00039 The tree consists of 00040 - treeNode : holds sub-treeNodes or treeLeaves 00041 - treeLeaf : is the one that actually holds data 00042 00043 The data is stored purely as a list of indices into octreeData. 00044 00045 The construction on the depth of the tree is: 00046 - one can specify a minimum depth 00047 (though the tree will never be refined if all leaves contain <=1 00048 shapes) 00049 - after the minimum depth two statistics are used to decide further 00050 refinement: 00051 - average number of entries per leaf (leafRatio). Since inside a 00052 leaf most algorithms are n or n^2 this value has to be small. 00053 - average number of leaves a shape is in. Because of bounding boxes, 00054 a single shape can be in multiple leaves. If the bbs are large 00055 compared to the leaf size this multiplicity can become extremely 00056 large and will become larger with more levels. 00057 00058 Note: the octree gets constructed with an overall bounding box. If your 00059 mesh is regular it is a good idea to make this overall bb a bit wider than 00060 the bb of the shapes itself. Otherwise lots of shapes end up exactly on the 00061 edge of a bb and hence go into more than one subcube. 00062 00063 E.g. octree of face centres of lid driven cavity. 00064 00065 -# bb exact -> total 1457 leaves (every point in 7.1 leaves) 00066 -# bb.max incremented by 1% -> total 80 leaves 00067 (every point in exactly 1 leaf) 00068 00069 @par Ideas for parallel implementation: 00070 00071 The data inserted into the octree (the 00072 'octreeData') has to be local to the processor. The data to be looked 00073 for (usually a sample point) can be global to the domain. 00074 The algorithm: 00075 - search for all my points 00076 - collect results which have to do with a processor patch 00077 - global sum all these. If 0 exit. 00078 - exchange data on all processor patches 00079 - start again 00080 00081 So data transfers one processor per iteration. One could think of having 00082 an extra search mechanism one level above which does an initial search 00083 knowing the average shape of a processor distribution (square/cube for 00084 most decomposition methods) and can assign sample points to the (almost) 00085 correct processor at once. 00086 00087 SourceFiles 00088 octree.C 00089 00090 \*---------------------------------------------------------------------------*/ 00091 00092 #ifndef octree_H 00093 #define octree_H 00094 00095 #include "treeBoundBoxList.H" 00096 #include "treeLeaf.H" 00097 #include "pointIndexHit.H" 00098 #include <OpenFOAM/linePointRef.H> 00099 00100 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00101 00102 namespace Foam 00103 { 00104 00105 // Forward declaration of classes 00106 template<class Type> class treeNode; 00107 00108 // Forward declaration of friend functions and operators 00109 00110 template<class Type> 00111 Ostream& operator<<(Ostream&, const octree<Type>&); 00112 00113 00114 /*---------------------------------------------------------------------------*\ 00115 Class octreeName Declaration 00116 \*---------------------------------------------------------------------------*/ 00117 00118 TemplateName(octree); 00119 00120 00121 00122 /*---------------------------------------------------------------------------*\ 00123 Class octree Declaration 00124 \*---------------------------------------------------------------------------*/ 00125 00126 template <class Type> 00127 class octree 00128 : 00129 public octreeName 00130 { 00131 // Private data 00132 00133 //- Top treeNode. Modified by lower levels. 00134 treeNode<Type>* topNode_; 00135 00136 //- all shapes 00137 const Type shapes_; 00138 00139 //- Overall bb of octree 00140 const treeBoundBox octreeBb_; 00141 00142 //- Refinement crit: size of leaves. Average number of entries per 00143 // leaf. Should be fine enough for efficient searching at lowest level. 00144 const scalar maxLeafRatio_; 00145 00146 //- Refinement crit: multiplicity of entries (so in how many leaves 00147 // each shape is mentioned) 00148 const scalar maxShapeRatio_; 00149 00150 //- Refinement crit: min no. of levels 00151 const label minNLevels_; 00152 00153 //- Actual depth 00154 label deepestLevel_; 00155 00156 //- Total number of (references to) shapes in octree 00157 // (shapes can be stored in more than one treeLeaf) 00158 label nEntries_; 00159 00160 //- Total number of treeNodes 00161 label nNodes_; 00162 00163 //- Total number of treeLeaves 00164 label nLeaves_; 00165 00166 00167 // Static data members 00168 //- Refinement crit: max number of level 00169 static const label maxNLevels = 20; 00170 00171 00172 00173 // Private Member Functions 00174 00175 public: 00176 00177 // Data types 00178 00179 //- volume types 00180 enum volumeType 00181 { 00182 UNKNOWN, 00183 MIXED, 00184 INSIDE, 00185 OUTSIDE 00186 }; 00187 00188 00189 // Static data members 00190 00191 //- for debugging:return printable representation of volumeType 00192 static string volType(const label); 00193 00194 //- Code the vector with respect to the geometry. geomNormal guaranteed 00195 // to point outside. 00196 static label getVolType 00197 ( 00198 const vector& geomNormal, 00199 const vector& vec 00200 ); 00201 00202 // Constructors 00203 00204 //- Construct from components 00205 octree 00206 ( 00207 const treeBoundBox& octreeBb, 00208 const Type& shapes, 00209 const label minNLevels, // minimum number of levels 00210 const scalar maxLeafRatio, // max avg. size of leaves 00211 const scalar maxShapeRatio // max avg. duplicity. 00212 ); 00213 00214 00215 // Destructor 00216 00217 ~octree(); 00218 00219 00220 // Member Functions 00221 00222 // Access 00223 00224 const Type& shapes() const 00225 { 00226 return shapes_; 00227 } 00228 00229 const treeBoundBox& octreeBb() const 00230 { 00231 return octreeBb_; 00232 } 00233 00234 scalar maxShapeRatio() const 00235 { 00236 return maxShapeRatio_; 00237 } 00238 00239 scalar maxLeafRatio() const 00240 { 00241 return maxLeafRatio_; 00242 } 00243 00244 label minNLevels() const 00245 { 00246 return minNLevels_; 00247 } 00248 00249 // After construction: octree statistics 00250 00251 treeNode<Type>* topNode() const 00252 { 00253 return topNode_; 00254 } 00255 00256 label deepestLevel() const 00257 { 00258 return deepestLevel_; 00259 } 00260 00261 label nEntries() const 00262 { 00263 return nEntries_; 00264 } 00265 00266 label nNodes() const 00267 { 00268 return nNodes_; 00269 } 00270 00271 label nLeaves() const 00272 { 00273 return nLeaves_; 00274 } 00275 00276 void setEntries(const label n) 00277 { 00278 nEntries_ = n; 00279 } 00280 00281 void setNodes(const label n) 00282 { 00283 nNodes_ = n; 00284 } 00285 00286 void setLeaves(const label n) 00287 { 00288 nLeaves_ = n; 00289 } 00290 00291 // Queries 00292 00293 //- Returns type of sample with respect to nearest shape. 00294 // Meaning of type is determined by shapes.getSampleType(). 00295 // Normally based on outwards pointing normal. For e.g. 00296 // octreeDataFace returns one of 00297 // inside : on other side of normal on nearest face 00298 // outside : on same side as normal on nearest face 00299 // unknown : not above nearest face; surface probably not 00300 // closed. 00301 // mixed : should never happen 00302 label getSampleType(const point& sample) const; 00303 00304 //- Find shape containing point in tree 00305 // Returns -1 if not in found. Uses Type::contains. 00306 label find(const point& sample) const; 00307 00308 //- Calculate tightest fitting bounding box. Uses 00309 // Type::findTightest. 00310 bool findTightest 00311 ( 00312 const point& sample, 00313 treeBoundBox& tightest 00314 ) const; 00315 00316 //- Find nearest shape. Returns index of shape or -1 if not found. 00317 // tightestDist is both input and output. Uses Type::calcNearest. 00318 label findNearest 00319 ( 00320 const point& sample, 00321 treeBoundBox& tightest, 00322 scalar& tightestDist 00323 ) const; 00324 00325 //- Find nearest to line. Returns -1 or index of shape and 00326 // sets: 00327 // - tightest (is both input and output). 00328 // - linePoint : point on line (-GREAT,-GREAT,-GREAT if not found) 00329 // - shapePoint : point on shape (GREAT, GREAT, GREAT if not found) 00330 // Uses Type::calcNearest. 00331 label findNearest 00332 ( 00333 const linePointRef& ln, 00334 treeBoundBox& tightest, 00335 point& linePoint, 00336 point& shapePoint 00337 ) const; 00338 00339 //- Find (in no particular order) indices of all shapes inside or 00340 // overlapping bounding box (i.e. all shapes not outside box) 00341 labelList findBox(const boundBox& bb) const; 00342 00343 //- Find intersected shape along line. pointIndexHit contains index 00344 // of nearest shape intersected and the intersection point. Uses 00345 // findLeafLine. 00346 pointIndexHit findLine(const point& start, const point& end) const; 00347 00348 //- Like above but just tests whether line hits anything. So 00349 // returns first intersection found, not nessecarily nearest. 00350 pointIndexHit findLineAny(const point& start, const point& end) 00351 const; 00352 00353 //- Find leaf along line. Set leafIntPoint to leave point of 00354 // treeLeaf. 00355 const treeLeaf<Type>* findLeafLine 00356 ( 00357 const point& start, 00358 const point& end, 00359 point& leafIntPoint 00360 ) const; 00361 00362 00363 // Write 00364 00365 //- Dump graphical representation in .obj format 00366 void writeOBJ(Ostream& os, label& vertNo) const; 00367 00368 //- Print some stats on octree 00369 void printStats(Ostream& os) const; 00370 00371 00372 // STL iterator 00373 00374 class iterator; 00375 friend class iterator; 00376 00377 //- An STL iterator for octree 00378 class iterator 00379 { 00380 // Private data 00381 00382 //- Reference to the octree this is an iterator for 00383 octree& octree_; 00384 00385 //- List of pointers to treeLeaves 00386 List<treeLeaf<Type>*> leaves_; 00387 00388 //- Current treeLeaf index 00389 label curLeaf_; 00390 00391 public: 00392 00393 //- Construct for a given octree 00394 iterator(octree&); 00395 00396 //- Contruct for a given octree, at a certain position 00397 iterator(octree& oc, const label index); 00398 00399 00400 // Member operators 00401 00402 void operator=(const iterator&); 00403 00404 bool operator==(const iterator&) const; 00405 bool operator!=(const iterator&) const; 00406 00407 treeLeaf<Type>& operator*(); 00408 00409 iterator& operator++(); 00410 iterator operator++(int); 00411 }; 00412 00413 //- iterator set to the begining of the octree 00414 iterator begin(); 00415 00416 //- iterator set to beyond the end of the octree 00417 const iterator& end(); 00418 00419 00420 // STL const_iterator 00421 00422 class const_iterator; 00423 friend class const_iterator; 00424 00425 //- An STL const_iterator for octree 00426 class const_iterator 00427 { 00428 // Private data 00429 00430 //- Reference to the list this is an iterator for 00431 const octree& octree_; 00432 00433 //- List of treeLeafs 00434 List<const treeLeaf<Type>*> leaves_; 00435 00436 //- Current treeLeaf index 00437 label curLeaf_; 00438 00439 public: 00440 00441 //- Construct for a given octree 00442 const_iterator(const octree&); 00443 00444 //- Construct for a given octree and index 00445 const_iterator(const octree&, label); 00446 00447 // Member operators 00448 00449 void operator=(const const_iterator&); 00450 00451 bool operator==(const const_iterator&) const; 00452 bool operator!=(const const_iterator&) const; 00453 00454 const treeLeaf<Type>& operator*(); 00455 00456 const_iterator& operator++(); 00457 const_iterator operator++(int); 00458 }; 00459 00460 00461 //- const_iterator set to the begining of the octree 00462 inline const_iterator begin() const; 00463 inline const_iterator cbegin() const; 00464 00465 //- const_iterator set to beyond the end of the octree 00466 inline const const_iterator& end() const; 00467 inline const const_iterator& cend() const; 00468 00469 00470 // IOstream Operators 00471 00472 friend Ostream& operator<< <Type>(Ostream&, const octree<Type>&); 00473 00474 00475 private: 00476 00477 //- iterator returned by end() 00478 iterator endIter_; 00479 00480 //- const_iterator returned by end() 00481 const_iterator endConstIter_; 00482 }; 00483 00484 00485 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00486 00487 } // End namespace Foam 00488 00489 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00490 00491 #ifdef NoRepository 00492 # include "octree.C" 00493 #endif 00494 00495 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00496 00497 #endif 00498 00499 // ************************ vim: set sw=4 sts=4 et: ************************ //