PeriDyno 1.0.0
Loading...
Searching...
No Matches
Subdivide.cpp
Go to the documentation of this file.
1
2#include "Subdivide.h"
3
7
8namespace dyno
9{
10
11 void loopSubdivide(std::vector<Vec3f>& vertices, std::vector<TopologyModule::Triangle>& triangles) {
12 Map<EKey, uint> middlePointIndexCache;
13 std::vector<TopologyModule::Triangle> newTriangles;
14 std::vector<Vec3f> newVertices;
16
17 newVertices = vertices;
18 triSet.setPoints(vertices);
19 triSet.setTriangles(triangles);
20 triSet.update();
21 triSet.updateTriangle2Edge();
22
24 c_Edg2Tri.assign(triSet.getEdge2Triangle());
26 c_Tri2Edg.assign(triSet.getTriangle2Edge());
28 c_Edge.assign(triSet.getEdges());
29 CArrayList<int> c_ver2edge;
30 c_ver2edge.assign(triSet.vertex2Edge());
31
32 Pair<EKey, uint>* pairs = new Pair<EKey, uint>[c_Edge.size()];
33 middlePointIndexCache.reserve(pairs, c_Edge.size());
34
35 auto getTriOtherPoint = [&](uint v0, uint v1, uint triId) {
36 if (triangles[triId][0] != v0 && triangles[triId][0] != v1)
37 return int(triangles[triId][0]);
38 else if (triangles[triId][1] != v0 && triangles[triId][1] != v1)
39 return int(triangles[triId][1]);
40 else if (triangles[triId][2] != v0 && triangles[triId][2] != v1)
41 return int(triangles[triId][2]);
42 else
43 {
44 return int(-1);
45 }
46 };
47
48 auto getMiddlePoint = [&](int eId) {
49 uint v0 = c_Edge[eId][0];
50 uint v1 = c_Edge[eId][1];
51
52 uint tri0 = c_Edg2Tri[eId][0];
53 uint tri1 = c_Edg2Tri[eId][1];
54
55 int v3 = tri0 != -1 ? getTriOtherPoint(v0, v1, tri0) : -1;
56 int v4 = tri1 != -1 ? getTriOtherPoint(v0, v1, tri1) : -1;
57
58 Vec3f p0 = vertices[v0];
59 Vec3f p1 = vertices[v1];
60
61 Vec3f p3 = vertices[v3];
62 Vec3f p4 = vertices[v4];
63
64 Vec3f newV;
65 if (v3 != -1 && v4 != -1)
66 {
67 newV = 3.0f / 8.0f * (p0 + p1) + 1.0f / 8.0f * (p3 + p4);
68 }
69 else
70 newV = 1.0f / 2.0f * (p0 + p1);
71
72 EKey edgeKey = EKey(v0, v1);
73 if (middlePointIndexCache.find(edgeKey) == nullptr)
74 middlePointIndexCache.insert(Pair<EKey, uint>(edgeKey, vertices.size() + eId));
75
76 newVertices.push_back(newV);
77
78 };
79
80 for (size_t i = 0; i < c_Edge.size(); i++)
81 {
82 //printf("\n******** %d ******\n", i);
83
84 getMiddlePoint(i);
85 }
86
87
88 auto updateOldPoints = [&]() {
89
90 auto getEdgeOtherPoint = [&](int vId, TopologyModule::Edge edge) {
91 if (edge[0] != vId && edge[1] != vId)
92 {
93 printf("Error getEdgeOtherPoint!!!!\ninput vId: %d\nedge vId: %d, %d \n", vId, edge[0], edge[1]);
94 return -1;
95 }
96 else
97 {
98 int targetV = edge[0] == vId ? edge[1] : edge[0];
99 //printf("getEdgeOtherPoint: \ninput V: %d\noutput V: %d \n", vId, targetV);
100 return targetV;
101 }
102 };
103
104
105
106 for (size_t i = 0; i < c_ver2edge.size(); i++)
107 {
108 uint v0 = i;
109 auto edgeList = c_ver2edge[v0];
110
111 Vec3f sum = Vec3f(0);
112 int n = edgeList.size();
113 Vec3f p0 = vertices[v0];
114 Vec3f newP;
115
116
117 if (n > 2)
118 {
119 for (size_t j = 0; j < n; j++)
120 {
121 uint edgeId = edgeList[j];
122 int connectionV = getEdgeOtherPoint(v0, c_Edge[edgeId]);
123 if (connectionV != -1)
124 sum += vertices[connectionV];
125 }
126
127 //double beta = 1 / double(n) * (5.0f / 8.0f - (3.0f / 8.0f + 1.0f / 4.0f * cos(2 * M_PI / double(n))));
128 double beta = n == 3 ? (double)3 / (double)16 : (double)3 / ((double)8 * (double)n);
129
130
131 //newP = (1 - double(n) * beta) * p0 + beta * sum;
132 newP = (1 - double(n) * beta) * p0 + beta * sum;
133 }
134 else if (n == 2)
135 {
136 Vec3f p1 = vertices[getEdgeOtherPoint(v0, c_Edge[edgeList[0]])];
137 Vec3f p2 = vertices[getEdgeOtherPoint(v0, c_Edge[edgeList[1]])];
138 newP = 3 / 4 * p0 + 1.0f / 8.0f * p1 + 1.0f / 8.0f + p2;
139 }
140 newVertices[v0] = newP;
141 }
142
143 };
144
145 updateOldPoints();
146
147 vertices = newVertices;
148
149 newTriangles.resize(4 * triangles.size());
150 for (size_t i = 0; i < triangles.size(); i++)
151 {
152 int v01 = middlePointIndexCache.find(EKey(triangles[i][0], triangles[i][1])) != middlePointIndexCache.end() ? (middlePointIndexCache.find(EKey(triangles[i][0], triangles[i][1]))->second) : -1;
153 int v12 = middlePointIndexCache.find(EKey(triangles[i][0], triangles[i][1])) != middlePointIndexCache.end() ? (middlePointIndexCache.find(EKey(triangles[i][1], triangles[i][2]))->second) : -1;
154 int v20 = middlePointIndexCache.find(EKey(triangles[i][0], triangles[i][1])) != middlePointIndexCache.end() ? (middlePointIndexCache.find(EKey(triangles[i][2], triangles[i][0]))->second) : -1;
155
156 int v0 = triangles[i][0];
157 int v1 = triangles[i][1];
158 int v2 = triangles[i][2];
159
160 newTriangles[4 * i] = TopologyModule::Triangle(v01, v1, v12);
161 newTriangles[4 * i + 1] = TopologyModule::Triangle(v12, v2, v20);
162 newTriangles[4 * i + 2] = TopologyModule::Triangle(v20, v0, v01);
163 newTriangles[4 * i + 3] = TopologyModule::Triangle(v01, v12, v20);
164 }
165 triangles = newTriangles;
166 }
167
168
169 template<typename TDataType>
171 : ParametricModel<TDataType>()
172 {
173 this->stateTriangleSet()->setDataPtr(std::make_shared<TriangleSet<TDataType>>());
174
175 this->varStep()->setRange(0, 6);
176
177 auto callback = std::make_shared<FCallBackFunc>(std::bind(&Subdivide<TDataType>::varChanged, this));
178 this->varStep()->attach(callback);
179
180 auto tsRender = std::make_shared<GLSurfaceVisualModule>();
181 this->stateTriangleSet()->connect(tsRender->inTriangleSet());
182 this->graphicsPipeline()->pushModule(tsRender);
183
184
185 auto esRender = std::make_shared<GLWireframeVisualModule>();
186 esRender->varBaseColor()->setValue(Color(0, 0, 0));
187 this->stateTriangleSet()->connect(esRender->inEdgeSet());
188 this->graphicsPipeline()->pushModule(esRender);
189
190 this->stateTriangleSet()->promoteOuput();
191 }
192
193
194 template<typename TDataType>
196 {
197 this->varChanged();
198 }
199
200
201 template<typename TDataType>
203 {
204 auto inTri = this->inInTriangleSet()->constDataPtr();
205
206 std::vector<Vec3f> vts;
207 std::vector<TopologyModule::Triangle> tris;
208
209 CArray<Vec3f> c_v;
211
212 c_v.assign(inTri->getPoints());
213 c_t.assign(inTri->getTriangles());
214
215 for (size_t i = 0; i < c_v.size(); i++)
216 {
217 vts.push_back(c_v[i]);
218 }
219 for (size_t i = 0; i < c_t.size(); i++)
220 {
221 tris.push_back(c_t[i]);
222 }
223
224 for (int i = 0; i < this->varStep()->getValue(); i++)
225 {
226 loopSubdivide(vts, tris);
227 }
228
229 this->stateTriangleSet()->getDataPtr()->setPoints(vts);
230 this->stateTriangleSet()->getDataPtr()->setTriangles(tris);
231 this->stateTriangleSet()->getDataPtr()->update();
232 }
233
234
236
237}
#define DEFINE_CLASS(name)
Definition Object.h:140
DArrayList< int > & vertex2Edge()
Get the Ver2 Edge object.
Definition EdgeSet.h:126
DArray< Edge > & getEdges()
Get all edges with each one containing the indices of two edge ends.
Definition EdgeSet.h:119
Be aware do not use this structure on GPU if the data size is large.
Definition Map.h:16
DYN_FUNC iterator find(MKey key)
Definition Map.inl:14
DYN_FUNC iterator insert(Pair< MKey, T > pair)
Definition Map.inl:22
DYN_FUNC void reserve(Pair< MKey, T > *buf, uint maxSize)
Definition Map.h:22
DYN_FUNC iterator end()
Definition Map.h:32
std::shared_ptr< GraphicsPipeline > graphicsPipeline()
Definition Node.cpp:320
void setPoints(const std::vector< Coord > &pos)
void resetStates() override
VectorND< PointType, 2 > Edge
Vector< PointType, 3 > Triangle
void setTriangles(std::vector< Triangle > &triangles)
void updateTriangle2Edge()
update the index from triangle id to edges ids
DArray< TopologyModule::Tri2Edg > & getTriangle2Edge()
DArray< TopologyModule::Edg2Tri > & getEdge2Triangle()
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
DYN_FUNC bool inTri(const Vector< T, 3 > &p, const Vector< T, 3 > &v0, const Vector< T, 3 > &v1, const Vector< T, 3 > &v2)
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
Array< T, DeviceType::CPU > CArray
Definition Array.h:151
unsigned int uint
Definition VkProgram.h:14