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 #include "treeLeaf.H"
00029 #include "treeNode.H"
00030 #include "treeBoundBox.H"
00031 #include "octree.H"
00032 #include <OpenFOAM/HashSet.H>
00033
00034
00035
00036 template <class Type>
00037 void Foam::treeLeaf<Type>::space(Ostream& os, const label n)
00038 {
00039 for (label i=0; i<n; i++)
00040 {
00041 os<< ' ';
00042 }
00043 }
00044
00045
00046
00047
00048
00049 template <class Type>
00050 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const label size)
00051 :
00052 treeElem<Type>(bb), size_(0), indices_(size)
00053 {}
00054
00055
00056
00057 template <class Type>
00058 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const labelList& indices)
00059 :
00060 treeElem<Type>(bb), size_(indices.size()), indices_(indices)
00061 {
00062 }
00063
00064
00065
00066 template <class Type>
00067 Foam::treeLeaf<Type>::treeLeaf(Istream& is)
00068 {
00069 is >> *this;
00070 }
00071
00072
00073
00074
00075 template <class Type>
00076 Foam::treeLeaf<Type>::~treeLeaf()
00077 {}
00078
00079
00080
00081
00082
00083 template <class Type>
00084 Foam::treeLeaf<Type>* Foam::treeLeaf<Type>::redistribute
00085 (
00086 const label level,
00087 octree<Type>& top,
00088 const Type& shapes
00089 )
00090 {
00091 if (debug & 1)
00092 {
00093 space(Pout, level);
00094 Pout<< "treeLeaf::redistribute with bb:" << this->bb() << endl;
00095 }
00096
00097 if (size_ <= top.maxLeafRatio())
00098 {
00099
00100 if (debug & 1)
00101 {
00102 space(Pout, level);
00103 Pout<< "end of treeLeaf::redistribute : small enough" << endl;
00104 }
00105 return this;
00106 }
00107 else
00108 {
00109
00110 treeNode<Type>* treeNodePtr = new treeNode<Type>(this->bb());
00111
00112 top.setNodes(top.nNodes() + 1);
00113
00114 treeNodePtr->distribute
00115 (
00116 level,
00117 top,
00118 shapes,
00119 indices_
00120 );
00121
00122 if (debug & 1)
00123 {
00124 space(Pout, level);
00125 Pout<< "end of treeLeaf::redistribute : done creating node"
00126 << this->bb() << endl;
00127 }
00128
00129
00130 return reinterpret_cast<treeLeaf<Type>*>(treeNodePtr);
00131 }
00132 }
00133
00134
00135
00136 template <class Type>
00137 Foam::label Foam::treeLeaf<Type>::setSubNodeType
00138 (
00139 const label level,
00140 octree<Type>& top,
00141 const Type& shapes
00142 ) const
00143 {
00144 if (size() == 0)
00145 {
00146 FatalErrorIn
00147 (
00148 "treeLeaf<Type>::setSubNodeType(const label, octree<Type>&, "
00149 "const Type&)"
00150 ) << "empty leaf. bb:" << this->bb()
00151 << abort(FatalError);
00152 }
00153 return octree<Type>::MIXED;
00154 }
00155
00156
00157 template <class Type>
00158 Foam::label Foam::treeLeaf<Type>::getSampleType
00159 (
00160 const label level,
00161 const octree<Type>& top,
00162 const Type& shapes,
00163 const point& sample
00164 ) const
00165 {
00166 return shapes.getSampleType(top, sample);
00167 }
00168
00169
00170 template <class Type>
00171 Foam::label Foam::treeLeaf<Type>::find
00172 (
00173 const Type& shapes,
00174 const point& sample
00175 ) const
00176 {
00177 forAll(indices_, i)
00178 {
00179 if (shapes.contains(indices_[i], sample))
00180 {
00181 return indices_[i];
00182 }
00183 }
00184
00185 return -1;
00186 }
00187
00188
00189 template <class Type>
00190 bool Foam::treeLeaf<Type>::findTightest
00191 (
00192 const Type& shapes,
00193 const point& sample,
00194 treeBoundBox& tightest
00195 ) const
00196 {
00197 bool changed = false;
00198
00199 forAll(indices_, i)
00200 {
00201 changed |= shapes.findTightest
00202 (
00203 indices_[i],
00204 sample,
00205 tightest
00206 );
00207 }
00208
00209 return changed;
00210 }
00211
00212
00213 template <class Type>
00214 bool Foam::treeLeaf<Type>::findNearest
00215 (
00216 const Type& shapes,
00217 const point& sample,
00218 treeBoundBox& tightest,
00219 label& tightestI,
00220 scalar& tightestDist
00221 ) const
00222 {
00223 bool changed = false;
00224
00225 forAll(indices_, i)
00226 {
00227 if (shapes.overlaps(indices_[i], tightest))
00228 {
00229 if (debug & 8)
00230 {
00231
00232 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
00233 << " shape:" << indices_[i] << " overlaps:" << tightest
00234 << endl;
00235 }
00236 point nearest;
00237 scalar thisDist = shapes.calcNearest(indices_[i], sample, nearest);
00238
00239 if (thisDist < tightestDist)
00240 {
00241
00242 point dist(thisDist, thisDist, thisDist);
00243
00244 tightest.min() = sample - dist;
00245 tightest.max() = sample + dist;
00246
00247
00248 tightestI = indices_[i];
00249
00250 tightestDist = thisDist;
00251
00252 changed = true;
00253
00254 if (debug & 8)
00255 {
00256
00257 Pout<< "treeLeaf<Type>::findNearest : Found nearer : shape:"
00258 << tightestI << " distance:" << tightestDist
00259 << " to sample:" << sample << endl;
00260 }
00261 }
00262 }
00263 }
00264
00265 if (changed)
00266 {
00267 if (debug & 8)
00268 {
00269
00270 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
00271 << " new nearer:" << tightestDist
00272 << endl;
00273 }
00274 }
00275 return changed;
00276 }
00277
00278
00279 template <class Type>
00280 bool Foam::treeLeaf<Type>::findNearest
00281 (
00282 const Type& shapes,
00283 const linePointRef& ln,
00284 treeBoundBox& tightest,
00285 label& tightestI,
00286 point& linePoint,
00287 point& shapePoint
00288 ) const
00289 {
00290
00291 scalar tightestDist = mag(linePoint - shapePoint);
00292
00293 bool changed = false;
00294
00295 forAll(indices_, i)
00296 {
00297 if (shapes.overlaps(indices_[i], tightest))
00298 {
00299
00300 point linePt, shapePt;
00301 scalar thisDist = shapes.calcNearest
00302 (
00303 indices_[i],
00304 ln,
00305 linePt,
00306 shapePt
00307 );
00308
00309 if (thisDist < tightestDist)
00310 {
00311
00312 tightestDist = thisDist;
00313 tightestI = indices_[i];
00314 linePoint = linePt;
00315 shapePoint = shapePt;
00316
00317
00318 vector span(thisDist, thisDist, thisDist);
00319
00320 tightest.min() = min(ln.start(), ln.end()) - span;
00321 tightest.max() = max(ln.start(), ln.end()) + span;
00322
00323 changed = true;
00324 }
00325 }
00326 }
00327
00328 return changed;
00329 }
00330
00331
00332 template <class Type>
00333 bool Foam::treeLeaf<Type>::findBox
00334 (
00335 const Type& shapes,
00336 const boundBox& box,
00337 labelHashSet& elements
00338 ) const
00339 {
00340 bool changed = false;
00341
00342 forAll(indices_, i)
00343 {
00344 if (shapes.overlaps(indices_[i], box))
00345 {
00346 elements.insert(indices_[i]);
00347
00348 changed = true;
00349 }
00350 }
00351
00352 return changed;
00353 }
00354
00355
00356 template <class Type>
00357 void Foam::treeLeaf<Type>::printLeaf
00358 (
00359 Ostream& os,
00360 const label level
00361 ) const
00362 {
00363 space(os, level);
00364
00365 os << "leaf:" << this->bb()
00366 << " number of entries:" << indices().size() << endl;
00367
00368 space(os, level);
00369
00370 os << indices() << endl;
00371 }
00372
00373
00374
00375 template <class Type>
00376 void Foam::treeLeaf<Type>::writeOBJ
00377 (
00378 Ostream& os,
00379 const label level,
00380 label& vertNo
00381 ) const
00382 {
00383 point min = this->bb().min();
00384 point max = this->bb().max();
00385
00386 os << "v " << min.x() << " " << min.y() << " " << min.z() << endl;
00387 os << "v " << max.x() << " " << min.y() << " " << min.z() << endl;
00388 os << "v " << max.x() << " " << max.y() << " " << min.z() << endl;
00389 os << "v " << min.x() << " " << max.y() << " " << min.z() << endl;
00390
00391 os << "v " << min.x() << " " << min.y() << " " << max.z() << endl;
00392 os << "v " << max.x() << " " << min.y() << " " << max.z() << endl;
00393 os << "v " << max.x() << " " << max.y() << " " << max.z() << endl;
00394 os << "v " << min.x() << " " << max.y() << " " << max.z() << endl;
00395
00396 os << "l " << vertNo << " " << vertNo+1 << endl;
00397 os << "l " << vertNo+1 << " " << vertNo+2 << endl;
00398 os << "l " << vertNo+2 << " " << vertNo+3 << endl;
00399 os << "l " << vertNo+3 << " " << vertNo << endl;
00400
00401 os << "l " << vertNo+4 << " " << vertNo+5 << endl;
00402 os << "l " << vertNo+5 << " " << vertNo+6 << endl;
00403 os << "l " << vertNo+6 << " " << vertNo+7 << endl;
00404 os << "l " << vertNo+7 << " " << vertNo << endl;
00405
00406 os << "l " << vertNo << " " << vertNo+4 << endl;
00407 os << "l " << vertNo+1 << " " << vertNo+5 << endl;
00408 os << "l " << vertNo+2 << " " << vertNo+6 << endl;
00409 os << "l " << vertNo+3 << " " << vertNo+7 << endl;
00410
00411 vertNo += 8;
00412 }
00413
00414
00415 template <class Type>
00416 Foam::label Foam::treeLeaf<Type>::countLeaf
00417 (
00418 Ostream& os,
00419 const label level
00420 ) const
00421 {
00422 label nItems = size();
00423
00424 space(os, level);
00425
00426 os << "leaf:" << this->bb() << " has size:" << nItems << endl;
00427
00428 return nItems;
00429 }
00430
00431
00432
00433
00434 template <class Type>
00435 Foam::Istream& Foam::operator>> (Istream& is, treeLeaf<Type>& leaf)
00436 {
00437 is >> leaf.bb() >> leaf.indices_;
00438
00439
00440 leaf.size_ = leaf.indices_.size();
00441 return is;
00442 }
00443
00444
00445 template <class Type>
00446 Foam::Ostream& Foam::operator<< (Ostream& os, const treeLeaf<Type>& leaf)
00447 {
00448 os << leaf.bb();
00449
00450 if (leaf.indices().size() == leaf.size())
00451 {
00452 os << leaf.indices();
00453 }
00454 else
00455 {
00456
00457 os << token::SPACE << leaf.size() << token::SPACE << token::BEGIN_LIST;
00458 for (label i = 0; i < leaf.size(); i++)
00459 {
00460 os << token::SPACE << leaf.indices()[i];
00461 }
00462 os << token::END_LIST;
00463 }
00464 return os;
00465 }
00466
00467
00468