// 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); }
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); }
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; }
override public bool compute(MPlug plug, MDataBlock dataBlock) { bool res = plug.attribute.equalEqual(output); if (res) { MDataHandle inputData; inputData = dataBlock.inputValue(input); MDataHandle outputHandle = dataBlock.outputValue(output); outputHandle.asFloat = 10 * (float)Math.Sin((double)inputData.asFloat); dataBlock.setClean(plug); return true; } return false; }
override public bool compute(MPlug plug, MDataBlock dataBlock) { bool res = plug.attribute.equalEqual(output); if (res) { MDataHandle inputData; inputData = dataBlock.inputValue(input); MDataHandle outputHandle = dataBlock.outputValue(output); outputHandle.asFloat = 10 * (float)Math.Sin((double)inputData.asFloat); dataBlock.setClean(plug); return(true); } return(false); }
// // Description // // Compute the outputSurface attribute. // // If there is no history, use cachedSurface as the // input surface. All tweaks will get written directly // to it. Output is just a copy of the cached surface // that can be connected etc. // public void computeOutputSurface( MPlug plug, MDataBlock datablock ) { // Check for an input surface. The input surface, if it // exists, is copied to the cached surface. // computeInputSurface( plug, datablock ); // Get a handle to the cached data // MDataHandle cachedHandle = datablock.outputValue( cachedSurface ); apiMeshData cached = cachedHandle.asPluginData as apiMeshData; if ( null == cached ) { MGlobal.displayInfo( "NULL cachedSurface data found" ); } datablock.setClean( plug ); // Apply any vertex offsets. // if ( hasHistory() ) { applyTweaks( datablock, cached.fGeometry ); } else { MArrayDataHandle cpHandle = datablock.inputArrayValue( mControlPoints ); cpHandle.setAllClean(); } // Create some output data // MFnPluginData fnDataCreator = new MFnPluginData(); fnDataCreator.create(new MTypeId(apiMeshData.id)); apiMeshData newData = (apiMeshData)fnDataCreator.data(); // Copy the data // if ( null != cached ) { newData.fGeometry = cached.fGeometry; } else { MGlobal.displayInfo( "computeOutputSurface: NULL cachedSurface data" ); } // Assign the new data to the outputSurface handle // MDataHandle outHandle = datablock.outputValue( outputSurface ); outHandle.set( newData ); // Update the bounding box attributes // computeBoundingBox( datablock ); }
public override bool compute( MPlug plug, MDataBlock block) { if ( plug.equalEqual(constraintGeometry) ) { // block.inputValue(constraintParentInverseMatrix); // MArrayDataHandle targetArray = block.inputArrayValue( compoundTarget ); uint targetArrayCount = targetArray.elementCount(); double weight,selectedWeight = 0; if ( weightType == GeometrySurfaceConstraintCommand.ConstraintType.kSmallestWeight ) selectedWeight = float.MaxValue; MObject selectedMesh = null; uint i; for ( i = 0; i < targetArrayCount; i++ ) { MDataHandle targetElement = targetArray.inputValue(); weight = targetElement.child(targetWeight).asDouble; if ( !equivalent(weight,0.0)) { if ( weightType == GeometrySurfaceConstraintCommand.ConstraintType.kLargestWeight ) { if ( weight > selectedWeight ) { MObject mesh = targetElement.child(targetGeometry).asMesh; if ( !mesh.isNull ) { selectedMesh = mesh; selectedWeight = weight; } } } else { if ( weight < selectedWeight ) { MObject mesh = targetElement.child(targetGeometry).asMesh; if ( !mesh.isNull ) { selectedMesh = mesh; selectedWeight = weight; } } } } targetArray.next(); } // if( selectedMesh == null ) { block.setClean(plug); } else { // The transform node via the geometry attribute will take care of // updating the location of the constrained geometry. MDataHandle outputConstraintGeometryHandle = block.outputValue(constraintGeometry); outputConstraintGeometryHandle.setMObject(selectedMesh); } } else { return false; } return true; }
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; }
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); }
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; }
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; }
// // Description // // This function takes an input surface of type kMeshData and converts // the geometry into this nodes attributes. // Returns false if nothing is connected. // public bool computeInputMesh(MPlug plug, MDataBlock datablock, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { // Get the input subdiv // MDataHandle inputData = datablock.inputValue(inputMesh); MObject surf = inputData.asMesh; // Check if anything is connected // MObject thisObj = thisMObject(); MPlug surfPlug = new MPlug(thisObj, inputMesh); if (!surfPlug.isConnected) { datablock.setClean(plug); return(false); } // Extract the mesh data // MFnMesh surfFn = new MFnMesh(surf); surfFn.getPoints(vertices, MSpace.Space.kObject); // Check to see if we have UVs to copy. // bool hasUVs = surfFn.numUVsProperty > 0; surfFn.getUVs(uvs.ucoord, uvs.vcoord); for (int i = 0; i < surfFn.numPolygons; i++) { MIntArray polyVerts = new MIntArray(); surfFn.getPolygonVertices(i, polyVerts); int pvc = (int)polyVerts.length; counts.append(pvc); int uvId; for (int v = 0; v < pvc; v++) { if (hasUVs) { surfFn.getPolygonUVid(i, v, out uvId); uvs.faceVertexIndex.append(uvId); } connects.append(polyVerts[v]); } } for (int n = 0; n < (int)vertices.length; n++) { MVector normal = new MVector(); surfFn.getVertexNormal(n, normal); normals.append(normal); } return(true); }
// // Description // // This function takes an input surface of type kMeshData and converts // the geometry into this nodes attributes. // Returns false if nothing is connected. // public bool computeInputMesh(MPlug plug, MDataBlock datablock, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { // Get the input subdiv // MDataHandle inputData = datablock.inputValue( inputMesh ); MObject surf = inputData.asMesh; // Check if anything is connected // MObject thisObj = thisMObject(); MPlug surfPlug = new MPlug( thisObj, inputMesh ); if ( !surfPlug.isConnected ) { datablock.setClean( plug ); return false; } // Extract the mesh data // MFnMesh surfFn = new MFnMesh(surf); surfFn.getPoints( vertices, MSpace.Space.kObject ); // Check to see if we have UVs to copy. // bool hasUVs = surfFn.numUVsProperty > 0; surfFn.getUVs( uvs.ucoord, uvs.vcoord ); for ( int i=0; i<surfFn.numPolygons; i++ ) { MIntArray polyVerts = new MIntArray(); surfFn.getPolygonVertices( i, polyVerts ); int pvc = (int)polyVerts.length; counts.append( pvc ); int uvId; for ( int v=0; v<pvc; v++ ) { if ( hasUVs ) { surfFn.getPolygonUVid( i, v, out uvId ); uvs.faceVertexIndex.append( uvId ); } connects.append( polyVerts[v] ); } } for ( int n=0; n<(int)vertices.length; n++ ) { MVector normal = new MVector(); surfFn.getVertexNormal( n, normal ); normals.append( normal ); } return true; }
// 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; }
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); }
public override bool compute(MPlug plug, MDataBlock block) { if (plug.equalEqual(constraintGeometry)) { // block.inputValue(constraintParentInverseMatrix); // MArrayDataHandle targetArray = block.inputArrayValue(compoundTarget); uint targetArrayCount = targetArray.elementCount(); double weight, selectedWeight = 0; if (weightType == GeometrySurfaceConstraintCommand.ConstraintType.kSmallestWeight) { selectedWeight = float.MaxValue; } MObject selectedMesh = null; uint i; for (i = 0; i < targetArrayCount; i++) { MDataHandle targetElement = targetArray.inputValue(); weight = targetElement.child(targetWeight).asDouble; if (!equivalent(weight, 0.0)) { if (weightType == GeometrySurfaceConstraintCommand.ConstraintType.kLargestWeight) { if (weight > selectedWeight) { MObject mesh = targetElement.child(targetGeometry).asMesh; if (!mesh.isNull) { selectedMesh = mesh; selectedWeight = weight; } } } else { if (weight < selectedWeight) { MObject mesh = targetElement.child(targetGeometry).asMesh; if (!mesh.isNull) { selectedMesh = mesh; selectedWeight = weight; } } } } targetArray.next(); } // if (selectedMesh == null) { block.setClean(plug); } else { // The transform node via the geometry attribute will take care of // updating the location of the constrained geometry. MDataHandle outputConstraintGeometryHandle = block.outputValue(constraintGeometry); outputConstraintGeometryHandle.setMObject(selectedMesh); } } else { return(false); } return(true); }
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); }