ug4
simple_grid_impl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3  * Author: Sebastian Reiter
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__REMESHING__SIMPLE_GRID_IMPL__
34 #define __H__REMESHING__SIMPLE_GRID_IMPL__
35 
36 #include <queue>
39 
40 namespace ug
41 {
43 // ObtainSimpleGrid
44 template <class TPosAcc, class TIntAcc, class TNormAcc>
45 bool ObtainSimpleGrid(SimpleGrid& sgOut, Grid& grid,
46  Vertex* vrt1, Vertex* vrt2, size_t size,
47  TPosAcc& aaPos, TNormAcc& aaNorm,
48  TIntAcc& aaInt)
49 {
50 // vVrts will be reused in each call. To avoid unnecessary allocations,
51 // we'll reuse this vector.
52  static std::vector<Vertex*> vVrts;
53  vVrts.clear();
54 
55 // clear the simple-grid
56  sgOut.clear();
57 
58 // collect vertices and triangles
59  grid.begin_marking();
60 
61 // mark the first two vertices and add them to simple-grid
62  grid.mark(vrt1);
63  grid.mark(vrt2);
64  vVrts.push_back(vrt1);
65  vVrts.push_back(vrt2);
66  aaInt[vrt1] = 0;
67  aaInt[vrt2] = 1;
68 
69 // this counter holds the next vertex for which we have to search for
70 // associated triangles
71  size_t nextVrt = 0;
72 // this number holds the first index that is not checked for neighbours.
73  size_t vrtsEnd = 2;
74 
75 // find the triangles that are adjacent to the edge between vrt1 and vrt2
76 // at this point we assume that all associated faces are triangles.
77 // If they are not they are simply treated as if they were some.
80  iter != iterEnd; ++iter)
81  {
82  Vertex* vUnmarked = NULL;
83  Face* f = *iter;
84  int counter = 0;
85 
86  for(uint j = 0; j < 3; ++j){
87  if(grid.is_marked(f->vertex(j)))
88  ++counter;
89  else
90  vUnmarked = f->vertex(j);
91  }
92 
93  if(counter > 1){
94  // we found an adjacent triangle. vUnmarked contains the connected vertex
95  if(!vUnmarked) goto bail_out;
96  // push the connected vertex to vVrts and assign the index
97  aaInt[vUnmarked] = vVrts.size();
98  vVrts.push_back(vUnmarked);
99  // add the triangle
100  sgOut.triangles.push_back(aaInt[f->vertex(0)]);
101  sgOut.triangles.push_back(aaInt[f->vertex(1)]);
102  sgOut.triangles.push_back(aaInt[f->vertex(2)]);
103  // mark the face
104  grid.mark(f);
105  }
106  }
107 
108 // mark the vertices in vVrts that are not yet marked
109  for(size_t i = nextVrt; i < vVrts.size(); ++i)
110  grid.mark(vVrts[i]);
111 
112 // collect all faces in the neighbourhood
113  for(size_t i = 0; i < size; ++i)
114  {
115  for(; nextVrt < vrtsEnd; ++nextVrt)
116  {
117  Vertex* vrt = vVrts[nextVrt];
118  // colelct neighbour faces
121  iter != iterEnd; ++iter)
122  {
123  Face* f = *iter;
124  // if f is unmarked
125  if(!grid.is_marked(f)){
126  // add unmarked vertices to vVrts
127  for(uint j = 0; j < 3; ++j){
128  if(!grid.is_marked(f->vertex(j))){
129  aaInt[f->vertex(j)] = vVrts.size();
130  grid.mark(f->vertex(j));
131  vVrts.push_back(f->vertex(j));
132  }
133  }
134 
135  // add the triangle
136  grid.mark(f);
137  sgOut.triangles.push_back(aaInt[f->vertex(0)]);
138  sgOut.triangles.push_back(aaInt[f->vertex(1)]);
139  sgOut.triangles.push_back(aaInt[f->vertex(2)]);
140  }
141  }
142  }
143  // in the next iteration we'll check all vertices up to this point
144  vrtsEnd = vVrts.size();
145  }
146 
147 // copy the vertex-positions and the normals to the grid
148  for(size_t i = 0; i < vVrts.size(); ++i)
149  {
150  sgOut.vertices.push_back(aaPos[vVrts[i]]);
151  sgOut.vertexNormals.push_back(aaNorm[vVrts[i]]);
152  }
153 
154 // calculate triangle normals
156 
157  grid.end_marking();
158  return true;
159 
160 bail_out:
161  grid.end_marking();
162  return false;
163 }
164 
166 // ObtainSimpleGrid
167 template <class TPosAcc, class TIntAcc, class TNormAcc>
169  Edge* e, size_t size,
170  TPosAcc& aaPos, TNormAcc& aaNorm,
171  TIntAcc& aaInt)
172 {
173 // clear the simple-grid
174  sgOut.clear();
175 
176 // collect triangles in the neighbourhood of e.
177 // Note that faces may (and most likely will) contain some faces twice
178  std::vector<Face*> faces;
179  CollectNeighborhood(faces, grid, e->vertex(0), size, false);
180  CollectNeighborhood(faces, grid, e->vertex(1), size, false);
181 
182 // the first vertex resembles the collapsed edge
183  typename TPosAcc::ValueType n;
184  VecAdd(n, aaNorm[e->vertex(0)], aaNorm[e->vertex(1)]);
185  VecNormalize(n, n);
186  sgOut.vertices.push_back(CalculateCenter(e, aaPos));
187  sgOut.vertexNormals.push_back(n);
188 
189 // now iterate over all associated triangles in the neighbourhood
190 // of e and create associated triangles in sgOut.
191  grid.begin_marking();
192  for(size_t i_face = 0; i_face < faces.size(); ++i_face){
193  Face* f = faces[i_face];
194  // make sure that the face is a triangle
195  if(f->num_vertices() != 3){
196  grid.end_marking();
197  return false;
198  }
199 
200  // avoid multiple insertion of the same face
201  if(!grid.is_marked(f)){
202  grid.mark(f);
203 
204  // get vertex indices
205  // make sure that the triangles adjacent to e will
206  // not be added to the grid
207  int ind[3];
208  int edgeVrts = 0;// increase for each vertex that lies on e
209 
210  for(size_t i = 0; i < 3; ++i){
211  Vertex* v = f->vertex(i);
212  if((v == e->vertex(0)) || (v == e->vertex(1))){
213  ind[i] = 0;
214  edgeVrts++;
215  }
216  else{
217  // get the index of v in sgOut.vertices.
218  // If it hasn't got one, create one.
219  if(!grid.is_marked(v)){
220  // NOTE that we add the position even though it is not clear
221  // whether the triangle will be created at all.
222  sgOut.vertices.push_back(aaPos[v]);
223  sgOut.vertexNormals.push_back(aaNorm[v]);
224  aaInt[v] = (int)sgOut.vertices.size() - 1;
225  grid.mark(v);
226  }
227  ind[i] = aaInt[v];
228  }
229  }
230 
231  // add the triangle
232  if(edgeVrts < 2){
233  sgOut.triangles.push_back(ind[0]);
234  sgOut.triangles.push_back(ind[1]);
235  sgOut.triangles.push_back(ind[2]);
236  }
237  }
238  }
239 
240  grid.end_marking();
241 
242 // calculate triangle normals
244 
245  return true;
246 }
247 
248 }// end of namespace
249 
250 #endif
Base-class for edges.
Definition: grid_base_objects.h:397
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:366
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
size_t size() const
returns the number of vertices.
Definition: grid_base_objects.h:492
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:486
virtual size_t num_vertices() const
Definition: grid_base_objects.h:488
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
void end_marking()
ends a marking sequence. Call this method when you're done with marking.
Definition: grid.cpp:1285
AssociatedFaceIterator associated_faces_begin(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:944
bool is_marked(GridObject *obj) const
returns true if the object is marked, false if not.
Definition: grid_impl.hpp:843
void mark(GridObject *obj)
marks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
Definition: grid_impl.hpp:773
void begin_marking()
begin marking.
Definition: grid.cpp:1262
AssociatedFaceIterator associated_faces_end(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:954
FaceContainer::iterator AssociatedFaceIterator
used to iterate over associated faces of vertices, edges and volumes
Definition: grid.h:251
Definition: simple_grid.h:45
std::vector< vector3 > vertices
Definition: simple_grid.h:48
std::vector< int > triangles
Definition: simple_grid.h:50
std::vector< vector3 > vertexNormals
Definition: simple_grid.h:49
void clear()
Definition: simple_grid.cpp:42
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
void CollectNeighborhood(std::vector< Face * > &facesOut, Grid &grid, Vertex *vrt, size_t range, bool clearContainer)
Collects all neighbors in a given neighborhood of a vertex.
Definition: neighborhood.cpp:415
unsigned int uint
Definition: types.h:114
void CalculateCenter(vector_t &centerOut, const vector_t *pointSet, size_t numPoints)
calculates the center of a point-set
Definition: math_util_impl.hpp:98
void VecNormalize(vector_t &vOut, const vector_t &v)
scales a vector_t to unit length
Definition: math_vector_functions_common_impl.hpp:501
void VecAdd(vector_t &vOut, const vector_t &v1, const vector_t &v2)
adds two MathVector<N>s and stores the result in a third one
Definition: math_vector_functions_common_impl.hpp:185
the ug namespace
void CalculateTriangleNormals(SimpleGrid &sg)
resizes sg.triangleNormals and calculates them
Definition: simple_grid.cpp:90
bool ObtainSimpleGrid_CollapseEdge(SimpleGrid &sgOut, Grid &grid, Edge *e, size_t size, TPosAcc &aaPos, TNormAcc &aaNorm, TIntAcc &aaInt)
returns a neighbourhood of the edge e after e has been collapsed.
Definition: simple_grid_impl.hpp:168
bool ObtainSimpleGrid(SimpleGrid &sgOut, Grid &grid, Vertex *vrt1, Vertex *vrt2, size_t size, TPosAcc &aaPos, TNormAcc &aaNorm, TIntAcc &aaInt)
returns a neighbourhood of the edge defined by vrt1 and vrt2 in a SimpleGrid.
Definition: simple_grid_impl.hpp:45