00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef indexedOctree_H
00036 #define indexedOctree_H
00037
00038 #include <meshTools/treeBoundBox.H>
00039 #include <meshTools/pointIndexHit.H>
00040 #include <OpenFOAM/FixedList.H>
00041 #include <OpenFOAM/Ostream.H>
00042 #include <OpenFOAM/HashSet.H>
00043 #include "labelBits.H"
00044 #include <OpenFOAM/PackedList.H>
00045
00046
00047
00048 namespace Foam
00049 {
00050
00051
00052 template<class Type> class indexedOctree;
00053 template<class Type> Ostream& operator<<(Ostream&, const indexedOctree<Type>&);
00054 class Istream;
00055
00056
00057
00058
00059
00060
00061 TemplateName(indexedOctree);
00062
00063
00064
00065
00066
00067
00068 template <class Type>
00069 class indexedOctree
00070 :
00071 public indexedOctreeName
00072 {
00073 public:
00074
00075
00076
00077
00078 enum volumeType
00079 {
00080 UNKNOWN = 0,
00081 MIXED = 1,
00082 INSIDE = 2,
00083 OUTSIDE = 3
00084 };
00085
00086
00087
00088
00089 class node
00090 {
00091 public:
00092
00093
00094 treeBoundBox bb_;
00095
00096
00097 label parent_;
00098
00099
00100 FixedList<labelBits, 8> subNodes_;
00101
00102 friend Ostream& operator<< (Ostream& os, const node& n)
00103 {
00104 return os << n.bb_ << token::SPACE
00105 << n.parent_ << token::SPACE << n.subNodes_;
00106 }
00107
00108 friend Istream& operator>> (Istream& is, node& n)
00109 {
00110 return is >> n.bb_ >> n.parent_ >> n.subNodes_;
00111 }
00112
00113 friend bool operator==(const node& a, const node& b)
00114 {
00115 return
00116 a.bb_ == b.bb_
00117 && a.parent_ == b.parent_
00118 && a.subNodes_ == b.subNodes_;
00119 }
00120
00121 friend bool operator!=(const node& a, const node& b)
00122 {
00123 return !(a == b);
00124 }
00125 };
00126
00127
00128 private:
00129
00130
00131
00132
00133
00134
00135
00136 static scalar perturbTol_;
00137
00138
00139
00140
00141
00142 const Type shapes_;
00143
00144
00145 List<node> nodes_;
00146
00147
00148 labelListList contents_;
00149
00150
00151 mutable PackedList<2> nodeTypes_;
00152
00153
00154
00155
00156
00157
00158 static bool overlaps
00159 (
00160 const treeBoundBox& parentBb,
00161 const direction octant,
00162 const scalar nearestDistSqr,
00163 const point& sample
00164 );
00165
00166
00167
00168
00169
00170 void divide
00171 (
00172 const labelList& indices,
00173 const treeBoundBox& bb,
00174 labelListList& result
00175 ) const;
00176
00177
00178
00179 node divide
00180 (
00181 const treeBoundBox& bb,
00182 DynamicList<labelList>& contents,
00183 const label contentI
00184 ) const;
00185
00186
00187 void splitNodes
00188 (
00189 const label minSize,
00190 DynamicList<node>& nodes,
00191 DynamicList<labelList>& contents
00192 ) const;
00193
00194 static label compactContents
00195 (
00196 DynamicList<node>& nodes,
00197 DynamicList<labelList>& contents,
00198 const label compactLevel,
00199 const label nodeI,
00200 const label level,
00201 List<labelList>& compactedContents,
00202 label& compactI
00203 );
00204
00205
00206
00207 volumeType calcVolumeType(const label nodeI) const;
00208
00209
00210 volumeType getVolumeType(const label nodeI, const point&) const;
00211
00212
00213
00214
00215
00216 void findNearest
00217 (
00218 const label nodeI,
00219 const linePointRef& ln,
00220
00221 treeBoundBox& tightest,
00222 label& nearestShapeI,
00223 point& linePoint,
00224 point& nearestPoint
00225 ) const;
00226
00227
00228 treeBoundBox subBbox
00229 (
00230 const label parentNodeI,
00231 const direction octant
00232 ) const;
00233
00234
00235
00236 static point pushPoint
00237 (
00238 const treeBoundBox&,
00239 const point&,
00240 const bool pushInside
00241 );
00242
00243
00244
00245 static point pushPoint
00246 (
00247 const treeBoundBox&,
00248 const direction,
00249 const point&,
00250 const bool pushInside
00251 );
00252
00253
00254
00255 static point pushPointIntoFace
00256 (
00257 const treeBoundBox& bb,
00258 const vector& dir,
00259 const point& pt
00260 );
00261
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 bool walkToParent
00273 (
00274 const label nodeI,
00275 const direction octant,
00276
00277 label& parentNodeI,
00278 label& parentOctant
00279 ) const;
00280
00281
00282
00283 bool walkToNeighbour
00284 (
00285 const point& facePoint,
00286 const direction faceID,
00287 label& nodeI,
00288 direction& octant
00289 ) const;
00290
00291
00292 static word faceString(const direction faceID);
00293
00294
00295
00296
00297
00298 void traverseNode
00299 (
00300 const bool findAny,
00301 const point& treeStart,
00302 const vector& treeVec,
00303
00304 const point& start,
00305 const point& end,
00306 const label nodeI,
00307 const direction octantI,
00308
00309 pointIndexHit& hitInfo,
00310 direction& faceID
00311 ) const;
00312
00313
00314 pointIndexHit findLine
00315 (
00316 const bool findAny,
00317 const point& treeStart,
00318 const point& treeEnd,
00319 const label startNodeI,
00320 const direction startOctantI,
00321 const bool verbose = false
00322 ) const;
00323
00324
00325 pointIndexHit findLine
00326 (
00327 const bool findAny,
00328 const point& start,
00329 const point& end
00330 ) const;
00331
00332
00333 void findBox
00334 (
00335 const label nodeI,
00336 const treeBoundBox& searchBox,
00337 labelHashSet& elements
00338 ) const;
00339
00340
00341
00342
00343 label countElements(const labelBits index) const;
00344
00345
00346 void writeOBJ(const label nodeI, const direction octant) const;
00347
00348
00349 static labelBits contentPlusOctant
00350 (
00351 const label i,
00352 const direction octant
00353 )
00354 {
00355 return labelBits(-i - 1, octant);
00356 }
00357
00358
00359 static labelBits nodePlusOctant
00360 (
00361 const label i,
00362 const direction octant
00363 )
00364 {
00365 return labelBits(i + 1, octant);
00366 }
00367
00368
00369 static labelBits emptyPlusOctant
00370 (
00371 const direction octant
00372 )
00373 {
00374 return labelBits(0, octant);
00375 }
00376
00377 public:
00378
00379
00380 static scalar& perturbTol();
00381
00382
00383
00384
00385
00386 indexedOctree(const Type& shapes);
00387
00388
00389 indexedOctree
00390 (
00391 const Type& shapes,
00392 const List<node>& nodes,
00393 const labelListList& contents
00394 );
00395
00396
00397 indexedOctree
00398 (
00399 const Type& shapes,
00400 const treeBoundBox& bb,
00401 const label maxLevels,
00402 const scalar maxLeafRatio,
00403 const scalar maxDuplicity
00404
00405 );
00406
00407
00408 indexedOctree(const Type& shapes, Istream& is);
00409
00410
00411 autoPtr<indexedOctree<Type> > clone() const
00412 {
00413 return autoPtr<indexedOctree<Type> >
00414 (
00415 new indexedOctree<Type>(*this)
00416 );
00417 }
00418
00419
00420
00421
00422
00423
00424 const Type& shapes() const
00425 {
00426 return shapes_;
00427 }
00428
00429
00430 const List<node>& nodes() const
00431 {
00432 return nodes_;
00433 }
00434
00435
00436
00437 const labelListList& contents() const
00438 {
00439 return contents_;
00440 }
00441
00442
00443 const treeBoundBox& bb() const
00444 {
00445 if (nodes_.empty())
00446 {
00447 FatalErrorIn("indexedOctree<Type>::bb() const")
00448 << "Tree is empty" << abort(FatalError);
00449 }
00450 return nodes_[0].bb_;
00451 }
00452
00453
00454
00455
00456 static bool isContent(const labelBits i)
00457 {
00458 return i.val() < 0;
00459 }
00460
00461 static bool isEmpty(const labelBits i)
00462 {
00463 return i.val() == 0;
00464 }
00465
00466 static bool isNode(const labelBits i)
00467 {
00468 return i.val() > 0;
00469 }
00470
00471 static label getContent(const labelBits i)
00472 {
00473 if (!isContent(i))
00474 {
00475 FatalErrorIn("getContent(const label)")
00476 << abort(FatalError);
00477 }
00478 return -i.val()-1;
00479 }
00480
00481 static label getNode(const labelBits i)
00482 {
00483 if (!isNode(i))
00484 {
00485 FatalErrorIn("getNode(const label)")
00486 << abort(FatalError);
00487 }
00488 return i.val() - 1;
00489 }
00490
00491 static direction getOctant(const labelBits i)
00492 {
00493 return i.bits();
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503 pointIndexHit findNearest
00504 (
00505 const point& sample,
00506 const scalar nearestDistSqr
00507 ) const;
00508
00509
00510 void findNearest
00511 (
00512 const label nodeI,
00513 const point&,
00514
00515 scalar& nearestDistSqr,
00516 label& nearestShapeI,
00517 point& nearestPoint
00518 ) const;
00519
00520
00521
00522
00523
00524
00525
00526 pointIndexHit findNearest
00527 (
00528 const linePointRef& ln,
00529 treeBoundBox& tightest,
00530 point& linePoint
00531 ) const;
00532
00533
00534 pointIndexHit findLine
00535 (
00536 const point& start,
00537 const point& end
00538 ) const;
00539
00540
00541 pointIndexHit findLineAny
00542 (
00543 const point& start,
00544 const point& end
00545 ) const;
00546
00547
00548
00549 labelList findBox(const treeBoundBox& bb) const;
00550
00551
00552
00553
00554 labelBits findNode(const label nodeI, const point&) const;
00555
00556
00557
00558 volumeType getVolumeType(const point&) const;
00559
00560
00561
00562 static volumeType getSide
00563 (
00564 const vector& outsideNormal,
00565 const vector& vec
00566 );
00567
00568
00569
00570 static bool overlaps
00571 (
00572 const point& bbMin,
00573 const point& bbMax,
00574 const scalar nearestDistSqr,
00575 const point& sample
00576 );
00577
00578
00579
00580
00581
00582
00583 void print
00584 (
00585 prefixOSstream&,
00586 const bool printContents,
00587 const label
00588 ) const;
00589
00590 bool write(Ostream& os) const;
00591
00592
00593
00594 friend Ostream& operator<< <Type>(Ostream&, const indexedOctree<Type>&);
00595
00596 };
00597
00598
00599
00600
00601 }
00602
00603
00604
00605 #ifdef NoRepository
00606 # include "indexedOctree.C"
00607 #endif
00608
00609
00610
00611 #endif
00612
00613