iMSTK issueshttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues2022-09-26T12:07:27-04:00https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/455Needle Component2022-09-26T12:07:27-04:00Andrew WilsonNeedle ComponentWith the component MR we are able to add a needle component. Which can be carried around in a SceneObject without subclassing. This would be a good next step towards a general needle architecture.
ie:
```
class NeedleComponent : public ...With the component MR we are able to add a needle component. Which can be carried around in a SceneObject without subclassing. This would be a good next step towards a general needle architecture.
ie:
```
class NeedleComponent : public Component
{
public:
// Could be stored in component as well
virtual Vec3d getNeedleDirection() { return Vec3d::Zero(); }
virtual Vec3d getNeedleTip() { return Vec3d::Zero(); }
PunctureState punctureState;
};
int main()
{
SceneObject obj0;
auto needleComp0 = obj0.addComponent<NeedleComponent>();
PbdObject obj1;
auto needleComp1 = obj1.addComponent<NeedleComponent>();
RigidObject obj2;
auto needleComp2 = obj2.addComponent<NeedleComponent>();
}
```
This dissolves the need for NeedleObject in every example which is especially annoying when different subclasses are used. One can refactor the examples and leave NeedleObjects in but just have the NeedleObjects add a NeedleComponent. Additionnally interaction will need to use the component now to get things like tip, direction, etc.Andrew WilsonAndrew Wilsonhttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/435Update logic inside `EdgeEdgeCCDState` with function call to `edgeToEdgeClose...2022-08-17T10:27:26-04:00Shreeraj JadhavUpdate logic inside `EdgeEdgeCCDState` with function call to `edgeToEdgeClosestPoints`Remove duplicate implementation and simplify `CollisionDetection/EdgeEdgeCCDState` by calling `CollisionUtils::edgeToEdgeClosestPoints` inside `EdgeEdgeCCDState`.
See: https://gitlab.kitware.com/iMSTK/iMSTK/-/blob/36664de0e276828c6b61e4...Remove duplicate implementation and simplify `CollisionDetection/EdgeEdgeCCDState` by calling `CollisionUtils::edgeToEdgeClosestPoints` inside `EdgeEdgeCCDState`.
See: https://gitlab.kitware.com/iMSTK/iMSTK/-/blob/36664de0e276828c6b61e4436e7899c9f6294119/Source/CollisionDetection/imstkCollisionUtils.h#L1038Jacob MooreJacob Moorehttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/420SurfaceMesh deepCopy parameter2022-08-30T13:25:25-04:00Connor BowleySurfaceMesh deepCopy parameterNot necessarily a big deal, but it was unexpected to me that I can only deep copy SurfaceMesh's if the one I want to copy is stored in a `shared_ptr`. I would expect the signature to instead be `void deepCopy(const SurfaceMesh& srcMesh)`...Not necessarily a big deal, but it was unexpected to me that I can only deep copy SurfaceMesh's if the one I want to copy is stored in a `shared_ptr`. I would expect the signature to instead be `void deepCopy(const SurfaceMesh& srcMesh)`, as there is no true requirement that one can only copy 1) surface meshes that are specifically stored in shared pointer, and 2) non-const surface meshes (as the current parameter is `shared_ptr<SurfaceMesh>` and not `shared_ptr<const SurfaceMesh>`.
As an aside regarding a comment in the code for deepCopy, `\todo: generalize base classes and implement for every geometry`, please consider using a clone approach rather than a deep copy approach so it will work nicely with class hierarchies. You wouldn't really be able to implement `void PointSet::deepCopy(const PointSet& src)` because I could do something like `surfaceMesh.deepCopy(lineMesh)` and that can't happen (yes, you could detect this at runtime and throw and exception (or do the VTK method and silently ignore it), but ensuring the type safe clone can always happen is better). However, doing `surfaceMesh.clone()` or even `pointSetThatCouldBeASurfaceMesh.clone()` is always well defined.
Also, should you go the clone route, I found this a neat way to fake covariant return types with smart pointers.
https://www.fluentcpp.com/2017/09/12/how-to-return-a-smart-pointer-and-use-covariance/
For reference:
- https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c130-for-making-deep-copies-of-polymorphic-classes-prefer-a-virtual-clone-function-instead-of-public-copy-constructionassignmenthttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/407Upgrade Examples That use Mouse Virtual Coupling to use DummyClient2022-08-22T03:17:53-04:00Andrew WilsonUpgrade Examples That use Mouse Virtual Coupling to use DummyClientRight now many examples implement a dumbed down virtual coupling in their post update with mouse controls. These should be ported to use DummyClient so that we can reuse the virtual coupling implemented in RigidObjectController.Right now many examples implement a dumbed down virtual coupling in their post update with mouse controls. These should be ported to use DummyClient so that we can reuse the virtual coupling implemented in RigidObjectController.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/406Consolidate RbdConstraint & PbdConstraint2022-09-27T20:45:41-04:00Andrew WilsonConsolidate RbdConstraint & PbdConstraintThe RbdConstraint & PbdConstraint could become more similar in implementation.
- [ ] Use a flag or some other interface to indicate that a constraint, be it PbdConstraint or RbdConstraint. Should be clearable. IE: Put into a separate c...The RbdConstraint & PbdConstraint could become more similar in implementation.
- [ ] Use a flag or some other interface to indicate that a constraint, be it PbdConstraint or RbdConstraint. Should be clearable. IE: Put into a separate container that is cleared every simulation frame.
- [ ] This would require introduction of a container of constraints in RigidBodyModel that does not clear. New feature.
- [ ] Rename RbdConstraint::compute to computeValueAndGradient, to match Pbd.
- [ ] Pass in the required constraint values by reference like computeValueAndGradient. J & vu.
- [ ] Explore why computeValueGradient is not called in a loop before RigidBodyModel::Solve.
- [ ] The signs might be backwards in one of the constraint gradients (I think RbdConstraint has backward sign).
- [ ] Consider renaming PbdConstraint::initConstraint to PbdConstraint::init. Then introducing RbdConstraint::init & removing constructor initialization.
- [ ] Remove PbdCollisionConstraint. Rework all PbdConstraints to stem from the same base PbdConstraint (may not be possible performantly without templates, was attempted at numerous points, difficult).
This should make it much easier to work with the two models.
I suspect as we approach a proper solution of compliance between the two models we will arrive at something similar to PBD rigid bodies described in the paper "Detailed Rigid Body Simulation with Extended Position Based Dynamics"https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/395ViewerVTK & RenderingVTK Module Toggles2022-05-12T22:25:15-04:00Andrew WilsonViewerVTK & RenderingVTK Module TogglesNow that the libraries have been separated we may add a toggle for ViewerVTK & RenderingVTK which will allow one to build without these modules. Ultimately for using iMSTK as a physics backend only (a VTK without vtk rendering or differe...Now that the libraries have been separated we may add a toggle for ViewerVTK & RenderingVTK which will allow one to build without these modules. Ultimately for using iMSTK as a physics backend only (a VTK without vtk rendering or different rendering libs can be provided).https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/392TBB Upgrade2021-12-20T15:57:18-05:00Andrew WilsonTBB UpgradeTBB should be upgraded, at least soon after the VTK9.1 goes in so they can be on the same version. It hasn't appeared to cause any issues.TBB should be upgraded, at least soon after the VTK9.1 goes in so they can be on the same version. It hasn't appeared to cause any issues.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/384Entity-Component (ECS) for Scene Object Interface2022-09-26T12:07:35-04:00Andrew WilsonEntity-Component (ECS) for Scene Object InterfaceIntroduction
---
The entity-component architecture is a well known architecture used in many game engines (ECS is more widely used). The motivation behind it is the desire for modularity and extensibility of a scene object interface. The...Introduction
---
The entity-component architecture is a well known architecture used in many game engines (ECS is more widely used). The motivation behind it is the desire for modularity and extensibility of a scene object interface. The idea is to prefer composition over inheritance for the scene object interface. This allows one to add/remove functionality (components) to an object easily. This also allows things like object morphing as you are not tied to a subclass (ex: a PbdObject can become a FemObject by addition of PbdModel and removal of FemModel).
A quick simple psuedo-example for the very unfamiliar (note many ECSs are data oriented and may not have an update, or hybrid and have a subclass that then adds the update):
```
class Component
{
virtual void update() = 0;
}
class Object
{
Component[] components;
void update()
{
for (every comp i in components) { comp.update(); }
}
}
// One should subclass Component to add functionality to Object
```
iMSTK is well suited for this type of architecture due to the large amount of "intra-object customization" required by users. This has been on iMSTK's plate for awhile and it's been lightly moving towards/prepping for it for quite some time now (moving functionality out of the Objects).
Example Use Case
---
Here's an idea of something that could be possible depending on design:
- Ex1: One could construct a ThreadObject which contains PbdModel & AnimatedModel components. Which simulates a line mesh and skins it to a thread geometry.
- Ex2: One could construct a SkinObject which contains multiple PbdModel's, VisualModels, & GeometryMap components.
- Ex3: One could construct a SkinObject which contains one PbdModel but multiple VisualModels + GeometryMap components.
- Ex4: One could construct a all-in-one tool (say arthoscope head) which contains a Camera, Light, RbdModel, & GeometryMap. Possibly even multiple RbdModel's for each piece.
Continued details in documents:
Documents
---
[Notion UML Diagram + Notes](https://www.notion.so/Imstk-ECS-8a00a245e9214ea187d29976e2f02784)Andrew WilsonAndrew Wilsonhttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/372Build without OpenVR support2022-04-12T16:46:28-04:00Connor BowleyBuild without OpenVR supportFor projects that don't need OpenVR, it would be useful to have a build flag to turn off OpenVR support and not require OpenVR in the build process.For projects that don't need OpenVR, it would be useful to have a build flag to turn off OpenVR support and not require OpenVR in the build process.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/368PbdConstraintFunctors should be constructed in PbdModelConfig and used for pa...2021-12-15T17:29:07-05:00Andrew WilsonPbdConstraintFunctors should be constructed in PbdModelConfig and used for parametersOne of the issues with the PbdModelConfig is how it stores parameters. Each Functor could have any set of parameters. Generally:
- "Regular Constraints": Have one double stiffness value
- FEMConstraints: Have either possions ratio+you...One of the issues with the PbdModelConfig is how it stores parameters. Each Functor could have any set of parameters. Generally:
- "Regular Constraints": Have one double stiffness value
- FEMConstraints: Have either possions ratio+youngs modulus OR lame parameters
- BendConstraint: Has an extra parameter for strides
Really there's no telling (literally unable to tell) what parameters a user would want to use with a functor. While we should still maintain the pretty simple PbdModelConfig::enableConstraint function. It should immediately create and store the functor otherwise PbdModelConfig has to worry about how to store all these parameters and then later use them to setup functors which causes nasty code.
This should eliminate complexities in PbdModelConfig for FEM and Bend constraints. Specialized functions such as enableBendConstraint(stiffness, stride) and enableFEMConstraint(type, material) should still be present.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/366VTKViewer::setDebugAxesLength Should not need an active VTKRenderer to set de...2022-09-26T12:07:41-04:00Andrew WilsonVTKViewer::setDebugAxesLength Should not need an active VTKRenderer to set debug axes lengthIf you call setDebugAxesLength before setting an active scene it will do nothing. This is because the renderer is lazy created. Not created until active scene is created (legacy reason of creating separate renderers for separate scenes, ...If you call setDebugAxesLength before setting an active scene it will do nothing. This is because the renderer is lazy created. Not created until active scene is created (legacy reason of creating separate renderers for separate scenes, which still work decently for scene switching).Andrew WilsonAndrew Wilsonhttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/362Transition to Default Adaptive Stepping2021-10-11T15:36:51-04:00Andrew WilsonTransition to Default Adaptive SteppingBy default we use parallel rendering and scene updates. So if you just setup a SceneManager and Viewer this is the behavior you get. The good majority of newer examples use adaptive and have the extra line: `sceneManager->setExecutionTyp...By default we use parallel rendering and scene updates. So if you just setup a SceneManager and Viewer this is the behavior you get. The good majority of newer examples use adaptive and have the extra line: `sceneManager->setExecutionType(Module::ExecutionType::ADAPTIVE);`.
Ideally adaptive is default and the user doesn't have to add this extra line (worse they forget). The reason adaptive should be default is that many things "just work" when using the sequential nature of the adaptive mode. Because:
- It's very easy to make mistakes, especially if you didn't know you were running them in parallel and you caused a race condition or something.
- The adaptive mode has more consistency across machines. Generally running on anything faster than what the simulation was tuned for will result in roughly the same simulation. This has been very helpful.
Transitioning every example to parallel is tricky as many physics parameters need reparameterization. What we can do though is make ADAPTIVE default and then go through every example and use sceneManager->setExecutionType(Module::ExecutionType::PARALLEL); And then eventually try to transition the parallel ones to adaptive.
Side Note: I am not prepared to completely removed parallel due to the high performance requirements of some simulators. It really depends on the program. If the scene itself is well parallelized, then running rendering and scene updates in parallel makes little difference. But in a number of programs it can make a decent difference.Andrew WilsonAndrew Wilsonhttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/361Remove Reals2021-09-16T15:47:08-04:00Andrew WilsonRemove RealsMixed usage of reals and doubles are in iMSTK. Mostly important we switch to one, at least for now we should just completely switch to doubles.Mixed usage of reals and doubles are in iMSTK. Mostly important we switch to one, at least for now we should just completely switch to doubles.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/350PolyMesh/CellMesh2022-07-20T17:43:58-04:00Andrew WilsonPolyMesh/CellMeshAn abstract base class for SurfaceMesh, LineMesh, TetrahedralMesh, and HexahedralMesh would be nice. Something we've discussed for awhile. Something to provide cells abstractly.
One simple use case is the abstract class "getCellWeights"...An abstract base class for SurfaceMesh, LineMesh, TetrahedralMesh, and HexahedralMesh would be nice. Something we've discussed for awhile. Something to provide cells abstractly.
One simple use case is the abstract class "getCellWeights". Whose signature would look like: getCellWeights(int cellId, const Vec3d& ptInCell);
Which would barycentric interpolate for a cell (triangle, tet, line, hexahedron, ...). Someone can then easily write a template function that works for any cell.
Also consider renaming indices to cells. getCells()
Functions for the base class:
```
getCellWeights(int cellId, const Vec3d& ptInCell): Computes interpolation weights (usually barycentric)
getCellBounds(int cellId, Vec3d& min, Vec3d& max): Computes bounding box of a single cell
getCellVolume(int cellId): Computes the signed volume of a cell
getCell(): Gets single cells indices
getIndices(): Gets the cell indices
setIndices(std::shared_ptr<AbstractDataArray> indices): Set the cell indices, could also require int type here
```Andrew WilsonAndrew Wilsonhttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/333PhysX Build Toggle in CMake2021-06-29T22:36:42-04:00Andrew WilsonPhysX Build Toggle in CMakePut PhysX on a toggle to optionally not build with it.Put PhysX on a toggle to optionally not build with it.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/326Move Example-RCM to Unit Tests2022-04-12T16:59:08-04:00Andrew WilsonMove Example-RCM to Unit TestsAs the title says this would be more appropriate as a unit tests in GeometryTests.As the title says this would be more appropriate as a unit tests in GeometryTests.Jianfeng YanJianfeng Yanhttps://gitlab.kitware.com/iMSTK/iMSTK/-/issues/325Make Sequential Execution Default2021-09-02T18:56:56-04:00Andrew WilsonMake Sequential Execution DefaultCurrently there are two execution modes in iMSTK.
One that renders and simulates in parallel:
```
// Setup a viewer to render
imstkNew<VTKViewer> viewer("Viewer");
viewer->setActiveScene(scene);
// Setup a scene manager to advance the ...Currently there are two execution modes in iMSTK.
One that renders and simulates in parallel:
```
// Setup a viewer to render
imstkNew<VTKViewer> viewer("Viewer");
viewer->setActiveScene(scene);
// Setup a scene manager to advance the scene
imstkNew<SceneManager> sceneManager("Scene Manager");
sceneManager->setActiveScene(scene);
imstkNew<SimulationManager> driver;
driver->addModule(viewer);
driver->addModule(sceneManager);
driver->start();
```
One that renders and simulates sequentially. Calling simulate N times per render:
```
// Setup a viewer to render
imstkNew<VTKViewer> viewer("Viewer");
viewer->setActiveScene(scene);
// Setup a scene manager to advance the scene
imstkNew<SceneManager> sceneManager("Scene Manager");
sceneManager->setActiveScene(scene);
sceneManager->setExecutionType(Module::ExecutionType::ADAPTIVE);
imstkNew<SimulationManager> driver;
driver->addModule(viewer);
driver->addModule(sceneManager);
driver->setDesiredDt(0.005); // Governs N/how many steps per render
driver->start();
```
The parallel one is hard to support but may have some niche use cases with respect to medical simulation. But I do believe sequential should be default. ie: get rid of line `sceneManager->setExecutionType(Module::ExecutionType::ADAPTIVE);`
For this to happen all examples need to be tuned for the sequential mode. Ideally tuned for lowest common denominator (ie: worst machine). So others can start imstk examples without problems. Some take no effort to tune and have large ranges of valid timesteps even on bad machines. Others have a small ranges of valid timesteps, making it harder to tune. Some need their other parameters changed to account for new timesteps.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/324Investigate Removal of GLM2021-06-04T14:55:01-04:00Andrew WilsonInvestigate Removal of GLMI don't believe GLM is being used for anything significant at this point. Or at least, nothing that can't be replaced with Eigen. It is just a vector math library (it is faster though). Especially with the recent removal of Vulkan.I don't believe GLM is being used for anything significant at this point. Or at least, nothing that can't be replaced with Eigen. It is just a vector math library (it is faster though). Especially with the recent removal of Vulkan.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/319Remove Vulkan2021-06-01T23:24:26-04:00Andrew WilsonRemove VulkanAs it stands Vulkan in iMSTK doesn't work. It really doesn't seem like we'll be able to realistically support this. We'd sooner support Unity or Unreal which can be used for more graphical performance/fidelity. If this is the case, some ...As it stands Vulkan in iMSTK doesn't work. It really doesn't seem like we'll be able to realistically support this. We'd sooner support Unity or Unreal which can be used for more graphical performance/fidelity. If this is the case, some other 3rd party module of iMSTK should be used if anyone wants to develop this.
Not to mention VTK has been making progress in rendering fidelity. I'm confident we'll be able to write some custom shaders for it in the future. But there are a few hard limits to what VTK can do currently. These things can be done in Unity and Unreal though. Also worth mentioning there are few things that VTK can do that Unity/Unreal can't (without 3rd party or other bad solutions), namely Volume Rendering which would be particularly difficult to support on Vulkan.https://gitlab.kitware.com/iMSTK/iMSTK/-/issues/318Remove apiUtilities2021-07-04T01:31:54-04:00Andrew WilsonRemove apiUtilitiesapiUtilities is redundant and just creates more interface to support, only a few examples use their "utility-like" functions as shorthands to create objects. They are also not used in any of our projects and I would highly caution using ...apiUtilities is redundant and just creates more interface to support, only a few examples use their "utility-like" functions as shorthands to create objects. They are also not used in any of our projects and I would highly caution using them anywhere.
The plotter utils aren't significant. If anything they should be absolved into a greater IO module. For now, we could move them to an example which could be referred to later if one wanted to write these files.