0

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

Juan Carlos
  • 179
  • 2
  • 9
  • replace library_path with self.file_path? – batFINGER Apr 16 '21 at 13:43
  • 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. – Juan Carlos Apr 18 '21 at 07:28
  • No limitation. You would have to declare a StringProperty in order to display the path and assign your path to accordingly. Suggest read: https://blender.stackexchange.com/questions/57306/how-to-create-a-custom-ui to get the basics. – brockmann Apr 21 '21 at 06:25

0 Answers0