Line data Source code
1 : /*
2 : * Copyright (c) 2012-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 "icosahedron.h"
34 : #include "lib_grid/refinement/regular_refinement.h"
35 : #include "lib_grid/refinement/projectors/sphere_projector.h"
36 :
37 : namespace ug{
38 :
39 : /// Creates an Icosahedron
40 0 : void GenerateIcosahedron(Grid& grid, const vector3& center,
41 : number radius, AVector3& aPos)
42 : {
43 : const number A = 0.85065080835204;
44 : const number B = 0.525731112119134;
45 :
46 : // create the vertices
47 0 : const number coords[12][3] = { {-B, A, 0}, {0, B, A}, {B, A, 0}, {0, B, -A},
48 : {-A, 0, B}, {A, 0, B}, {A, 0, -B}, {-A, 0, -B},
49 : {-B, -A, 0}, {0, -B, A}, {B, -A, 0}, {0, -B, -A}};
50 :
51 0 : const int inds[20][3] = { {0, 1, 2}, {0, 2, 3},
52 : {3, 7, 0}, {7, 4, 0}, {0, 4, 1},
53 : {1, 5, 2}, {5, 6, 2}, {2, 6, 3},
54 : {4, 9, 1}, {1, 9, 5}, {7, 3, 11}, {3, 6, 11},
55 : {11, 8, 7}, {7, 8, 4}, {8, 9, 4},
56 : {9, 10, 5}, {10, 6, 5}, {10, 11, 6},
57 : {8, 10, 9}, {8, 11, 10}};
58 :
59 : Vertex* vrts[12];
60 :
61 0 : if(!grid.has_vertex_attachment(aPos))
62 0 : grid.attach_to_vertices(aPos);
63 : Grid::AttachmentAccessor<Vertex, AVector3> aaPos(grid, aPos);
64 :
65 0 : for(size_t i = 0; i < 12; ++i){
66 0 : vrts[i] = *grid.create<RegularVertex>();
67 0 : aaPos[vrts[i]] = vector3(coords[i][0], coords[i][1], coords[i][2]);
68 : VecScaleAdd(aaPos[vrts[i]], 1.0, center, radius, aaPos[vrts[i]]);
69 : }
70 :
71 : // construct triangles
72 0 : for(size_t i = 0; i < 20; ++i){
73 0 : grid.create<Triangle>(TriangleDescriptor(vrts[inds[i][0]], vrts[inds[i][1]],
74 0 : vrts[inds[i][2]]));
75 : }
76 0 : }
77 :
78 0 : void GenerateIcosphere(Grid& grid, const vector3& center, number radius,
79 : int numRefinements, AVector3& aPos, Selector* psel)
80 : {
81 0 : Selector defSel;
82 0 : if(!psel){
83 0 : defSel.assign_grid(grid);
84 : psel = &defSel;
85 : }
86 :
87 : Selector& sel = *psel;
88 :
89 : // enable autoselection
90 : bool autoselectionEnabled = sel.autoselection_enabled();
91 0 : sel.enable_autoselection(true);
92 :
93 : // clear the selector
94 0 : sel.clear();
95 :
96 : // create an icosahedron. All elements of the sphere will be selected, since we
97 : // enabled autoselection
98 0 : GenerateIcosahedron(grid, center, radius, aPos);
99 :
100 : // perform refinement steps
101 : // we need a temporary int attachment for the edges
102 : AInt aInt;
103 : grid.attach_to_edges(aInt);
104 :
105 : // use a refinement callback to project the new vertices to the sphere
106 0 : SphereProjector sphereProjecton(MakeGeometry3d(grid, aPos), center);
107 :
108 0 : for(int i = 0; i < numRefinements; ++i)
109 0 : Refine(grid, sel, aInt, &sphereProjecton);
110 :
111 : // remove attachments
112 : grid.detach_from_edges(aInt);
113 :
114 : // restore autoselection
115 0 : sel.enable_autoselection(autoselectionEnabled);
116 0 : }
117 :
118 :
119 0 : void GenerateIcosphere( std::vector<vector3>& trisOut,
120 : const vector3& center,
121 : number radius,
122 : size_t refinements)
123 : {
124 0 : Grid g;
125 : APosition aPos = aPosition;
126 : g.attach_to_vertices(aPos);
127 : Grid::VertexAttachmentAccessor<APosition> aaPos(g, aPos);
128 :
129 0 : GenerateIcosphere(g, center, radius, refinements, aPos);
130 :
131 0 : trisOut.reserve(trisOut.size() + g.num<Face>() * 3);
132 :
133 0 : for(FaceIterator f_iter = g.begin<Face>(); f_iter != g.end<Face>(); ++f_iter)
134 : {
135 : Face* f = *f_iter;
136 0 : for(size_t i_vrt = 0; i_vrt < f->num_vertices(); ++i_vrt){
137 0 : trisOut.push_back(aaPos[f->vertex(i_vrt)]);
138 : }
139 : }
140 0 : }
141 :
142 : }// end of namespace
|