def doPointConstraintObjectGroup(targets,object,mode=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Groups an object and constrains that group to the other objects ARGUMENTS: targets(list) object(string mode(int) - 0 - equal influence 1 - distance spread RETURNS: group(string) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ objGroup = rigging.groupMeObject(object,True,True) constraint = mc.pointConstraint (targets,objGroup, maintainOffset=True) if mode == 1: distances = [] for target in targets: distances.append(distance.returnDistanceBetweenObjects(target,objGroup)) normalizedDistances = cgmMath.normList(distances) targetWeights = mc.pointConstraint(constraint,q=True, weightAliasList=True) cnt=1 for value in normalizedDistances: mc.setAttr(('%s%s%s' % (constraint[0],'.',targetWeights[cnt])),value ) cnt-=1 return objGroup
def nurbsCVSmoothWeights(cv): surface = '.'.join(cv.split('.')[0:-1]) skinCluster = querySkinCluster (surface) cvPos = mc.pointPosition (cv,world=True) wantedName = (cv + 'loc') actualName = mc.spaceLocator (n= wantedName) mc.move (cvPos[0],cvPos[1],cvPos[2], [actualName[0]]) influenceObjects = queryInfluences (skinCluster) culledList = influenceObjects """figure out our closest objects""" bestChoices = [] cnt = 5 while cnt >= 0: goodChoice = (distance.returnClosestObjToCV (cv, culledList)) culledList.remove(goodChoice) bestChoices.append (goodChoice) print bestChoices cnt-=1 distanceList = [] for obj in bestChoices: distanceList.append (distance.returnDistanceBetweenObjects(actualName[0],obj)) print distanceList """ return normalization value """ buffer=0 y = 1 + (x-A)*(10-1)/(B-A) for value in distanceList: buffer += value print buffer normalize = ((len(distanceList))*.1) print normalize mc.delete (actualName[0])
def doPointConstraintObjectGroup(targets, object, mode=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Groups an object and constrains that group to the other objects ARGUMENTS: targets(list) object(string mode(int) - 0 - equal influence 1 - distance spread RETURNS: group(string) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ objGroup = rigging.groupMeObject(object, True, True) constraint = mc.pointConstraint(targets, objGroup, maintainOffset=True) if mode == 1: distances = [] for target in targets: distances.append( distance.returnDistanceBetweenObjects(target, objGroup)) normalizedDistances = cgmMath.normList(distances) targetWeights = mc.pointConstraint(constraint, q=True, weightAliasList=True) cnt = 1 for value in normalizedDistances: mc.setAttr(('%s%s%s' % (constraint[0], '.', targetWeights[cnt])), value) cnt -= 1 return objGroup
def returnNormalizedWeightsByDistance(obj,targets): """ Returns a normalized weight set based on distance from object to targets ARGUMENTS: obj(string)-- targets(string)-- RETURNS: weights(list)-- """ weights = [] distances = [] distanceObjDict = {} objDistanceDict = {} for t in targets: buffer = distance.returnDistanceBetweenObjects(obj,t) # get the distance distances.append(buffer) distanceObjDict[buffer] = t objDistanceDict[t] = buffer normalizedDistances = cgmMath.normList(distances) # get normalized distances to 1 distances.sort() #sort our distances normalizedDistances.sort() # sort the normalized list (should match the distance sort) normalizedDistances.reverse() # reverse the sort for weight values for i,t in enumerate(targets): d = objDistanceDict[t] index = distances.index(d) weights.append( normalizedDistances[index] ) return weights
def returnLocalAimDirection(rootObj, aimObj): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Returns a local aim direction ARGUMENTS: rootObj(string) aimObj(string) RETURNS: direction(list) - [0,0,0] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ directionalLocArray = [] locGroups = [] directions = ['+x', '-x', '+y', '-y', '+z', '-z'] returnDirections = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]] distanceBuffer = distance.returnDistanceBetweenObjects(rootObj, aimObj) #distanceValues = distanceBuffer /2 cnt = 0 for direction in directions: locBuffer = locators.locMeObject(rootObj) locBuffer = mc.rename(locBuffer, (locBuffer + '_' + str(cnt))) locGroups.append(rigging.groupMeObject(locBuffer)) directionBuffer = list(direction) if directionBuffer[0] == '-': mc.setAttr((locBuffer + '.t' + directionBuffer[1]), -1) else: mc.setAttr((locBuffer + '.t' + directionBuffer[1]), 1) directionalLocArray.append(locBuffer) cnt += 1 closestLoc = distance.returnClosestObject(aimObj, directionalLocArray) matchIndex = directionalLocArray.index(closestLoc) for grp in locGroups: mc.delete(grp) return returnDirections[matchIndex]
def simpleControlSurfaceSmoothWeights(surface,maxBlend = 3): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Early version of a weight smoother for a ARGUMENTS: surface(string) RETURNS: Nada >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ cvList = (mc.ls ([surface+'.cv[*][*]'],flatten=True)) skinCluster = querySkinCluster (surface) influenceObjects = queryInfluences (skinCluster) #find the closest influence object to the start startObject = (distance.returnClosestObjToCV (cvList[0], influenceObjects)) #find the closest influence object to the end endObject = (distance.returnClosestObjToCV (cvList[-1], influenceObjects)) #getting the last cv list number cvChainLength = ((len(cvList)-1)/2) #Smooth interior weights """ get our interior CVs """ interiorCvList = [] cnt = 1 for i in range(cvChainLength): interiorCvList.append('%s%s%i%s' % (surface,'.cv[0][',cnt,']')) interiorCvList.append('%s%s%i%s' % (surface,'.cv[1][',cnt,']')) cnt += 1 """ overall blend """ for cv in interiorCvList: closestObject = (distance.returnClosestObjToCV (cv, influenceObjects)) closestObjectsDict = distance.returnClosestObjectsFromAim(closestObject,influenceObjects) upObjects = closestObjectsDict.get('up') downObjects = closestObjectsDict.get('dn') objectsToCheck = [] if upObjects != None: objectsToCheck += upObjects if downObjects != None: objectsToCheck += downObjects blendInfluences =[] blendInfluences.append(closestObject) distances = [] cnt = 1 print objectsToCheck while cnt < maxBlend and cnt < len(objectsToCheck): closestSubObj = distance.returnClosestObject(closestObject, objectsToCheck) blendInfluences.append(closestSubObj) objectsToCheck.remove(closestSubObj) cnt+=1 """ get our distances to normalize """ locBuffer = locators.locMeSurfaceCV(cv) for obj in blendInfluences: distances.append(distance.returnDistanceBetweenObjects(locBuffer,obj)) normalizedDistances = cgmMath.normList(distances, normalizeTo=1) cnt = 0 for obj in blendInfluences: mc.skinPercent (skinCluster,cv, tv = [obj,normalizedDistances[cnt]]) cnt +=1 mc.delete(locBuffer) """ Set closest cv's to respective infuences to max """ cvList1 = [] cvList2 = [] for i in range(cvChainLength): cvList1.append('%s%s%i%s' % (surface,'.cv[0][',cnt,']')) cvList2.append('%s%s%i%s' % (surface,'.cv[1][',cnt,']')) cnt += 1 for obj in influenceObjects: closestCV1 = distance.returnClosestCVFromList(obj, cvList1) mc.skinPercent (skinCluster,closestCV1, tv = [obj,1]) closestCV2 = distance.returnClosestCVFromList(obj, cvList2) mc.skinPercent (skinCluster,closestCV2, tv = [obj,1]) #set the skin weights for the top and bottom mc.skinPercent (skinCluster,(surface+'.cv[0:1][0:1]'), tv = [startObject,1]) mc.skinPercent (skinCluster,('%s%s%i%s%i%s' % (surface,'.cv[0:1][',(cvChainLength-1),':',cvChainLength,']')), tv = [endObject,1]) #Blend in the nearest row to the start and end mc.skinPercent (skinCluster,(surface+'.cv[0:1][2]'), tv = [startObject,1]) mc.skinPercent (skinCluster,('%s%s%i%s' % (surface,'.cv[0:1][',(cvChainLength-2),']')), tv = [endObject,1]) mc.skinPercent (skinCluster,(surface+'.cv[0:1][3]'), tv = [startObject,.7]) mc.skinPercent (skinCluster,('%s%s%i%s' % (surface,'.cv[0:1][',(cvChainLength-3),']')), tv = [endObject,.7])
def doPointAimConstraintObjectGroup(targets,object,mode=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ACKNOWLEDGEMENT: Idea for this stype of constraint setup is from http://td-matt.blogspot.com/2011/01/spine-control-rig.html DESCRIPTION: Groups an object and constrains that group to the other objects ARGUMENTS: targets(list) - should be in format of from to back with the last one being the aim object object(string) mode(int) - 0 - equal influence 1 - distance spread RETURNS: group(string) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ returnList = [] """ figure out which is the aim direction """ aimVector = logic.returnLocalAimDirection(object,targets[-1]) upVector = logic.returnLocalUp(aimVector) """ create locators """ locs = [] toMake = ['point','aim','up'] for type in toMake: locBuffer = locators.locMeObject(object) attributes.storeInfo(locBuffer,'cgmName',object) attributes.storeInfo(locBuffer,'cgmTypeModifier',type) locs.append(NameFactory.doNameObject(locBuffer)) pointLoc = locs[0] aimLoc = locs[1] upLoc = locs[2] """ move the locators """ mc.xform(aimLoc,t=aimVector,r=True,os=True) mc.xform(upLoc,t=upVector,r=True,os=True) """group constraint""" objGroup = rigging.groupMeObject(object,True,True) attributes.storeInfo(objGroup,'cgmName',object) attributes.storeInfo(objGroup,'cgmTypeModifier','follow') objGroup = NameFactory.doNameObject(objGroup) pointConstraintBuffer = mc.pointConstraint (pointLoc,objGroup, maintainOffset=False) aimConstraintBuffer = mc.aimConstraint(aimLoc,objGroup,maintainOffset = False, weight = 1, aimVector = aimVector, upVector = upVector, worldUpObject = upLoc, worldUpType = 'object' ) """loc constraints""" locConstraints = [] for loc in locs: parentConstraintBuffer = mc.parentConstraint (targets,loc, maintainOffset=True) locConstraints.append(parentConstraintBuffer[0]) if mode == 1: distances = [] for target in targets: distances.append(distance.returnDistanceBetweenObjects(target,objGroup)) normalizedDistances = cgmMath.normList(distances) for constraint in locConstraints: targetWeights = mc.parentConstraint(constraint,q=True, weightAliasList=True) cnt=1 for value in normalizedDistances: mc.setAttr(('%s%s%s' % (constraint,'.',targetWeights[cnt])),value ) cnt-=1 returnList.append(objGroup) returnList.append(locs) return returnList
def createWrapControlShape( targetObjects, targetGeo=None, latheAxis='z', aimAxis='y+', objectUp='y+', points=8, curveDegree=1, insetMult=None, #Inset multiplier minRotate=None, maxRotate=None, posOffset=[], rootOffset=[], #offset root before cast rootRotate=None, joinMode=False, extendMode=None, closedCurve=True, l_specifiedRotates=None, maxDistance=1000, closestInRange=True, vectorOffset=None, midMeshCast=False, subSize=None, #For ball on loli for example rotateBank=None, joinHits=None, #keys to processed hits to see what to join axisToCheck=['x', 'y'], **kws): #'segment,radial,disc' """ This function lathes an axis of an object, shoot rays out the aim axis at the provided mesh and returning hits. it then uses this information to build a curve shape. :parameters: mesh(string) | Surface to cast at mi_obj(string/mObj) | our casting object latheAxis(str) | axis of the objec to lathe TODO: add validation aimAxis(str) | axis to shoot out of points(int) | how many points you want in the curve curveDegree(int) | specified degree minRotate(float) | let's you specify a valid range to shoot maxRotate(float) | let's you specify a valid range to shoot posOffset(vector) | transformational offset for the hit from a normalized locator at the hit. Oriented to the surface markHits(bool) | whether to keep the hit markers returnDict(bool) | whether you want all the infomation from the process. rotateBank (float) | let's you add a bank to the rotation object l_specifiedRotates(list of values) | specify where to shoot relative to an object. Ignores some other settings maxDistance(float) | max distance to cast rays closestInRange(bool) | True by default. If True, takes first hit. Else take the furthest away hit in range. :returns: Dict ------------------------------------------------------------------ 'source'(double3) | point from which we cast 'hit'(double3) | world space points | active during single return 'hits'(list) | world space points | active during multi return 'uv'(double2) | uv on surface of hit | only works for mesh surfaces :raises: Exception | if reached """ _str_func = "createWrapControlShape" log.debug(">> %s >> " % (_str_func) + "=" * 75) _joinModes = [] _extendMode = [] if type(targetObjects) not in [list, tuple]: targetObjects = [targetObjects] targetGeo = VALID.objStringList(targetGeo, calledFrom=_str_func) assert type(points) is int, "Points must be int: %s" % points assert type(curveDegree) is int, "Points must be int: %s" % points assert curveDegree > 0, "Curve degree must be greater than 1: %s" % curveDegree if posOffset is not None and len(posOffset) and len(posOffset) != 3: raise StandardError, "posOffset must be len(3): %s | len: %s" % ( posOffset, len(posOffset)) if rootOffset is not None and len(rootOffset) and len(rootOffset) != 3: raise StandardError, "rootOffset must be len(3): %s | len: %s" % ( rootOffset, len(rootOffset)) if rootRotate is not None and len(rootRotate) and len(rootRotate) != 3: raise StandardError, "rootRotate must be len(3): %s | len: %s" % ( rootRotate, len(rootRotate)) if extendMode in ['loliwrap', 'cylinder', 'disc'] and insetMult is None: insetMult = 1 for axis in ['x', 'y', 'z']: if axis in latheAxis.lower(): latheAxis = axis log.debug("targetObjects: %s" % targetObjects) if len(aimAxis) == 2: single_aimAxis = aimAxis[0] else: single_aimAxis = aimAxis mAxis_aim = VALID.simpleAxis(aimAxis) log.debug("Single aim: %s" % single_aimAxis) log.debug("createWrapControlShape>> midMeshCast: %s" % midMeshCast) log.debug("|{0}| >> extendMode: {1}".format(_str_func, extendMode)) #>> Info l_groupsBuffer = [] il_curvesToCombine = [] l_sliceReturns = [] #Need to do more to get a better size #>> Build curves #================================================================= #> Root curve # log.debug("RootRotate: %s" % rootRotate) mi_rootLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() if rootOffset: log.debug("rootOffset: %s" % rootOffset) mc.move(rootOffset[0], rootOffset[1], rootOffset[2], [mi_rootLoc.mNode], r=True, rpr=True, os=True, wd=True) if rootRotate is not None and len(rootRotate): log.debug("rootRotate: %s" % rootRotate) mc.rotate(rootRotate[0], rootRotate[1], rootRotate[2], [mi_rootLoc.mNode], os=True, r=True) #>> Root mi_rootLoc.doGroup() #Group to zero if extendMode == 'segment': log.debug("segment mode. Target len: %s" % len(targetObjects[1:])) if len(targetObjects) < 2: log.warning( "Segment build mode only works with two objects or more") else: if insetMult is not None: rootDistanceToMove = distance.returnDistanceBetweenObjects( targetObjects[0], targetObjects[1]) log.debug("rootDistanceToMove: %s" % rootDistanceToMove) mi_rootLoc.__setattr__('t%s' % latheAxis, rootDistanceToMove * insetMult) #mi_rootLoc.tz = (rootDistanceToMove*insetMult)#Offset it #Notes -- may need to play with up object for aim snapping #mi_upLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() #mi_upLoc.doGroup()#To zero objectUpVector = dictionary.returnStringToVectors(objectUp) log.debug("objectUpVector: %s" % objectUpVector) #mi_uploc for i, obj in enumerate(targetObjects[1:]): log.debug("i: %s" % i) #> End Curve mi_endLoc = cgmMeta.cgmNode(obj).doLoc() aimVector = dictionary.returnStringToVectors(latheAxis + '-') log.debug("segment aimback: %s" % aimVector) #Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,aim=True,aimVector=aimVector,upVector=objectUpVector) #Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,orient=True) SNAP.go(mi_endLoc.mNode, mi_rootLoc.mNode, position=False, rotation=True) mi_endLoc.doGroup() if i == len(targetObjects[1:]) - 1: if insetMult is not None: log.debug("segment insetMult: %s" % insetMult) distanceToMove = distance.returnDistanceBetweenObjects( targetObjects[-1], targetObjects[0]) log.debug("distanceToMove: %s" % distanceToMove) #mi_endLoc.tz = -(distanceToMove*insetMult)#Offset it mi_endLoc.__setattr__('t%s' % latheAxis, -(distanceToMove * insetMult)) log.debug("segment lathe: %s" % latheAxis) log.debug("segment aim: %s" % aimAxis) log.debug("segment rotateBank: %s" % rotateBank) d_endCastInfo = createMeshSliceCurve( targetGeo, mi_endLoc, midMeshCast=midMeshCast, curveDegree=curveDegree, latheAxis=latheAxis, aimAxis=aimAxis, posOffset=posOffset, points=points, returnDict=True, closedCurve=closedCurve, maxDistance=maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates=l_specifiedRotates, axisToCheck=axisToCheck) l_sliceReturns.append(d_endCastInfo) mi_end = cgmMeta.cgmObject(d_endCastInfo['curve']) il_curvesToCombine.append(mi_end) mc.delete(mi_endLoc.parent) #delete the loc elif extendMode == 'radial': log.debug("|{0}| >> radial...".format(_str_func)) d_handleInner = createMeshSliceCurve( targetGeo, mi_rootLoc, midMeshCast=midMeshCast, curveDegree=curveDegree, latheAxis=latheAxis, aimAxis=aimAxis, posOffset=0, points=points, returnDict=True, closedCurve=closedCurve, maxDistance=maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates=l_specifiedRotates, axisToCheck=axisToCheck) mi_buffer = cgmMeta.cgmObject(d_handleInner['curve']) #instance curve l_sliceReturns.append(d_handleInner) il_curvesToCombine.append(mi_buffer) elif extendMode == 'disc': log.debug("|{0}| >> disc...".format(_str_func)) d_size = returnBaseControlSize(mi_rootLoc, targetGeo, axis=[aimAxis]) #Get size #discOffset = d_size[ d_size.keys()[0]]*insetMult size = False l_absSize = [abs(i) for i in posOffset] if l_absSize: size = max(l_absSize) if not size: d_size = returnBaseControlSize(mi_rootLoc, targetGeo, axis=[aimAxis]) #Get size log.debug("d_size: %s" % d_size) size = d_size[d_size.keys()[0]] * insetMult discOffset = size log.debug("d_size: %s" % d_size) log.debug("discOffset is: %s" % discOffset) mi_rootLoc.__setattr__('t%s' % latheAxis, discOffset) if posOffset: tmp_posOffset = [ posOffset[0] * .5, posOffset[1] * .5, posOffset[2] * .5 ] d_handleInnerUp = createMeshSliceCurve( targetGeo, mi_rootLoc, curveDegree=curveDegree, midMeshCast=midMeshCast, latheAxis=latheAxis, aimAxis=aimAxis, posOffset=tmp_posOffset, points=points, returnDict=True, closedCurve=closedCurve, maxDistance=maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates=l_specifiedRotates, axisToCheck=axisToCheck) mi_buffer = cgmMeta.cgmObject( d_handleInnerUp['curve']) #instance curve l_sliceReturns.append(d_handleInnerUp) il_curvesToCombine.append(mi_buffer) mi_rootLoc.__setattr__('t%s' % latheAxis, -discOffset) d_handleInnerDown = createMeshSliceCurve( targetGeo, mi_rootLoc, curveDegree=curveDegree, midMeshCast=midMeshCast, latheAxis=latheAxis, aimAxis=aimAxis, posOffset=tmp_posOffset, points=points, returnDict=True, closedCurve=closedCurve, maxDistance=maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates=l_specifiedRotates, axisToCheck=axisToCheck) mi_buffer = cgmMeta.cgmObject( d_handleInnerDown['curve']) #instance curve l_sliceReturns.append(d_handleInnerDown) il_curvesToCombine.append(mi_buffer) mi_rootLoc.tz = 0 elif extendMode == 'cylinder': log.debug("|{0}| >> cylinder...".format(_str_func)) d_size = returnBaseControlSize(mi_rootLoc, targetGeo, axis=[aimAxis]) #Get size discOffset = d_size[d_size.keys()[0]] * insetMult log.debug("d_size: %s" % d_size) log.debug("discOffset is: %s" % discOffset) mi_rootLoc.__setattr__('t%s' % latheAxis, discOffset) d_handleInnerUp = createMeshSliceCurve( targetGeo, mi_rootLoc, curveDegree=curveDegree, midMeshCast=midMeshCast, latheAxis=latheAxis, aimAxis=aimAxis, posOffset=posOffset, points=points, returnDict=True, closedCurve=closedCurve, maxDistance=maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates=l_specifiedRotates, axisToCheck=axisToCheck) mi_buffer = cgmMeta.cgmObject( d_handleInnerUp['curve']) #instance curve l_sliceReturns.append(d_handleInnerUp) il_curvesToCombine.append(mi_buffer) mi_rootLoc.__setattr__('t%s' % latheAxis, 0) elif extendMode == 'loliwrap': log.debug("|{0}| >> lolipop...".format(_str_func)) #l_absSize = [abs(i) for i in posOffset] size = False #if l_absSize: #log.debug("l_absSize: %s"%l_absSize) #size = max(l_absSize)*1.25 if subSize is not None: size = subSize if not size: d_size = returnBaseControlSize(mi_rootLoc, targetGeo, axis=[aimAxis]) #Get size log.info("d_size: %s" % d_size) l_size = d_size[single_aimAxis] size = l_size / 3 log.info("loli size: %s" % size) i_ball = cgmMeta.cgmObject( curves.createControlCurve('sphere', size=size)) elif extendMode == 'endCap': log.debug("|{0}| >> endCap...".format(_str_func)) returnBuffer1 = createMeshSliceCurve( targetGeo, mi_rootLoc.mNode, aimAxis='{0}+'.format(latheAxis), latheAxis=objectUp[0], curveDegree=curveDegree, maxDistance=maxDistance, closestInRange=closestInRange, closedCurve=False, l_specifiedRotates=[-90, -60, -30, 0, 30, 60, 90], posOffset=posOffset) mi_rootLoc.rotate = [0, 0, 0] mi_rootLoc.__setattr__('r%s' % latheAxis, 90) returnBuffer2 = createMeshSliceCurve( targetGeo, mi_rootLoc.mNode, aimAxis='{0}+'.format(latheAxis), latheAxis=objectUp[0], curveDegree=curveDegree, maxDistance=maxDistance, closedCurve=False, closestInRange=closestInRange, l_specifiedRotates=[-90, -60, -30, 0, 30, 60, 90], posOffset=posOffset) l_sliceReturns.extend([returnBuffer1, returnBuffer2]) il_curvesToCombine.append(cgmMeta.cgmObject(returnBuffer1)) il_curvesToCombine.append(cgmMeta.cgmObject(returnBuffer2)) mi_rootLoc.rotate = [0, 0, 0] #Now cast our root since we needed to move it with segment mode before casting if extendMode == 'cylinder': log.debug("|{0}| >> cylinder move...".format(_str_func)) mi_rootLoc.__setattr__('t%s' % latheAxis, -discOffset) log.debug("|{0}| >> Rootcast...".format(_str_func)) d_rootCastInfo = createMeshSliceCurve( targetGeo, mi_rootLoc, curveDegree=curveDegree, minRotate=minRotate, maxRotate=maxRotate, latheAxis=latheAxis, midMeshCast=midMeshCast, aimAxis=aimAxis, posOffset=posOffset, points=points, vectorOffset=vectorOffset, returnDict=True, closedCurve=closedCurve, maxDistance=maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates=l_specifiedRotates, axisToCheck=axisToCheck) #d_rootCastInfo = createMeshSliceCurve(targetGeo,mi_rootLoc,**kws) log.debug("|{0}| >> Rootcast done".format(_str_func) + cgmGEN._str_subLine) if extendMode == 'disc': l_sliceReturns.insert(1, d_rootCastInfo) else: l_sliceReturns.insert(0, d_rootCastInfo) #Special loli stuff if extendMode == 'loliwrap': SNAP.go(i_ball.mNode, mi_rootLoc.mNode, True, True) #Snap to main object #log.debug("hitReturns: %s"%d_rootCastInfo['hitReturns']) #cgmGEN.walk_dat(d_rootCastInfo['hitReturns'],'hitReturns') mi_crv = cgmMeta.cgmObject(d_rootCastInfo['curve']) """ d_return = RayCast.findMeshIntersectionFromObjectAxis(targetGeo,mi_rootLoc.mNode,mAxis_aim.p_string) or {} if not d_return.get('hit'): log.info(d_return) raise ValueError,"No hit on loli check" pos = d_return.get('hit') dist = distance.returnDistanceBetweenPoints(i_ball.getPosition(),pos) * 2""" if vectorOffset is not None: dist = vectorOffset + subSize * 4 else: dist = max(posOffset) + subSize * 4 if '-' in aimAxis: distM = -dist else: distM = dist log.debug("distM: %s" % distM) #Move the ball pBuffer = i_ball.doGroup() i_ball.__setattr__('t%s' % single_aimAxis, distM) i_ball.parent = False mc.delete(pBuffer) uPos = distance.returnClosestUPosition(i_ball.mNode, mi_crv.mNode) SNAP.aim(i_ball.mNode, mi_rootLoc.mNode, aimAxis='z-') #if posOffset: #mc.move(posOffset[0]*3,posOffset[1]*3,posOffset[2]*3, [i_ball.mNode], r = True, rpr = True, os = True, wd = True) #Make the curve between the two mi_traceCrv = cgmMeta.cgmObject( mc.curve(degree=1, ep=[uPos, i_ball.getPosition()])) #Combine il_curvesToCombine.extend([i_ball, mi_traceCrv]) mi_root = cgmMeta.cgmObject(d_rootCastInfo['curve']) #instance curve il_curvesToCombine.append(mi_root) mc.delete(mi_rootLoc.parent) #delete the loc l_curvesToCombine = [mi_obj.mNode for mi_obj in il_curvesToCombine ] #Build our combine list before adding connectors log.debug("|{0}| >> processed: {1}".format( _str_func, d_rootCastInfo['processedHits'])) if joinMode and extendMode not in ['loliwrap', 'endCap' ] and len(l_sliceReturns) > 1: if joinHits: keys = d_rootCastInfo['processedHits'].keys() keys.sort() #goodDegrees = [] #for i,key in enumerate(keys): #if i in joinHits: #goodDegrees.append(key) goodDegrees = [key for i, key in enumerate(keys) if i in joinHits] log.debug("joinHits: %s" % joinHits) log.debug("goodDegrees: %s" % goodDegrees) else: goodDegrees = [ key for key in d_rootCastInfo['processedHits'].keys() ] #> Side Curves for degree in goodDegrees: l_pos = [] for d in l_sliceReturns: l_pos.append(d['processedHits'].get(degree) or False) while False in l_pos: l_pos.remove(False) log.debug("l_pos: %s" % l_pos) if len(l_pos) >= 2: try: l_curvesToCombine.append( mc.curve(d=curveDegree, ep=l_pos, os=True)) #Make the curve except: log.debug( "createWrapControlShape>>> skipping curve fail: %s" % (degree)) #>>Combine the curves newCurve = curves.combineCurves(l_curvesToCombine) mi_crv = cgmMeta.cgmObject(rigging.groupMeObject(targetObjects[0], False)) curves.parentShapeInPlace(mi_crv.mNode, newCurve) #Parent shape mc.delete(newCurve) #>>Copy tags and name mi_crv.doCopyNameTagsFromObject(targetObjects[0], ignore=['cgmType', 'cgmTypeModifier']) mi_crv.addAttr('cgmType', attrType='string', value='controlCurve', lock=True) mi_crv.doName() #Store for return return {'curve': mi_crv.mNode, 'instance': mi_crv}
def doConstraintObjectGroup(targets, obj=False, constraintTypes=[], group=False, mode=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Groups an object and constrains that group to the other objects ARGUMENTS: targets(list) object(string) constraintTypes(list) group(string) -- whether to pass a group through mode(int) - 0 - equal influence 1 - distance spread RETURNS: group(string) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ log.debug(">>> doConstraintObjectGroup") log.info("targets: %s" % str(targets)) log.debug("obj: %s" % str(obj)) log.info("constraintTypes: %s" % str(constraintTypes)) log.debug("group: %s" % str(group)) log.debug("mode: %s" % str(mode)) if targets and not type(targets) == list: targets = [targets] #thanks Mark, for this syntax if constraintTypes and not type(constraintTypes) == list: constraintTypes = [constraintTypes] normalizedDistances = False if not obj and not group: log.warning("Must have a obj or a group") return False if group and mc.objExists(group): objGroup = group elif obj: objGroup = rigging.groupMeObject(obj, True, True) else: log.warning("Not enough info") return False for c in constraintTypes: constraint = False if mode == 1: distances = [] for target in targets: distances.append( distance.returnDistanceBetweenObjects(target, objGroup)) normalizedDistances = cgmMath.normList(distances) if c == 'point': constraint = mc.pointConstraint(targets, objGroup, maintainOffset=True) targetWeights = mc.pointConstraint(constraint, q=True, weightAliasList=True) if c == 'parent': constraint = mc.parentConstraint(targets, objGroup, maintainOffset=True) targetWeights = mc.parentConstraint(constraint, q=True, weightAliasList=True) if c == 'orient': constraint = mc.orientConstraint(targets, objGroup, maintainOffset=True) targetWeights = mc.orientConstraint(constraint, q=True, weightAliasList=True) if c == 'scale': constraint = mc.scaleConstraint(targets, objGroup, maintainOffset=True) targetWeights = mc.scaleConstraint(constraint, q=True, weightAliasList=True) if constraint: try: mc.setAttr("%s.interpType" % constraint[0], 0) #Set to no flip except: pass if normalizedDistances: for cnt, value in enumerate(normalizedDistances): mc.setAttr( ('%s%s%s' % (constraint[0], '.', targetWeights[cnt])), value) return objGroup
def doPointAimConstraintObjectGroup(targets, object, mode=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ACKNOWLEDGEMENT: Idea for this stype of constraint setup is from http://td-matt.blogspot.com/2011/01/spine-control-rig.html DESCRIPTION: Groups an object and constrains that group to the other objects ARGUMENTS: targets(list) - should be in format of from to back with the last one being the aim object object(string) mode(int) - 0 - equal influence 1 - distance spread RETURNS: group(string) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ returnList = [] """ figure out which is the aim direction """ aimVector = logic.returnLocalAimDirection(object, targets[-1]) upVector = logic.returnLocalUp(aimVector) """ create locators """ locs = [] toMake = ['point', 'aim', 'up'] for type in toMake: locBuffer = locators.locMeObject(object) attributes.storeInfo(locBuffer, 'cgmName', object) attributes.storeInfo(locBuffer, 'cgmTypeModifier', type) locs.append(NameFactory.doNameObject(locBuffer)) pointLoc = locs[0] aimLoc = locs[1] upLoc = locs[2] """ move the locators """ mc.xform(aimLoc, t=aimVector, r=True, os=True) mc.xform(upLoc, t=upVector, r=True, os=True) """group constraint""" objGroup = rigging.groupMeObject(object, True, True) attributes.storeInfo(objGroup, 'cgmName', object) attributes.storeInfo(objGroup, 'cgmTypeModifier', 'follow') objGroup = NameFactory.doNameObject(objGroup) pointConstraintBuffer = mc.pointConstraint(pointLoc, objGroup, maintainOffset=False) aimConstraintBuffer = mc.aimConstraint(aimLoc, objGroup, maintainOffset=False, weight=1, aimVector=aimVector, upVector=upVector, worldUpObject=upLoc, worldUpType='object') """loc constraints""" locConstraints = [] for loc in locs: parentConstraintBuffer = mc.parentConstraint(targets, loc, maintainOffset=True) locConstraints.append(parentConstraintBuffer[0]) if mode == 1: distances = [] for target in targets: distances.append( distance.returnDistanceBetweenObjects(target, objGroup)) normalizedDistances = cgmMath.normList(distances) for constraint in locConstraints: targetWeights = mc.parentConstraint(constraint, q=True, weightAliasList=True) cnt = 1 for value in normalizedDistances: mc.setAttr(('%s%s%s' % (constraint, '.', targetWeights[cnt])), value) cnt -= 1 returnList.append(objGroup) returnList.append(locs) return returnList
def skeletonize(moduleNull, stiffIndex=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Basic limb skeletonizer ARGUMENTS: moduleNull(string) stiffIndex(int) - the index of the template objects you want to not have roll joints For example, a value of -1 will let the chest portion of a spine segment be solid instead of having a roll segment. Default is '0' which will put roll joints in every segment RETURNS: limbJoints(list) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>>>Get our info #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> partName = NameFactory.returnUniqueGeneratedName(moduleNull, ignore='cgmType') """ template null """ templateNull = modules.returnTemplateNull(moduleNull) templateNullData = attributes.returnUserAttrsToDict(templateNull) """ template object nulls """ templatePosObjectsInfoNull = modules.returnInfoTypeNull( moduleNull, 'templatePosObjects') templateControlObjectsNull = modules.returnInfoTypeNull( moduleNull, 'templateControlObjects') templatePosObjectsInfoData = attributes.returnUserAttrsToDict( templatePosObjectsInfoNull) templateControlObjectsData = attributes.returnUserAttrsToDict( templateControlObjectsNull) jointOrientation = modules.returnSettingsData('jointOrientation') moduleRootBuffer = modules.returnInfoNullObjects(moduleNull, 'templatePosObjects', types='templateRoot') moduleRoot = moduleRootBuffer[0] stiffIndex = templateNullData.get('stiffIndex') rollJoints = templateNullData.get('rollJoints') """ AutonameStuff """ divider = NameFactory.returnCGMDivider() skinJointsNull = modules.returnInfoTypeNull(moduleNull, 'skinJoints') templateObjects = [] coreNamesArray = [] #>>>TemplateInfo for key in templatePosObjectsInfoData.keys(): if (mc.attributeQuery(key, node=templatePosObjectsInfoNull, msg=True)) == True: templateObjects.append(templatePosObjectsInfoData[key]) coreNamesArray.append(key) posTemplateObjects = [] """ Get the positional template objects""" for obj in templateObjects: bufferList = obj.split(divider) if (typesDictionary.get('templateObject')) in bufferList: posTemplateObjects.append(obj + divider + typesDictionary.get('locator')) """put objects in order of closeness to root""" posTemplateObjects = distance.returnDistanceSortedList( moduleRoot, posTemplateObjects) curve = (templatePosObjectsInfoData['curve']) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>>> Actually making the skeleton with consideration for roll joints and the stiffIndex! #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if stiffIndex == 0: """ If no roll joints """ limbJoints = joints.createJointsFromCurve(curve, partName, rollJoints) else: rolledJoints = joints.createJointsFromCurve(curve, partName, rollJoints) if rollJoints == 0: limbJoints = rolledJoints else: if stiffIndex < 0: """ Get our to delete number in a rolledJoints[-4:] format""" #searchIndex = (int('%s%s' %('-',(rollJoints+1)))*abs(stiffIndex)-1) searchIndex = (int('%s%s' % ('-', (rollJoints + 1))) * abs(stiffIndex)) toDelete = rolledJoints[searchIndex:] """ delete out the roll joints we don't want""" mc.delete(toDelete[0]) for name in toDelete: rolledJoints.remove(name) """ make our stiff joints """ jointPositions = [] if abs(stiffIndex) == 1: jointPositions.append( distance.returnClosestUPosition( posTemplateObjects[stiffIndex], curve)) else: for obj in posTemplateObjects[stiffIndex:]: jointPositions.append( distance.returnClosestUPosition(obj, curve)) stiffJoints = joints.createJointsFromPosListName( jointPositions, 'partName') """ connect em up """ mc.parent(stiffJoints[0], rolledJoints[-1]) limbJoints = [] for joint in rolledJoints: limbJoints.append(joint) for joint in stiffJoints: limbJoints.append(joint) else: """ if it's not negative, it's positive....""" searchIndex = ((rollJoints + 1) * abs(stiffIndex)) toDelete = rolledJoints[:searchIndex] toKeep = rolledJoints[searchIndex:] """ delete out the roll joints we don't want""" mc.parent(toKeep[0], world=True) mc.delete(toDelete[0]) for name in toDelete: rolledJoints.remove(name) """ make our stiff joints """ jointPositions = [] if abs(stiffIndex) == 1: jointPositions.append( distance.returnClosestUPosition( posTemplateObjects[stiffIndex - 1], curve)) else: for obj in posTemplateObjects[:stiffIndex]: jointPositions.append( distance.returnClosestUPosition(obj, curve)) stiffJoints = joints.createJointsFromPosListName( jointPositions, 'partName') """ connect em up """ mc.parent(rolledJoints[0], stiffJoints[-1]) limbJoints = [] for joint in stiffJoints: limbJoints.append(joint) for joint in rolledJoints: limbJoints.append(joint) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>>> Naming #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ Copy naming information from template objects to the joints closest to them copy over a cgmNameModifier tag from the module first """ attributes.copyUserAttrs(moduleNull, limbJoints[0], attrsToCopy=['cgmNameModifier']) """ First we need to find our matches """ for obj in posTemplateObjects: closestJoint = distance.returnClosestObject(obj, limbJoints) transferObj = attributes.returnMessageObject(obj, 'cgmName') """Then we copy it""" attributes.copyUserAttrs( transferObj, closestJoint, attrsToCopy=['cgmNameModifier', 'cgmDirection', 'cgmName']) limbJointsBuffer = NameFactory.doRenameHeir(limbJoints[0]) limbJoints = [] limbJoints.append(limbJointsBuffer[0]) for joint in limbJointsBuffer[1]: limbJoints.append(joint) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>>> Orientation #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> limbJoints = orientSegment(limbJoints, posTemplateObjects, jointOrientation) #>>> Set its radius and toggle axis visbility on #averageDistance = distance.returnAverageDistanceBetweenObjects (limbJoints) jointSize = ( distance.returnDistanceBetweenObjects(limbJoints[0], limbJoints[-1]) / 6) for jnt in limbJoints: mc.setAttr((jnt + '.radi'), jointSize * .2) #>>>>>>> TEMP joints.toggleJntLocalAxisDisplay(jnt) print 'to orientation' #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>>> Storing data #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> skinJointsNull = modules.returnInfoTypeNull(moduleNull, 'skinJoints') skinJointsNullData = attributes.returnUserAttrsToList(skinJointsNull) existingSkinJoints = lists.removeMatchedIndexEntries( skinJointsNullData, 'cgm') print existingSkinJoints if len(existingSkinJoints) > 0: for entry in existingSkinJoints: attrBuffer = (skinJointsNull + '.' + entry[0]) print attrBuffer attributes.doDeleteAttr(skinJointsNull, entry[0]) for i in range(len(limbJoints)): buffer = ('%s%s' % ('joint_', i)) attributes.storeInfo(skinJointsNull, buffer, limbJoints[i]) return limbJoints
def createWrapControlShape(targetObjects, targetGeo = None, latheAxis = 'z',aimAxis = 'y+',objectUp = 'y+', points = 8, curveDegree = 1, insetMult = None,#Inset multiplier posOffset = [], rootOffset = [],#offset root before cast rootRotate = None, joinMode = False, extendMode = None, closedCurve = True, l_specifiedRotates = None, maxDistance = 1000, closestInRange = True, midMeshCast = False, rotateBank = None, joinHits = None,#keys to processed hits to see what to join axisToCheck = ['x','y'], ):#'segment,radial,disc' """ Function for creating control curves from other objects. Currently assumes z aim, y up 1) Cather info 2) Get initial curves 3) Store info 4) return TODO: Change offsets to use lathe axis rather than """ _str_funcName = "createWrapControlShape" log.debug(">> %s >> "%(_str_funcName) + "="*75) if type(targetObjects) not in [list,tuple]:targetObjects = [targetObjects] if not targetGeo: raise NotImplementedError, "Must have geo for now" if len(mc.ls(targetGeo))>1: raise StandardError,"createWrapControlShape>> More than one mesh named: %s"%targetGeo assert type(points) is int,"Points must be int: %s"%points assert type(curveDegree) is int,"Points must be int: %s"%points assert curveDegree > 0,"Curve degree must be greater than 1: %s"%curveDegree if posOffset is not None and len(posOffset) and len(posOffset)!=3:raise StandardError, "posOffset must be len(3): %s | len: %s"%(posOffset,len(posOffset)) if rootOffset is not None and len(rootOffset) and len(rootOffset)!=3:raise StandardError, "rootOffset must be len(3): %s | len: %s"%(rootOffset,len(rootOffset)) if rootRotate is not None and len(rootRotate) and len(rootRotate)!=3:raise StandardError, "rootRotate must be len(3): %s | len: %s"%(rootRotate,len(rootRotate)) if extendMode in ['loliwrap'] and insetMult is None:insetMult = 1 for axis in ['x','y','z']: if axis in latheAxis.lower():latheAxis = axis log.debug("targetObjects: %s"%targetObjects) if len(aimAxis) == 2:single_aimAxis = aimAxis[0] else:single_aimAxis = aimAxis log.debug("Single aim: %s"%single_aimAxis) log.debug("createWrapControlShape>> midMeshCast: %s"%midMeshCast) #>> Info l_groupsBuffer = [] il_curvesToCombine = [] l_sliceReturns = [] #Need to do more to get a better size #>> Build curves #================================================================= #> Root curve # log.debug("RootRotate: %s"%rootRotate) mi_rootLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() if rootOffset: log.debug("rootOffset: %s"%rootOffset) mc.move(rootOffset[0],rootOffset[1],rootOffset[2], [mi_rootLoc.mNode], r=True, rpr = True, os = True, wd = True) if rootRotate is not None and len(rootRotate): log.debug("rootRotate: %s"%rootRotate) mc.rotate(rootRotate[0],rootRotate[1],rootRotate[2], [mi_rootLoc.mNode], os = True,r=True) #>> Root mi_rootLoc.doGroup()#Group to zero if extendMode == 'segment': log.debug("segment mode. Target len: %s"%len(targetObjects[1:])) try: if len(targetObjects) < 2: log.warning("Segment build mode only works with two objects or more") else: if insetMult is not None: rootDistanceToMove = distance.returnDistanceBetweenObjects(targetObjects[0],targetObjects[1]) log.debug("rootDistanceToMove: %s"%rootDistanceToMove) mi_rootLoc.__setattr__('t%s'%latheAxis,rootDistanceToMove*insetMult) #mi_rootLoc.tz = (rootDistanceToMove*insetMult)#Offset it #Notes -- may need to play with up object for aim snapping #mi_upLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() #mi_upLoc.doGroup()#To zero objectUpVector = dictionary.returnStringToVectors(objectUp) log.debug("objectUpVector: %s"%objectUpVector) #mi_uploc for i,obj in enumerate(targetObjects[1:]): log.debug("i: %s"%i) #> End Curve mi_endLoc = cgmMeta.cgmNode(obj).doLoc() aimVector = dictionary.returnStringToVectors(latheAxis+'-') log.debug("segment aimback: %s"%aimVector) #Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,aim=True,aimVector=aimVector,upVector=objectUpVector) Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,orient=True) mi_endLoc.doGroup() if i == len(targetObjects[1:])-1: if insetMult is not None: log.debug("segment insetMult: %s"%insetMult) distanceToMove = distance.returnDistanceBetweenObjects(targetObjects[-1],targetObjects[0]) log.debug("distanceToMove: %s"%distanceToMove) #mi_endLoc.tz = -(distanceToMove*insetMult)#Offset it mi_endLoc.__setattr__('t%s'%latheAxis,-(distanceToMove*insetMult)) log.debug("segment lathe: %s"%latheAxis) log.debug("segment aim: %s"%aimAxis) log.debug("segment rotateBank: %s"%rotateBank) d_endCastInfo = createMeshSliceCurve(targetGeo,mi_endLoc,midMeshCast=midMeshCast,curveDegree=curveDegree,latheAxis=latheAxis,aimAxis=aimAxis,posOffset = posOffset,points = points,returnDict=True,closedCurve = closedCurve, maxDistance = maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates = l_specifiedRotates,axisToCheck = axisToCheck) l_sliceReturns.append(d_endCastInfo) mi_end = cgmMeta.cgmObject(d_endCastInfo['curve']) il_curvesToCombine.append(mi_end) mc.delete(mi_endLoc.parent)#delete the loc except StandardError,error: raise StandardError,"createWrapControlShape>> segment wrap fail! | %s"%error
def createWrapControlShape(targetObjects, targetGeo = None, latheAxis = 'z',aimAxis = 'y+',objectUp = 'y+', points = 8, curveDegree = 1, insetMult = None,#Inset multiplier posOffset = [], rootOffset = [],#offset root before cast rootRotate = None, joinMode = False, extendMode = None, closedCurve = True, l_specifiedRotates = None, maxDistance = 1000, closestInRange = True, midMeshCast = False, rotateBank = None, joinHits = None,#keys to processed hits to see what to join axisToCheck = ['x','y'], ):#'segment,radial,disc' """ This function lathes an axis of an object, shoot rays out the aim axis at the provided mesh and returning hits. it then uses this information to build a curve shape. :parameters: mesh(string) | Surface to cast at mi_obj(string/mObj) | our casting object latheAxis(str) | axis of the objec to lathe TODO: add validation aimAxis(str) | axis to shoot out of points(int) | how many points you want in the curve curveDegree(int) | specified degree minRotate(float) | let's you specify a valid range to shoot maxRotate(float) | let's you specify a valid range to shoot posOffset(vector) | transformational offset for the hit from a normalized locator at the hit. Oriented to the surface markHits(bool) | whether to keep the hit markers returnDict(bool) | whether you want all the infomation from the process. rotateBank (float) | let's you add a bank to the rotation object l_specifiedRotates(list of values) | specify where to shoot relative to an object. Ignores some other settings maxDistance(float) | max distance to cast rays closestInRange(bool) | True by default. If True, takes first hit. Else take the furthest away hit in range. :returns: Dict ------------------------------------------------------------------ 'source'(double3) | point from which we cast 'hit'(double3) | world space points | active during single return 'hits'(list) | world space points | active during multi return 'uv'(double2) | uv on surface of hit | only works for mesh surfaces :raises: Exception | if reached """ _str_funcName = "createWrapControlShape" log.debug(">> %s >> "%(_str_funcName) + "="*75) _joinModes = [] _extendMode = [] if type(targetObjects) not in [list,tuple]:targetObjects = [targetObjects] targetGeo = cgmValid.objStringList(targetGeo, calledFrom = _str_funcName) assert type(points) is int,"Points must be int: %s"%points assert type(curveDegree) is int,"Points must be int: %s"%points assert curveDegree > 0,"Curve degree must be greater than 1: %s"%curveDegree if posOffset is not None and len(posOffset) and len(posOffset)!=3:raise StandardError, "posOffset must be len(3): %s | len: %s"%(posOffset,len(posOffset)) if rootOffset is not None and len(rootOffset) and len(rootOffset)!=3:raise StandardError, "rootOffset must be len(3): %s | len: %s"%(rootOffset,len(rootOffset)) if rootRotate is not None and len(rootRotate) and len(rootRotate)!=3:raise StandardError, "rootRotate must be len(3): %s | len: %s"%(rootRotate,len(rootRotate)) if extendMode in ['loliwrap','cylinder','disc'] and insetMult is None:insetMult = 1 for axis in ['x','y','z']: if axis in latheAxis.lower():latheAxis = axis log.debug("targetObjects: %s"%targetObjects) if len(aimAxis) == 2:single_aimAxis = aimAxis[0] else:single_aimAxis = aimAxis log.debug("Single aim: %s"%single_aimAxis) log.debug("createWrapControlShape>> midMeshCast: %s"%midMeshCast) #>> Info l_groupsBuffer = [] il_curvesToCombine = [] l_sliceReturns = [] #Need to do more to get a better size #>> Build curves #================================================================= #> Root curve # log.debug("RootRotate: %s"%rootRotate) mi_rootLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() if rootOffset: log.debug("rootOffset: %s"%rootOffset) mc.move(rootOffset[0],rootOffset[1],rootOffset[2], [mi_rootLoc.mNode], r=True, rpr = True, os = True, wd = True) if rootRotate is not None and len(rootRotate): log.debug("rootRotate: %s"%rootRotate) mc.rotate(rootRotate[0],rootRotate[1],rootRotate[2], [mi_rootLoc.mNode], os = True,r=True) #>> Root mi_rootLoc.doGroup()#Group to zero if extendMode == 'segment': log.debug("segment mode. Target len: %s"%len(targetObjects[1:])) try: if len(targetObjects) < 2: log.warning("Segment build mode only works with two objects or more") else: if insetMult is not None: rootDistanceToMove = distance.returnDistanceBetweenObjects(targetObjects[0],targetObjects[1]) log.debug("rootDistanceToMove: %s"%rootDistanceToMove) mi_rootLoc.__setattr__('t%s'%latheAxis,rootDistanceToMove*insetMult) #mi_rootLoc.tz = (rootDistanceToMove*insetMult)#Offset it #Notes -- may need to play with up object for aim snapping #mi_upLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() #mi_upLoc.doGroup()#To zero objectUpVector = dictionary.returnStringToVectors(objectUp) log.debug("objectUpVector: %s"%objectUpVector) #mi_uploc for i,obj in enumerate(targetObjects[1:]): log.debug("i: %s"%i) #> End Curve mi_endLoc = cgmMeta.cgmNode(obj).doLoc() aimVector = dictionary.returnStringToVectors(latheAxis+'-') log.debug("segment aimback: %s"%aimVector) #Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,aim=True,aimVector=aimVector,upVector=objectUpVector) Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,orient=True) mi_endLoc.doGroup() if i == len(targetObjects[1:])-1: if insetMult is not None: log.debug("segment insetMult: %s"%insetMult) distanceToMove = distance.returnDistanceBetweenObjects(targetObjects[-1],targetObjects[0]) log.debug("distanceToMove: %s"%distanceToMove) #mi_endLoc.tz = -(distanceToMove*insetMult)#Offset it mi_endLoc.__setattr__('t%s'%latheAxis,-(distanceToMove*insetMult)) log.debug("segment lathe: %s"%latheAxis) log.debug("segment aim: %s"%aimAxis) log.debug("segment rotateBank: %s"%rotateBank) d_endCastInfo = createMeshSliceCurve(targetGeo,mi_endLoc,midMeshCast=midMeshCast,curveDegree=curveDegree,latheAxis=latheAxis,aimAxis=aimAxis,posOffset = posOffset,points = points,returnDict=True,closedCurve = closedCurve, maxDistance = maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates = l_specifiedRotates,axisToCheck = axisToCheck) l_sliceReturns.append(d_endCastInfo) mi_end = cgmMeta.cgmObject(d_endCastInfo['curve']) il_curvesToCombine.append(mi_end) mc.delete(mi_endLoc.parent)#delete the loc except StandardError,error: raise StandardError,"createWrapControlShape>> segment wrap fail! | %s"%error
def getPartBaseDistance(self,PuppetInstance,locator): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Pass a generated locator (z is forward) from this system and it measures the distance to the bounding box edge ARGUMENTS: locator(string) meshGroup(string) RETURNS: distance(float) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ vectorToStringDict = {'x':[1,0,0],'-x':[1,0,0],'y':[0,1,0],'-y':[0,1,0],'z':[0,0,1],'-z':[0,0,1]} """ size distance for pivot """ boundingBoxSize = distance.returnBoundingBoxSize( PuppetInstance.GeoGroup.nameLong ) boundingBoxSize = cgmMath.multiplyLists([[.5,.5,.5],boundingBoxSize]) """ make our bounding box pivot """ cgmLoc = locators.centerPivotLocMeObject( PuppetInstance.GeoGroup.nameLong ) """makeour measure loc and snap it to the the cgmLoc""" measureLocBuffer = mc.duplicate(locator) measureLoc = measureLocBuffer[0] position.movePointSnap(measureLoc,cgmLoc) """ Get it up on the axis with the cgmLoc back to where it was """ distanceToPivot = mc.xform(measureLoc,q=True, t=True,os=True) mc.xform(measureLoc, t= [0,0,distanceToPivot[2]],os=True) """ figure out our relationship between our locators, which is in front""" measureLocPos = mc.xform(measureLoc,q=True, t=True,os=True) mainLocPos = mc.xform(locator,q=True, t=True,os=True) if measureLocPos[2] < mainLocPos[2]: distanceCombineMode = 'subtract' locOrder = [measureLoc,locator] else: distanceCombineMode = 'add' locOrder = [locator,measureLoc] """ determine our aim direction """ aimDirection = logic.returnLinearDirection(locOrder[0],locOrder[1]) aimVector = vectorToStringDict.get(aimDirection) maxIndexMatch = max(aimVector) maxIndex = aimVector.index(maxIndexMatch) fullDistance = boundingBoxSize[maxIndex] """ get some measurements """ distanceToSubtract = distance.returnDistanceBetweenObjects(locOrder[0],locOrder[1]) if distanceCombineMode == 'subtract': returnDistance = fullDistance - distanceToSubtract else: returnDistance = fullDistance + distanceToSubtract mc.delete(measureLoc) mc.delete(cgmLoc) return returnDistance
def doCreateStartingPositionLoc(self, modeType='child', workingObject=None, aimingObject=None, cvIndex = None ): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Adds a locator setup to duplicate to get our initial position locators. All should be zeroed out. The top node of the return group has the loctor and move group connected is message nodes if needed. ARGUMENTS: modeType(string) child - basic child locator to the workingObject innerChild - aims locator from the working to the aiming curves cvBack - works off working curves cvIndex. Places it and aiming it back on z. Mainly used for tails radialOut - Works off working curve cv for position and radial orientation. It's transform group is oriented to the aiming curves equivalent cv. Good for arms radialDown - same as radial out but locator orientation is y down zup for legs. transform orientation is the same as radial out footBase - looking for it's module Parent's last loc to start from parentDuplicate - looking for it's module Parent's last loc to start from workingObject(string) - usually the sizing objects start curve (can be a locator for parentchild loc) aimingObject(string) - usually the sizing objects end curve cvIndex(int) - cv to work off of RETURNS: returnList(list) = [rootHelper(string),helperObjects(list),helperObjectGroups(list)] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ if modeType == 'child': """ make initial loc and orient it """ returnLoc = [] curveShapes = mc.listRelatives(workingObject, shapes = True) startLoc = locators.locMeObject(workingObject) aimLoc = locators.locMeObject(workingObject) upLoc = locators.locMeCvFromCvIndex(curveShapes[0],0) startLoc = mc.rename(startLoc,(self.ModuleNull.nameBase+'child_startLoc')) StartLoc = ObjectFactory(startLoc) sizeObjectLength = distance.returnDistanceBetweenObjects(workingObject,aimingObject) mc.xform(aimLoc,t=[0,0,sizeObjectLength],r=True,os=True) aimConstraintBuffer = mc.aimConstraint(aimLoc,startLoc,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,1,0], worldUpObject = upLoc, worldUpType = 'object' ) mc.delete(aimConstraintBuffer[0]) mc.delete(upLoc) mc.delete(aimLoc) zeroGroup = StartLoc.doGroup() returnLoc.append(StartLoc.nameLong) attributes.storeInfo(zeroGroup,'locator',startLoc) returnLoc.append(zeroGroup) return returnLoc elif modeType == 'innerChild': """ make initial lock and orient it """ returnLoc = [] curveShapes = mc.listRelatives(workingObject, shapes = True) startLoc = locators.locMeObject(workingObject) aimLoc = locators.locMeObject(aimingObject) upLoc = locators.locMeCvFromCvIndex(curveShapes[0],0) startLoc = mc.rename(startLoc, (self.ModuleNull.nameBase+'_innerChild_startLoc')) StartLoc = ObjectFactory(startLoc) aimConstraintBuffer = mc.aimConstraint(aimLoc,startLoc,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,1,0], worldUpObject = upLoc, worldUpType = 'object' ) mc.delete(aimConstraintBuffer[0]) mc.delete(upLoc) mc.delete(aimLoc) zeroGroup = StartLoc.doGroup() returnLoc.append(StartLoc.nameLong) #zeroGroup = rigging.zeroTransformMeObject(startLoc) #attributes.storeInfo(zeroGroup,'locator',startLoc) returnLoc.append(zeroGroup) return returnLoc elif modeType == 'cvBack': returnLoc = [] curveShapes = mc.listRelatives(workingObject, shapes = True) startLoc = locators.locMeCvFromCvIndex(curveShapes[0],cvIndex) upLoc = locators.locMeObject(workingObject) initialAimLoc = locators.locMeObject(aimingObject) aimConstraintBuffer = mc.aimConstraint(initialAimLoc,startLoc,maintainOffset = False, weight = 1, aimVector = [0,0,-1], upVector = [0,-1,0], worldUpObject = upLoc, worldUpType = 'object', skip = ['x','z']) mc.delete(aimConstraintBuffer[0]) mc.delete(initialAimLoc) aimLoc = locators.locMeCvFromCvIndex(curveShapes[0],cvIndex) startLoc = mc.rename(startLoc, (self.ModuleNull.nameBase+'_radialBackl_startLoc')) StartLoc = ObjectFactory(startLoc) sizeObjectLength = distance.returnDistanceBetweenObjects(workingObject,aimingObject) mc.xform(aimLoc,t=[0,0,-sizeObjectLength],r=True,ws=True) aimConstraintBuffer = mc.aimConstraint(aimLoc,startLoc,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,1,0], worldUpType = 'vector' ) mc.delete(aimConstraintBuffer[0]) mc.delete(aimLoc) mc.delete(upLoc) returnLoc.append(startLoc) zeroGroup = StartLoc.doGroup() returnLoc.append(StartLoc.nameLong) return returnLoc elif modeType == 'radialOut': sizeObjectLength = distance.returnDistanceBetweenObjects(workingObject,aimingObject) returnLoc = [] workingObjectShapes = mc.listRelatives(workingObject, shapes = True) aimingObjectShapes = mc.listRelatives(aimingObject, shapes = True) """initial loc creation and orientation""" startLoc = locators.locMeCvFromCvIndex(workingObjectShapes[0],cvIndex) startLocAim = locators.locMeObject(workingObject) startLocUp = locators.locMeCvFromCvIndex(workingObjectShapes[0],cvIndex) startLoc = mc.rename(startLoc, (self.ModuleNull.nameBase+'_radialOut_startLoc')) StartLoc = ObjectFactory(startLoc) """ move the up loc up """ mc.xform(startLocUp,t=[0,sizeObjectLength,0],r=True,ws=True) """ aim it """ aimConstraintBuffer = mc.aimConstraint(startLocAim,startLoc,maintainOffset = False, weight = 1, aimVector = [0,0,-1], upVector = [0,1,0], worldUpType = 'vector' ) mc.delete(aimConstraintBuffer[0]) mc.delete(startLocUp) """ setup the transform group""" transformGroup = rigging.groupMeObject(startLoc,False) transformGroup = mc.rename(transformGroup,('%s%s' %(startLoc,'_moveGroup'))) groupUp = startLocAim groupAim = locators.locMeCvFromCvIndex(aimingObjectShapes[0],cvIndex) """aim it""" aimConstraintBuffer = mc.aimConstraint(groupAim,transformGroup,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,-1,0], worldUpObject = groupUp, worldUpType = 'object') mc.delete(aimConstraintBuffer[0]) mc.delete(groupUp) mc.delete(groupAim) startLoc = rigging.doParentReturnName(startLoc,transformGroup) rigging.zeroTransformMeObject(startLoc) returnLoc.append(startLoc) returnLoc.append(transformGroup) zeroGroup = rigging.groupMeObject(transformGroup) attributes.storeInfo(zeroGroup,'move',transformGroup) returnLoc.append(zeroGroup) return returnLoc elif modeType == 'radialDown': sizeObjectLength = distance.returnDistanceBetweenObjects(workingObject,aimingObject) returnLoc = [] workingObjectShapes = mc.listRelatives(workingObject, shapes = True) aimingObjectShapes = mc.listRelatives(aimingObject, shapes = True) """initial loc creation and orientation""" startLoc = locators.locMeCvFromCvIndex(workingObjectShapes[0],cvIndex) startLocAim = locators.locMeCvFromCvIndex(workingObjectShapes[0],cvIndex) startLoc = mc.rename(startLoc, (self.ModuleNull.nameBase+'_radialDown_startLoc')) StartLoc = ObjectFactory(startLoc) """ move the up loc up """ mc.xform(startLocAim,t=[0,-sizeObjectLength,0],r=True, ws=True) """ aim it """ aimConstraintBuffer = mc.aimConstraint(startLocAim,startLoc,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,0,1], worldUpType = 'vector' ) mc.delete(aimConstraintBuffer[0]) """ setup the transform group""" transformGroup = rigging.groupMeObject(startLoc,False) transformGroup = mc.rename(transformGroup,('%s%s' %(startLoc,'_moveGroup'))) groupUp = startLocAim groupAim = locators.locMeCvFromCvIndex(aimingObjectShapes[0],cvIndex) """aim it""" aimConstraintBuffer = mc.aimConstraint(groupAim,transformGroup,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,-1,0], worldUpObject = groupUp, worldUpType = 'object') mc.delete(aimConstraintBuffer[0]) mc.delete(groupUp) mc.delete(groupAim) startLoc = rigging.doParentReturnName(startLoc,transformGroup) rigging.zeroTransformMeObject(startLoc) returnLoc.append(startLoc) returnLoc.append(transformGroup) zeroGroup = rigging.groupMeObject(transformGroup) attributes.storeInfo(zeroGroup,'move',transformGroup) returnLoc.append(zeroGroup) return returnLoc elif modeType == 'footBase': returnLoc = [] startLoc = locators.locMeObject(workingObject) startLoc = mc.rename(startLoc,(self.ModuleNull.nameBase+'_footcgmase_startLoc')) StartLoc = ObjectFactory(startLoc) masterGroup = rigging.groupMeObject(startLoc) mc.setAttr((startLoc+'.rx'),-90) returnLoc.append(startLoc) zeroGroup = rigging.zeroTransformMeObject(startLoc) currentPos = mc.xform(zeroGroup,q=True, t=True,ws=True) mc.xform(zeroGroup,t=[currentPos[0],0,currentPos[2]], ws = True) attributes.storeInfo(zeroGroup,'locator',startLoc) returnLoc.append(zeroGroup) returnLoc.append(masterGroup) return returnLoc elif modeType == 'parentDuplicate': returnLoc = [] startLoc = locators.locMeObject(workingObject) startLoc = mc.rename(startLoc,(self.ModuleNull.nameBase+'_parentDup_startLoc')) StartLoc = ObjectFactory(startLoc) masterGroup = rigging.groupMeObject(startLoc) returnLoc.append(startLoc) returnLoc.append(masterGroup) return returnLoc else: return False
def doConstraintObjectGroup(targets,obj = False,constraintTypes = [],group = False, mode=0): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Groups an object and constrains that group to the other objects ARGUMENTS: targets(list) object(string) constraintTypes(list) group(string) -- whether to pass a group through mode(int) - 0 - equal influence 1 - distance spread RETURNS: group(string) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ log.debug(">>> doConstraintObjectGroup") log.info("targets: %s"%str(targets)) log.debug("obj: %s"%str(obj)) log.info("constraintTypes: %s"%str(constraintTypes)) log.debug("group: %s"%str(group)) log.debug("mode: %s"%str(mode)) if targets and not type(targets)==list:targets=[targets]#thanks Mark, for this syntax if constraintTypes and not type(constraintTypes)==list:constraintTypes=[constraintTypes] normalizedDistances = False if not obj and not group: log.warning("Must have a obj or a group") return False if group and mc.objExists(group): objGroup = group elif obj: objGroup = rigging.groupMeObject(obj,True,True) else: log.warning("Not enough info") return False for c in constraintTypes: constraint = False if mode == 1: distances = [] for target in targets: distances.append(distance.returnDistanceBetweenObjects(target,objGroup)) normalizedDistances = cgmMath.normList(distances) if c == 'point': constraint = mc.pointConstraint(targets,objGroup, maintainOffset=True) targetWeights = mc.pointConstraint(constraint,q=True, weightAliasList=True) if c == 'parent': constraint = mc.parentConstraint(targets,objGroup, maintainOffset=True) targetWeights = mc.parentConstraint(constraint,q=True, weightAliasList=True) if c == 'orient': constraint = mc.orientConstraint(targets,objGroup, maintainOffset=True) targetWeights = mc.orientConstraint(constraint,q=True, weightAliasList=True) if c == 'scale': constraint = mc.scaleConstraint(targets,objGroup, maintainOffset=True) targetWeights = mc.scaleConstraint(constraint,q=True, weightAliasList=True) if constraint: try:mc.setAttr("%s.interpType"%constraint[0],0)#Set to no flip except:pass if normalizedDistances: for cnt,value in enumerate(normalizedDistances): mc.setAttr(('%s%s%s' % (constraint[0],'.',targetWeights[cnt])),value ) return objGroup
def makeJointControlSurfaceFish(startJoint,controlJointList,outChannel,name): """ Makes a ricgmon surface for ricgmon rigging """ heirarchyJoints = [] heirarchyJoints.append (startJoint) childrenBuffer = [] controlJointGroups = [] """ Makes some transform groups for our groups""" """ Get joint list """ for jnt in (mc.listRelatives (startJoint, ad = True, type = 'joint')): childrenBuffer.append (jnt) childrenBuffer.reverse () heirarchyJoints += childrenBuffer """ return a good length for out loft curves """ length = (distance.returnDistanceBetweenObjects (heirarchyJoints[0], heirarchyJoints[-1])/2) loftCurveList = [] crvPosBuffer = [] crvPosBuffer.append ([0,0,0]) if outChannel == 'x': crvPosBuffer.append ([length,0,0]) elif outChannel == 'y': crvPosBuffer.append ([0,length,0]) elif outChannel == 'z': crvPosBuffer.append ([0,0,length]) crvPosBuffer.reverse () """ for each joint, make a loft curve and snap it to the joint it goes with """ for jnt in heirarchyJoints: crvBuffer = mc.curve (d=1, p = crvPosBuffer , os=True, n=(jnt+'_tmpCrv')) mc.xform (crvBuffer, cp = True) posBuffer = distance.returnWorldSpacePosition (jnt) cnstBuffer = mc.parentConstraint ([jnt], [crvBuffer], maintainOffset = False) mc.delete (cnstBuffer) loftCurveList.append (crvBuffer) controlSurface = mc.loft (loftCurveList, reverseSurfaceNormals = True, ch = False, uniform = True, degree = 3, n = (name+'_surf') ) """ deletes our loft curve list""" for crv in loftCurveList: mc.delete (crv) cvList = (mc.ls ([controlSurface[0]+'.cv[*]'],flatten=True)) """ Time to set skin our surface to our control joints """ surfaceSkinCluster = mc.skinCluster (controlJointList,controlSurface[0],tsb=True, n=(controlSurface[0]+'_skinCluster'),maximumInfluences = 3, normalizeWeights = 1, dropoffRate=2,smoothWeights=.5,obeyMaxInfluences=True, weight = 1) #surfaceSkinCluster = mc.skinCluster (controlJointList,controlSurface,tsb=True, n=(controlSurface[0]+'_skinCluster'),maximumInfluences = 5, normalizeWeights = 2, dropoffRate=4,smoothWeights=.5,forceNormalizeWeights=True) """ Make our groups to follow the surface and drive out """ posGroups = [] upGroups = [] cnt = 0 for jnt in heirarchyJoints: posGroups.append (mc.group (n= ('%s%s' % (jnt,'_Pos_grp')), w=True, empty=True)) upGroups.append (mc.group (n= ('%s%s' % (jnt,'_Up_grp')), w=True, empty=True)) mc.parent (upGroups[cnt],posGroups[cnt]) cnt +=1 """ Make our v values for our position info groups""" vValues = [] vValues.append (.5) cnt = 0 for item in heirarchyJoints: vValues.append (cnt + 1) cnt += 1 """ Make our position info nodes""" posInfoNodes = [] cnt = 0 for grp in posGroups: node = mc.createNode ('pointOnSurfaceInfo',name= (grp+'_posInfoNode')) print node posInfoNodes.append (node) """ Connect the info node to the surface """ mc.connectAttr ((controlSurface[0]+'Shape.worldSpace'),(posInfoNodes[cnt]+'.inputSurface')) """ Contect the pos group to the info node""" mc.connectAttr ((posInfoNodes[cnt]+'.position'),(grp+'.translate')) """ Connect the U tangent attribute to the child of our first group """ mc.connectAttr ((posInfoNodes[cnt]+'.tangentU'),(upGroups[cnt]+'.translate')) mc.setAttr ((posInfoNodes[cnt]+'.parameterU'),.5) mc.setAttr ((posInfoNodes[cnt]+'.parameterV'),(vValues[cnt])) cnt += 1 """ Make our measure nodes to keep joint position """ posPairsList = lists.parseListToPairs (posInfoNodes) posDistConnections = [] poseDistNameList = [] for pair in posPairsList: distanceInfoBuffer = distance.createDistanceNodeBetweenPosInfoNodes (pair[0],pair[1]) posDistConnections.append(distanceInfoBuffer[2]) poseDistNameList.append(distanceInfoBuffer[0]) """ connect the distances to our stretch translation channels on our joints """ """ connect the distances to our stretch translation channels on our joints """ #find it directionCap = 'X' cnt = 0 jointLengths = [] mdNodes = [] """ need to make our master scale connector""" scaleHolderGrp= (controlSurface[0]+'_scaleHolder_grp') masterScaleAttrBuffer = (scaleHolderGrp+'.worldScale') if mc.objExists (scaleHolderGrp): pass else: mc.group (n= scaleHolderGrp, w=True, empty=True) mc.addAttr (scaleHolderGrp, ln = 'worldScale', at = 'float', hidden=False ) mc.setAttr(masterScaleAttrBuffer,1) """ return our default lengths and store them,then run them through an md node to return our scale values """ for jnt in heirarchyJoints[0:-1]: lengthBuffer = mc.getAttr (posDistConnections[cnt]) jointLengths.append (lengthBuffer) #mc.addAttr (jnt, ln = 'baseLength', at = 'float') mc.addAttr (scaleHolderGrp, ln = (jnt+'_baseLength'), at = 'float') jntAttrBuffer = (scaleHolderGrp+'.'+jnt+'_baseLength') mc.setAttr (jntAttrBuffer,jointLengths[cnt]) mdNodeBuffer = nodes.createNamedNode ((jnt+'_jntScale'), 'multiplyDivide') mdNodes.append(mdNodeBuffer) mc.setAttr ((mdNodeBuffer+'.operation'),2) mc.connectAttr((posDistConnections[cnt]),(mdNodeBuffer+'.input1X')) mc.connectAttr((jntAttrBuffer),(mdNodeBuffer+'.input2X')) mc.connectAttr(masterScaleAttrBuffer,(jnt+'.scaleY')) mc.connectAttr(masterScaleAttrBuffer,(jnt+'.scaleZ')) mc.connectAttr((mdNodeBuffer+'.output.outputX'),(jnt+'.scale'+directionCap)) cnt+=1 """ """ #mc.connectAttr ( """ SET SPECIAL CONDITION FOR FIRST POS GROUP """ #mc.setAttr ((posInfoNodes[0]+'.parameterV'),0) """Clean up stuff """ cleanupGrp = mc.group (n= 'surfacePosFollowStuff_grp', w=True, empty=True) for grp in posGroups: mc.parent (grp, cleanupGrp) """ make some IK effectors and connect everything up""" effectorList = [] cnt = (len(heirarchyJoints) - 1) firstTermCount = 0 secondTermCount = 1 while cnt > 0: effector = mc.ikHandle (name = (heirarchyJoints[firstTermCount]+'_ikHandle') , startJoint=heirarchyJoints[firstTermCount], endEffector = heirarchyJoints[secondTermCount], setupForRPsolver = True, solver = 'ikRPsolver', enableHandles=True ) """ if it's the not the last effector, do this """ if cnt > 1: mc.parent (effector[0],posGroups[secondTermCount]) """ if it is, parent it to the last controlJoint """ if cnt == 1: mc.parent (effector[0],posGroups[secondTermCount]) effectorList.append (effector[0]) cnt-=1 firstTermCount += 1 secondTermCount += 1 if cnt == 0: break """ let's make some pole vector constraints""" #----------->>>>> Need to find a good way of "discovering" correct twist for the effectors cnt = 0 """ Connect first joint to surface """ mc.connectAttr ((posGroups[0]+'.translate'),(heirarchyJoints[0]+'.translate')) for effector in effectorList: #print ('Constrain '+effector+' to '+ upGroups[cnt]) poleVector = mc.poleVectorConstraint (upGroups[cnt],effector,name = (effector+'_pvConst')) """ fix the twist""" if (len(effectorList) - cnt) == 0: mc.setAttr ((effector+'.twist'),-180) elif cnt == 0: mc.setAttr ((effector+'.twist'),0) else: mc.setAttr ((effector+'.twist'),-90) cnt+=1 # """return all our data together to return""" """ clean up measure stuff """ if mc.objExists (name+'_measureStuff_grp'): distCleanupGrp = (name+'_measureStuff_grp') else: distCleanupGrp = mc.group (n= (name+'_measureStuff_grp'), w=True, empty=True) for dist in poseDistNameList: mc.parent (dist, distCleanupGrp) mc.setAttr ((dist+'.v'),0) mc.parent (distCleanupGrp, 'rigStuff_grp') mc.parent (cleanupGrp, 'rigStuff_grp') mc.parent (scaleHolderGrp, 'rigStuff_grp') """ connect master scale to the master """ mc.connectAttr(('placement_anim.sy'),masterScaleAttrBuffer) return controlSurface
def getGeneratedInitialPositionData(self, PuppetInstance, startLocList, *a, **kw): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Calculates initial positioning info for objects ARGUMENTS: sourceObjects(list) visAttr(string) PuppetInstance.templateSizeObjects['start'],PuppetInstance.templateSizeObjects['end'] RETURNS: returnList(list) = [posList(list),endChildLoc(loc)] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ guiFactory.report("Generating Initial position data via Limb - '%s'" % self.ModuleNull.nameBase) partBaseDistance = kw.pop('partBaseDistance', 1) startLoc = startLocList[0] #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Distances #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ measure root object""" absStartCurveSize = distance.returnAbsoluteSizeCurve( PuppetInstance.templateSizeObjects['start']) sizeObjectLength = distance.returnDistanceBetweenObjects( startLoc, PuppetInstance.templateSizeObjects['end']) corePositionList = modules.returncgmTemplatePartPositionData( self.afModuleType.value) or False if not corePositionList: corePositionList = [] positions = cgmMath.divideLength(1, self.optionHandles.value) for position in positions: bufferList = [0, 0] bufferList.append(position) corePositionList.append(bufferList) guiFactory.report("Core position list %s" % corePositionList) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Things with the character root as a base Limb segments and Torsos #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if not self.moduleParent: """ Get the data in a usable format. Our positional ratios are stored in x,y,z format so we're going to get the absolute size data in that format with our distance being our z value """ moduleSizeBaseDistanceValues = [] moduleSizeBaseDistanceValues.append(absStartCurveSize[0]) moduleSizeBaseDistanceValues.append(absStartCurveSize[2]) moduleSizeBaseDistanceValues.append(sizeObjectLength) """ multiply our values """ translationValues = [] for list in corePositionList: translationValues.append( cgmMath.multiplyLists([list, moduleSizeBaseDistanceValues])) baseLocs = [] for value in translationValues: locBuffer = mc.duplicate(startLoc) mc.xform(locBuffer, t=value, r=True, os=True) baseLocs.append(locBuffer[0]) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # SubSplitting #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> splitTransformationValues = [] if self.optionStiffIndex.value != 0: if self.optionHandles.value > len(baseLocs): if self.optionStiffIndex.value > 0: stiff = 'positive' splitDistance = distance.returnDistanceBetweenObjects( baseLocs[self.optionStiffIndex.value], baseLocs[-1]) print splitDistance print baseLocs[self.optionStiffIndex.value] positions = cgmMath.divideLength( splitDistance, (self.optionHandles.value - len(baseLocs) + 2)) for position in positions[1:-1]: splitTransformationValues.append([0, 0, position]) else: stiff = 'negative' splitDistance = distance.returnDistanceBetweenObjects( baseLocs[0], baseLocs[self.optionStiffIndex.value + -1]) positions = cgmMath.divideLength( splitDistance, (self.optionHandles.value - len(baseLocs) + 2)) for pos in positions[1:-1]: splitTransformationValues.append([0, 0, pos]) else: if self.optionHandles.value > len(baseLocs): stiff = 'zero' splitDistance = distance.returnDistanceBetweenObjects( baseLocs[0], baseLocs[1]) positions = cgmMath.divideLength( splitDistance, (self.optionHandles.value - len(baseLocs) + 2)) for pos in positions[1:-1]: splitTransformationValues.append([0, 0, pos]) if len(splitTransformationValues) > 0: for value in splitTransformationValues: if stiff == 'positive': locBuffer = mc.duplicate(baseLocs[stiffIndex]) else: locBuffer = mc.duplicate(baseLocs[0]) mc.xform(locBuffer, t=value, r=True, os=True) baseLocs.append(locBuffer[0]) baseLocs = distance.returnDistanceSortedList(startLoc, baseLocs) mc.delete(startLoc) posList = distance.returnWorldSpacePositionFromList(baseLocs) returnList = {} returnList['positions'] = posList returnList['locator'] = baseLocs[-1] for loc in baseLocs[:-1]: mc.delete(loc) guiFactory.report("Initial position list is %s" % returnList) return returnList else: """ Get the data in a usable format. Our positional ratios are stored in x,y,z format so we're going to get the absolute size data in that format with our distance being our z value """ moduleSizeBaseDistanceValues = [] moduleSizeBaseDistanceValues.append(absStartCurveSize[0]) moduleSizeBaseDistanceValues.append(absStartCurveSize[2]) moduleSizeBaseDistanceValues.append(sizeObjectLength) """ multiply our values """ translationValues = [] for list in corePositionList: translationValues.append( cgmMath.multiplyLists([list, moduleSizeBaseDistanceValues])) baseLocs = [] if partType == 'clavicle' and direction == 'left': for value in translationValues: locBuffer = mc.duplicate(startLoc) mc.xform(locBuffer, t=[-value[0], value[1], value[2]], r=True, os=True) baseLocs.append(locBuffer[0]) else: for value in translationValues: locBuffer = mc.duplicate(startLoc) mc.xform(locBuffer, t=value, r=True, os=True) baseLocs.append(locBuffer[0]) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # SubSplitting #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> splitTransformationValues = [] if stiffIndex != 0: if handles > len(baseLocs): if stiffIndex > 0: stiff = 'positive' splitDistance = distance.returnDistanceBetweenObjects( baseLocs[stiffIndex], baseLocs[-1]) print splitDistance print baseLocs[stiffIndex] positions = cgmMath.divideLength( splitDistance, (handles - len(baseLocs) + 2)) for position in positions[1:-1]: splitTransformationValues.append([0, 0, position]) else: stiff = 'negative' splitDistance = distance.returnDistanceBetweenObjects( baseLocs[0], baseLocs[stiffIndex + -1]) positions = cgmMath.divideLength( splitDistance, (handles - len(baseLocs) + 2)) for position in positions[1:-1]: splitTransformationValues.append([0, 0, position]) else: if handles > len(baseLocs): stiff = 'zero' splitDistance = distance.returnDistanceBetweenObjects( baseLocs[0], baseLocs[1]) positions = cgmMath.divideLength(splitDistance, (handles - len(baseLocs) + 2)) for position in positions[1:-1]: splitTransformationValues.append([0, 0, position]) if len(splitTransformationValues) > 0: for value in splitTransformationValues: if stiff == 'positive': locBuffer = mc.duplicate(baseLocs[stiffIndex]) else: locBuffer = mc.duplicate(baseLocs[0]) mc.xform(locBuffer, t=value, r=True, os=True) baseLocs.append(locBuffer[0]) baseLocs = distance.returnDistanceSortedList(startLoc, baseLocs) mc.delete(startLoc) posList = distance.returnWorldSpacePositionFromList(baseLocs) if partType == 'clavicle': posList.reverse() returnList = {} returnList['positions'] = posList returnList['locator'] = baseLocs[-1] for loc in baseLocs[:-1]: mc.delete(loc) print "Initial position list is %s" % returnList return returnList