Exemple #1
0
    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'}
Exemple #2
0
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
Exemple #3
0
 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'}
Exemple #4
0
    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
Exemple #5
0
 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'}
Exemple #6
0
    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'}
Exemple #7
0
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
Exemple #8
0
    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'}
Exemple #9
0
 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'}
Exemple #10
0
    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'}
Exemple #11
0
    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'}
Exemple #12
0
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
Exemple #13
0
    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
Exemple #14
0
 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'}
Exemple #15
0
    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'}
Exemple #16
0
    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'}
Exemple #17
0
 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'}
Exemple #18
0
 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'}
Exemple #19
0
 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'}
Exemple #20
0
 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'}
Exemple #21
0
 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'}
Exemple #22
0
 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'}
Exemple #23
0
 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'}
Exemple #24
0
    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'
Exemple #25
0
 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'}
Exemple #26
0
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
Exemple #27
0
 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'}
Exemple #28
0
 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'}
Exemple #29
0
    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'}
Exemple #30
0
 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'}
Exemple #31
0
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
Exemple #32
0
    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'}
Exemple #33
0
 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'}
Exemple #34
0
    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))
Exemple #35
0
    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'}
Exemple #36
0
    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'}
Exemple #37
0
    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'}
Exemple #38
0
 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'}
Exemple #39
0
 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'}
Exemple #40
0
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
Exemple #41
0
    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')
Exemple #42
0
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")
Exemple #43
0
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)
Exemple #44
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')
Exemple #45
0
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
Exemple #46
0
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))
Exemple #47
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')
Exemple #48
0
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()