PeriDyno 1.0.0
Loading...
Searching...
No Matches
CubeModel.cpp
Go to the documentation of this file.
1#include "CubeModel.h"
2
5
7#include "Mapping/Extract.h"
8
9
10namespace dyno
11{
12 template<typename TDataType>
14 : BasicShape<TDataType>()
15 {
16 this->varLength()->setRange(0.01, 100.0f);
17 this->varSegments()->setRange(1, 100);
18
19 this->statePolygonSet()->setDataPtr(std::make_shared<PolygonSet<TDataType>>());
20
21 this->stateTriangleSet()->setDataPtr(std::make_shared<TriangleSet<TDataType>>());
22
23 this->stateQuadSet()->setDataPtr(std::make_shared<QuadSet<TDataType>>());
24
25 auto callback = std::make_shared<FCallBackFunc>(std::bind(&CubeModel<TDataType>::varChanged, this));
26
27 this->varLocation()->attach(callback);
28 this->varScale()->attach(callback);
29 this->varRotation()->attach(callback);
30
31 this->varSegments()->attach(callback);
32 this->varLength()->attach(callback);
33
34 auto tsRender = std::make_shared<GLSurfaceVisualModule>();
35 tsRender->setVisible(true);
36 this->stateTriangleSet()->connect(tsRender->inTriangleSet());
37 this->graphicsPipeline()->pushModule(tsRender);
38
39 auto exES = std::make_shared<ExtractEdgeSetFromPolygonSet<TDataType>>();
40 this->statePolygonSet()->connect(exES->inPolygonSet());
41 this->graphicsPipeline()->pushModule(exES);
42
43 auto esRender = std::make_shared<GLWireframeVisualModule>();
44 esRender->varBaseColor()->setValue(Color(0, 0, 0));
45 exES->outEdgeSet()->connect(esRender->inEdgeSet());
46 this->graphicsPipeline()->pushModule(esRender);
47
48 //this->statePolygonSet()->promoteOuput();
49 this->stateTriangleSet()->promoteOuput();
50 this->stateQuadSet()->promoteOuput();
51 this->statePolygonSet()->promoteOuput();
52 }
53
54 struct Index2D
55 {
56 Index2D() : x(), y() {}
57 Index2D(int x, int y) : x(x), y(y) {}
58 int x, y;
59 };
60
61 bool operator<(const Index2D& lhs, const Index2D& rhs)
62 {
63 return lhs.x != rhs.x ? lhs.x < rhs.x : lhs.y < rhs.y;
64 }
65
66 template<typename TDataType>
68 {
69 NBoundingBox bound;
70
71 auto box = this->outCube()->getData();
72 auto aabb = box.aabb();
73
74 Coord v0 = aabb.v0;
75 Coord v1 = aabb.v1;
76
77 bound.lower = Vec3f(v0.x, v0.y, v0.z);
78 bound.upper = Vec3f(v1.x, v1.y, v1.z);
79
80 return bound;
81 }
82
83 template<typename TDataType>
88
89 template<typename TDataType>
91 {
92 auto center = this->varLocation()->getValue();
93 auto rot = this->varRotation()->getValue();
94 auto scale = this->varScale()->getValue();
95
96 auto length = this->varLength()->getValue();
97
98
99 length[0] *= scale[0];
100 length[1] *= scale[1];
101 length[2] *= scale[2];
102
103 Quat<Real> q = this->computeQuaternion();
104
105 q.normalize();
106
108 box.center = center;
109 box.u = q.rotate(Coord(1, 0, 0));
110 box.v = q.rotate(Coord(0, 1, 0));
111 box.w = q.rotate(Coord(0, 0, 1));
112 box.extent = 0.5 * length;
113
114 this->outCube()->setValue(box);
115
116 auto segments = this->varSegments()->getValue();
117
118 uint nyz = 2 * (segments[1] + segments[2]);
119
120 std::vector<Coord> vertices;
121 //std::vector<TopologyModule::Quad> quads;
122
123 Real dx = length[0] / segments[0];
124 Real dy = length[1] / segments[1];
125 Real dz = length[2] / segments[2];
126
127 std::map<Index2D, uint> indexTop;
128 std::map<Index2D, uint> indexBottom;
129
130 //A lambda function to rotate a vertex
131 auto RV = [&](const Coord& v)->Coord {
132 return center + q.rotate(v - center);
133 };
134
135 uint numOfPolygon = 2 * (segments[0] * segments[1] + segments[0] * segments[2] + segments[1] * segments[2]);
136
137 CArray<uint> counter2(numOfPolygon);
138
139 uint incre = 0;
140
141 for (uint j = 0; j < numOfPolygon; j++)
142 {
143 counter2[incre] = 4;
144 incre++;
145 }
146
147 CArrayList<uint> polygonIndices;
148 polygonIndices.resize(counter2);
149
150 incre = 0;
151
152 int v0, v1, v2, v3;
153
154 //Rim
155 uint counter = 0;
156 Real x, y, z;
157 for (int nx = 0; nx < segments[0] + 1; nx++)
158 {
159 x = center[0] - length[0] / 2 + nx * dx;
160
161 z = center[2] - length[2] / 2;
162 for (int ny = 0; ny < segments[1]; ny++)
163 {
164 if (nx == 0)
165 indexBottom[Index2D(ny, 0)] = vertices.size();
166
167 if (nx == segments[0])
168 indexTop[Index2D(ny, 0)] = vertices.size();
169
170 Real y = center[1] - length[1] / 2 + dy * ny;
171 vertices.push_back(RV(Coord(x, y, z)));
172 }
173
174 y = center[1] + length[1] / 2;
175 for (int nz = 0; nz < segments[2]; nz++)
176 {
177 if (nx == 0)
178 indexBottom[Index2D(segments[1], nz)] = vertices.size();
179
180 if (nx == segments[0])
181 indexTop[Index2D(segments[1], nz)] = vertices.size();
182
183 Real z = center[2] - length[2] / 2 + dz * nz;
184 vertices.push_back(RV(Coord(x, y, z)));
185 }
186
187 z = center[2] + length[2] / 2;
188 for (int ny = segments[1]; ny > 0; ny--)
189 {
190 if (nx == 0)
191 indexBottom[Index2D(ny, segments[2])] = vertices.size();
192
193 if (nx == segments[0])
194 indexTop[Index2D(ny, segments[2])] = vertices.size();
195
196 Real y = center[1] - length[1] / 2 + dy * ny;
197 vertices.push_back(RV(Coord(x, y, z)));
198 }
199
200 y = center[1] - length[1] / 2;
201 for (int nz = segments[2]; nz > 0; nz--)
202 {
203 if (nx == 0)
204 indexBottom[Index2D(0, nz)] = vertices.size();
205
206 if (nx == segments[0])
207 indexTop[Index2D(0, nz)] = vertices.size();
208
209 Real z = center[2] - length[2] / 2 + dz * nz;
210 vertices.push_back(RV(Coord(x, y, z)));
211 }
212
213 if (nx < segments[0])
214 {
215 for (int t = 0; t < nyz - 1; t++)
216 {
217 v0 = counter + t;
218 v1 = counter + t + 1;
219 v2 = counter + t + nyz + 1;
220 v3 = counter + t + nyz;
221
222 auto& quads = polygonIndices[incre];
223
224 quads.insert(v0);
225 quads.insert(v1);
226 quads.insert(v2);
227 quads.insert(v3);
228
229 incre++;
230 }
231
232 v0 = counter + nyz - 1;
233 v1 = counter;
234 v2 = counter + nyz;
235 v3 = counter + 2 * nyz - 1;
236
237 auto& quads = polygonIndices[incre];
238
239 quads.insert(v0);
240 quads.insert(v1);
241 quads.insert(v2);
242 quads.insert(v3);
243
244 incre++;
245
246 }
247
248 counter += nyz;
249 }
250
251 //Top
252 x = center[0] + length[0] / 2;
253 for (int ny = 1; ny < segments[1]; ny++)
254 {
255 for (int nz = 1; nz < segments[2]; nz++)
256 {
257 indexTop[Index2D(ny, nz)] = vertices.size();
258
259 y = center[1] - length[1] / 2 + ny * dy;
260 z = center[2] - length[2] / 2 + nz * dz;
261 vertices.push_back(RV(Coord(x, y, z)));
262 }
263 }
264
265 for (int ny = 0; ny < segments[1]; ny++)
266 {
267 for (int nz = 0; nz < segments[2]; nz++)
268 {
269 v0 = indexTop[Index2D(ny, nz)];
270 v1 = indexTop[Index2D(ny + 1, nz)];
271 v2 = indexTop[Index2D(ny + 1, nz + 1)];
272 v3 = indexTop[Index2D(ny, nz + 1)];
273
274 auto& quads = polygonIndices[incre];
275
276 quads.insert(v0);
277 quads.insert(v1);
278 quads.insert(v2);
279 quads.insert(v3);
280
281 incre++;
282
283
284 }
285 }
286
287
288 x = center[0] - length[0] / 2;
289 for (int ny = 1; ny < segments[1]; ny++)
290 {
291 for (int nz = 1; nz < segments[2]; nz++)
292 {
293 indexBottom[Index2D(ny, nz)] = vertices.size();
294
295 y = center[1] - length[1] / 2 + ny * dy;
296 z = center[2] - length[2] / 2 + nz * dz;
297 vertices.push_back(RV(Coord(x, y, z)));
298 }
299 }
300
301 for (int ny = 0; ny < segments[1]; ny++)
302 {
303 for (int nz = 0; nz < segments[2]; nz++)
304 {
305 v0 = indexBottom[Index2D(ny, nz)];
306 v1 = indexBottom[Index2D(ny + 1, nz)];
307 v2 = indexBottom[Index2D(ny + 1, nz + 1)];
308 v3 = indexBottom[Index2D(ny, nz + 1)];
309
310 auto& quads = polygonIndices[incre];
311
312 quads.insert(v3);
313 quads.insert(v2);
314 quads.insert(v1);
315 quads.insert(v0);
316
317 incre++;
318
319
320 }
321 }
322
323 auto polySet = this->statePolygonSet()->getDataPtr();
324
325 polySet->setPoints(vertices);
326 polySet->setPolygons(polygonIndices);
327 polySet->update();
328
329 polygonIndices.clear();
330
331 auto& ts = this->stateTriangleSet()->getData();
332 polySet->turnIntoTriangleSet(ts);
333
334 auto& qs = this->stateQuadSet()->getData();
335 polySet->extractQuadSet(qs);
336
337 vertices.clear();
338
339 indexTop.clear();
340 indexBottom.clear();
341 vertices.clear();
342
343 }
344
345
347}
#define DEFINE_CLASS(name)
Definition Object.h:140
TDataType::Real Real
Definition CubeModel.h:31
void resetStates() override
Definition CubeModel.cpp:84
TDataType::Coord Coord
Definition CubeModel.h:32
NBoundingBox boundingBox() override
Definition CubeModel.cpp:67
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
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
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
ArrayList< T, DeviceType::CPU > CArrayList
Definition ArrayList.h:207
DYN_FUNC bool operator<(const priority_queue< T, Container, Compare > &a, const priority_queue< T, Container, Compare > &b)
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
Array< T, DeviceType::CPU > CArray
Definition Array.h:151
unsigned int uint
Definition VkProgram.h:14
Index2D(int x, int y)
Definition CubeModel.cpp:57