ug4
face_util_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__LIB_GRID__FACE_UTIL_IMPL__
34 #define __H__LIB_GRID__FACE_UTIL_IMPL__
35 
36 #include "face_util.h"
37 
38 namespace ug
39 {
40 
42 template <class TIterator>
43 number AreaFaceQuality(TIterator facesBegin, TIterator facesEnd,
45 {
46 // if the area is empty return 0 (bad)
47  if(facesBegin == facesEnd)
48  return 0;
49 
50 // get the first
51  number q = FaceQuality(*facesBegin, aaPos);
52  ++facesBegin;
53 
54 // iterate over the others and find a worse one
55  for(; facesBegin != facesEnd; ++facesBegin){
56  number tq = FaceQuality(*facesBegin, aaPos);
57  if(tq < q)
58  q = tq;
59  }
60 
61 // return the quality
62  return q;
63 }
64 
66 inline void Triangulate(Grid& grid,
68 {
69  Triangulate(grid, grid.begin<Quadrilateral>(),
70  grid.end<Quadrilateral>(), paaPos);
71 }
72 
73 
75 template<class TVertexPositionAttachmentAccessor>
76 typename TVertexPositionAttachmentAccessor::ValueType
77 CalculateCenter(const FaceVertices* f, TVertexPositionAttachmentAccessor& aaPosVRT)
78 {
79  const size_t numVrts = f->num_vertices();
80  typename TVertexPositionAttachmentAccessor::ValueType v;
81 // init v with 0.
82  VecSet(v, 0);
83 
85 
86 // sum up
87  for(size_t i = 0; i < numVrts; ++i)
88  {
89  VecAdd(v, v, aaPosVRT[vrts[i]]);
90  }
91 
92 // average
93  if(numVrts > 0)
94  VecScale(v, v, 1./(number)numVrts);
95 
96  return v;
97 }
98 
99 
101 template<class TAAPosVRT, class TAAWeightVRT>
102 UG_API
103 typename TAAPosVRT::ValueType
104 CalculateCenter(const FaceVertices* f, TAAPosVRT& aaPos, TAAWeightVRT& aaWeight)
105 {
106  uint numVrts = f->num_vertices();
107  typename TAAPosVRT::ValueType v;
108  typedef typename TAAWeightVRT::ValueType weight_t;
109 // init v with 0.
110  VecSet(v, 0);
111 
113 
114 // sum up
115  weight_t totalWeight = 0;
116  for(uint i = 0; i < numVrts; ++i)
117  {
118  weight_t w = aaWeight[vrts[i]];
119  VecScaleAppend(v, w, aaPos[vrts[i]]);
120  totalWeight += w;
121  }
122 
123 // average
124  if(totalWeight != 0)
125  VecScale(v, v, 1./(number)totalWeight);
126 
127  return v;
128 }
129 
131 template <class vector_t, class TAAPos>
132 bool
133 ContainsPoint(const FaceVertices* f, const vector_t& p, TAAPos aaPos)
134 {
135  switch(f->num_vertices()){
136  case 3: return PointIsInsideTriangle(p, aaPos[f->vertex(0)],
137  aaPos[f->vertex(1)],
138  aaPos[f->vertex(2)]);
139  case 4: return PointIsInsideQuadrilateral(p, aaPos[f->vertex(0)],
140  aaPos[f->vertex(1)],
141  aaPos[f->vertex(2)],
142  aaPos[f->vertex(3)]);
143  default:
144  UG_THROW("Unknown face type with " << f->num_vertices()
145  << " vertices encountered in ContainsPoint(...).");
146  }
147  return false;
148 }
149 
151 // project points to surface
152 template <class TTriangleIterator, class TAAPosVRT>
153 bool ProjectPointToSurface(vector3& vOut, const vector3& v, const vector3& n,
154  TTriangleIterator trisBegin, TTriangleIterator trisEnd,
155  TAAPosVRT& aaPos, bool compareNormals)
156 {
157  bool gotOne = false;
158  number bestDist = 0; // value doesn't matter - will be overwritten later on.
159 
160 // iterate through all triangles and find the closest intersection
161  for(TTriangleIterator iter = trisBegin; iter != trisEnd; ++iter)
162  {
163  Triangle* tri = *iter;
164 
165  const vector3& p1 = aaPos[tri->vertex(0)];
166  const vector3& p2 = aaPos[tri->vertex(1)];
167  const vector3& p3 = aaPos[tri->vertex(2)];
168 
169  vector3 tn;
170  CalculateTriangleNormalNoNormalize(tn, p1, p2, p3);
171 
172  // if normal-check is enabled, we have to make sure, that the points
173  // normal points into the same direction as the triangles normal.
174  if(compareNormals){
175  if(VecDot(tn, n) <= 0)
176  continue;
177  }
178 
179  number bc1, bc2;
180  vector3 vTmp;
181  number distance = DistancePointToTriangle(vTmp, bc1, bc2,
182  v, p1, p2, p3, tn);
183 
184  if(gotOne){
185  if(distance < bestDist){
186  bestDist = distance;
187  vOut = vTmp;
188  }
189  }
190  else{
191  gotOne = true;
192  vOut = vTmp;
193  bestDist = distance;
194  }
195  }
196 
197  return gotOne;
198 }
199 
200 template <class TAAPosVRT>
201 int PointFaceTest(vector3& v, Face* f, TAAPosVRT& aaPos)
202 {
203  vector3 n;
204  vector3 dir;
205 
206  CalculateNormal(n, f, aaPos);
207  VecSubtract(dir, v, aaPos[f->vertex(0)]);
208 
209  number d = VecDot(dir, n);
210  if(d > 0)
211  return 1;
212  if(d < 0)
213  return -1;
214  return 0;
215 }
216 
217 template <class TAAPosVRT>
218 bool IsDegenerated(Face* f, TAAPosVRT& aaPos, number threshold)
219 {
220  number threshSQ = threshold * threshold;
221  size_t numVrts = f->num_vertices();
222 
223  for(size_t i = 0; i < numVrts; ++i){
224  if(VecDistanceSq(aaPos[f->vertex(i)], aaPos[f->vertex((i+1) % numVrts)])
225  < threshSQ)
226  {
227  return true;
228  }
229  }
230  return false;
231 }
232 
234 template <class TAAPosVRT>
235 number FaceArea(FaceVertices* f, TAAPosVRT& aaPos)
236 {
237  number area = 0;
238  for(size_t i = 2; i < f->num_vertices(); ++i){
239  area += TriangleArea(aaPos[f->vertex(0)],
240  aaPos[f->vertex(i - 1)],
241  aaPos[f->vertex(i)]);
242  }
243  return area;
244 }
245 
247 template <class TIterator, class TAAPosVRT>
248 number FaceArea(TIterator facesBegin, TIterator facesEnd, TAAPosVRT& aaPos)
249 {
250  number sum = 0.;
251 
252  for (; facesBegin != facesEnd; ++facesBegin)
253  sum += FaceArea(*facesBegin, aaPos);
254 
255  return sum;
256 }
257 
259 template <class TIterator, class TAAPosVRT>
260 Face* FindSmallestFace(TIterator facesBegin, TIterator facesEnd, TAAPosVRT& aaPos)
261 {
262  // if facesBegin equals facesEnd, then the list is empty and we can
263  // immediately return NULL
264  if(facesBegin == facesEnd)
265  return NULL;
266 
267  // the first face is the first candidate for the smallest face.
268  Face* smallestFace = *facesBegin;
269  number smallestArea = FaceArea(smallestFace, aaPos);
270  ++facesBegin;
271 
272  for(; facesBegin != facesEnd; ++facesBegin){
273  Face* curFace = *facesBegin;
274  number curArea = FaceArea(curFace, aaPos);
275  if(curArea < smallestArea){
276  smallestFace = curFace;
277  smallestArea = curArea;
278  }
279  }
280 
281  return smallestFace;
282 }
283 
284 
285 }// end of namespace
286 
287 #endif
parameterString p
virtual Vertex * vertex(size_t index) const
Definition: grid_objects_2d.h:120
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
Definition: grid_base_objects.h:483
virtual ConstVertexArray vertices() const
Definition: grid_base_objects.h:487
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
geometry_traits< TGeomObj >::iterator begin()
Definition: grid_impl.hpp:164
geometry_traits< TGeomObj >::iterator end()
Definition: grid_impl.hpp:175
Vertex *const * ConstVertexArray
Definition: grid_base_objects.h:319
a face with four points.
Definition: grid_objects_2d.h:323
the most simple form of a face
Definition: grid_objects_2d.h:174
static number FaceArea(TDomain &dom, ISubsetHandler &sh, int si, size_t lvl)
Definition: domain_bridge.cpp:262
int CalculateNormal(vector3 &vNormOut, Grid &grid, Edge *e, Grid::AttachmentAccessor< Vertex, APosition > &aaPos, Grid::AttachmentAccessor< Face, ANormal > *paaNormFACE)
Calculates the normal of the given edge.
Definition: edge_util.cpp:314
UG_API bool ContainsPoint(const EdgeVertices *e, const vector_t &p, TAAPos aaPos)
Returns true if the given point lies on the given edge.
Definition: edge_util_impl.hpp:513
UG_API bool IsDegenerated(Face *f, TAAPosVRT &aaPos, number threshold=SMALL)
returns true if the given face is degenerated.
Definition: face_util_impl.hpp:218
number FaceQuality(FaceVertices *f, Grid::VertexAttachmentAccessor< APosition > aaPos)
a simple measure for the quality of a face
Definition: face_util.cpp:203
UG_API number AreaFaceQuality(TIterator facesBegin, TIterator facesEnd, Grid::VertexAttachmentAccessor< APosition > &aaPos)
returns a value between 0 (bad) and 1 (good) that describes the quality of the area.
Definition: face_util_impl.hpp:43
UG_API int PointFaceTest(vector3 &v, Face *f, TAAPosVRT &aaPos)
Definition: face_util_impl.hpp:201
UG_API bool ProjectPointToSurface(vector3 &vOut, const vector3 &v, const vector3 &n, TTriangleIterator trisBegin, TTriangleIterator trisEnd, TAAPosVRT &aaPos, bool compareNormals=false)
Definition: face_util_impl.hpp:153
void Triangulate(Grid &grid, Quadrilateral *q, Grid::VertexAttachmentAccessor< APosition > *paaPos)
removes the quadrilateral and replaces it by two triangles.
Definition: face_util.cpp:273
UG_API Face * FindSmallestFace(TIterator facesBegin, TIterator facesEnd, TAAPosVRT &aaPos)
Returns the face with the smallest area.
Definition: face_util_impl.hpp:260
#define UG_THROW(msg)
Definition: error.h:57
#define UG_API
Definition: ug_config.h:65
unsigned int uint
Definition: types.h:114
double number
Definition: types.h:124
number TriangleArea(const vector_t &p1, const vector_t &p2, const vector_t &p3)
calculates the are of the triangle defined by p1, p2 and p3
Definition: math_util_impl.hpp:914
bool PointIsInsideQuadrilateral(const vector_t &v, const vector_t &v0, const vector_t &v1, const vector_t &v2, const vector_t &v3)
Returns true if the point lies inside or on the boundary of a quadrilateral.
Definition: math_util_impl.hpp:1040
bool PointIsInsideTriangle(const vector_t &v, const vector_t &v0, const vector_t &v1, const vector_t &v2)
Returns true if the point lies inside or on the boundary of a triangle.
Definition: math_util_impl.hpp:971
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
number DistancePointToTriangle(vector_t &vOut, number &bc1Out, number &bc2Out, const vector_t &p, const vector_t &v1, const vector_t &v2, const vector_t &v3, const vector_t &n)
calculates the minimal distance of a point to a triangle.
Definition: math_util_impl.hpp:243
void VecScaleAppend(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1)
Scales a Vector and adds it to a second vector.
Definition: math_vector_functions_common_impl.hpp:126
void VecSet(vector_t &vInOut, typename vector_t::value_type s)
Set each vector component to scalar (componentwise)
Definition: math_vector_functions_common_impl.hpp:539
void CalculateTriangleNormalNoNormalize(vector_t &vOut, const vector_t &v1, const vector_t &v2, const vector_t &v3)
Calculates a triangle-normal in 3d (no normalization is performed).
Definition: math_vector_functions_common_impl.hpp:514
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition: math_vector_functions_common_impl.hpp:226
vector_t::value_type VecDistanceSq(const vector_t &v1, const vector_t &v2)
returns the squared distance of two vector_ts.
Definition: math_vector_functions_common_impl.hpp:351
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
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
scales a MathVector<N>
Definition: math_vector_functions_common_impl.hpp:252
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
returns the dot-product of two vector_ts
Definition: math_vector_functions_common_impl.hpp:385
the ug namespace