1+ # Required import for python
2+ import Sofa
3+
4+
5+ # Choose in your script to activate or not the GUI
6+ USE_GUI = True
7+
8+
9+ def main ():
10+ import SofaRuntime
11+ import Sofa .Gui
12+
13+ root = Sofa .Core .Node ("root" )
14+ createScene (root )
15+ Sofa .Simulation .init (root )
16+
17+ if not USE_GUI :
18+ for iteration in range (10 ):
19+ Sofa .Simulation .animate (root , root .dt .value )
20+ else :
21+ Sofa .Gui .GUIManager .Init ("myscene" , "qglviewer" )
22+ Sofa .Gui .GUIManager .createGUI (root , __file__ )
23+ Sofa .Gui .GUIManager .SetDimension (1080 , 1080 )
24+ Sofa .Gui .GUIManager .MainLoop (root )
25+ Sofa .Gui .GUIManager .closeGUI ()
26+
27+
28+ def createScene (root ):
29+ root .gravity = [0 , - 9.81 , 0 ]
30+ root .dt = 0.02
31+
32+ root .addObject ('DefaultVisualManagerLoop' )
33+ root .addObject ('DefaultAnimationLoop' )
34+
35+ root .addObject ('VisualStyle' , displayFlags = "showCollisionModels hideVisualModels showForceFields" )
36+ root .addObject ('RequiredPlugin' , pluginName = "SofaImplicitOdeSolver SofaLoader SofaOpenglVisual SofaBoundaryCondition SofaGeneralLoader SofaGeneralSimpleFem" )
37+ root .addObject ('DefaultPipeline' , name = "CollisionPipeline" )
38+ root .addObject ('BruteForceDetection' , name = "N2" )
39+ root .addObject ('DefaultContactManager' , name = "CollisionResponse" , response = "default" )
40+ root .addObject ('DiscreteIntersection' )
41+
42+ root .addObject ('MeshObjLoader' , name = "LiverSurface" , filename = "mesh/liver-smooth.obj" )
43+
44+ liver = root .addChild ('Liver' )
45+ liver .addObject ('EulerImplicitSolver' , name = "cg_odesolver" , rayleighStiffness = 0.1 , rayleighMass = 0.1 )
46+ liver .addObject ('CGLinearSolver' , name = "linear_solver" , iterations = 25 , tolerance = 1e-09 , threshold = 1e-09 )
47+ liver .addObject ('MeshGmshLoader' , name = "meshLoader" , filename = "mesh/liver.msh" )
48+ liver .addObject ('TetrahedronSetTopologyContainer' , name = "topo" , src = "@meshLoader" )
49+ liver .addObject ('MechanicalObject' , name = "dofs" , src = "@meshLoader" )
50+ liver .addObject ('TetrahedronSetGeometryAlgorithms' , template = "Vec3d" , name = "GeomAlgo" )
51+ liver .addObject ('DiagonalMass' , name = "Mass" , massDensity = 1.0 )
52+ liver .addObject ('TetrahedralCorotationalFEMForceField' , template = "Vec3d" , name = "FEM" , method = "large" , poissonRatio = 0.3 , youngModulus = 3000 , computeGlobalMatrix = False )
53+ liver .addObject ('FixedConstraint' , name = "FixedConstraint" , indices = "3 39 64" )
54+
55+ visu = liver .addChild ('Visu' )
56+ visu .addObject ('OglModel' , name = "VisualModel" , src = "@../../LiverSurface" )
57+ visu .addObject ('BarycentricMapping' , name = "VisualMapping" , input = "@../dofs" , output = "@VisualModel" )
58+
59+ surf = liver .addChild ('Surf' )
60+ surf .addObject ('SphereLoader' , name = "sphereLoader" , filename = "mesh/liver.sph" )
61+ surf .addObject ('MechanicalObject' , name = "spheres" , position = "@sphereLoader.position" )
62+ surf .addObject ('SphereCollisionModel' , name = "CollisionModel" , listRadius = "@sphereLoader.listRadius" )
63+ surf .addObject ('BarycentricMapping' , name = "CollisionMapping" , input = "@../dofs" , output = "@spheres" )
64+
65+ root .addObject (KeyPressedController (name = "SphereCreator" ))
66+
67+ return root
68+
69+
70+ class KeyPressedController (Sofa .Core .Controller ):
71+ """ This controller monitors new sphere objects.
72+ Press ctrl and the L key to make spheres falling!
73+ """
74+ def __init__ (self , * args , ** kwargs ):
75+ Sofa .Core .Controller .__init__ (self , * args , ** kwargs )
76+ self .iteration = 0
77+
78+ def onKeypressedEvent (self , event ):
79+ # Press L key triggers the creation of new objects in the scene
80+ if event ['key' ]== 'L' :
81+ self .createNewSphere ()
82+
83+ def createNewSphere (self ):
84+ root = self .getContext ()
85+ newSphere = root .addChild ('FallingSphere-' + str (self .iteration ))
86+ newSphere .addObject ('EulerImplicitSolver' )
87+ newSphere .addObject ('CGLinearSolver' , threshold = '1e-09' , tolerance = '1e-09' , iterations = '200' )
88+ MO = newSphere .addObject ('MechanicalObject' , showObject = True , position = [- 2 , 10 + self .iteration , 0 , 0 , 0 , 0 , 1 ], name = f'Particle-{ self .iteration } ' , template = 'Rigid3d' )
89+ Mass = newSphere .addObject ('UniformMass' , totalMass = 1 )
90+ Force = newSphere .addObject ('ConstantForceField' , name = "CFF" , totalForce = [0 , - 1 , 0 , 0 , 0 , 0 ] )
91+ Sphere = newSphere .addObject ('SphereCollisionModel' , name = "SCM" , radius = 1.0 )
92+
93+ newSphere .init ()
94+ self .iteration = self .iteration + 1
95+
96+
97+ # Function used only if this script is called from a python environment
98+ if __name__ == '__main__' :
99+ main ()
0 commit comments