void SurfaceAttach::setOutPlugs(MDataBlock dataBlock, const MFnNurbsSurface &fnSurface,
                                const double dataOffset, const bool dataReverse, const short dataGenus, const double dataStaticLength,
                                const MMatrix &dataParentInverse, const short dataDirection) {

    MTransformationMatrix tfm;
    MVector t;
    MEulerRotation r;

    MArrayDataHandle outputHandle = dataBlock.outputArrayValue(SurfaceAttach::out);
    std::int32_t count = outputHandle.elementCount();
    MDataHandle o;

    for (unsigned int k = 0; k < count; ++k) {
        outputHandle.jumpToElement(k);

        // Get Transformations
        tfm = this->matrix(fnSurface, outputHandle.elementIndex(), dataOffset, dataReverse, dataGenus,
                           dataStaticLength, dataParentInverse, dataDirection);
        t = tfm.translation(MSpace::Space::kWorld);
        r = tfm.eulerRotation();

        o = outputHandle.outputValue();
        o.child(SurfaceAttach::translate).set(t);
        o.child(SurfaceAttach::rotate).set(r.x, r.y, r.z);
    }

    // Mark Clean
    dataBlock.setClean(SurfaceAttach::translate);
    dataBlock.setClean(SurfaceAttach::rotate);
    dataBlock.setClean(SurfaceAttach::out);
}
Beispiel #2
0
//
// DESCRIPTION:
///////////////////////////////////////////////////////
MStatus mtmEnvLight::compute(
const MPlug&      plug,
      MDataBlock& block ) 
{ 
    if ((plug != aLightData) && (plug.parent() != aLightData))
		return MS::kUnknownParameter;

    MFloatVector resultColor;

	// Real user input
    MFloatVector LColor(1,0,0);
    //MFloatVector& LColor  = block.inputValue( aColor ).asFloatVector();
    // MFloatVector& Position  = block.inputValue( aPosition ).asFloatVector();
    float LIntensity  = block.inputValue( aIntensity ).asFloat();

	// Components to build LightData
    MFloatVector& LDirection  = block.inputValue( aInputDirection ).asFloatVector();
    bool  LAmbient  = block.inputValue( aInputAmbient ).asBool();
    bool  LDiffuse  = block.inputValue( aInputDiffuse ).asBool();
    bool  LSpecular = block.inputValue( aInputSpecular ).asBool();


    resultColor = LColor * LIntensity;
  
    // set ouput color attribute
    MDataHandle outLightDataHandle = block.outputValue( aLightData );

    MFloatVector& outIntensity = outLightDataHandle.child(aLightIntensity).asFloatVector();
    outIntensity = resultColor;

    MFloatVector& outDirection = outLightDataHandle.child(aLightDirection).asFloatVector();

    outDirection = LDirection;

    bool& outAmbient = outLightDataHandle.child(aLightAmbient).asBool();
    outAmbient = LAmbient;
    bool& outDiffuse = outLightDataHandle.child(aLightDiffuse).asBool();
    outDiffuse = LDiffuse;
    bool& outSpecular = outLightDataHandle.child(aLightSpecular).asBool();
    outSpecular = LSpecular;

    float& outSFraction = outLightDataHandle.child(aLightShadowFraction).asFloat();
    outSFraction = 1.0f;

    float& outPSIntensity = outLightDataHandle.child(aPreShadowIntensity).asFloat();
    outPSIntensity = (resultColor[0] + resultColor[1] + resultColor[2]) / 3.0f;

	void*& outBlindData = outLightDataHandle.child(aLightBlindData).asAddr();
	outBlindData = NULL;

    outLightDataHandle.setClean();


    return MS::kSuccess;
}
//
// DESCRIPTION:
///////////////////////////////////////////////////////
MStatus ShadowMatte::compute(
const MPlug&      plug,
      MDataBlock& block ) 
{
    if ((plug != aOutColor) && (plug.parent() != aOutColor) &&
		(plug != aOutTransparency) && (plug.parent() != aOutTransparency))
		return MS::kUnknownParameter;

    MFloatVector shadowColor(0.0,0.0,0.0);

    bool  ViewFlag  = block.inputValue( aViewColor ).asBool();

    // get light list
    MArrayDataHandle lightData = block.inputArrayValue( aLightData );
    int numLights = lightData.elementCount();

    // iterate through light list and get ambient/diffuse values
    for( int count=1; count <= numLights; count++ )
    {
        MDataHandle currentLight = lightData.inputValue();
        float lightShadow = currentLight.child(aLightShadowFraction).asFloat();

		// shadow fraction tells how much an object is in shadow:
		// (1)   totally in shadow
		// (0-1) partially in shadow
		// (0)   not in shadow

        shadowColor[0] += lightShadow;
        shadowColor[1] += lightShadow;
        shadowColor[2] += lightShadow;
     
        if( !lightData.next() ) break;
    }

    // set ouput color attribute
    MFloatVector ghostColor(0.0,0.0,0.0);
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();

    if (ViewFlag)
        outColor = shadowColor;
    else
        outColor = ghostColor;

    outColorHandle.setClean();

    // set ouput transparency
    MDataHandle outTransHandle = block.outputValue( aOutTransparency );
    MFloatVector& outTrans = outTransHandle.asFloatVector();
    outTrans = shadowColor;
    outTransHandle.setClean();

    return MS::kSuccess;
}
Beispiel #4
0
MStatus RippleDeformer::deform(MDataBlock& dataBlock,
								MItGeometry& itGeo,
								const MMatrix& localToWorldMatrix,
								unsigned int geomIndex)
{
	MStatus status;
	
	//get attriubtes as a datahandle
	float env = dataBlock.inputValue(envelope).asFloat();
	float amplitude = dataBlock.inputValue(aAmplitude).asFloat();
	float displace = dataBlock.inputValue(aDisplace).asFloat();
	//get the mesh 
	
	//retrieve the handle to the input attribute
	MArrayDataHandle hInput = dataBlock.outputArrayValue(input, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	//get the input array index handle
	status = hInput.jumpToElement(geomIndex);
	//get the handle of geomIndex attribute
	MDataHandle hInputElement = hInput.outputValue(&status);
	//Get the MObject of the input geometry of geomindex
	MObject oInputGeom = hInputElement.child(inputGeom).asMesh();

	MFnMesh fnMesh(oInputGeom, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	if (oInputGeom.isNull())
	{
		return MS::kSuccess;
	}

	MFloatVectorArray normals;
	fnMesh.getVertexNormals(false, normals);

	MPoint pointPos;
	float weight;
	
	for (; !itGeo.isDone(); itGeo.next())
	{
		//get current point position
		pointPos = itGeo.position();
		weight = weightValue(dataBlock, geomIndex, itGeo.index());
		pointPos.x = pointPos.x + sin(itGeo.index() + displace) * amplitude * normals[itGeo.index()].x * weight * env;
		pointPos.y = pointPos.y + sin(itGeo.index() + displace) * amplitude * normals[itGeo.index()].y * weight * env;
		pointPos.z = pointPos.z + sin(itGeo.index() + displace) * amplitude * normals[itGeo.index()].z * weight * env;
		//setPosition
		itGeo.setPosition(pointPos);
	}	
	
	return MS::kSuccess;
}
MStatus anisotropicShaderNode::compute( const MPlug& plug, MDataBlock& block )
{
    if ((plug == aOutColor) || (plug.parent() == aOutColor))
	{
        MFloatVector resultColor(0.0,0.0,0.0);
        MFloatVector diffuseColor( 0.0,0.0,0.0 );
        MFloatVector specularColor( 0.0,0.0,0.0 );
        MFloatVector ambientColor( 0.0,0.0,0.0 );

        // get matrix
        MFloatMatrix& matrixOToW = block.inputValue( aMatrixOToW ).asFloatMatrix();
        MFloatMatrix& matrixWToC = block.inputValue( aMatrixWToC ).asFloatMatrix();

        // spin scratch around this vector (in object space )
        MFloatVector& A = block.inputValue( aAxesVector ).asFloatVector();
        A.normalize();

        // spin scratch around this vector (in world space )
        MFloatVector wa = A * matrixOToW;
        wa.normalize();

        // spin scratch around this vector (in camera space )
        MFloatVector ca = wa * matrixWToC;
        ca.normalize();

        MFloatVector& surfacePoint = block.inputValue( aPointCamera ).asFloatVector();

        // get sample surface shading parameters
        MFloatVector& N = block.inputValue( aNormalCamera ).asFloatVector();
        MFloatVector& surfaceColor = block.inputValue( aColor ).asFloatVector();

        float diffuseReflectivity = block.inputValue( aDiffuseReflectivity ).asFloat();
        float specularCoeff = block.inputValue( aSpecularCoeff ).asFloat();

        // get light list
        MArrayDataHandle lightData = block.inputArrayValue( aLightData );
        int numLights = lightData.elementCount();

        // iterate through light list and get ambient/diffuse values
        for( int count=0; count < numLights; count++ ) {
            MDataHandle currentLight = lightData.inputValue();

            MFloatVector& lightIntensity = 
                currentLight.child( aLightIntensity ).asFloatVector();
            MFloatVector& lightDirection = 
                currentLight.child( aLightDirection ).asFloatVector();

            // find ambient component
            if( currentLight.child(aLightAmbient).asBool()) {
                ambientColor[0] += lightIntensity[0] * surfaceColor[0];
                ambientColor[1] += lightIntensity[1] * surfaceColor[1];
                ambientColor[2] += lightIntensity[2] * surfaceColor[2];
            }

            float cosln = lightDirection * N;
            if( cosln > 0.0f ){ // illuminated!

                // find diffuse component
                if( currentLight.child(aLightDiffuse).asBool()) {
                
                    float cosDif = cosln * diffuseReflectivity;
                    diffuseColor[0] += lightIntensity[0] * cosDif * surfaceColor[0];
                    diffuseColor[1] += lightIntensity[1] * cosDif * surfaceColor[1];
                    diffuseColor[2] += lightIntensity[2] * cosDif * surfaceColor[2];
                }

                // find specular component
                if( currentLight.child( aLightSpecular).asBool()){

                    MFloatVector& rayDirection = block.inputValue( aRayDirection ).asFloatVector();
                    MFloatVector viewDirection = -rayDirection;
                    MFloatVector half = calcHalfVector( viewDirection, lightDirection );


                    // Beckmann function

                    MFloatVector nA;
                    if( fabs(1.0-fabs(N*ca)) <= 0.0001f ){
                        MFloatPoint oo( 0.0,0.0,0.0 );
                        MFloatPoint ow = oo * matrixOToW;
                        MFloatPoint oc = ow * matrixWToC;
                        MFloatVector origin( oc[0], oc[1], oc[2] );
                        nA = origin - surfacePoint;
                        nA.normalize();
                    }else{
                        nA = ca;
                    }

                    MFloatVector x = N ^ nA;
                    x.normalize();
                    MFloatVector y = N ^ x;
                    y.normalize();

                    MFloatVector azimuthH = N ^ half;
                    azimuthH = N ^ azimuthH;
                    azimuthH.normalize();

                    float cos_phai = x * azimuthH;
                    float sin_phai = 0.0;
                    if( fabs(1 - cos_phai*cos_phai) < 0.0001 ){
                        sin_phai = 0.0;
                    }else{
                        sin_phai = sqrtf( 1.0f - cos_phai*cos_phai );
                    }
                    double co = pow( (half * N), 4.0f );
                    double t = tan( acos(half*N) );
                    t *= -t;

                    float rough1 = block.inputValue( aRoughness1 ).asFloat();
                    float rough2 = block.inputValue( aRoughness2 ).asFloat();

                    double aaa = cos_phai / rough1;
                    double bbb = sin_phai / rough2;

                    t = t * ( aaa*aaa + bbb*bbb );

                    double D = pow( (1.0/((double)rough1*(double)rough2 * co)), t );

                    double aa = (2.0 * (N*half) * (N*viewDirection) ) / (viewDirection*half);
                    double bb = (2.0 * (N*half) * (N*lightDirection) ) / (viewDirection*half);
                    double cc = 1.0;
                    double G = 0.0;
                    G = MIN( aa, bb );
                    G = MIN( G, cc );

                    float s = (float) (D * G /
                            (double)((N*lightDirection) * (N*viewDirection)));
                    MFloatVector& specColor = block.inputValue( aSpecColor ).asFloatVector();
                    specularColor[0] += lightIntensity[0] * specColor[0] * 
                                            s * specularCoeff;
                    specularColor[1] += lightIntensity[1] * specColor[1] * 
                                            s * specularCoeff;
                    specularColor[2] += lightIntensity[2] * specColor[2] * 
                                            s * specularCoeff;
                }
            }

            if( !lightData.next() ){
                break;
            }
        }

        // result = specular + diffuse + ambient;
        resultColor = diffuseColor + specularColor + ambientColor;

        MFloatVector& transparency = block.inputValue( aInTransparency ).asFloatVector();
        resultColor[0] *= ( 1.0f - transparency[0] );
        resultColor[1] *= ( 1.0f - transparency[1] );
        resultColor[2] *= ( 1.0f - transparency[2] );

        // set ouput color attribute
        MDataHandle outColorHandle = block.outputValue( aOutColor );
        MFloatVector& outColor = outColorHandle.asFloatVector();
        outColor = resultColor;
        outColorHandle.setClean();
        block.setClean( plug );
    }
	else if ((plug == aOutTransparency) || (plug.parent() == aOutTransparency))
	{
        MFloatVector& tr = block.inputValue( aInTransparency ).asFloatVector();

        // set ouput color attribute
        MDataHandle outTransHandle = block.outputValue( aOutTransparency );
        MFloatVector& outTrans = outTransHandle.asFloatVector();
        outTrans = tr;
        block.setClean( plug );
    } else
		return MS::kUnknownParameter;

    return MS::kSuccess;
}
Beispiel #6
0
MStatus sgBulgeDeformer::deform(MDataBlock& dataBlock, MItGeometry& iter, const MMatrix& mtx, unsigned int index)
{
	MStatus status;

	float bulgeWeight = dataBlock.inputValue(aBulgeWeight).asFloat();
	double bulgeRadius = dataBlock.inputValue(aBulgeRadius).asDouble();

	MArrayDataHandle hArrInputs = dataBlock.inputArrayValue(aBulgeInputs);

	MPointArray allPositions;
	iter.allPositions(allPositions);

	if (mem_resetElements)
	{
		unsigned int elementCount = hArrInputs.elementCount();
		mem_meshInfosInner.resize(mem_maxLogicalIndex);
		mem_meshInfosOuter.resize(mem_maxLogicalIndex);

		for (unsigned int i = 0; i < elementCount; i++, hArrInputs.next())
		{
			MDataHandle hInput = hArrInputs.inputValue();
			MDataHandle hMatrix = hInput.child(aMatrix);
			MDataHandle hMesh   = hInput.child(aMesh);

			MMatrix mtxMesh = hMatrix.asMatrix();
			MObject oMesh   = hMesh.asMesh();

			MFnMeshData meshDataInner, meshDataOuter;
			MObject oMeshInner = meshDataInner.create();
			MObject oMeshOuter = meshDataOuter.create();
			MFnMesh fnMesh;
			fnMesh.copy(oMesh, oMeshInner);
			fnMesh.copy(oMesh, oMeshOuter);

			sgMeshInfo* newMeshInfoInner = new sgMeshInfo(oMeshInner, hMatrix.asMatrix());
			sgMeshInfo* newMeshInfoOuter = new sgMeshInfo(oMeshOuter, hMatrix.asMatrix());

			mem_meshInfosInner[hArrInputs.elementIndex()] = newMeshInfoInner;
			mem_meshInfosOuter[hArrInputs.elementIndex()] = newMeshInfoOuter;
		}
	}
	
	for (unsigned int i = 0; i < elementCount; i++)
	{
		mem_meshInfosInner[i]->setBulge(bulgeWeight, MSpace::kWorld );
	}
	
	MFloatArray weightList;
	weightList.setLength(allPositions.length());
	for (unsigned int i = 0; i < weightList.length(); i++)
		weightList[i] = 0.0f;
	MMatrixArray inputMeshMatrixInverses;
	inputMeshMatrixInverses.setLength(elementCount);
	for (unsigned int i = 0; i < elementCount; i++)
	{
		inputMeshMatrixInverses[i] = mem_meshInfosInner[i]->matrix();
	}

	for (unsigned int i = 0; i < allPositions.length(); i++)
	{
		float resultWeight = 0;
		for (unsigned int infoIndex = 0; infoIndex < elementCount; infoIndex++)
		{
			MPoint localPoint = allPositions[i] * mtx* inputMeshMatrixInverses[infoIndex];
			MPoint innerPoint = mem_meshInfosInner[infoIndex]->getClosestPoint(localPoint);
			MPoint outerPoint = mem_meshInfosOuter[infoIndex]->getClosestPoint(localPoint);
			MVector innerVector = innerPoint - localPoint;
			MVector outerVector = outerPoint - localPoint;

			if (innerVector * outerVector < 0)
			{
				double innerLength = innerVector.length();
				double outerLength = outerVector.length();
				double allLength = innerLength + outerLength;

				float numerator = float( innerLength * outerLength );
				float denominator = float( pow(allLength / 2.0, 2) );

				resultWeight = numerator / denominator;
			}
		}
		weightList[i] = resultWeight;
	}

	for (unsigned int i = 0; i < allPositions.length(); i++)
	{
		allPositions[i] += weightList[i] * MVector(0, 1, 0);
	}
	
	iter.setAllPositions(allPositions);

	return MS::kSuccess;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MStatus CVstWeldNode::compute(
	const MPlug &mPlug,
	MDataBlock &mDataBlock )
{
	if ( mPlug == m_oaWeldOutput || mPlug == m_oaTranslate || mPlug == m_oaRotate ||
			mPlug == m_oaTranslateX || mPlug == m_oaTranslateY || mPlug == m_oaTranslateZ ||
			mPlug == m_oaRotateX || mPlug == m_oaRotateY || mPlug == m_oaRotateZ )
	{
		const MObject geoObj = mDataBlock.inputValue( m_iaWorldGeometry ).data();
		if ( geoObj.apiType() == MFn::kMeshData )
		{
			MStatus mStatus;

			MObject meshObj = mDataBlock.inputValue( m_iaWorldGeometry ).asMeshTransformed();
			MFnMesh meshFn( meshObj );
			MItMeshPolygon pIt( meshObj );
			MPointArray facePoints;

			MArrayDataHandle wiAH = mDataBlock.inputArrayValue( m_iaWeldInput );
			MArrayDataHandle woAH = mDataBlock.outputArrayValue( m_oaWeldOutput, &mStatus );
			MArrayDataBuilder woADB = woAH.builder( &mStatus );

			const int nWeldCount = wiAH.elementCount();
			for ( int i = 0; i < nWeldCount; ++i, wiAH.next() )
			{
				MDataHandle wiDH = wiAH.inputValue();

				const MMatrix &offsetMatrix = wiDH.child( m_iaOffsetMatrix ).asMatrix();
				const MMatrix &inverseParentSpace = wiDH.child( m_iaInverseParentSpace ).asMatrix();
				const MEulerRotation::RotationOrder rotationOrder = static_cast< MEulerRotation::RotationOrder >( wiDH.child( m_iaRotateOrder ).asShort() );
				MMatrix geoMatrix;

				switch ( wiDH.child( m_iaType ).asShort() )
				{
				case kMeshFace:
					{
						const int nMeshFaceIndex = wiDH.child( m_iaInt ).asInt();
						GetMeshMatrix( pIt, nMeshFaceIndex, geoMatrix );
					}
					break;
				default:
					merr << "Unknown Weld Type " << wiDH.child( m_iaType ).asShort() << std::endl;
					break;
				}

				const int nWeldIndex = wiAH.elementIndex();
				MDataHandle woDH = woADB.addElement( nWeldIndex );

				MTransformationMatrix L( inverseParentSpace * offsetMatrix * geoMatrix );

				woDH.child( m_oaTranslate ).set( L.getTranslation( MSpace::kWorld ) );
				MEulerRotation e = L.rotation().asEulerRotation();
				e.reorder( rotationOrder );
				woDH.child( m_oaRotate ).set( e.asVector() );
			}
		}
		else
		{
			merr << "Invalid .inputGeometry data of type: " << geoObj.apiTypeStr() << " found while computing " << mPlug.info() << std::endl;
			return MS::kFailure;
		}

		return MS::kSuccess;
	}

	return MS::kUnknownParameter;
}
Beispiel #8
0
MStatus sseDeformer::compute(const MPlug& plug, MDataBlock& data)
{
    MStatus status;
    if (plug.attribute() != outputGeom) {
        printf("Ignoring requested plug\n");
        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;
    }

    MObject iSurf = inputData.asMesh() ;
    MFnMesh inMesh;
    inMesh.setObject( iSurf ) ;

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

    MObject oSurf = outputData.asMesh() ;
    if(oSurf.isNull()) {
        printf("Output surface is NULL\n");
        return MStatus::kFailure;
    }

    MFnMesh outMesh;
    outMesh.setObject( oSurf ) ;
    MCheckStatus(status, "ERROR setting points\n");

    // get all points at once for demo purposes. Really should get points from the current group using iterator
    MFloatPointArray pts;
    outMesh.getPoints(pts);

    int nPoints = pts.length();

    MDataHandle envData = data.inputValue(envelope, &status);
    float env = envData.asFloat();

    MDataHandle sseData = data.inputValue(sseEnabled, &status);
    bool sseEnabled = (bool) sseData.asBool();

    // NOTE: Using MTimer and possibly other classes disables
    // autovectorization with Intel <=10.1 compiler on OSX and Linux!!
    // Must compile this function with -fno-exceptions on OSX and
    // Linux to guarantee autovectorization is done. Use -fvec_report2
    // to check for vectorization status messages with Intel compiler.
    MTimer timer;
    timer.beginTimer();

    if(sseEnabled) {

        // Innter loop will autovectorize. Around 3x faster than the
        // loop below it. It would be faster if first element was
        // guaranteed to be aligned on 16 byte boundary.
        for(int i=0; i<nPoints; i++) {
            float* ptPtr = &pts[i].x;
            for(int j=0; j<4; j++) {
                ptPtr[j] = env * (cosf(ptPtr[j]) * sinf(ptPtr[j]) * tanf(ptPtr[j]));
            }
        }

    } else {

        // This inner loop will not autovectorize.
        for(int i=0; i<nPoints; i++) {
            MFloatPoint& pt = pts[i];
            for(int j=0; j<3; j++) {
                pt[j] = env * (cosf(pt[j]) * sinf(pt[j]) * tanf(pt[j]));
            }

        }
    }

    timer.endTimer();
    if(sseEnabled) {
        printf("SSE enabled, runtime %f\n", timer.elapsedTime());
    } else {
        printf("SSE disabled, runtime %f\n", timer.elapsedTime());
    }

    outMesh.setPoints(pts);

    return status;
}
Beispiel #9
0
MStatus dynExprField::compute(const MPlug& plug, MDataBlock& block)
//
//	Descriptions:
//		compute output force.
//
{
	MStatus status;

	if( !(plug == mOutputForce) )
        return( MS::kUnknownParameter );

	// get the logical index of the element this plug refers to.
	//
	int multiIndex = plug.logicalIndex( &status );
	McheckErr(status, "ERROR in plug.logicalIndex.\n");

	// 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 = block.outputArrayValue( mInputData, &status );
	McheckErr(status,"ERROR in hInputArray = block.outputArrayValue().\n");
	
	status = hInputArray.jumpToElement( multiIndex );
	McheckErr(status, "ERROR: hInputArray.jumpToElement failed.\n");
	
	// get children of aInputData.
	
	MDataHandle hCompond = hInputArray.inputValue( &status );
	McheckErr(status, "ERROR in hCompond=hInputArray.inputValue\n");
	
	MDataHandle hPosition = hCompond.child( mInputPositions );
	MObject dPosition = hPosition.data();
	MFnVectorArrayData fnPosition( dPosition );
	MVectorArray points = fnPosition.array( &status );
	McheckErr(status, "ERROR in fnPosition.array(), not find points.\n");
	
	// Comment out the following since velocity, and mass are 
	// not needed in this field.
	//
	// MDataHandle hVelocity = hCompond.child( mInputVelocities );
	// MObject dVelocity = hVelocity.data();
	// MFnVectorArrayData fnVelocity( dVelocity );
	// MVectorArray velocities = fnVelocity.array( &status );
	// McheckErr(status, "ERROR in fnVelocity.array(), not find velocities.\n");
	//
	// MDataHandle hMass = hCompond.child( mInputMass );
	// MObject dMass = hMass.data();
	// MFnDoubleArrayData fnMass( dMass );
	// MDoubleArray masses = fnMass.array( &status );
	// McheckErr(status, "ERROR in fnMass.array(), not find masses.\n");

	// The attribute mInputPPData contains the attribute in an array form 
	// parpared 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 = block.inputArrayValue( mInputPPData, &status );
	McheckErr(status,"ERROR in mhInputPPData = block.inputArrayValue().\n");

	status = mhInputPPData.jumpToElement( multiIndex );
	McheckErr(status, "ERROR: mhInputPPArray.jumpToElement failed.\n");

	MDataHandle hInputPPData = mhInputPPData.inputValue( &status );
	McheckErr(status, "ERROR in hInputPPData = mhInputPPData.inputValue\n");

	MObject dInputPPData = hInputPPData.data();
	MFnArrayAttrsData inputPPArray( dInputPPData );

	MDataHandle hOwnerPPData = block.inputValue( mOwnerPPData, &status );
	McheckErr(status, "ERROR in hOwnerPPData = block.inputValue\n");

	MObject dOwnerPPData = hOwnerPPData.data();
	MFnArrayAttrsData ownerPPArray( dOwnerPPData );

	const MString magString("magnitude");
	MFnArrayAttrsData::Type doubleType(MFnArrayAttrsData::kDoubleArray);

	bool arrayExist;
	MDoubleArray magnitudeArray;
	arrayExist = inputPPArray.checkArrayExist(magString, doubleType, &status);
	// McheckErr(status, "ERROR in checkArrayExist(magnitude)\n");
	if(arrayExist) {
	    magnitudeArray = inputPPArray.getDoubleData(magString, &status);
	    // McheckErr(status, "ERROR in inputPPArray.doubleArray(magnitude)\n");
	}

	MDoubleArray magnitudeOwnerArray;
	arrayExist = ownerPPArray.checkArrayExist(magString, doubleType, &status);
	// McheckErr(status, "ERROR in checkArrayExist(magnitude)\n");
	if(arrayExist) {
	    magnitudeOwnerArray = ownerPPArray.getDoubleData(magString, &status);
	    // McheckErr(status, "ERROR in ownerPPArray.doubleArray(magnitude)\n");
	}

	const MString dirString("direction");
	MFnArrayAttrsData::Type vectorType(MFnArrayAttrsData::kVectorArray);

	arrayExist = inputPPArray.checkArrayExist(dirString, vectorType, &status);
        MVectorArray directionArray;
	// McheckErr(status, "ERROR in checkArrayExist(direction)\n");
	if(arrayExist) {
	    directionArray = inputPPArray.getVectorData(dirString, &status);
	    // McheckErr(status, "ERROR in inputPPArray.vectorArray(direction)\n");
	}

	arrayExist = ownerPPArray.checkArrayExist(dirString, vectorType, &status);
        MVectorArray directionOwnerArray;
	// McheckErr(status, "ERROR in checkArrayExist(direction)\n");
	if(arrayExist) {
	    directionOwnerArray = ownerPPArray.getVectorData(dirString, &status);
	    // McheckErr(status, "ERROR in ownerPPArray.vectorArray(direction)\n");
	}

	// Compute the output force.
	//
	MVectorArray forceArray;

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

	// get output data handle
	//
	MArrayDataHandle hOutArray = block.outputArrayValue( mOutputForce, &status);
	McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n");
	MArrayDataBuilder bOutArray = hOutArray.builder( &status );
	McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n");

	// get output force array from block.
	//
	MDataHandle hOut = bOutArray.addElement(multiIndex, &status);
	McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n");

	MFnVectorArrayData fnOutputForce;
	MObject dOutputForce = fnOutputForce.create( forceArray, &status );
	McheckErr(status, "ERROR in dOutputForce = fnOutputForce.create\n");

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

	return( MS::kSuccess );
}
Beispiel #10
0
MStatus sgIkSmoothStretch::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus stat;

	if ( plug == aOutputDistance )
	{
		MArrayDataHandle hArrInputDistance = data.inputArrayValue( aInputDistance );
		MDataHandle hStretchAble = data.inputValue( aStretchAble );
		MDataHandle hSmoothArea = data.inputValue( aSmoothArea );

		float stretchAble = hStretchAble.asFloat();

		double allDistance = 0.0;
		int arrayCount = hArrInputDistance.elementCount();

		double* outputDistances = new double[arrayCount]; 

		int multMinus = 1;
		for( int i=0; i<arrayCount; i++ )
		{
			MDataHandle hInputDistance = hArrInputDistance.inputValue();
			double inputDistance = hInputDistance.asDouble();

			if( inputDistance < 0 )
			{
				multMinus = -1;
				outputDistances[i] = -inputDistance;
			}
			else
			{
				outputDistances[i] = inputDistance;
			}
			allDistance += outputDistances[i];
			hArrInputDistance.next();
		}
		
		MDataHandle hInPosition = data.inputValue( aInPosition );
		MDataHandle hInPositionX = hInPosition.child( aInPositionX );
		MDataHandle hInPositionY = hInPosition.child( aInPositionY );
		MDataHandle hInPositionZ = hInPosition.child( aInPositionZ );

		double smoothArea = hSmoothArea.asDouble()*0.1;

		double poseDistance = sqrt( pow( hInPositionX.asDouble(), 2 )+pow( hInPositionY.asDouble(), 2 )+pow( hInPositionZ.asDouble(), 2 ) ) ;
		allDistance = fabs( allDistance );

		double stretchRate = getSmoothStretchRate( outputDistances[0], outputDistances[1], poseDistance, smoothArea );
		double smoothRate  = getSmoothRate( outputDistances[0], outputDistances[1], poseDistance, smoothArea );

		double currentRate = ( 1-stretchAble )*smoothRate + stretchAble*stretchRate;

		outputDistances[0] *= currentRate*multMinus;
		outputDistances[1] *= currentRate*multMinus;

		MArrayDataHandle hArrOutputDistance = data.outputArrayValue( aOutputDistance );
		MArrayDataBuilder bArrOutputDistance( aOutputDistance, arrayCount, &stat );

		for( int i=0; i<arrayCount; i++ )
		{
			MDataHandle hOutputDistance = bArrOutputDistance.addElement( i );
			hOutputDistance.set( outputDistances[i] );
		}

		hArrOutputDistance.set( bArrOutputDistance );
		hArrOutputDistance.setAllClean();

		data.setClean( plug );
	}
	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;
}
Beispiel #12
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;
}
Beispiel #13
0
MStatus OnbShader::compute(const MPlug& plug, MDataBlock& block)
{
	// Sanity check
	if (plug != aOutColor && plug.parent() != aOutColor &&
		plug != aOutTransparency && plug.parent() != aOutTransparency)
	{
		return MS::kUnknownParameter;
	}

	// Note that this currently only implements the diffuse portion of the
	// shader and ignores specular. The diffuse portion is the Oren-Nayar
	// computation from:
	//   Engel, Wolfgang et al. Programming Vertex, Geometry, and Pixel Shaders
	//   http://content.gpwiki.org/index.php/D3DBook:(Lighting)_Oren-Nayar
	// Further extensions could be added to this compute method to include
	// the intended Blinn specular component as well as ambient and
	// incandescence components.
	// See the VP2 fragment-based implementation in onbShaderOverride for the
	// full shader.
	MStatus status;
	MFloatVector resultColor(0.0f, 0.0f, 0.0f);
	MFloatVector resultTransparency(0.0f, 0.0f, 0.0f);

	// Get surface shading parameters from input block
	const MFloatVector& surfaceColor =
		block.inputValue(aColor, &status).asFloatVector();
	CHECK_MSTATUS(status);
	const float roughness = block.inputValue(aRoughness, &status).asFloat();
	CHECK_MSTATUS(status);
	const MFloatVector& transparency =
		block.inputValue(aTransparency, &status).asFloatVector();
	CHECK_MSTATUS(status);
	const MFloatVector& surfaceNormal =
		block.inputValue(aNormalCamera, &status).asFloatVector();
	CHECK_MSTATUS(status);
	const MFloatVector& rayDirection =
		block.inputValue(aRayDirection).asFloatVector();
	const MFloatVector viewDirection = -rayDirection;

	// Pre-compute some values that do not vary with lights
	const float NV = viewDirection*surfaceNormal;
	const float acosNV = acosf(NV);
	const float roughnessSq = roughness*roughness;
	const float A = 1.0f - 0.5f*(roughnessSq/(roughnessSq + 0.57f));
	const float B = 0.45f*(roughnessSq/(roughnessSq + 0.09f));

	// Get light list
	MArrayDataHandle lightData = block.inputArrayValue(aLightData, &status);
	CHECK_MSTATUS(status);
	const int numLights = lightData.elementCount(&status);
	CHECK_MSTATUS(status);

	// Iterate through light list and get ambient/diffuse values
	for (int count=1; count<=numLights; count++)
	{
		// Get the current light
		MDataHandle currentLight = lightData.inputValue(&status);
		CHECK_MSTATUS(status);

		// Find diffuse component
		if (currentLight.child(aLightDiffuse).asBool())
		{
			// Get the intensity and direction of that light
			const MFloatVector& lightIntensity =
				currentLight.child(aLightIntensity).asFloatVector();
			const MFloatVector& lightDirection =
				currentLight.child(aLightDirection).asFloatVector();

			// Compute the diffuse factor
			const float NL = lightDirection*surfaceNormal;
			const float acosNL = acosf(NL);
			const float alpha = std::max(acosNV, acosNL);
			const float beta = std::min(acosNV, acosNL);
			const float gamma =
				(viewDirection - (surfaceNormal*NV)) *
				(lightDirection - (surfaceNormal*NL));
			const float C = sinf(alpha)*tanf(beta);
			const float factor =
				std::max(0.0f, NL)*(A + B*std::max(0.0f, gamma)*C);

			// Add to result color
			resultColor += lightIntensity*factor;
		}

		// Advance to the next light.
		if (count < numLights)
		{
			status = lightData.next();
			CHECK_MSTATUS(status);
		}
	}

	// Factor incident light with surface color
	resultColor[0] = resultColor[0]*surfaceColor[0];
	resultColor[1] = resultColor[1]*surfaceColor[1];
	resultColor[2] = resultColor[2]*surfaceColor[2];

	// Set ouput color attribute
	if (plug == aOutColor || plug.parent() == aOutColor)
	{
		// Get the handle to the attribute
		MDataHandle outColorHandle = block.outputValue(aOutColor, &status);
		CHECK_MSTATUS(status);
		MFloatVector& outColor = outColorHandle.asFloatVector();

		// Set the result and mark it clean
		outColor = resultColor;
		outColorHandle.setClean();
	}

	// Set ouput transparency
	if (plug == aOutTransparency || plug.parent() == aOutTransparency)
	{
		// Get the handle to the attribute
		MDataHandle outTransHandle =
			block.outputValue(aOutTransparency, &status);
		CHECK_MSTATUS(status);
		MFloatVector& outTrans = outTransHandle.asFloatVector();

		// Set the result and mark it clean
		outTrans = transparency;
		outTransHandle.setClean();
	}

	return MS::kSuccess;
}
MStatus geometrySurfaceConstraint::compute( const MPlug& plug, MDataBlock& block )
{	
	MStatus returnStatus;
 
	if ( plug == geometrySurfaceConstraint::constraintGeometry )
	{
		//
		block.inputValue(constraintParentInverseMatrix);
		//
		MArrayDataHandle targetArray = block.inputArrayValue( compoundTarget );
		unsigned int targetArrayCount = targetArray.elementCount();
		double weight,selectedWeight = 0;
		if ( weightType == geometrySurfaceConstraintCommand::kSmallestWeight )
			selectedWeight = FLT_MAX;
		MObject selectedMesh;
		unsigned int i;
		for ( i = 0; i < targetArrayCount; i++ )
		{
			MDataHandle targetElement = targetArray.inputValue();
			weight = targetElement.child(targetWeight).asDouble();
			if ( !equivalent(weight,0.0))
			{
				if ( weightType == geometrySurfaceConstraintCommand::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.isNull() )
		{
			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 MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
Beispiel #15
0
MStatus PushDeformer::deform(MDataBlock& dataBlock,
								MItGeometry& itGeo,
								const MMatrix& localToWorldMatrix,
								unsigned int geomIndex)
{
	MStatus status;
	//get attribute handles
	double bulgeAmount = dataBlock.inputValue(aAmount, &status).asDouble();
	CHECK_MSTATUS_AND_RETURN_IT(status);
	m_taskData.envelope = dataBlock.inputValue(envelope, &status).asFloat();
	CHECK_MSTATUS_AND_RETURN_IT(status);
	bool useStressV = dataBlock.inputValue(aUseStress, &status).asBool();
	CHECK_MSTATUS_AND_RETURN_IT(status);
	int multiThreadingType = dataBlock.inputValue(aMultiThreadingType, &status).asBool();
	CHECK_MSTATUS_AND_RETURN_IT(status);

	if (m_taskData.envelope <= 0.001)
	{
		return MS::kSuccess;
	}
	// if the use stress plug is turned on pull 
	MDoubleArray stressV;
	if (useStressV == true)
	{
		//pull out the raw data as an Mobject
		MObject stressMap = dataBlock.inputValue(aStressMap, &status).data();
		CHECK_MSTATUS_AND_RETURN_IT(status);
		MFnDoubleArrayData stressDataFn(stressMap);
    m_taskData.stressV = stressDataFn.array();
	}

	//retrieve the handle to the output array attribute
	MArrayDataHandle hInput = dataBlock.outputArrayValue(input, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	//get the input array index handle
	status = hInput.jumpToElement(geomIndex);
	//get the handle of geomIndex attribute
	MDataHandle hInputElement = hInput.outputValue(&status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	//Get the MObject of the input geometry of geomindex
	MObject oInputGeom = hInputElement.child(inputGeom).asMesh();
	MFnMesh fnMesh(oInputGeom, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);

  
	fnMesh.getVertexNormals(false, m_taskData.normals, MSpace::kWorld);
	itGeo.allPositions(m_taskData.points, MSpace::kWorld);
  //MGlobal::displayInfo( "test" );
  /*for (int i = 0; i < itGeo.count();  i++)
	{
    MGlobal::displayInfo( MFnAttribute(weightList).isArray );
  }*/
  m_taskData.bulgeAmount = bulgeAmount;

  if(multiThreadingType == 1)
  {
    ThreadData* pThreadData = createThreadData( NUM_TASKS, &m_taskData );
    MThreadPool::newParallelRegion( createTasks, (void*)pThreadData );
    itGeo.setAllPositions(m_taskData.points);
    delete [] pThreadData;
    return MS::kSuccess;
  }


  else if(multiThreadingType == 2)
  {
    tbb::parallel_for(size_t(0), size_t(itGeo.count()), [this](size_t i)
    {
		  //const float w = weightValue(dataBlock, geomIndex, i);
      const float w = 1.0;
		  if (m_taskData.useStressV == true && (m_taskData.stressV.length() > 0))
		  {
			  //deform
			  m_taskData.points[i] += (MVector(m_taskData.normals[i]) * m_taskData.bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[i]);
		  }
		  else
		  {
			  //deform
        m_taskData.points[i] += m_taskData.normals[i] * m_taskData.bulgeAmount * m_taskData.envelope * w;
		  }  
  
    });
  }

  
	//
  else if(multiThreadingType == 3)
  #pragma omp parallel for 

  for (int i = 0; i < itGeo.count();  i++)
	{
		float w = weightValue(dataBlock, geomIndex, itGeo.index());
		if (useStressV == true && (stressV.length() > 0))
		{
			//deform
      m_taskData.points[i] += (MVector(m_taskData.normals[i]) * bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[i]);
			
		}
		else
		{
			//deform
      m_taskData.points[i] += m_taskData.normals[i] * bulgeAmount * m_taskData.envelope * w;

		}
	}
  else
  {
    for (; !itGeo.isDone(); itGeo.next())
	  {
		  float w = weightValue(dataBlock, geomIndex, itGeo.index());
		  if (useStressV == true && (stressV.length() > 0))
		  {
			  //deform
        m_taskData.points[itGeo.index()] += (MVector(m_taskData.normals[itGeo.index()]) * bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[itGeo.index()]);
			
		  }
		  else
		  {
			  //deform
        m_taskData.points[itGeo.index()] += m_taskData.normals[itGeo.index()] * bulgeAmount * m_taskData.envelope * w;
		  }
	  }
  }
	itGeo.setAllPositions(m_taskData.points);

	return MS::kSuccess;

}
Beispiel #16
0
//
// DESCRIPTION:
///////////////////////////////////////////////////////
MStatus PhongNode::compute(
const MPlug&      plug,
      MDataBlock& block )
{
    if ((plug != aOutColor) && (plug.parent() != aOutColor))
		return MS::kUnknownParameter;

    MFloatVector resultColor(0.0,0.0,0.0);

    // get sample surface shading parameters
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    MFloatVector& cameraPosition = block.inputValue( aPointCamera ).asFloatVector();

	// use for raytracing api enhancement below
	MFloatVector point = cameraPosition;
	MFloatVector normal = surfaceNormal;

    MFloatVector& surfaceColor  = block.inputValue( aColor ).asFloatVector();
    MFloatVector& incandescence = block.inputValue( aIncandescence ).asFloatVector();
    float diffuseReflectivity = block.inputValue( aDiffuseReflectivity ).asFloat();
    // float translucenceCoeff   = block.inputValue( aTranslucenceCoeff ).asFloat();
	// User-defined Reflection Color Gain
	float reflectGain = block.inputValue( aReflectGain ).asFloat();

    // Phong shading attributes
    float power = block.inputValue( aPower ).asFloat();
    float spec = block.inputValue( aSpecularity ).asFloat();

    float specularR, specularG, specularB;
    float diffuseR, diffuseG, diffuseB;
    diffuseR = diffuseG = diffuseB = specularR = specularG = specularB = 0.0;

    // get light list
    MArrayDataHandle lightData = block.inputArrayValue( aLightData );
    int numLights = lightData.elementCount();

    // iterate through light list and get ambient/diffuse values
    for( int count=1; count <= numLights; count++ )
    {
        MDataHandle currentLight = lightData.inputValue();
        MFloatVector& lightIntensity = currentLight.child(aLightIntensity).asFloatVector();

        // Find the blind data
        void*& blindData = currentLight.child( aLightBlindData ).asAddr();

        // find ambient component
        if( currentLight.child(aLightAmbient).asBool() ) {
            diffuseR += lightIntensity[0];
            diffuseG += lightIntensity[1];
            diffuseB += lightIntensity[2];
        }

        MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector();

        if ( blindData == NULL )
        {
			// find diffuse and specular component
			if( currentLight.child(aLightDiffuse).asBool() )
			{
			    float cosln = lightDirection * surfaceNormal;;
			    if( cosln > 0.0f )  // calculate only if facing light
			    {
			         diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity );
			         diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity );
			         diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity );
			    }

			    CHECK_MSTATUS( cameraPosition.normalize() );

				if( cosln > 0.0f ) // calculate only if facing light
				{
				    float RV = ( ( (2*surfaceNormal) * cosln ) - lightDirection ) * cameraPosition;
				    if( RV > 0.0 ) RV = 0.0;
				    if( RV < 0.0 ) RV = -RV;

				    if ( power < 0 ) power = -power;

				    float s = spec * powf( RV, power );

				    specularR += lightIntensity[0] * s;
				    specularG += lightIntensity[1] * s;
				    specularB += lightIntensity[2] * s;
				}
			}
        }
        else
        {
			float cosln = MRenderUtil::diffuseReflectance( blindData, lightDirection, point, surfaceNormal, true );
			if( cosln > 0.0f )  // calculate only if facing light
			{
			     diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity );
			     diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity );
			     diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity );
			}

			CHECK_MSTATUS ( cameraPosition.normalize() );

			if ( currentLight.child(aLightSpecular).asBool() )
			{
				MFloatVector specLightDirection = lightDirection;
				MDataHandle directionH = block.inputValue( aRayDirection );
				MFloatVector direction = directionH.asFloatVector();
				float lightAttenuation = 1.0;

				specLightDirection = MRenderUtil::maximumSpecularReflection( blindData,
										lightDirection, point, surfaceNormal, direction );
				lightAttenuation = MRenderUtil::lightAttenuation( blindData, point, surfaceNormal, false );

				// Are we facing the light
				if ( specLightDirection * surfaceNormal > 0.0f )
				{
					float power2 = block.inputValue( aPower ).asFloat();
					MFloatVector rv = 2 * surfaceNormal * ( surfaceNormal * direction ) - direction;
					float s = spec * powf( rv * specLightDirection, power2 );

					specularR += lightIntensity[0] * s * lightAttenuation;
					specularG += lightIntensity[1] * s * lightAttenuation;
					specularB += lightIntensity[2] * s * lightAttenuation;
				}
			 }
       }
       if( !lightData.next() ) break;
    }

    // factor incident light with surface color and add incandescence
    resultColor[0] = ( diffuseR * surfaceColor[0] ) + specularR + incandescence[0];
    resultColor[1] = ( diffuseG * surfaceColor[1] ) + specularG + incandescence[1];
    resultColor[2] = ( diffuseB * surfaceColor[2] ) + specularB + incandescence[2];

	// add the reflection color
	if (reflectGain > 0.0) {

		MStatus status;

		// required attributes for using raytracer
		// origin, direction, sampler, depth, and object id.
		//
		MDataHandle originH = block.inputValue( aRayOrigin, &status);
		MFloatVector origin = originH.asFloatVector();

		MDataHandle directionH = block.inputValue( aRayDirection, &status);
		MFloatVector direction = directionH.asFloatVector();

		MDataHandle samplerH = block.inputValue( aRaySampler, &status);
		void*& samplerPtr = samplerH.asAddr();

		MDataHandle depthH = block.inputValue( aRayDepth, &status);
		short depth = depthH.asShort();

		MDataHandle objH = block.inputValue( aObjectId, &status);
		void*& objId = objH.asAddr();

		MFloatVector reflectColor;
		MFloatVector reflectTransparency;

		MFloatVector& triangleNormal = block.inputValue( aTriangleNormalCamera ).asFloatVector();

		// compute reflected ray
		MFloatVector l = -direction;
		float dot = l * normal;
		if( dot < 0.0 ) dot = -dot;
		MFloatVector refVector = 2 * normal * dot - l; 	// reflection ray
		float dotRef = refVector * triangleNormal;
		if( dotRef < 0.0 ) {
		    const float s = 0.01f;
			MFloatVector mVec = refVector - dotRef * triangleNormal;
			mVec.normalize();
			refVector = mVec + s * triangleNormal;
		}
		CHECK_MSTATUS ( refVector.normalize() );

		status = MRenderUtil::raytrace(
				point,    	//  origin
				refVector,  //  direction
				objId,		//  object id
				samplerPtr, //  sampler info
				depth,		//  ray depth
				reflectColor,	// output color and transp
				reflectTransparency);

		// add in the reflection color
		resultColor[0] += reflectGain * (reflectColor[0]);
		resultColor[1] += reflectGain * (reflectColor[1]);
		resultColor[2] += reflectGain * (reflectColor[2]);

	}

    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();

    return MS::kSuccess;
}
MStatus liqSurfaceNode::compute( const MPlug& plug, MDataBlock& block )
{
  // outColor or individual R, G, B channel
  if( (plug == aOutColor) || (plug.parent() == aOutColor) ||
	  (plug == aOutTransparency) || (plug.parent() == aOutTransparency)
  	) {

    //cout <<"compute... "<<endl;

    // init shader
    MStatus status;
    MFloatVector theColor( 0.0f, 0.0f, 0.0f );
    MFloatVector& cColor  = block.inputValue(aColor).asFloatVector();
    MFloatVector& cTrans  = block.inputValue(aOpacity).asFloatVector();
    MFloatVector& ctex    = block.inputValue(aGLPreviewTexture).asFloatVector();

    // exploit maya's free openGL preview
    if ( ctex != MFloatVector( -1.0, -1.0, -1.0 ) ) theColor = ctex;
    else theColor = cColor;

    MFloatVector resultColor( 0.0, 0.0, 0.0 );
    MFloatVector resultTrans( cTrans );



    // lambert calc -------------------
    bool&  ignoreLights = block.inputValue( aMayaIgnoreLights, &status ).asBool();
    float& Ka = block.inputValue( aMayaKa, &status ).asFloat();
    float& Kd = block.inputValue( aMayaKd, &status ).asFloat();

    // get surface normal
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera, &status ).asFloatVector();
    CHECK_MSTATUS( status );

    if ( ignoreLights ) {

      MFloatVector cam( 0.0, 0.0, 1.0 );
      float cosln = cam * surfaceNormal;
      if ( cosln > 0.0f ) {
        float diff = cosln * cosln * Kd + Ka;
        resultColor = diff * theColor;
      }

    } else {

      // Get light list
      MArrayDataHandle lightData = block.inputArrayValue( aLightData, &status );
      CHECK_MSTATUS( status );
      int numLights = lightData.elementCount( &status );
      CHECK_MSTATUS( status );

      // Iterate through light list and get ambient/diffuse values
      for( int count=1; count <= numLights; count++ )
      {
        // Get the current light out of the array
        MDataHandle currentLight = lightData.inputValue( &status );
        CHECK_MSTATUS( status );

        // Get the intensity of that light
        MFloatVector& lightIntensity = currentLight.child( aLightIntensity ).asFloatVector();

        // Find ambient component
        if ( currentLight.child( aLightAmbient ).asBool() ) {
          resultColor += lightIntensity;
        }

        // Find diffuse component
        if ( currentLight.child( aLightDiffuse ).asBool() ) {
          MFloatVector& lightDirection = currentLight.child( aLightDirection ).asFloatVector();
          float cosln = lightDirection * surfaceNormal;
          if ( cosln > 0.0f )  resultColor += lightIntensity * cosln * Kd ;
        }

        // Advance to the next light.
        if ( count < numLights ) {
          status = lightData.next();
          CHECK_MSTATUS( status );
        }
      }

      resultColor[0] *= theColor[0];
      resultColor[1] *= theColor[1];
      resultColor[2] *= theColor[2];

    }

    resultTrans[0] = ( 1 - resultTrans[0] );
    resultTrans[1] = ( 1 - resultTrans[1] );
    resultTrans[2] = ( 1 - resultTrans[2] );


    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();

    MDataHandle outTransHandle = block.outputValue( aOutTransparency );
    MFloatVector& outTrans = outTransHandle.asFloatVector();
    outTrans = resultTrans;
    outTransHandle.setClean();

  } else return MS::kUnknownParameter;


  return MS::kSuccess;
}
MStatus geometrySurfaceConstraint::compute( const MPlug& plug, MDataBlock& block )
{	
	MStatus returnStatus;
 
    if(plug == constraintTranslateX || plug == constraintTranslateY || plug == constraintTranslateZ) {
        if(!m_isInitd) {
// read rest position
            MDataHandle htgo = block.inputValue(targetRestP);
            double3 & tgo = htgo.asDouble3();
            MGlobal::displayInfo(MString("target rest p ")+tgo[0]+" "+tgo[1]+" "+tgo[2]);
            m_restPos = MPoint(tgo[0],tgo[1],tgo[2]);
			m_isInitd = true;
		}
		
		MArrayDataHandle targetArray = block.inputArrayValue( compoundTarget );
		const unsigned int targetArrayCount = targetArray.elementCount();
        MMatrix tm;
        tm.setToIdentity();
        unsigned int i;
		for ( i = 0; i < targetArrayCount; i++ ) {
            MDataHandle targetElement = targetArray.inputValue(&returnStatus);
            if(!returnStatus) {
                MGlobal::displayInfo("failed to get input value target element");
            }
            MDataHandle htm = targetElement.child(targetTransform);
            MFnMatrixData ftm(htm.data(), &returnStatus);
            if(!returnStatus) {
                MGlobal::displayInfo("failed to get matrix data");
            }
            tm = ftm.matrix();
            targetArray.next();
        }
		
		MDataHandle hparentInvMat = block.inputValue(constraintParentInverseMatrix);
		MMatrix parentInvMat = hparentInvMat.asMatrix();

// world position
        MPoint curPos(tm(3,0), tm(3,1), tm(3,2));
// offset in local space
		m_offsetToRest = m_restPos - curPos;
// object position in world space
		MPoint localP = m_offsetToRest * tm + curPos;
// in local space
		localP *= parentInvMat;

        MDataHandle hout;
        if(plug == constraintTranslateX) {
            hout = block.outputValue(constraintTranslateX);
			hout.set(localP.x);
        }
        else if(plug == constraintTranslateY) {
            hout = block.outputValue(constraintTranslateY);
			hout.set(localP.y);
        }
        else if(plug == constraintTranslateZ) {
            hout = block.outputValue(constraintTranslateZ);
			hout.set(localP.z);
        }
		
		//MPlug pgTx(thisMObject(), constraintTargetX);
		//pgTx.setValue(m_lastPos.x);
		//MPlug pgTy(thisMObject(), constraintTargetY);
		//pgTy.setValue(m_lastPos.y);
		//MPlug pgTz(thisMObject(), constraintTargetZ);
		//pgTz.setValue(m_lastPos.z);
		
		MPlug pgOx(thisMObject(), constraintObjectX);
		pgOx.setValue(m_offsetToRest.x);
		MPlug pgOy(thisMObject(), constraintObjectY);
		pgOy.setValue(m_offsetToRest.y);
		MPlug pgOz(thisMObject(), constraintObjectZ);
		pgOz.setValue(m_offsetToRest.z);
        
       // MFnNumericData nd;
		//MObject offsetData = nd.create( MFnNumericData::k3Double);
        //nd.setData3Double(m_lastPos.x, m_lastPos.y, m_lastPos.z);
        //MPlug pgTgo(thisMObject(), targetOffset);
        //pgTgo.setValue(offsetData); 
    }
	else
		return MS::kUnknownParameter;

	return MS::kSuccess;
}
Beispiel #19
0
MStatus puttyNode::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& worldMatrix, unsigned int multiIndex)
{
//	MGlobal::displayInfo("deform");
    MStatus status = MS::kSuccess;

    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // get inputs
    //
	
	// get the node ready flag
	MDataHandle dh = block.inputValue(aScriptSourced,&status);
	SYS_ERROR_CHECK(status, "Error getting aScriptSourced data handle\n");
	bool scriptSourced = dh.asBool();
	if (!scriptSourced)
		return MS::kSuccess;


	dh = block.inputValue(aNodeReady,&status);
	SYS_ERROR_CHECK(status, "Error getting node ready data handle\n");
	bool nodeReady = dh.asBool();

	// if it's not ready, don't do anything
	if (!nodeReady)
		return MS::kSuccess;

    dh = block.inputValue(aDefSpace,&status);
    SYS_ERROR_CHECK(status, "Error getting defSpace data handle\n");
    short defSpace = dh.asShort();
    
    dh = block.inputValue(aDefWeights,&status);
    SYS_ERROR_CHECK(status, "Error getting defWeights data handle\n");
    short defWeights = dh.asShort();
 
    dh = block.inputValue(aDefEnvelope,&status);
    SYS_ERROR_CHECK(status, "Error getting defEnvelope data handle\n");
    short defEnvelope = dh.asShort();
    

    
    // get the command
    dh = block.inputValue(aCmdBaseName,&status);
    SYS_ERROR_CHECK(status, "Error getting aCmdBaseName  handle\n");    
    MString script =  dh.asString(); 
        
 /*   if (script == "")
    {
        status = MS::kFailure;
        USER_ERROR_CHECK(status, "no script provided!\n");    
    }
   */ 
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // build mel cmd string
    //
    
    // check if it's a valid cmd
        
   
    // get the envelope
    //
    double env = 1;
    
    if (defEnvelope == MSD_ENVELOPE_AUTO)
    {
        dh = block.inputValue(envelope,&status);
    	SYS_ERROR_CHECK(status, "Error getting envelope data handle\n");	
	    env = double(dh.asFloat());	
        
        // early stop 'cause there is nothing more to do
        if (env == 0.0)
            return MS::kSuccess;
    }
    
    // get the points, transform them into the right space if needed
    //
    int count = iter.count();
    MVectorArray points(count);
    for ( ; !iter.isDone(); iter.next()) 
        points[iter.index()] = iter.position();
        
    if ( defSpace == MSD_SPACE_WORLD )
    {
        for (int i = 0;i<count;i++)
            points[i] = MPoint(points[i]) * worldMatrix;
    }
    
    
    // get the weights
    //
    MDoubleArray weights;
    if ( defWeights == MSD_WEIGHTS_AUTO)
    {
        weights.setLength(count);
        
        for (int i = 0;i<count;i++)
            weights[i]  = weightValue(block,multiIndex,i);
        
    }


    // get the object name and type
    // get the input geometry, traverse through the data handles    
    MArrayDataHandle adh = block.outputArrayValue( input, &status );
    SYS_ERROR_CHECK(status,"error getting input array data handle.\n");

    status = adh.jumpToElement( multiIndex );
    SYS_ERROR_CHECK(status, "input jumpToElement failed.\n");

    // compound data 
    MDataHandle cdh = adh.inputValue( &status );
    SYS_ERROR_CHECK(status, "error getting input inputValue\n");
   
    // input geometry child
    dh = cdh.child( inputGeom );
    MObject dInputGeometry = dh.data();
   
    // get the type      
    MString geometryType = dInputGeometry.apiTypeStr();

    // get the name    
//    MFnDagNode dagFn( dInputGeometry, &status);
//    SYS_ERROR_CHECK(status, "error converting geometry obj to dag node\n");
   
//    MString geometryName = dagFn.fullPathName(&status);
//    SYS_ERROR_CHECK(status, "error getting full path name \n");

//    MString geometryType = "";
//    MString geometryName = "";
    
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //  
    //  set the current values on the temp plugs for the script to be picked up
    //
    
    // the position
    MObject thisNode = thisMObject();
    
    MPlug currPlug(thisNode,aCurrPosition);
    MFnVectorArrayData vecD;
    MObject currObj = vecD.create(points,&status);
    currPlug.setValue(currObj);
    SYS_ERROR_CHECK(status, "error setting currPosPlug value\n");
    
    // the weights
    currPlug =MPlug(thisNode,aCurrWeight);
    MFnDoubleArrayData dblD;
    currObj = dblD.create(weights,&status);
    currPlug.setValue(currObj);
    SYS_ERROR_CHECK(status, "error setting currWeightsPlug value\n");
    
    // world matrix
    currPlug =MPlug(thisNode,aCurrWorldMatrix);
    MFnMatrixData matD;
    currObj = matD.create(worldMatrix,&status);
    currPlug.setValue(currObj);
    SYS_ERROR_CHECK(status, "error setting currWorldMatrixPlug value\n");

    // the multi index
    currPlug =MPlug(thisNode,aCurrMultiIndex);
    currPlug.setValue(int(multiIndex));
    SYS_ERROR_CHECK(status, "error setting currMultiIndexPlug value\n");
    
    // geometry name/type
//    currPlug =MPlug(thisNode,aCurrGeometryName);
//    currPlug.setValue(geometryName);
//    SYS_ERROR_CHECK(status, "error setting aCurrGeometryName value\n");

    currPlug =MPlug(thisNode,aCurrGeometryType);
    currPlug.setValue(geometryType);
    SYS_ERROR_CHECK(status, "error setting aCurrGeometryType value\n");

   
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // execute the mel script
    //
    MString melCmd = script+"(\"" +name()+"\","+count+")";
    
    MCommandResult melResult;
    status = MGlobal::executeCommand(melCmd,melResult);
	
	// if the command did not work, then try to resource the script
	// (might have been that we were in a fresh scene and nothing was ready yet
	if (status != MS::kSuccess)
	{
		dh = block.inputValue(aScript,&status);
	    SYS_ERROR_CHECK(status, "Error getting aCmdBaseName  handle\n");    
		MString scriptFile =  dh.asString(); 	

		// try to source the script
		MString cmd = "source \"" + scriptFile+"\"";
			
		MCommandResult melResult;
		status = MGlobal::executeCommand(cmd,melResult);
		// if successfull, retry the command 
		if (!status.error())
		{
			status = MGlobal::executeCommand(melCmd,melResult);
		}
	}

	USER_ERROR_CHECK(status, "Error executing mel command, please check the function you provided is valid, error free and has the appropriate parameters!");

    // check the result type
    if ((melResult.resultType()) != (MCommandResult::kDoubleArray))
    {
        USER_ERROR_CHECK(MS::kFailure, "result of mel command has wrong type, should be doubleArray (which will be interpreted as vectorArray)!");
    }
    
    // get the result as a double array
    MDoubleArray newP;  
    status = melResult.getResult(newP);
    USER_ERROR_CHECK(status, "Error getting result of mel command!");
    
    int newCount = newP.length()/3;
    // size check
    if (newCount != count)
    {
        USER_ERROR_CHECK(MS::kFailure, "the size of the result does not match the size of the input!");
    }

    // convert the double array into a vector array
    MPointArray newPoints(newCount);
    
    for(int i=0;i<newCount;i++)
        newPoints[i]=MPoint(newP[i*3],newP[i*3+1],newP[i*3+2]);
    
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // interprete and apply the result
    //


  
    // do the envelope and weights   
    if ((defEnvelope == MSD_ENVELOPE_AUTO)||((defWeights == MSD_WEIGHTS_AUTO)))
    {
        MDoubleArray envPP(count, env);
    
        if (defWeights == MSD_WEIGHTS_AUTO)
        { 
            for (int i = 0;i<count;i++)
                envPP[i] *= weights[i];
        }

        // linear interpolation between old and new points
        for (int i = 0;i<count;i++)
            newPoints[i] = (points[i] * (1-envPP[i])) + (newPoints[i] * envPP[i]);
    }


    // retransform the result if it was in world space
    if ( defSpace == MSD_SPACE_WORLD )
    {
        MMatrix worldMatrixInv = worldMatrix.inverse();
        
        for (int i = 0;i<count;i++)
            newPoints[i] *= worldMatrixInv;
    }
 
 
    // set the points    
    iter.reset();
  	for ( ; !iter.isDone(); iter.next()) 
     	iter.setPosition(newPoints[iter.index()]);    

    return status;
}
Beispiel #20
0
MStatus  retargetLocator::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MDataHandle hDiscMatrix = data.inputValue( aDiscMatrix );
	MDataHandle hDiscAxis = data.inputValue( aDiscAxis );
	MDataHandle hDiscAngle = data.inputValue( aDiscAngle );
	MDataHandle hDiscDivision = data.inputValue( aDiscDivision );
	MDataHandle hDiscOffset = data.inputValue( aDiscOffset );
	MDataHandle hDiscSize = data.inputValue( aDiscSize );
	MDataHandle hDiscActiveColor = data.inputValue( aDiscActiveColor );
	MDataHandle hDiscLeadColor = data.inputValue( aDiscLeadColor );
	MDataHandle hDiscDefaultColor = data.inputValue( aDiscDefaultColor );
	MDataHandle hDiscFillAlpha = data.inputValue( aDiscFillAlpha );
	MDataHandle hDiscLineAlpha = data.inputValue( aDiscLineAlpha );

	discAxis = hDiscAxis.asInt();
	discDivision = hDiscDivision.asInt();
	discAngle = hDiscAngle.asDouble();
	discSize = hDiscSize.asVector();
	discOffset = hDiscOffset.asVector();
	discActiveColor = hDiscActiveColor.asFloat3();
	discLeadColor = hDiscLeadColor.asFloat3();
	discDefaultColor = hDiscDefaultColor.asFloat3();
	discFillAlpha = hDiscFillAlpha.asFloat();
	discLineAlpha = hDiscLineAlpha.asFloat();

	MArrayDataHandle hArrArrow = data.inputArrayValue( aArrow );
	arrowNum = hArrArrow.elementCount();

	inheritMatrix.setLength( arrowNum );
	aimMatrix.setLength( arrowNum );
	inputMeshObj.setLength( arrowNum );
	startSize.setLength( arrowNum );
	size.setLength( arrowNum );
	activeColor.setLength( arrowNum );
	leadColor.setLength( arrowNum );
	defaultColor.setLength( arrowNum );
	fillAlpha.setLength( arrowNum );
	lineAlpha.setLength( arrowNum );
	offset.setLength( arrowNum );

	for( int i =0; i < arrowNum; i++ )
	{
		MDataHandle hArrow = hArrArrow.inputValue();

		MDataHandle hInheritMatrix = hArrow.child( aInheritMatrix );
		MDataHandle hAimMatrix = hArrow.child( aAimMatrix );
		MDataHandle hInputMesh = hArrow.child( aInputMesh );
		MDataHandle hStartSize = hArrow.child( aStartSize );
		MDataHandle hSize = hArrow.child( aSize );
		MDataHandle hActiveColor = hArrow.child( aActiveColor );
		MDataHandle hLeadColor = hArrow.child( aLeadColor );
		MDataHandle hDefaultColor = hArrow.child( aDefaultColor );
		MDataHandle hFillAlpha = hArrow.child( aFillAlpha );
		MDataHandle hLineAlpha = hArrow.child( aLineAlpha );
		MDataHandle hOffset = hArrow.child( aOffset );

		inheritMatrix[i] = hInheritMatrix.asBool();
		aimMatrix[i] = hAimMatrix.asMatrix()*hDiscMatrix.asMatrix().inverse();
		inputMeshObj[i] = hInputMesh.asMesh();
		startSize[i] = hStartSize.asFloat();
		size[i] = hSize.asFloat();
		activeColor[i] = hActiveColor.asFloat3();
		leadColor[i] = hLeadColor.asFloat3();
		defaultColor[i] = hDefaultColor.asFloat3();
		fillAlpha[i] = hFillAlpha.asFloat();
		lineAlpha[i] = hLineAlpha.asFloat();
		offset[i] = hOffset.asVector();

		hArrArrow.next();
	}

	MDataHandle hOutput = data.outputValue( aOutput );
	hOutput.set( 1.0 );
	data.setClean( plug );

	return MS::kSuccess;
}
MStatus sgHair_controlJoint::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MDataHandle   hStaticRotation = data.inputValue( aStaticRotation );
	m_bStaticRotation = hStaticRotation.asBool();

	if( m_isDirtyMatrix )
	{
		MDataHandle hInputBaseCurveMatrix = data.inputValue( aInputBaseCurveMatrix );
		m_mtxBaseCurve       = hInputBaseCurveMatrix.asMatrix(); 
	}
	if( m_isDirtyParentMatrixBase )
	{
		MDataHandle hJointParenBasetMatrix = data.inputValue( aJointParentBaseMatrix );
		m_mtxJointParentBase = hJointParenBasetMatrix.asMatrix();
	}
	if( m_isDirtyCurve || m_isDirtyParentMatrixBase )
	{
		MDataHandle hInputBaseCurve = data.inputValue( aInputBaseCurve );
		MFnNurbsCurve fnCurve = hInputBaseCurve.asNurbsCurve();
		fnCurve.getCVs( m_cvs );
		getJointPositionBaseWorld();
	}
	if( m_isDirtyGravityOption || m_isDirtyCurve || m_isDirtyParentMatrixBase )
	{
		MDataHandle hGravityParam  = data.inputValue( aGravityParam );
		MDataHandle hGravityRange  = data.inputValue( aGravityRange );
		MDataHandle hGravityWeight = data.inputValue( aGravityWeight );
		MDataHandle hGravityOffsetMatrix = data.inputValue( aGravityOffsetMatrix );

		m_paramGravity = hGravityParam.asDouble();
		m_rangeGravity = hGravityRange.asDouble();
		m_weightGravity = hGravityWeight.asDouble();
		m_mtxGravityOffset = hGravityOffsetMatrix.asMatrix();
		m_mtxGravityOffset( 3,0 ) = 0.0;
		m_mtxGravityOffset( 3,1 ) = 0.0;
		m_mtxGravityOffset( 3,2 ) = 0.0;
		setGravityJointPositionWorld();
	}

	setOutput();

	MArrayDataHandle  hArrOutput = data.outputValue( aOutput );
	MArrayDataBuilder builderOutput( aOutput, m_cvs.length() );

	for( int i=0; i< m_cvs.length(); i++ )
	{
		MDataHandle hOutput = builderOutput.addElement( i );
		MDataHandle hOutTrans = hOutput.child( aOutTrans );
		MDataHandle hOutOrient = hOutput.child( aOutOrient );

		hOutTrans.set( m_vectorArrTransJoint[i] );
		hOutOrient.set( m_vectorArrRotateJoint[i] );
	}

	hArrOutput.set( builderOutput );
	hArrOutput.setAllClean();

	data.setClean( plug );

	m_isDirtyMatrix  = false;
	m_isDirtyCurve   = false;
	m_isDirtyGravityOption = false;
	m_isDirtyParentMatrixBase = false;

	return MS::kSuccess;
}
// 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.
//
MStatus asMicrofacet_brdf::compute( const MPlug& plug, MDataBlock& block )
{
    // The plug parameter will allow us to determine which output attribute
    // needs to be calculated.
    //
	if( plug == aOutColor || plug == aOutTransparency || plug.parent() == aOutColor || plug.parent() == aOutTransparency  )
    {
        MStatus status;
        MFloatVector resultColor( 0.0, 0.0, 0.0 );

        // Get surface shading parameters from input block
        //
        MFloatVector& surfaceNormal = block.inputValue( aNormalCamera, &status ).asFloatVector();
        CHECK_MSTATUS( status );

        MFloatVector& surfaceColor = block.inputValue( aColor, &status ).asFloatVector();
        CHECK_MSTATUS( status );

        MFloatVector& incandescence = block.inputValue( aIncandescence,  &status ).asFloatVector();
        CHECK_MSTATUS( status );

        float diffuseReflectivity = block.inputValue( aDiffuseReflectivity, &status ).asFloat();
        CHECK_MSTATUS( status );

//      float translucenceCoeff = block.inputValue( aTranslucenceCoeff,
//              &status ).asFloat();
//      CHECK_MSTATUS( status );


        // Get light list
        //
        MArrayDataHandle lightData = block.inputArrayValue( aLightData, &status );
        CHECK_MSTATUS( status );

        int numLights = lightData.elementCount( &status );
        CHECK_MSTATUS( status );


        // Calculate the effect of the lights in the scene on the color
        //

        // Iterate through light list and get ambient/diffuse values
        //
        for( int count=1; count <= numLights; count++ )
        {
            // Get the current light out of the array
            //
            MDataHandle currentLight = lightData.inputValue( &status );
            CHECK_MSTATUS( status );


            // Get the intensity of that light
            //
            MFloatVector& lightIntensity = currentLight.child( aLightIntensity ).asFloatVector();


            // Find ambient component
            //
            if ( currentLight.child( aLightAmbient ).asBool() )
            {
                resultColor += lightIntensity;
            }


            // Find diffuse component
            //
            if ( currentLight.child( aLightDiffuse ).asBool() )
            {
                MFloatVector& lightDirection = currentLight.child( aLightDirection ).asFloatVector();
                float cosln = lightDirection * surfaceNormal;

               if ( cosln > 0.0f ) 
			   {
                    resultColor += lightIntensity * ( cosln * diffuseReflectivity );
               }
            }


            // Advance to the next light.
            //
            if ( count < numLights ) {
                status = lightData.next();
                CHECK_MSTATUS( status );
            }
        }


        // Factor incident light with surface color and add incandescence
        //
        resultColor[0] = resultColor[0] * surfaceColor[0] + incandescence[0];
        resultColor[1] = resultColor[1] * surfaceColor[1] + incandescence[1];
        resultColor[2] = resultColor[2] * surfaceColor[2] + incandescence[2];


        // Set ouput color attribute
        //
		if ( plug == aOutColor || plug.parent() == aOutColor )
        {
            // Get the handle to the attribute
            //
            MDataHandle outColorHandle = block.outputValue( aOutColor, &status );
            CHECK_MSTATUS( status );
            MFloatVector& outColor = outColorHandle.asFloatVector();

            outColor = resultColor;     // Set the output value
            outColorHandle.setClean(); // Mark the output value as clean
        }


        // Set ouput transparency
        //
		if ( plug == aOutTransparency || plug.parent() == aOutTransparency )
        {
            MFloatVector& transparency = block.inputValue( aInTransparency, &status ).asFloatVector();
            CHECK_MSTATUS( status );


            // Get the handle to the attribute
            //
            MDataHandle outTransHandle = block.outputValue( aOutTransparency, &status );
            CHECK_MSTATUS( status );
            MFloatVector& outTrans = outTransHandle.asFloatVector();

            outTrans = transparency;   // Set the output value
            outTransHandle.setClean(); // Mark the output value as clean
        }
    }
    else
    {
        return( MS::kUnknownParameter ); // We got an unexpected plug
    }

    return( MS::kSuccess );
}
Beispiel #23
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;
}