Line data Source code
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 : #include <cassert>
34 : #include "common/math/ugmath.h"
35 : #include "simple_grid.h"
36 :
37 : using namespace std;
38 :
39 : namespace ug
40 : {
41 : ////////////////////////////////////////////////////////////////////////
42 0 : void SimpleGrid::clear()
43 : {
44 : vertices.clear();
45 : vertexNormals.clear();
46 : triangles.clear();
47 : triangleNormals.clear();
48 0 : }
49 :
50 0 : void PrintSimpleGrid(SimpleGrid& sg)
51 : {
52 : cout << "simple-grid:" << endl;
53 : cout << "num vrts: " << sg.vertices.size() << endl;
54 : cout << "num tris: " << sg.triangles.size() << endl;
55 :
56 0 : cout << "vertices: ";
57 0 : for(size_t i = 0; i < sg.vertices.size(); ++i)
58 0 : cout << sg.vertices[i] << ", ";
59 : cout << endl;
60 :
61 0 : cout << "normals: ";
62 0 : for(size_t i = 0; i < sg.vertexNormals.size(); ++i)
63 0 : cout << sg.vertexNormals[i] << ", ";
64 : cout << endl;
65 :
66 0 : cout << "triangles: ";
67 0 : for(size_t i = 0; i < sg.triangles.size(); ++i)
68 0 : cout << sg.triangles[i] << ", ";
69 : cout << endl;
70 :
71 0 : cout << "triangle normals: ";
72 0 : for(size_t i = 0; i < sg.triangleNormals.size(); ++i)
73 0 : cout << sg.triangleNormals[i] << ", ";
74 : cout << endl;
75 0 : }
76 :
77 : ////////////////////////////////////////////////////////////////////////
78 0 : void CalculateTriangleNormal(SimpleGrid& sg, int triIndex)
79 : {
80 0 : int i = triIndex * 3;
81 : assert(((int)sg.triangles.size() > i + 2) && ((int)sg.triangleNormals.size() > triIndex) && "bad triangle index.");
82 :
83 0 : CalculateTriangleNormal(sg.triangleNormals[triIndex],
84 0 : sg.vertices[sg.triangles[i]],
85 0 : sg.vertices[sg.triangles[i+1]],
86 0 : sg.vertices[sg.triangles[i+2]]);
87 0 : }
88 :
89 : ////////////////////////////////////////////////////////////////////////
90 0 : void CalculateTriangleNormals(SimpleGrid& sg)
91 : {
92 0 : size_t numTris = sg.triangles.size() / 3;
93 0 : sg.triangleNormals.resize(numTris);
94 :
95 0 : for(size_t i = 0; i < numTris; ++i)
96 0 : CalculateTriangleNormal(sg, i);
97 0 : }
98 :
99 : ////////////////////////////////////////////////////////////////////////
100 0 : number GeometricApproximationDegree(SimpleGrid& sg, int triIndex)
101 : {
102 0 : size_t i = triIndex * 3;
103 :
104 0 : return GeometricApproximationDegree(sg.vertexNormals[sg.triangles[i]],
105 0 : sg.vertexNormals[sg.triangles[i+1]],
106 0 : sg.vertexNormals[sg.triangles[i+2]],
107 0 : sg.triangleNormals[triIndex]);
108 : }
109 :
110 : ////////////////////////////////////////////////////////////////////////
111 0 : number GeometricApproximationDegree(SimpleGrid& sg)
112 : {
113 0 : if(sg.triangles.size() < 3)
114 : return 0;
115 :
116 0 : number q = GeometricApproximationDegree(sg, 0);
117 0 : size_t numTris = sg.triangles.size() / 3;
118 0 : for(size_t i = 1; i < numTris; ++i)
119 0 : q = min(q, GeometricApproximationDegree(sg, i));
120 :
121 0 : return q;
122 : }
123 :
124 : ////////////////////////////////////////////////////////////////////////
125 0 : number ShapeQualityDegree(SimpleGrid& sg, int triIndex)
126 : {
127 0 : int i = triIndex * 3;
128 0 : return TriangleQuality_Area(sg.vertices[sg.triangles[i]],
129 0 : sg.vertices[sg.triangles[i+1]],
130 0 : sg.vertices[sg.triangles[i+2]]);
131 : }
132 :
133 : ////////////////////////////////////////////////////////////////////////
134 0 : number ShapeQualityDegree(SimpleGrid& sg)
135 : {
136 0 : if(sg.triangles.size() < 3)
137 : return 0;
138 :
139 0 : number q = ShapeQualityDegree(sg, 0);
140 0 : size_t numTris = sg.triangles.size() / 3;
141 0 : for(size_t i = 1; i < numTris; ++i)
142 0 : q = min(q, ShapeQualityDegree(sg, i));
143 :
144 0 : return q;
145 : }
146 :
147 : ////////////////////////////////////////////////////////////////////////
148 0 : bool SwapEdge(SimpleGrid& sg)
149 : {
150 0 : if(sg.triangles.size() < 6)
151 : return false;
152 :
153 : // get the two connected indices
154 : int ci[2];
155 : int counter = 0;
156 0 : for(size_t i = 0; i < 6; ++i){
157 0 : if(sg.triangles[i] > 1){
158 0 : if(counter < 2)
159 0 : ci[counter] = i;
160 0 : ++counter;
161 : }
162 : }
163 :
164 : // both triangle 0 and 1 have to contain indices 0 and 1.
165 0 : if(counter != 2)
166 : return false;
167 :
168 : // the other indices of the first triangle
169 0 : int ind0 = sg.triangles[(ci[0] + 1) % 3];
170 0 : int ind1 = sg.triangles[(ci[0] + 2) % 3];
171 :
172 : // assign the vertex indices
173 0 : ci[0] = sg.triangles[ci[0]];
174 0 : ci[1] = sg.triangles[ci[1]];
175 :
176 : // create the new triangles
177 0 : sg.triangles[0] = ci[0];
178 0 : sg.triangles[1] = ind0;
179 0 : sg.triangles[2] = ci[1];
180 :
181 0 : sg.triangles[3] = ci[0];
182 0 : sg.triangles[4] = ci[1];
183 0 : sg.triangles[5] = ind1;
184 :
185 : // calculate the normals of the new triangles
186 0 : CalculateTriangleNormal(sg, 0);
187 0 : CalculateTriangleNormal(sg, 1);
188 :
189 : // done
190 : return true;
191 : }
192 :
193 : ////////////////////////////////////////////////////////////////////////
194 0 : bool CollapseEdge(SimpleGrid& sg)
195 : {
196 0 : if(sg.triangles.size() < 6)
197 : return false;
198 :
199 : // the index of the new vertex
200 0 : int newInd = sg.vertices.size();
201 :
202 : // add the new vertex
203 : vector3 vNew;
204 : VecAdd(vNew, sg.vertices[0], sg.vertices[1]);
205 : VecScale(vNew, vNew, 0.5);
206 0 : sg.vertices.push_back(vNew);
207 :
208 : // and the new normal
209 : vector3 nNew;
210 : VecAdd(nNew, sg.vertexNormals[0], sg.vertexNormals[1]);
211 0 : VecNormalize(nNew, nNew);
212 0 : sg.vertexNormals.push_back(nNew);
213 :
214 : // create the new triangle list
215 : // the new list contains 2 triangles less than the old list
216 0 : vector<int> tris(sg.triangles.size() - 6);
217 :
218 0 : for(size_t i = 6; i < sg.triangles.size(); ++i){
219 0 : if(sg.triangles[i] < 2)
220 0 : tris[i-6] = newInd;
221 : else
222 0 : tris[i-6] = sg.triangles[i];
223 : }
224 :
225 : // swap the lists
226 : sg.triangles.swap(tris);
227 :
228 : // recalculate the normals
229 0 : CalculateTriangleNormals(sg);
230 :
231 : // done
232 : return true;
233 0 : }
234 :
235 : }// end of namespace
|