Commit 08b08212 authored by Andrew Wilson's avatar Andrew Wilson
Browse files

ENH: CDHRefactor

parent bbc9cbb1
#-----------------------------------------------------------------------------
# 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}")
......@@ -56,9 +56,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
......@@ -20,20 +20,20 @@
=========================================================================*/
#include "imstkCamera.h"
#include "imstkCollidingObject.h"
#include "imstkCollisionGraph.h"
#include "imstkDirectionalLight.h"
#include "imstkHapticDeviceClient.h"
#include "imstkHapticDeviceManager.h"
#include "imstkKeyboardSceneControl.h"
#include "imstkDirectionalLight.h"
#include "imstkLogger.h"
#include "imstkMeshIO.h"
#include "imstkMouseSceneControl.h"
#include "imstkNew.h"
#include "imstkObjectInteractionFactory.h"
#include "imstkRigidBodyModel2.h"
#include "imstkRigidObject2.h"
#include "imstkRigidObjectController.h"
#include "imstkScene.h"
#include "imstkSceneManager.h"
#include "imstkSceneObjectController.h"
#include "imstkSimulationManager.h"
#include "imstkSphere.h"
#include "imstkTetrahedralMesh.h"
......@@ -62,6 +62,7 @@ main()
// Create bone scene object
// Load the mesh
auto tetMesh = MeshIO::read<TetrahedralMesh>(iMSTK_DATA_ROOT "/asianDragon/asianDragon.veg");
tetMesh->translate(Vec3d(0.0, -10.0, 0.0));
if (!tetMesh)
{
LOG(FATAL) << "Could not read mesh from file.";
......@@ -73,19 +74,30 @@ main()
scene->addSceneObject(bone);
// Create a virtual coupling object: Drill
imstkNew<Sphere> drillGeom(Vec3d(0.0, 0.0, 0.0), 3.0);
imstkNew<CollidingObject> drill("Drill");
imstkNew<Sphere> drillGeom(Vec3d(0.0, 0.0, 0.0), 3.0);
imstkNew<RigidObject2> drill("Drill");
drill->setCollidingGeometry(drillGeom);
drill->setVisualGeometry(drillGeom);
drill->setPhysicsGeometry(drillGeom);
imstkNew<RigidBodyModel2> rbdModel;
rbdModel->getConfig()->m_gravity = Vec3d(0.0, 0.0, 0.0);
rbdModel->getConfig()->m_dt = 0.01;
drill->setDynamicalModel(rbdModel);
scene->addSceneObject(drill);
// Create and add virtual coupling object controller in the scene
imstkNew<SceneObjectController> controller(drill, client);
imstkNew<RigidObjectController> controller(drill, client);
controller->setLinearKs(100.0);
controller->setLinearKd(10.0);
controller->setAngularKs(0.0);
controller->setAngularKd(0.0);
scene->addController(controller);
// Add interaction
scene->getCollisionGraph()->addInteraction(makeObjectInteractionPair(bone, drill,
InteractionType::CollidingObjToCollidingObjBoneDrilling, CollisionDetection::Type::PointSetToSphere));
InteractionType::RbdObjCollision, "PointSetToSphereCD"));
/*scene->getCollisionGraph()->addInteraction(makeObjectInteractionPair(bone, drill,
InteractionType::BoneDrilling, "PointSetToSphereCD"));*/
// Light
imstkNew<DirectionalLight> light;
......
......@@ -33,11 +33,4 @@ if(iMSTK_USE_OpenHaptics)
# Link libraries to executable
#-----------------------------------------------------------------------------
target_link_libraries(${PROJECT_NAME} SimulationManager)
#-----------------------------------------------------------------------------
# Associate external data
#-----------------------------------------------------------------------------
list(APPEND FILE_LIST
asianDragon/,REGEX:.*)
imstk_add_data(${PROJECT_NAME} ${FILE_LIST})
endif()
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& 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.txt
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.
=========================================================================*/
#include "imstkCamera.h"
#include "imstkCollidingObject.h"
#include "imstkCollisionDataDebugObject.h"
#include "imstkGeometryUtilities.h"
#include "imstkKeyboardDeviceClient.h"
#include "imstkKeyboardSceneControl.h"
#include "imstkMeshToMeshBruteForceCD.h"
#include "imstkMouseSceneControl.h"
#include "imstkNew.h"
#include "imstkOrientedBox.h"
#include "imstkRenderMaterial.h"
#include "imstkScene.h"
#include "imstkSceneManager.h"
#include "imstkSimulationManager.h"
#include "imstkSurfaceMesh.h"
#include "imstkVisualModel.h"
#include "imstkVTKRenderer.h"
#include "imstkVTKViewer.h"
using namespace imstk;
int
main()
{
// Setup logger (write to file and stdout)
Logger::startLogger();
// Create a box mesh
imstkNew<OrientedBox> box1(Vec3d::Zero(), Vec3d(0.5, 0.5, 0.5), Quatd::Identity());
imstkNew<OrientedBox> box2(Vec3d::Zero(), Vec3d(0.4, 0.4, 0.4), Quatd::Identity());
std::shared_ptr<SurfaceMesh> box1Mesh = GeometryUtils::toSurfaceMesh(box1);
std::shared_ptr<SurfaceMesh> box2Mesh = GeometryUtils::toSurfaceMesh(box2);
box2Mesh->rotate(Vec3d(0.0, 0.0, 1.0), PI_2 * 0.5);
box2Mesh->rotate(Vec3d(1.0, 0.0, 0.0), PI_2 * 0.5);
box2Mesh->translate(Vec3d(0.0, 0.8, 0.8));
// Setup the scene
imstkNew<Scene> scene("BoxBoxMeshTest");
scene->getActiveCamera()->setPosition(0.073, 1.743, 3.679);
scene->getActiveCamera()->setFocalPoint(0.333, 0.333, 0.25);
scene->getActiveCamera()->setViewUp(0.041, 0.928, -0.371);
imstkNew<CollidingObject> obj1("obj1");
obj1->setVisualGeometry(box1Mesh);
obj1->setCollidingGeometry(box1Mesh);
obj1->getVisualModel(0)->getRenderMaterial()->setOpacity(0.5);
obj1->getVisualModel(0)->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
scene->addSceneObject(obj1);
imstkNew<CollidingObject> obj2("obj2");
obj2->setVisualGeometry(box2Mesh);
obj2->setCollidingGeometry(box2Mesh);
obj2->getVisualModel(0)->getRenderMaterial()->setOpacity(0.5);
obj2->getVisualModel(0)->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
scene->addSceneObject(obj2);
imstkNew<MeshToMeshBruteForceCD> cd;
cd->setInputGeometryA(box1Mesh);
cd->setInputGeometryB(box2Mesh);
cd->setGenerateEdgeEdgeContacts(true);
cd->update();
// Debug Collision Geometry
imstkNew<CollisionDataDebugObject> cdDebugObj;
cdDebugObj->setInputCD(cd->getCollisionData());
cdDebugObj->setPrintContacts(true);
scene->addSceneObject(cdDebugObj);
// Run the simulation
{
// Setup a viewer to render
imstkNew<VTKViewer> viewer("Viewer");
viewer->setActiveScene(scene);
std::dynamic_pointer_cast<VTKRenderer>(viewer->getActiveRenderer())->setAxesLength(0.05, 0.05, 0.05);
// Setup a scene manager to advance the scene
imstkNew<SceneManager> sceneManager("Scene Manager");
sceneManager->setActiveScene(scene);
sceneManager->init();
sceneManager->update();
cdDebugObj->debugUpdate();
connect<KeyEvent>(viewer->getKeyboardDevice(), &KeyboardDeviceClient::keyPress, [&](KeyEvent* e)
{
const double s = 0.05;
if (e->m_key == 'i')
{
box2Mesh->translate(Vec3d(0.0, 0.0, 1.0) * s);
}
else if (e->m_key == 'k')
{
box2Mesh->translate(Vec3d(0.0, 0.0, -1.0) * s);
}
else if (e->m_key == 'j')
{
box2Mesh->translate(Vec3d(-1.0, 0.0, 0.0) * s);
}
else if (e->m_key == 'l')
{
box2Mesh->translate(Vec3d(1.0, 0.0, 0.0) * s);
}
else if (e->m_key == 'u')
{
box2Mesh->translate(Vec3d(0.0, -1.0, 0.0) * s);
}
else if (e->m_key == 'o')
{
box2Mesh->translate(Vec3d(0.0, 1.0, 0.0) * s);
}
else if (e->m_key == '1')
{
box2Mesh->rotate(Vec3d(0.0, 0.0, 1.0), 0.1);
}
else if (e->m_key == '2')
{
box2Mesh->rotate(Vec3d(0.0, 0.0, 1.0), -0.1);
}
else if (e->m_key == '3')
{
box2Mesh->rotate(Vec3d(0.0, 1.0, 0.0), 0.1);
}
else if (e->m_key == '4')
{
box2Mesh->rotate(Vec3d(0.0, 1.0, 0.0), -0.1);
}
box2Mesh->postModified();
box2Mesh->updatePostTransformData();
cd->update();
sceneManager->update();
cdDebugObj->debugUpdate();
});
imstkNew<SimulationManager> driver;
driver->addModule(viewer);
// Add mouse and keyboard controls to the viewer
{
imstkNew<MouseSceneControl> mouseControl(viewer->getMouseDevice());
mouseControl->setSceneManager(sceneManager);
viewer->addControl(mouseControl);
imstkNew<KeyboardSceneControl> keyControl(viewer->getKeyboardDevice());
keyControl->setSceneManager(sceneManager);
keyControl->setModuleDriver(driver);
viewer->addControl(keyControl);
}
driver->start();
}
return 0;
}
###########################################################################
#
# Copyright (c) Kitware, Inc.
#
# 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.txt
#
# 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.
#
###########################################################################
project(Example-BoxBoxMeshTest)
#-----------------------------------------------------------------------------
# Create executable
#-----------------------------------------------------------------------------
imstk_add_executable(${PROJECT_NAME} BoxBoxMeshTestExample.cpp)
#-----------------------------------------------------------------------------
# Add the target to Examples folder
#-----------------------------------------------------------------------------
SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/CollisionDetection)
#-----------------------------------------------------------------------------
# Link libraries to executable
#-----------------------------------------------------------------------------
target_link_libraries(${PROJECT_NAME} SimulationManager)
......@@ -16,21 +16,21 @@
#
###########################################################################
project(Example-CD-ManualCDWithOctree)
project(Example-OctreeIntersection)
#-----------------------------------------------------------------------------
# Create executable
#-----------------------------------------------------------------------------
imstk_add_executable(${PROJECT_NAME} ManualCDWithOctreeExample.cpp
../Sphere.cpp
../Box.cpp
../Triangle.cpp
../BunnyMesh.cpp)
imstk_add_executable(${PROJECT_NAME}
OctreeIntersectionExample.cpp
../BunnyMesh.cpp
OctreeDebugObject.h
OctreeDebugObject.cpp)
#-----------------------------------------------------------------------------
# Add the target to Examples folder
#-----------------------------------------------------------------------------
SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples)
SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/CollisionDetection)
#-----------------------------------------------------------------------------
# Link libraries to executable
......
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& 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.txt
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.
=========================================================================*/
#include "OctreeDebugObject.h"
#include "imstkLooseOctree.h"
namespace imstk
{
bool
OctreeDebugObject::updateGeom(OctreeNode* node)
{
if (node->m_Depth > m_maxDisplayDepth)
{
return false;
}
// Compute the current nodes vertices
// Which nodes are rendered
// The amount of child nodes rendered
int renderCount = 0;
Vec3d vertices[8];
bool rendered[8]{ false, false, false, false,
false, false, false, false };
// Recurse down the tree so long as the current node isn't a leaf
for (int i = 0; i < 8; i++)
{
vertices[i] = node->m_Center;
vertices[i][0] += (i & 1) ? node->m_HalfWidth : -node->m_HalfWidth;
vertices[i][1] += (i & 2) ? node->m_HalfWidth : -node->m_HalfWidth;
vertices[i][2] += (i & 4) ? node->m_HalfWidth : -node->m_HalfWidth;
if (!node->isLeaf())
{
rendered[i] = updateGeom(&node->m_pChildren->m_Nodes[i]);
renderCount += static_cast<int>(rendered[i]);
}
}
//--------------------------------------------------------
//
// 6-------7
// /| /|
// 2-+-----3 |
// | | | | y
// | 4-----+-5 | z
// |/ |/ |/
// 0-------1 +--x
//
// 0 => 0, 0, 0
// 1 => 0, 0, 1
// 2 => 0, 1, 0
// 3 => 0, 1, 1
// 4 => 1, 0, 0
// 5 => 1, 0, 1
// 6 => 1, 1, 0
// 7 => 1, 1, 1
//
//--------------------------------------------------------
// If the current node is empty
if (node->m_PrimitiveCounts[OctreePrimitiveType::Point] == 0
&& node->m_PrimitiveCounts[OctreePrimitiveType::Triangle] == 0
&& node->m_PrimitiveCounts[OctreePrimitiveType::Analytical] == 0)
{
// If we shouldn't draw empty parents
if (!m_drawNonEmptyParents)
{
// So long as no child is rendered
return renderCount > 0;
}
if (renderCount == 0 // Children did not render
&& node->m_pTree->getRootNode() != node) // Not root node, and no data in this node)
{
return false;
}
}
if (renderCount < 8) // If renderCount == 8 then no need to render this node
{
//const auto& debugLines = node->m_pTree->m_DebugGeometry;
for (int i = 0; i < 8; i++)
{
if ((i & 1) && (!rendered[i] || !rendered[i - 1]))
{
addLine(vertices[i], vertices[i - 1]);
}
if ((i & 2) && (!rendered[i] || !rendered[i - 2]))
{
addLine(vertices[i], vertices[i - 2]);
}
if ((i & 4) && (!rendered[i] || !rendered[i - 4]))
{
addLine(vertices[i], vertices[i - 4]);
}
}
}
return true;
}
void
OctreeDebugObject::debugUpdate(int maxDisplayDepth, bool drawNonEmptyParents)
{
m_maxDisplayDepth = maxDisplayDepth;
m_drawNonEmptyParents = drawNonEmptyParents;
// Clear the geometry
clear();
if (m_looseOctree != nullptr)
{
// Buffer the vertices and indices for lines to avoid reallocations
// Update the geometry, recursively appending for each node
updateGeom(m_looseOctree->getRootNode());
}
}
}
\ No newline at end of file
......@@ -21,44 +21,47 @@
#pragma once
#include "imstkVTKPolyDataRenderDelegate.h"
class vtkCellArray;
class vtkDoubleArray;
class vtkPoints;
class vtkPolyData;
#include "imstkDebugGeometryObject.h"
namespace imstk
{
class SurfaceMesh;
class LooseOctree;
class OctreeNode;
///
/// \class VTKdbgTrianglesRenderDelegate
/// \class OctreeDebugObject
///
/// \brief Render delegate for a set of disjoint triangles whose size could change
/// more frequently which is typically he case for rendering arbitrary set of triangles
/// \brief DebugGeometryObject for debug visualizing an octree
///
class VTKdbgTrianglesRenderDelegate : public VTKPolyDataRenderDelegate
class OctreeDebugObject : public DebugGeometryObject
{
public:
OctreeDebugObject() : DebugGeometryObject(),
m_looseOctree(nullptr),
m_maxDisplayDepth(5),
m_drawNonEmptyParents(true) { }
virtual ~OctreeDebugObject() override = default;
public:
///
/// \brief Constructor
/// \brief Update the geometry
/// \param Max depth to display
///
explicit VTKdbgTriangles