예제 #1
0
        // The compute() method does the actual work of the node using the inputs
        // of the node to generate its output.
        //
        // Compute takes two parameters: plug and data.
        // - Plug is the the data value that needs to be recomputed
        // - Data provides handles to all of the nodes attributes, only these
        //   handles should be used when performing computations.
        //
        public override bool compute(MPlug plug, MDataBlock dataBlock)
        {
            MObject           thisNode   = thisMObject();
            MFnDependencyNode fnThisNode = new MFnDependencyNode(thisNode);

            MGlobal.displayInfo("affects::compute(), plug being computed is \"" + plug.name + "\"");

            if (plug.partialName() == "B")
            {
                // Plug "B" is being computed. Assign it the value on plug "A"
                // if "A" exists.
                //
                MPlug pA = fnThisNode.findPlug("A");

                MGlobal.displayInfo("\t\t... found dynamic attribute \"A\", copying its value to \"B\"");
                MDataHandle inputData = dataBlock.inputValue(pA);

                int value = inputData.asInt;

                MDataHandle outputHandle = dataBlock.outputValue(plug);

                outputHandle.set(value);
                dataBlock.setClean(plug);
            }
            else
            {
                return(false);
            }
            return(true);
        }
예제 #2
0
        public override bool compute(MPlug plug, MDataBlock dataBlock)
        {
            if (plug.equalEqual(animCube.outputMesh))
            {
                /* Get time */
                MDataHandle timeData = dataBlock.inputValue(animCube.time);
                MTime       time     = timeData.asTime;

                /* Get output object */

                MDataHandle outputHandle = dataBlock.outputValue(outputMesh);

                MFnMeshData dataCreator   = new MFnMeshData();
                MObject     newOutputData = dataCreator.create();

                createMesh(time, ref newOutputData);

                outputHandle.set(newOutputData);
                dataBlock.setClean(plug);
            }
            else
            {
                return(false);
            }

            return(true);
        }
예제 #3
0
 public override bool getInternalValueInContext(MPlug plug, MDataHandle dataHandle, MDGContext ctx)
 {
     if (plug.equalEqual(aTransparency))
     {
         dataHandle.set(fTransparency);
         return(true);
     }
     return(base.getInternalValueInContext(plug, dataHandle, ctx));
 }
예제 #4
0
 public override bool getInternalValueInContext(MPlug plug, MDataHandle dataHandle, MDGContext ctx)
 {
     if (plug.equalEqual(aTransparency))
     {
         dataHandle.set(fTransparency);
         return true;
     }
     return base.getInternalValueInContext(plug, dataHandle, ctx);
 }
예제 #5
0
        public override bool getInternalValue(MPlug plug, MDataHandle datahandle)
        {
            bool isOk = true;

            if (plug.attribute.equalEqual(radius1))
            {
                datahandle.set(fGeometry.radius1);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(radius2))
            {
                datahandle.set(fGeometry.radius2);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(height))
            {
                datahandle.set(fGeometry.height);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(startAngle))
            {
                datahandle.set(fGeometry.startAngle);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(sweepAngle))
            {
                datahandle.set(fGeometry.sweepAngle);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(slices))
            {
                datahandle.set(fGeometry.slices);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(loops))
            {
                datahandle.set(fGeometry.loops);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(stacks))
            {
                datahandle.set(fGeometry.stacks);
                isOk = true;
            }
            else
            {
                isOk = base.getInternalValue(plug, datahandle);
            }

            return(isOk);
        }
예제 #6
0
        public override void validateAndSetValue(MPlug plug, MDataHandle handle, MDGContext context)
        {
            //	Make sure that there is something interesting to process.
            //
            if (plug.isNull)
            {
                throw new ArgumentNullException("plug");
            }

            if (plug.equalEqual(aRockInX))
            {
                MDataBlock  block       = _forceCache(context);
                MDataHandle blockHandle = block.outputValue(plug);

                // Update our new rock in x value
                double rockInX = handle.asDouble;
                blockHandle.set(rockInX);
                rockXValue = rockInX;

                // Update the custom transformation matrix to the
                // right rock value.
                rockingTransformCheckMatrix ltm = getRockingTransformMatrix();
                if (ltm != null)
                {
                    ltm.setRockInX(rockXValue);
                }
                else
                {
                    MGlobal.displayError("Failed to get rock transform matrix");
                }

                blockHandle.setClean();

                // Mark the matrix as dirty so that DG information
                // will update.
                dirtyMatrix();

                return;
            }
            base.validateAndSetValue(plug, handle, context);
        }
예제 #7
0
        //
        // Description
        //
        //    Handle internal attributes.
        //
        //    Attributes that require special storage, bounds checking,
        //    or other non-standard behavior can be marked as "Internal" by
        //    using the "MFnAttribute.setInternal" method.
        //
        //    The get/setInternalValue methods will get called for internal
        //    attributes whenever the attribute values are stored or retrieved
        //    using getAttr/setAttr or MPlug getValue/setValue.
        //
        //    The inherited attribute mControlPoints is internal and we want
        //    its values to get stored only if there is input history. Otherwise
        //    any changes to the vertices are stored in the cachedMesh and outputMesh
        //    directly.
        //
        //    If values are retrieved then we want the controlPoints value
        //    returned if there is history, this will be the offset or tweak.
        //    In the case of no history, the vertex position of the cached mesh
        //    is returned.
        //
        public override bool getInternalValue(MPlug plug, MDataHandle result)
        {
            bool isOk = true;

            if( plug.attribute.equalEqual(mControlPoints) ||
                plug.attribute.equalEqual(mControlValueX) ||
                plug.attribute.equalEqual(mControlValueY) ||
                plug.attribute.equalEqual(mControlValueZ) )
            {
                // If there is input history then the control point value is
                // directly returned. This is the tweak or offset that
                // was applied to the vertex.
                //
                // If there is no input history then return the actual vertex
                // position and ignore the controlPoints attribute.
                //
                if ( hasHistory() ) {
                    return base.getInternalValue( plug, result );
                }
                else {
                    double val = 0.0;
                    if ( plug.attribute.equalEqual(mControlPoints) && !plug.isArray ) {
                        MPoint pnt = new MPoint();
                        int index = (int)plug.logicalIndex;
                        value( index, ref pnt );
                        result.set( pnt[0], pnt[1], pnt[2] );
                    }
                    else if ( plug.attribute.equalEqual(mControlValueX) ) {
                        MPlug parentPlug = plug.parent;
                        int index = (int)parentPlug.logicalIndex;
                        value( index, 0, ref val );
                        result.set( val );
                    }
                    else if ( plug.attribute.equalEqual(mControlValueY) ) {
                        MPlug parentPlug = plug.parent;
                        int index = (int)parentPlug.logicalIndex;
                        value( index, 1, ref val );
                        result.set( val );
                    }
                    else if ( plug.attribute.equalEqual(mControlValueZ) ) {
                        MPlug parentPlug = plug.parent;
                        int index = (int)parentPlug.logicalIndex;
                        value( index, 2, ref val );
                        result.set( val );
                    }
                }
            }
            // This inherited attribute is used to specify whether or
            // not this shape has history. During a file read, the shape
            // is created before any input history can get connected.
            // This attribute, also called "tweaks", provides a way to
            // for the shape to determine if there is input history
            // during file reads.
            //
            else if ( plug.attribute.equalEqual(mHasHistoryOnCreate) ) {
                result.set( fHasHistoryOnCreate );
            }
            else {
                isOk = base.getInternalValue( plug, result );
            }

            return isOk;
        }
예제 #8
0
        public override bool getInternalValue(MPlug plug, MDataHandle datahandle)
        {
            bool isOk = true;

            if (plug.attribute.equalEqual(radius1))
            {
                datahandle.set(fGeometry.radius1);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(radius2))
            {
                datahandle.set(fGeometry.radius2);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(height))
            {
                datahandle.set(fGeometry.height);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(startAngle))
            {
                datahandle.set(fGeometry.startAngle);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(sweepAngle))
            {
                datahandle.set(fGeometry.sweepAngle);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(slices))
            {
                datahandle.set(fGeometry.slices);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(loops))
            {
                datahandle.set(fGeometry.loops);
                isOk = true;
            }
            else if (plug.attribute.equalEqual(stacks))
            {
                datahandle.set(fGeometry.stacks);
                isOk = true;
            }
            else
            {
                isOk = base.getInternalValue(plug, datahandle);
            }

            return isOk;
        }
예제 #9
0
        public override bool compute(MPlug plug, MDataBlock dataBlock)
        {
            if (plug.equalEqual(gOutputFloat_2Float_3Float))
            {
                // attribute affecting generic attribute case.  Based on the
                // input attribute, we modify the output generic attribute
                MDataHandle inputDataInt = dataBlock.inputValue(gInputInt);
                int         inputInt     = inputDataInt.asInt;

                // Get the output handle
                MDataHandle outputData       = dataBlock.outputValue(plug);
                bool        isGenericNumeric = false;
                bool        isGenericNull    = false;

                // Is the output handle generic data
                if (outputData.isGeneric(ref isGenericNumeric, ref isGenericNull))
                {
                    // Based on the inputHandle, update the generic
                    // output handle
                    if (inputInt == 1)
                    {
                        outputData.setGenericBool(false, true);
                    }
                    else if (inputInt == 2)
                    {
                        outputData.setGenericBool(true, true);
                    }
                    else if (inputInt == 3)
                    {
                        outputData.setGenericChar(127, true);
                    }
                    else if (inputInt == 4)
                    {
                        outputData.setGenericDouble(3.145, true);
                    }
                    else if (inputInt == 5)
                    {
                        outputData.setGenericFloat((float)9.98, true);
                    }
                    else if (inputInt == 6)
                    {
                        outputData.setGenericShort(3245, true);
                    }
                    else if (inputInt == 7)
                    {
                        outputData.setGenericInt(32768, true);
                    }
                    else if (inputInt == 8)
                    {
                        MFnNumericData numericData = new MFnNumericData();
                        MObject        obj         = numericData.create(MFnNumericData.Type.k2Float);
                        numericData.setData((float)1.5, (float)6.7);
                        outputData.set(obj);
                    }
                    else if (inputInt == 9)
                    {
                        MFnNumericData numericData = new MFnNumericData();
                        MObject        obj         = numericData.create(MFnNumericData.Type.k3Float);
                        numericData.setData((float)2.5, (float)8.7, (float)2.3345);
                        outputData.set(obj);
                    }
                    else if (inputInt == 10)
                    {
                        outputData.setGenericInt(909, true);
                    }

                    // Mark the data clean
                    outputData.setClean();
                    dataBlock.setClean(gOutputFloat_2Float_3Float);
                }
            }
            else
            {
                return(false);
            }

            return(true);
        }
예제 #10
0
		public override bool getInternalValue(MPlug plug, MDataHandle result)
		//
		// Description
		//
		//    Handle internal attributes.
		//
		//    Attributes that require special storage, bounds checking,
		//    or other non-standard behavior can be marked as "Internal" by
		//    using the "MFnAttribute.setInternal" method.
		//
		//    The get/setInternalValue methods will get called for internal
		//    attributes whenever the attribute values are stored or retrieved
		//    using getAttr/setAttr or MPlug getValue/setValue.
		//
		//    The inherited attribute mControlPoints is internal and we want
		//    its values to get stored only if there is input history. Otherwise
		//    any changes to the vertices are stored in the cachedMesh and outputMesh
		//    directly.
		//
		//    If values are retrieved then we want the controlPoints value
		//    returned if there is history, this will be the offset or tweak.
		//    In the case of no history, the vertex position of the cached mesh
		//    is returned.
		//
		{
			bool isOk = true;

			if( plug.attribute.equalEqual(mControlPoints) ||
				plug.attribute.equalEqual(mControlValueX) ||
				plug.attribute.equalEqual(mControlValueY) ||
				plug.attribute.equalEqual(mControlValueZ) )
			{
				// If there is input history then the control point value is
				// directly returned. This is the tweak or offset that
				// was applied to the vertex.
				//
				// If there is no input history then return the actual vertex
				// position and ignore the controlPoints attribute.
				//
				if ( hasHistory() ) {
					return base.getInternalValue( plug, result );
				}
				else {
					double val = 0.0;
					if ( plug.attribute.equalEqual(mControlPoints) && !plug.isArray ) {
						MPoint pnt = new MPoint();
						int index = (int)plug.logicalIndex;
						value( index, ref pnt );
						result.set( pnt[0], pnt[1], pnt[2] );
					}
					else if ( plug.attribute.equalEqual(mControlValueX) ) {
						MPlug parentPlug = plug.parent;
						int index = (int)parentPlug.logicalIndex;
						value( index, 0, ref val );
						result.set( val );
					}
					else if ( plug.attribute.equalEqual(mControlValueY) ) {
						MPlug parentPlug = plug.parent;
						int index = (int)parentPlug.logicalIndex;
						value( index, 1, ref val );
						result.set( val );
					}
					else if ( plug.attribute.equalEqual(mControlValueZ) ) {
						MPlug parentPlug = plug.parent;
						int index = (int)parentPlug.logicalIndex;
						value( index, 2, ref val );
						result.set( val );
					}
				}
			}
			// This inherited attribute is used to specify whether or
			// not this shape has history. During a file read, the shape
			// is created before any input history can get connected.
			// This attribute, also called "tweaks", provides a way to
			// for the shape to determine if there is input history
			// during file reads.
			//
			else if ( plug.attribute.equalEqual(mHasHistoryOnCreate) ) {
				result.set( fHasHistoryOnCreate );
			}
			else {
				isOk = base.getInternalValue( plug, result );
			}

			return isOk;
		}
예제 #11
0
        //
        //	Calls applyRotationLocks && applyRotationLimits
        //	This method verifies that the passed value can be set on the
        //	rotate plugs. In the base class, limits as well as locking are
        //	checked by this method.
        //
        //	The compute, validateAndSetValue, and rotateTo functions
        //	all use this method.
        //
        protected override void checkAndSetRotation(MDataBlock block, MPlug plug, MEulerRotation newRotation, MSpace.Space space)
        {
            MDGContext context = block.context;

            updateMatrixAttrs(context);

            MEulerRotation outRotation = newRotation;

            if (context.isNormal)
            {
                //	For easy reading.
                //
                MPxTransformationMatrix xformMat = baseTransformationMatrix;

                //	Get the current translation in transform space for
                //	clamping and locking.
                //
                MEulerRotation savedRotation =
                    xformMat.eulerRotation(MSpace.Space.kTransform);

                //	Translate to transform space, since the limit test needs the
                //	values in transform space. The locking test needs the values
                //	in the same space as the savedR value - which is transform
                //	space as well.
                //
                baseTransformationMatrix.rotateTo(newRotation, space);

                outRotation = xformMat.eulerRotation(MSpace.Space.kTransform);

                //	Now that everything is in the same space, apply limits
                //	and change the value to adhere to plug locking.
                //
                outRotation = applyRotationLimits(outRotation, block);
                outRotation = applyRotationLocks(outRotation, savedRotation);

                //	The value that remain is in transform space.
                //
                xformMat.rotateTo(outRotation, MSpace.Space.kTransform);

                //	Get the value that was just set. It needs to be in transform
                //	space since it is used to set the datablock values at the
                //	end of this method. Getting the vaolue right before setting
                //	ensures that the transformation matrix and data block will
                //	be synchronized.
                //
                outRotation = xformMat.eulerRotation(MSpace.Space.kTransform);
            }
            else
            {
                //	Get the rotation for clamping and locking. This will get the
                //	rotate value in transform space.
                //
                double[]       s3            = block.inputValue(rotate).Double3;
                MEulerRotation savedRotation = new MEulerRotation(s3[0], s3[1], s3[2]);

                //	Create a local transformation matrix for non-normal context
                //	calculations.
                //
                MPxTransformationMatrix local = createTransformationMatrix();
                if (null == local)
                {
                    throw new InvalidOperationException("rockingTransformCheck::checkAndSetRotation internal error");
                }

                //	Fill the newly created transformation matrix.
                //
                computeLocalTransformation(local, block);

                //	Translate the values to transform space. This will allow the
                //	limit and locking tests to work properly.
                //
                local.rotateTo(newRotation, space);

                outRotation = local.eulerRotation(MSpace.Space.kTransform);

                //	Apply limits
                //
                outRotation = applyRotationLimits(outRotation, block);

                outRotation = applyRotationLocks(outRotation, savedRotation);

                local.rotateTo(outRotation, MSpace.Space.kTransform);

                //	Get the rotate value in transform space for placement in the
                //	data block.
                //
                outRotation = local.eulerRotation(MSpace.Space.kTransform);

                local.Dispose();
            }

            MDataHandle handle = block.outputValue(plug);

            if (plug.equalEqual(rotate))
            {
                handle.set(outRotation.x, outRotation.y, outRotation.z);
            }
            else if (plug.equalEqual(rotateX))
            {
                handle.set(outRotation.x);
            }
            else if (plug.equalEqual(rotateY))
            {
                handle.set(outRotation.y);
            }
            else
            {
                handle.set(outRotation.z);
            }

            return;
        }
예제 #12
0
        public override bool compute(MPlug plug, MDataBlock dataBlock)
        //
        //	Descriptions:
        //		compute output force.
        //
        {
            if (plug.notEqual(mOutputForce))
            {
                return(false);
            }

            // get the logical index of the element this plug refers to.
            //
            uint multiIndex = plug.logicalIndex;

            // Get input data handle, use outputArrayValue since we do not
            // want to evaluate both inputs, only the one related to the
            // requested multiIndex. Evaluating both inputs at once would cause
            // a dependency graph loop.

            MArrayDataHandle hInputArray = dataBlock.outputArrayValue(mInputData);

            hInputArray.jumpToElement(multiIndex);

            // get children of aInputData.

            MDataHandle hCompond = hInputArray.inputValue();

            MDataHandle        hPosition  = hCompond.child(mInputPositions);
            MObject            dPosition  = hPosition.data();
            MFnVectorArrayData fnPosition = new MFnVectorArrayData(dPosition);
            MVectorArray       points     = fnPosition.array();

            // The attribute mInputPPData contains the attribute in an array form
            // prepared by the particleShape if the particleShape has per particle
            // attribute fieldName_attrName.
            //
            // Suppose a field with the name dynExprField1 is connecting to
            // particleShape1, and the particleShape1 has per particle float attribute
            // dynExprField1_magnitude and vector attribute dynExprField1_direction,
            // then hInputPPArray will contains a MdoubleArray with the corresponding
            // name "magnitude" and a MvectorArray with the name "direction".  This
            // is a mechanism to allow the field attributes being driven by dynamic
            // expression.
            MArrayDataHandle mhInputPPData = dataBlock.inputArrayValue(mInputPPData);

            mhInputPPData.jumpToElement(multiIndex);

            MDataHandle       hInputPPData = mhInputPPData.inputValue();
            MObject           dInputPPData = hInputPPData.data();
            MFnArrayAttrsData inputPPArray = new MFnArrayAttrsData(dInputPPData);

            MDataHandle       hOwnerPPData = dataBlock.inputValue(mOwnerPPData);
            MObject           dOwnerPPData = hOwnerPPData.data();
            MFnArrayAttrsData ownerPPArray = new MFnArrayAttrsData(dOwnerPPData);

            string magString = "magnitude";

            MFnArrayAttrsData.Type doubleType = MFnArrayAttrsData.Type.kDoubleArray;

            bool         arrayExist;
            MDoubleArray magnitudeArray;

            arrayExist = inputPPArray.checkArrayExist(magString, out doubleType);
            if (arrayExist)
            {
                magnitudeArray = inputPPArray.getDoubleData(magString);
            }
            else
            {
                magnitudeArray = new MDoubleArray();
            }

            MDoubleArray magnitudeOwnerArray;

            arrayExist = ownerPPArray.checkArrayExist(magString, out doubleType);
            if (arrayExist)
            {
                magnitudeOwnerArray = ownerPPArray.getDoubleData(magString);
            }
            else
            {
                magnitudeOwnerArray = new MDoubleArray();
            }

            string dirString = "direction";

            MFnArrayAttrsData.Type vectorType = MFnArrayAttrsData.Type.kVectorArray;
            MVectorArray           directionArray;

            arrayExist = inputPPArray.checkArrayExist(dirString, out vectorType);
            if (arrayExist)
            {
                directionArray = inputPPArray.getVectorData(dirString);
            }
            else
            {
                directionArray = new MVectorArray();
            }

            MVectorArray directionOwnerArray;

            arrayExist = ownerPPArray.checkArrayExist(dirString, out vectorType);
            if (arrayExist)
            {
                directionOwnerArray = ownerPPArray.getVectorData(dirString);
            }
            else
            {
                directionOwnerArray = new MVectorArray();
            }

            // Compute the output force.
            //
            MVectorArray forceArray = new MVectorArray();

            apply(dataBlock, points.length, magnitudeArray, magnitudeOwnerArray,
                  directionArray, directionOwnerArray, forceArray);

            // get output data handle
            //
            MArrayDataHandle  hOutArray = dataBlock.outputArrayValue(mOutputForce);
            MArrayDataBuilder bOutArray = hOutArray.builder();

            // get output force array from block.
            //
            MDataHandle        hOut          = bOutArray.addElement(multiIndex);
            MFnVectorArrayData fnOutputForce = new MFnVectorArrayData();
            MObject            dOutputForce  = fnOutputForce.create(forceArray);

            // update data block with new output force data.
            //
            hOut.set(dOutputForce);
            dataBlock.setClean(plug);

            return(true);
        }
예제 #13
0
        public override bool compute(MPlug plug, MDataBlock datablock)
        //
        // Description
        //
        //    When input attributes are dirty this method will be called to
        //    recompute the output attributes.
        //
        {
            if (plug.attribute.equalEqual(outputSurface))
            {
                // Create some user-defined geometry data and access the
                // geometry so that we can set it
                //
                MFnPluginData fnDataCreator = new MFnPluginData();
                fnDataCreator.create(new MTypeId(apiMeshData.id));
                apiMeshData meshData = (apiMeshData)fnDataCreator.data();
                apiMeshGeom meshGeom = meshData.fGeometry;

                // If there is an input mesh then copy it's values
                // and construct some apiMeshGeom for it.
                //
                bool hasHistory = computeInputMesh(plug,
                                                   datablock,
                                                   meshGeom.vertices,
                                                   meshGeom.face_counts,
                                                   meshGeom.face_connects,
                                                   meshGeom.normals,
                                                   meshGeom.uvcoords);

                // There is no input mesh so check the shapeType attribute
                // and create either a cube or a sphere.
                //
                if (!hasHistory)
                {
                    MDataHandle sizeHandle = datablock.inputValue(size);
                    double      shape_size = sizeHandle.asDouble;
                    MDataHandle typeHandle = datablock.inputValue(shapeType);
                    short       shape_type = typeHandle.asShort;

                    switch (shape_type)
                    {
                    case 0:                              // build a cube
                        buildCube(shape_size,
                                  meshGeom.vertices,
                                  meshGeom.face_counts,
                                  meshGeom.face_connects,
                                  meshGeom.normals,
                                  meshGeom.uvcoords
                                  );
                        break;

                    case 1:                              // build a sphere
                        buildSphere(shape_size,
                                    32,
                                    meshGeom.vertices,
                                    meshGeom.face_counts,
                                    meshGeom.face_connects,
                                    meshGeom.normals,
                                    meshGeom.uvcoords
                                    );
                        break;
                    }                     // end switch
                }

                meshGeom.faceCount = meshGeom.face_counts.length;

                // Assign the new data to the outputSurface handle
                //
                MDataHandle outHandle = datablock.outputValue(outputSurface);
                outHandle.set(meshData);

                datablock.setClean(plug);
                return(true);
            }

            return(false);
        }