8
$\begingroup$

How to show open dialog box that can navigate to blender datablocks. I can show open dialog that can select .blend files, but how to select specific datablock just as 'File->Link' or 'File->Append' does?

Below is the code I am using ( copied from template ):

def read_some_data( context, filepath ):
  print("running read_some_data...")
  print( filepath )
  return {'FINISHED'}

class ImportSomeData( Operator, ImportHelper ):
    bl_idname = "import_test.some_data"
    bpy.ops.import_test.some_data is constructed
    bl_label = "Import Some Data"

    filename_ext = ".blend"

    filter_glob = StringProperty(
        default="*.blend",
        options={ 'HIDDEN' },
        )

def execute(self, context):
    return read_some_data(context, self.filepath)

Thanks!

$\endgroup$
  • $\begingroup$ The question I would ask in response to this is why you would want to do this, if the feature already exists? I presume you want to access data blocks from code, rather than a visual interface, then? $\endgroup$ – MaVCArt Nov 27 '15 at 11:17
  • $\begingroup$ No @MaVCArt, if you have a question, ask it in a different thread lol :p Let programmers be programmers, that's why we have the internet in the first place ^_^. My boss said I couldn't reasonably render 11 billion points in a browser application. I didn't even have to prove him wrong! (see potree) Anyways, hovering over the append/link commands exposes the python code executed when you click them. I LOVE LOVE blender for this epic use of open source tooltips. Turns out your question has already been answered here: blender.stackexchange.com/questions/3 $\endgroup$ – Thomas Pendergrass Feb 25 '17 at 7:10
1
$\begingroup$

You need to use bpy.data.libraries. The class has a function load which read the datablock of a blend file.

Here an example of how to draw such dialog box to append either a group or an object.

class open_blend_file(bpy.types.Operator, ImportHelper):
    """Import a .blend file to append model from"""
    bl_idname = "blend.open"
    bl_label = "Import"
    bl_options = {'UNDO'}

    filter_glob = StringProperty(
        default="*.blend",
        options={'HIDDEN'},
    )

    group = BoolProperty()

    def get_lib_groups(self,context):
        l = [];
        if os.path.exists(self.filepath) and self.filepath.endswith('.blend'):
            with bpy.data.libraries.load(self.filepath) as (data_from, data_to):
                groups = data_from.groups;
                # objects = data_from.objects;
                for g in groups:
                    l.append((g,g,g));
        if len(l) == 0:
            l = [("None","None","None")];

        return l;

    def get_lib_objects(self,context):
        l = [];
        if os.path.exists(self.filepath) and self.filepath.endswith('.blend'):
            with bpy.data.libraries.load(self.filepath) as (data_from, data_to):
                # groups = data_from.groups;
                objects = data_from.objects;
                for o in objects:
                    l.append((o, o, o));
        if len(l) == 0:
            l = [("None","None","None")];

        return l;

    lib_groups= EnumProperty(       
        name = "List of groups in the .blend file",
        description = "List of groups in the .blend file",
        items = get_lib_groups
    );

    lib_objects = EnumProperty(
        name = "List of objects in the .blend file",
        description = "List of objects in the .blend file",
        items = get_lib_objects
    );


    def draw(self, context):
        scene = bpy.context.scene;
        props = scene.property;
        layout = self.layout;

        row = layout.row();
        row.prop(props,'import_from', expand = True)     

        if props.import_from =='Groups':
            if len(self.lib_groups)>0:       
                row = layout.row();
                row.prop(self,'lib_groups', text = "Groups", icon = "GROUP")     
        else:
            if len(self.lib_objects)>0:       
                row = layout.row();
                row.prop(self,'lib_objects', text = "Objects", icon = "OBJECT_DATA")

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

    def execute(self, context):
        if self.group :
            name = self.lib_groups;
        else:
            name = self.lib_objects;

        if self.group:
            blend_file = self.filepath + "/Group/"
            bpy.ops.wm.append(directory=blend_file, link=False, filename=name, autoselect = True);

            group = bpy.data.groups.get(name); 
            if group is not None:
                bpy.ops.object.empty_add(type='PLAIN_AXES', location = (0,0,0));
                obj = get_active_object();
                obj.name = group.name;

                for o in group.objects:
                    o.parent = obj;

                group.objects.link(obj);


        else:
            blend_file = self.filepath + "/Object/"
            bpy.ops.wm.append(directory=blend_file, link=False, filename=name, autoselect = True);

        return {'FINISHED'}
$\endgroup$
  • $\begingroup$ What does scene.property look like? I get the error: AttributeError: 'Scene' object has no attribute 'property' $\endgroup$ – dval Feb 24 at 9:17
  • $\begingroup$ Ahh, got it. 'propterty' can be a PropertyGroup with a StringProperty 'import_from'. $\endgroup$ – dval Feb 24 at 10:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.