1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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
27 \*---------------------------------------------------------------------------*/
31 #include "treeBoundBox.H"
33 #include "labelHashSet.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 void treeLeaf<Type>::space(Ostream& os, const label n)
45 for(label i=0; i<n; i++)
52 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54 // Construct with given size
56 treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const label size)
58 treeElem<Type>(bb), size_(0), indices_(size)
62 // Construct from list
64 treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const labelList& indices)
66 treeElem<Type>(bb), size_(indices.size()), indices_(indices)
71 // Construct from Istream
73 treeLeaf<Type>::treeLeaf(Istream& is)
79 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
82 treeLeaf<Type>::~treeLeaf()
86 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
88 // Take cells at this level and distribute them to lower levels
90 treeLeaf<Type>* treeLeaf<Type>::redistribute
100 Pout<< "treeLeaf::redistribute with bb:" << this->bb() << endl;
103 if (size_ <= top.maxLeafRatio())
109 Pout<< "end of treeLeaf::redistribute : small enough" << endl;
115 // create treeNode for this level
116 treeNode<Type>* treeNodePtr = new treeNode<Type>(this->bb());
118 top.setNodes(top.nNodes() + 1);
120 treeNodePtr->distribute
131 Pout<< "end of treeLeaf::redistribute : done creating node"
132 << this->bb() << endl;
135 // return pointer to let level above know.
136 return reinterpret_cast<treeLeaf<Type>*>(treeNodePtr);
141 // Set type of subnodes. Since contains elements return mixed type always.
142 template <class Type>
143 Foam::label treeLeaf<Type>::setSubNodeType
154 "treeLeaf<Type>::setSubNodeType(const label, octree<Type>&, "
156 ) << "empty leaf. bb:" << this->bb()
157 << abort(FatalError);
159 return octree<Type>::MIXED;
163 template <class Type>
164 Foam::label treeLeaf<Type>::getSampleType
167 const octree<Type>& top,
172 return shapes.getSampleType(top, sample);
176 template <class Type>
177 label treeLeaf<Type>::find
185 if (shapes.contains(indices_[i], sample))
195 template <class Type>
196 bool treeLeaf<Type>::findTightest
200 treeBoundBox& tightest
203 bool changed = false;
220 template <class Type>
221 bool treeLeaf<Type>::findNearest
225 treeBoundBox& tightest,
230 bool changed = false;
234 if (shapes.overlaps(indices_[i], tightest))
238 //space(Pout, level);
239 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
240 << " shape:" << indices_[i] << " overlaps:" << tightest
244 scalar thisDist = shapes.calcNearest(indices_[i], sample, nearest);
246 if (thisDist < tightestDist)
248 // Construct new tightest Bb
249 point dist(thisDist, thisDist, thisDist);
251 tightest.min() = sample - dist;
252 tightest.max() = sample + dist;
254 // Update other return values
255 tightesti = indices_[i];
257 tightestDist = thisDist;
263 //space(Pout, level);
264 Pout<< "treeLeaf<Type>::findNearest : Found nearer : shape:"
265 << tightesti << " distance:" << tightestDist
266 << " to sample:" << sample << endl;
276 //space(Pout, level);
277 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
278 << " new nearer:" << tightestDist
286 template <class Type>
287 bool treeLeaf<Type>::findNearest
290 const linePointRef& ln,
291 treeBoundBox& tightest,
293 point& linePoint, // nearest point on line
294 point& shapePoint // nearest point on shape
297 // Initial smallest distance
298 scalar tightestDist = mag(linePoint - shapePoint);
300 bool changed = false;
304 if (shapes.overlaps(indices_[i], tightest))
306 // Calculate nearest point on line and on shape.
307 point linePt, shapePt;
308 scalar thisDist = shapes.calcNearest
316 if (thisDist < tightestDist)
318 // Found nearer. Use.
319 tightestDist = thisDist;
320 tightesti = indices_[i];
322 shapePoint = shapePt;
323 // Construct new tightest Bb. Nearest point can never be further
324 // away than bounding box of line + margin equal to the distance
325 vector span(thisDist, thisDist, thisDist);
327 tightest.min() = min(ln.start(), ln.end()) - span;
328 tightest.max() = max(ln.start(), ln.end()) + span;
339 template <class Type>
340 bool treeLeaf<Type>::findBox
344 labelHashSet& elements
347 bool changed = false;
351 if (shapes.overlaps(indices_[i], box))
353 elements.insert(indices_[i]);
363 template <class Type>
364 void treeLeaf<Type>::printLeaf
372 os << "leaf:" << this->bb()
373 << " number of entries:" << indices().size() << endl;
377 os << indices() << endl;
381 // Dump cube coordinates in OBJ format
382 template <class Type>
383 void treeLeaf<Type>::writeOBJ
390 point min = this->bb().min();
391 point max = this->bb().max();
393 os << "v " << min.x() << " " << min.y() << " " << min.z() << endl;
394 os << "v " << max.x() << " " << min.y() << " " << min.z() << endl;
395 os << "v " << max.x() << " " << max.y() << " " << min.z() << endl;
396 os << "v " << min.x() << " " << max.y() << " " << min.z() << endl;
398 os << "v " << min.x() << " " << min.y() << " " << max.z() << endl;
399 os << "v " << max.x() << " " << min.y() << " " << max.z() << endl;
400 os << "v " << max.x() << " " << max.y() << " " << max.z() << endl;
401 os << "v " << min.x() << " " << max.y() << " " << max.z() << endl;
403 os << "l " << vertNo << " " << vertNo+1 << endl;
404 os << "l " << vertNo+1 << " " << vertNo+2 << endl;
405 os << "l " << vertNo+2 << " " << vertNo+3 << endl;
406 os << "l " << vertNo+3 << " " << vertNo << endl;
408 os << "l " << vertNo+4 << " " << vertNo+5 << endl;
409 os << "l " << vertNo+5 << " " << vertNo+6 << endl;
410 os << "l " << vertNo+6 << " " << vertNo+7 << endl;
411 os << "l " << vertNo+7 << " " << vertNo << endl;
413 os << "l " << vertNo << " " << vertNo+4 << endl;
414 os << "l " << vertNo+1 << " " << vertNo+5 << endl;
415 os << "l " << vertNo+2 << " " << vertNo+6 << endl;
416 os << "l " << vertNo+3 << " " << vertNo+7 << endl;
422 template <class Type>
423 label treeLeaf<Type>::countLeaf
429 label nItems = size();
433 os << "leaf:" << this->bb() << " has size:" << nItems << endl;
439 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
441 template <class Type>
442 Istream& operator>> (Istream& is, treeLeaf<Type>& leaf)
444 is >> leaf.bb() >> leaf.indices_;
446 // Was written trimmed
447 leaf.size_ = leaf.indices_.size();
452 template <class Type>
453 Ostream& operator<< (Ostream& os, const treeLeaf<Type>& leaf)
457 if (leaf.indices().size() == leaf.size())
459 os << leaf.indices();
463 // Storage not trimmed
464 os << token::SPACE << leaf.size() << token::SPACE << token::BEGIN_LIST;
465 for (label i = 0; i < leaf.size(); i++)
467 os << token::SPACE << leaf.indices()[i];
469 os << token::END_LIST;
476 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
478 } // End namespace Foam
480 // ************************************************************************* //