Beispiel #1
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'}
Beispiel #2
0
def importBlenderModel(filepath, namespace='', prefix=False):
    """Imports an existing Blender model into the current .blend scene

    Args:
      filepath(str): Path of the .blend file
      namespace: (Default value = '')
      prefix: (Default value = False)

    Returns:

    """
    if os.path.exists(filepath) and os.path.isfile(filepath) and filepath.endswith('.blend'):
        log("Importing Blender model" + filepath, "INFO")
        objects = []
        with bpy.data.libraries.load(filepath) as (data_from, data_to):
            for objname in data_from.objects:
                objects.append({'name': objname})
        bpy.ops.wm.append(directory=filepath + "/Object/", files=objects)
        imported_objects = bpy.context.selected_objects
        resources = [obj for obj in imported_objects if obj.name.startswith('resource::')]
        new_objects = [obj for obj in imported_objects if not obj.name.startswith('resource::')]
        if resources:
            if 'resources' not in bpy.data.scenes.keys():
                bpy.data.scenes.new('resources')
            sUtils.selectObjects(resources)
            bpy.ops.object.make_links_scene(scene='resources')
            bpy.ops.object.delete(use_global=False)
            sUtils.selectObjects(new_objects)
        bpy.ops.view3d.view_selected(use_all_regions=False)
        # allow the use of both prefixes and namespaces, thus truly merging
        # models or keeping them separate for export
        if namespace != '':
            if prefix:
                for obj in bpy.context.selected_objects:
                    # set prefix instead of namespace
                    obj.name = namespace + '__' + obj.name
                    # make sure no internal name-properties remain
                    for key in obj.keys():
                        try:
                            if obj[key].endswidth("/name"):
                                del obj[key]
                        except AttributeError:  # prevent exceptions from non-string properties
                            pass
            else:
                for obj in bpy.context.selected_objects:
                    nUtils.addNamespace(obj, namespace)
        submechanism_roots = [
            obj
            for obj in bpy.data.objects
            if obj.phobostype == 'link' and 'submechanism/spanningtree' in obj
        ]
        for root in submechanism_roots:
            partlist = [root] + root['submechanism/spanningtree']
            if 'submechanism/freeloader' in root:
                partlist += root['submechanism/freeloader']
            sUtils.selectObjects(partlist, active=0)
            bpy.ops.group.create(name='submechanism:' + root['submechanism/name'])
        return True
    else:
        return False
Beispiel #3
0
def importBlenderModel(filepath, namespace='', prefix=False):
    """Imports an existing Blender model into the current .blend scene

    Args:
      filepath(str): Path of the .blend file
      namespace: (Default value = '')
      prefix: (Default value = False)

    Returns:

    """
    if os.path.exists(filepath) and os.path.isfile(filepath) and filepath.endswith('.blend'):
        log("Importing Blender model" + filepath, "INFO")
        objects = []
        with bpy.data.libraries.load(filepath) as (data_from, data_to):
            for objname in data_from.objects:
                objects.append({'name': objname})
        bpy.ops.wm.append(directory=filepath + "/Object/", files=objects)
        imported_objects = bpy.context.selected_objects
        resources = [obj for obj in imported_objects if obj.name.startswith('resource::')]
        new_objects = [obj for obj in imported_objects if not obj.name.startswith('resource::')]
        if resources:
            if 'resources' not in bpy.data.scenes.keys():
                bpy.data.scenes.new('resources')
            sUtils.selectObjects(resources)
            bpy.ops.object.make_links_scene(scene='resources')
            bpy.ops.object.delete(use_global=False)
            sUtils.selectObjects(new_objects)
        bpy.ops.view3d.view_selected(use_all_regions=False)
        # allow the use of both prefixes and namespaces, thus truly merging
        # models or keeping them separate for export
        if namespace != '':
            if prefix:
                for obj in bpy.context.selected_objects:
                    # set prefix instead of namespace
                    obj.name = namespace + '__' + obj.name
                    # make sure no internal name-properties remain
                    for key in obj.keys():
                        try:
                            if obj[key].endswidth("/name"):
                                del obj[key]
                        except AttributeError:  # prevent exceptions from non-string properties
                            pass
            else:
                for obj in bpy.context.selected_objects:
                    nUtils.addNamespace(obj, namespace)
        submechanism_roots = [
            obj
            for obj in bpy.data.objects
            if obj.phobostype == 'link' and 'submechanism/spanningtree' in obj
        ]
        for root in submechanism_roots:
            partlist = [root] + root['submechanism/spanningtree']
            if 'submechanism/freeloader' in root:
                partlist += root['submechanism/freeloader']
            sUtils.selectObjects(partlist, active=0)
            bpy.ops.group.create(name='submechanism:' + root['submechanism/name'])
        return True
    else:
        return False
Beispiel #4
0
def importBlenderModel(filepath, namespace='', prefix=True):
    if (os.path.exists(filepath) and os.path.isfile(filepath) and
       filepath.endswith('.blend')):
        log("Importing Blender model" + filepath, "INFO")
        objects = []
        with bpy.data.libraries.load(filepath) as (data_from, data_to):
            for obj in data_from.objects:
                objects.append({'name': obj})
        bpy.ops.wm.append(directory=filepath + "/Object/", files=objects)
        bpy.ops.view3d.view_selected(use_all_regions=False)
        # allow the use of both prefixes and namespaces, thus truly merging
        # models or keeping them separate for export
        if namespace != '':
            if prefix:
                for obj in bpy.context.selected_objects:
                    # set prefix instead of namespace
                    obj.name = namespace + '__' + obj.name
                    # make sure no internal name-properties remain
                    for ptype in defs.subtypes:
                        nametag = ptype + "/name"
                        if nametag in obj:
                            del obj[nametag]
            else:
                for obj in bpy.context.selected_objects:
                    nUtils.addNamespace(obj, namespace)
        return True
    else:
        return False
Beispiel #5
0
def importResources(restuple, filepath=None):
    """Accepts an iterable of iterables describing resource objects to import. For instance,
    reslist=(('joint', 'continuous'), ('interface', 'default', 'bidirectional'))
    would import the resource objects named 'joint_continuous' and
    'interface_default_bidirectional'.

    Args:
      restuple: iterable of iterables containing import objects
      filepath: path to file from which to load resource (Default value = None)
    Returns(tuple of bpy.types.Object): imported objects

    Returns:

    """
    currentscene = bpy.context.scene.name
    bUtils.switchToScene('resources')
    # avoid importing the same objects multiple times
    imported_objects = [
        nUtils.stripNamespaceFromName(obj.name)
        for obj in bpy.data.scenes['resources'].objects
    ]
    requested_objects = ['_'.join(resource) for resource in restuple]
    new_objects = [
        obj for obj in requested_objects if obj not in imported_objects
    ]

    # if no filepath is provided, use the path from the preferences
    if not filepath:
        filepath = os.path.join(bUtils.getPhobosConfigPath(), 'resources',
                                'resources.blend')
        print(filepath)

    # import new objects from resources.blend
    if new_objects:
        with bpy.data.libraries.load(filepath) as (data_from, data_to):
            objects = [{
                'name': name
            } for name in new_objects if name in data_from.objects]
            if objects:
                bpy.ops.wm.append(directory=filepath + "/Object/",
                                  files=objects)
            else:
                log('Resource objects could not be imported.', 'ERROR')
                bUtils.switchToScene(currentscene)
                return None
    objects = bpy.context.selected_objects
    for obj in objects:
        nUtils.addNamespace(obj, 'resource')
    bUtils.switchToScene(currentscene)
    return objects
Beispiel #6
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'}
Beispiel #7
0
def importResources(restuple, filepath=None):
    """Accepts an iterable of iterables describing resource objects to import. For instance,
    reslist=(('joint', 'continuous'), ('interface', 'default', 'bidirectional'))
    would import the resource objects named 'joint_continuous' and
    'interface_default_bidirectional'.

    Args:
      restuple: iterable of iterables containing import objects
      filepath: path to file from which to load resource (Default value = None)
    Returns(tuple of bpy.types.Object): imported objects

    Returns:

    """
    currentscene = bpy.context.scene.name
    bUtils.switchToScene('resources')
    # avoid importing the same objects multiple times
    imported_objects = [
        nUtils.stripNamespaceFromName(obj.name) for obj in bpy.data.scenes['resources'].objects
    ]
    requested_objects = ['_'.join(resource) for resource in restuple]
    new_objects = [obj for obj in requested_objects if obj not in imported_objects]

    # if no filepath is provided, use the path from the preferences
    if not filepath:
        filepath = os.path.join(bUtils.getPhobosConfigPath(), 'resources', 'resources.blend')
        print(filepath)

    # import new objects from resources.blend
    if new_objects:
        with bpy.data.libraries.load(filepath) as (data_from, data_to):
            objects = [{'name': name} for name in new_objects if name in data_from.objects]
            if objects:
                bpy.ops.wm.append(directory=filepath + "/Object/", files=objects)
            else:
                log('Resource objects could not be imported.', 'ERROR')
                bUtils.switchToScene(currentscene)
                return None
    objects = bpy.context.selected_objects
    for obj in objects:
        nUtils.addNamespace(obj, 'resource')
    bUtils.switchToScene(currentscene)
    return objects
Beispiel #8
0
def instantiateSubmodel(submodelname, instancename, size=1.0):
    """Creates an instance of the submodel specified by the submodelname.
    
    The instance receives the definitions of the group as it is generated.

    Args:
      submodelname: name of the submodel (Blender group) to create an
    instance of
      instancename: name the instance object will receive
      size: (Default value = 1.0)

    Returns:

    """
    submodel = None
    interfaces = None

    # find the existing group for submodel and interface
    for group in bpy.data.groups:
        # search for namespaced groups with the exact name
        if ':' in group.name and submodelname == group.name:
            submodel = group
        if group.name.startswith('interfaces:') and submodelname.split(
                ':')[1] in group.name:
            interfaces = group

    if not submodel:
        log('Selected submodel is not defined.', 'ERROR')
    if not interfaces:
        log('No interfaces defined for this submodel.', 'INFO')

    # add the submodel and write in data
    bpy.ops.object.group_instance_add(group=submodel.name)
    submodelobj = bpy.context.active_object
    submodelobj.phobostype = 'submodel'
    submodelobj['submodeltype'] = submodel.name.split(':')[0]
    # TODO currently this works only by name binding, we should add links to
    # the group here
    submodelobj['submodel/name'] = submodelname
    submodelobj['submodelname'] = submodelname
    # copy custom props from group to instance
    for key in submodel.keys():
        submodelobj[key] = submodel[key]
    submodelobj.name = instancename
    submodelobj.empty_draw_size = size

    # add the interfaces if available
    if interfaces:
        # create group and make real
        bpy.ops.object.group_instance_add(group=interfaces.name)
        bpy.ops.object.duplicates_make_real()

        # write interface parameters and change namespace
        for obj in bpy.context.selected_objects:
            nUtils.addNamespace(obj, instancename)
            obj.name = obj.name.rsplit('.')[0]
            obj['submodeltype'] = 'interface'
            bUtils.toggleTransformLock(obj, True)

        # parent interfaces to submodel empty
        parentObjectsTo(bpy.context.selected_objects, submodelobj)

        # delete empty parent object of interfaces
        sUtils.selectObjects(
            objects=[
                a for a in bpy.context.selected_objects if a.type == 'EMPTY'
                and 'submodeltype' in a and a['submodeltype'] == 'interface'
            ],
            clear=True,
            active=0,
        )
        bpy.ops.object.delete(use_global=False)
    return submodelobj
Beispiel #9
0
def instantiateSubmodel(submodelname, instancename, size=1.0):
    """Creates an instance of the submodel specified by the submodelname.
    
    The instance receives the definitions of the group as it is generated.

    Args:
      submodelname: name of the submodel (Blender group) to create an
    instance of
      instancename: name the instance object will receive
      size: (Default value = 1.0)

    Returns:

    """
    submodel = None
    interfaces = None

    # find the existing group for submodel and interface
    for group in bpy.data.groups:
        # search for namespaced groups with the exact name
        if ':' in group.name and submodelname == group.name:
            submodel = group
        if group.name.startswith('interfaces:') and submodelname.split(':')[1] in group.name:
            interfaces = group

    if not submodel:
        log('Selected submodel is not defined.', 'ERROR')
    if not interfaces:
        log('No interfaces defined for this submodel.', 'INFO')

    # add the submodel and write in data
    bpy.ops.object.group_instance_add(group=submodel.name)
    submodelobj = bpy.context.active_object
    submodelobj.phobostype = 'submodel'
    submodelobj['submodeltype'] = submodel.name.split(':')[0]
    # TODO currently this works only by name binding, we should add links to
    # the group here
    submodelobj['submodel/name'] = submodelname
    # copy custom props from group to instance
    for key in submodel.keys():
        submodelobj[key] = submodel[key]
    submodelobj.name = instancename
    submodelobj.empty_draw_size = size

    # add the interfaces if available
    if interfaces:
        # create group and make real
        bpy.ops.object.group_instance_add(group=interfaces.name)
        bpy.ops.object.duplicates_make_real()

        # write interface parameters and change namespace
        for obj in bpy.context.selected_objects:
            nUtils.addNamespace(obj, instancename)
            obj.name = obj.name.rsplit('.')[0]
            obj['submodeltype'] = 'interface'
            bUtils.toggleTransformLock(obj, True)

        # parent interfaces to submodel empty
        parentObjectsTo(bpy.context.selected_objects, submodelobj)

        # delete empty parent object of interfaces
        sUtils.selectObjects(
            objects=[
                a
                for a in bpy.context.selected_objects
                if a.type == 'EMPTY' and 'submodeltype' in a and a['submodeltype'] == 'interface'
            ],
            clear=True,
            active=0,
        )
        bpy.ops.object.delete(use_global=False)
    return submodelobj