|
| 1 | +import Sofa |
| 2 | +import Sofa.SofaDeformable |
| 3 | + |
| 4 | +from Sofa.Units.Definitions import s, m, cm, N, g, kg, MPa |
| 5 | +from Sofa.Units.UnitSystem import MechanicalUnitSystem |
| 6 | + |
| 7 | +def createScene(root_node): |
| 8 | + |
| 9 | + plugins = [ |
| 10 | + "Sofa.Component.Constraint.Projective", |
| 11 | + "Sofa.Component.Engine.Select", |
| 12 | + "Sofa.Component.LinearSolver.Direct", |
| 13 | + "Sofa.Component.Mapping.Linear", |
| 14 | + "Sofa.Component.Mass", |
| 15 | + "Sofa.Component.ODESolver.Backward", |
| 16 | + "Sofa.Component.SolidMechanics.FEM.HyperElastic", |
| 17 | + "Sofa.Component.StateContainer", |
| 18 | + "Sofa.Component.Topology.Container.Dynamic", |
| 19 | + "Sofa.Component.Topology.Container.Grid", |
| 20 | + "Sofa.Component.Topology.Mapping", |
| 21 | + "Sofa.GL.Component.Rendering3D", |
| 22 | + "Sofa.Component.SolidMechanics.FEM.Elastic" |
| 23 | + ] |
| 24 | + root_node.addObject('RequiredPlugin', pluginName=plugins) |
| 25 | + |
| 26 | + scene_unit = MechanicalUnitSystem(s, cm, g) |
| 27 | + |
| 28 | + root_node.gravity = scene_unit([0, -9.81, 0], N / kg) |
| 29 | + root_node.dt = scene_unit(0.01, s) |
| 30 | + |
| 31 | + root_node.addObject('EulerImplicitSolver', name="backwardEuler", rayleighStiffness=0.1, rayleighMass=0.1) |
| 32 | + root_node.addObject('SparseLDLSolver', template="CompressedRowSparseMatrixMat3x3d") |
| 33 | + root_node.addObject('RegularGridTopology', name="grid", min=[-5, -5, 0], max=[5, 5, 40], n=[5, 5, 20]) |
| 34 | + root_node.addObject('MechanicalObject', template="Vec3", name="state") |
| 35 | + root_node.addObject('NodalMassDensity', property=scene_unit(1150, kg/m**3)) |
| 36 | + root_node.addObject('FEMMass', template="Vec3,Hexahedron", topology="@grid") |
| 37 | + |
| 38 | + with root_node.addChild('tetra') as tetra: |
| 39 | + |
| 40 | + tetra.addObject('TetrahedronSetTopologyContainer', name="Tetra_topo") |
| 41 | + tetra.addObject('TetrahedronSetTopologyModifier', name="Modifier") |
| 42 | + tetra.addObject('TetrahedronSetGeometryAlgorithms', template="Vec3", name="GeomAlgo", drawTetrahedra="false") |
| 43 | + tetra.addObject('Hexa2TetraTopologicalMapping', input="@grid", output="@Tetra_topo") |
| 44 | + |
| 45 | + young_modulus = scene_unit(0.5, MPa) |
| 46 | + poisson_ratio = 0.45 |
| 47 | + lame_parameters = Sofa.SofaDeformable.toLameParameters3D(young_modulus, poisson_ratio) |
| 48 | + tetra.addObject('TetrahedronHyperelasticityFEMForceField', name="FEM", topology="@Tetra_topo", |
| 49 | + ParameterSet=lame_parameters, materialName="StVenantKirchhoff") |
| 50 | + |
| 51 | + with tetra.addChild('triangles') as triangles: |
| 52 | + |
| 53 | + triangles.addObject('TriangleSetTopologyContainer', name="Container") |
| 54 | + triangles.addObject('TriangleSetTopologyModifier') |
| 55 | + triangles.addObject('Tetra2TriangleTopologicalMapping', input="@../Tetra_topo", output="@Container") |
| 56 | + |
| 57 | + with triangles.addChild('Visu') as visu: |
| 58 | + |
| 59 | + visu.addObject('OglModel', name="Visual", color="red") |
| 60 | + visu.addObject('IdentityMapping', input="@../../../state", output="@Visual") |
| 61 | + |
| 62 | + root_node.addObject('BoxROI', template="Vec3", name="box_roi", box=[-6, -6, -1, 6, 6, 0.1]) |
| 63 | + root_node.addObject('FixedProjectiveConstraint', template="Vec3", indices="@box_roi.indices") |
| 64 | + |
| 65 | + |
| 66 | +def main(): |
| 67 | + import Sofa |
| 68 | + import SofaImGui |
| 69 | + |
| 70 | + root = Sofa.Core.Node("root") |
| 71 | + createScene(root) |
| 72 | + Sofa.Simulation.initRoot(root) |
| 73 | + |
| 74 | + import Sofa.Gui |
| 75 | + Sofa.Gui.GUIManager.Init("myscene", "imgui") |
| 76 | + Sofa.Gui.GUIManager.createGUI(root, __file__) |
| 77 | + Sofa.Gui.GUIManager.SetDimension(1080, 1080) |
| 78 | + Sofa.Gui.GUIManager.MainLoop(root) |
| 79 | + Sofa.Gui.GUIManager.closeGUI() |
| 80 | + |
| 81 | + |
| 82 | +if __name__ == '__main__': |
| 83 | + main() |
0 commit comments