Rigify: generate UI script for custom properties from metarig.
Improve auto-generated UI naming and update basic.pivot, basic.raw_copy and basic.super_copy. Also allow raw_copy to generate builtin widgets.
This commit is contained in:
parent
a7c0667baa
commit
1ada831ca1
|
@ -24,6 +24,7 @@ from ...base_rig import BaseRig
|
|||
|
||||
from ...utils.naming import make_derived_name
|
||||
from ...utils.bones import set_bone_widget_transform
|
||||
from ...utils.mechanism import copy_custom_properties_with_ui
|
||||
from ...utils.widgets import layout_widget_dropdown, create_registered_widget
|
||||
from ...utils.widgets_basic import create_pivot_widget
|
||||
from ...utils.switch_parent import SwitchParentBuilder
|
||||
|
@ -114,11 +115,13 @@ class Rig(BaseRig):
|
|||
|
||||
|
||||
def configure_bones(self):
|
||||
if self.make_control:
|
||||
self.copy_bone_properties(self.bones.org, self.bones.ctrl.master)
|
||||
org = self.bones.org
|
||||
ctrl = self.bones.ctrl
|
||||
main_ctl = ctrl.master if self.make_control else ctrl.pivot
|
||||
|
||||
else:
|
||||
self.copy_bone_properties(self.bones.org, self.bones.ctrl.pivot)
|
||||
self.copy_bone_properties(org, main_ctl, props=False)
|
||||
|
||||
copy_custom_properties_with_ui(self, org, main_ctl)
|
||||
|
||||
|
||||
def rig_bones(self):
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
import bpy
|
||||
|
||||
from ...utils.naming import strip_org, strip_prefix, choose_derived_bone
|
||||
from ...utils.naming import strip_org, strip_prefix, choose_derived_bone, is_control_bone
|
||||
from ...utils.mechanism import copy_custom_properties_with_ui
|
||||
from ...utils.widgets import layout_widget_dropdown, create_registered_widget
|
||||
|
||||
from ...base_rig import BaseRig
|
||||
from ...base_generate import SubstitutionRig
|
||||
|
@ -156,13 +158,31 @@ class Rig(BaseRig, RelinkConstraintsMixin):
|
|||
def parent_bones(self):
|
||||
self.relink_bone_parent(self.bones.org)
|
||||
|
||||
def configure_bones(self):
|
||||
org = self.bones.org
|
||||
if is_control_bone(org):
|
||||
copy_custom_properties_with_ui(self, org, org, ui_controls=[org])
|
||||
|
||||
def rig_bones(self):
|
||||
self.relink_bone_constraints(self.bones.org)
|
||||
|
||||
def generate_widgets(self):
|
||||
org = self.bones.org
|
||||
widget = self.params.optional_widget_type
|
||||
if widget and is_control_bone(org):
|
||||
create_registered_widget(self.obj, org, widget)
|
||||
|
||||
@classmethod
|
||||
def add_parameters(self, params):
|
||||
self.add_relink_constraints_params(params)
|
||||
|
||||
params.optional_widget_type = bpy.props.StringProperty(
|
||||
name = "Widget Type",
|
||||
default = '',
|
||||
description = "Choose the type of the widget to create"
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def parameters_ui(self, layout, params):
|
||||
col = layout.column()
|
||||
|
@ -171,6 +191,11 @@ class Rig(BaseRig, RelinkConstraintsMixin):
|
|||
|
||||
self.add_relink_constraints_ui(layout, params)
|
||||
|
||||
pbone = bpy.context.active_pose_bone
|
||||
|
||||
if pbone and is_control_bone(pbone.name):
|
||||
layout_widget_dropdown(layout, params, "optional_widget_type")
|
||||
|
||||
|
||||
#add_parameters = InstanceRig.add_parameters
|
||||
#parameters_ui = InstanceRig.parameters_ui
|
||||
|
|
|
@ -23,6 +23,7 @@ import bpy
|
|||
from ...base_rig import BaseRig
|
||||
|
||||
from ...utils.naming import strip_org, make_deformer_name
|
||||
from ...utils.mechanism import copy_custom_properties_with_ui
|
||||
from ...utils.widgets import layout_widget_dropdown, create_registered_widget
|
||||
from ...utils.widgets_basic import create_bone_widget
|
||||
|
||||
|
@ -77,7 +78,9 @@ class Rig(BaseRig, RelinkConstraintsMixin):
|
|||
bones = self.bones
|
||||
|
||||
if self.make_control:
|
||||
self.copy_bone_properties(bones.org, bones.ctrl)
|
||||
self.copy_bone_properties(bones.org, bones.ctrl, props=False)
|
||||
|
||||
copy_custom_properties_with_ui(self, bones.org, bones.ctrl)
|
||||
|
||||
|
||||
def rig_bones(self):
|
||||
|
|
|
@ -196,16 +196,9 @@ def copy_bone_properties(obj, bone_name_1, bone_name_2, transforms=True, props=T
|
|||
|
||||
# Copy custom properties
|
||||
if props:
|
||||
for key in pose_bone_1.keys():
|
||||
if key != "_RNA_UI" \
|
||||
and key != "rigify_parameters" \
|
||||
and key != "rigify_type":
|
||||
prop1 = rna_idprop_ui_prop_get(pose_bone_1, key, create=False)
|
||||
pose_bone_2[key] = pose_bone_1[key]
|
||||
if prop1 is not None:
|
||||
prop2 = rna_idprop_ui_prop_get(pose_bone_2, key, create=True)
|
||||
for key in prop1.keys():
|
||||
prop2[key] = prop1[key]
|
||||
from .mechanism import copy_custom_properties
|
||||
|
||||
copy_custom_properties(pose_bone_1, pose_bone_2)
|
||||
|
||||
if widget:
|
||||
pose_bone_2.custom_shape = pose_bone_1.custom_shape
|
||||
|
|
|
@ -387,16 +387,18 @@ def copy_custom_properties(src, dest, *, prefix='', dest_prefix='', link_driver=
|
|||
if key.startswith(prefix) and key not in exclude:
|
||||
new_key = dest_prefix + key[len(prefix):]
|
||||
|
||||
dest[new_key] = value
|
||||
|
||||
info = rna_idprop_ui_prop_get(src, key, False)
|
||||
if info:
|
||||
info2 = rna_idprop_ui_prop_get(dest, new_key, True)
|
||||
for ki, vi in info.items():
|
||||
info2[ki] = vi
|
||||
|
||||
if link_driver:
|
||||
make_driver(src, quote_property(key), variables=[(dest.id_data, dest, new_key)])
|
||||
if src != dest or new_key != key:
|
||||
dest[new_key] = value
|
||||
|
||||
if info:
|
||||
info2 = rna_idprop_ui_prop_get(dest, new_key, True)
|
||||
for ki, vi in info.items():
|
||||
info2[ki] = vi
|
||||
|
||||
if link_driver:
|
||||
make_driver(src, quote_property(key), variables=[(dest.id_data, dest, new_key)])
|
||||
|
||||
res.append((key, new_key, value, info))
|
||||
|
||||
|
@ -412,10 +414,21 @@ def copy_custom_properties_with_ui(rig, src, dest_bone, *, ui_controls=None, **o
|
|||
mapping = copy_custom_properties(src, bone, **options)
|
||||
|
||||
if mapping:
|
||||
panel = rig.script.panel_with_selected_check(rig, ui_controls or rig.bones.ctrl.flatten())
|
||||
panel = rig.script.panel_with_selected_check(rig, ui_controls or rig.bones.flatten('ctrl'))
|
||||
|
||||
for key,new_key,value,info in sorted(mapping, key=lambda item: item[1]):
|
||||
name = new_key
|
||||
|
||||
# Replace delimiters with spaces
|
||||
if ' ' not in name:
|
||||
name = re.sub(r'[_.-]', ' ', name)
|
||||
# Split CamelCase
|
||||
if ' ' not in name:
|
||||
name = re.sub(r'([a-z])([A-Z])', r'\1 \2', name)
|
||||
# Capitalize
|
||||
if name.lower() == name:
|
||||
name = name.title()
|
||||
|
||||
for key,new_key,value,info in mapping:
|
||||
name = re.sub(r'[_.-]', ' ', new_key).title()
|
||||
slider = type(value) is float and info and info.get("min", None) == 0 and info.get("max", None) == 1
|
||||
|
||||
panel.custom_prop(dest_bone, new_key, text=name, slider=slider)
|
||||
|
|
|
@ -43,6 +43,10 @@ def split_name(name):
|
|||
return NameParts(*name_parts.groups())
|
||||
|
||||
|
||||
def is_control_bone(name):
|
||||
return not split_name(name).prefix
|
||||
|
||||
|
||||
def combine_name(parts, *, prefix=None, base=None, side_z=None, side=None, number=None):
|
||||
eff_prefix = prefix if prefix is not None else parts.prefix
|
||||
eff_number = number if number is not None else parts.number
|
||||
|
|
Loading…
Reference in New Issue