Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
subdivision_loop.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * Authors: Sebastian Reiter, Martin Stepniewski
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__SUBDIVISION_LOOP__
34#define __H__UG__SUBDIVISION_LOOP__
35
36#include "lib_grid/lg_base.h"
39
40namespace ug
41{
42
45
48template <class TAVrtPos> void
49ProjectToLimitPLoop(Grid& grid, TAVrtPos aPos, TAVrtPos aProjPos)
50{
51// position type
52 typedef typename TAVrtPos::ValueType pos_type;
53
54// access the subdivision weights
56
57// if aPos and aProjPos are equal, we'll have to create a temporary
58// attachment
59 bool usingTmpAttachment = false;
60 if(aPos == aProjPos){
61 // create temporary attachment
62 usingTmpAttachment = true;
63 aProjPos = TAVrtPos();
64 }
65
66// attach aProjPos if required
67 if(!grid.has_vertex_attachment(aProjPos))
68 grid.attach_to_vertices(aProjPos);
69
70// attachment accessors
72 Grid::VertexAttachmentAccessor<TAVrtPos> aaProjPos(grid, aProjPos);
73
74// vectors to hold temporary results
75 typedef SubdivRules_PLoop::NeighborInfo NbrInfo;
76 std::vector<NbrInfo> nbrInfos;
77 std::vector<Vertex*> vrts;
78 std::vector<number> nbrWgts;
79
80// if volumes are contained in the grid, we currently only perform projection
81// of boundary elements (no creases...)
82 if(grid.num<Volume>() > 0){
83 for(VertexIterator iter = grid.vertices_begin();
84 iter != grid.vertices_end(); ++iter)
85 {
86 Vertex* vrt = *iter;
87 // collect all surface neighbors of vrt in vrts
88 vrts.clear();
90 iter != grid.associated_edges_end(vrt); ++iter)
91 {
92 if(IsBoundaryEdge3D(grid, *iter))
93 vrts.push_back(GetConnectedVertex(*iter, vrt));
94 }
95
96 // default loop projection
97 VecScale(aaProjPos[vrt], aaPos[vrt],
98 subdiv.proj_inner_center_weight(vrts.size()));
99
100 for(size_t i = 0; i < vrts.size(); ++i){
101 VecScaleAdd(aaProjPos[vrt], 1.0, aaProjPos[vrt],
102 subdiv.proj_inner_nbr_weight(vrts.size()),
103 aaPos[vrts[i]]);
104 }
105 }
106 }
107 else{
108 // iterate through all vertices
109 for(VertexIterator iter = grid.vertices_begin();
110 iter != grid.vertices_end(); ++iter)
111 {
112 Vertex* v = *iter;
113
114 // check whether the vertex is a crease vertex or not
115 //todo: this has to be more flexible
116 if(IsBoundaryVertex2D(grid, v)){
117 // project the crease vertex
118 Edge* nbrs[2];
119 size_t numNbrs = 0;
121 iter != grid.associated_edges_end(v); ++iter)
122 {
123 if(IsBoundaryEdge2D(grid, *iter)){
124 nbrs[numNbrs] = *iter;
125 ++numNbrs;
126 if(numNbrs == 2)
127 break;
128 }
129 }
130
131 if(numNbrs == 2){
132 pos_type& p0 = aaPos[GetConnectedVertex(nbrs[0], v)];
133 pos_type& p1 = aaPos[GetConnectedVertex(nbrs[1], v)];
134 vector3 w = subdiv.proj_crease_weights();
135 VecScaleAdd(aaProjPos[v], w.x(), aaPos[v], w.y(), p0, w.z(), p1);
136 }
137 else
138 aaProjPos[v] = aaPos[v];
139 }
140 else{
141 // project an inner vertex
142 // we have to calculate the valence and
143 // we have to check whether the vertex is a neighbor to a crease.
144 //todo: This could be given my some kind of mark.
145 bool creaseNbr = false;
146
147 // collect all neighbors in an ordered set.
148 //todo: the order is only important if the node is indeed a crease neighbor.
149 if(!CollectSurfaceNeighborsSorted(vrts, grid, v)){
150 UG_LOG("WARNING in ProjectToLimitPLoop: surface is not regular.");
151 UG_LOG(" Ignoring vertex...\n");
152 aaProjPos[v] = aaPos[v];
153 continue;
154 }
155
156 nbrInfos.resize(vrts.size());
157 for(size_t i = 0; i < vrts.size(); ++i)
158 {
159 Vertex* nbrVrt = vrts[i];
160 // we have to check whether nbrVrt is a crease edge. If it is,
161 // we have to calculate its valence.
162 if(IsBoundaryVertex2D(grid, nbrVrt)){
163 creaseNbr = true;
164 size_t creaseValence = 0;
166 iter != grid.associated_edges_end(nbrVrt); ++iter)
167 {
168 ++creaseValence;
169 }
170
171 nbrInfos[i] = NbrInfo(nbrVrt, creaseValence);
172 }
173 else
174 nbrInfos[i] = NbrInfo(nbrVrt, 0);
175 }
176
177 // if the vertex is a crease-nbr, we'll apply special weights.
178 // if not, normal loop-projection-masks are used.
179
180 if(creaseNbr){
181 number cntrWgt;
182 nbrWgts.resize(vrts.size());
183 subdiv.proj_inner_crease_nbr_weights(cntrWgt, &nbrWgts.front(),
184 &nbrInfos.front(), nbrInfos.size());
185
186 // special crease neighbor projection
187 VecScale(aaProjPos[v], aaPos[v], cntrWgt);
188
189 for(size_t i = 0; i < nbrWgts.size(); ++i){
190 VecScaleAdd(aaProjPos[v], 1.0, aaProjPos[v],
191 nbrWgts[i], aaPos[nbrInfos[i].nbr]);
192 }
193 }
194 else{
195 // default loop projection
196 VecScale(aaProjPos[v], aaPos[v],
197 subdiv.proj_inner_center_weight(nbrInfos.size()));
198
199 for(size_t i = 0; i < nbrInfos.size(); ++i){
200 VecScaleAdd(aaProjPos[v], 1.0, aaProjPos[v],
201 subdiv.proj_inner_nbr_weight(nbrInfos.size()),
202 aaPos[nbrInfos[i].nbr]);
203 }
204 }
205 }
206 }
207 }
208
209// clean up
210 if(usingTmpAttachment){
211 // swap attachment buffers
212 aaPos.swap(aaProjPos);
213
214 // detach it
215 grid.detach_from_vertices(aProjPos);
216 }
217}
218
221template <class TAVrtPos> void
222ProjectToLimitSubdivBoundary(Grid& grid, TAVrtPos aPos, TAVrtPos aProjPos)
223{
224// position type
225 typedef typename TAVrtPos::ValueType pos_type;
226
227// access the subdivision weights
229
230// if aPos and aProjPos are equal, we'll have to create a temporary
231// attachment
232 bool usingTmpAttachment = false;
233 if(aPos == aProjPos){
234 // create temporary attachment
235 usingTmpAttachment = true;
236 aProjPos = TAVrtPos();
237 }
238
239// attach aProjPos if required
240 if(!grid.has_vertex_attachment(aProjPos))
241 grid.attach_to_vertices(aProjPos);
242
243// attachment accessors
245 Grid::VertexAttachmentAccessor<TAVrtPos> aaProjPos(grid, aProjPos);
246
247// iterate through all vertices
248 for(VertexIterator iter = grid.vertices_begin();
249 iter != grid.vertices_end(); ++iter)
250 {
251 Vertex* v = *iter;
252
253 // check whether the vertex is a crease vertex or not
254 //todo: this has to be more flexible
255 if(IsBoundaryVertex2D(grid, v)){
256 // project the crease vertex
257 Edge* nbrs[2];
258 size_t numNbrs = 0;
260 iter != grid.associated_edges_end(v); ++iter)
261 {
262 if(IsBoundaryEdge2D(grid, *iter)){
263 nbrs[numNbrs] = *iter;
264 ++numNbrs;
265 if(numNbrs == 2)
266 break;
267 }
268 }
269
270 if(numNbrs == 2){
271 pos_type& p0 = aaPos[GetConnectedVertex(nbrs[0], v)];
272 pos_type& p1 = aaPos[GetConnectedVertex(nbrs[1], v)];
273 vector3 w = subdiv.proj_crease_weights();
274 VecScaleAdd(aaProjPos[v], w.x(), aaPos[v], w.y(), p0, w.z(), p1);
275 }
276 else
277 aaProjPos[v] = aaPos[v];
278 }
279 else{
280 // inner vertices are not moved
281 aaProjPos[v] = aaPos[v];
282 }
283 }
284
285// clean up
286 if(usingTmpAttachment){
287 // swap attachment buffers
288 aaPos.swap(aaProjPos);
289
290 // detach it
291 grid.detach_from_vertices(aProjPos);
292 }
293}
294
296// ProjectToLimitLoop
298bool ProjectToLimitLoop(Grid& grid, APosition& aProjPos);
299
301
302}// end of namespace
303
304#endif
void swap(AttachmentAccessor< TElem, TAttachment, TElemHandler > &acc)
calls swap on associated containers
Definition attachment_pipe.h:560
Base-class for edges.
Definition grid_base_objects.h:397
Manages the elements of a grid and their interconnection.
Definition grid.h:132
EdgeContainer::iterator AssociatedEdgeIterator
used to iterate over associated edges of vertices, faces and volumes
Definition grid.h:249
AssociatedEdgeIterator associated_edges_begin(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition grid.cpp:882
VertexIterator vertices_begin()
Definition grid.h:513
size_t num() const
Definition grid_impl.hpp:230
AssociatedEdgeIterator associated_edges_end(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition grid.cpp:892
VertexIterator vertices_end()
Definition grid.h:514
void detach_from_vertices(IAttachment &attachment)
Definition grid.h:787
bool has_vertex_attachment(IAttachment &attachment)
Definition grid.h:798
void attach_to_vertices(IAttachment &attachment, bool passOnValues)
Definition grid.h:728
A singleton that stores all rules for a piecewise-loop subdivision surface.
Definition subdivision_rules_piecewise_loop.h:48
number proj_inner_nbr_weight(size_t valence) const
Definition subdivision_rules_piecewise_loop.h:111
number proj_inner_center_weight(size_t valence) const
Definition subdivision_rules_piecewise_loop.h:108
static SubdivRules_PLoop & inst()
returns the only instance to this singleton.
Definition subdivision_rules_piecewise_loop.h:64
void proj_inner_crease_nbr_weights(number &centerWgtOut, number *nbrWgtsOut, NeighborInfo *nbrInfos, size_t numNbrs) const
Definition subdivision_rules_piecewise_loop.h:118
vector3 proj_crease_weights() const
Definition subdivision_rules_piecewise_loop.h:114
Base-class for all vertex-types.
Definition grid_base_objects.h:231
Volumes are 3-dimensional objects.
Definition grid_base_objects.h:754
bool IsBoundaryEdge2D(Grid &grid, Edge *e)
returns whether an edge lies on the boundary of a 2D grid.
Definition edge_util.cpp:112
bool IsBoundaryEdge3D(Grid &grid, Edge *e)
returns whether an edge lies on the boundary of a 3D grid.
Definition edge_util.cpp:139
bool ProjectToLimitLoop(Grid &grid, APosition &aProjPos)
projects surface vertices to their limit subdivision surface position
Definition subdivision_loop.cpp:43
void ProjectToLimitSubdivBoundary(Grid &grid, TAVrtPos aPos, TAVrtPos aProjPos)
projects all boundary vertices in the given grid to their limit-positions using the piecewise loop sc...
Definition subdivision_loop.h:222
void ProjectToLimitPLoop(Grid &grid, TAVrtPos aPos, TAVrtPos aProjPos)
projects all vertices in the given grid to their limit-positions using the piecewise loop scheme.
Definition subdivision_loop.h:49
bool IsBoundaryVertex2D(Grid &grid, Vertex *v)
returns whether a vertex lies on the boundary of a 2D grid.
Definition vertex_util.cpp:531
bool CollectSurfaceNeighborsSorted(std::vector< Vertex * > &vNeighborsOut, Grid &grid, Vertex *v)
Collects neighbor-vertices in either clockwise or counter clockwise order.
Definition vertex_util.cpp:217
Vertex * GetConnectedVertex(Edge *e, Vertex *v)
returns the vertex that is connected to v via e.
Definition vertex_util.cpp:78
#define UG_LOG(msg)
Definition log.h:367
double number
Definition types.h:124
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 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
the ug namespace
ElementStorage< Vertex >::SectionContainer::iterator VertexIterator
This Iterator will be used as base-class for iterators of specialized geometric objects.
Definition grid_base_object_traits.h:73
APosition3 APosition
Definition common_attachments.h:76
Definition subdivision_rules_piecewise_loop.h:50