Brushstroke Tools: Initial Version #328

Merged
Simon Thommes merged 229 commits from SimonThommes/blender-studio-tools:brushstroke_tools-initial-version into main 2024-11-06 15:03:47 +01:00
3 changed files with 72 additions and 28 deletions
Showing only changes of commit f967b92bfa - Show all commits

View File

@ -16,16 +16,8 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
def poll(cls, context): def poll(cls, context):
return context.mode == 'OBJECT' return context.mode == 'OBJECT'
def execute(self, context): def new_brushstrokes_object(self, context, name):
settings = context.scene.BSBST_settings settings = context.scene.BSBST_settings
utils.ensure_resources()
surface_object = context.object if context.object in context.selected_objects else None
name = 'Brushstrokes'
if settings.curve_mode == 'GP': if settings.curve_mode == 'GP':
bpy.ops.object.grease_pencil_add(type='EMPTY') bpy.ops.object.grease_pencil_add(type='EMPTY')
context.object.name = name context.object.name = name
@ -43,9 +35,51 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
for ob in bpy.data.objects: for ob in bpy.data.objects:
ob.select_set(False) ob.select_set(False)
brushstrokes_object.select_set(True) brushstrokes_object.select_set(True)
return brushstrokes_object
def new_flow_object(self, context, name):
settings = context.scene.BSBST_settings
if settings.curve_mode == 'GP':
bpy.ops.object.grease_pencil_add(type='EMPTY')
context.object.name = name
context.object.data.name = name
flow_object = context.object
else:
if settings.curve_mode == 'CURVE':
flow_data = bpy.data.curves.new(name, type='CURVE')
flow_data.dimensions = '3D'
elif settings.curve_mode == 'CURVES':
flow_data = bpy.data.hair_curves.new(name)
flow_object = bpy.data.objects.new(name, flow_data)
context.collection.objects.link(flow_object)
context.view_layer.objects.active = flow_object
for ob in bpy.data.objects:
ob.select_set(False)
flow_object.select_set(True)
return flow_object
def execute(self, context):
settings = context.scene.BSBST_settings
utils.ensure_resources()
surface_object = context.object if context.object in context.selected_objects else None
flow_object = None
name = 'Brushstrokes'
brushstrokes_object = self.new_brushstrokes_object(context, name)
flow_is_required = settings.brushstroke_method == 'SURFACE_FILL'
if flow_is_required:
flow_object = self.new_flow_object(context, f'{name}-FLOW')
# attach surface object pointer # attach surface object pointer
brushstrokes_object['BSBST_surface_object'] = surface_object if surface_object:
brushstrokes_object['BSBST_surface_object'] = surface_object
if flow_object:
flow_object['BSBST_surface_object'] = surface_object
if flow_object:
brushstrokes_object['BSBST_flow_object'] = flow_object
brushstrokes_object['BSBST_active'] = True brushstrokes_object['BSBST_active'] = True
brushstrokes_object['BSBST_method'] = settings.brushstroke_method brushstrokes_object['BSBST_method'] = settings.brushstroke_method

View File

@ -1,4 +1,5 @@
import bpy import bpy
from . import utils
from bpy.app.handlers import persistent from bpy.app.handlers import persistent
@persistent @persistent
@ -9,17 +10,20 @@ def find_context_brushstrokes(dummy):
for el in range(len(settings.context_brushstrokes)): for el in range(len(settings.context_brushstrokes)):
settings.context_brushstrokes.remove(0) settings.context_brushstrokes.remove(0)
context_object = context.object context_object = context.object
if 'BSBST_surface_object' in context_object.keys(): surf_ob = utils.get_surface_object(context_object)
ob = context_object['BSBST_surface_object'] if surf_ob:
if ob: context_object = surf_ob
context_object = ob
for ob in bpy.data.objects: for ob in bpy.data.objects:
if not ('BSBST_surface_object' in ob.keys()): if not utils.is_brushstrokes_object(ob):
continue
if not ob['BSBST_surface_object']:
continue
if not ob['BSBST_surface_object'] == context_object:
continue continue
surf_ob = utils.get_surface_object(ob)
flow_ob = utils.get_flow_object(ob)
if not surf_ob:
if not flow_ob:
continue
if not surf_ob == context_object:
if not flow_ob == context_object:
continue
bs = settings.context_brushstrokes.add() bs = settings.context_brushstrokes.add()
bs.name = ob.name bs.name = ob.name
bs.method = ob['BSBST_method'] bs.method = ob['BSBST_method']

View File

@ -83,14 +83,20 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
layout = self.layout layout = self.layout
settings = context.scene.BSBST_settings settings = context.scene.BSBST_settings
surface_object = None surface_object = None
if context.object: if settings.context_brushstrokes:
if 'BSBST_surface_object' in context.object.keys(): active_brushstrokes_object = bpy.data.objects.get(settings.context_brushstrokes[settings.active_context_brushstrokes_index].name)
surface_object = context.object['BSBST_surface_object'] if active_brushstrokes_object:
else: if 'BSBST_surface_object' in active_brushstrokes_object.keys():
surface_object = context.object surface_object = active_brushstrokes_object['BSBST_surface_object']
layout.label(text=f'Surface Object: {surface_object.name}' if surface_object else 'No Surface Object', icon='OUTLINER_OB_SURFACE') else:
surface_object = context.object
else:
surface_object = context.object
else:
surface_object = context.object
layout.label(text=f'{surface_object.name}' if surface_object else 'No Surface Object', icon='OUTLINER_OB_SURFACE')
layout.prop(settings, 'brushstroke_method', expand=True) layout.prop(settings, 'brushstroke_method', expand=True)
@ -111,7 +117,7 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
if settings.style_context=='PRESET': if settings.style_context=='PRESET':
style_object = settings.preset_object style_object = settings.preset_object
else: else:
if 'BSBST_active' in context.object.keys(): if utils.is_brushstrokes_object(context.object):
style_object = context.object style_object = context.object
else: else:
if settings.context_brushstrokes: if settings.context_brushstrokes:
@ -132,7 +138,7 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
style_header.row().prop(settings, 'style_context', icon_only=True, expand=True) style_header.row().prop(settings, 'style_context', icon_only=True, expand=True)
if style_panel: if style_panel:
if settings.style_context=='BRUSHSTROKES' and not 'BSBST_active' in style_object.keys(): if settings.style_context=='BRUSHSTROKES' and not utils.is_brushstrokes_object(style_object):
style_panel.label(text='No Brushstroke Context Found', icon='ERROR') style_panel.label(text='No Brushstroke Context Found', icon='ERROR')
return return
if not is_preset and len(settings.context_brushstrokes)>0: if not is_preset and len(settings.context_brushstrokes)>0: