Commit ed212e8f authored by Sreekanth Arikatla's avatar Sreekanth Arikatla
Browse files

Merge branch 'CDHRefactor' into 'master'

ENH: CD and CH Refactored to Deal With Ambiguities

See merge request iMSTK/iMSTK!565
parents 099d1d2f ab85c196
#-----------------------------------------------------------------------------
# Add External Project
#-----------------------------------------------------------------------------
include(imstkAddExternalProject)
imstk_define_external_dirs( SCCD )
if(MSVC)
set(config_dir "$(Configuration)")
endif()
set(copy_sccd_headers_command
${CMAKE_COMMAND} -E copy_directory
${SCCD_SOURCE_DIR}/inc
${CMAKE_INSTALL_PREFIX}/include/sccd
)
if(WIN32)
set(copy_sccd_lib_command
${CMAKE_COMMAND} -E copy
${SCCD_BINARY_DIR}/src/${config_dir}/sccd$<$<CONFIG:Debug>:d>.lib
${CMAKE_INSTALL_PREFIX}/lib
)
else()
set(copy_sccd_lib_command
${CMAKE_COMMAND} -E copy
${SCCD_BINARY_DIR}/src/${config_dir}/libsccd$<$<CONFIG:Debug>:d>.a
${CMAKE_INSTALL_PREFIX}/lib
)
endif()
imstk_add_external_project( SCCD
URL https://gitlab.kitware.com/iMSTK/SCCD/-/archive/addressWarnings/SCCD-addressWarnings.zip
URL_MD5 a45b33df99ea3e7ad85340afe8dcc489
CMAKE_CACHE_ARGS
-DBUILD_SAMPLE_APP:BOOL=OFF
RELATIVE_INCLUDE_PATH "inc"
INSTALL_COMMAND
COMMAND ${copy_sccd_headers_command}
COMMAND ${copy_sccd_lib_command}
DEPENDENCIES
Eigen3
#VERBOSE
)
include(imstkFind)
#-----------------------------------------------------------------------------
# Find All Headers and Libraries for SCCD
#-----------------------------------------------------------------------------
imstk_find_header(SCCD ccdAPI.h sccd)
imstk_find_libary(SCCD sccd)
imstk_find_package(SCCD)
#message(STATUS "SCCD include : ${SCCD_INCLUDE_DIRS}")
#message(STATUS "SCCD libraries : ${SCCD_LIBRARIES}")
......@@ -57,9 +57,6 @@ if (iMSTK_USE_PHYSX)
find_package(PhysX REQUIRED)
endif()
#SCCD
find_package( SCCD REQUIRED )
# SFML
if(WIN32)
find_package( SFML REQUIRED )
......
......@@ -147,7 +147,6 @@ if(${PROJECT_NAME}_SUPERBUILD)
if (${PROJECT_NAME}_USE_PHYSX)
imstk_define_dependency(PhysX)
endif()
imstk_define_dependency(SCCD)
imstk_define_dependency(tbb)
imstk_define_dependency(VegaFEM)
imstk_define_dependency(VTK)
......@@ -235,9 +234,6 @@ if (${PROJECT_NAME}_USE_PHYSX)
find_package(PhysX REQUIRED)
endif()
# SCCD
find_package( SCCD REQUIRED )
# SFML
if(APPLE OR LINUX)
remove_definitions( -DiMSTK_AUDIO_ENABLED )
......
8d7fefd9b6e7f114f6812e99cf8348504fb17ddfd82c5102e61cd3875397da2c471651bf455b30658e2a2cf0615f0db25c662328c5f3556856d61c97dcfed31d
\ No newline at end of file
This diff is collapsed.
Collision Handling
==================
:code:`CollisionHandling` classes in iMSTK defines methods for handling collisions. That is, one may want to take action when a collision happens. This is either an instant response (explicit solution) or something added to a system to solve later (implicitly).
:code:`CollisionHandling` classes in iMSTK defines methods for handling collisions. They take input objects (often two) and input collision data. When updated they will consume the collision data to produce appropriate responses. Normally this is a response in a dynamical system. This may either be an instant response at the time of handling or something (such as a constraint) added to the system to solve and produce the response later.
Collision handling methods directly consume collision data which is produced by :code:`CollisionDetection` objects. For this reason, every :code:`CollisionHandling` constructor accepts a :code:`CollisionData` object.
CollisionHandlers and CollisionDetection is normally setup by an interaction through the scene such that the user doesn't have to mess with them unless they want to change parameters of a handler/detection or even subclass them for custom functionalities.
Collision handling happens between a pair of objects. Given this pair the handling has a side. We can either handle the collision for object A, object B, or both at the same time/AB.
LevelSetCH
--------------------------------
With this you will see three strategies then:
The levelSetCH consumes PointDirection data from a collision detection method to produce impulses/movement in a LevelSet using gaussian kernels. One can alter this kernel size, gaussian sigma. If one chooses to use proportional velocity, then the force of the rigid object is considered in how fast the level set is moved.
While the handler is standalone and can be used in other contexts, it finds its main use in the RigidObjectLevelSetCollision interaction which may be used like so:
::
imstkNew<RigidObjectLevelSetCollision> interaction(rbdObj, femurObj);
scene->getCollisionGraph()->addInteraction(interaction);
Should more control be needed one can access the underlying handlers like so:
::
auto colHandlerA = std::dynamic_pointer_cast<RigidBodyCH>(interaction->getCollisionHandlingA());
colHandlerA->setUseFriction(false);
colHandlerA->setBeta(0.05); // inelastic collision
auto colHandlerB = std::dynamic_pointer_cast<LevelSetCH>(interaction->getCollisionHandlingB());
colHandlerB->setLevelSetVelocityScaling(0.01);
colHandlerB->setKernel(3, 1.0);
colHandlerB->setUseProportionalVelocity(true);
PBDCollisionHandling
--------------------------------
Given two input objects (pbd vs pbd or pbd vs colliding/static) and input collision data it will produce collision constraints in a solver to then be solved later. One of the more complex handlers in iMSTK and handles many cases:
The implementation of this handler is broken into two functions:
* Mesh-Non-Mesh Interactions: The PbdObject is garunteed to be a mesh, but the CollidingObject could be mesh, a primitive, an implicit geometry, etc. The following CD data's are handled:
* PointIndexDirection-None: Moves the vertex of the mesh (given by index) in the direction and depth specified by the element.
* Triangle-Vertex/PointDirection: Moves the triangle to the vertex.
* Edge-Vertex/PointDirection: Moves the edge to the vertex.
* Mesh-Mesh Interactions: In the case both are a mesh the following CD data's are handled:
* Vertex-Triangle/Triangle-Vertex: Moves the vertex and triangle to just touching.
* Edge-Edge: Moves the two edges to just touching.
* Edge-Vertex/Vertex-Edge: Moves the vertex and edge to just touching.
Whats supported then:
* PbdObject vs PbdObject mesh collisions.
* PbdObject vs CollidingObject mesh collisions.
* PbdObject vs CollidingObject primitive collisions.
* PbdObject vs CollidingObject implicit geometry collisions.
The PbdCollisionHandling can be used through the PbdObjectCollision interaction like so:
::
// Add collision between the two objects with the following collision strategy
imstkNew<PbdObjectCollision> myCollision(tissueObj, toolObj, "MeshToMeshBruteForceCD");
scene->getCollisionGraph()->addInteraction(myCollision);
If more control is needed that is not available in the PbdObjectCollision, you may attain the handler like so:
::
imstkNew<CustomSPHCollisionHandlerOneSided> handler(sphObj1, Side::A, collisionData);
imstkNew<CustomSPHCollisionHandlerOneSided> handler(sphObj1, Side::A, collisionData);
imstkNew<CustomSPHCollisionHandlerOneSided> handler(sphObj2, Side::B, collisionData);
imstkNew<CustomSPHCollisionHandlerTwoSided> handler(sphObj1, sphObj2, collisionData);
auto pbdHandler = std::dynamic_pointer_cast<PbdCollisionHandling>(myCollision->getCollisionHandlingA());
Generally, having one sided collision handlers is better for modularity, but sometimes it is required to consider both models.
When subclassing one may override the base class handling function which is called to consume the collision data or you may override the constraint addition functions. Such functions are useful when custom response (say constraints) is needed upon contact. See PbdTissueSurfaceNeedleContact example for subclassing.
Typical usage in an iMSTK Scene will be done through iMSTK interactions found in the scene. Interactions agglomerate CollisionHandling (how to consume collision data) and CollisionDetection to produce an interaction between SceneObjects (objects on the scene level).
You can read more about interactions here.
\ No newline at end of file
PBDPickingCH
--------------------------------
The PbdPickingCH consumes CD data to constrain PbdObject vertices in contact with an analytical geometry. It constraints them such that their relative positions to the analytical geometry origin and orientation are maintained. It may only be used with PbdObject vs CollidingObject that has an analytical geometry.
The user can call beginPick or endPick to constrain or unconstrain the PbdObject vertices.
The PbdPickingCH can be used through the PbdObjectPicking interaction like so:
::
// Add picking interaction between a clothObj (PbdObject) and toolObj (with capsule analytical geometry)
imstkNew<PbdObjectPicking> objectPicking(clothObj, toolObj, "PointSetToCapsuleCD");
scene->getCollisionGraph()->addInteraction(objectPicking);
PenaltyCH
--------------------------------
The PenaltyCH uses a penalty response method between a FEM simulated and rigid body object. It consumes CD data between the geometries and produces forces in both models. It currently only works with PointDirection data, of which only primtive collision detection supports. So it is currently limited to implicit and primitive shapes only.
RigidBodyCH
--------------------------------
The RigidBodyCH handles collisions between two RigidObject2's or a RigidObject2 and a CollidingObject (where CollidingObject is static/immovable by the rigid object). Currently it only handles mesh to primitive+implicit and primitive to primitive rigid body shapes. It can be used through the RigidObjectCollision interaction like so:
::
// Create an interaction between a rigid object with a sphere and CollidingObject with plane geometry, resolves undirectionally (always above the plane normal)
auto rbdInteraction = std::make_shared<RigidObjectCollision>(rbdObjSphere, planeObj, "UnidirectionalPlaneToSphereCD");
rbdInteraction->setFriction(0.0);
rbdInteraction->setStiffness(0.0001);
scene->getCollisionGraph()->addInteraction(rbdInteraction);
Another example using between a rigid OBB and an implicit/SDF geometry:
::
// Create an interaction between a rigid object with a OBB geometry and CollidingObject with an SignedDistanceField geometry (great for static curved surfaces)
auto rbdInteraction = std::make_shared<RigidObjectCollision>(cubeObj, planeObj, "ImplicitGeometryToPointSetCD");
rbdInteraction->setFriction(0.0); // Don't use friction
rbdInteraction->setStiffness(0.05);
scene->getCollisionGraph()->addInteraction(rbdInteraction);
SPHCollisionHandling
--------------------------------
The SPHCollisionHandling moves SPH particles out of collision with an object and applies boundary friction to the velocity of the particle. It currently only works with PointDirection data, of which only primtive collision detection supports. So it is currently limited to implicit and primitive shapes only.
One may use it through the SPHCollision interaction like so:
::
// Add collision between the two objects (fluidObj is SPHObject and solidObj is a CollidingObject with primitive geometry)
imstkNew<SphObjectCollision> myCollision(fluidObj, solidObj);
scene->getCollisionGraph()->addInteraction(myCollision);
\ No newline at end of file
......@@ -17,7 +17,7 @@ The "connect" function is used to add a receiver/observer to a sender. There are
Consider a KeyboardDeviceClient. It may emit a KeyEvent.
::
.. code:: c++
std::shared_ptr<KeyboardDeviceClient> myKeyboardDevice = ...
connect<KeyEvent>(myKeyboardDevice, &KeyboardDeviceClient::keyPress, [&](KeyEvent* e)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment