def deform(self, dataBlock, geomIter, matrix, multiIndex):
     # get input mesh
     hInput = dataBlock.outputArrayValue(self.input)
     hInput.jumpToElement(multiIndex)
     hInputGeom = hInput.outputValue().child(self.inputGeom)
     oInputGeom = hInputGeom.asMesh()
     fnPoint = OpenMaya.MFnMesh(oInputGeom)
     # attribute handles
     hDivide = dataBlock.inputValue(self.aDivide)
     hVertex = dataBlock.inputArrayValue(self.aVertex)
     hDistance = dataBlock.outputArrayValue(self.aDistance)
     # attribute values
     vDivide = hDivide.asFloat()
     # MArrayDataBuilder:
     #    value of third argument (numElements) does not seem to matter (in Python ?!)
     dbDistance = OpenMaya.MArrayDataBuilder(dataBlock, self.aDistance,
                                             hVertex.elementCount())
     # calculate (loop through vertex 2D-array)
     for x in range(hVertex.elementCount()):
         hVertex.jumpToArrayElement(x)
         # get vertices
         iVtx0, iVtx1 = hVertex.inputValue().asInt2()
         p1 = OpenMaya.MPoint()
         p2 = OpenMaya.MPoint()
         fnPoint.getPoint(iVtx0, p1, OpenMaya.MSpace.kWorld)
         fnPoint.getPoint(iVtx1, p2, OpenMaya.MSpace.kWorld)
         # calculate distance
         vecP1toP2 = OpenMaya.MVector(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z)
         fDistance = vecP1toP2.length() / vDivide
         # set distance
         hDistanceBuilder = dbDistance.addElement(hVertex.elementIndex())
         hDistanceBuilder.setFloat(fDistance)
         hDistance.set(dbDistance)
Пример #2
0
    def compute(self, plug, dataBlock):
        if plug == arrayTest.output1WgtAttr:
            #calculations here
            #get inputs
            dataHandleInput = dataBlock.inputValue(arrayTest.input1VecAttr)
            inVal = dataHandleInput.asFloat()

            #get ouput array
            arrayDataHandle = OpenMaya.MArrayDataHandle(
                dataBlock.outputArrayValue(arrayTest.output1WgtAttr))
            myBuilder = OpenMaya.MArrayDataBuilder(arrayTest.output1WgtAttr, 0)

            for i in range(arrayDataHandle.elementCount()):
                #arrayDataHandle.next()
                output = inVal / (i + 1)
                #output = inVal + outValue

                myElementHandle = OpenMaya.MDataHandle(myBuilder.addElement(i))
                myElementHandle.setFloat(output)

            arrayDataHandle.set(myBuilder)
            arrayDataHandle.setAllClean()

            dataBlock.setClean(plug)

        else:
            return OpenMaya.kUnknownParameter
Пример #3
0
def MVectorsToNodeAttr(DataBlock, NodeAttr, Mvectors):
    builder = om.MArrayDataBuilder(DataBlock, NodeAttr, len(Mvectors))
    for i in range(0, len(Mvectors)):
        handle = builder.addElement(i)
        handle.setMFloatVector(Mvectors[i])

    arrayDataHandle = DataBlock.outputArrayValue(NodeAttr)
    arrayDataHandle.set(builder)
    arrayDataHandle.setAllClean()
	def utils_MMatricesToNodeAttr( self , DataBlock , NodeAttr  , Mmatices ):
		print('utils_MMatricesToNodeAttr')	               
		arrayDataHandle = DataBlock.outputArrayValue( NodeAttr )
		builder = om.MArrayDataBuilder(DataBlock, NodeAttr, len(Mmatices))		
		print(builder.elementCount())
		for i in range(0, len(Mmatices) ):
			handle = builder.addElement(i)
			print( builder.elementCount() , utils_MMatrixToNum(Mmatices[i]) )
			handle.setMMatrix( Mmatices[i] )
		
		arrayDataHandle.set(builder)
		arrayDataHandle.setAllClean()  	             	      
    def initVertMapping(self, data, iter, localToWorldMatrix, mIndex):
        #make poly mesh function set object:
        meshAttrHandle = data.inputValue(self.driver_mesh)
        meshMobj = meshAttrHandle.asMesh()
        vertIter = OpenMaya.MItMeshVertex(meshMobj)
        vertIter.reset()
        count = iter.count()

        vertMapOutArrayData = data.outputArrayValue(self.vert_map)

        vertMapOutArrayBuilder = OpenMaya.MArrayDataBuilder(
            self.vert_map, count)
        allPts = OpenMaya.MPointArray()
        allPts.clear()

        i = 0
        #first initialize all mappings to -1, and also store a buffer pt array to search through:
        while (iter.isDone() == False):
            initIndexDataHnd = vertMapOutArrayBuilder.addElement(i)
            negIndex = -1

            initIndexDataHnd.setInt(negIndex)
            initIndexDataHnd.setClean()

            allPts.append(iter.position() * localToWorldMatrix)
            i = i + 1
            iter.next()

        vertMapOutArrayData.set(vertMapOutArrayBuilder)

        while (vertIter.isDone() == False):
            driver_pt = OpenMaya.MPoint()
            driver_pt = vertIter.position(OpenMaya.MSpace.kWorld)
            closest_pt_index = self.getClosestPt(driver_pt, allPts)
            #save the closest point mapping to snap verts to each other here:

            snapDataHnd = vertMapOutArrayBuilder.addElement(closest_pt_index)
            snapDataHnd.setInt(vertIter.index())

            snapDataHnd.setClean()
            vertIter.next()

        vertMapOutArrayData.set(vertMapOutArrayBuilder)

        tObj = self.thisMObject()

        setInitMode = OpenMaya.MPlug(tObj, self.initialized_data)
        setInitMode.setShort(2)

        iter.reset(
        )  #important, reset the geom iterator so it starts from zero again
    def set_inverted_from_tweak(self, data_block):
        """
        Update .inverted_tweak_attr from the current value of .tweak.
        """
        tweak_data = data_block.inputArrayValue(self.tweak_attr)

        matrices = self.get_matrices(data_block)

        outputInvertedTweak = data_block.outputArrayValue(self.inverted_tweak_attr)

        # Don't use outputInvertedTweak.builder().  That'll return a builder containing
        # the existing data of the plug.  If there are tweak indexes that are now (0,0,0)
        # which used to have data, we'd need to remove them in the short-circuit case
        # below, and there's no fast way to do that.  Create a new builder instead.
        # builder = outputInvertedTweak.builder()
        builder = OpenMaya.MArrayDataBuilder(data_block, self.inverted_tweak_attr, 0)

        # Always add an element at index 0, or compute() will be called every frame.
        # This seems like a quirk of the tweak connection.
        newElement = builder.addElement(0)
        newElement.set3Float(0,0,0)

        for item in iterate_array_handle(tweak_data):
            thisValue = tweak_data.inputValue()
            delta = thisValue.asFloat3()

            # Skip zero tweaks.  Most blend shapes will have small, localized changes to
            # some part of the mesh, so we save a lot of time by not processing vertices
            # that haven't been changed.  This also saves time during MPxGeometryFilter_outputGeom
            # calculation, since that also won't spend any time deforming unchanged vertices.
            if abs(delta[0]) < 0.001 and abs(delta[1]) < 0.001 and abs(delta[2]) < 0.001:
                continue

            delta = OpenMaya.MVector(*delta)

            idx = array_current_index(tweak_data)
            if idx < len(matrices):
                delta *= matrices[idx]

            newElement = builder.addElement(idx)
            newElement.set3Float(*delta)

        outputInvertedTweak.set(builder)
        outputInvertedTweak.setAllClean()
        data_block.setClean(self.inverted_tweak_attr)
    def remap(self, data, iter, localToWorldMatrix, mIndex):

        # check what kind of bind we want to perform
        # worldspace or uv based
        transferType = data.inputValue(self.transferType).asShort()

        meshAttrHandle = data.inputValue(self.inputMesh)
        driverMesh = meshAttrHandle.asMesh()

        driverVtxIter = om.MItMeshVertex(driverMesh)
        driverMFnMesh = om.MFnMesh(driverMesh)

        vtxMappingArrayData = data.outputArrayValue(self.vertexMapping)
        vtxMapOutArrayBuilder = om.MArrayDataBuilder(self.vertexMapping,
                                                     iter.count())

        indexArray = om.MPointArray()

        inputAttribute = omMPx.cvar.MPxGeometryFilter_input
        inputGeometryAttribute = omMPx.cvar.MPxGeometryFilter_inputGeom
        inputHandle = data.outputArrayValue(inputAttribute)
        inputHandle.jumpToElement(mIndex)
        drivenMesh = inputHandle.outputValue().child(
            inputGeometryAttribute).asMesh()

        drivenVtxIter = om.MItMeshVertex(drivenMesh)

        driven = om.MFnMesh(drivenMesh)

        if transferType == 0:

            u, v = om.MFloatArray(), om.MFloatArray()
            driverUvs = driverMFnMesh.getUVs(u, v)
            sortedDriverUvs = map(list, zip(u, v))

            while not drivenVtxIter.isDone():
                drivenIndex = drivenVtxIter.index()
                vtxMapDataHandler = vtxMapOutArrayBuilder.addElement(
                    drivenIndex)
                vtxMapDataHandler.setInt(-1)
                vtxMapDataHandler.setClean()

                drivenVtxIter.next()

            drivenVtxIter.reset()

            driverMapped = {}
            while not driverVtxIter.isDone():

                u, v = self.getMeshUVAtIndex(driverVtxIter)
                driverIndex = int(driverVtxIter.index())
                uvKey = str([u, v])
                driverMapped.update({uvKey: driverIndex})
                driverVtxIter.next()

            drivenVtxIter.reset()

            while not drivenVtxIter.isDone():

                drivenIndex = drivenVtxIter.index()

                d_u, d_v = self.getMeshUVAtIndex(drivenVtxIter)
                driven_uv = [d_u, d_v]

                if driven_uv in sortedDriverUvs:
                    if driverMapped.has_key(str(driven_uv)):
                        driverIndex = driverMapped[str(driven_uv)]
                        vtxMapDataHandler = vtxMapOutArrayBuilder.addElement(
                            drivenIndex)
                        vtxMapDataHandler.setInt(driverIndex)
                        vtxMapDataHandler.setClean()

                drivenVtxIter.next()
            drivenVtxIter.reset()

            vtxMappingArrayData.set(vtxMapOutArrayBuilder)

        elif transferType == 1:
            return

        setInitMode = om.MPlug(self.thisMObject(), self.initilizeData)
        setInitMode.setShort(2)
Пример #8
0
    def initOrigin(self, data, iter, localToWorldMatrix, mIndex):
        # get the handle for the driver mesh
        meshAttrHandle = data.inputValue(self.driver_mesh)

        # get mfnmesh
        meshMobj = meshAttrHandle.asMesh()

        meshVerItFn = OpenMaya.MItMeshVertex(meshMobj)
        meshVerItFn.reset()

        bind_count = meshVerItFn.count()
        bindOutArrayData = data.outputArrayValue(self.bindData)
        bindOutArrayBuilder = OpenMaya.MArrayDataBuilder(
            self.bindData, bind_count)

        # get the origin points
        origin_points = []
        i = 0
        while not meshVerItFn.isDone():
            wsPoint = meshVerItFn.position(
                OpenMaya.MSpace.kWorld)  # * localToWorldMatrix #
            origin_points.append(np.array([wsPoint.x, wsPoint.y, wsPoint.z]))

            bindDataHnd = bindOutArrayBuilder.addElement(i)
            bindDataHnd.set3Float(wsPoint.x, wsPoint.y, wsPoint.z)
            bindDataHnd.setClean()

            i += 1
            meshVerItFn.next()

        bindOutArrayData.set(bindOutArrayBuilder)

        origin_m = np.array(origin_points)

        # shuffle array
        inputdata = []
        for value_A in origin_m.T:
            sort_array = []
            for value_B in origin_m.T:
                sort_array.append(value_B)
            sort_array.append(value_A)
            inputdata.append(np.array([sort_array]))

        # create rbfs
        rbfs = [
            Rbf(value[0][0], value[0][1], value[0][2], value[0][3])
            for value in inputdata
        ]

        # get target points
        target_points = []
        while not iter.isDone():
            wsPoint = iter.position() * localToWorldMatrix  #localToWorldMatrix
            target_points.append(np.array([wsPoint.x, wsPoint.y, wsPoint.z]))
            iter.next()

        target_m = np.array(target_points)

        delta_count = iter.count()
        deltaOutArrayData = data.outputArrayValue(self.deltaData)
        deltaOutArrayBuilder = OpenMaya.MArrayDataBuilder(
            self.deltaData, delta_count)

        for i, target in enumerate(target_m):
            output = [rbf(*target) for rbf in rbfs]
            delta = np.round((output - target), 4)

            deltaDataHnd = deltaOutArrayBuilder.addElement(i)
            deltaDataHnd.set3Float(float(delta[0]), float(delta[1]),
                                   float(delta[2]))
            deltaDataHnd.setClean()

        deltaOutArrayData.set(deltaOutArrayBuilder)

        tObj = self.thisMObject()
        setInitMode = OpenMaya.MPlug(tObj, self.initialized_data)
        setInitMode.setShort(2)

        iter.reset()