示例#1
0
bool
OpenSubdivShader::setInternalValueInContext(const MPlug &plug, const MDataHandle &handle, MDGContext &) 
{
    if (plug == aLevel) {
        _hbrMeshDirty = true;
        _level = handle.asLong();
    } else if (plug == aTessFactor) {
        _tessFactor = handle.asLong();
    } else if (plug == aScheme) {
        _hbrMeshDirty = true;
        _scheme = (OsdMeshData::SchemeType)handle.asShort();
    } else if (plug == aKernel) {
        _hbrMeshDirty = true;
        _kernel = (OsdMeshData::KernelType)handle.asShort();
    } else if (plug == aInterpolateBoundary) {
        _hbrMeshDirty = true;
        _interpolateBoundary = (OsdMeshData::InterpolateBoundaryType)handle.asShort();
    } else if (plug == aAdaptive) {
        _hbrMeshDirty = true;
        _adaptiveDirty = true;
        _adaptive = handle.asBool();
 
    } else if (plug == aDiffuseMapFile) {
        _diffuseMapDirty = true;
        _diffuseMapFile = handle.asString();
    } else if (plug == aUVSet) {
        _hbrMeshDirty = true;
        _uvSet = handle.asString();
    } else if (plug == aInterpolateUVBoundary) {
        _hbrMeshDirty = true;
        _interpolateUVBoundary = (OsdMeshData::InterpolateBoundaryType)handle.asShort();

    } else if (plug == aShaderSource) {
        _shaderSourceFilename = handle.asString();
        std::ifstream ifs;
        ifs.open(_shaderSourceFilename.asChar());
        if (ifs.fail()) {
            printf("Using default shader\n");
            _shaderSource.clear();
            _shaderSourceFilename.clear();
        } else {
            printf("Using %s shader\n", _shaderSourceFilename.asChar());
            std::stringstream buffer;
            buffer << ifs.rdbuf();
            _shaderSource = buffer.str();
        }
        ifs.close();
        _shaderSourceDirty = true;
    }

    return false;
}
//------------------------------------------------------------------------------
bool
OpenSubdivShader::setInternalValueInContext(const MPlug &plug, const MDataHandle &handle, MDGContext &)
{
    if(plug == aLevel)
    {
        _level = handle.asLong();
    }
    else if(plug == aScheme)
    {
        _scheme = handle.asShort();
    }
    else if(plug == aKernel)
    {
        _kernel = handle.asShort();
    }
    return false;
}
示例#3
0
MStatus blindDataMesh::compute(const MPlug& plug, MDataBlock& data)

{
	MStatus returnStatus;

	if (plug == outputMesh) {

		// Get the given random number generator seed. We need to use a
		// seed, because a pseudo-random number generator will always give
		// the same random numbers for a constant seed. This means that the
		// mesh will not change when it is recalculated.
		//
		MDataHandle seedHandle = data.inputValue(seed, &returnStatus);
		McheckErr(returnStatus,"ERROR getting random number generator seed\n");

		long seed = seedHandle.asLong();

		// Get the handle to the output mesh. The creation of the output mesh
		// is done in two steps. First, the mesh is created. That involves
		// calculating the position of the vertices and their connectivity.
		//
		// Second, blind data is associated to the vertices on the mesh.
		// For this example, three double blind data values is associated
		// to each vertex: "red", "green" and "blue".
		//
		MFnMeshData dataCreator;
		MDataHandle outputHandle = data.outputValue(outputMesh, &returnStatus);
		McheckErr(returnStatus, "ERROR getting polygon data handle\n");
		MObject newOutputData = dataCreator.create(&returnStatus);
		McheckErr(returnStatus, "ERROR creating outputData");
		createMesh(seed, newOutputData, returnStatus);
		McheckErr(returnStatus, "ERROR creating new plane");
		returnStatus = setMeshBlindData(newOutputData);
		McheckErr(returnStatus, "ERROR setting the blind Data on the plane");

		outputHandle.set(newOutputData);
		data.setClean( plug );
	} else
		return MS::kUnknownParameter;

	return MS::kSuccess;
}
bool
OpenSubdivPtexShader::setInternalValueInContext(const MPlug &plug, const MDataHandle &handle, MDGContext &)
{
    if (plug == aLevel) {
        _hbrMeshDirty = true;
        _level = handle.asLong();
    } else if (plug == aTessFactor) {
        _tessFactor = handle.asLong();
    } else if (plug == aScheme) {
        _hbrMeshDirty = true;
        _scheme = (OsdPtexMeshData::SchemeType)handle.asShort();
    } else if (plug == aKernel) {
        _hbrMeshDirty = true;
        _kernel = (OsdPtexMeshData::KernelType)handle.asShort();
    } else if (plug == aInterpolateBoundary) {
        _hbrMeshDirty = true;
        _interpolateBoundary = (OsdPtexMeshData::InterpolateBoundaryType)handle.asShort();
    } else if (plug == aAdaptive) {
        _hbrMeshDirty = true;
        _adaptiveDirty = true;
        _adaptive = handle.asBool();

    } else if (plug == aShaderSource) {
        _shaderSourceFilename = handle.asString();
        std::ifstream ifs;
        ifs.open(_shaderSourceFilename.asChar());
        if (ifs.fail()) {
            printf("Using default shader\n");
            _shaderSource.clear();
            _shaderSourceFilename.clear();
        } else {
            printf("Using %s shader\n", _shaderSourceFilename.asChar());
            std::stringstream buffer;
            buffer << ifs.rdbuf();
            _shaderSource = buffer.str();
        }
        ifs.close();
        _shaderSourceDirty = true;

    } else if (plug == aDiffuseEnvironmentMapFile) {
        _diffEnvMapDirty = true;
        _diffEnvMapFile = handle.asString();
    } else if (plug == aSpecularEnvironmentMapFile) {
        _specEnvMapDirty = true;
        _specEnvMapFile = handle.asString();
    } else if (plug == aColorFile) {
        _ptexColorDirty = true;
        _colorFile = handle.asString();
    } else if (plug == aDisplacementFile) {
        _ptexDisplacementDirty = true;
        _displacementFile = handle.asString();
    } else if (plug == aOcclusionFile) {
        _ptexOcclusionDirty = true;
        _occlusionFile = handle.asString();
    } else if (plug == aEnableColor) {
        _enableColor = handle.asBool();
    } else if (plug == aEnableDisplacement) {
        _enableDisplacement = handle.asBool();
    } else if (plug == aEnableOcclusion) {
        _enableOcclusion = handle.asBool();
    } else if (plug == aEnableNormal) {
        _enableNormal = handle.asBool();
    }

    return false;
}
示例#5
0
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;
}
MStatus proWater::compute(const MPlug& plug, MDataBlock& dataBlock)
{
    MStatus status = MStatus::kUnknownParameter;
    if (plug.attribute() == outputGeom) {
        // get the input corresponding to this output
        //
        unsigned int index = plug.logicalIndex();
        MObject thisNode = this->thisMObject();
        MPlug inPlug(thisNode,input);
        inPlug.selectAncestorLogicalIndex(index,input);
        MDataHandle hInput = dataBlock.inputValue(inPlug);
        
        // get the input geometry and input groupId
        //
        MDataHandle hGeom = hInput.child(inputGeom);
        MDataHandle hGroup = hInput.child(groupId);
        
        
        
        unsigned int groupId = hGroup.asLong();
        MDataHandle hOutput = dataBlock.outputValue(plug);
        hOutput.copy(hGeom);
        
        
        MStatus returnStatus;
        
        MDataHandle envData = dataBlock.inputValue(envelope, &returnStatus);
        if (MS::kSuccess != returnStatus) return returnStatus;
        float env = envData.asFloat();
        
        MDataHandle timeData = dataBlock.inputValue(time, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double t = timeData.asDouble();
        
        MDataHandle dirData = dataBlock.inputValue(dir, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double dirDeg = dirData.asDouble();
        
        MDataHandle bigData = dataBlock.inputValue(bigFreq, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double bigFreqAmp = bigData.asDouble();
        
        MDataHandle ampData = dataBlock.inputValue(amplitude1, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double amp1 = ampData.asDouble();
        
        MDataHandle freqData = dataBlock.inputValue(frequency1, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double freq1 = freqData.asDouble();
        
        MDataHandle ampData2 = dataBlock.inputValue(amplitude2, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double amp2 = ampData2.asDouble();
        
        MDataHandle freqData2 = dataBlock.inputValue(frequency2, &returnStatus);
        if(MS::kSuccess != returnStatus) return returnStatus;
        double freq2 = freqData2.asDouble();
        
        
        // Get the MFnMesh
        MStatus stat;
        MObject inputObj = hOutput.data();
        MFnMesh * meshFn = new MFnMesh(inputObj, &stat);
        
        // do the deformation
        //
        MItGeometry iter(hOutput,groupId,false);
        
        for ( ; !iter.isDone(); iter.next()) {
            MPoint pt = iter.position();
            
            //float2 uvPoint;
            //float u,v;
            
            //uvPoint[0] = u;
            //uvPoint[1] = v;
            
            //meshFn->getUVAtPoint(pt, uvPoint, MSpace::kObject);
            
            float u = pt.x; //uvPoint[0]*100;
            float v = pt.z; //uvPoint[1]*100;
            
            float degDir = dirDeg;
            
            float dir = degDir* M_PI/180;
            
            float dirX = cos(dir);
            float dirY = sin(dir);
            
            
            float bigFreq = 0.01;
            
            float bigWaves = scaled_raw_noise_3d(0, 1, (u + 3*t*dirX)*bigFreq*dirX, (v + 3*t*dirY)*bigFreq*dirY*2, t*0.01);
            
            
            float frequency1 = freq1/10;//0.2;
            float amplitude1 = amp1;//1.3;
            
            float firstOctave = -(std::abs(scaled_raw_noise_3d(-amplitude1, amplitude1, (float)(u + 0.7*t*dirX)*frequency1*0.4, (float)(v + 0.7*t*dirY)*frequency1*0.6, 0.05*t))-amplitude1);
            
            float frequency2 = freq2/10;
            float amplitude2 = amp2;
        
            float secondOctave = - (std::abs(scaled_raw_noise_3d(-amplitude2, amplitude2, (float)(u + 0.7*t*dirX)*frequency2*0.35, (float)(v + 0.7*t*dirY)*frequency2*0.65, 0.005*t))-amplitude2);
            
            float frequency3 = freq1/10;
            float amplitude3 = amp1/1.5;
            
            float thirdOctave = - (std::abs(scaled_raw_noise_3d(-amplitude3, amplitude3, (float)(u + t*0.5*dirX)*frequency3*0.4, (float)(v + t*0.5*dirY)*frequency3*0.6, 30))-amplitude3);
            
            float frequency4 = freq2/10;
            float amplitude4 = amp2/1.5;
            
            float fourthOctave = scaled_raw_noise_3d(-amplitude4, amplitude4, (float)(u + t*0.5*dirX)*frequency4*0.4, (float)(v + t*0.5*dirY)*frequency4*0.6, 50);
            
            float frequency5 = freq2;
            float amplitude5 = amp2/2;
            
            float fifthOctave = scaled_raw_noise_3d(-amplitude5, amplitude5, (float)(u + t*0.5*dirX)*frequency5*0.15, (float)(v + t*0.5*dirY)*frequency5*0.85, 0.001*t);
            
            float disp = bigFreqAmp*bigWaves + 7*(bigWaves)*firstOctave + secondOctave + thirdOctave*thirdOctave + fourthOctave + std::abs(bigWaves-1)*fifthOctave;
            
            pt = pt + iter.normal()*disp;
            
            iter.setPosition(pt);
        }
        
        delete meshFn;
        status = MStatus::kSuccess;
    }
    
    
    return status;
}
示例#7
0
MStatus VmIslandNode::compute( const MPlug& i_plug, MDataBlock& io_dataBlock )
{
    MStatus status;
    
    fprintf( stderr, "VmIslandNode::compute()...\n" );
    
    //Check plugs
    if( i_plug == oa_update )
    {
        //Make sure all internal structures are up to date with attributes
        fprintf( stderr, "VmIslandNode::compute(oa_update)\n" );
        
        MDataHandle seedHandle = io_dataBlock.inputValue( ia_seed, & status);
        const long seed = seedHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle roughnessHandle = io_dataBlock.inputValue( ia_roughness, & status);
        const float roughness = roughnessHandle.asFloat();
        CHECK_MSTATUS( status );
        
        MDataHandle planeHeightHandle = io_dataBlock.inputValue( ia_planeHeight, & status);
        const long planeHeight = planeHeightHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle smoothHandle = io_dataBlock.inputValue( ia_smooth, & status);
        const long smooth = smoothHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle resolutionHandle = io_dataBlock.inputValue( ia_resolution, & status);
        const long resolution = resolutionHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle planeSizeHandle = io_dataBlock.inputValue( ia_planeSize, & status);
        const long planeSize = planeSizeHandle.asLong();
        CHECK_MSTATUS( status );


        
        MDataHandle gridSizeHandle = io_dataBlock.inputValue( ia_gridSize, & status);
        const long gridSize = gridSizeHandle.asLong();
        m_gridSize = (int) gridSize;
        CHECK_MSTATUS( status );


        //Grass
        //--------------
        MDataHandle baseWidthHandle = io_dataBlock.inputValue( ia_baseWidth, & status);
        const float baseWidth = baseWidthHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle grassMultiplierHandle = io_dataBlock.inputValue( ia_grassMultiplier, & status);
        const long grassMultiplier = grassMultiplierHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle grassSegmentLengthHandle = io_dataBlock.inputValue( ia_grassSegmentLength, & status);
        const float grassSegmentLength = grassSegmentLengthHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle grassNumSegmentsHandle = io_dataBlock.inputValue( ia_grassNumSegments, & status);
        const long grassNumSegments = grassNumSegmentsHandle.asLong();
        CHECK_MSTATUS( status );

        //MDataHandle windDirectionHandle = io_dataBlock.inputValue( ia_windDirection, & status);
        MFloatVector& windDirVec = io_dataBlock.inputValue( ia_windDirection, & status).asFloatVector();
        const Vcore::Vec3 windDirection = Vec3(windDirVec.x, windDirVec.y, windDirVec.z);
        CHECK_MSTATUS( status );

        MDataHandle grassBendAmountHandle = io_dataBlock.inputValue( ia_grassBendAmount, & status);
        const float grassBendAmount = grassBendAmountHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle windSpreadHandle = io_dataBlock.inputValue( ia_windSpread, & status);
        const float windSpread = windSpreadHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle clockHandle = io_dataBlock.inputValue( ia_clock, & status);
        const float clock = clockHandle.asLong();
        CHECK_MSTATUS( status );

        //Colours
        //-----------------
        MFloatVector& grassBaseColour1Vec = io_dataBlock.inputValue( ia_grassBaseColour1, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour1 = Vec3(grassBaseColour1Vec.x, grassBaseColour1Vec.y, grassBaseColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour1Vec = io_dataBlock.inputValue( ia_grassTipColour1, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour1 = Vec3(grassTipColour1Vec.x, grassTipColour1Vec.y, grassTipColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassBaseColour2Vec = io_dataBlock.inputValue( ia_grassBaseColour2, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour2 = Vec3(grassBaseColour2Vec.x, grassBaseColour2Vec.y, grassBaseColour2Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour2Vec = io_dataBlock.inputValue( ia_grassTipColour2, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour2 = Vec3(grassTipColour2Vec.x, grassTipColour2Vec.y, grassTipColour2Vec.z);
        CHECK_MSTATUS( status );


        //Update paramters of external lib system and rebuild
        m_island.setPlaneParameters( 
            planeSize, 
            planeHeight, 
            seed, 
            roughness, 
            resolution, 
            gridSize, 
            grassMultiplier, 
            baseWidth,
            grassSegmentLength, 
            grassNumSegments, 
            windDirection, 
            grassBendAmount, 
            windSpread, 
            clock, 
            smooth,
            grassBaseColour1,
            grassTipColour1,
            grassBaseColour2,
            grassTipColour2
        );
        
        //Rebuild object and check for success
        const bool updateOK = m_island.build();

        m_cachedVertices = m_island.getComponents( Vcore::Visland::VERTICES );
        m_cachedColours = m_island.getComponents( Vcore::Visland::COLOURS );
        m_cachedNormals = m_island.getComponents( Vcore::Visland::NORMALS );
        m_cachedIndices = m_island.getAllIndices();
        m_geomInstances = m_island.getAllGeometryInstances();
        
        // We must set a value for the plug we have been asked to evaluate,
        // even if we are not going to use it. We set it in the data-block,
        // and to set it we use outputValue().
        //
        // Here we usually set the result to true. The caller who triggered the
        // computation for this attribute might not look at the value that
        // we are setting this plug to. But they do ask for the value of this plug,
        // only to trigger an update of the internal structures. See the draw()
        // and boundingBox() methods to see how this is done.
        
        MDataHandle updateHandle = io_dataBlock.outputValue( i_plug );
        updateHandle.set( updateOK );
        
        //Need to set plug to clean to refresh it
        io_dataBlock.setClean( i_plug );
    }
    
    else if( i_plug == oa_rib ) {
        //Set up rib system to ready renderman values
        
        fprintf( stderr, "VmIslandNode::compute(oa_rib)\n" );
        
        MDataHandle seedHandle = io_dataBlock.inputValue( ia_seed, & status);
        const long seed = seedHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle smoothHandle = io_dataBlock.inputValue( ia_smooth, & status);
        const float smooth = smoothHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle roughnessHandle = io_dataBlock.inputValue( ia_roughness, & status);
        const float roughness = roughnessHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle rmanResolutionHandle = io_dataBlock.inputValue( ia_rmanResolution, & status);
        const long rmanResolution = rmanResolutionHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle planeHeightHandle = io_dataBlock.inputValue( ia_planeHeight, & status);
        const long planeHeight = planeHeightHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle planeSizeHandle = io_dataBlock.inputValue( ia_planeSize, & status);
        const long planeSize = planeSizeHandle.asLong();
        CHECK_MSTATUS( status );


        //Grass
        //----------------

        MDataHandle gridSizeHandle = io_dataBlock.inputValue( ia_gridSize, & status);
        const long gridSize = gridSizeHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle grassMultiplierHandle = io_dataBlock.inputValue( ia_grassMultiplier, & status);
        const long grassMultiplier = grassMultiplierHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle baseWidthHandle = io_dataBlock.inputValue( ia_baseWidth, & status);
        const float baseWidth = baseWidthHandle.asFloat();
        m_gridSize = (int) baseWidth;
        CHECK_MSTATUS( status );

        MDataHandle grassSegmentLengthHandle = io_dataBlock.inputValue( ia_grassSegmentLength, & status);
        const float grassSegmentLength = grassSegmentLengthHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle grassNumSegmentsHandle = io_dataBlock.inputValue( ia_grassNumSegments, & status);
        const long grassNumSegments = grassNumSegmentsHandle.asLong();
        CHECK_MSTATUS( status );

        MFloatVector& windDirVec = io_dataBlock.inputValue( ia_windDirection, & status).asFloatVector();
        const Vcore::Vec3 windDirection = Vec3(windDirVec.x, windDirVec.y, windDirVec.z);
        CHECK_MSTATUS( status );

        MDataHandle grassBendAmountHandle = io_dataBlock.inputValue( ia_grassBendAmount, & status);
        const float grassBendAmount = grassBendAmountHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle windSpreadHandle = io_dataBlock.inputValue( ia_windSpread, & status);
        const float windSpread = windSpreadHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle clockHandle = io_dataBlock.inputValue( ia_clock, & status);
        const float clock = clockHandle.asLong();
        CHECK_MSTATUS( status );

        //Colours
        //-------------------
        MFloatVector& grassBaseColour1Vec = io_dataBlock.inputValue( ia_grassBaseColour1, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour1 = Vec3(grassBaseColour1Vec.x, grassBaseColour1Vec.y, grassBaseColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour1Vec = io_dataBlock.inputValue( ia_grassTipColour1, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour1 = Vec3(grassTipColour1Vec.x, grassTipColour1Vec.y, grassTipColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassBaseColour2Vec = io_dataBlock.inputValue( ia_grassBaseColour2, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour2 = Vec3(grassBaseColour2Vec.x, grassBaseColour2Vec.y, grassBaseColour2Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour2Vec = io_dataBlock.inputValue( ia_grassTipColour2, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour2 = Vec3(grassTipColour2Vec.x, grassTipColour2Vec.y, grassTipColour2Vec.z);
        CHECK_MSTATUS( status );

        char rib[4096];
        sprintf( rib, "seed=%d;roughness=%f;planeHeight=%d;planeSize=%d;resolution=%d;gridSize=%d;grassMultiplier=%d;baseWidth=%f;grassSegmentLength=%f;grassNumSegments=%d;windDirectionX=%f;windDirectionY=%f;windDirectionZ=%f;grassBendAmount=%f;windSpread=%f;clock=%d;smooth=%d;grassBaseColour1X=%f;grassBaseColour1Y=%f;grassBaseColour1Z=%f;grassTipColour1X=%f;grassTipColour1Y=%f;grassTipColour1Z=%f;grassBaseColour2X=%f;grassBaseColour2Y=%f;grassBaseColour2Z=%f;grassTipColour2X=%f;grassTipColour2Y=%f;grassTipColour2Z=%f;",
            (int) seed, 
            (float) roughness, 
            (int) planeHeight, 
            (int) planeSize, 
            (int) rmanResolution , 
            (int) gridSize, 
            (int) grassMultiplier, 
            (float) baseWidth,
            (float) grassSegmentLength, 
            (int) grassNumSegments, 
            (float) windDirection.x, 
            (float) windDirection.y,
            (float) windDirection.z,
            (float) grassBendAmount, 
            (float) windSpread,
            (int) clock,
            (int) smooth,
            (float) grassBaseColour1.x,
            (float) grassBaseColour1.y,
            (float) grassBaseColour1.z,
            (float) grassTipColour1.x,
            (float) grassTipColour1.y,
            (float) grassTipColour1.z,
            (float) grassBaseColour2.x,
            (float) grassBaseColour2.y,
            (float) grassBaseColour2.z,
            (float) grassTipColour2.x,
            (float) grassTipColour2.y,
            (float) grassTipColour2.z
        );        
        
        // We must set a value for the plug we have been asked to evaluate,
        // even if we are not going to use it. We set it in the data-block,
        // and to set it we use outputValue().
        //
        // Here we are calculating a string value, and that value will 
        // be used by the caller in a "rib-gen" operation - a process in 
        // which a RIB file is generated for Renderman.
        //
        // Notice also that strings in Maya or more complicated than numbers.
        // We need to make a data object for the string data.
        
        MFnStringData stringDataFn;
        MObject stringDataObj = stringDataFn.create( rib, & status );
        CHECK_MSTATUS( status );
        
        MDataHandle ribHandle = io_dataBlock.outputValue( i_plug );
        ribHandle.set( stringDataObj );
        io_dataBlock.setClean( i_plug );
    }
    
    else {
        //Shouldn't be here.
        return MStatus::kSuccess;
    }
}
示例#8
0
MStatus splatDeformer::compute(const MPlug& plug, MDataBlock& data)
{
	// do this if we are using an OpenMP implementation that is not the same as Maya's.
	// Even if it is the same, it does no harm to make this call.
	MThreadUtils::syncNumOpenMPThreads();

	MStatus status = MStatus::kUnknownParameter;
 	if (plug.attribute() != outputGeom) {
		return status;
	}

	unsigned int index = plug.logicalIndex();
	MObject thisNode = this->thisMObject();

	// get input value
	MPlug inPlug(thisNode,input);
	inPlug.selectAncestorLogicalIndex(index,input);
	MDataHandle hInput = data.inputValue(inPlug, &status);
	MCheckStatus(status, "ERROR getting input mesh\n");
	
	// get the input geometry
	MDataHandle inputData = hInput.child(inputGeom);
	if (inputData.type() != MFnData::kMesh) {
 		printf("Incorrect input geometry type\n");
		return MStatus::kFailure;
 	}

	// get the input groupId - ignored for now...
	MDataHandle hGroup = inputData.child(groupId);
	unsigned int groupId = hGroup.asLong();

	// get deforming mesh
	MDataHandle deformData = data.inputValue(deformingMesh, &status);
	MCheckStatus(status, "ERROR getting deforming mesh\n");
    if (deformData.type() != MFnData::kMesh) {
		printf("Incorrect deformer geometry type %d\n", deformData.type());
		return MStatus::kFailure;
	}

  	MObject dSurf = deformData.asMeshTransformed();
 	MFnMesh fnDeformingMesh;
 	fnDeformingMesh.setObject( dSurf ) ;

	MDataHandle outputData = data.outputValue(plug);
	outputData.copy(inputData);
 	if (outputData.type() != MFnData::kMesh) {
		printf("Incorrect output mesh type\n");
		return MStatus::kFailure;
	}
	
	MItGeometry iter(outputData, groupId, false);

	// create fast intersector structure
	MMeshIntersector intersector;
	intersector.create(dSurf);

	// get all points at once. Faster to query, and also better for
	// threading than using iterator
	MPointArray verts;
	iter.allPositions(verts);
	int nPoints = verts.length();

	// use bool variable as lightweight object for failure check in loop below
	bool failed = false;

 	MTimer timer; timer.beginTimer();

#ifdef _OPENMP
#pragma omp parallel for
#endif
 	for(int i=0; i<nPoints; i++) {

		// Cannot break out of an OpenMP loop, so if one of the
		// intersections failed, skip the rest
		if(failed) continue;

		// mesh point object must be in loop-local scope to avoid race conditions
		MPointOnMesh meshPoint;

		// Do intersection. Need to use per-thread status value as
		// MStatus has internal state and may trigger race conditions
		// if set from multiple threads. Probably benign in this case,
		// but worth being careful.
		MStatus localStatus = intersector.getClosestPoint(verts[i], meshPoint);
		if(localStatus != MStatus::kSuccess) {
			// NOTE - we cannot break out of an OpenMP region, so set
			// bad status and skip remaining iterations
			failed = true;
			continue;
		}

		// default OpenMP scheduling breaks traversal into large
		// chunks, so low risk of false sharing here in array write.
		verts[i] = meshPoint.getPoint();
 	}

 	timer.endTimer(); printf("Runtime for threaded loop %f\n", timer.elapsedTime());

	// write values back onto output using fast set method on iterator
	iter.setAllPositions(verts);

	if(failed) {
		printf("Closest point failed\n");
		return MStatus::kFailure;
	}

	return status;
}
示例#9
0
MStatus multiCurve::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus stat;

	if ( plug == outputCurves )
	{
		MDataHandle numCurvesHandle =  data.inputValue(numCurves, &stat);
		PERRORfail(stat, "multiCurve::compute getting numCurves");
		int num = numCurvesHandle.asLong();

		MDataHandle curveOffsetHandle =  data.inputValue(curveOffset, &stat);
		PERRORfail(stat, "multiCurve::compute getting curveOffset");
		double baseOffset = curveOffsetHandle.asDouble();

		MDataHandle inputCurveHandle = data.inputValue(inputCurve, &stat);
		PERRORfail(stat, "multiCurve::compute getting inputCurve");

		MObject inputCurveObject ( inputCurveHandle.asNurbsCurveTransformed() );
		MFnNurbsCurve inCurveFS ( inputCurveObject );

		MArrayDataHandle outputArray = data.outputArrayValue(outputCurves,
															 &stat);
		PERRORfail(stat, "multiCurve::compute getting output data handle");

		// Create an array data build that is preallocated to hold just
		// the number of curves we plan on creating.  When this builder
		// is set in to the MArrayDataHandle at the end of the compute
		// method, the new array will replace the existing array in the
		// scene.
		// 
		// If the number of elements of the multi does not change between
		// compute cycles, then one can reuse the space allocated on a
		// previous cycle by extracting the existing builder from the
		// MArrayDataHandle:
		//		MArrayDataBuilder builder( outputArray.builder(&stat) );
		// this later form of the builder will allow you to rewrite elements
		// of the array, and to grow it, but the array can only be shrunk by
		// explicitly removing elements with the method
		//		MArrayDataBuilder::removeElement(unsigned index);
		//
		MArrayDataBuilder builder(outputCurves, num, &stat);
		PERRORfail(stat, "multiCurve::compute creating builder");
		
		for (int curveNum = 0; curveNum < num; curveNum++) {
			MDataHandle outHandle = builder.addElement(curveNum);
			MFnNurbsCurveData dataCreator;
			MObject outCurveData = dataCreator.create();
			MObject outputCurve  = inCurveFS.copy(inputCurveObject,
												  outCurveData, &stat);
			PERRORfail(stat, "multiCurve::compute copying curve");

			MFnNurbsCurve outCurveFS ( outputCurve );
			MPointArray cvs;

			double offset = baseOffset * (curveNum+1);

			outCurveFS.getCVs ( cvs, MSpace::kWorld );
			int numCVs = cvs.length();
			for (int i = 0; i < numCVs; i++) {
				cvs[i].x += offset;
			}
			outCurveFS.setCVs ( cvs );

			outHandle.set(outCurveData);
		}
		
		// Set the builder back into the output array.  This statement
		// is always required, no matter what constructor was used to
		// create the builder.
		stat = outputArray.set(builder);
		PERRORfail(stat, "multiCurve::compute setting the builder");

		// Since we compute all the elements of the array, instead of
		// just marking the plug we were asked to compute as clean, mark
		// every element of the array as clean to prevent further calls
		// to this compute method during this DG evaluation cycle.
		stat = outputArray.setAllClean();
		PERRORfail(stat, "multiCurve::compute cleaning outputCurves");

	} else {
		return MS::kUnknownParameter;
	}
	
	return stat;
}
示例#10
0
MStatus finalproject::compute(const MPlug& plug, MDataBlock& data)
{
	// do this if we are using an OpenMP implementation that is not the same as Maya's.
	// Even if it is the same, it does no harm to make this call.
	MThreadUtils::syncNumOpenMPThreads();

	MStatus status = MStatus::kUnknownParameter;
 	if (plug.attribute() != outputGeom) {
		return status;
	}

	unsigned int index = plug.logicalIndex();
	MObject thisNode = this->thisMObject();

	// get input value
	MPlug inPlug(thisNode,input);
	inPlug.selectAncestorLogicalIndex(index,input);
	MDataHandle hInput = data.inputValue(inPlug, &status);
	MCheckStatus(status, "ERROR getting input mesh\n");
	
	// get the input geometry
	MDataHandle inputData = hInput.child(inputGeom);
	if (inputData.type() != MFnData::kMesh) {
 		printf("Incorrect input geometry type\n");
		return MStatus::kFailure;
 	}

	// get the input groupId - ignored for now...
	MDataHandle hGroup = inputData.child(groupId);
	unsigned int groupId = hGroup.asLong();

	// get deforming mesh
	MDataHandle deformData = data.inputValue(deformingMesh, &status);
	MCheckStatus(status, "ERROR getting deforming mesh\n");
    if (deformData.type() != MFnData::kMesh) {
		printf("Incorrect deformer geometry type %d\n", deformData.type());
		return MStatus::kFailure;
	}
	
   MDataHandle offloadData = data.inputValue(offload, &status);

   //gathers world space positions of the object and the magnet
  	MObject dSurf = deformData.asMeshTransformed();
  	MObject iSurf = inputData.asMeshTransformed();
 	MFnMesh fnDeformingMesh, fnInputMesh;
 	fnDeformingMesh.setObject( dSurf ) ;
 	fnInputMesh.setObject( iSurf ) ;

	MDataHandle outputData = data.outputValue(plug);
	outputData.copy(inputData);
 	if (outputData.type() != MFnData::kMesh) {
		printf("Incorrect output mesh type\n");
		return MStatus::kFailure;
	}
	
	MItGeometry iter(outputData, groupId, false);

	// get all points at once. Faster to query, and also better for
	// threading than using iterator
	MPointArray objVerts;
	iter.allPositions(objVerts);
	int objNumPoints = objVerts.length();
 	
 	MPointArray magVerts, tempverts;
 	fnDeformingMesh.getPoints(magVerts);
 	fnInputMesh.getPoints(tempverts);
 	int magNumPoints = magVerts.length();
 	
 	double min = DBL_MAX, max = -DBL_MAX;
   
   //finds min and max z-coordinate values to determine middle point (choice of z-axis was ours)
 	for (int i = 0; i < magNumPoints; i++) {
      min = magVerts[i].z < min ? magVerts[i].z : min;
      max = magVerts[i].z > max ? magVerts[i].z : max;
   }

   double middle = (min + max) / 2;
   double polarity[magNumPoints];
   
   //assigns polarity based on middle point of mesh
   for (int i = 0; i < magNumPoints; i++) {
      polarity[i] = magVerts[i].z > middle ? max / magVerts[i].z : -min / magVerts[i].z;
   }
 	
 	double* objdVerts = (double *)malloc(sizeof(double) * objNumPoints * 3);
 	double* magdVerts = (double *)malloc(sizeof(double) * magNumPoints * 3);
 	
   //creates handles to use attribute data
 	MDataHandle vecX = data.inputValue(transX, &status);
   MDataHandle vecY = data.inputValue(transY, &status);
   MDataHandle vecZ = data.inputValue(transZ, &status);
   
   //gathers previously stored coordinates of the center of the object
   double moveX = vecX.asFloat();
   double moveY = vecY.asFloat();
   double moveZ = vecZ.asFloat();
 	
   //translates object based on the position stored in the attribute values
 	for (int i=0; i<objNumPoints; i++) {
 	   objdVerts[i * 3] = tempverts[i].x + moveX;
 	   objdVerts[i * 3 + 1] = tempverts[i].y + moveY;
 	   objdVerts[i * 3 + 2] = tempverts[i].z + moveZ;
 	}
 	
 	for (int i=0; i<magNumPoints; i++) {
 	   magdVerts[i * 3] = magVerts[i].x;
 	   magdVerts[i * 3 + 1] = magVerts[i].y;
 	   magdVerts[i * 3 + 2] = magVerts[i].z;
 	}
 	
 	double teslaData = data.inputValue(tesla, &status).asDouble();
   MDataHandle posiData = data.inputValue(positivelycharged, &status);
   
   double pivot[6] = {DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX};
   
   //finds the pivot point of the object in world space prior to being affected by the magnet
 	for (int i = 0; i < tempverts.length(); i++) {
      pivot[0] = tempverts[i].x < pivot[0] ? tempverts[i].x : pivot[0];
      pivot[1] = tempverts[i].x > pivot[1] ? tempverts[i].x : pivot[1];
      pivot[2] = tempverts[i].y < pivot[2] ? tempverts[i].y : pivot[2];
      pivot[3] = tempverts[i].y > pivot[3] ? tempverts[i].y : pivot[3];
      pivot[4] = tempverts[i].z < pivot[4] ? tempverts[i].z : pivot[4];
      pivot[5] = tempverts[i].z > pivot[5] ? tempverts[i].z : pivot[5];
   }
   
   MTimer timer; timer.beginTimer();
 	
   //main function call
   magnetForce(magNumPoints, objNumPoints, teslaData, magdVerts, 
      objdVerts, polarity, posiData.asBool(), offloadData.asBool());
      
   timer.endTimer(); printf("Runtime for threaded loop %f\n", timer.elapsedTime());
 	
 	for (int i=0; i<objNumPoints; i++) {
 	   objVerts[i].x = objdVerts[i * 3 + 0];
 	   objVerts[i].y = objdVerts[i * 3 + 1];
 	   objVerts[i].z = objdVerts[i * 3 + 2];      
 	}
 	
   //finds the pivot point of object in world space after being affected by the magnet
   double objCenter[6] = {DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX};
 	for (int i = 0; i < tempverts.length(); i++) {
      objCenter[0] = objVerts[i].x < objCenter[0] ? objVerts[i].x : objCenter[0];
      objCenter[1] = objVerts[i].x > objCenter[1] ? objVerts[i].x : objCenter[1];
      objCenter[2] = objVerts[i].y < objCenter[2] ? objVerts[i].y : objCenter[2];
      objCenter[3] = objVerts[i].y > objCenter[3] ? objVerts[i].y : objCenter[3];
      objCenter[4] = objVerts[i].z < objCenter[4] ? objVerts[i].z : objCenter[4];
      objCenter[5] = objVerts[i].z > objCenter[5] ? objVerts[i].z : objCenter[5];
   }
 	
   //creates vector based on the two calculated pivot points
 	moveX = (objCenter[0] + objCenter[1]) / 2 - (pivot[0] + pivot[1]) / 2;
 	moveY = (objCenter[2] + objCenter[3]) / 2 - (pivot[2] + pivot[3]) / 2;
 	moveZ = (objCenter[4] + objCenter[5]) / 2 - (pivot[4] + pivot[5]) / 2;
 	
   //stores pivot vector for next computation
 	if (teslaData) {
 	   vecX.setFloat(moveX);
 	   vecY.setFloat(moveY);
 	   vecZ.setFloat(moveZ);
 	}
 	
	// write values back onto output using fast set method on iterator
	iter.setAllPositions(objVerts, MSpace::kWorld);
   
   free(objdVerts);
   free(magdVerts);

	return status;
}