0
$\begingroup$

UPDATE: I reorganized the code in a way that now it runs and does what is meant to do when opening the file explorer. But still I fail on having the directory path on the UI.

I have this script made by stephen_leger over BlenderArtist which does what I need, now I need to add the file path in the UI, and I found another script (sorry don't remember the author) which does exactly what I want. The problem right now is how to combine both so when I hit the Sync button it loads the file that is set in the file path.

Can anyone please shed some light on this?

This is the UI that I'm looking after: enter image description here

Here is the code updated:

    import bpy
    import os
    
    from bpy.props import StringProperty, BoolProperty
    from bpy_extras.io_utils import ImportHelper
    from bpy.types import (Panel,
                           Operator,
                           AddonPreferences,
                           PropertyGroup,
                           )
    
    
    class OT_TestOpenFilebrowser(Operator, ImportHelper):
        """Sync materials from older file"""
        bl_idname = "object.sync_mats_from_file_operator"
        bl_label = "Sync Materials"
        bl_options = {'REGISTER', 'UNDO'}
    
        filter_glob: StringProperty(
            default='*.blend',
            options={'HIDDEN'}
        )
            
        def execute(self, context):
            """Do something with the selected file(s)."""
    
            filename, extension = os.path.splitext(self.filepath)
                        
            library_path = self.filepath
            # get mat names available in library
            with bpy.data.libraries.load(library_path) as (data_from, data_to):
                    available = set(data_from.materials)
    
            old_mats = {mat.name: mat for mat in bpy.data.materials if mat.name in available}
    
            # assign temp name to old materials
            for name, mat in old_mats.items():
                mat.name = "{}_tmp".format(name)
    
            # load from library
            with bpy.data.libraries.load(library_path, False, False) as (data_from, data_to):
                data_to.materials = list(old_mats.keys())
    
            # replace or remove temp name
            for name, mat in old_mats.items():
                new_mat = bpy.data.materials.get(name)
                if new_mat is None:
                    mat.name = name
                else:
                    mat.user_remap(new_mat)
                    bpy.data.materials.remove(mat)
            
            return {'FINISHED'}
    
    
    class SomePanel(Panel):
        """Creates a Panel in the Object properties window"""
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_category = "TEST CATEGORY"
        bl_label = "Material Sync"
        bl_idname = "TEST"
    
        def draw(self, context):
            layout = self.layout
    
            box = layout.box()
            row = box.column()
            row.operator("object.sync_mats_from_file_operator")
    
    
    def register():
        bpy.utils.register_class(OT_TestOpenFilebrowser)
        bpy.utils.register_class(SomePanel)
    
    
    def unregister():
        bpy.utils.unregister_class(OT_TestOpenFilebrowser)
        bpy.utils.unregister_class(SomePanel)
    
    
    if __name__ == "__main__":
        register()

Thanks in advance, Juan

$\endgroup$
3
  • $\begingroup$ replace library_path with self.file_path? $\endgroup$
    – batFINGER
    Apr 16 at 13:43
  • $\begingroup$ Thanks, I got it working now with the updated code, but now the file path ui is no more, not sure if this could be a Blender limitation though. $\endgroup$ Apr 18 at 7:28
  • $\begingroup$ No limitation. You would have to declare a StringProperty in order to display the path and assign your path to accordingly. Suggest read: blender.stackexchange.com/questions/57306/… to get the basics. $\endgroup$
    – brockmann
    Apr 21 at 6:25

Browse other questions tagged or ask your own question.