1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
28 #include "treeBoundBox.H"
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 void Foam::treeLeaf<Type>::space(Ostream& os, const label n)
37 for (label i=0; i<n; i++)
44 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 // Construct with given size
48 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const label size)
50 treeElem<Type>(bb), size_(0), indices_(size)
54 // Construct from list
56 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const labelList& indices)
58 treeElem<Type>(bb), size_(indices.size()), indices_(indices)
63 // Construct from Istream
65 Foam::treeLeaf<Type>::treeLeaf(Istream& is)
71 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
74 Foam::treeLeaf<Type>::~treeLeaf()
78 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
80 // Take cells at this level and distribute them to lower levels
82 Foam::treeLeaf<Type>* Foam::treeLeaf<Type>::redistribute
92 Pout<< "treeLeaf::redistribute with bb:" << this->bb() << endl;
95 if (size_ <= top.maxLeafRatio())
101 Pout<< "end of treeLeaf::redistribute : small enough" << endl;
107 // create treeNode for this level
108 treeNode<Type>* treeNodePtr = new treeNode<Type>(this->bb());
110 top.setNodes(top.nNodes() + 1);
112 treeNodePtr->distribute
123 Pout<< "end of treeLeaf::redistribute : done creating node"
124 << this->bb() << endl;
127 // return pointer to let level above know.
128 return reinterpret_cast<treeLeaf<Type>*>(treeNodePtr);
133 // Set type of subnodes. Since contains elements return mixed type always.
134 template <class Type>
135 Foam::label Foam::treeLeaf<Type>::setSubNodeType
146 "treeLeaf<Type>::setSubNodeType(const label, octree<Type>&, "
148 ) << "empty leaf. bb:" << this->bb()
149 << abort(FatalError);
151 return octree<Type>::MIXED;
155 template <class Type>
156 Foam::label Foam::treeLeaf<Type>::getSampleType
159 const octree<Type>& top,
164 return shapes.getSampleType(top, sample);
168 template <class Type>
169 Foam::label Foam::treeLeaf<Type>::find
177 if (shapes.contains(indices_[i], sample))
187 template <class Type>
188 bool Foam::treeLeaf<Type>::findTightest
192 treeBoundBox& tightest
195 bool changed = false;
199 changed |= shapes.findTightest
211 template <class Type>
212 bool Foam::treeLeaf<Type>::findNearest
216 treeBoundBox& tightest,
221 bool changed = false;
225 if (shapes.overlaps(indices_[i], tightest))
229 //space(Pout, level);
230 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
231 << " shape:" << indices_[i] << " overlaps:" << tightest
235 scalar thisDist = shapes.calcNearest(indices_[i], sample, nearest);
237 if (thisDist < tightestDist)
239 // Construct new tightest Bb
240 point dist(thisDist, thisDist, thisDist);
242 tightest.min() = sample - dist;
243 tightest.max() = sample + dist;
245 // Update other return values
246 tightestI = indices_[i];
248 tightestDist = thisDist;
254 //space(Pout, level);
255 Pout<< "treeLeaf<Type>::findNearest : Found nearer : shape:"
256 << tightestI << " distance:" << tightestDist
257 << " to sample:" << sample << endl;
267 //space(Pout, level);
268 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
269 << " new nearer:" << tightestDist
277 template <class Type>
278 bool Foam::treeLeaf<Type>::findNearest
281 const linePointRef& ln,
282 treeBoundBox& tightest,
284 point& linePoint, // nearest point on line
285 point& shapePoint // nearest point on shape
288 // Initial smallest distance
289 scalar tightestDist = mag(linePoint - shapePoint);
291 bool changed = false;
295 if (shapes.overlaps(indices_[i], tightest))
297 // Calculate nearest point on line and on shape.
298 point linePt, shapePt;
299 scalar thisDist = shapes.calcNearest
307 if (thisDist < tightestDist)
309 // Found nearer. Use.
310 tightestDist = thisDist;
311 tightestI = indices_[i];
313 shapePoint = shapePt;
314 // Construct new tightest Bb. Nearest point can never be further
315 // away than bounding box of line + margin equal to the distance
316 vector span(thisDist, thisDist, thisDist);
318 tightest.min() = min(ln.start(), ln.end()) - span;
319 tightest.max() = max(ln.start(), ln.end()) + span;
330 template <class Type>
331 bool Foam::treeLeaf<Type>::findBox
335 labelHashSet& elements
338 bool changed = false;
342 if (shapes.overlaps(indices_[i], box))
344 elements.insert(indices_[i]);
354 template <class Type>
355 void Foam::treeLeaf<Type>::printLeaf
363 os << "leaf:" << this->bb()
364 << " number of entries:" << indices().size() << endl;
368 os << indices() << endl;
372 // Dump cube coordinates in OBJ format
373 template <class Type>
374 void Foam::treeLeaf<Type>::writeOBJ
381 point min = this->bb().min();
382 point max = this->bb().max();
384 os << "v " << min.x() << " " << min.y() << " " << min.z() << endl;
385 os << "v " << max.x() << " " << min.y() << " " << min.z() << endl;
386 os << "v " << max.x() << " " << max.y() << " " << min.z() << endl;
387 os << "v " << min.x() << " " << max.y() << " " << min.z() << endl;
389 os << "v " << min.x() << " " << min.y() << " " << max.z() << endl;
390 os << "v " << max.x() << " " << min.y() << " " << max.z() << endl;
391 os << "v " << max.x() << " " << max.y() << " " << max.z() << endl;
392 os << "v " << min.x() << " " << max.y() << " " << max.z() << endl;
394 os << "l " << vertNo << " " << vertNo+1 << endl;
395 os << "l " << vertNo+1 << " " << vertNo+2 << endl;
396 os << "l " << vertNo+2 << " " << vertNo+3 << endl;
397 os << "l " << vertNo+3 << " " << vertNo << endl;
399 os << "l " << vertNo+4 << " " << vertNo+5 << endl;
400 os << "l " << vertNo+5 << " " << vertNo+6 << endl;
401 os << "l " << vertNo+6 << " " << vertNo+7 << endl;
402 os << "l " << vertNo+7 << " " << vertNo << endl;
404 os << "l " << vertNo << " " << vertNo+4 << endl;
405 os << "l " << vertNo+1 << " " << vertNo+5 << endl;
406 os << "l " << vertNo+2 << " " << vertNo+6 << endl;
407 os << "l " << vertNo+3 << " " << vertNo+7 << endl;
413 template <class Type>
414 Foam::label Foam::treeLeaf<Type>::countLeaf
420 label nItems = size();
424 os << "leaf:" << this->bb() << " has size:" << nItems << endl;
430 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
432 template <class Type>
433 Foam::Istream& Foam::operator>> (Istream& is, treeLeaf<Type>& leaf)
435 is >> leaf.bb() >> leaf.indices_;
437 // Was written trimmed
438 leaf.size_ = leaf.indices_.size();
443 template <class Type>
444 Foam::Ostream& Foam::operator<< (Ostream& os, const treeLeaf<Type>& leaf)
448 if (leaf.indices().size() == leaf.size())
450 os << leaf.indices();
454 // Storage not trimmed
455 os << token::SPACE << leaf.size() << token::SPACE << token::BEGIN_LIST;
458 os << token::SPACE << leaf.indices()[i];
460 os << token::END_LIST;
466 // ************************************************************************* //