|
| 1 | + |
| 2 | + |
| 3 | +def main(): |
| 4 | + # Required import for python |
| 5 | + import Sofa |
| 6 | + import SofaImGui |
| 7 | + |
| 8 | + root = Sofa.Core.Node("root") |
| 9 | + createScene(root) |
| 10 | + Sofa.Simulation.initRoot(root) |
| 11 | + |
| 12 | + for iteration in range(10): |
| 13 | + Sofa.Simulation.animate(root, root.dt.value) |
| 14 | + print(root.PlateMecha.Visual.BoxROI.trianglesInROI.value) |
| 15 | + |
| 16 | +def createScene(root_node): |
| 17 | + root_node.name = "root" |
| 18 | + root_node.dt = 0.1 |
| 19 | + root_node.gravity = [-0.981, 0, 0] |
| 20 | + |
| 21 | + plugins = root_node.addChild('plugins') |
| 22 | + |
| 23 | + plugins.addObject('RequiredPlugin', name="MultiThreading") |
| 24 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.AnimationLoop") |
| 25 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Collision.Detection.Algorithm") |
| 26 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Collision.Detection.Intersection") |
| 27 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Collision.Geometry") |
| 28 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Collision.Response.Contact") |
| 29 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Lagrangian.Correction") |
| 30 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Lagrangian.Solver") |
| 31 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.IO.Mesh") |
| 32 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Direct") |
| 33 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Mapping.Linear") |
| 34 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Mass") |
| 35 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward") |
| 36 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.FEM.Elastic") |
| 37 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.StateContainer") |
| 38 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Dynamic") |
| 39 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Grid") |
| 40 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Topology.Mapping") |
| 41 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Visual") |
| 42 | + plugins.addObject('RequiredPlugin', name="Sofa.GL.Component.Rendering3D") |
| 43 | + plugins.addObject('RequiredPlugin', name="Sofa.Component.Engine.Select") |
| 44 | + plugins.addObject('RequiredPlugin', name="Sofa.GUI.Component") |
| 45 | + |
| 46 | + root_node.addObject('VisualStyle', displayFlags="showVisual") |
| 47 | + root_node.addObject('ConstraintAttachButtonSetting') |
| 48 | + root_node.addObject('FreeMotionAnimationLoop', computeBoundingBox=False) |
| 49 | + root_node.addObject('BlockGaussSeidelConstraintSolver', maxIterations=1000, tolerance=1.0e-6) |
| 50 | + root_node.addObject('CollisionPipeline', name="Pipeline") |
| 51 | + root_node.addObject('ParallelBruteForceBroadPhase', name="BroadPhase") |
| 52 | + root_node.addObject('ParallelBVHNarrowPhase', name="NarrowPhase") |
| 53 | + root_node.addObject('CollisionResponse', name="ContactManager", response="FrictionContactConstraint", responseParams="mu=0.4") |
| 54 | + root_node.addObject('CCDTightInclusionIntersection', name="Intersection", continuousCollisionType="FreeMotion",maxIterations=1000, alarmDistance=0.0, contactDistance=0.0) |
| 55 | + # root_node.addObject('NewProximityIntersection', name="Intersection", alarmDistance="0.5", contactDistance="0.0") |
| 56 | + |
| 57 | + |
| 58 | + #Liver mecha |
| 59 | + Liver = root_node.addChild('Liver') |
| 60 | + |
| 61 | + Liver.addObject('EulerImplicitSolver') |
| 62 | + Liver.addObject('SparseLDLSolver', name="ldl", template="CompressedRowSparseMatrixMat3x3", parallelInverseProduct=True) |
| 63 | + Liver.addObject('MeshGmshLoader', name="meshLoader", filename="mesh/liver.msh", scale3d=[0.2, 0.2, 0.2], rotation=[0, 180, -45], translation=[15.2, -0.15, 0.14]) |
| 64 | + Liver.addObject('TetrahedronSetTopologyContainer', name="Container", src='@meshLoader') |
| 65 | + Liver.addObject('TetrahedronSetTopologyModifier', name="Modifier") |
| 66 | + Liver.addObject('TetrahedronSetGeometryAlgorithms', name="Algorithms") |
| 67 | + Liver.addObject('MechanicalObject', name="mstate", template="Vec3d", position="@Container.position", velocity=[-5,0,0]*181) |
| 68 | + Liver.addObject('TetrahedronFEMForceField', name="forceField", listening=True, youngModulus=1e2, poissonRatio=0.3, method="large") |
| 69 | + Liver.addObject('MeshMatrixMass', totalMass=3) |
| 70 | + |
| 71 | + surface = Liver.addChild('Surface') |
| 72 | + surface.addObject('TriangleSetTopologyContainer', name="Container") |
| 73 | + surface.addObject('TriangleSetTopologyModifier', name="Modifier") |
| 74 | + surface.addObject('TriangleSetGeometryAlgorithms', name="Algorithms") |
| 75 | + surface.addObject('Tetra2TriangleTopologicalMapping', input="@../Container", output="@Container", flipNormals=False) |
| 76 | + surface.addObject('MechanicalObject', name="dofs", rest_position="@../mstate.rest_position") |
| 77 | + surface.addObject('PointCollisionModel', name="Collision", contactDistance=0.0001, color=[0.0, 0.93725490196078, 0.89411764705882, 1]) |
| 78 | + surface.addObject('IdentityMapping', name="SurfaceMapping") |
| 79 | + |
| 80 | + visual = Liver.addChild('Visual') |
| 81 | + visual.addObject('TriangleSetTopologyContainer', name="Container") |
| 82 | + visual.addObject('TriangleSetTopologyModifier', name="Modifier") |
| 83 | + visual.addObject('TriangleSetGeometryAlgorithms', name="Algorithms") |
| 84 | + visual.addObject('Tetra2TriangleTopologicalMapping', input="@../Container", output="@Container", flipNormals=False) |
| 85 | + visual.addObject('OglModel', name="VisualModel", src="@Container", color=[0.5, 0, 0.125, 1]) |
| 86 | + visual.addObject('IdentityMapping', name="SurfaceMapping") |
| 87 | + |
| 88 | + Liver.addObject('LinearSolverConstraintCorrection', linearSolver="@ldl") |
| 89 | + |
| 90 | + |
| 91 | + |
| 92 | + #Plate topology |
| 93 | + PlateTopo = root_node.addChild('BeamDomainFromGridTopology') |
| 94 | + |
| 95 | + PlateTopo.addObject('RegularGridTopology', name="HexaTop", n=[3, 10, 10], min=[-0.3, -1.5, -1.5], max=[0.3, 1.5, 1.5]) |
| 96 | + tetra_topology = PlateTopo.addChild('TetraTopology') |
| 97 | + |
| 98 | + tetra_topology.addObject('TetrahedronSetTopologyContainer', name="Container", position="@HexaTop.position") |
| 99 | + tetra_topology.addObject('TetrahedronSetTopologyModifier', name="Modifier") |
| 100 | + tetra_topology.addObject('Hexa2TetraTopologicalMapping', input="@HexaTop", output="@Container", swapping=True) |
| 101 | + |
| 102 | + #Plate mecha |
| 103 | + PlateMecha = root_node.addChild('PlateMecha') |
| 104 | + |
| 105 | + PlateMecha.addObject('EulerImplicitSolver') |
| 106 | + PlateMecha.addObject('SparseLDLSolver', name="ldl", template="CompressedRowSparseMatrixMat3x3", parallelInverseProduct=True) |
| 107 | + PlateMecha.addObject('TetrahedronSetTopologyContainer', name="Container", position="@../BeamDomainFromGridTopology/HexaTop.position", tetrahedra="@../BeamDomainFromGridTopology/TetraTopology/Container.tetrahedra") |
| 108 | + PlateMecha.addObject('TetrahedronSetTopologyModifier', name="Modifier") |
| 109 | + PlateMecha.addObject('TetrahedronSetGeometryAlgorithms', name="Algorithms") |
| 110 | + PlateMecha.addObject('MechanicalObject', name="mstate", template="Vec3d", position="@Container.position", velocity=[15,0,0]*300) |
| 111 | + PlateMecha.addObject('TetrahedronFEMForceField', name="forceField", listening=True, youngModulus=2e3, poissonRatio=0.3, method="large") |
| 112 | + PlateMecha.addObject('MeshMatrixMass', totalMass=2) |
| 113 | + |
| 114 | + visual = PlateMecha.addChild('Visual') |
| 115 | + visual.addObject('TriangleSetTopologyContainer', name="Container") |
| 116 | + visual.addObject('TriangleSetTopologyModifier', name="Modifier") |
| 117 | + visual.addObject('TriangleSetGeometryAlgorithms', name="Algorithms") |
| 118 | + visual.addObject('Tetra2TriangleTopologicalMapping', input="@../Container", output="@Container", flipNormals=False) |
| 119 | + visual.addObject('BoxROI', name="FrontCollisionTriangles", box=[0.25, 1.6, 1.6, 0.35, -1.6, -1.6]) |
| 120 | + visual.addObject('BoxROI', name="BackCollisionTriangles", box=[-0.35, 1.6, 1.6, -0.25, -1.6, -1.6]) |
| 121 | + |
| 122 | + visual.addObject('OglModel', name="VisualModel", src="@Container" , color=[0.6, 1, 1, 1]) |
| 123 | + visual.addObject('IdentityMapping', name="SurfaceMapping") |
| 124 | + |
| 125 | + |
| 126 | + surface = PlateMecha.addChild('FrontSurface') |
| 127 | + surface.addObject('TriangleSetTopologyContainer',triangles="@../Visual/FrontCollisionTriangles.trianglesInROI") |
| 128 | + surface.addObject('TriangleSetTopologyModifier', name="Modifier") |
| 129 | + surface.addObject('TriangleSetGeometryAlgorithms', name="Algorithms") |
| 130 | + surface.addObject('MechanicalObject', name="dofs", rest_position="@../mstate.rest_position") |
| 131 | + surface.addObject('TriangleCollisionModel', name="Collision",group=1, contactDistance=0.000001, color=[0.94117647058824, 0.93725490196078, 0.89411764705882, 1]) |
| 132 | + surface.addObject('IdentityMapping', name="SurfaceMapping") |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | + surface = PlateMecha.addChild('BackCollisionEdges') |
| 137 | + surface.addObject('TriangleSetTopologyContainer',triangles="@../Visual/BackCollisionTriangles.trianglesInROI") |
| 138 | + surface.addObject('TriangleSetTopologyModifier', name="Modifier") |
| 139 | + surface.addObject('TriangleSetGeometryAlgorithms', name="Algorithms") |
| 140 | + surface.addObject('MechanicalObject', name="dofs", rest_position="@../mstate.rest_position") |
| 141 | + surface.addObject('PointCollisionModel', name="Collision", group=1, contactDistance=0.000001, color=[0.94117647058824, 0.93725490196078, 0.89411764705882, 1]) |
| 142 | + surface.addObject('IdentityMapping', name="SurfaceMapping") |
| 143 | + |
| 144 | + |
| 145 | + PlateMecha.addObject('LinearSolverConstraintCorrection', linearSolver="@ldl") |
| 146 | + |
| 147 | + |
| 148 | + |
| 149 | + #Ground |
| 150 | + Ground = root_node.addChild('Ground') |
| 151 | + |
| 152 | + Ground.addObject('TriangleSetTopologyContainer', name="FloorTopology", position="-5 -15 -15 -5 -15 15 -5 15 15 -5 15 -15", triangles="0 2 1 0 3 2") |
| 153 | + Ground.addObject('MechanicalObject', name="FloorDOF", template="Vec3d") |
| 154 | + Ground.addObject('TriangleCollisionModel', name="FloorCM", contactDistance="0.0001", moving="0", simulated="0", color="0.3 0.3 0.3 0.1") |
| 155 | + visu = Ground.addChild('Visu') |
| 156 | + visu.addObject('OglModel', name="VisualModel", src="@../FloorTopology") |
| 157 | + |
| 158 | +if __name__ == "__main__": |
| 159 | + main() |
0 commit comments