2#include "CodimensionalPD.h"
3#include "ParticleSystem/Module/ParticleIntegrator.h"
4#include "Primitive/Primitive3D.h"
5#include "Topology/TriangleSet.h"
6#include "Mapping/PointSetToPointSet.h"
8#include "Module/CoSemiImplicitHyperelasticitySolver.h"
12 IMPLEMENT_TCLASS(CodimensionalPD, TDataType)
14 template<typename TDataType>
15 CodimensionalPD<TDataType>::CodimensionalPD()
16 : TriangularSystem<TDataType>()
18 this->varHorizon()->setValue(0.0085);
20 auto integrator = std::make_shared<ParticleIntegrator<TDataType>>();
21 this->stateTimeStep()->connect(integrator->inTimeStep());
22 this->statePosition()->connect(integrator->inPosition());
23 this->stateVelocity()->connect(integrator->inVelocity());
24 this->stateAttribute()->connect(integrator->inAttribute());
25 this->animationPipeline()->pushModule(integrator);
27 auto hyperElasticity = std::make_shared<CoSemiImplicitHyperelasticitySolver<TDataType>>();
28 this->varHorizon()->connect(hyperElasticity->inHorizon());
29 this->stateTimeStep()->connect(hyperElasticity->inTimeStep());
30 this->varEnergyType()->connect(hyperElasticity->inEnergyType());
31 this->varEnergyModel()->connect(hyperElasticity->inEnergyModels());
32 this->stateRestPosition()->connect(hyperElasticity->inX());
33 this->statePosition()->connect(hyperElasticity->inY());
34 this->stateVelocity()->connect(hyperElasticity->inVelocity());
35 this->stateRestNorm()->connect(hyperElasticity->inRestNorm());
36 this->stateNorm()->connect(hyperElasticity->inNorm());
37 this->stateRestShape()->connect(hyperElasticity->inBonds());
38 this->stateAttribute()->connect(hyperElasticity->inAttribute());
39 this->stateMaxLength()->connect(hyperElasticity->inUnit());
40 this->stateOldPosition()->connect(hyperElasticity->inOldPosition());
41 this->stateTriangleSet()->connect(hyperElasticity->inTriangularMesh());
43 this->animationPipeline()->pushModule(hyperElasticity);
45 EnergyModels<Real> funcs;
46 Real s0 = hyperElasticity->getS0(2000,0.1);
47 Real s1 = hyperElasticity->getS1(2000,0.1);
48 funcs.linearModel = LinearModel<Real>(48000, 12000);
49 funcs.neohookeanModel = NeoHookeanModel<Real>(s0,s1);
50 funcs.stvkModel = StVKModel<Real>(1, 12000);
51 funcs.xuModel = XuModel<Real>(hyperElasticity->getE());
52 funcs.fiberModel = FiberModel<Real>(1, 1, 1);
54 this->varEnergyModel()->setValue(funcs);
59 template<typename TDataType>
60 CodimensionalPD<TDataType>::~CodimensionalPD()
67 template<typename TDataType>
68 void CodimensionalPD<TDataType>::updateTopology()
70 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
71 triSet->getPoints().assign(this->statePosition()->getData());
72 triSet->updateAngleWeightedVertexNormal(this->stateNorm()->getData());
76 template<typename TDataType>
77 void CodimensionalPD<TDataType>::loadSurface(std::string filename)
79 auto triSetPtr = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
80 triSetPtr ->loadObjFile(filename);
85 template<typename TDataType>
86 void CodimensionalPD<TDataType>::setEnergyModel(XuModel<Real> model)
88 this->varEnergyType()->setValue(Xuetal);
90 auto models = this->varEnergyModel()->getValue();
91 models.xuModel = model;
93 this->varEnergyModel()->setValue(models);
96 template<typename TDataType>
97 void CodimensionalPD<TDataType>::setEnergyModel(NeoHookeanModel<Real> model)
99 this->varEnergyType()->setValue(NeoHooekean);
101 auto models = this->varEnergyModel()->getValue();
102 models.neohookeanModel = model;
104 this->varEnergyModel()->setValue(models);
107 template<typename TDataType>
108 void CodimensionalPD<TDataType>::setEnergyModel(LinearModel<Real> model)
110 this->varEnergyType()->setValue(Linear);
112 auto models = this->varEnergyModel()->getValue();
113 models.linearModel = model;
115 this->varEnergyModel()->setValue(models);
118 template<typename TDataType>
119 void CodimensionalPD<TDataType>::setEnergyModel(StVKModel<Real> model)
121 this->varEnergyType()->setValue(StVK);
123 auto models = this->varEnergyModel()->getValue();
124 models.stvkModel = model;
126 this->varEnergyModel()->setValue(models);
129 template<typename TDataType>
130 void CodimensionalPD<TDataType>::setEnergyModel(FiberModel<Real> model)
132 this->varEnergyType()->setValue(Fiber);
134 auto models = this->varEnergyModel()->getValue();
135 models.fiberModel = model;
137 this->varEnergyModel()->setValue(models);
140 template<typename TDataType>
141 bool CodimensionalPD<TDataType>::translate(Coord t)
143 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
144 triSet->translate(t);
149 template<typename TDataType>
150 bool CodimensionalPD<TDataType>::scale(Real s)
152 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
155 this->varHorizon()->setValue(s * this->varHorizon()->getData());
160 template<typename TDataType>
161 bool CodimensionalPD<TDataType>::scale(Coord s)
163 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
166 this->varHorizon()->setValue((s[0] + s[1] + s[2]) / 3.0f * this->varHorizon()->getData());
171 template<typename TDataType>
172 void CodimensionalPD<TDataType>::preUpdateStates()
175 auto& posOld = this->stateOldPosition()->getData();
176 auto& posNew = this->statePosition()->getData();
177 posOld.assign(posNew);
181 template<typename Matrix>
182 __global__ void InitRotation(
185 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
186 if (pId >= rots.size()) return;
188 rots[pId] = Matrix::identityMatrix();
191 template<typename TDataType>
192 void CodimensionalPD<TDataType>::resetStates()
194 TriangularSystem<TDataType>::resetStates();
196 printf("inside reset States\n");
197 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
198 if (triSet == nullptr) return;
199 printf("host attribute\n");
201 CArray<Attribute> host_attribute;
202 host_attribute.resize(triSet->getPoints().size());
203 for (int i = 0; i < triSet->getPoints().size(); i++)
205 host_attribute[i] = Attribute();
208 CArray<Coord> triPoints;
209 CArray<TopologyModule::Triangle> triIds;
211 triPoints.resize(triSet->getPoints().size());
212 triPoints.assign(triSet->getPoints());
214 triIds.resize(triSet->getTriangles().size());
215 triIds.assign(triSet->getTriangles());
218 float global_min = 1000000;
219 float global_max = 0.0f;
220 for (int i = 0; i < triIds.size(); i++)
222 auto tri = triIds[i];
224 Vec3f v0 = triPoints[tri[0]];
225 Vec3f v1 = triPoints[tri[1]];
226 Vec3f v2 = triPoints[tri[2]];
229 Vec3f min_v = v0.minimum(v1).minimum(v2);
230 Vec3f max_v = v0.maximum(v1).maximum(v2);
232 Vec3f bounding = max_v - min_v;
234 float max_edge = maximum(maximum(bounding[0], bounding[1]), bounding[2]);
236 global_min = max_edge < global_min ? max_edge : global_min;
237 global_max = max_edge > global_max ? max_edge : global_max;
242 this->varHorizon()->setValue(1.5 * global_max);
244 printf("host attr size %d\n", host_attribute.size());
246 int vNum = triSet->getPoints().size();
249 this->stateRestNorm()->resize(vNum);
250 triSet->updateAngleWeightedVertexNormal(this->stateRestNorm()->getData());
253 this->stateNorm()->assign(this->stateRestNorm()->getData());
256 this->stateRestPosition()->assign(triSet->getPoints());
258 this->stateOldPosition()->assign(triSet->getPoints());
260 this->stateAttribute()->assign(host_attribute);
262 host_attribute.clear();
267 this->updateVolume();
268 this->updateRestShape();
272 __global__ void CPD_SetSize(
274 DArrayList<int> lists)
276 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
277 if (pId >= lists.size()) return;
278 index[pId] = lists[pId].size() + 1;
282 template<typename Coord, typename Bond>
283 __global__ void SetRestShape(
284 DArray<Coord> restPos,
285 DArrayList<Bond> restShapes,
286 DArrayList<int> lists)
288 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
289 if (pId >= lists.size()) return;
292 List<Bond>& list_i = restShapes[pId];
294 List<int> list = lists[pId];
296 list_i.insert(Bond(pId, restPos[pId]));
298 for (auto it = list.begin(); it != list.end(); it++)
302 list_i.insert(Bond(j, restPos[j]));
306 int size_i = restShapes[pId].size();
309 template<typename TDataType>
310 void CodimensionalPD<TDataType>::updateRestShape()
312 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
313 if (triSet == nullptr) return;
315 DArrayList<int> neighbors;
316 triSet->requestPointNeighbors(neighbors);
318 auto& restPos = this->stateRestPosition()->getData();
320 this->stateRestShape()->resize(restPos.size());
322 auto index = this->stateRestShape()->getData().index();
323 auto elements = this->stateRestShape()->getData().elements();
325 DArray<uint> index_temp;
326 index_temp.resize(index.size());
328 cuExecute(neighbors.size(),
333 this->stateRestShape()->getData().resize(index_temp);
335 cuExecute(neighbors.size(),
338 stateRestShape()->getData(),
344 template<typename Real, typename Coord, typename Triangle>
345 __global__ void HB_UpdateUnit(
346 DArray<Coord> restPos,
347 DArray<Triangle> tris,
351 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
352 if (tId >= tris.size()) return;
354 auto Coordnorm = [](Coord res) {
356 Real tmp = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
361 Triangle triIndex = tris[tId];
362 Real length1 = Coordnorm(restPos[triIndex[0]] - restPos[triIndex[1]]);
363 Real length2 = Coordnorm(restPos[triIndex[1]] - restPos[triIndex[2]]);
364 Real length3 = Coordnorm(restPos[triIndex[2]] - restPos[triIndex[0]]);
365 auto tmpMax = maximum(maximum(length3, Real(1e-9)), maximum(length1, length2));
366 auto tmpMin = minimum(maximum(length3, Real(1e-9)), minimum(length1, length2));
371 template<typename Real, typename Coord, typename Triangle>
372 __global__ void HB_CalculateVolume(
374 DArray<Coord> restPos,
375 DArray<Triangle> tris,
376 DArrayList<int> lists)
378 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
379 if (pId >= volume.size()) return;
381 Real vol_i = Real(0);
383 List<int>& list_i = lists[pId];
384 int nbSize = list_i.size();
386 for (int i = 0; i < nbSize; i++)
388 int triId = list_i[i];//lists.getElement(pId, i);
389 Triangle triIndex = tris[triId];
391 TTriangle3D<Real> tri(restPos[triIndex[0]], restPos[triIndex[1]], restPos[triIndex[2]]);
393 vol_i += abs(tri.area());
396 //volume[pId] = samplingDistance * samplingDistance * samplingDistance;//1.0f;//maximum(vol_i, Real(0.0000000000001));
397 volume[pId] = maximum(vol_i, Real(0.0000000000001));
401 template<typename TDataType>
402 void CodimensionalPD<TDataType>::updateVolume()
404 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
405 if (triSet == nullptr) return;
407 auto& ver2Tri = triSet->getVertex2Triangles();
409 auto& restPos = this->stateRestPosition()->getData();
411// if (this->stateMaxLength()->isEmpty()) {
412// this->stateMaxLength()->allocate();
414// if (this->stateMinLength()->isEmpty()) {
415// this->stateMinLength()->allocate();
419 maxL.resize(triSet->getTriangles().size());
421 minL.resize(triSet->getTriangles().size());
423 cuExecute(triSet->getTriangles().size(),
426 triSet->getTriangles(),
431 this->stateVolume()->resize(restPos.size());
433 cuExecute(restPos.size(),
435 this->stateVolume()->getData(),
437 triSet->getTriangles(),
440 auto& volume = this->stateVolume()->getData();
442 Reduction<Real> reduce;
443 Real max_vol = reduce.maximum(volume.begin(), volume.size());
444 Real min_vol = reduce.minimum(volume.begin(), volume.size());
445 Real min_L = reduce.minimum(minL.begin(), minL.size());
446 Real max_L = reduce.maximum(maxL.begin(), maxL.size());
447 this->stateMaxLength()->setValue(max_L);
448 this->stateMinLength()->setValue(min_L);
449 printf("max vol: %f; min vol: %f \n", max_vol, min_vol);
450 printf("max length: %f; min length: %f \n",this->stateMaxLength()->getData() , this->stateMinLength()->getData());
453 DEFINE_CLASS(CodimensionalPD);