1 Commits
Author SHA1 Message Date
ChristopheSeux da68f7a429 test draw the picker inside a gizmo 2024-02-26 14:13:43 +01:00
8 changed files with 254 additions and 100 deletions
-7
View File
@@ -2,8 +2,6 @@
> Blender addon for picking rig contollers > Blender addon for picking rig contollers
Rig_picker is an OpenGl tool for having a 2d interface for the 3d animators allowing them to pick a controller easily. Rig_picker is an OpenGl tool for having a 2d interface for the 3d animators allowing them to pick a controller easily.
The addon is drawing 2d shapes inside a dedicated Node Editor Area using the gpu module.
You can use multiple pickers for one rig, each picker shapes are in there own collection.
Video of the previous version : https://vimeo.com/241970235 Video of the previous version : https://vimeo.com/241970235
@@ -25,12 +23,7 @@ Video of the previous version : https://vimeo.com/241970235
<!-- INSTALLATION --> <!-- INSTALLATION -->
## Installation ## Installation
For external user, you can clone the repository using:
```sh
git clone https://git.autourdeminuit.com/autour_de_minuit/rig_picker.git
```
For Internal user:
1. Create your own local directory in 1. Create your own local directory in
```sh ```sh
/home/<USER>/dev /home/<USER>/dev
+3 -6
View File
@@ -459,7 +459,7 @@ class Picker:
if shape.type == 'bone' and shape.hover: if shape.type == 'bone' and shape.hover:
shape.assign_bone_event() shape.assign_bone_event()
bpy.ops.rigpicker.save_picker(index=self.index) bpy.ops._rigpicker.save_picker(index=self.index)
def press_event(self, mode='SET'): def press_event(self, mode='SET'):
for shape in self.shapes: for shape in self.shapes:
@@ -712,7 +712,7 @@ class PickerGroup:
def load_picker_data(rig): def load_picker_data(rig):
if 'pickers' in rig.data.rig_picker: if 'pickers' in rig.data.rig_picker:
picker_datas = [[s.to_dict() for s in p] for p in rig.data.rig_picker['pickers']] picker_datas = [p.to_dict() for p in rig.rig_picker['pickers']]
else: else:
picker_datas = [] picker_datas = []
@@ -736,11 +736,8 @@ def get_picker_path(rig, source, start=None):
def pack_picker(rig, start=None): def pack_picker(rig, start=None):
if not 'rig_picker' in rig.data:
return
pickers = [] pickers = []
for picker_source in rig.data['rig_picker'].get('sources', []): for picker_source in rig.data.get('rig_picker', {}).get('sources', {}):
picker_path = get_picker_path(rig, picker_source['source'], start) picker_path = get_picker_path(rig, picker_source['source'], start)
if not picker_path.exists(): if not picker_path.exists():
print(f'{picker_path} not exists') print(f'{picker_path} not exists')
+3 -3
View File
@@ -93,7 +93,7 @@ def get_shape_data(ob, matrix=None, depsgraph=None):
for vert in mesh.vertices: for vert in mesh.vertices:
co = matrix @ (ob.matrix_world @ Vector(vert.co)) co = matrix @ (ob.matrix_world @ Vector(vert.co))
points.append([round(co[0], 1), round(co[1], 1)]) points.append([round(co[0]), round(co[1])])
depths += [co[2]] depths += [co[2]]
@@ -148,8 +148,8 @@ def get_picker_data(collection):
canvas_coords = [canvas.matrix_world@Vector((p.co)) for p in canvas_points] canvas_coords = [canvas.matrix_world@Vector((p.co)) for p in canvas_points]
height = abs(max(co.y for co in canvas_coords) - min(co.y for co in canvas_coords)) height = abs(max(canvas_coords).y - min(canvas_coords).y)
width = abs(max(co.x for co in canvas_coords) - min(co.x for co in canvas_coords)) width = abs(max(canvas_coords).x - min(canvas_coords).x)
center = sum(canvas_coords, Vector()) / len(canvas_coords) center = sum(canvas_coords, Vector()) / len(canvas_coords)
scale = 2048 / max(height, width)# Reference height for the canvas scale = 2048 / max(height, width)# Reference height for the canvas
+214 -21
View File
@@ -3,10 +3,13 @@ import bpy
from bpy.props import (IntProperty, EnumProperty, BoolProperty) from bpy.props import (IntProperty, EnumProperty, BoolProperty)
from bpy.types import (AddonPreferences, GizmoGroup, Operator, Gizmo) from bpy.types import (AddonPreferences, GizmoGroup, Operator, Gizmo)
import gpu
from mathutils import Vector, Matrix, Euler from mathutils import Vector, Matrix, Euler
from .constants import PICKERS from gpu_extras.batch import batch_for_shader
from .constants import PICKERS, SHADERS
from .core.picker import Picker from .core.picker import Picker
from .core.geometry_utils import bounding_rect
@@ -38,14 +41,133 @@ class RP_OT_simple_operator(bpy.types.Operator):
print('Select Shape') print('Select Shape')
return {'FINISHED'} return {'FINISHED'}
''' '''
'''
class RP_OT_box_select(Operator):
"""Box Select bones in the picker view"""
bl_idname = "node.rp_box_select"
bl_label = "Picker Box Select"
mode: EnumProperty(items=[(i, i.title(), '') for i in ('SET', 'EXTEND', 'SUBSTRACT')])
@classmethod
def poll(cls, context):
if not is_picker_space(context.space_data):
return
ob = context.object
return ob and ob in PICKERS
def draw_callback(self):
#print('draw callback border')
if not self.draw_border:
return
gpu.state.blend_set('ALPHA')
#print('DRAW BORDER')
self.color_shader.bind()
self.color_shader.uniform_float("color", self.bg_color)
self.bg_batch.draw(self.color_shader)
self.dash_shader.bind()
matrix = gpu.matrix.get_projection_matrix()
self.dash_shader.uniform_float("color", self.border_color)
self.dash_shader.uniform_float("viewMatrix", matrix)
self.dash_shader.uniform_float("dashSize", 5)
self.dash_shader.uniform_float("gapSize", 4)
self.contour_batch.draw(self.dash_shader)
gpu.state.blend_set('NONE')
def invoke(self, context, event):
#print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
if context.object.mode != 'POSE':
bpy.ops.object.posemode_toggle()
self.timer = None
#self.mode = self.mode_from_event(event)
#self.invoke_event = event.copy()
self.region = context.region
self.draw_border = False
self.picker = PICKERS[context.object]
self.start_mouse = event.mouse_region_x, event.mouse_region_y
#self.shader = line_strip_shader
self.border_color = [1, 1, 1, 1]
self.bg_color = [1, 1, 1, 0.05]
#args = (self, context)
self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR')
self.dash_shader = SHADERS['dashed_line']
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
context.window_manager.modal_handler_add(self)
self.picker.press_event(self.mode)
self.region.tag_redraw()
return {'RUNNING_MODAL'}
def modal(self, context, event):
self.mouse = event.mouse_region_x, event.mouse_region_y
self.border = bounding_rect((self.start_mouse, self.mouse))
self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border})
self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border})
self.draw_border = True
self.region.tag_redraw()
if event.value == 'RELEASE':
return self.release_event(context)
return {'RUNNING_MODAL'}
def release_event(self, context):
scn = context.scene
if scn.rig_picker.use_pick_bone:
self.picker.assign_bone_event()
elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]):
self.picker.border_select(self.border, self.mode)
else:
self.picker.move_event(self.mouse)
self.picker.release_event(self.mode)
bpy.ops.ed.undo_push(message="Box Select")
return self.exit(context)
def exit(self, context):
bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, 'WINDOW')
context.region.tag_redraw()
return {'FINISHED'}
'''
class RP_GT_gizmo(Gizmo): class RP_GT_gizmo(Gizmo):
def mode_from_event(self, event):
if event.alt:
return 'SUBSTRACT'
elif event.ctrl or event.shift:
return 'EXTEND'
else:
return 'SET'
def test_select(self, context, location): def test_select(self, context, location):
ob = context.object ob = context.object
@@ -54,41 +176,109 @@ class RP_GT_gizmo(Gizmo):
return -1 return -1
picker.move_event(location) picker.move_event(location)
#if bpy.app.timers.is_registered(tooltip):
# bpy.app.timers.unregister(tooltip)
#context.region.tag_redraw()
#picker.tooltip_event(event='START')
#bpy.app.timers.register(partial(tooltip, context.region), first_interval=1)
#print(location)
context.region.tag_redraw() context.region.tag_redraw()
#print(location) return 1
return -1
def draw(self, context): def draw(self, context):
print('DRAW_SELECT', self.border)
if not self.draw_border:
return return
'''
gpu.state.blend_set('ALPHA')
gpu.state.depth_test_set('ALWAYS')
gpu.state.depth_mask_set(False)
#print('DRAW BORDER')
self.color_shader.bind()
self.color_shader.uniform_float("color", self.bg_color)
self.bg_batch.draw(self.color_shader)
self.dash_shader.bind()
matrix = gpu.matrix.get_projection_matrix()
self.dash_shader.uniform_float("color", self.border_color)
self.dash_shader.uniform_float("viewMatrix", matrix)
self.dash_shader.uniform_float("dashSize", 5)
self.dash_shader.uniform_float("gapSize", 4)
self.contour_batch.draw(self.dash_shader)
#gpu.state.depth_mask_set(False)
gpu.state.blend_set('NONE')
def invoke(self, context, event): def invoke(self, context, event):
print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}') print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
print(self)
if context.object.mode != 'POSE':
bpy.ops.object.posemode_toggle()
#self.timer = None
#self.mode = self.mode_from_event(event)
#self.invoke_event = event.copy()
#self.region = context.region
self.draw_border = False
self.picker = PICKERS[context.object]
self.start_mouse = event.mouse_region_x, event.mouse_region_y
#self.shader = line_strip_shader
self.border_color = [1, 1, 1, 1]
self.bg_color = [1, 1, 1, 0.05]
#args = (self, context)
self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR')
self.dash_shader = SHADERS['dashed_line']
#self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
self.border = [(0, 0), (0, 0), (0, 0), (0, 0)]
#context.window_manager.modal_handler_add(self)
self.mode = self.mode_from_event(event)
self.picker.press_event(self.mode)
context.region.tag_redraw()
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
def modal(self, context, event, tweak): def modal(self, context, event, tweak):
print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}') #print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
self.mouse = event.mouse_region_x, event.mouse_region_y
self.border = bounding_rect((self.start_mouse, self.mouse))
self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border})
self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border})
self.draw_border = True
context.region.tag_redraw()
#self.draw(context)
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
def exit(self, context, cancel): def exit(self, context, cancel):
print('EXIT') scn = context.scene
if scn.rig_picker.use_pick_bone:
self.picker.assign_bone_event()
elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]):
self.picker.border_select(self.border, self.mode)
else:
self.picker.move_event(self.mouse)
self.picker.release_event(self.mode)
bpy.ops.ed.undo_push(message="Box Select")
self.draw_border = False
context.region.tag_redraw()
'''
@@ -106,6 +296,9 @@ class RP_GT_gizmogroup(GizmoGroup):
def setup(self, context): def setup(self, context):
self.gizmo = self.gizmos.new("RP_GT_gizmo") self.gizmo = self.gizmos.new("RP_GT_gizmo")
self.gizmo.draw_border = False
self.gizmo.border = []
self.gizmo.use_draw_modal = True
+13 -25
View File
@@ -130,8 +130,9 @@ class RP_OT_box_select(Operator):
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
def release_event(self, context): def release_event(self, context):
scn = context.scene
if get_picker_collection(): if scn.rig_picker.use_pick_bone:
self.picker.assign_bone_event() self.picker.assign_bone_event()
elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]): elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]):
@@ -391,19 +392,24 @@ class RP_OT_reload_picker(Operator):
# return # return
def execute(self, context): def execute(self, context):
#PICKERS.clear()
if context.object.type == 'ARMATURE': if context.object.type == 'ARMATURE':
rig = context.object rig = context.object
else: else:
collection = get_picker_collection(context.object) collection = get_picker_collection(context.object)
rig = collection.rig_picker.rig rig = collection.rig_picker.rig
#print('Reload', rig)
load_picker_data(rig) load_picker_data(rig)
'''
for area in context.screen.areas: for area in context.screen.areas:
#print(area.type, is_picker_space(area.spaces.active))
if is_picker_space(area.spaces.active): if is_picker_space(area.spaces.active):
area.tag_redraw()
print('Tag Redraw Region', area.type)
area.regions[0].tag_redraw()
area.tag_redraw()
'''
return {"FINISHED"} return {"FINISHED"}
@@ -545,8 +551,7 @@ class RP_MT_context_menu(Menu):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
col = layout.column() col = layout.column()
col.operator_context = 'INVOKE_DEFAULT' col.use_property_split = True
#col.use_property_split = True
ob = context.object ob = context.object
picker = PICKERS.get(ob) picker = PICKERS.get(ob)
@@ -556,25 +561,9 @@ class RP_MT_context_menu(Menu):
else: else:
bone = context.active_pose_bone bone = context.active_pose_bone
# Draw Space Switch Operator
if getattr(ob.data, 'space_switch'):
space_switch = ob.data.space_switch
data_paths = [f'pose.bones["{bone.name}"]["{k}"]' for k in bone.keys()]
space_bone = next((s for s in space_switch.bones if s.data_path in data_paths), None)
if space_bone:
index = list(space_switch.bones).index(space_bone)
value = ob.path_resolve(space_bone.data_path)
space = next((s.name for s in space_bone.spaces if s.value == value), None)
op = col.operator("spaceswitch.change_space", text=f'({space})', icon='PINNED')
op.index=index
col.separator()
if bone: if bone:
for key in bone.keys(): for key in bone.keys():
col.prop(bone,f'["{key}"]', slider=True) layout.prop(bone,f'["{key}"]', slider=True)
#layout.operator("rigpicker.show_bone_layer", text="Show Bone Layer", ).type = 'ACTIVE' #layout.operator("rigpicker.show_bone_layer", text="Show Bone Layer", ).type = 'ACTIVE'
#layout.operator("rigidbody.objects_add", text="B Add Passive").type = 'PASSIVE' #layout.operator("rigidbody.objects_add", text="B Add Passive").type = 'PASSIVE'
@@ -766,7 +755,7 @@ def register_keymaps():
kmi = km.keymap_items.new("node.context_menu_picker", type="RIGHTMOUSE", value="PRESS") kmi = km.keymap_items.new("node.context_menu_picker", type="RIGHTMOUSE", value="PRESS")
keymaps.append((km, kmi)) keymaps.append((km, kmi))
'''
kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS") kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS")
kmi.properties.mode = 'SET' kmi.properties.mode = 'SET'
keymaps.append((km, kmi)) keymaps.append((km, kmi))
@@ -775,11 +764,10 @@ def register_keymaps():
kmi.properties.mode = 'EXTEND' kmi.properties.mode = 'EXTEND'
keymaps.append((km, kmi)) keymaps.append((km, kmi))
#kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", ctrl=True)
kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", alt=True) kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", alt=True)
kmi.properties.mode = 'SUBSTRACT' kmi.properties.mode = 'SUBSTRACT'
keymaps.append((km, kmi)) keymaps.append((km, kmi))
'''
#km = wm.keyconfigs.addon.keymaps.new(name="View2D") #km = wm.keyconfigs.addon.keymaps.new(name="View2D")
#kmi = km.keymap_items.new("rigpicker.call_operator", type="MIDDLEMOUSE", value="PRESS") #kmi = km.keymap_items.new("rigpicker.call_operator", type="MIDDLEMOUSE", value="PRESS")
#kmi.properties.operator = "bpy.ops.view2d.pan('INVOKE_DEFAULT')" #kmi.properties.operator = "bpy.ops.view2d.pan('INVOKE_DEFAULT')"
+14 -22
View File
@@ -21,14 +21,6 @@ class RP_OT_create_shape(Operator):
def poll(cls, context): def poll(cls, context):
return (context.object and context.object.mode == 'POSE') return (context.object and context.object.mode == 'POSE')
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
for col in bpy.data.collections:
if col.rig_picker.enabled:
self.layout.prop(col.rig_picker, 'link_shape', text=col.name)
def execute(self,context): def execute(self,context):
scn = context.scene scn = context.scene
vl = context.view_layer vl = context.view_layer
@@ -48,11 +40,8 @@ class RP_OT_create_shape(Operator):
mesh.from_pydata(verts, edges, faces) mesh.from_pydata(verts, edges, faces)
for col in bpy.data.collections: for c in scn.rig_picker.canvas.users_collection:
if col.rig_picker.link_shape: c.objects.link(ob)
col.objects.link(ob)
else:
scn.collection.objects.link(ob)
ob.location.z = 0.05 ob.location.z = 0.05
ob.location.x = offset ob.location.x = offset
@@ -71,16 +60,16 @@ class RP_OT_create_shape(Operator):
class RP_OT_name_from_bone(Operator): class RP_OT_name_from_bone(Operator):
bl_label = 'Name Shape from selected bones' bl_label = 'Name Shape from selected bones'
bl_idname = 'rigpicker.name_from_bone' bl_idname = 'rigpicker.name_from_bone'
bl_description = 'Rename all shapes from related bones name'
#bl_options = {'REGISTER', 'UNDO'} #bl_options = {'REGISTER', 'UNDO'}
def execute(self,context): def execute(self,context):
scene = context.scene
rig = scene.rig_picker.rig
bone = rig.data.bones.active
col = get_picker_collection(context.object) if bone:
context.object.name = bone.name
for ob in col.all_objects: context.object.rig_picker.name = bone.name
if ob.rig_picker.shape_type == 'BONE':
ob.name = ob.rig_picker.name
return {'FINISHED'} return {'FINISHED'}
@@ -95,7 +84,9 @@ class RP_OT_mirror_shape(Operator):
return (context.object and context.object.type in ('MESH', 'CURVE', 'TEXT')) return (context.object and context.object.type in ('MESH', 'CURVE', 'TEXT'))
def execute(self,context): def execute(self,context):
collection = get_picker_collection(context.object) scn = context.scene
ob = context.object
collection = get_picker_collection(ob)
objects = context.selected_objects objects = context.selected_objects
# Remove mirror object: # Remove mirror object:
@@ -104,7 +95,7 @@ class RP_OT_mirror_shape(Operator):
continue continue
for mod in ob.modifiers: for mod in ob.modifiers:
if (mod.type == 'NODES' and mod.node_group and mod.node_group.name == 'Symmetrize' and if (mod.type == 'NODES' and mod.node_group.name == 'Symmetrize' and
mod.get('Socket_2') in objects): mod.get('Socket_2') in objects):
bpy.data.objects.remove(ob) bpy.data.objects.remove(ob)
@@ -133,7 +124,7 @@ class RP_OT_mirror_shape(Operator):
for mod in list(flipped_object.modifiers): for mod in list(flipped_object.modifiers):
flipped_object.modifiers.remove(mod) flipped_object.modifiers.remove(mod)
# Add symmetrize modifier TODO add it into a resource # Add symmetrize modifier
mod = flipped_object.modifiers.new(name='Symmetrize', type='NODES') mod = flipped_object.modifiers.new(name='Symmetrize', type='NODES')
mod.node_group = bpy.data.node_groups['Symmetrize'] mod.node_group = bpy.data.node_groups['Symmetrize']
mod['Socket_2'] = ob mod['Socket_2'] = ob
@@ -231,6 +222,7 @@ class RP_OT_save_picker(Operator):
bpy.ops.rigpicker.reload_picker() bpy.ops.rigpicker.reload_picker()
return {'FINISHED'} return {'FINISHED'}
classes = ( classes = (
+4 -9
View File
@@ -44,17 +44,14 @@ class RP_PG_object_ui_settings(bpy.types.PropertyGroup):
name: StringProperty() name: StringProperty()
class RP_PG_collection_ui_settings(bpy.types.PropertyGroup): class RP_PG_scene_ui_settings(bpy.types.PropertyGroup):
enabled : BoolProperty(default=False) enabled : BoolProperty(default=False)
rig: PointerProperty(type=bpy.types.Object) rig: PointerProperty(type=bpy.types.Object)
canvas: PointerProperty(type=bpy.types.Object) canvas: PointerProperty(type=bpy.types.Object)
symmetry: PointerProperty(type=bpy.types.Object) symmetry: PointerProperty(type=bpy.types.Object)
#idname: EnumProperty(items=[])
destination: StringProperty(subtype='FILE_PATH') destination: StringProperty(subtype='FILE_PATH')
use_pick_bone : BoolProperty(default=False) #bone_list: bpy.props.EnumProperty(items = bones_item
link_shape : BoolProperty(default=False)
class RP_PG_scene_ui_settings(bpy.types.PropertyGroup):
use_pick_bone : BoolProperty(default=False) use_pick_bone : BoolProperty(default=False)
@@ -81,7 +78,6 @@ class RP_OT_operator_selector(bpy.types.Operator):
classes = ( classes = (
RP_PG_picker_source, RP_PG_picker_source,
RP_PG_object_ui_settings, RP_PG_object_ui_settings,
RP_PG_collection_ui_settings,
RP_PG_scene_ui_settings, RP_PG_scene_ui_settings,
RP_PG_armature_ui_settings, RP_PG_armature_ui_settings,
RP_OT_operator_selector, RP_OT_operator_selector,
@@ -93,12 +89,11 @@ def register():
bpy.types.Armature.rig_picker = bpy.props.PointerProperty(type=RP_PG_armature_ui_settings) bpy.types.Armature.rig_picker = bpy.props.PointerProperty(type=RP_PG_armature_ui_settings)
bpy.types.Object.rig_picker = bpy.props.PointerProperty(type=RP_PG_object_ui_settings) bpy.types.Object.rig_picker = bpy.props.PointerProperty(type=RP_PG_object_ui_settings)
bpy.types.Collection.rig_picker = bpy.props.PointerProperty(type=RP_PG_collection_ui_settings)
bpy.types.Scene.rig_picker = bpy.props.PointerProperty(type=RP_PG_scene_ui_settings) bpy.types.Scene.rig_picker = bpy.props.PointerProperty(type=RP_PG_scene_ui_settings)
bpy.types.Collection.rig_picker = bpy.props.PointerProperty(type=RP_PG_scene_ui_settings)
def unregister(): def unregister():
del bpy.types.Scene.rig_picker del bpy.types.Scene.rig_picker
del bpy.types.Collection.rig_picker
del bpy.types.Object.rig_picker del bpy.types.Object.rig_picker
del bpy.types.Armature.rig_picker del bpy.types.Armature.rig_picker
+1 -5
View File
@@ -91,12 +91,8 @@ class RP_PT_shape(bpy.types.Panel):
row = col.row(align=True) row = col.row(align=True)
row.operator('rigpicker.create_shape', icon='MESH_DATA', text='Create Shape') row.operator('rigpicker.create_shape', icon='MESH_DATA', text='Create Shape')
row.operator('rigpicker.mirror_shape', icon='MOD_MIRROR', text='Mirror Shape') row.operator('rigpicker.mirror_shape', icon='MOD_MIRROR', text='Mirror Shape')
col.prop(scn.rig_picker, 'use_pick_bone', icon='EYEDROPPER', text='Auto Bone Assign')
col.operator('rigpicker.name_from_bone', icon='SORTALPHA' , text='Name From Bones') col.operator('rigpicker.name_from_bone', icon='SORTALPHA' , text='Name From Bones')
else: col.prop(scn.rig_picker, 'use_pick_bone', icon='EYEDROPPER', text='Auto Bone Assign')
col = layout.column(align=True)
row = col.row(align=True)
row.operator('rigpicker.create_shape', icon='MESH_DATA', text='Create Shape')
if ob.type != 'ARMATURE': if ob.type != 'ARMATURE':
box = layout.box() box = layout.box()