101 lines
3.3 KiB
Python
101 lines
3.3 KiB
Python
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)
|