Skip to content

Commit

Permalink
Merge pull request #570 from james-baber/main
Browse files Browse the repository at this point in the history
UE to Rigify 1.6.1
  • Loading branch information
james-baber authored Mar 2, 2023
2 parents 3329038 + 9862613 commit d2d2758
Show file tree
Hide file tree
Showing 14 changed files with 3,069 additions and 57 deletions.
10 changes: 5 additions & 5 deletions docs/ue2rigify/user-interface/3d-view-panel.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This section defines all the properties and operators depicted below in the ‘U
![1](./images/3d-view-panel/1.jpg)
![2](./images/3d-view-panel/2.jpg)
![3](./images/3d-view-panel/3.jpg)
![4](./images/3d-view-panel/4.jpg)
![4](./images/3d-view-panel/4.png)

### Source

Expand Down Expand Up @@ -66,7 +66,7 @@ This operator switches the current mode to ‘Source’ mode, and restores the v

This operator bakes the ‘Control’ rig actions to the ‘Source’ rig actions.

### Freeze
This operator freezes the rig so the user doesn't lose their data by changing modes. If the .blend file is saved in control mode, UE to Rigify will automatically freeze the rig so the rig stays unmodified from when it was last saved.
Since mode changes are actually a complete deletion and creation of a new rigify rig, only the info provided by the "template" will be available after a mode change. So this is what freezing is for; it is a way to prevent doing a mode change. Mode changes can potentially be destructive. If you are adding information that is not through the rigify properties on the metarig, or through the node trees, then that data will be deleted on a mode change.
UE to Rigify is designed to quickly create and delete all the constraint hierarchy, rigify rigs, and their associated data while the user is flipping through modes and editing the custom template. However, once a final custom template is made, it is highly recommended that the user freeze the rig when animating in control mode.
### Bake every bone

If enabled, this will bake every bone on the source rig. If not enabled, it will only bake the source rig bones
that are linked to the control rig's FK bones in the FK to Source template.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions tests/test_ue2rigify_mannequins.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@ def test_baking(self):
'template': 'male_mannequin',
'control_rig': 'rig',
'animations': ['third_person_run_01', 'third_person_walk_01'],
# 'animations': ['third_person_walk_01'],
'bones': ['pelvis', 'calf_r', 'hand_l'],
# 'bones': ['pelvis', 'calf_r', 'foot_l', 'hand_l'], # TODO make this pass with the hands and feet
'bones': ['pelvis', 'calf_r'],
'frames': [2, 7],
'ik_fk_switch': {'upper_arm_parent.L': 'hand_ik.L'}
'ik_fk_switch': {
# IK bake is not precise, greater than 2cm world location difference
'upper_arm_parent.L': 'hand_ik.L',
'thigh_parent.L': 'foot_ik.L'
}
},
# TODO investigate female template fix failure
# 'female_root': {
Expand Down
4 changes: 2 additions & 2 deletions ue2rigify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"name": "UE to Rigify",
"author": "Epic Games Inc.",
"description": "Allows you to drive a given rig and its animations with a Rigify rig.",
"blender": (2, 93, 0),
"version": (1, 6, 0),
"version": (1, 6, 1),
"blender": (3, 3, 0),
"location": "3D View > Tools > UE to Rigify",
"wiki_url": "https://epicgames.github.io/BlenderTools/ue2rigify",
"warning": "",
Expand Down
142 changes: 124 additions & 18 deletions ue2rigify/core/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def get_from_rig_animation_data(from_rig_object, to_rig_object, links_data, prop
:param object properties: The property group that contains variables that maintain the addon's correct state.
:return dict: A dictionary of the animation data from the from rig objects related bones
"""
from_rig_animation_data = None
from_rig_animation_data = {}

# if there are links
if from_rig_object.animation_data:
Expand Down Expand Up @@ -832,19 +832,6 @@ def move_collection_to_collection(collection, to_collection):
to_collection.children.link(collection)


def has_iks_on(rig_object):
"""
Check to see if any IK switches are on.
:param object rig_object: A object of type armature.
"""
for bone in rig_object.pose.bones:
if isinstance(bone.get("IK_FK"), float):
if bone['IK_FK'] != 1.000:
return True
return False


def select_related_keyed_bones(to_rig_object, from_rig_action_data, links_data):
"""
Selects all the bones that need to keyed in the action bake.
Expand Down Expand Up @@ -1239,11 +1226,14 @@ def bake_from_rig_to_rig(from_rig_object, to_rig_object, properties, bake_to_sou
for fcurve in to_rig_action.fcurves:
to_rig_action.fcurves.remove(fcurve)

# check if iks are on
iks_on = has_iks_on(from_rig_object)
if from_rig_action_data['data'] or iks_on:
if from_rig_action_data['data'] or properties.bake_every_bone:
# bake the visual pose transforms of the bones to the current action
bake_pose_animation(to_rig_object, from_rig_action_data, links_data, only_selected=not iks_on)
bake_pose_animation(
to_rig_object,
from_rig_action_data,
links_data,
only_selected=not properties.bake_every_bone
)

# remove the control rig action when baking to source
if bake_to_source:
Expand Down Expand Up @@ -1333,6 +1323,115 @@ def save_rig_nodes(properties):
node_editor.unregister()


def load_metadata(properties):
"""
Loads metadata from the template and applies it to the rig.
:param object properties: The property group that contains variables that maintain the addon's correct state.
"""
if properties.selected_mode == Modes.CONTROL.name:

# load the visual data
visual_data = templates.load_template_file_data(f'{Modes.CONTROL.name.lower()}_metadata.json', properties)
rig_object = bpy.data.objects.get(Rigify.CONTROL_RIG_NAME)

# set the rig object attributes
for attribute, value in visual_data.get('object', {}).items():
setattr(rig_object, attribute, value)

# set the rig armature attributes
for attribute, value in visual_data.get('armature', {}).items():
setattr(rig_object.data, attribute, value)

# set the bone groups
for bone_group_name, bone_group_data in visual_data.get('bone_groups', {}).items():
bone_group = rig_object.pose.bone_groups.get(bone_group_name)
if not bone_group:
bone_group = rig_object.pose.bone_groups.new(name=bone_group_name)
bone_group.color_set = bone_group_data['color_set']
bone_group.colors.active = bone_group_data['colors']['active']
bone_group.colors.normal = bone_group_data['colors']['normal']
bone_group.colors.select = bone_group_data['colors']['select']

# set the bone attributes
for bone_name, bone_data in visual_data.get('bones', {}).items():
bone = rig_object.pose.bones.get(bone_name)
if not bone:
continue

# set the custom bone shapes
custom_shape_data = bone_data.get('custom_shape', {})
custom_shape = bpy.data.objects.get(custom_shape_data.get('name', ''))
if custom_shape:
bone.custom_shape = custom_shape
bone.custom_shape_translation = custom_shape_data['translation']
bone.custom_shape_rotation_euler = custom_shape_data['rotation']
bone.custom_shape_scale_xyz = custom_shape_data['scale']
bone.use_custom_shape_bone_size = custom_shape_data['use_bone_size']

# set the bone group
bone_group = rig_object.pose.bone_groups.get(bone_data.get('bone_group', ''))
if bone_group:
bone.bone_group = bone_group


def save_metadata(properties):
"""
Saves the rigify visual metadata when in control mode, like custom bone shape widgets and bone group colors.
:param object properties: The property group that contains variables that maintain the addon's correct state.
"""
if properties.previous_mode == Modes.CONTROL.name:
rig_object = bpy.data.objects.get(Rigify.CONTROL_RIG_NAME)
if rig_object:
visual_data = {
'object': {
'show_in_front': rig_object.show_in_front
},
'armature': {
'show_group_colors': rig_object.data.show_group_colors,
'show_names': rig_object.data.show_names,
'show_bone_custom_shapes': rig_object.data.show_bone_custom_shapes
},
'bones': {},
'bone_groups': {}
}

# save the bone settings
for bone in rig_object.pose.bones:
bone_data = {}

# save custom bone shape
if bone.custom_shape:
bone_data['custom_shape'] = {
'name': bone.custom_shape.name,
'translation': bone.custom_shape_translation[:],
'rotation': bone.custom_shape_rotation_euler[:],
'scale': bone.custom_shape_scale_xyz[:],
'use_bone_size': bone.use_custom_shape_bone_size
}
# save bone group
if bone.bone_group:
bone_data['bone_group'] = bone.bone_group.name

if bone_data:
visual_data['bones'][bone.name] = bone_data

# save the bone_groups
for bone_group in rig_object.pose.bone_groups:
visual_data['bone_groups'][bone_group.name] = {
'color_set': bone_group.color_set,
'colors': {
'normal': bone_group.colors.normal[:],
'select': bone_group.colors.select[:],
'active': bone_group.colors.active[:],
}
}

file_path = templates.get_template_file_path(f'{Modes.CONTROL.name.lower()}_metadata.json', properties)
templates.save_json_file(visual_data, file_path)


def edit_meta_rig_template(properties):
"""
Switches the addons state to edit metarig mode.
Expand Down Expand Up @@ -1489,6 +1588,9 @@ def convert_to_control_rig(properties):

organize_rig_objects()

# set the metadata from the template
load_metadata(properties)

# set the viewport settings
utilities.set_viewport_settings({
source_rig.name: control_mode_settings['source_rig'],
Expand All @@ -1497,6 +1599,7 @@ def convert_to_control_rig(properties):
)



def switch_modes(self=None, context=None):
"""
Called every time the mode enumeration dropdown is updated.
Expand All @@ -1515,6 +1618,9 @@ def switch_modes(self=None, context=None):
# save and remove the nodes
save_rig_nodes(properties)

# save metadata
save_metadata(properties)

# revert to the source rig
revert_to_source_rig(properties)

Expand Down
18 changes: 18 additions & 0 deletions ue2rigify/core/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,24 @@ def populate_templates_dropdown(self=None, context=None):
return rig_templates


def load_template_file_data(file_name, properties):
"""
Loads the data from the given template file.
:param str file_name: The name of the template file.
:param object properties: The property group that contains variables that maintain the addon's correct state.
:returns: The template file data.
:rtype: dict
"""
file_path = get_template_file_path(file_name, properties)

if os.path.exists(file_path):
with open(file_path, 'r') as data_file:
return json.load(data_file)
else:
return {}


def save_text_file(data, file_path):
"""
This function saves text data to a file provided a full file path.
Expand Down
6 changes: 3 additions & 3 deletions ue2rigify/core/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,8 @@ def set_viewport_settings(viewport_settings, properties):
child.hide_set(rig_object_settings['hide_rig_mesh'])

# set a custom bone shape for all the bones
previous_settings['custom_bone_shape'] = False
if rig_object_settings['custom_bone_shape']:
previous_settings['red_sphere_bones'] = False
if rig_object_settings.get('red_sphere_bones'):
# set a give the rig a custom color
set_rig_color(rig_object, 'THEME01', True)

Expand All @@ -464,7 +464,7 @@ def set_viewport_settings(viewport_settings, properties):
bone.custom_shape_scale = 0.1

# remove custom bone shapes from all the bones
if not rig_object_settings['custom_bone_shape']:
if not rig_object_settings.get('red_sphere_bones'):
if rig_object.name != Rigify.CONTROL_RIG_NAME:

# remove the custom rig color
Expand Down
6 changes: 6 additions & 0 deletions ue2rigify/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class UE2RigifyProperties(bpy.types.PropertyGroup):
description=tool_tips.overwrite_animation
)

bake_every_bone: bpy.props.BoolProperty(
default=True,
name="Bake every bone",
description=tool_tips.bake_every_bone
)

selected_starter_metarig_template: bpy.props.EnumProperty(
name="Metarig",
description=tool_tips.starter_metarig_template_tool_tip,
Expand Down
24 changes: 6 additions & 18 deletions ue2rigify/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
# UE to Rigify 1.6.0

### Major Changes
* Added Female Mannequin template
* All property data is now scene data
* Fixed issues with saving and reloading file while maintaining the current mode
* Updated documentation
* Improved testing coverage
* Added Male and Female Mannequin templates to starter template option
* https://github.com/EpicGames/BlenderTools/issues/68
* Blender 3.1 support
* https://github.com/EpicGames/BlenderTools/issues/355

### Minor Changes
* Template location move to system temp location instead of addon
* https://github.com/EpicGames/BlenderTools/issues/294
* Added metadata template file for control mode attributes like custom bone shapes, colors, and transforms.
* [530](https://github.com/EpicGames/BlenderTools/issues/530)

* Added Bake every option
* [496](https://github.com/EpicGames/BlenderTools/issues/496)

### Deprecated
* Freeze rig operator(Lock Icon). No need to lock rigs anymore

## Tests Passing On
* Blender `2.93`,`3.0`, `3.1`
* Blender `3.3`, `3.4`
Loading

0 comments on commit d2d2758

Please sign in to comment.