7 #include "InflatableObject.h" 8 #include "imstkCollisionUtils.h" 9 #include "imstkGeometryUtilities.h" 10 #include "imstkImageData.h" 11 #include "imstkMeshIO.h" 13 #include "imstkPbdConstraintContainer.h" 14 #include "imstkPbdInflatableDistanceConstraint.h" 15 #include "imstkPbdInflatableVolumeConstraint.h" 16 #include "imstkPbdModel.h" 17 #include "imstkPbdModelConfig.h" 18 #include "imstkPointwiseMap.h" 19 #include "imstkRenderMaterial.h" 20 #include "imstkVisualModel.h" 22 InflatableObject::InflatableObject(
const std::string& name,
const Vec3d& tissueSize,
23 const Vec3i& tissueDim,
const Vec3d& tissueCenter) :
PbdObject(name)
27 m_objectSurfMesh = m_objectTetMesh->extractSurfaceMesh();
28 setSphereTexCoords(4.0);
33 pbdParams->
m_gravity = Vec3d(0.0, 0.0, 0.0);
34 pbdParams->
m_dt = 0.05;
39 auto distanceFunctor = std::make_shared<PbdInflatableDistanceConstraintFunctor>();
40 distanceFunctor->setStiffness(0.95);
41 auto volumeFunctor = std::make_shared<PbdInflatableVolumeConstraintFunctor>();
42 volumeFunctor->setStiffness(0.9);
54 auto diffuseTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshDiffuse.jpg");
55 material->
addTexture(std::make_shared<Texture>(diffuseTex, Texture::Type::Diffuse));
56 auto normalTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshNormal.jpg");
57 material->
addTexture(std::make_shared<Texture>(normalTex, Texture::Type::Normal));
58 auto ormTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshORM.jpg");
59 material->
addTexture(std::make_shared<Texture>(ormTex, Texture::Type::ORM));
63 visualModel->setGeometry(m_objectSurfMesh);
65 addVisualModel(visualModel);
68 setPhysicsGeometry(m_objectTetMesh);
69 setCollidingGeometry(m_objectSurfMesh);
70 setPhysicsToCollidingMap(std::make_shared<PointwiseMap>(m_objectTetMesh, m_objectSurfMesh));
71 setDynamicalModel(pbdModel);
73 distanceFunctor->setBodyIndex(getPbdBody()->bodyHandle);
74 volumeFunctor->setBodyIndex(getPbdBody()->bodyHandle);
77 getPbdBody()->uniformMassValue = 0.1;
78 for (
int z = 0; z < tissueDim[2]; z++)
80 for (
int y = 0; y < tissueDim[1]; y++)
82 for (
int x = 0; x < tissueDim[0]; x++)
84 if (x == 0 || z == 0 || x == tissueDim[0] - 1 || z == tissueDim[2] - 1 || y == 0)
86 getPbdBody()->fixedNodeIds.push_back(x + tissueDim[0] * (y + tissueDim[1] * z));
97 m_objectSurfMesh->computeBoundingBox(min, max);
98 const Vec3d size = max - min;
99 const Vec3d center = (max + min) * 0.5;
101 const double radius = (size * 0.5).norm();
105 for (
int i = 0; i < m_objectSurfMesh->getNumVertices(); i++)
107 Vec3d vertex = m_objectSurfMesh->getVertexPosition(i) - center;
110 const double theta = asin(vertex[0] / radius);
111 const double phi = atan2(vertex[1], vertex[2]);
112 uvCoords[i] = Vec2f(phi / (PI * 2.0) + 0.5, theta / (PI * 2.0) + 0.5) * uvScale;
114 m_objectSurfMesh->setVertexTCoords(
"tcoords", uvCoordsPtr);
120 m_constraintIDandWeight.clear();
123 m_objectTetMesh->computeBoundingBox(min, max);
124 if (!CollisionUtils::testAabbToAabb(toolTip[0], toolTip[0], toolTip[1], toolTip[1], toolTip[2], toolTip[2],
125 min[0], max[0], min[1], max[1], min[2], max[2]))
130 const auto& vertices = m_objectTetMesh->getVertexPositions();
132 std::vector<int> constraintIDs;
133 std::vector<double> weights;
135 double minDistance = LONG_MAX;
136 for (
auto& c : m_pbdModel->getConstraints()->getConstraints())
138 const std::vector<PbdParticleId>& ids = c->getParticles();
140 Vec3d center(0.0, 0.0, 0.0);
143 center += (*vertices)[i.second];
146 double distance = (center / ids.size() - toolTip).norm();
148 if (distance < radius)
150 constraintIDs.push_back(counter);
151 weights.push_back(computeGaussianWeight(distance));
154 if (distance < minDistance)
156 minDistance = distance;
162 if (minDistance > 0.5)
168 for (
size_t i = 0; i < constraintIDs.size(); i++)
170 m_constraintIDandWeight.push_back(std::make_pair(constraintIDs[i], weights[i]));
173 m_affectedAreaUpdated =
true;
180 if (!m_affectedAreaUpdated)
182 findAffectedConstraint(toolTip, radius);
186 if (m_inflationType == InflationType::Exponential)
190 else if (m_inflationType == InflationType::Linear)
195 for (
auto&
id : m_constraintIDandWeight)
197 const double dv =
id.second * de;
199 auto& c = (m_pbdModel->getConstraints()->getConstraints())[
id.first];
200 if (
auto volConstraint = std::dynamic_pointer_cast<PbdInflatableVolumeConstraint>(c))
202 volConstraint->setRestVolume(dv + volConstraint->getRestVolume());
203 volConstraint->setStiffness(1.0);
205 else if (
auto distConstraint = std::dynamic_pointer_cast<PbdInflatableDistanceConstraint>(c))
207 distConstraint->setRestLength(0.00001 * cbrt(dv) + distConstraint->getRestLength());
208 distConstraint->setStiffness(0.1);
216 if (m_inflationType == InflationType::Linear)
218 m_inflationType = InflationType::Exponential;
219 std::cout <<
"Inflation Type: Exponential." << std::endl;
221 else if (m_inflationType == InflationType::Exponential)
223 m_inflationType = InflationType::Linear;
224 std::cout <<
"Inflation Type: Linear." << std::endl;
231 m_affectedAreaUpdated =
false;
232 m_inflationRatio = 1.0;
236 InflatableObject::reset()
240 m_inflationRatio = 1.0;
242 for (
auto& c : m_pbdModel->getConstraints()->getConstraints())
244 if (
auto volConstraint = std::dynamic_pointer_cast<PbdInflatableVolumeConstraint>(c))
246 volConstraint->resetRestVolume();
248 else if (
auto distConstraint = std::dynamic_pointer_cast<PbdInflatableDistanceConstraint>(c))
250 distConstraint->resetRestLength();
double m_linearDampingCoeff
Damping coefficient applied to linear velocity [0, 1].
void addTexture(std::shared_ptr< Texture > texture)
Add/Remove/Get texture.
void configure(std::shared_ptr< PbdModelConfig > params)
Set simulation parameters.
void inject(const Vec3d &toolTip, const double radius, double rate)
Perform injection on the tissue given tool tip position.
void reset() override
Reset the dynamic object by reseting the respective DynamicalModel and Geometry.
void setSphereTexCoords(const double uvScale)
Spherically project the texture coordinates.
void addPbdConstraintFunctor(std::shared_ptr< PbdConstraintFunctor > functor)
Adds a functor to generate constraints.
std::shared_ptr< TetrahedralMesh > toTetGrid(const Vec3d ¢er, const Vec3d &size, const Vec3i &divisions, const Quatd orientation=Quatd::Identity())
Produces a tetrahedral grid given the OrientedBox with the given divisions.
void findAffectedConstraint(const Vec3d &toolTip, const double radius)
find affected constraints id and distance in the injection area
unsigned int m_iterations
Internal constraints pbd solver iterations.
Simple dynamic array implementation that also supports event posting and viewing/facade.
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
void setUpdateAffectedConstraint()
set update affected constraints flag
Base class for scene objects that move and/or deform under position based dynamics formulation...
void setRenderMaterial(std::shared_ptr< RenderMaterial > renderMaterial)
Set/Get render material.
bool m_doPartitioning
Does graph coloring to solve in parallel.
double m_dt
Time step size.
Physically based rendering.
void switchInflationType()
Switch between linear and exponential inflation type.
Vec3d m_gravity
Gravity acceleration.