active bone shape

master
Christophe SEUX 2023-02-06 15:10:00 +01:00
parent 32abe225f3
commit 2cd54ee22b
23 changed files with 53 additions and 17 deletions

View File

@ -53,6 +53,7 @@ def register():
#bpy.types.Scene.bone_widget = bpy.props.PointerProperty(type=BoneWidgetSettings) #bpy.types.Scene.bone_widget = bpy.props.PointerProperty(type=BoneWidgetSettings)
#get_widgets(DefaultFolder, DefaultShapes) #get_widgets(DefaultFolder, DefaultShapes)
#get_widgets(CustomFolder, CustomShapes) #get_widgets(CustomFolder, CustomShapes)
sys.modules.update({"bone_widget.ctx": context.BW_context()})
from bone_widget import ctx from bone_widget import ctx
for f in ctx.folders: for f in ctx.folders:

View File

@ -153,12 +153,15 @@ class BW_context:
ob = bpy.context.object ob = bpy.context.object
if ob.type == 'ARMATURE': if ob.type == 'ARMATURE':
bones = ob.pose.bones return bpy.context.selected_pose_bones
return [b for b in bones if b.bone.select] #bones = ob.pose.bones
else: #return [b for b in bones if b.bone.select]
elif self.rig:
widgets = self.selected_widgets widgets = self.selected_widgets
return [b for b in self.rig.pose.bones if b.custom_shape in widgets] return [b for b in self.rig.pose.bones if b.custom_shape in widgets]
return []
@property @property
def widget(self): def widget(self):
if not self.poll(): if not self.poll():
@ -253,7 +256,7 @@ class BW_context:
return False return False
if ob.type == 'ARMATURE' and ob.mode == 'POSE': if ob.type == 'ARMATURE' and ob.mode == 'POSE':
return True return True
if ob.type in ('MESH','CURVE'): if ob.type in ('MESH', 'CURVE'):
return True return True
return False return False

View File

@ -420,7 +420,7 @@ class BW_OT_create_widget(Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return ctx.bone and ctx.active_widget return ctx.selected_bones and ctx.active_widget
def execute(self, context): def execute(self, context):
folder = ctx.active_folder folder = ctx.active_folder
@ -633,23 +633,33 @@ class BW_OT_add_widget(Operator):
bl_label = "Add Widget" bl_label = "Add Widget"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
replace: BoolProperty(default=False, name='Replace')
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return ctx.widget return ctx.widget
def invoke(self, context, event):
if event.ctrl:
self.replace = True
return self.execute(context)
def execute(self, context): def execute(self, context):
folder = ctx.active_folder
shape = ctx.widget shape = ctx.widget
bone = ctx.bone bone = ctx.bone
if bone: if self.replace and ctx.active_widget:
name = bone.name name = ctx.active_widget.name
else: else: #Find a unique name
name = shape.name name = folder.get_widget_display_name(bone.name if bone else shape.name)
#name = name.split('-', 1)[-1] i = 0
#name = re.sub('.\d{3}', '', name) org_name = name
folder = ctx.active_folder while name in folder.widgets:
name = folder.get_widget_clean_name(name) name = f'{org_name} {i:02d}'
i += 1
widget_path = folder.get_widget_path(name) widget_path = folder.get_widget_path(name)
icon_path = folder.get_icon_path(name) icon_path = folder.get_icon_path(name)
@ -661,10 +671,11 @@ class BW_OT_add_widget(Operator):
shape_copy = shape.copy() shape_copy = shape.copy()
shape_copy.data = shape_copy.data.copy() shape_copy.data = shape_copy.data.copy()
shape_copy.matrix_world = get_bone_matrix(bone) if bone:
shape_copy.matrix_world = get_bone_matrix(bone)
mat = custom_shape_matrix(bone) mat = custom_shape_matrix(bone)
shape_copy.data.transform(mat) shape_copy.data.transform(mat)
render_widget(shape_copy, icon_path) render_widget(shape_copy, icon_path)
folder.add_widget(name) folder.add_widget(name)

View File

@ -70,12 +70,17 @@ def refresh(self, context):
bpy.ops.bonewidget.refresh_folders() bpy.ops.bonewidget.refresh_folders()
class BW_PG_folder(PropertyGroup): class BW_PG_folder(PropertyGroup):
icons = bpy.utils.previews.new() #icons = bpy.utils.previews.new()
path: StringProperty(subtype='FILE_PATH', default='Default', update=refresh) path: StringProperty(subtype='FILE_PATH', default='Default', update=refresh)
expand: BoolProperty() expand: BoolProperty()
widgets: CollectionProperty(type=BW_PG_widget) widgets: CollectionProperty(type=BW_PG_widget)
widget_index: IntProperty() widget_index: IntProperty()
@property
def icons(self):
prefs = ctx.prefs
return prefs.get_folder_previews(self.as_pointer())
@property @property
def abspath(self): def abspath(self):
return ctx.abspath(self.path) return ctx.abspath(self.path)
@ -202,6 +207,8 @@ class BW_PG_bone_color(PropertyGroup):
class BW_prefs(AddonPreferences): class BW_prefs(AddonPreferences):
bl_idname = __package__ bl_idname = __package__
previews = {}
default_folder: PointerProperty(type=BW_PG_folder) default_folder: PointerProperty(type=BW_PG_folder)
folders: CollectionProperty(type=BW_PG_folder) folders: CollectionProperty(type=BW_PG_folder)
folder_index: IntProperty() folder_index: IntProperty()
@ -225,6 +232,12 @@ class BW_prefs(AddonPreferences):
#use_custom_colors: BoolProperty(name='Custom Colors', default=False, update=set_default_colors) #use_custom_colors: BoolProperty(name='Custom Colors', default=False, update=set_default_colors)
def get_folder_previews(self, adress):
if adress not in self.previews:
self.previews[adress] = bpy.utils.previews.new()
return self.previews[adress]
def draw(self, context): def draw(self, context):
draw_prefs(self.layout) draw_prefs(self.layout)

8
ui.py
View File

@ -249,6 +249,14 @@ class BW_PT_main(Panel):
edit_row.operator('bonewidget.create_widget', text='Create') edit_row.operator('bonewidget.create_widget', text='Create')
edit_row.operator('bonewidget.edit_widget', text='Edit') edit_row.operator('bonewidget.edit_widget', text='Edit')
# Draw Active Bone Shape
if context.active_pose_bone:
widget_col.separator()
col = widget_col.column(align=False)
col.use_property_split = True
col.prop(context.active_pose_bone, 'name', text='Bone Name')
col.prop(context.active_pose_bone, 'custom_shape', text='Widget')
if ctx.prefs.use_custom_collection and ctx.rig: if ctx.prefs.use_custom_collection and ctx.rig:
widget_col.separator() widget_col.separator()
row = widget_col.row() row = widget_col.row()

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
widgets/Default/arrow.blend Normal file

Binary file not shown.

BIN
widgets/Default/arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

BIN
widgets/Default/plane.blend Normal file

Binary file not shown.

BIN
widgets/Default/plane.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 1.7 KiB