Line data Source code
1 : /*
2 : * Copyright (c) 2009-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__
34 : #define __H__LIB_GRID__FACE_UTIL__
35 :
36 : #include "lib_grid/grid/grid.h"
37 : #include "lib_grid/grid_objects/grid_objects.h"
38 : #include "lib_grid/common_attachments.h"
39 :
40 : namespace ug
41 : {
42 :
43 : /**
44 : * \brief contains methods to manipulate faces
45 : *
46 : * \defgroup lib_grid_algorithms_face_util face util
47 : * \ingroup lib_grid_algorithms
48 : * @{
49 : */
50 :
51 :
52 : ////////////////////////////////////////////////////////////////////////
53 : // GetFaceIndex
54 : /// returns the index at which face f is found in the given object
55 : /**
56 : * returns -1 if the face was not found.
57 : */
58 : UG_API int GetFaceIndex(Volume* vol, Face* f);
59 :
60 :
61 : ////////////////////////////////////////////////////////////////////////
62 : // CalculateNormal
63 : /// calculates the normal of the given face
64 : /**
65 : * aaPos has to be a valid positition-attachment-accessor to the vertices
66 : * of the grid which contains the face.
67 : * if the face contains less than 3 vertices (0, 0, 0) will be written
68 : * to vNormOut (this should never happen!).
69 : * For triangles the normal is calculated using the standard cross-product.
70 : * for quadrilaterals the normals of the two sub-triangles (0, 1, 2) and
71 : * (2, 3, 0) is calculated and averaged.
72 : * If the face contains more than 4 vertices the normal of the first
73 : * sub-triangle is returned.
74 : *
75 : * Performs normalization on the calcluated normals.
76 : */
77 : UG_API
78 : void CalculateNormal(vector3& vNormOut, const FaceVertices* face,
79 : Grid::AttachmentAccessor<Vertex, APosition>& aaPos);
80 :
81 : ////////////////////////////////////////////////////////////////////////
82 : // CalculateNormal
83 : /// calculates the normal of the given face
84 : /**
85 : * aaPos has to be a valid positition-attachment-accessor to the vertices
86 : * of the grid which contains the face.
87 : * if the face contains less than 3 vertices (0, 0, 0) will be written
88 : * to vNormOut (this should never happen!).
89 : * For triangles the normal is calculated using the standard cross-product.
90 : * for quadrilaterals the normals of the two sub-triangles (0, 1, 2) and
91 : * (2, 3, 0) is calculated and averaged.
92 : * If the face contains more than 4 vertices the normal of the first
93 : * sub-triangle is returned.
94 : *
95 : * performs no normalization on the calculated normals
96 : */
97 : UG_API
98 : void CalculateNormalNoNormalize(vector3& vNormOut, FaceVertices* face,
99 : Grid::AttachmentAccessor<Vertex, APosition>& aaPos);
100 :
101 : ////////////////////////////////////////////////////////////////////////
102 : // CalculateFaceNormals
103 : /// calculates the normal of each face. Presumes that all faces are flat.
104 : /**
105 : * aPos has to be attached to the vertices of the grid.
106 : * aPos should contain the position data.
107 : * Normals will be written to aNorm (face attachment).
108 : */
109 : UG_API
110 : void CalculateFaceNormals(Grid& grid, const FaceIterator& facesBegin,
111 : const FaceIterator& facesEnd,
112 : AVector3& aPos, AVector3& aNorm);
113 :
114 : ////////////////////////////////////////////////////////////////////////
115 : /// returns the number of associated volumes of the specified face
116 : int NumAssociatedVolumes(Grid& grid, Face* f);
117 :
118 : ////////////////////////////////////////////////////////////////////////
119 : // IsVolumeBoundaryFace
120 : /// returns true if the given face is a boundary face.
121 : /** A face is regarded as a boundary face if it is adjacent
122 : * to exactly one volume.
123 : *
124 : * Please note that overloads of this function for Constrained- and
125 : * ConstrainingFaces exist.*/
126 : UG_API
127 : bool IsVolumeBoundaryFace(Grid& grid, Face* f);
128 :
129 : ////////////////////////////////////////////////////////////////////////
130 : // IsVolumeBoundaryFace
131 : /// returns true if the given face is a boundary face.
132 : /** Overload for ConstrainedFace.
133 : * A face is regarded as a boundary face if it is adjacent
134 : * to exactly one volume.*/
135 : UG_API
136 : bool IsVolumeBoundaryFace(Grid& grid, ConstrainedFace* f);
137 :
138 : ////////////////////////////////////////////////////////////////////////
139 : // IsVolumeBoundaryFace
140 : /// returns true if the given face is a boundary face.
141 : /** Overload for ConstrainedFace.
142 : * A face is regarded as a boundary face if it is adjacent
143 : * to exactly one volume.*/
144 : UG_API
145 : bool IsVolumeBoundaryFace(Grid& grid, ConstrainingFace* f);
146 :
147 : ////////////////////////////////////////////////////////////////////////
148 : /// A wrapper for IsVolumeBoundaryFace
149 : template <class TFace>
150 : UG_API
151 : bool IsBoundaryFace3D(Grid& grid, TFace* f)
152 0 : {return IsVolumeBoundaryFace(grid, f);}
153 :
154 : ////////////////////////////////////////////////////////////////////////
155 : /// A wrapper for IsVolumeBoundaryFace
156 : template <class TFace>
157 : UG_API
158 : bool LiesOnBoundary(Grid& grid, TFace* f)
159 : {return IsBoundaryFace3D(grid, f);}
160 :
161 : ////////////////////////////////////////////////////////////////////////
162 : // FaceArea
163 : /// Returns the area of a convex face
164 : template <class TAAPosVRT>
165 : UG_API
166 : number FaceArea(FaceVertices* f, TAAPosVRT& aaPos);
167 :
168 : ////////////////////////////////////////////////////////////////////////
169 : // FaceArea
170 : /// Returns the area sum of convex faces
171 : template <class TIterator, class TAAPosVRT>
172 : UG_API
173 : number FaceArea(TIterator facesBegin, TIterator facesEnd, TAAPosVRT& aaPos);
174 :
175 : ////////////////////////////////////////////////////////////////////////
176 : /// Returns the face with the smallest area
177 : /**
178 : * Make sure that TIterator::value_type equals Face* and that aaPos operates
179 : * on the grid from which the faces were taken.
180 : */
181 : template <class TIterator, class TAAPosVRT>
182 : UG_API
183 : Face* FindSmallestFace(TIterator facesBegin, TIterator facesEnd, TAAPosVRT& aaPos);
184 :
185 : ////////////////////////////////////////////////////////////////////////
186 : // FaceQuality
187 : /// a simple measure for the quality of a face
188 : /**
189 : * returns a value between 0 and 1, where 1 indicates a
190 : * good quality and 0 a bad.
191 : * This method checks the dot-products of edges at the corners.
192 : * The worst one (closest to 1 or -1) determines the quality.
193 : * \sa TriangleQuality
194 : */
195 : UG_API
196 : number FaceQuality(FaceVertices* f, Grid::VertexAttachmentAccessor<APosition> aaPos);
197 :
198 : ////////////////////////////////////////////////////////////////////////
199 : // AreaFaceQuality
200 : /// returns a value between 0 (bad) and 1 (good) that describes the quality of the area.
201 : /**
202 : * returns the worst FaceQuality of the faces between facesBegin and FacesEnd.
203 : * TIterator has to be an iterator with a value-type compatible to Face*.
204 : */
205 : template <class TIterator>
206 : UG_API
207 : number AreaFaceQuality(TIterator facesBegin, TIterator facesEnd,
208 : Grid::VertexAttachmentAccessor<APosition>& aaPos);
209 :
210 : ////////////////////////////////////////////////////////////////////////
211 : // TriangleQuality
212 : /// a simple measure for the quality of a triangle
213 : /**
214 : * returns a value between 0 and 1, where 1 indicates a
215 : * good quality and 0 a bad.
216 : * This method checks the dot-products of edges at the corners.
217 : * The worst one (closest to 1 or -1) determines the quality.
218 : * \sa FaceQuality
219 : */
220 : UG_API number TriangleQuality(vector3& v1, vector3& v2, vector3& v3);
221 :
222 : ////////////////////////////////////////////////////////////////////////
223 : // Triangulate
224 : /// removes the quadrilateral and replaces it by two triangles.
225 : /**
226 : * if paaPos is set to NULL, the quadrilateral will be splitted
227 : * along the edge between the first and the third vertex.
228 : * If paaPos points to a position-attachment-accessor,
229 : * then the new edge will be chosen so that the worst triangle-quality
230 : * is better.
231 : */
232 : UG_API
233 : void Triangulate(Grid& grid, Quadrilateral* q,
234 : Grid::VertexAttachmentAccessor<APosition>* paaPos = NULL);
235 :
236 : ////////////////////////////////////////////////////////////////////////
237 : // Triangulate
238 : /// replaces all specified quadrilaterals by triangles.
239 : /**
240 : * if paaPos is set to NULL, the quadrilaterals will be splitted
241 : * along the edge between their first and their third vertex.
242 : * If paaPos points to a position-attachment-accessor,
243 : * then the new edge will be chosen so that the worst triangle-quality
244 : * is better.
245 : */
246 : UG_API
247 : void Triangulate(Grid& grid,
248 : QuadrilateralIterator iterBegin,
249 : QuadrilateralIterator iterEnd,
250 : Grid::VertexAttachmentAccessor<APosition>* paaPos = NULL);
251 :
252 : UG_API
253 : inline void Triangulate(Grid& grid,
254 : Grid::VertexAttachmentAccessor<APosition>* paaPos = NULL);
255 :
256 : ////////////////////////////////////////////////////////////////////////
257 : // GetNeighbours
258 : /// collects neighbours of the given side of a face.
259 : /**
260 : * collects all faces that are adjacent to the given side of f.
261 : */
262 : UG_API
263 : void GetNeighbours(std::vector<Face*>& vFacesOut, Grid& grid, Face* f,
264 : int side, bool clearContainer = true);
265 :
266 :
267 : ////////////////////////////////////////////////////////////////////////
268 : ////////////////////////////////////////////////////////////////////////
269 : // template methods
270 : ////////////////////////////////////////////////////////////////////////
271 : // CalculateCenter
272 : /// calculates the center of a face.
273 : /**
274 : * TVertexPositionAttachmentAccessor has to be an AttachmentAccessor,
275 : * where AttachmentAccessor::ValueType is a vector-type compatible to
276 : * the lgmath vector descriptor.
277 : * The accessor has to access an attachment of the vertices,
278 : * to which f refers.
279 : *
280 : * \{
281 : */
282 : template<class TVertexPositionAttachmentAccessor>
283 : UG_API
284 : typename TVertexPositionAttachmentAccessor::ValueType
285 : CalculateCenter(const FaceVertices* f, TVertexPositionAttachmentAccessor& aaPosVRT);
286 : /** \} */
287 :
288 :
289 : ////////////////////////////////////////////////////////////////////////
290 : /// returns the weighted center of the vertices of the given face
291 : /** TAAWeightVRT has to be an attachment to the vertices of the grid in which
292 : * f is contained, with ValueType number (or compatible).
293 : */
294 : template<class TAAPosVRT, class TAAWeightVRT>
295 : UG_API
296 : typename TAAPosVRT::ValueType
297 : CalculateCenter(const FaceVertices* f, TAAPosVRT& aaPos, TAAWeightVRT& aaWeight);
298 :
299 :
300 : ////////////////////////////////////////////////////////////////////////
301 : /// Returns true if the given point lies inside the given face.
302 : /** \note The method only works properly, if the point and the face are located
303 : * in the same x-y-plane.
304 : */
305 : template <class vector_t, class TAAPos>
306 : UG_API bool
307 : ContainsPoint(const FaceVertices* f, const vector_t& p, TAAPos aaPos);
308 :
309 :
310 : ////////////////////////////////////////////////////////////////////////
311 : // project points to surface
312 : template <class TTriangleIterator, class TAAPosVRT>
313 : UG_API
314 : bool ProjectPointToSurface(vector3& vOut, const vector3& v, const vector3& n,
315 : TTriangleIterator trisBegin, TTriangleIterator trisEnd,
316 : TAAPosVRT& aaPos, bool compareNormals = false);
317 :
318 : ////////////////////////////////////////////////////////////////////////
319 : /**
320 : * returns 1 if a point lies in front of a face,
321 : * 0 if it lies on the face and -1 if it lies behind the face.
322 : * TAAPosVRT has to be an AttachmentAccessor compatible type that
323 : * operates on vector3.
324 : */
325 : template <class TAAPosVRT>
326 : UG_API
327 : int PointFaceTest(vector3& v, Face* f, TAAPosVRT& aaPos);
328 :
329 : ////////////////////////////////////////////////////////////////////////
330 : /// returns true if the given face is degenerated.
331 : /** Faces are degenerated if at least one edge is shorter than the given threshold.*/
332 : template <class TAAPosVRT>
333 : UG_API
334 : bool IsDegenerated(Face* f, TAAPosVRT& aaPos, number threshold = SMALL);
335 :
336 :
337 : ////////////////////////////////////////////////////////////////////////
338 : /// Refines the face by connecting its sides with the new center.
339 : /** Make sure that the specified vertex is belongs to the specified grid, and
340 : * that its position lies inside the specified face (self-intersections would
341 : * occur if it would lie outside).
342 : * The original face may optionally be deleted.
343 : */
344 : UG_API
345 : void InsertCenterVertex(Grid& g, Face* f, Vertex* vrt, bool eraseOldFace);
346 :
347 : /// @}
348 :
349 : }// end of namespace
350 :
351 : ////////////////////////////////
352 : // include implementation
353 : #include "face_util_impl.hpp"
354 :
355 : #endif
|