def processProperties(self, key, kv, stack, frame): if not isinstance(kv, list): raise Exception("This shouldn't happen, exepecting only list") msg = "" for k,v in kv: ## Check if the property named by "k" already exists. if hasattr(self, k): msg += " - cannot add a property named '"+k+"' as it already exists" continue if isAStringToken(v): v=processString(v, stack, frame) if isinstance(v, int): self.addNewData(k, "Properties", "", "d", v) elif isinstance(v, str) or isinstance(v,unicode): self.addNewData(k, "Properties", "", "s", str(v)) elif isinstance(v, float): self.addNewData(k, "Properties", "", "f", v) if hasattr(self, k): msg += " - adding: '"+str(k)+"' = "+str(v) else: msg += " - unable to create a property from the value '"+str(v)+"'" Sofa.msg_info(self, pslprefix+"Adding a user properties: \n"+msg)
def processAlias(parent, key, token, stack, frame): if not isAStringToken(token, ('p')): Sofa.msg_error(parent, pslprefix+" Unable to set an alias because of invalid syntax.") global aliases value = token[1] oldName, newName = value.split(' as ') aliases[newName]=oldName
def insertMergeRigid(self, mergeNodeName="dofRigid", tags=None, rigidIndexById=None ): """ Merge all the rigids in a single MechanicalObject using a SubsetMultiMapping optionnaly give a list of tags to select the rigids which are merged return the created node""" mergeNode = None currentRigidIndex=0 input="" indexPairs="" if tags is None: _tags = self.param.rigidTags else: _tags = tags for solid in self.model.getSolidsByTags(_tags): if not solid.id in self.rigids: Sofa.msg_warning("Compliant.sml","SceneArticulatedRigid.insertMergeRigid: "+solid.name+" is not a rigid") continue rigid = self.rigids[solid.id] if mergeNode is None: mergeNode = rigid.node.createChild(mergeNodeName) else: rigid.node.addChild(mergeNode) input += '@'+rigid.node.getPathName()+" " indexPairs += str(currentRigidIndex) + " 0 " if not rigidIndexById is None: rigidIndexById[solid.id]=currentRigidIndex currentRigidIndex+=1 if input: mergeNode.createObject("MechanicalObject", template = "Rigid3", name="dofs") mergeNode.createObject('SubsetMultiMapping', template = "Rigid3,Rigid3", name="mapping", input = input , output = '@./', indexPairs=indexPairs, applyRestPosition=True ) else: Sofa.msg_warning("Compliant.sml", "insertMergeRigid: no rigid merged") return mergeNode
def createScene(self): model=self.model # shortcut for solid in model.solids.values(): if printLog: Sofa.msg_info("SofaPython.sml","SceneDisplay: Display solid:" + solid.name) color = getValueByTag(self.param.colorByTag, solid.tags) insertVisual(self.node, solid, color)
def as_numpy(data, read_only=-1): """ maps data content as a numpy array :param data: the Data :param readOnly: (boolean) if true you should not modify the numpy array content if false (read/write), ***you have to call endEdit*** to unlock the Data and set it as dirty :return: numpy array """ if not isinstance(read_only, bool): # backward compatibility Sofa.msg_deprecated( "SofaNumpy", "as_numpy: Data must be explicitly accessed as read-only or read-write. " "With a read-only access, the numpy array should not be modified. " "With a read-write access, the Data must be explicitly unlocked and set as dirty with a call to 'Data.endEditVoidPtr'" ) read_only = True # similar to the first behavior if read_only: ptr, shape, typename = data.getValueVoidPtr() else: ptr, shape, typename = data.beginEditVoidPtr() nparray = wrap_as_numpy_array(ptr, shape, typename) if read_only: nparray.flags['WRITEABLE'] = False return nparray
def onKeyPressed(self, c): if (c == "+"): print 'heating' wire = self.node.getObject('actuator_wire') ls = Sofa.LinearSpring(0, 0, 0, 0, 0) #(0, 1, 500., 5., 100.) for i in range(0, len(wire.spring)): ls = wire.spring[i] # insert SMA heating algorithm here ls.L *= 0.95 ls.Ks += 100 wire.spring[i] = ls #wire.stiffness *=10 #stiffness is controlled for the whole wire, not segmentwise #self.node.getObject('actuator_wire').reinit() print wire.spring elif (c == "-"): print 'cooling' wire = self.node.getObject('actuator_wire') ls = Sofa.LinearSpring(0, 0, 0, 0, 0) #(0, 1, 500., 5., 100.) for i in range(0, len(wire.spring)): ls = wire.spring[i] # insert SMA cooling algorithm here ls.L /= 0.95 ls.Ks -= 100 wire.spring[i] = ls #self.node.getObject('actuator_wire').reinit() print wire.spring sys.stdout.flush() return 0
def setupUnits(myUnits): message = "units:" for quantity, unit in myUnits.iteritems(): exec("units.local_{0} = units.{0}_{1}".format(quantity, unit)) message += " " + quantity + ":" + unit if printLog: Sofa.msg_info("SofaPython.sml", message)
def processProperties(self, key, kv, stack, frame): if not isinstance(kv, list): raise Exception("This shouldn't happen, exepecting only list") msg = "" for k, v in kv: ## Check if the property named by "k" already exists. if hasattr(self, k): msg += " - cannot add a property named '" + k + "' as it already exists" continue if isAStringToken(v): v = processString(v, stack, frame) if isinstance(v, int): self.addNewData(k, "Properties", "", "d", v) elif isinstance(v, str) or isinstance(v, unicode): self.addNewData(k, "Properties", "", "s", str(v)) elif isinstance(v, float): self.addNewData(k, "Properties", "", "f", v) if hasattr(self, k): msg += " - adding: '" + str(k) + "' = " + str(v) else: msg += " - unable to create a property from the value '" + str( v) + "'" Sofa.msg_info(self, pslprefix + "Adding a user properties: \n" + msg)
def dagValidation(self): err = DAGValidation.test(self.root, True) if not len(err) is 0: Sofa.msg_error("SofaPython.sml", "BaseScene: your DAG scene is not valid") for e in err: Sofa.msg_error("SofaPython.sml", e)
def processPython(parent, key, token, stack, frame): """Process a python fragment of code with context provided by the content of the stack.""" if not isAStringToken(token, ("s", "m")): Sofa.msg_error( parent, "Python expect string only argument instead of '" + str(token) + "'") return None #if not isAStringToken(token, ("s", "m")): # raise Exception("Only string or multiline string allowed: "+str(token)) ## retrieve the value as a string. stringvalue = token[1] p = parent.createObject("Python", name='"' + stringvalue[0:20] + '..."') p.addNewData("psl_source", "PSL", "This hold a python expression.", "s", str(stringvalue)) context = flattenStackFrame(stack) local = {} exec(stringvalue, context, local) ## Transfer the local entries to the previously defined context or in the existing variable ## somewhere in the stack frame. ## This allow import in one line and use the imported in the following ones. for k in local: lframe = findStackLevelFor(k, stack) if lframe != None: lframe[k] = local[k] else: stack[-1][k] = local[k]
def read(self, filenamePrefix=None, directory="", **kwargs): filename = self.getFilename(filenamePrefix, directory) data = dict() with open(filename, 'r') as f: data.update(json.load(f)) self.type = data['type'] self.sampler = self.node.createObject( 'GaussPointContainer', name='GPContainer', volumeDim=data['volumeDim'], inputVolume=data['inputVolume'], position=data['position'], **kwargs) if not self.labelImage is None and not self.labels is None: if self.labelImage.prefix == "Branching": celloffsets = self.node.createObject( "BranchingCellOffsetsFromPositions", template=self.labelImage.template(), name="cell", position=self.sampler.getLinkPath() + ".position", src=self.labelImage.getImagePath(), labels=concat(self.labels)) self.cell = celloffsets.getLinkPath() + ".cell" if printLog: Sofa.msg_info("Flexible.API.Behavior", 'Imported Gauss Points from ' + filename)
def addMeshToImage(self, voxelSize): args = dict() i = 1 for name in self.meshSeq: mesh = self.meshes[name] if mesh.mesh is None: Sofa.msg_error("Image.API", "addMeshToImage : no mesh for " + name) return meshPath = mesh.mesh.getLinkPath() args["position" + str(i)] = meshPath + ".position" args["triangles" + str(i)] = meshPath + ".triangles" args["value" + str(i)] = mesh.value if mesh.insideValue is None: args["fillInside" + str(i)] = False else: args["insideValue" + str(i)] = mesh.insideValue if not mesh.roiIndices is None and len(mesh.roiValue) != 0: args["roiIndices" + str(i)] = mesh.roiIndices args["roiValue" + str(i)] = concat(mesh.roiValue) i += 1 self.image = self.node.createObject( "MeshToImageEngine", template=self.template(), name="image", voxelSize=voxelSize, padSize=1, subdiv=8, rotateImage=False, nbMeshes=len(self.meshes), **args )
def write(self, filenamePrefix=None, directory=""): filename = self.getFilename(filenamePrefix,directory) data = {'massMatrix': str(self.mass.findData('massMatrix').value).replace('\n',' ')} with open(filename, 'w') as f: json.dump(data, f) if printLog: Sofa.msg_info("Flexible.API.AffineMass",'Exported Affine Mass to '+filename)
def read(self, filenamePrefix=None, directory=""): filename = self.getFilename(filenamePrefix, directory) if os.path.isfile(filename): data = dict() with open(filename, 'r') as f: data.update(json.load(f)) # dofs self.dof = self.node.createObject( "MechanicalObject", name="dofs", template=data['template'], position=(data['position']), rest_position=(data['rest_position'])) # mesh if 'hexahedra' in data and 'tetrahedra' in data: self.mesh = self.node.createObject( "Mesh", name="mesh", position=(data['rest_position']), hexahedra=data['hexahedra'], tetrahedra=data['tetrahedra']) # uniform mass if 'totalMass' in data: self.addUniformMass(data['totalMass']) if printLog: Sofa.msg_info("Flexible.API.FEMDof", 'Imported FEM Dof from ' + filename)
def addVisual(self, color=[1,1,1,1]): if self.dofs is None: Sofa.msg_error("Flexible.API.Deformable","addVisual : visual mesh not added because there is no dof, use LoadVisual instead to have a static visual mesh ") else: # create a new deformable d = Deformable(self.node,"Visual") d.visualFromDeformable(self,color) return d
def createScene(self): model=self.model # shortcut for solid in model.solids.values(): if printLog: Sofa.msg_info("SofaPython.sml","SceneDisplay: Display solid:" + solid.name) color = solid.getValueByTag(self.param.colorByTag) insertVisual(self.node, solid, color)
def setupUnits(myUnits): message = "units:" for quantity,unit in myUnits.iteritems(): exec("units.local_{0} = units.{0}_{1}".format(quantity,unit)) message+=" "+quantity+":"+unit if printLog: Sofa.msg_info("SofaPython.sml",message)
def processPython(parent, key, token, stack, frame): """Process a python fragment of code with context provided by the content of the stack.""" if not isAStringToken(token, ("s", "m")): Sofa.msg_error(parent, "Python expect string only argument instead of '"+str(token)+"'") return None #if not isAStringToken(token, ("s", "m")): # raise Exception("Only string or multiline string allowed: "+str(token)) ## retrieve the value as a string. stringvalue = token[1] p=parent.createObject("Python", name='"'+stringvalue[0:20]+'..."') p.addNewData("psl_source","PSL", "This hold a python expression.", "s", str(stringvalue)) context = flattenStackFrame(stack) local = {} exec(stringvalue, context, local) ## Transfer the local entries to the previously defined context or in the existing variable ## somewhere in the stack frame. ## This allow import in one line and use the imported in the following ones. for k in local: lframe = findStackLevelFor(k, stack) if lframe != None: lframe[k] = local[k] else: stack[-1][k] = local[k]
def onBeginAnimationStep(self, deltaTime): if self.options['time_parameters']['time_profiling']: Sofa.timerSetEnabled(self.options['time_parameters']['timer_name'], True) Sofa.timerBegin(self.options['time_parameters']['timer_name']) return 0
def insertRigidScale(parentNode, solidModel, param): """ create a RigidScale.API.ShearlessAffineBody from the solidModel """ if printLog: Sofa.msg_info("RigidScale.sml", "insertRigidScale "+solidModel.name) body = RigidScale.API.ShearlessAffineBody(parentNode, solidModel.name) if (not len(solidModel.mesh)==1): Sofa.msg_warning("RigidScale.sml", "insertRigidScale support only single mesh solid (nb meshes={0}) - solid {1} ignored".format(len(solidModel.mesh), solidModel.name)) return None # TODO support multi meshes body.setFromMesh(solidModel.mesh[0].source, numberOfPoints = SofaPython.sml.getValueByTag(param.rigidScaleNbDofByTag, solidModel.tags), voxelSize = SofaPython.units.length_from_SI(param.voxelSize), density = SofaPython.units.massDensity_from_SI(1000.), offset = solidModel.position) body.addBehavior(youngModulus=SofaPython.units.elasticity_from_SI(param.rigidScaleStiffness), numberOfGaussPoint=8) cm = body.addCollisionMesh(solidModel.mesh[0].source) cm.addVisualModel() body.affineDofs.showObject=param.showAffine body.affineDofs.showObjectScale=SofaPython.units.length_from_SI(param.showAffineScale) if param.showImage: body.image.addViewer() return body
def AnimationManager(node): """ A Controller to manage all animations in the scene. Before using the animation framework an AnimationManager must be added to the scene. It has in charge, at each time step to update all the running animations. Returns: AnimationManagerController Example: .. sourcecode:: python def createScene(rootNode) AnimationManager(rootNode) """ global manager if manager != None: Sofa.msg_info( node, "There is already one animation manager in this scene...why do you need a second one ?" ) return manager manager = AnimationManagerController(node) return manager
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 parseImages(self, obj, objXml): images=objXml.findall("image") for i,m in enumerate(images): imageId = m.attrib["id"] if imageId in self.images: obj.addImage(self.images[imageId]) else: Sofa.msg_error("SofaPython.sml","Model: solid {0} references undefined image {1}".format(obj.name, imageId))
def numpy_data(obj, name): ## @deprecated Sofa.msg_deprecated( "SofaNumpy", "numpy_data: Data must be explicitly accessed as read-only or read-write. " " Use 'read_only()' or 'edit_data' context instead") data = obj.findData(name) return as_numpy(data, -1)
def addMechanicalObject(self, position=None, **kwargs): if position is None: if not self.mesh is None: # use implicit definition from mesh topology self.dof = self.node.createObject("MechanicalObject", template="Vec3", name="dofs", **kwargs) else: Sofa.msg_error("Flexible.API.FEMDof","addMechanicalObject : no input position") return self.dof = self.node.createObject("MechanicalObject", template="Vec3", name="dofs", position=position, **kwargs)
def writeObj(self, filenamePrefix=None, directory=""): filename = self.getFilename(filenamePrefix,directory).replace("json","obj") with open(filename, 'w') as f: f.write(self.name+"\n") for p in self.sampler.position: f.write("v "+SofaPython.Tools.listToStr(p)+"\n") if printLog: Sofa.msg_info("Flexible.API.Behavior",'Exported Gauss Points as a mesh: '+filename)
def test_loggedMessagesBinding(self): node = create_scene("a_node") self.assertEqual(node.getLoggedMessagesAsString(), "") Sofa.msg_info(node, "This is a new message") self.assertTrue("This is a new message" in node.getLoggedMessagesAsString()) self.assertEqual(node.countLoggedMessages(), 1) node.clearLoggedMessages() self.assertEqual(node.countLoggedMessages(), 0)
def writeStrains(self, filenamePrefix=None, directory=""): if not self.strainDofs is None: filename = self.getFilename(filenamePrefix,directory).replace(".json","_E.json") data = {'type': self.type,'position': SofaPython.Tools.listListToStr(self.strainDofs.position) } with open(filename, 'w') as f: json.dump(data, f) if printLog: Sofa.msg_info("Flexible.API.Behavior",'Exported Strains in: '+filename)
def load(self): if self.format.lower() == "obj": return SofaPython.MeshLoader.loadOBJ(self.source) else: Sofa.msg_error( "SofaPython.sml", "Mesh: format " + self.format + " not yet loadable") return SofaPython.MeshLoader.Mesh()
def addMesh(self, src=None, **kwargs): if src is None: Sofa.msg_error("Flexible.API.FEMDof", "addMesh : no input mesh") return self.mesh = self.node.createObject("Mesh", name="mesh", src=src, **kwargs)
def MainHeader(node, gravity=[0.0, -9.8, 0.0], dt=0.01, plugins=[], repositoryPaths=[], doDebug=False): ''' Args: gravity (vec3f): define the gravity vector. dt (float): define the timestep. plugins (list str): list of plugins to load repositoryPaths (list str): list of path to the specific data repository Structure: .. sourcecode:: qml rootNode : { gravity : gravity, dt : dt, VisualStyle, RepositoryPath, RequiredPlugin, OglSceneFrame, FreeMotionAnimationLoop, GenericConstraintSolver, DiscreteIntersection } ''' node.createObject('VisualStyle') node.findData('gravity').value=gravity; node.findData('dt').value=dt if not isinstance(plugins, list): Sofa.msg_error("MainHeader", "'plugins' expected to be a list, got "+str(type(plugins))) return node if "SofaMiscCollision" not in plugins: plugins.append("SofaMiscCollision") if "SofaPython" not in plugins: plugins.append("SofaPython") confignode = node.createChild("Config") for name in plugins: confignode.createObject('RequiredPlugin', name=name, printLog=False) i=0 for repository in repositoryPaths: confignode.createObject('AddResourceRepository', name="AddResourceRepository"+str(i), path=repository) i+=1 confignode.createObject('OglSceneFrame', style="Arrows", alignment="TopRight") if doDebug: from splib.debug import DebugManager DebugManager(node) AnimationManager(node) return node
def test_parents_property(self): root = Sofa.Node("rootNode") c1 = root.addChild(Sofa.Node("child1")) c2 = root.addChild(Sofa.Node("child2")) d = c1.addChild(Sofa.Node("subchild")) d = c2.addChild(Sofa.Node("subchild")) self.assertEqual(len(d.parents), 1) c1.addChild(d) self.assertEqual(len(d.parents), 2)
def processAlias(parent, key, token, stack, frame): if not isAStringToken(token, ('p')): Sofa.msg_error( parent, pslprefix + " Unable to set an alias because of invalid syntax.") global aliases value = token[1] oldName, newName = value.split(' as ') aliases[newName] = oldName
def texWall(texInt,position, r_angle, r_axis, length, width): '''Draws a wall with the given texture.''' glBindTexture(GL_TEXTURE_2D,int(textureIDs[texInt])) glPushMatrix() glTranslate(*position) glRotate(r_angle,*r_axis) glScale(length,width,1) Sofa.texQuad() # the the texQuad method in Sofa.py glPopMatrix()
def refreshComponentListFromFactory(): global sofaComponents, sofaAliases sofaComponents = [] sofaAliases = {} for (name, desc) in Sofa.getAvailableComponents(): sofaComponents.append(name) sofaHelp[name] = desc for alias in Sofa.getAliasesFor(name): sofaAliases[alias] = name
def addMeshVisual(self, meshName=None, color=None): name = self.meshSeq[0] if meshName is None else meshName mesh = self.meshes[name] if mesh.mesh is None: Sofa.msg_error('Image.API',"addMeshVisual : no mesh for "+ meshName) return mesh.visual = self.node.createObject("VisualModel", name="visual_"+name, src=mesh.mesh.getLinkPath()) if not color is None: mesh.visual.setColor(color[0],color[1],color[2],color[3])
def createTimeProfiler(self): print 'Time statistics file: ' + self.estFolder + '/' + self.opt['time']['time_statistics_file'] Sofa.timerSetInterval(self.opt['time']['timer_name'], self.opt['time']['iterations_interval']) ### Set the number of steps neded to compute the timer Sofa.timerSetOutputType(self.opt['time']['timer_name'], 'json') ### Set output file format with open(self.estFolder + '/' + self.opt['time']['time_statistics_file'], "a") as outputFile: outputFile.write('{') outputFile.close() return 0
def addMechanicalObject(self, template="Vec3"): if self.sampler is None: Sofa.msg_error('Image.API',"addMechanicalObject : no sampler") return None if self.mesh is None: self.dofs = self.node.createObject("MechanicalObject", template=template, name="dofs", position='@sampler.position') else: self.dofs = self.node.createObject("MechanicalObject", template=template, name="dofs") return self.dofs
def parseMeshes(self, obj, objXml): meshes=objXml.findall("mesh") for i,m in enumerate(meshes): meshId = m.attrib["id"] attr = Model.MeshAttributes(m) if meshId in self.meshes: obj.addMesh(self.meshes[meshId], attr) else: Sofa.msg_error("SofaPython.sml","Model: solid {0} references undefined mesh {1}".format(obj.name, meshId))
def addMeshVisual(self, meshName=None, color=None): name = self.meshSeq[0] if meshName is None else meshName mesh = self.meshes[name] if mesh.mesh is None: Sofa.msg_error("Image.API", "addMeshVisual : no mesh for " + meshName) return mesh.visual = self.node.createObject("VisualModel", name="visual_" + name, src=mesh.mesh.getLinkPath()) if not color is None: mesh.visual.setColor(color[0], color[1], color[2], color[3])
def read(self, filenamePrefix=None, directory=""): filename = self.getFilename(filenamePrefix,directory) if os.path.isfile(filename): data = dict() with open(filename,'r') as f: data.update(json.load(f)) self.dof = self.node.createObject("MechanicalObject", name="dofs", template=data['template'], position=data['position'], rest_position=data['rest_position']) if printLog: Sofa.msg_info("Flexible.API.AffineDof",'Imported Affine Dof from '+filename)
def checkSysPathDuplicate(): for p in sys.path: print p for p in sys.path: print p if (sys.path.count(p)>1): Sofa.msg_info("Found duplicate path : "+p) if not EXPECT_EQ(1,sys.path.count(p),"sys.path.count("+p+")"): return False return True
def write(self, filenamePrefix=None, directory=""): if self.dof is None: Sofa.msg_error("Flexible.API.AffineDof","write : no dof") return filename = self.getFilename(filenamePrefix,directory) data = {'template':'Affine', 'rest_position': affineDatatostr(self.dof.rest_position), 'position': affineDatatostr(self.dof.position)} with open(filename, 'w') as f: json.dump(data, f) if printLog: Sofa.msg_info("Flexible.API.AffineDof",'Exported Affine Dof to '+filename)
def read(self, filenamePrefix=None, directory=""): filename = self.getFilename(filenamePrefix,directory) if os.path.isfile(filename): data = dict() with open(filename,'r') as f: data.update(json.load(f)) self.mass = self.dofAffineNode.createObject('AffineMass', name='mass', massMatrix=data['massMatrix']) if printLog: Sofa.msg_info("Flexible.API.AffineMass",'Imported Affine Mass from '+filename)
def addMechanicalObject(self, template="Vec3"): if self.sampler is None: Sofa.msg_error("Image.API", "addMechanicalObject : no sampler") return None if self.mesh is None: self.dofs = self.node.createObject( "MechanicalObject", template=template, name="dofs", position="@sampler.position" ) else: self.dofs = self.node.createObject("MechanicalObject", template=template, name="dofs") return self.dofs
def initGraph(self, node): Sofa.msg_info("initGraph ENTER") child = node.createChild("temporary_node") # FROM HERE, 'child' was added to the nodes to init in ScriptEnvironment, but it is not anymore node.removeChild( child ) # 'child' is no longer in the scene graph but still was in ScriptEnvironment, but it is not anymore Sofa.msg_info("initGraph EXIT")
def addViewer(self): if self.image is None: Sofa.msg_error("Image.API", "addViewer : no image") return self.viewer = self.node.createObject( "ImageViewer", name="viewer", template=self.imageType, image=self.getImagePath() + ".image", transform=self.getImagePath() + ".transform", )
def write(self, filenamePrefix=None, directory=""): filename = self.getFilename(filenamePrefix,directory) volumeDim = len(self.sampler.volume)/ len(self.sampler.position) if isinstance(self.sampler.volume, list) is True else 1 # when volume is a list (several GPs or order> 1) data = {'type': self.type, 'volumeDim': str(volumeDim), 'inputVolume': SofaPython.Tools.listListToStr(self.sampler.volume), 'position': SofaPython.Tools.listListToStr(self.sampler.position), 'indices': self.mapping.indices, 'weights': self.mapping.weights, 'weightGradients': self.mapping.weightGradients, 'weightHessians': self.mapping.weightHessians} # @todo: add restShape ? with open(filename, 'w') as f: json.dump(data, f) if printLog: Sofa.msg_info("Flexible.API.Behavior",'Exported Gauss Points to '+filename)
def read(self, filenamePrefix=None, directory="", **kwargs): filename = self.getFilename(filenamePrefix,directory) data = dict() with open(filename,'r') as f: data.update(json.load(f)) self.sampler = self.node.createObject('GaussPointContainer',name='GPContainer', volumeDim=data['volumeDim'], inputVolume=data['inputVolume'], position=data['position'], **kwargs) if not self.labelImage is None and not self.labels is None: if self.labelImage.prefix == "Branching": celloffsets = self.node.createObject("BranchingCellOffsetsFromPositions", template=self.labelImage.template(), name="cell", position =self.sampler.getLinkPath()+".position", src=self.labelImage.getImagePath(), labels=concat(self.labels)) self.cell = celloffsets.getLinkPath()+".cell" if printLog: Sofa.msg_info("Flexible.API.Behavior",'Imported Gauss Points from '+filename)
def addVoronoi(self, image, position='', cells='', nbRef=8): """ Add a Voronoi shape function using path to position and possibly cells """ if position =='': Sofa.msg_error("Flexible.API.ShapeFunction","addVoronoi : no position") return self.prefix = image.prefix # branching or regular image ? self.shapeFunction = self.node.createObject( "VoronoiShapeFunction", template="ShapeFunction,"+image.template(), name="shapeFunction", cell=cells, position=position, src=image.getImagePath(), method=0, nbRef=nbRef, bias=True)
def write(self, filenamePrefix=None, directory=""): """ write weights of the linear mapping """ if self.mapping is None: return if self.mapping.getClassName().find("Linear") == -1: return filename = self.getFilename(filenamePrefix,directory) data = {'indices': self.mapping.indices, 'weights': self.mapping.weights} with open(filename, 'w') as f: json.dump(data, f) if printLog: Sofa.msg_info("Flexible.API.Deformable",'Exported Weights to '+filename)