예제 #1
0
def getFaceNormal(facepath):
    verts = getWindingOrder(facepath, False)

    if len(verts) < 3:
        return (1, 0, 0
                )  #if there are less than 3 verts we have no uv area so bail

    #get edge vectors and cross them to get the uv face normal
    vertAPos = Vector(
        cmd.xform(verts[0],
                  query=True,
                  worldSpace=True,
                  absolute=True,
                  translation=True))
    vertBPos = Vector(
        cmd.xform(verts[1],
                  query=True,
                  worldSpace=True,
                  absolute=True,
                  translation=True))
    vertCPos = Vector(
        cmd.xform(verts[2],
                  query=True,
                  worldSpace=True,
                  absolute=True,
                  translation=True))
    vecAB = vertBPos - vertAPos
    vecBC = vertCPos - vertBPos
    faceNormal = (vecAB ^ vecBC).normalize()

    return faceNormal
예제 #2
0
def bakeManualRotateDelta(src, ctrl, presetStr):
    '''
	When you need to apply motion from a skeleton that is completely different from a skeleton driven
	by the rig you're working with (transferring motion from old assets to newer assets for example)
	you can manually align the control to the joint and then use this function to generate offset
	rotations and bake a post trace cmd.
	'''
    srcInvMat = Matrix(getAttr('%s.worldInverseMatrix' % src))
    ctrlMat = Matrix(getAttr('%s.worldMatrix' % ctrl))

    #generate the offset matrix as
    mat_o = ctrlMat * srcInvMat

    #now figure out the euler rotations for the offset
    ro = getAttr('%s.ro' % ctrl)
    rotDelta = constants.MATRIX_ROTATION_ORDER_CONVERSIONS_TO[ro](mat_o, True)

    #now get the positional delta
    posDelta = Vector(xform(src, q=True, ws=True, rp=True)) - Vector(
        xform(ctrl, q=True, ws=True, rp=True))
    posDelta *= -1
    ctrlParentInvMat = Matrix(getAttr('%s.parentInverseMatrix' % ctrl))
    posDelta = posDelta * ctrlParentInvMat

    #construct a list to use for the format str
    formatArgs = tuple(rotDelta) + tuple(posDelta)

    #build the post trace cmd str
    PostTraceNode(ctrl).setCmd(presetStr % formatArgs)

    return rotDelta
예제 #3
0
def getAlignedBoundsForJoint(joint, threshold=0.65, onlyVisibleMeshes=True):
    '''
	looks at the verts the given joint/s and determines a local space (local to the first joint
	in the list if multiple are given) bounding box of the verts, and positions the hitbox
	accordingly

	if onlyVisibleMeshes is True, then only meshes that are visible in the viewport will
	contribute to the bounds
	'''
    theJoint = joint
    verts = []

    #so this is just to deal with the input arg being a tuple, list or string.  you can pass in a list
    #of joint names and the verts affected just get accumulated into a list, and the resulting bound
    #should be the inclusive bounding box for the given joints
    if isinstance(joint, (tuple, list)):
        theJoint = joint[0]
        for joint in joint:
            verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes)
    else:
        verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes)

    jointDag = apiExtensions.asMDagPath(theJoint)
    jointMatrix = jointDag.inclusiveMatrix()
    vJointPos = OpenMaya.MTransformationMatrix(jointMatrix).rotatePivot(
        OpenMaya.MSpace.kWorld) + OpenMaya.MTransformationMatrix(
            jointMatrix).getTranslation(OpenMaya.MSpace.kWorld)
    vJointPos = Vector([vJointPos.x, vJointPos.y, vJointPos.z])
    vJointBasisX = OpenMaya.MVector(-1, 0, 0) * jointMatrix
    vJointBasisY = OpenMaya.MVector(0, -1, 0) * jointMatrix
    vJointBasisZ = OpenMaya.MVector(0, 0, -1) * jointMatrix

    bbox = OpenMaya.MBoundingBox()
    for vert in verts:
        #get the position relative to the joint in question
        vPos = Vector(xform(vert, query=True, ws=True, t=True))
        vPos = vJointPos - vPos

        #now transform the joint relative position into the coordinate space of that joint
        #we do this so we can get the width, height and depth of the bounds of the verts
        #in the space oriented along the joint
        vPosInJointSpace = Vector((vPos.x, vPos.y, vPos.z))
        vPosInJointSpace = vPosInJointSpace.change_space(
            vJointBasisX, vJointBasisY, vJointBasisZ)
        bbox.expand(OpenMaya.MPoint(*vPosInJointSpace))

    minB, maxB = bbox.min(), bbox.max()

    return minB[0], minB[1], minB[2], maxB[0], maxB[1], maxB[2]
예제 #4
0
def getJointSizeAndCentre(joints, threshold=0.65, space=SPACE_OBJECT):
    '''
	minor modification to the getJointSize function in rigging.utils - uses the
	child of the joint[ 0 ] (if any exist) to determine the size of the joint in
	the axis aiming toward
	'''

    centre = Vector.Zero(3)
    if not isinstance(joints, (list, tuple)):
        joints = [joints]

    joints = [str(j) for j in joints if j is not None]
    if not joints:
        return Vector((1, 1, 1))

    size, centre = rigUtils.getJointSizeAndCentre(joints, threshold, space)
    if size.within(Vector.Zero(3), 1e-2):
        while threshold > 1e-2:
            threshold *= 0.9
            size, centre = rigUtils.getJointSizeAndCentre(joints, threshold)

        if size.within(Vector.Zero(3), 1e-2):
            size = Vector((1, 1, 1))

    children = listRelatives(joints[0], pa=True, type='transform')
    if children:
        childPos = Vector([0.0, 0.0, 0.0])
        childPosMag = childPos.get_magnitude()
        for child in children:
            curChildPos = Vector(xform(
                child, q=True, ws=True, rp=True)) - Vector(
                    xform(joints[0], q=True, ws=True, rp=True))
            curChildPosMag = curChildPos.get_magnitude()
            if curChildPosMag > childPosMag:
                childPos = curChildPos
                childPosMag = curChildPosMag

        axis = rigUtils.getObjectAxisInDirection(joints[0], childPos,
                                                 DEFAULT_AXIS)
        axisValue = getAttr('%s.t%s' % (children[0], axis.asCleanName()))

        if space == SPACE_WORLD:
            axis = Axis.FromVector(childPos)

        size[axis % 3] = abs(axisValue)
        centre[axis % 3] = axisValue / 2.0

    return size, centre
예제 #5
0
def getUVFaceNormal(facepath):
    uvs = getWindingOrder(facepath)

    if len(uvs) < 3:
        return (1, 0, 0
                )  #if there are less than 3 uvs we have no uv area so bail

    #get edge vectors and cross them to get the uv face normal
    uvAPos = cmd.polyEditUV(uvs[0], query=True, uValue=True, vValue=True)
    uvBPos = cmd.polyEditUV(uvs[1], query=True, uValue=True, vValue=True)
    uvCPos = cmd.polyEditUV(uvs[2], query=True, uValue=True, vValue=True)
    uvAB = Vector([uvBPos[0] - uvAPos[0], uvBPos[1] - uvAPos[1], 0])
    uvBC = Vector([uvCPos[0] - uvBPos[0], uvCPos[1] - uvBPos[1], 0])
    uvNormal = uvAB.cross(uvBC).normalize()

    return uvNormal
예제 #6
0
    def blend(self, other, amount):
        assert isinstance(other, PoseClip)

        #this simplifies the code below as we don't have to check which values exist in one dict and not the other
        for key, value in self._nodeAttrDict.iteritems():
            other._nodeAttrDict.setdefault(key, value)

        for key, value in other._nodeAttrDict.iteritems():
            self._nodeAttrDict.setdefault(key, value)

        #build new dicts by blending values from the two clips
        newNodeAttrDict = {}
        for node, nodeAttrDict in self._nodeAttrDict.iteritems():
            otherNodeAttrDict = other._nodeAttrDict[node]
            newNodeAttrDict[node] = newAttrDict = {}
            for attr, value in nodeAttrDict.iteritems():
                if attr in otherNodeAttrDict:
                    otherValue = otherNodeAttrDict[attr]
                else:
                    otherValue = value

                blendedValue = newAttrDict[attr] = (value * (1 - amount)) + (
                    otherValue * amount)

        newWorldAttrDict = {}
        for node, (pos, rot, ro) in self._nodeWorldDict.iteritems():
            if node in other._nodeWorldDict:
                otherPos, otherRot, otherRo = other._nodeWorldDict[node]
                blendedPos = (Vector(pos) *
                              (1 - amount)) + (Vector(otherPos) * amount)
                blendedRot = (Vector(rot) *
                              (1 - amount)) + (Vector(otherRot) * amount)
                #if ro != otherRo things get a bit more complicated...

                newWorldAttrDict[node] = list(blendedPos), list(blendedRot), ro

        return PoseClip(newNodeAttrDict, newWorldAttrDict)
예제 #7
0
def findFlipped(obj):
    flipped = []
    faces = cmd.polyListComponentConversion(obj, toFace=True)
    if not faces:
        return flipped

    faces = cmd.ls(faces, flatten=True)
    for face in faces:
        uvNormal = getUVFaceNormal(face)

        #if the uv face normal is facing into screen then its flipped - add it to the list
        if uvNormal * Vector([0, 0, 1]) < 0:
            flipped.append(face)

    return flipped
예제 #8
0
def stampVolumeToJoint(joint, volume, amount=0.1):
    meshes = cmd.ls(cmd.listHistory(joint, f=True, interestLevel=2),
                    type='mesh')
    assert meshes

    jointPos = Vector(cmd.xform(joint, q=True, ws=True, rp=True))
    vertsDict = findVertsInVolume(meshes, volume)
    for mesh, verts in vertsDict.iteritems():
        skinCluster = cmd.ls(cmd.listHistory(mesh), type='skinCluster')[0]
        for vert in verts:
            vertName = '%s.vtx[%s]' % (mesh, vert.id)
            weight = vert.weight
            #print weight, vertName
            #print cmd.skinPercent(skinCluster, vertName, q=True, t=joint, v=True)
            currentWeight = cmd.skinPercent(skinCluster,
                                            vertName,
                                            q=True,
                                            t=joint,
                                            v=True)
            currentWeight += weight * amount
            #cmd.skinPercent(skinCluster, vertName, t=joint, v=currentWeight)
            print vertName, currentWeight
예제 #9
0
    def setup(self, axis=None):
        '''
		sets up the initial state of the pair node
		'''

        if axis:
            axis = abs(Axis(axis))
            setAttr('%s.axis' % self.node, axis)

        #if we have two controls try to auto determine the orientAxis and the flipAxes
        if self.controlA and self.controlB:
            worldMatrixA = getWorldRotMatrix(self.controlA)
            worldMatrixB = getWorldRotMatrix(self.controlB)

            #so restPoseB = restPoseA * offsetMatrix
            #restPoseAInv * restPoseB = restPoseAInv * restPoseA * offsetMatrix
            #restPoseAInv * restPoseB = I * offsetMatrix
            #thus offsetMatrix = restPoseAInv * restPoseB
            offsetMatrix = worldMatrixA.inverse() * worldMatrixB

            AXES = AX_X.asVector(), AX_Y.asVector(), AX_Z.asVector()
            flippedAxes = []
            for n in range(3):
                axisNVector = Vector(offsetMatrix[n][:3])

                #if the axes are close to being opposite, then consider it a flipped axis...
                if axisNVector.dot(AXES[n]) < -0.8:
                    flippedAxes.append(n)

            for n, flipAxes in enumerate(self.FLIP_AXES):
                if tuple(flippedAxes) == flipAxes:
                    setAttr('%s.flipAxes' % self.node, n)
                    break

        #this is a bit of a hack - and not always true, but generally singular controls built by skeleton builder will work with this value
        elif self.controlA:
            setAttr('%s.flipAxes' % self.node, 0)
            self.setWorldSpace(False)
예제 #10
0
	def apply( self, nodes=None, applySettings=None, worldSpace=False, additive=False ):
		if nodes is None:
			nodes = self._nodeAttrDict.iterkeys()

		for node in nodes:
			if node in self._nodeAttrDict:
				for attr, value in self._nodeAttrDict[ node ].iteritems():
					attrpath = '%s.%s' % (node, attr)
					if objExists( attrpath ):
						if additive:
							value += getAttr( attrpath )

						setAttr( attrpath, value, clamp=True )

			if worldSpace:
				if node in self._nodeWorldDict:
					if cmd.objectType( node, isAType='transform' ):
						pos, rot, rotateOrder = self._nodeWorldDict[node]
						if additive:
							pos = Vector( pos ) + Vector( xform( node, q=True, ws=True, rp=True ) )

						move( pos[0], pos[1], pos[2], node, ws=True, a=True, rpr=True )

						roAttrpath = '%s.ro' % node
						initialRotateOrder = getAttr( roAttrpath )
						rotateOrderMatches = initialRotateOrder == rotateOrder

						if rotateOrderMatches:
							if additive:
								rot = Vector( rot ) + Vector( xform( node, q=True, ws=True, ro=True ) )

							rotate( rot[0], rot[1], rot[2], node, ws=True, a=True )
						else:
							if additive:
								xform( node, ro=constants.ROTATE_ORDER_STRS[ rotateOrder ], p=True )
								rot = Vector( rot ) + Vector( xform( node, q=True, ws=True, ro=True ) )

							setAttr( roAttrpath, rotateOrder )
							rotate( rot[0], rot[1], rot[2], node, ws=True, a=True )
							xform( node, ro=constants.ROTATE_ORDER_STRS[ initialRotateOrder ], p=True )
예제 #11
0
def _asPy(self):
    return Vector((self.x, self.y, self.z))
예제 #12
0
def __asNice(self):
    return Vector([self.x, self.y, self.z])
예제 #13
0
    def mirrorMatrix(self, matrix):
        matrix = mirrorMatrix(matrix, self.getAxis())
        for flipAxis in self.getFlips():
            matrix.setRow(flipAxis, -Vector(matrix.getRow(flipAxis)))

        return matrix
예제 #14
0
def buildControl(name,
                 placementDesc=DEFAULT_PLACE_DESC,
                 pivotModeDesc=PivotModeDesc.MID,
                 shapeDesc=DEFAULT_SHAPE_DESC,
                 colour=DEFAULT_COLOUR,
                 constrain=True,
                 oriented=True,
                 offset=Vector((0, 0, 0)),
                 offsetSpace=SPACE_OBJECT,
                 size=Vector((1, 1, 1)),
                 scale=1.0,
                 autoScale=False,
                 parent=None,
                 qss=None,
                 asJoint=False,
                 freeze=True,
                 lockAttrs=('scale', ),
                 hideAttrs=DEFAULT_HIDE_ATTRS,
                 niceName=None,
                 displayLayer=None):
    '''
	this rather verbosely called function deals with creating control objects in
	a variety of ways.

	the following args take "struct" like instances of the classes defined above,
	so look to them for more detail on defining those options

	displayLayer (int) will create layers (if doesn't exist) and add control shape to that layer.
	layer None or zero doesn't create.
	'''

    select(cl=True)

    #sanity checks...
    if not isinstance(placementDesc, PlaceDesc):
        if isinstance(placementDesc, (list, tuple)):
            placementDesc = PlaceDesc(*placementDesc)
        else:
            placementDesc = PlaceDesc(placementDesc)

    if not isinstance(shapeDesc, ShapeDesc):
        if isinstance(shapeDesc, (list, tuple)):
            shapeDesc = ShapeDesc(*shapeDesc)
        else:
            shapeDesc = ShapeDesc(shapeDesc)

    offset = Vector(offset)

    #if we've been given a parent, cast it to be an MObject so that if its name path changes (for example if
    #parent='aNode' and we create a control called 'aNode' then the parent's name path will change to '|aNode' - yay!)
    if parent:
        parent = asMObject(parent)

    #unpack placement objects
    place, align, pivot = placementDesc.place, placementDesc.align, placementDesc.pivot

    if shapeDesc.surfaceType == ShapeDesc.SKIN:
        shapeDesc.curveType = ShapeDesc.NULL_SHAPE  #never build curve shapes if the surface type is skin
        if shapeDesc.joints is None:
            shapeDesc.joints = [str(place)]

        shapeDesc.expand *= scale

    #determine auto scale/size - if nessecary
    if autoScale:
        _scale = list(getJointSize([place] + (shapeDesc.joints or [])))
        _scale = sorted(_scale)[-1]
        if abs(_scale) < 1e-2:
            print 'AUTO SCALE FAILED', _scale, name, place
            _scale = scale

        scale = _scale

    if size is AUTO_SIZE:
        tmpKw = {} if oriented else {'space': SPACE_WORLD}
        size = getJointSize([place] + (shapeDesc.joints or []), **tmpKw)
        for n, v in enumerate(size):
            if abs(v) < 1e-2:
                size[n] = scale

        scale = 1.0

    #if we're doing a SKIN shape, ensure there is actually geometry skinned to the joints, otherwise bail on the skin and change to the default type
    if shapeDesc.surfaceType == ShapeDesc.SKIN:
        try:
            #loop over all joints and see if there is geo skinned to it
            for j in shapeDesc.joints:
                verts = meshUtils.jointVerts(
                    j, tolerance=DEFAULT_SKIN_EXTRACTION_TOLERANCE)

                #if so throw a breakException to bail out of the loop
                if verts:
                    raise BreakException

            #if we get this far that means none of the joints have geo skinned to them - so set the surface and curve types to their default values
            shapeDesc.surfaceType = shapeDesc.curveType = ShapeDesc.DEFAULT_TYPE
            print 'WARNING - surface type was set to SKIN, but no geometry is skinned to the joints: %s' % shapeDesc.joints
        except BreakException:
            pass

    #build the curve shapes first
    if shapeDesc.curveType != ShapeDesc.NULL_SHAPE \
       and shapeDesc.curveType != ShapeDesc.SKIN:
        curveShapeFile = getFileForShapeName(shapeDesc.curveType)
        assert curveShapeFile is not None, "cannot find shape %s" % shapeDesc.curveType

        createCmd = ''.join(curveShapeFile.read())
        mel.eval(createCmd)
    else:
        select(group(em=True))

    sel = ls(sl=True)
    obj = asMObject(sel[0])

    #now to deal with the surface - if its different from the curve, then build it
    if shapeDesc.surfaceType != shapeDesc.curveType \
       and shapeDesc.surfaceType != ShapeDesc.NULL_SHAPE \
       and shapeDesc.surfaceType != ShapeDesc.SKIN:

        #if the typesurface is different from the typecurve, then first delete all existing surface shapes under the control
        shapesTemp = listRelatives(obj, s=True, pa=True)
        for s in shapesTemp:
            if nodeType(s) == "nurbsSurface":
                delete(s)

        #now build the temporary control
        surfaceShapeFile = getFileForShapeName(shapeDesc.surfaceType)
        assert surfaceShapeFile is not None, "cannot find shape %s" % shapeDesc.surfaceType

        createCmd = ''.join(surfaceShapeFile.read())
        mel.eval(createCmd)

        #and parent its surface shape nodes to the actual control, and then delete it
        tempSel = ls(sl=True)
        shapesTemp = listRelatives(tempSel[0], s=True, pa=True) or []
        for s in shapesTemp:
            if nodeType(s) == "nurbsSurface":
                cmd.parent(s, obj, add=True, s=True)

        delete(tempSel[0])
        select(sel)

    #if the joint flag is true, parent the object shapes under a joint instead of a transform node
    if asJoint:
        select(cl=True)
        j = joint()
        for s in listRelatives(obj, s=True, pa=True) or []:
            cmd.parent(s, j, add=True, s=True)

        setAttr('%s.radius' % j, keyable=False)
        setAttr('%s.radius' % j, cb=False)
        delete(obj)
        obj = asMObject(j)

    setAttr('%s.s' % obj, scale, scale, scale)

    #rename the object - if no name has been given, call it "control".  if there is a node with the name already, get maya to uniquify it
    if not name:
        name = 'control'

    if objExists(name):
        name = '%s#' % name

    rename(obj, name)

    #move the pivot - if needed
    makeIdentity(obj, a=1, s=1)
    shapeStrs = getShapeStrs(obj)
    if pivotModeDesc == PivotModeDesc.TOP:
        for s in shapeStrs:
            move(0, -scale / 2.0, 0, s, r=True)
    elif pivotModeDesc == PivotModeDesc.BASE:
        for s in shapeStrs:
            move(0, scale / 2.0, 0, s, r=True)

    #rotate it accordingly
    rot = AXIS_ROTATIONS[shapeDesc.axis]
    rotate(rot[0], rot[1], rot[2], obj, os=True)
    makeIdentity(obj, a=1, r=1)

    #if the user wants the control oriented, create the orientation group and parent the control
    grp = obj
    if oriented:
        grp = group(em=True, n="%s_space#" % obj)
        cmd.parent(obj, grp)
        attrState(grp, ['s', 'v'], *LOCK_HIDE)
        if align is not None:
            delete(parentConstraint(align, grp))

    #place and align
    if place:
        delete(pointConstraint(place, grp))

    if align:
        delete(orientConstraint(align, grp))
    else:
        rotate(0, 0, 0, grp, a=True, ws=True)

    #do the size scaling...
    if shapeDesc.surfaceType != ShapeDesc.SKIN:
        for s in getShapeStrs(obj):
            cmd.scale(size[0], size[1], size[2], s)

    #if the parent exists - parent the new control to the given parent
    if parent is not None:
        grp = cmd.parent(grp, parent)[0]

    #do offset
    for s in getShapeStrs(obj):
        mkw = {'r': True}
        if offsetSpace == SPACE_OBJECT: mkw['os'] = True
        elif offsetSpace == SPACE_LOCAL: mkw['ls'] = True
        elif offsetSpace == SPACE_WORLD: mkw['ws'] = True
        if offset:
            move(offset[0], offset[1], offset[2], s, **mkw)

    if freeze:
        makeIdentity(obj, a=1, r=1)

    makeIdentity(obj, a=1, t=1)  #always freeze translations

    #delete shape data that we don't want
    if shapeDesc.curveType is None:
        for s in listRelatives(obj, s=True, pa=True) or []:
            if nodeType(s) == "nurbsCurve":
                delete(s)

    if shapeDesc.surfaceType is None:
        for s in listRelatives(obj, s=True, pa=True) or []:
            if nodeType(s) == "nurbsSurface":
                delete(s)

    #now snap the pivot to alignpivot object if it exists
    if pivot is not None and objExists(pivot):
        p = placementDesc.pivotPos
        move(p[0],
             p[1],
             p[2],
             '%s.rp' % obj,
             '%s.sp' % obj,
             a=True,
             ws=True,
             rpr=True)

    #constrain the target object to this control?
    if constrain:
        #check to see if the transform is constrained already - if so, bail.  buildControl doesn't do multi constraints
        if not listConnections(pivot, d=0, type='constraint'):
            if place:
                parentConstraint(obj, pivot, mo=True)
                setItemRigControl(pivot, obj)

    #if the user has specified skin geometry as the representation type, then build the geo
    #NOTE: this really needs to happen after ALL the placement has happened otherwise the extracted
    #will be offset from the surface its supposed to be representing
    if shapeDesc.surfaceType == ShapeDesc.SKIN:

        #extract the surface geometry
        geo = meshUtils.extractMeshForJoints(shapeDesc.joints,
                                             expand=shapeDesc.expand)

        #if the geo is None, use the default control representation instead
        writeTrigger = True
        if geo is None:
            writeTrigger = False
            curveShapeFile = getFileForShapeName(ShapeDesc.DEFAULT_TYPE)
            createCmd = ''.join(curveShapeFile.read())
            mel.eval(createCmd)
            geo = ls(sl=True)[0]

        geo = cmd.parent(geo, obj)[0]
        makeIdentity(geo, a=True, s=True, r=True, t=True)

        cmd.parent(listRelatives(geo, s=True, pa=True), obj, add=True, s=True)
        delete(geo)

        #when selected, turn the mesh display off, and only highlight edges
        if writeTrigger:
            triggered.Trigger.CreateTrigger(
                str(obj),
                cmdStr=
                "for( $s in `listRelatives -s -pa #` ) setAttr ( $s +\".displayEdges\" ) 2;"
            )

    #build a shader for the control
    if colour is not None:
        colours.setObjShader(obj, colours.getShader(colour, True))

    #add to a selection set if desired
    if qss is not None:
        sets(obj, add=qss)

    #hide and lock attributes
    attrState(obj, lockAttrs, lock=True)
    attrState(obj, hideAttrs, show=False)

    if niceName:
        setNiceName(obj, niceName)

    # display layer
    if displayLayer and not int(displayLayer) <= 0:
        layerName = 'ctrl_%d' % int(displayLayer)
        allLayers = ls(type='displayLayer')

        layer = ''
        if layerName in allLayers:
            layer = layerName
        else:
            layer = createDisplayLayer(n=layerName, number=1, empty=True)
            setAttr('%s.color' % layer, 24 + int(displayLayer))

        for s in listRelatives(obj, s=True, pa=True) or []:
            connectAttr('%s.drawInfo.visibility' % layer, '%s.v' % s)
            connectAttr('%s.drawInfo.displayType' % layer,
                        '%s.overrideDisplayType' % s)

    return obj
예제 #15
0
    def getLocation(self, obj):
        if obj is None:
            return Vector()

        return xform(obj, q=True, ws=True, rp=True)
예제 #16
0
def findVertsInVolume(meshes, volume):
    '''
	returns a dict containing meshes and the list of vert attributes contained
	within the given <volume>
	'''

    #define a super simple vector class to additionally record vert id with position...
    class VertPos(Vector):
        def __init__(self, x, y, z, vertIdx=None):
            Vector.__init__(self, [x, y, z])
            self.id = vertIdx

    #this dict provides the functions used to determine whether a point is inside a volume or not
    insideDeterminationMethod = {
        ExportManager.kVOLUME_SPHERE: isPointInSphere,
        ExportManager.kVOLUME_CUBE: isPointInCube
    }

    #if there are any uniform overrides for the contained method (called if the volume's scale is
    #unity) it can be registered here
    insideDeterminationIfUniform = {
        ExportManager.kVOLUME_SPHERE: isPointInUniformSphere,
        ExportManager.kVOLUME_CUBE: isPointInCube
    }

    #grab any data we're interested in for the volume
    volumePos = Vector(cmd.xform(volume, q=True, ws=True, rp=True))
    volumeScale = map(abs, cmd.getAttr('%s.s' % volume)[0])
    volumeBasis = rigUtils.getObjectBasisVectors(volume)

    #make sure the basis is normalized
    volumeBasis = [v.normalize() for v in volumeBasis]

    #now lets determine the volume type
    type = ExportManager.kVOLUME_SPHERE
    try:
        type = int(cmd.getAttr('%s.exportVolume' % volume))
    except TypeError:
        pass

    isContainedMethod = insideDeterminationMethod[type]
    print 'method for interior volume determination', isContainedMethod.__name__
    sx = volumeScale[0]
    if Vector(volumeScale).within((sx, sx, sx)):
        try:
            isContainedMethod = insideDeterminationIfUniform[type]
        except KeyError:
            pass

    #now lets iterate over the geometry
    meshVertsWithin = {}
    for mesh in meshes:
        #its possible to pass not a mesh but a component in - this is totally valid, as the polyListComponentConversion
        #should make sure we're always dealing with verts no matter what, but we still need to make sure the dict key is
        #the actual name of the mesh - hence this bit of jiggery pokery
        dotIdx = mesh.rfind('.')
        meshName = mesh if dotIdx == -1 else mesh[:dotIdx]

        meshPositions = []
        meshVertsWithin[meshName] = meshPositions

        #this gives us a huge list of floats - each sequential triple is the position of a vert
        try:
            #if this complains its most likely coz the geo is bad - so skip it...
            vertPosList = cmd.xform(cmd.ls(cmd.polyListComponentConversion(
                mesh, toVertex=True),
                                           fl=True),
                                    q=True,
                                    t=True,
                                    ws=True)
        except TypeError:
            continue
        count = len(vertPosList) / 3

        for idx in xrange(count):
            pos = VertPos(vertPosList.pop(0), vertPosList.pop(0),
                          vertPosList.pop(0), idx)
            contained = isContainedMethod(pos, volumePos, volumeScale,
                                          volumeBasis)
            if contained:
                pos.weight = contained[1]
                meshPositions.append(pos)

    return meshVertsWithin