meshOctreeCubeRefine.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
11  cfMesh 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 3 of the License, or (at your
14  option) any later version.
15 
16  cfMesh 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.
20 
21  You should have received a copy of the GNU General Public License
22  along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "meshOctreeCube.H"
29 #include "VRWGraph.H"
30 #include "triSurf.H"
31 
32 # ifdef USE_OMP
33 #include <omp.h>
34 # endif
35 
36 //#define DEBUGSearch
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 
46 (
47  const triSurf& surface,
48  const boundBox& rootBox
49 )
50 {
51  const VRWGraph& faceEdges = surface.facetEdges();
52  const VRWGraph& edgeFaces = surface.edgeFacets();
53  const edgeLongList& edges = surface.edges();
54  const pointField& points = surface.points();
55 
56  const VRWGraph& containedElements = activeSlotPtr_->containedTriangles_;
57  VRWGraph& containedEdges = activeSlotPtr_->containedEdges_;
58 
59  DynList<label> addedEdges;
60  labelHashSet addEdge;
61  forAllRow(containedElements, containedElementsLabel_, tI)
62  {
63  const label facetI = containedElements(containedElementsLabel_, tI);
64 
65  forAllRow(faceEdges, facetI, feI)
66  {
67  const label edgeI = faceEdges(facetI, feI);
68 
69  if( addEdge.found(edgeI) )
70  continue;
71 
72  if( edgeFaces.sizeOfRow(edgeI) != 2 )
73  continue;
74 
75  if(
76  surface[edgeFaces(edgeI, 0)].region() !=
77  surface[edgeFaces(edgeI, 1)].region()
78  )
79  {
80  const edge& edg = edges[edgeI];
81  const point& s = points[edg.start()];
82  const point& e = points[edg.end()];
83  if( intersectsLine(rootBox, s, e) )
84  {
85  addEdge.insert(edgeI);
86  addedEdges.append(edgeI);
87  }
88  }
89  }
90  }
91 
92  if( addedEdges.size() != 0 )
93  {
94  containedEdgesLabel_ = containedEdges.size();
95  containedEdges.appendList(addedEdges);
96  }
97 }
98 
99 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
100 
102 (
103  const triSurf& surface,
104  const boundBox& rootBox,
105  meshOctreeSlot* slotPtr
106 )
107 {
108  if( !slotPtr )
109  slotPtr = activeSlotPtr_;
110 
111  # ifdef DEBUGSearch
112  Info << "Refining the cube " << *this << endl;
113  # endif
114 
115  //- set the cube label to -1
116  cubeLabel_ = -1;
117 
118  //- create subCubes
120  forAll(subCubes, scI)
121  subCubes[scI] = NULL;
122 
123  //- create new cubes in the Z-order fashion
124  for(label scI=0;scI<4;++scI)
125  {
126  const label cubeI = slotPtr->cubes_.size();
127  const meshOctreeCubeCoordinates cc = this->refineForPosition(scI);
128 
129  slotPtr->cubes_.append(cc);
130 
131  subCubes[scI] = &slotPtr->cubes_[cubeI];
132  subCubes[scI]->activeSlotPtr_ = slotPtr;
133  subCubes[scI]->setCubeType(this->cubeType());
134  subCubes[scI]->setProcNo(this->procNo());
135  }
136 
137  const label subCubesLabel = slotPtr->childCubes_.size();
138  slotPtr->childCubes_.appendFixedList(subCubes);
139  subCubesPtr_ = &slotPtr->childCubes_(subCubesLabel, 0);
140 
141  if( hasContainedElements() )
142  {
143  const VRWGraph& containedElements =
144  activeSlotPtr_->containedTriangles_;
145 
146  # ifdef DEBUGSearch
147  Info << "Distributing contained elements "
148  << containedElements[containedElementsLabel_] << endl;
149  # endif
150 
151  //- check if the subCube contain the element
152  FixedList<DynList<label, 512>, 4> elementsInSubCubes;
153 
154  forAllRow(containedElements, containedElementsLabel_, tI)
155  {
156  const label elI = containedElements(containedElementsLabel_, tI);
157 
158  bool used(false);
159  for(label scI=0;scI<4;++scI)
160  if(
161  subCubes[scI]->intersectsTriangleExact
162  (
163  surface,
164  rootBox,
165  elI
166  )
167  )
168  {
169  used = true;
170  elementsInSubCubes[scI].append(elI);
171  }
172 
173  if( !used )
174  {
175  Warning << "Triangle " << elI
176  << " is not transferred to the child cubes!" << endl;
177  }
178  }
179 
180  forAll(elementsInSubCubes, scI)
181  {
182  const DynList<label, 512>& elmts = elementsInSubCubes[scI];
183 
184  if( elmts.size() != 0 )
185  {
186  VRWGraph& ct = slotPtr->containedTriangles_;
187  subCubes[scI]->containedElementsLabel_ = ct.size();
188  ct.appendList(elmts);
189 
190 
191  # ifdef DEBUGSearch
192  Info << "Elements in leaf " << scI << " are "
193  << ct[subCubes[scI]->containedElements()]
194  << endl;
195  # endif
196  }
197  }
198 
199  //- find surface edges within the cube
200  for(label scI=0;scI<4;++scI)
201  if( subCubes[scI]->hasContainedElements() )
202  {
203  subCubes[scI]->findContainedEdges
204  (
205  surface,
206  rootBox
207  );
208  }
209  else if( subCubes[scI]->cubeType() & DATA )
210  {
211  subCubes[scI]->setCubeType(UNKNOWN);
212  }
213  }
214 
215  # ifdef DEBUGSearch
216  for(label scI=0;scI<4;++scI)
217  Info << "Refined cube " << scI << " is "
218  << *subCubes[scI] << endl;
219  # endif
220 }
221 
223 (
224  const triSurf& surface,
225  const boundBox& rootBox,
226  meshOctreeSlot* slotPtr
227 )
228 {
229  if( !slotPtr )
230  slotPtr = activeSlotPtr_;
231 
232  # ifdef DEBUGSearch
233  Info << "Refining the cube " << *this << endl;
234  # endif
235 
236  //- set the cube label to -1
237  cubeLabel_ = -1;
238 
239  //- create subCubes
241 
242  //- create new cubes in the Z-order fashion
243  for(label scI=0;scI<8;++scI)
244  {
245  const label cubeI = slotPtr->cubes_.size();
246  slotPtr->cubes_.append(meshOctreeCube(this->refineForPosition(scI)));
247 
248  subCubes[scI] = &slotPtr->cubes_[cubeI];
249  subCubes[scI]->activeSlotPtr_ = slotPtr;
250  subCubes[scI]->setCubeType(this->cubeType());
251  subCubes[scI]->setProcNo(this->procNo());
252  }
253 
254  const label subCubesLabel = slotPtr->childCubes_.size();
255  slotPtr->childCubes_.appendFixedList(subCubes);
256  subCubesPtr_ = &slotPtr->childCubes_(subCubesLabel, 0);
257 
258  if( hasContainedElements() )
259  {
260  const VRWGraph& containedElements =
261  activeSlotPtr_->containedTriangles_;
262 
263  # ifdef DEBUGSearch
264  Info << "Distributing contained elements "
265  << containedElements[containedElementsLabel_] << endl;
266  # endif
267 
268  //- check if the subCube contain the element
269  FixedList<DynList<label, 512>, 8> elementsInSubCubes;
270 
271  forAllRow(containedElements, containedElementsLabel_, tI)
272  {
273  const label elI = containedElements(containedElementsLabel_, tI);
274 
275  bool used(false);
276  for(label scI=0;scI<8;++scI)
277  if(
278  subCubes[scI]->intersectsTriangleExact
279  (
280  surface,
281  rootBox,
282  elI
283  )
284  )
285  {
286  used = true;
287  elementsInSubCubes[scI].append(elI);
288  }
289 
290  if( !used )
291  {
292  Warning << "Triangle " << elI
293  << " is not transferred to the child cubes!" << endl;
294  }
295  }
296 
297  forAll(elementsInSubCubes, scI)
298  {
299  const DynList<label, 512>& elmts = elementsInSubCubes[scI];
300 
301  if( elmts.size() != 0 )
302  {
303  VRWGraph& ct = slotPtr->containedTriangles_;
304  subCubes[scI]->containedElementsLabel_ = ct.size();
305  ct.appendList(elmts);
306 
307 
308  # ifdef DEBUGSearch
309  Info << "Elements in leaf " << scI << " are "
310  << ct[subCubes[scI]->containedElements()]
311  << endl;
312  # endif
313  }
314  }
315 
316  //- find surface edges within the cube
317  for(label scI=0;scI<8;++scI)
318  if( subCubes[scI]->hasContainedElements() )
319  {
320  subCubes[scI]->findContainedEdges
321  (
322  surface,
323  rootBox
324  );
325  }
326  else if( subCubes[scI]->cubeType() & DATA )
327  {
328  subCubes[scI]->setCubeType(UNKNOWN);
329  }
330  }
331 
332  # ifdef DEBUGSearch
333  for(label scI=0;scI<8;++scI)
334  Info << "Refined cube " << scI << " is "
335  << *subCubes[scI] << endl;
336  # endif
337 }
338 
340 (
341  const triSurf& ts,
342  const boundBox& rootBox,
343  const label scI,
344  meshOctreeSlot* slotPtr
345 )
346 {
347  if( !slotPtr )
348  slotPtr = activeSlotPtr_;
349 
350  if( !subCubesPtr_ )
351  {
353  forAll(sCubes, i)
354  sCubes[i] = NULL;
355 
356  const label subCubesLabel = slotPtr->childCubes_.size();
357 
358  slotPtr->childCubes_.appendFixedList(sCubes);
359  subCubesPtr_ = &slotPtr->childCubes_(subCubesLabel, 0);
360  }
361 
362  //- set the cube label to -1
363  cubeLabel_ = -1;
364 
365  //- refine the cube for the selected position
366  const label cubeI = slotPtr->cubes_.size();
367  slotPtr->cubes_.append(meshOctreeCube(this->refineForPosition(scI)));
368  subCubesPtr_[scI] = &slotPtr->cubes_[cubeI];
369 
370  subCubesPtr_[scI]->activeSlotPtr_ = slotPtr;
371  subCubesPtr_[scI]->setCubeType(this->cubeType());
372  subCubesPtr_[scI]->setProcNo(this->procNo());
373 
374  if( hasContainedElements() )
375  {
376  const VRWGraph& containedElements =
377  activeSlotPtr_->containedTriangles_;
379 
380  forAllRow(containedElements, containedElementsLabel_, tI)
381  {
382  const label elI = containedElements(containedElementsLabel_, tI);
383  if(
384  subCubesPtr_[scI]->intersectsTriangleExact
385  (
386  ts,
387  rootBox,
388  elI
389  )
390  )
391  {
392  ce.append(elI);
393  }
394  }
395 
396  if( ce.size() != 0 )
397  {
398  subCubesPtr_[scI]->containedElementsLabel_ =
399  slotPtr->containedTriangles_.size();
400  slotPtr->containedTriangles_.appendList(ce);
401 
402  subCubesPtr_[scI]->findContainedEdges
403  (
404  ts,
405  rootBox
406  );
407  }
408  }
409 }
410 
412 (
413  const label scI,
414  const label elementsRowI,
415  const label edgesRowI,
416  meshOctreeSlot* slotPtr
417 )
418 {
419  if( !slotPtr )
420  slotPtr = activeSlotPtr_;
421 
422  if( subCubesPtr_ )
423  {
425  forAll(sCubes, i)
426  sCubes[i] = NULL;
427 
428  const label subCubesLabel = slotPtr->childCubes_.size();
429  slotPtr->childCubes_.appendFixedList(sCubes);
430  subCubesPtr_ = &slotPtr->childCubes_(subCubesLabel, 0);
431  }
432 
433  //- set the cube label to -1
434  cubeLabel_ = -1;
435 
436  //- refine the cube for the selected position
437  const label cubeI = slotPtr->cubes_.size();
438  slotPtr->cubes_.append(meshOctreeCube(this->refineForPosition(scI)));
439  subCubesPtr_[scI] = &slotPtr->cubes_[cubeI];
440 
441  subCubesPtr_[scI]->activeSlotPtr_ = slotPtr;
442  subCubesPtr_[scI]->setCubeType(this->cubeType());
443  subCubesPtr_[scI]->setProcNo(this->procNo());
444 
445  //- set the contained elements and edges
446  subCubesPtr_[scI]->containedElementsLabel_ = elementsRowI;
447  subCubesPtr_[scI]->containedEdgesLabel_ = edgesRowI;
448 }
449 
450 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
451 
452 } // End namespace Foam
453 
454 // ************************************************************************* //
triSurf.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::meshOctreeCubeCoordinates
Definition: meshOctreeCubeCoordinates.H:55
Foam::meshOctreeCube::refineCube
void refineCube(const triSurf &, const boundBox &, meshOctreeSlot *slotPtr=NULL)
subdivide the octree cube
Definition: meshOctreeCubeRefine.C:223
VRWGraph.H
Foam::Warning
messageStream Warning
meshOctreeCube.H
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::meshOctreeSlot::cubes_
LongList< meshOctreeCube > cubes_
List of octree cubes.
Definition: meshOctreeSlot.H:56
Foam::HashSet< label, Hash< label > >
Foam::meshOctreeSlot::childCubes_
FRWGraph< meshOctreeCube *, 8 > childCubes_
Pointers to child cubes.
Definition: meshOctreeSlot.H:59
Foam::meshOctreeSlot
Definition: meshOctreeSlot.H:50
Foam::edge::end
label end() const
Return end vertex label.
Definition: edgeI.H:92
Foam::LongList< edge >
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::Info
messageStream Info
Foam::VRWGraph::size
label size() const
Returns the number of rows.
Definition: VRWGraphI.H:122
Foam::meshOctreeCube::findContainedEdges
void findContainedEdges(const triSurf &, const boundBox &)
find edges contained in the cube
Definition: meshOctreeCubeRefine.C:46
forAllRow
#define forAllRow(graph, rowI, index)
Definition: VRWGraph.H:277
Foam::meshOctreeCube::refineMissingCube
void refineMissingCube(const triSurf &, const boundBox &, const label scI, meshOctreeSlot *slotPtr=NULL)
Definition: meshOctreeCubeRefine.C:340
Foam::VRWGraph::sizeOfRow
label sizeOfRow(const label rowI) const
Returns the number of elements in the given row.
Definition: VRWGraphI.H:127
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
s
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::DynList< label >
Foam::meshOctreeSlot::containedTriangles_
VRWGraph containedTriangles_
surface triangles contained in an octree cube
Definition: meshOctreeSlot.H:62
Foam::edge::start
label start() const
Return start vertex label.
Definition: edgeI.H:81
Foam::VRWGraph::appendList
void appendList(const ListType &l)
Append a list as a row at the end of the graph.
Definition: VRWGraphI.H:286
Foam::Vector< scalar >
Foam::FixedList
A 1D vector of objects of type <T> with a fixed size <Size>.
Definition: FixedList.H:53
Foam::meshOctreeCube
Definition: meshOctreeCube.H:56
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::surface
Definition: surface.H:55
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Foam::boundBox
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:55
Foam::meshOctreeCube::refineCube2D
void refineCube2D(const triSurf &, const boundBox &, meshOctreeSlot *slotPtr=NULL)
refine cube in two directions, it is used for generating quadtrees
Definition: meshOctreeCubeRefine.C:102
Foam::DynList::size
label size() const
Definition: DynListI.H:235
Foam::VRWGraph
Definition: VRWGraph.H:101
Foam::triSurf
Definition: triSurf.H:59
Foam::DynList::append
void append(const T &e)
Append an element at the end of the list.
Definition: DynListI.H:304