def _makeSharedShape(obj, name, shapeType): ''' shapeType should be either 'sharedShape' or 'kinematicSwitch' Returns a string of the shape, ex 'Foot_L|sharedShape' (to bypass pymel warnings) ''' shape = cmds.createNode( 'nurbsCurve', p=obj.longName() ) # 2017 added a bunch of keyable attrs so get rid of them if possible. for attr in cmds.listAttr(shape, k=True): try: cmds.setAttr(shape + '.' + attr, k=False, l=True) except Exception as e: # noqa #print( e ) pass # Make it a valid curve so it doesn't get deleted during optimize scene # but lock and hide it. mel.eval('''setAttr "%s.cc" -type "nurbsCurve" 1 1 0 no 3 2 0 1 2 0 0 0 0 0 0 ;''' % shape ) setAttr(shape + '.visibility', False, l=True) # noqa addAttr(shape, ln=core.shape.sharedShapeTag, at='message') cmds.addAttr( shape, ln=shapeType, at='message' ) cmds.rename( shape, name ) return obj.longName() + '|' + name
def connect(obj, name_level): ''' Hook the given obj's visibility to the `name` attribute on the sharedShape. If the attr doesn't exist, it will be made. Optionanal `level` will determine when the `obj` will become visible. For example, 2 will not be visible at 1, but will at 2 and higher. ''' name, level = name_level # Probably should just update this eventually to be 3 params orig = obj zero = pdil.dagObj.zero(obj, apply=False, make=False) if zero: obj = zero shape = get() if not shape: warning( 'Unable to add vis control, no object exists named "main" or tagged with ".fossilMainControl"' ) return log.debug('Applying vis control to {}, was given {} using {}'.format( obj, orig, shape)) plug = shape + '.' + name if not cmds.objExists(plug): cmds.addAttr(shape, ln=name, at='short', min=0, max=level, dv=1) cmds.setAttr(shape + '.' + name, cb=True) elif cmds.getAttr(shape + '.' + name, type=True) not in [ 'bool', 'double', 'float', 'long', 'short' ]: warning( '{0} is not a good name for a vis group since the sharedShape has an attr already that is of the wrong type' .format(name)) return if cmds.addAttr(plug, q=True, max=True) < level: cmds.addAttr(plug, e=True, max=level) if level == 1: connectAttr(plug, obj.visibility.name(), f=True) else: connectAttr(getConditionNode(plug, level).outColorR, obj.visibility, f=True) obj.visibility.setKeyable(False) if not pdil.sharedShape.find(orig, VIS_NODE_TYPE): pdil.sharedShape.use(orig, shape) # If we have a main controller, put the container in a subgroup to make # the main group more organized. ''' 2021-11-25 Taking this out, I think redoing the hierarchery is probalby more confusing that having lots there.
def getNames(ctrl): ''' Returns a list of the spaces a control has. ''' if not ctrl.hasAttr(ENUM_ATTR): return [] return cmds.addAttr(ctrl.attr(ENUM_ATTR).name(), q=True, enumName=True).split(':')
def _processAttr(plug, dups, forceKeys, staticValues, start, end): ''' Used by `save` ''' crvs = cmds.listConnections(plug, type='animCurve') if not crvs: if forceKeys: setKeyframe(plug, t=start) setKeyframe(plug, t=end) crvs = cmds.listConnections(plug, type='animCurve') else: if not cmds.getAttr(plug, lock=True) and not cmds.listConnections( plug, s=True, d=False): staticValues[plug] = cmds.getAttr(plug) if crvs: dup = cmds.duplicate(crvs)[0] if not objExists(dup + '.' + TAGGING_ATTR): cmds.addAttr(dup, ln=TAGGING_ATTR, dt='string') cmds.setAttr(dup + '.' + TAGGING_ATTR, plug, type='string') dups.append(dup)
def connect(obj, name): ''' Hook the given obj's visibility to the `name` attribute on the sharedShape. If the attr doesn't exist, it will be made. ''' orig = obj zero = core.dagObj.zero(obj, apply=False, make=False) if zero: obj = zero shape = get() plug = shape + '.' + name if not cmds.objExists(plug): cmds.addAttr(shape, ln=name, at='short', min=0, max=1, dv=1) cmds.setAttr(shape + '.' + name, cb=True) elif cmds.getAttr(shape + '.' + name, type=True) not in [ 'bool', 'double', 'float', 'long', 'short' ]: warning( '{0} is not a good name for a vis group since the sharedShape has an attr already that is of the wrong type' .format(name)) return connectAttr(plug, obj.visibility.name(), f=True) obj.visibility.setKeyable(False) # If we have a main controller, put the container in a subgroup to make # the main group more organized. visGroupName = '_vis_' + name if isinstance(orig, nodeApi.RigController): if shortName(orig.container.getParent()) != visGroupName: orig.setGroup(visGroupName)
If the attr doesn't exist, it will be made. Optionanal `level` will determine when the `obj` will become visible. For example, 2 will not be visible at 1, but will at 2 and higher. ''' orig = obj zero = core.dagObj.zero(obj, apply=False, make=False) if zero: obj = zero shape = get() plug = shape + '.' + name if not cmds.objExists( plug ): cmds.addAttr( shape, ln=name, at='short', min=0, max=level, dv=1 ) cmds.setAttr( shape + '.' + name, cb=True ) elif cmds.getAttr( shape + '.' + name, type=True) not in ['bool', 'double', 'float', 'long', 'short']: warning( '{0} is not a good name for a vis group since the sharedShape has an attr already that is of the wrong type'.format(name) ) return if cmds.addAttr(plug, q=True, max=True) < level: cmds.addAttr(plug, e=True, max=level) if level == 1: connectAttr( plug, obj.visibility.name(), f=True) else: connectAttr( getConditionNode(plug, level).outColorR, obj.visibility, f=True) obj.visibility.setKeyable(False)
def ikFkSwitch(name, ikRigController, ikPlugs, fkRigController, fkPlugs): ''' Adds "<name>_Switch" attr to the shared shape, controlling the given ik and fk plugs (which are expected to be 0=off and 1.0=on) .. todo:: * Verify an existing switch doesn't exist ''' # When adding the switcher shape, re-add the shared shape to ensure it is last. lib.sharedShape.remove(ikRigController) shape = lib.sharedShape._makeSharedShape(ikRigController, '%s_FKIK_SWITCH' % name, 'kinematicSwitch') lib.sharedShape.use(ikRigController) for key, obj in itertools.chain(ikRigController.subControl.items(), fkRigController.subControl.items()): cmds.parent(shape, obj.longName(), add=True, shape=True) lib.sharedShape.remove(obj) lib.sharedShape.use(obj) cmds.parent(shape, fkRigController.longName(), add=True, shape=True) lib.sharedShape.remove(fkRigController) lib.sharedShape.use(fkRigController) attrName = 'IkSwitch' if not cmds.objExists(shape + '.' + attrName): cmds.addAttr(shape, longName=attrName, at='double', min=0.0, max=1.0, k=True) plug = Attribute(shape + '.' + attrName) if ikPlugs and fkPlugs: # Optionally skip in case retrofitting, where these connections are made elsewhere for ikPlug in ikPlugs: plug >> ikPlug if not ikRigController.visibility.isDestination(): plug >> ikRigController.visibility ikRigController.visibility.setKeyable(False) for name, ctrl in ikRigController.subControl.items(): if not ctrl.visibility.isDestination(): plug >> ctrl.visibility ctrl.visibility.setKeyable(False) opposite = core.math.opposite(plug) for fkPlug in fkPlugs: opposite >> fkPlug if not fkRigController.visibility.isDestination(): opposite >> fkRigController.visibility fkRigController.visibility.setKeyable(False) for name, ctrl in fkRigController.subControl.items(): if not ctrl.visibility.isDestination(): opposite >> ctrl.visibility ctrl.visibility.setKeyable(False) return plug