def execute(self, context): """ Args: context: Returns: """ if self.complete: roots = set([sUtils.getRoot(obj) for obj in context.selected_objects]) - {None} objects = set() for root in roots: objects = objects | set(sUtils.getChildren(root)) objlist = list(objects) else: objlist = [bpy.context.active_object] for obj in objlist: try: entityname = sUtils.getRoot(obj)['entity/name'] except (KeyError, TypeError): entityname = '' log(nUtils.getObjectName(obj) + " is not part of a well-defined entity.", "WARNING") namespace = self.namespace if self.namespace else entityname nUtils.toggleNamespace(obj, namespace) return {'FINISHED'}
def deriveStoredPoses(): """ """ poses_dict = {} if len(bpy.data.actions) == 0: return {} pose_lib_name = bpy.data.actions.keys()[0] some_obj = bpy.context.scene.objects.active bpy.ops.object.mode_set(mode='OBJECT') for pose_name, i in zip(bpy.data.actions[pose_lib_name].pose_markers.keys(), range(len(bpy.data.actions[pose_lib_name].pose_markers.keys()))): selectionUtils.selectObjects([selectionUtils.getRoot(some_obj)], clear=True, active=0) pose_dict = {} bpy.ops.object.mode_set(mode='POSE') bpy.ops.poselib.apply_pose(pose_index=i) bpy.ops.object.mode_set(mode='OBJECT') for obj in bpy.context.scene.objects: if obj.phobostype == 'link': selectionUtils.selectObjects([obj], clear=True, active=0) bpy.ops.object.mode_set(mode='POSE') obj.pose.bones['Bone'].rotation_mode = 'XYZ' y_angle = obj.pose.bones['Bone'].rotation_euler.y bpy.ops.object.mode_set(mode='OBJECT') pose_dict[obj.name] = y_angle poses_dict[pose_name] = pose_dict return poses_dict
def execute(self, context): root = sUtils.getRoot(context.selected_objects[0]) objectlist = sUtils.getChildren(root, selected_only=True, include_hidden=False) sUtils.selectObjects(objectlist) poses = models.getPoses(root['modelname']) i = 1 for pose in poses: sUtils.selectObjects([root] + objectlist, clear=True, active=0) models.loadPose(root['modelname'], pose) parameter = self.decimate_ratio if self.decimate_type == 'UNSUBDIV': parameter = self.decimate_iteration elif self.decimate_type == 'DISSOLVE': parameter = self.decimate_angle_limit exporter.bakeModel(objectlist, root['modelname'], pose, decimate_type=self.decimate_type, decimate_parameter=parameter) display.setProgress(i / len(poses)) i += 1 sUtils.selectObjects([root] + objectlist, clear=True, active=0) bpy.ops.scene.reload_models_and_poses_operator() return {'FINISHED'}
def poll(self, context): """ Args: context: Returns: """ result = False modelsPosesColl = bUtils.getPhobosPreferences().models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose root = None # TODO delete me? # print("modelfile: ("+modelsPosesColl[bpy.data.images[activeModelPoseIndex].name].model_file+")") if context.scene.objects.active != None: root = sUtils.getRoot(context.scene.objects.active) try: if ( not root or not sUtils.isRoot(root) or bpy.data.images[activeModelPoseIndex].name in modelsPosesColl.keys() and modelsPosesColl[bpy.data.images[activeModelPoseIndex].name].model_file != '' and len(bpy.context.selected_objects) == 0 or modelsPosesColl[bpy.data.images[activeModelPoseIndex].name].robot_name != root["model/name"] ): result = True except KeyError: result = False return result
def execute(self, context): startLog(self) root = sUtils.getRoot(context.selected_objects[0]) model, objectlist = robotdictionary.buildModelDictionary(root) exporter.export(model, objectlist) endLog() return {'FINISHED'}
def execute(self, context): modelsPosesColl = bUtils.getPhobosPreferences().models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose if bpy.data.images[activeModelPoseIndex].name in modelsPosesColl.keys( ): activeModelPose = modelsPosesColl[ bpy.data.images[activeModelPoseIndex].name] if activeModelPose.type != "robot_name": # show on view_3d root = None if context.scene.objects.active != None: root = sUtils.getRoot(context.scene.objects.active) if not bpy.context.scene.preview_visible and \ (bpy.data.images[activeModelPoseIndex].type == 'IMAGE') and \ (root is None or not sUtils.isRoot(root) or not (modelsPosesColl[bpy.data.images[activeModelPoseIndex].name] != root["modelname"]) or len(bpy.context.selected_objects) == 0): bpy.ops.view3d.draw_preview_operator() bpy.context.scene.preview_visible = True else: activeModelPose.hide = not activeModelPose.hide if activeModelPose.hide: activeModelPose.icon = "RIGHTARROW" else: activeModelPose.icon = "DOWNARROW_HLT" for modelPose in modelsPosesColl: if (modelPose.type != "robot_name") and ( modelPose.parent == activeModelPose.name): modelPose.hide = activeModelPose.hide return {'FINISHED'}
def connectInterfaces(parentinterface, childinterface, transform=None): """ Args: parentinterface: childinterface: transform: (Default value = None) Returns: """ # first check if the interface is child of the root object and if not, restructure the tree root = sUtils.getRoot(childinterface) parent = childinterface.parent if root != parent: restructureKinematicTree(parent) childsubmodel = childinterface.parent # connect the interfaces sUtils.selectObjects(objects=[parentinterface], clear=True, active=0) bpy.ops.object.make_single_user(object=True, obdata=True) bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) sUtils.selectObjects(objects=[childinterface], clear=True, active=0) bpy.ops.object.make_single_user(object=True, obdata=True) bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) # parent interfaces bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') parentObjectsTo(childsubmodel, childinterface, clear=True) parentObjectsTo(childinterface, parentinterface) loc, rot, sca = parentinterface.matrix_world.decompose() # apply additional transform (ignoring the scale of the parent interface) if not transform: transform = (mathutils.Euler( (math.radians(180.0), 0.0, math.radians(180.0)), 'XYZ').to_matrix().to_4x4()) childinterface.matrix_world = (mathutils.Matrix.Translation(loc) @ rot.to_matrix().to_4x4() @ transform) # TODO clean this up # try: # del childsubmodel['modelname'] # except KeyError: # pass # TODO: re-implement this for MECHANICS models # try: # # parent visual and collision objects to new parent # children = sUtils.getImmediateChildren(parent, ['visual', 'collision', 'interface']) # print(children) # sUtils.selectObjects(children, True, 0) # bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') # print() # parentObjectsTo(children, sUtils.getEffectiveParent(parent, ignore_selection=True)) # bpy.ops.object.parent_set(type='BONE_RELATIVE') # except (IndexError, AttributeError): # pass # no objects to re-parent parentinterface.show_name = False childinterface.show_name = False
def execute(self, context): """ Args: context: Returns: """ root = sUtils.getRoot(context.selected_objects[0]) modelsPosesColl = bUtils.getPhobosPreferences().models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose selected_robot = modelsPosesColl[bpy.data.images[activeModelPoseIndex].name] objectlist = sUtils.getChildren(root, selected_only=True, include_hidden=False) sUtils.selectObjects([root] + objectlist, clear=True, active=0) models.loadPose(selected_robot.robot_name, selected_robot.label) parameter = self.decimate_ratio if self.decimate_type == 'UNSUBDIV': parameter = self.decimate_iteration elif self.decimate_type == 'DISSOLVE': parameter = self.decimate_angle_limit exporter.bakeModel( objectlist, root['model/name'], selected_robot.label, decimate_type=self.decimate_type, decimate_parameter=parameter, ) sUtils.selectObjects([root] + objectlist, clear=True, active=0) bpy.ops.scene.reload_models_and_poses_operator() return {'FINISHED'}
def execute(self, context): root = sUtils.getRoot(context.active_object) if root: root["modelname"] = self.modelname else: log("Could not set modelname due to missing root link. No name was set.", "ERROR") return {'FINISHED'}
def execute(self, context): """ Args: context: Returns: """ selection = [] if self.modelname: log("phobos: Selecting model" + self.modelname, "INFO") roots = sUtils.getRoots() for root in roots: if nUtils.getModelName(root) == self.modelname: selection = sUtils.getChildren(root) else: log("No model name provided, deriving from selection...", "INFO") roots = set() for obj in bpy.context.selected_objects: roots.add(sUtils.getRoot(obj)) for root in list(roots): selection.extend(sUtils.getChildren(root)) sUtils.selectObjects(list(selection), True) return {'FINISHED'}
def execute(self, context): """ Args: context: Returns: """ root = sUtils.getRoot(context.selected_objects[0]) objectlist = sUtils.getChildren(root, selected_only=True, include_hidden=False) sUtils.selectObjects(objectlist) poses = models.getPoses(root['model/name']) i = 1 for pose in poses: sUtils.selectObjects([root] + objectlist, clear=True, active=0) models.loadPose(root['model/name'], pose) parameter = self.decimate_ratio if self.decimate_type == 'UNSUBDIV': parameter = self.decimate_iteration elif self.decimate_type == 'DISSOLVE': parameter = self.decimate_angle_limit exporter.bakeModel( objectlist, root['model/name'], pose, decimate_type=self.decimate_type, decimate_parameter=parameter, ) display.setProgress(i / len(poses)) i += 1 sUtils.selectObjects([root] + objectlist, clear=True, active=0) bpy.ops.scene.reload_models_and_poses_operator() return {'FINISHED'}
def addNamespace(obj): """This function namespaces a given blender object. :param obj: The object to namespace. :type obj: bpy.types.Object """ types = defs.subtypes name = obj.name root = selection.getRoot(obj) namespace = root[ "entity/name"] if root != None and "entity/name" in root else None if not namespace: log( "The obj " + getObjectName(obj) + "has no namespace to append to. Aborting.", "ERROR") return obj.name = namespace + "::" + name for ptype in types: typetag = ptype + "/type" nametag = ptype + "/name" if (typetag in obj or ("phobostype" in obj and obj.phobostype == ptype)) and nametag not in obj: obj[nametag] = name
def poll(self, context): """ Args: context: Returns: """ result = False modelsPosesColl = bUtils.getPhobosPreferences().models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose root = None # TODO delete me? # print("modelfile: ("+modelsPosesColl[bpy.data.images[activeModelPoseIndex].name].model_file+")") if context.view_layer.objects.active != None: root = sUtils.getRoot(context.view_layer.objects.active) try: if (not root or not sUtils.isRoot(root) or bpy.data.images[activeModelPoseIndex].name in modelsPosesColl.keys() and modelsPosesColl[bpy.data.images[activeModelPoseIndex]. name].model_file != '' and len(bpy.context.selected_objects) == 0 or modelsPosesColl[bpy.data.images[activeModelPoseIndex]. name].robot_name != root["model/name"]): result = True except KeyError: result = False return result
def execute(self, context): startLog(self) objlist = context.selected_objects if self.complete: roots = list( set([sUtils.getRoot(obj) for obj in context.selected_objects])) if None in roots: roots.remove(None) objlist = [ elem for sublist in [sUtils.getChildren(root) for root in roots] for elem in sublist ] objnames = [o.name for o in bpy.data.objects] for obj in objlist: if "::" in obj.name: if nUtils.namesAreExplicit({obj.name.split("::")[-1]}, objnames): nUtils.removeNamespace(obj) else: log( "Cannot remove namespace from " + obj.name + ". Name wouldn't be explicit", "ERROR") else: nUtils.addNamespace(obj) endLog() return {'FINISHED'}
def execute(self, context): """ Args: context: Returns: """ roots = set() # add root object of each selected object for obj in context.selected_objects: roots.add(sUtils.getRoot(obj)) # select all found root objects if roots: # toggle layer to make objects visible for root in roots: bUtils.setObjectLayersActive(root, extendlayers=True) # select objects sUtils.selectObjects(list(roots), True) context.scene.objects.active = list(roots)[0] else: log("Couldn't find any root object.", 'ERROR') return {'FINISHED'}
def execute(self, context): root = sUtils.getRoot(context.selected_objects[0]) modelsPosesColl = bpy.context.user_preferences.addons[ 'phobos'].preferences.models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose selected_robot = modelsPosesColl[ bpy.data.images[activeModelPoseIndex].name] objectlist = sUtils.getChildren(root, selected_only=True, include_hidden=False) sUtils.selectObjects([root] + objectlist, clear=True, active=0) models.loadPose(selected_robot.robot_name, selected_robot.label) parameter = self.decimate_ratio if self.decimate_type == 'UNSUBDIV': parameter = self.decimate_iteration elif self.decimate_type == 'DISSOLVE': parameter = self.decimate_angle_limit exporter.bakeModel(objectlist, root['modelname'], selected_robot.label, decimate_type=self.decimate_type, decimate_parameter=parameter) sUtils.selectObjects([root] + objectlist, clear=True, active=0) bpy.ops.scene.reload_models_and_poses_operator() return {'FINISHED'}
def execute(self, context): modelsPosesColl = bUtils.getPhobosPreferences().models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose modelPose = modelsPosesColl[bpy.data.images[activeModelPoseIndex].name] root = sUtils.getRoot(context.scene.objects.active) bpy.context.scene.objects.active = root robot.loadPose(modelPose.robot_name, modelPose.label) return {'FINISHED'}
def execute(self, context): selection = [] if self.modelname: print("phobos: Selecting model", self.modelname) roots = sUtils.getRoots() for root in roots: if root["modelname"] == self.modelname: selection = sUtils.getChildren(root) else: print("phobos: No model name provided, deriving from selection...") roots = set() for obj in bpy.context.selected_objects: print("Selecting", sUtils.getRoot(obj).name) roots.add(sUtils.getRoot(obj)) for root in list(roots): selection.extend(sUtils.getChildren(root)) sUtils.selectObjects(list(selection), True) return {'FINISHED'}
def execute(self, context): startLog(self) root = selectionUtils.getRoot(bpy.context.active_object) if root == None: log("Could not set modelname due to missing root link. No name was set.", "ERROR") return {'FINISHED'} root["modelname"] = self.modelname endLog() return {'FINISHED'}
def execute(self, context): selection = [] if self.modelname: print("phobos: Selecting model", self.modelname) roots = selectionUtils.getRoots() for root in roots: if root["modelname"] == self.modelname: selection = selectionUtils.getChildren(root) else: print("phobos: No model name provided, deriving from selection...") roots = set() for obj in bpy.context.selected_objects: print("Selecting", selectionUtils.getRoot(obj).name) roots.add(selectionUtils.getRoot(obj)) for root in list(roots): selection.extend(selectionUtils.getChildren(root)) selectionUtils.selectObjects(list(selection), True) return {'FINISHED'}
def execute(self, context): startLog(self) root = sUtils.getRoot(context.selected_objects[0]) if root.phobostype != 'link': log("Selection includes objects not parented to any model root, please adapt selection.", "ERROR", "ExportModelOperator") else: model, objectlist = robotdictionary.buildModelDictionary(root) exporter.export(model, objectlist) endLog() return {'FINISHED'}
def execute(self, context): startLog(self) root = selectionUtils.getRoot(bpy.context.active_object) if root == None: log( "Could not set modelname due to missing root link. No name was set.", "ERROR") return {'FINISHED'} root["modelname"] = self.modelname endLog() return {'FINISHED'}
def execute(self, context): roots = set() for obj in bpy.context.selected_objects: roots.add(sUtils.getRoot(obj)) if len(roots) > 0: sUtils.selectObjects(list(roots), True) bpy.context.scene.objects.active = list(roots)[0] else: # bpy.ops.error.message('INVOKE_DEFAULT', type="ERROR", message="Couldn't find any root object.") log("Couldn't find any root object.", "ERROR") return {'FINISHED'}
def poll(cls, context): """Hide operator if there is no link present. Args: context: Returns: """ root = sUtils.getRoot(context.active_object) return root and root.phobostype == 'link'
def execute(self, context): startLog(self) root = sUtils.getRoot(context.selected_objects[0]) if root.phobostype != 'link': log( "Selection includes objects not parented to any model root, please adapt selection.", "ERROR", "ExportModelOperator") else: model, objectlist = robotdictionary.buildModelDictionary(root) exporter.export(model, objectlist) endLog() return {'FINISHED'}
def createSensor(sensor, reference, origin=mathutils.Matrix()): blenderUtils.toggleLayer(defs.layerTypes['sensor'], value=True) # create sensor object if 'Camera' in sensor['type']: bpy.context.scene.layers[defs.layerTypes['sensor']] = True bpy.ops.object.add(type='CAMERA', location=origin.to_translation(), rotation=origin.to_euler(), layers=blenderUtils.defLayers([defs.layerTypes['sensor']])) newsensor = bpy.context.active_object if reference is not None: selectionUtils.selectObjects([newsensor, bpy.data.objects[reference]], clear=True, active=1) bpy.ops.object.parent_set(type='BONE_RELATIVE') elif sensor['type'] in ['RaySensor', 'RotatingRaySensor', 'ScanningSonar', 'MultiLevelLaserRangeFinder']: # TODO: create a proper ray sensor scanning layer disc here newsensor = blenderUtils.createPrimitive(sensor['name'], 'disc', (0.5, 36), defs.layerTypes['sensor'], 'phobos_laserscanner', origin.to_translation(), protation=origin.to_euler()) if reference is not None and reference != []: if type(reference) == str: key = reference else: key = reference[0] selectionUtils.selectObjects([newsensor, bpy.data.objects[key]], clear=True, active=1) bpy.ops.object.parent_set(type='BONE_RELATIVE') else: # contact, force and torque sensors (or unknown sensors) newsensor = blenderUtils.createPrimitive(sensor['name'], 'sphere', 0.05, defs.layerTypes['sensor'], 'phobos_sensor', origin.to_translation(), protation=origin.to_euler()) if 'Node' in sensor['type']: newsensor['sensor/nodes'] = sorted(reference) elif 'Joint' in sensor['type'] or 'Motor' in sensor['type']: newsensor['sensor/joints'] = sorted(reference) if reference is not None and reference != []: selectionUtils.selectObjects([newsensor, selectionUtils.getRoot(bpy.data.objects[0])], clear=True, active=1) bpy.ops.object.parent_set(type='BONE_RELATIVE') # set sensor properties newsensor.phobostype = 'sensor' newsensor.name = sensor['name'] newsensor['sensor/type'] = sensor['type'] for prop in sensor['props']: newsensor['sensor/'+prop] = sensor['props'][prop] # add custom properties #for prop in sensor: # if prop.startswith('$'): # for tag in sensor[prop]: # newsensor[prop[1:]+'/'+tag] = sensor[prop][tag] # throw warning if type is not known if sensor['type'] not in defs.sensortypes: print("### Warning: sensor", sensor['name'], "is of unknown/custom type.") selectionUtils.selectObjects([newsensor], clear=False, active=0) return newsensor
def execute(self, context): root = sUtils.getRoot(context.active_object) if root: if self.usegitbranch: gitbranch = iUtils.getgitbranch() if gitbranch: root["version"] = self.version.replace('*', gitbranch) else: root["version"] = self.version else: log("Could not set version due to missing root link. No version was set.", "ERROR") return {'FINISHED'}
def execute(self, context): startLog(self) roots = set() for obj in bpy.context.selected_objects: roots.add(selectionUtils.getRoot(obj)) if len(roots) > 0: selectionUtils.selectObjects(list(roots), True) bpy.context.scene.objects.active = list(roots)[0] else: # bpy.ops.error.message('INVOKE_DEFAULT', type="ERROR", message="Couldn't find any root object.") log("Couldn't find any root object.", "ERROR") endLog() return {'FINISHED'}
def execute(self, context): startLog(self) messages = {} root = sUtils.getRoot(context.selected_objects[0]) model, objectlist = robotdictionary.buildModelDictionary(root) validator.check_dict(model, defs.dictConstraints, messages) defs.checkMessages = messages if len(list(messages.keys())) > 0 else {"NoObject": []} for entry in messages: log("Errors in object " + entry + ":", 'INFO') for error in messages[entry]: log(error, 'INFO') endLog() return {'FINISHED'}
def execute(self, context): messages = {} root = sUtils.getRoot(context.selected_objects[0]) model, objectlist = models.buildModelDictionary(root) vUtils.check_dict(model, defs.definitions['model'], messages) vUtils.checkMessages = messages if len(list( messages.keys())) > 0 else { "NoObject": [] } for entry in messages: log("Errors in object " + entry + ":", 'INFO') for error in messages[entry]: log(error, 'INFO') return {'FINISHED'}
def addNamespace(obj): types = defs.subtypes name = obj.name root = selection.getRoot(obj) namespace = root["modelname"] if root != None and "modelname" in root else None if not namespace: log("The obj " + getObjectName(obj) + "has no namespace to append to. Aborting.", "ERROR") return obj.name = namespace + "::" + name for pType in types: typeTag = pType + "/type" nameTag = pType + "/name" if (typeTag in obj or ("phobostype" in obj and obj.phobostype == pType)) and nameTag not in obj: obj[nameTag] = name
def execute(self, context): roots = set() # add root object of each selected object for obj in bpy.context.selected_objects: roots.add(sUtils.getRoot(obj)) # select all found root objects if len(roots) > 0: sUtils.selectObjects(list(roots), True) bpy.context.scene.objects.active = list(roots)[0] else: log("Couldn't find any root object.", "ERROR") return {'FINISHED'}
def execute(self, context): startLog(self) objs = context.selected_objects root = sUtils.getRoot(context.selected_objects[0]) model = robotdictionary.buildModelDictionary(root) sUtils.selectObjects(objs) if bpy.data.worlds[0].relativePath: outpath = exporter.securepath(os.path.expanduser(os.path.join(bpy.path.abspath("//"), bpy.data.worlds[0].path))) else: outpath = exporter.securepath(os.path.expanduser(bpy.data.worlds[0].path)) exporter.bakeModel(objs, outpath, model["modelname"]) with open(os.path.join(outpath, "info.bake"), "w") as f: f.write(yaml.dump({"name": model["modelname"]})) endLog() return {'FINISHED'}
def draw(self, context): import phobos.utils.selection as sUtils layout = self.layout obj = context.active_object modelname = '' rootname = '' root = sUtils.getRoot(obj) if 'modelname' in root: modelname = root['modelname'] rootname = root.name row = layout.row() descr = row.column() content = row.column() descr.label(text='Part of model', icon='POSE_DATA') content.operator('phobos.name_model', text=modelname, icon='OUTLINER_DATA_FONT') descr.label(text='Root object', icon='OOPS') if obj == root: content.label("selected", icon='MATCUBE') else: content.operator('phobos.select_root', text=rootname, icon='FILE_PARENT') # add parent object if available if obj.parent: descr.label('Parent object', icon='CONSTRAINT') goto_op = content.operator('phobos.goto_object', icon='FILE_PARENT', text='{0}'.format(obj.parent.name)) goto_op.objectname = obj.parent.name layout.separator() row = layout.row() row.label(icon="OBJECT_DATA", text="Phobostype") row.prop(context.active_object, 'phobostype', text="") # show object name as button row = layout.row() row.label(icon='COPY_ID', text="Object name") row.operator('phobos.change_object_name', icon='OUTLINER_DATA_FONT', text=nUtils.getObjectName(obj))
def execute(self, context): """ Args: context: Returns: """ modelsPosesColl = bUtils.getPhobosPreferences().models_poses activeModelPoseIndex = bpy.context.scene.active_ModelPose if bpy.data.images[activeModelPoseIndex].name in modelsPosesColl.keys(): activeModelPose = modelsPosesColl[bpy.data.images[activeModelPoseIndex].name] if activeModelPose.type != "robot_name": # show on view_3d root = None if context.scene.objects.active != None: root = sUtils.getRoot(context.scene.objects.active) if ( not bpy.context.scene.preview_visible and (bpy.data.images[activeModelPoseIndex].type == 'IMAGE') and ( root is None or not sUtils.isRoot(root) or not ( modelsPosesColl[bpy.data.images[activeModelPoseIndex].name] != root["model/name"] ) or len(bpy.context.selected_objects) == 0 ) ): bpy.ops.view3d.draw_preview_operator() bpy.context.scene.preview_visible = True else: activeModelPose.hide = not activeModelPose.hide if activeModelPose.hide: activeModelPose.icon = "RIGHTARROW" else: activeModelPose.icon = "DOWNARROW_HLT" for modelPose in modelsPosesColl: if (modelPose.type != "robot_name") and ( modelPose.parent == activeModelPose.name ): modelPose.hide = activeModelPose.hide return {'FINISHED'}
def execute(self, context): """ Args: context: Returns: """ root = sUtils.getRoot(context.active_object) if self.usegitbranch: gitbranch = ioUtils.getgitbranch() if gitbranch: root["model/version"] = self.version.replace('*', gitbranch) else: root["model/version"] = self.version return {'FINISHED'}
def execute(self, context): """ Args: context: Returns: """ root = sUtils.getRoot(context.active_object) if root: root["model/name"] = self.modelname # write model information to new root root.pose.bones[0].custom_shape = ioUtils.getResource(('link', 'root')) else: log("Could not set modelname due to missing root link. No name was set.", "ERROR") return {'FINISHED'}
def execute(self, context): startLog(self) objs = context.selected_objects root = sUtils.getRoot(context.selected_objects[0]) model = robotdictionary.buildModelDictionary(root) sUtils.selectObjects(objs) if bpy.data.worlds[0].relativePath: outpath = exporter.securepath( os.path.expanduser( os.path.join(bpy.path.abspath("//"), bpy.data.worlds[0].path))) else: outpath = exporter.securepath( os.path.expanduser(bpy.data.worlds[0].path)) exporter.bakeModel(objs, outpath, model["modelname"]) with open(os.path.join(outpath, "info.bake"), "w") as f: f.write(yaml.dump({"name": model["modelname"]})) endLog() return {'FINISHED'}
def execute(self, context): startLog(self) objlist = context.selected_objects if self.complete: roots = list(set([selectionUtils.getRoot(obj) for obj in context.selected_objects])) if None in roots: roots.remove(None) objlist = [elem for sublist in [selectionUtils.getChildren(root) for root in roots] for elem in sublist] objnames = [o.name for o in bpy.data.objects] for obj in objlist: if "::" in obj.name: if namingUtils.namesAreExplicit({obj.name.split("::")[-1]}, objnames): namingUtils.removeNamespace(obj) else: log("Cannot remove namespace from " + obj.name + ". Name wouldn't be explicit", "ERROR") else: namingUtils.addNamespace(obj) endLog() return {'FINISHED'}
def addNamespace(obj): """This function namespaces a given blender object. :param obj: The object to namespace. :type obj: bpy.types.Object """ types = defs.subtypes name = obj.name root = selection.getRoot(obj) namespace = root["entityname"] if root != None and "entityname" in root else None if not namespace: log("The obj " + getObjectName(obj) + "has no namespace to append to. Aborting.", "ERROR") return obj.name = namespace + "::" + name for pType in types: typeTag = pType + "/type" nameTag = pType + "/name" if (typeTag in obj or ("phobostype" in obj and obj.phobostype == pType)) and nameTag not in obj: obj[nameTag] = name
def draw(self, context): import phobos.utils.selection as sUtils layout = self.layout obj = context.active_object modelname = '' rootname = '' root = sUtils.getRoot(obj) if 'modelname' in root.keys(): modelname = root['modelname'] rootname = root.name datatop = layout.split() datatopl = datatop.column(align=True) datatopr = datatop.column(align=True) # dataright = layout.column(align=True) datatopl.operator('phobos.name_model', text=('Part of model: ' + modelname), icon='POSE_DATA') datatopr.operator('phobos.select_root', text=('Root object: ' + rootname), icon='OOPS')
def addNamespace(obj): """This function namespaces a given blender object. :param obj: The object to namespace. :type obj: bpy.types.Object """ types = defs.subtypes name = obj.name root = selection.getRoot(obj) try: namespace = root["entity/name"] obj.name = namespace + "::" + name for ptype in types: typetag = ptype + "/type" nametag = ptype + "/name" if (typetag in obj or ("phobostype" in obj and obj.phobostype == ptype)) and nametag not in obj: obj[nametag] = name except (TypeError, KeyError): log( getObjectName(obj) + " is not part of a well-defined entity.", "ERROR", "utils/naming/addNamespace")
def buildRobotDictionary(): """Builds a python dictionary representation of a Blender robot model for export and inspection.""" objectlist = bpy.context.selected_objects #notifications, faulty_objects = robotupdate.updateModel(bpy.context.selected_objects) #print(notifications) robot = {'links': {}, 'joints': {}, 'sensors': {}, 'motors': {}, 'controllers': {}, 'materials': {}, 'groups': {}, 'chains': {}, 'lights': {} } #save timestamped version of model robot["date"] = datetime.now().strftime("%Y%m%d_%H:%M") root = selectionUtils.getRoot(bpy.context.selected_objects[0]) if root.phobostype != 'link': raise Exception("Found no 'link' object as root of the robot model.") else: if 'modelname' in root: robot['modelname'] = root["modelname"] else: robot['modelname'] = 'unnamed_robot' # digest all the links to derive link and joint information print('\nParsing links, joints and motors...') for obj in bpy.context.selected_objects: if obj.phobostype == 'link': link, joint, motor = deriveKinematics(obj) robot['links'][namingUtils.getObjectName(obj, phobostype="link")] = link # it's important that this is really the object's name if joint: # joint can be None if link is a root robot['joints'][joint['name']] = joint if motor: robot['motors'][joint['name']] = motor obj.select = False # add inertial information to link print('\n\nParsing inertials...') for l in robot['links']: #link = bpy.data.objects[l] NEW NAMING! link = selectionUtils.getObjectByName(l)[0] if selectionUtils.getObjectByName(l) is not None else "ERROR!" inertials = selectionUtils.getImmediateChildren(link, ['inertial']) if len(inertials) == 1: props, parent = deriveDictEntry(inertials[0]) if not (props is None or parent is None): # this may be the case if there is inertia information missing robot['links'][namingUtils.getObjectName(parent)]['inertial'] = props inertials[0].select = False elif len(inertials) > 1: for i in inertials: if namingUtils.getObjectName(i, phobostype="inertial") == 'inertial_' + l: props, parent = deriveDictEntry(i) robot['links'][namingUtils.getObjectName(parent, phobostype="link")]['inertial'] = props # FIXME: this has to be re-implemented #if linkinertial == None: # mass, com, inertia = inertia.fuseInertiaData(inertials) # parent = inertials[0].parent # matrix_local = mathutils.Matrix.Translation(mathutils.Vector(com)) # pose = {} # pose['matrix'] = [list(vector) for vector in list(matrix_local)] # pose['translation'] = list(matrix_local.to_translation()) # pose['rotation_euler'] = list(matrix_local.to_euler()) # pose['rotation_quaternion'] = list(matrix_local.to_quaternion()) # props = {'mass': mass, 'pose': pose, 'inertia': inertia} # robot['links'][parent.name]['inertial'] = props for i in inertials: i.select = False # complete link information by parsing visuals and collision objects print('\n\nParsing visual and collision (approximation) objects...') for obj in bpy.context.selected_objects: print("Parsing object " + namingUtils.getObjectName(obj)) if obj.phobostype in ['visual', 'collision']: props, parent = deriveDictEntry(obj) robot['links'][namingUtils.getObjectName(parent, phobostype="link")][obj.phobostype][namingUtils.getObjectName(obj, phobostype=obj.phobostype)] = props obj.select = False elif obj.phobostype == 'approxsphere': props, parent = deriveDictEntry(obj) robot['links'][namingUtils.getObjectName(parent)]['approxcollision'].append(props) obj.select = False # combine collision information for links for linkname in robot['links']: link = robot['links'][linkname] bitmask = 0 for collname in link['collision']: try: bitmask = bitmask | link['collision'][collname]['bitmask'] except KeyError: pass link['collision_bitmask'] = bitmask # parse sensors and controllers print('\n\nParsing sensors and controllers...') for obj in bpy.context.selected_objects: if obj.phobostype in ['sensor', 'controller']: robot[obj.phobostype+'s'][namingUtils.getObjectName(obj)] = deriveDictEntry(obj) obj.select = False # parse materials print('\n\nParsing materials...') robot['materials'] = collectMaterials(objectlist) for obj in objectlist: if obj.phobostype == 'visual' and len(obj.data.materials) > 0: mat = obj.data.materials[0] if not namingUtils.getObjectName(mat) in robot['materials']: robot['materials'][namingUtils.getObjectName(mat)] = deriveMaterial(mat) #this should actually never happen robot['links'][namingUtils.getObjectName(obj.parent)]['visual'][namingUtils.getObjectName(obj, phobostype="visual")]['material'] = namingUtils.getObjectName(mat) # gather information on groups of objects print('\n\nParsing groups...') for group in bpy.data.groups: # TODO: get rid of the "data" part if len(group.objects) > 0 and namingUtils.getObjectName(group) != "RigidBodyWorld": robot['groups'][namingUtils.getObjectName(group)] = deriveGroupEntry(group) # gather information on chains of objects print('\n\nParsing chains...') chains = [] for obj in bpy.data.objects: if obj.phobostype == 'link' and 'endChain' in obj: chains.extend(deriveChainEntry(obj)) for chain in chains: robot['chains'][chain['name']] = chain # gather information on global lights print('\n\nParsing lights...') for obj in bpy.context.selected_objects: if obj.phobostype == 'light': robot['lights'][namingUtils.getObjectName(obj)] = deriveLight(obj) robot['poses'] = deriveStoredPoses() #shorten numbers in dictionary to n decimalPlaces and return it print('\n\nRounding numbers...') epsilon = 10**(-bpy.data.worlds[0].decimalPlaces) # TODO: implement this separately return generalUtils.epsilonToZero(robot, epsilon, bpy.data.worlds[0].decimalPlaces)
def restructureKinematicTree(link, root=None): """Restructures a tree such that the ``link`` provided becomes the root of the tree. If no root object is provided, :func:`phobos.utils.selection.getRoot` will be used. For instance, the following tree:: A / \\ B C / \ \\ D E F would, using the call restructureKinematicsTree(C), become:: C / \\ A F / B / \\ D E Currently, this function ignores all options such as unselected or hidden objects. Args: link(bpy.types.Object): the link which will become the new root object root(bpy.types.Object, optional): the current root object (Default value = None) Returns: None: None """ if not root: root = sUtils.getRoot(link) links = [link] obj = link # stop right now when the link is already root if not obj.parent: log('No restructure necessary. Link is already root.', 'INFO') return # gather chain of links ascending the tree while obj.parent.name != root.name: obj = obj.parent if obj.phobostype == 'link': links.append(obj) links.append(root) log("Unparenting objects for restructure: " + str([link.name for link in links]) + ".", 'DEBUG') # unparent all links sUtils.selectObjects(links, True) bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') log("Restructuring objects for new hierarchy.", 'DEBUG') for i in range(len(links) - 1): parent = links[i] child = links[i + 1] parentObjectsTo(child, parent) log("Copying model information from old root.", 'DEBUG') # copy properties if 'model/name' in root: link['model/name'] = root['model/name'] del root['model/name'] if 'model/version' in root: link['model/version'] = root['model/version'] del root['model/version'] log("Restructured kinematic tree to new root: {}.".format(link.name), 'INFO')
def connectInterfaces(parentinterface, childinterface, transform=None): """ Args: parentinterface: childinterface: transform: (Default value = None) Returns: """ # first check if the interface is child of the root object and if not, restructure the tree root = sUtils.getRoot(childinterface) parent = childinterface.parent if root != parent: restructureKinematicTree(parent) childsubmodel = childinterface.parent # connect the interfaces sUtils.selectObjects(objects=[parentinterface], clear=True, active=0) bpy.ops.object.make_single_user(object=True, obdata=True) bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) sUtils.selectObjects(objects=[childinterface], clear=True, active=0) bpy.ops.object.make_single_user(object=True, obdata=True) bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) # parent interfaces bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') parentObjectsTo(childsubmodel, childinterface, clear=True) parentObjectsTo(childinterface, parentinterface) loc, rot, sca = parentinterface.matrix_world.decompose() # apply additional transform (ignoring the scale of the parent interface) if not transform: transform = ( mathutils.Euler((math.radians(180.0), 0.0, math.radians(180.0)), 'XYZ') .to_matrix() .to_4x4() ) childinterface.matrix_world = ( mathutils.Matrix.Translation(loc) * rot.to_matrix().to_4x4() * transform ) # TODO clean this up # try: # del childsubmodel['modelname'] # except KeyError: # pass # TODO: re-implement this for MECHANICS models # try: # # parent visual and collision objects to new parent # children = sUtils.getImmediateChildren(parent, ['visual', 'collision', 'interface']) # print(children) # sUtils.selectObjects(children, True, 0) # bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') # print() # parentObjectsTo(children, sUtils.getEffectiveParent(parent, ignore_selection=True)) # bpy.ops.object.parent_set(type='BONE_RELATIVE') # except (IndexError, AttributeError): # pass # no objects to re-parent parentinterface.show_name = False childinterface.show_name = False
def buildModelFromDictionary(model): """Creates the Blender representation of the imported model, using a model dictionary. """ # DOCU add some more docstring log("Creating Blender model...", 'INFO') log("Creating links...", 'INFO') for l in model['links']: link = model['links'][l] linkmodel.createLink(link) log("Creating joints...", 'INFO') for j in model['joints']: joint = model['joints'][j] jointmodel.createJoint(joint) # build tree recursively and correct translation & rotation on the fly log("Placing links...", 'INFO') for l in model['links']: if 'parent' not in model['links'][l]: root = model['links'][l] linkmodel.placeChildLinks(model, root) log("Assigning model name...", 'INFO') try: rootlink = sUtils.getRoot(bpy.data.objects[root['name']]) rootlink['modelname'] = model['name'] rootlink.location = (0, 0, 0) except KeyError: log("Could not assign model name to root link.", "ERROR") log("Placing visual and collision objects...", 'INFO') for link in model['links']: linkmodel.placeLinkSubelements(model['links'][link]) try: log("Creating sensors...", 'INFO') for s in model['sensors']: sensormodel.createSensor(model['sensors'][s]) except KeyError: log("No sensors in model " + model['name'], 'INFO') try: log("Creating motors...", 'INFO') for m in model['motors']: eUtils.addDictionaryToObj( model['motors'][m], model['joints'][model['motors'][m]['joint']], category='motor') except KeyError: log("No motors in model " + model['name'], 'INFO') try: log("Creating controllers...", 'INFO') for c in model['controllers']: controllermodel.createController(model['controllers'][c]) except KeyError: log("No controllers in model " + model['name'], 'INFO') try: log("Creating groups...", 'INFO') for g in model['groups']: createGroup(model['groups'][g]) except KeyError: log("No kinematic groups in model " + model['name'], 'INFO') try: log("Creating chains...", 'INFO') for ch in model['chains']: createChain(model['chains'][ch]) except KeyError: log("No kinematic chains in model " + model['name'], 'INFO') try: log("Creating lights...", 'INFO') for l in model['lights']: lightmodel.createLight(model['lights'][l]) except KeyError: log("No lights in model " + model['name'], 'INFO') # FIXME: this is a trick to force Blender to apply matrix_local # AAAAAARGH: THIS DOES NOT WORK! for obj in bpy.data.objects: bUtils.setObjectLayersActive(obj) bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.select_all(action='SELECT') bpy.ops.transform.translate(value=(0, 0, 0))
def restructureKinematicTree(link, root=None): """Restructures a tree such that the ``link`` provided becomes the root of the tree. If no root object is provided, :func:`phobos.utils.selection.getRoot` will be used. For instance, the following tree:: A / \\ B C / \ \\ D E F would, using the call restructureKinematicsTree(C), become:: C / \\ A F / B / \\ D E Currently, this function ignores all options such as unselected or hidden objects. Args: link(bpy.types.Object): the link which will become the new root object root(bpy.types.Object, optional): the current root object (Default value = None) Returns: None: None """ if not root: root = sUtils.getRoot(link) links = [link] obj = link # stop right now when the link is already root if not obj.parent: log('No restructure necessary. Link is already root.', 'INFO') return # gather chain of links ascending the tree while obj.parent.name != root.name: obj = obj.parent if obj.phobostype == 'link': links.append(obj) links.append(root) log( "Unparenting objects for restructure: " + str([link.name for link in links]) + ".", 'DEBUG') # unparent all links sUtils.selectObjects(links, True) bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') log("Restructuring objects for new hierarchy.", 'DEBUG') for i in range(len(links) - 1): parent = links[i] child = links[i + 1] parentObjectsTo(child, parent) log("Copying model information from old root.", 'DEBUG') # copy properties if 'model/name' in root: link['model/name'] = root['model/name'] del root['model/name'] if 'model/version' in root: link['model/version'] = root['model/version'] del root['model/version'] log("Restructured kinematic tree to new root: {}.".format(link.name), 'INFO')
def buildModelFromDictionary(model): """Creates the Blender representation of the imported model, using a model dictionary. Args: model: Returns: """ # DOCU add some more docstring log("Creating Blender model...", 'INFO') log("Creating links...", 'INFO') for l in model['links']: link = model['links'][l] model['links'][l]['object'] = linkmodel.createLink(link) log("Setting parent-child relationships", 'INFO') bUtils.toggleLayer(defs.layerTypes['link'], True) for l in model['links']: parent = model['links'][l] for c in parent['children']: child = model['links'][c] child['object'].matrix_world = parent['object'].matrix_world sUtils.selectObjects([child['object'], parent['object']], True, 1) bpy.ops.object.parent_set(type='BONE_RELATIVE') log("Creating joints...", 'INFO') for j in model['joints']: joint = model['joints'][j] jointmodel.createJoint(joint) log('...finished.', 'INFO') # set transformations log("Placing links...", 'INFO') for l in model['links']: if 'parent' not in model['links'][l]: root = model['links'][l] break linkmodel.placeChildLinks(model, root) log("Assigning model name...", 'INFO') try: rootlink = sUtils.getRoot(bpy.data.objects[root['name']]) rootlink['modelname'] = model['name'] rootlink.location = (0, 0, 0) except (KeyError, NameError): log("Could not assign model name to root link.", "ERROR") try: log("Creating sensors...", 'INFO') for s in model['sensors']: sensormodel.createSensor(model['sensors'][s]) except KeyError: log("No sensors in model " + model['name'], 'INFO') try: log("Creating motors...", 'INFO') for m in model['motors']: eUtils.addDictionaryToObj( model['motors'][m], model['joints'][model['motors'][m]['joint']], category='motor') except KeyError: log("No motors in model " + model['name'], 'INFO') try: log("Creating controllers...", 'INFO') for c in model['controllers']: controllermodel.createController(model['controllers'][c]) except KeyError: log("No controllers in model " + model['name'], 'INFO') try: log("Creating groups...", 'INFO') for g in model['groups']: createGroup(model['groups'][g]) except KeyError: log("No kinematic groups in model " + model['name'], 'INFO') try: log("Creating chains...", 'INFO') for ch in model['chains']: createChain(model['chains'][ch]) except KeyError: log("No kinematic chains in model " + model['name'], 'INFO') try: log("Creating lights...", 'INFO') for l in model['lights']: lightmodel.createLight(model['lights'][l]) except KeyError: log("No lights in model " + model['name'], 'INFO') # display all objects after import for obj in bpy.data.objects: bUtils.setObjectLayersActive(obj) bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.select_all(action='SELECT') bpy.ops.view3d.view_selected() # update transformations bUtils.update()