Untitled
unknown
plain_text
3 years ago
14 kB
9
Indexable
# iRig
import rig_factory.build.utilities.controller_utilities as cut
import rig_factory.utilities.face_utilities.face_utilities as fut
import rig_factory.build.utilities.build_utilities as but
import rig_factory.object_versions as obs
# Maya module
import maya.cmds as mc
def auto_individual_lid_shapes(controller, vertical_lid_driver_dict, horizontal_lid_driver_value):
"""
Creates individual lid shapes automatically based on the main lid shapes
"""
# Find on face eye container parts
left_eye_container = controller.root.find_first_part(
obs.PartGroup,
root_name='Eye',
side='left'
)
right_eye_container = controller.root.find_first_part(
obs.PartGroup,
root_name='Eye',
side='right'
)
lid_part, lid_up_mid_part, lid_down_mid_part, lid_up_out_part, lid_down_out_part = left_eye_container.parts[0:5]
if not left_eye_container:
raise Exception('No Eye container found')
# Check if face network created, if not, import from build directory
face_network = controller.face_network
if not face_network:
if not controller.face_network:
face_blueprint_path = '{0}/face_blueprint.json'.format(controller.build_directory)
but.build_face_heirarchy(
controller,
face_blueprint_path=face_blueprint_path
)
# If the main lid/blink shapes are missing, abort
if not controller.named_objects.get('L_Face_LidUprVertical_Grp', None) and not \
controller.named_objects.get('L_Face_LidLwrVertical_Grp', None):
raise StandardError('Missing main lid shapes, aborting...')
# Assigning an index/segment to determine which control is the inner/middle/outer
# 0 == inner, 1 == middle, 2 == outer
vertical_face_group_names = {
'L_Face_UpLidInVertical_Grp': 0,
'L_Face_DownLidInVertical_Grp': 0,
'L_Face_UpLidMidVertical_Grp': 1,
'L_Face_DownLidMidVertical_Grp': 1,
'L_Face_UpLidOutVertical_Grp': 2,
'L_Face_DownLidOutVertical_Grp': 2,
}
horizontal_face_group_names = {
'L_Face_UpLidInHorizontal_Grp': 0,
'L_Face_DownLidInHorizontal_Grp': 0,
'L_Face_UpLidMidHorizontal_Grp': 1,
'L_Face_DownLidMidHorizontal_Grp': 1,
'L_Face_UpLidOutHorizontal_Grp': 2,
'L_Face_DownLidOutHorizontal_Grp': 2,
}
# Define settings to use for a remap node which will be used to grab the transforms from secondary handles
remap_settings = {
0: {
0: {
'value_Position': 0.0,
'value_FloatValue': 1.0
},
1: {
'value_Position': 0.5,
'value_FloatValue': 0.0
}
},
1: {
0: {
'value_Position': 0.0,
'value_FloatValue': 0.0
},
1: {
'value_Position': 0.5,
'value_FloatValue': 1.0
},
2: {
'value_Position': 1.0,
'value_FloatValue': 0.0
}
},
2: {
0: {
'value_Position': 0.5,
'value_FloatValue': 0.0
},
1: {
'value_Position': 1.0,
'value_FloatValue': 1.0
}
}
}
# Separate upper and lower face groups into separate lists
upper_vertical_face_group_names = [x for x in vertical_face_group_names if 'UpLid' in x]
lower_vertical_face_group_names = [x for x in vertical_face_group_names if 'DownLid' in x]
upper_horizontal_face_group_names = [x for x in horizontal_face_group_names if 'UpLid' in x]
lower_horizontal_face_group_names = [x for x in horizontal_face_group_names if 'DownLid' in x]
for side in vertical_lid_driver_dict:
face_group_positions = {} # Dict for storing postions of the handles after triggering main shapes
# Define variables needed depending on which side is being used
if side == 'Upr':
filtered_vertical_face_group_names = upper_vertical_face_group_names
all_handles = [lid_part.upper_handles, lid_up_mid_part.handles, lid_up_out_part.handles]
secondary_handles = lid_part.upper_spline_handles
driver_group = controller.named_objects['L_Face_LidUprVertical_Grp']
elif side == 'Lwr':
filtered_vertical_face_group_names = lower_vertical_face_group_names
all_handles = [lid_part.lower_handles, lid_down_mid_part.handles, lid_down_out_part.handles]
secondary_handles = lid_part.lower_spline_handles
driver_group = controller.named_objects['L_Face_LidLwrVertical_Grp']
# Check to see if individual lid shapes already exist based on list defined earlier
for face_group_name in vertical_face_group_names:
face_group = controller.named_objects.get(face_group_name, None)
if not face_group:
raise StandardError('Missing {0}'.format(face_group_name))
for driver_value, driven_value in vertical_lid_driver_dict[side].items():
# Trigger the lid shape needed for individual shapes
driver_group.driver_plug.set_value(driver_value)
for face_group_name in filtered_vertical_face_group_names:
data = {}
segment = vertical_face_group_names[face_group_name]
handles = [x[segment] for x in all_handles]
# Get position and store them
for handle in handles:
translation = mc.xform(
handle,
query=True,
worldSpace=True,
translation=True
)
rotation = mc.xform(
handle,
query=True,
worldSpace=True,
rotation=True
)
data[handle] = [translation, rotation]
for secondary_handle in secondary_handles:
translation = mc.xform(
secondary_handle.drv,
query=True,
objectSpace=True,
translation=True
)
rotation = mc.xform(
secondary_handle.drv,
query=True,
objectSpace=True,
rotation=True
)
data[secondary_handle] = [translation, rotation]
face_group_positions[segment] = data
# Reset shape before triggering individual shapes
controller.face_network.reset_driver_plugs()
for face_group_name in filtered_vertical_face_group_names:
face_group = controller.named_objects[face_group_name]
segment = vertical_face_group_names[face_group_name]
data = face_group_positions.get(segment)
handles = [x[segment] for x in all_handles]
driven_face_target_index = None
# Find which index of face target is equal to the correct driven value
for i, face_target in enumerate(face_group.face_targets):
if face_target.driver_value == driven_value:
driven_face_target_index = i
break
if not driven_face_target_index:
raise Exception('{0} does not seem to be a valid driver value at {1}'.format(
face_group.name, driven_value
))
# Set position of controls
for handle in handles:
translation, rotation = data[handle]
mc.xform(
handle,
worldSpace=True,
translation=translation
)
mc.xform(
handle,
worldSpace=True,
rotation=rotation
)
# Need to ramp off secondary handles for each sections
remap = mc.createNode('remapValue')
attr_data = remap_settings[segment]
for index in attr_data:
remap_data = attr_data[index]
for attr, value in remap_data.items():
mc.setAttr(
'{0}.value[{1}].{2}'.format(remap, index, attr),
value
)
mc.setAttr(
'{0}.value[{1}].value_Interp'.format(remap, index),
3
)
for i, secondary_handle in enumerate(secondary_handles):
# Find value at point of remap
remap_value = i / (len(secondary_handles) - 1.0)
mc.setAttr('{0}.inputValue'.format(remap), remap_value)
out_value = mc.getAttr('{0}.outValue'.format(remap))
translation, rotation = data[secondary_handle]
mc.xform(
secondary_handle,
objectSpace=True,
translation=[x * out_value for x in translation]
)
mc.xform(
secondary_handle,
objectSpace=True,
rotation=[x * out_value for x in rotation]
)
# Update sdks
fut.update_face_target_sdks(
face_group.face_targets[driven_face_target_index],
consolidate_surfaces=True,
consolidate_groups=True
)
controller.face_network.reset_driver_plugs()
mc.delete(remap)
# Horizontal lid shapes
for side in ['Upr', 'Lwr']:
# Define variables needed depending on which side is being used
if side == 'Upr':
filtered_horizontal_face_group_names = upper_horizontal_face_group_names
lid_handles = lid_part.upper_handles
mid_lid_handles = lid_up_mid_part.handles
elif side == 'Lwr':
filtered_horizontal_face_group_names = lower_horizontal_face_group_names
lid_handles = lid_part.lower_handles
mid_lid_handles = lid_down_mid_part.handles
for face_group_name in filtered_horizontal_face_group_names:
# Check to see if individual lid shapes already exist based on list defined earlier
face_group = controller.named_objects.get(face_group_name, None)
if not face_group:
raise StandardError('Missing {0}'.format(face_group_name))
face_group = controller.named_objects[face_group_name]
segment = horizontal_face_group_names[face_group_name]
handles = [x[segment] for x in [lid_handles, mid_lid_handles]]
driver_values = [-1.0, 1.0]
for driver_value in driver_values:
# Find which index of face target is equal to the correct driven value
for i, face_target in enumerate(face_group.face_targets):
if face_target.driver_value == driver_value:
driven_face_target_index = i
if driver_value < 0.0:
horizontal_update_driver_value = -horizontal_lid_driver_value
else:
horizontal_update_driver_value = horizontal_lid_driver_value
break
if not driven_face_target_index:
raise Exception('{0} does not seem to be a valid driver value at {1}'.format(
face_group.name, driver_value
))
# Set position of controls
for handle in handles:
if handle in lid_handles:
mc.setAttr(
'{0}.ParameterU'.format(handle),
horizontal_update_driver_value
)
elif handle in mid_lid_handles:
mc.setAttr(
'{0}.ParameterU'.format(handle),
horizontal_update_driver_value / 2.0
)
# Update sdks
fut.update_face_target_sdks(
face_group.face_targets[driven_face_target_index],
consolidate_surfaces=True,
consolidate_groups=True
)
controller.face_network.reset_driver_plugs()
print 'Done'
controller = cut.get_controller()
vertical_lid_driver_dict = {
'Upr': {-0.25: -1.0, 0.25: 1.0}, # For example, -0.25 of the main lid shape will drive -1.0 of individual shape
'Lwr': {-0.5: -1.0, 0.3: 1.0}
}
horizontal_lid_driver_value = 0.1 # This will move the parameterU attribute by +-x amount
auto_individual_lid_shapes(controller, vertical_lid_driver_dict, horizontal_lid_driver_value)
Editor is loading...