def __init__(self, node, filepath, scale3d, offset, name_suffix='', generatedDir=None): r = Quaternion.to_euler(offset[3:]) * 180.0 / math.pi global idxVisualModel self.node = node.createChild('visual' + name_suffix) # node self.model = self.node.createObject('VisualModel', name='visual' + str(idxVisualModel), fileMesh=filepath, scale3d=concat(scale3d), translation=concat(offset[:3]), rotation=concat(r)) if generatedDir is None: self.mapping = self.node.createObject( 'LinearMapping', template='Affine,ExtVec3f', name='mapping') else: serialization.importLinearMapping( self.node, generatedDir + "_visualmapping.json") idxVisualModel += 1
def __init__(self, node, filepath, scale3d, offset, name_suffix='', generatedDir=None): r = Quaternion.to_euler(offset[3:]) * 180.0 / math.pi self.node = node.createChild('collision' + name_suffix) # node self.loader = SofaPython.Tools.meshLoader(self.node, filename=filepath, name='loader', scale3d=concat(scale3d), translation=concat( offset[:3]), rotation=concat(r), triangulate=True) self.topology = self.node.createObject('MeshTopology', name='topology', src='@loader') self.dofs = self.node.createObject('MechanicalObject', name='dofs', template='Vec3' + template_suffix) self.triangles = self.node.createObject('TriangleModel', name='model') if generatedDir is None: self.mapping = self.node.createObject('LinearMapping', template='Affine,Vec3' + template_suffix, name='mapping') else: serialization.importLinearMapping( self.node, generatedDir + "_collisionmapping.json") self.normals = None
def addMotor(self, forces=[0, 0, 0, 0, 0, 0]): ## adding a constant force/torque to the rigid body (that could be driven by a controller to simulate a motor) return self.rigidNode.createObject('ConstantForceField', template='Rigid3' + template_suffix, name='motor', indices='0', forces=concat(forces))
def addMotor(self, forces=[0, 0, 0, 0, 0, 0]): ## adding a constant force/torque at the offset location (that could be driven by a controller to simulate a motor) return self.node.createObject('ConstantForceField', template='Rigid3' + template_suffix, name='motor', points='0', forces=concat(forces))
def setManually(self, filepath=None, offset=[[0,0,0,0,0,0,1]], voxelSize=0.01, density=1000, generatedDir=None): if len(offset) == 0: Sofa.msg_error("RigidScale.API","ShearlessAffineBody should have at least 1 ShearLessAffine") return self.framecom = Frame.Frame() self.bodyOffset = Frame.Frame([0,0,0,0,0,0,1]) path_affine_rigid = '@'+ Tools.node_path_rel(self.affineNode, self.rigidNode) path_affine_scale = '@'+ Tools.node_path_rel(self.affineNode, self.scaleNode) if len(offset) == 1: self.frame = [Frame.Frame(offset[0])] str_position = "" for p in offset: str_position = str_position + concat(p) + " " ### scene creation # rigid dof self.rigidDofs = self.rigidNode.createObject('MechanicalObject', template='Rigid3'+template_suffix, name='dofs', position=str_position, rest_position=str_position) # scale dofs self.scaleDofs = self.scaleNode.createObject('MechanicalObject', template='Vec3'+template_suffix, name='dofs', position=concat([1,1,1]*len(offset))) positiveNode = self.scaleNode.createChild('positive') positiveNode.createObject('MechanicalObject', template='Vec3'+template_suffix, name='positivescaleDOFs') positiveNode.createObject('DifferenceFromTargetMapping', template='Vec3'+template_suffix+',Vec3'+template_suffix, applyRestPosition=1, targets=concat(target_scale)) positiveNode.createObject('UniformCompliance', isCompliance=1, compliance=0) positiveNode.createObject('UnilateralConstraint') positiveNode.createObject('Stabilization', name='Stabilization') # affine dofs self.affineDofs = self.affineNode.createObject('MechanicalObject', template='Affine', name='parent', showObject=0) self.affineNode.createObject('RigidScaleToAffineMultiMapping', template='Rigid,Vec3,Affine', input1=path_affine_rigid, input2=path_affine_scale, output='@.', autoInit='1', printLog='0') if filepath: self.image = SofaImage.API.Image(self.affineNode, name="image_" + self.name, imageType="ImageUC") self.shapeFunction = Flexible.API.ShapeFunction(self.affineNode) if generatedDir is None: self.image.addMeshLoader(filepath, value=1, insideValue=1, scale=scale3d) # TODO support multiple meshes closingValue=1, self.image.addMeshToImage(voxelSize) self.shapeFunction.addVoronoi(self.image, position='@dofs.rest_position') # mass self.affineMassNode = self.affineNode.createChild('mass') self.affineMassNode.createObject('TransferFunction', name='density', template='ImageUC,ImageD', inputImage='@../image.image', param='0 0 1 '+str(density)) self.affineMassNode.createObject('MechanicalObject', template='Vec3'+template_suffix) self.affineMassNode.createObject('LinearMapping', template='Affine,Vec3'+template_suffix) self.affineMassNode.createObject('MassFromDensity', name='MassFromDensity', template='Affine,ImageD', image='@density.outputImage', transform='@../image.transform', lumping='0') self.mass = self.affineNode.createObject('AffineMass', massMatrix='@mass/MassFromDensity.massMatrix') else: self.image.addContainer(filename=self.node.name + "_rasterization.raw", directory=generatedDir) self.shapeFunction.shapeFunction = serialization.importImageShapeFunction(self.affineNode, generatedDir+self.node.name+"_SF_indices.raw", generatedDir+self.node.name+"_SF_weights.raw", 'dofs') self.mass = serialization.importAffineMass(self.affineNode, generatedDir+self.node.name+"_affinemass.json") # computation of the object mass center massInfo = SofaPython.mass.RigidMassInfo() massInfo.setFromMesh(filepath, density, [1,1,1]) # get the object mass center self.framecom.rotation = massInfo.inertia_rotation self.framecom.translation = massInfo.com else: print "You need a mesh to create an articulated system" self.frame = [] for o in offset: self.frame.append(Frame.Frame(o))
def __init__(self, node, color=[1, 1, 1, 1]): global idxVisualModel self.node = node.createChild('visual') # node self.visual = self.node.createObject( 'VisualModel', name='model' + str(idxVisualModel), color=concat(color) ) # @to do: Add the filename in order to keep the texture coordinates otherwise we lost them ... self.mapping = self.node.createObject('IdentityMapping', name='mapping') idxVisualModel += 1
def addSkinning(self, node, armatureNode, indices, weights, assemble=True, isMechanical=True): """ Add skinning (linear) mapping based on the armature (Rigid3) in armatureNode using """ self.mapping = node.createObject("LinearMapping", template="Affine,Vec3", name="mapping", input="@" + armatureNode.getPathName(), indices=concat(indices), weights=concat(weights), assemble=assemble, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)
def __init__(self, node, name, position): self.node = node.createChild(name) self.dofs = self.node.createObject('MechanicalObject', name='dofs', template='Vec3' + template_suffix, position=concat(position)) self.mapping = self.node.createObject( 'LinearMapping', name='mapping', geometricStiffness=geometric_stiffness)
def addVisualModel(self, filepath, scale3d=[1, 1, 1], offset=[0, 0, 0, 0, 0, 0, 1], name_suffix='', generatedDir=None, color=[1, 1, 1, 1]): ## adding a visual model to the rigid body with a relative offset self.visual = ShearlessAffineBody.VisualModel( self.affineNode, filepath, scale3d, (self.bodyOffset * Frame.Frame(offset)).offset(), name_suffix, generatedDir=generatedDir, color=concat(color)) return self.visual
def setMeshLess(self, offset=[[0,0,0,0,0,0,1]], mass=1, rayleigh=0.1, generatedDir=None): if len(offset) == 0: Sofa.msg_error("RigidScale.API","ShearlessAffineBody should have at least 1 ShearLessAffine") return self.framecom = Frame.Frame() self.bodyOffset = Frame.Frame([0,0,0,0,0,0,1]) path_affine_rigid = '@' + Tools.node_path_rel(self.affineNode, self.rigidNode) path_affine_scale = '@' + Tools.node_path_rel(self.affineNode, self.scaleNode) if len(offset) == 1: self.frame = [Frame.Frame(offset[0])] str_position = "" for p in offset: str_position = str_position + concat(p) + " " ### scene creation # rigid dof self.rigidDofs = self.rigidNode.createObject('MechanicalObject', template='Rigid3'+template_suffix, name='dofs', position=str_position, rest_position=str_position) self.rigidNode.createObject('UniformMass', totalMass=mass, rayleighStiffness=rayleigh); # scale dofs self.scaleDofs = self.scaleNode.createObject('MechanicalObject', template='Vec3'+template_suffix, name='dofs', position= concat([1,1,1]*len(offset))) self.scaleNode.createObject('UniformMass', totalMass=mass, rayleighStiffness=rayleigh); #positiveNode = self.scaleNode.createChild('positive') #positiveNode.createObject('MechanicalObject', template='Vec3'+template_suffix, name='positivescaleDOFs') #target_scale = [0.5,0.5,0.5] #positiveNode.createObject('DifferenceFromTargetMapping', template='Vec3d,Vec3'+template_suffix, applyRestPosition=1, targets=concat(target_scale)) #positiveNode.createObject('UniformCompliance', isCompliance=1, compliance=0) #positiveNode.createObject('UnilateralConstraint') #positiveNode.createObject('Stabilization', name='Stabilization') # affine dofs self.affineDofs = self.affineNode.createObject('MechanicalObject', template='Affine', name='parent') self.affineNode.createObject('RigidScaleToAffineMultiMapping', template='Rigid,Vec3,Affine', input1=path_affine_rigid, input2=path_affine_scale, output='@.', autoInit='1', printLog='0') self.frame = [] for o in offset: self.frame.append(Frame.Frame(o))
def setFromMesh(self, filepath, density=1000, offset=[0,0,0,0,0,0,1], scale3d=[1,1,1], voxelSize=0.01, numberOfPoints=1, generatedDir=None): # variables self.bodyOffset = Frame.Frame(offset) path_affine_rigid = '@' + Tools.node_path_rel(self.affineNode, self.rigidNode) path_affine_scale = '@' + Tools.node_path_rel(self.affineNode, self.scaleNode) massInfo = SofaPython.mass.RigidMassInfo() massInfo.setFromMesh(filepath, density, scale3d) self.image = SofaImage.API.Image(self.node, name="image_" + self.name, imageType="ImageUC") self.image.node.addChild(self.affineNode) # for initialization self.image.node.addChild(self.rigidNode) # for initialization self.shapeFunction = Flexible.API.ShapeFunction(self.rigidNode) if generatedDir is None: self.image.addMeshLoader(filepath, value=1, insideValue=1, offset=offset, scale=scale3d) # TODO support multiple meshes closingValue=1, self.image.addMeshToImage(voxelSize) # rigid dofs self.sampler = SofaImage.API.Sampler(self.rigidNode) self.sampler.addImageSampler(self.image, numberOfPoints) self.rigidDofs = self.sampler.addMechanicalObject('Rigid3'+template_suffix) else: self.image.addContainer(filename=self.node.name+"_rasterization.raw", directory=generatedDir) self.rigidDofs = serialization.importRigidDofs(self.rigidNode, generatedDir+"/"+self.node.name+'_dofs.json') # scale dofs self.scaleDofs = self.scaleNode.createObject('MechanicalObject', template='Vec3'+template_suffix, name='dofs', position=concat([1,1,1]*numberOfPoints)) positiveNode = self.scaleNode.createChild('positive') positiveNode.createObject('MechanicalObject', template='Vec3'+template_suffix, name='positivescaleDOFs') positiveNode.createObject('DifferenceFromTargetMapping', template='Vec3d,Vec3'+template_suffix, applyRestPosition=1, targets=concat(target_scale)) positiveNode.createObject('UniformCompliance', isCompliance=1, compliance=0) positiveNode.createObject('UnilateralConstraint') # affine dofs self.affineDofs = self.affineNode.createObject('MechanicalObject', template='Affine', name='dofs') self.affineNode.createObject('RigidScaleToAffineMultiMapping', template='Rigid,Vec3d,Affine', input1=path_affine_rigid, input2=path_affine_scale, output='@.', autoInit='1', printLog='0') # shapefunction and mass if generatedDir is None: self.shapeFunction.addVoronoi(self.image, position='@dofs.rest_position') # mass densityImage = self.image.createTransferFunction(self.affineNode, "density", param='0 0 1 '+str(density)) affineMass = Flexible.API.AffineMass(self.affineNode) affineMass.massFromDensityImage(self.affineNode, densityImage=densityImage) self.mass = affineMass.mass else: self.shapeFunction.shapeFunction = serialization.importImageShapeFunction(self.affineNode, generatedDir+self.node.name+"_SF_indices.raw", generatedDir+self.node.name+"_SF_weights.raw", 'dofs') self.mass = serialization.importAffineMass(self.affineNode, generatedDir+self.node.name+"_affinemass.json") # hack to get the frame position self.node.init() for p in self.rigidDofs.position: p.extend([0,0,0,1]) self.frame.append(Frame.Frame(p))
def __init__(self, node, name, position): self.node = node.createChild(name) self.dofs = self.node.createObject('MechanicalObject', name='dofs', template='Vec3'+template_suffix, position=concat(position)) self.mapping = self.node.createObject('LinearMapping', name='mapping', geometricStiffness = geometric_stiffness)
def addMotor(self, forces=[0,0,0,0,0,0]): ## adding a constant force/torque at the offset location (that could be driven by a controller to simulate a motor) return self.node.createObject('ConstantForceField', template='Rigid3'+template_suffix, name='motor', points='0', forces=concat(forces))
def __init__(self, node, filepath, scale3d, offset, name_suffix='', generatedDir=None): r = Quaternion.to_euler(offset[3:]) * 180.0 / math.pi global idxVisualModel; self.node = node.createChild('visual'+name_suffix) # node self.model = self.node.createObject('VisualModel', name='visual'+str(idxVisualModel), fileMesh=filepath, scale3d=concat(scale3d), translation=concat(offset[:3]), rotation=concat(r)) if generatedDir is None: self.mapping = self.node.createObject('LinearMapping', template='Affine,ExtVec3f', name='mapping') else: serialization.importLinearMapping(self.node, generatedDir+"_visualmapping.json") idxVisualModel+=1
def __init__(self, node, filepath, scale3d, offset, name_suffix='', generatedDir=None): r = Quaternion.to_euler(offset[3:]) * 180.0 / math.pi self.node = node.createChild('collision'+name_suffix) # node self.loader = SofaPython.Tools.meshLoader(self.node, filename=filepath, name='loader', scale3d=concat(scale3d), translation=concat(offset[:3]) , rotation=concat(r), triangulate=True) self.topology = self.node.createObject('MeshTopology', name='topology', src='@loader') self.dofs = self.node.createObject('MechanicalObject', name='dofs', template='Vec3'+template_suffix) self.triangles = self.node.createObject('TriangleModel', name='model') if generatedDir is None: self.mapping = self.node.createObject('LinearMapping', template='Affine,Vec3'+template_suffix, name='mapping') else: serialization.importLinearMapping(self.node, generatedDir+"_collisionmapping.json") self.normals = None
def setFromMesh(self, filepath, density=1000, offset=[0, 0, 0, 0, 0, 0, 1], scale3d=[1, 1, 1], voxelSize=0.01, numberOfPoints=1, generatedDir=None): # variables self.bodyOffset = Frame.Frame(offset) path_affine_rigid = '@' + Tools.node_path_rel(self.affineNode, self.rigidNode) path_affine_scale = '@' + Tools.node_path_rel(self.affineNode, self.scaleNode) massInfo = SofaPython.mass.RigidMassInfo() massInfo.setFromMesh(filepath, density, scale3d) self.image = SofaImage.API.Image(self.node, name="image_" + self.name, imageType="ImageUC") self.image.node.addChild(self.affineNode) # for initialization self.image.node.addChild(self.rigidNode) # for initialization self.shapeFunction = Flexible.API.ShapeFunction(self.rigidNode) if generatedDir is None: self.image.addMeshLoader( filepath, value=1, insideValue=1, offset=offset, scale=scale3d) # TODO support multiple meshes closingValue=1, self.image.addMeshToImage(voxelSize) # rigid dofs self.sampler = SofaImage.API.Sampler(self.rigidNode) self.sampler.addImageSampler(self.image, numberOfPoints) self.rigidDofs = self.sampler.addMechanicalObject('Rigid3' + template_suffix) else: self.image.addContainer(filename=self.node.name + "_rasterization.raw", directory=generatedDir) self.rigidDofs = serialization.importRigidDofs( self.rigidNode, generatedDir + "/" + self.node.name + '_dofs.json') # scale dofs self.scaleDofs = self.scaleNode.createObject( 'MechanicalObject', template='Vec3' + template_suffix, name='dofs', position=concat([1, 1, 1] * numberOfPoints)) positiveNode = self.scaleNode.createChild('positive') positiveNode.createObject('MechanicalObject', template='Vec3' + template_suffix, name='positivescaleDOFs') positiveNode.createObject('DifferenceFromTargetMapping', template='Vec3d,Vec3' + template_suffix, applyRestPosition=1, targets=concat(target_scale)) positiveNode.createObject('UniformCompliance', isCompliance=1, compliance=0) positiveNode.createObject('UnilateralConstraint') positiveNode.createObject('Stabilization', name='Stabilization') # affine dofs self.affineDofs = self.affineNode.createObject('MechanicalObject', template='Affine', name='dofs') self.affineNode.createObject('RigidScaleToAffineMultiMapping', template='Rigid,Vec3d,Affine', input1=path_affine_rigid, input2=path_affine_scale, output='@.', autoInit='1', printLog='0') # shapefunction and mass if generatedDir is None: self.shapeFunction.addVoronoi(self.image, position='@dofs.rest_position') # mass densityImage = self.image.createTransferFunction(self.affineNode, "density", param='0 0 1 ' + str(density)) affineMass = Flexible.API.AffineMass(self.affineNode) affineMass.massFromDensityImage(self.affineNode, densityImage=densityImage) self.mass = affineMass.mass else: self.shapeFunction.shapeFunction = serialization.importImageShapeFunction( self.affineNode, generatedDir + self.node.name + "_SF_indices.raw", generatedDir + self.node.name + "_SF_weights.raw", 'dofs') self.mass = serialization.importAffineMass( self.affineNode, generatedDir + self.node.name + "_affinemass.json") # hack to get the frame position self.node.init() for p in self.rigidDofs.position: p.extend([0, 0, 0, 1]) self.frame.append(Frame.Frame(p))
def addSkinning(self, node, armatureNode, indices, weights, assemble=True, isMechanical=True): """ Add skinning (linear) mapping based on the armature (Rigid3) in armatureNode using """ self.mapping = node.createObject("LinearMapping", template="Affine,Vec3", name="mapping", input="@"+armatureNode.getPathName(), indices=concat(indices), weights=concat(weights), assemble=assemble, mapForces=isMechanical, mapConstraints=isMechanical, mapMasses=isMechanical)
def setManually(self, filepath=None, offset=[[0, 0, 0, 0, 0, 0, 1]], voxelSize=0.01, density=1000, generatedDir=None): if len(offset) == 0: Sofa.msg_error( "RigidScale.API", "ShearlessAffineBody should have at least 1 ShearLessAffine") return self.framecom = Frame.Frame() self.bodyOffset = Frame.Frame([0, 0, 0, 0, 0, 0, 1]) path_affine_rigid = '@' + Tools.node_path_rel(self.affineNode, self.rigidNode) path_affine_scale = '@' + Tools.node_path_rel(self.affineNode, self.scaleNode) if len(offset) == 1: self.frame = [Frame.Frame(offset[0])] str_position = "" for p in offset: str_position = str_position + concat(p) + " " ### scene creation # rigid dof self.rigidDofs = self.rigidNode.createObject( 'MechanicalObject', template='Rigid3' + template_suffix, name='dofs', position=str_position, rest_position=str_position) # scale dofs self.scaleDofs = self.scaleNode.createObject( 'MechanicalObject', template='Vec3' + template_suffix, name='dofs', position=concat([1, 1, 1] * len(offset))) positiveNode = self.scaleNode.createChild('positive') positiveNode.createObject('MechanicalObject', template='Vec3' + template_suffix, name='positivescaleDOFs') positiveNode.createObject('DifferenceFromTargetMapping', template='Vec3' + template_suffix + ',Vec3' + template_suffix, applyRestPosition=1, targets=concat(target_scale)) positiveNode.createObject('UniformCompliance', isCompliance=1, compliance=0) positiveNode.createObject('UnilateralConstraint') positiveNode.createObject('Stabilization', name='Stabilization') # affine dofs self.affineDofs = self.affineNode.createObject('MechanicalObject', template='Affine', name='parent', showObject=0) self.affineNode.createObject('RigidScaleToAffineMultiMapping', template='Rigid,Vec3,Affine', input1=path_affine_rigid, input2=path_affine_scale, output='@.', autoInit='1', printLog='0') if filepath: self.image = SofaImage.API.Image(self.affineNode, name="image_" + self.name, imageType="ImageUC") self.shapeFunction = Flexible.API.ShapeFunction(self.affineNode) if generatedDir is None: self.image.addMeshLoader( filepath, value=1, insideValue=1 ) # TODO support multiple meshes closingValue=1, self.image.addMeshToImage(voxelSize) self.shapeFunction.addVoronoi(self.image, position='@dofs.rest_position') # mass self.affineMassNode = self.affineNode.createChild('mass') self.affineMassNode.createObject('TransferFunction', name='density', template='ImageUC,ImageD', inputImage='@../image.image', param='0 0 1 ' + str(density)) self.affineMassNode.createObject('MechanicalObject', template='Vec3' + template_suffix) self.affineMassNode.createObject('LinearMapping', template='Affine,Vec3' + template_suffix) self.affineMassNode.createObject( 'MassFromDensity', name='MassFromDensity', template='Affine,ImageD', image='@density.outputImage', transform='@../image.transform', lumping='0') self.mass = self.affineNode.createObject( 'AffineMass', massMatrix='@mass/MassFromDensity.massMatrix') else: self.image.addContainer(filename=self.node.name + "_rasterization.raw", directory=generatedDir) self.shapeFunction.shapeFunction = serialization.importImageShapeFunction( self.affineNode, generatedDir + self.node.name + "_SF_indices.raw", generatedDir + self.node.name + "_SF_weights.raw", 'dofs') self.mass = serialization.importAffineMass( self.affineNode, generatedDir + self.node.name + "_affinemass.json") # computation of the object mass center massInfo = SofaPython.mass.RigidMassInfo() massInfo.setFromMesh(filepath, density, [1, 1, 1]) # get the object mass center self.framecom.rotation = massInfo.inertia_rotation self.framecom.translation = massInfo.com else: print "You need a mesh to create an articulated system" self.frame = [] for o in offset: self.frame.append(Frame.Frame(o))