示例#1
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    from stlib3.physics.deformable import ElasticMaterialObject

    MainHeader(rootNode)

    # Tetrahedron and triangle subtopology
    target = ElasticMaterialObject(volumeMeshFileName="mesh/liver2.msh",
                                   totalMass=0.5,
                                   attachedTo=rootNode)

    target.addObject('BoxROI',
                     name='boxROI',
                     box=[-20, -20, -20, 20, 20, 20],
                     drawBoxes=True)

    SubTopology(attachedTo=target,
                containerLink='@../container.position',
                boxRoiLink='@../boxROI.tetrahedraInROI',
                name='Default-tetrahedron')

    SubTopology(attachedTo=target,
                containerLink='@../container.position',
                linkType='triangle',
                boxRoiLink='@../boxROI.trianglesInROI',
                name='Triangles')
示例#2
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    from stlib3.physics.rigid import Floor

    MainHeader(rootNode,
               plugins=["SofaPython"],
               dt=1.,
               gravity=[0., -9810., 0.])

    rootNode.VisualStyle.displayFlags = "showVisual showBehavior"

    floor = Floor(rootNode,
                  name="Plane",
                  color=[1., 0., 1.],
                  isAStaticObject=True,
                  uniformScale=10)

    addOrientedBoxRoi(floor,
                      name="MyBoxRoi",
                      position=[[50, 0, 0], [15, 15, 0], [60, 70, 25]],
                      scale=[100, 100, 100])

    myOrientedBox = getOrientedBoxFromTransform(translation=[400, 100, 100],
                                                eulerRotation=[0, 65, 0],
                                                scale=[400, 400, 800])
    floor.addObject("BoxROI", orientedBox=myOrientedBox, drawBoxes=True)
示例#3
0
def createScene(rootNode):
    from stlib3.scene import MainHeader, ContactHeader
    MainHeader(rootNode, gravity=[0.0, -981.0, 0.0], plugins=["SoftRobots"])
    ContactHeader(rootNode, alarmDistance=4, contactDistance=3, frictionCoef=0.08)

    Finger(rootNode, translation=[1.0,0.0,0.0])
    return rootNode
示例#4
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    from stlib3.solver import DefaultSolver

    MainHeader(rootNode)
    DefaultSolver(rootNode)
    Cube(rootNode, translation=[5.0,0.0,0.0])
    Sphere(rootNode, translation=[-5.0,0.0,0.0])
    Floor(rootNode, translation=[0.0,-1.0,0.0])
示例#5
0
def createScene(node):
    from stlib3.scene import MainHeader
    from stlib3.physics.deformable import ElasticMaterialObject

    MainHeader(node, plugins=["SoftRobots"])
    target = ElasticMaterialObject(volumeMeshFileName="mesh/liver.msh",
                                   totalMass=0.5,
                                   attachedTo=node)

    PullingCable(target)
示例#6
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    from stlib3.physics.deformable import ElasticMaterialObject
    from stlib3.physics.constraints import FixedBox

    MainHeader(rootNode)
    target = ElasticMaterialObject(volumeMeshFileName="mesh/liver.msh",
                                   totalMass=0.5,
                                   attachedTo=rootNode)

    FixedBox(atPositions=[-4, 0, 0, 5, 5, 4],
             applyTo=target,
             doVisualization=True)
示例#7
0
def createScene(rootNode):
    from stlib3.scene import MainHeader

    MainHeader(rootNode, gravity=[0, 0, 0])
    rootNode.addChild(
        ElasticMaterialObject(name='ElasticMaterialObject1',
                              volumeMeshFileName="mesh/liver.msh",
                              translation=[3.0, 0.0, 0.0]))
    rootNode.addChild(
        ElasticMaterialObject(name='ElasticMaterialObject2',
                              volumeMeshFileName="mesh/liver.msh",
                              translation=[-3, 0, 0],
                              surfaceMeshFileName="mesh/liver.obj",
                              surfaceColor=[1.0, 0.0, 0.0]))
示例#8
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    from stlib3.physics.deformable import ElasticMaterialObject
    from stlib3.physics.constraints import PartiallyFixedBox

    MainHeader(rootNode)
    target = ElasticMaterialObject(fromVolumeMesh="mesh/liver.msh",
                                   withTotalMass=0.5,
                                   attachedTo=rootNode)

    PartiallyFixedBox(box=[-4, 0, 0, 5, 5, 4],
                      attachedTo=target,
                      drawBoxes=True,
                      fixedAxis=[0, 1, 0])
示例#9
0
def createScene(rootNode):
    """
        """
    from stlib3.scene import MainHeader
    from stlib3.physics.deformable import ElasticMaterialObject
    from stlib3.physics.mixedmaterial import Rigidify
    from splib3.objectmodel import setData

    MainHeader(rootNode,
               plugins=[
                   "SofaSparseSolver", "SofaImplicitOdeSolver",
                   "SofaMiscMapping", "SofaRigid", "SofaBoundaryCondition"
               ])
    rootNode.VisualStyle.displayFlags = "showBehavior"

    modelNode = rootNode.addChild("Modeling")
    elasticobject = ElasticMaterialObject(volumeMeshFileName="mesh/liver.msh",
                                          name="ElasticMaterialObject")
    modelNode.addChild(elasticobject)

    # Rigidification of the elasticobject for given indices with given frameOrientations.
    o = Rigidify(modelNode,
                 elasticobject,
                 name="RigidifiedStructure",
                 frames=[[0., 0., 0], [0., 0., 0]],
                 groupIndices=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                               [48, 49, 50, 51]])

    # Activate some rendering on the rigidified object.
    setData(o.RigidParts.dofs, showObject=True, showObjectScale=1, drawMode=2)
    setData(o.RigidParts.RigidifiedParticules.dofs,
            showObject=True,
            showObjectScale=0.1,
            drawMode=1,
            showColor=[1., 1., 0., 1.])
    setData(o.DeformableParts.dofs,
            showObject=True,
            showObjectScale=0.1,
            drawMode=2)
    o.RigidParts.addObject("FixedConstraint", indices=0)

    simulationNode = rootNode.addChild("Simulation")
    simulationNode.addObject("EulerImplicitSolver")
    simulationNode.addObject("CGLinearSolver")
    simulationNode.addChild(o)
    return rootNode
示例#10
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    MainHeader(rootNode,
               plugins=[
                   "SoftRobots", "SoftRobots.Inverse", "SofaSparseSolver",
                   'SofaDeformable', "SofaPreconditioner", "SofaOpenglVisual",
                   "CosseratPlugin", "BeamAdapter", "SofaGeneralRigid",
                   "SofaImplicitOdeSolver"
               ],
               repositoryPaths=[os.getcwd()])
    rootNode.addObject(
        'VisualStyle',
        displayFlags='showVisualModels hideBehaviorModels showCollisionModels '
        'hideBoundingCollisionModels hideForceFields showInteractionForceFields '
        'showWireframe')

    rootNode.addObject('FreeMotionAnimationLoop')
    qp_solver = rootNode.createObject('QPInverseProblemSolver', printLog='0')
    rootNode.addObject('CollisionPipeline', depth="6", verbose="0", draw="1")
    rootNode.addObject('BruteForceDetection', name="N2")
    rootNode.addObject('DefaultContactManager',
                       response="FrictionContact",
                       responseParams="mu=0.65")
    rootNode.addObject('LocalMinDistance',
                       name="Proximity",
                       alarmDistance="0.6",
                       contactDistance="0.44",
                       angleCone="0.01")

    rootNode.gravity = [0.0, 0.0, 0.0]
    rootNode.dt = 0.01

    rootNode.addObject('BackgroundSetting', color='0 0.168627 0.211765')
    rootNode.addObject('OglSceneFrame', style="Arrows", alignment="TopRight")

    ##########################################
    # Effector goal for interactive control  #
    ##########################################
    goal = rootNode.addChild('goal')
    goal.addObject('EulerImplicitSolver', firstOrder='1')
    goal.addObject('CGLinearSolver',
                   iterations='100',
                   tolerance="1e-5",
                   threshold="1e-5")
    goalPos = goal.addObject('MechanicalObject',
                             name='goalMO',
                             position='90.0 3.0  0.35857')
    goal.addObject('SphereCollisionModel', radius='2', color="red")
    goal.addObject('UncoupledConstraintCorrection')

    # #######################################
    # New adds to use the sliding Actuator  #
    #########################################
    cableNode = rootNode.addChild('cableNode')
    cableNode.addObject('EulerImplicitSolver',
                        firstOrder="0",
                        rayleighStiffness="1.0",
                        rayleighMass='0.1')
    cableNode.addObject('SparseLUSolver', name='solver')
    cableNode.addObject('GenericConstraintCorrection')

    #################################
    ##           RigidBase         ##
    #################################
    rigidBaseNode = cableNode.addChild('rigidBase')
    RigidBaseMO = rigidBaseNode.addObject('MechanicalObject',
                                          template='Rigid3d',
                                          name="RigidBaseMO",
                                          position="0 0 0  0 0 0 1",
                                          showObject='1',
                                          showObjectScale='0.1')
    rigidBaseNode.addObject('RestShapeSpringsForceField',
                            name='spring',
                            stiffness="5",
                            angularStiffness="5",
                            external_points="0",
                            mstate="@RigidBaseMO",
                            points="0",
                            template="Rigid3d")

    #################################################################
    ##  Sliding actuator to guide the base of the needle, only the  ##
    ##  translation are tacking into account here.
    #################################################################
    for j in range(0, 3):
        direction = [0, 0, 0, 0, 0, 0]
        direction[j] = 1
        rigidBaseNode.addObject('SlidingActuator',
                                name="SlidingActuator" + str(j),
                                template='Rigid3d',
                                direction=direction,
                                indices=0,
                                maxForce='100000',
                                minForce='-30000')

    #############################################
    # Rate of angular Deformation  (2 sections)
    #############################################

    # Define: the number of section, the total lenght and the lenght of each beam.
    nbSectionS = 6
    totalLength = 80.0
    lengthS = totalLength / nbSectionS

    # Define: the length of each beam in a list, the positions of eahc beam
    # (flexion, torsion), the abs of each section
    positionS = []
    longeurS = []
    temp = 0.
    curv_abs_inputS = [0.0]
    for i in range(nbSectionS):
        positionS.append([0, 0, 0])
        longeurS.append((((i + 1) * lengthS) - i * lengthS))
        temp += longeurS[i]
        curv_abs_inputS.append(temp)
    curv_abs_inputS[nbSectionS] = totalLength

    rateAngularDeformNode = cableNode.addChild('rateAngularDeform')
    rateAngularDeformMO = rateAngularDeformNode.addObject(
        'MechanicalObject',
        template='Vec3d',
        name='rateAngularDeformMO',
        position=positionS)
    BeamHookeLawForce = rateAngularDeformNode.addObject(
        'BeamHookeLawForceField',
        crossSectionShape='circular',
        length=longeurS,
        radius='0.5',
        youngModulus='5e6')

    for i in range(1, 6):
        rateAngularDeformNode.addObject('SlidingActuator',
                                        name="SlidingActuatory" + str(i),
                                        template='Vec3d',
                                        direction='0 1 0 ',
                                        indices=i,
                                        maxForce='100000',
                                        minForce='-30000')
    for i in range(1, 6):
        rateAngularDeformNode.addObject('SlidingActuator',
                                        name="SlidingActuatorz" + str(i),
                                        template='Vec3d',
                                        direction='0 0 1',
                                        indices=i,
                                        maxForce='100000',
                                        minForce='-30000')

    ##############
    #   Frames   #
    ##############
    # Define: the number of frame and the length between each frame.
    nbFramesF = 16
    lengthF = totalLength / nbFramesF

    # Define: the abs of each frame and the position of each frame.
    framesF = []
    curv_abs_outputF = []
    cable_positionF = []
    for i in range(nbFramesF):
        sol = i * lengthF
        framesF.append([sol, 0, 0, 0, 0, 0, 1])
        cable_positionF.append([sol, 0, 0])
        curv_abs_outputF.append(sol)

    framesF.append([totalLength, 0, 0, 0, 0, 0, 1])
    cable_positionF.append([totalLength, 0, 0])
    curv_abs_outputF.append(totalLength)

    # the node of the frame needs to inherit from rigidBaseMO and rateAngularDeform
    mappedFrameNode = rigidBaseNode.addChild('MappedFrames')
    rateAngularDeformNode.addChild(mappedFrameNode)
    framesMO = mappedFrameNode.addObject('MechanicalObject',
                                         template='Rigid3d',
                                         name="FramesMO",
                                         position=framesF,
                                         showObject='1',
                                         showObjectScale='1')

    # The mapping has two inputs: RigidBaseMO and rateAngularDeformMO
    #                 one output: FramesMO
    inputMO = rateAngularDeformMO.getLinkPath()
    inputMO_rigid = RigidBaseMO.getLinkPath()
    outputMO = framesMO.getLinkPath()

    mappedFrameNode.addObject('DiscreteCosseratMapping',
                              curv_abs_input=curv_abs_inputS,
                              output=outputMO,
                              curv_abs_output=curv_abs_outputF,
                              input1=inputMO,
                              input2=inputMO_rigid,
                              debug='0',
                              max=6.e-2,
                              deformationAxis=1,
                              nonColored="0",
                              radius=5)

    # #Mapped mechanical points
    #  This create a new node in the scene. This node is appended to the finger's node.
    slidingPoint = mappedFrameNode.addChild('slidingPoint')
    slidingPoint.addObject('MechanicalObject',
                           name="cablePos",
                           position=cable_positionF,
                           showObject="1",
                           showIndices="0")
    slidingPoint.addObject('IdentityMapping')

    ##########################################
    # Effector                               #
    ##########################################
    effector = mappedFrameNode.addChild('fingertip')
    effMO = effector.addObject('MechanicalObject', position=[81., 0., 0.35857])
    effector.addObject('PositionEffector',
                       template='Vec3d',
                       indices="0",
                       effectorGoal="@../../../../goal/goalMO.position")
    effector.addObject('SkinningMapping',
                       nbRef='1',
                       mapForces='false',
                       mapMasses='false')

    return rootNode
示例#11
0
def createScene(node):
    from stlib3.scene import MainHeader
    MainHeader(node, plugins=["SoftRobots"])
    node.addObject('MechanicalObject')
    PneumaticCavity(surfaceMeshFileName="mesh/cube.obj",
                    attachedAsAChildOf=node)
示例#12
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    MainHeader(rootNode)

    f = Node(rootNode, "Finger")
    StringSensor(f)
示例#13
0
def createScene(rootNode):
    from stlib3.scene import MainHeader
    MainHeader(rootNode,
               plugins=[
                   "SoftRobots", "SoftRobots.Inverse", "SofaSparseSolver",
                   'SofaDeformable', "SofaPreconditioner", "SofaOpenglVisual",
                   "CosseratPlugin", "BeamAdapter", "SofaGeneralRigid",
                   "SofaImplicitOdeSolver", 'SofaEngine', 'SofaMeshCollision',
                   'SofaSimpleFem', 'SofaTopologyMapping', 'SofaConstraint'
               ],
               repositoryPaths=[os.getcwd()])
    rootNode.addObject(
        'VisualStyle',
        displayFlags='showVisualModels hideBehaviorModels showCollisionModels '
        'hideBoundingCollisionModels hideForceFields showInteractionForceFields '
        'showWireframe')

    rootNode.addObject('FreeMotionAnimationLoop')
    rootNode.createObject('QPInverseProblemSolver',
                          printLog='0',
                          epsilon=0.0002)
    rootNode.addObject('CollisionPipeline', depth="6", verbose="0", draw="1")
    rootNode.addObject('BruteForceDetection', name="N2")
    rootNode.addObject('DefaultContactManager',
                       response="FrictionContact",
                       responseParams="mu=0.65")
    rootNode.addObject('LocalMinDistance',
                       name="Proximity",
                       alarmDistance="0.6",
                       contactDistance="0.44",
                       angleCone="0.01")

    rootNode.gravity = [0.0, 0.0, 0.0]
    rootNode.dt = 0.01

    rootNode.addObject('BackgroundSetting', color='0 0.168627 0.211765')
    rootNode.addObject('OglSceneFrame', style="Arrows", alignment="TopRight")

    # #######################################
    # New adds to use the sliding Actuator  #
    #########################################
    cableNode = rootNode.addChild('cableNode')
    cableNode.addObject('EulerImplicitSolver',
                        firstOrder="0",
                        rayleighStiffness="1.0",
                        rayleighMass='0.1')
    cableNode.addObject('SparseLUSolver', name='solver')
    cableNode.addObject('GenericConstraintCorrection')

    #################################
    ##           RigidBase         ##
    #################################
    rigidBaseNode = cableNode.addChild('rigidBase')
    RigidBaseMO = rigidBaseNode.addObject('MechanicalObject',
                                          template='Rigid3d',
                                          name="RigidBaseMO",
                                          position="0 0 0  0 0 0 1",
                                          showObject='1',
                                          showObjectScale='0.1')
    rigidBaseNode.addObject('RestShapeSpringsForceField',
                            name='spring',
                            stiffness="5",
                            angularStiffness="5",
                            external_points="0",
                            mstate="@RigidBaseMO",
                            points="0",
                            template="Rigid3d")

    #################################################################
    ##  Sliding actuator to guide the base of the needle, only the  ##
    ##  translation are tacking into account here.
    #################################################################
    for j in range(0, 6):
        direction = [0, 0, 0, 0, 0, 0]
        direction[j] = 1
        rigidBaseNode.addObject('SlidingActuator',
                                name="SlidingActuator" + str(j),
                                template='Rigid3d',
                                direction=direction,
                                indices=0,
                                maxForce='1e6',
                                minForce='-30000')

    [positionS, curv_abs_inputS, longeurS, framesF, curv_abs_outputF, cable_positionF] = \
        BuildCosseratGeometry(nbSection=8, nbFrames=16, totalLength=80)

    #############################################
    # Rate of angular Deformation  (2 sections)
    #############################################
    rateAngularDeformNode = cableNode.addChild('rateAngularDeform')
    rateAngularDeformMO = rateAngularDeformNode.addObject(
        'MechanicalObject',
        template='Vec3d',
        name='rateAngularDeformMO',
        position=positionS)
    rateAngularDeformNode.addObject('BeamHookeLawForceField',
                                    crossSectionShape='circular',
                                    length=longeurS,
                                    radius='0.5',
                                    youngModulus='1.0e12')

    # for i in range(0, nbSectionS):
    #     rateAngularDeformNode.addObject('SlidingActuator', name="SlidingActuatorY" + str(i), template='Vec3d',
    #                                     direction='0 1 0 ', indices=i, maxForce='100000', minForce='-30000')
    # for i in range(0, nbSectionS):
    #     rateAngularDeformNode.addObject('SlidingActuator', name="SlidingActuatorZ" + str(i), template='Vec3d',
    #                                     direction='0 0 1', indices=i, maxForce='100000', minForce='-30000')

    ##############
    #   Frames   #
    ##############
    # the node of the frame needs to inherit from rigidBaseMO and rateAngularDeform
    mappedFrameNode = rigidBaseNode.addChild('MappedFrames')
    rateAngularDeformNode.addChild(mappedFrameNode)
    framesMO = mappedFrameNode.addObject('MechanicalObject',
                                         template='Rigid3d',
                                         name="FramesMO",
                                         position=framesF,
                                         showObject='1',
                                         showObjectScale='1')

    # The mapping has two inputs: RigidBaseMO and rateAngularDeformMO
    #                 one output: FramesMO
    inputMO = rateAngularDeformMO.getLinkPath()
    inputMO_rigid = RigidBaseMO.getLinkPath()
    outputMO = framesMO.getLinkPath()

    mappedFrameNode.addObject('DiscreteCosseratMapping',
                              curv_abs_input=curv_abs_inputS,
                              output=outputMO,
                              curv_abs_output=curv_abs_outputF,
                              input1=inputMO,
                              input2=inputMO_rigid,
                              debug='0',
                              max=6.e-2,
                              deformationAxis=1,
                              nonColored="0",
                              radius=5)

    # #Mapped mechanical points
    #  This create a new node in the scene. This node is appended to the finger's node.
    framePoints = mappedFrameNode.addChild('framePoints')
    framePointsMO = framePoints.addObject('MechanicalObject',
                                          name="cablePos",
                                          position=cable_positionF,
                                          showObject="1",
                                          showIndices="0")
    framePoints.addObject('IdentityMapping')

    ##########################################
    # ## create FEM grid
    ##########################################
    cubeNode = createFemCube(rootNode)
    ####################################################################################
    # Attached the target to FEM model
    # targetNode = cubeNode.gelNode.addChild('target')
    # targetNode.addObject('VisualStyle', displayFlags='showCollisionModels ')
    # targetMO = targetNode.addObject('MechanicalObject', name="targetMO", position='85.0 1.5  0.35857', showObject="1",
    #                                 showIndices="1", template="Vec3d")
    # targetNode.addObject('SphereCollisionModel', radius='2', color="red")
    # targetNode.addObject('BarycentricMapping')
    [targetNode, targetMO] = effectorTarget(rootNode)
    ####################################################################################
    # Create constraint Points inside the volume of the deformable object
    # These points are created
    femPos = [" 41.0 0 0  45 0 0 50 0 0 55 0 0 "]
    gelNode = cubeNode.getChild('gelNode')
    femPoints = gelNode.addChild('femPoints')
    inputFEMCable = femPoints.addObject('MechanicalObject',
                                        name="pointsInFEM",
                                        position=femPos,
                                        showIndices="1")
    femPoints.addObject('BarycentricMapping')

    ####################################################################################
    # Effector constraint,
    # first define the tip on then needle then attach the effector constraint which
    # leads the tip of the needle to the defined target #
    ####################################################################################
    effector = mappedFrameNode.addChild('fingertip')
    effMO = effector.addObject('MechanicalObject', position=[80., 0., 0.35857])
    posEffector = effector.addObject(
        'PositionEffector',
        template='Vec3d',
        indices="0",
        effectorGoal=targetMO.getLinkPath() +
        '.position')  # "@../../../../FemNode/gelNode/target/targetMO.position"
    targetNode.addObject(MoveTargetProcess(posEffector))
    effector.addObject('SkinningMapping',
                       nbRef='1',
                       mapForces='false',
                       mapMasses='false')

    mappedPointsNode = framePoints.addChild('MappedPoints')
    mappedPoints = mappedPointsNode.addObject('MechanicalObject',
                                              template='Vec3d',
                                              position=femPos,
                                              name="FramesMO",
                                              showObject='1',
                                              showIndices='1',
                                              showObjectScale='1')
    mappedPointsNode.addObject('CosseratEquality',
                               name="QPConstraint",
                               eqDisp='0.0',
                               lastPointIsFixed="false")

    ## Get the tree mstate links for the mapping
    inputCableMO = framePointsMO.getLinkPath()
    inputFEMCableMO = inputFEMCable.getLinkPath()
    outputPointMO = mappedPoints.getLinkPath()

    femPoints.addChild(mappedPointsNode)

    mappedPointsNode.addObject('DifferenceMultiMapping',
                               name="pointsMulti",
                               input1=inputFEMCableMO,
                               lastPointIsFixed=0,
                               input2=inputCableMO,
                               output=outputPointMO,
                               direction="@../../FramesMO.position")
示例#14
0
def createScene(rootNode):

    from stlib3.scene import MainHeader
    # from stlib3.physics.collision import CollisionMesh

    MainHeader(rootNode, plugins=["SoftRobots", "SofaSparseSolver", 'SofaDeformable', 'SofaEngine',
                                  'SofaImplicitOdeSolver', 'SofaLoader', 'SofaSimpleFem', "SofaPreconditioner",
                                  "SofaOpenglVisual", "CosseratPlugin", "BeamAdapter", "SofaConstraint"],
               repositoryPaths=[os.getcwd()])
    rootNode.addObject('VisualStyle', displayFlags='showVisualModels showInteractionForceFields showWireframe')

    rootNode.addObject('FreeMotionAnimationLoop')
    rootNode.addObject('GenericConstraintSolver', tolerance="1e-20", maxIterations="500", printLog="0")
    # ContactHeader(rootNode, alarmDistance=2.5, contactDistance=2, frictionCoef=0.08)

    gravity = [0, 0, 0]
    rootNode.gravity.value = gravity
    rootNode.addObject('BackgroundSetting', color='0 0.168627 0.211765')
    rootNode.addObject('OglSceneFrame', style="Arrows", alignment="TopRight")

    ##########################################
    # FEM Model                              #
    ##########################################
    finger = rootNode.addChild('finger')
    finger.addObject('EulerImplicitSolver', name='odesolver', firstOrder='0', rayleighMass=0.1, rayleighStiffness=0.1)
    finger.addObject('SparseLDLSolver', name='preconditioner')

    # Add a componant to load a VTK tetrahedral mesh and expose the resulting topology in the scene .
    finger.addObject('MeshVTKLoader', name='loader', filename=path + 'finger.vtk', translation="-17.5 -12.5 7.5",
                     rotation="0 180 0")
    finger.addObject('TetrahedronSetTopologyContainer', src='@loader', name='container')
    finger.addObject('TetrahedronSetTopologyModifier')
    # Create a mechanicaobject component to stores the DoFs of the model
    finger.addObject('MechanicalObject', name='tetras', template='Vec3d', showIndices='false', showIndicesScale='4e-5',
                     rx='0', dz='0')
    # Gives a mass to the model
    finger.addObject('UniformMass', totalMass='0.075')
    # Add a TetrahedronFEMForceField component which implement an elastic material model
    # solved using the Finite Element Method on
    # tetrahedrons.
    finger.addObject('TetrahedronFEMForceField', template='Vec3d',
                        name='FEM', method='large', poissonRatio='0.45',  youngModulus='500')

    finger.addObject('BoxROI', name='ROI1', box='-18 -15 -8 2 -3 8', drawBoxes='true')
    finger.addObject('RestShapeSpringsForceField', points='@ROI1.indices', stiffness='1e12')

    ##########################################
    # Cable points                           #
    ##########################################
    # Mappe points inside the meca, this points will be use for the bilateral mapping
    FEMpos = [" 0.0 0 0 15 0 0 30 0 0 45 0 0 60 0 0 66 0 0 81 0.0 0.0"]

    femPoints = finger.addChild('femPoints')
    inputFEMCable = femPoints.addObject('MechanicalObject', name="pointsInFEM", position=FEMpos, showObject="1",
                                        showIndices="1")
    femPoints.addObject('BarycentricMapping')

    ##########################################
    #  Finger auto-Collision            #
    ##########################################
    # CollisionMesh(finger,
    #               surfaceMeshFileName="mesh/fingerCollision_part1.stl",
    #               name="CollisionMeshAuto1", translation="-17.5 -12.5 7.5", rotation="0 180 0", collisionGroup=[1])
    #
    # CollisionMesh(finger,
    #               surfaceMeshFileName="mesh/fingerCollision_part2.stl",
    #               name="CollisionMeshAuto2", translation="-17.5 -12.5 7.5", rotation="0 180 0", collisionGroup=[2])

    finger.addObject('LinearSolverConstraintCorrection')

    ##########################################
    # Visualization                          #
    ##########################################
    fingerVisu = finger.addChild('visu')
    fingerVisu.addObject(
        'MeshSTLLoader', filename=path+"finger.stl", name="loader", translation="-17.5 -12.5 7.5",
        rotation="0 180 0")
    fingerVisu.addObject('OglModel', src="@loader", template='ExtVec3f', color="0.0 0.7 0.7")
    fingerVisu.addObject('BarycentricMapping')

    # ###############
    # New adds to use the sliding Actuator
    ###############
    cableNode = rootNode.addChild('cableNode')
    cableNode.addObject('EulerImplicitSolver', firstOrder="0", rayleighStiffness="0.1", rayleighMass='0.1')
    cableNode.addObject('SparseLUSolver', name='solver')
    cableNode.addObject('GenericConstraintCorrection')

    # ###############
    # RigidBase
    ###############
    rigidBaseNode = cableNode.addChild('rigidBase')
    RigidBaseMO = rigidBaseNode.addObject('MechanicalObject', template='Rigid3d', name="RigidBaseMO",
                                          position="0 0 0  0 0 0 1", showObject='1', showObjectScale='5.')
    rigidBaseNode.addObject('RestShapeSpringsForceField', name='spring', stiffness="50000",
                            angularStiffness="50000", external_points="0", mstate="@RigidBaseMO", points="0",
                            template="Rigid3d")

    ###############
    # Rate of angular Deformation  (2 sections)
    ###############
    position = [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.], [0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]
    longeur = [15, 15, 15, 15, 6, 15]  # beams size
    rateAngularDeformNode = cableNode.addChild('rateAngularDeform')
    rateAngularDeformMO = rateAngularDeformNode.addObject('MechanicalObject', template='Vec3d',
                                                          name='rateAngularDeformMO', position=position,
                                                          showIndices="1")
    BeamHookeLawForce = rateAngularDeformNode.addObject('BeamHookeLawForceField', crossSectionShape='circular',
                                                        length=longeur, radius='0.50', youngModulus='5e6')

    ################################
    # Animation (to move the dofs) #
    ################################
    animate = Animation(RigidBaseMO, rateAngularDeformMO)
    rootNode.addObject(animate)

    ##############
    #   Frames   #
    ##############
    frames = [
        "0.0 0 0  0 0 0 1   5 0 0  0 0 0 1  10.0 0 0  0 0 0 1    15.0 0 0  0 0 0 1   20.0 0 0  0 0 0 1  "
        "30.0 0 0  0 0 0 1  35.0 0 0  0 0 0 1   40.0 0 0  0 0 0 1   45.0 0 0  0 0 0 1 55.0 0 0  0 0 0 1 "
        "60.0 0 0  0 0 0 1  66.0 0 0  0 0 0 1   71.0 0 0  0 0 0 1   76.0 0 0  0 0 0 1  81.0 0 0  0 0 0 1"]
    # the node of the frame needs to inherit from rigidBaseMO and rateAngularDeform
    mappedFrameNode = rigidBaseNode.addChild('MappedFrames')
    rateAngularDeformNode.addChild(mappedFrameNode)
    framesMO = mappedFrameNode.addObject(
        'MechanicalObject', template='Rigid3d', name="FramesMO", position=frames, showObject='1', showObjectScale='1')

    # The mapping has two inputs: RigidBaseMO and rateAngularDeformMO
    #                 one output: FramesMO
    inputMO = rateAngularDeformMO.getLinkPath()
    inputMO_rigid = RigidBaseMO.getLinkPath()
    outputMO = framesMO.getLinkPath()

    curv_abs_input = '0 15 30 45 60 66 81'
    curv_abs_output = '0.0 5 10 15 20 30 35 40 45 55 60 66 71 76 81'
    # mappedFrameNode.addObject('DiscreteCosseratMapping', curv_abs_input=curv_abs_input,
    #                              curv_abs_output=curv_abs_output, input1=inputMO, input2=inputMO_rigid,
    #                              output=outputMO, debug='0', max=2.e-3, deformationAxis=1)
    mappedFrameNode.addObject('DiscreteCosseratMapping', curv_abs_input=curv_abs_input,
                                 curv_abs_output=curv_abs_output, input1=inputMO, input2=inputMO_rigid,
                                 output=outputMO, debug='0', max=6.e-2, deformationAxis=1, nonColored="0", radius=5)

    # actuators = mappedFrameNode.addObject('actuators')
    # actuator0 = actuators.addObject('SlidingActuator', name="SlidingActuator0", template='Rigid3d',
    #                                    direction='0 0 0 1 0 0', indices=1, maxForce='100000', minForce='-30000')
    cable_position = [[0.0, 0.0, 0.0], [5.0, 0.0, 0.0], [10.0, 0.0, 0.0], [15.0, 0.0, 0.0], [20.0, 0.0, 0.0],
                      [30.0, 0.0, 0.0], [35.0, 0.0, 0.0], [40.0, 0.0, 0.0], [45.0, 0.0, 0.0],
                      [55.0, 0.0, 0.0], [60.0, 0.0, 0.0], [66.0, 0.0, 0.0], [71.0, 0.0, 0.0], [76.0, 0.0, 0.0],
                      [81.0, 0.0, 0.0]]
    #  This create a new node in the scene. This node is appended to the finger's node.
    slidingPoint = mappedFrameNode.addChild('slidingPoint')

    # This create a MechanicalObject, a componant holding the degree of freedom of our
    # mechanical modelling. In the case of a cable it is a set of positions specifying
    # the points where the cable is passing by.
    slidingPointMO = slidingPoint.addObject('MechanicalObject', name="cablePos",
                              position=cable_position, showObject="1", showIndices="0")
    slidingPoint.addObject('IdentityMapping')


    mappedPointsNode = slidingPoint.addChild('MappedPoints')
    femPoints.addChild(mappedPointsNode)
    mappedPoints = mappedPointsNode.addObject('MechanicalObject', template='Vec3d', position=FEMpos,
                                                 name="FramesMO", showObject='1', showObjectScale='1')

    inputCableMO = slidingPointMO.getLinkPath()
    inputFEMCableMO = inputFEMCable.getLinkPath()
    outputPointMO = mappedPoints.getLinkPath()

    mappedPointsNode.addObject('QPSlidingConstraint', name="QPConstraint")
    mappedPointsNode.addObject('DifferenceMultiMapping', name="pointsMulti", input1=inputFEMCableMO,
                                  input2=inputCableMO, output=outputPointMO, direction="@../../FramesMO.position")
    ## Get the tree mstate links for the mapping


    return rootNode
def createScene(rootNode):

    MainHeader(rootNode, plugins=["SoftRobots", "SofaSparseSolver", "SofaPreconditioner",
                                  "SofaOpenglVisual", "CosseratPlugin", "BeamAdapter", "SofaDeformable",
                                  "SofaImplicitOdeSolver", 'SofaEngine', 'SofaMeshCollision', 'SofaSimpleFem',
                                  'SofaConstraint', 'SofaTopologyMapping', 'NeedleConstraintPlugin'],
               repositoryPaths=[os.getcwd()])

    # rootNode.addObject('VisualStyle', displayFlags='showVisualModels showInteractionForceFields')
    rootNode.addObject('VisualStyle', displayFlags='showBehaviorModels hideCollisionModels hideBoundingCollisionModels '
                                                   'showForceFields hideInteractionForceFields showWireframe')
    rootNode.addObject('FreeMotionAnimationLoop')
    rootNode.addObject('GenericConstraintSolver', tolerance="1e-20", maxIterations="500", printLog="0")

    gravity = [0, 0, 0]
    rootNode.gravity.value = gravity
    rootNode.addObject('BackgroundSetting', color='0 0.168627 0.211765')
    rootNode.addObject('OglSceneFrame', style="Arrows", alignment="TopRight")
    # ###############
    # New adds to use the sliding Actuator
    ###############
    cableNode = rootNode.addChild('cableNode')
    cableNode.addObject('EulerImplicitSolver', firstOrder="0", rayleighStiffness="0.1", rayleighMass='0.1')
    cableNode.addObject('SparseLUSolver', name='solver')
    cableNode.addObject('GenericConstraintCorrection')

    # ###############
    # RigidBase
    ###############
    rigidBaseNode = cableNode.addChild('rigidBase')
    RigidBaseMO = rigidBaseNode.addObject('MechanicalObject', template='Rigid3d', name="RigidBaseMO",
                                          position="0 0 0  0 0 0 1", showObject='1', showObjectScale='5.')
    rigidBaseNode.addObject('RestShapeSpringsForceField', name='spring', stiffness="50000",
                            angularStiffness="50000", external_points="0", mstate="@RigidBaseMO", points="0",
                            template="Rigid3d")

    ###############
    # Rate of angular Deformation  (2 sections)
    ###############
    [positionS, curv_abs_inputS, longeurS, framesF, curv_abs_outputF, cable_positionF] = \
        BuildCosseratGeometry(nbSection=8, nbFrames=16, totalLength=80)

    rateAngularDeformNode = cableNode.addChild('rateAngularDeform')
    rateAngularDeformMO = rateAngularDeformNode.addObject(
        'MechanicalObject', template='Vec3d', name='rateAngularDeformMO', position=positionS, showIndices="1")
    rateAngularDeformNode.addObject(
        'BeamHookeLawForceField', crossSectionShape='circular', length=longeurS, radius='2.0', youngModulus='1.e12')
    ################################
    # Animation (to move the dofs) #
    ################################
    rootNode.addObject(Animation(RigidBaseMO, rateAngularDeformMO))

    ##############
    #   Frames   #
    ##############

    # the node of the frame needs to inherit from rigidBaseMO and rateAngularDeform
    mappedFrameNode = rigidBaseNode.addChild('MappedFrames')
    rateAngularDeformNode.addChild(mappedFrameNode)
    framesMO = mappedFrameNode.addObject(
        'MechanicalObject', template='Rigid3d', name="FramesMO", position=framesF, showObject='1', showObjectScale='1')

    # The mapping has two inputs: RigidBaseMO and rateAngularDeformMO
    #                 one output: FramesMO
    inputMO = rateAngularDeformMO.getLinkPath()
    inputMO_rigid = RigidBaseMO.getLinkPath()
    outputMO = framesMO.getLinkPath()

    mappedFrameNode.addObject('DiscreteCosseratMapping', curv_abs_input=curv_abs_inputS,
                              curv_abs_output=curv_abs_outputF, input1=inputMO, input2=inputMO_rigid,
                              output=outputMO, debug='0', max=6.e-2, deformationAxis=1, nonColored="0", radius=5)

    slidingPoint = mappedFrameNode.addChild('slidingPoint')
    edgeList = "0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16"
    slidingPoint.addObject('EdgeSetTopologyContainer', name="Container", position=cable_positionF, edges=edgeList)
    slidingPointMO = slidingPoint.addObject('MechanicalObject', name="cablePos", position=cable_positionF,
                                            showObject="1", showIndices="0")
    slidingPoint.addObject('NeedleGeometry', name='Needle')  ####  NeedleConstriantPlugin
    slidingPoint.addObject('IdentityMapping')

    # Create FEM Node
    femPos = [" 41.0 0 0 45 0 0 50 0 0 55 0 0 60 0 0 60 0 0  70 0 0  80 0 0 "]
    cubeNode = createFemCube(rootNode)
    gelNode = cubeNode.getChild('gelNode')

    Trajectory = gelNode.addChild('Trajectory')
    Trajectory.addObject('EdgeSetTopologyContainer', name="Container")
    Trajectory.addObject('EdgeSetTopologyModifier', name='Modifier')
    inputFEMCable = Trajectory.addObject('MechanicalObject', name="pointsInFEM", position=femPos, showIndices="1")
    Trajectory.addObject('NeedleTrajectoryGeometry',     name="trajectory", entryDist="1", constraintDist="3",
                            clearTrajectory="true")
    Trajectory.addObject('BarycentricMapping')

    mappedPointsNode = slidingPoint.addChild('MappedPoints')
    Trajectory.addChild(mappedPointsNode)
    mappedPoints = mappedPointsNode.addObject('MechanicalObject', template='Vec3d', position=femPos, name="FramesMO")

    inputCableMO = slidingPointMO.getLinkPath()
    inputFEMCableMO = inputFEMCable.getLinkPath()
    outputPointMO = mappedPoints.getLinkPath()

    mappedPointsNode.addObject('CosseratNeedleSlidingConstraint', name="QPConstraint")
    mappedPointsNode.addObject('DifferenceMultiMapping', name="pointsMulti", input1=inputFEMCableMO, lastPointIsFixed=0,
                               input2=inputCableMO, output=outputPointMO, direction="@../../FramesMO.position")

    return rootNode