Commit 4365e56e authored by Ricardo Ortiz's avatar Ricardo Ortiz
Browse files

Merge branch 'RefactoringSDK' into 'master'

ENH: Refactoring the SDK and Assembler, cleaning other components.



See merge request !77
parents ad414954 adc98a11
......@@ -23,8 +23,9 @@
#include "CollisionContext/CollisionContext.h"
#include "Core/ContactHandling.h"
#include "Core/Model.h"
#include "TimeIntegrators/OdeSystem.h"
#include "Solvers/SystemOfEquations.h"
#include "TimeIntegrators/OdeSystem.h"
#include "SceneModels/InteractionSceneModel.h"
namespace imstk {
......@@ -71,19 +72,14 @@ void Assembler::type1Interactions()
return;
}
auto ch = this->collisionContext->getContactHandlers();
for(auto & ch : this->collisionContext->getContactHandlers())
{
const auto &forces = ch->getContactForces();
auto sceneModel = ch->getSecondSceneObject();
sceneModel->updateExternalForces(forces);
}
this->collisionContext->computeCollisions();
this->collisionContext->resolveContacts();
}
//---------------------------------------------------------------------------
void Assembler::initSystem()
{
this->collisionContext->createAdjacencyMatrix();
for(auto & rows : this->collisionContext->getIslands())
{
size_t dofSize = 0;
......@@ -95,12 +91,11 @@ void Assembler::initSystem()
{
// For the moment only DeformableSceneObject are SystemsOfEquations
auto sceneModel = this->collisionContext->getSceneModel(col);
auto linearSystem = std::dynamic_pointer_cast<SparseLinearSystem>(sceneModel);
if(sceneModel && linearSystem)
if(sceneModel)
{
this->equationList.push_back(linearSystem);
nnz += linearSystem->getMatrix().nonZeros();
dofSize += linearSystem->getRHSVector().size();
this->equationList.push_back(sceneModel);
nnz += sceneModel->getMatrix().nonZeros();
dofSize += sceneModel->getRHSVector().size();
}
}
......
......@@ -17,6 +17,11 @@
###########################################################################
set(MODULE_NAME Assembler)
if(WIN32)
remove_definitions(-DWIN32_LEAN_AND_MEAN)
endif(WIN32)
imstk_add_library(${MODULE_NAME}
SOURCES
Assembler.cpp
......@@ -25,15 +30,9 @@ imstk_add_library(${MODULE_NAME}
)
target_link_libraries(Assembler
PUBLIC
Core
PRIVATE
Event
ContactHandling
Simulators
Core
CollisionContext
TimeIntegrators
SceneModels
)
if(BUILD_TESTING)
......
......@@ -25,6 +25,6 @@ add_executable(${Module}UnitTestRunner
target_compile_options(${Module}UnitTestRunner PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wno-old-style-cast -Wno-multichar -Wno-type-limits>)
target_link_libraries(${Module}UnitTestRunner Assembler)
target_link_libraries(${Module}UnitTestRunner Core Assembler)
simple_test(${Module} --reporter=spec)
......@@ -177,7 +177,7 @@ if(MSVC)
set(msvc_suppressed_warnings
# C++ exception specification ignored except to indicate a function is not
# __declspec(nothrow)
"/wd4290"
"/wd4290 /wd4267"
)
set(msvc_other_flags
# Enable C++ Exceptions
......
......@@ -18,6 +18,10 @@
set(Module Collision)
if(WIN32)
remove_definitions(-DWIN32_LEAN_AND_MEAN)
endif(WIN32)
add_executable(${Module}UnitTestRunner
${BANDIT_RUNNER}
SpatialHashSpec.cpp
......
......@@ -19,14 +19,17 @@
#include "CollisionContext/CollisionContext.h"
#include "Solvers/SystemOfEquations.h"
#include "SceneModels/InteractionSceneModel.h"
#include "Core/CollisionDetection.h"
#include "Core/CollisionManager.h"
#include "Core/ContactHandling.h"
namespace imstk {
//---------------------------------------------------------------------------
void CollisionContext::addInteraction(
std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB,
std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB,
std::shared_ptr< CollisionDetection > collisionDetection,
std::shared_ptr< ContactHandling > contactHandlingA,
std::shared_ptr< ContactHandling > contactHandlingB,
......@@ -57,8 +60,8 @@ void CollisionContext::addInteraction(
//---------------------------------------------------------------------------
void CollisionContext::addInteraction(
std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB,
std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB,
std::shared_ptr< CollisionDetection > collisionDetection)
{
if (!sceneObjectA || !sceneObjectB || !collisionDetection)
......@@ -79,8 +82,8 @@ void CollisionContext::addInteraction(
//---------------------------------------------------------------------------
void CollisionContext::addInteraction(
std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB,
std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB,
std::shared_ptr< ContactHandling > contactHandler)
{
if (!sceneObjectA || !sceneObjectB)
......@@ -102,8 +105,8 @@ void CollisionContext::addInteraction(
//---------------------------------------------------------------------------
void CollisionContext::addInteraction(
std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB)
std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB)
{
if (!sceneObjectA || !sceneObjectB)
{
......@@ -121,8 +124,8 @@ void CollisionContext::addInteraction(
}
//---------------------------------------------------------------------------
void CollisionContext::disableInteraction(std::shared_ptr< SystemOfEquations > sceneObject1,
std::shared_ptr< SystemOfEquations > sceneObject2)
void CollisionContext::disableInteraction(std::shared_ptr< InteractionSceneModel > sceneObject1,
std::shared_ptr< InteractionSceneModel > sceneObject2)
{
auto it = this->interactionMap.find(std::make_tuple(sceneObject1, sceneObject2));
......@@ -140,8 +143,8 @@ void CollisionContext::disableInteraction(std::shared_ptr< SystemOfEquations > s
//---------------------------------------------------------------------------
void CollisionContext::removeInteraction(
std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB)
std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB)
{
if (!sceneObjectA || !sceneObjectB)
{
......@@ -163,8 +166,8 @@ void CollisionContext::removeInteraction(
//---------------------------------------------------------------------------
void CollisionContext::
setCollisionDetection(std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB,
setCollisionDetection(std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB,
std::shared_ptr< CollisionDetection > collisionDetection)
{
if (!sceneObjectA || !sceneObjectB || !collisionDetection)
......@@ -177,8 +180,8 @@ setCollisionDetection(std::shared_ptr< SystemOfEquations > sceneObjectA,
//---------------------------------------------------------------------------
void CollisionContext::
setContactHandling(std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB,
setContactHandling(std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB,
std::shared_ptr< ContactHandling > contactHandler)
{
if (!sceneObjectA || !sceneObjectB || !contactHandler)
......@@ -190,15 +193,15 @@ setContactHandling(std::shared_ptr< SystemOfEquations > sceneObjectA,
}
//---------------------------------------------------------------------------
bool CollisionContext::exist(std::shared_ptr< SystemOfEquations > sceneObject1,
std::shared_ptr< SystemOfEquations > sceneObject2)
bool CollisionContext::exist(std::shared_ptr< InteractionSceneModel > sceneObject1,
std::shared_ptr< InteractionSceneModel > sceneObject2)
{
auto it = this->interactionMap.find(std::make_tuple(sceneObject1, sceneObject2));
return it != std::end(this->interactionMap);
}
//---------------------------------------------------------------------------
void CollisionContext::createAssemblerAdjacencyMatrix()
void CollisionContext::createAdjacencyMatrix()
{
// Extract all potential interactive scene objects and create an index map
// in order to create the adjacency matrix
......@@ -222,13 +225,13 @@ void CollisionContext::createAssemblerAdjacencyMatrix()
}
// Populate the triplets for the adjacency matrix
auto numSystemOfEquationss = this->objectIndexMap.size();
auto numInteractionSceneModels = this->objectIndexMap.size();
// set the size of the adjacency matrix
this->interactionMatrix.resize(numSystemOfEquationss);
for (size_t i = 0; i < numSystemOfEquationss; ++i)
this->interactionMatrix.resize(numInteractionSceneModels);
for (size_t i = 0; i < numInteractionSceneModels; ++i)
{
this->interactionMatrix[i].resize(numSystemOfEquationss);
this->interactionMatrix[i].resize(numInteractionSceneModels);
}
std::vector<Eigen::Triplet<int>> triplets;
......@@ -248,6 +251,7 @@ void CollisionContext::createAssemblerAdjacencyMatrix()
if (i == std::end(this->objectIndexMap) || j == std::end(this->objectIndexMap))
{
// TODO: Log this
std::cout << "Warning: scene object does not have an index" << std::endl;
continue;
}
......@@ -264,38 +268,37 @@ void CollisionContext::createAssemblerAdjacencyMatrix()
if (i == std::end(this->objectIndexMap) || j == std::end(this->objectIndexMap))
{
// TODO: Log this
std::cout << "Warning: scene object does not have an index" << std::endl;
continue;
}
else
{
this->interactionMatrix[i->second][j->second] = 1;
}
this->interactionMatrix[i->second][j->second] = 1;
}
}
//---------------------------------------------------------------------------
void CollisionContext::solveSimultaneously(std::shared_ptr< SystemOfEquations > sceneObjectA,
std::shared_ptr< SystemOfEquations > sceneObjectB)
void CollisionContext::solveSimultaneously(std::shared_ptr< InteractionSceneModel > sceneObjectA,
std::shared_ptr< InteractionSceneModel > sceneObjectB)
{
auto i = this->objectIndexMap.find(sceneObjectA);
auto j = this->objectIndexMap.find(sceneObjectB);
if (i == std::end(this->objectIndexMap) || j == std::end(this->objectIndexMap))
{
// TODO: Log this
std::cout << "Warning: scene object does not have an index" << std::endl;
return;
}
else
{
this->modelPairs.emplace_back(sceneObjectA, sceneObjectB);
}
this->modelPairs.emplace_back(sceneObjectA, sceneObjectB);
}
//---------------------------------------------------------------------------
bool CollisionContext::configure()
{
this->createAssemblerAdjacencyMatrix();
this->createAdjacencyMatrix();
return true;
}
......@@ -331,7 +334,7 @@ std::vector<std::shared_ptr<ContactHandling>> CollisionContext::getContactHandle
handlerList.emplace_back(hA);
}
if (hB)
if (hB && hB != hA)
{
handlerList.emplace_back(hB);
}
......@@ -407,4 +410,47 @@ void CollisionContext::appendNeighbors(std::vector<bool>& visited,
}
}
//---------------------------------------------------------------------------
std::shared_ptr< InteractionSceneModel > CollisionContext::getSceneModel(int index)
{
auto fn = [ = ](const std::unordered_map<std::shared_ptr<InteractionSceneModel>, int>::value_type & vt)
{
return vt.second == index;
};
auto it = std::find_if(std::begin(this->objectIndexMap), std::end(this->objectIndexMap), fn);
if(it != std::end(this->objectIndexMap))
{
return it->first;
}
return nullptr;
}
//---------------------------------------------------------------------------
void CollisionContext::computeCollisions()
{
for(auto & interaction : this->interactionMap)
{
if(!std::get<Enabled>(interaction.second))
{
continue;
}
auto collisionDetection = std::get<Detection>(interaction.second);
auto collisionData = std::get<Data>(interaction.second);
collisionDetection->computeCollision(collisionData);
}
}
//---------------------------------------------------------------------------
void CollisionContext::resolveContacts()
{
for(auto & ch : this->getContactHandlers())
{
ch->resolveContacts();
}
}
}
......@@ -20,24 +20,19 @@
#ifndef COLLISION_CONTEXT_COLLISION_CONTEXT_H
#define COLLISION_CONTEXT_COLLISION_CONTEXT_H
// iMSTK includes
#include "Core/CoreClass.h"
#include "Core/Matrix.h"
#include "Core/Config.h"
// collision detection includes
#include "Core/CollisionDetection.h"
#include "Core/CollisionManager.h"
#include "Collision/PlaneToMeshCollision.h"
#include "Collision/SpatialHashCollision.h"
// contact handling includes
#include "Core/ContactHandling.h"
#include "ContactHandling/PenaltyContactFemToStatic.h"
#include<memory>
#include<tuple>
#include<vector>
#include<list>
#include<algorithm>
#include<unordered_map>
namespace imstk {
class SystemOfEquations;
class CollisionDetection;
class CollisionManager;
class ContactHandling;
class InteractionSceneModel;
///
/// \brief This class manages all the information related to
......@@ -54,8 +49,8 @@ public:
/// This type hold a pair of potential scene objects that need to
/// be queried for interaction
using InteractionPairType = std::tuple<std::shared_ptr<SystemOfEquations>,
std::shared_ptr<SystemOfEquations>> ;
using InteractionPairType = std::tuple<std::shared_ptr<InteractionSceneModel>,
std::shared_ptr<InteractionSceneModel>> ;
/// This type holds the algorithms and data types for the interaction pair
using InteractionPairDataType = std::tuple<std::shared_ptr<CollisionDetection>,
......@@ -69,8 +64,8 @@ public:
{
size_t operator()(const InteractionPairType &pair) const
{
size_t h1 = std::hash<std::shared_ptr<SystemOfEquations>>()(std::get<ObjectA>(pair));
size_t h2 = std::hash<std::shared_ptr<SystemOfEquations>>()(std::get<ObjectB>(pair));
size_t h1 = std::hash<std::shared_ptr<InteractionSceneModel>>()(std::get<ObjectA>(pair));
size_t h2 = std::hash<std::shared_ptr<InteractionSceneModel>>()(std::get<ObjectB>(pair));
return h1 ^ (h2 << 1);
};
};
......@@ -104,8 +99,8 @@ public:
///
/// \note Scene objects passed as arguments should be registered
///
void addInteraction(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB,
void addInteraction(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB,
std::shared_ptr<CollisionDetection> collisionDetection,
std::shared_ptr<ContactHandling> contactHandlingA,
std::shared_ptr<ContactHandling> contactHandlingB,
......@@ -117,63 +112,63 @@ public:
/// in the scene to the collision context. Assigns collision
/// detection method. This does not assign contact handler.
///
void addInteraction(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB,
void addInteraction(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB,
std::shared_ptr<CollisionDetection> collisionDetection);
///
/// \brief Adds two given scene objects will interact
/// in the scene to the collision context. Assigns contact handling method.
///
void addInteraction(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB,
void addInteraction(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB,
std::shared_ptr<ContactHandling> contactHandler);
///
/// \brief Adds two given scene objects that will interact in the scene to the
/// collision context
///
void addInteraction(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB);
void addInteraction(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB);
///
/// \brief Disables interaction between two given scene objects
///
void disableInteraction(std::shared_ptr<SystemOfEquations> sceneObject1,
std::shared_ptr<SystemOfEquations> sceneObject2);
void disableInteraction(std::shared_ptr<InteractionSceneModel> sceneObject1,
std::shared_ptr<InteractionSceneModel> sceneObject2);
///
/// \brief Removes interaction from the context between two given scene objects
///
void removeInteraction(std::shared_ptr<SystemOfEquations> sceneObject1,
std::shared_ptr<SystemOfEquations> sceneObject2);
void removeInteraction(std::shared_ptr<InteractionSceneModel> sceneObject1,
std::shared_ptr<InteractionSceneModel> sceneObject2);
///
/// \brief Assign a collision detection method between two scene given scene objects
///
void setCollisionDetection(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB,
void setCollisionDetection(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB,
std::shared_ptr<CollisionDetection> collisionDetection);
///
/// \brief Assign a contact handler method between two scene given scene objects
///
void setContactHandling(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB,
void setContactHandling(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB,
std::shared_ptr<ContactHandling> contactHandler);
///
/// \brief check if the interaction between two scene objects
/// already exists
///
bool exist(std::shared_ptr<SystemOfEquations> sceneObject1,
std::shared_ptr<SystemOfEquations> sceneObject2);
bool exist(std::shared_ptr<InteractionSceneModel> sceneObject1,
std::shared_ptr<InteractionSceneModel> sceneObject2);
///
/// \brief Populate the assembler adjacency matrix based on input
/// interactions
///
void createAssemblerAdjacencyMatrix();
void createAdjacencyMatrix();
///
/// \brief Count the number of interaction of type T.
......@@ -253,27 +248,15 @@ public:
/// \param sceneObjectA
/// \param sceneObjectB
///
void solveSimultaneously(std::shared_ptr<SystemOfEquations> sceneObjectA,
std::shared_ptr<SystemOfEquations> sceneObjectB);
void solveSimultaneously(std::shared_ptr<InteractionSceneModel> sceneObjectA,
std::shared_ptr<InteractionSceneModel> sceneObjectB);
///
/// \brief Get the scene model associated with ith index if exists.
///
/// \param index
///
std::shared_ptr<SystemOfEquations> getSceneModel(int index)
{
auto fn = [=](const std::unordered_map<std::shared_ptr<SystemOfEquations>,int>::value_type& vt)
{
return vt.second == index;
};
auto it = std::find_if(std::begin(this->objectIndexMap), std::end(this->objectIndexMap),fn);
if(it != std::end(this->objectIndexMap))
{
return it->first;
}
return nullptr;
}
std::shared_ptr<InteractionSceneModel> getSceneModel(int index);
///
/// \brief Get the scene model associated with ith index if exists.
......@@ -281,22 +264,32 @@ public:
/// \param index
///
template<typename T>
std::shared_ptr<SystemOfEquations> getSceneModelAs(int index)
std::shared_ptr<InteractionSceneModel> getSceneModelAs(int index)
{
auto sm = this->getSceneModel(index);
return std::dynamic_pointer_cast<T>(sm);
}
///
/// \brief Compute collision for all models in the scene
///
void computeCollisions();
///
/// \brief Resolve contacts for all models in the scene
///
void resolveContacts();
private:
std::vector<std::vector<int>> interactionMatrix; ///> Adjacency matrix for the
///> assembly graph (undirected)
InteractionMapType interactionMap;
std::unordered_map<std::shared_ptr<SystemOfEquations>, int> objectIndexMap;
std::unordered_map<std::shared_ptr<InteractionSceneModel>, int> objectIndexMap;
std::list<std::pair<std::shared_ptr<SystemOfEquations>,
std::shared_ptr<SystemOfEquations>>> modelPairs;
std::list<std::pair<std::shared_ptr<InteractionSceneModel>,
std::shared_ptr<InteractionSceneModel>>> modelPairs;
std::vector<std::vector<int>> islands;
int totalNumberOfSceneModels;
......
......@@ -18,6 +18,10 @@
set(Module CollisionContext)
if(WIN32)
remove_definitions(-DWIN32_LEAN_AND_MEAN)
endif(WIN32)
add_executable(${Module}UnitTestRunner
${BANDIT_RUNNER}
CollisionContextSpec.cpp
......
......@@ -18,7 +18,7 @@
// limitations under the License.
#include "ContactHandling/PenaltyContactFemToStatic.h"
#include "Core/CollisionManager.h"
#include "SceneModels/InteractionSceneModel.h"
namespace imstk {
......@@ -30,8 +30,8 @@ PenaltyContactFemToStatic::PenaltyContactFemToStatic(bool typeBilateral) : Penal
//---------------------------------------------------------------------------
PenaltyContactFemToStatic::PenaltyContactFemToStatic(
bool typeBilateral,
const std::shared_ptr<SceneObject>& sceneObjFirst,
const std::shared_ptr<DeformableSceneObject>& sceneObjSecond)
const std::shared_ptr<InteractionSceneModel>& sceneObjFirst,
const std::shared_ptr<InteractionSceneModel>& sceneObjSecond)
: PenaltyContactHandling(typeBilateral, sceneObjFirst, sceneObjSecond)
{
type = PenaltyFemToStatic;
......@@ -45,8 +45,7 @@ PenaltyContactFemToStatic::~PenaltyContactFemToStatic()
//---------------------------------------------------------------------------
void PenaltyContactFemToStatic::computeUnilateralContactForces()
{
auto femSceneObject = std::static_pointer_cast<DeformableSceneObject>(this->getSecondSceneObject());
this->computeForces(femSceneObject);
this->computeForces(this->getSecondInteractionSceneModel());
}
//---------------------------------------------------------------------------
......@@ -55,7 +54,7 @@ void PenaltyContactFemToStatic::computeBilateralContactForces()
}
//---------------------------------------------------------------------------