<commit_before>import math
import os.path
import Sofa
import json

import Flexible.IO
import sys

import SofaPython.Tools
from SofaPython.Tools import listToStr as concat
from SofaPython import Quaternion

printLog = True


def insertLinearMapping(node, dofRigidNode=None, dofAffineNode=None, cell='', assemble=True, geometricStiffness=2, isMechanical=True):
    """ insert the correct Linear(Multi)Mapping
    hopefully the template is deduced automatically by the component
    """
    if dofRigidNode is None and dofAffineNode is None:
        print "[Flexible.API.insertLinearMapping] ERROR: no dof given"
    else:
        if dofRigidNode is None:
            return node.createObject(
                "LinearMapping", cell=cell, shapeFunction = 'shapeFunction',
                input="@"+dofAffineNode.getPathName(), output="@.", assemble=assemble, geometricStiffness=geometricStiffness, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)
        elif dofAffineNode is None:
            return node.createObject(
                "LinearMapping", cell=cell, shapeFunction = 'shapeFunction',
                input="@"+dofRigidNode.getPathName(), output="@.", assemble=assemble, geometricStiffness=geometricStiffness, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)
        else:
            return node.createObject(
                "LinearMultiMapping", cell=cell, shapeFunction = 'shapeFunction',
                input1="@"+dofRigidNode.getPathName(), input2="@"+dofAffineNode.getPathName(), output="@.", assemble=assemble, geometricStiffness=geometricStiffness, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)

class Deformable:
    """ This class reprents a deformable object build from a mesh.
        Various cases are handled:
        - collision model :
            x static (loaded from file or subset of another static model)
            x linearly mapped from dofs
            x identity mapped from several collision models
            x subset mapped from another collision model
        - visual model :
            x static (loaded from file or subset of another static model)
            x linearly mapped from dof
            x identity mapped from a collision model
            x subset mapped from a collision model
    """
    
    def __init__(self, node, name = None):
        if not name is None :
            self.node=node.createChild(name)
        else:
            self.node=node
        self.name=name
        self.meshLoader=None
        self.topology=None
        self.dofs=None
        self.visual=None
        self.mapping=None
        self.normals=None
        self.mass=None


    def loadMesh(self, meshPath, offset = [0,0,0,0,0,0,1], scale=[1,1,1], triangulate=False):
        r = Quaternion.to_euler(offset[3:])  * 180.0 / math.pi
        self.meshLoader = SofaPython.Tools.meshLoader(self.node, meshPath, translation=concat(offset[:3]) , rotation=concat(r), scale3d=concat(scale), triangulate=triangulate)
        self.topology = self.node.createObject("MeshTopology", name="topology", src="@"+self.meshLoader.name )

    def loadVisual(self, meshPath, offset = [0,0,0,0,0,0,1], scale=[1,1,1], color=[1,1,1,1]):
        r = Quaternion.to_euler(offset[3:])  * 180.0 / math.pi
        self.visual =  self.node.createObject("VisualModel", name="model", filename=meshPath, translation=concat(offset[:3]) , rotation=concat(r), scale3d=concat(scale), color=concat(color))
        self.topology = self.node.createObject("MeshTopology", name="topology", src="@"+self.visual.name )
        self.normals = self.visual


    def addVisual(self, color=[1,1,1,1]):
        if self.dofs is None: # use static (triangulated) mesh from topology
            self.visual = self.node.createObject("VisualModel", name="model", color=concat(color), src="@"+self.topology.name)
            self.normals = self.visual
        else:   # create a new deformable
            d = Deformable(self.node,"Visual")
            d.visualFromDeformable(self,color)
            return d

    def visualFromDeformable(self, deformable, color=[1,1,1,1]):
        deformable.node.addChild(self.node)
        self.visual = self.node.createObject("VisualModel", name="model", filename="@"+SofaPython.Tools.getObjectPath(deformable.meshLoader)+".filename", color=concat(color))
        self.mapping = self.node.createObject("IdentityMapping", name="mapping", input='@'+deformable.node.getPathName(),output="@.", mapForces=False, mapConstraints=False, mapMasses=False )
        self.normals = self.meshLoader

    def subsetFromDeformable(self, deformable, indices ):
        if not deformable.topology is None:<commit_msg>[Flexible] python API: allows tuning visual model<commit_after>import math
import os.path
import Sofa
import json

import Flexible.IO
import sys

import SofaPython.Tools
from SofaPython.Tools import listToStr as concat
from SofaPython import Quaternion

printLog = True


def insertLinearMapping(node, dofRigidNode=None, dofAffineNode=None, cell='', assemble=True, geometricStiffness=2, isMechanical=True):
    """ insert the correct Linear(Multi)Mapping
    hopefully the template is deduced automatically by the component
    """
    if dofRigidNode is None and dofAffineNode is None:
        print "[Flexible.API.insertLinearMapping] ERROR: no dof given"
    else:
        if dofRigidNode is None:
            return node.createObject(
                "LinearMapping", cell=cell, shapeFunction = 'shapeFunction',
                input="@"+dofAffineNode.getPathName(), output="@.", assemble=assemble, geometricStiffness=geometricStiffness, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)
        elif dofAffineNode is None:
            return node.createObject(
                "LinearMapping", cell=cell, shapeFunction = 'shapeFunction',
                input="@"+dofRigidNode.getPathName(), output="@.", assemble=assemble, geometricStiffness=geometricStiffness, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)
        else:
            return node.createObject(
                "LinearMultiMapping", cell=cell, shapeFunction = 'shapeFunction',
                input1="@"+dofRigidNode.getPathName(), input2="@"+dofAffineNode.getPathName(), output="@.", assemble=assemble, geometricStiffness=geometricStiffness, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)

class Deformable:
    """ This class reprents a deformable object build from a mesh.
        Various cases are handled:
        - collision model :
            x static (loaded from file or subset of another static model)
            x linearly mapped from dofs
            x identity mapped from several collision models
            x subset mapped from another collision model
        - visual model :
            x static (loaded from file or subset of another static model)
            x linearly mapped from dof
            x identity mapped from a collision model
            x subset mapped from a collision model
    """
    
    def __init__(self, node, name = None):
        if not name is None :
            self.node=node.createChild(name)
        else:
            self.node=node
        self.name=name
        self.meshLoader=None
        self.topology=None
        self.dofs=None
        self.visual=None
        self.mapping=None
        self.normals=None
        self.mass=None


    def loadMesh(self, meshPath, offset = [0,0,0,0,0,0,1], scale=[1,1,1], triangulate=False):
        r = Quaternion.to_euler(offset[3:])  * 180.0 / math.pi
        self.meshLoader = SofaPython.Tools.meshLoader(self.node, meshPath, translation=concat(offset[:3]) , rotation=concat(r), scale3d=concat(scale), triangulate=triangulate)
        self.topology = self.node.createObject("MeshTopology", name="topology", src="@"+self.meshLoader.name )

    def loadVisual(self, meshPath, offset = [0,0,0,0,0,0,1], scale=[1,1,1], color=[1,1,1,1],**kwargs):
        r = Quaternion.to_euler(offset[3:])  * 180.0 / math.pi
        self.visual =  self.node.createObject("VisualModel", name="model", filename=meshPath, translation=concat(offset[:3]) , rotation=concat(r), scale3d=concat(scale), color=concat(color),**kwargs)
        self.topology = self.node.createObject("MeshTopology", name="topology", src="@"+self.visual.name )
        self.normals = self.visual


    def addVisual(self, color=[1,1,1,1]):
        if self.dofs is None: # use static (triangulated) mesh from topology
            self.visual = self.node.createObject("VisualModel", name="model", color=concat(color), src="@"+self.topology.name)
            self.normals = self.visual
        else:   # create a new deformable
            d = Deformable(self.node,"Visual")
            d.visualFromDeformable(self,color)
            return d

    def visualFromDeformable(self, deformable, color=[1,1,1,1]):
        deformable.node.addChild(self.node)
        self.visual = self.node.createObject("VisualModel", name="model", filename="@"+SofaPython.Tools.getObjectPath(deformable.meshLoader)+".filename", color=concat(color))
        self.mapping = self.node.createObject("IdentityMapping", name="mapping", input='@'+deformable.node.getPathName(),output="@.", mapForces=False, mapConstraints=False, mapMasses=False )
        self.normals = self.meshLoader

    def subsetFromDeformable(self, deformable, indices ):
        if not deformable.topology is None:
{'fraction_non_alphanumeric': 0.11248415716096324, 'fraction_numerical': 0.010350654837346852, 'mean_word_length': 3.3777161349976885, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7244270', 'n_tokens_mistral': 2862, 'n_tokens_neox': 2695, 'n_words': 639}