ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / meshTools / octree / treeLeaf.C
blob8dc6694710c1e7432363cd066cb58aab22a99351
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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 \*---------------------------------------------------------------------------*/
26 #include "treeLeaf.H"
27 #include "treeNode.H"
28 #include "treeBoundBox.H"
29 #include "octree.H"
30 #include "HashSet.H"
32 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
34 template <class Type>
35 void Foam::treeLeaf<Type>::space(Ostream& os, const label n)
37     for (label i=0; i<n; i++)
38     {
39         os  << ' ';
40     }
44 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
46 // Construct with given size
47 template <class Type>
48 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const label size)
50     treeElem<Type>(bb), size_(0), indices_(size)
54 // Construct from list
55 template <class Type>
56 Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const labelList& indices)
58     treeElem<Type>(bb), size_(indices.size()), indices_(indices)
63 // Construct from Istream
64 template <class Type>
65 Foam::treeLeaf<Type>::treeLeaf(Istream& is)
67     is >> *this;
71 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
73 template <class Type>
74 Foam::treeLeaf<Type>::~treeLeaf()
78 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
80 // Take cells at this level and distribute them to lower levels
81 template <class Type>
82 Foam::treeLeaf<Type>* Foam::treeLeaf<Type>::redistribute
84     const label level,
85     octree<Type>& top,
86     const Type& shapes
89     if (debug & 1)
90     {
91         space(Pout, level);
92         Pout<< "treeLeaf::redistribute with bb:" << this->bb() << endl;
93     }
95     if (size_ <= top.maxLeafRatio())
96     {
97         // leaf small enough
98         if (debug & 1)
99         {
100             space(Pout, level);
101             Pout<< "end of treeLeaf::redistribute : small enough" << endl;
102         }
103         return this;
104     }
105     else
106     {
107         // create treeNode for this level
108         treeNode<Type>* treeNodePtr = new treeNode<Type>(this->bb());
110         top.setNodes(top.nNodes() + 1);
112         treeNodePtr->distribute
113         (
114             level,
115             top,
116             shapes,
117             indices_
118         );
120         if (debug & 1)
121         {
122             space(Pout, level);
123             Pout<< "end of treeLeaf::redistribute : done creating node"
124                 << this->bb() << endl;
125         }
127         // return pointer to let level above know.
128         return reinterpret_cast<treeLeaf<Type>*>(treeNodePtr);
129     }
133 // Set type of subnodes. Since contains elements return mixed type always.
134 template <class Type>
135 Foam::label Foam::treeLeaf<Type>::setSubNodeType
137     const label level,
138     octree<Type>& top,
139     const Type& shapes
140 ) const
142     if (size() == 0)
143     {
144         FatalErrorIn
145         (
146             "treeLeaf<Type>::setSubNodeType(const label, octree<Type>&, "
147             "const Type&)"
148         )   << "empty leaf. bb:" << this->bb()
149             << abort(FatalError);
150     }
151     return octree<Type>::MIXED;
155 template <class Type>
156 Foam::label Foam::treeLeaf<Type>::getSampleType
158     const label level,
159     const octree<Type>& top,
160     const Type& shapes,
161     const point& sample
162 ) const
164     return shapes.getSampleType(top, sample);
168 template <class Type>
169 Foam::label Foam::treeLeaf<Type>::find
171     const Type& shapes,
172     const point& sample
173 ) const
175     forAll(indices_, i)
176     {
177         if (shapes.contains(indices_[i], sample))
178         {
179             return indices_[i];
180         }
181     }
183     return -1;
187 template <class Type>
188 bool Foam::treeLeaf<Type>::findTightest
190     const Type& shapes,
191     const point& sample,
192     treeBoundBox& tightest
193 ) const
195     bool changed = false;
197     forAll(indices_, i)
198     {
199         changed |= shapes.findTightest
200         (
201             indices_[i],
202             sample,
203             tightest
204         );
205     }
207     return changed;
211 template <class Type>
212 bool Foam::treeLeaf<Type>::findNearest
214     const Type& shapes,
215     const point& sample,
216     treeBoundBox& tightest,
217     label& tightestI,
218     scalar& tightestDist
219 ) const
221     bool changed = false;
223     forAll(indices_, i)
224     {
225         if (shapes.overlaps(indices_[i], tightest))
226         {
227             if (debug & 8)
228             {
229                 //space(Pout, level);
230                 Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
231                     << "  shape:" << indices_[i] << " overlaps:" << tightest
232                     << endl;
233             }
234             point nearest;
235             scalar thisDist = shapes.calcNearest(indices_[i], sample, nearest);
237             if (thisDist < tightestDist)
238             {
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;
250                 changed = true;
252                 if (debug & 8)
253                 {
254                     //space(Pout, level);
255                     Pout<< "treeLeaf<Type>::findNearest : Found nearer : shape:"
256                         << tightestI << "  distance:" << tightestDist
257                         << " to sample:" << sample << endl;
258                 }
259             }
260         }
261     }
263     if (changed)
264     {
265         if (debug & 8)
266         {
267             //space(Pout, level);
268             Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
269                 << "  new nearer:" << tightestDist
270                 << endl;
271         }
272     }
273     return changed;
277 template <class Type>
278 bool Foam::treeLeaf<Type>::findNearest
280     const Type& shapes,
281     const linePointRef& ln,
282     treeBoundBox& tightest,
283     label& tightestI,
284     point& linePoint,   // nearest point on line
285     point& shapePoint   // nearest point on shape
286 ) const
288     // Initial smallest distance
289     scalar tightestDist = mag(linePoint - shapePoint);
291     bool changed = false;
293     forAll(indices_, i)
294     {
295         if (shapes.overlaps(indices_[i], tightest))
296         {
297             // Calculate nearest point on line and on shape.
298             point linePt, shapePt;
299             scalar thisDist = shapes.calcNearest
300             (
301                 indices_[i],
302                 ln,
303                 linePt,
304                 shapePt
305             );
307             if (thisDist < tightestDist)
308             {
309                 // Found nearer. Use.
310                 tightestDist = thisDist;
311                 tightestI = indices_[i];
312                 linePoint = linePt;
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;
321                 changed = true;
322             }
323         }
324     }
326     return changed;
330 template <class Type>
331 bool Foam::treeLeaf<Type>::findBox
333     const Type& shapes,
334     const boundBox& box,
335     labelHashSet& elements
336 ) const
338     bool changed = false;
340     forAll(indices_, i)
341     {
342         if (shapes.overlaps(indices_[i], box))
343         {
344             elements.insert(indices_[i]);
346             changed = true;
347         }
348     }
350     return changed;
354 template <class Type>
355 void Foam::treeLeaf<Type>::printLeaf
357     Ostream& os,
358     const label level
359 ) const
361     space(os, level);
363     os  << "leaf:" << this->bb()
364         << "   number of entries:" << indices().size() << endl;
366     space(os, level);
368     os << indices() << endl;
372 // Dump cube coordinates in OBJ format
373 template <class Type>
374 void Foam::treeLeaf<Type>::writeOBJ
376     Ostream& os,
377     const label level,
378     label& vertNo
379 ) const
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;
409     vertNo += 8;
413 template <class Type>
414 Foam::label Foam::treeLeaf<Type>::countLeaf
416     Ostream& os,
417     const label level
418 ) const
420     label nItems = size();
422     space(os, level);
424     os << "leaf:" << this->bb() << " has size:" << nItems << endl;
426     return nItems;
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();
439     return is;
443 template <class Type>
444 Foam::Ostream& Foam::operator<< (Ostream& os, const treeLeaf<Type>& leaf)
446     os << leaf.bb();
448     if (leaf.indices().size() == leaf.size())
449     {
450         os << leaf.indices();
451     }
452     else
453     {
454         // Storage not trimmed
455         os << token::SPACE << leaf.size() << token::SPACE << token::BEGIN_LIST;
456         forAll(leaf, i)
457         {
458             os << token::SPACE << leaf.indices()[i];
459         }
460         os << token::END_LIST;
461     }
462     return os;
466 // ************************************************************************* //