Commit fe72dc5a authored by Ricardo Ortiz's avatar Ricardo Ortiz
Browse files

ENH: Clean up the code and update examples.

parent 6d66149e
Pipeline #4808 passed with stage
......@@ -33,7 +33,7 @@ PenaltyContactFemToStatic::PenaltyContactFemToStatic(bool typeBilateral) : Penal
PenaltyContactFemToStatic::PenaltyContactFemToStatic(
bool typeBilateral,
const std::shared_ptr<SceneObject>& sceneObjFirst,
const std::shared_ptr<SceneObjectDeformable>& sceneObjSecond)
const std::shared_ptr<DeformableSceneObject>& sceneObjSecond)
: PenaltyContactHandling(typeBilateral, sceneObjFirst, sceneObjSecond)
{
type = ContactHandlingType::PenaltyFemToStatic;
......@@ -47,7 +47,7 @@ PenaltyContactFemToStatic::~PenaltyContactFemToStatic()
//---------------------------------------------------------------------------
void PenaltyContactFemToStatic::computeUnilateralContactForces()
{
auto femSceneObject = std::static_pointer_cast<SceneObjectDeformable>(this->getSecondSceneObject());
auto femSceneObject = std::static_pointer_cast<DeformableSceneObject>(this->getSecondSceneObject());
this->computeForces(femSceneObject);
}
......@@ -57,7 +57,7 @@ void PenaltyContactFemToStatic::computeBilateralContactForces()
}
//---------------------------------------------------------------------------
void PenaltyContactFemToStatic::computeForces(std::shared_ptr< SceneObjectDeformable > sceneObject)
void PenaltyContactFemToStatic::computeForces(std::shared_ptr< DeformableSceneObject > sceneObject)
{
if(sceneObject->computeContactForce())
{
......
......@@ -25,7 +25,7 @@
// SimMedTK includes
#include "ContactHandling/PenaltyContactHandling.h"
#include "Simulators/VegaFemSceneObject.h"
#include "SceneModels/DeformableSceneObject.h"
///
/// @brief Penalty based for contact handling
......@@ -37,7 +37,7 @@ public:
PenaltyContactFemToStatic(bool typeBilateral,
const std::shared_ptr<SceneObject>& sceneObjFirst,
const std::shared_ptr<SceneObjectDeformable>& sceneObjSecond);
const std::shared_ptr<DeformableSceneObject>& sceneObjSecond);
virtual ~PenaltyContactFemToStatic();
......@@ -48,7 +48,7 @@ public:
virtual void computeBilateralContactForces() override;
/// \brief Get the forces on both the scene objects using penalty method
virtual void computeForces(std::shared_ptr<SceneObjectDeformable> sceneObject);
virtual void computeForces(std::shared_ptr<DeformableSceneObject> sceneObject);
};
......
......@@ -22,7 +22,6 @@
//---------------------------------------------------------------------------
#include "ContactHandling/PenaltyContactHandling.h"
#include "Simulators/VegaFemSceneObject.h"
#include "Core/CollisionPair.h"
PenaltyContactHandling::PenaltyContactHandling(bool typeBilateral) :
......
......@@ -25,7 +25,6 @@
// SimMedTK includes
#include "Core/ContactHandling.h"
#include "Simulators/SceneObjectDeformable.h"
#include "Core/CollisionPair.h"
/// \brief Penalty based for contact handling
......
......@@ -17,6 +17,7 @@ target_link_libraries(${Module}UnitTestRunner
ContactHandling
Solvers
SceneModels
TimeIntegrators
)
simple_test(${Module} --reporter=spec)
......@@ -28,8 +28,8 @@
#include "ContactHandling/PenaltyContactFemToStatic.h"
#include "Collision/PlaneCollisionModel.h"
#include "Core/CollisionPair.h"
#include "Simulators/VegaFemSceneObject.h"
#include "SceneModels/StaticSceneObject.h"
#include "SceneModels/VegaFEMDeformableSceneObject.h"
using namespace bandit;
......@@ -79,7 +79,7 @@ go_bandit([]() {
it("attaches a scene object ", []() {
auto handler = std::make_shared<PenaltyContactFemToStatic>(false);
auto fem = std::make_shared<VegaFemSceneObject>();
auto fem = std::make_shared<VegaFEMDeformableSceneObject>();
auto plane = createStaticPlaneSceneObject();
handler->setSceneObjects(plane,fem);
AssertThat(handler->getFirstSceneObject() == plane, IsTrue());
......@@ -90,24 +90,23 @@ go_bandit([]() {
it("computes contact force ", []() {
auto handler = std::make_shared<PenaltyContactFemToStatic>(false);
auto fem = std::make_shared<VegaFemSceneObject>();
auto fem = std::make_shared<VegaFEMDeformableSceneObject>();
auto collisionPair = createSampleCollisionPair();
auto plane = createStaticPlaneSceneObject();
handler->setSceneObjects(plane,fem);
handler->setCollisionPairs(collisionPair);
auto &v = fem->getVelocities();
v.push_back(1);
v.push_back(1);
v.push_back(1);
auto state = fem->getCurrentState();
state = std::make_shared<OdeSystemState>();
state->resize(3);
auto &f = fem->getForces();
f.push_back(0);
f.push_back(0);
f.push_back(0);
auto &v = state->getVelocities();
v(0) = 1;
v(1) = 1;
v(2) = 1;
// TODO: Add a more rigurous test.
// TODO: Add a more rigorous test.
fem->setContactForce(0,core::Vec3d(-110000,0,0));
auto &contactForce = fem->getContactForces();
......
......@@ -27,13 +27,10 @@
#include "SimulationManager/SDK.h"
// Include required types scene objects
#include "Simulators/VegaFemSceneObject.h"
#include "SceneModels/StaticSceneObject.h"
#include "Mesh/VegaVolumetricMesh.h"
// Include required simulators
#include "Simulators/VegaFEMModelSimulator.h"
#include "Simulators/DefaultSimulator.h"
#include "SceneModels/StaticSceneObject.h"
#include "SceneModels/VegaFEMDeformableSceneObject.h"
#include "Simulators/ObjectSimulator.h"
#include "Core/CollisionPair.h"
#include "Collision/PlaneCollisionModel.h"
......@@ -69,25 +66,25 @@ int main(int ac, char **av)
// Create scene actor 1: fem scene object + fem simulator
//-------------------------------------------------------
// create a FEM simulator
auto femSimulator = std::make_shared<VegaFEMModelSimulator>();
auto femSimulator = std::make_shared<ObjectSimulator>();
// create a Vega based FEM object and attach it to the fem simulator
auto femObject = std::make_shared<VegaFemSceneObject>(sdk->getErrorLog(),configFile);
auto femModel = std::make_shared<VegaFEMDeformableSceneObject>("nidusV1764.vtk",
configFile);
sdk->addSceneActor(femObject, femSimulator);
sdkSimulator->registerObjectSimulator(femSimulator);
sdk->addSceneActor(femModel, femSimulator);
//-------------------------------------------------------
// Create scene actor 2: plane + dummy simulator
//-------------------------------------------------------
// Create dummy simulator
auto staticSimulator = std::make_shared<DefaultSimulator>();
auto staticSimulator = std::make_shared<ObjectSimulator>();
// Create a static plane scene object of given normal and position
auto staticObject = std::make_shared<StaticSceneObject>();
auto plane = std::make_shared<PlaneCollisionModel>(core::Vec3d(0.0, 0.0, -35.0),
core::Vec3d(0.0, 0.0, 1.0));
auto plane = std::make_shared<PlaneCollisionModel>(core::Vec3d(0.0,0.0,-35.0),
core::Vec3d(0.0,0.0,1.0));
staticObject->setModel(plane);
sdk->addSceneActor(staticObject, staticSimulator);
......@@ -95,26 +92,32 @@ int main(int ac, char **av)
//-------------------------------------------------------
// Enable collision between scene actors 1 and 2
//-------------------------------------------------------
auto meshModel = std::make_shared<MeshCollisionModel>();
meshModel->setMesh(femObject->getVolumetricMesh()->getAttachedMesh(0));
auto meshModel = femModel->getCollisionModel();
if(!meshModel)
{
std::cout << "There is no collision model attached to this scene object" << std::endl;
}
else
{
auto planeMeshCollisionPairs = std::make_shared<CollisionPair>();
planeMeshCollisionPairs->setModels(meshModel, plane);
auto planeMeshCollisionPairs = std::make_shared<CollisionPair>();
planeMeshCollisionPairs->setModels(meshModel, plane);
sdkSimulator->addCollisionPair(planeMeshCollisionPairs);
sdkSimulator->addCollisionPair(planeMeshCollisionPairs);
auto planeToMeshCollisionDetection = std::make_shared<PlaneToMeshCollision>();
auto planeToMeshCollisionDetection = std::make_shared<PlaneToMeshCollision>();
sdkSimulator->registerCollisionDetection(planeToMeshCollisionDetection);
sdkSimulator->registerCollisionDetection(planeToMeshCollisionDetection);
//-------------------------------------------------------
// Enable contact handling between scene actors 1 and 2
//-------------------------------------------------------
auto planeToMeshContact = std::make_shared<PenaltyContactFemToStatic>(false);
planeToMeshContact->setCollisionPairs(planeMeshCollisionPairs);
planeToMeshContact->setSceneObjects(staticObject, femModel);
//-------------------------------------------------------
// Enable contact handling between scene actors 1 and 2
//-------------------------------------------------------
auto planeToMeshContact = std::make_shared<PenaltyContactFemToStatic>(false);
planeToMeshContact->setCollisionPairs(planeMeshCollisionPairs);
planeToMeshContact->setSceneObjects(staticObject, femObject);
sdkSimulator->registerContactHandling(planeToMeshContact);
}
sdkSimulator->registerContactHandling(planeToMeshContact);
//-------------------------------------------------------
// Customize the viewer
......
......@@ -27,26 +27,21 @@
#include "SimulationManager/SDK.h"
// Include required types scene objects
#include "SceneModels/StaticSceneObject.h"
#include "SceneModels/VegaFEMDeformableSceneObject.h"
#include "Mesh/VegaVolumetricMesh.h"
#include "Devices/VRPNForceDevice.h"
#include "Devices/VRPNDeviceServer.h"
#include "VirtualTools/ToolCoupler.h"
// Include required simulators
#include "Simulators/ObjectSimulator.h"
#include "Simulators/DefaultSimulator.h"
#include "Core/CollisionPair.h"
#include "Collision/PlaneCollisionModel.h"
#include "Collision/MeshCollisionModel.h"
#include "Collision/PlaneCollisionModel.h"
#include "Collision/PlaneToMeshCollision.h"
#include "ContactHandling/PenaltyContactFemToStatic.h"
#include "IO/IOMesh.h"
#include "Core/CollisionPair.h"
#include "Devices/VRPNDeviceServer.h"
#include "Devices/VRPNForceDevice.h"
#include "IO/InitIO.h"
#include "IO/IOMesh.h"
#include "Mesh/VegaVolumetricMesh.h"
#include "SceneModels/StaticSceneObject.h"
#include "SceneModels/VegaFEMDeformableSceneObject.h"
#include "Simulators/DefaultSimulator.h"
#include "Simulators/ObjectSimulator.h"
#include "VirtualTools/ToolCoupler.h"
#include "VTKRendering/InitVTKRendering.h"
int main(int ac, char** av)
......@@ -62,7 +57,7 @@ int main(int ac, char** av)
InitIODelegates();
//-------------------------------------------------------
// 1. Create an instance of the SoFMIS framework/SDK
// 1. Create an instance of the iMSTK framework/SDK
// 2. Create viewer
// 3. Create default scene (scene 0)
//-------------------------------------------------------
......@@ -167,37 +162,34 @@ int main(int ac, char** av)
// Enable collision between scene actors 1 and 2
//-------------------------------------------------------
auto sdkSimulator = sdk->getSimulator();
auto meshModel = std::make_shared<MeshCollisionModel>();
auto collisionMesh = volumeMesh->getCollisionMesh();
if(collisionMesh)
auto meshModel = femObject->getCollisionModel();
if(!meshModel)
{
meshModel->setMesh(collisionMesh);
std::cout << "There is no collision model attached to this scene object" << std::endl;
}
else
{
auto planeMeshCollisionPairs = std::make_shared<CollisionPair>();
femObject->setCollisionModel(meshModel);
auto planeMeshCollisionPairs = std::make_shared<CollisionPair>();
planeMeshCollisionPairs->setModels(meshModel, plane);
sdkSimulator->addCollisionPair(planeMeshCollisionPairs);
planeMeshCollisionPairs->setModels(meshModel, plane);
auto planeToMeshCollisionDetection = std::make_shared<PlaneToMeshCollision>();
sdkSimulator->addCollisionPair(planeMeshCollisionPairs);
sdkSimulator->registerCollisionDetection(planeToMeshCollisionDetection);
auto planeToMeshCollisionDetection = std::make_shared<PlaneToMeshCollision>();
//-------------------------------------------------------
// Enable contact handling between scene actors 1 and 2
//-------------------------------------------------------
auto planeToMeshContact = std::make_shared<PenaltyContactFemToStatic>(false);
sdkSimulator->registerCollisionDetection(planeToMeshCollisionDetection);
planeToMeshContact->setCollisionPairs(planeMeshCollisionPairs);
//-------------------------------------------------------
// Enable contact handling between scene actors 1 and 2
//-------------------------------------------------------
auto planeToMeshContact = std::make_shared<PenaltyContactFemToStatic>(false);
planeToMeshContact->setSceneObjects(staticObject, femObject);
planeToMeshContact->setCollisionPairs(planeMeshCollisionPairs);
sdkSimulator->registerContactHandling(planeToMeshContact);
planeToMeshContact->setSceneObjects(staticObject, femObject);
sdkSimulator->registerContactHandling(planeToMeshContact);
}
//-------------------------------------------------------
// Customize the viewer
//-------------------------------------------------------
......
......@@ -28,6 +28,7 @@
#include "Core/MakeUnique.h"
#include "IO/IOMesh.h"
#include "Geometry/MeshModel.h"
#include "Collision/MeshCollisionModel.h"
// Vega includes
#include "configFile.h"
......@@ -134,6 +135,7 @@ VegaConfiguration::VegaConfiguration(const std::string &configurationFile, bool
{
// TODO: Log this.
std::cout << "Empty configuration filename." << std::endl;
return;
}
this->vegaConfigFile = configurationFile;
......@@ -284,6 +286,11 @@ VegaFEMDeformableSceneObject(const std::string &meshFilename,
this->initialize();
}
//---------------------------------------------------------------------------
VegaFEMDeformableSceneObject::
VegaFEMDeformableSceneObject() : vegaFemConfig(new VegaConfiguration(""))
{}
//---------------------------------------------------------------------------
VegaFEMDeformableSceneObject::~VegaFEMDeformableSceneObject()
{ // This destructor must be defined here
......@@ -297,10 +304,14 @@ void VegaFEMDeformableSceneObject::loadVolumeMesh(const std::string &fileName)
meshModel->load(fileName);
this->setPhysicsModel(meshModel);
std::cout << "meshmodel = " << meshModel << std::endl;
this->volumetricMesh = std::static_pointer_cast<VegaVolumetricMesh>(meshModel->getMesh());
std::cout << "volumetricMesh = " << this->volumetricMesh << std::endl;
auto collisionModel = std::make_shared<MeshCollisionModel>();
collisionModel->setMesh(this->volumetricMesh->getCollisionMesh());
this->setCollisionModel(collisionModel);
if(!this->volumetricMesh)
{
......
......@@ -53,7 +53,7 @@ public:
VegaFEMDeformableSceneObject(const std::string &meshFilename,
const std::string &vegaConfigFileName);
VegaFEMDeformableSceneObject() = delete;
VegaFEMDeformableSceneObject();
~VegaFEMDeformableSceneObject();
///
......
simmedtk_add_library(Simulators
SOURCES
DefaultSimulator.cpp
SceneObjectDeformable.cpp
VegaFemSceneObject.cpp
VegaFEMModelSimulator.cpp
VegaObjectConfig.cpp
ObjectSimulator.cpp
PUBLIC_HEADERS
DefaultSimulator.h
SceneObjectDeformable.h
VegaFemSceneObject.h
VegaFEMModelSimulator.h
VegaObjectConfig.h
ObjectSimulator.h
)
......
// This file is part of the SimMedTK project.
// Copyright (c) Center for Modeling, Simulation, and Imaging in Medicine,
// Rensselaer Polytechnic Institute
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//---------------------------------------------------------------------------
//
// Authors:
//
// Contact:
//---------------------------------------------------------------------------
// SimMedTK includes
#include "Simulators/SceneObjectDeformable.h"
#include "Core/Factory.h"
#include <Core/RenderDelegate.h>
SceneObjectDeformable::SceneObjectDeformable() :
renderSecondaryMesh(false),
topologyAltered(false),
pulledVertex(-1),
timestepCounter(0),
subTimestepCounter(0)
{
this->setRenderDelegate(
Factory<RenderDelegate>::createConcreteClassForGroup(
"SceneObjectDeformableRenderDelegate",
RenderDelegate::RendererType::VTK));
}
SceneObjectDeformable::~SceneObjectDeformable()
{
}
void SceneObjectDeformable::applyContactForces()
{
for(const auto &cf : this->getContactForces())
{
int i = cf.first;
f_ext[i] += cf.second[0];
f_ext[i+1] += cf.second[1];
f_ext[i+2] += cf.second[2];
}
}
Eigen::Map<core::Vec3d> SceneObjectDeformable::getVelocity(const int dofID)
{
double *pointer = &uvel[dofID];
return Eigen::Map<core::Vec3d>(pointer);
}
core::Vec3d SceneObjectDeformable::getDisplacementOfNodeWithDofID(const int dofID) const
{
core::Vec3d disp(u[dofID], u[dofID + 1], u[dofID + 2]);
return disp;
}
core::Vec3d SceneObjectDeformable::getAccelerationOfNodeWithDofID(const int dofID) const
{
core::Vec3d accn(uaccel[dofID], uaccel[dofID + 1], uaccel[dofID + 2]);
return accn;
}
int SceneObjectDeformable::getNumNodes() const
{
return numNodes;
}
int SceneObjectDeformable::getNumTotalDof() const
{
return numTotalDOF;
}
int SceneObjectDeformable::getNumDof() const
{
return numDOF;
}
int SceneObjectDeformable::getNumFixedNodes() const
{
return numFixedNodes;
}
int SceneObjectDeformable::getNumFixedDof() const
{
return numFixedDof;
}
void SceneObjectDeformable::setRenderDetail(const std::shared_ptr<RenderDetail> &r)
{
primarySurfaceMesh->setRenderDetail(r);
if (secondarySurfaceMesh != nullptr)
{
secondarySurfaceMesh->setRenderDetail(r);
}
}
void SceneObjectDeformable::setRenderSecondaryMesh()
{
if (secondarySurfaceMesh != nullptr)
{
renderSecondaryMesh = true;
}
else
{
std::cout << "Secondary rendering mesh is not initilized! Cannot render secondary mesh\n";
}
}
void SceneObjectDeformable::setRenderPrimaryMesh()
{
renderSecondaryMesh = false;
}
std::shared_ptr<SurfaceMesh> SceneObjectDeformable::getPrimarySurfaceMesh() const
{
return primarySurfaceMesh;
}
std::shared_ptr<SurfaceMesh> SceneObjectDeformable::getSecondarySurfaceMesh() const
{
return secondarySurfaceMesh;
}
// This file is part of the SimMedTK project.
// Copyright (c) Center for Modeling, Simulation, and Imaging in Medicine,
// Rensselaer Polytechnic Institute
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//---------------------------------------------------------------------------
//
// Authors:
//
// Contact:
//---------------------------------------------------------------------------
#ifndef SMVEGAFEMSCENEOBJECT_DEFORMABLE_H
#define SMVEGAFEMSCENEOBJECT_DEFORMABLE_H
// STL includes
#include <unordered_map>
// SimMedTK includes
#include "Mesh/SurfaceMesh.h"
#include "SceneModels/SceneObject.h"
#include "Core/ErrorLog.h"
#include "VegaObjectConfig.h"
/// \brief Base class for any scene object that is defmormable
class SceneObjectDeformable : public SceneObject
{
public:
/// \brief Constructor
SceneObjectDeformable();
/// \brief Destructor
~SceneObjectDeformable();
/// \brief rest the object to inital configuration
/// and reset initial states
virtual void resetToInitialState() = 0;
/// \brief Load specified meshes
virtual void loadVolumeMesh() = 0;
/// \brief Load the rendering mesh if it is designated
virtual void loadSurfaceMesh() = 0;
/// \brief Load the data related to the vertices that will be fixed
virtual void loadFixedBC() = 0;
/// \brief Forces as a result of user interaction
/// (through an interface such as mouse or haptic device)
/// with the scene during runtime are added here
virtual void applyUserInteractionForces() = 0;
/// \brief Use the computed displacemetnt
/// update to interpolate to the secondary display mesh
virtual void updateSecondaryRenderingMesh() = 0;