From 539c9e53a45a5ef6f565319f03bc8f6570e2716c Mon Sep 17 00:00:00 2001 From: Andreas Esau Date: Thu, 19 Jul 2018 09:48:42 +0200 Subject: [PATCH] Fixing Crash Edit Shapekey mode - fixed a reproducable crash in Edit Shapekey Mode. Objects were not valid anymore when running undo. --- .../coa_tools/operators/animation_handling.py | 30 +++++------ Blender/coa_tools/operators/edit_shapekey.py | 43 ++++++++------- Blender/coa_tools/operators/edit_weights.py | 54 +++++++++---------- 3 files changed, 67 insertions(+), 60 deletions(-) diff --git a/Blender/coa_tools/operators/animation_handling.py b/Blender/coa_tools/operators/animation_handling.py index 459aa12..3632f67 100644 --- a/Blender/coa_tools/operators/animation_handling.py +++ b/Blender/coa_tools/operators/animation_handling.py @@ -384,49 +384,49 @@ def get_empty_track(self,anim_data,strip_range): for strip in track.strips: if (strip_range[0] > strip.frame_start and strip_range[0] < strip.frame_end) or (strip_range[1] > strip.frame_start and strip_range[1] < strip.frame_end) or (strip_range[0] == strip.frame_start and strip_range[1] == strip.frame_end): intersecting_strip_found = True - + if not intersecting_strip_found: return track - - + + return anim_data.nla_tracks.new() - + def execute(self, context): obj = bpy.context.active_object sprite_object = get_sprite_object(obj) children = get_children(context,sprite_object,ob_list=[]) - + context.scene.coa_nla_mode = "NLA" - + if self.anim_collection_name == "": anim_collection = sprite_object.coa_anim_collections[sprite_object.coa_anim_collections_index] - else: + else: anim_collection = sprite_object.coa_anim_collections[self.anim_collection_name] - + if self.insert_at_cursor: self.start = context.scene.frame_current - + for child in children: if child.animation_data != None: for track in child.animation_data.nla_tracks: for strip in track.strips: strip.select = False - + action_name = anim_collection.name + "_" + child.name if action_name in bpy.data.actions: action_start = 0 action_end = anim_collection.frame_end strip_start = self.start strip_end = self.start + anim_collection.frame_end - - + + action = bpy.data.actions[action_name] - + if child.animation_data != None: child.animation_data_create() anim_data = child.animation_data - nla_track = self.get_empty_track(anim_data,[strip_start,strip_end]) - + nla_track = self.get_empty_track(anim_data,[strip_start,strip_end]) + strip = nla_track.strips.new(action_name,self.start,action) strip.action_frame_start = action_start strip.action_frame_end = action_end diff --git a/Blender/coa_tools/operators/edit_shapekey.py b/Blender/coa_tools/operators/edit_shapekey.py index f130794..71a2c6a 100644 --- a/Blender/coa_tools/operators/edit_shapekey.py +++ b/Blender/coa_tools/operators/edit_shapekey.py @@ -31,6 +31,7 @@ from .. functions_draw import * import bgl, blf import traceback +import pdb class LeaveSculptmode(bpy.types.Operator): bl_idname = "coa_tools.leave_sculptmode" @@ -159,9 +160,10 @@ def get_shapekeys(self,context): shapekeys = EnumProperty(name="Shapekey",items=get_shapekeys) shapekey_name = StringProperty(name="Name",default="New Shape") mode_init = StringProperty() - obj_init = None armature = None + armature_name = "" sprite_object = None + sprite_object_name = None shape = None create_shapekey = BoolProperty(default=False) objs = [] @@ -211,13 +213,13 @@ def execute(self, context): if context.active_object == None: self.report({"ERROR"},"Armature is hidden or not selected. Cannot go in Edit Mode.") return{"CANCELLED"} - obj = context.active_object - - self.sprite_object = get_sprite_object(obj) + obj = bpy.data.objects[context.active_object.name] if context.active_object.name in bpy.data.objects else None - armature_name = get_armature(self.sprite_object).name - self.armature = context.scene.objects[armature_name] if armature_name in context.scene.objects else None - self.obj_init = context.active_object + self.sprite_object_name = get_sprite_object(obj).name + self.sprite_object = bpy.data.objects[self.sprite_object_name] + + self.armature_name = get_armature(self.sprite_object).name + self.armature = context.scene.objects[self.armature_name] if self.armature_name in context.scene.objects else None self.mode_init = obj.mode if obj.mode != "SCULPT" else "OBJECT" @@ -247,15 +249,14 @@ def execute(self, context): return {"RUNNING_MODAL"} def exit_edit_mode(self,context,event,obj): - ### remove draw handler on exiting modal mode - bpy.types.SpaceView3D.draw_handler_remove(self.draw_handler, "WINDOW") - - + ### remove draw handler on exiting modal mode + bpy.types.SpaceView3D.draw_handler_remove(self.draw_handler, "WINDOW") + for obj in context.selected_objects: obj.select = False self.sprite_object.coa_edit_shapekey = False self.sprite_object.coa_edit_mode = "OBJECT" - + for obj_name in self.objs: obj = bpy.context.scene.objects[obj_name] obj.hide = False @@ -263,20 +264,26 @@ def exit_edit_mode(self,context,event,obj): context.scene.objects.active = obj bpy.ops.object.mode_set(mode="OBJECT") obj.show_only_shape_key = False - + context.scene.objects.active = obj obj.select = True - if self.armature != None: - self.armature.data.pose_position = "POSE" + if self.armature != None and self.armature.data != None: + self.armature.data.pose_position = "POSE" return {"FINISHED"} def modal(self, context, event): obj = None obj_name = context.active_object.name if context.active_object != None else None obj = context.scene.objects[obj_name] if obj_name != None else None + self.sprite_object = bpy.data.objects[self.sprite_object_name] + self.armature = bpy.data.objects[self.armature_name] + try: + # used for debugging + # if event.ctrl and event.type == "Z" and len(context.selected_objects) == 2: + # pdb.set_trace() + if obj != None: - if obj_name != self.last_obj_name: if obj.type == "MESH": self.set_most_driven_shapekey(obj) @@ -290,7 +297,7 @@ def modal(self, context, event): if obj.coa_selected_shapekey != obj.active_shape_key.name: obj.coa_selected_shapekey = str(obj.active_shape_key_index) #obj.active_shape_key.name - if self.sprite_object.coa_edit_shapekey == False: + if self.sprite_object.coa_edit_shapekey == False and obj != None: return self.exit_edit_mode(context,event,obj) except Exception as e: @@ -299,7 +306,7 @@ def modal(self, context, event): self.exit_edit_mode(context,event,obj) if obj_name != self.last_obj_name: - self.last_obj_name = obj_name + self.last_obj_name = str(obj_name) return {"PASS_THROUGH"} diff --git a/Blender/coa_tools/operators/edit_weights.py b/Blender/coa_tools/operators/edit_weights.py index 11f4eb7..d2c3ab6 100644 --- a/Blender/coa_tools/operators/edit_weights.py +++ b/Blender/coa_tools/operators/edit_weights.py @@ -55,7 +55,7 @@ def __init__(self): self.use_unified_strength = False self.non_deform_bones = [] self.deform_bones = [] - + def armature_set_mode(self,context,mode,select): armature = bpy.data.objects[self.armature_name] armature.select = select @@ -64,20 +64,20 @@ def armature_set_mode(self,context,mode,select): bpy.ops.object.mode_set(mode=mode) context.scene.objects.active = bpy.data.objects[active_object_name] - + def select_bone(self): armature = bpy.data.objects[self.armature_name] for bone in armature.data.bones: bone.select = False armature.data.bones.active = None - + for i,vertex_group in enumerate(bpy.data.objects[self.obj_name].vertex_groups): if vertex_group.name in armature.data.bones: bpy.data.objects[self.obj_name].vertex_groups.active_index = i bone = armature.data.bones[vertex_group.name] armature.data.bones.active = bone break - + def exit_edit_weights(self,context): tool_settings = context.scene.tool_settings tool_settings.unified_paint_settings.use_unified_strength = self.use_unified_strength @@ -91,19 +91,19 @@ def exit_edit_weights(self,context): bpy.ops.object.mode_set(mode="OBJECT") for i,bone_layer in enumerate(bone_layers): armature.data.layers[i] = bone_layer - + for name in self.selected_objects: obj = bpy.data.objects[name] obj.select = True context.scene.objects.active = bpy.data.objects[self.active_object_name] self.unhide_non_deform_bones(context) - + def exit_edit_mode(self,context): ### remove draw call bpy.types.SpaceView3D.draw_handler_remove(self.draw_handler, "WINDOW") - - sprite_object = bpy.data.objects[self.sprite_object_name] - + + sprite_object = bpy.data.objects[self.sprite_object_name] + self.exit_edit_weights(context) sprite_object.coa_edit_weights = False sprite_object.coa_edit_mode = "OBJECT" @@ -111,7 +111,7 @@ def exit_edit_mode(self,context): self.disable_object_color(False) context.active_object.active_material.use_shadeless = self.shadeless return {"FINISHED"} - + def modal(self, context, event): try: if get_local_view(context) == None or (context.active_object != None and context.active_object.mode != "WEIGHT_PAINT") or context.active_object == None: @@ -119,10 +119,10 @@ def modal(self, context, event): except Exception as e: traceback.print_exc() self.report({"ERROR"},"An Error occured, please check console for more Information.") - self.exit_edit_mode(context) - + self.exit_edit_mode(context) + return {"PASS_THROUGH"} - + def disable_object_color(self,disable): sprite_object = get_sprite_object(bpy.context.active_object) children = get_children(bpy.context,sprite_object,ob_list=[]) @@ -134,38 +134,38 @@ def disable_object_color(self,disable): obj.material_slots[0].material.use_object_color = not disable else: obj.material_slots[0].material.use_object_color = self.object_color_settings[obj.name] - + def unhide_deform_bones(self,context): armature = bpy.data.objects[self.armature_name] for bone in armature.data.bones: if bone.hide and bone.use_deform: self.deform_bones.append(bone) bone.hide = False - + def hide_deform_bones(self,context): for bone in self.deform_bones: bone.hide = True - + def hide_non_deform_bones(self,context): armature = bpy.data.objects[self.armature_name] for bone in armature.data.bones: if not bone.hide and not bone.use_deform: self.non_deform_bones.append(bone) bone.hide = True - + def unhide_non_deform_bones(self,context): for bone in self.non_deform_bones: bone.hide = False - - + + def create_armature_modifier(self,context,obj,armature): for mod in obj.modifiers: if mod.type == "ARMATURE": return mod - mod = obj.modifiers.new("Armature","ARMATURE") + mod = obj.modifiers.new("Armature","ARMATURE") mod.object = armature return mod - + def invoke(self, context, event): if context.active_object == None: self.report({"ERROR"},"Armature is hidden or not selected. Cannot go in Edit Mode.") @@ -175,24 +175,24 @@ def invoke(self, context, event): self.sprite_object_name = get_sprite_object(context.active_object).name sprite_object = bpy.data.objects[self.sprite_object_name] if get_armature(sprite_object) == None or get_armature(sprite_object) not in context.visible_objects: - self.report({'WARNING'},'No Armature Available or Visible') + self.report({'WARNING'},'No Armature Available or Visible') return{"CANCELLED"} self.armature_name = get_armature(sprite_object).name armature = bpy.data.objects[self.armature_name] - + self.shadeless = context.active_object.active_material.use_shadeless context.active_object.active_material.use_shadeless = True - + self.create_armature_modifier(context,obj,armature) - + scene = context.scene tool_settings = scene.tool_settings self.use_unified_strength = tool_settings.unified_paint_settings.use_unified_strength tool_settings.unified_paint_settings.use_unified_strength = True - + self.disable_object_color(True) context.window_manager.modal_handler_add(self) - + self.active_object_name = context.active_object.name for obj in context.selected_objects: