hemocell
Loading...
Searching...
No Matches
meshGeneratingFunctions.hh
Go to the documentation of this file.
1/*
2This file is part of the HemoCell library
3
4HemoCell is developed and maintained by the Computational Science Lab
5in the University of Amsterdam. Any questions or remarks regarding this library
6can be sent to: info@hemocell.eu
7
8When using the HemoCell library in scientific work please cite the
9corresponding paper: https://doi.org/10.3389/fphys.2017.00563
10
11The HemoCell library is free software: you can redistribute it and/or
12modify it under the terms of the GNU Affero General Public License as
13published by the Free Software Foundation, either version 3 of the
14License, or (at your option) any later version.
15
16The library is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU Affero General Public License for more details.
20
21You should have received a copy of the GNU Affero General Public License
22along with this program. If not, see <http://www.gnu.org/licenses/>.
23*/
24#ifndef MESH_GENERATING_FUNCTIONS_HH
25#define MESH_GENERATING_FUNCTIONS_HH
26
28
29namespace plb {
30
31template<typename T>
32TriangleSet<T> constructSphereIcosahedron(plb::Array<T,3> const& center, T radius, plint minNumOfTriangles)
33{
34 std::vector<typename TriangleSet<T>::Triangle> triangles;
35#ifdef PLB_DEBUG
36 static const T eps = std::numeric_limits<T>::epsilon();
37#endif
38 PLB_ASSERT(radius > (T) 0.0 && !util::fpequal(radius, (T) 0.0, eps) &&
39 minNumOfTriangles >= 8);
40
41 // Create a triangularized unit sphere
42 // Twelve vertices of icosahedron on unit sphere
43 T tau = -0.8506508084; // t=(1+sqrt(5))/2, tau=t/sqrt(1+t^2)
44 T one = -0.5257311121; // one=1/sqrt(1+t^2) , unit sphere
45
46 // Initial 6 vertices
47 plb::Array<T,3> v1( tau, one, 0); //ZA
48 plb::Array<T,3> v2(-tau, one, 0); //ZB
49 plb::Array<T,3> v3(-tau, -one, 0); //ZC
50 plb::Array<T,3> v4( tau, -one, 0); //ZD
51 plb::Array<T,3> v5( one, 0 , tau); //YA
52 plb::Array<T,3> v6( one, 0 , -tau); //YB
53 plb::Array<T,3> v7(-one, 0 , -tau); //YC
54 plb::Array<T,3> v8(-one, 0 , tau); //YD
55 plb::Array<T,3> v9( 0 , tau, one); //XA
56 plb::Array<T,3> v10( 0 , -tau, one); //XB
57 plb::Array<T,3> v11( 0 , -tau, -one); //XC
58 plb::Array<T,3> v12( 0 , tau, -one); //XD
59
60 // Structure for unit icosahedron
61 typename TriangleSet<T>::Triangle tmp;
62
63 tmp[0] = v5; tmp[1] = v8; tmp[2] = v9;
64 triangles.push_back(tmp);
65 tmp[0] = v5; tmp[1] = v10; tmp[2] = v8;
66 triangles.push_back(tmp);
67 tmp[0] = v6; tmp[1] = v12; tmp[2] = v7;
68 triangles.push_back(tmp);
69 tmp[0] = v6; tmp[1] = v7; tmp[2] = v11;
70 triangles.push_back(tmp);
71 tmp[0] = v1; tmp[1] = v4; tmp[2] = v5;
72 triangles.push_back(tmp);
73 tmp[0] = v1; tmp[1] = v6; tmp[2] = v4;
74 triangles.push_back(tmp);
75 tmp[0] = v3; tmp[1] = v2; tmp[2] = v8;
76 triangles.push_back(tmp);
77 tmp[0] = v3; tmp[1] = v7; tmp[2] = v2;
78 triangles.push_back(tmp);
79 tmp[0] = v9; tmp[1] = v12; tmp[2] = v1;
80 triangles.push_back(tmp);
81 tmp[0] = v9; tmp[1] = v2; tmp[2] = v12;
82 triangles.push_back(tmp);
83 tmp[0] = v10; tmp[1] = v4; tmp[2] = v11;
84 triangles.push_back(tmp);
85 tmp[0] = v10; tmp[1] = v11; tmp[2] = v3;
86 triangles.push_back(tmp);
87 tmp[0] = v9; tmp[1] = v1; tmp[2] = v5;
88 triangles.push_back(tmp);
89 tmp[0] = v12; tmp[1] = v6; tmp[2] = v1;
90 triangles.push_back(tmp);
91 tmp[0] = v5; tmp[1] = v4; tmp[2] = v10;
92 triangles.push_back(tmp);
93 tmp[0] = v6; tmp[1] = v11; tmp[2] = v4;
94 triangles.push_back(tmp);
95 tmp[0] = v8; tmp[1] = v2; tmp[2] = v9;
96 triangles.push_back(tmp);
97 tmp[0] = v7; tmp[1] = v12; tmp[2] = v2;
98 triangles.push_back(tmp);
99 tmp[0] = v8; tmp[1] = v10; tmp[2] = v3;
100 triangles.push_back(tmp);
101 tmp[0] = v7; tmp[1] = v3; tmp[2] = v11;
102 triangles.push_back(tmp);
103
104 // Perform refinement iterations
105
106 plint size;
107 plb::Array<T,3> va,vb,vc,vd,ve,vf;
108 while ((size = triangles.size()) < minNumOfTriangles) {
109 for (plint i = 0; i < size; i++) {
110 va = triangles[i][0];
111 vb = triangles[i][1];
112 vc = triangles[i][2];
113
114 vd = (T) 0.5 * (va + vb);
115 ve = (T) 0.5 * (vb + vc);
116 vf = (T) 0.5 * (vc + va);
117
118 vd /= norm(vd);
119 ve /= norm(ve);
120 vf /= norm(vf);
121
122 triangles[i][0] = vd;
123 triangles[i][1] = ve;
124 triangles[i][2] = vf;
125
126 tmp[0] = va;
127 tmp[1] = vd;
128 tmp[2] = vf;
129 triangles.push_back(tmp);
130
131 tmp[0] = vd;
132 tmp[1] = vb;
133 tmp[2] = ve;
134 triangles.push_back(tmp);
135
136 tmp[0] = vf;
137 tmp[1] = ve;
138 tmp[2] = vc;
139 triangles.push_back(tmp);
140 }
141 }
142
143 // Scale and translate the mesh
144
145 TriangleSet<T> triangleSet(triangles);
146
147 triangleSet.scale(radius);
148 triangleSet.translate(center);
149
150 return triangleSet;
151}
152
153template<typename T>
154plb::Array<T,3> spherePointToRBCPoint(const plb::Array<T,3> point, T R) {
155 plb::Array<T,3> rbcPoint(point);
156 T r2 = rbcPoint[0]*rbcPoint[0] + rbcPoint[1]*rbcPoint[1];
157 T val = rbcPoint[2];
158 plint sign = (T(0) < val) - (val < T(0));
159 rbcPoint[0] *= R;
160 rbcPoint[1] *= R;
161 if (1-r2 <0) {
162 r2 =1 ;
163 }
164 //T C0 = 0.0135805, C2 = 1.001279, C4 = -0.561381;
165 T C0 = 0.054322, C2 = 1.001279, C4 = -0.561381;
166 rbcPoint[2] = sign * R * sqrt(1-r2) * (C0 + C2*r2 + C4*r2*r2);
167 return rbcPoint;
168}
169
170template<typename T>
171plb::Array<T,3> spherePointToEllipsoidPoint(const plb::Array<T,3> point, T R, T aspectRatio) {
172 plb::Array<T,3> elPoint(point);
173 T r2 = elPoint[0]*elPoint[0] + elPoint[1]*elPoint[1];
174 T val = elPoint[2];
175 plint sign = (T(0) < val) - (val < T(0));
176 if (1-r2 <0) {
177 r2 =1 ;
178 }
179 elPoint[0] *= R;
180 elPoint[1] *= R;
181 elPoint[2] = sign * aspectRatio * R * sqrt(1-r2) ;
182 return elPoint;
183}
184
185template<typename T>
186plb::Array<T,3> mapMeshAsRBC(const plb::Array<T,3> point, const plb::Array<T,3> center, T R) {
187 plb::Array<T,3> rbcPoint(point - center);
188 rbcPoint[0] = rbcPoint[0] > R ? R : rbcPoint[0];
189 rbcPoint[1] = rbcPoint[1] > R ? R : rbcPoint[1];
190 T r2 = rbcPoint[0]*rbcPoint[0] + rbcPoint[1]*rbcPoint[1];
191 //T C0 = 0.02716, C2 = 2.0024, C4 = -1.123;
192 T C0 = 0.02716, C2 = 2.0024, C4 = -1.123;
193 T val = rbcPoint[2];
194 plint sign = (T(0) < val) - (val < T(0));
195// rbcPoint[0] *= R;
196// rbcPoint[1] *= R;
197 r2 = r2 / (R*R);
198 if (1-r2 <0) {
199 r2 =1 ;
200 }
201 rbcPoint[2] = sign * 0.5 * R * sqrt(1-r2) * (C0 + C2*r2 + C4*r2*r2);
202 rbcPoint = (rbcPoint + center);
203 return rbcPoint;
204}
205
206
207template<typename T>
208TriangleSet<T> constructRBC(plb::Array<T,3> const& center, T radius, plint minNumOfTriangles, plb::Array<T,3> const& eulerAngles) {
209 return constructCell(center, radius, "./lib/RBC.stl", eulerAngles);
210}
211
212
213template<typename T>
214TriangleSet<T> constructRBCFromSphere(plb::Array<T,3> const& center, T radius, plint minNumOfTriangles,
215 plb::Array<T,3> const& eulerAngles, pluint initialSphereShape)
216{
217 TriangleSet<T> sphere;
218 if (initialSphereShape == 1) {
219 sphere = constructSphereIcosahedron<T>(plb::Array<T,3>(0,0,0), 1.0, minNumOfTriangles);
220 } else if (initialSphereShape == 0) {
221 sphere = constructSphere<T>(plb::Array<T,3>(0,0,0), 1.0, minNumOfTriangles);
222 }
223 sphere.rotate(
224 PI/2.0 + eulerAngles[0],
225 PI/2.0 + eulerAngles[1],
226 0. + eulerAngles[2]);
227 std::vector<typename TriangleSet<T>::Triangle> rbcTriangles = sphere.getTriangles();
228 for (pluint var = 0; var < rbcTriangles.size(); ++var) {
229 rbcTriangles[var][0] = spherePointToRBCPoint(rbcTriangles[var][0]);
230 rbcTriangles[var][1] = spherePointToRBCPoint(rbcTriangles[var][1]);
231 rbcTriangles[var][2] = spherePointToRBCPoint(rbcTriangles[var][2]);
232 }
233 TriangleSet<T> rbc(rbcTriangles);
234 rbc.scale(radius);
235 rbc.rotate(
236 PI/2.0 + eulerAngles[0],
237 PI/2.0 + eulerAngles[1],
238 0. + eulerAngles[2]);
239 rbc.translate(center);
240 return rbc;
241}
242
243
244template<typename T>
245TriangleSet<T> constructEllipsoidFromSphere(plb::Array<T,3> const& center, T radius, T aspectRatio, plint minNumOfTriangles,
246 plb::Array<T,3> const& eulerAngles, pluint initialSphereShape)
247{
248 TriangleSet<T> sphere;
249 if (initialSphereShape == 1) {
250 sphere = constructSphereIcosahedron<T>(plb::Array<T,3>(0,0,0), 1.0, minNumOfTriangles);
251 } else if (initialSphereShape == 0) {
252 sphere = constructSphere<T>(plb::Array<T,3>(0,0,0), 1.0, minNumOfTriangles);
253 }
254 sphere.rotate(
255 PI/2.0 + eulerAngles[0],
256 PI/2.0 + eulerAngles[1],
257 0. + eulerAngles[2]);
258 std::vector<typename TriangleSet<T>::Triangle> ellipsoidTriangles = sphere.getTriangles();
259 for (pluint var = 0; var < ellipsoidTriangles.size(); ++var) {
260 ellipsoidTriangles[var][0] = spherePointToEllipsoidPoint(ellipsoidTriangles[var][0], radius, aspectRatio);
261 ellipsoidTriangles[var][1] = spherePointToEllipsoidPoint(ellipsoidTriangles[var][1], radius, aspectRatio);
262 ellipsoidTriangles[var][2] = spherePointToEllipsoidPoint(ellipsoidTriangles[var][2], radius, aspectRatio);
263 }
264 TriangleSet<T> ellipsoid(ellipsoidTriangles);
265 ellipsoid.rotate(
266 PI/2.0 + eulerAngles[0],
267 PI/2.0 + eulerAngles[1],
268 0. + eulerAngles[2]);
269 ellipsoid.translate(center);
270 return ellipsoid;
271}
272
273
274template<typename T>
275TriangleSet<T> constructCell(plb::Array<T,3> const& center, T radius, std::string cellFilename, plb::Array<T,3> const& eulerAngles) {
276// Cuboid<T> boundingCuboid;
277 TriangleSet<T> Cell(cellFilename);
278 Cuboid<T> cb = Cell.getBoundingCuboid();
279 plb::Array<T,3> dr = (cb.upperRightCorner - cb.lowerLeftCorner);
280 T scaleFactor = std::max(dr[0],std::max(dr[1],dr[2]));
281 Cell.scale(radius*2.0/scaleFactor);
282 Cell.rotate(
283 PI/2.0 + eulerAngles[0],
284 PI/2.0 + eulerAngles[1],
285 0. + eulerAngles[2]);
286 Cell.translate(center);
287 return Cell;
288}
289
290} // namespace plb
291
292#endif // MESH_GENERATING_FUNCTIONS_HH
#define PI
Definition constant_defaults.h:122
double T
Definition constant_defaults.h:118
long int plint
Definition constant_defaults.h:127
long unsigned int pluint
Definition constant_defaults.h:130
Definition meshGeneratingFunctions.cpp:28
plb::Array< T, 3 > spherePointToEllipsoidPoint(const plb::Array< T, 3 > point, T R, T aspectRatio)
Definition meshGeneratingFunctions.hh:171
plb::Array< T, 3 > mapMeshAsRBC(const plb::Array< T, 3 > point, const plb::Array< T, 3 > center, T R)
Definition meshGeneratingFunctions.hh:186
TriangleSet< T > constructCell(plb::Array< T, 3 > const &center, T radius, std::string cellFilename, plb::Array< T, 3 > const &eulerAngles)
Definition meshGeneratingFunctions.hh:275
plb::Array< T, 3 > spherePointToRBCPoint(const plb::Array< T, 3 > point, T R=1.0)
Definition meshGeneratingFunctions.hh:154
TriangleSet< T > constructRBCFromSphere(plb::Array< T, 3 > const &center, T radius, plint minNumOfTriangles, plb::Array< T, 3 > const &eulerAngles, pluint initialSphereShape=0)
Definition meshGeneratingFunctions.hh:214
TriangleSet< T > constructRBC(plb::Array< T, 3 > const &center, T radius, plint minNumOfTriangles, plb::Array< T, 3 > const &eulerAngles)
Definition meshGeneratingFunctions.hh:208
TriangleSet< T > constructEllipsoidFromSphere(plb::Array< T, 3 > const &center, T radius, T aspectRatio, plint minNumOfTriangles, plb::Array< T, 3 > const &eulerAngles, pluint initialSphereShape)
Definition meshGeneratingFunctions.hh:245
TriangleSet< T > constructSphereIcosahedron(plb::Array< T, 3 > const &center, T radius, plint minNumOfTriangles)
Definition meshGeneratingFunctions.hh:32