import Sofa
import SofaPython.Tools
import random

def createSceneAndController(rootNode):
    rootNode.createObject("RequiredPlugin", pluginName="Flexible")
    rootNode.createObject("RequiredPlugin", pluginName="Image")
    rootNode.createObject("RequiredPlugin", pluginName="LinearSubspace")
    
    rootNode.createObject("MeshObjLoader", name="loader", filename="mesh/Armadillo_simplified.obj")
    
    meshVisualNode = rootNode.createChild("meshVisual")
    meshVisualNode.createObject("VisualModel", src="@../loader", color="0.75 0.75 0.75 0.5")
    meshVisualNode.activated = False
    
    
    
    rasterNode = rootNode.createChild("raster")
    rasterNode.createObject("MeshToImageEngine", template="ImageUC", name="image", src="@../loader", voxelSize=0.5, value="1", fillInside=True, insideValue="2")
    
    imageVisualNode = rasterNode.createChild("imageVisual")
    imageVisualNode.createObject("ImageViewer", template="ImageUC",  name="viewer", src="@../image")
    
    voronoiSFNode = rasterNode.createChild("voronoiSF")
    voronoiSFNode.createObject("VoronoiShapeFunction", template="ShapeFunctiond,ImageD", name="SF_vor", position="0 1 0 0 2 0", src="@../image", method="0", nbRef="2")
    
    rasterNode.activated = False

    tetraNode = rootNode.createChild("tetra")

    tetraNode.createObject("MeshVTKLoader", name="loader", filename="mesh/Armadillo_Tetra_4406.vtu", createSubelements=True)
#    tetraNode.createObject("MeshVTKLoader", name="loader", filename="/home/ulysse/Documents/temp/tetra/DoubleCube_point.vtu", createSubelements=True)
#    tetraNode.createObject("MeshVTKLoader", name="loader", filename="/home/ulysse/Documents/temp/exported_unchanged.vtu", createSubelements=True)
#    tetraNode.createObject("MeshVTKLoader", name="loader", filename="/home/ulysse/Documents/temp/exported.vtk", createSubelements=True)
#    posConstraintIndices = [0, 1, 2, 4];
#    posConstraintIndices = [0, 1, 2, 4, 8, 9, 10, 13];
    posConstraintIndices = [732, 726, 1253, 465];
    regionConstraintIndices =[];
#    regionConstraintIndices = [[76, 125, 160, 172, 314, 440, 453, 460, 470, 646, 661, 662, 663, 666, 667, 668, 669, 701, 738, 743, 796, 930, 956, 1009, 1010, 1035, 1036, 1092, 1093, 1094, 1095, 1097, 1098, 1120, 1172, 1410],[99,  100,  101,  102,  103,  122,  149,  150,  151,  204,  219,  262,  275,  316,  318,  327,  355,  358,  361,  387,  411,  435,  454,  481,  489,  518,  557,  562,  570,  588,  600,  611,  623,  627,  648,  654,  655,  670,  674,  675,  682,  683,  684,  717,  747,  748,  749,  750,  751,  755,  780,  788,  797,  798,  799,  800,  801,  802,  803,  804,  805,  806,  807,  818,  819,  820,  824,  840,  841,  897,  911,  928,  945,  968, 1039, 1066, 1086, 1087, 1129, 1181, 1185, 1187, 1188, 1196, 1197, 1202, 1211, 1216, 1217, 1319, 1397]];

    tetraNode.createObject("MeshTopology", name="topology", src="@loader", drawTetrahedra=False)
    tetraNode.createObject("PointsFromIndices", template="Vec3d", name="posConstraintValues", position="@loader.position", indices=SofaPython.Tools.listToStr(posConstraintIndices))
    
    linearSSNode = tetraNode.createChild("linearSS")
    linearSSNode.createObject("EulerImplicitSolver")
    linearSSNode.createObject("CGLinearSolver", iterations="25", tolerance="1e-05", threshold="1e-05")
    linearSSNode.createObject("JacobsonEnergyComputationEngine", template="Vec3d", name="Energy", position="@../loader.position", laplacianScheme="3", massScheme="0")
    linearSSNode.createObject("JacobsonWeightComputationEngine", template="Vec3d", name="Weights", position="@../loader.position", Q="@Energy.Q", posConstraints=SofaPython.Tools.listToStr(posConstraintIndices), regionConstraints=SofaPython.Tools.listListToSStr(regionConstraintIndices))
#    return
    linearSSNode.createObject("WeightTranslationEngine", template="double", name="SkinningWeights", W="@Weights.W", nbPosConstraints=len(posConstraintIndices))
    linearSSNode.createObject("MechanicalObject", template="Vec3", name="dofs", position="@../posConstraintValues.indices_position", showObject=True, showObjectScale=5.)
    
    
    visualNode = linearSSNode.createChild("deformedMesh")
    visualNode.createObject("MechanicalObject", template="Vec3", name="proxyPosition", showObject=False, showObjectScale=10., position="@../../loader.position")
    visualNode.createObject("MeshTopology", name="visual", drawTetrahedra=True, drawTriangles=True, position="@proxyPosition.position", tetrahedra="@../../loader.tetrahedra")
#    visualNode.createObject("VisualModel", name="visual", src="@../../loader")

#    visualNode.createObject("MechanicalObject", template="Vec3", name="proxyPosition", showObject=False, showObjectScale=10., position="@../TransformedPositions.position")
#    visualNode.createObject("MeshTopology", name="visual", drawTetrahedra=True, drawTriangles=True, position="@../TransformedPositions.position", tetrahedra="@../../loader.tetrahedra")
    
    visualNode.createObject("LinearMapping", name="mapping", indices="@../SkinningWeights.indices", weights="@../SkinningWeights.weights", restPosition="@../../loader.position")
    
