1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 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 <OpenFOAM/HashSet.H>
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 void Foam::treeLeaf<Type>::space(Ostream& os, const label n)
40 for (label i=0; i<n; i++)
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 // Construct with given size
51 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const label size)
53 treeElem<Type>(bb), size_(0), indices_(size)
57 // Construct from list
59 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const labelList& indices)
61 treeElem<Type>(bb), size_(indices.size()), indices_(indices)
66 // Construct from Istream
68 Foam::treeLeaf<Type>::treeLeaf(Istream& is)
74 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
77 Foam::treeLeaf<Type>::~treeLeaf()
81 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
83 // Take cells at this level and distribute them to lower levels
85 Foam::treeLeaf<Type>* Foam::treeLeaf<Type>::redistribute
95 Pout<< "treeLeaf::redistribute with bb:" << this->bb() << endl;
98 if (size_ <= top.maxLeafRatio())
104 Pout<< "end of treeLeaf::redistribute : small enough" << endl;
110 // create treeNode for this level
111 treeNode<Type>* treeNodePtr = new treeNode<Type>(this->bb());
113 top.setNodes(top.nNodes() + 1);
115 treeNodePtr->distribute
126 Pout<< "end of treeLeaf::redistribute : done creating node"
127 << this->bb() << endl;
130 // return pointer to let level above know.
131 return reinterpret_cast<treeLeaf<Type>*>(treeNodePtr);
136 // Set type of subnodes. Since contains elements return mixed type always.
137 template <class Type>
138 Foam::label Foam::treeLeaf<Type>::setSubNodeType
149 "treeLeaf<Type>::setSubNodeType(const label, octree<Type>&, "
151 ) << "empty leaf. bb:" << this->bb()
152 << abort(FatalError);
154 return octree<Type>::MIXED;
158 template <class Type>
159 Foam::label Foam::treeLeaf<Type>::getSampleType
162 const octree<Type>& top,
167 return shapes.getSampleType(top, sample);
171 template <class Type>
172 Foam::label Foam::treeLeaf<Type>::find
180 if (shapes.contains(indices_[i], sample))
190 template <class Type>
191 bool Foam::treeLeaf<Type>::findTightest
195 treeBoundBox& tightest
198 bool changed = false;
202 changed |= shapes.findTightest
214 template <class Type>
215 bool Foam::treeLeaf<Type>::findNearest
219 treeBoundBox& tightest,
224 bool changed = false;
228 if (shapes.overlaps(indices_[i], tightest))
232 //space(Pout, level);
233 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
234 << " shape:" << indices_[i] << " overlaps:" << tightest
238 scalar thisDist = shapes.calcNearest(indices_[i], sample, nearest);
240 if (thisDist < tightestDist)
242 // Construct new tightest Bb
243 point dist(thisDist, thisDist, thisDist);
245 tightest.min() = sample - dist;
246 tightest.max() = sample + dist;
248 // Update other return values
249 tightestI = indices_[i];
251 tightestDist = thisDist;
257 //space(Pout, level);
258 Pout<< "treeLeaf<Type>::findNearest : Found nearer : shape:"
259 << tightestI << " distance:" << tightestDist
260 << " to sample:" << sample << endl;
270 //space(Pout, level);
271 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
272 << " new nearer:" << tightestDist
280 template <class Type>
281 bool Foam::treeLeaf<Type>::findNearest
284 const linePointRef& ln,
285 treeBoundBox& tightest,
287 point& linePoint, // nearest point on line
288 point& shapePoint // nearest point on shape
291 // Initial smallest distance
292 scalar tightestDist = mag(linePoint - shapePoint);
294 bool changed = false;
298 if (shapes.overlaps(indices_[i], tightest))
300 // Calculate nearest point on line and on shape.
301 point linePt, shapePt;
302 scalar thisDist = shapes.calcNearest
310 if (thisDist < tightestDist)
312 // Found nearer. Use.
313 tightestDist = thisDist;
314 tightestI = indices_[i];
316 shapePoint = shapePt;
317 // Construct new tightest Bb. Nearest point can never be further
318 // away than bounding box of line + margin equal to the distance
319 vector span(thisDist, thisDist, thisDist);
321 tightest.min() = min(ln.start(), ln.end()) - span;
322 tightest.max() = max(ln.start(), ln.end()) + span;
333 template <class Type>
334 bool Foam::treeLeaf<Type>::findBox
338 labelHashSet& elements
341 bool changed = false;
345 if (shapes.overlaps(indices_[i], box))
347 elements.insert(indices_[i]);
357 template <class Type>
358 void Foam::treeLeaf<Type>::printLeaf
366 os << "leaf:" << this->bb()
367 << " number of entries:" << indices().size() << endl;
371 os << indices() << endl;
375 // Dump cube coordinates in OBJ format
376 template <class Type>
377 void Foam::treeLeaf<Type>::writeOBJ
384 point min = this->bb().min();
385 point max = this->bb().max();
387 os << "v " << min.x() << " " << min.y() << " " << min.z() << endl;
388 os << "v " << max.x() << " " << min.y() << " " << min.z() << endl;
389 os << "v " << max.x() << " " << max.y() << " " << min.z() << endl;
390 os << "v " << min.x() << " " << max.y() << " " << min.z() << endl;
392 os << "v " << min.x() << " " << min.y() << " " << max.z() << endl;
393 os << "v " << max.x() << " " << min.y() << " " << max.z() << endl;
394 os << "v " << max.x() << " " << max.y() << " " << max.z() << endl;
395 os << "v " << min.x() << " " << max.y() << " " << max.z() << endl;
397 os << "l " << vertNo << " " << vertNo+1 << endl;
398 os << "l " << vertNo+1 << " " << vertNo+2 << endl;
399 os << "l " << vertNo+2 << " " << vertNo+3 << endl;
400 os << "l " << vertNo+3 << " " << vertNo << endl;
402 os << "l " << vertNo+4 << " " << vertNo+5 << endl;
403 os << "l " << vertNo+5 << " " << vertNo+6 << endl;
404 os << "l " << vertNo+6 << " " << vertNo+7 << endl;
405 os << "l " << vertNo+7 << " " << vertNo << endl;
407 os << "l " << vertNo << " " << vertNo+4 << endl;
408 os << "l " << vertNo+1 << " " << vertNo+5 << endl;
409 os << "l " << vertNo+2 << " " << vertNo+6 << endl;
410 os << "l " << vertNo+3 << " " << vertNo+7 << endl;
416 template <class Type>
417 Foam::label Foam::treeLeaf<Type>::countLeaf
423 label nItems = size();
427 os << "leaf:" << this->bb() << " has size:" << nItems << endl;
433 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
435 template <class Type>
436 Foam::Istream& Foam::operator>> (Istream& is, treeLeaf<Type>& leaf)
438 is >> leaf.bb() >> leaf.indices_;
440 // Was written trimmed
441 leaf.size_ = leaf.indices_.size();
446 template <class Type>
447 Foam::Ostream& Foam::operator<< (Ostream& os, const treeLeaf<Type>& leaf)
451 if (leaf.indices().size() == leaf.size())
453 os << leaf.indices();
457 // Storage not trimmed
458 os << token::SPACE << leaf.size() << token::SPACE << token::BEGIN_LIST;
459 for (label i = 0; i < leaf.size(); i++)
461 os << token::SPACE << leaf.indices()[i];
463 os << token::END_LIST;
469 // ************************ vim: set sw=4 sts=4 et: ************************ //