7 #include "imstkCamera.h" 8 #include "imstkDirectionalLight.h" 9 #include "imstkImageDistanceTransform.h" 10 #include "imstkKeyboardDeviceClient.h" 11 #include "imstkKeyboardSceneControl.h" 12 #include "imstkMeshIO.h" 13 #include "imstkMouseDeviceClient.h" 14 #include "imstkMouseSceneControl.h" 16 #include "imstkRenderMaterial.h" 17 #include "imstkScene.h" 18 #include "imstkSceneManager.h" 19 #include "imstkSignedDistanceField.h" 20 #include "imstkSimulationManager.h" 21 #include "imstkSimulationUtils.h" 22 #include "imstkSphModel.h" 23 #include "imstkSphObject.h" 24 #include "imstkSphObjectCollision.h" 25 #include "imstkSurfaceMesh.h" 26 #include "imstkSurfaceMeshDistanceTransform.h" 27 #include "imstkSurfaceMeshImageMask.h" 28 #include "imstkVisualModel.h" 29 #include "imstkVTKViewer.h" 31 using namespace imstk;
36 static std::shared_ptr<VecDataArray<double, 3>>
37 generateFluidVolume(
const double particleRadius, std::shared_ptr<SurfaceMesh> spawnSurfaceVolume)
40 spawnSurfaceVolume->computeBoundingBox(minima, maxima);
42 double particleDiameter = particleRadius * 2.0;
43 const Vec3d size = (maxima - minima) + Vec3d(particleDiameter, particleDiameter, particleDiameter);
44 Vec3i dim = size.cwiseProduct(Vec3d(1.0 / particleDiameter, 1.0 / particleDiameter, 1.0 / particleDiameter)).cast<
int>();
48 makeBinaryMask->setInputMesh(spawnSurfaceVolume);
49 makeBinaryMask->setDimensions(dim[0], dim[1], dim[2]);
50 makeBinaryMask->update();
54 distTransformFromMask->
setInputImage(makeBinaryMask->getOutputImage());
55 distTransformFromMask->
update();
57 std::shared_ptr<DataArray<float>> scalarsPtr = std::dynamic_pointer_cast<
DataArray<float>>(distTransformFromMask->getOutputImage()->getScalars());
59 const Vec3i& dim1 = makeBinaryMask->getOutputImage()->getDimensions();
60 const Vec3d& spacing = makeBinaryMask->getOutputImage()->getSpacing();
61 const Vec3d& shift = makeBinaryMask->getOutputImage()->getOrigin() + spacing * 0.5;
62 const double threshold = particleDiameter * 1.0;
65 particles->reserve(dim1[0] * dim1[1] * dim1[2]);
68 for (
int z = 0; z < dim1[2]; z++)
70 for (
int y = 0; y < dim1[1]; y++)
72 for (
int x = 0; x < dim1[0]; x++, i++)
74 if (x > 1 && y > 1 && z > 1 && scalars[i] < -threshold)
76 particles->push_back(Vec3d(x, y, z).cwiseProduct(spacing) + shift);
85 static std::shared_ptr<SphObject>
86 makeSPHObject(
const std::string& name,
const double particleRadius,
const double particleSpacing)
92 auto spawnMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/legs/femoralArteryCut.stl");
94 std::shared_ptr<VecDataArray<double, 3>> particles = generateFluidVolume(particleSpacing, spawnMesh);
95 LOG(INFO) <<
"Number of particles: " << particles->size();
101 sphParams->m_bNormalizeDensity =
true;
102 sphParams->m_kernelOverParticleRadiusRatio = 6.0;
103 sphParams->m_surfaceTensionStiffness = 5.0;
104 sphParams->m_frictionBoundary = 0.1;
114 fluidVisualModel->setGeometry(fluidGeometry);
117 fluidMaterial->setPointSize(particleRadius * 2.0f);
123 fluidObj->setDynamicalModel(sphModel);
124 fluidObj->addVisualModel(fluidVisualModel);
125 fluidObj->setCollidingGeometry(fluidGeometry);
126 fluidObj->setPhysicsGeometry(fluidGeometry);
131 static std::shared_ptr<CollidingObject>
132 makeLegs(
const std::string& name)
138 auto legsMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/legs/legsCutaway.stl");
139 auto bonesMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/legs/legsBones.stl");
140 auto femoralMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/legs/femoralArtery.stl");
141 auto collisionMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/legs/femoralArteryCut.stl");
145 legsMeshModel->setGeometry(legsMesh);
147 legsMaterial->setDisplayMode(RenderMaterial::DisplayMode::Surface);
148 legsMaterial->setOpacity(0.85f);
149 legsMaterial->setDiffuseColor(
Color(0.8, 0.688, 0.396));
150 legsMeshModel->setRenderMaterial(legsMaterial);
154 bonesMeshModel->setGeometry(bonesMesh);
156 bonesMaterial->setDisplayMode(RenderMaterial::DisplayMode::Surface);
157 bonesMaterial->setDiffuseColor(
Color(0.538, 0.538, 0.538));
162 femoralMeshModel->setGeometry(femoralMesh);
164 femoralMaterial->setDisplayMode(RenderMaterial::DisplayMode::Surface);
165 femoralMaterial->setOpacity(0.2f);
166 femoralMaterial->setDiffuseColor(
Color(0.8, 0.119, 0.180));
170 legsObj->addVisualModel(legsMeshModel);
171 legsObj->addVisualModel(bonesMeshModel);
172 legsObj->addVisualModel(femoralMeshModel);
174 LOG(INFO) <<
"Computing SDF";
177 computeSdf->setDimensions(100, 100, 100);
179 collisionMesh->computeBoundingBox(min, max);
180 const Vec3d size = max - min;
182 bounds[0] = min[0] - size[0] * 0.25;
183 bounds[1] = max[0] + size[0] * 0.25;
184 bounds[2] = min[1] - size[1] * 0.25;
185 bounds[3] = max[1] + size[1] * 0.25;
186 bounds[4] = min[2] - size[2] * 0.25;
187 bounds[5] = max[2] + size[2] * 0.25;
190 LOG(INFO) <<
"SDF Complete";
191 legsObj->setCollidingGeometry(std::make_shared<SignedDistanceField>(computeSdf->getOutputImage()));
211 std::shared_ptr<CollidingObject> legsObj = makeLegs(
"Legs");
212 scene->addSceneObject(legsObj);
217 scene->getActiveCamera()->setPosition(3.25, 1.6, 3.38);
218 scene->getActiveCamera()->setFocalPoint(-2.05, 1.89, -1.32);
219 scene->getActiveCamera()->setViewUp(-0.66, 0.01, 0.75);
222 std::shared_ptr<SphObject> sphObj = makeSPHObject(
"Fluid", 0.004, 0.0035);
223 scene->addSceneObject(sphObj);
226 scene->addInteraction(
227 std::make_shared<SphObjectCollision>(sphObj, legsObj));
233 scene->addLight(
"light0", light);
246 sceneManager->pause();
254 std::shared_ptr<Entity> mouseAndKeyControls =
255 SimulationUtils::createDefaultSceneControl(driver);
256 scene->addSceneObject(mouseAndKeyControls);
void initialize(std::shared_ptr< VecDataArray< double, 3 >> positions)
Initializes the data structure given vertex positions.
void setDesiredDt(const double dt)
Sets the target fixed timestep (may violate), seconds This ultimately effects the number of iteration...
void setActiveScene(std::shared_ptr< Scene > scene) override
Set scene to be rendered.
void configure(const std::shared_ptr< SphModelConfig > ¶ms)
Set simulation parameters.
Renders a set of points using a screen-space fluid renderer.
virtual void setTimeStepSizeType(const TimeSteppingType type)
Get/Set the type of approach used to update the time step size after every frame. ...
void addModule(std::shared_ptr< Module > module) override
Add a module to run.
virtual void setBackgroundColors(const Color color1, const Color color2=Color(0.0, 0.0, 0.0), const bool gradientBackground=false) override
Set the coloring of the screen background If 'gradientBackground' is false or not supplied color1 wil...
void setIntensity(const double intensity)
Set the light intensity. This value is unbounded.
void setBounds(const Vec3d &min, const Vec3d &max)
Optionally one may specify bounds, if not specified bounds of the input SurfaceMesh is used...
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
void update()
Do the actual algorithm.
void setModelGeometry(std::shared_ptr< Geometry > geometry)
Sets the model geometry.
void setRenderMaterial(std::shared_ptr< RenderMaterial > renderMaterial)
Set/Get render material.
void setDirection(const Vec3d &dir)
Set the direction of the light.
void setInputImage(std::shared_ptr< ImageData > refImage)
Required input, port 0.
void setActiveScene(std::string newSceneName)
Sets the currently updating scene.
Simple dynamic array implementation that also supports event posting and viewing/facade.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.
void setInputMesh(std::shared_ptr< SurfaceMesh > surfMesh)
Required input, port 0.