Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ Several components are still work in progress or just benchmarks. Here are the c
- CuttingPerformer: will define a fine cut or incision in the mesh (using [MeshRefinement plugin](https://github.com/InfinyTech3D/MeshRefinement))

<img align="center" width="60%" height="auto" src="https://github.com/InfinyTech3D/InfinyToolkit/blob/main/doc/MeshRefinement_AdvancedCarving_penetration.gif">


### Sub-plugins
- **InfinyToolkit.MeshRefinement:** provides the `TetrahedronSubdivisionController` component, to cut and refine a tetrahedral mesh during the simulation: cutting along a plane or between two triangles, refining a chosen set of tetrahedra or the whole mesh. It is the public interface of the [MeshRefinement plugin](https://github.com/InfinyTech3D/MeshRefinement), which does the work, and is configured automatically when that plugin is found.
**See [extensions/MeshRefinement/README.md](extensions/MeshRefinement/README.md) for the full documentation, the Data reference and the example scenes.**

### Architecture
- **examples:** with several examples of the components and some benchmarks.
- **scripts:** a bunch of python scripts to apply changes to the SOFA code base or scenes. Such as:
Expand All @@ -45,6 +49,7 @@ Several components are still work in progress or just benchmarks. Here are the c
- Update headers inclusion
- ...
- **src/InfinyToolkit:** All the source code of the SOFA components.
- **extensions:** sub-plugins, built only when their own dependencies are found. See [Sub-plugins](#sub-plugins) above.


## Installation
Expand Down
71 changes: 71 additions & 0 deletions examples/MeshRefinement/SubdivisionController_CutFromPlane.scn
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" ?>
<!--
TetrahedronSubdivisionController: cut along a plane.

The cut plane is the quad spanned by cutPointA and cutPointB, extruded along
cutDir over cutDepth. drawDebugCut="1" draws it.

Press '1' to build the cut path, which draws the intersections without changing
the topology, then '2' to apply it. Setting performCut="1" from the GUI does
both at the end of the next time step.
-->
<Node name="root" dt="0.03" gravity="0 -9 0">
<Node name="RequiredPlugins">
<RequiredPlugin pluginName="InfinyToolkit.MeshRefinement"/> <!-- Needed to use components [TetrahedronSubdivisionController] -->
<RequiredPlugin pluginName="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin pluginName="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin pluginName="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin pluginName="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass] -->
<RequiredPlugin pluginName="Sofa.Component.MechanicalLoad"/> <!-- Needed to use components [PlaneForceField] -->
<RequiredPlugin pluginName="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin pluginName="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [FastTetrahedralCorotationalForceField] -->
<RequiredPlugin pluginName="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms,TetrahedronSetTopologyContainer,TetrahedronSetTopologyModifier,TriangleSetGeometryAlgorithms,TriangleSetTopologyContainer,TriangleSetTopologyModifier] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2TetraTopologicalMapping,Tetra2TriangleTopologicalMapping] -->
<RequiredPlugin pluginName="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
</Node>

<DefaultAnimationLoop />
<DefaultVisualManagerLoop />
<VisualStyle displayFlags="showBehaviorModels hideVisual hideWireframe" />

<RegularGridTopology name="grid" n="10 10 10" min="-10 -10 -10" max="10 10 10" />

<Node name="TetraGenerator">
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Container" />
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" />
<Hexa2TetraTopologicalMapping name="hexa2tetra" input="@../grid" output="@Container" />
</Node>

<Node name="Beam">
<EulerImplicitSolver name="odesolver" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="10" name="linearSolver" tolerance="1e-5" threshold="1e-5"/>
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Tetra_topo" src="@../TetraGenerator/Container"/>
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" drawTetrahedra="1" drawScaleTetrahedra="0.7"/>

<!-- The cut quad spans (-12, 0, -12) to (12, 6, -12) and is extruded 20
units along +Z, so it crosses the whole beam. -->
<TetrahedronSubdivisionController name="Cutter" listening="1" printLog="1"
cutPointA="-12 0 -12" cutPointB="12 6 -12" cutDir="0 0 1" cutDepth="20"
drawDebugCut="1"/>

<BoxROI name="box_roi" box="-12 9.9 -12 12 11 12" drawBoxes="1"/>
<FixedProjectiveConstraint indices="@box_roi.indices" />

<DiagonalMass massDensity="2.0" />
<FastTetrahedralCorotationalForceField name="FEM" youngModulus="1000" poissonRatio="0.3" method="large" />
<PlaneForceField normal="0 1 0" d="-20" stiffness="100000" showPlane="1" showPlaneSize="20"/>

<Node name="Surface">
<TriangleSetTopologyContainer name="ContainerTri" />
<TriangleSetTopologyModifier name="Modifier" />
<TriangleSetGeometryAlgorithms name="GeomAlgo" drawTriangles="0"/>
<Tetra2TriangleTopologicalMapping input="@../Tetra_topo" output="@ContainerTri" />
</Node>
</Node>
</Node>
81 changes: 81 additions & 0 deletions examples/MeshRefinement/SubdivisionController_CutWithSurface.scn
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?xml version="1.0" ?>
<!--
TetrahedronSubdivisionController: cut along a plane and build the cut surface.

Same cut as SubdivisionController_CutFromPlane.scn, with surfaceCut="1". On top
of splitting the tetrahedra, the engine then creates two mapped surfaces - one
per side of the cut - under the first child of the node holding the surface
TriangleSetTopologyContainer, and renders them with textureName.

That scene structure is a requirement, not a convention: the triangle container
must live in a node ("Surface" here) that itself has a child node ("Visu"), or
the surface creation reports an error and does nothing. Cutting still happens.

Press '1' to build the cut path, then '2' to apply it.
-->
<Node name="root" dt="0.03" gravity="0 -9 0">
<Node name="RequiredPlugins">
<RequiredPlugin pluginName="InfinyToolkit.MeshRefinement"/> <!-- Needed to use components [TetrahedronSubdivisionController] -->
<RequiredPlugin pluginName="MeshRefinement"/> <!-- Needed to use components [MeshCutSurface] -->
<RequiredPlugin pluginName="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin pluginName="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin pluginName="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin pluginName="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [IdentityMapping] -->
<RequiredPlugin pluginName="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass] -->
<RequiredPlugin pluginName="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin pluginName="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [FastTetrahedralCorotationalForceField] -->
<RequiredPlugin pluginName="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms,TetrahedronSetTopologyContainer,TetrahedronSetTopologyModifier,TriangleSetGeometryAlgorithms,TriangleSetTopologyContainer,TriangleSetTopologyModifier] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2TetraTopologicalMapping,Tetra2TriangleTopologicalMapping] -->
<RequiredPlugin pluginName="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<RequiredPlugin pluginName="Sofa.GL.Component.Rendering3D"/> <!-- Needed to use components [OglModel] -->
</Node>

<DefaultAnimationLoop />
<DefaultVisualManagerLoop />
<VisualStyle displayFlags="showBehaviorModels showVisual hideWireframe" />

<RegularGridTopology name="grid" n="6 6 6" min="-5 -5 -5" max="5 5 5" />

<Node name="TetraGenerator">
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Container" />
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" />
<Hexa2TetraTopologicalMapping name="hexa2tetra" input="@../grid" output="@Container" />
</Node>

<Node name="Cube">
<EulerImplicitSolver name="odesolver" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="25" name="linearSolver" tolerance="1e-5" threshold="1e-5"/>
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Tetra_topo" src="@../TetraGenerator/Container"/>
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" drawTetrahedra="1" drawScaleTetrahedra="0.7"/>

<TetrahedronSubdivisionController name="Cutter" listening="1" printLog="1"
cutPointA="-6 0 -6" cutPointB="6 3 -6" cutDir="0 0 1" cutDepth="12"
surfaceCut="1" textureName="textures/colorMap.png"
drawDebugCut="1"/>

<BoxROI name="box_roi" box="-5.1 4.9 -5.1 5.1 5.1 5.1" drawBoxes="1"/>
<FixedProjectiveConstraint indices="@box_roi.indices" />

<DiagonalMass massDensity="2.0" />
<FastTetrahedralCorotationalForceField name="FEM" youngModulus="1000" poissonRatio="0.3" method="large" />

<Node name="Surface">
<TriangleSetTopologyContainer name="ContainerTri" />
<TriangleSetTopologyModifier name="Modifier" />
<TriangleSetGeometryAlgorithms name="GeomAlgo" drawTriangles="0"/>
<Tetra2TriangleTopologicalMapping input="@../Tetra_topo" output="@ContainerTri" />

<!-- Required: the cut surfaces are created as children of this node. -->
<Node name="Visu">
<OglModel name="Visual" />
<IdentityMapping input="@../../Volume" output="@Visual" />
</Node>
</Node>
</Node>
</Node>
59 changes: 59 additions & 0 deletions examples/MeshRefinement/SubdivisionController_RefineFullMesh.scn
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" ?>
<!--
TetrahedronSubdivisionController: refine the whole mesh.

Press '4' to split every tetrahedron into eight, by splitting all six of its
edges. One midpoint is created per edge and shared by the tetrahedra using it,
so the mesh stays conforming.

The grid is kept small on purpose: each press multiplies the tetrahedron count
by eight.
-->
<Node name="root" dt="0.01" gravity="0 -9 0">
<Node name="RequiredPlugins">
<RequiredPlugin pluginName="InfinyToolkit.MeshRefinement"/> <!-- Needed to use components [TetrahedronSubdivisionController] -->
<RequiredPlugin pluginName="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin pluginName="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin pluginName="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin pluginName="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass] -->
<RequiredPlugin pluginName="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin pluginName="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [FastTetrahedralCorotationalForceField] -->
<RequiredPlugin pluginName="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms,TetrahedronSetTopologyContainer,TetrahedronSetTopologyModifier] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2TetraTopologicalMapping] -->
<RequiredPlugin pluginName="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
</Node>

<DefaultAnimationLoop />
<DefaultVisualManagerLoop />
<VisualStyle displayFlags="showBehaviorModels hideVisual hideWireframe" />

<RegularGridTopology name="grid" n="3 3 3" min="-5 -5 -5" max="5 5 5" />

<Node name="TetraGenerator">
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Container" />
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" />
<Hexa2TetraTopologicalMapping name="hexa2tetra" input="@../grid" output="@Container" />
</Node>

<Node name="Cube">
<EulerImplicitSolver name="odesolver" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="25" name="linearSolver" tolerance="1e-05" threshold="1e-05"/>
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Tetra_topo" src="@../TetraGenerator/Container" />
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" drawTetrahedra="1" drawScaleTetrahedra="0.7"/>

<!-- Press '4' to subdivide the whole mesh. -->
<TetrahedronSubdivisionController name="Refiner" listening="1" printLog="1"/>

<BoxROI name="box_roi" box="-5.1 4.9 -5.1 5.1 5.1 5.1" drawBoxes="1"/>
<FixedProjectiveConstraint indices="@box_roi.indices" />

<DiagonalMass massDensity="1.0" />
<FastTetrahedralCorotationalForceField name="FEM" youngModulus="360" poissonRatio="0.3" method="large" />
</Node>
</Node>
61 changes: 61 additions & 0 deletions examples/MeshRefinement/SubdivisionController_RefineTetrahedra.scn
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" ?>
<!--
TetrahedronSubdivisionController: refine a chosen set of tetrahedra.

Press '3' to subdivide the tetrahedra listed in testID, plus the neighbours
the new points affect, so the mesh stays conforming.

The mesh is generated by the scene (RegularGridTopology + Hexa2Tetra), so this
example needs no mesh file.
-->
<Node name="root" dt="0.01" gravity="0 -9 0">
<Node name="RequiredPlugins">
<RequiredPlugin pluginName="InfinyToolkit.MeshRefinement"/> <!-- Needed to use components [TetrahedronSubdivisionController] -->
<RequiredPlugin pluginName="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin pluginName="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin pluginName="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin pluginName="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass] -->
<RequiredPlugin pluginName="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin pluginName="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [FastTetrahedralCorotationalForceField] -->
<RequiredPlugin pluginName="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms,TetrahedronSetTopologyContainer,TetrahedronSetTopologyModifier] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin pluginName="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2TetraTopologicalMapping] -->
<RequiredPlugin pluginName="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
</Node>

<DefaultAnimationLoop />
<DefaultVisualManagerLoop />
<VisualStyle displayFlags="showBehaviorModels hideVisual hideWireframe" />

<RegularGridTopology name="grid" n="4 4 4" min="-5 -5 -5" max="5 5 5" />

<Node name="TetraGenerator">
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Container" />
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" />
<Hexa2TetraTopologicalMapping name="hexa2tetra" input="@../grid" output="@Container" />
</Node>

<Node name="Beam">
<EulerImplicitSolver name="odesolver" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="25" name="linearSolver" tolerance="1e-05" threshold="1e-05"/>
<MechanicalObject src="@../grid" name="Volume" />
<TetrahedronSetTopologyContainer name="Tetra_topo" src="@../TetraGenerator/Container" />
<TetrahedronSetTopologyModifier name="Modifier" />
<TetrahedronSetGeometryAlgorithms name="GeomAlgo" template="Vec3d" drawTetrahedra="1" drawScaleTetrahedra="0.7"/>

<!-- Press '3' to subdivide these tetrahedra. refineCriteria="0" subdivides
every edge regardless of its length. -->
<TetrahedronSubdivisionController name="Refiner" listening="1" printLog="1"
testID="40 41 42" refineCriteria="0"
drawTetra="1" drawScaleTetrahedra="0.6"/>

<BoxROI name="box_roi" box="-5.1 4.9 -5.1 5.1 5.1 5.1" drawBoxes="1"/>
<FixedProjectiveConstraint indices="@box_roi.indices" />

<DiagonalMass massDensity="1.0" />
<FastTetrahedralCorotationalForceField name="FEM" youngModulus="360" poissonRatio="0.3" method="large" />
</Node>
</Node>
1 change: 1 addition & 0 deletions extensions/MeshRefinement/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ sofa_create_package_with_targets(
TARGETS ${PROJECT_NAME} AUTO_SET_TARGET_PROPERTIES
INCLUDE_SOURCE_DIR "src"
INCLUDE_INSTALL_DIR "${PROJECT_NAME}"
EXAMPLE_INSTALL_DIR "examples"
RELOCATABLE "plugins"
)

Expand Down
Loading