EasyWeight: Major update #317

Merged
Demeter Dzadik merged 9 commits from easyweight-updates into main 2024-06-25 21:09:03 +02:00
3 changed files with 63 additions and 29 deletions
Showing only changes of commit 5f25bc43f7 - Show all commits

View File

@ -17,11 +17,27 @@ class EASYWEIGHT_addon_preferences(bpy.types.AddonPreferences):
bl_idname = __package__ bl_idname = __package__
easyweight_keymap_items = {} easyweight_keymap_items = {}
always_show_zero_weights: BoolProperty(
name="Always Show Zero Weights",
description="A lack of weights will always be indicated with black color to differentiate it from a weight of 0.0 being assigned",
default=True,
)
always_auto_normalize: BoolProperty(
name="Always Auto Normalize",
description="Weight auto-normalization will always be turned on, so the sum of all deforming weights on a vertex always add up to 1",
default=True,
)
always_multipaint: BoolProperty(
name="Always Multi-Paint",
description="Multi-paint will always be turned on, allowing you to select more than one deforming bone while weight painting",
default=True,
)
auto_clean_weights: BoolProperty( auto_clean_weights: BoolProperty(
name="Auto Clean", name="Always Auto Clean",
description="While this is enabled, zero-weights will be removed automatically after every brush stroke", description="While this is enabled, zero-weights will be removed automatically after every brush stroke",
default=True, default=True,
) )
show_hotkeys: BoolProperty( show_hotkeys: BoolProperty(
name="Show Hotkeys", name="Show Hotkeys",
description="Reveal the hotkey list. You may customize or disable these hotkeys", description="Reveal the hotkey list. You may customize or disable these hotkeys",
@ -33,6 +49,12 @@ class EASYWEIGHT_addon_preferences(bpy.types.AddonPreferences):
layout.use_property_split = True layout.use_property_split = True
layout.use_property_decorate = False layout.use_property_decorate = False
col = layout.column()
col.prop(self, 'auto_clean_weights')
col.prop(self, 'always_show_zero_weights')
col.prop(self, 'always_auto_normalize')
col.prop(self, 'always_multipaint')
main_col = layout.column(align=True) main_col = layout.column(align=True)
hotkey_col = self.draw_fake_dropdown(main_col, self, 'show_hotkeys', "Hotkeys") hotkey_col = self.draw_fake_dropdown(main_col, self, 'show_hotkeys', "Hotkeys")
if self.show_hotkeys: if self.show_hotkeys:

View File

@ -1,5 +1,6 @@
import bpy import bpy
from bpy.types import Object, Operator, VIEW3D_MT_paint_weight, VIEW3D_MT_object from bpy.types import Object, Operator, VIEW3D_MT_paint_weight, VIEW3D_MT_object
from .prefs import get_addon_prefs
# This operator is added to the Object menu. # This operator is added to the Object menu.
@ -27,22 +28,31 @@ def enter_wp(context) -> bool:
obj = context.object obj = context.object
wm = context.window_manager wm = context.window_manager
# Store old shading settings in a Custom Property dictionary in the Scene. prefs = get_addon_prefs(context)
if 'wpt' not in wm: tool_settings = context.scene.tool_settings
wm['wpt'] = {} if prefs.always_show_zero_weights:
tool_settings.vertex_group_user = 'ACTIVE'
if prefs.always_auto_normalize:
tool_settings.use_auto_normalize = True
if prefs.always_multipaint:
tool_settings.use_multipaint = True
wpt = wm['wpt'] # Store old shading settings in a Custom Property dictionary in the WindowManager.
wpt_as_dict = wpt.to_dict() if 'weight_paint_toggle' not in wm:
wm['weight_paint_toggle'] = {}
wp_toggle = wm['weight_paint_toggle']
wp_toggle_as_dict = wp_toggle.to_dict()
# If we are entering WP mode for the first time or if the last time # If we are entering WP mode for the first time or if the last time
# the operator was exiting WP mode, then save current state. # the operator was exiting WP mode, then save current state.
if 'last_switch_in' not in wpt_as_dict or wpt_as_dict['last_switch_in'] == False: if 'last_switch_in' not in wp_toggle_as_dict or wp_toggle_as_dict['last_switch_in'] == False:
wpt['active_object'] = obj wp_toggle['active_object'] = obj
# This flag indicates that the last time this operator ran, we were # This flag indicates that the last time this operator ran, we were
# switching INTO wp mode. # switching INTO wp mode.
wpt['last_switch_in'] = True wp_toggle['last_switch_in'] = True
wpt['mode'] = obj.mode wp_toggle['mode'] = obj.mode
# Enter WP mode. # Enter WP mode.
bpy.ops.object.mode_set(mode='WEIGHT_PAINT') bpy.ops.object.mode_set(mode='WEIGHT_PAINT')
@ -52,21 +62,21 @@ def enter_wp(context) -> bool:
if not armature: if not armature:
return return
# Save all object visibility related info so it can be restored later. # Save all object visibility related info so it can be restored later.
wpt['arm_enabled'] = armature.hide_viewport wp_toggle['arm_enabled'] = armature.hide_viewport
wpt['arm_hide'] = armature.hide_get() wp_toggle['arm_hide'] = armature.hide_get()
wpt['arm_in_front'] = armature.show_in_front wp_toggle['arm_in_front'] = armature.show_in_front
wpt['arm_coll_assigned'] = False wp_toggle['arm_coll_assigned'] = False
armature.hide_viewport = False armature.hide_viewport = False
armature.hide_set(False) armature.hide_set(False)
armature.show_in_front = True armature.show_in_front = True
if context.space_data.local_view: if context.space_data.local_view:
wpt['arm_local_view'] = armature.local_view_get(context.space_data) wp_toggle['arm_local_view'] = armature.local_view_get(context.space_data)
armature.local_view_set(context.space_data, True) armature.local_view_set(context.space_data, True)
# If the armature is still not visible, add it to the scene root collection. # If the armature is still not visible, add it to the scene root collection.
if not armature.visible_get() and not armature.name in context.scene.collection.objects: if not armature.visible_get() and not armature.name in context.scene.collection.objects:
context.scene.collection.objects.link(armature) context.scene.collection.objects.link(armature)
wpt['arm_coll_assigned'] = True wp_toggle['arm_coll_assigned'] = True
if armature.visible_get(): if armature.visible_get():
context.view_layer.objects.active = armature context.view_layer.objects.active = armature
@ -83,37 +93,37 @@ def leave_wp(context):
obj = context.object obj = context.object
wm = context.window_manager wm = context.window_manager
if 'wpt' not in wm or 'mode' not in wm['wpt'].to_dict(): if 'weight_paint_toggle' not in wm or 'mode' not in wm['weight_paint_toggle'].to_dict():
# There is no saved data to restore from, nothing else to do. # There is no saved data to restore from, nothing else to do.
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
return {'FINISHED'} return {'FINISHED'}
wpt = wm['wpt'] wp_toggle = wm['weight_paint_toggle']
wpt_as_dict = wpt.to_dict() wp_toggle_as_dict = wp_toggle.to_dict()
# Restore mode. # Restore mode.
bpy.ops.object.mode_set(mode=wpt_as_dict['mode']) bpy.ops.object.mode_set(mode=wp_toggle_as_dict['mode'])
# Reset the stored data # Reset the stored data
wm['wpt'] = {} wm['weight_paint_toggle'] = {}
# Flag to save that the last time the operator ran we were EXITING wp mode. # Flag to save that the last time the operator ran we were EXITING wp mode.
wm['wpt']['last_switch_in'] = False wm['weight_paint_toggle']['last_switch_in'] = False
armature = get_armature_of_meshob(obj) armature = get_armature_of_meshob(obj)
if not armature: if not armature:
return return
# If an armature was un-hidden, hide it again. # If an armature was un-hidden, hide it again.
armature.hide_viewport = wpt_as_dict['arm_enabled'] armature.hide_viewport = wp_toggle_as_dict['arm_enabled']
armature.hide_set(wpt_as_dict['arm_hide']) armature.hide_set(wp_toggle_as_dict['arm_hide'])
armature.show_in_front = wpt_as_dict['arm_in_front'] armature.show_in_front = wp_toggle_as_dict['arm_in_front']
# Restore whether the armature is in local view or not. # Restore whether the armature is in local view or not.
if 'arm_local_view' in wpt_as_dict and context.space_data.local_view: if 'arm_local_view' in wp_toggle_as_dict and context.space_data.local_view:
armature.local_view_set( armature.local_view_set(
context.space_data, wpt_as_dict['arm_local_view']) context.space_data, wp_toggle_as_dict['arm_local_view'])
# Remove armature from scene root collection if it was moved there. # Remove armature from scene root collection if it was moved there.
if wpt_as_dict['arm_coll_assigned']: if wp_toggle_as_dict['arm_coll_assigned']:
context.scene.collection.objects.unlink(armature) context.scene.collection.objects.unlink(armature)
return return
@ -141,6 +151,9 @@ class EASYWEIGHT_OT_toggle_weight_paint(Operator):
return {'FINISHED'} return {'FINISHED'}
else: else:
leave_wp(context) leave_wp(context)
wm = context.window_manager
if 'weight_paint_toggle' in wm:
del wm['weight_paint_toggle']
return {'FINISHED'} return {'FINISHED'}

View File

@ -176,7 +176,6 @@ class EASYWEIGHT_OT_wp_context_menu(bpy.types.Operator):
return wm.invoke_props_dialog(self) return wm.invoke_props_dialog(self)
def execute(self, context): def execute(self, context):
context.scene.tool_settings.vertex_group_user = 'ACTIVE'
return {'FINISHED'} return {'FINISHED'}