Assign bones
parent
450d029dc4
commit
3a06eb6890
3
area.py
3
area.py
|
@ -36,6 +36,9 @@ def draw_header(self, context):
|
||||||
#layout.separator_spacer()
|
#layout.separator_spacer()
|
||||||
|
|
||||||
layout.operator('rigpicker.reload_picker', icon='FILE_REFRESH', text='')
|
layout.operator('rigpicker.reload_picker', icon='FILE_REFRESH', text='')
|
||||||
|
|
||||||
|
#layout.prop('rigpicker.reload_picker', icon='FILE_REFRESH', text='')
|
||||||
|
|
||||||
layout.separator_spacer()
|
layout.separator_spacer()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -20,7 +20,7 @@ def get_picker_datas(objects, canvas, rig):
|
||||||
canvas_y = [p[1] for p in canvas_coords]
|
canvas_y = [p[1] for p in canvas_coords]
|
||||||
|
|
||||||
canvas_center = sum(canvas_coords, Vector()) / len(canvas_coords)
|
canvas_center = sum(canvas_coords, Vector()) / len(canvas_coords)
|
||||||
canvas_scale_fac = 1024 / (max(canvas_y) - min(canvas_y))# Reference height for the canvas
|
canvas_scale_fac = 4096 / (max(canvas_y) - min(canvas_y))# Reference height for the canvas
|
||||||
|
|
||||||
objects.append(canvas)
|
objects.append(canvas)
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ def get_picker_datas(objects, canvas, rig):
|
||||||
color = [0.5, 0.5, 0.5]
|
color = [0.5, 0.5, 0.5]
|
||||||
|
|
||||||
shape = {
|
shape = {
|
||||||
|
'source_name': ob.name,
|
||||||
'tooltip': ob.rig_picker.name,
|
'tooltip': ob.rig_picker.name,
|
||||||
'points': points,
|
'points': points,
|
||||||
'polygons': polygons,
|
'polygons': polygons,
|
||||||
|
@ -96,7 +97,7 @@ def get_picker_datas(objects, canvas, rig):
|
||||||
picker_datas.append(shape)
|
picker_datas.append(shape)
|
||||||
|
|
||||||
|
|
||||||
print(picker_datas)
|
#print(picker_datas)
|
||||||
|
|
||||||
return picker_datas
|
return picker_datas
|
||||||
#rig.data.rig_picker['shapes'] = picker_datas
|
#rig.data.rig_picker['shapes'] = picker_datas
|
||||||
|
|
|
@ -171,7 +171,12 @@ class RP_OT_box_select(bpy.types.Operator):
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
def release_event(self):
|
def release_event(self):
|
||||||
if (self.start_mouse[0] != self.mouse[0] and self.start_mouse[1] != self.mouse[1]):
|
scn = bpy.context.scene
|
||||||
|
|
||||||
|
if scn.rig_picker.use_pick_bone:
|
||||||
|
self.picker.assign_bone_event()
|
||||||
|
|
||||||
|
elif (self.start_mouse[0] != self.mouse[0] and self.start_mouse[1] != self.mouse[1]):
|
||||||
self.picker.border_select(self.border, self.mode)
|
self.picker.border_select(self.border, self.mode)
|
||||||
else:
|
else:
|
||||||
self.picker.move_event(self.mouse)
|
self.picker.move_event(self.mouse)
|
||||||
|
|
|
@ -183,7 +183,7 @@ class RP_OT_save_picker(bpy.types.Operator):
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
scn = context.scene
|
scn = context.scene
|
||||||
canvas= scn.rig_picker.canvas
|
canvas = scn.rig_picker.canvas
|
||||||
rig = scn.rig_picker.rig
|
rig = scn.rig_picker.rig
|
||||||
shapes = [o for o in scn.objects if o != canvas and is_shape(o)]
|
shapes = [o for o in scn.objects if o != canvas and is_shape(o)]
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class RP_PT_picker_maker_panel(bpy.types.Panel):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
col = layout.column(align=False)
|
col = layout.column(align=False)
|
||||||
col.prop_search(scn.rig_picker, 'rig', scn, 'objects', text='Rig ')
|
col.prop_search(scn.rig_picker, 'rig', scn, 'objects', text='Rig ')
|
||||||
col.prop_search(scn.rig_picker, 'canvas', scn, 'objects', text='canvas ')
|
col.prop_search(scn.rig_picker, 'canvas', scn, 'objects', text='Canvas ')
|
||||||
col.prop_search(scn.rig_picker, 'symmetry', scn, 'objects', text='Symmetry ')
|
col.prop_search(scn.rig_picker, 'symmetry', scn, 'objects', text='Symmetry ')
|
||||||
|
|
||||||
if ob.type == 'ARMATURE':
|
if ob.type == 'ARMATURE':
|
||||||
|
@ -42,6 +42,7 @@ class RP_PT_picker_maker_panel(bpy.types.Panel):
|
||||||
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='ARROW_LEFTRIGHT', text='Mirror shape')
|
row.operator('rigpicker.mirror_shape', icon='ARROW_LEFTRIGHT', text='Mirror shape')
|
||||||
col.operator('rigpicker.name_from_bone', icon='SORTALPHA' , text='Name from bones')
|
col.operator('rigpicker.name_from_bone', icon='SORTALPHA' , text='Name from bones')
|
||||||
|
col.prop(scn.rig_picker, 'use_pick_bone', icon='EYEDROPPER', text='Auto bone assign')
|
||||||
|
|
||||||
|
|
||||||
if ob.type !='ARMATURE':
|
if ob.type !='ARMATURE':
|
||||||
|
|
88
picker.py
88
picker.py
|
@ -18,11 +18,12 @@ import threading
|
||||||
|
|
||||||
|
|
||||||
class Shape:
|
class Shape:
|
||||||
def __init__(self, picker, points, polygons=None, edges=None, tooltip='', color=None):
|
def __init__(self, picker, points, polygons=None, edges=None, tooltip='', color=None, source_name=''):
|
||||||
|
|
||||||
self.type = 'display'
|
self.type = 'display'
|
||||||
self.picker = picker
|
self.picker = picker
|
||||||
self.rig = picker.rig
|
self.rig = picker.rig
|
||||||
|
self.source_name = source_name
|
||||||
|
|
||||||
self.hover = False
|
self.hover = False
|
||||||
self.press = False
|
self.press = False
|
||||||
|
@ -116,9 +117,9 @@ class Shape:
|
||||||
|
|
||||||
|
|
||||||
class BoneShape(Shape):
|
class BoneShape(Shape):
|
||||||
def __init__(self, picker, points, polygons, edges, bone, tooltip='', color=None):
|
def __init__(self, picker, points, polygons, edges, bone, tooltip='', color=None, source_name=''):
|
||||||
super().__init__(picker, points=points, polygons=polygons, edges=edges,
|
super().__init__(picker, points=points, polygons=polygons, edges=edges,
|
||||||
tooltip=tooltip, color=color)
|
tooltip=tooltip, color=color, source_name=source_name)
|
||||||
|
|
||||||
self.type = 'bone'
|
self.type = 'bone'
|
||||||
self.bone = bone
|
self.bone = bone
|
||||||
|
@ -141,7 +142,7 @@ class BoneShape(Shape):
|
||||||
'hide': [0.85, 0.85, 0.85, 0.2],
|
'hide': [0.85, 0.85, 0.85, 0.2],
|
||||||
}
|
}
|
||||||
|
|
||||||
if bone.bone_group:
|
if bone and bone.bone_group:
|
||||||
normal_color = bone.bone_group.colors.normal.copy()
|
normal_color = bone.bone_group.colors.normal.copy()
|
||||||
normal_color.s *= 0.75
|
normal_color.s *= 0.75
|
||||||
self.bone_colors['normal'] = [*normal_color, 1]
|
self.bone_colors['normal'] = [*normal_color, 1]
|
||||||
|
@ -149,16 +150,27 @@ class BoneShape(Shape):
|
||||||
self.bone_colors['active'] = [*bone.bone_group.colors.active, 1]
|
self.bone_colors['active'] = [*bone.bone_group.colors.active, 1]
|
||||||
self.bone_colors['hide'] = [*normal_color, 0.1]
|
self.bone_colors['hide'] = [*normal_color, 0.1]
|
||||||
|
|
||||||
|
#self.color = [i for i in self.color]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def select(self):
|
def select(self):
|
||||||
|
if not self.bone:
|
||||||
|
return False
|
||||||
|
|
||||||
return self.bone in (bpy.context.selected_pose_bones or []) #self.bone.bone.select
|
return self.bone in (bpy.context.selected_pose_bones or []) #self.bone.bone.select
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def active(self):
|
def active(self):
|
||||||
|
if not self.bone:
|
||||||
|
return False
|
||||||
|
|
||||||
return self.bone == bpy.context.active_pose_bone #self.rig.data.bones.active == self.bone.bone
|
return self.bone == bpy.context.active_pose_bone #self.rig.data.bones.active == self.bone.bone
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hide(self):
|
def hide(self):
|
||||||
|
if not self.bone:
|
||||||
|
return False
|
||||||
|
|
||||||
#return self.bone not in (bpy.context.visible_pose_bones or [])
|
#return self.bone not in (bpy.context.visible_pose_bones or [])
|
||||||
bl = [i for i, l in enumerate(self.bone.bone.layers) if l]
|
bl = [i for i, l in enumerate(self.bone.bone.layers) if l]
|
||||||
rl = [i for i, l in enumerate(self.rig.data.layers) if l]
|
rl = [i for i, l in enumerate(self.rig.data.layers) if l]
|
||||||
|
@ -166,6 +178,9 @@ class BoneShape(Shape):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bone_color(self):
|
def bone_color(self):
|
||||||
|
if not self.bone:
|
||||||
|
return [0, 0, 0, 1]
|
||||||
|
|
||||||
bone = self.bone.bone
|
bone = self.bone.bone
|
||||||
|
|
||||||
bl = bone.layers
|
bl = bone.layers
|
||||||
|
@ -192,6 +207,10 @@ class BoneShape(Shape):
|
||||||
else:
|
else:
|
||||||
super().draw()
|
super().draw()
|
||||||
|
|
||||||
|
# Overlay the fill slightly with the bone color
|
||||||
|
#self.shader.uniform_float("color", (*self.bone_color[:3], 0.1))
|
||||||
|
#self.p_batch.draw(self.shader)
|
||||||
|
|
||||||
if self.select:
|
if self.select:
|
||||||
color = self.hover_color
|
color = self.hover_color
|
||||||
|
|
||||||
|
@ -204,6 +223,10 @@ class BoneShape(Shape):
|
||||||
self.shader.uniform_float("color", color)
|
self.shader.uniform_float("color", color)
|
||||||
self.p_batch.draw(self.shader)
|
self.p_batch.draw(self.shader)
|
||||||
|
|
||||||
|
#Overlay the fill slightly with the bone color
|
||||||
|
self.shader.uniform_float("color", (*self.bone_colors['normal'][:3], 0.1))
|
||||||
|
self.p_batch.draw(self.shader)
|
||||||
|
|
||||||
|
|
||||||
#self.contour_shader.bind()
|
#self.contour_shader.bind()
|
||||||
|
|
||||||
|
@ -218,23 +241,39 @@ class BoneShape(Shape):
|
||||||
bgl.glLineWidth(1)
|
bgl.glLineWidth(1)
|
||||||
bgl.glDisable(bgl.GL_BLEND)
|
bgl.glDisable(bgl.GL_BLEND)
|
||||||
|
|
||||||
|
def assign_bone_event(self):
|
||||||
|
|
||||||
|
#print('assign_bone_event', self)
|
||||||
|
scn = bpy.context.scene
|
||||||
|
rig = scn.rig_picker.rig
|
||||||
|
source_object = scn.objects.get(self.source_name)
|
||||||
|
if not source_object:
|
||||||
|
print(f'Source object {self.source_name} not found')
|
||||||
|
return
|
||||||
|
|
||||||
|
active_bone = rig.data.bones.active
|
||||||
|
if not active_bone:
|
||||||
|
print('You need to have an active bone')
|
||||||
|
return
|
||||||
|
|
||||||
|
source_object.rig_picker.name = rig.data.bones.active.name
|
||||||
|
|
||||||
def release_event(self, mode='SET'):
|
def release_event(self, mode='SET'):
|
||||||
super().release_event(mode)
|
super().release_event(mode)
|
||||||
|
|
||||||
if self.hide:
|
if self.hide or not self.bone:
|
||||||
return
|
return
|
||||||
|
|
||||||
select = True
|
select = True
|
||||||
if mode == 'SUBSTRACT':
|
if mode == 'SUBSTRACT':
|
||||||
select = False
|
select = False
|
||||||
|
|
||||||
|
self.bone.bone.select = select
|
||||||
if self.hover:
|
if self.hover:
|
||||||
self.bone.bone.select = select
|
|
||||||
|
|
||||||
if mode != 'SUBSTRACT':
|
if mode != 'SUBSTRACT':
|
||||||
self.rig.data.bones.active = self.bone.bone
|
self.rig.data.bones.active = self.bone.bone
|
||||||
else:
|
|
||||||
self.bone.bone.select = select
|
|
||||||
|
|
||||||
def border_select(self, border, mode='SET'):
|
def border_select(self, border, mode='SET'):
|
||||||
'''
|
'''
|
||||||
|
@ -242,6 +281,8 @@ class BoneShape(Shape):
|
||||||
not any(intersect_point_quad_2d(b, *border) for b in self.bound) ):
|
not any(intersect_point_quad_2d(b, *border) for b in self.bound) ):
|
||||||
return
|
return
|
||||||
'''
|
'''
|
||||||
|
if not self.bone:
|
||||||
|
return
|
||||||
|
|
||||||
if self.hide:
|
if self.hide:
|
||||||
self.bone.bone.select = False
|
self.bone.bone.select = False
|
||||||
|
@ -287,8 +328,9 @@ class BoneShape(Shape):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class OperatorShape(Shape):
|
class OperatorShape(Shape):
|
||||||
def __init__(self, picker, points, polygons, operator, tooltip='', color=None):
|
def __init__(self, picker, points, polygons, operator, tooltip='', color=None, source_name=''):
|
||||||
super().__init__(picker, points=points, polygons=polygons, tooltip=tooltip, color=color)
|
super().__init__(picker, points=points, polygons=polygons, tooltip=tooltip,
|
||||||
|
color=color, source_name=source_name)
|
||||||
|
|
||||||
self.type = 'operator'
|
self.type = 'operator'
|
||||||
self.active_color = [1, 1, 1, 0.15]
|
self.active_color = [1, 1, 1, 0.15]
|
||||||
|
@ -376,11 +418,13 @@ class Picker:
|
||||||
|
|
||||||
elif s['type'] == 'BONE':
|
elif s['type'] == 'BONE':
|
||||||
bone = rig.pose.bones.get(s['bone'])
|
bone = rig.pose.bones.get(s['bone'])
|
||||||
if not bone:
|
#if not bone:
|
||||||
print(f'Bone {s["bone"]} not exist')
|
# print(f'Bone {s["bone"]} not exist')
|
||||||
continue
|
# continue
|
||||||
|
|
||||||
shape = BoneShape(
|
shape = BoneShape(
|
||||||
self,
|
self,
|
||||||
|
source_name=s['source_name'],
|
||||||
points=s['points'],
|
points=s['points'],
|
||||||
polygons=s['polygons'],
|
polygons=s['polygons'],
|
||||||
edges=s['edges'],
|
edges=s['edges'],
|
||||||
|
@ -391,6 +435,7 @@ class Picker:
|
||||||
elif s['type'] == 'OPERATOR':
|
elif s['type'] == 'OPERATOR':
|
||||||
shape = OperatorShape(
|
shape = OperatorShape(
|
||||||
self,
|
self,
|
||||||
|
source_name=s['source_name'],
|
||||||
points=s['points'],
|
points=s['points'],
|
||||||
polygons=s['polygons'],
|
polygons=s['polygons'],
|
||||||
operator=s['operator'],
|
operator=s['operator'],
|
||||||
|
@ -400,6 +445,13 @@ class Picker:
|
||||||
|
|
||||||
self.shapes.append(shape)
|
self.shapes.append(shape)
|
||||||
|
|
||||||
|
def assign_bone_event(self):
|
||||||
|
for s in self.shapes:
|
||||||
|
if s.type=='bone' and s.hover:
|
||||||
|
s.assign_bone_event()
|
||||||
|
|
||||||
|
bpy.ops.rigpicker.save_picker()
|
||||||
|
|
||||||
def press_event(self, mode='SET'):
|
def press_event(self, mode='SET'):
|
||||||
for s in self.shapes:
|
for s in self.shapes:
|
||||||
if s.hover:
|
if s.hover:
|
||||||
|
@ -427,6 +479,8 @@ class Picker:
|
||||||
def tooltip_event(self):
|
def tooltip_event(self):
|
||||||
#print('Tooltip Event', self)
|
#print('Tooltip Event', self)
|
||||||
|
|
||||||
|
#print(self.hover_shape, self.hover_shape.type)
|
||||||
|
|
||||||
if self.hover_shape and self.hover_shape.type != 'display':
|
if self.hover_shape and self.hover_shape.type != 'display':
|
||||||
if self.hover_shape.type == 'bone':
|
if self.hover_shape.type == 'bone':
|
||||||
self.tooltip = self.hover_shape.bone.name
|
self.tooltip = self.hover_shape.bone.name
|
||||||
|
@ -441,6 +495,8 @@ class Picker:
|
||||||
|
|
||||||
self.timer.cancel()
|
self.timer.cancel()
|
||||||
|
|
||||||
|
#print(self.tooltip)
|
||||||
|
|
||||||
self.region.tag_redraw()
|
self.region.tag_redraw()
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -567,6 +623,8 @@ def draw_callback_px():
|
||||||
|
|
||||||
text = picker.tooltip
|
text = picker.tooltip
|
||||||
|
|
||||||
|
#print('Draw text', text)
|
||||||
|
|
||||||
font_id = 0
|
font_id = 0
|
||||||
#blf.dimensions(font_id, text)
|
#blf.dimensions(font_id, text)
|
||||||
blf.enable(font_id, blf.SHADOW)
|
blf.enable(font_id, blf.SHADOW)
|
||||||
|
@ -575,11 +633,11 @@ def draw_callback_px():
|
||||||
|
|
||||||
# BLF drawing routine
|
# BLF drawing routine
|
||||||
blf.position(font_id, picker.tooltip_mouse[0]-5, picker.tooltip_mouse[1]+5, 0)
|
blf.position(font_id, picker.tooltip_mouse[0]-5, picker.tooltip_mouse[1]+5, 0)
|
||||||
blf.size(font_id, 14, 0)
|
blf.size(font_id, 14)
|
||||||
blf.color(font_id, 1, 1, 1, 1)
|
blf.color(font_id, 1, 1, 1, 1)
|
||||||
|
|
||||||
blf.shadow(font_id , 5, 0.0, 0.0, 0.0, 1)
|
blf.shadow(font_id , 5, 0.0, 0.0, 0.0, 1)
|
||||||
blf.shadow_offset(font_id, 1, -1)
|
blf.shadow_offset(font_id, 2, -2)
|
||||||
|
|
||||||
blf.draw(font_id, text)
|
blf.draw(font_id, text)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.props import EnumProperty, StringProperty, PointerProperty
|
from bpy.props import EnumProperty, StringProperty, PointerProperty, BoolProperty
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -42,7 +42,8 @@ class RP_PG_scene_ui_settings(bpy.types.PropertyGroup):
|
||||||
symmetry: PointerProperty(type=bpy.types.Object)
|
symmetry: PointerProperty(type=bpy.types.Object)
|
||||||
#idname: EnumProperty(items=[])
|
#idname: EnumProperty(items=[])
|
||||||
destination: StringProperty(subtype='FILE_PATH')
|
destination: StringProperty(subtype='FILE_PATH')
|
||||||
#bone_list: bpy.props.EnumProperty(items = bones_item)
|
#bone_list: bpy.props.EnumProperty(items = bones_item
|
||||||
|
use_pick_bone : BoolProperty(default=False)
|
||||||
|
|
||||||
|
|
||||||
class RP_OT_operator_selector(bpy.types.Operator):
|
class RP_OT_operator_selector(bpy.types.Operator):
|
||||||
|
|
20
utils.py
20
utils.py
|
@ -184,20 +184,18 @@ def find_mirror(name):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def is_shape(ob):
|
def is_shape(ob):
|
||||||
shape = False
|
scn = bpy.context.scene
|
||||||
|
canvas = scn.rig_picker.canvas
|
||||||
|
if not canvas or ob.hide_render:
|
||||||
|
return False
|
||||||
|
|
||||||
if ob.hide_render:
|
shapes = {ob for col in canvas.users_collection for ob in col.all_objects}
|
||||||
return shape
|
|
||||||
|
|
||||||
if ob.type in ('MESH', 'CURVE', 'FONT'):
|
if ob.type in ('MESH', 'CURVE', 'FONT') and ob in shapes:
|
||||||
if ob.rig_picker.shape_type == 'BONE':
|
return True
|
||||||
if ob.rig_picker.name:
|
|
||||||
shape = True
|
return False
|
||||||
else:
|
|
||||||
shape = True
|
|
||||||
return shape
|
|
||||||
|
|
||||||
def is_over_region(self,context,event):
|
def is_over_region(self,context,event):
|
||||||
inside = 2 < event.mouse_region_x < context.region.width -2 and \
|
inside = 2 < event.mouse_region_x < context.region.width -2 and \
|
||||||
|
|
Loading…
Reference in New Issue