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("MeshVTKLoader", name="loader", filename="mesh/Armadillo_Tetra_4406.vtu", createSubelements=True)
    
    posConstraintIndices = [732, 726, 1253, 465];
    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]];


    rootNode.createObject("VisualStyle", displayFlags="showVisualModels showBehaviorModels")
    
    rootNode.createObject("EulerImplicitSolver")
    rootNode.createObject("CGLinearSolver", iterations="25", tolerance="1e-05", threshold="1e-05")
    
    rootNode.createObject("MeshTopology", name="visual", drawTetrahedra=False, drawTriangles=False, position="@loader.position", tetrahedra="@loader.tetrahedra")
    
    rootNode.createObject("PointsFromIndices", template="Vec3d", name="posConstraintValues", position="@loader.position", indices=SofaPython.Tools.listToStr(posConstraintIndices))
    
    rootNode.createObject("JacobsonEnergyComputationEngine", template="Vec3d", name="Energy", position="@loader.position", laplacianScheme="3", massScheme="0")
    rootNode.createObject("JacobsonWeightComputationEngine", template="Vec3d", name="Weights", position="@loader.position", Q="@Energy.Q", posConstraints=SofaPython.Tools.listToStr(posConstraintIndices), regionConstraints=SofaPython.Tools.listListToSStr(regionConstraintIndices))
    
    rootNode.createObject("WeightMultiTranslationEngine", template="double", name="SplitWeights", W="@Weights.W", nbPosConstraints=len(posConstraintIndices))
    
    
    nodeVec = rootNode.createChild("vec")  
    nodeVec.createObject("MechanicalObject", template="Vec3", name="dofs", size=len(posConstraintIndices), position="@../posConstraintValues.indices_position", showObject=True, showObjectScale=10.)
    
    
    nodeAffine = rootNode.createChild("affine")
    nodeAffine.createObject("MechanicalObject", template="Affine", name="dofs", size=len(regionConstraintIndices), showObject=True, showObjectScale=1.)
    
    
    mappedNode = nodeVec.createChild("mapped")
    nodeAffine.addChild(mappedNode)
    mappedNode.createObject("MechanicalObject", template="Vec3", name="dofs", position="@/loader.position")
    mappedNode.createObject("LSMultiMapping", template="Vec3,Affine,Vec3", name="mapping", input1="@/vec", input2="@/affine", output="@./", index1="@/SplitWeights.index1", index2="@/SplitWeights.index2", weight1="@/SplitWeights.weight1", weight2="@/SplitWeights.weight2")
    
    mappedNode.createObject("MeshTopology", name="visual", drawTetrahedra=True, drawTriangles=True, position="@dofs.position", tetrahedra="@/loader.tetrahedra")
    
