PeriDyno 1.0.0
Loading...
Searching...
No Matches
ConvertToTextureMesh.cu
Go to the documentation of this file.
1#include "ConvertToTextureMesh.h"
2
3#include "GLPhotorealisticRender.h"
4#include "Primitive/Primitive3D.h"
5#include "MaterialFunc.h"
6#include "GLSurfaceVisualModule.h"
7#include "GLPointVisualModule.h"
8
9namespace dyno
10{
11 template< typename Coord, typename Vec3f >
12 __global__ void ToCenter(
13 DArray<Coord> iniPos,
14 DArray<Coord> finalPos,
15 Vec3f translation
16 )
17 {
18 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
19 if (pId >= iniPos.size()) return;
20
21 finalPos[pId] = iniPos[pId] - translation;
22 }
23
24 template< typename Triangle, typename Coord >
25 __global__ void updateNormal(
26 DArray<Triangle> Tris,
27 DArray<Coord> Pts,
28 DArray<Coord> Normals
29 )
30 {
31 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
32 if (pId >= Tris.size()) return;
33
34 Vec3f a;
35 Vec3f b;
36
37 //Tri[0]
38 a = Pts[Tris[pId][0]] - Pts[Tris[pId][1]];
39 b = Pts[Tris[pId][2]] - Pts[Tris[pId][0]];
40 Normals[pId * 3] = (a.normalize()).cross(b.normalize()).normalize();
41
42 //Tri[1]
43 a = Pts[Tris[pId][1]] - Pts[Tris[pId][2]];
44 b = Pts[Tris[pId][0]] - Pts[Tris[pId][1]];
45 Normals[pId * 3 + 1] = (a.normalize()).cross(b.normalize()).normalize();
46
47 //Tri[2]
48 a = Pts[Tris[pId][2]] - Pts[Tris[pId][0]];
49 b = Pts[Tris[pId][1]] - Pts[Tris[pId][2]];
50 Normals[pId * 3 + 2] = (a.normalize()).cross(b.normalize()).normalize();
51
52 }
53
54 template< typename Triangle, typename Coord, typename Vec2f>
55 __global__ void updateTexCoord(
56 DArray<Triangle> Tris,
57 DArray<Coord> Pts,
58 DArray<Vec2f> TexCoords
59 )
60 {
61 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
62 if (pId >= Tris.size()) return;
63
64 //Tri[0]
65 TexCoords[3 * pId] = Vec2f(Pts[Tris[pId][0]][0], Pts[Tris[pId][0]][1]);
66
67 //Tri[1]
68 TexCoords[3 * pId + 1] = Vec2f(Pts[Tris[pId][1]][0], Pts[Tris[pId][1]][1]);
69
70 //Tri[2]
71 TexCoords[3 * pId + 2] = Vec2f(Pts[Tris[pId][2]][0], Pts[Tris[pId][2]][1]);
72 }
73
74 template<typename Coord, typename Vec2f>
75 __global__ void updateTexCoordByVertexNormal(
76 DArray<Vec3f> Normals,
77 DArray<Coord> Pts,
78 DArray<Vec2f> TexCoords,
79 Vec2f scale
80 )
81 {
82 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
83 if (pId >= Normals.size()) return;
84
85 int mode = -1;//x = 0,y = 1,z =2;
86
87 float xdot = abs(Normals[pId].dot(Vec3f(1, 0, 0)));
88 float ydot = abs(Normals[pId].dot(Vec3f(0, 1, 0)));
89 float zdot = abs(Normals[pId].dot(Vec3f(0, 0, 1)));
90
91 mode = xdot > ydot ? 0 : 1;
92 float temp = xdot > ydot ? xdot : ydot;
93 mode = temp > zdot ? mode : 2;
94
95 //UV Tri-Plane Project
96 if (mode == 0)
97 TexCoords[pId] = Vec2f(Pts[pId][2] * scale[0] , Pts[pId][1] * scale[1]);
98 if (mode == 1)
99 TexCoords[pId] = Vec2f(Pts[pId][2] * scale[0], Pts[pId][0] * scale[1]) ;
100 if (mode == 2)
101 TexCoords[pId] = Vec2f(Pts[pId][0] * scale[0], Pts[pId][1] * scale[1]) ;
102 }
103
104 template< typename Coord, typename Triangle>
105 __global__ void convertTriangleSetToTexturemesh(
106 DArray<Coord> srcPts,
107 DArray<Triangle> srcTris,
108 DArray<Coord> targetPts,
109 DArray<Triangle> targetTris
110 )
111 {
112 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
113 if (pId >= srcTris.size()) return;
114
115 //Tri[0]
116 targetPts[3 * pId] = srcPts[srcTris[pId][0]];
117
118 //Tri[1]
119 targetPts[3 * pId + 1] = srcPts[srcTris[pId][1]];
120
121 //Tri[2]
122 targetPts[3 * pId + 2] = srcPts[srcTris[pId][2]];
123
124 //Triangle_PointID
125 targetTris[pId][0] = 3 * pId;
126 targetTris[pId][1] = 3 * pId + 1;
127 targetTris[pId][2] = 3 * pId + 2;
128 }
129
130 template<typename TDataType>
131 ConvertToTextureMesh<TDataType>::ConvertToTextureMesh()
132 : ModelEditing<TDataType>()
133 {
134 this->stateTextureMesh()->setDataPtr(std::make_shared<TextureMesh>());
135
136 auto render = std::make_shared<GLPhotorealisticRender>();
137 this->stateTextureMesh()->connect(render->inTextureMesh());
138 this->graphicsPipeline()->pushModule(render);
139
140 auto callback = std::make_shared<FCallBackFunc>(std::bind(&ConvertToTextureMesh<TDataType>::varChanged, this));
141
142 auto pointsTrianglesCallback = std::make_shared<FCallBackFunc>(std::bind(&ConvertToTextureMesh<TDataType>::createTextureMesh, this));
143 auto materialCallback = std::make_shared<FCallBackFunc>(std::bind(&ConvertToTextureMesh<TDataType>::createMaterial, this));
144 auto normalCallback = std::make_shared<FCallBackFunc>(std::bind(&ConvertToTextureMesh<TDataType>::createNormal, this));
145 auto uvCallback = std::make_shared<FCallBackFunc>(std::bind(&ConvertToTextureMesh<TDataType>::createUV, this));
146 auto moveCenterCallback = std::make_shared<FCallBackFunc>(std::bind(&ConvertToTextureMesh<TDataType>::moveToCenter, this));
147
148
149 this->varDiffuseTexture()->attach(materialCallback);
150 this->varNormalTexture()->attach(materialCallback);
151 this->varUseBoundingTransform()->attach(moveCenterCallback);
152 this->varUvScaleU()->attach(uvCallback);
153 this->varUvScaleV()->attach(uvCallback);
154
155 this->varUvScaleU()->setRange(0, 20);
156 this->varUvScaleV()->setRange(0, 20);
157
158 this->stateTextureMesh()->promoteOuput();
159 }
160
161 template<typename TDataType>
162 void ConvertToTextureMesh<TDataType>::resetStates()
163 {
164 this->varChanged();
165 }
166
167 template<typename TDataType>
168 void ConvertToTextureMesh<TDataType>::varChanged()
169 {
170 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->inTopology()->getDataPtr());
171 if (triSet == NULL)
172 return;
173
174 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
175 texMesh->shapes().resize(1);
176 texMesh->materials().resize(1);
177
178 createTextureMesh();
179
180 createNormal();
181
182 createUV();
183
184 moveToCenter();
185
186 createMaterial();
187
188 auto& TargetPoints = texMesh->vertices();
189 texMesh->shapeIds().assign(std::vector<uint>(TargetPoints.size(), 0));
190
191 }
192
193 template<typename TDataType>
194 void ConvertToTextureMesh<TDataType>::createTextureMesh()
195 {
196 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
197 //Points
198 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->inTopology()->getDataPtr());
199 if (triSet == NULL)
200 return;
201
202 auto SourceTriangles = triSet->getTriangles();
203 auto SourcePoints = triSet->getPoints();
204
205 texMesh->shapes()[0] = std::make_shared<Shape>();
206 texMesh->shapes()[0]->vertexIndex.resize(SourceTriangles.size());
207
208 texMesh->vertices().resize(SourceTriangles.size() * 3);
209
210 auto& TargetTriangles = texMesh->shapes()[0]->vertexIndex;
211 auto& TargetPoints = texMesh->vertices();
212
213 // ShapeIndex and rebuild Points;
214 cuExecute(SourceTriangles.size(),
215 convertTriangleSetToTexturemesh,
216 SourcePoints,
217 SourceTriangles,
218 TargetPoints,
219 TargetTriangles
220 );
221
222 }
223
224 template<typename TDataType>
225 void ConvertToTextureMesh<TDataType>::createNormal()
226 {
227 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
228 auto& TargetTriangles = texMesh->shapes()[0]->vertexIndex;
229 auto& TargetPoints = texMesh->vertices();
230 // Normals
231 auto& Normals = texMesh->normals();
232 Normals.resize(TargetPoints.size());
233
234 cuExecute(TargetTriangles.size(),
235 updateNormal,
236 TargetTriangles,
237 TargetPoints,
238 Normals
239 );
240 texMesh->shapes()[0]->normalIndex.assign(TargetTriangles);
241
242 }
243
244 template<typename TDataType>
245 void ConvertToTextureMesh<TDataType>::createUV()
246 {
247 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
248 auto& TargetTriangles = texMesh->shapes()[0]->vertexIndex;
249 auto& TargetPoints = texMesh->vertices();
250 auto& Normals = texMesh->normals();
251
252 auto& TexCoords = texMesh->texCoords();
253 TexCoords.resize(TargetPoints.size());
254 //this->statePointColors()->resize(TargetPoints.size());
255 //auto& colors = this->statePointColors()->getData();
256 cuExecute(Normals.size(),
257 updateTexCoordByVertexNormal,//updateTexCoord
258 Normals,
259 TargetPoints,
260 TexCoords,
261 Vec2f(this->varUvScaleU()->getValue(), this->varUvScaleV()->getValue())
262 );
263 texMesh->shapes()[0]->texCoordIndex.assign(TargetTriangles);
264
265 }
266
267 template<typename TDataType>
268 void ConvertToTextureMesh<TDataType>::createMaterial()
269 {
270 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
271 if (texMesh->shapes().empty() | texMesh->vertices().isEmpty())
272 return;
273
274 auto& TargetTriangles = texMesh->shapes()[0]->vertexIndex;
275 auto& TargetPoints = texMesh->vertices();
276 // Assign Material;
277 texMesh->materials()[0] = std::make_shared<Material>();
278 texMesh->shapes()[0]->material = texMesh->materials()[0];
279
280 //set Material
281 dyno::CArray2D<dyno::Vec4f> texture(1, 1);
282
283 auto diffusePath = this->varDiffuseTexture()->getValue().string();
284 if (diffusePath.size())
285 {
286 if (loadTexture(diffusePath.c_str(), texture))
287 texMesh->shapes()[0]->material->texColor.assign(texture);
288 }
289
290 auto bumpPath = this->varNormalTexture()->getValue().string();
291 if (bumpPath.size())
292 {
293 if (loadTexture(bumpPath.c_str(), texture))
294 texMesh->shapes()[0]->material->texBump.assign(texture);
295 }
296
297 }
298
299 template<typename TDataType>
300 void ConvertToTextureMesh<TDataType>::moveToCenter()
301 {
302 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
303 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->inTopology()->getDataPtr());
304 if (triSet == NULL)
305 return;
306
307 auto SourceTriangles = triSet->getTriangles();
308 auto SourcePoints = triSet->getPoints();
309
310 auto& TargetTriangles = texMesh->shapes()[0]->vertexIndex;
311 auto& TargetPoints = texMesh->vertices();
312
313 // Move To Center, use Transform
314 Reduction<Coord> reduceBounding;
315
316 auto& bounding = texMesh->shapes()[0]->boundingBox;
317 Coord lo = reduceBounding.minimum(SourcePoints.begin(), SourcePoints.size());
318 Coord hi = reduceBounding.maximum(SourcePoints.begin(), SourcePoints.size());
319
320 bounding.v0 = lo;
321 bounding.v1 = hi;
322
323 if (this->varUseBoundingTransform()->getValue())
324 {
325 texMesh->shapes()[0]->boundingTransform.translation() = (lo + hi) / 2;
326 DArray<Coord> iniPos;
327 iniPos.assign(TargetPoints);
328
329 cuExecute(TargetPoints.size(),
330 ToCenter,
331 iniPos,
332 TargetPoints,
333 (lo + hi) / 2
334 );
335 }
336 else
337 {
338 texMesh->shapes()[0]->boundingTransform.translation() = Vec3f(0);
339 }
340 }
341
342 DEFINE_CLASS(ConvertToTextureMesh);
343}