Skip to content

Commit 9afe05a

Browse files
authored
Fix undo history (#137)
Fixed undo bug by clearing all undo history after mode change #12
1 parent a4de25c commit 9afe05a

File tree

4 files changed

+40
-19
lines changed

4 files changed

+40
-19
lines changed

ue2rigify/addon/__init__.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"author": "Epic Games Inc.",
1515
"description": "Allows you to convert a given rig and its animations to a Rigify rig.",
1616
"blender": (2, 83, 0),
17-
"version": (1, 3, 10),
17+
"version": (1, 3, 11),
1818
"location": "3D View > Tools > UE to Rigify",
1919
"wiki_url": "https://github.com/EpicGames/BlenderTools/wiki/UE-to-Rigify-Home",
2020
"warning": "",
@@ -56,6 +56,7 @@
5656
operators.ConstrainSourceToDeform,
5757
operators.RemoveConstraints,
5858
operators.SwitchModes,
59+
operators.NullOperator,
5960
addon_preferences.Ue2RigifyAddonPreferences,
6061
view_3d.UE_RIGIFY_PT_RigTemplatePanel
6162
)
@@ -82,9 +83,6 @@ def register():
8283
bpy.app.handlers.load_post.append(utilities.load_properties)
8384
bpy.app.handlers.save_pre.append(utilities.save_properties)
8485

85-
# add an event handler that loads the saved scene properties after an undo
86-
bpy.app.handlers.undo_post.append(utilities.undo)
87-
8886

8987
def unregister():
9088
"""
@@ -97,7 +95,6 @@ def unregister():
9795
# remove event handlers
9896
bpy.app.handlers.load_post.remove(utilities.load_properties)
9997
bpy.app.handlers.save_pre.remove(utilities.save_properties)
100-
bpy.app.handlers.undo_post.remove(utilities.undo)
10198

10299
# remove the added system path
103100
sys.path.pop(0)

ue2rigify/addon/functions/scene.py

+4
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,7 @@ def switch_modes(self=None, context=None):
13231323

13241324
# if the rig is not frozen run the following operations
13251325
if not properties.freeze_rig:
1326+
13261327
# save the metarig
13271328
save_meta_rig(properties)
13281329

@@ -1353,5 +1354,8 @@ def switch_modes(self=None, context=None):
13531354
if properties.selected_mode == properties.control_mode:
13541355
convert_to_control_rig(properties)
13551356

1357+
# record this mode change in the history
1358+
utilities.clear_undo_history()
1359+
13561360
# restore the context
13571361
utilities.load_context(properties)

ue2rigify/addon/functions/utilities.py

+24-14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@
77
pie_menu_classes = []
88

99

10+
def get_modes():
11+
"""
12+
This function gets all the ue2rigify modes
13+
"""
14+
properties = bpy.context.window_manager.ue2rigify
15+
return [
16+
properties.source_mode,
17+
properties.metarig_mode,
18+
properties.fk_to_source_mode,
19+
properties.source_to_deform_mode,
20+
properties.control_mode
21+
]
22+
23+
1024
def get_picker_object():
1125
"""
1226
This function gets or creates a new picker object if needed.
@@ -694,7 +708,7 @@ def save_properties(*args):
694708

695709
# assign all the addon property values to the scene property values
696710
for attribute in dir(window_manager_properties):
697-
if not attribute.startswith(('__', 'bl_', 'rna_type', 'group')):
711+
if not attribute.startswith(('__', 'bl_', 'rna_type', 'group', 'idp_array')):
698712
value = getattr(window_manager_properties, attribute)
699713
try:
700714
scene_properties[attribute] = value
@@ -763,22 +777,18 @@ def load_properties(*args):
763777
setattr(window_manager_properties, attribute, scene_value)
764778

765779

766-
@bpy.app.handlers.persistent
767-
def undo(*args):
780+
def clear_undo_history():
768781
"""
769-
This function sets the selected mode back to the previous mode on an undo.
770-
771-
:param args: This soaks up the extra arguments for the app handler.
782+
This function clears blenders undo history by doing a deselect all operation and repeatedly
783+
pushing that operation into the undo stack until all previous history is cleared from the undo
784+
history.
772785
"""
773-
properties = bpy.context.window_manager.ue2rigify
774-
scene_properties = bpy.context.scene.ue2rigify
775-
776-
if bpy.context.space_data.type == 'VIEW_3D' and properties.selected_mode != properties.source_mode:
777-
# load the scene properties
778-
load_properties()
786+
# run this null operator
787+
bpy.ops.ue2rigify.null_operator()
779788

780-
# set the selected mode to the previous mode
781-
properties.selected_mode = scene_properties['previous_mode']
789+
# repeatedly push the last operator into the undo stack till there are no more undo steps
790+
for item in range(0, bpy.context.preferences.edit.undo_steps+1):
791+
bpy.ops.ed.undo_push(message='UE to Rigify Mode Change')
782792

783793

784794
def get_formatted_operator_parameter(parameter_name, regex, code_line):

ue2rigify/addon/operators.py

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import bpy
44
from .ui import exporter
5+
from .functions import undo
56
from .functions import scene
67
from .functions import nodes
78
from .functions import templates
@@ -279,3 +280,12 @@ def execute(self, context):
279280
scene.switch_modes()
280281
return {'FINISHED'}
281282

283+
284+
class NullOperator(bpy.types.Operator):
285+
"""This is an operator that changes nothing, but it used to clear the undo stack"""
286+
bl_idname = "ue2rigify.null_operator"
287+
bl_label = "Null Operator"
288+
289+
def execute(self, context):
290+
return {'FINISHED'}
291+

0 commit comments

Comments
 (0)