Exemplo n.º 1
0
MStatus VolumePushCollider::compute(const MPlug& plug, MDataBlock& dataBlock)
{
	MStatus status;

	if (plug == aOutput)
	{
		// inCollider
		MArrayDataHandle hInCollider = dataBlock.inputArrayValue(aInCollider);
		// inVolume
		MArrayDataHandle hInVolume = dataBlock.inputArrayValue(aInVolume);
		// output
		MArrayDataHandle hOutput = dataBlock.inputArrayValue(aOutput);
		MDoubleArray daValues(hInVolume.elementCount());

		for (unsigned int c=0; c<hInCollider.elementCount(); c++)
		{
			// Calculate the total of every collider value for each volume
			status = hInCollider.jumpToArrayElement(c);
			CHECK_MSTATUS_AND_RETURN_IT(status);
			MMatrix mInCollider = hInCollider.inputValue().asMatrix();
			MTransformationMatrix tmInCollider(mInCollider);
			MPoint pInCollider = tmInCollider.getTranslation(MSpace::kWorld, &status);
			CHECK_MSTATUS_AND_RETURN_IT(status);

			for (unsigned int v=0; v<hInVolume.elementCount(); v++)
			{
				// pointMatrixMult
				status = hInVolume.jumpToArrayElement(v);
				CHECK_MSTATUS_AND_RETURN_IT(status);
				MMatrix mInVolume = hInVolume.inputValue().asMatrix();
				MVector vVolCollider = pInCollider * mInVolume;
				// condition
				if (vVolCollider.length() <= 1.0)
				{
					// reverse
					daValues[v] += abs(1.0 - vVolCollider.length());
				}
			}
		}
		for (unsigned int i=0; i<hInVolume.elementCount(); i++)
		{
			// set outputs
			status = hOutput.jumpToArrayElement(i);
			CHECK_MSTATUS_AND_RETURN_IT(status);
			hOutput.outputValue().set(daValues[i]);
		}
		dataBlock.setClean(plug);
	}
	return MS::kSuccess;
}
Exemplo n.º 2
0
void SurfaceAttach::setOutPlugs(MDataBlock dataBlock, const MFnNurbsSurface &fnSurface,
                                const double dataOffset, const bool dataReverse, const short dataGenus, const double dataStaticLength,
                                const MMatrix &dataParentInverse, const short dataDirection) {

    MTransformationMatrix tfm;
    MVector t;
    MEulerRotation r;

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

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

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

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

    // Mark Clean
    dataBlock.setClean(SurfaceAttach::translate);
    dataBlock.setClean(SurfaceAttach::rotate);
    dataBlock.setClean(SurfaceAttach::out);
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
	}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
// COMPUTE ======================================
MStatus gear_curveCns::deform( MDataBlock& data, MItGeometry& iter, const MMatrix &mat, unsigned int mIndex )
{
    MStatus returnStatus;

	MArrayDataHandle adh = data.inputArrayValue( inputs );
	int deformer_count = adh.elementCount( &returnStatus );

	// Process
	while (! iter.isDone()){
		if (iter.index() < deformer_count){
			adh.jumpToElement(iter.index());
			MTransformationMatrix m(adh.inputValue().asMatrix() * mat.inverse());
			MVector v = m.getTranslation(MSpace::kWorld, &returnStatus );
			MPoint pt(v);
			iter.setPosition(pt);
		}
		iter.next();
	}
 
    return MS::kSuccess;
}
Exemplo n.º 7
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 );
}
Exemplo n.º 8
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;
}
Exemplo n.º 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;
}
Exemplo n.º 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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
MStatus nwayDeformerNode::deform( MDataBlock& data, MItGeometry& itGeo, const MMatrix &localToWorldMatrix, unsigned int mIndex )
{
//            clock_t clock_start=clock();

    MObject thisNode = thisMObject();
    MStatus status;
    MThreadUtils::syncNumOpenMPThreads();    // for OpenMP

    MArrayDataHandle hBlendMesh = data.inputArrayValue(aBlendMesh);
    short numIter = data.inputValue( aIteration ).asShort();
    short nblendMode = data.inputValue( aBlendMode ).asShort();
    short ntetMode = data.inputValue( aTetMode ).asShort();
    double visualisationMultiplier = data.inputValue(aVisualisationMultiplier).asDouble();
    bool visualiseEnergy = data.inputValue( aVisualiseEnergy ).asBool();
    bool nrotationCosistency = data.inputValue( aRotationConsistency ).asBool();
    if( nrotationCosistency != rotationCosistency) {
        numMesh = 0;
        rotationCosistency = nrotationCosistency;
    }
    MPointArray Mpts;
    itGeo.allPositions(Mpts);
    int nnumMesh = hBlendMesh.elementCount();
    int numPts = Mpts.length();
    int numTet = (int)tetList.size()/4;
    // initialisation
    if(tetMode != ntetMode) {
//        clock_t clock_start=clock();
        tetMode = ntetMode;
        numMesh = 0;
        // point list
        pts.resize(numPts);
        for(int i=0; i<numPts; i++) {
            pts[i] << Mpts[i].x, Mpts[i].y, Mpts[i].z;
        }
        std::vector<Matrix4d> P;
        getMeshData(data, input, inputGeom, mIndex, tetMode, pts, tetList, faceList, edgeList, vertexList, P);
        dim = removeDegenerate(tetMode, numPts, tetList, faceList, edgeList, vertexList, P);
        makeAdjacencyList(tetMode, tetList, edgeList, vertexList, adjacencyList);
        makeTetMatrix(tetMode, pts, tetList, faceList, edgeList, vertexList, P);
        // prepare ARAP solver
        numTet = (int)tetList.size()/4;
        PI.resize(numTet);
        for(int i=0; i<numTet; i++) {
            PI[i] = P[i].inverse().eval();
        }
        std::vector<double> tetWeight(numTet,1.0);
        std::vector< std::map<int,double> > constraint(0);
        //constraint[0][0]=1.0;
        isError = ARAPprecompute(PI, tetList, tetWeight, constraint, EPSILON, dim, constraintMat, solver);
//        MString es="Init timing: ";
//        double timing=(double)(clock()- clock_start)/CLOCKS_PER_SEC;
//        es += timing;
//        MGlobal::displayInfo(es);
    }
    if(isError>0) return MS::kFailure;
    // if blend mesh is added, compute log for each tet
    logR.resize(nnumMesh);
    logS.resize(nnumMesh);
    R.resize(nnumMesh);
    S.resize(nnumMesh);
    GL.resize(nnumMesh);
    logGL.resize(nnumMesh);
    quat.resize(nnumMesh);
    L.resize(nnumMesh);
    // for recomputation of parametrisation
    if(numMesh>nnumMesh || nblendMode != blendMode) {
        numMesh =0;
        blendMode = nblendMode;
    }
    for(int j=numMesh; j<nnumMesh; j++) {
        hBlendMesh.jumpToElement(j);
        MFnMesh blendMesh(hBlendMesh.inputValue().asMesh());
        MPointArray Mbpts;
        blendMesh.getPoints( Mbpts );
        if(numPts != Mbpts.length()) {
            MGlobal::displayInfo("incompatible mesh");
            return MS::kFailure;
        }
        std::vector<Vector3d> bpts(numPts);
        for(int i=0; i<numPts; i++) {
            bpts[i] << Mbpts[i].x, Mbpts[i].y, Mbpts[i].z;
        }
        std::vector<Matrix4d> Q(numTet);
        makeTetMatrix(tetMode, bpts, tetList, faceList, edgeList, vertexList, Q);
        logR[j].resize(numTet);
        logS[j].resize(numTet);
        R[j].resize(numTet);
        S[j].resize(numTet);
        GL[j].resize(numTet);
        logGL[j].resize(numTet);
        quat[j].resize(numTet);
        L[j].resize(numTet);
        for(int i=0; i<numTet; i++)  {
            Matrix4d aff=PI[i]*Q[i];
            GL[j][i]=aff.block(0,0,3,3);
            L[j][i]=transPart(aff);
            parametriseGL(GL[j][i], logS[j][i] ,R[j][i]);
        }
        if( blendMode == BM_LOG3) {
            for(int i=0; i<numTet; i++)
                logGL[j][i]=GL[j][i].log();
        } else if( blendMode == BM_SQL) {
            for(int i=0; i<numTet; i++) {
                S[j][i]=expSym(logS[j][i]);
                Quaternion<double> q(R[j][i].transpose());
                quat[j][i] << q.x(), q.y(), q.z(), q.w();
            }
        } else if( blendMode == BM_SlRL) {
            for(int i=0; i<numTet; i++) {
                S[j][i]=expSym(logS[j][i]);
            }
        }
        // traverse tetrahedra to compute continuous log of rotation
        if(rotationCosistency) {
            std::set<int> remain;
            std::queue<int> later;
            // load initial rotation from the attr
            Matrix3d initR;
            double angle = data.inputValue(aInitRotation).asDouble();
            initR << 0,M_PI * angle/180.0,0,  -M_PI * angle/180.0,0,0, 0,0,0;
            std::vector<Matrix3d> prevSO(numTet, initR);
            // create the adjacency graph to traverse
            for(int i=0; i<numTet; i++) {
                remain.insert(remain.end(),i);
            }
            while(!remain.empty()) {
                int next;
                if( !later.empty()) {
                    next = later.front();
                    later.pop();
                    remain.erase(next);
                } else {
                    next = *remain.begin();
                    remain.erase(remain.begin());
                }
                logR[j][next]=logSOc(R[j][next],prevSO[next]);
                for(int k=0; k<adjacencyList[next].size(); k++) {
                    int f=adjacencyList[next][k];
                    if(remain.erase(f)>0) {
                        prevSO[f]=logR[j][next];
                        later.push(f);
                    }
                }
            }
        } else {
            for(int i=0; i<numTet; i++)
                logR[j][i] = logSO(R[j][i]);
        }
    }
    numMesh=nnumMesh;
    if(numMesh == 0) return MS::kSuccess;

    // load weights
    std::vector<double> weight(numMesh);
    MArrayDataHandle hWeight = data.inputArrayValue(aWeight);
    if(hWeight.elementCount() != numMesh) {
        return MS::kSuccess;
    }
    for(int i=0; i<numMesh; i++) {
        hWeight.jumpToArrayElement(i);
        weight[i]=hWeight.inputValue().asDouble();
    }
    // compute ideal affine
    std::vector<Vector3d> new_pts(numPts);
    std::vector<Matrix4d> A(numTet);
    std::vector<Matrix3d> AR(numTet),AS(numTet);
    std::vector<Vector3d> AL(numTet);

    blendMatList(L, weight, AL);
    if(blendMode==BM_SRL) {
        blendMatList(logR, weight, AR);
        blendMatList(logS, weight, AS);
        #pragma omp parallel for
        for(int i=0; i<numTet; i++) {
            AR[i] = expSO(AR[i]);
            AS[i] = expSym(AS[i]);
        }
    } else if(blendMode == BM_LOG3) { // log
        blendMatList(logGL, weight, AR);
        #pragma omp parallel for
        for(int i=0; i<numTet; i++) {
            AR[i] = AR[i].exp();
            AS[i] = Matrix3d::Identity();
        }
    } else if(blendMode == BM_SQL) { // quaternion
        std::vector<Vector4d> Aq(numTet);
        blendMatLinList(S, weight, AS);
        blendQuatList(quat, weight, Aq);
        #pragma omp parallel for
        for(int i=0; i<numTet; i++) {
            Quaternion<double> Q(Aq[i]);
            AR[i] = Q.matrix().transpose();
        }
    } else if(blendMode == BM_SlRL) { // expSO+linear Sym
        blendMatList(logR, weight, AR);
        blendMatLinList(S, weight, AS);
        #pragma omp parallel for
        for(int i=0; i<numTet; i++) {
            AR[i] = expSO(AR[i]);
        }
    } else if(blendMode == BM_AFF) { // linear
        blendMatLinList(GL, weight, AR);
        for(int i=0; i<numTet; i++) {
            AS[i] = Matrix3d::Identity();
        }
    } else {
        return MS::kFailure;
    }

    MatrixXd G(dim+1,3),Sol;
    std::vector<double> tetEnergy(numTet);
    // iterate to determine vertices position
    for(int k=0; k<numIter; k++) {
        for(int i=0; i<numTet; i++) {
            A[i]=pad(AS[i]*AR[i],AL[i]);
        }
        // solve ARAP
        std::vector<Vector3d> constraintVector(0);
        std::vector<double> tetWeight(numTet,1.0);
        //constraintVector[0]=pts[0];
        ARAPSolve(A, PI, tetList, tetWeight, constraintVector, EPSILON, dim, constraintMat, solver, Sol);

        // set new vertices position
        for(int i=0; i<numPts; i++) {
            new_pts[i][0]=Sol(i,0);
            new_pts[i][1]=Sol(i,1);
            new_pts[i][2]=Sol(i,2);
        }
        // if iteration continues
        if(k+1<numIter || visualiseEnergy) {
            std::vector<Matrix4d> Q(numTet);
            makeTetMatrix(tetMode, new_pts, tetList, faceList, edgeList, vertexList, Q);
            Matrix3d S,R;
            #pragma omp parallel for
            for(int i=0; i<numTet; i++)  {
                polarHigham((PI[i]*Q[i]).block(0,0,3,3), S, AR[i]);
                tetEnergy[i] = (S-AS[i]).squaredNorm();
            }
        }
    }
    // set new vertex position
    for(int i=0; i<numPts; i++) {
        Mpts[i].x=Sol(i,0);
        Mpts[i].y=Sol(i,1);
        Mpts[i].z=Sol(i,2);
    }
    itGeo.setAllPositions(Mpts);

    // set vertex color according to ARAP energy
    if(visualiseEnergy) {
        std::vector<double> ptsEnergy;
        makePtsWeightList(tetMode, numPts, tetList, faceList, edgeList, vertexList, tetEnergy, ptsEnergy);
        //double max_energy = *std::max_element(ptsEnergy.begin(), ptsEnergy.end());
        outputAttr(data, aEnergy, ptsEnergy);
        for(int i=0; i<numPts; i++) {
            ptsEnergy[i] *= visualisationMultiplier;     //  or /= max_energy
        }
        visualise(data, outputGeom, ptsEnergy);
    }

//    MString es="Runtime timing: ";
//    double timing=(double)(clock()- clock_start)/CLOCKS_PER_SEC;
//    es += timing;
//    MGlobal::displayInfo(es);

    return MS::kSuccess;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
MStatus OnbShader::compute(const MPlug& plug, MDataBlock& block)
{
	// Sanity check
	if (plug != aOutColor && plug.parent() != aOutColor &&
		plug != aOutTransparency && plug.parent() != aOutTransparency)
	{
		return MS::kUnknownParameter;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return MS::kSuccess;
}
MStatus probeDeformerARAPNode::deform( MDataBlock& data, MItGeometry& itGeo, const MMatrix &localToWorldMatrix, unsigned int mIndex )
{
	MObject thisNode = thisMObject();
    MStatus status;
    MThreadUtils::syncNumOpenMPThreads();    // for OpenMP
    
    bool worldMode = data.inputValue( aWorldMode ).asBool();
    bool areaWeighted = data.inputValue( aAreaWeighted ).asBool();
    short stiffnessMode = data.inputValue( aStiffness ).asShort();
    short blendMode = data.inputValue( aBlendMode ).asShort();
    short tetMode = data.inputValue( aTetMode ).asShort();
    short numIter = data.inputValue( aIteration ).asShort();
    short constraintMode = data.inputValue( aConstraintMode ).asShort();
    short visualisationMode = data.inputValue( aVisualisationMode ).asShort();
    mesh.transWeight = data.inputValue( aTransWeight ).asDouble();
    double constraintWeight = data.inputValue( aConstraintWeight ).asDouble();
    double normExponent = data.inputValue( aNormExponent ).asDouble();
    double visualisationMultiplier = data.inputValue(aVisualisationMultiplier).asDouble();
    MArrayDataHandle hMatrixArray = data.inputArrayValue(aMatrix);
    MArrayDataHandle hInitMatrixArray = data.inputArrayValue(aInitMatrix);
    // check connection
    if(hMatrixArray.elementCount() > hInitMatrixArray.elementCount() || hMatrixArray.elementCount() == 0 || blendMode == BM_OFF){
        return MS::kSuccess;
    }else if(hMatrixArray.elementCount() < hInitMatrixArray.elementCount()){
        std::set<int> indices;
        for(int i=0;i<hInitMatrixArray.elementCount();i++){
            hInitMatrixArray.jumpToArrayElement(i);
            indices.insert(hInitMatrixArray.elementIndex());
        }
        for(int i=0;i<hMatrixArray.elementCount();i++){
            hMatrixArray.jumpToArrayElement(i);
            indices.erase(hMatrixArray.elementIndex());
        }
        deleteAttr(data, aInitMatrix, indices);
        deleteAttr(data, aProbeConstraintRadius, indices);
        deleteAttr(data, aProbeWeight, indices);
    }
    bool isNumProbeChanged = (numPrb != hMatrixArray.elementCount());
    numPrb = hMatrixArray.elementCount();
    B.setNum(numPrb);
    // read matrices from probes
    std::vector<Matrix4d> initMatrix(numPrb), matrix(numPrb);
    readMatrixArray(hInitMatrixArray, initMatrix);
    readMatrixArray(hMatrixArray, matrix);
    // read vertex positions
    MPointArray Mpts;
    itGeo.allPositions(Mpts);
    int numPts = Mpts.length();
    
    // compute distance
    if(!data.isClean(aARAP) || !data.isClean(aComputeWeight) || isNumProbeChanged){
        // load points list
        if(worldMode){
            for(int j=0; j<numPts; j++ )
                Mpts[j] *= localToWorldMatrix;
        }
        pts.resize(numPts);
        for(int i=0;i<numPts;i++){
            pts[i] << Mpts[i].x, Mpts[i].y, Mpts[i].z;
        }
        // make tetrahedral structure
        getMeshData(data, input, inputGeom, mIndex, tetMode, pts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetMatrix, mesh.tetWeight);
        mesh.dim = removeDegenerate(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetMatrix);
        makeTetMatrix(tetMode, pts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetMatrix, mesh.tetWeight);
        makeTetCenterList(tetMode, pts, mesh.tetList, tetCenter);
        mesh.numTet = (int)mesh.tetList.size()/4;
        mesh.computeTetMatrixInverse();
        // initial probe position
        for(int i=0;i<numPrb;i++){
            B.centre[i] = transPart(initMatrix[i]);
        }
        // compute distance between probe and tetrahedra
        D.setNum(numPrb, numPts, mesh.numTet);
        D.computeDistTet(tetCenter, B.centre);
        D.findClosestTet();
        D.computeDistPts(pts, B.centre);
        D.findClosestPts();
        if(!areaWeighted){
            mesh.tetWeight.clear();
            mesh.tetWeight.resize(mesh.numTet,1.0);
        }
    }
    
    // (re)compute ARAP
    if(!data.isClean(aARAP) || isNumProbeChanged){
        // load painted weights
        if(stiffnessMode == SM_PAINT) {
            VectorXd ptsWeight(numPts);
            for (int i=0; !itGeo.isDone(); itGeo.next()){
                double w=weightValue(data, mIndex, itGeo.index());
                ptsWeight[i++] = (w>EPSILON) ? w : EPSILON;
            }
            makeTetWeightList(tetMode, mesh.tetList, faceList, edgeList, vertexList, ptsWeight, mesh.tetWeight);
        }else if(stiffnessMode == SM_LEARN) {
            std::vector<double> tetEnergy(mesh.numTet,0);
            MArrayDataHandle hSupervisedMesh = data.inputArrayValue(aSupervisedMesh);
            int numSupervisedMesh = hSupervisedMesh.elementCount();
            for(int j=0;j<numSupervisedMesh;j++){
                hSupervisedMesh.jumpToElement(j);
                MFnMesh ex_mesh(hSupervisedMesh.inputValue().asMesh());
                MPointArray Mspts;
                ex_mesh.getPoints( Mspts );
                if(numPts != Mspts.length()){
                    MGlobal::displayInfo("incompatible mesh");
                    return MS::kFailure;
                }
                std::vector<Vector3d> spts(numPts);
                for(int i=0;i<numPts;i++){
                    spts[i] << Mspts[i].x, Mspts[i].y, Mspts[i].z;
                }
                std::vector<double> dummy_weight;
                makeTetMatrix(tetMode, spts, mesh.tetList, faceList, edgeList, vertexList, Q, dummy_weight);
                Matrix3d S,R;
                for(int i=0;i<mesh.numTet;i++)  {
                    polarHigham((mesh.tetMatrixInverse[i]*Q[i]).block(0,0,3,3), S, R);
                    tetEnergy[i] += (S-Matrix3d::Identity()).squaredNorm();
                }
            }
            // compute weight (stiffness)
            double max_energy = *std::max_element(tetEnergy.begin(), tetEnergy.end());
            for(int i=0;i<mesh.numTet;i++)  {
                double w = 1.0 - tetEnergy[i]/(max_energy+EPSILON);
                mesh.tetWeight[i] *= w*w;
            }
        }

        // find constraint points
        constraint.resize(3*numPrb);
        for(int i=0;i<numPrb;i++){
            constraint[3*i] = T(i,mesh.tetList[4*D.closestTet[i]],constraintWeight);
            constraint[3*i+1] = T(i,mesh.tetList[4*D.closestTet[i]+1],constraintWeight);
            constraint[3*i+2] = T(i,mesh.tetList[4*D.closestTet[i]+2],constraintWeight);
        }
        if( constraintMode == CONSTRAINT_NEIGHBOUR ){
            std::vector<double> probeConstraintRadius(numPrb);
            MArrayDataHandle handle = data.inputArrayValue(aProbeConstraintRadius);
            if(handle.elementCount() != numPrb){
                MGlobal::displayInfo("# of Probes and probeConstraintRadius are different");
                return MS::kFailure;
            }
            for(int i=0;i<numPrb;i++){
                handle.jumpToArrayElement(i);
                probeConstraintRadius[i]=handle.inputValue().asDouble();
            }
            double constraintRadius = data.inputValue( aConstraintRadius ).asDouble();
            for(int i=0;i<numPrb;i++){
                double r = constraintRadius * probeConstraintRadius[i];
                for(int j=0;j<numPts;j++){
                    if(D.distPts[i][j]<r){
                        constraint.push_back(T(i,j,constraintWeight * pow((r-D.distPts[i][j])/r,normExponent)));
                    }
                }
            }
        }
        int numConstraint=constraint.size();
        mesh.constraintWeight.resize(numConstraint);
        mesh.constraintVal.resize(numConstraint,numPrb);
        for(int cur=0;cur<numConstraint;cur++){
            mesh.constraintWeight[cur] = std::make_pair(constraint[cur].col(), constraint[cur].value());
        }
        //
        isError = mesh.ARAPprecompute();
        status = data.setClean(aARAP);
    }        // END of ARAP precomputation
    
    if(isError>0){
        return MS::kFailure;
    }
    
    // probe weight computation
    if(!data.isClean(aComputeWeight) || isNumProbeChanged){
        // load probe weights
        MArrayDataHandle handle = data.inputArrayValue(aProbeWeight);
        if(handle.elementCount() != numPrb){
            MGlobal::displayInfo("# of Probes and probeWeight are different");
            isError = ERROR_ATTR;
            return MS::kFailure;
        }
        double effectRadius = data.inputValue( aEffectRadius ).asDouble();
        std::vector<double> probeWeight(numPrb), probeRadius(numPrb);
        for(int i=0;i<numPrb;i++){
            handle.jumpToArrayElement(i);
            probeWeight[i] = handle.inputValue().asDouble();
            probeRadius[i] = probeWeight[i] * effectRadius;
        }
        wr.resize(mesh.numTet);ws.resize(mesh.numTet);wl.resize(mesh.numTet);
        for(int j=0;j<mesh.numTet;j++){
            wr[j].resize(numPrb); ws[j].resize(numPrb); wl[j].resize(numPrb);
        }
        short weightMode = data.inputValue( aWeightMode ).asShort();
        if (weightMode == WM_INV_DISTANCE){
            for(int j=0;j<mesh.numTet;j++){
                double sum=0.0;
                std::vector<double> idist(numPrb);
                for (int i = 0; i<numPrb; i++){
                    idist[i] = probeRadius[i] / pow(D.distTet[i][j], normExponent);
                    sum += idist[i];
                }
                for (int i = 0; i<numPrb; i++){
                    wr[j][i] = ws[j][i] = wl[j][i] = sum > 0 ? idist[i] / sum : 0.0;
                }
            }
        }
        else if (weightMode == WM_CUTOFF_DISTANCE){
            for(int j=0;j<mesh.numTet;j++){
                for (int i = 0; i<numPrb; i++){
                    wr[j][i] = ws[j][i] = wl[j][i] = (D.distTet[i][j] > probeRadius[i])
                    ? 0 : pow((probeRadius[i] - D.distTet[i][j]) / probeRadius[i], normExponent);
                }
            }
        }else if (weightMode == WM_DRAW){
            float val;
            MRampAttribute rWeightCurveR( thisNode, aWeightCurveR, &status );
            MRampAttribute rWeightCurveS( thisNode, aWeightCurveS, &status );
            MRampAttribute rWeightCurveL( thisNode, aWeightCurveL, &status );
            for(int j=0;j<mesh.numTet;j++){
                for (int i = 0; i < numPrb; i++){
                    rWeightCurveR.getValueAtPosition(D.distTet[i][j] / probeRadius[i], val);
                    wr[j][i] = val;
                    rWeightCurveS.getValueAtPosition(D.distTet[i][j] / probeRadius[i], val);
                    ws[j][i] = val;
                    rWeightCurveL.getValueAtPosition(D.distTet[i][j] / probeRadius[i], val);
                    wl[j][i] = val;
                }
            }
        }else if(weightMode & WM_HARMONIC){
            Laplacian harmonicWeighting;
            makeFaceTet(data, input, inputGeom, mIndex, pts, harmonicWeighting.tetList, harmonicWeighting.tetMatrix, harmonicWeighting.tetWeight);
            harmonicWeighting.numTet = (int)harmonicWeighting.tetList.size()/4;
            std::vector<T> weightConstraint(numPrb);
            // the vertex closest to the probe is given probeWeight
            for(int i=0;i<numPrb;i++){
                weightConstraint[i]=T(i,D.closestPts[i],probeWeight[i]);
            }
            // vertices within effectRadius are given probeWeight
            if( data.inputValue( aNeighbourWeighting ).asBool() ){
                for(int i=0;i<numPrb;i++){
                    for(int j=0;j<numPts;j++){
                        if(D.distPts[i][j]<probeRadius[i]){
                            weightConstraint.push_back(T(i,j,probeWeight[i]));
                        }
                    }
                }
            }
            // set boundary condition for weight computation
            int numConstraint=weightConstraint.size();
            harmonicWeighting.constraintWeight.resize(numConstraint);
            harmonicWeighting.constraintVal.resize(numConstraint,numPrb);
            harmonicWeighting.constraintVal.setZero();
            for(int i=0;i<numConstraint;i++){
                harmonicWeighting.constraintVal(i,weightConstraint[i].row())=weightConstraint[i].value();
                harmonicWeighting.constraintWeight[i] = std::make_pair(weightConstraint[i].col(), weightConstraint[i].value());
            }
            // clear tetWeight
            if(!areaWeighted){
                harmonicWeighting.tetWeight.clear();
                harmonicWeighting.tetWeight.resize(harmonicWeighting.numTet,1.0);
            }
            // solve the laplace equation
            if( weightMode == WM_HARMONIC_ARAP){
                harmonicWeighting.computeTetMatrixInverse();
                harmonicWeighting.dim = numPts + harmonicWeighting.numTet;
                isError = harmonicWeighting.ARAPprecompute();
            }else if(weightMode == WM_HARMONIC_COTAN){
                harmonicWeighting.dim = numPts;
                isError = harmonicWeighting.cotanPrecompute();
            }
            if(isError>0) return MS::kFailure;
            std::vector< std::vector<double> > w_tet(numPrb);
            harmonicWeighting.harmonicSolve();
            for(int i=0;i<numPrb;i++){
                makeTetWeightList(tetMode, mesh.tetList, faceList, edgeList, vertexList, harmonicWeighting.Sol.col(i), w_tet[i]);
                for(int j=0;j<mesh.numTet; j++){
                    wr[j][i] = ws[j][i] = wl[j][i] = w_tet[i][j];
                }
            }
        }
        // normalise weights
        short normaliseWeightMode = data.inputValue( aNormaliseWeight ).asShort();
        for(int j=0;j<mesh.numTet;j++){
            D.normaliseWeight(normaliseWeightMode, wr[j]);
            D.normaliseWeight(normaliseWeightMode, ws[j]);
            D.normaliseWeight(normaliseWeightMode, wl[j]);
        }
        status = data.setClean(aComputeWeight);
    } // END of weight computation


    // setting up transformation matrix
    B.rotationConsistency = data.inputValue( aRotationConsistency ).asBool();
    bool frechetSum = data.inputValue( aFrechetSum ).asBool();
    blendedSE.resize(mesh.numTet); blendedR.resize(mesh.numTet); blendedS.resize(mesh.numTet); blendedL.resize(mesh.numTet);A.resize(mesh.numTet);
    for(int i=0;i<numPrb;i++){
        B.Aff[i]=initMatrix[i].inverse()*matrix[i];
    }
    B.parametrise(blendMode);
    

// prepare transform matrix for each simplex
#pragma omp parallel for
	for (int j = 0; j < mesh.numTet; j++){
		// blend matrix
		if (blendMode == BM_SRL){
			blendedS[j] = expSym(blendMat(B.logS, ws[j]));
			Vector3d l = blendMat(B.L, wl[j]);
            blendedR[j] = frechetSum ? frechetSO(B.R, wr[j]) : expSO(blendMat(B.logR, wr[j]));
			A[j] = pad(blendedS[j]*blendedR[j], l);
		}
		else if (blendMode == BM_SSE){
			blendedS[j] = expSym(blendMat(B.logS, ws[j]));
            blendedSE[j] = expSE(blendMat(B.logSE, wr[j]));
			A[j] = pad(blendedS[j], Vector3d::Zero()) * blendedSE[j];
		}
		else if (blendMode == BM_LOG3){
			blendedR[j] = blendMat(B.logGL, wr[j]).exp();
			Vector3d l = blendMat(B.L, wl[j]);
			A[j] = pad(blendedR[j], l);
		}
		else if (blendMode == BM_LOG4){
			A[j] = blendMat(B.logAff, wr[j]).exp();
		}
		else if (blendMode == BM_SQL){
			Vector4d q = blendQuat(B.quat, wr[j]);
			Vector3d l = blendMat(B.L, wl[j]);
			blendedS[j] = blendMatLin(B.S, ws[j]);
			Quaternion<double> RQ(q);
			blendedR[j] = RQ.matrix().transpose();
			A[j] = pad(blendedS[j]*blendedR[j], l);
		}
		else if (blendMode == BM_AFF){
			A[j] = blendMatLin(B.Aff, wr[j]);
		}
	}

    // compute target vertices position
    tetEnergy.resize(mesh.numTet);
    
    // set constraint
    int numConstraints = constraint.size();
    mesh.constraintVal.resize(numConstraints,3);
    RowVector4d cv;
    for(int cur=0;cur<numConstraints;cur++){
        cv = pad(pts[constraint[cur].col()]) * B.Aff[constraint[cur].row()];
        mesh.constraintVal(cur,0) = cv[0];
        mesh.constraintVal(cur,1) = cv[1];
        mesh.constraintVal(cur,2) = cv[2];
    }

    // iterate to determine vertices position
    for(int k=0;k<numIter;k++){
        // solve ARAP
        mesh.ARAPSolve(A);
        // set new vertices position
        new_pts.resize(numPts);
        for(int i=0;i<numPts;i++){
            new_pts[i][0]=mesh.Sol(i,0);
            new_pts[i][1]=mesh.Sol(i,1);
            new_pts[i][2]=mesh.Sol(i,2);
        }
        // if iteration continues
        if(k+1<numIter || visualisationMode == VM_ENERGY){
            std::vector<double> dummy_weight;
            makeTetMatrix(tetMode, new_pts, mesh.tetList, faceList, edgeList, vertexList, Q, dummy_weight);
            Matrix3d S,R,newS,newR;
            if(blendMode == BM_AFF || blendMode == BM_LOG4 || blendMode == BM_LOG3){
                for(int i=0;i<mesh.numTet;i++){
                    polarHigham(A[i].block(0,0,3,3), blendedS[i], blendedR[i]);
                }
            }
            #pragma omp parallel for
            for(int i=0;i<mesh.numTet;i++){
                polarHigham((mesh.tetMatrixInverse[i]*Q[i]).block(0,0,3,3), newS, newR);
                tetEnergy[i] = (newS-blendedS[i]).squaredNorm();
                A[i].block(0,0,3,3) = blendedS[i]*newR;
//                polarHigham((A[i].transpose()*PI[i]*Q[i]).block(0,0,3,3), newS, newR);
//                A[i].block(0,0,3,3) *= newR;
            }
        }
    }
    for(int i=0;i<numPts;i++){
        Mpts[i].x=mesh.Sol(i,0);
        Mpts[i].y=mesh.Sol(i,1);
        Mpts[i].z=mesh.Sol(i,2);
    }
    if(worldMode){
        for(int i=0;i<numPts;i++)
            Mpts[i] *= localToWorldMatrix.inverse();
    }
    itGeo.setAllPositions(Mpts);
    
    // set vertex colour
    if(visualisationMode != VM_OFF){
        std::vector<double> ptsColour(numPts, 0.0);
        if(visualisationMode == VM_ENERGY){
            makePtsWeightList(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, tetEnergy, ptsColour);
            for(int i=0;i<numPts;i++){
                ptsColour[i] *= visualisationMultiplier;
            }
        }else if(visualisationMode == VM_STIFFNESS){
            makePtsWeightList(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetWeight, ptsColour);
            double maxval = *std::max_element(ptsColour.begin(), ptsColour.end());
            for(int i=0;i<numPts;i++){
                ptsColour[i] = 1.0 - ptsColour[i]/maxval;
            }
        }else if(visualisationMode == VM_CONSTRAINT){
            for(int i=0;i<constraint.size();i++){
                ptsColour[constraint[i].col()] += constraint[i].value();
            }
        }else if(visualisationMode == VM_EFFECT){
            std:vector<double> wsum(mesh.numTet);
            for(int j=0;j<mesh.numTet;j++){
                //wsum[j] = std::accumulate(wr[j].begin(), wr[j].end(), 0.0);
                wsum[j]= visualisationMultiplier * wr[j][numPrb-1];
            }
            makePtsWeightList(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, wsum, ptsColour);
        }
        visualise(data, outputGeom, ptsColour);
    }
    
    return MS::kSuccess;
}
Exemplo n.º 18
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 ));



}
Exemplo n.º 19
0
void TestDeformer::_deform_on_one_mesh(MDataBlock& data,
                                      MItGeometry& iter,
                                      const MMatrix& localToWorldMatrix,
                                      unsigned int mIndex,
                                      MObject &driver_mesh,
                                      const MDataHandle &envelopeHandle, MArrayDataHandle &vertMapArrayData, MPointArray &tempOutputPts)
{
    MStatus status;

    float env = envelopeHandle.asFloat();

    // use driver_meshVertIter to walk through the vertex of the current driver mesh
    MItMeshVertex driver_meshVertIter( driver_mesh, &status );
    CHECK_MSTATUS( status );

    int i = 0;
    iter.reset();
    while( !iter.isDone(&status) )
    {
        CHECK_MSTATUS( status );

        // get the weight
        float weight = weightValue( data, mIndex, iter.index() ); //painted weight
        float ww = weight * env;

        if ( fabs(ww) > FLT_EPSILON )//if ( ww != 0 )
        {
            __debug("%s(), vertMapArrayData.elementCount()=%d, iter.index()=%d",
                    __FUNCTION__, vertMapArrayData.elementCount(), iter.index());

            // get index_mapped to which the currrent vertex vI is mapped
            CHECK_MSTATUS(vertMapArrayData.jumpToElement(iter.index()));
            int index_mapped = vertMapArrayData.inputValue(&status).asInt();
            CHECK_MSTATUS( status );

            if( index_mapped >= 0 )
            {
                __debug("index_mapped=%d", index_mapped);

                int prevInt;
                CHECK_MSTATUS( driver_meshVertIter.setIndex(index_mapped, prevInt) );

                // vertex wrold position on driver mesh
                MPoint mappedPt = driver_meshVertIter.position( MSpace::kWorld, &status );
                CHECK_MSTATUS( status );
                // vertex wrold position on driven mesh
                MPoint iterPt = iter.position(MSpace::kObject, &status) * localToWorldMatrix;
                CHECK_MSTATUS( status );

                // use ww to interpolate between mappedPt and iterPt
                MPoint pt = iterPt + ((mappedPt - iterPt) * ww );
                pt = pt * localToWorldMatrix.inverse();

                /// put the deform points to tempOutputPts
                tempOutputPts[i] += pt;
            }
        }//if
        CHECK_MSTATUS(iter.next());
        ++i;
    }//while
}
Exemplo n.º 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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
MStatus   clusterControledCurve::compute( const MPlug& plug, MDataBlock& data )
{
	//MFnDependencyNode thisNode( thisMObject() );
	//cout << thisNode.name() << ", start" << endl;

	MStatus status;

	MDataHandle hInputCurve = data.inputValue( aInputCurve, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputCurveMatrix = data.inputValue( aInputCurveMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hOutputCurve = data.outputValue( aOutputCurve, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MArrayDataHandle hArrBindPreMatrix = data.inputArrayValue( aBindPreMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MArrayDataHandle hArrMatrix = data.inputArrayValue( aMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MArrayDataHandle hArrWeightList = data.inputArrayValue( aWeightList, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MDataHandle hUpdate = data.inputValue( aUpdate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MObject oInputCurve = hInputCurve.asNurbsCurve();

	int bindPreMatrixLength = hArrBindPreMatrix.elementCount();
	int matrixLength = hArrMatrix.elementCount();

	MFnNurbsCurve fnInputCurve = oInputCurve;
	int numCVs = fnInputCurve.numCVs();
	int weightListLength = hArrWeightList.elementCount();

	if( weightListLength > 100 )
	{
		cout << "WeightList Count Error : " << weightListLength << endl;
		return MS::kFailure;
	}

	MPointArray inputCvPoints;
	MPointArray outputCvPoints;

	fnInputCurve.getCVs( inputCvPoints );
	outputCvPoints.setLength( numCVs );

	MMatrix matrix;
	MMatrix inputCurveMatrix = hInputCurveMatrix.asMatrix();
	MMatrix inputCurveMatrixInverse = inputCurveMatrix.inverse();

	if( requireUpdate )
	CHECK_MSTATUS_AND_RETURN_IT( updateBindPreMatrix( oInputCurve, inputCurveMatrixInverse,
				                                      hArrMatrix, hArrBindPreMatrix, hUpdate.asBool() ) );

	for( int i=0; i< numCVs; i++ )
	{
		inputCvPoints[i] *= inputCurveMatrix;
	}

	for( int i=0; i< numCVs; i++ )
	{
		outputCvPoints[i] = MPoint( 0,0,0 );
		double weight;

		for( int j=0; j< matrixLength; j++ )
		{
			weight = setWeights[i][j];

			hArrMatrix.jumpToElement( j );
			matrix = hArrMatrix.inputValue().asMatrix();
			outputCvPoints[i] += inputCvPoints[i]*bindPreMatrix[j]*matrix*weight;
		}
	}

	for( int i=0; i< numCVs; i++ )
	{
		outputCvPoints[i] *= inputCurveMatrixInverse;
	}

	MFnNurbsCurveData outputCurveData;
	MObject oOutputCurve = outputCurveData.create();

	fnInputCurve.copy( oInputCurve, oOutputCurve );

	MFnNurbsCurve fnOutputCurve( oOutputCurve, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	fnOutputCurve.setCVs( outputCvPoints );

	hOutputCurve.set( oOutputCurve );

	data.setClean( plug );

	//cout << thisNode.name() << ", end" << endl;

	return status;
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
MStatus n_tentacle::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus returnStatus;

	//make sure we have the curve
	MObject curveObj = data.inputValue(curve).asNurbsCurve();

	if(!curveObj.isNull())
	{
		//get the data
		MArrayDataHandle inMatrixArrayHnd = data.inputArrayValue(matrix);

		int tangentAxisI = data.inputValue(tangentAxis).asInt();
		if(tangentAxisI > 2)
			tangentAxisI = - (tangentAxisI - 2);
		else
			tangentAxisI = tangentAxisI + 1;

		double stretchF = data.inputValue(stretch).asDouble();
		double globalScaleF = data.inputValue(globalScale).asDouble();
		double iniLengthF = data.inputValue(iniLength).asDouble();

		const MFnNurbsCurve curve(curveObj);
		MArrayDataHandle parameterArrayHnd = data.inputArrayValue(parameter);
		MArrayDataHandle blendRotArrayHnd = data.inputArrayValue(blendRot);
		MArrayDataHandle intervalArrayHnd = data.inputArrayValue(interval);
		MArrayDataHandle outTranslateArrayHnd = data.outputArrayValue(outTranslate);
		MArrayDataHandle outRotateArrayHnd = data.outputArrayValue(outRotate);

		int parameterNrPlugs = parameterArrayHnd.elementCount();
		int blendRotNrPlugs = blendRotArrayHnd.elementCount();
		int outTranslateNrPlugs = outTranslateArrayHnd.elementCount();
		int outRotateNrPlugs = outRotateArrayHnd.elementCount();

		//get the current curve length
        double currCurveLen = curve.length();

        if(this->init == false)
        {
        	if(outTranslateNrPlugs == parameterNrPlugs && outRotateNrPlugs == parameterNrPlugs && parameterNrPlugs == blendRotNrPlugs)
        	{
        		this->init = true;
        	}
        }

		if( plug == outTranslate || plug == outRotate || plug == outRotateX || plug == outRotateY || plug == outRotateZ)
		{
			if(this->init)
			{
                MArrayDataBuilder tbuilder(outTranslate, parameterNrPlugs);
                MArrayDataBuilder rbuilder(outRotate, parameterNrPlugs);

				for(int i = 0; i < parameterNrPlugs; i++)
				{
					intervalArrayHnd.jumpToArrayElement(i);
					int intervalI = intervalArrayHnd.inputValue().asInt();

					inMatrixArrayHnd.jumpToArrayElement(intervalI);
					MMatrix matrix1 = inMatrixArrayHnd.inputValue().asMatrix();
					this->removeMatrixScale(matrix1);

					inMatrixArrayHnd.jumpToArrayElement(intervalI + 1);
					MMatrix matrix2 = inMatrixArrayHnd.inputValue().asMatrix();
					this->removeMatrixScale(matrix2);

					parameterArrayHnd.jumpToArrayElement(i);
					double parameterF = parameterArrayHnd.inputValue().asDouble();

					blendRotArrayHnd.jumpToArrayElement(i);
					double blendRotF = blendRotArrayHnd.inputValue().asDouble();

					MVector outPos, outRot;

					this->computeSlerp(matrix1, matrix2, curve, parameterF, blendRotF, iniLengthF, currCurveLen, stretchF, globalScaleF, tangentAxisI, outPos, outRot);

                    MDataHandle outTranslateHnd = tbuilder.addElement(i);
                    outTranslateHnd.set3Double(outPos.x, outPos.y, outPos.z);

                    MDataHandle outRotateHnd = rbuilder.addElement(i);
                    double rotation[3];
                    outRotateHnd.set( outRot.x, outRot.y, outRot.z );

                    //this->output(outPos, outRot, i, outTranslateArrayHnd, outRotateArrayHnd);

				}

                outTranslateArrayHnd.set(tbuilder);
                outTranslateArrayHnd.setAllClean();

                outRotateArrayHnd.set(rbuilder);
                outRotateArrayHnd.setAllClean();
			}
            data.setClean(plug);

		}
		else
		{
			return MS::kUnknownParameter;
		}
	}

	return MS::kSuccess;
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
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;
	}
Exemplo n.º 28
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;
}
Exemplo n.º 29
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 );
}
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;
}