Пример #1
0
    def deform(self, dataBlock, geoIterator, matrix, geometryIndex):
        input = OpenMayaMPx.cvar.MPxGeometryFilter_input
        # 1. Attach a handle to input Array Attribute.
        dataHandleInputArray = dataBlock.outputArrayValue(input)
        # 2. Jump to particular element
        dataHandleInputArray.jumpToElement(geometryIndex)
        # 3. Attach a handle to specific data block
        dataHandleInputElement = dataHandleInputArray.outputValue()
        # 4. Reach to the child - inputGeom
        inputGeom = OpenMayaMPx.cvar.MPxGeometryFilter_inputGeom
        dataHandleInputGeom = dataHandleInputElement.child(inputGeom)
        inMesh = dataHandleInputGeom.asMesh()

        #Envelope
        envelope = OpenMayaMPx.cvar.MPxGeometryFilter_envelope
        dataHandleEnvelope = dataBlock.inputValue(envelope)
        envelopeValue = dataHandleEnvelope.asFloat()

        # Amplitude
        dataHandleAmplitude = dataBlock.inputValue(Ripple.mObj_Amplitude)
        amplitudeValue = dataHandleAmplitude.asFloat()

        # Displace
        dataHandleDisplace = dataBlock.inputValue(Ripple.mObj_Displace)
        displaceValue = dataHandleDisplace.asFloat()

        # Matrix
        dataHandleMatrix = dataBlock.inputValue(Ripple.mObj_Matrix)
        matrixValue = dataHandleMatrix.asMatrix()

        # Read the translation from Matrix
        mTransMatrix = OpenMaya.MTransformationMatrix(matrixValue)
        translationValue = mTransMatrix.getTranslation(OpenMaya.MSpace.kObject)

        mFloatVectorArray_normal = OpenMaya.MFloatVectorArray()
        mFnMesh = OpenMaya.MFnMesh(inMesh)
        mFnMesh.getVertexNormals(False, mFloatVectorArray_normal,
                                 OpenMaya.MSpace.kObject)

        mPointArray_meshVert = OpenMaya.MPointArray()
        while (not geoIterator.isDone()):
            pointPosition = geoIterator.position()
            weight = self.weightValue(dataBlock, geometryIndex,
                                      geoIterator.index())
            pointPosition.x = pointPosition.x + math.sin(
                geoIterator.index() + displaceValue + translationValue[0]
            ) * amplitudeValue * mFloatVectorArray_normal[
                geoIterator.index()].x * weight * envelopeValue
            pointPosition.y = pointPosition.y + math.sin(
                geoIterator.index() + displaceValue + translationValue[0]
            ) * amplitudeValue * mFloatVectorArray_normal[
                geoIterator.index()].y * weight * envelopeValue
            pointPosition.z = pointPosition.z + math.sin(
                geoIterator.index() + displaceValue + translationValue[0]
            ) * amplitudeValue * mFloatVectorArray_normal[
                geoIterator.index()].z * weight * envelopeValue
            mPointArray_meshVert.append(pointPosition)
            #geoIterator.setPosition(pointPosition)
            geoIterator.next()
        geoIterator.setAllPositions(mPointArray_meshVert)
Пример #2
0
 def deform(self, pDataBlock, pGeometryIterator, pLocalToWorldMatrix, pGeometryIndex):
     
     envelopeAttribute = kEnvelope
     envelopeValue = pDataBlock.inputValue( envelopeAttribute ).asFloat()
     
     AmplitudeValue =  pDataBlock.inputValue(RippleNode.mObjAmplitude).asFloat()
     
     DisplaceValue =  pDataBlock.inputValue(RippleNode.mObjDisplace).asFloat()
     
     inputGeometryObject = self.getDeformerInputGeometry(pDataBlock, pGeometryIndex)    
     
             
     mFloatVectorArrayNormal  = OpenMaya.MFloatVectorArray()
     mFnMesh = OpenMaya.MFnMesh(inputGeometryObject)
     mFnMesh.getVertexNormals(False,mFloatVectorArrayNormal,OpenMaya.MSpace.kObject)
     
     
     while (not pGeometryIterator.isDone()):
         pointsPosition =  pGeometryIterator.position()
         weight =  self.weightValue(pDataBlock, pGeometryIndex, pGeometryIterator.index())
         pointsPosition.x = pointsPosition.x + math.sin(pGeometryIterator.index()+DisplaceValue)*AmplitudeValue *mFloatVectorArrayNormal[pGeometryIterator.index()].x *envelopeValue *weight
         pointsPosition.Y = pointsPosition.y + math.sin(pGeometryIterator.index()+DisplaceValue)*AmplitudeValue *mFloatVectorArrayNormal[pGeometryIterator.index()].y *envelopeValue * weight
         pointsPosition.z = pointsPosition.z + math.sin(pGeometryIterator.index()+DisplaceValue)*AmplitudeValue *mFloatVectorArrayNormal[pGeometryIterator.index()].z *envelopeValue * weight
         
         pGeometryIterator.setPosition(pointsPosition)
         
         
         pGeometryIterator.next()
Пример #3
0
def getNormals(mesh, worldSpace=False):
    '''
	Return all vertex normals for the specified mesh
	@param mesh: Mesh to get vertex normals for
	@type mesh: str
	@param worldSpace: Return the normals in world or object space
	@type worldSpace: bool
	'''
    # Check mesh
    if not isMesh(mesh):
        raise Exception('Object ' + mesh + ' is not a polygon mesh!')

    # Get MFnMesh
    meshFn = getMeshFn(mesh)

    # Determine sample space
    if worldSpace:
        sampleSpace = OpenMaya.MSpace.kWorld
    else:
        sampleSpace = OpenMaya.MSpace.kObject

    # Get Normals
    normalArray = OpenMaya.MFloatVectorArray()
    meshFn.getVertexNormals(False, normalArray, sampleSpace)

    # Return result
    return normalArray
Пример #4
0
class model:

    fnMesh = om.MFnMesh()
    numVtx = 0
    numPoly = 0
    mPointArr = om.MPointArray()
    mCountArr = om.MIntArray()
    verticesInFaces = []
    facesInVertices = []
    normals = om.MFloatVectorArray()
    nearestDists = om.MDoubleArray()
    weights = om.MFloatArray()
    circleNames = []
    checkLevels = om.MIntArray()
    continueIndex = om.MIntArray()

    def clear(cls):
        cls.fnMesh = om.MFnMesh()
        cls.numVtx = 0
        cls.numPoly = 0
        cls.mPointArr = om.MPointArray()
        cls.mCountArr = om.MIntArray()
        cls.verticesInFaces = []
        cls.facesInVertices = []
        cls.normals = om.MFloatVectorArray()
        cls.nearestDists = om.MDoubleArray()
        cls.weights = om.MFloatArray()
        cls.circleNames = []
        cls.checkLevels = om.MIntArray()
        cls.continueIndex = om.MIntArray()

    clear = classmethod(clear)
Пример #5
0
    def deform(self, dataBlock, geoIterator, matrix, geometryIndex):

        input = omp.cvar.MPxGeometryFilter_input
        dataHandleInputArray = dataBlock.inputArrayValue(input)
        dataHandleInputArray.jumpToElement(geometryIndex)
        dataHandleInputElement = dataHandleInputArray.inputValue()

        inputGeom = omp.cvar.MPxGeometryFilter_inputGeom
        dataHandleInputGeom = dataHandleInputElement.child(inputGeom)
        inMesh = dataHandleInputGeom.asMesh()

        envelope = omp.cvar.MPxGeometryFilter_envelope
        dataHandleEnvelope = dataBlock.inputValue(envelope)
        envelopeValue = dataHandleEnvelope.asFloat()

        dataHandleAmplitude = dataBlock.inputValue(rippleNode.mObj_Amplitude)
        amplitudeValue = dataHandleAmplitude.asFloat()

        dataHandleDisplace = dataBlock.inputValue(rippleNode.mObj_Displace)
        displaceValue = dataHandleDisplace.asFloat()

        mFloatVectorArray_normal = om.MFloatVectorArray()
        mFnMesh = om.MFnMesh(inMesh)
        mFnMesh.getVertexNormals(False, mFloatVectorArray_normal, om.MSpace.kObject)

        while(not geoIterator.isDone()):
            pointPosition = geoIterator.position()
            pointPosition.x = pointPosition.x + math.sin(geoIterator.index() + displaceValue) * amplitudeValue * mFloatVectorArray_normal[geoIterator.index()].x * envelopeValue
            pointPosition.y = pointPosition.y + math.sin(geoIterator.index() + displaceValue) * amplitudeValue * mFloatVectorArray_normal[geoIterator.index()].y * envelopeValue
            pointPosition.z = pointPosition.z + math.sin(geoIterator.index() + displaceValue) * amplitudeValue * mFloatVectorArray_normal[geoIterator.index()].z * envelopeValue
            geoIterator.setPosition(pointPosition)
            geoIterator.next()
Пример #6
0
    def deform(self, pDataBlock, pGeometryIterator, pLocalToWorldMatrix,
               pGeometryIndex):
        ''' Deform each vertex using the geometry iterator. '''

        # The envelope determines the overall weight of the deformer on the mesh.
        # The envelope is obtained via the OpenMayaMPx.cvar.MPxDeformerNode_envelope variable.
        # This variable and others like it are generated by SWIG to expose variables or constants declared in C++ header files.
        envelopeAttribute = OpenMayaMPx.cvar.MPxDeformerNode_envelope
        envelopeValue = pDataBlock.inputValue(envelopeAttribute).asFloat()

        # Get the value of the mesh inflation node attribute.
        meshInflationHandle = pDataBlock.inputValue(
            MyDeformerNode.meshInflationAttribute)
        meshInflation = meshInflationHandle.asDouble()

        # Get the value of the bounding box scale node attribute.
        boundingBoxScaleHandle = pDataBlock.inputValue(
            MyDeformerNode.boundingBoxScaleAttribute)
        boundingBoxScale = boundingBoxScaleHandle.asDouble()

        # Get the input mesh from the datablock using our getDeformerInputGeometry() helper function.
        inputGeometryObject = self.getDeformerInputGeometry(
            pDataBlock, pGeometryIndex)

        # Compute the bounding box using the input the mesh.
        boundingBox = self.getBoundingBox(inputGeometryObject,
                                          boundingBoxScale)

        # Obtain the list of normals for each vertex in the mesh.
        normals = OpenMaya.MFloatVectorArray()
        meshFn = OpenMaya.MFnMesh(inputGeometryObject)
        meshFn.getVertexNormals(True, normals, OpenMaya.MSpace.kTransform)

        # Iterate over the vertices to move them.
        global vertexIncrement
        while not pGeometryIterator.isDone():

            # Obtain the vertex normal of the geometry. This normal is the vertex's averaged normal value if that
            # vertex is shared among several polygons.
            vertexIndex = pGeometryIterator.index()
            normal = OpenMaya.MVector(
                normals[vertexIndex]
            )  # Cast the MFloatVector into a simple vector.

            # Increment the point along the vertex normal.
            point = pGeometryIterator.position()
            newPoint = point + (normal * vertexIncrement * meshInflation *
                                envelopeValue)

            # Clamp the new point within the bounding box.
            self.clampPointInBoundingBox(newPoint, boundingBox)

            # Set the position of the current vertex to the new point.
            pGeometryIterator.setPosition(newPoint)

            # Jump to the next vertex.
            pGeometryIterator.next()
Пример #7
0
    def deform(self, dataBlock, geoIter, mtx, multiIndex):
        """This method performs the deformation algorithm.
        The geometry iterator passed to this method is in local space and not world space. To convert
        points to world space use the matrix that is suppied.
            * dataBlock [MDataBlock] is the node's datablock.
            * geoIter [MItGeometry] is an iterator for the current geometry being deformed.
            * mtx [MMatrix] is the geometry's world space transformation matrix.
            * multiIndex [int] is the index corresponding to the requested output geometry.
        """
        # pylint: disable=unused-argument
        envelope = dataBlock.inputValue(
            ompx.cvar.MPxGeometryFilter_envelope).asFloat()
        amplitude = dataBlock.inputValue(TestDeformer.inAmplitude).asFloat()
        displace = dataBlock.inputValue(TestDeformer.inDisplace).asFloat()
        inputArrayHandle = dataBlock.outputArrayValue(
            ompx.cvar.MPxGeometryFilter_input)
        inputArrayHandle.jumpToElement(multiIndex)
        inputElement = inputArrayHandle.outputValue()
        inMesh = inputElement.child(
            ompx.cvar.MPxGeometryFilter_inputGeom).asMesh()
        outMeshArrayHandle = dataBlock.outputArrayValue(
            ompx.cvar.MPxGeometryFilter_outputGeom)
        outMesh = outMeshArrayHandle.inputValue().asMesh()
        mMatrix = dataBlock.inputValue(TestDeformer.inMatrix).asMatrix()

        vTrans = om1.MVector(mMatrix(3, 0), mMatrix(3, 1), mMatrix(3, 2))

        meshFn = om1.MFnMesh(inMesh)
        normalsArray = om1.MFloatVectorArray()
        meshFn.getVertexNormals(False, normalsArray, om1.MSpace.kObject)
        posArray = om1.MPointArray()
        colorsArray = om1.MColorArray()
        vertexArray = om1.MIntArray()

        while not geoIter.isDone():
            index = geoIter.index()
            vertexArray.append(index)
            pntPos = geoIter.position()
            weight = self.weightValue(dataBlock, multiIndex, index)
            colorsArray.append(om1.MColor(1, 0, 0, 1))
            if weight != 0:
                pntPos.x = pntPos.x + math.sin(
                    index + displace - vTrans[0]
                ) * amplitude * normalsArray[index].x * weight * envelope
                pntPos.y = pntPos.y + math.sin(
                    index + displace - vTrans[0]
                ) * amplitude * normalsArray[index].y * weight * envelope
                pntPos.z = pntPos.z + math.sin(
                    index + displace - vTrans[0]
                ) * amplitude * normalsArray[index].z * weight * envelope
            posArray.append(pntPos)
            geoIter.next()
        meshFn.setObject(outMesh)
        meshFn.setVertexColors(colorsArray, vertexArray)
        geoIter.setAllPositions(posArray)
Пример #8
0
	def __init__(self):
		self.vertAry = OpenMaya.MFloatPointArray()
		self.normAry = OpenMaya.MFloatVectorArray()
		self.uAry = OpenMaya.MFloatArray()
		self.vAry = OpenMaya.MFloatArray()
	
		self.vertIndex = OpenMaya.MIntArray()
		self.normIndex = OpenMaya.MIntArray()
		self.uvIndex = OpenMaya.MIntArray()
	
		self.matIndex = 0
Пример #9
0
    def deform(self, dataBlock, geoIterator, matrix, grometryIndex):
        """
        Args:
            dataBlock: the node's datablock. MDataBlock
            geoIterator: an iterator for the current geometry being deformed. MItGeometry
            matrix: the geometry's world space transformation matrix. MMatrix
            grometryIndex: the index corresponding to the requested output geometry. Unsigned Int
        """
        # print 'hi i am inputAttr %s:' % inputAttr
        # print 'hi i am inputGeom %s:' % inputGeom
        # print 'hi i am outputGeom %s:' % outputGeom

        # 1. attach a handle to input Array Attribute
        # EXPLANATION: MDataBlock: provides storage for the data being received by or sent by the node.
        dataHandleInputArray = dataBlock.outputArrayValue(inputAttr)
        # 2. Jump to particular element and get the desired output by geometryIndex
        dataHandleInputArray.jumpToElement(grometryIndex)
        # 3. attach a handle to specific data Block
        dataHandleInputElement = dataHandleInputArray.outputValue()
        # 4. reach the child - inputGeom
        dataHandleInputGeom = dataHandleInputElement.child(inputGeom)
        inMesh = dataHandleInputGeom.asMesh()

        # Envelope
        dataHandleEnvelope = dataBlock.inputValue(envelope)
        # get envelope Value inserted by the user
        envelopeValue = dataHandleEnvelope.asFloat()

        # Amplitude, editable value
        dataHandleAmplitude = dataBlock.inputValue(self.mObj_Amplitude)
        amplitudeValue = dataHandleAmplitude.asFloat()

        # Displace, editable value
        dataHandleDisplace = dataBlock.inputValue(self.mObj_Displace)
        displaceValue = dataHandleDisplace.asFloat()

        mFloatVectorArray_normal = OpenMaya.MFloatVectorArray()
        mFnMesh = OpenMaya.MFnMesh(inMesh)
        mFnMesh.getVertexNormals(False, mFloatVectorArray_normal, OpenMaya.MSpace.kObject)

        mPointArray_meshVert = OpenMaya.MPointArray()
        while not geoIterator.isDone():
            pointPosition = geoIterator.position()
            pointPosition.x = pointPosition.x + math.sin(geoIterator.index() + displaceValue) * amplitudeValue * mFloatVectorArray_normal[geoIterator.index()].x * envelopeValue
            pointPosition.y = pointPosition.y + math.sin(geoIterator.index() + displaceValue) * amplitudeValue * mFloatVectorArray_normal[geoIterator.index()].y * envelopeValue
            pointPosition.z = pointPosition.z + math.sin(geoIterator.index() + displaceValue) * amplitudeValue * mFloatVectorArray_normal[geoIterator.index()].z * envelopeValue
            mPointArray_meshVert.append(pointPosition)

            geoIterator.next()

        geoIterator.setAllPositions(mPointArray_meshVert)
Пример #10
0
def sampleShadingNetworkAtPoints(nodeAttr, points):

    numSamples = len(points)
    pointArray = points
    pointArray = OpenMaya.MFloatPointArray()
    pointArray.setLength(numSamples)

    refPoints = OpenMaya.MFloatPointArray()
    refPoints.setLength(numSamples)

    for i, point in enumerate(points):
        location = OpenMaya.MFloatPoint(point[0], point[1], point[2])
        pointArray.set(location, i)
        refPoints.set(location, i)

    # but we don't need these
    useShadowMap = False
    reuseMaps = False
    cameraMatrix = OpenMaya.MFloatMatrix()
    uCoords = None
    vCoords = None
    normals = None
    tangentUs = None
    tangentVs = None
    filterSizes = None

    # and the return arguments are empty....
    resultColors = OpenMaya.MFloatVectorArray()
    resultTransparencies = OpenMaya.MFloatVectorArray()

    # sample the node network
    OpenMayaRender.MRenderUtil.sampleShadingNetwork(
        nodeAttr, numSamples, useShadowMap, reuseMaps, cameraMatrix,
        pointArray, uCoords, vCoords, normals, refPoints, tangentUs, tangentVs,
        filterSizes, resultColors, resultTransparencies)

    # return formatted sampled colours
    return resultColors
Пример #11
0
    def deform(self, data, geoIterator, matrix, geometryIndex):
        # get push value
        # data is a class?
        pushHandle = data.inputValue(self.push)
        push = pushHandle.asFloat()

        # get envelope value
        envelopeHandle = data.inputValue(envelopeAttr)
        envelope = envelopeHandle.asFloat()

        # get the input geometry
        mesh = self.getInputMesh(data, geometryIndex)

        # crete an empty array (list) of floats vectors to store our normals
        normals = om.MFloatVectorArray()
        # the make de meshFn to interact with the mesh
        meshFn = om.MFnMesh(mesh)
        # use this to get and store the normals froms the mesh onto the normals array 'normals'
        # remember pay attention to the pluralization of the normals
        meshFn.getVertexNormals(
            # if True, the normals are angleWeighted which is what we want
            True,
            # we tell were store normals, in this case normals above
            normals,
            # finally tell the space, in this case object space
            om.MSpace.kTransform)

        # now we can iterate throught the geometry vertices and do our deformation
        while not geoIterator.isDone():  # geo iterator is ...
            # current point index
            index = geoIterator.index()
            # look normal from our array
            normal = om.MVector(normals[index])  # index may be int
            # get the positions of the point
            position = geoIterator.position()
            # calculate the offset
            # multiply vector by magnitude
            offset = (normal * push * envelope)  # push is the input value //

            # we then query the painted weitght for this area
            weight = self.weightValue(data, geometryIndex,
                                      index)  # from MPxDeformerNode class
            offset = (offset * weight)

            # Finally we can set the position
            geoIterator.setPosition(position + offset)
            # go to the next item
            geoIterator.next()
    def deform(self, data_block, geo_iter, world_matrix, multi_index):

        envelope = data_block.inputValue(self.envelope).asFloat()
        if envelope == 0:
            return

        max_distance = data_block.inputValue(
            AttractorDeformerNode.max_distance).asFloat()
        if max_distance == 0:
            return

        target_position = data_block.inputValue(
            AttractorDeformerNode.target_position).asFloatVector()
        target_position = om.MPoint(target_position) * world_matrix.inverse()
        target_position = om.MFloatVector(target_position)

        input_handle = data_block.outputArrayValue(self.input)
        input_handle.jumpToElement(multi_index)
        input_element_handle = input_handle.outputValue()

        input_geom = input_element_handle.child(self.inputGeom).asMesh()
        mesh_fn = om.MFnMesh(input_geom)

        normals = om.MFloatVectorArray()
        mesh_fn.getVertexNormals(False, normals)

        geo_iter.reset()
        while not geo_iter.isDone():

            pt_local = geo_iter.position()

            target_vector = target_position - om.MFloatVector(pt_local)

            distance = target_vector.length()
            if distance <= max_distance:

                normal = normals[geo_iter.index()]

                angle = normal.angle(target_vector)
                if angle <= AttractorDeformerNode.MAX_ANGLE:

                    offset = target_vector * (
                        (max_distance - distance) / max_distance)

                    geo_iter.setPosition(pt_local + om.MVector(offset))

            geo_iter.next()
Пример #13
0
    def deform(self, data, geoIterator, matrix, geometryIndex):

        # Get the push value
        pushHandle = data.inputValue(self.push)
        push = pushHandle.asFloat()

        # get the envelope value
        envelopeHandle = data.inputValue(envelopeAttr)
        envelope = envelopeHandle.asFloat()

        # Get the input geometry
        mesh = self.getInputMesh(data, geometryIndex)

        # Create an empty array(list) of Float Vectors to store our normals in
        normals = om.MFloatVectorArray()
        # Then make the meshFn to interact with the mesh
        meshFn = om.MFnMesh(mesh)
        # And we use this to get and store the normals from the mesh onto the normals array we created above
        # Remember to pay attention to the pluralization of normals
        meshFn.getVertexNormals(
            True,  # If True, the normals are angleWeighted which is what we want
            normals,  # We tell it what to store the data in, in this case our array above,
            om.MSpace.
            kTransform  # Finally we tell it what space we want the normals in, in this case the local object space
        )

        # Now we can iterate through the geometry vertices and do our deformation
        while not geoIterator.isDone():
            # Get the index of our current point
            index = geoIterator.index()
            # Look up the normals for this point from our array
            normal = om.MVector(normals[index])
            # Get the position of the point
            position = geoIterator.position()
            # Then calculate the offset
            # we do this by multiplying the magnitude of the normal vector by the intensity of the push and envelope
            offset = (normal * push * envelope)

            # We then query the painted weight for this area
            weight = self.weightValue(data, geometryIndex, index)
            offset = (offset * weight)

            # Finally we can set the position
            geoIterator.setPosition(position + offset)
            # And always remember to go on to the next item in the list
            geoIterator.next()
Пример #14
0
    def deform(self, data, geom_it, local_to_world_mat, geom_idx):
        envelope_attr = OpenMayaMPx.cvar.MPxDeformerNode_envelope
        envelope = data.inputValue(envelope_attr).asFloat()

        inflation_handle = data.inputValue(PushDeformerNode.inflation_attr)
        inflation = inflation_handle.asDouble()

        input_geom_obj = self.get_input_geom(data, geom_idx)
        normals = OpenMaya.MFloatVectorArray()
        mesh = OpenMaya.MFnMesh(input_geom_obj)
        mesh.getVertexNormals(True, normals, OpenMaya.MSpace.kTransform)

        while not geom_it.isDone():
            idx = geom_it.index()
            nrm = OpenMaya.MVector(normals[idx])
            pos = geom_it.position()
            new_pos = pos + (nrm * inflation * envelope)
            geom_it.setPosition(new_pos)
            geom_it.next()
Пример #15
0
    def __init__(self):
        super(polyModifierCmd, self).__init__()

        # polymesh
        self._fDagPathInitialized = False
        self._fDagPath = om.MDagPath()
        self._fDuplicateDagPath = om.MDagPath()

        # modifier node type
        self._fModifierNodeTypeInitialized = False
        self._fModifierNodeNameInitialized = False
        self._fModifierNodeType = om.MTypeId()
        self._fModifierNodeName = ""

        # node state

        self._fHasHistory = False
        self._fHasTweaks = False
        self._fHasRecordHistory = False

        # cached tweak data

        self._fTweakIndexArray = om.MIntArray()
        self._fTweakVectorArray = om.MFloatVectorArray()

        # cached mesh data

        self._fMeshData = om.MObject()

        # dg and dag modifier

        self._fDGModifier = om.MDGModifier()
        self._fDagModifier = om.MDagModifier()

        # manual shape management
        self._manual_redo_queue = []

        numDataFn = om.MFnNumericData()
        numDataFn.create(om.MFnNumericData.k3Float)
        numDataFn.setData3Float(0.0, 0.0, 0.0)
        self.__class__.NULL_VECTOR = numDataFn.object()
Пример #16
0
    def getTangent(self, faceID, targetFnMesh):
        """ Return a tangent vector of a face.
            Args:
                faceID  (int)
                mVector (OpenMaya.MVector)
            Returns:
                OpenMaya.MVector : tangent vector
        """

        tangentArray = OpenMaya.MFloatVectorArray()
        targetFnMesh.getFaceVertexTangents(faceID, tangentArray, self.SPACE)
        numOfVtx = tangentArray.length()
        x = sum([tangentArray[i].x for i in range(numOfVtx)]) / numOfVtx
        y = sum([tangentArray[i].y for i in range(numOfVtx)]) / numOfVtx
        z = sum([tangentArray[i].z for i in range(numOfVtx)]) / numOfVtx
        tangentVector = OpenMaya.MVector()
        tangentVector.x = x
        tangentVector.y = y
        tangentVector.z = z
        tangentVector.normalize()

        return tangentVector
Пример #17
0
    def __init__(self):
        super(polyModifierCmd, self).__init__()

        # polymesh
        self._fDagPathInitialized = False
        self._fDagPath = om.MDagPath()
        self._fDuplicateDagPath = om.MDagPath()

        # modifier node type
        self._fModifierNodeTypeInitialized = False
        self._fModifierNodeNameInitialized = False
        self._fModifierNodeType = om.MTypeId()
        self._fModifierNodeName = ""

        # node state

        self._fHasHistory = False
        self._fHasTweaks = False
        self._fHasRecordHistory = False

        # cached tweak data

        self._fTweakIndexArray = om.MIntArray()
        self._fTweakVectorArray = om.MFloatVectorArray()

        # cached mesh data

        self._fMeshData = om.MObject()

        # dg and dag modifier

        self._fDGModifier = om.MDGModifier()
        self._fDagModifier = om.MDagModifier()

        # manual shape management
        self._manual_redo_queue = []
Пример #18
0
def averageNormal( *args ):
    
    for dagPath, vtxList in selectedVertices():
        fnMesh = OpenMaya.MFnMesh( dagPath )
        
        points = OpenMaya.MPointArray()
        normals = OpenMaya.MFloatVectorArray()
        
        fnMesh.getPoints( points )
        fnMesh.getVertexNormals( True, normals )
        
        itMeshVtx = OpenMaya.MItMeshVertex( dagPath )
        
        resultPoints = []
        for i in range( vtxList.length() ):
            pPrevIndex = getIntPtr()
            itMeshVtx.setIndex( vtxList[i], pPrevIndex )
            conVertices = OpenMaya.MIntArray();
            itMeshVtx.getConnectedVertices(conVertices)
            
            bb = OpenMaya.MBoundingBox()
            for j in range( conVertices.length() ):
                bb.expand( points[conVertices[j]] )
            
            center = bb.center()
            centerVector = points[ vtxList[i] ] - center
            normal       = normals[ vtxList[i] ]
            normal.normalize()
            projVector = normal * ( normal * OpenMaya.MFloatVector(centerVector) )
            
            resultPoint = -OpenMaya.MVector(projVector)/3.0 + OpenMaya.MVector( points[ vtxList[i] ] )
            resultPoints.append( resultPoint )
        
        meshName = fnMesh.partialPathName()
        for i in range( vtxList.length() ):
            cmds.move( resultPoints[i].x, resultPoints[i].y, resultPoints[i].z, meshName + ".vtx[%d]" % vtxList[i], os=1 )
Пример #19
0
    def getGeometry(self, iSet):

        # get all object verts
        meshPoints = OpenMaya.MPointArray()
        self.fShape.getPoints(meshPoints)

        # get all object normals
        meshNormals = OpenMaya.MFloatVectorArray()
        self.fShape.getNormals(meshNormals)

        # get all object UVs, if any
        if self.hasUVs:
            try:
                meshUArray = OpenMaya.MFloatArray()
                meshVArray = OpenMaya.MFloatArray()
                self.fShape.getUVs(meshUArray, meshVArray,
                                   self.UVSets[self.currentUVSet])
            except:
                OpenMaya.MGlobal.displayError(
                    "Error with UV mapping on object: %s" % self.fShape.name())
                raise

        # set up some scripting junk
        numTrianglesPx = OpenMaya.MScriptUtil()
        numTrianglesPx.createFromInt(0)
        numTrianglesPtr = numTrianglesPx.asIntPtr()
        uvIdxPx = OpenMaya.MScriptUtil()
        uvIdxPx.createFromInt(0)
        uvIdxPtr = uvIdxPx.asIntPtr()

        # set up mesh face iterator
        itMeshPolys = OpenMaya.MItMeshPolygon(self.dagPath,
                                              self.fPolygonComponents[iSet])

        if not itMeshPolys.hasValidTriangulation():
            OpenMaya.MGlobal.displayWarning(
                "Shape %s has invalid triangulation, skipping" %
                self.fShape.name())
            return

        # storage for obj-relative vert indices in a face
        polygonVertices = OpenMaya.MIntArray()

        # storage for the face vert points
        vertPoints = OpenMaya.MPointArray()

        # storage for the face vert indices
        vertIndices = OpenMaya.MIntArray()

        # set syntax for trianglemesh/loopsubdiv or portalshape
        if self.type == 'geom':
            # detect Material or AreaLight

            materialNode = self.findSurfaceShader(self.instanceNum, iSet)
            if materialNode.typeName() == "pbrtAreaLightMaterial":
                self.addToOutput(self.getAreaLight(materialNode))
            else:
                self.addToOutput(self.getNamedMaterial(materialNode))

            #self.shadingGroup = self.findShadingGroup(self.instanceNum, iSet)
            #self.addToOutput( self.findSurfaceShader( shadingGroup = self.shadingGroup ) )

            # detect trianglemesh/loopsubdiv
            subPlug1 = self.fShape.findPlug('useMaxSubdivisions')
            useLoopSubdiv = subPlug1.asBool()
            if useLoopSubdiv:
                self.mode = 'loopsubdiv'
                subPlug2 = self.fShape.findPlug('maxSubd')
                nlevels = subPlug2.asInt()
                self.addToOutput('\tShape "loopsubdiv"')
                self.addToOutput('\t\t"integer nlevels" [%i]' % nlevels)
                # find displacement, if any
                #self.addToOutput( self.findDisplacementShader( self.shadingGroup ) )
            else:
                self.mode = 'trianglemesh'
                self.addToOutput('\tShape "trianglemesh"')

        def compileWithUVs():
            totalVertIndices = 0
            # each face
            while not itMeshPolys.isDone():

                # get number of triangles in face
                itMeshPolys.numTriangles(numTrianglesPtr)
                numTriangles = OpenMaya.MScriptUtil(numTrianglesPtr).asInt()

                itMeshPolys.getVertices(polygonVertices)

                # each triangle in each face
                for currentTriangle in range(0, numTriangles):

                    # get the triangle points and indices
                    itMeshPolys.getTriangle(currentTriangle, vertPoints,
                                            vertIndices,
                                            OpenMaya.MSpace.kObject)

                    # get a list of local indices
                    localIndex = self.GetLocalIndex(polygonVertices,
                                                    vertIndices)

                    # each vert in this triangle
                    for i, vertIndex in enumerate(vertIndices):

                        # get indices to points/normals/uvs
                        vertNormalIndex = itMeshPolys.normalIndex(
                            localIndex[i])

                        try:
                            itMeshPolys.getUVIndex(
                                localIndex[i], uvIdxPtr,
                                self.UVSets[self.currentUVSet])
                            vertUVIndex = OpenMaya.MScriptUtil(
                                uvIdxPtr).asInt()
                        except:
                            OpenMaya.MGlobal.displayWarning(
                                'Invalid UV data on object %s (UV set "%s"), restarting object export without UVs'
                                % (self.dagPath.fullPathName(),
                                   self.UVSets[self.currentUVSet]))
                            self.resetLists()
                            itMeshPolys.reset()
                            compileWithoutUVs()
                            self.hasUVs = False
                            return

                        # if we've seen this combo before,
                        testVal = (vertIndex, vertNormalIndex, vertUVIndex)
                        #try:
                        if testVal in self.vertNormUVList:
                            self.vertIndexList.append(
                                self.vertNormUVList[testVal])
                        #except KeyError:
                        else:
                            # add it to the lists
                            self.vertPointList.append(meshPoints[vertIndex])
                            self.vertNormList.append(
                                meshNormals[vertNormalIndex])
                            self.vertUVList.append((meshUArray[vertUVIndex],
                                                    meshVArray[vertUVIndex]))

                            # and keep track of what we've seen
                            self.vertNormUVList[testVal] = totalVertIndices
                            # and use the most recent idx value
                            self.vertIndexList.append(totalVertIndices)
                            totalVertIndices += 1

                itMeshPolys.next()

        def compileWithoutUVs():
            totalVertIndices = 0
            # each face
            while not itMeshPolys.isDone():

                # get number of triangles in face
                itMeshPolys.numTriangles(numTrianglesPtr)
                numTriangles = OpenMaya.MScriptUtil(numTrianglesPtr).asInt()

                itMeshPolys.getVertices(polygonVertices)

                # each triangle in each face
                for currentTriangle in range(0, numTriangles):

                    # get the triangle points and indices
                    itMeshPolys.getTriangle(currentTriangle, vertPoints,
                                            vertIndices,
                                            OpenMaya.MSpace.kObject)

                    # get a list of local indices
                    localIndex = self.GetLocalIndex(polygonVertices,
                                                    vertIndices)

                    # each vert in this triangle
                    for i, vertIndex in enumerate(vertIndices):

                        # get indices to points/normals/uvs
                        vertNormalIndex = itMeshPolys.normalIndex(
                            localIndex[i])

                        # if we've seen this combo yet,
                        testVal = (vertIndex, vertNormalIndex)
                        #try:
                        if testVal in self.vertNormUVList:
                            self.vertIndexList.append(
                                self.vertNormUVList[testVal])
                        #except KeyError:
                        else:
                            # add it to the lists
                            self.vertPointList.append(meshPoints[vertIndex])
                            self.vertNormList.append(
                                meshNormals[vertNormalIndex])

                            # and keep track of what we've seen
                            self.vertNormUVList[testVal] = totalVertIndices
                            # and use the most recent idx value
                            self.vertIndexList.append(totalVertIndices)
                            totalVertIndices += 1

                itMeshPolys.next()

        startTime = time.clock()

        if itMeshPolys.hasUVs():
            compileWithUVs()
        else:
            compileWithoutUVs()

        procTime = time.clock()
        procDuration = procTime - startTime

        # mesh iteration done, do output.

        self.addToOutput('\t"integer indices" [')
        self.addToOutput('\t\t' + ' '.join(map(str, self.vertIndexList)))
        self.addToOutput('\t]')

        self.fileHandle.flush()

        self.addToOutput('\t"point P" [')
        for vP in self.vertPointList:
            self.addToOutput('\t\t%f %f %f' % (vP.x, vP.y, vP.z))
        self.addToOutput('\t]')

        self.fileHandle.flush()

        # add UVs for trianglemesh and loopsubdiv, but not for portals and only if the shape has uvs
        if self.type == 'geom' and itMeshPolys.hasUVs() and len(
                self.vertUVList) > 0:
            self.addToOutput('\t"float uv" [')
            for uv in self.vertUVList:
                self.addToOutput('\t\t%f %f' % uv)
            self.addToOutput('\t]')

        self.fileHandle.flush()

        # Add normals to trianglemesh
        if self.mode == 'trianglemesh':
            self.addToOutput('\t"normal N" [')
            for vN in self.vertNormList:
                self.addToOutput('\t\t%f %f %f' % (vN.x, vN.y, vN.z))
            self.addToOutput('\t]')

        outTime = time.clock()
        writeDuration = outTime - procTime

        if self.doBenchmark:
            vLen = len(self.vertNormUVList)
            pSpeed = vLen / procDuration
            wSpeed = vLen / writeDuration
            print "%i verts processed in %f seconds: %f verts/sec" % (
                vLen, procDuration, pSpeed)
            print " -> written in %f seconds: %f verts/sec" % (writeDuration,
                                                               wSpeed)

            sf = open("e:\meshopt_stats.csv", "a")
            sf.write(('%i,%f,%f' % (vLen, pSpeed, wSpeed)) + os.linesep)
            sf.close()
Пример #20
0
    def exportPly(self, mObject, mFnDagNode, dagPath, exportOptions):
        verbose = False
        triangulate = False
        if exportOptions:
            if 'verbose' in exportOptions and exportOptions[
                    'verbose'] == 'true':
                verbose = True
            if 'triangulate' in exportOptions and exportOptions[
                    'triangulate'] == 'true':
                triangulate = True

        dagNode = OpenMaya.MDagPath()
        mFnDagNode.getPath(dagNode)
        dagNode.extendToShape()
        meshNode = OpenMaya.MFnMesh(dagNode)

        dagPath = dagNode.fullPathName()
        if verbose:
            print("exportPly : %s" % dagPath)

        # Space to evaluate normals, point positions
        space = OpenMaya.MSpace.kWorld
        if exportOptions:
            if 'space' in exportOptions and exportOptions['space'] == 'object':
                if verbose:
                    print("\tSpace               : %s" % "object space")
                space = OpenMaya.MSpace.kObject
            else:
                if verbose:
                    print("\tSpace               : %s" % "world space")
        '''
        polygonSets = OpenMaya.MObjectArray()
        polygonComponents = OpenMaya.MObjectArray()
        isInstanced = dagNode.isInstanced()
        print( "\tInstanced           : %s" % isInstanced )
        if dagNode.isInstanced():
            instanceNum = dagNode.instanceNumber()
            print( "\tInstance Number     : %s" % instanceNum )

            meshNode.getConnectedSetsAndMembers(instanceNum, polygonSets, polygonComponents, True)
            print( "\tPolygon Sets        : %s" % polygonSets.length() )
            print( "\tPolygon Components  : %s" % polygonComponents.length() )
        '''

        # Get Vertices
        numVertices = meshNode.numVertices()
        if verbose:
            print("\tVerts               : %d" % numVertices)

        points = OpenMaya.MPointArray()
        meshNode.getPoints(points, space)
        numPoints = points.length()
        if verbose:
            print("\tPoints              : %d" % numPoints)

        # Get UVs
        us = OpenMaya.MFloatArray()
        vs = OpenMaya.MFloatArray()
        meshNode.getUVs(us, vs)
        numUVs = us.length()
        if verbose:
            print("\tUVs                 : %d" % numUVs)

        # Get Normals
        normals = OpenMaya.MFloatVectorArray()
        meshNode.getNormals(normals, space)
        numNormals = normals.length()
        if verbose:
            print("\tNorms               : %d" % numNormals)

        # Faces
        numFaces = meshNode.numPolygons()
        if verbose:
            print("\tFaces               : %d" % numFaces)

        # Vertex Colors
        numColors = meshNode.numColors()

        vertexColors = None
        faceVertexColors = None
        if numColors > 0:
            vertexColors = OpenMaya.MColorArray()
            meshNode.getVertexColors(vertexColors)
            numVertexColors = vertexColors.length()
            if verbose:
                print("\tVertex Colors       : %d" % numVertexColors)

                #for i in range(numVertexColors):
                #    print( "Color %d : %3.3f, %3.3f, %3.3f" % (
                #        i, vertexColors[i].r, vertexColors[i].g, vertexColors[i].b))

            faceVertexColors = OpenMaya.MColorArray()
            meshNode.getFaceVertexColors(faceVertexColors)
            numFaceVertexColors = faceVertexColors.length()
            if verbose:
                print("\tFace Vert Colors    : %d" % numFaceVertexColors)

                #for i in range(numFaceVertexColors):
                #    print( "Color %d : %3.3f, %3.3f, %3.3f" % (
                #        i, faceVertexColors[i].r, faceVertexColors[i].g, faceVertexColors[i].b))

        # Per-Face data
        itMeshPoly = OpenMaya.MItMeshPolygon(mObject)

        # Check for triangulation
        hasValidTriangulation = itMeshPoly.hasValidTriangulation()
        if verbose:
            print("\tHas Triangulation   : %s" % hasValidTriangulation)
        if hasValidTriangulation:
            triangleCount = OpenMaya.MIntArray()
            triangleIndices = OpenMaya.MIntArray()
            meshNode.getTriangles(triangleCount, triangleIndices)
        else:
            if triangulate:
                OpenMaya.MGlobal.displayWarning(
                    "Shape %s has invalid triangulation, skipping" % dagPath)
                return None

        if verbose:
            t0 = timeit.default_timer()

        if triangulate and hasValidTriangulation:
            plyData = self.exportTriangulatedMesh(mObject, dagPath, meshNode,
                                                  points, us, vs, normals,
                                                  faceVertexColors,
                                                  triangleCount,
                                                  triangleIndices,
                                                  exportOptions, verbose)
        else:
            plyData = self.exportMesh(mObject, dagPath, meshNode, points, us,
                                      vs, normals, faceVertexColors,
                                      exportOptions, verbose)

        if verbose:
            t1 = timeit.default_timer()
            elapsed = (t1 - t0)
            print("export elapsed : %s" % elapsed)

        return plyData
Пример #21
0
    def deform(self, dataBlock, geoIterator, matrix, geometryIndex):

        # 0. Grab the input Attribute come with the deformer node
        # input = openmayampx.cvar.MPxDeformerNode_input
        input = openmayampx.cvar.MPxGeometryFilter_input

        # 1. Attach a handle to input Array Attribute
        # Whenever using MDatablock.inputValue, it will check the Dependency Node plugs are clean or dirty.
        # If the plugs are dirty, it will starting evaluating the whole linked Dependency Graph.
        # The complete Dependency Graph will be evaluated, it will return the clean values.
        # Then it will start compute() i.e deform() method.
        # To prevent the re-computation of the mesh, we need to replace the inputArrayValue with outputArrayValue.
        dataHandleInputArray = dataBlock.outputArrayValue(input)

        # 2. Jump to particular element in array
        dataHandleInputArray.jumpToElement(geometryIndex)

        # 3. Attach a handle to specific data block
        # To prevent the re-computation of the mesh, we need to replace the inputValue with outputValue.
        dataHandleInputElement = dataHandleInputArray.outputValue()

        # 4. Reach to the child - inputGeom
        # inputGeom = openmayampx.cvar.MPxDeformerNode_inputGeom
        inputGeom = openmayampx.cvar.MPxGeometryFilter_inputGeom
        dataHandleInputGeom = dataHandleInputElement.child(inputGeom)
        inMesh = dataHandleInputGeom.asMesh()

        # Envelope
        # envelope = openmayampx.cvar.MPxDeformerNode_envelope
        envelope = openmayampx.cvar.MPxGeometryFilter_envelope
        dataHandleEnvolope = dataBlock.inputValue(envelope)
        envelopeValue = dataHandleEnvolope.asFloat()

        # Amplitude
        dataHandleAmplitude = dataBlock.inputValue(Ripple.mObj_Amplitude)
        amplitudeValue = dataHandleAmplitude.asFloat()

        # Displace
        dataHandleDisplace = dataBlock.inputValue(Ripple.mObj_Displace)
        disPlaceValue = dataHandleDisplace.asFloat()

        mFloatVectorArray_normal = openmaya.MFloatVectorArray()
        mFnMesh = openmaya.MFnMesh(inMesh)
        mFnMesh.getVertexNormals(False, mFloatVectorArray_normal,
                                 openmaya.MSpace.kObject)

        # store the vertex positions of the mesh.
        mPointArray_meshVert = openmaya.MPointArray()

        while (not geoIterator.isDone()):
            pointPosition = geoIterator.position()
            pointPosition.x = pointPosition.x + math.sin(geoIterator.index(
            ) + disPlaceValue) * amplitudeValue * mFloatVectorArray_normal[
                geoIterator.index()].x * envelopeValue
            pointPosition.y = pointPosition.y + math.sin(geoIterator.index(
            ) + disPlaceValue) * amplitudeValue * mFloatVectorArray_normal[
                geoIterator.index()].y * envelopeValue
            pointPosition.z = pointPosition.z + math.sin(geoIterator.index(
            ) + disPlaceValue) * amplitudeValue * mFloatVectorArray_normal[
                geoIterator.index()].z * envelopeValue

            #geoIterator.setPosition(pointPosition)
            mPointArray_meshVert.append(pointPosition)

            geoIterator.next()
        # Set all the Position at once.
        geoIterator.setAllPositions(mPointArray_meshVert)
Пример #22
0
# Only click on load to load plugin. Click again to unload. You'll need to 
# load and unload the plugin to see code changes

# put this file in C:\Program Files\Autodesk\Maya<year>\bin\plug-ins

import sys
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
import maya.OpenMayaRender as OpenMayaRender
import fileExportHeader as header
import array
import maya.cmds as cmds

# Unique Lists
uniqueVertAry = OpenMaya.MFloatPointArray()
uniqueNormAry = OpenMaya.MFloatVectorArray()
uniqueUAry = OpenMaya.MFloatArray()
uniqueVAry = OpenMaya.MFloatArray()
uniqueMaterialPathAry = list()
faceGrpList = list()

#cmds.confirmDialog( title='Confirm', message='Are you sure?', button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )

kPluginCmdName = "myExport"

class CFaceGrp:
	# define as self so that these arrays are unique instances
	def __init__(self):
		self.vertAry = OpenMaya.MFloatPointArray()
		self.normAry = OpenMaya.MFloatVectorArray()
		self.uAry = OpenMaya.MFloatArray()
Пример #23
0
    def compute(self, plug, data):
        if plug == self.outColor or plug.parent() == self.outColor:
            thisNode = self.thisMObject()
            fnThisNode = om.MFnDependencyNode(thisNode)

            uData = data.inputValue(self.inUCoord)
            uValue = uData.asFloat()
            uArray = om.MFloatArray(1)
            uArray.set(uValue, 0)

            timeData = data.inputValue(self.time)
            timeValue = timeData.asFloat()

            vData = data.inputValue(self.inVCoord)
            vValue = vData.asFloat()
            vArray = om.MFloatArray(1)
            vArray.set(vValue, 0)

            shadowsData = data.inputValue(self.useShadowMaps)
            shadowsValue = shadowsData.asBool()

            reShadowsData = data.inputValue(self.reUseShadowMaps)
            reShadowsValue = reShadowsData.asBool()

            filterSizeData = data.inputValue(self.filterSize)
            filterSizeValue = filterSizeData.asFloat()
            filterSizeArray = om.MFloatArray(1)
            filterSizeArray.set(filterSizeValue, 0)

            inPointData = data.inputValue(self.inPoint)
            inPointValue = inPointData.asFloatVector()
            inPointArray = om.MFloatPointArray(1)
            inPointArray.set(0, inPointValue.x, inPointValue.y, inPointValue.z,
                             1)

            useRefPointData = data.inputValue(self.useRefPoint)
            useRefPointValue = useRefPointData.asBool()

            refPointArray = om.MFloatPointArray(1)
            if useRefPointValue:
                refPointData = data.inputValue(self.refPoint)
                refPointValue = refPointData.asFloatVector()
                refPointArray.set(0, refPointValue.x, refPointValue.y,
                                  refPointValue.z, 1)
            else:
                refPointArray.set(0, inPointValue.x, inPointValue.y,
                                  inPointValue.z, 1)

            normalData = data.inputValue(self.normal)
            normalValue = normalData.asFloatVector()
            normalArray = om.MFloatVectorArray(1)
            normalArray.set(normalValue, 0)

            tangentUData = data.inputValue(self.tangentU)
            tangentUValue = tangentUData.asFloatVector()
            tangentUArray = om.MFloatVectorArray(1)
            tangentUArray.set(tangentUValue, 0)

            tangentVData = data.inputValue(self.tangentV)
            tangentVValue = tangentVData.asFloatVector()
            tangentVArray = om.MFloatVectorArray(1)
            tangentVArray.set(tangentVValue, 0)

            useSGData = data.inputValue(self.useSG)
            useSGValue = useSGData.asBool()

            plugArray = om.MPlugArray()
            inColorPlugName = ""
            inSGPlugName = ""
            sampleSource = ""
            isSGNode = False

            sgPlug = om.MPlug(thisNode, self.inSG)
            hasConnections = sgPlug.connectedTo(plugArray, 1, 0)
            if hasConnections:
                inSGPlugName = plugArray[0].name()
                inSGPlugNameSplit = inSGPlugName.split(".")
                sourceNode = om.MObject()
                sourceNode = plugArray[0].node()
                isSGNode = sourceNode.hasFn(om.MFn.kShadingEngine)
                inSGPlugName = inSGPlugNameSplit[0]
            else:
                inSGPlugName = ""

            colorPlug = om.MPlug(thisNode, self.inColor)
            hasConnections = colorPlug.connectedTo(plugArray, 1, 0)
            if hasConnections:
                inColorData = data.inputValue(self.inColor)
                inColorPlugName = plugArray[0].name()

            if useSGValue:
                if isSGNode:
                    sampleSource = inSGPlugName
                elif inSGPlugName == "":
                    print(
                        "\"inSG\" has no connections. Please connect the \"message\" attribute of a shadingGroup to \"inSG\""
                    )
                    #return om.MStatus.kUnknownParameter
                else:
                    print(
                        inSGPlugName +
                        " is not a shading group. Only the \"message\" attribute of a shadingGroup should be connected to \"inSG\""
                    )
                    #return om.MStatus.kUnknownParameter
            else:
                if not inColorPlugName == "":
                    sampleSource = inColorPlugName
                else:
                    print("\"inColor\" has no connections")
                    #return om.MStatus.kUnknownParameter

            cameraMatData = data.inputValue(self.eyeToWorld)
            cameraMat = om.MFloatMatrix()
            cameraMat = cameraMatData.asFloatMatrix()

            resColors = om.MFloatVectorArray(1)
            resTransparencies = om.MFloatVectorArray(1)

            renderUtil = omRender.MRenderUtil
            renderUtil.sampleShadingNetwork(
                sampleSource, 1, shadowsValue, reShadowsValue, cameraMat,
                inPointArray, uArray, vArray, normalArray, refPointArray,
                tangentUArray, tangentVArray, filterSizeArray, resColors,
                resTransparencies)

            outColorRAttr = fnThisNode.attribute("outColorR")
            outColorRPlug = om.MPlug(thisNode, outColorRAttr)
            outColorRHandle = data.outputValue(outColorRPlug)
            outColorRHandle.setFloat(resColors[0].x)
            outColorRHandle.setClean()

            outColorGAttr = fnThisNode.attribute("outColorG")
            outColorGPlug = om.MPlug(thisNode, outColorGAttr)
            outColorGHandle = data.outputValue(outColorGPlug)
            outColorGHandle.setFloat(resColors[0].y)
            outColorGHandle.setClean()

            outColorBAttr = fnThisNode.attribute("outColorB")
            outColorBPlug = om.MPlug(thisNode, outColorBAttr)
            outColorBHandle = data.outputValue(outColorBPlug)
            outColorBHandle.setFloat(resColors[0].z)
            outColorBHandle.setClean()

            data.setClean(plug)

            #return om.MStatus.kSuccess

        else:
            print("something Failed")
Пример #24
0
    def doIt(self, args):
        """
        Print string to the console.
        """
        try:
            argData = om.MArgDatabase(
                self.syntax(),
                args)  # if this fails, it will raise its own exception...
        except:
            print "failed..."
            pass  # ...so we can just pass here
        else:
            print "converting..."
            # get the active selection
            selection = om.MSelectionList()
            om.MGlobal.getActiveSelectionList(selection)
            iterSel = om.MItSelectionList(selection, om.MFn.kMesh)
            if argData.isFlagSet(MP_WriteMeshCmd.kVoxelSizeFlag):
                self.__voxelSize = argData.flagArgumentDouble(
                    MP_WriteMeshCmd.kVoxelSizeFlag, 0)
            if argData.isFlagSet(MP_WriteMeshCmd.kFileNameFlag):
                self.__fileName = argData.flagArgumentString(
                    MP_WriteMeshCmd.kFileNameFlag, 0)
            # go through selection
            while not iterSel.isDone():

                # get dagPath
                dagPath = om.MDagPath()
                iterSel.getDagPath(dagPath)

                # create empty point array
                inMeshMPointArray = om.MPointArray()
                # create empy normal array
                inMeshMNormalArray = om.MFloatVectorArray()
                # create function set and get points and normals in world space
                currentInMeshMFnMesh = om.MFnMesh(dagPath)
                currentInMeshMFnMesh.getPoints(inMeshMPointArray,
                                               om.MSpace.kWorld)
                currentInMeshMFnMesh.getNormals(inMeshMNormalArray,
                                                om.MSpace.kWorld)
                #get the number of faces for the selection
                numFaces = currentInMeshMFnMesh.numPolygons()
                normalList = []
                faceList = []
                #get normals
                for i in range(0, numFaces):
                    normal = om.MVector()
                    currentInMeshMFnMesh.getPolygonNormal(
                        i, normal, om.MFn.kMesh)
                    normal = normal.normal()
                    normalList.append(
                        [str(normal[0]),
                         str(normal[1]),
                         str(normal[2])])

                #get faces
                for i in range(0, numFaces):
                    vertexL = om.MIntArray()
                    currentInMeshMFnMesh.getPolygonVertices(i, vertexL)
                    vertices = []
                    for n in range(vertexL.length()):
                        vertices.append(str(vertexL[n] + 1))
                        faceList.append(vertices)
                        # put each point to a list
                pointList = []
                for i in range(inMeshMPointArray.length()):
                    pointList.append([
                        str(inMeshMPointArray[i][0]),
                        str(inMeshMPointArray[i][1]),
                        str(inMeshMPointArray[i][2])
                    ])
                # return the vertices, normals and faces
                omesh_cube = vdbout.VDBOutputMesh()
                meshspec = mepo.MeshSpec()
                meshspec.voxelSize = self.__voxelSize
                omesh_cube.loadMesh(mepo.getPythonList(pointList),
                                    mepo.getPythonList(normalList),
                                    mepo.getPythonList(faceList), meshspec)
                omesh_cube.writeMesh(str(self.__fileName))
                print("Wrote mesh %s" % self.__fileName)

                return [pointList, normalList, faceList]
Пример #25
0
    def _getMeshData(self):
        maya.cmds.select(self.maya_node)
        selList = OpenMaya.MSelectionList()
        OpenMaya.MGlobal.getActiveSelectionList(selList)
        meshPath = OpenMaya.MDagPath()
        selList.getDagPath(0, meshPath)
        meshIt = OpenMaya.MItMeshPolygon(meshPath)
        meshFn = OpenMaya.MFnMesh(meshPath)
        dagFn = OpenMaya.MFnDagNode(meshPath)
        boundingBox = dagFn.boundingBox()
        do_color = False
        if meshFn.numColorSets():
            do_color = True
        indices = []
        positions = [None] * meshFn.numVertices()
        normals = [None] * meshFn.numVertices()
        colors = [None] * meshFn.numVertices()
        uvs = [None] * meshFn.numVertices()
        ids = OpenMaya.MIntArray()
        points = OpenMaya.MPointArray()
        if do_color:
            vertexColorList = OpenMaya.MColorArray()
            meshFn.getFaceVertexColors(vertexColorList)
        normal = OpenMaya.MVector()
        face_verts = OpenMaya.MIntArray()
        polyNormals = OpenMaya.MFloatVectorArray()
        meshFn.getNormals(polyNormals)
        uv_util = OpenMaya.MScriptUtil()
        uv_util.createFromList([0, 0], 2)
        uv_ptr = uv_util.asFloat2Ptr()
        while not meshIt.isDone():
            meshIt.getTriangles(points, ids)
            meshIt.getVertices(face_verts)
            face_vertices = list(face_verts)
            for point, vertex_index in zip(points, ids):
                indices.append(vertex_index)
                pos = (point.x, point.y, point.z)
                face_vert_id = face_vertices.index(vertex_index)
                norm_id = meshIt.normalIndex(face_vert_id)
                norm = polyNormals[norm_id]
                norm = (norm.x, norm.y, norm.z)
                meshIt.getUV(face_vert_id, uv_ptr, meshFn.currentUVSetName())
                u = uv_util.getFloat2ArrayItem(uv_ptr, 0, 0)
                v = uv_util.getFloat2ArrayItem(uv_ptr, 0, 1)
                # flip V for openGL
                # This fails if the the UV is exactly on the border (e.g. (0.5,1))
                # but we really don't know what udim it's in for that case.
                if ExportSettings.vflip:
                    v = int(v) + (1 - (v % 1))
                uv = (u, v)
                if not positions[vertex_index]:
                    positions[vertex_index] = pos
                    normals[vertex_index] = norm
                    uvs[vertex_index] = uv
                elif not (positions[vertex_index] == pos
                          and normals[vertex_index] == norm
                          and uvs[vertex_index] == uv):
                    positions.append(pos)
                    normals.append(norm)
                    uvs.append(uv)
                    indices[-1] = len(positions) - 1

                if do_color:
                    color = vertexColorList[vertex_index]
                    colors[vertex_index] = (color.r, color.g, color.b)
            meshIt.next()

        if not len(Buffer.instances):
            primary_buffer = Buffer('primary_buffer')
        else:
            primary_buffer = Buffer.instances[0]

        if len(positions) >= 0xffff:
            idx_component_type = ComponentTypes.UINT
        else:
            idx_component_type = ComponentTypes.USHORT
        self.indices_accessor = Accessor(indices,
                                         "SCALAR",
                                         idx_component_type,
                                         34963,
                                         primary_buffer,
                                         name=self.name + '_idx')
        self.indices_accessor.min_ = [0]
        self.indices_accessor.max_ = [len(positions) - 1]
        self.position_accessor = Accessor(positions,
                                          "VEC3",
                                          ComponentTypes.FLOAT,
                                          34962,
                                          primary_buffer,
                                          name=self.name + '_pos')
        self.position_accessor.max_ = list(boundingBox.max())[:3]
        self.position_accessor.min_ = list(boundingBox.min())[:3]
        self.normal_accessor = Accessor(normals,
                                        "VEC3",
                                        ComponentTypes.FLOAT,
                                        34962,
                                        primary_buffer,
                                        name=self.name + '_norm')
        self.texcoord0_accessor = Accessor(uvs,
                                           "VEC2",
                                           ComponentTypes.FLOAT,
                                           34962,
                                           primary_buffer,
                                           name=self.name + '_uv')
def sampleColorAtParticle(textureNode, particleShapeNode):

    # get the particle object as an MObject

    selectionList = om.MSelectionList()
    selectionList.add(particleShapeNode)
    particleObject = om.MObject()
    selectionList.getDependNode(0, particleObject)

    # create a MFnParticle to get to the data

    particleDataFn = omFX.MFnParticleSystem(particleObject)

    # get the positionPP data

    posPPArray = om.MVectorArray()

    particleDataFn.getPerParticleAttribute("position", posPPArray)

    # these are the arguments required to sample a 3d texture:
    shadingNodeName = textureNode

    numSamples = posPPArray.length()
    pointArray = om.MFloatPointArray()
    pointArray.setLength(numSamples)

    refPoints = om.MFloatPointArray()
    refPoints.setLength(numSamples)

    for i in range(posPPArray.length()):
        particlePosVector = om.MVector()
        particlePosVector = posPPArray[i]
        location = om.MFloatPoint(
            particlePosVector[0], particlePosVector[1], particlePosVector[2])

        pointArray.set(location, i)
        refPoints.set(location, i)

    # but we don't need these
    useShadowMap = False
    reuseMaps = False
    cameraMatrix = om.MFloatMatrix()
    uCoords = None
    vCoords = None
    normals = None
    tangentUs = None
    tangentVs = None
    filterSizes = None

    # and the return arguments are empty....
    resultColors = om.MFloatVectorArray()
    resultTransparencies = om.MFloatVectorArray()

    # this is the command wot samples

    omr.MRenderUtil.sampleShadingNetwork(shadingNodeName, numSamples, useShadowMap, reuseMaps, cameraMatrix, pointArray,
                                         uCoords, vCoords, normals, refPoints, tangentUs, tangentVs, filterSizes, resultColors, resultTransparencies)

    # use the sampled colours to set rgbPP
    resultPPColors = om.MVectorArray()
    resultPPColors.clear()

    for i in range(resultColors.length()):
        floatVector = om.MFloatVector(resultColors[i])
        vector = om.MVector(floatVector)
        resultPPColors.append(vector)

    particleDataFn.setPerParticleAttribute("rgbPP", resultPPColors)
Пример #27
0
def ExportMesh(filepath, meshShapedagPath):
    meshFn = OpenMaya.MFnMesh(meshShapedagPath)
    meshIntersector = OpenMaya.MMeshIntersector()
    meshIntersector.create(meshShapedagPath.node())

    faceIdList = []
    baryCoordList = []

    points = OpenMaya.MPointArray()
    meshFn.getPoints(points, OpenMaya.MSpace.kWorld)

    normals = OpenMaya.MFloatVectorArray()
    meshFn.getVertexNormals(False, normals, OpenMaya.MSpace.kWorld)

    triangleCounts = OpenMaya.MIntArray()
    triangleVertexIndices = OpenMaya.MIntArray(
    )  # the size of this array is three times of the number of total triangles
    meshFn.getTriangles(triangleCounts, triangleVertexIndices)

    #-------------------------
    # Get skin cluster object
    #-------------------------
    skinClusterName = ''
    mesh_shape_name = meshFn.name()
    skinClusters = cmds.listHistory(mesh_shape_name)
    skinClusters = cmds.ls(skinClusters, type="skinCluster")
    if skinClusters:
        skinClusterName = skinClusters[0]
    else:
        cmds.warning('No skin cluster found on ' + mesh_shape_name)
        return

    #print skinClusterName

    # get the MFnSkinCluster using skinClusterName
    selList = OpenMaya.MSelectionList()
    selList.add(skinClusterName)
    skinClusterNode = OpenMaya.MObject()
    selList.getDependNode(0, skinClusterNode)
    skinFn = OpenMayaAnim.MFnSkinCluster(skinClusterNode)

    dagPaths = MDagPathArray()
    skinFn.influenceObjects(dagPaths)

    # influence object is a joint
    influenceObjectsNames = []

    # get joint names
    for i in range(dagPaths.length()):
        influenceName = dagPaths[i].partialPathName()
        influenceObjectsNames.append(
            influenceName)  # Need to remove namespace?

    skinMeshes = cmds.skinCluster(skinClusterName, query=1, geometry=1)
    geoIter = OpenMaya.MItGeometry(meshShapedagPath)
    infCount = OpenMaya.MScriptUtil()
    infCountPtr = infCount.asUintPtr()
    numVertices = geoIter.count()

    weightArray = [
        0
    ] * TRESSFX_MAX_INFLUENTIAL_BONE_COUNT * numVertices  # joint weight array for all vertices. Each vertex will have TRESSFX_MAX_INFLUENTIAL_BONE_COUNT  weights.
    # It is initialized with zero for empty weight in case there are less weights than TRESSFX_MAX_INFLUENTIAL_BONE_COUNT .
    jointIndexArray = [
        -1
    ] * TRESSFX_MAX_INFLUENTIAL_BONE_COUNT * numVertices  # joint index array for all vertices. It is initialized with -1 for an empty element in case
    # there are less weights than TRESSFX_MAX_INFLUENTIAL_BONE_COUNT .

    # collect bone weights for all vertices in the mesh
    index = 0

    progressBar = ProgressBar('Collect data', numVertices)

    while geoIter.isDone() == False:
        weights = OpenMaya.MDoubleArray()
        skinFn.getWeights(meshShapedagPath, geoIter.currentItem(), weights,
                          infCountPtr)

        weightJointIndexPairs = []

        for i in range(len(weights)):
            pair = WeightJointIndexPair()
            pair.weight = weights[i]
            pair.joint_index = i
            weightJointIndexPairs.append(pair)

        weightJointIndexPairs.sort()

        a = 0

        for j in range(
                min(len(weightJointIndexPairs),
                    TRESSFX_MAX_INFLUENTIAL_BONE_COUNT)):
            weightArray[index * TRESSFX_MAX_INFLUENTIAL_BONE_COUNT +
                        a] = weightJointIndexPairs[j].weight
            jointIndexArray[index * TRESSFX_MAX_INFLUENTIAL_BONE_COUNT +
                            a] = weightJointIndexPairs[j].joint_index
            a += 1

        index += 1
        progressBar.Increment()
        geoIter.next()

    progressBar.Kill()

    #----------------------------------------------------------
    # We collected all necessary data. Now save them in file.
    #----------------------------------------------------------
    totalProgress = points.length() + triangleVertexIndices.length() / 3 + len(
        influenceObjectsNames)
    progressBar = ProgressBar('Export collision mesh', totalProgress)

    f = open(filepath, "w")
    f.write("# TressFX collision mesh exported by TressFX Exporter in Maya\n")

    # Write all bone (joint) names
    f.write("numOfBones %g\n" % (len(influenceObjectsNames)))
    f.write("# bone index, bone name\n")
    for i in range(len(influenceObjectsNames)):
        f.write("%d %s\n" % (i, influenceObjectsNames[i]))
        progressBar.Increment()

    # write vertex positions and skinning data
    f.write("numOfVertices %g\n" % (points.length()))
    f.write(
        "# vertex index, vertex position x, y, z, normal x, y, z, joint index 0, joint index 1, joint index 2, joint index 3, weight 0, weight 1, weight 2, weight 3\n"
    )
    for vertexIndex in xrange(points.length()):
        point = points[vertexIndex]
        normal = normals[vertexIndex]
        weightJointIndexPairs = GetSortedWeightsFromOneVertex(
            TRESSFX_MAX_INFLUENTIAL_BONE_COUNT, vertexIndex, jointIndexArray,
            weightArray)
        f.write(
            "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n" %
            (vertexIndex, point.x, point.y, point.z, normal.x, normal.y,
             normal.z, weightJointIndexPairs[0].joint_index,
             weightJointIndexPairs[1].joint_index,
             weightJointIndexPairs[2].joint_index,
             weightJointIndexPairs[3].joint_index,
             weightJointIndexPairs[0].weight, weightJointIndexPairs[1].weight,
             weightJointIndexPairs[2].weight, weightJointIndexPairs[3].weight))
        progressBar.Increment()

    # write triangle face indices
    f.write("numOfTriangles %g\n" % (triangleVertexIndices.length() / 3))
    f.write(
        "# triangle index, vertex index 0, vertex index 1, vertex index 2\n")
    for i in range(triangleVertexIndices.length() / 3):
        f.write("%g %d %d %d\n" % (i, triangleVertexIndices[i * 3 + 0],
                                   triangleVertexIndices[i * 3 + 1],
                                   triangleVertexIndices[i * 3 + 2]))
        progressBar.Increment()

    f.close()
    progressBar.Kill()
    return
Пример #28
0
    def deform(self, dataBlock, geoIterator, local2WorldMatrix, geomIndex):

        inputAttr = ompx.cvar.MPxGeometryFilter_input

        # Envelope
        envelope = ompx.cvar.MPxGeometryFilter_envelope
        dataHandleEnvolope = dataBlock.inputValue(envelope)
        envelopeValue = dataHandleEnvolope.asFloat()

        # damping
        dataHandleDamping = dataBlock.inputValue(JiggleDeformerNode.dampingVal)
        dampMagnitude = dataHandleDamping.asFloat()

        # stiffness
        dataHandleStiff = dataBlock.inputValue(JiggleDeformerNode.stiffVal)
        stiffMagnitude = dataHandleStiff.asFloat()

        # time
        dataHandleTime = dataBlock.inputValue(JiggleDeformerNode.time)
        currentTime = dataHandleTime.asTime()

        # scale
        dataHandleScale = dataBlock.inputValue(JiggleDeformerNode.scale)
        scale = dataHandleScale.asFloat()

        # max velocity
        dataHandleVelocity = dataBlock.inputValue(
            JiggleDeformerNode.maxVelocity)
        maxVelocity = dataHandleVelocity.asFloat() * scale

        # direction bias
        dataHandleDirection = dataBlock.inputValue(
            JiggleDeformerNode.directionBias)
        directionBias = dataHandleDirection.asFloat()

        # normal strength
        dataHandleNormalStrength = dataBlock.inputValue(
            JiggleDeformerNode.normalStrength)
        normalStrength = dataHandleNormalStrength.asFloat()

        # start frame
        dataHandleStartFrame = dataBlock.inputValue(
            JiggleDeformerNode.startFrame)
        startFrame = dataHandleStartFrame.asInt()

        # points' positions in local space
        points = om.MPointArray()
        geoIterator.allPositions(points)

        # INITIALIZE ATTRIBUTES
        if geomIndex not in self.initialFlagDict.keys():
            self.initialFlagDict[geomIndex] = False

        if geomIndex not in self.dirtyMapDict.keys():
            self.dirtyMapDict[geomIndex] = False

        if geomIndex not in self.preTimeDict.keys():
            self.preTimeDict[geomIndex] = om.MTime()

        if geomIndex not in self.curPosDict.keys():
            self.curPosDict[geomIndex] = om.MPointArray()

        if geomIndex not in self.prePosDict.keys():
            self.prePosDict[geomIndex] = om.MPointArray()

        if geomIndex not in self.membershipDict.keys():
            self.membershipDict[geomIndex] = om.MIntArray()

        # Get normalsDict
        normals = om.MFloatVectorArray()
        if directionBias != 0.0 or normalStrength < 1.0:

            inputMesh = self.getInputMesh(dataBlock, geomIndex, inputAttr)

            MFnMesh = om.MFnMesh(inputMesh)

            MFnMesh.getVertexNormals(0, normals)

        # test initialize flag for the first time
        if not self.initialFlagDict[geomIndex]:
            self.preTimeDict[geomIndex] = currentTime

            self.curPosDict[geomIndex].setLength(geoIterator.count())
            self.prePosDict[geomIndex].setLength(geoIterator.count())

            for i in range(points.length()):
                self.curPosDict[geomIndex].set(points[i] * local2WorldMatrix,
                                               i)
                self.prePosDict[geomIndex].set(self.curPosDict[geomIndex][i],
                                               i)

            self.initialFlagDict[geomIndex] = True

            self.dirtyMapDict[geomIndex] = True

        # for stable simulation, check the time difference whether it is 1 frame or not
        # If the current time smaller than the startFrame, jiggling effect will not be performed
        timeDiff = currentTime.value() - self.preTimeDict[geomIndex].value()

        if timeDiff > 1.0 or timeDiff < 0.0 or currentTime.value(
        ) <= startFrame:
            self.initialFlagDict[geomIndex] = False
            self.preTimeDict[geomIndex] = om.MTime(currentTime)
            return

        # perGeometry
        hGeo = dataBlock.inputArrayValue(JiggleDeformerNode.perGeo)

        # jump to each geometry
        self.jump2Element(hGeo, geomIndex)
        hGeo.jumpToElement(geomIndex)

        hPerGeo = hGeo.inputValue()

        # get the different map handle in component attribute
        hJiggleMap = om.MArrayDataHandle(
            hPerGeo.child(JiggleDeformerNode.jiggleMap))
        hStiffMap = om.MArrayDataHandle(
            hPerGeo.child(JiggleDeformerNode.stiffMap))
        hDampMap = om.MArrayDataHandle(
            hPerGeo.child(JiggleDeformerNode.dampMap))

        matrix = hPerGeo.child(JiggleDeformerNode.worldMatrix).asMatrix()

        if geomIndex not in self.weightMapDict.keys():
            self.weightMapDict[geomIndex] = om.MFloatArray()
            # self.weightMapDict[geomIndex].setLength(geoIterator.count())

        if geomIndex not in self.jiggleMapDict.keys():
            self.jiggleMapDict[geomIndex] = om.MFloatArray()
            # self.jiggleMapDict[geomIndex].setLength(geoIterator.count())

        if geomIndex not in self.stiffMapDict.keys():
            self.stiffMapDict[geomIndex] = om.MFloatArray()
            # self.stiffMapDict[geomIndex].setLength(geoIterator.count())

        if geomIndex not in self.dampMapDict.keys():
            self.dampMapDict[geomIndex] = om.MFloatArray()
            # self.dampMapDict[geomIndex].setLength(geoIterator.count())

        if self.dirtyMapDict[geomIndex] or geoIterator.count(
        ) != self.membershipDict[geomIndex].length():
            self.weightMapDict[geomIndex].setLength(geoIterator.count())
            self.jiggleMapDict[geomIndex].setLength(geoIterator.count())
            self.stiffMapDict[geomIndex].setLength(geoIterator.count())
            self.dampMapDict[geomIndex].setLength(geoIterator.count())
            self.membershipDict[geomIndex].setLength(geoIterator.count())

            # loop through the geoIterator.count() (i.e. mesh geometry) for getting the jiggleMap Value.
            ii = 0
            geoIterator.reset()
            while not geoIterator.isDone():
                index = geoIterator.index()

                # JIGGLE MAP
                self.jump2Element(hJiggleMap, index)
                hJiggleMap.jumpToElement(index)
                self.jiggleMapDict[geomIndex].set(
                    hJiggleMap.inputValue().asFloat(), ii)

                # STIFF MAP
                self.jump2Element(hStiffMap, index)
                hStiffMap.jumpToElement(index)
                self.stiffMapDict[geomIndex].set(
                    hStiffMap.inputValue().asFloat(), ii)

                # DAMP MAP
                self.jump2Element(hDampMap, index)
                hDampMap.jumpToElement(index)
                self.dampMapDict[geomIndex].set(
                    hDampMap.inputValue().asFloat(), ii)

                # WEIGHT MAP
                self.weightMapDict[geomIndex].set(
                    self.weightValue(dataBlock, geomIndex,
                                     geoIterator.index()), ii)

                # MEMBERSHIP
                self.membershipDict[geomIndex].set(geoIterator.index(), ii)

                ii += 1
                geoIterator.next()

            self.dirtyMapDict[geomIndex] = False

        #######################
        # CALCULATE POSITIONS #
        #######################

        i = 0
        geoIterator.reset()
        while not geoIterator.isDone():
            goal = points[i] * local2WorldMatrix

            damping = dampMagnitude * self.dampMapDict[geomIndex][i]
            stiff = stiffMagnitude * self.stiffMapDict[geomIndex][i]

            # velocity
            velocity = (self.curPosDict[geomIndex][i] -
                        self.prePosDict[geomIndex][i]) * (1.0 - damping)
            newPos = self.curPosDict[geomIndex][i] + velocity

            goalForce = (goal - newPos) * stiff

            newPos = newPos + goalForce

            # clamp to the MAX velocity
            displacement = newPos - goal
            if displacement.length() > maxVelocity:
                displacement = displacement.normal() * maxVelocity
                newPos = goal + displacement

            # normal strength
            if normalStrength < 1.0:
                normalDot = displacement * om.MVector(
                    normals[self.membershipDict[geomIndex][i]])
                newPos -= om.MVector(
                    normals[self.membershipDict[geomIndex][i]]) * normalDot * (
                        1.0 - normalStrength)

            # direction bias
            membership = self.membershipDict[geomIndex][i]

            # displacement = om.MFloatVector(displacement)
            if directionBias > 0.0:
                normalDot = displacement.normal() * om.MVector(
                    normals[membership])

                if normalDot < 0.0:
                    RESULT = displacement * (
                        (displacement * om.MVector(normals[membership])) *
                        directionBias)
                    newPos = newPos + RESULT

            elif directionBias < 0.0:
                normalDot = displacement.normal() * om.MVector(
                    normals[membership])

                if normalDot > 0.0:
                    RESULT = displacement * (
                        (displacement * om.MVector(normals[membership])) *
                        directionBias)
                    newPos = newPos + RESULT

            # store for next time computing
            self.prePosDict[geomIndex].set(self.curPosDict[geomIndex][i], i)
            self.curPosDict[geomIndex].set(newPos, i)

            # multi with weight map and envelope
            newPosLoc = newPos * local2WorldMatrix.inverse()
            jiggle = self.jiggleMapDict[geomIndex][i]
            weight = self.weightMapDict[geomIndex][i]

            points.set(
                (points[i] +
                 (newPosLoc - points[i]) * weight * envelopeValue * jiggle), i)

            self.preTimeDict[geomIndex] = om.MTime(currentTime)

            i = i + 1
            geoIterator.next()

        # set positions
        geoIterator.setAllPositions(points)
Пример #29
0
    def deform(self, block, geoIterator, matrix, geometryIndex):
        # Configure mesh and get all inputs attributes
        kInput = omp.cvar.MPxGeometryFilter_input
        inputArray_dh = block.outputArrayValue(kInput)
        inputArray_dh.jumpToElement(geometryIndex)
        inputElement_dh = inputArray_dh.outputValue()

        kInputGeom = omp.cvar.MPxGeometryFilter_inputGeom
        inputGeom_dh = inputElement_dh.child(kInputGeom)
        inMesh = inputGeom_dh.asMesh()

        kEnvelope = omp.cvar.MPxGeometryFilter_envelope
        dataHandleEnvelope = block.inputValue(kEnvelope)
        envelope_value = dataHandleEnvelope.asFloat()

        # Getting custom inputs attributes data handles
        try:
            inputMatrix_dh = block.inputValue(noiseDeformer.inputMatrix)
        except ImportError:
            sys.stderr.write("Failed to get MDataHandle")

        # Getting values of custom inputs attributes through data handles
        inputMatrix_value = inputMatrix_dh.asMatrix()

        # Getting translation of input transform matrix
        mTransMatrix = om.MTransformationMatrix(inputMatrix_value)
        inputMatrixTranslation_value = mTransMatrix.getTranslation(
            om.MSpace.kObject)

        # Get mesh normals
        mFloatVectorArray_normal = om.MFloatVectorArray()
        mFnMesh = om.MFnMesh(inMesh)
        mFnMesh.getVertexNormals(False, mFloatVectorArray_normal,
                                 om.MSpace.kObject)

        # Temporal array to save all vertices modified
        mPointArray_meshVertex = om.MPointArray()

        # Iterate around all vertices
        while (not geoIterator.isDone()):
            pointPosition = geoIterator.position()

            # Get the painted weights of the mesh
            weight = self.weightValue(block, geometryIndex,
                                      geoIterator.index())

            # Create a new vertex position
            pointPosition.x = pointPosition.x + (
                inputMatrixTranslation_value[0] *
                mFloatVectorArray_normal[geoIterator.index()].x *
                envelope_value * weight)
            pointPosition.y = pointPosition.y + (
                inputMatrixTranslation_value[1] *
                mFloatVectorArray_normal[geoIterator.index()].y *
                envelope_value * weight)
            pointPosition.z = pointPosition.z + (
                inputMatrixTranslation_value[2] *
                mFloatVectorArray_normal[geoIterator.index()].z *
                envelope_value * weight)

            # Save the new position in the temporal array
            mPointArray_meshVertex.append(pointPosition)
            geoIterator.next()

        # When the iterator finish, we replace its vertices values with the
        # temporal array
        geoIterator.setAllPositions(mPointArray_meshVertex)
Пример #30
0
    def deform(self, block, iter, mat, multiIndex):
        # ###################################
        # get attributes
        # ###################################
        # envelope
        envelope = block.inputValue(
            OpenMayaMPx.cvar.MPxDeformerNode_envelope).asFloat()
        if (envelope == 0.0):
            return

        # ==================================
        # aOrigMesh
        oOrig = block.inputValue(self.aOrigMesh).asMesh()
        if oOrig.isNull():
            return
        fnOrig = om.MFnMesh(oOrig)

        # ==================================
        # input[multiIndex].inputGeometry
        hInput = block.outputArrayValue(self.input)
        hInput.jumpToElement(multiIndex)
        hInputGeom = hInput.outputValue().child(self.inputGeom)
        oInputGeom = hInputGeom.asMesh()
        fnCurrent = om.MFnMesh(oInputGeom)

        # ==================================
        # aDisplayColors
        displayColors = block.inputValue(self.aDisplayColors).asBool()
        if (displayColors):
            colorBase = block.inputValue(self.aColorBase).asFloatVector()
            colorStretch = block.inputValue(self.aColorStretch).asFloatVector()
            colorSquash = block.inputValue(self.aColorSquash).asFloatVector()

        # ==================================
        # aMeasureTypeHeat
        measureTypeHeat = block.inputValue(self.aMeasureTypeHeat).asShort()

        # aMultiplyHeat aSquashMultiplyHeat aStretchMultiplyHeat
        multHeat = block.inputValue(self.aMultiplyHeat).asFloat()
        squashMultHeat = block.inputValue(self.aSquashMultiplyHeat).asFloat()
        stretchMultHeat = block.inputValue(self.aStretchMultiplyHeat).asFloat()
        if (multHeat == 0.0
                or squashMultHeat == 0.0 and stretchMultHeat == 0.0):
            return

        # aMaxHeat aSquashMaxHeat aStretchMaxHeat
        maxHeat = block.inputValue(self.aMaxHeat).asBool()
        squashMaxHeat = block.inputValue(self.aSquashMaxHeat).asFloat() * -1
        stretchMaxHeat = block.inputValue(self.aStretchMaxHeat).asFloat()
        if (squashMaxHeat == 0.0 and stretchMaxHeat == 0.0):
            return

        # aGrowHeat aSquashGrowHeat aStretchGrowHeat
        growHeat = block.inputValue(self.aGrowHeat).asInt()
        squashGrowHeat = block.inputValue(self.aSquashGrowHeat).asInt()
        stretchGrowHeat = block.inputValue(self.aStretchGrowHeat).asInt()

        # aIterationsSmoothHeat
        iterationsSmoothHeat = block.inputValue(
            self.aIterationsSmoothHeat).asInt()

        # aStrengthSmoothHeat
        strengthSmoothHeat = block.inputValue(
            self.aStrengthSmoothHeat).asFloat()

        # ==================================
        # aDeformationType
        deformationType = block.inputValue(self.aDeformationType).asShort()
        if (deformationType == 0):
            return

        # aIterationsSmoothDeformation
        iterationsSmoothDeformation = block.inputValue(
            self.aIterationsSmoothDeformation).asInt()

        # aStrengthSmoothDeformation
        strengthSmoothDeformation = block.inputValue(
            self.aStrengthSmoothDeformation).asFloat()

        # aTangentSpace
        tangentSpace = False
        if (deformationType == 2):
            tangentSpace = block.inputValue(self.aTangentSpace).asShort()

        # ==================================
        # aStretchMesh aSquashMesh
        if (deformationType == 2):
            # aStretchMesh
            oStretch = block.inputValue(self.aStretchMesh).asMesh()
            if oStretch.isNull():
                return
            fnStretch = om.MFnMesh(oStretch)
            stretchPoints = om.MPointArray()
            fnStretch.getPoints(stretchPoints)
            # aSquashMesh
            oSquash = block.inputValue(self.aSquashMesh).asMesh()
            if oSquash.isNull():
                return
            fnSquash = om.MFnMesh(oSquash)
            squashPoints = om.MPointArray()
            fnSquash.getPoints(squashPoints)
            # orig points
            origPoints = om.MPointArray()
            fnOrig.getPoints(origPoints)

        # ###################################
        # Gather information TODO: STORE in node (refresh button)
        # ###################################
        d_util = om.MScriptUtil()
        doublePtr = d_util.asDoublePtr()
        # orig edge lengths
        itEdgeOrig = om.MItMeshEdge(oOrig)
        edgeLengthsOrig = []
        lengthSum = 0.0
        while not itEdgeOrig.isDone():
            itEdgeOrig.getLength(doublePtr)
            eachLength = d_util.getDouble(doublePtr)
            lengthSum += eachLength
            edgeLengthsOrig.append(eachLength)
            itEdgeOrig.next()
        edgeLengthAvrg = lengthSum / itEdgeOrig.count()
        # orig face area
        itPolyOrig = om.MItMeshPolygon(oOrig)
        polyAreasOrig = []
        while not itPolyOrig.isDone():
            itPolyOrig.getArea(doublePtr)
            eachArea = d_util.getDouble(doublePtr)
            polyAreasOrig.append(eachArea)
            itPolyOrig.next()
        # connected edges and vertices (and faces)
        connectedEdges = []
        connectedPoints = []
        connectedFaces = []
        itPointCurrent = om.MItMeshVertex(oOrig)
        iaConnectedObjects = om.MIntArray()
        while not itPointCurrent.isDone():
            # edges
            itPointCurrent.getConnectedEdges(iaConnectedObjects)
            connectedEdges.append(list(iaConnectedObjects))
            # vertices
            itPointCurrent.getConnectedVertices(iaConnectedObjects)
            connectedPoints.append(list(iaConnectedObjects))
            # faces
            itPointCurrent.getConnectedFaces(iaConnectedObjects)
            connectedFaces.append(list(iaConnectedObjects))
            # finish
            itPointCurrent.next()

        # ###################################
        # Gather information per call
        # ###################################
        d_util = om.MScriptUtil()
        doublePtr = d_util.asDoublePtr()
        # current polygon area
        if (measureTypeHeat == 0):
            itPolyCurrent = om.MItMeshPolygon(oInputGeom)
            polyAreasCurrent = []
            while not itPolyCurrent.isDone():
                itPolyCurrent.getArea(doublePtr)
                eachArea = d_util.getDouble(doublePtr)
                polyAreasCurrent.append(eachArea)
                itPolyCurrent.next()
        # current edge length
        elif (measureTypeHeat == 1):
            edgeLengthsCurrent = []
            itEdgeCurrent = om.MItMeshEdge(oInputGeom)
            while not itEdgeCurrent.isDone():
                itEdgeCurrent.getLength(doublePtr)
                edgeLengthsCurrent.append(d_util.getDouble(doublePtr))
                itEdgeCurrent.next()
        # current normals
        if (deformationType == 1):
            currentNormals = om.MFloatVectorArray()
            fnCurrent.getVertexNormals(False, currentNormals,
                                       om.MSpace.kObject)
        # find relevant points
        paPoints = om.MPointArray()
        ptIndices = []
        ptWeights = []
        while not iter.isDone():
            iterIndex = iter.index()
            pt = iter.position()
            # get painted weight
            wPt = self.weightValue(block, multiIndex, iterIndex)
            if (wPt == 0.0):
                iter.next()
                continue
            # only store points with weights
            paPoints.append(pt)
            ptIndices.append(iterIndex)
            ptWeights.append(wPt)
            iter.next()
        iter.reset()

        # ###################################
        # Heat Calculation
        # ###################################
        # input: relevant points, default lengths, current lengths, edgeLengthAvrg
        # output: arHeat
        #
        # eachHeat =-1.0 // origLength*0 // squashed
        # eachHeat = 0.0 // origLength*1 // default
        # eachHeat = 1.0 // origLength*2 // stretched
        arHeat = []
        for x, eachId in enumerate(ptIndices):
            # measure difference between orig and current
            currentMeasure = 0.0
            origMeasure = 0.0
            # faces
            if (measureTypeHeat == 0):
                for eachFace in connectedFaces[eachId]:
                    currentMeasure += polyAreasCurrent[eachFace]
                    origMeasure += polyAreasOrig[eachFace]
                eachHeat = ((currentMeasure - origMeasure) / origMeasure)
            # edges
            elif (measureTypeHeat == 1):
                for eachEdge in connectedEdges[eachId]:
                    currentMeasure += edgeLengthsCurrent[eachEdge]
                    origMeasure += edgeLengthsOrig[eachEdge]
                # to have similar behavior as face area multiply
                eachHeat = ((currentMeasure - origMeasure) / origMeasure) * 2
            #

            # stretch and squash specific modification
            if (eachHeat < 0.0):
                eachHeat *= squashMultHeat * multHeat
                if (eachHeat < squashMaxHeat and maxHeat):
                    eachHeat = squashMaxHeat
            elif (eachHeat > 0.0):
                eachHeat *= stretchMultHeat * multHeat
                if (eachHeat > stretchMaxHeat and maxHeat):
                    eachHeat = stretchMaxHeat
            # store
            arHeat.append(eachHeat)

        # ###################################
        # Heat Grow
        # ###################################
        squashGrowHeat += growHeat
        stretchGrowHeat += growHeat
        if (squashGrowHeat or stretchGrowHeat):
            # find iteration count
            growIterations = squashGrowHeat
            if (stretchGrowHeat > growIterations):
                growIterations = stretchGrowHeat

            for y in range(growIterations):
                arHeatNew = list(arHeat)
                # loop through effected points
                for x, eachId in enumerate(ptIndices):
                    strongestSquash = arHeatNew[x]
                    strongestStretch = arHeatNew[x]
                    # loop over neighbors
                    for eachNeighborId in connectedPoints[eachId]:
                        if (eachNeighborId in ptIndices):
                            eachNeighborHeat = arHeat[ptIndices.index(
                                eachNeighborId)]
                            if (eachNeighborHeat < strongestSquash):
                                strongestSquash = eachNeighborHeat
                            if (eachNeighborHeat > strongestStretch):
                                strongestStretch = eachNeighborHeat
                    # set proper value
                    if (squashGrowHeat > y and stretchGrowHeat > y):
                        newValue = 0.0
                        if (strongestSquash < 0.0):
                            newValue = strongestSquash
                        if (strongestStretch > 0.0):
                            newValue += strongestStretch
                        if (newValue):
                            arHeatNew[x] = newValue
                    elif (squashGrowHeat > y and strongestSquash < 0.0):
                        if (arHeatNew[x] > 0.0):
                            arHeatNew[x] += strongestSquash
                        else:
                            arHeatNew[x] = strongestSquash
                    elif (stretchGrowHeat > y and strongestStretch > 0.0):
                        if (arHeatNew[x] < 0.0):
                            arHeatNew[x] += strongestStretch
                        else:
                            arHeatNew[x] = strongestStretch
                arHeat = arHeatNew
            #

        # ###################################
        # Heat Smooth
        # ###################################
        # input: arHeat
        # output: arHeat
        for y in range(iterationsSmoothHeat):
            arHeatNew = list(arHeat)
            for x, eachId in enumerate(ptIndices):
                neighborIds = connectedPoints[eachId]
                neighborAvrg = 0.0
                validNeighbor = False
                for eachNeighborId in neighborIds:
                    if (eachNeighborId in ptIndices):
                        validNeighbor = True
                        neighborAvrg += arHeat[ptIndices.index(eachNeighborId)]
                if (validNeighbor):
                    neighborAvrg /= len(neighborIds)
                    arHeatNew[x] = arHeatNew[x] * (
                        1.0 -
                        strengthSmoothHeat) + neighborAvrg * strengthSmoothHeat
            arHeat = arHeatNew

        # ###################################
        # Heat Display
        # ###################################
        # input: arHeat
        # result: vertexColors
        if (displayColors):
            colorList = om.MColorArray()
            indexList = om.MIntArray()
            for x, eachId in enumerate(ptIndices):
                # colorBase colorStretch colorSquash
                eachColor = om.MFloatVector(colorBase)
                if (arHeat[x] > 0.0):
                    eachColor += (colorStretch - eachColor) * (arHeat[x])
                elif (arHeat[x] < 0.0):
                    eachColor += (colorSquash - eachColor) * (arHeat[x] * -1)
                colorList.append(
                    om.MColor(eachColor.x, eachColor.y, eachColor.z, 1.0))
                indexList.append(eachId)
                #fnCurrent.setVertexColor( om.MColor(eachColor.x, eachColor.y, eachColor.z), eachId )# (setting all at once is faster)
            fnCurrent.setVertexColors(colorList, indexList)

        # ###################################
        # Deformation Calculation
        # ###################################
        # input: heatArray
        # output: motionVectorArray
        arVectors = []
        for x, eachId in enumerate(ptIndices):
            eachHeat = arHeat[x]
            vecMove = om.MVector()

            # skip calculation for 0.0 heat
            if (eachHeat == 0.0):
                arVectors.append(vecMove)
                continue

            # ###################################
            # Normal
            # ###################################
            if (deformationType == 1):
                # normal deformation
                vecMove += om.MVector(
                    currentNormals[eachId]) * (eachHeat * -1) * edgeLengthAvrg

            # ###################################
            # BlendShape
            # ###################################
            if (deformationType == 2):
                if (eachHeat < 0.0):
                    targetPt = squashPoints[eachId]
                    vecMove += (targetPt - origPoints[eachId]) * (eachHeat *
                                                                  -1)
                elif (eachHeat > 0.0):
                    targetPt = stretchPoints[eachId]
                    vecMove += (targetPt - origPoints[eachId]) * (eachHeat)
                # tangent spaces
                if (tangentSpace):
                    matTangentOrig = getTangentSpace(tangentSpace, fnOrig,
                                                     eachId,
                                                     connectedFaces[eachId])
                    matTangentCurrent = getTangentSpace(
                        tangentSpace, fnCurrent, eachId,
                        connectedFaces[eachId])
                    vecMove *= matTangentOrig.inverse() * matTangentCurrent
                #
            # save vector
            arVectors.append(vecMove)

        # ###################################
        # Deformation Smooth
        # ###################################
        # input: motionVectorArray
        # result: motionVectorArray
        for x in range(iterationsSmoothDeformation):
            arVectorsNew = list(arVectors)
            for x, eachId in enumerate(ptIndices):
                neighborIds = connectedPoints[eachId]
                neighborAvrg = om.MVector()
                validNeighbor = False
                for eachNeighborId in neighborIds:
                    if (eachNeighborId in ptIndices):
                        validNeighbor = True
                        neighborAvrg += arVectors[ptIndices.index(
                            eachNeighborId)]
                if (validNeighbor):
                    neighborAvrg /= len(neighborIds)
                    arVectorsNew[x] = arVectorsNew[x] * (
                        1.0 - strengthSmoothDeformation
                    ) + neighborAvrg * strengthSmoothDeformation
            arVectors = arVectorsNew

        # ###################################
        # Deformation
        # ###################################
        # input: motionVectorArray, weights
        # result: deformed mesh
        counter = 0
        while not iter.isDone():
            if (iter.index() in ptIndices):
                iter.setPosition(paPoints[counter] + arVectors[counter] *
                                 ptWeights[counter] * envelope)
                counter += 1
            iter.next()