예제 #1
0
MStatus HRBFSkinCluster::skinLB(MMatrixArray&  transforms,
	int numTransforms,
	MArrayDataHandle& weightListHandle,
	MItGeometry& iter) {
	MStatus returnStatus;

	// Iterate through each point in the geometry.
	//
	for (; !iter.isDone(); iter.next()) {
		MPoint pt = iter.position();
		MPoint skinned;
		// get the weights for this point -> must be dependent on the iterator somehow
		MArrayDataHandle weightsHandle = weightListHandle.inputValue().child(weights);
		// compute the skinning -> TODO: what's the order that the weights are given in? Appears to just be maya list relatives order.
		for (int i = 0; i<numTransforms; ++i) {
			if (MS::kSuccess == weightsHandle.jumpToElement(i)) {
				skinned += (pt * transforms[i]) * weightsHandle.inputValue().asDouble();
			}
		}

		// Set the final position.
		iter.setPosition(skinned);
		// advance the weight list handle
		weightListHandle.next();
	}
	return returnStatus;
}
예제 #2
0
//
// 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;
}
예제 #3
0
MStatus MG_curve::compute(const MPlug& plug,MDataBlock& dataBlock)
	{

		if (plug==output)
		{
			
			//MStatus
			MStatus stat;


			//Point array for the curve
			MPointArray pointArray ;

			//Get data from inputs
			MDataHandle degreeH = dataBlock.inputValue(degree);
			int degreeValue = degreeH.asInt();

			MDataHandle tmH = dataBlock.inputValue(transformMatrix);
			MMatrix tm = tmH.asMatrix();


			MArrayDataHandle inputMatrixH = dataBlock.inputArrayValue(inputMatrix);
			inputMatrixH.jumpToArrayElement(0);
			//Loop to get matrix data and convert in points

			for (int unsigned i=0;i<inputMatrixH.elementCount();i++,inputMatrixH.next())
			{
				

				MMatrix currentMatrix = inputMatrixH.inputValue(&stat).asMatrix() ;
				
				//Compensate the locator matrix
				
				MMatrix fixedMatrix = currentMatrix*tm.inverse();
				MPoint matrixP (fixedMatrix[3][0],fixedMatrix[3][1],fixedMatrix[3][2]);
				pointArray.append(matrixP);
				
			}
			
		MFnNurbsCurve curveFn;
		MFnNurbsCurveData curveDataFn;
		MObject curveData= curveDataFn.create();

		curveFn.createWithEditPoints(pointArray,degreeValue,MFnNurbsCurve::kOpen,0,0,0,curveData,&stat);
		
		MDataHandle outputH = dataBlock.outputValue(output);
		outputH.set(curveData);
		outputH.setClean();

		}


		return MS::kSuccess;
	}
예제 #4
0
MStatus ArrayAngleConstructorNode::compute(const MPlug& plug, MDataBlock& data)
{
    if (plug != aOutput)
        return MS::kUnknownParameter;

    MStatus status;

    int index;

    MArrayDataHandle inputArrayHandle = data.inputArrayValue(aInput);
    int inputSize = inputArrayHandle.elementCount();
    int outputSize = data.inputValue(aSize).asInt();

    MDoubleArray outputArray(outputSize);

    MAngle::Unit uiUnit = MAngle::uiUnit();

    for (int i = 0; i < inputSize; i++)
    {
        index = inputArrayHandle.elementIndex();

        if (index >= outputSize) break;

        if (uiUnit == MAngle::kRadians)
        { 
            outputArray[index] = inputArrayHandle.inputValue().asAngle().asRadians();
        } else {
            outputArray[index] = inputArrayHandle.inputValue().asAngle().asDegrees();
        }

        if (!inputArrayHandle.next()) break;
    }

    MFnDoubleArrayData outputArrayData;
    MObject outputData = outputArrayData.create(outputArray, &status);
    CHECK_MSTATUS_AND_RETURN_IT(status);

    MDataHandle outputHandle = data.outputValue(aOutput);
    outputHandle.setMObject(outputData);
    outputHandle.setClean();

    return MS::kSuccess;
}
예제 #5
0
void TestDeformer::initVertMapping(MDataBlock& data,
                          MItGeometry& iter,
                          const MMatrix& localToWorldMatrix,
                          unsigned int mIndex)
{
    MStatus status;


    MArrayDataHandle vertMapOutArrayData = data.outputArrayValue( vert_map, &status );
    CHECK_MSTATUS( status );

    // use vertMapOutArrayBuilder to modify vertMapOutArrayData
    iter.reset();
    int count = iter.count();
    MArrayDataBuilder vertMapOutArrayBuilder( vert_map, count, &status );
    CHECK_MSTATUS( status );


    MPointArray allPts;// world vertex position of the driven mesh
    allPts.clear();

    // walk through the driven mesh
    /// copy MItGeometry's vertex to vertMapOutArrayData
    int i = 0;
    while( !iter.isDone(&status) )
    {
        CHECK_MSTATUS( status );

        MDataHandle initIndexDataHnd = vertMapOutArrayBuilder.addElement( i, &status );
        CHECK_MSTATUS( status );

        int negIndex = -1;

        initIndexDataHnd.setInt( negIndex );
        initIndexDataHnd.setClean();

        // append a vertex position(world coordination) to allPts
        CHECK_MSTATUS(allPts.append( iter.position() * localToWorldMatrix ));
        i = i+1;
        iter.next();
    }
    CHECK_MSTATUS(vertMapOutArrayData.set( vertMapOutArrayBuilder ));




    /// Append more vertex from each driver mesh to vertMapOutArrayData
    MArrayDataHandle meshAttrHandle = data.inputArrayValue( driver_mesh, &status );
    CHECK_MSTATUS( status );

    int numMeshes = meshAttrHandle.elementCount();
    __debug("%s(), numMeshes=%d", __FUNCTION__, numMeshes);

    CHECK_MSTATUS(meshAttrHandle.jumpToElement(0));
    for( int meshIndex=0; meshIndex < numMeshes; ++meshIndex )
    {
        __debug("%s(), meshIndex=%d", __FUNCTION__, meshIndex);

        MDataHandle currentMesh = meshAttrHandle.inputValue(&status);
        CHECK_MSTATUS(status);

        MObject meshMobj = currentMesh.asMesh();
        __debug("%s(), meshMobj.apiTypeStr()=%s", __FUNCTION__, meshMobj.apiTypeStr());

        __debugMeshInfo(__FUNCTION__, meshMobj);
        {
            _initVertMapping_on_one_mesh(meshMobj, vertMapOutArrayBuilder, allPts);// Note: vertMapOutArrayBuilder is updated in this function!
            //CHECK_MSTATUS(vertMapOutArrayData.set( vertMapOutArrayBuilder ));
        }

        if( !meshAttrHandle.next() )
        {
            break;
        }
    }// for (mesh
    CHECK_MSTATUS(vertMapOutArrayData.set( vertMapOutArrayBuilder ));



}
예제 #6
0
MStatus TestDeformer::deform(MDataBlock& data,
                          MItGeometry& iter,
                          const MMatrix& localToWorldMatrix,
                          unsigned int mIndex)
{
    MStatus status;

    // get the current node state
    short initialized_mapping = data.inputValue( initialized_data, &status).asShort();
    CHECK_MSTATUS(status);
    __debug("%s(), initialized_mapping=%d, mIndex=%d", __FUNCTION__, initialized_mapping, mIndex);

    if( initialized_mapping == 1 )
    {
        initVertMapping(data, iter, localToWorldMatrix, mIndex);

        // set initialized_data to 2 automatically. User don't have to set it manully.
        MObject tObj  =  thisMObject();
        MPlug setInitMode = MPlug( tObj, initialized_data  );
        setInitMode.setShort( 2 );
        // and sync initialized_mapping from initialized_data
        // so, the code section:
        //     if (initialized_mapping == 2)
        //     {
        //         ...
        //     }
        // will be executed when this deform() function is called next time.
        initialized_mapping = data.inputValue( initialized_data, &status ).asShort();
        CHECK_MSTATUS(status);
    }

    if( initialized_mapping == 2 )
    {
        envelope = MPxDeformerNode::envelope;
        MDataHandle envelopeHandle = data.inputValue( envelope, &status );
        CHECK_MSTATUS( status );

        MArrayDataHandle vertMapArrayData  = data.inputArrayValue( vert_map, &status  );
        CHECK_MSTATUS( status );

        MArrayDataHandle meshAttrHandle = data.inputArrayValue( driver_mesh, &status );
        CHECK_MSTATUS( status );


        /// 1. init tempOutputPts to zero points
        MPointArray tempOutputPts;
        iter.reset();
        while( !iter.isDone(&status) )
        {
            CHECK_MSTATUS(tempOutputPts.append(MPoint(0, 0, 0)));
            CHECK_MSTATUS(iter.next());
        }
        assert(tempOutputPts.length() == iter.count());


        /// 2. set tempOutputPts to deform values which comes from each driver mesh
        iter.reset();

        int numMeshes = meshAttrHandle.elementCount();
        __debug("%s(), numMeshes=%d", __FUNCTION__, numMeshes);

        CHECK_MSTATUS(meshAttrHandle.jumpToElement(0));
        // for each driver mesh
        for( int count=0; count < numMeshes; ++count )
        {
            __debug("%s(), count=%d", __FUNCTION__, count);

            // for one driver mesh: currentMesh
            MDataHandle currentMesh = meshAttrHandle.inputValue(&status);
            CHECK_MSTATUS( status );
            MObject meshMobj = currentMesh.asMesh();
            __debugMeshInfo(__FUNCTION__, meshMobj);

            // accumulate deform values of currentMesh to tempOutputPts
            _deform_on_one_mesh(data, iter, localToWorldMatrix, mIndex,
                                meshMobj,
                                envelopeHandle, vertMapArrayData, tempOutputPts );


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

        }// for each driver mesh


        /// 3. add deform value to this geometry(driven mesh)
        int i = 0;
        iter.reset();
        while( !iter.isDone(&status) )
        {
            MPoint p = iter.position(MSpace::kObject, &status);
            CHECK_MSTATUS(status);

            // add the deform value to this vertex
            CHECK_MSTATUS(iter.setPosition( p + tempOutputPts[i]/numMeshes ));

            CHECK_MSTATUS(iter.next());
            ++i;
        }
        assert(tempOutputPts.length() == iter.count());
    }// if

	return( MS::kSuccess );
}
예제 #7
0
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;
}
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;
}
예제 #9
0
MObject fullLoft::loft( MArrayDataHandle &inputArray, MObject &newSurfData,
					  MStatus &stat )
{
	MFnNurbsSurface surfFn;
	MPointArray cvs;
	MDoubleArray ku, kv;
	int i, j;
	int numCVs;
	int numCurves = inputArray.elementCount ();

	// Ensure that we have at least 1 element in the input array
	// We must not do an inputValue on an element that does not
	// exist.
	if ( numCurves < 1 )
		return MObject::kNullObj;

	// Count the number of CVs
	inputArray.jumpToElement(0);
	MDataHandle elementHandle = inputArray.inputValue(&stat);
	if (!stat) {
		stat.perror("fullLoft::loft: inputValue");
		return MObject::kNullObj;
	}
	MObject countCurve (elementHandle.asNurbsCurve());
	MFnNurbsCurve countCurveFn (countCurve);
	numCVs = countCurveFn.numCVs (&stat);
	PERRORnull("fullLoft::loft counting CVs");

	// Create knot vectors for U and V
	// U dimension contains one CV from each curve, triple knotted
	for (i = 0; i < numCurves; i++)
	{
		ku.append (double (i));
		ku.append (double (i));
		ku.append (double (i));
	}

	// V dimension contains all of the CVs from one curve, triple knotted at
	// the ends
	kv.append( 0.0 );
	kv.append( 0.0 );
	kv.append( 0.0 );

	for ( i = 1; i < numCVs - 3; i ++ )
		kv.append( (double) i );

	kv.append( numCVs-3 );
	kv.append( numCVs-3 );
	kv.append( numCVs-3 );

	// Build the surface's CV array
	for (int curveNum = 0; curveNum < numCurves; curveNum++)
	{
		MObject curve (inputArray.inputValue ().asNurbsCurve ());
		MFnNurbsCurve curveFn (curve);
		MPointArray curveCVs;

		stat = curveFn.getCVs (curveCVs, MSpace::kWorld);
		PERRORnull("fullLoft::loft getting CVs");

		if (curveCVs.length() != (unsigned)numCVs)
			stat = MS::kFailure;
		PERRORnull("fullLoft::loft inconsistent number of CVs - rebuild curves");

		// Triple knot for every curve but the first
		int repeats = (curveNum == 0) ? 1 : 3;

		for (j = 0; j < repeats; j++)
			for ( i = 0; i < numCVs; i++ )
				cvs.append (curveCVs [i]);

		stat = inputArray.next ();
	}
	MObject surf = surfFn.create(cvs, ku, kv, 3, 3,
								 MFnNurbsSurface::kOpen,
								 MFnNurbsSurface::kOpen,
								 false, newSurfData, &stat );
	PERRORnull ("fullLoft::Loft create surface");

	return surf;
}
예제 #10
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;
}
예제 #11
0
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock)
{
    MStatus status;

    // update the frame number to be imported
    MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status);
    double speed = speedHandle.asDouble();

    MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status);
    double offset = offsetHandle.asDouble();

    MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status);
    MTime t = timeHandle.asTime();
    double inputTime = t.as(MTime::kSeconds);

    double fps = getFPS();

    // scale and offset inputTime.
    inputTime = computeAdjustedTime(inputTime, speed, offset/fps);

    // this should be done only once per file
    if (mFileInitialized == false)
    {
        mFileInitialized = true;

        MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr);
        MFileObject fileObject;
        fileObject.setRawFullName(dataHandle.asString());
        MString fileName = fileObject.resolvedFullName();

        // TODO, make sure the file name, or list of files create a valid
        // Alembic IArchive

        // initialize some flags for plug update
        mSubDInitialized = false;
        mPolyInitialized = false;

        // When an alembic cache will be imported at the first time using
        // AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be
        // mIncludeFilterString for later use. When we save a maya scene(.ma)
        // mIncludeFilterAttr will be saved. Then when we load the saved
        // .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr.
        MDataHandle includeFilterHandle =
                        dataBlock.inputValue(mIncludeFilterAttr, &status);
        MString& includeFilterString = includeFilterHandle.asString();

       if (mIncludeFilterString.length() > 0)
        {
            includeFilterHandle.set(mIncludeFilterString);
            dataBlock.setClean(mIncludeFilterAttr);
        }
        else if (includeFilterString.length() > 0)
        {
            mIncludeFilterString = includeFilterString;
        }

        MDataHandle excludeFilterHandle =
                        dataBlock.inputValue(mExcludeFilterAttr, &status);
        MString& excludeFilterString = excludeFilterHandle.asString();

       if (mExcludeFilterString.length() > 0)
        {
            excludeFilterHandle.set(mExcludeFilterString);
            dataBlock.setClean(mExcludeFilterAttr);
        }
        else if (excludeFilterString.length() > 0)
        {
            mExcludeFilterString = excludeFilterString;
        }


        MFnDependencyNode dep(thisMObject());
        MPlug allSetsPlug = dep.findPlug("allColorSets");
        CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(),
            MObject::kNullObj, CreateSceneVisitor::NONE, "",
            mIncludeFilterString, mExcludeFilterString);

        {
           mData.getFrameRange(mSequenceStartTime, mSequenceEndTime);
            MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr,
                                                                &status);
            startFrameHandle.set(mSequenceStartTime*fps);
            MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr,
                                                                &status);
            endFrameHandle.set(mSequenceEndTime*fps);
        }
    }

    // Retime
    MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status);
    short playType = cycleHandle.asShort();
    inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime,
                              playType);

    clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime);

    // update only when the time lapse is big enough
    if (fabs(inputTime - mCurTime) > 0.00001)
    {
        mOutRead = std::vector<bool>(mOutRead.size(), false);
        mCurTime = inputTime;
    }

    if (plug == mOutPropArrayAttr)
    {

        if (mOutRead[0])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[0] = true;

        unsigned int propSize =
            static_cast<unsigned int>(mData.mPropList.size());

        if (propSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPropArrayAttr, &status);

            unsigned int outHandleIndex = 0;
            MDataHandle outHandle;

            // for all of the nodes with sampled attributes
            for (unsigned int i = 0; i < propSize; i++)
            {
                // only use the handle if it matches the index.
                // The index wont line up in the sparse case so we
                // can just skip that element.
                if (outArrayHandle.elementIndex() == outHandleIndex++)
                {
                    outHandle = outArrayHandle.outputValue();
                }
                else
                {
                    continue;
                }

                if (mData.mPropList[i].mArray.valid())
                {
                    readProp(mCurTime, mData.mPropList[i].mArray, outHandle);
                }
                else if (mData.mPropList[i].mScalar.valid())
                {
                    // for visibility only
                    if (mData.mPropList[i].mScalar.getName() ==
                        Alembic::AbcGeom::kVisibilityPropertyName)
                    {
                        Alembic::Util::int8_t visVal = 1;
                        mData.mPropList[i].mScalar.get(&visVal,
                            Alembic::Abc::ISampleSelector(mCurTime,
                                Alembic::Abc::ISampleSelector::kNearIndex ));
                        outHandle.setGenericBool(visVal != 0, false);
                    }
                    else
                    {
                        // for all scalar props
                        readProp(mCurTime, mData.mPropList[i].mScalar, outHandle);
                    }
                }
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
        }

    }
    else if (plug == mOutTransOpArrayAttr )
    {
        if (mOutRead[1])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[1] = true;

        unsigned int xformSize =
            static_cast<unsigned int>(mData.mXformList.size());

        if (xformSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutTransOpArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < xformSize; i++)
            {
                std::vector<double> sampleList;

                if (mData.mIsComplexXform[i])
                {
                    readComplex(mCurTime, mData.mXformList[i], sampleList);
                }
                else
                {
                    Alembic::AbcGeom::XformSample samp;
                    read(mCurTime, mData.mXformList[i], sampleList, samp);
                }

                unsigned int sampleSize = (unsigned int)sampleList.size();

                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutLocatorPosScaleArrayAttr )
    {
        if (mOutRead[8])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[8] = true;

        unsigned int locSize =
            static_cast<unsigned int>(mData.mLocList.size());

        if (locSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < locSize; i++)
            {
                std::vector< double > sampleList;
                read(mCurTime, mData.mLocList[i], sampleList);

                unsigned int sampleSize = (unsigned int)sampleList.size();
                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutSubDArrayAttr)
    {
        if (mOutRead[2])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutSubDArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[2] = true;

        unsigned int subDSize =
            static_cast<unsigned int>(mData.mSubDList.size());

        if (subDSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < subDSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j],
                        mSubDInitialized);
                    outHandle.set(obj);
                }
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue();
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutPolyArrayAttr)
    {
        if (mOutRead[3])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[3] = true;

        unsigned int polySize =
            static_cast<unsigned int>(mData.mPolyMeshList.size());

        if (polySize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < polySize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j],
                        mPolyInitialized);
                    outHandle.set(obj);
                }
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPolyArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue(&status);
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutCameraArrayAttr)
    {
        if (mOutRead[4])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[4] = true;

        unsigned int cameraSize =
            static_cast<unsigned int>(mData.mCameraList.size());

        if (cameraSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutCameraArrayAttr, &status);
            MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr);
            double angleConversion = 1.0;

            switch (MAngle::uiUnit())
            {
                case MAngle::kRadians:
                    angleConversion = 0.017453292519943295;
                break;
                case MAngle::kAngMinutes:
                    angleConversion = 60.0;
                break;
                case MAngle::kAngSeconds:
                    angleConversion = 3600.0;
                break;
                default:
                break;
            }

            MDataHandle outHandle;
            unsigned int index = 0;

            for (unsigned int cameraIndex = 0; cameraIndex < cameraSize;
                cameraIndex++)
            {
                Alembic::AbcGeom::ICamera & cam =
                    mData.mCameraList[cameraIndex];
                std::vector<double> array;

                read(mCurTime, cam, array);

                for (unsigned int dataIndex = 0; dataIndex < array.size();
                    dataIndex++, index++)
                {
                    // skip over sparse elements
                    if (index != outArrayHandle.elementIndex())
                    {
                        continue;
                    }

                    outHandle = outArrayHandle.outputValue(&status);
                    outArrayHandle.next();

                    // not shutter angle index, so not an angle
                    if (dataIndex != 11)
                    {
                        outHandle.set(array[dataIndex]);
                    }
                    else
                    {
                        outHandle.set(array[dataIndex] * angleConversion);
                    }
                }  // for the per camera data handles
            }  // for each camera
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsSurfaceArrayAttr)
    {
        if (mOutRead[5])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[5] = true;

        unsigned int nSurfaceSize =
            static_cast<unsigned int>(mData.mNurbsList.size());

        if (nSurfaceSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < nSurfaceSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                    continue;

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kNurbsSurface))
                {
                    readNurbs(mCurTime, mData.mNurbsList[j], obj);
                    outHandle.set(obj);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsCurveGrpArrayAttr)
    {
        if (mOutRead[6])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[6] = true;

        unsigned int nCurveGrpSize =
            static_cast<unsigned int>(mData.mCurvesList.size());

        if (nCurveGrpSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            MDataHandle outHandle;

            std::vector<MObject> curvesObj;
            for (unsigned int i = 0; i < nCurveGrpSize; ++i)
            {
                readCurves(mCurTime, mData.mCurvesList[i],
                    mData.mNumCurves[i], curvesObj);
            }

            std::size_t numChild = curvesObj.size();

            // not the best way to do this
            // only reading bunches of curves based on the connections would be
            // more efficient when there is a bunch of broken connections
            for (unsigned int i = 0; i < numChild; i++)
            {
                if (outArrayHandle.elementIndex() != i)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();
                status = outHandle.set(curvesObj[i]);
            }

            outArrayHandle.setAllClean();
        }
    }
    else
    {
        return MS::kUnknownParameter;
    }

    dataBlock.setClean(plug);
    return status;
}
예제 #12
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;
}
예제 #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;
}
예제 #14
0
MStatus
HRBFSkinCluster::skinDQ(MMatrixArray&  transforms,
						int numTransforms,
						MArrayDataHandle& weightListHandle,
						MItGeometry& iter) {
	MStatus returnStatus;

	// compute dual quaternions. we're storing them as a parallel array.
	std::vector<MQuaternion> tQuaternions(numTransforms); // translation quaterions
	std::vector<MQuaternion> rQuaternions(numTransforms); // rotation quaternions

	for (int i = 0; i < numTransforms; i++) {
		rQuaternions.at(i) = getRotationQuaternion(transforms[i]);
		rQuaternions.at(i).normalizeIt();
		tQuaternions.at(i) = getTranslationQuaternion(transforms[i], rQuaternions.at(i));
#if DEBUG_PRINTS
		std::cout << "rota quaternion " << i << " is: " << rQuaternions.at(i) << std::endl;
		std::cout << "tran quaternion " << i << " is: " << tQuaternions.at(i) << std::endl;
#endif
	}

	MQuaternion rBlend; // blended rotation quaternions
	MQuaternion tBlend; // blended translation quaternions
	MQuaternion scaleMe; // Maya's quaternion scaling is in-place
	double weight;


	// Iterate through each point in the geometry.
	//
	for (; !iter.isDone(); iter.next()) {
		MPoint pt = iter.position();
		MPoint skinned;

		rBlend = MQuaternion(); // reset
		tBlend = MQuaternion(); // reset
		rBlend[3] = 0.0;
		tBlend[3] = 0.0;

		// get the weights for this point
		MArrayDataHandle weightsHandle = weightListHandle.inputValue().child(weights);

		// compute the skinning
		for (int i = 0; i<numTransforms; ++i) {
			if (MS::kSuccess == weightsHandle.jumpToElement(i)) {
				weight = weightsHandle.inputValue().asDouble();
				scaleMe = rQuaternions.at(i);
				rBlend = rBlend + scaleMe.scaleIt(weight);
				scaleMe = tQuaternions.at(i);
				tBlend = tBlend + scaleMe.scaleIt(weight);
			}
		}

		MMatrix dqMatrix = makeDQMatrix(rBlend.normalizeIt(), tBlend);
		skinned = pt * dqMatrix;

		// Set the final position.
		iter.setPosition(skinned);

		// advance the weight list handle
		weightListHandle.next();
	}
	return returnStatus;
}
예제 #15
0
MStatus
HRBFSkinCluster::deform( MDataBlock& block,
                      MItGeometry& iter,
                      const MMatrix& m,
                      unsigned int multiIndex)
//
// Method: deform1
//
// Description:   Deforms the point with a simple smooth skinning algorithm
//
// Arguments:
//   block      : the datablock of the node
//   iter       : an iterator for the geometry to be deformed
//   m          : matrix to transform the point into world space
//   multiIndex : the index of the geometry that we are deforming
//
//
{
	MStatus returnStatus;

	// get HRBF status
	MDataHandle HRBFstatusData = block.inputValue(rebuildHRBF, &returnStatus);
	McheckErr(returnStatus, "Error getting rebuildHRBF handle\n");
	int rebuildHRBFStatusNow = HRBFstatusData.asInt();
	// handle signaling to the rest of deform that HRBFs must be rebuild
	bool signalRebuildHRBF = false;
	signalRebuildHRBF = (rebuildHRBFStatus != rebuildHRBFStatusNow);
	MMatrixArray bindTFs; // store just the bind transforms in here.
	MMatrixArray boneTFs; // ALWAYS store just the bone transforms in here.

	// get HRBF export status
	MDataHandle exportCompositionData = block.inputValue(exportComposition, &returnStatus);
	McheckErr(returnStatus, "Error getting exportComposition handle\n");
	int exportCompositionStatusNow = exportCompositionData.asInt();

	MDataHandle HRBFExportSamplesData = block.inputValue(exportHRBFSamples, &returnStatus);
	McheckErr(returnStatus, "Error getting exportHRBFSamples handle\n");
	std::string exportHRBFSamplesStatusNow = HRBFExportSamplesData.asString().asChar();

	MDataHandle HRBFExportValuesData = block.inputValue(exportHRBFValues, &returnStatus);
	McheckErr(returnStatus, "Error getting exportHRBFValues handle\n");
	std::string exportHRBFValuesStatusNow = HRBFExportValuesData.asString().asChar();

	// get skinning type
	MDataHandle useDQData = block.inputValue(useDQ, &returnStatus);
	McheckErr(returnStatus, "Error getting useDQ handle\n");
	int useDQNow = useDQData.asInt();

	// determine if we're using HRBF
	MDataHandle useHRBFData = block.inputValue(useHRBF, &returnStatus);
	McheckErr(returnStatus, "Error getting useHRBFData handle\n");
	int useHRBFnow = useHRBFData.asInt();

	// get envelope because why not
	MDataHandle envData = block.inputValue(envelope, &returnStatus);
	float env = envData.asFloat();

	// get point in space for evaluating HRBF
	MDataHandle checkHRBFAtData = block.inputValue(checkHRBFAt, &returnStatus);
	McheckErr(returnStatus, "Error getting useDQ handle\n");
	double* data = checkHRBFAtData.asDouble3();

	// get the influence transforms
	//
	MArrayDataHandle transformsHandle = block.inputArrayValue( matrix ); // tell block what we want
	int numTransforms = transformsHandle.elementCount();
	if ( numTransforms == 0 ) { // no transforms, no problems
		return MS::kSuccess;
	}
	MMatrixArray transforms; // fetch transform matrices -> actual joint matrices
	for ( int i=0; i<numTransforms; ++i ) {
		MMatrix worldTF = MFnMatrixData(transformsHandle.inputValue().data()).matrix();
		transforms.append(worldTF);
		boneTFs.append(worldTF);
		transformsHandle.next();
	}
	// inclusive matrices inverse of the driving transform at time of bind
	// matrices for transforming vertices to joint local space
	MArrayDataHandle bindHandle = block.inputArrayValue( bindPreMatrix ); // tell block what we want
	if ( bindHandle.elementCount() > 0 ) {
		for ( int i=0; i<numTransforms; ++i ) {
			MMatrix bind = MFnMatrixData(bindHandle.inputValue().data()).matrix();
			transforms[i] = bind * transforms[i];
			bindHandle.next();
			if (signalRebuildHRBF) bindTFs.append(bind);
		}
	}

	MArrayDataHandle weightListHandle = block.inputArrayValue(weightList);
	if (weightListHandle.elementCount() == 0) {
		// no weights - nothing to do
		std::cout << "no weights!" << std::endl;
		//rebuildHRBFStatus = rebuildHRBFStatusNow - 1; // HRBFs will need to rebuilt no matter what
		return MS::kSuccess;
	}

	// print HRBF samples if requested
	if (exportHRBFSamplesStatusNow != exportHRBFSamplesStatus) {
		std::cout << "instructed to export HRBF samples: " << exportHRBFSamplesStatusNow.c_str() << std::endl;
		exportHRBFSamplesStatus = exportHRBFSamplesStatusNow;
		// TODO: handle exporting HRBFs to the text file format
		hrbfMan->debugSamplesToConsole(exportHRBFSamplesStatus);
	}

	// print HRBF values if requested
	if (exportHRBFValuesStatusNow != exportHRBFValuesStatus) {
		std::cout << "instructed to export HRBF values: " << exportHRBFValuesStatusNow.c_str() << std::endl;
		exportHRBFValuesStatus = exportHRBFValuesStatusNow;
		// TODO: handle exporting HRBFs to the text file format
		hrbfMan->debugValuesToConsole(exportHRBFValuesStatus);
	}

	// print HRBF composition if requested
	if (exportCompositionStatusNow != exportCompositionStatus) {
		std::cout << "instructed to export HRBF composition." << std::endl;
		exportCompositionStatus = exportCompositionStatusNow;
		// TODO: handle exporting HRBFs to the text file format
		hrbfMan->debugCompositionToConsole(boneTFs, numTransforms);
	}

	// check the HRBF value if the new point is significantly different
	MPoint checkHRBFHereNow(data[0], data[1], data[2]);
	if ((checkHRBFHereNow - checkHRBFHere).length() > 0.0001) {
		if (hrbfMan->m_HRBFs.size() == numTransforms) {
			std::cout << "checking HRBF at x:" << data[0] << " y: " << data[1] << " z: " << data[2] << std::endl;
			hrbfMan->compose(boneTFs);
			float val = 0.0f;
			float dx = 0.0f;
			float dy = 0.0f;
			float dz = 0.0f;
			float grad = 0.0f;

			hrbfMan->mf_vals->trilinear(data[0], data[1], data[2], val);
			hrbfMan->mf_gradX->trilinear(data[0], data[1], data[2], dx);
			hrbfMan->mf_gradY->trilinear(data[0], data[1], data[2], dy);
			hrbfMan->mf_gradZ->trilinear(data[0], data[1], data[2], dz);
			hrbfMan->mf_gradMag->trilinear(data[0], data[1], data[2], grad);
			std::cout << "val: " << val << " dx: " << dx << " dy: " << dy << " dz: " << dz << " grad: " << grad << std::endl;
			checkHRBFHere = checkHRBFHereNow;
		}
	}

	// rebuild HRBFs if needed
	if (signalRebuildHRBF) {
		std::cout << "instructed to rebuild HRBFs" << std::endl;
		rebuildHRBFStatus = rebuildHRBFStatusNow;

		MArrayDataHandle parentIDCsHandle = block.inputArrayValue(jointParentIdcs); // tell block what we want
		std::vector<int> jointParentIndices(numTransforms);
		if (parentIDCsHandle.elementCount() > 0) {
			for (int i = 0; i<numTransforms; ++i) {
				jointParentIndices[i] = parentIDCsHandle.inputValue().asInt();
				parentIDCsHandle.next();
			}
		}

		MArrayDataHandle jointNamesHandle = block.inputArrayValue(jointNames); // tell block what we want
		std::vector<std::string> jointNames(numTransforms);
		if (jointNamesHandle.elementCount() > 0) {
			for (int i = 0; i<numTransforms; ++i) {
				jointNames[i] = jointNamesHandle.inputValue().asString().asChar();
				jointNamesHandle.next();
			}
		}

		// debug
		//std::cout << "got joint hierarchy info! it's:" << std::endl;
		//for (int i = 0; i < numTransforms; ++i) {
		//	std::cout << i << ": " << jointNames[i].c_str() << " : " << jointParentIndices[i] << std::endl;
		//}
		std::cout << "rebuilding HRBFs... " << std::endl;
		hrbfMan->buildHRBFs(jointParentIndices, jointNames, bindTFs, boneTFs, 
			weightListHandle, iter, weights);
		std::cout << "done rebuilding!" << std::endl;
		weightListHandle.jumpToElement(0); // reset this, it's an iterator. trust me.
		iter.reset(); // reset this iterator so we can go do normal skinning
	}


	// perform traditional skinning
	if (useDQNow != 0) {
		returnStatus = skinDQ(transforms, numTransforms, weightListHandle, iter);
	}
	else {
		returnStatus = skinLB(transforms, numTransforms, weightListHandle, iter);
	}

	// do HRBF corrections
	if (useHRBFnow != 0) {
		if (hrbfMan->m_HRBFs.size() == numTransforms) {
			hrbfMan->compose(boneTFs);
			iter.reset();
			hrbfMan->correct(iter);
		}
	}

	return returnStatus;
}
예제 #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;
}
예제 #17
0
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;
}
예제 #18
0
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;
}
예제 #19
0
MStatus BCIViz::compute( const MPlug& plug, MDataBlock& block )
{
	if( plug == outValue ) {
		MStatus status;
		
		MDagPath path;
		MDagPath::getAPathTo(thisMObject(), path);
		
		MMatrix worldInverseSpace = path.inclusiveMatrixInverse();
		
		MDataHandle inputdata = block.inputValue(ainput, &status);
        if(status) {
			const MMatrix drvSpace = inputdata.asMatrix();
			fDriverPos.x = drvSpace(3, 0);
			fDriverPos.y = drvSpace(3, 1);
			fDriverPos.z = drvSpace(3, 2);
			
			fDriverPos *= worldInverseSpace;
		}
		
		fTargetPositions.clear();
		
		MArrayDataHandle htarget = block.inputArrayValue( atargets );
		unsigned numTarget = htarget.elementCount();
		
		fTargetPositions.setLength(numTarget);
		
		for(unsigned i = 0; i<numTarget; i++) {
			MDataHandle tgtdata = htarget.inputValue(&status);
			if(status) {
				const MMatrix tgtSpace = tgtdata.asMatrix();
				MPoint tgtPos(tgtSpace(3,0), tgtSpace(3,1), tgtSpace(3,2));
				tgtPos *= worldInverseSpace;
				MVector disp = tgtPos;
				disp.normalize();
				tgtPos = disp;
				fTargetPositions[i] = tgtPos;
			}
			htarget.next();
		}
		
		m_hitTriangle = 0;
		neighbourId[0] = 0;
		neighbourId[1] = 1;
		neighbourId[2] = 2;
		
		if(!checkTarget())
		{
			MGlobal::displayWarning("convex hull must have no less than 4 targes.");
			return MS::kSuccess;
		}
		
		if(!checkFirstFour(fTargetPositions))
		{
			MGlobal::displayWarning("first 4 targes cannot sit on the same plane.");
			return MS::kSuccess;
		}
		
		if(!constructHull())
		{
			MGlobal::displayWarning("convex hull failed on construction.");
			return MS::kSuccess;
		}

		findNeighbours();
		
		calculateWeight();

        MArrayDataHandle outputHandle = block.outputArrayValue( outValue );
		
		int numWeight = fTargetPositions.length();

		m_resultWeights.setLength(numWeight);
		
		for(int i=0; i < numWeight; i++) 
			m_resultWeights[i] = 0.0;
			
		m_resultWeights[neighbourId[0]] = fAlpha;
		m_resultWeights[neighbourId[1]] = fBeta;
		m_resultWeights[neighbourId[2]] = fGamma;
		
		MArrayDataBuilder builder(outValue, numWeight, &status);
		
		for(int i=0; i < numWeight; i++) {
			MDataHandle outWeightHandle = builder.addElement(i);
			outWeightHandle.set( m_resultWeights[i] );
			//MGlobal::displayInfo(MString("wei ") + i + " " + weights[i]);
		}
		
		outputHandle.set(builder);
		outputHandle.setAllClean();
    }

	return MS::kSuccess;
}
예제 #20
0
MStatus NBuddyEMPSaverNode::compute( const MPlug& plug, MDataBlock& data )
{
    MStatus status;
    if (plug == _outTrigger)
    {
	MDataHandle outputPathHdl = data.inputValue( _empOutputPath, &status );
        NM_CheckMStatus( status, "Failed to get the output path handle");
	MString outputPath = outputPathHdl.asString();

       	// Get the input time
	MDataHandle timeHdl = data.inputValue( _time, &status );
	NM_CheckMStatus( status, "Failed to get time handle");
	MTime time = timeHdl.asTime();

        // Get the frame padding
        MDataHandle framePaddingHdl = data.inputValue( _framePadding, &status );
        NM_CheckMStatus( status, "Failed to get the framePadding handle");
        int numPad = framePaddingHdl.asInt();

      // Get the frame padding
        MDataHandle timeStepHdl = data.inputValue( _timeStep, &status );
        NM_CheckMStatus( status, "Failed to get the timeStep handle");
        int timeStep = timeStepHdl.asInt();
  
        // Get the time in frames
        int frameNr = (int)floor( time.as( time.uiUnit() ) );

        //Create the writer, givin it the time index in seconds
        Nb::EmpWriter* writer = 
            new Nb::EmpWriter( 
                "",
                outputPath.asChar(),       // absolute fullpath of emp
                frameNr,                   // frame
                timeStep,                  // timestep
                numPad,                    // zero-padding                
                time.as( MTime::kSeconds ) // emp timestamp
                );

        // Then get the inputBodies
        MArrayDataHandle inBodyArrayData = data.inputArrayValue( _inBodies, &status );
        NM_CheckMStatus( status, "Failed to create get inBodyArrayData handle");

        // Loop the input in the inBody multi plug
        unsigned int numBodies = inBodyArrayData.elementCount();
        if ( numBodies > 0 )
        {
            //Jump to the first element in the array
            inBodyArrayData.jumpToArrayElement(0);

            //Loop all the body inputs and add them to the empWriter
            for ( unsigned int i(0); i < numBodies; ++i)
            {
                MDataHandle bodyDataHnd = inBodyArrayData.inputValue( &status );
                MFnPluginData dataFn(bodyDataHnd.data());

                //Get naiad body from datatype
                naiadBodyData * bodyData = (naiadBodyData*)dataFn.data( &status );
                if ( bodyData && bodyData->nBody() )
                {
                    //Add body to writer
                    try{
                        Nb::String channels("*.*");
                        writer->write(bodyData->nBody(),channels);
                    }
                    catch(std::exception& e) {
                        std::cerr << "NBuddyEMPSaverNode::compute() " << e.what() << std::endl;
                    }
                }
                else
                    std::cerr << "NBuddyEMPSaverNode::compute() :: No body in input " << inBodyArrayData.elementIndex() << std::endl;

                //Next body in the input multi
                inBodyArrayData.next();
            }
        }

        try{
            writer->close();
            // Get rid of the writer object
            delete writer;
        }
        catch(std::exception& e) {
            std::cerr << "NBuddyEMPSaverNode::compute() " << e.what() << std::endl;
        }

        //Set the output to be clean indicating that we have saved out the file
        MDataHandle outTriggerHnd = data.outputValue( _outTrigger, &status );
        outTriggerHnd.set(true);
        data.setClean( plug );
    }

    return status;
}
예제 #21
0
	// ==========================================================================================================
	// ==========================================================================================================
	virtual MStatus compute(const MPlug& plug, MDataBlock& dataBlock)
	{

		// enable this node or not
		if ( dataBlock.inputValue(aEnable).asBool() == false )
		{
			return MS::kSuccess;
		}

		// check if the inpute attribute is connected
		// in Not, stop compute()
		// in order to avoid crash when disconnect input attributes on the fly 
		
		//cout << "isPlugConnect: " << isPlugConnect(aVolumeObj) << endl;
		
		if ( isPlugConnect(aSourceObj) == false || isPlugConnect(aVolumeObj) == false )
		{
			return MS::kSuccess;
		}

		// execution when output attr needs to be updated
		if ( plug == aOutValue || plug == aOutMesh || plug == aOutCompList )
		{
			// test if input source object is a valid type
			if ( dataBlock.inputValue(aSourceObj).type() != MFnData::kMesh )
			{
				MGlobal::displayInfo( MString("No Object Input!") ); 
				return MS::kSuccess;
			}

			MObject sourceObj = dataBlock.inputValue(aSourceObj).asMeshTransformed();

			MArrayDataHandle arrayHandle = dataBlock.inputValue(aVolumeObj);
			arrayHandle.jumpToArrayElement(0);

			MSelectionList sList;		// add the vertice every ligal loop 
			for ( int idx=0; idx < arrayHandle.elementCount(); idx++, arrayHandle.next() )
			{

				// first, check if the sub-plug is un-connected
				if ( isPlugConnect( aVolumeObj, idx ) == false  )
				{
					cout << "No Data " << idx << endl;
					continue;
				}

				// second, check if the input object is mesh
				if ( arrayHandle.inputValue().type() != MFnData::kMesh )
				{
					return MS::kSuccess;
					MGlobal::displayError( "input voulme objects is not mesh" );
				}

				// input volume object as Wrold mesh
				MObject volumeObj = arrayHandle.inputValue().asMeshTransformed();

				MFnMesh sourceMeshFn;
				MFnMesh volumeMeshFn;

				// third, test if the input obj is compatible with meshFn
				if ( volumeMeshFn.hasObj(sourceObj) && volumeMeshFn.hasObj(volumeObj) )
				{
					volumeMeshFn.setObject(volumeObj);

					// check if object is closed
					if ( isClosedMesh(volumeObj) == false )
					{
						if ( dataBlock.inputValue(aClosedObj).asBool() == true )
						{
							//MGlobal::displayInfo( MString("The volume object is not closed!") );
							continue;
						}
					}

					sourceMeshFn.setObject( sourceObj );
					int numVtx = sourceMeshFn.numVertices();

					vector<int> tmpCompArray;	// an temporary int array to store component index

					// do hit test
					// to check if each source's component is inside
					//
					for ( int i=0; i < numVtx; i++ )
					{
						// get each vertex of source object
						MPoint srcVtx;
						sourceMeshFn.getPoint( i, srcVtx, MSpace::kWorld );

						// Test how much hit is for each vertex 
						// declare parameters for allIntersection()
						MFloatPoint raySource;
						raySource.setCast(srcVtx);

						MFloatVector rayDirection(0, 0, 1);
						MFloatPointArray hitPoints;
						MIntArray hitFaces;

						bool hit = volumeMeshFn.allIntersections( raySource,
																	rayDirection,
																	NULL,
																	NULL,
																	false,
																	MSpace::kWorld,
																	99999,
																	false,
																	NULL,
																	true,
																	hitPoints,
																	NULL,
																	&hitFaces,
																	NULL,
																	NULL,
																	NULL,
																	1e-6 );

						if (hit)
						{
							int isInside = hitFaces.length() % 2;
							// cout << "isInside: " << isInside << endl;

							// if the mod is odd, it's inside
							if ( isInside > 0 )
							{
								tmpCompArray.push_back(i);
							}
						}
					}

					// declare a dynamic array to recieve All elements from tmpCompArray
					int* compArray = new int[tmpCompArray.size()];

					// copy array data from tmpCompArray --> compArray
					memcpy( &compArray[0], &tmpCompArray[0], sizeof( int ) * tmpCompArray.size() );


					// the below processes are to collect component data, and then select them in viewport
					//
					// first, get dagPath from the source object 
					MDagPath dPathSrcObj = getConnectNodeDagPath(aSourceObj);


					// second, get the selection list storing components by feeding comopnet array  
					MSelectionList vtxSelList = getVtxSelList( dPathSrcObj, compArray, tmpCompArray.size() );
					sList.merge(vtxSelList);

					delete [] compArray;
				}
			}
			// end of loop


			// if so, actively select these component
			int compType = dataBlock.inputValue(aComponentType).asInt();
			MSelectionList currCompSelList;

			if( dataBlock.inputValue(aKeepSel).asBool() == true )
			{
				// clear if last-time is not keep selection
				if (flag==0)
				{
					addSelComponentList.clear();
					flag = 1; 
				}
				else
				{
					addSelComponentList.merge(sList);	// merge the accumulative components
					currCompSelList = convertVtxSListToCompSList( addSelComponentList, compType );
					MGlobal::setActiveSelectionList( currCompSelList, MGlobal::kReplaceList );
					flag = 1;
				}
			}
			else
			{
				addSelComponentList.clear();	// celar all components
				addSelComponentList.merge(sList);
				currCompSelList = convertVtxSListToCompSList( addSelComponentList, compType );
				MGlobal::setActiveSelectionList( currCompSelList, MGlobal::kReplaceList );
				flag = 0;
			}

			// keep this node selecting 
			if ( dataBlock.inputValue(aFixPanel).asBool() == true )
				MGlobal::select( thisMObject(), MGlobal::kAddToList );


			// **** OUTPUT ATTRIBUTE ****
			MObject currCompList = getCompListFromSList( currCompSelList );
			
			MFnComponentListData compListDataFn;
			MObject currCompListData = compListDataFn.create();		// pointer to the component data
			compListDataFn.add( currCompList );

			dataBlock.outputValue(aOutCompList).set( currCompListData );
			
			// 
			MFnMeshData outMeshDataFn;
			MObject outObj = outMeshDataFn.create();
			MFnMesh outMeshFn( outObj );
			outMeshFn.copy( sourceObj, outObj );

			dataBlock.outputValue(aOutMesh).set( outObj );
		}		
		// end of if ( plug == aOutValue || plug == aOutMesh )

		return MS::kSuccess;
	}
예제 #22
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;
}
예제 #23
0
// 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 );
}
예제 #24
0
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
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;
}