Skip to content
Snippets Groups Projects
Commit 488969d9 authored by Andrew Wilson's avatar Andrew Wilson :elephant:
Browse files

REFAC: Clean up stitch interface

parent 0a1f55a6
No related branches found
No related tags found
No related merge requests found
......@@ -33,4 +33,6 @@ SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/PBD)
#-----------------------------------------------------------------------------
target_link_libraries(${PROJECT_NAME}
SimulationManager
ViewerVTK)
\ No newline at end of file
ViewerVTK)
#target_compile_options(${PROJECT_NAME} PUBLIC -DUSE_THIN_TISSUE)
\ No newline at end of file
......@@ -46,10 +46,9 @@
using namespace imstk;
#define USE_FEM
//#define USE_HAPTICS
// #define USE_THIN_TISSUE
#ifdef USE_HAPTICS
#ifdef iMSTK_USE_OPENHAPTICS
#include "imstkHapticDeviceClient.h"
#include "imstkHapticDeviceManager.h"
#else
......@@ -155,6 +154,8 @@ makeTetGrid(const Vec3d& size, const Vec3i& dim, const Vec3d& center)
/// \brief Creates triangle grid geometry
/// \param cloth width (x), height (z)
/// \param cloth dimensions/divisions
/// \param center of tissue/translation control
/// \param tex coord scale
///
static std::shared_ptr<SurfaceMesh>
makeTriangleGrid(const Vec2d size,
......@@ -221,7 +222,7 @@ makeTriangleGrid(const Vec2d size,
}
///
/// \brief Creates tissue object
/// \brief Creates tetrahedral tissue object
/// \param name
/// \param physical dimension of tissue
/// \param dimensions of tetrahedral grid used for tissue
......@@ -239,16 +240,13 @@ makeTetTissueObj(const std::string& name,
// Setup the Parameters
auto pbdParams = std::make_shared<PbdModelConfig>();
#ifdef USE_FEM
// Use FEMTet constraints (42k - 85k for tissue, but we want
// something much more stretchy to wrap)
pbdParams->m_femParams->m_YoungModulus = 1000.0;
pbdParams->m_femParams->m_PoissonRatio = 0.4; // 0.48 for tissue
pbdParams->enableFemConstraint(PbdFemConstraint::MaterialType::StVK);
#else
pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Volume, 0.01);
pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, 0.4);
#endif
/* pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Volume, 0.01);
pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, 0.4);*/
pbdParams->m_doPartitioning = false;
pbdParams->m_uniformMassValue = 0.00001;
pbdParams->m_gravity = Vec3d(0.0, 0.0, 0.0);
......@@ -294,6 +292,9 @@ makeTetTissueObj(const std::string& name,
return tissueObj;
}
///
/// \brief Creates thin tissue object
///
static std::shared_ptr<PbdObject>
makeTriTissueObj(const std::string& name,
const Vec2d& size, const Vec2i& dim, const Vec3d& center)
......@@ -333,10 +334,9 @@ makeTriTissueObj(const std::string& name,
// Setup the VisualModel
auto material = std::make_shared<RenderMaterial>();
material->setBackFaceCulling(false);
material->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
material->setColor(Color(0.77, 0.53, 0.34));
material->setEdgeColor(Color(0.87, 0.63, 0.44));
material->setOpacity(0.5);
// Setup the Object
tissueObj->setVisualGeometry(triMesh);
......@@ -387,13 +387,12 @@ makeToolObj()
int
main()
{
// Setup logger (write to file and stdout)
Logger::startLogger();
const double capsuleRadius = 0.02;
const bool useThinTissue = false;
const double tissueLength = 0.15;
// Setup logger (write to file and stdout)
Logger::startLogger();
// Setup the scene
auto scene = std::make_shared<Scene>("PbdTissueStitch");
scene->getActiveCamera()->setPosition(0.0012, 0.0451, 0.1651);
......@@ -401,19 +400,15 @@ main()
scene->getActiveCamera()->setViewUp(0.0, 0.96, -0.28);
// Setup a tet tissue
std::shared_ptr<PbdObject> tissueObj = nullptr;
if (useThinTissue)
{
tissueObj = makeTriTissueObj("Tissue",
Vec2d(tissueLength, 0.07), Vec2i(15, 5),
Vec3d(tissueLength * 0.5, -0.01 - capsuleRadius, 0.0));
}
else
{
tissueObj = makeTetTissueObj("Tissue",
Vec3d(tissueLength, 0.01, 0.07), Vec3i(15, 2, 5),
Vec3d(tissueLength * 0.5, -0.01 - capsuleRadius, 0.0));
}
#ifdef USE_THIN_TISSUE
std::shared_ptr<PbdObject> tissueObj = makeTriTissueObj("Tissue",
Vec2d(tissueLength, 0.07), Vec2i(15, 5),
Vec3d(tissueLength * 0.5, -0.01 - capsuleRadius, 0.0));
#else
std::shared_ptr<PbdObject> tissueObj = makeTetTissueObj("Tissue",
Vec3d(tissueLength, 0.01, 0.07), Vec3i(15, 2, 5),
Vec3d(tissueLength * 0.5, -0.01 - capsuleRadius, 0.0));
#endif
scene->addSceneObject(tissueObj);
// Setup a capsule to wrap around
......@@ -433,11 +428,12 @@ main()
scene->addSceneObject(toolObj);
// Setup CD with a cylinder CD object
auto col1 = std::make_shared<PbdObjectCollision>(tissueObj, cdObj, "SurfaceMeshToCapsuleCD");
col1->setFriction(0.0);
scene->addInteraction(col1);
auto collisionInteraction = std::make_shared<PbdObjectCollision>(tissueObj, cdObj, "SurfaceMeshToCapsuleCD");
collisionInteraction->setFriction(0.0);
scene->addInteraction(collisionInteraction);
auto stitching = std::make_shared<PbdObjectStitching>(tissueObj);
stitching->setStitchDistance(0.015);
scene->addInteraction(stitching);
// Lights
......@@ -467,7 +463,7 @@ main()
driver->addModule(sceneManager);
driver->setDesiredDt(0.001);
#ifdef USE_HAPTICS
#ifdef iMSTK_USE_OPENHAPTICS
auto hapticManager = std::make_shared<HapticDeviceManager>();
hapticManager->setSleepDelay(0.1); // Delay for 1ms (haptics thread is limited to max 1000hz)
std::shared_ptr<HapticDeviceClient> deviceClient = hapticManager->makeDeviceClient();
......@@ -478,16 +474,13 @@ main()
[&](Event*)
{
const Vec2d& pos = viewer->getMouseDevice()->getPos();
if (useThinTissue)
{
deviceClient->setPosition(Vec3d(40.0, 40.0, -(pos[1] * 100.0 - 50.0)));
deviceClient->setOrientation(Quatd(Rotd(-0.6, Vec3d(0.0, 0.0, 1.0))));
}
else
{
deviceClient->setPosition(Vec3d(37.0, 0.0, -(pos[1] * 100.0 - 50.0)));
deviceClient->setOrientation(Quatd(Rotd(0.65, Vec3d(0.0, 0.0, 1.0))));
}
#ifdef USE_THIN_TISSUE
deviceClient->setPosition(Vec3d(40.0, 40.0, -(pos[1] * 100.0 - 50.0)));
deviceClient->setOrientation(Quatd(Rotd(-0.6, Vec3d(0.0, 0.0, 1.0))));
#else
deviceClient->setPosition(Vec3d(37.0, 0.0, -(pos[1] * 100.0 - 50.0)));
deviceClient->setOrientation(Quatd(Rotd(0.65, Vec3d(0.0, 0.0, 1.0))));
#endif
});
#endif
......@@ -501,7 +494,7 @@ main()
controller->setUseForceSmoothening(true);
scene->addController(controller);
#ifdef USE_HAPTICS
#ifdef iMSTK_USE_OPENHAPTICS
connect<ButtonEvent>(deviceClient, &HapticDeviceClient::buttonStateChanged,
[&](ButtonEvent* e)
{
......@@ -510,7 +503,7 @@ main()
auto toolGeom = std::dynamic_pointer_cast<LineMesh>(toolObj->getCollidingGeometry());
const Vec3d& v1 = toolGeom->getVertexPosition(0);
const Vec3d& v2 = toolGeom->getVertexPosition(1);
stitching->beginRayPointStitch(v1, (v2 - v1).normalized());
stitching->beginStitch(v1, (v2 - v1).normalized());
}
});
#endif
......@@ -531,7 +524,7 @@ main()
auto toolGeom = std::dynamic_pointer_cast<LineMesh>(toolObj->getCollidingGeometry());
const Vec3d& v1 = toolGeom->getVertexPosition(0);
const Vec3d& v2 = toolGeom->getVertexPosition(1);
stitching->beginRayPointStitch(v1, (v2 - v1).normalized());
stitching->beginStitch(v1, (v2 - v1).normalized());
}
// Reset
else if (e->m_key == 'r')
......@@ -575,10 +568,9 @@ main()
{
if (!stopped)
{
// Clear and reinit all constraints (new resting lengths)
stopped = true;
tissueObj->getPbdModel()->getConfig()->m_fixedNodeIds.clear();
// Clear and reinit all constraints
tissueObj->initialize();
}
}
......
......@@ -20,21 +20,16 @@ limitations under the License.
=========================================================================*/
#include "imstkPbdObjectStitching.h"
#include "imstkCDObjectFactory.h"
#include "imstkCellPicker.h"
#include "imstkLineMesh.h"
#include "imstkOneToOneMap.h"
#include "imstkPbdBaryPointToPointConstraint.h"
#include "imstkPbdModel.h"
#include "imstkPbdObject.h"
#include "imstkPointPicker.h"
#include "imstkSurfaceMesh.h"
#include "imstkSurfaceToTetraMap.h"
#include "imstkTaskGraph.h"
#include "imstkTetrahedralMesh.h"
#include "imstkVertexPicker.h"
#include "imstkSurfaceToTetraMap.h"
#include "imstkVisualModel.h"
#include "imstkRenderMaterial.h"
namespace imstk
{
......@@ -144,14 +139,13 @@ PbdObjectStitching::PbdObjectStitching(std::shared_ptr<PbdObject> obj) :
}
void
PbdObjectStitching::beginRayPointStitch(const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist)
PbdObjectStitching::beginStitch(const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist)
{
auto pointPicker = std::make_shared<PointPicker>();
pointPicker->setPickingRay(rayStart, rayDir, maxDist);
m_pickMethod = pointPicker;
m_mode = StitchMode::RayPoint;
m_isStitching = true;
m_performStitch = true;
LOG(INFO) << "Begin stitch";
}
......@@ -178,18 +172,15 @@ PbdObjectStitching::addStitchConstraints()
}
std::shared_ptr<VecDataArray<double, 3>> verticesPtr = pbdPhysicsGeom->getVertexPositions();
//VecDataArray<double, 3>& vertices = *verticesPtr;
// Get the attributes from the physics geometry
auto velocitiesPtr =
std::dynamic_pointer_cast<VecDataArray<double, 3>>(pbdPhysicsGeom->getVertexAttribute("Velocities"));
CHECK(velocitiesPtr != nullptr) << "Trying to vertex pick with geometry that has no Velocities";
//VecDataArray<double, 3>& velocities = *velocitiesPtr;
auto invMassesPtr =
std::dynamic_pointer_cast<DataArray<double>>(pbdPhysicsGeom->getVertexAttribute("InvMass"));
CHECK(invMassesPtr != nullptr) << "Trying to vertex pick with geometry that has no InvMass";
//const DataArray<double>& invMasses = *invMassesPtr;
std::shared_ptr<AbstractDataArray> indicesPtr = nullptr;
if (auto lineMesh = std::dynamic_pointer_cast<LineMesh>(pointSetToPick))
......@@ -221,30 +212,31 @@ PbdObjectStitching::addStitchConstraints()
indicesPtr.get(),
map);
auto getCellVerts = [&](const PickData& data)
{
const CellTypeId pickedCellType = data.cellType;
std::vector<std::pair<int, VertexMassPair>> cellIdVerts;
if (pickedCellType == IMSTK_TETRAHEDRON)
{
cellIdVerts = getElement<4>(data, meshStruct);
}
else if (pickedCellType == IMSTK_TRIANGLE)
{
cellIdVerts = getElement<3>(data, meshStruct);
}
else if (pickedCellType == IMSTK_EDGE)
{
cellIdVerts = getElement<2>(data, meshStruct);
}
std::vector<VertexMassPair> cellVerts(cellIdVerts.size());
for (size_t j = 0; j < cellIdVerts.size(); j++)
{
cellVerts[j] = cellIdVerts[j].second;
}
return cellVerts;
};
auto getCellVerts =
[&](const PickData& data)
{
const CellTypeId pickedCellType = data.cellType;
std::vector<std::pair<int, VertexMassPair>> cellIdVerts;
if (pickedCellType == IMSTK_TETRAHEDRON)
{
cellIdVerts = getElement<4>(data, meshStruct);
}
else if (pickedCellType == IMSTK_TRIANGLE)
{
cellIdVerts = getElement<3>(data, meshStruct);
}
else if (pickedCellType == IMSTK_EDGE)
{
cellIdVerts = getElement<2>(data, meshStruct);
}
std::vector<VertexMassPair> cellVerts(cellIdVerts.size());
for (size_t j = 0; j < cellIdVerts.size(); j++)
{
cellVerts[j] = cellIdVerts[j].second;
}
return cellVerts;
};
auto pointPicker = std::dynamic_pointer_cast<PointPicker>(m_pickMethod);
pointPicker->setUseFirstHit(false);
......@@ -330,23 +322,14 @@ PbdObjectStitching::addStitchConstraints()
}
}
// Digest the pick data based on grasp mode
if (m_mode == StitchMode::RayCell)
// Constrain only the pick points between the two elements
for (size_t i = 0; i < constraintPair.size(); i++)
{
// Constrain all vertices of the elements
// If a tetrahedron, use the mapped face
const PickData& pickData1 = constraintPair[i].first;
const PickData& pickData2 = constraintPair[i].second;
// If a surfacemesh just use the face
}
else if (m_mode == StitchMode::RayPoint)
{
// Constrain only the pick points between the two elements
for (size_t i = 0; i < constraintPair.size(); i++)
if (m_maxStitchDist == -1.0 || (pickData2.pickPoint - pickData1.pickPoint).norm() < m_maxStitchDist)
{
const PickData& pickData1 = constraintPair[i].first;
const PickData& pickData2 = constraintPair[i].second;
std::vector<VertexMassPair> cellVerts1 = getCellVerts(pickData1);
std::vector<double> weights1 = getWeights(cellVerts1, pickData1.pickPoint);
std::vector<VertexMassPair> cellVerts2 = getCellVerts(pickData2);
......@@ -383,13 +366,11 @@ PbdObjectStitching::updateStitching()
m_objectToStitch->updateGeometries();
// If started
if (!m_isPrevStitching && m_isStitching)
if (m_performStitch)
{
addStitchConstraints();
m_isStitching = false;
m_performStitch = false;
}
// Push back the state
m_isPrevStitching = m_isStitching;
updateConstraints();
}
......
......@@ -43,15 +43,6 @@ class PickingAlgorithm;
///
class PbdObjectStitching : public SceneObject
{
protected:
enum class StitchMode
{
Vertex, // Stitch two vertices together
Cell, // Stitch two cells together
RayPoint, // Stitch two points on two cells together found via rays
RayCell // Stitch two cells found via rays
};
public:
PbdObjectStitching(std::shared_ptr<PbdObject> obj1);
~PbdObjectStitching() override = default;
......@@ -66,34 +57,19 @@ public:
double getStiffness() const { return m_stiffness; }
///@}
/* ///
/// \brief Begin a vertex grasp (picking will begin on the next update)
/// \param Geometry attached/grasped too
///
void beginVertexGrasp(std::shared_ptr<AnalyticalGeometry> geometry);
///
/// \brief Begin a cell grasp (picking will begin on the next update)
/// \param Geometry attached/grasped too
/// \param The intersection type/class name
///
void beginCellGrasp(std::shared_ptr<AnalyticalGeometry> geometry, std::string cdType);*/
///
/// \brief Set/Get the maximum distance for which a stitch may be placed
///@{
void setStitchDistance(const double distance) { m_maxStitchDist = distance; }
double getStitchDistance() const { return m_maxStitchDist; }
///@}
///
/// \brief Begin a ray point grasp (picking will begin on the next update)
/// \brief Begin a ray point stitch. Stitches two points for separate elements.
/// \param Global space ray start
/// \param Global space ray direction
///
void beginRayPointStitch(const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist = -1.0);
/* ///
/// \brief Begin a ray point grasp (picking will begin on the next update)
/// \param Geometry attached/grasped too
/// \param Global space ray start
/// \param Global space ray direction
///
void beginRayCellStitch(std::shared_ptr<AnalyticalGeometry> geometry,
const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist = -1.0);*/
void beginStitch(const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist = -1.0);
///
/// \brief Compute/generate the constraints for stitching
......@@ -158,16 +134,13 @@ protected:
std::shared_ptr<PbdObject> m_objectToStitch = nullptr;
std::shared_ptr<PickingAlgorithm> m_pickMethod = nullptr;
StitchMode m_mode = StitchMode::Cell;
bool m_isStitching = false;
bool m_isPrevStitching = false;
bool m_performStitch = false;
/// Stiffness of stitches, when 1 the position is completely moved too the grasp point
/// when stiffness < 1 it will slowly converge on the grasp point
double m_stiffness = 0.1;
//bool m_retractingStitch = false; ///< Place a stitch that slowly retracts to 0 after placement
double m_stiffness = 0.1;
double m_maxStitchDist = -1.0; // Set a maximum distance for which a stitch can be placed
std::vector<std::shared_ptr<PbdBaryPointToPointConstraint>> m_constraints; ///< List of PBD constraints
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment