Brushstroke Tools: Initial Version #328
Binary file not shown.
@ -128,6 +128,9 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
|
||||
brushstrokes_object.modifiers[mod.name][f'{v.identifier}_use_attribute'] = False
|
||||
brushstrokes_object.modifiers[mod.name][f'{v.identifier}'] = type(brushstrokes_object.modifiers[mod.name][f'{v.identifier}'])(val)
|
||||
|
||||
# transfer modifier info data from preset to brush strokes
|
||||
utils.deep_copy_mod_info(settings.preset_object, brushstrokes_object)
|
||||
|
||||
# refresh UI
|
||||
for mod in brushstrokes_object.modifiers:
|
||||
mod.node_group.interface_update(context)
|
||||
@ -209,8 +212,12 @@ class BSBST_OT_init_preset(bpy.types.Operator):
|
||||
mod_info = settings.preset_object.modifier_info.add()
|
||||
mod_info.name = mod.name
|
||||
|
||||
# context link settings
|
||||
utils.mark_socket_context_type(mod_info, 'Socket_2', 'SURFACE_OBJECT')
|
||||
|
||||
# ui visibility settings
|
||||
mod_info.hide_ui = True
|
||||
|
||||
## brushstrokes
|
||||
mod = preset_object.modifiers.new('Brushstrokes', 'NODES')
|
||||
mod.node_group = bpy.data.node_groups['.brushstroke_tools.surface_fill']
|
||||
@ -220,9 +227,36 @@ class BSBST_OT_init_preset(bpy.types.Operator):
|
||||
mod_info = settings.preset_object.modifier_info.add()
|
||||
mod_info.name = mod.name
|
||||
|
||||
# context link settings
|
||||
utils.mark_socket_context_type(mod_info, 'Socket_2', 'FLOW_OBJECT')
|
||||
utils.mark_socket_context_type(mod_info, 'Socket_3', 'UVMAP')
|
||||
utils.mark_socket_context_type(mod_info, 'Socket_9', 'RANDOM')
|
||||
utils.mark_socket_context_type(mod_info, 'Socket_60', 'FLOW_OBJECT')
|
||||
|
||||
# ui visibility settings
|
||||
hide_sockets =[
|
||||
'Socket_3',
|
||||
'Socket_8',
|
||||
'Socket_9',
|
||||
'Socket_12',
|
||||
'Socket_15',
|
||||
'Socket_27',
|
||||
'Socket_35',
|
||||
]
|
||||
for s in hide_sockets:
|
||||
utils.mark_socket_hidden(mod_info, s)
|
||||
|
||||
hide_panels = [
|
||||
'Surface',
|
||||
'Flow',
|
||||
'Stroke Culling',
|
||||
'Lighting Influence',
|
||||
'Offset Override',
|
||||
'Debug',
|
||||
]
|
||||
for p in hide_panels:
|
||||
utils.mark_panel_hidden(mod_info, p)
|
||||
|
||||
|
||||
def init_draw(self, context):
|
||||
settings = context.scene.BSBST_settings
|
||||
|
@ -122,9 +122,11 @@ class BSBST_socket_info(bpy.types.PropertyGroup):
|
||||
link_context: bpy.props.BoolProperty(default=False, name='Link to Context')
|
||||
link_context_type: bpy.props.EnumProperty(default=1, name='Link to Context', update=update_link_context_type,
|
||||
items=link_context_type_items)
|
||||
hide_ui: bpy.props.BoolProperty(default=False)
|
||||
|
||||
class BSBST_modifier_info(bpy.types.PropertyGroup):
|
||||
name: bpy.props.StringProperty(default='')
|
||||
hide_ui: bpy.props.BoolProperty(default=False)
|
||||
socket_info: bpy.props.CollectionProperty(type=BSBST_socket_info)
|
||||
|
||||
class BSBST_context_brushstrokes(bpy.types.PropertyGroup):
|
||||
@ -164,6 +166,7 @@ class BSBST_Settings(bpy.types.PropertyGroup):
|
||||
update=update_active_brushstrokes,
|
||||
get=get_active_context_brushstrokes_index,
|
||||
set=set_active_context_brushstrokes_index)
|
||||
ui_options: bpy.props.BoolProperty(default=False, name='UI Options')
|
||||
|
||||
classes = [
|
||||
BSBST_socket_info,
|
||||
|
@ -2,7 +2,7 @@ import bpy
|
||||
from . import utils
|
||||
from . import settings as settings_py
|
||||
|
||||
def draw_panel_ui_recursive(panel, panel_name, mod, items):
|
||||
def draw_panel_ui_recursive(panel, panel_name, mod, items, display_mode):
|
||||
|
||||
scene = bpy.context.scene
|
||||
settings = scene.BSBST_settings
|
||||
@ -19,15 +19,40 @@ def draw_panel_ui_recursive(panel, panel_name, mod, items):
|
||||
|
||||
for k, v in items:
|
||||
if type(v) == bpy.types.NodeTreeInterfacePanel:
|
||||
|
||||
v_id = f'Panel_{v.index}' # TODO: replace with panel identifier once that is exposed in Blender 4.3
|
||||
|
||||
if not mod_info:
|
||||
continue
|
||||
s = mod_info.socket_info.get(v_id)
|
||||
if not s:
|
||||
continue
|
||||
if display_mode == 0:
|
||||
if s.hide_ui:
|
||||
continue
|
||||
|
||||
subpanel_header, subpanel = panel.panel(k, default_closed = v.default_closed)
|
||||
subpanel_header.label(text=k)
|
||||
draw_panel_ui_recursive(subpanel, k, mod, v.interface_items.items())
|
||||
if display_mode != 0:
|
||||
subpanel_header.prop(s, 'hide_ui', icon_only=True, icon='REMOVE')
|
||||
draw_panel_ui_recursive(subpanel, k, mod, v.interface_items.items(), display_mode)
|
||||
else:
|
||||
if v.parent.name != panel_name:
|
||||
continue
|
||||
if f'{v.identifier}' not in mod.keys():
|
||||
continue
|
||||
|
||||
if not mod_info:
|
||||
continue
|
||||
|
||||
s = mod_info.socket_info.get(v.identifier)
|
||||
if not s:
|
||||
continue
|
||||
if display_mode == 0:
|
||||
if s.hide_ui:
|
||||
continue
|
||||
row = panel.row(align=True)
|
||||
|
||||
col = row.column()
|
||||
input_row = col.row(align=True)
|
||||
attribute_toggle = False
|
||||
@ -51,21 +76,17 @@ def draw_panel_ui_recursive(panel, panel_name, mod, items):
|
||||
toggle.input_name = v.identifier
|
||||
else:
|
||||
input_row.prop(mod, f'["{v.identifier}"]', text=k)
|
||||
if not mod_info:
|
||||
continue
|
||||
if type(v) in utils.linkable_sockets:
|
||||
s = mod_info.socket_info.get(v.identifier)
|
||||
if not s:
|
||||
continue
|
||||
col.enabled = not s.link_context
|
||||
if not s:
|
||||
continue
|
||||
icon = settings_py.icon_from_link_type(s.link_context_type)
|
||||
row.alignment = 'EXPAND'
|
||||
if s.link_context:
|
||||
row.prop(s, 'link_context', text='', icon_value=icon)
|
||||
else:
|
||||
if display_mode == -1:
|
||||
row.prop(s, 'link_context_type', text='', emboss=True, icon='LINKED', icon_only=True)
|
||||
if display_mode != 0:
|
||||
row.prop(s, 'hide_ui', icon_only=True, icon='REMOVE')
|
||||
|
||||
class BSBST_UL_brushstroke_objects(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
@ -121,7 +142,7 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
|
||||
new_advanced_panel.label(text='Curve mode does not support drawing on deformed geometry', icon='ERROR')
|
||||
|
||||
new_advanced_panel.prop(settings, 'assign_materials')
|
||||
row = new_advanced_panel.row()
|
||||
new_advanced_panel.prop(settings, 'ui_options', icon='OPTIONS')
|
||||
|
||||
# identify style context
|
||||
style_object = context.object if settings.style_context=='BRUSHSTROKES' else settings.preset_object
|
||||
@ -139,6 +160,10 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
|
||||
|
||||
is_preset = style_object == settings.preset_object
|
||||
|
||||
display_mode = settings.ui_options
|
||||
if is_preset:
|
||||
display_mode = -1
|
||||
|
||||
style_header, style_panel = layout.panel("brushstrokes_style", default_closed=False)
|
||||
|
||||
if is_preset:
|
||||
@ -161,15 +186,25 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
|
||||
|
||||
if style_object:
|
||||
for mod in style_object.modifiers:
|
||||
mod_info = mod.id_data.modifier_info.get(mod.name)
|
||||
if not mod_info:
|
||||
continue
|
||||
if display_mode == 0:
|
||||
if mod_info.hide_ui:
|
||||
continue
|
||||
|
||||
mod_header, mod_panel = style_panel.panel(mod.name, default_closed = False)
|
||||
mod_header.label(text='', icon='GEOMETRY_NODES')
|
||||
mod_header.prop(mod, 'name', text='')
|
||||
row = mod_header.row(align=True)
|
||||
row.label(text='', icon='GEOMETRY_NODES')
|
||||
row.prop(mod, 'name', text='')
|
||||
|
||||
if is_preset:
|
||||
op = mod_header.operator('brushstroke_tools.preset_remove_mod', text='', icon='X')
|
||||
op = row.operator('brushstroke_tools.preset_remove_mod', text='', icon='X')
|
||||
else:
|
||||
op = mod_header.operator('object.modifier_remove', text='', icon='X')
|
||||
op = row.operator('object.modifier_remove', text='', icon='X')
|
||||
op.modifier = mod.name
|
||||
if display_mode != 0:
|
||||
mod_header.prop(mod_info, 'hide_ui', icon_only=True, icon='REMOVE')
|
||||
|
||||
if not mod_panel:
|
||||
continue
|
||||
@ -184,7 +219,11 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
|
||||
if not mod.node_group:
|
||||
continue
|
||||
|
||||
draw_panel_ui_recursive(mod_panel, '', mod, mod.node_group.interface.items_tree.items())
|
||||
draw_panel_ui_recursive(mod_panel,
|
||||
'',
|
||||
mod,
|
||||
mod.node_group.interface.items_tree.items(),
|
||||
display_mode)
|
||||
|
||||
# expose add modifier operator for preset context
|
||||
if is_preset:
|
||||
|
@ -26,21 +26,19 @@ def refresh_preset(dummy):
|
||||
if not settings.preset_object:
|
||||
return
|
||||
for mod in settings.preset_object.modifiers:
|
||||
if not mod.type == 'NODES':
|
||||
continue
|
||||
if not mod.node_group:
|
||||
continue
|
||||
mod_info = settings.preset_object.modifier_info.get(mod.name)
|
||||
if not mod_info:
|
||||
mod_info = settings.preset_object.modifier_info.add()
|
||||
mod_info.name = mod.name
|
||||
for v in mod.node_group.interface.items_tree.values():
|
||||
if not type(v) in linkable_sockets:
|
||||
continue
|
||||
if v.identifier in [s.name for s in mod_info.socket_info]:
|
||||
if type(v) is bpy.types.NodeTreeInterfacePanel:
|
||||
v_id = f'Panel_{v.index}' # TODO: replace with panel identifier once that is exposed in Blender 4.3
|
||||
else:
|
||||
v_id = v.identifier
|
||||
if v_id in [s.name for s in mod_info.socket_info]:
|
||||
continue
|
||||
n = mod_info.socket_info.add()
|
||||
n.name = v.identifier
|
||||
n.name = v_id
|
||||
# TODO: clean up old settings
|
||||
|
||||
def mark_socket_context_type(mod_info, socket_name, link_type):
|
||||
@ -50,6 +48,37 @@ def mark_socket_context_type(mod_info, socket_name, link_type):
|
||||
socket_info.name = socket_name
|
||||
socket_info.link_context_type = link_type
|
||||
|
||||
def mark_socket_hidden(mod_info, socket_name, hide=True):
|
||||
socket_info = mod_info.socket_info.get(socket_name)
|
||||
if not socket_info:
|
||||
socket_info = mod_info.socket_info.add()
|
||||
socket_info.name = socket_name
|
||||
socket_info.hide_ui = hide
|
||||
|
||||
def mark_panel_hidden(mod_info, panel_name, hide=True):
|
||||
mod = mod_info.id_data.modifiers.get(mod_info.name)
|
||||
if not mod:
|
||||
return
|
||||
if not mod.type == 'NODES':
|
||||
return
|
||||
ng = mod.node_group
|
||||
if not ng:
|
||||
return
|
||||
v_id = ''
|
||||
for k, v in ng.interface.items_tree.items():
|
||||
if type(v) != bpy.types.NodeTreeInterfacePanel:
|
||||
continue
|
||||
if v.name == panel_name:
|
||||
v_id = f'Panel_{v.index}'
|
||||
break
|
||||
if not v_id:
|
||||
return
|
||||
socket_info = mod_info.socket_info.get(v_id)
|
||||
if not socket_info:
|
||||
socket_info = mod_info.socket_info.add()
|
||||
socket_info.name = v_id
|
||||
socket_info.hide_ui = hide
|
||||
|
||||
def deep_copy_mod_info(source_object, target_object):
|
||||
for mod_info in source_object.modifier_info:
|
||||
mod_info_tgt = target_object.modifier_info.add()
|
||||
|
Loading…
Reference in New Issue
Block a user