MStatus pointOnSubd::compute( const MPlug& plug, MDataBlock& data ) // // Description: // This method computes the value of the given output plug based // on the values of the input attributes. // // Arguments: // plug - the plug to compute // data - object that provides access to the attributes for this node // { MStatus returnStatus; // Check which output attribute we have been asked to compute. If this // node doesn't know how to compute it, we must return // MS::kUnknownParameter. // if( (plug == aPoint) || (plug == aNormal) || (plug == aPointX) || (plug == aNormalX) || (plug == aPointY) || (plug == aNormalY) || (plug == aPointZ) || (plug == aNormalZ) ) { // Get a handle to the input attribute that we will need for the // computation. If the value is being supplied via a connection // in the dependency graph, then this call will cause all upstream // connections to be evaluated so that the correct value is supplied. // do { MDataHandle subdHandle = data.inputValue( aSubd, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get subd\n" ); break; } MDataHandle faceFirstHandle = data.inputValue( aFaceFirst, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get face first\n" ); break; } MDataHandle faceSecondHandle = data.inputValue( aFaceSecond, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get face2\n" ); break; } MDataHandle uHandle = data.inputValue( aU, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get u\n" ); break; } MDataHandle vHandle = data.inputValue( aV, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get v\n" ); break; } MDataHandle relHandle = data.inputValue( aRelativeUV, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get relative UV\n" ); break; } // Read the input value from the handle. // MStatus stat; MObject subdValue = subdHandle.asSubdSurface(); MFnSubd subdFn( subdValue, &stat ); McheckErr(stat,"ERROR creating subd function set"); int faceFirstValue = faceFirstHandle.asLong(); int faceSecondValue = faceSecondHandle.asLong(); double uValue = uHandle.asDouble(); double vValue = vHandle.asDouble(); bool relUV = relHandle.asBool(); MPoint point; MVector normal; MUint64 polyId; stat = MFnSubdNames::fromSelectionIndices( polyId, faceFirstValue, faceSecondValue ); McheckErr(stat,"ERROR converting indices"); stat = subdFn.evaluatePositionAndNormal( polyId, uValue, vValue, relUV, point, normal ); normal.normalize(); McheckErr(stat,"ERROR evaluating the position and the normal"); // Get handles to the output attributes. This is similar to the // "inputValue" call above except that no dependency graph // computation will be done as a result of this call. // MDataHandle pointHandle = data.outputValue( aPoint ); pointHandle.set( point.x, point.y, point.z ); data.setClean(plug); MDataHandle normalHandle = data.outputValue( aNormal ); normalHandle.set( normal.x, normal.y, normal.z ); data.setClean(plug); } while( false ); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
/*! Compute function, gets the input surface, determines what type it is and calls the appropriate conversion function Encapsulates an cowpointer to the body into the naiadBodyData type and outputs it */ MStatus NBuddySurfaceToBodyNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; if (plug == _outBody) { //Get the body name MDataHandle bodyNameHndl = data.inputValue( _bodyName, &status ); MString bodyName = bodyNameHndl.asString(); //Create the MFnPluginData for the naiadBody MFnPluginData dataFn; dataFn.create( MTypeId( naiadBodyData::id ), &status); NM_CheckMStatus( status, "Failed to create naiadBodyData in MFnPluginData"); //Get subdivision info from plugs so better approximations of meshes can be done int divisions = data.inputValue( _subDivide, &status ).asBool(); //Getting genericAttribute handle containing the surface and pick the correct conversion function MObject meshObj; MDataHandle inSurfaceHdl = data.inputValue( _inSurface, &status ); if (inSurfaceHdl.type() == MFnData::kNurbsSurface) { MFnNurbsSurface nurbsFn(inSurfaceHdl.asNurbsSurface()); // Create the data holder for the tesselated mesh MFnMeshData dataCreator; MObject newOutputData = dataCreator.create(&status); //Setup the tesselation parameters MTesselationParams tParams; tParams.setOutputType( MTesselationParams::kTriangles ); tParams.setFormatType( MTesselationParams::kGeneralFormat ); tParams.setUIsoparmType( MTesselationParams::kSpanEquiSpaced ); tParams.setVIsoparmType( MTesselationParams::kSpanEquiSpaced ); tParams.setUNumber( divisions+1 ); tParams.setVNumber( divisions+1 ); // Tesselate and get the returned mesh meshObj = nurbsFn.tesselate( tParams, newOutputData, &status ); NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate nurbs surface to poly"); } else if (inSurfaceHdl.type() == MFnData::kMesh) { meshObj = inSurfaceHdl.asMesh(); if ( divisions > 0 ) { MFnMeshData dataCreator; MObject newOutputData = dataCreator.create(&status); MFnMesh meshFn(meshObj); MIntArray faceIds; for ( unsigned int i(0); i < meshFn.numPolygons(); ++i ) faceIds.append(i); meshFn.subdivideFaces( faceIds , divisions ); } } else if (inSurfaceHdl.type() == MFnData::kSubdSurface) { // Create the subd function set so we can tesselate MFnSubd subDfn(inSurfaceHdl.asSubdSurface()); // Create the data holder for the tesselated mesh MFnMeshData dataCreator; MObject newOutputData = dataCreator.create(&status); // Tesselate the subD surface meshObj = subDfn.tesselate(true, 1 , divisions , newOutputData, &status ); NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate SubD surface to poly"); } else return status ; //Get the handle for the input transform MDataHandle inTransformHdl = data.inputValue( _inTransform, &status ); NM_CheckMStatus( status, "Failed to get inTransform handle"); MDataHandle useTransformHdl = data.inputValue( _useTransform, &status); NM_CheckMStatus( status, "Failed to get worldSpaceHdl "); bool useTransform = useTransformHdl.asBool(); //Get a new naiadBodyData naiadBodyData * newBodyData = (naiadBodyData*)dataFn.data( &status ); NM_CheckMStatus( status, "Failed to get naiadBodyData handle from MFnPluginData"); try { newBodyData->nBody = mayaMeshToNaiadBody( meshObj, std::string(bodyName.asChar()), useTransform, inTransformHdl.asMatrix() ); } catch(std::exception& ex) { NM_ExceptionPlugDisplayError("NBuddySurfaceToBodyNode::compute ", plug, ex ); } //Give the data to the output handle and set it clean MDataHandle bodyDataHnd = data.outputValue( _outBody, &status ); NM_CheckMStatus( status, "Failed to get outputData handle for outBody"); bodyDataHnd.set( newBodyData ); data.setClean( plug ); } return status; }