def on_orientJointsButton_clicked(self): undoInfo(openChunk=True) sel = selected() kwargs = {} if self.zeroScaleOrientCB.isChecked(): kwargs.update({'zeroScaleOrient': True}) if self.aimAxisNoneRadio.isChecked(): val = 'none' else: for i, radio in enumerate( (self.aimAxisXRadio, self.aimAxisYRadio, self.aimAxisZRadio)): if radio.isChecked(): xyz = 'xyz' if self.upAxisNoneRadio.isChecked(): val = xyz[i:] + xyz[:i] else: val = str(radio.text()).lower() for up_radio in (self.upAxisXRadio, self.upAxisYRadio, self.upAxisZRadio): if up_radio.isChecked(): val += str(up_radio.text()).lower() break for c in xyz: if c not in val: val += c break sao = self.worldUpYRadio.isChecked() and 'y' \ or self.worldUpZRadio.isChecked() and 'z' \ or upAxis(query=True, axis=True) sao += self.worldUpReverseCB.isChecked() \ and 'down' or 'up' kwargs.update({'secondaryAxisOrient': sao}) break reverse_aim = self.aimAxisReverseCB.isChecked() \ and Vector([val[1] == c for c in 'xyz']) * 180 or None reverse_up = self.upAxisReverseCB.isChecked() \ and Vector([val[0] == c for c in 'xyz']) * 180 or None for j in self.get_affected_joints(): if j.numChildren(): j.orientJoint(val, **kwargs) else: p = j.getParent() if p: delete(orientConstraint(p, j)) else: self.freeze(j, jointOrient=True) if self.zeroScaleOrientCB.isChecked(): j.zeroScaleOrient() if reverse_aim: self.tweak_joint_orientation(1, rotateAxis=reverse_aim) if reverse_up: self.tweak_joint_orientation(1, rotateAxis=reverse_up) select(sel) undoInfo(closeChunk=True)
def getRotationAxis(normalVector): yVector = Vector(normalVector) if pm.upAxis(q=True, axis=True) == 'y': upVector = Vector(0, 1, 0) else: upVector = Vector(0, 0, 1) xVector = Vector.cross(yVector, upVector) zVector = Vector.cross(xVector, yVector) rotationMatrix = Matrix(xVector.x, xVector.y, xVector.z, yVector.x, yVector.y, yVector.z, zVector.x, zVector.y, zVector.z)
def get_matrix_from_direction(look_vec, upp_vec): # Ensure we deal with normalized vectors look_vec.normalize() upp_vec.normalize() side_vec = Vector.cross(look_vec, upp_vec) #recross in case up and front were not originally orthogonal: upp_vec = Vector.cross(side_vec, look_vec) #the new matrix is return Matrix ( look_vec.x, look_vec.y, look_vec.z, 0, upp_vec.x, upp_vec.y, upp_vec.z, 0, side_vec.x, side_vec.y, side_vec.z, 0, 0, 0, 0, 1)
def matrix_from_normal(up_vect, front_vect): # normalize first! up_vect.normalize() front_vect.normalize() #get the third axis with the cross vector side_vect = Vector.cross(up_vect, front_vect) #recross in case up and front were not originally orthoganl: front_vect = Vector.cross(side_vect, up_vect ) #the new matrix is return Matrix ( side_vect.x, side_vect.y, side_vect.z, 0, up_vect.x, up_vect.y, up_vect.z, 0, front_vect.x, front_vect.y, front_vect.z, 0, 0,0,0,1)
def tweak_joint_orientation(self, mult, **kwargs): kwargs.update({'rotateAxis': kwargs.pop('ra', kwargs.pop('rotateAxis', Vector( \ self.tweakXDouble.value(), self.tweakYDouble.value(), self.tweakZDouble.value()) * mult))}) zso = self.zeroScaleOrientCB.isChecked() for j in self.get_affected_joints(): xform(j, objectSpace=True, relative=True, **kwargs) if zso: j.zeroScaleOrient() self.freeze(j)
def unflattenFloat3Array(arr): """Unflatten a float3 array representing vectors to a list of PyMEL vectors.""" x, y, z = itertools.islice(arr, 0, None, 3), \ itertools.islice(arr, 1, None, 3), \ itertools.islice(arr, 2, None, 3) vzip = itertools.izip(x, y, z) return [Vector(*x) for x in vzip]
def getPoleVectorPosition(joints, offset, curveGuide=True): """ Creates locator with offset for the ideal pole vector control location Uses basic math to find the average position across all the joints and creates a vector from the average midpoint to the middle joint in the chain. """ totalJoints = len(joints) joints = map(pmc.nodetypes.Joint, joints) midpoint = Vector() midpoint.x = sum([jnt.getTranslation('world')[0] for jnt in joints]) midpoint.y = sum([jnt.getTranslation('world')[1] for jnt in joints]) midpoint.z = sum([jnt.getTranslation('world')[2] for jnt in joints]) midpoint /= totalJoints if totalJoints % 2 == 0: first = totalJoints / 2 second = first - 1 midJointPos = Vector() midJointPos.x = joints[first].getTranslation('world')[0] + joints[second].getTranslation('world')[0] midJointPos.y = joints[first].getTranslation('world')[1] + joints[second].getTranslation('world')[1] midJointPos.z = joints[first].getTranslation('world')[2] + joints[second].getTranslation('world')[2] midJointPos /= 2 else: midJointPos = Vector(pmc.xform(joints[totalJoints / 2], q=True, worldSpace=True, translation=True)) poleVector = (midJointPos - midpoint).normal() result = pmc.spaceLocator(n='loc_midchain_test') result.setTranslation((poleVector * offset) + midJointPos, 'world') if curveGuide: crv = pmc.curve(degree=1, point=[midpoint, (poleVector * 200) + midJointPos], k=[0, 1], n='curveGuide') return [result, crv] return result
def faceLocators(): """ Iterates through faces on surface, attaches locators and objects """ # Selects all faces, puts average center coordinates in a list pm.select(nameOfSurface) fc = pm.polyEvaluate(face=True) faceLocCount = 0 for x in range(0, fc): numGen = r.random() bBox = pm.xform(nameOfSurface + '.f[' + str(x) + ']', ws=True, q=True, bb=True) transX = (bBox[0] + bBox[3]) / 2 transY = (bBox[1] + bBox[4]) / 2 transZ = (bBox[2] + bBox[5]) / 2 # Creates locators if (numGen <= num): pm.spaceLocator(n="faceLoc{0}".format(1), p=(transX, transY, transZ)) duplicatedObject = pm.instance(selectedObject, leaf=True) pm.setAttr(duplicatedObject[0] + '.translate', transX, transY, transZ) randomScaleNumber = r.randrange(minRandomScale, maxRandomScale) randomRotationNumber = r.randrange(minRandomRotation, maxRandomRotation) if randomScale is True: pm.setAttr(duplicatedObject[0] + '.scale', randomScaleNumber, randomScaleNumber, randomScaleNumber) if setToNormals is True: poly = PyNode(nameOfSurface + '.f[' + str(x) + ']') normalVector = poly.getNormal() rotationMatrix = getRotationAxis(Vector(normalVector)) if randomRotation is True: pm.setAttr(duplicatedObject[0] + '.rotate', randomRotationNumber, randomRotationNumber, randomRotationNumber) if randomX is True: pm.setAttr(duplicatedObject[0] + '.rotateX', randomRotationNumber) if randomY is True: pm.setAttr(duplicatedObject[0] + '.rotateY', randomRotationNumber) if randomZ is True: pm.setAttr(duplicatedObject[0] + '.rotateZ', randomRotationNumber) faceLocCount += 1 totalFace = round(float(faceLocCount) / fc * 100.0, 2) _logger.debug("Generated " + str(faceLocCount) + " locators at faces for " + str(fc) + " possible surfaces.(" + str(totalFace) + "%) ")
def getPoleVectorPosition(joints, offset, curveGuide=True): """ Creates locator with offset for the ideal pole vector control location Uses basic math to find the average position across all the joints and creates a vector from the average midpoint to the middle joint in the chain. """ totalJoints = len(joints) joints = map(pmc.nodetypes.Joint, joints) midpoint = Vector() midpoint.x = sum([jnt.getTranslation('world')[0] for jnt in joints]) midpoint.y = sum([jnt.getTranslation('world')[1] for jnt in joints]) midpoint.z = sum([jnt.getTranslation('world')[2] for jnt in joints]) midpoint /= totalJoints if totalJoints % 2 == 0: first = totalJoints / 2 second = first - 1 midJointPos = Vector() midJointPos.x = joints[first].getTranslation( 'world')[0] + joints[second].getTranslation('world')[0] midJointPos.y = joints[first].getTranslation( 'world')[1] + joints[second].getTranslation('world')[1] midJointPos.z = joints[first].getTranslation( 'world')[2] + joints[second].getTranslation('world')[2] midJointPos /= 2 else: midJointPos = Vector( pmc.xform(joints[totalJoints / 2], q=True, worldSpace=True, translation=True)) poleVector = (midJointPos - midpoint).normal() result = pmc.spaceLocator(n='loc_midchain_test') result.setTranslation((poleVector * offset) + midJointPos, 'world') if curveGuide: crv = pmc.curve(degree=1, point=[midpoint, (poleVector * 200) + midJointPos], k=[0, 1], n='curveGuide') return [result, crv] return result