Rigify: use separate widget collection for each generated rig.
As pointed out in comments to T73114, using the same name has downsides. In addition, remove the widget parent object that was inherited from the old pre-collection way Rigify worked and has no other purpose than grouping objects like the collection already does. Rename the widgets and the collection when renaming the rig. Finally as an aside add a couple of options to create_widget.
This commit is contained in:
parent
c93dc35588
commit
f8d6489fb6
|
@ -112,35 +112,47 @@ class Generator(base_generate.BaseGenerator):
|
|||
return obj
|
||||
|
||||
|
||||
def __create_widget_group(self, new_group_name):
|
||||
context = self.context
|
||||
scene = self.scene
|
||||
id_store = self.id_store
|
||||
|
||||
# Create/find widge collection
|
||||
self.widget_collection = ensure_widget_collection(context)
|
||||
|
||||
# Remove wgts if force update is set
|
||||
def __create_widget_group(self):
|
||||
new_group_name = "WGTS_" + self.obj.name
|
||||
wgts_group_name = "WGTS_" + (self.rig_old_name or self.obj.name)
|
||||
if wgts_group_name in scene.objects and self.metarig.data.rigify_force_widget_update:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for wgt in bpy.data.objects[wgts_group_name].children:
|
||||
wgt.select_set(True)
|
||||
bpy.ops.object.delete(use_global=False)
|
||||
|
||||
# Find the old widgets collection
|
||||
old_collection = bpy.data.collections.get(wgts_group_name)
|
||||
|
||||
if not old_collection:
|
||||
# Update the old 'Widgets' collection
|
||||
legacy_collection = bpy.data.collections.get('Widgets')
|
||||
|
||||
if legacy_collection and wgts_group_name in legacy_collection.objects:
|
||||
legacy_collection.name = wgts_group_name
|
||||
old_collection = legacy_collection
|
||||
|
||||
if old_collection:
|
||||
# Remove widgets if force update is set
|
||||
if self.metarig.data.rigify_force_widget_update:
|
||||
for obj in list(old_collection.objects):
|
||||
bpy.data.objects.remove(obj)
|
||||
|
||||
# Rename widgets and collection if renaming
|
||||
if self.rig_old_name:
|
||||
bpy.data.objects[wgts_group_name].name = new_group_name
|
||||
old_prefix = WGT_PREFIX + self.rig_old_name + "_"
|
||||
new_prefix = WGT_PREFIX + self.obj.name + "_"
|
||||
|
||||
# Create Group widget
|
||||
wgts_group_name = new_group_name
|
||||
if wgts_group_name not in scene.objects:
|
||||
if wgts_group_name in bpy.data.objects:
|
||||
bpy.data.objects[wgts_group_name].user_clear()
|
||||
bpy.data.objects.remove(bpy.data.objects[wgts_group_name])
|
||||
mesh = bpy.data.meshes.new(wgts_group_name)
|
||||
wgts_obj = bpy.data.objects.new(wgts_group_name, mesh)
|
||||
self.widget_collection.objects.link(wgts_obj)
|
||||
for obj in list(old_collection.objects):
|
||||
if obj.name.startswith(old_prefix):
|
||||
new_name = new_prefix + obj.name[len(old_prefix):]
|
||||
elif obj.name == wgts_group_name:
|
||||
new_name = new_group_name
|
||||
else:
|
||||
continue
|
||||
|
||||
obj.data.name = new_name
|
||||
obj.name = new_name
|
||||
|
||||
old_collection.name = new_group_name
|
||||
|
||||
# Create/find widget collection
|
||||
self.widget_collection = ensure_widget_collection(self.context, new_group_name)
|
||||
self.wgts_group_name = new_group_name
|
||||
|
||||
|
||||
|
@ -351,7 +363,7 @@ class Generator(base_generate.BaseGenerator):
|
|||
|
||||
#------------------------------------------
|
||||
# Create Group widget
|
||||
self.__create_widget_group("WGTS_" + obj.name)
|
||||
self.__create_widget_group()
|
||||
|
||||
t.tick("Create main WGTS: ")
|
||||
|
||||
|
|
|
@ -65,9 +65,7 @@ def filter_layer_collections_by_object(layer_collections, obj):
|
|||
return [lc for lc in layer_collections if obj in lc.collection.objects.values()]
|
||||
|
||||
|
||||
def ensure_widget_collection(context):
|
||||
wgts_collection_name = "Widgets"
|
||||
|
||||
def ensure_widget_collection(context, wgts_collection_name):
|
||||
view_layer = context.view_layer
|
||||
layer_collection = bpy.context.layer_collection
|
||||
collection = layer_collection.collection
|
||||
|
@ -89,6 +87,8 @@ def ensure_widget_collection(context):
|
|||
collection.children.link(widget_collection)
|
||||
widget_layer_collection = [c for c in layer_collection.children if c.collection == widget_collection][0]
|
||||
|
||||
widget_layer_collection.exclude = True
|
||||
|
||||
# Make the widget the active collection for the upcoming added (widget) objects
|
||||
view_layer.active_layer_collection = widget_layer_collection
|
||||
return widget_collection
|
||||
|
|
|
@ -54,7 +54,7 @@ def obj_to_bone(obj, rig, bone_name, bone_transform_name=None):
|
|||
obj.matrix_basis = rig.matrix_world @ bone.bone.matrix_local @ Matrix.Scale(scale, 4)
|
||||
|
||||
|
||||
def create_widget(rig, bone_name, bone_transform_name=None):
|
||||
def create_widget(rig, bone_name, bone_transform_name=None, *, widget_name=None, widget_force_new=False):
|
||||
""" Creates an empty widget object for a bone, and returns the object.
|
||||
"""
|
||||
assert rig.mode != 'EDIT'
|
||||
|
@ -64,37 +64,34 @@ def create_widget(rig, bone_name, bone_transform_name=None):
|
|||
if bone.custom_shape:
|
||||
return None
|
||||
|
||||
obj_name = WGT_PREFIX + rig.name + '_' + bone_name
|
||||
obj_name = widget_name or WGT_PREFIX + rig.name + '_' + bone_name
|
||||
scene = bpy.context.scene
|
||||
collection = ensure_widget_collection(bpy.context)
|
||||
collection = ensure_widget_collection(bpy.context, 'WGTS_' + rig.name)
|
||||
|
||||
# Check if it already exists in the scene
|
||||
if obj_name in scene.objects:
|
||||
# Move object to bone position, in case it changed
|
||||
obj = scene.objects[obj_name]
|
||||
obj_to_bone(obj, rig, bone_name, bone_transform_name)
|
||||
if not widget_force_new:
|
||||
if obj_name in scene.objects:
|
||||
# Move object to bone position, in case it changed
|
||||
obj = scene.objects[obj_name]
|
||||
obj_to_bone(obj, rig, bone_name, bone_transform_name)
|
||||
|
||||
return None
|
||||
|
||||
return None
|
||||
else:
|
||||
# Delete object if it exists in blend data but not scene data.
|
||||
# This is necessary so we can then create the object without
|
||||
# name conflicts.
|
||||
if obj_name in bpy.data.objects:
|
||||
bpy.data.objects[obj_name].user_clear()
|
||||
bpy.data.objects.remove(bpy.data.objects[obj_name])
|
||||
|
||||
# Create mesh object
|
||||
mesh = bpy.data.meshes.new(obj_name)
|
||||
obj = bpy.data.objects.new(obj_name, mesh)
|
||||
collection.objects.link(obj)
|
||||
# Create mesh object
|
||||
mesh = bpy.data.meshes.new(obj_name)
|
||||
obj = bpy.data.objects.new(obj_name, mesh)
|
||||
collection.objects.link(obj)
|
||||
|
||||
# Move object to bone position and set layers
|
||||
obj_to_bone(obj, rig, bone_name, bone_transform_name)
|
||||
wgts_group_name = 'WGTS_' + rig.name
|
||||
if wgts_group_name in bpy.data.objects.keys():
|
||||
obj.parent = bpy.data.objects[wgts_group_name]
|
||||
# Move object to bone position and set layers
|
||||
obj_to_bone(obj, rig, bone_name, bone_transform_name)
|
||||
|
||||
return obj
|
||||
return obj
|
||||
|
||||
|
||||
def create_circle_polygon(number_verts, axis, radius=1.0, head_tail=0.0):
|
||||
|
|
Loading…
Reference in New Issue