PeriDyno 1.0.0
Loading...
Searching...
No Matches
SphereModel.cpp
Go to the documentation of this file.
1#include "SphereModel.h"
2
4
8
9#include "Mapping/Extract.h"
10#include "Subdivide.h"
11
12namespace dyno
13{
14 template<typename TDataType>
16 : BasicShape<TDataType>()
17 {
18 this->varRadius()->setRange(0.001f, 100.0f);
19
20 this->stateTriangleSet()->setDataPtr(std::make_shared<TriangleSet<TDataType>>());
21
22 this->statePolygonSet()->setDataPtr(std::make_shared<PolygonSet<TDataType>>());
23
24 this->varLatitude()->setRange(2, 10000);
25 this->varLongitude()->setRange(3, 10000);
26 this->varIcosahedronStep()->setRange(0,6);
27
28 auto callback = std::make_shared<FCallBackFunc>(std::bind(&SphereModel<TDataType>::varChanged, this));
29
30
31 this->varLocation()->attach(callback);
32 this->varScale()->attach(callback);
33 this->varRotation()->attach(callback);
34 this->varRadius()->attach(callback);
35 this->varLatitude()->attach(callback);
36 this->varLongitude()->attach(callback);
37 this->varType()->attach(callback);
38
39 auto tsRender = std::make_shared<GLSurfaceVisualModule>();
40 this->stateTriangleSet()->connect(tsRender->inTriangleSet());
41 this->graphicsPipeline()->pushModule(tsRender);
42
43 auto exES = std::make_shared<ExtractEdgeSetFromPolygonSet<TDataType>>();
44 this->statePolygonSet()->connect(exES->inPolygonSet());
45 this->graphicsPipeline()->pushModule(exES);
46
47 auto esRender = std::make_shared<GLWireframeVisualModule>();
48 esRender->varBaseColor()->setValue(Color(0, 0, 0));
49 exES->outEdgeSet()->connect(esRender->inEdgeSet());
50 this->graphicsPipeline()->pushModule(esRender);
51
52 this->stateTriangleSet()->promoteOuput();
53 this->statePolygonSet()->promoteOuput();
54 }
55
56 template<typename TDataType>
61
62 template<typename TDataType>
64 {
65
66 auto center = this->varLocation()->getData();
67 auto rot = this->varRotation()->getData();
68 auto scale = this->varScale()->getData();
69
70 auto radius = this->varRadius()->getData();
71
72 Coord length(radius);
73 length[0] *= scale[0];
74 length[1] *= scale[1];
75 length[2] *= scale[2];
76
77 Quat<Real> q = this->computeQuaternion();
78
79 q.normalize();
80
82 box.center = center;
83 box.u = q.rotate(Coord(1, 0, 0));
84 box.v = q.rotate(Coord(0, 1, 0));
85 box.w = q.rotate(Coord(0, 0, 1));
86 box.extent = length;
87
88 auto AABB = box.aabb();
89 auto& v0 = AABB.v0;
90 auto& v1 = AABB.v1;
91
92
93 NBoundingBox ret;
94 ret.lower = Vec3f(v0.x, v0.y, v0.z);
95 ret.upper = Vec3f(v1.x, v1.y, v1.z);
96
97 return ret;
98 }
99
100 template<typename TDataType>
102 {
103
104 auto center = this->varLocation()->getValue();
105 auto rot = this->varRotation()->getValue();
106 auto scale = this->varScale()->getValue();
107
108 auto radius = this->varRadius()->getValue();
109
110 auto latitude = this->varLatitude()->getValue();
111 auto longitude = this->varLongitude()->getValue();
112
113 auto type = this->varType()->getValue();
114
115 auto polySet = this->statePolygonSet()->getDataPtr();
116
117 std::vector<Coord> vertices;
118
119
120 Real deltaTheta = M_PI / latitude;
121 Real deltaPhi = 2 * M_PI / longitude;
122
123 //Setup vertices
124 vertices.push_back(Coord(0, radius, 0));
125
126 Real theta = 0;
127 for (uint i = 0; i < latitude - 1; i++)
128 {
129 theta += deltaTheta;
130
131 Real phi = 0;
132 for (uint j = 0; j < longitude; j++)
133 {
134 phi += deltaPhi;
135
136 Real y = radius * std::cos(theta);
137 Real x = (std::sin(theta) * radius) * std::sin(phi);
138 Real z = (std::sin(theta) * radius) * std::cos(phi);
139
140 vertices.push_back(Coord(x, y, z));
141 }
142 }
143
144 vertices.push_back(Coord(0, -radius, 0));
145
146 //Setup polygon indices
147 uint numOfPolygon = latitude * longitude;
148
149 CArray<uint> counter(numOfPolygon);
150
151 uint incre = 0;
152 for (uint j = 0; j < longitude; j++)
153 {
154 counter[incre] = 3;
155 incre++;
156 }
157
158 for (uint i = 0; i < latitude - 2; i++)
159 {
160 for (uint j = 0; j < longitude; j++)
161 {
162 counter[incre] = 4;
163 incre++;
164 }
165 }
166
167 for (uint j = 0; j < longitude; j++)
168 {
169 counter[incre] = 3;
170 incre++;
171 }
172
173 CArrayList<uint> polygonIndices;
174 polygonIndices.resize(counter);
175
176 incre = 0;
177 uint offset = 1;
178 for (uint j = 0; j < longitude; j++)
179 {
180 auto& index = polygonIndices[incre];
181 index.insert(0);
182 index.insert(offset + j);
183 index.insert(offset + (j + 1) % longitude);
184
185 incre++;
186 }
187
188 for (uint i = 0; i < latitude - 2; i++)
189 {
190 for (uint j = 0; j < longitude; j++)
191 {
192 auto& index = polygonIndices[incre];
193 index.insert(offset + j);
194 index.insert(offset + j + longitude);
195 index.insert(offset + (j + 1) % longitude + longitude);
196 index.insert(offset + (j + 1) % longitude);
197
198 incre++;
199 }
200 offset += longitude;
201 }
202
203 for (uint j = 0; j < longitude; j++)
204 {
205 auto& index = polygonIndices[incre];
206 index.insert(offset + j);
207 index.insert(vertices.size() - 1);
208 index.insert(offset + (j + 1) % longitude);
209
210 incre++;
211 }
212
213 //Apply transformation
214 Quat<Real> q = this->computeQuaternion();
215
216 auto RV = [&](const Coord& v)->Coord {
217 return center + q.rotate(v - center);
218 };
219
220 int numpt = vertices.size();
221
222 for (int i = 0; i < numpt; i++) {
223 vertices[i] = RV(vertices[i] * scale + RV(center));
224 }
225
226 polySet->setPoints(vertices);
227 polySet->setPolygons(polygonIndices);
228 polySet->update();
229
230 polygonIndices.clear();
231
232 auto& ts = this->stateTriangleSet()->getData();
233 polySet->turnIntoTriangleSet(ts);
234
235 vertices.clear();
236 }
237
238 template<typename TDataType>
240 {
241 std::vector<Vec3f> vts;
242 std::vector<TopologyModule::Triangle> trs;
243
244 generateIcosahedron(vts, trs);
245 float fixScale = this->varIcosahedronStep()->getValue() >= 2 ? 1.08 : 1;
246
247 Quat<Real> q = this->computeQuaternion();
248 auto center = this->varLocation()->getData();
249 auto scale = this->varScale()->getData();
250
251 auto RV = [&](const Coord& v)->Coord {
252 return center + q.rotate(v - center);
253 };
254
255 for (int i = 0; i < vts.size(); i++) {
256 vts[i] = RV(vts[i] * scale * fixScale + RV(center));
257 }
258
259 if (this->varIcosahedronStep()->getValue() >= 2)
260 {
261 for (int i = 0; i < (int)this->varIcosahedronStep()->getValue() - 1; i++)
262 {
263 loopSubdivide(vts, trs);
264 }
265 }
266
267
268 this->stateTriangleSet()->getDataPtr()->setPoints(vts);
269 this->stateTriangleSet()->getDataPtr()->setTriangles(trs);
270 this->stateTriangleSet()->getDataPtr()->update();
271
272 this->statePolygonSet()->getDataPtr()->triangleSetToPolygonSet(this->stateTriangleSet()->getData());
273
274 return;
275 }
276
277
278
279 template<typename TDataType>
281 {
282 auto center = this->varLocation()->getValue();
283 auto rot = this->varRotation()->getValue();
284 auto scale = this->varScale()->getValue();
285
286 auto radius = this->varRadius()->getValue();
287
288 //Setup a sphere primitive
289 TSphere3D<Real> ball;
290 ball.center = center;
291 ball.radius = radius;
292 this->outSphere()->setValue(ball);
293
294 if (this->varType()->getDataPtr()->currentKey() == SphereType::Icosahedron)
295 {
297 }
298 else {
300 }
301
302 }
303
304
305 template<typename TDataType>
306 void SphereModel<TDataType>::generateIcosahedron(std::vector<Vec3f>& vertices, std::vector<TopologyModule::Triangle>& triangles)
307 {
308 auto radius = this->varRadius()->getValue() * 2;
309
310 if (this->varIcosahedronStep()->getValue() == 0)
311 {
312 float phi = (1.0 + std::sqrt(5.0)) / 2.0;
313
314 vertices = {
315 Vec3f(-1, phi, 0), Vec3f(1, phi, 0), Vec3f(-1, -phi, 0), Vec3f(1, -phi, 0),
316 Vec3f(0, -1, phi), Vec3f(0, 1, phi), Vec3f(0, -1, -phi), Vec3f(0, 1, -phi),
317 Vec3f(phi, 0, -1), Vec3f(phi, 0, 1), Vec3f(-phi, 0, -1), Vec3f(-phi, 0, 1)
318 };
319
320 triangles = {
325 };
326
327 for (auto& v : vertices) {
328 v = v / M_PI * radius;
329 }
330 }
331 else
332 {
333 vertices =
334 {
335 Vec3f(0,0, -0.5) * radius,
336 Vec3f(0, 0.262865603, -0.425325394) * radius,
337 Vec3f(0.249999985, 0.0812300518, -0.425325394) * radius,
338 Vec3f(0, 0.44721368, -0.223606572) * radius,
339 Vec3f(0.249999985, 0.344095677, -0.262865305) * radius,
340 Vec3f(0.425325423, 0.138196841, -0.223606601) * radius,
341 Vec3f(0.154508501, -0.212662712, -0.425325423) * radius,
342 Vec3f(0.404508621, -0.131432697, -0.262865394) * radius,
343 Vec3f(0.262865603, -0.361803472, -0.223606631) * radius,
344 Vec3f(-0.154508501, -0.212662712, -0.425325423) * radius,
345 Vec3f(0, -0.425325513, -0.262865365) * radius,
346 Vec3f(-0.262865603, -0.361803472, -0.223606631) * radius,
347 Vec3f(-0.249999985, 0.0812300518, -0.425325394) * radius,
348 Vec3f(-0.404508621, -0.131432697, -0.262865394) * radius,
349 Vec3f(-0.425325423, 0.138196841, -0.223606601) * radius,
350 Vec3f(-0.249999985, 0.344095677, -0.262865305) * radius,
351 Vec3f(-0.154508486, 0.4755283, 0) * radius,
352 Vec3f(-0.404508412, 0.293892711, 0) * radius,
353 Vec3f(-0.262865603, 0.361803472, 0.223606631) * radius,
354 Vec3f(-0.5, 0, 0) * radius,
355 Vec3f(-0.404508412, -0.293892711, 0) * radius,
356 Vec3f(-0.425325423, -0.138196841, 0.223606601) * radius,
357 Vec3f(-0.154508486, -0.4755283, 0) * radius,
358 Vec3f(0.154508486, -0.4755283, 0) * radius,
359 Vec3f(0, -0.44721368, 0.223606572) * radius,
360 Vec3f(0.404508412, -0.293892711, 0) * radius,
361 Vec3f(0.5, 0 ,0) * radius,
362 Vec3f(0.425325423, -0.138196841, 0.223606601) * radius,
363 Vec3f(0.404508412, 0.293892711, 0) * radius,
364 Vec3f(0.154508486, 0.4755283, 0) * radius,
365 Vec3f(0.262865603, 0.361803472 ,0.223606631) * radius,
366 Vec3f(0, 0.425325513, 0.262865365) * radius,
367 Vec3f(-0.404508621, 0.131432697, 0.262865394) * radius,
368 Vec3f(-0.249999985, -0.344095677, 0.262865305) * radius,
369 Vec3f(0.249999985, -0.344095677, 0.262865305) * radius,
370 Vec3f(0.404508621, 0.131432697, 0.262865394) * radius,
371 Vec3f(0, 0, 0.5) * radius,
372 Vec3f(0.154508501, 0.212662712 ,0.425325423) * radius,
373 Vec3f(-0.154508501, 0.212662712, 0.425325423) * radius,
374 Vec3f(0.249999985, -0.0812300518, 0.425325394) * radius,
375 Vec3f(0, -0.262865603, 0.425325394) * radius,
376 Vec3f(-0.249999985, -0.0812300518, 0.425325394) * radius
377 };
378
379 triangles =
380 {
389 TopologyModule::Triangle(10, 1, 7),
390 TopologyModule::Triangle(11, 7, 9),
391 TopologyModule::Triangle(12, 10, 11),
392 TopologyModule::Triangle(10, 7, 11),
393 TopologyModule::Triangle(13, 1, 10),
394 TopologyModule::Triangle(14, 10, 12),
395 TopologyModule::Triangle(15, 13, 14),
396 TopologyModule::Triangle(13, 10, 14),
397 TopologyModule::Triangle(2 ,1, 13),
398 TopologyModule::Triangle(16, 13, 15),
399 TopologyModule::Triangle(4 ,2, 16),
400 TopologyModule::Triangle(2 ,13, 16),
401 TopologyModule::Triangle(17, 4, 16),
402 TopologyModule::Triangle(18, 16, 15),
403 TopologyModule::Triangle(19, 17, 18),
404 TopologyModule::Triangle(17, 16, 18),
405 TopologyModule::Triangle(20, 15, 14),
406 TopologyModule::Triangle(21, 14, 12),
407 TopologyModule::Triangle(22, 20, 21),
408 TopologyModule::Triangle(20, 14, 21),
409 TopologyModule::Triangle(23, 12, 11),
410 TopologyModule::Triangle(24, 11, 9),
411 TopologyModule::Triangle(25, 23, 24),
412 TopologyModule::Triangle(23, 11, 24),
413 TopologyModule::Triangle(26, 9, 8),
414 TopologyModule::Triangle(27, 8, 6),
415 TopologyModule::Triangle(28, 26, 27),
416 TopologyModule::Triangle(26, 8, 27),
417 TopologyModule::Triangle(29, 6, 5),
418 TopologyModule::Triangle(30, 5, 4),
419 TopologyModule::Triangle(31, 29, 30),
420 TopologyModule::Triangle(29, 5, 30),
421 TopologyModule::Triangle(30, 4, 17),
422 TopologyModule::Triangle(32, 17, 19),
423 TopologyModule::Triangle(31, 30, 32),
424 TopologyModule::Triangle(30, 17, 32),
425 TopologyModule::Triangle(18, 15, 20),
426 TopologyModule::Triangle(33, 20, 22),
427 TopologyModule::Triangle(19, 18, 33),
428 TopologyModule::Triangle(18, 20, 33),
429 TopologyModule::Triangle(21, 12, 23),
430 TopologyModule::Triangle(34, 23, 25),
431 TopologyModule::Triangle(22, 21, 34),
432 TopologyModule::Triangle(21, 23, 34),
433 TopologyModule::Triangle(24, 9, 26),
434 TopologyModule::Triangle(35, 26, 28),
435 TopologyModule::Triangle(25, 24, 35),
436 TopologyModule::Triangle(24, 26, 35),
437 TopologyModule::Triangle(27, 6, 29),
438 TopologyModule::Triangle(36, 29, 31),
439 TopologyModule::Triangle(28, 27, 36),
440 TopologyModule::Triangle(27, 29, 36),
441 TopologyModule::Triangle(39, 37, 38),
442 TopologyModule::Triangle(32, 38, 31),
443 TopologyModule::Triangle(19, 39, 32),
444 TopologyModule::Triangle(39, 38, 32),
445 TopologyModule::Triangle(38, 37, 40),
446 TopologyModule::Triangle(36, 40, 28),
447 TopologyModule::Triangle(31, 38, 36),
448 TopologyModule::Triangle(38, 40, 36),
449 TopologyModule::Triangle(40, 37, 41),
450 TopologyModule::Triangle(35, 41, 25),
451 TopologyModule::Triangle(28, 40, 35),
452 TopologyModule::Triangle(40, 41, 35),
453 TopologyModule::Triangle(41, 37, 42),
454 TopologyModule::Triangle(34, 42, 22),
455 TopologyModule::Triangle(25, 41, 34),
456 TopologyModule::Triangle(41, 42, 34),
457 TopologyModule::Triangle(42, 37, 39),
458 TopologyModule::Triangle(33, 39, 19),
459 TopologyModule::Triangle(22, 42, 33),
460 TopologyModule::Triangle(42, 39, 33)
461 };
462 for (size_t i = 0; i < triangles.size(); i++)
463 {
464 triangles[i] = TopologyModule::Triangle(triangles[i][0] - 1, triangles[i][1] - 1, triangles[i][2] - 1);
465 }
466
467 }
468 }
469
470
471
472
474}
#define DEFINE_CLASS(name)
Definition Object.h:140
#define M_PI
Definition Typedef.inl:36
std::shared_ptr< GraphicsPipeline > graphicsPipeline()
Definition Node.cpp:320
Quat< Real > computeQuaternion()
a class to store polygon whose vertex number is greater or equal than 3
Definition PolygonSet.h:29
DYN_FUNC Quat< Real > & normalize()
Definition Quat.inl:183
DYN_FUNC Vector< Real, 3 > rotate(const Vector< Real, 3 > &v) const
Rotate a vector by the quaternion, guarantee the quaternion is normalized before rotating the vector.
Definition Quat.inl:259
void generateIcosahedron(std::vector< Vec3f > &vertices, std::vector< TopologyModule::Triangle > &triangles)
void resetStates() override
NBoundingBox boundingBox() override
TDataType::Real Real
Definition SphereModel.h:36
TDataType::Coord Coord
Definition SphereModel.h:37
Coord3D u
three unit vectors u, v and w forming a right-handed orthornormal basis
Coord3D extent
half the dimension in each of the u, v, and w directions
Coord3D center
centerpoint
DYN_FUNC TAlignedBox3D< Real > aabb()
3D geometric primitives in three-dimensional space
Vector< PointType, 3 > Triangle
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
void loopSubdivide(std::vector< Vec3f > &vertices, std::vector< TopologyModule::Triangle > &triangles)
Definition Subdivide.cpp:11
ArrayList< T, DeviceType::CPU > CArrayList
Definition ArrayList.h:207
::dyno::TAlignedBox3D< Real > AABB
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
Array< T, DeviceType::CPU > CArray
Definition Array.h:151
unsigned int uint
Definition VkProgram.h:14