diff --git a/__init__.py b/__init__.py index 18cd587..4023153 100644 --- a/__init__.py +++ b/__init__.py @@ -24,7 +24,7 @@ modules = [ ] functions = [ - '.func_picker', + #'.func_picker', '.func_shape', '.snapping_utils', '.utils' diff --git a/op_picker.py b/op_picker.py index ef49f57..c1936d2 100644 --- a/op_picker.py +++ b/op_picker.py @@ -8,7 +8,8 @@ import gpu import bgl from mathutils import Vector from gpu_extras.batch import batch_for_shader - +from pathlib import Path +import json vertex_shader = ''' @@ -79,6 +80,13 @@ def draw_callback(self): bgl.glDisable(bgl.GL_BLEND) +def is_picker_space(context): + sp = context.space_data + if sp and (sp.type == 'NODE_EDITOR' and sp.tree_type == 'RigPickerTree'): + return True + + return False + class RP_OT_box_select(bpy.types.Operator): """Tooltip""" @@ -92,9 +100,7 @@ class RP_OT_box_select(bpy.types.Operator): @classmethod def poll(cls, context): - sp = context.space_data - - if not sp.tree_type == 'RigPickerTree': + if not is_picker_space(context): return ob = context.object @@ -276,13 +282,13 @@ class RP_OT_toogle_bone_layer(bpy.types.Operator): @classmethod def poll(cls, context): - if not context.space_data.tree_type == 'RigPickerTree': + if not is_picker_space(context): return ob = context.object picker = PICKERS.get(ob) - if picker.hover_shape and picker.hover_shape.type=='bone': + if picker.hover_shape and picker.hover_shape.type == 'bone': return True def execute(self, context): @@ -306,6 +312,35 @@ class RP_OT_toogle_bone_layer(bpy.types.Operator): return {"FINISHED"} +class RP_OT_pack_picker(bpy.types.Operator): + """Pack Unpack the picker on the rig""" + bl_idname = "rigpicker.pack_picker" + bl_label = 'Toogle Bone Layer' + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'ARMATURE' and ob.data.rig_picker.source) + + def execute(self, context): + print('Pack Picker') + + ob = context.object + picker_src = Path(bpy.path.abspath(ob.data.rig_picker.source, library=ob.data.library)) + + if 'picker' in ob.data.rig_picker.keys(): + del ob.data.rig_picker['picker'] + return {"FINISHED"} + + if not picker_src.exists(): + self.report({"ERROR"}, f'The path of the picker not exist: {picker_src}') + return {"CANCELLED"} + + ob.data.rig_picker['picker'] = json.loads(picker_src.read_text()) + + return {"FINISHED"} + + class RP_OT_call_operator(bpy.types.Operator): bl_idname = "rigpicker.call_operator" bl_label = 'Toogle Bone Layer' @@ -314,14 +349,16 @@ class RP_OT_call_operator(bpy.types.Operator): @classmethod def poll(cls, context): - sp = context.space_data - return (sp.type=='NODE_EDITOR' and sp.tree_type != 'RigPickerTree') + return is_picker_space(context) def execute(self, context): print('CALL OPERATOR', self.operator) - exec(self.operator) + try: + exec(self.operator) + except Exception as e: + self.report({"ERROR"}, e) context.region.tag_redraw() @@ -330,7 +367,7 @@ class RP_OT_call_operator(bpy.types.Operator): class RP_MT_context_menu(bpy.types.Menu): bl_label = "Context Menu" - bl_idname = "rigpicker.context_menu" + #bl_idname = "RP_MT_context_menu" # Set the menu operators and draw functions def draw(self, context): @@ -486,7 +523,7 @@ def register_keymaps(): keymaps.append((km, kmi)) kmi = km.keymap_items.new("wm.call_menu", type="RIGHTMOUSE", value="PRESS") - kmi.properties.name = "rigpicker.context_menu" + kmi.properties.name = "RP_MT_context_menu" keymaps.append((km, kmi)) kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS") @@ -515,7 +552,8 @@ classes = ( RP_OT_toogle_bone_layer, RP_OT_call_operator, RP_MT_context_menu, - RP_OT_move_bone + RP_OT_move_bone, + RP_OT_pack_picker #RP_OT_ui_draw ) diff --git a/panels.py b/panels.py index f05730e..130f588 100644 --- a/panels.py +++ b/panels.py @@ -28,8 +28,13 @@ class RP_PT_picker_maker_panel(bpy.types.Panel): col.prop_search(scn.rig_picker, 'canvas', scn, 'objects', text='canvas ') col.prop_search(scn.rig_picker, 'symmetry', scn, 'objects', text='Symmetry ') - if ob.type=='ARMATURE': - layout.prop(ob.data.rig_picker, 'source', text='Picker') + if ob.type == 'ARMATURE': + row = layout.row(align=True) + is_packed = ('picker' in ob.data.rig_picker.keys()) + sub_row = row.row(align=True) + sub_row.prop(ob.data.rig_picker, 'source', text='Picker') + sub_row.enabled = not is_packed + row.operator('rigpicker.pack_picker', icon='PACKAGE' if is_packed else 'UGLYPACKAGE', text='') col = layout.column(align=True) diff --git a/picker.py b/picker.py index 02cd75d..46cdf3c 100644 --- a/picker.py +++ b/picker.py @@ -523,7 +523,7 @@ class Picker: def draw_callback_view(): sp = bpy.context.space_data - if not sp.tree_type == 'RigPickerTree': + if not sp or not sp.tree_type == 'RigPickerTree': return ob = bpy.context.object @@ -531,10 +531,18 @@ def draw_callback_view(): return if ob not in PICKERS: - picker_path = Path(bpy.path.abspath(ob.data.rig_picker.source, library=ob.data.library)) - print('Load picker from', picker_path.resolve()) - picker_datas = json.loads(picker_path.read_text()) - #shapes = [s.to_dict() for s in ob.data.rig_picker['shapes']] + if 'picker' in ob.data.rig_picker: + picker_datas = [s.to_dict() for s in ob.data.rig_picker['picker']] + else: + picker_path = Path(bpy.path.abspath(ob.data.rig_picker.source, library=ob.data.library)) + + if not picker_path.exists(): + print(f'Picker path not exists: {picker_path.resolve()}') + return + + print('Load picker from', picker_path.resolve()) + picker_datas = json.loads(picker_path.read_text()) + #shapes = [s.to_dict() for s in ob.data.rig_picker['shapes']] PICKERS[ob] = Picker(ob, shapes=picker_datas) picker = PICKERS.get(ob)