import bpy from bpy_extras.io_utils import ImportHelper from pathlib import Path from .utils import get_addon_prefs def get_brushes(blend_fp): '''Get all brush from passed blend that aren't already in there (can take Path object)''' cur_brushes = [b.name for b in bpy.data.brushes] with bpy.data.libraries.load(str(blend_fp), link=False) as (data_from, data_to): # load brushes if not already there data_to.brushes = [b for b in data_from.brushes if not b in cur_brushes] ## force fake user for appended the brushes for b in data_to.brushes: print(f'Append Brush: {b.name}') b.use_fake_user = True return len(data_to.brushes) class GPTB_OT_load_brushes(bpy.types.Operator, ImportHelper): bl_idname = "gp.load_brushes" bl_label = "Load Brushes" bl_description = "Load all brushes from chosen blend file in current if brushes aren't already there\nIf a replacement is needed, delete the previous brush before" #bl_options = {"REGISTER", "INTERNAL"} # @classmethod # def poll(cls, context): # return context.object and context.object.type == 'GREASEPENCIL' filename_ext = '.blend' filter_glob: bpy.props.StringProperty(default='*.blend', options={'HIDDEN'} ) filepath : bpy.props.StringProperty( name="File Path", description="File path used for import", maxlen= 1024) def execute(self, context): print(f'Appending brushes from file : {self.filepath}') bct = get_brushes(self.filepath) if bct: self.report({'INFO'}, f'{bct} brushes appended') else: self.report({'WARNING'}, 'Brushes are already there (if need to re-import, delete first)') return {"FINISHED"} class GPTB_OT_brush_set(bpy.types.Operator): bl_idname = "gp.brush_set" bl_label = "Set Brush" bl_description = "Set Gpencil brush" bl_options = {"REGISTER", "UNDO"} brush_name : bpy.props.StringProperty(name='Brush', description='Name of the brush to use') @classmethod def poll(cls, context): return context.object and context.mode == 'PAINT_GREASE_PENCIL' def execute(self, context): brush = bpy.data.brushes.get(self.brush_name) if not brush: self.report({'ERROR'}, f'Brush "{self.brush_name}" not found') return {"CANCELLED"} context.scene.tool_settings.gpencil_paint.brush = brush return {"FINISHED"} ### -- MENU ENTRY -- def load_brush_ui(self, context): prefs = get_addon_prefs() if context.mode == 'PAINT_GREASE_PENCIL': self.layout.operator('gp.load_brushes', icon='KEYTYPE_JITTER_VEC').filepath = prefs.brush_path def load_brush_top_bar_ui(self, context): prefs = get_addon_prefs() if context.mode == 'PAINT_GREASE_PENCIL': self.layout.operator('gp.load_brushes').filepath = prefs.brush_path classes = ( GPTB_OT_load_brushes, GPTB_OT_brush_set, ) def register(): for cl in classes: bpy.utils.register_class(cl) bpy.types.VIEW3D_MT_brush_context_menu.append(load_brush_ui) bpy.types.VIEW3D_HT_tool_header.append(load_brush_top_bar_ui) def unregister(): bpy.types.VIEW3D_HT_tool_header.remove(load_brush_top_bar_ui) bpy.types.VIEW3D_MT_brush_context_menu.remove(load_brush_ui) for cl in reversed(classes): bpy.utils.unregister_class(cl)