ug4
manifold_smoothing.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-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__UG__manifold_smoothing__
34 #define __H__UG__manifold_smoothing__
35 
36 #include "common/types.h"
38 #include "../volume_calculation.h"
39 
40 namespace ug{
41 
43 template <class TIterator, class AAPosVRT>
44 void LaplacianSmooth(Grid& grid, TIterator vrtsBegin,
45  TIterator vrtsEnd, AAPosVRT& aaPos,
46  number alpha, int numIterations)
47 {
51 
52  bool gotFaces = grid.num<Face>() > 0;
53  bool gotVols = grid.num<Volume>() > 0;
54 
55  for(int iteration = 0; iteration < numIterations; ++iteration){
56  // iterate through all vertices
57  for(TIterator iter = vrtsBegin; iter != vrtsEnd; ++iter){
58  // smooth each one
59  Vertex* vrt = *iter;
60  vector3 v;
61  VecSet(v, 0);
62  number weight = 0;
63 
64  // calculate smoothing vector relative to neighbors
65  grid.associated_elements(edges, vrt);
66  for(size_t i = 0; i < edges.size(); ++i){
67  // number w = EdgeLength(edges[i], aaPos);
68  number w = 1;
69  VecScaleAdd(v, 1, v, w, aaPos[GetConnectedVertex(edges[i], vrt)]);
70  weight += w;
71  }
72 
73  if(gotFaces){
74  grid.associated_elements(faces, vrt);
75  for(size_t i = 0; i < faces.size(); ++i){
76  Face* f = faces[i];
77  // number a = CalculateVolume(f, aaPos);
78  number a = 1;
79  VecScaleAdd(v, 1, v, a,
81  grid.get_opposing_object(vrt, f),
82  aaPos));
83 
84  weight += a;
85  }
86  }
87 
88  if(gotVols){
89  grid.associated_elements(vols, vrt);
90  for(size_t i = 0; i < vols.size(); ++i){
91  Volume* vol = vols[i];
92  // number a = CalculateVolume(vol, aaPos);
93  number a = 1;
94  VecScaleAdd(v, 1, v, a,
96  grid.get_opposing_object(vrt, vol),
97  aaPos));
98 
99  weight += a;
100  }
101  }
102 
103  if(weight > 0){
104  VecScale(v, v, 1. / weight);
105  VecSubtract(v, v, aaPos[vrt]);
106  VecScale(v, v, alpha);
107  VecAdd(aaPos[vrt], aaPos[vrt], v);
108  }
109  }
110  }
111 }
112 
115 
116 template <class TVrtIter, class TAAPos3>
117 void TangentialSmoothSimple(Grid& g, TVrtIter vrtsBegin, TVrtIter vrtsEnd,
118  TAAPos3 aaPos, number alpha, size_t numIterations)
119 {
121  for(size_t iteration = 0; iteration < numIterations; ++iteration){
122  for(TVrtIter iter = vrtsBegin; iter != vrtsEnd; ++iter){
123  Vertex* vrt = *iter;
124  g.associated_elements(faces, vrt);
125  if(faces.empty())
126  continue;
127 
128  // calculate the normal at the current vertex
129  vector3 n(0, 0, 0);
130  for(size_t i = 0; i < faces.size(); ++i){
131  vector3 tn;
132  CalculateNormal(tn, faces[i], aaPos);
133  VecAdd(n, n, tn);
134  }
135 
136  // calculate the center of connected vertices
137  vector3 c(0, 0, 0);
138  size_t numConnected = 0;
139  g.begin_marking();
140  for(size_t i_face = 0; i_face < faces.size(); ++i_face){
141  Face::ConstVertexArray vrts = faces[i_face]->vertices();
142  const size_t numVrts = faces[i_face]->num_vertices();
143  for(size_t i_vrt = 0; i_vrt < numVrts; ++i_vrt){
144  Vertex* v = vrts[i_vrt];
145  if((v != vrt) && (!g.is_marked(v))){
146  g.mark(v);
147  VecAdd(c, c, aaPos[v]);
148  ++numConnected;
149  }
150  }
151  }
152  g.end_marking();
153  if(numConnected == 0)
154  continue;
155 
156  VecScale(c, c, 1. / (number)numConnected);
157 
158  // project the center of connected vertices to the plane through vrt
159  vector3 cp;
160  ProjectPointToPlane(cp, c, aaPos[vrt], n);
161 
162  // move the vertex
163  VecScaleAdd(aaPos[vrt], (1. - alpha), aaPos[vrt], alpha, cp);
164  }
165  }
166 }
167 
170 
174 template <class TVrtIter, class TAAPos3>
175 void TangentialSmooth(Grid& g, TVrtIter vrtsBegin, TVrtIter vrtsEnd,
176  TAAPos3 aaPos, number alpha, size_t numIterations)
177 {
178 // attach an integer index to all vertices
179  AInt aInt;
180  g.attach_to_vertices_dv(aInt, -1);
182 
183  int counter = 0;
184  std::vector<vector3*> vrtPos;
185  for(TVrtIter iter = vrtsBegin; iter != vrtsEnd; ++iter){
186  aaInt[*iter] = counter++;
187  vrtPos.push_back(&aaPos[*iter]);
188  }
189 
190  std::vector<int> adjVrtInds;
191  std::vector<int> adjVrtOffsets;
192  std::vector<Face*> adjFaces;
193  std::vector<int> adjFaceOffsets;
194 
195  adjVrtInds.reserve(counter * 7);//just a guess
196  adjVrtOffsets.reserve(counter + 1);
197  vrtPos.reserve(counter);
198  adjFaces.reserve(counter * 7);//just a guess
199  adjFaceOffsets.reserve(counter + 1);
200 
201 // build adjacency graph
203  for(TVrtIter iter = vrtsBegin; iter != vrtsEnd; ++iter){
204  Vertex* vrt = *iter;
205  adjVrtOffsets.push_back(adjVrtInds.size());
206  adjFaceOffsets.push_back(adjFaces.size());
207 
208  g.associated_elements(faces, vrt);
209  if(faces.empty())
210  continue;
211 
212  // create adjacencies
213  g.begin_marking();
214  for(size_t i_face = 0; i_face < faces.size(); ++i_face){
215  adjFaces.push_back(faces[i_face]);
216  Face::ConstVertexArray vrts = faces[i_face]->vertices();
217  const size_t numVrts = faces[i_face]->num_vertices();
218  for(size_t i_vrt = 0; i_vrt < numVrts; ++i_vrt){
219  Vertex* v = vrts[i_vrt];
220  if((v != vrt) && (!g.is_marked(v))){
221  g.mark(v);
222  if(aaInt[v] == -1){
223  // positions of vertices which are not to be smoothed but which are
224  // adjacent to smoothed ones, are inserted on the fly.
225  aaInt[v] = (int)vrtPos.size();
226  vrtPos.push_back(&aaPos[v]);
227  }
228  adjVrtInds.push_back(aaInt[v]);
229  }
230  }
231  }
232  g.end_marking();
233  }
234 
235  adjVrtOffsets.push_back(adjVrtInds.size());
236  adjFaceOffsets.push_back(adjFaces.size());
237  g.detach_from_vertices(aInt);
238 
239  std::vector<vector3> offsets(vrtPos.size());
240  std::vector<vector3> newOffsets(vrtPos.size());
241 
242  for(size_t iteration = 0; iteration < numIterations; ++iteration){
243  // calculate the initial offset vectors for each vertex
244  for(size_t i_vrt = 0; i_vrt + 1 < adjVrtOffsets.size(); ++i_vrt){
245  // calculate plane normal
246  int adjFacesBegin = adjFaceOffsets[i_vrt];
247  int adjFacesEnd = adjFaceOffsets[i_vrt+1];
248 
249  if(adjFacesBegin == adjFacesEnd){
250  offsets[i_vrt] = vector3(0, 0, 0);
251  continue;
252  }
253 
254  vector3 n(0, 0, 0);
255  for(int i_adj = adjFacesBegin; i_adj < adjFacesEnd; ++i_adj){
256  vector3 tn;
257  CalculateNormal(tn, adjFaces[i_adj], aaPos);
258  VecAdd(n, n, tn);
259  }
260 
261  // calculate center of adjacent vertices
262  int adjVrtsBegin = adjVrtOffsets[i_vrt];
263  int adjVrtsEnd = adjVrtOffsets[i_vrt+1];
264 
265  if(adjVrtsBegin == adjVrtsEnd){
266  offsets[i_vrt] = vector3(0, 0, 0);
267  continue;
268  }
269 
270  vector3 c(0, 0, 0);
271  for(int i_adj = adjVrtsBegin; i_adj < adjVrtsEnd; ++i_adj){
272  int adjVrt = adjVrtInds[i_adj];
273  VecAdd(c, c, *vrtPos[adjVrt]);
274  }
275  VecScale(c, c, 1. / number(adjVrtsEnd - adjVrtsBegin));
276 
277  // project center to plane and calculate the offset
278  vector3 cp;
279  ProjectPointToPlane(cp, c, *vrtPos[i_vrt], n);
280  VecSubtract(offsets[i_vrt], cp, *vrtPos[i_vrt]);
281  }
282 
283  // now smooth the offset vectors by repeatedly taking the average of
284  // neighbored vectors
285  const size_t numOffsetSmoothSteps = 1;
286  for(size_t i_step = 0; i_step < numOffsetSmoothSteps; ++i_step){
287  for(size_t i_vrt = 0; i_vrt + 1 < adjVrtOffsets.size(); ++i_vrt){
288  int adjVrtsBegin = adjVrtOffsets[i_vrt];
289  int adjVrtsEnd = adjVrtOffsets[i_vrt+1];
290 
291  if(adjVrtsBegin == adjVrtsEnd)
292  continue;
293 
294  int numAdj = adjVrtsEnd - adjVrtsBegin;
295  //vector3 o = offsets[i_vrt];
296  vector3 o;
297  VecScale(o, offsets[i_vrt], numAdj);
298  for(int i_adj = adjVrtsBegin; i_adj < adjVrtsEnd; ++i_adj){
299  int adjVrt = adjVrtInds[i_adj];
300  VecAdd(o, o, offsets[adjVrt]);
301  }
302  VecScale(newOffsets[i_vrt], o, 1. / number(2 * numAdj));
303 
304  // restrict offset to plane
305  int adjFacesBegin = adjFaceOffsets[i_vrt];
306  int adjFacesEnd = adjFaceOffsets[i_vrt+1];
307 
308  if(adjFacesBegin == adjFacesEnd){
309  offsets[i_vrt] = vector3(0, 0, 0);
310  continue;
311  }
312 
313  vector3 n(0, 0, 0);
314  for(int i_adj = adjFacesBegin; i_adj < adjFacesEnd; ++i_adj){
315  vector3 tn;
316  CalculateNormal(tn, adjFaces[i_adj], aaPos);
317  VecAdd(n, n, tn);
318  }
319 
320  VecNormalize(n, n);
321  number dot = VecDot(n, newOffsets[i_vrt]);
322  VecScale(n, n, dot);
323  VecSubtract(newOffsets[i_vrt], newOffsets[i_vrt], n);
324  }
325  offsets.swap(newOffsets);
326  }
327 
328  // and now move the vertices by their smoothed offset vectors
329  for(size_t i_vrt = 0; i_vrt + 1 < adjVrtOffsets.size(); ++i_vrt){
330  VecScaleAdd(*vrtPos[i_vrt], 1, *vrtPos[i_vrt], alpha, offsets[i_vrt]);
331  }
332  }
333 }
334 
335 
337 
343 template <class TIterator, class AAPosVRT>
344 void WeightedEdgeSmooth(Grid& grid, TIterator vrtsBegin,
345  TIterator vrtsEnd, AAPosVRT& aaPos,
346  number alpha, int numIterations,
347  Grid::vertex_traits::callback cbSmoothVertex)
348 {
349  typedef typename AAPosVRT::ValueType vector_t;
350 
352 
353  for(int iteration = 0; iteration < numIterations; ++iteration){
354  // iterate through all vertices
355  for(TIterator iter = vrtsBegin; iter != vrtsEnd; ++iter){
356  // smooth each one
357  Vertex* vrt = *iter;
358  vector_t vrtPos = aaPos[vrt];
359  vector_t avDir;
360  VecSet(avDir, 0);
361  number weight = 0;
362 
363  // calculate smoothing vector relative to neighbors
364  grid.associated_elements(edges, vrt);
365  number numNonSmooth = 0;
366  for(size_t i = 0; i < edges.size(); ++i){
367  Vertex* connVrt = GetConnectedVertex(edges[i], vrt);
368  if(!cbSmoothVertex(connVrt))
369  numNonSmooth += 1;
370  }
371 
372  number nonSmoothWeight = 1. / std::max<number>(1, numNonSmooth);
373 
374  for(size_t i = 0; i < edges.size(); ++i){
375  Vertex* connVrt = GetConnectedVertex(edges[i], vrt);
376  number w = 1;
377  if(!cbSmoothVertex(connVrt))
378  w = nonSmoothWeight;
379 
380  vector_t dir;
381  VecSubtract(dir, aaPos[connVrt], vrtPos);
382  w *= VecLengthSq(dir);
383  dir *= w;
384  VecAdd(avDir, avDir, dir);
385  weight += w;
386  }
387 
388  if(weight > 0){
389  avDir *= alpha / weight;
390  VecAdd(aaPos[vrt], vrtPos, avDir);
391  }
392  }
393  }
394 }
395 
397 
403 template <class TIterator, class AAPosVRT>
404 void WeightedFaceSmooth(Grid& grid, TIterator vrtsBegin,
405  TIterator vrtsEnd, AAPosVRT& aaPos,
406  number alpha, int numIterations,
407  Grid::vertex_traits::callback cbSmoothVertex)
408 {
409  typedef typename AAPosVRT::ValueType vector_t;
410 
412 
413  for(int iteration = 0; iteration < numIterations; ++iteration){
414  // iterate through all vertices
415  for(TIterator iter = vrtsBegin; iter != vrtsEnd; ++iter){
416  // smooth each one
417  Vertex* vrt = *iter;
418  vector_t vrtPos = aaPos[vrt];
419  vector_t avDir;
420  VecSet(avDir, 0);
421  number weight = 0;
422 
423  // calculate smoothing vector relative to neighbors
424  grid.associated_elements(faces, vrt);
425 
426  for(size_t i = 0; i < faces.size(); ++i){
427  Face* f = faces[i];
428  if(f->num_vertices() != 3)
429  continue;
430 
431  number w = 1;
432  Edge* e = GetConnectedEdge(grid, vrt, f);
433  Vertex* v0 = e->vertex(0);
434  Vertex* v1 = e->vertex(1);
435  vector_t edgeCenter;
436  if(cbSmoothVertex(v0)){
437  if(cbSmoothVertex(v1))
438  VecScaleAdd(edgeCenter, 0.5, aaPos[v0], 0.5, aaPos[v1]);
439  else
440  VecScaleAdd(edgeCenter, 0.75, aaPos[v0], 0.25, aaPos[v1]);
441  }
442  else if(cbSmoothVertex(v1))
443  VecScaleAdd(edgeCenter, 0.25, aaPos[v0], 0.75, aaPos[v1]);
444  else{
445  VecScaleAdd(edgeCenter, 0.5, aaPos[v0], 0.5, aaPos[v1]);
446  w = 0.5;
447  }
448 
449  vector_t dir;
450  VecSubtract(dir, edgeCenter, vrtPos);
451  w *= CalculateVolume(f, aaPos);
452  dir *= w;
453  VecAdd(avDir, avDir, dir);
454  weight += w;
455  }
456 
457  if(weight > 0){
458  avDir *= alpha / weight;
459  VecAdd(aaPos[vrt], vrtPos, avDir);
460  }
461  }
462  }
463 }
464 
465 
467 
470 template <class TIterator, class AAPosVRT>
471 void WeightedNormalSmooth(Grid& grid, TIterator vrtsBegin,
472  TIterator vrtsEnd, AAPosVRT& aaPos,
473  number alpha, number dotThreshold,
474  int numIterations)
475 {
476  using std::min;
477  using std::max;
478 
479  typedef typename AAPosVRT::ValueType vector_t;
480 
482 
483  for(int iteration = 0; iteration < numIterations; ++iteration){
484  // iterate through all vertices
485  for(TIterator iter = vrtsBegin; iter != vrtsEnd; ++iter){
486  // smooth each one
487  Vertex* vrt = *iter;
488  vector_t vrtPos = aaPos[vrt];
489  vector_t vrtNorm;
490  CalculateVertexNormal(vrtNorm, grid, vrt, aaPos);
491 
492  vector_t avDir;
493  VecSet(avDir, 0);
494 
495  grid.associated_elements(edges, vrt);
496  number nbrs = 0;
497  for(size_t i = 0; i < edges.size(); ++i){
498  Vertex* connVrt = GetConnectedVertex(edges[i], vrt);
499  vector_t dir = aaPos[connVrt];
500  dir -= vrtPos;
501  vector_t ndir;
502  VecNormalize(ndir, dir);
503  number dot = VecDot(vrtNorm, ndir);
504  if(dot >= dotThreshold){
505  dir *= 0.5 * (dot + 1);
506  avDir += dir;
507  ++nbrs;
508  }
509  }
510 
511  if(nbrs > 0){
512  avDir *= alpha / nbrs;
513  aaPos[vrt] += avDir;
514  }
515  }
516  }
517 }
518 
519 
521 
522 template <class TIterator, class AAPosVRT>
523 void SlopeSmooth(Grid& grid, TIterator vrtsBegin,
524  TIterator vrtsEnd, AAPosVRT& aaPos,
525  number alpha, const vector3& up,
526  int numIterations)
527 {
528  using std::min;
529  using std::max;
530 
531  typedef typename AAPosVRT::ValueType vector_t;
532 
533  vector3 upN;
534  VecNormalize(upN, up);
535 
536 // we'll approximate the gradient by finding the path between the intersections
537 // of connected edges and the plane through the center-vertex, spanned by the normal-
538 // and up-vectors
541 
542  for(int iteration = 0; iteration < numIterations; ++iteration){
543  // iterate through all vertices
544  for(TIterator iter = vrtsBegin; iter != vrtsEnd; ++iter){
545  // smooth each one
546  Vertex* vrt = *iter;
547  vector_t vrtPos = aaPos[vrt];
548  vector_t vrtNorm;
549 
550  // check if the vertex is a boundary vertex. If so, we'll only consider
551  // the connected boundary vertices
552  if(LiesOnBoundary(grid, vrt)){
553  grid.associated_elements(edges, vrt);
554 
555  vector3 target(0, 0, 0);
556  number numBndEdges = 0;
557 
558  for(size_t i = 0; i < edges.size(); ++i){
559  if(IsBoundaryEdge2D(grid, edges[i])){
560  target += aaPos[GetConnectedVertex(edges[i], vrt)];
561  ++numBndEdges;
562  }
563  }
564 
565  if(numBndEdges > 0)
566  VecScaleAdd(aaPos[vrt], alpha/numBndEdges, target, 1. - alpha, vrtPos);
567  }
568  else{
569  CalculateVertexNormal(vrtNorm, grid, vrt, aaPos);
570 
571  //todo: one could think about performing laplacian smoothing in this case
572  if(fabs(VecDot(vrtNorm, upN)) > 1. - SMALL)
573  continue;
574 
575  vector3 planeNormal;
576  VecCross(planeNormal, vrtNorm, upN);
577 
578  vector3 inters[2];
579  int numInters = 0;
580 
581  grid.associated_elements(faces, vrt);
582  for(size_t i = 0; i < faces.size(); ++i){
583  Edge* e = GetConnectedEdge(grid, vrt, faces[i]);
584  vector3 v0 = aaPos[e->vertex(0)];
585  vector3 dir = aaPos[e->vertex(1)];
586  dir -= v0;
587 
588  vector3 vi;
589  number t;
590  if(RayPlaneIntersection(vi, t, v0, dir, vrtPos, planeNormal)){
591  if(t >= -SMALL && t <= 1 + SMALL){
592  if((numInters > 1) &&
593  (VecDistanceSq(vi, inters[0]) > VecDistanceSq(inters[1], inters[0])))
594  {
595  inters[1] = vi;
596  }
597  else{
598  inters[numInters] = vi;
599  ++numInters;
600  }
601  }
602  }
603  }
604 
605  if(numInters == 2){
606  vector3 target;
607  VecScaleAdd(target, 0.5, inters[0], 0.5, inters[1]);
608  VecScaleAdd(aaPos[vrt], alpha, target, 1. - alpha, vrtPos);
609  }
610  }
611  }
612  }
613 }
614 
615 
616 }// end of namespace
617 
618 #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
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
void attach_to_vertices_dv(TAttachment &attachment, const typename TAttachment::ValueType &defaultValue)
Definition: grid.h:754
bool is_marked(GridObject *obj) const
returns true if the object is marked, false if not.
Definition: grid_impl.hpp:843
size_t num() const
Definition: grid_impl.hpp:230
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
void detach_from_vertices(IAttachment &attachment)
Definition: grid.h:787
GridObject * get_opposing_object(Vertex *vrt, Face *elem)
returns the geometric object on the opposing side of the given vertex regarding the given element.
Definition: grid.cpp:631
void associated_elements(traits< Vertex >::secure_container &elemsOut, TElem *e)
Puts all elements of type TAss which are contained in 'e' or which contain 'e' into elemsOut.
Definition: grid_impl.hpp:466
Vertex *const * ConstVertexArray
Definition: grid_base_objects.h:319
Container which holds an array of pointers.
Definition: pointer_const_array.h:84
size_t size() const
returns the size of the associated array.
Definition: pointer_const_array_impl.hpp:106
bool empty() const
returns true if the associated array is empty
Definition: pointer_const_array_impl.hpp:113
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
Volumes are 3-dimensional objects.
Definition: grid_base_objects.h:754
bool LiesOnBoundary(Grid &grid, Edge *e)
returns true, if the edge lies on a 2d or 3d boundary
Definition: edge_util.cpp:169
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
bool IsBoundaryEdge2D(Grid &grid, Edge *e)
returns whether an edge lies on the boundary of a 2D grid.
Definition: edge_util.cpp:112
UG_API TAAPosVRT::ValueType CalculateGridObjectCenter(const GridObject *o, TAAPosVRT &aaPosVRT)
calculates the center for arbitrary geometric object
Definition: misc_util_impl.hpp:81
Edge * GetConnectedEdge(Grid &g, Vertex *vrt, Face *tri)
returns the edge in the triangle tri, which does not contain vrt.
Definition: vertex_util.cpp:121
UG_API void CalculateVertexNormal(vector3 &nOut, Grid &grid, Vertex *vrt, TAAPosVRT &aaPos)
calculates the normal of a vertex using associated faces
Definition: vertex_util_impl.hpp:61
Vertex * GetConnectedVertex(Edge *e, Vertex *v)
returns the vertex that is connected to v via e.
Definition: vertex_util.cpp:78
number CalculateVolume(Volume *elem, TAAPos aaPos)
Calculates the volume of the given element.
Definition: volume_calculation_impl.hpp:43
number alpha
double number
Definition: types.h:124
bool RayPlaneIntersection(vector_t &vOut, number &tOut, const vector_t &rayFrom, const vector_t &rayDir, const vector_t &p, const vector_t &n)
calculates the intersection of the ray rayFrom+t*rayDir and the plane (x-p)*n=0.
Definition: math_util_impl.hpp:360
void ProjectPointToPlane(vector_t &vOut, const vector_t &v, const vector_t &p, const vector_t &n)
projects v onto the plane defined by the point p and the planes normal n.
Definition: math_util_impl.hpp:342
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 VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition: math_vector_functions_common_impl.hpp:265
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 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
MathVector< 3, number > vector3
a 3d vector
Definition: ugmath_types.h:72
vector_t::value_type VecLengthSq(const vector_t &v)
returns the squared length of v. Faster than VecLength.
Definition: math_vector_functions_common_impl.hpp:324
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
void VecCross(vector_t &vOut, const vector_t &v1, const vector_t &v2)
calculates the cross product of two Vectors of dimension 3. It makes no sense to use VecCross for vec...
Definition: math_vector_functions_common_impl.hpp:437
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
size_t target(SM_edge< typename T::value_type > const &e, ug::BidirectionalMatrix< T > const &m)
Definition: bidirectional_boost.h:100
the ug namespace
void TangentialSmooth(Grid &g, TVrtIter vrtsBegin, TVrtIter vrtsEnd, TAAPos3 aaPos, number alpha, size_t numIterations)
Definition: manifold_smoothing.h:175
void SlopeSmooth(Grid &grid, TIterator vrtsBegin, TIterator vrtsEnd, AAPosVRT &aaPos, number alpha, const vector3 &up, int numIterations)
Definition: manifold_smoothing.h:523
const number SMALL
Definition: math_constants.h:41
void WeightedEdgeSmooth(Grid &grid, TIterator vrtsBegin, TIterator vrtsEnd, AAPosVRT &aaPos, number alpha, int numIterations, Grid::vertex_traits::callback cbSmoothVertex)
Definition: manifold_smoothing.h:344
void WeightedNormalSmooth(Grid &grid, TIterator vrtsBegin, TIterator vrtsEnd, AAPosVRT &aaPos, number alpha, number dotThreshold, int numIterations)
Definition: manifold_smoothing.h:471
void TangentialSmoothSimple(Grid &g, TVrtIter vrtsBegin, TVrtIter vrtsEnd, TAAPos3 aaPos, number alpha, size_t numIterations)
Definition: manifold_smoothing.h:117
void WeightedFaceSmooth(Grid &grid, TIterator vrtsBegin, TIterator vrtsEnd, AAPosVRT &aaPos, number alpha, int numIterations, Grid::vertex_traits::callback cbSmoothVertex)
Definition: manifold_smoothing.h:404
void LaplacianSmooth(Grid &grid, TIterator vrtsBegin, TIterator vrtsEnd, AAPosVRT &aaPos, number alpha, int numIterations)
Definition: manifold_smoothing.h:44
boost::function< bool(base_object *)> callback
callback type for the elements base type.
Definition: grid.h:150