Changeset View
Changeset View
Standalone View
Standalone View
rigify/utils/mechanism.py
| Show All 26 Lines | |||||
| #============================================= | #============================================= | ||||
| _TRACK_AXIS_MAP = { | _TRACK_AXIS_MAP = { | ||||
| 'X': 'TRACK_X', '-X': 'TRACK_NEGATIVE_X', | 'X': 'TRACK_X', '-X': 'TRACK_NEGATIVE_X', | ||||
| 'Y': 'TRACK_Y', '-Y': 'TRACK_NEGATIVE_Y', | 'Y': 'TRACK_Y', '-Y': 'TRACK_NEGATIVE_Y', | ||||
| 'Z': 'TRACK_Z', '-Z': 'TRACK_NEGATIVE_Z', | 'Z': 'TRACK_Z', '-Z': 'TRACK_NEGATIVE_Z', | ||||
| } | } | ||||
| def _set_default_attr(obj, options, attr, value): | |||||
| if hasattr(obj, attr): | |||||
| options.setdefault(attr, value) | |||||
| def make_constraint( | def make_constraint( | ||||
| owner, type, target=None, subtarget=None, *, | owner, type, target=None, subtarget=None, *, | ||||
| space=None, track_axis=None, use_xyz=None, | space=None, track_axis=None, use_xyz=None, use_limit_xyz=None, | ||||
| **options): | **options): | ||||
| """ | """ | ||||
| Creates and initializes constraint of the specified type for the owner bone. | Creates and initializes constraint of the specified type for the owner bone. | ||||
| Specially handled keyword arguments: | Specially handled keyword arguments: | ||||
| target, subtarget: if both not None, passed through to the constraint | target, subtarget: if both not None, passed through to the constraint | ||||
| space : assigned to both owner_space and target_space | space : assigned to both owner_space and target_space | ||||
| track_axis : allows shorter X, Y, Z, -X, -Y, -Z notation | track_axis : allows shorter X, Y, Z, -X, -Y, -Z notation | ||||
| use_xyz : list of 3 items is assigned to use_x, use_y and use_z options | use_xyz : list of 3 items is assigned to use_x, use_y and use_z options | ||||
| min/max_x/y/z : a corresponding use_min/max_x/y/z option is set to True | use_limit_xyz : list of 3 items is assigned to use_limit_x/y/z options | ||||
| min/max_x/y/z : a corresponding use_(min/max/limit)_(x/y/z) option is set to True | |||||
| Other keyword arguments are directly assigned to the constraint options. | Other keyword arguments are directly assigned to the constraint options. | ||||
| Returns the newly created constraint. | Returns the newly created constraint. | ||||
| """ | """ | ||||
| con = owner.constraints.new(type) | con = owner.constraints.new(type) | ||||
| if target is not None and hasattr(con, 'target'): | if target is not None and hasattr(con, 'target'): | ||||
| con.target = target | con.target = target | ||||
| if subtarget is not None: | if subtarget is not None: | ||||
| con.subtarget = subtarget | con.subtarget = subtarget | ||||
| if space is not None: | if space is not None: | ||||
| con.owner_space = con.target_space = space | _set_default_attr(con, options, 'owner_space', space) | ||||
| _set_default_attr(con, options, 'target_space', space) | |||||
| if track_axis is not None: | if track_axis is not None: | ||||
| con.track_axis = _TRACK_AXIS_MAP.get(track_axis, track_axis) | con.track_axis = _TRACK_AXIS_MAP.get(track_axis, track_axis) | ||||
| if use_xyz is not None: | if use_xyz is not None: | ||||
| con.use_x, con.use_y, con.use_z = use_xyz[0:3] | con.use_x, con.use_y, con.use_z = use_xyz[0:3] | ||||
| if use_limit_xyz is not None: | |||||
| con.use_limit_x, con.use_limit_y, con.use_limit_z = use_limit_xyz[0:3] | |||||
| for key in ['min_x', 'max_x', 'min_y', 'max_y', 'min_z', 'max_z']: | for key in ['min_x', 'max_x', 'min_y', 'max_y', 'min_z', 'max_z']: | ||||
| if key in options and 'use_'+key not in options: | if key in options: | ||||
| options['use_'+key] = True | _set_default_attr(con, options, 'use_'+key, True) | ||||
| _set_default_attr(con, options, 'use_limit_'+key[-1], True) | |||||
| for p, v in options.items(): | for p, v in options.items(): | ||||
| setattr(con, p, v) | setattr(con, p, v) | ||||
| return con | return con | ||||
| #============================================= | #============================================= | ||||
| # Custom property creation utilities | # Custom property creation utilities | ||||
| Show All 39 Lines | if isinstance(var_info, tuple): | ||||
| else: | else: | ||||
| # If subtarget is a string, look up a bone in the target | # If subtarget is a string, look up a bone in the target | ||||
| if isinstance(subtarget, str): | if isinstance(subtarget, str): | ||||
| subtarget = target_id.pose.bones[subtarget] | subtarget = target_id.pose.bones[subtarget] | ||||
| # Use ".foo" type path items verbatim, otherwise quote | # Use ".foo" type path items verbatim, otherwise quote | ||||
| path = subtarget.path_from_id() | path = subtarget.path_from_id() | ||||
| for item in refs: | for item in refs: | ||||
| if isinstance(item, str): | |||||
| path += item if item[0] == '.' else '["'+item+'"]' | path += item if item[0] == '.' else '["'+item+'"]' | ||||
| else: | |||||
| path += '[%r]' % (item) | |||||
| drv_target.id = target_id | drv_target.id = target_id | ||||
| drv_target.data_path = path | drv_target.data_path = path | ||||
| else: | else: | ||||
| # { 'id': ..., ... } | # { 'id': ..., ... } | ||||
| target_id = var_info.get('id', target_id) | target_id = var_info.get('id', target_id) | ||||
| ▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | def make_driver(owner, prop, *, index=-1, type='SUM', expression=None, variables={}, polynomial=None, target_id=None): | ||||
| drv = fcu.driver | drv = fcu.driver | ||||
| if expression is not None: | if expression is not None: | ||||
| drv.type = 'SCRIPTED' | drv.type = 'SCRIPTED' | ||||
| drv.expression = expression | drv.expression = expression | ||||
| else: | else: | ||||
| drv.type = type | drv.type = type | ||||
| # In case the driver already existed, remove contents | |||||
| for var in list(drv.variables): | |||||
| drv.variables.remove(var) | |||||
| for mod in list(fcu.modifiers): | |||||
| fcu.modifiers.remove(mod) | |||||
| # Fill in new data | |||||
| if isinstance(variables, list): | if isinstance(variables, list): | ||||
| # variables = [ info, ... ] | # variables = [ info, ... ] | ||||
| for i, var_info in enumerate(variables): | for i, var_info in enumerate(variables): | ||||
| var_name = 'var' if i == 0 else 'var' + str(i) | var_name = 'var' if i == 0 else 'var' + str(i) | ||||
| _add_driver_variable(drv, var_name, var_info, target_id) | _add_driver_variable(drv, var_name, var_info, target_id) | ||||
| else: | else: | ||||
| # variables = { 'varname': info, ... } | # variables = { 'varname': info, ... } | ||||
| for var_name, var_info in variables.items(): | for var_name, var_info in variables.items(): | ||||
| _add_driver_variable(drv, var_name, var_info, target_id) | _add_driver_variable(drv, var_name, var_info, target_id) | ||||
| if polynomial is not None: | if polynomial is not None: | ||||
| drv_modifier = fcu.modifiers[0] | drv_modifier = fcu.modifiers.new('GENERATOR') | ||||
| drv_modifier.mode = 'POLYNOMIAL' | drv_modifier.mode = 'POLYNOMIAL' | ||||
| drv_modifier.poly_order = len(polynomial)-1 | drv_modifier.poly_order = len(polynomial)-1 | ||||
| for i,v in enumerate(polynomial): | for i,v in enumerate(polynomial): | ||||
| drv_modifier.coefficients[i] = v | drv_modifier.coefficients[i] = v | ||||
| return fcu | return fcu | ||||
| ▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines | |||||