import Sofa

import LinearSubspace.API as LS

def createScene(rootNode):
    rootNode.createObject("RequiredPlugin", pluginName="Flexible")
    rootNode.createObject("RequiredPlugin", pluginName="Image")
    rootNode.createObject("RequiredPlugin", pluginName="LinearSubspace")
    rootNode.createObject("RequiredPlugin", pluginName="SofaTetGen")

    rootNode.gravity=[0, -10, 0]

    rootNode.createObject("VisualStyle", displayFlags="showVisualModels showBehaviorModels")

    rootNode.createObject("EulerImplicitSolver")
    rootNode.createObject("CGLinearSolver", iterations="25", tolerance="1e-05", threshold="1e-05")

    dataNode = rootNode.createChild("data")
    # (un) comment for one mesh or the other
    # armadillo
#    mesh = dataNode.createObject("MeshObjLoader", name="mesh", filename="mesh/Armadillo_verysimplified.obj") # TetGen crashes on Armadillo_simplified
    # liver
#    mesh = dataNode.createObject("MeshObjLoader", name="mesh", filename="mesh/liver.obj")
    # steak
    mesh = dataNode.createObject("MeshObjLoader", name="mesh", filename="/home/ulysse/Documents/temp/steak_data/steak.obj")

    #dataNode.createObject("VisualModel", src="@mesh", color="1 1 1 0.5")
    #dataNode.createObject("MechanicalObject", template="Vec3", src="@mesh", showObject = True, showObjectScale = 0.01, drawMode = 1, showIndices=True, showIndicesScale=0.1)

    lsNode = rootNode.createChild("ls")

    sfMesh = LS.ShapeFunctionMesh(lsNode)
    sfMesh.addEnvelop("mesh", mesh)
    sfMesh.addTetGenTetrahedrization()
#    sfMesh.showTetra()

    return

    lsDof = LS.LSDof(sfMesh)

    # armadillo
#    lsDof.addAffineFromBoxRoi(box=[-7, 5, -6, -4, 9, -3], showObject=True)
#    lsDof.addAffineFromBoxRoi(box=[7, 6, -4, 4, 9, -2], showObject=True)
#    lsDof.addAffineFromBoxRoi(box=[1, -6, -1, 4.5, -4, 3.5], showObject=True)
#    lsDof.addAffineFromBoxRoi(box=[-2, -6, -1, -6, -4, 3.5], showObject=True)

    # liver
#    lsDof.addAffineFromBoxRoi(box=[0, 2, -2, 2, 6, 3], showObject=True)
#    lsDof.addAffineFromBoxRoi(box=[-5, 0, -2, -3, 3, 3], showObject=True)
#    lsDof.addPointIndex(127)
#    lsDof.addPointIndex(22)

    # steak
    lsNode.createObject("MeshObjLoader", name="boneLoader", filename="/home/ulysse/Documents/temp/steak_data/steak_bone_inflated.obj")
    lsDof.addAffineFromMeshRoi("boneLoader", showObject=True)
    lsDof.addPointsNear([[-1.0, 0.0, 0.0]])
    lsDof.addPointsNear([[2.0, -1.0, 0.0]])
#    lsDof.addPointsNear([[0.0, 0.0, 0.0]])
    lsDof.addPointsNear([[2.0, 4.0, 0.0]])
#    lsDof.addPointsNear([[-1.0, 0.0, 0.0], [1.0, 0.0, 0.0], [2.0, 4.0, 0.0]])
#    lsDof.addAffineFromBoxRoi(box=[0, 2, -2, 2, 6, 3], showObject=True)
#    lsDof.addAffineFromBoxRoi(box=[-5, 0, -2, -3, 3, 3], showObject=True)
#    lsDof.addPointIndex(127)
#    lsDof.addPointIndex(22)
#    lsDof.addPointIndex(22)

    lsDof.addMechanicalObjects()
    pointDof = lsDof.pointNode.getObject("dof")
    pointDof.showObject = True
    pointDof.showObjectScale = 0.1
    pointDof.showColor="1 0 0 1"
    pointDof.drawMode = 1
    affineDof = lsDof.affineNode.getObject("dof")
    affineDof.showObject = True
    affineDof.showObjectScale = 1.0
    lsDof.affineNode.createObject("FixedConstraint")

    sf = LS.ShapeFunction(sfMesh, lsDof)
    sf.addJaconsonShapeFunction()

    collisionNode = lsDof.createChild("collision")
    collisionNode.createObject("MechanicalObject", template="Vec3", position="@/data/mesh.position")

    collisionNode.createObject("UniformMass", name="mass", totalmass=10)

    lsDof.insertLSMapping(collisionNode, isMechanical=True)
    visualNode = collisionNode.createChild("visual")
    visualNode.createObject("VisualModel", src="@/data/mesh")
#    visualNode.createObject("VisualModel", src="@/data/mesh", color="#aaaaaaee")
#    visualNode.createObject("OglModel", src="@/data/mesh", texturename="/home/ulysse/Documents/temp/steak_data/steak.png", normals="0")
    visualNode.createObject("IdentityMapping")


#    behaviorNode = lsDof.createChild("behavior")
#    behaviorNode.createObject("MeshTopology", name="topology", src="@"+sfMesh.topology.getPathName())
#    behaviorNode.createObject("MechanicalObject", name="dofs", template="Vec3")
#    behaviorNode.createObject("UniformMass", name="mass", totalmass=10)
##    behaviorNode.createObject("TetrahedronFEMForceField", name="ff", youngModulus=50, poissonRatio=0.45)
#    mapping = lsDof.insertLSMapping(behaviorNode)
#    mapping.applyRestPosition=True
#    behaviorNode.createObject("BarycentricShapeFunction", name="barySF", nbRef="4")

#    behaviorNode2 = behaviorNode.createChild("behavior2")
#    behaviorNode2.createObject("TopologyGaussPointSampler",  name="sampler", inPosition="@../dofs.rest_position", method="0", order="2")
#    behaviorNode2.createObject("MechanicalObject", name="F", template="F331")
#    behaviorNode2.createObject("LinearMapping", shapeFunction="barySF")

#    eNode = behaviorNode2.createChild("E")
#    eNode.createObject("MechanicalObject", name="E", template="E331")
#    eNode.createObject("CorotationalStrainMapping", name="mapping", template="F331,E331")
#    eNode.createObject("HookeForceField", name="force", template="E331")









    behaviorNode = lsDof.createChild("deformedMeshPhys")
#    physNode.createObject("MeshTopology", name="topology", src="@"+sfMesh.topology.getPathName())
#    behaviorNode.createObject("MeshToImageEngine", template="ImageUC", name="rasterizer", src="@"+sfMesh.topology.getPathName(), voxelSize="0.5", padSize="1")
#    behaviorNode.createObject("LSShapeFunctionDiscretizer", name="SF3D", src="@rasterizer")
#    behaviorNode.createObject("ImageGaussPointSampler", src="@SF3D", method="2", order="1", showSamplesScale="0.1", targetNumber="300" )
    behaviorNode.createObject("TopologyGaussPointSampler",  name="sampler", inPosition="@/ls/tetrahedrizer.out_position", method="0", order="1")

    behaviorNode.createObject("MechanicalObject", name="F", template="F331", position="@sampler.position")
#    mapping = lsDof.insertLSMapping(physNode)
#    mapping = behaviorNode.createObject("LSMultiMapping", name="mapping", template="Vec3,Affine,F331", input1="@"+lsDof.pointNode.getPathName(), input2="@"+lsDof.affineNode.getPathName(), output="@.", mapForces=True, mapConstraints=True, mapMasses=True)
    mapping = behaviorNode.createObject("LinearLSMultiMapping", name="mapping", template="Vec3,Affine,F331", input1="@"+lsDof.pointNode.getPathName(), input2="@"+lsDof.affineNode.getPathName(), output="@.", mapForces=True, mapConstraints=True, mapMasses=True, shapeFunction="shapeFunction")


    eNode = behaviorNode.createChild("E")
    eNode.createObject("MechanicalObject", name="E", template="E331")
    eNode.createObject("CorotationalStrainMapping", name="mapping", template="F331,E331")
    eNode.createObject("HookeForceField", name="force", template="E331", youngModulus=50)





