示例#1
0
    def compute(self, plug, block):
        # カスタムアトリビュートのハンドルを取得
        sVal = block.inputValue(self.sVal).asDouble()
        origMesh = block.inputValue(self.origMesh).asMesh()
        targetMesh = block.inputValue(self.targetMesh).asMesh()

        cacheOriEdgeLenHandle = block.outputArrayValue(self.cacheOriEdgeLen)
        outMeshHandle = block.outputValue(self.outputMesh)

        # イテレータを取得
        origEdgeIter = OM.MItMeshEdge(origMesh)
        targetEdgeIter = OM.MItMeshEdge(targetMesh)
        origFnMesh = OM.MFnMesh(origMesh)
        tarVerIter = OM.MItMeshVertex(targetMesh)

        # デフォームメッシュデータを準備
        meshObject = OM.MFnMeshData().create()
        resultMesh = OM.MFnMesh()
        resultMesh.copy(targetMesh, meshObject)

        # core
        if origEdgeIter.count() == targetEdgeIter.count():
            # 各エッジの長さをリストにしておく
            oEdgeLenArray = []
            while not origEdgeIter.isDone():
                oEdgeLenArray.append(origEdgeIter.length())
                origEdgeIter.next()
            tEdgeLenArray = []
            while not targetEdgeIter.isDone():
                tEdgeLenArray.append(targetEdgeIter.length())
                targetEdgeIter.next()

            # デフォーム
            while not tarVerIter.isDone():
                edgePack = tarVerIter.getConnectedEdges()
                val = 0.0
                oVal = 0.0
                tVal = 0.0
                for edge in edgePack:
                    oVal += oEdgeLenArray[edge]
                    tVal += tEdgeLenArray[edge]
                val = 1.0 - tVal / oVal

                if val < 0.0:
                    curveAttribute = OM.MRampAttribute(self.thisMObject(),
                                                       self.curveRamp)
                    i = tarVerIter.index()
                    ratio = sVal - abs(origFnMesh.getPoint(i).y) / sVal
                    val *= curveAttribute.getValueAtPosition(ratio)
                offset = tarVerIter.getNormal() * val

                resultMesh.setPoint(tarVerIter.index(),
                                    tarVerIter.position() + offset)
                tarVerIter.next()

        # メッシュを出力
        outMeshHandle.setMObject(meshObject)

        # 終了宣言
        block.setClean(plug)
示例#2
0
    def compute(self, plug, block):
        # カスタムアトリビュートのハンドルを取得
        follow = block.inputValue(self.follow).asDouble()
        restore = block.inputValue(self.restore).asDouble()
        time = block.inputValue(self.time).asDouble()
        pos = block.inputValue(self.pos).asVector()
        origMesh = block.inputValue(self.origMesh).asMesh()

        posResHandle = block.outputValue(self.positionRest)
        velResHandle = block.outputValue(self.velocityRest)
        outMeshHandle = block.outputValue(self.outputMesh)

        # イテレータを取得
        origVerIter = OM.MItMeshVertex(origMesh)

        # デフォームメッシュデータを準備
        meshObject = OM.MFnMeshData().create()
        resultMesh = OM.MFnMesh()
        resultMesh.copy(origMesh, meshObject)

        # core
        if time == 1.0:  # reset
            velResHandle.set3Double(0, 0, 0)
            posResHandle.set3Double(0, 0, 0)
        posRest = posResHandle.asVector()
        velRest = velResHandle.asVector()
        newPos = (pos - posRest) * follow
        vlct = velRest + (newPos - velRest) * restore
        velResHandle.set3Double(vlct.x, vlct.y, vlct.z)
        offset = posRest + velRest
        posResHandle.set3Double(offset.x, offset.y, offset.z)

        while not origVerIter.isDone():
            poiPos = origVerIter.position() + offset
            resultMesh.setPoint(origVerIter.index(), poiPos)
            origVerIter.next()

        # メッシュを出力
        outMeshHandle.setMObject(meshObject)

        # 終了宣言
        block.setClean(plug)
示例#3
0
    def compute(self, pPlug, pDataBlock):
        ''' Here, we will create a voxelized version of the input mesh. '''

        if (pPlug == VoxelizerNode.outputMeshAttribute):

            # Get our custom input node attributes and values.
            voxelWidthHandle = pDataBlock.inputValue(
                VoxelizerNode.voxelWidthAttribute)
            voxelWidth = voxelWidthHandle.asFloat()

            voxelDistanceHandle = pDataBlock.inputValue(
                VoxelizerNode.voxelDistanceAttribute)
            voxelDistance = voxelDistanceHandle.asFloat()

            inputMeshHandle = pDataBlock.inputValue(
                VoxelizerNode.inputMeshAttribute)
            inputMeshObj = inputMeshHandle.asMesh()

            # Compute the bounding box around the mesh vertices.
            boundingBox = self.getBoundingBox(inputMeshObj)

            # Determine which voxel centerpoints are contained within the mesh.
            voxels = self.getVoxels(voxelDistance, inputMeshObj, boundingBox)

            # Create a mesh data container, which will store our new voxelized mesh.
            meshDataFn = OpenMaya.MFnMeshData()
            newOutputMeshData = meshDataFn.create()

            # Create a cubic polygon for each voxel and populate the 'newOutputMeshData' MeshData object.
            self.createVoxelMesh(voxels, voxelWidth, newOutputMeshData)

            # Set the output data.
            outputMeshHandle = pDataBlock.outputValue(
                VoxelizerNode.outputMeshAttribute)
            outputMeshHandle.setMObject(newOutputMeshData)

        else:
            return OpenMaya.kUnknownParameter
	def compute(self, _plug, _dataBlock):
		# Check if the plug is the output mesh
		if (_plug == WarpNodeClass.m_outMesh):
			# Get handles for the attributes
			terrainDataHandle = _dataBlock.inputValue(WarpNodeClass.m_terrain)
			terrainValue = terrainDataHandle.asMesh()
			maxRadiusDataHandle = _dataBlock.inputValue(WarpNodeClass.m_maxRadius)
			maxRadiusValue = maxRadiusDataHandle.asFloat()
			controlPointsDataHandle = _dataBlock.inputArrayValue(WarpNodeClass.m_controlPoints)
			outMeshDataHandle = _dataBlock.outputValue(WarpNodeClass.m_outMesh)

			# Get all the vertices from the terrain
			inTerrainFn = om.MFnMesh(terrainValue)
			vertexPositions = inTerrainFn.getPoints()

			if self.m_firstCompute == True:
				# Get a list of the original control points positions
				controlPointsOriginalDataHandle = _dataBlock.inputArrayValue(WarpNodeClass.m_controlPointsOriginal)
				self.m_controlPointsOriginal = []
				if (len(controlPointsOriginalDataHandle) > 0):
					controlPointsOriginalDataHandle.jumpToPhysicalElement(0)
					while not controlPointsOriginalDataHandle.isDone():
						inputDataHandle = controlPointsOriginalDataHandle.inputValue()
						point = inputDataHandle.asDouble3()
						self.m_controlPointsOriginal.append(point)
						controlPointsOriginalDataHandle.next()

				numControlPoints = len(self.m_controlPointsOriginal)

				# Calculate the max radius for each control point
				maxRadiusSquared = maxRadiusValue * maxRadiusValue
				controlPointsRadii = numControlPoints * [maxRadiusSquared]
				for i in range(numControlPoints):
					distances = []
					for j in range(numControlPoints):
						dX = self.m_controlPointsOriginal[i][0] - self.m_controlPointsOriginal[j][0]
						dZ = self.m_controlPointsOriginal[i][2] - self.m_controlPointsOriginal[j][2]
						distances.append(dX*dX + dZ*dZ)
					distances.sort()
					if distances[3] < maxRadiusSquared:
						controlPointsRadii[i] = distances[3]

				# Calculate which vertices are affected
				for i in range(numControlPoints):
					tempArray = []
					# Calculate the min and max X and Z coordinates
					minX = self.m_controlPointsOriginal[i][0] - controlPointsRadii[i]
					maxX = self.m_controlPointsOriginal[i][0] + controlPointsRadii[i]
					minZ = self.m_controlPointsOriginal[i][2] - controlPointsRadii[i]
					maxZ = self.m_controlPointsOriginal[i][2] + controlPointsRadii[i]
					vertexIterator = om.MItMeshVertex(terrainValue)
					position = om.MPoint()
					while not vertexIterator.isDone():
						position = vertexIterator.position(om.MSpace.kWorld)
						if minX < position.x < maxX:
							if minZ < position.z < maxZ:
								index = vertexIterator.index()
								dX = self.m_controlPointsOriginal[i][0] - position.x
								dZ = self.m_controlPointsOriginal[i][2] - position.z
								distanceSquared = dX * dX + dZ * dZ
								if distanceSquared < controlPointsRadii[i]:
									ratio = distanceSquared / controlPointsRadii[i]
									softSelectValue = 1.0 - ratio
									tempArray.append((index, softSelectValue))
						vertexIterator.next()
					self.m_controlPointsVertices.append(tempArray)
				# Set this variable as false so this block of code is never recomputed
				self.m_firstCompute = False

			# Get a list of the control points positions
			controlPoints = []
			if (len(controlPointsDataHandle) > 0):
				controlPointsDataHandle.jumpToPhysicalElement(0)
			while not controlPointsDataHandle.isDone():
				inputDataHandle = controlPointsDataHandle.inputValue()
				point = inputDataHandle.asDouble3()
				controlPoints.append(point)
				controlPointsDataHandle.next()

			# Compute the difference in positions
			controlPointsDifference = []
			for cp, cpOriginal in zip(controlPoints,self.m_controlPointsOriginal):
				dX = cp[0] - cpOriginal[0]
				dY = cp[1] - cpOriginal[1]
				dZ = cp[2] - cpOriginal[2]
				controlPointsDifference.append(om.MVector(dX,dY,dZ))

			# Move the affected vertices
			numControlPoints = len(self.m_controlPointsOriginal)
			for i in range(numControlPoints):
				for point in self.m_controlPointsVertices[i]:
					vertexPositions[point[0]] += controlPointsDifference[i] * point[1]

			# Create a copy of the mesh to output
			meshDataFn = om.MFnMeshData()
			outTerrain = meshDataFn.create()
			outTerrainFn = om.MFnMesh()
			outTerrainFn.copy(terrainValue, outTerrain)

			# Set the output vertices
			outTerrainFn.setPoints(vertexPositions)

			# Set the output value
			outMeshDataHandle.setMObject(outTerrain)

			# Mark the output data handle as clean
			outMeshDataHandle.setClean()
    def compute(self, _plug, _dataBlock):
        # Check if the plug is the output
        if (_plug == SculptNodeClass.m_outMesh):

            # Get data handles and typecast
            terrainDataHandle = _dataBlock.inputValue(
                SculptNodeClass.m_terrain)
            terrainValue = terrainDataHandle.asMesh()

            curveMaskDataHandle = _dataBlock.inputValue(
                SculptNodeClass.m_curveMask)
            curveMaskValue = curveMaskDataHandle.asNurbsCurve()

            sculptedMeshDataHandle = _dataBlock.inputValue(
                SculptNodeClass.m_sculptedMesh)
            sculptedMeshValue = sculptedMeshDataHandle.asMesh()

            sculptStrengthDataHandle = _dataBlock.inputValue(
                SculptNodeClass.m_sculptStrength)
            sculptStrengthValue = sculptStrengthDataHandle.asFloat()

            curveOffsetDataHandle = _dataBlock.inputValue(
                SculptNodeClass.m_curveOffset)
            curveOffsetValue = curveOffsetDataHandle.asFloat()

            maxProjectionDistanceDataHandle = _dataBlock.inputValue(
                SculptNodeClass.m_maxProjectionDistance)
            maxProjectionDistanceValue = maxProjectionDistanceDataHandle.asFloat(
            )

            outMeshDataHandle = _dataBlock.outputValue(
                SculptNodeClass.m_outMesh)

            # Computation
            # Create a copy of the terrain
            meshDataFn = om.MFnMeshData()
            outTerrain = meshDataFn.create()
            outTerrainFn = om.MFnMesh()
            outTerrainFn.copy(terrainValue, outTerrain)

            # Get all the vertices from the terrain
            inTerrainFn = om.MFnMesh(terrainValue)
            vertexPositions = inTerrainFn.getPoints()

            # Create a function set for the curve and find the centre
            curveFn = om.MFnNurbsCurve(curveMaskValue)
            curveCentre = self.findCurveCentre(curveFn)

            # If this is the first computation, store the curve positions as the original and compute the affectedVertices
            if self.m_curveOriginalPoints == None:
                self.m_curveOriginalPoints = curveFn.cvPositions(
                    om.MSpace.kWorld)
                # Create a polygon iterator
                polygonIterator = om.MItMeshPolygon(terrainValue)
                # Find the closest face on the terrain
                centreFaceIndex = inTerrainFn.getClosestPoint(
                    curveCentre, om.MSpace.kWorld)[1]
                # Calculate the affected vertices
                self.findVerticesInsideCurve(polygonIterator, centreFaceIndex,
                                             curveFn, curveCentre,
                                             curveOffsetValue)
                # Store values
                self.m_lastCurveOffset = curveOffsetValue
                self.m_lastNumVertices = inTerrainFn.numVertices
                self.m_lastCurveCentreClosestVertex = centreFaceIndex
            # Check if the input terrain, curve offset or the curve has changed
            else:
                recomputeAffectedVertices = False
                centreFaceIndex = inTerrainFn.getClosestPoint(
                    curveCentre, om.MSpace.kWorld)[1]
                if self.m_lastNumVertices != inTerrainFn.numVertices:
                    recomputeAffectedVertices = True
                    self.m_lastNumVertices = inTerrainFn.numVertices
                elif curveOffsetValue != self.m_lastCurveOffset:
                    recomputeAffectedVertices = True
                    self.m_lastCurveOffset = curveOffsetValue
                elif self.m_lastCurveCentreClosestVertex != centreFaceIndex:
                    recomputeAffectedVertices = True
                    self.m_lastCurveCentreClosestVertex = centreFaceIndex
                elif len(self.m_curveOriginalPoints) != curveFn.numCVs:
                    recomputeAffectedVertices = True
                else:
                    curvePoints = curveFn.cvPositions(om.MSpace.kWorld)
                    for originalPos, newPos in zip(self.m_curveOriginalPoints,
                                                   curvePoints):
                        if originalPos != newPos:
                            recomputeAffectedVertices = True
                            break
                if recomputeAffectedVertices == True:
                    # Create a polygon iterator
                    polygonIterator = om.MItMeshPolygon(terrainValue)
                    # Find the closest face on the terrain
                    centreFaceIndex = inTerrainFn.getClosestPoint(
                        curveCentre, om.MSpace.kWorld)[1]
                    self.findVerticesInsideCurve(polygonIterator,
                                                 centreFaceIndex, curveFn,
                                                 curveCentre, curveOffsetValue)
                    self.m_curveOriginalPoints == curveFn.cvPositions(
                        om.MSpace.kWorld)

            # Create a function set for the sculpted mesh
            sculptedMeshFn = om.MFnMesh(sculptedMeshValue)
            accelerationParams = sculptedMeshFn.autoUniformGridParams()

            # Iterate through affected vertices and project onto the sculpted mesh
            numVertices = len(self.m_affectedVertices)
            for i in xrange(numVertices):
                # Find a ray intersection from the original point in the direction of the normal to the scul mesh
                raySource = om.MFloatPoint(
                    vertexPositions[self.m_affectedVertices[i]])
                normal = inTerrainFn.getVertexNormal(
                    self.m_affectedVertices[i], True, om.MSpace.kWorld)
                intersection = sculptedMeshFn.closestIntersection(
                    raySource,
                    om.MFloatVector(normal),
                    om.MSpace.kWorld,
                    maxProjectionDistanceValue,
                    True,
                    accelParams=accelerationParams)
                # Calculate a vector from the original point to the new point
                difference = om.MPoint(intersection[0]) - vertexPositions[
                    self.m_affectedVertices[i]]
                # Ensure the vertices are not sliding perpendicular to the normal
                if difference * normal != 0.0:
                    closestPointOnCurve = curveFn.closestPoint(
                        vertexPositions[self.m_affectedVertices[i]],
                        space=om.MSpace.kWorld)[0]
                    vertexPositions[self.m_affectedVertices[
                        i]] += difference * sculptStrengthValue * self.calculateSoftSelectValue(
                            curveCentre,
                            vertexPositions[self.m_affectedVertices[i]],
                            closestPointOnCurve)

            # Free the accelerator from memory as it is not automatically managed
            sculptedMeshFn.freeCachedIntersectionAccelerator()

            # Set the new vertices of the mesh
            outTerrainFn.setPoints(vertexPositions)

            # Set the output value
            outMeshDataHandle.setMObject(outTerrain)

            # Mark the plug as clean
            outMeshDataHandle.setClean()
示例#6
0
    def initialize(cls):
        print('initialize')
        nData = ompy.MFnNumericData()
        cData = ompy.MFnNurbsCurveData()
        mData = ompy.MFnMeshData()
        sData = ompy.MFnStringData()

        nAttr = ompy.MFnNumericAttribute()
        eAttr = ompy.MFnEnumAttribute()
        mAttr = ompy.MFnMatrixAttribute()
        gAttr = ompy.MFnGenericAttribute()
        tAttr = ompy.MFnTypedAttribute()
        sAttr = ompy.MFnTypedAttribute()

        cls.inAttrs = []
        # OUT ATTR
        cls.inAttrs.append(mAttr.create('camMatrix', 'camMatrix',
                                        nData.kFloat))

        drawPlaneMode_choices = ['none', 'foreground', 'background']
        cls.inAttrs.append(eAttr.create('drawPlaneMode', 'drawPlaneMode', 0))
        for i in range(0, len(drawPlaneMode_choices)):
            eAttr.addField(drawPlaneMode_choices[i], i)
        eAttr.channelBox = True

        cls.inAttrs.append(nAttr.create('shapes', 'shapes', nData.kInt, 0))
        nAttr.array = True
        #nAttr.dynamic = True
        nAttr.usesArrayDataBuilder = True

        cls.inAttrs.append(nAttr.createPoint('coords', 'coords'))
        nAttr.array = True
        #nAttr.dynamic = True
        nAttr.usesArrayDataBuilder = True

        cls.inAttrs.append(
            nAttr.createPoint('screenSpaceOffsets', 'screenSpaceOffsets'))
        nAttr.array = True
        #nAttr.dynamic = True
        nAttr.usesArrayDataBuilder = True

        cls.inAttrs.append(nAttr.create('sizes', 'sizes', nData.kFloat, 1.0))
        nAttr.array = True
        #nAttr.dynamic = True
        nAttr.usesArrayDataBuilder = True

        cls.inAttrs.append(
            nAttr.create('thicknesses', 'thicknesses', nData.kFloat, 1.0))
        nAttr.array = True
        #nAttr.dynamic = True
        nAttr.usesArrayDataBuilder = True

        cls.inAttrs.append(nAttr.createPoint('colors', 'colors'))
        nAttr.array = True
        #nAttr.dynamic = True
        nAttr.usesArrayDataBuilder = True

        cls.inAttrs.append(tAttr.create('names', 'names', sData.kString))
        tAttr.array = True
        #nAttr.dynamic = True
        tAttr.usesArrayDataBuilder = True
        '''
        cls.attrOutTrig = nAttr.create( 'outTrig', 'outTrig' , nData.kFloat  )   
        nAttr.setReadable(True) 
        nAttr.setStorable(True)
        nAttr.setConnectable(True) 
        '''

        for i in range(0, len(cls.inAttrs)):
            cls.addAttribute(cls.inAttrs[i])

        #INFLUENCE
        '''