2026-03-16
This commit is contained in:
@@ -10,13 +10,13 @@ D:\Work\9 iClone\Amazon\
|
||||
D:\Amazon\00_external-files\
|
||||
N:\1. CHARACTERS\remapping\
|
||||
[Recent]
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Deliverable\
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\
|
||||
A:\1 Amazon_Active_Projects\260127_Pick-and-Stage_2026_edits\Blends\stills\
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\
|
||||
C:\Program Files (x86)\Steam\steamapps\common\Blender\5.0\scripts\startup\
|
||||
P:\260217_Jarvis-Defense\Blends\animations\
|
||||
T:\1 BlenderAssets\
|
||||
A:\1 Amazon_Active_Projects\1 BlenderAssets\
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\
|
||||
F:\renders\
|
||||
P:\260217_Jarvis-Defense\Assets\Blends\Props\
|
||||
C:\Users\Nathan\Downloads\Shot5\
|
||||
P:\260217_Jarvis-Defense\Assets\Blends\textures\
|
||||
P:\260217_Jarvis-Defense\Assets\Blends\textures\3075 Decade Dr\common\
|
||||
P:\260217_Jarvis-Defense\Assets\
|
||||
|
||||
+51
-2
@@ -1,11 +1,60 @@
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18h.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18g.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_3d.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18f.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18e.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18c.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18d.blend
|
||||
A:\1 Amazon_Active_Projects\260127_Pick-and-Stage_2026_edits\Blends\stills\iP&S_2026_10.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\stills\iP&S_BD2_18b.blend
|
||||
A:\1 Amazon_Active_Projects\260127_Pick-and-Stage_2026_edits\Blends\stills\iP&S_2026_3a-b.blend
|
||||
A:\1 Amazon_Active_Projects\260127_Pick-and-Stage_2026_edits\Blends\stills\iP&S_2026_1a.blend
|
||||
A:\1 Amazon_Active_Projects\260127_Pick-and-Stage_2026_edits\Blends\stills\iP&S_2026_1c.blend
|
||||
A:\1 Amazon_Active_Projects\260127_Pick-and-Stage_2026_edits\Blends\stills\iP&S_2026_1d.blend
|
||||
C:\Users\Nathan\Downloads\P&S_BD2_animation 6d.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 6d.blend
|
||||
C:\Users\Nathan\Downloads\PnS_BD2_animation 6d\UNC_NEXUS_amazon\1 Amazon_Active_Projects\1 BlenderAssets\Amazon\Char\Cartoon3\Bebe_v1.1.blend
|
||||
C:\Users\Nathan\Downloads\PnS_BD2_animation 6d\UNC_NEXUS_amazon\1 Amazon_Active_Projects\1 BlenderAssets\Amazon\Char\Cartoon1\Kirk_v4.4.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 6a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 6c.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 6b.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 8c_part2.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 11a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 9b.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 7c.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 5b.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 4d.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 3a_part2.blend
|
||||
F:\jobs\P&S_BD2_animation 8c\P&S_BD2_animation 8c.flamenco.blend
|
||||
F:\jobs\P&S_BD2_animation 9e\P&S_BD2_animation 9e.flamenco.blend
|
||||
F:\jobs\P&S_BD2_animation 8b\P&S_BD2_animation 8b.flamenco.blend
|
||||
F:\jobs\P&S_BD2_animation 8c_part2\P&S_BD2_animation 8c_part2.flamenco.blend
|
||||
F:\jobs\P&S_BD2_animation 8a\P&S_BD2_animation 8a.flamenco.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 8a.blend
|
||||
T:\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 8a.blend
|
||||
T:\260311_PnS-Beyond-Day-2\Blends\stills\P&S_BD2_animation 8a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 8c.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 9e.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 8b.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 9c.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 9a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 12b_part2.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 12b.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 12a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 11b.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 10b_part3.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 10b_part2.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 10a.blend
|
||||
A:\1 Amazon_Active_Projects\260311_PnS-Beyond-Day-2\Blends\animations\P&S_BD2_animation 10b_part1.blend
|
||||
P:\260217_Jarvis-Defense\Blends\animations\Shot_4.blend
|
||||
P:\260217_Jarvis-Defense\Blends\animations\Shot_3_retimed.blend
|
||||
F:\jobs\Shot_4c\Shot_4.flamenco.blend
|
||||
F:\jobs\Shot_4e\Shot_4.flamenco.blend
|
||||
F:\jobs\Shot_4a\Shot_4.flamenco.blend
|
||||
F:\jobs\Shot_4g\Shot_4.flamenco.blend
|
||||
P:\260217_Jarvis-Defense\Blends\animations\Shot_4.blend
|
||||
F:\jobs\Shot_1a-tqpj\Shot_1.flamenco.blend
|
||||
F:\jobs\Shot_6-4dkh\closeup.flamenco.blend
|
||||
P:\260217_Jarvis-Defense\Blends\animations\Shot_3_retimed.blend
|
||||
F:\jobs\Shot_0_5a\Shot_0_5.flamenco.blend
|
||||
P:\260217_Jarvis-Defense\Blends\animations\closeup.blend
|
||||
F:\jobs\Shot5c\Shot_Q.flamenco.blend
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
schema_version = "1.0.0"
|
||||
|
||||
id = "brushstroke_tools"
|
||||
version = "1.1.2"
|
||||
version = "1.2.1"
|
||||
name = "Brushstroke Tools"
|
||||
tagline = "Brushstroke painting tools by the Blender Studio"
|
||||
maintainer = "Simon Thommes <simon@blender.org>"
|
||||
|
||||
@@ -94,6 +94,12 @@ class BSBST_OT_pre_process_brushstroke(bpy.types.Operator):
|
||||
for prop in props_list:
|
||||
setattr(context.tool_settings.curve_paint_settings, prop, getattr(tool_settings, prop))
|
||||
|
||||
if bpy.app.version >= (5,1):
|
||||
utils.ensure_resources()
|
||||
ng_process = bpy.data.node_groups['.brushstroke_tools.draw_processing']
|
||||
ng_process.asset_mark() # workaround to let Blender register the node tool as an operator with the automatically generated id
|
||||
ng_process.asset_clear()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class BSBST_OT_post_process_brushstroke(bpy.types.Operator):
|
||||
@@ -119,7 +125,11 @@ class BSBST_OT_post_process_brushstroke(bpy.types.Operator):
|
||||
if 'BSBST_surface_object' in context.object.keys():
|
||||
if context.object['BSBST_surface_object']:
|
||||
self.ng_process.nodes['surface_object'].inputs[0].default_value = context.object['BSBST_surface_object']
|
||||
bpy.ops.geometry.execute_node_group(name="set_brush_stroke_color", session_uid=self.ng_process.session_uid)
|
||||
|
||||
if bpy.app.version < (5,1):
|
||||
bpy.ops.geometry.execute_node_group(name="set_brush_stroke_color", session_uid=self.ng_process.session_uid)
|
||||
else:
|
||||
bpy.ops.geometry._brushstroke_tools_draw_processing()
|
||||
|
||||
preserve_draw_settings(context, restore=True)
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -30,21 +30,18 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
|
||||
settings.brushstroke_method = self.method
|
||||
|
||||
if settings.curve_mode == 'GP':
|
||||
bpy.ops.object.grease_pencil_add(type='EMPTY')
|
||||
context.object.name = name
|
||||
context.object.data.name = name
|
||||
brushstrokes_object = context.object
|
||||
context.collection.objects.unlink(brushstrokes_object)
|
||||
else:
|
||||
if settings.curve_mode == 'CURVE':
|
||||
brushstrokes_data = bpy.data.curves.new(name, type='CURVE')
|
||||
brushstrokes_data.dimensions = '3D'
|
||||
elif settings.curve_mode == 'CURVES':
|
||||
brushstrokes_data = bpy.data.hair_curves.new(name)
|
||||
brushstrokes_object = bpy.data.objects.new(name, brushstrokes_data)
|
||||
brushstrokes_data = bpy.data.grease_pencils.new(name)
|
||||
bs_layer = brushstrokes_data.layers.new('Brushstrokes')
|
||||
bs_layer.frames.new(1)
|
||||
elif settings.curve_mode == 'CURVE':
|
||||
brushstrokes_data = bpy.data.curves.new(name, type='CURVE')
|
||||
brushstrokes_data.dimensions = '3D'
|
||||
elif settings.curve_mode == 'CURVES':
|
||||
brushstrokes_data = bpy.data.hair_curves.new(name)
|
||||
brushstrokes_object = bpy.data.objects.new(name, brushstrokes_data)
|
||||
|
||||
# link to surface object's collections (fall back to active collection if all are linked data)
|
||||
utils.link_to_collections_by_ref(brushstrokes_object, surface_object)
|
||||
utils.link_to_collections_by_ref(brushstrokes_object, surface_object, unlink=False)
|
||||
|
||||
brushstrokes_object.visible_shadow = False
|
||||
brushstrokes_object['BSBST_version'] = utils.addon_version
|
||||
@@ -55,21 +52,18 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
|
||||
def new_flow_object(self, context, name, surface_object):
|
||||
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
|
||||
context.collection.objects.unlink(flow_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)
|
||||
flow_data = bpy.data.grease_pencils.new(name)
|
||||
fl_layer = flow_data.layers.new('Flow')
|
||||
fl_layer.frames.new(1)
|
||||
elif 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)
|
||||
|
||||
# link to surface object's collections (fall back to active collection if all are linked data)
|
||||
utils.link_to_collections_by_ref(flow_object, surface_object)
|
||||
utils.link_to_collections_by_ref(flow_object, surface_object, unlink=False)
|
||||
|
||||
visibility_options = [
|
||||
'visible_camera',
|
||||
@@ -112,7 +106,7 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
|
||||
self.report({"ERROR"}, "Surface Object needs an available UV Map")
|
||||
return {"CANCELLED"}
|
||||
|
||||
name = f'{surface_object.name} - Brushstrokes'
|
||||
name = utils.bs_name(surface_object.name)
|
||||
brushstrokes_object = self.new_brushstrokes_object(context, name, surface_object)
|
||||
flow_is_required = settings.brushstroke_method == 'SURFACE_FILL'
|
||||
if flow_is_required:
|
||||
@@ -151,7 +145,9 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
|
||||
with context.temp_override(**override):
|
||||
bpy.ops.object.material_slot_add()
|
||||
brushstrokes_object.material_slots[0].material = preset_material
|
||||
settings.silent_switch = True
|
||||
settings.context_material = preset_material
|
||||
settings.silent_switch = False
|
||||
brushstrokes_object['BSBST_material'] = settings.context_material
|
||||
|
||||
# transfer preset modifiers to new brushstrokes TODO: refactor to deduplicate
|
||||
@@ -238,7 +234,7 @@ class BSBST_OT_new_brushstrokes(bpy.types.Operator):
|
||||
mod.show_group_selector = False
|
||||
|
||||
# update brushstroke context
|
||||
utils.find_context_brushstrokes(None)
|
||||
utils.find_context_brushstrokes(context.scene, context.view_layer.depsgraph)
|
||||
for i, name in enumerate([bs.name for bs in settings.context_brushstrokes]):
|
||||
if name == brushstrokes_object.name:
|
||||
settings.active_context_brushstrokes_index = i
|
||||
@@ -297,7 +293,7 @@ class BSBST_OT_delete_brushstrokes(bpy.types.Operator):
|
||||
edit_toggle = settings.edit_toggle
|
||||
settings.edit_toggle = False
|
||||
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
settings.edit_toggle = edit_toggle
|
||||
return {"CANCELLED"}
|
||||
@@ -313,7 +309,7 @@ class BSBST_OT_delete_brushstrokes(bpy.types.Operator):
|
||||
|
||||
if surface_object:
|
||||
context.view_layer.objects.active = surface_object
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if bs_ob:
|
||||
context.view_layer.objects.active = bs_ob
|
||||
bs_ob.select_set(True)
|
||||
@@ -346,7 +342,7 @@ class BSBST_OT_duplicate_brushstrokes(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
settings = context.scene.BSBST_settings
|
||||
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -410,7 +406,7 @@ class BSBST_OT_copy_brushstrokes(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
settings = context.scene.BSBST_settings
|
||||
|
||||
active_surface_object = utils.get_surface_object(utils.get_active_context_brushstrokes_object(context))
|
||||
active_surface_object = utils.get_surface_object(utils.get_active_context_brushstrokes_object(context.scene))
|
||||
|
||||
surface_objects = [ob for ob in context.selected_objects
|
||||
if ob.type=='MESH'
|
||||
@@ -423,7 +419,7 @@ class BSBST_OT_copy_brushstrokes(bpy.types.Operator):
|
||||
bs_objects = [bpy.data.objects.get(bs.name) for bs in settings.context_brushstrokes]
|
||||
bs_objects = [bs for bs in bs_objects if bs]
|
||||
else:
|
||||
bs_objects = [utils.get_active_context_brushstrokes_object(context)]
|
||||
bs_objects = [utils.get_active_context_brushstrokes_object(context.scene)]
|
||||
if not bs_objects:
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -450,6 +446,17 @@ class BSBST_OT_copy_brushstrokes(bpy.types.Operator):
|
||||
|
||||
# remap surface pointers and context linked data TODO: refactor to deduplicate
|
||||
for ob in new_bs:
|
||||
utils.link_to_collections_by_ref(ob, surface_object)
|
||||
|
||||
# if it's still using the default name initialize names again
|
||||
if utils.split_id_name(ob.name)[0] == utils.bs_name(active_surface_object.name):
|
||||
if utils.is_flow_object(ob):
|
||||
ob.name = utils.flow_name(utils.bs_name(surface_object.name))
|
||||
else:
|
||||
ob.name = utils.bs_name(surface_object.name)
|
||||
elif ob.name.startswith(active_surface_object.name):
|
||||
ob.name = f"{surface_object.name}{ob.name[len(active_surface_object.name):]}"
|
||||
|
||||
ob.parent = surface_object
|
||||
utils.set_surface_object(ob, surface_object)
|
||||
|
||||
@@ -504,16 +511,16 @@ class BSBST_OT_select_surface(bpy.types.Operator):
|
||||
return bool(settings.context_brushstrokes)
|
||||
|
||||
def execute(self, context):
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
return {"CANCELLED"}
|
||||
surface_object = getattr(bs_ob, '["BSBST_surface_object"]', None)
|
||||
if not surface_object:
|
||||
return {"CANCELLED"}
|
||||
|
||||
bpy.context.view_layer.objects.active = surface_object
|
||||
if not context.mode == 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.context.view_layer.objects.active = surface_object
|
||||
for ob in bpy.data.objects:
|
||||
ob.select_set(False)
|
||||
surface_object.select_set(True)
|
||||
@@ -537,7 +544,7 @@ class BSBST_OT_assign_surface(bpy.types.Operator):
|
||||
return bool(settings.context_brushstrokes)
|
||||
|
||||
def execute(self, context):
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -555,7 +562,7 @@ class BSBST_OT_assign_surface(bpy.types.Operator):
|
||||
layout.prop_search(self, 'surface_object', bpy.data, 'objects')
|
||||
|
||||
def invoke(self, context, event):
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
surf_ob = utils.get_surface_object(bs_ob)
|
||||
if surf_ob:
|
||||
self.surface_object = surf_ob.name
|
||||
@@ -632,7 +639,7 @@ class BSBST_OT_copy_flow(bpy.types.Operator):
|
||||
return bool(settings.context_brushstrokes)
|
||||
|
||||
def execute(self, context):
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
flow_ob_old = utils.get_flow_object(bs_ob)
|
||||
if not bs_ob:
|
||||
return {"CANCELLED"}
|
||||
@@ -670,7 +677,7 @@ class BSBST_OT_copy_flow(bpy.types.Operator):
|
||||
def invoke(self, context, event):
|
||||
settings = context.scene.BSBST_settings
|
||||
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
|
||||
for i in range(len(self.bs_list)):
|
||||
self.bs_list.remove(0)
|
||||
@@ -721,7 +728,7 @@ class BSBST_OT_switch_deformable(bpy.types.Operator):
|
||||
bs_objects = [bpy.data.objects.get(bs.name) for bs in settings.context_brushstrokes]
|
||||
bs_objects = [bs for bs in bs_objects if bs]
|
||||
else:
|
||||
bs_objects = [utils.get_active_context_brushstrokes_object(context)]
|
||||
bs_objects = [utils.get_active_context_brushstrokes_object(context.scene)]
|
||||
if not bs_objects:
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -762,7 +769,7 @@ class BSBST_OT_switch_animated(bpy.types.Operator):
|
||||
bs_objects = [bpy.data.objects.get(bs.name) for bs in settings.context_brushstrokes]
|
||||
bs_objects = [bs for bs in bs_objects if bs]
|
||||
else:
|
||||
bs_objects = [utils.get_active_context_brushstrokes_object(context)]
|
||||
bs_objects = [utils.get_active_context_brushstrokes_object(context.scene)]
|
||||
if not bs_objects:
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -963,7 +970,7 @@ class BSBST_OT_make_preset(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return bool(utils.get_active_context_brushstrokes_object(context))
|
||||
return bool(utils.get_active_context_brushstrokes_object(context.scene))
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
@@ -977,7 +984,7 @@ class BSBST_OT_make_preset(bpy.types.Operator):
|
||||
settings.preset_object.modifiers.remove(mod)
|
||||
|
||||
# transfer brushstrokes modifiers to preset
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
return {"CANCELLED"}
|
||||
for mod in bs_ob.modifiers:
|
||||
@@ -1098,7 +1105,7 @@ class BSBST_OT_brushstrokes_toggle_attribute(bpy.types.Operator):
|
||||
edit_toggle = settings.edit_toggle
|
||||
settings.edit_toggle = False
|
||||
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
settings.edit_toggle = edit_toggle
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -25,7 +25,7 @@ def update_brushstroke_method(self, context):
|
||||
preset_object = bpy.data.objects.get(preset_name)
|
||||
settings.preset_object = preset_object
|
||||
|
||||
style_object = utils.get_active_context_brushstrokes_object(context)
|
||||
style_object = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not style_object:
|
||||
style_object = preset_object
|
||||
|
||||
@@ -45,7 +45,7 @@ def update_context_material(self, context):
|
||||
if settings.silent_switch:
|
||||
return
|
||||
|
||||
style_object = utils.get_active_context_brushstrokes_object(context)
|
||||
style_object = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
if not style_object:
|
||||
style_object = settings.preset_object
|
||||
if not style_object:
|
||||
@@ -119,7 +119,14 @@ def get_active_context_brushstrokes_index(self):
|
||||
return self["active_context_brushstrokes_index"]
|
||||
|
||||
def set_active_context_brushstrokes_index(self, value):
|
||||
settings = bpy.context.scene.BSBST_settings
|
||||
scene = self.id_data
|
||||
settings = scene.BSBST_settings
|
||||
|
||||
for window in bpy.context.window_manager.windows:
|
||||
if window.scene == scene:
|
||||
view_layer = window.view_layer
|
||||
active_object = view_layer.objects.active
|
||||
|
||||
if not settings.context_brushstrokes:
|
||||
if not settings.preset_object:
|
||||
return
|
||||
@@ -136,12 +143,11 @@ def set_active_context_brushstrokes_index(self, value):
|
||||
return
|
||||
if not bs_ob:
|
||||
return
|
||||
if not bpy.context.object:
|
||||
if not active_object:
|
||||
return
|
||||
view_layer = bpy.context.view_layer
|
||||
if bpy.context.object.visible_get(view_layer = view_layer):
|
||||
if active_object.visible_get(view_layer = view_layer):
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.context.view_layer.objects.active = bs_ob
|
||||
view_layer.objects.active = bs_ob
|
||||
if bs_ob.visible_get(view_layer = view_layer):
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
for ob in bpy.data.objects:
|
||||
@@ -257,7 +263,7 @@ class BSBST_Settings(bpy.types.PropertyGroup):
|
||||
gpv3 = bpy.context.preferences.experimental.use_grease_pencil_version3
|
||||
except:
|
||||
v0, v1, v3 = bpy.app.version
|
||||
gpv3 = v0 >= 4 and v1 >= 3
|
||||
gpv3 = v0 >= 4 or (v0 == 4 and v1 >= 3)
|
||||
curve_mode: bpy.props.EnumProperty(default='CURVES',
|
||||
items= [('CURVE', 'Legacy', 'Use legacy curve type (Limited Support)', 'CURVE_DATA', 0),\
|
||||
('CURVES', 'Curves', 'Use hair curves (Fully supported)', 'CURVES_DATA', 1),
|
||||
|
||||
@@ -536,7 +536,7 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
|
||||
row = style_panel.row()
|
||||
row_edit = row.row(align=True)
|
||||
row_edit.operator('brushstroke_tools.select_surface', icon='OUTLINER_OB_SURFACE', text='')
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context)
|
||||
bs_ob = utils.get_active_context_brushstrokes_object(context.scene)
|
||||
text = 'Edit Flow' if getattr(bs_ob, '["BSBST_method"]', None)=='SURFACE_FILL' else 'Edit Brushstrokes'
|
||||
row_edit.operator('brushstroke_tools.edit_brushstrokes', icon='GREASEPENCIL', text = text)
|
||||
row_edit.prop(settings, 'edit_toggle', icon='RESTRICT_SELECT_OFF' if settings.edit_toggle else 'RESTRICT_SELECT_ON', icon_only=True)
|
||||
@@ -549,15 +549,15 @@ class BSBST_PT_brushstroke_tools_panel(bpy.types.Panel):
|
||||
|
||||
class BSBST_MT_PIE_brushstroke_data_marking(bpy.types.Menu):
|
||||
bl_idname= "BSBST_MT_PIE_brushstroke_data_marking"
|
||||
bl_label = "Mark Brushstroke Flow"
|
||||
bl_label = "Mark Brushstroke Data"
|
||||
|
||||
items = {
|
||||
"Brush Flow - Mark": ['FORCE_WIND'],
|
||||
"Brush Flow - Clear": ['NONE'],
|
||||
"Brush Break - Mark": ['MOD_PHYSICS'],
|
||||
"Brush Break - Clear": ['NONE'],
|
||||
"Brush Ignore - Mark": ['X'],
|
||||
"Brush Ignore - Clear": ['NONE'],
|
||||
"Brush Flow - Mark": ['geometry.brush_flow_mark','FORCE_WIND'],
|
||||
"Brush Flow - Clear": ['geometry.brush_flow_clear','NONE'],
|
||||
"Brush Break - Mark": ['geometry.brush_break_mark','MOD_PHYSICS'],
|
||||
"Brush Break - Clear": ['geometry.brush_break_clear','NONE'],
|
||||
"Brush Ignore - Mark": ['geometry.brush_ignore_mark','X'],
|
||||
"Brush Ignore - Clear": ['geometry.brush_ignore_clear','NONE'],
|
||||
}
|
||||
|
||||
def draw(self, context):
|
||||
@@ -567,10 +567,13 @@ class BSBST_MT_PIE_brushstroke_data_marking(bpy.types.Menu):
|
||||
|
||||
for name, info in self.items.items():
|
||||
pie.alert=True
|
||||
op = pie.operator("geometry.execute_node_group", text=name, icon=info[0])
|
||||
op.asset_library_type='CUSTOM'
|
||||
op.asset_library_identifier=utils.asset_lib_name
|
||||
op.relative_asset_identifier=f"core/brushstroke_tools-resources.blend/NodeTree/{name}"
|
||||
if bpy.app.version < (5,1):
|
||||
op = pie.operator("geometry.execute_node_group", text=name, icon=info[1])
|
||||
op.asset_library_type='CUSTOM'
|
||||
op.asset_library_identifier=utils.asset_lib_name
|
||||
op.relative_asset_identifier=f"core/brushstroke_tools-resources.blend/NodeTree/{name}"
|
||||
else:
|
||||
op = pie.operator(info[0], text=name, icon=info[1])
|
||||
|
||||
class BSBST_OT_brushstroke_data_marking(bpy.types.Operator):
|
||||
"""
|
||||
|
||||
@@ -37,9 +37,8 @@ linkable_sockets = [
|
||||
asset_lib_name = 'Brushstroke Tools Library'
|
||||
|
||||
@persistent
|
||||
def find_context_brushstrokes(dummy):
|
||||
context = bpy.context
|
||||
settings = context.scene.BSBST_settings
|
||||
def find_context_brushstrokes(scene, depsgraph):
|
||||
settings = scene.BSBST_settings
|
||||
|
||||
edit_toggle = settings.edit_toggle
|
||||
settings.edit_toggle = False
|
||||
@@ -49,7 +48,7 @@ def find_context_brushstrokes(dummy):
|
||||
# identify context brushstrokes
|
||||
for el in range(len(settings.context_brushstrokes)):
|
||||
settings.context_brushstrokes.remove(0)
|
||||
context_object = context.object
|
||||
context_object = depsgraph.view_layer.objects.active
|
||||
if not is_brushstrokes_object(context_object):
|
||||
bs_ob = is_flow_object(context_object)
|
||||
if bs_ob:
|
||||
@@ -97,12 +96,11 @@ def find_context_brushstrokes(dummy):
|
||||
settings.edit_toggle = edit_toggle
|
||||
|
||||
@persistent
|
||||
def refresh_preset(dummy):
|
||||
context = bpy.context
|
||||
settings = context.scene.BSBST_settings
|
||||
def refresh_preset(scene, depsgraph):
|
||||
settings = scene.BSBST_settings
|
||||
if not settings:
|
||||
return
|
||||
for ob in [settings.preset_object, get_active_context_brushstrokes_object(context)]:
|
||||
for ob in [settings.preset_object, get_active_context_brushstrokes_object(scene)]:
|
||||
if not ob:
|
||||
continue
|
||||
for mod in ob.modifiers:
|
||||
@@ -313,6 +311,25 @@ def write_lib_version(dir: Path = None):
|
||||
with open(dir.joinpath(".version"), "w") as file:
|
||||
file.write(str(addon_version))
|
||||
|
||||
def get_file_blend_version(path: Path):
|
||||
with open(path, "rb") as f:
|
||||
prefix = f.read(4)
|
||||
f.seek(0)
|
||||
|
||||
if prefix.startswith(b"BLENDER"):
|
||||
header = f.read(12)
|
||||
|
||||
elif prefix == b"\x28\xb5\x2f\xfd": # zstd
|
||||
dctx = zstd.ZstdDecompressor()
|
||||
with dctx.stream_reader(f) as reader:
|
||||
header = reader.read(12)
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown blend format")
|
||||
|
||||
version = header[9:12].decode()
|
||||
return int(version[0]), int(version[1:])
|
||||
|
||||
def copy_resources_to_dir(tgt_dir = ''):
|
||||
source_dir = get_addon_directory().joinpath('assets')
|
||||
if not tgt_dir:
|
||||
@@ -545,8 +562,21 @@ def find_brush_style_by_name(name: str):
|
||||
return brush_style
|
||||
return None
|
||||
|
||||
def link_to_collections_by_ref(obj, ref_obj):
|
||||
def link_to_collections_by_ref(obj, ref_obj, unlink=True):
|
||||
col_list = []
|
||||
|
||||
if unlink:
|
||||
for col in obj.users_collection:
|
||||
if col.library:
|
||||
continue
|
||||
col_list += [col]
|
||||
|
||||
if col_list:
|
||||
for col in col_list:
|
||||
col.objects.unlink(obj)
|
||||
|
||||
col_list = []
|
||||
|
||||
for col in ref_obj.users_collection:
|
||||
if col.library:
|
||||
continue
|
||||
@@ -754,8 +784,8 @@ def context_brushstrokes(context):
|
||||
settings = context.scene.BSBST_settings
|
||||
return settings.context_brushstrokes
|
||||
|
||||
def get_active_context_brushstrokes_object(context):
|
||||
settings = context.scene.BSBST_settings
|
||||
def get_active_context_brushstrokes_object(scene):
|
||||
settings = scene.BSBST_settings
|
||||
if not settings.context_brushstrokes:
|
||||
return None
|
||||
bs = settings.context_brushstrokes[settings.active_context_brushstrokes_index]
|
||||
@@ -765,19 +795,22 @@ def get_active_context_brushstrokes_object(context):
|
||||
def get_active_context_surface_object(context):
|
||||
if not context.object:
|
||||
return None
|
||||
bs_ob = get_active_context_brushstrokes_object(context)
|
||||
bs_ob = get_active_context_brushstrokes_object(context.scene)
|
||||
if bs_ob:
|
||||
return get_surface_object(bs_ob)
|
||||
if context.object.type == 'MESH':
|
||||
return context.object
|
||||
|
||||
def flow_name(name):
|
||||
return f'{name}-FLOW'
|
||||
def bs_name(surf_name: str) -> str:
|
||||
return f'{surf_name} - Brushstrokes'
|
||||
|
||||
def flow_name(bs_name: str) -> str:
|
||||
return f'{bs_name}-FLOW'
|
||||
|
||||
def edit_active_brushstrokes(context):
|
||||
context.view_layer.depsgraph.update()
|
||||
|
||||
bs_ob = get_active_context_brushstrokes_object(context)
|
||||
bs_ob = get_active_context_brushstrokes_object(context.scene)
|
||||
if not bs_ob:
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"id": "rainclouds_bulk_scene_tools",
|
||||
"name": "Raincloud's Bulk Scene Tools",
|
||||
"tagline": "Bulk utilities for optimizing scene data",
|
||||
"version": "0.16.0",
|
||||
"version": "0.17.0",
|
||||
"type": "add-on",
|
||||
"maintainer": "RaincloudTheDragon <raincloudthedragon@gmail.com>",
|
||||
"license": [
|
||||
@@ -49,9 +49,9 @@
|
||||
"Workflow",
|
||||
"Materials"
|
||||
],
|
||||
"archive_url": "https://github.com/RaincloudTheDragon/Rainys-Bulk-Scene-Tools/releases/download/v0.16.0/Rainys_Bulk_Scene_Tools.v0.16.0.zip",
|
||||
"archive_size": 80251,
|
||||
"archive_hash": "sha256:3e6fafe11caa39e48b94288c12b2a88e521c928955a854ffdd1bd0936e6bc70a"
|
||||
"archive_url": "https://github.com/RaincloudTheDragon/Rainys-Bulk-Scene-Tools/releases/download/v0.17.0/Rainys_Bulk_Scene_Tools.v0.17.0.zip",
|
||||
"archive_size": 80981,
|
||||
"archive_hash": "sha256:419433069465b45ea903bd7bb46d89aa28b9c96c541d587d5f3be651a762811f"
|
||||
},
|
||||
{
|
||||
"schema_version": "1.0.0",
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"version": "v1",
|
||||
"blocklist": [],
|
||||
"data": [
|
||||
{
|
||||
"schema_version": "1.0.0",
|
||||
"id": "basedplayblast",
|
||||
"name": "BasedPlayblast",
|
||||
"tagline": "Easily create playblasts from Blender and Flamenco",
|
||||
"version": "2.6.3",
|
||||
"type": "add-on",
|
||||
"maintainer": "RaincloudTheDragon <raincloudthedragon@gmail.com>",
|
||||
"license": [
|
||||
"GPL-3.0-or-later"
|
||||
],
|
||||
"blender_version_min": "4.2.0",
|
||||
"website": "https://github.com/RaincloudTheDragon/BasedPlayblast",
|
||||
"permissions": {
|
||||
"files": "Import/export files and data"
|
||||
},
|
||||
"tags": [
|
||||
"Animation",
|
||||
"Render",
|
||||
"Workflow",
|
||||
"Video"
|
||||
],
|
||||
"archive_url": "https://github.com/RaincloudTheDragon/BasedPlayblast/releases/download/v2.6.3/BasedPlayblast.v2.6.3.zip",
|
||||
"archive_size": 49732,
|
||||
"archive_hash": "sha256:078b406105ce6f4802e75233569841e2f73d082e09cd1d954696681ebf72b627"
|
||||
},
|
||||
{
|
||||
"schema_version": "1.0.0",
|
||||
"id": "rainclouds_bulk_scene_tools",
|
||||
"name": "Raincloud's Bulk Scene Tools",
|
||||
"tagline": "Bulk utilities for optimizing scene data",
|
||||
"version": "0.17.0",
|
||||
"type": "add-on",
|
||||
"maintainer": "RaincloudTheDragon <raincloudthedragon@gmail.com>",
|
||||
"license": [
|
||||
"GPL-3.0-or-later"
|
||||
],
|
||||
"blender_version_min": "4.2.0",
|
||||
"website": "https://github.com/RaincloudTheDragon/Rainys-Bulk-Scene-Tools",
|
||||
"permissions": {
|
||||
"files": "Read and write external resources referenced by scenes"
|
||||
},
|
||||
"tags": [
|
||||
"Scene",
|
||||
"Workflow",
|
||||
"Materials"
|
||||
],
|
||||
"archive_url": "https://github.com/RaincloudTheDragon/Rainys-Bulk-Scene-Tools/releases/download/v0.17.0/Rainys_Bulk_Scene_Tools.v0.17.0.zip",
|
||||
"archive_size": 80981,
|
||||
"archive_hash": "sha256:419433069465b45ea903bd7bb46d89aa28b9c96c541d587d5f3be651a762811f"
|
||||
},
|
||||
{
|
||||
"schema_version": "1.0.0",
|
||||
"id": "atomic_data_manager",
|
||||
"name": "Atomic Data Manager",
|
||||
"tagline": "Smart cleanup and inspection of Blender data-blocks",
|
||||
"version": "2.5.0",
|
||||
"type": "add-on",
|
||||
"maintainer": "RaincloudTheDragon",
|
||||
"license": [
|
||||
"GPL-3.0-or-later"
|
||||
],
|
||||
"blender_version_min": "4.2.0",
|
||||
"tags": [
|
||||
"utility",
|
||||
"management",
|
||||
"cleanup"
|
||||
],
|
||||
"archive_url": "https://github.com/RaincloudTheDragon/atomic-data-manager/releases/download/v2.5.0/Atomic_Data_Manager.v2.5.0.zip",
|
||||
"archive_size": 114674,
|
||||
"archive_hash": "sha256:4b4834ed3910a428d4cb01f1891247ad80089b6c5324fc27c6862b09e81ff1c1"
|
||||
},
|
||||
{
|
||||
"schema_version": "1.0.0",
|
||||
"id": "sheepit_project_submitter",
|
||||
"name": "SheepIt Project Submitter",
|
||||
"tagline": "Submit projects to SheepIt render farm",
|
||||
"version": "0.0.7",
|
||||
"type": "add-on",
|
||||
"maintainer": "RaincloudTheDragon",
|
||||
"license": [
|
||||
"GPL-3.0-or-later"
|
||||
],
|
||||
"blender_version_min": "3.0.0",
|
||||
"tags": [
|
||||
"render",
|
||||
"farm",
|
||||
"submission",
|
||||
"utility"
|
||||
],
|
||||
"archive_url": "https://github.com/RaincloudTheDragon/sheepit_project_submitter/releases/download/v0.0.7/SheepIt_Project_Submitter.v0.0.7.zip",
|
||||
"archive_size": 47250,
|
||||
"archive_hash": "sha256:cb8dee48c45cc51dd8237981f4ab96d97d476b547c8c640606e9bbfd0390a055"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,7 @@ schema_version = "1.0.0"
|
||||
id = "rainclouds_bulk_scene_tools"
|
||||
name = "Raincloud's Bulk Scene Tools"
|
||||
tagline = "Bulk utilities for optimizing scene data"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
type = "add-on"
|
||||
|
||||
maintainer = "RaincloudTheDragon <raincloudthedragon@gmail.com>"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# v0.17.0 2026-03-13
|
||||
- Remove Action FU: new operator in Animation Data section—clears fake users from all actions so only used animations are kept
|
||||
|
||||
# v0.16.0 2026-01-15
|
||||
- Delete Single Keyframe Actions: Blender 5.0 compatible (action layers/strips/channelbags); skip actions from linked libraries
|
||||
- Find Material Users: removed (issue #14; use Atomic or DBU)
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class RemoveActionFakeUsers(bpy.types.Operator):
|
||||
"""Remove fake users from all actions so only used animations are kept on save"""
|
||||
bl_idname = "bst.remove_action_fake_users"
|
||||
bl_label = "Remove Action FU"
|
||||
bl_description = "Remove fake users from all actions so only used animations are kept"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
actions = bpy.data.actions
|
||||
cleared_count = 0
|
||||
|
||||
for action in actions:
|
||||
if getattr(action, "library", None) is not None:
|
||||
continue
|
||||
if action.use_fake_user:
|
||||
action.use_fake_user = False
|
||||
cleared_count += 1
|
||||
print(f"Removed fake user from action '{action.name}'")
|
||||
|
||||
self.report({'INFO'}, f"Removed fake users from {cleared_count} actions")
|
||||
return {'FINISHED'}
|
||||
@@ -6,6 +6,7 @@ from ..ops.spawn_scene_structure import SpawnSceneStructure
|
||||
from ..ops.delete_single_keyframe_actions import DeleteSingleKeyframeActions
|
||||
from ..ops.remove_unused_material_slots import RemoveUnusedMaterialSlots
|
||||
from ..ops.convert_relations_to_constraint import ConvertRelationsToConstraint
|
||||
from ..ops.remove_action_fake_users import RemoveActionFakeUsers
|
||||
from ..ops.white_world import WhiteWorld
|
||||
from ..utils import compat
|
||||
|
||||
@@ -56,6 +57,8 @@ class RBST_SceneGen_PT_BulkSceneGeneral(bpy.types.Panel):
|
||||
box = layout.box()
|
||||
box.label(text="Animation Data")
|
||||
row = box.row(align=True)
|
||||
row.operator("bst.remove_action_fake_users", text="Remove Action FU", icon='FAKE_USER_OFF')
|
||||
row = box.row(align=True)
|
||||
row.operator("bst.delete_single_keyframe_actions", text="Delete Single Keyframe Actions", icon='ANIM_DATA')
|
||||
row = box.row(align=True)
|
||||
row.operator("bst.convert_relations_to_constraint", text="Convert Relations to Constraint", icon_value=405)
|
||||
@@ -71,6 +74,7 @@ classes = (
|
||||
DeleteSingleKeyframeActions,
|
||||
RemoveUnusedMaterialSlots,
|
||||
ConvertRelationsToConstraint,
|
||||
RemoveActionFakeUsers,
|
||||
)
|
||||
|
||||
# Registration
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"last_check": "2026-03-06 10:02:06.473451",
|
||||
"last_check": "2026-03-16 11:19:55.639825",
|
||||
"backup_date": "January-12-2026",
|
||||
"update_ready": false,
|
||||
"ignore": false,
|
||||
|
||||
@@ -3,7 +3,7 @@ schema_version = "1.0.0"
|
||||
id = "dynamiclinkmanager"
|
||||
name = "Dynamic Link Manager"
|
||||
tagline = "Character migrator and linked library tools"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
type = "add-on"
|
||||
|
||||
# Optional: Semantic Versioning
|
||||
|
||||
@@ -482,14 +482,36 @@ def run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep):
|
||||
for ob in candidates:
|
||||
if ob.parent == orig:
|
||||
ob.parent = rep
|
||||
for c in getattr(ob, "constraints", []):
|
||||
if getattr(c, "target", None) == orig:
|
||||
c.target = rep
|
||||
if ob.type == "MESH" and ob.modifiers:
|
||||
for m in ob.modifiers:
|
||||
if getattr(m, "object", None) == orig:
|
||||
m.object = rep
|
||||
|
||||
# Retarget constraints on ALL objects (including orig hierarchy like eyes)
|
||||
for ob in bpy.data.objects:
|
||||
for c in getattr(ob, "constraints", []):
|
||||
if getattr(c, "target", None) == orig:
|
||||
c.target = rep
|
||||
|
||||
# Retarget bone constraints on ALL armatures (other characters, etc.)
|
||||
for ob in bpy.data.objects:
|
||||
if ob.type != "ARMATURE" or not ob.pose:
|
||||
continue
|
||||
for pbone in ob.pose.bones:
|
||||
for c in pbone.constraints:
|
||||
if getattr(c, "target", None) == orig:
|
||||
c.target = rep
|
||||
|
||||
# Camera DOF: retarget focus_object from orig to rep
|
||||
for ob in bpy.data.objects:
|
||||
if ob.type != 'CAMERA':
|
||||
continue
|
||||
camera = ob.data
|
||||
if not camera.dof:
|
||||
continue
|
||||
if camera.dof.focus_object == orig:
|
||||
camera.dof.focus_object = rep
|
||||
|
||||
|
||||
def _base_body_name_match(ob):
|
||||
"""True if object looks like the base body mesh (MESH, name has body+base)."""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
"""Tweak tools: add/remove/bake COPY_TRANSFORMS on Rigify arm/leg tweak bones."""
|
||||
"""Tweak tools: add/remove/bake COPY_TRANSFORMS on Rigify tweak bones (arm, leg, or all)."""
|
||||
|
||||
import bpy
|
||||
|
||||
@@ -22,7 +22,7 @@ TWEAK_CONSTRAINT_NAME = "Copy from Original"
|
||||
|
||||
|
||||
def get_tweak_bones(armature, limb):
|
||||
"""Return list of tweak bone names that exist on armature. limb in 'arm', 'leg', 'both'."""
|
||||
"""Return list of tweak bone names that exist on armature. limb in 'arm', 'leg', 'body', 'both'."""
|
||||
if not armature or armature.type != "ARMATURE" or not armature.pose:
|
||||
return []
|
||||
bones = armature.pose.bones
|
||||
@@ -30,8 +30,20 @@ def get_tweak_bones(armature, limb):
|
||||
names = ARM_TWEAK_BONES
|
||||
elif limb == "leg":
|
||||
names = LEG_TWEAK_BONES
|
||||
elif limb == "body":
|
||||
# Body/torso tweaks: tweak_spine, spine_fk, etc. (no arm/leg)
|
||||
arm_leg_names = set(ARM_TWEAK_BONES + LEG_TWEAK_BONES)
|
||||
names = [
|
||||
b.name for b in bones
|
||||
if ("tweak" in b.name.lower() or "spine_fk" in b.name.lower())
|
||||
and b.name not in arm_leg_names
|
||||
]
|
||||
elif limb == "both":
|
||||
names = ARM_TWEAK_BONES + LEG_TWEAK_BONES
|
||||
# ALL tweak bones: any bone with "tweak" or "spine_fk" in the name
|
||||
names = [
|
||||
b.name for b in bones
|
||||
if "tweak" in b.name.lower() or "spine_fk" in b.name.lower()
|
||||
]
|
||||
else:
|
||||
return []
|
||||
return [n for n in names if n in bones]
|
||||
@@ -101,7 +113,7 @@ def bake_tweak_constraints(context, orig, rep, limb, track_name, post_clean):
|
||||
# Select only tweak bones on rep
|
||||
bpy.ops.pose.select_all(action="DESELECT")
|
||||
for name in names:
|
||||
rep.pose.bones[name].bone.select = True
|
||||
rep.pose.bones[name].select = True
|
||||
|
||||
# Bake
|
||||
try:
|
||||
|
||||
@@ -735,10 +735,72 @@ class DLM_OT_tweak_bake_leg(Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
class DLM_OT_tweak_add_body(Operator):
|
||||
bl_idname = "dlm.tweak_add_body"
|
||||
bl_label = "Add Body Tweaks"
|
||||
bl_description = "Add tweak bone constraints to body/torso bones (spine, no arm/leg)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return _tweak_poll(context)
|
||||
|
||||
def execute(self, context):
|
||||
orig, rep = _get_migrator_pair(context)
|
||||
from ..ops import tweak_tools
|
||||
tweak_tools.add_tweak_constraints(orig, rep, "body")
|
||||
self.report({"INFO"}, "Body tweak constraints added.")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DLM_OT_tweak_remove_body(Operator):
|
||||
bl_idname = "dlm.tweak_remove_body"
|
||||
bl_label = "Remove Body Tweaks"
|
||||
bl_description = "Remove body/torso tweak constraints from the replacement character"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return _tweak_poll(context)
|
||||
|
||||
def execute(self, context):
|
||||
orig, rep = _get_migrator_pair(context)
|
||||
from ..ops import tweak_tools
|
||||
n = tweak_tools.remove_tweak_constraints(orig, rep, "body")
|
||||
self.report({"INFO"}, f"Removed {n} body tweak constraints.")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DLM_OT_tweak_bake_body(Operator):
|
||||
bl_idname = "dlm.tweak_bake_body"
|
||||
bl_label = "Bake Body Tweaks"
|
||||
bl_description = "Bake body/torso tweak constraints to keyframes and optionally remove constraints"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return _tweak_poll(context)
|
||||
|
||||
def execute(self, context):
|
||||
orig, rep = _get_migrator_pair(context)
|
||||
props = context.scene.dynamic_link_manager
|
||||
from ..ops import tweak_tools
|
||||
ok, msg = tweak_tools.bake_tweak_constraints(
|
||||
context, orig, rep, "body",
|
||||
getattr(props, "tweak_nla_track_name", "") or "",
|
||||
getattr(props, "tweak_bake_post_clean", False),
|
||||
)
|
||||
if ok:
|
||||
self.report({"INFO"}, msg)
|
||||
return {"FINISHED"}
|
||||
self.report({"ERROR"}, msg)
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
class DLM_OT_tweak_add_both(Operator):
|
||||
bl_idname = "dlm.tweak_add_both"
|
||||
bl_label = "Add Arm & Leg Tweaks"
|
||||
bl_description = "Add tweak bone constraints to both arm and leg bones"
|
||||
bl_label = "Add All Tweaks"
|
||||
bl_description = "Add tweak bone constraints to all tweak bones (arm, leg, body)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
@@ -749,14 +811,14 @@ class DLM_OT_tweak_add_both(Operator):
|
||||
orig, rep = _get_migrator_pair(context)
|
||||
from ..ops import tweak_tools
|
||||
tweak_tools.add_tweak_constraints(orig, rep, "both")
|
||||
self.report({"INFO"}, "Arm & leg tweak constraints added.")
|
||||
self.report({"INFO"}, "All tweak constraints added.")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DLM_OT_tweak_remove_both(Operator):
|
||||
bl_idname = "dlm.tweak_remove_both"
|
||||
bl_label = "Remove Arm & Leg Tweaks"
|
||||
bl_description = "Remove all arm and leg tweak constraints from the replacement character"
|
||||
bl_label = "Remove All Tweaks"
|
||||
bl_description = "Remove all tweak constraints from the replacement character"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
@@ -773,8 +835,8 @@ class DLM_OT_tweak_remove_both(Operator):
|
||||
|
||||
class DLM_OT_tweak_bake_both(Operator):
|
||||
bl_idname = "dlm.tweak_bake_both"
|
||||
bl_label = "Bake Arm & Leg Tweaks"
|
||||
bl_description = "Bake all arm and leg tweak constraints to keyframes and optionally remove constraints"
|
||||
bl_label = "Bake All Tweaks"
|
||||
bl_description = "Bake all tweak constraints (arm, leg, body) to keyframes and optionally remove constraints"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
@@ -825,6 +887,9 @@ OPERATOR_CLASSES = [
|
||||
DLM_OT_tweak_add_leg,
|
||||
DLM_OT_tweak_remove_leg,
|
||||
DLM_OT_tweak_bake_leg,
|
||||
DLM_OT_tweak_add_body,
|
||||
DLM_OT_tweak_remove_body,
|
||||
DLM_OT_tweak_bake_body,
|
||||
DLM_OT_tweak_add_both,
|
||||
DLM_OT_tweak_remove_both,
|
||||
DLM_OT_tweak_bake_both,
|
||||
|
||||
@@ -119,9 +119,13 @@ class DLM_PT_main_panel(Panel):
|
||||
row.operator("dlm.tweak_remove_leg", text="Remove Leg", icon="X")
|
||||
row.operator("dlm.tweak_bake_leg", text="Bake Leg", icon="KEYFRAME")
|
||||
row = tweak_box.row(align=True)
|
||||
row.operator("dlm.tweak_add_both", text="Add Both", icon="CONSTRAINT_BONE")
|
||||
row.operator("dlm.tweak_remove_both", text="Remove Both", icon="X")
|
||||
row.operator("dlm.tweak_bake_both", text="Bake Both", icon="KEYFRAME")
|
||||
row.operator("dlm.tweak_add_body", text="Add Body", icon="CONSTRAINT_BONE")
|
||||
row.operator("dlm.tweak_remove_body", text="Remove Body", icon="X")
|
||||
row.operator("dlm.tweak_bake_body", text="Bake Body", icon="KEYFRAME")
|
||||
row = tweak_box.row(align=True)
|
||||
row.operator("dlm.tweak_add_both", text="Add All", icon="CONSTRAINT_BONE")
|
||||
row.operator("dlm.tweak_remove_both", text="Remove All", icon="X")
|
||||
row.operator("dlm.tweak_bake_both", text="Bake All", icon="KEYFRAME")
|
||||
row = tweak_box.row()
|
||||
row.prop(props, "tweak_nla_track_name", text="NLA track")
|
||||
row = tweak_box.row()
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
keyconfig_version = (4, 3, 29)
|
||||
keyconfig_version = (5, 0, 118)
|
||||
keyconfig_data = \
|
||||
[("3D View",
|
||||
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
|
||||
@@ -1519,11 +1519,6 @@ keyconfig_data = \
|
||||
),
|
||||
("anim.change_frame", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None),
|
||||
("action.duplicate_move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
("action.keymove",
|
||||
{"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("action.keymove",
|
||||
{"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True},
|
||||
{ "active":False,
|
||||
@@ -1591,11 +1586,7 @@ keyconfig_data = \
|
||||
],
|
||||
},
|
||||
),
|
||||
("screen.animation_play",
|
||||
{"type": 'SPACE', "value": 'PRESS', "repeat": True},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("screen.animation_play", {"type": 'V', "value": 'PRESS', "alt": True, "repeat": True}, None),
|
||||
("screen.animation_play",
|
||||
{"type": 'SPACE', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True},
|
||||
{"properties":
|
||||
@@ -1956,38 +1947,10 @@ keyconfig_data = \
|
||||
("Grease Pencil Stroke Paint (Draw brush)",
|
||||
{"space_type": 'EMPTY', "region_type": 'WINDOW'},
|
||||
{"items":
|
||||
[("gpencil.draw",
|
||||
{"type": 'LEFTMOUSE', "value": 'PRESS'},
|
||||
{"properties":
|
||||
[("mode", 'DRAW'),
|
||||
("wait_for_input", False),
|
||||
],
|
||||
},
|
||||
),
|
||||
("gpencil.draw",
|
||||
{"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties":
|
||||
[("mode", 'DRAW'),
|
||||
("wait_for_input", False),
|
||||
],
|
||||
},
|
||||
),
|
||||
("gpencil.draw",
|
||||
{"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "alt": True},
|
||||
{"properties":
|
||||
[("mode", 'DRAW_STRAIGHT'),
|
||||
("wait_for_input", False),
|
||||
],
|
||||
},
|
||||
),
|
||||
("gpencil.draw",
|
||||
{"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties":
|
||||
[("mode", 'ERASER'),
|
||||
("wait_for_input", False),
|
||||
],
|
||||
},
|
||||
),
|
||||
[("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "alt": True}, None),
|
||||
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("gpencil.draw", {"type": 'O', "value": 'PRESS'}, None),
|
||||
("gpencil.draw", {"type": 'J', "value": 'PRESS'}, None),
|
||||
("gpencil.draw", {"type": 'J', "value": 'PRESS', "alt": True}, None),
|
||||
@@ -2002,14 +1965,7 @@ keyconfig_data = \
|
||||
("gpencil.draw", {"type": 'M', "value": 'PRESS'}, None),
|
||||
("gpencil.draw", {"type": 'C', "value": 'PRESS'}, None),
|
||||
("gpencil.draw", {"type": 'C', "value": 'PRESS', "alt": True}, None),
|
||||
("gpencil.draw",
|
||||
{"type": 'ERASER', "value": 'PRESS'},
|
||||
{"properties":
|
||||
[("mode", 'ERASER'),
|
||||
("wait_for_input", False),
|
||||
],
|
||||
},
|
||||
),
|
||||
("gpencil.draw", {"type": 'ERASER', "value": 'PRESS'}, None),
|
||||
("gpencil.select_box", {"type": 'B', "value": 'PRESS'}, None),
|
||||
("gpencil.select_lasso", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
|
||||
],
|
||||
@@ -2838,11 +2794,9 @@ keyconfig_data = \
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("wm.call_menu",
|
||||
{"type": 'DEL', "value": 'PRESS', "repeat": True},
|
||||
{"properties":
|
||||
[("name", 'VIEW3D_MT_edit_mesh_delete'),
|
||||
],
|
||||
("object.swapmode",
|
||||
{"type": 'MIDDLEMOUSE', "value": 'DOUBLE_CLICK'},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("object.swapmode",
|
||||
@@ -2850,6 +2804,23 @@ keyconfig_data = \
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("object.swapmode",
|
||||
{"type": 'MIDDLEMOUSE', "value": 'DOUBLE_CLICK'},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("object.swapmode",
|
||||
{"type": 'MIDDLEMOUSE', "value": 'DOUBLE_CLICK'},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("wm.call_menu",
|
||||
{"type": 'DEL', "value": 'PRESS', "repeat": True},
|
||||
{"properties":
|
||||
[("name", 'VIEW3D_MT_edit_mesh_delete'),
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
@@ -3014,6 +2985,11 @@ keyconfig_data = \
|
||||
("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS', "repeat": True}, None),
|
||||
("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True, "repeat": True}, None),
|
||||
("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": True}, None),
|
||||
("collection.create",
|
||||
{"type": 'G', "value": 'PRESS', "ctrl": True, "repeat": True},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("collection.objects_remove", {"type": 'G', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": True}, None),
|
||||
("collection.objects_remove_all", {"type": 'G', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": True}, None),
|
||||
("collection.objects_add_active", {"type": 'G', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, None),
|
||||
@@ -3211,7 +3187,7 @@ keyconfig_data = \
|
||||
],
|
||||
},
|
||||
),
|
||||
("object.pivotlock", {"type": 'V', "value": 'PRESS', "repeat": True}, None),
|
||||
("object.pivotlock", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
|
||||
("object.hideorigin", {"type": 'D', "value": 'PRESS', "repeat": True}, None),
|
||||
("theme.double", {"type": 'B', "value": 'PRESS', "alt": True, "repeat": True}, None),
|
||||
("object.keygridsnap", {"type": 'G', "value": 'PRESS', "key_modifier": 'D', "repeat": True}, None),
|
||||
@@ -3413,7 +3389,6 @@ keyconfig_data = \
|
||||
("outliner.drivers_add_selected", {"type": 'D', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
|
||||
("outliner.drivers_delete_selected", {"type": 'D', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": True}, None),
|
||||
("outliner.collection_new", {"type": 'C', "value": 'PRESS', "repeat": True}, None),
|
||||
("outliner.collection_delete", {"type": 'X', "value": 'PRESS', "repeat": True}, None),
|
||||
("outliner.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, None),
|
||||
("object.move_to_collection", {"type": 'M', "value": 'PRESS', "repeat": True}, None),
|
||||
("object.link_to_collection", {"type": 'M', "value": 'PRESS', "shift": True, "repeat": True}, None),
|
||||
@@ -3528,6 +3503,7 @@ keyconfig_data = \
|
||||
("outliner.show_active", {"type": 'F', "value": 'PRESS', "repeat": True}, None),
|
||||
("outliner.item_rename", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
|
||||
("object.move_to_collection", {"type": 'G', "value": 'PRESS', "ctrl": True}, None),
|
||||
("outliner.delete", {"type": 'X', "value": 'PRESS'}, None),
|
||||
],
|
||||
},
|
||||
),
|
||||
@@ -4306,6 +4282,7 @@ keyconfig_data = \
|
||||
{"properties":
|
||||
[("extend", False),
|
||||
],
|
||||
"active":False,
|
||||
},
|
||||
),
|
||||
("uv.select",
|
||||
@@ -4503,14 +4480,13 @@ keyconfig_data = \
|
||||
},
|
||||
),
|
||||
("wm.call_menu",
|
||||
{"type": 'E', "value": 'PRESS', "repeat": True},
|
||||
{"type": 'RIGHTMOUSE', "value": 'PRESS'},
|
||||
{"properties":
|
||||
[("name", 'IMAGE_MT_uvs_specials'),
|
||||
[("name", 'IMAGE_MT_uvs_context_menu'),
|
||||
],
|
||||
"active":False,
|
||||
},
|
||||
),
|
||||
("uv.cursor_set", {"type": 'LEFTMOUSE', "value": 'CLICK'}, None),
|
||||
("uv.cursor_set", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True}, None),
|
||||
("wm.tool_set_by_name", {"type": 'Q', "value": 'PRESS', "repeat": True}, None),
|
||||
("wm.tool_set_by_name", {"type": 'W', "value": 'PRESS', "repeat": True}, None),
|
||||
("wm.tool_set_by_id",
|
||||
@@ -4541,6 +4517,7 @@ keyconfig_data = \
|
||||
],
|
||||
},
|
||||
),
|
||||
("uv.select", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
],
|
||||
},
|
||||
),
|
||||
@@ -4595,6 +4572,24 @@ keyconfig_data = \
|
||||
("ui.list_start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
|
||||
("ui.view_start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
|
||||
("anim.keyframe_insert_by_name", {"type": 'S', "value": 'PRESS'}, None),
|
||||
("ui.view_item_select", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("ui.view_item_select",
|
||||
{"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties":
|
||||
[("extend", True),
|
||||
],
|
||||
},
|
||||
),
|
||||
("ui.view_item_select",
|
||||
{"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties":
|
||||
[("range_select", True),
|
||||
],
|
||||
},
|
||||
),
|
||||
("ui.view_scroll", {"type": 'WHEELUPMOUSE', "value": 'ANY'}, None),
|
||||
("ui.view_scroll", {"type": 'WHEELDOWNMOUSE', "value": 'ANY'}, None),
|
||||
("ui.view_scroll", {"type": 'TRACKPADPAN', "value": 'ANY'}, None),
|
||||
],
|
||||
},
|
||||
),
|
||||
@@ -4603,12 +4598,7 @@ keyconfig_data = \
|
||||
{"items":
|
||||
[("view2d.scroller_activate", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("view2d.scroller_activate", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None),
|
||||
("view2d.pan",
|
||||
{"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True},
|
||||
{ "active":False,
|
||||
},
|
||||
),
|
||||
("view2d.pan", {"type": 'TRACKPADPAN', "value": 'ANY'}, None),
|
||||
("view2d.pan", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None),
|
||||
("view2d.scroll_right", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("view2d.scroll_left", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("view2d.scroll_down", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
@@ -4670,8 +4660,8 @@ keyconfig_data = \
|
||||
{"type": 'F', "value": 'PRESS', "repeat": True},
|
||||
{"properties":
|
||||
[("data_path_primary", 'tool_settings.weight_paint.brush.size'),
|
||||
("data_path_secondary", 'tool_settings.unified_paint_settings.size'),
|
||||
("use_secondary", 'tool_settings.unified_paint_settings.use_unified_size'),
|
||||
("data_path_secondary", 'tool_settings.weight_paint.unified_paint_settings.size'),
|
||||
("use_secondary", 'tool_settings.weight_paint.unified_paint_settings.use_unified_size'),
|
||||
("rotation_path", 'tool_settings.weight_paint.brush.texture_slot.angle'),
|
||||
("color_path", 'tool_settings.weight_paint.brush.cursor_color_add'),
|
||||
("fill_color_path", ''),
|
||||
@@ -4687,8 +4677,8 @@ keyconfig_data = \
|
||||
{"type": 'F', "value": 'PRESS', "shift": True, "repeat": True},
|
||||
{"properties":
|
||||
[("data_path_primary", 'tool_settings.weight_paint.brush.strength'),
|
||||
("data_path_secondary", 'tool_settings.unified_paint_settings.strength'),
|
||||
("use_secondary", 'tool_settings.unified_paint_settings.use_unified_strength'),
|
||||
("data_path_secondary", 'tool_settings.weight_paint.unified_paint_settings.strength'),
|
||||
("use_secondary", 'tool_settings.weight_paint.unified_paint_settings.use_unified_strength'),
|
||||
("rotation_path", 'tool_settings.weight_paint.brush.texture_slot.angle'),
|
||||
("color_path", 'tool_settings.weight_paint.brush.cursor_color_add'),
|
||||
("fill_color_path", ''),
|
||||
@@ -4704,8 +4694,8 @@ keyconfig_data = \
|
||||
{"type": 'F', "value": 'PRESS', "ctrl": True, "repeat": True},
|
||||
{"properties":
|
||||
[("data_path_primary", 'tool_settings.weight_paint.brush.weight'),
|
||||
("data_path_secondary", 'tool_settings.unified_paint_settings.weight'),
|
||||
("use_secondary", 'tool_settings.unified_paint_settings.use_unified_weight'),
|
||||
("data_path_secondary", 'tool_settings.weight_paint.unified_paint_settings.weight'),
|
||||
("use_secondary", 'tool_settings.weight_paint.unified_paint_settings.use_unified_weight'),
|
||||
("rotation_path", 'tool_settings.weight_paint.brush.texture_slot.angle'),
|
||||
("color_path", 'tool_settings.weight_paint.brush.cursor_color_add'),
|
||||
("fill_color_path", ''),
|
||||
|
||||
Reference in New Issue
Block a user