Exemplo n.º 1
0
MStatus animCube::compute(const MPlug& plug, MDataBlock& data)

{
	MStatus returnStatus;

	if (plug == outputMesh) {
		/* Get time */
		MDataHandle timeData = data.inputValue( time, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		MTime time = timeData.asTime();

		/* Get output object */

		MDataHandle outputHandle = data.outputValue(outputMesh, &returnStatus);
		McheckErr(returnStatus, "ERROR getting polygon data handle\n");

		MFnMeshData dataCreator;
		MObject newOutputData = dataCreator.create(&returnStatus);
		McheckErr(returnStatus, "ERROR creating outputData");

		createMesh(time, newOutputData, returnStatus);
		McheckErr(returnStatus, "ERROR creating new Cube");

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

	return MS::kSuccess;
}
Exemplo n.º 2
0
MStatus blindDataMesh::initialize()
{
	MFnTypedAttribute typedAttr;
	MStatus returnStatus;

	blindDataMesh::outputMesh = typedAttr.create( "outputMesh", "out",
		MFnData::kMesh, &returnStatus ); 
	McheckErr(returnStatus, "ERROR creating blindDataMesh output attribute\n");
	typedAttr.setStorable(false);

	returnStatus = addAttribute(blindDataMesh::outputMesh);
	McheckErr(returnStatus, "ERROR adding outputMesh attribute\n");

	MFnNumericAttribute numAttr;
	blindDataMesh::seed = numAttr.create( "randomSeed", "seed",
		MFnNumericData::kLong, 0, &returnStatus );
	McheckErr(returnStatus, "ERROR creating blindDataMesh input attribute\n");

	returnStatus = addAttribute(blindDataMesh::seed);
	McheckErr(returnStatus, "ERROR adding input attribute\n");

	returnStatus = attributeAffects(blindDataMesh::seed,
								    blindDataMesh::outputMesh);
	McheckErr(returnStatus, "ERROR in attributeAffects\n");

	return MS::kSuccess;
}
Exemplo n.º 3
0
MStatus animCube::initialize()
{
	MFnUnitAttribute unitAttr;
	MFnTypedAttribute typedAttr;

	MStatus returnStatus;

	animCube::time = unitAttr.create( "time", "tm",
										  MFnUnitAttribute::kTime,
										  0.0, &returnStatus );
	McheckErr(returnStatus, "ERROR creating animCube time attribute\n");


	animCube::outputMesh = typedAttr.create( "outputMesh", "out",
												 MFnData::kMesh,
												 &returnStatus ); 
	McheckErr(returnStatus, "ERROR creating animCube output attribute\n");
	typedAttr.setStorable(false);

	returnStatus = addAttribute(animCube::time);
	McheckErr(returnStatus, "ERROR adding time attribute\n");

	returnStatus = addAttribute(animCube::outputMesh);
	McheckErr(returnStatus, "ERROR adding outputMesh attribute\n");

	returnStatus = attributeAffects(animCube::time,
								    animCube::outputMesh);
	McheckErr(returnStatus, "ERROR in attributeAffects\n");

	return MS::kSuccess;
}
Exemplo n.º 4
0
MStatus TCC::compute(const MPlug& plug, MDataBlock& data)

{
    MStatus stat;

    if (plug == aOutputMesh) {
        /* Get time */
        int subdivRes = data.inputValue(aRes, &stat).asInt();
        int subdivRefRes = data.inputValue(aRefRes, &stat).asInt();
        float lineThickness = data.inputValue(aLineThickness, &stat).asFloat();

        MDataHandle inMeshHandle = data.inputValue( aInputMesh, &stat ); McheckErr(stat,"ERROR getting attribute");
        MObject inMeshObj = inMeshHandle.asMesh();
        MFnMesh inMeshFn(inMeshObj);
        
        MIntArray nFV, F;
        inMeshFn.getVertices(nFV, F);
        
        MIntArray nFVc = MFnIntArrayData( data.inputValue( anFVc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray Fc   = MFnIntArrayData( data.inputValue( aFc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        
        MIntArray pole = MFnIntArrayData( data.inputValue( aPole ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray corner = MFnIntArrayData( data.inputValue( aCorner ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray T    = MFnIntArrayData( data.inputValue( aT ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray eqc  = MFnIntArrayData( data.inputValue( aEqc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MDoubleArray itv  = MFnDoubleArrayData( data.inputValue( aItv ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray err  = MFnIntArrayData( data.inputValue( aErr ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");

        TCCData tccData(nFV, F, nFVc, Fc, pole, corner, T, eqc, itv, err);

        /* Get output object */
        MDataHandle outMeshHandle = data.outputValue(aOutputMesh, &stat); McheckErr(stat, "ERROR getting attribute\n");

        if (validTopology(tccData))
        {
            stat = createSubdividedMesh(subdivRes, subdivRefRes, inMeshFn, tccData, outMeshHandle, lineThickness, stat);
        } 
        else 
        {
            outMeshHandle.setMObject(inMeshObj);
            
            MFnMesh outMeshFn(outMeshHandle.asMesh());
            
            stat = setErrorColors(outMeshFn, tccData);
        }
        
        data.setClean( plug );
    } else
        return MS::kUnknownParameter;

    return stat;
}
Exemplo n.º 5
0
MStatus sweptEmitter::emitCountPerPoint
	(
		const MPlug &plug,
		MDataBlock &block,
		int length,					// length of emitCountPP
		MIntArray &emitCountPP		// output: emitCount for each point
	)
//
//	Descriptions:
//		Compute emitCount for each point where new particles come from.
//
{
	MStatus status;

	int plugIndex = plug.logicalIndex( &status );
	McheckErr(status, "ERROR in emitCountPerPoint: when plug.logicalIndex.\n");

	// Get rate and delta time.
	//
	double rate = rateValue( block );
	MTime dt = deltaTimeValue( plugIndex, block );

	// Compute emitCount for each point.
	//
	double dblCount = rate * dt.as( MTime::kSeconds );

	int intCount = (int)dblCount;
	for( int i = 0; i < length; i++ )
	{
		emitCountPP.append( intCount );
	}

	return( MS::kSuccess );
}
Exemplo n.º 6
0
MStatus blindDataMesh::compute(const MPlug& plug, MDataBlock& data)

{
	MStatus returnStatus;

	if (plug == outputMesh) {

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

		long seed = seedHandle.asLong();

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

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

	return MS::kSuccess;
}
Exemplo n.º 7
0
MStatus LSystemNode::compute(const MPlug& plug, MDataBlock& data)
{
        MStatus returnStatus;

        if (plug == outputMesh) {
			//angle
			MDataHandle angleData = data.inputValue(angle,&returnStatus);
			McheckErr(returnStatus, "Error getting angle data handle\n");
			double angle = angleData.asDouble();
			//step
			MDataHandle stepData = data.inputValue(step,&returnStatus);
			McheckErr(returnStatus, "Error getting step data handle\n");
			double step = stepData.asDouble();
			//grammar
			MDataHandle grammarData = data.inputValue(grammar,&returnStatus);
			McheckErr(returnStatus, "Error getting grammar data handle\n");
			MString grammar = grammarData.asString();

                /* Get time */
                MDataHandle timeData = data.inputValue( time, &returnStatus ); 
                McheckErr(returnStatus, "Error getting time data handle\n");
                MTime time = timeData.asTime();

                /* Get output object */

                MDataHandle outputHandle = data.outputValue(outputMesh, &returnStatus);
                McheckErr(returnStatus, "ERROR getting polygon data handle\n");

                MFnMeshData dataCreator;
                MObject newOutputData = dataCreator.create(&returnStatus);
                McheckErr(returnStatus, "ERROR creating outputData");

                createMesh(angle, step, grammar, time, newOutputData, returnStatus);
                McheckErr(returnStatus, "ERROR creating new Cube");

                outputHandle.set(newOutputData);
                data.setClean( plug );
        } else
        return MS::kUnknownParameter;
		return MS::kSuccess;
}
Exemplo n.º 8
0
MStatus LSystemNode::initialize()
{
        MFnUnitAttribute unitAttr;
        MFnTypedAttribute typedAttr;
		MFnNumericAttribute numericAttr;

        MStatus returnStatus;
		//(i)angle
		LSystemNode::angle = numericAttr.create("angle","ag",MFnNumericData::kDouble,90.0,&returnStatus);
		McheckErr(returnStatus, "ERROR creating LSystemNode angle attribute\n");
		//(ii)size
		step = numericAttr.create("step","st",MFnNumericData::kDouble,1.0, &returnStatus);
		McheckErr(returnStatus, "ERROR creating LSystemNode step attribute\n");//(iv)time
        //(iii)grammar
		LSystemNode::grammar = typedAttr.create( "grammar", "grm", MFnData::kString, &returnStatus );
		McheckErr(returnStatus, "ERROR creating LSystemNode grammar attribute\n");
		//(iv)time
		LSystemNode::time = unitAttr.create( "time", "tm", MFnUnitAttribute::kTime, 0.0, &returnStatus );
        McheckErr(returnStatus, "ERROR creating LSystemNode time attribute\n");
		//(v)output
        LSystemNode::outputMesh = typedAttr.create( "outputMesh", "out", MFnData::kMesh, &returnStatus ); 
        McheckErr(returnStatus, "ERROR creating LSystemNode output attribute\n");
        typedAttr.setStorable(false);


		//(i)angle
		returnStatus = addAttribute(LSystemNode::angle);
		McheckErr(returnStatus, "ERROR adding angle attribute\n");
		//(ii)step
		returnStatus = addAttribute(LSystemNode::step);
		McheckErr(returnStatus, "ERROR adding step attribute\n");
		//(iii)grammar
		returnStatus = addAttribute(LSystemNode::grammar);
		McheckErr(returnStatus, "ERROR adding grammar attribute\n");
		//(iv)time
        returnStatus = addAttribute(LSystemNode::time);
        McheckErr(returnStatus, "ERROR adding time attribute\n");
		//(v)output
        returnStatus = addAttribute(LSystemNode::outputMesh);
        McheckErr(returnStatus, "ERROR adding outputMesh attribute\n");

		returnStatus = attributeAffects(LSystemNode::angle,LSystemNode::outputMesh);
        McheckErr(returnStatus, "ERROR in attributeAffects\n");
		returnStatus = attributeAffects(LSystemNode::step,LSystemNode::outputMesh);
        McheckErr(returnStatus, "ERROR in attributeAffects\n");
		returnStatus = attributeAffects(LSystemNode::grammar,LSystemNode::outputMesh);
        McheckErr(returnStatus, "ERROR in attributeAffects\n");
        returnStatus = attributeAffects(LSystemNode::time,LSystemNode::outputMesh);
        McheckErr(returnStatus, "ERROR in attributeAffects\n");

        return MS::kSuccess;
}
Exemplo n.º 9
0
MStatus weightList::compute( const MPlug& plug, MDataBlock& block)
{
        MStatus status = MS::kSuccess;

	unsigned i, j;
	MObject thisNode = thisMObject();
	MPlug wPlug(thisNode, aWeights); 

	// Write into aWeightList
	for( i = 0; i < 3; i++) {
	    status = wPlug.selectAncestorLogicalIndex( i, aWeightsList );
	    MDataHandle wHandle = wPlug.constructHandle(block);
	    MArrayDataHandle arrayHandle(wHandle, &status);
	    McheckErr(status, "arrayHandle construction failed\n");
	    MArrayDataBuilder arrayBuilder = arrayHandle.builder(&status);
	    McheckErr(status, "arrayBuilder accessing/construction failed\n");
	    for( j = 0; j < i+2; j++) {
	        MDataHandle handle = arrayBuilder.addElement(j,&status);
		McheckErr(status, "addElement to arrayBuilder failed\n");
		float val = 1.0f*(i+j); 
		handle.set(val);
	    }
	    status = arrayHandle.set(arrayBuilder);
	    McheckErr(status, "set arrayBuilder failed\n");
	    wPlug.setValue(wHandle);
	    wPlug.destructHandle(wHandle);
	}

	// Read from aWeightList and print out result
	MArrayDataHandle arrayHandle = block.inputArrayValue(aWeightsList, &status);
	McheckErr(status, "arrayHandle construction for aWeightsList failed\n");
	unsigned count = arrayHandle.elementCount();
	for( i = 0; i < count; i++) {
	    arrayHandle.jumpToElement(i);
	    MDataHandle eHandle = arrayHandle.inputValue(&status).child(aWeights);
	    McheckErr(status, "handle evaluation failed\n");
	    MArrayDataHandle eArrayHandle(eHandle, &status);
	    McheckErr(status, "arrayHandle construction for aWeights failed\n");
	    unsigned eCount = eArrayHandle.elementCount();
	    for( j = 0; j < eCount; j++) {
	        eArrayHandle.jumpToElement(j);
		float weight = eArrayHandle.inputValue(&status).asFloat();
		McheckErr(status, "weight evaluation error\n");
		fprintf(stderr, "weightList[%u][%u] = %g\n",i,j,weight);
	    }
	}

	// Read from aWeightList and print out result using the more
	// efficient jumpToArrayElement() call
	arrayHandle = block.inputArrayValue(aWeightsList, &status);
	McheckErr(status, "arrayHandle construction for aWeightsList failed\n");
	count = arrayHandle.elementCount();
	for( i = 0; i < count; i++) {
	    arrayHandle.jumpToArrayElement(i);
	    MDataHandle eHandle = arrayHandle.inputValue(&status).child(aWeights);
	    McheckErr(status, "handle evaluation failed\n");
	    MArrayDataHandle eArrayHandle(eHandle, &status);
	    McheckErr(status, "arrayHandle construction for aWeights failed\n");
	    unsigned eCount = eArrayHandle.elementCount();
	    for( j = 0; j < eCount; j++) {
	        eArrayHandle.jumpToArrayElement(j);
		float weight = eArrayHandle.inputValue(&status).asFloat();
		McheckErr(status, "weight evaluation error\n");
		fprintf(stderr, "weightList[%d][%d] = %g\n",i,j,weight);
	    }
	}

	return status;
}
Exemplo n.º 10
0
MStatus
tm_noisePerlin::deform( MDataBlock& block,
                        MItGeometry& iter,
                        const MMatrix& /*m*/,
                        unsigned int /*multiIndex*/)
{
    MStatus status = MS::kSuccess;

    // It's a fake data access try to workaround strange behavior on x86_64 linux systems...
    MDataHandle dummyData = block.inputValue(dummy,&status);

    MDataHandle lev_MampData = block.inputValue(lev_Mamp,&status);
    McheckErr(status, "Error getting lev_Mamp data handle\n");
    double _lev_Mamp = lev_MampData.asDouble();

    MDataHandle lev_MfreqData = block.inputValue(lev_Mfreq,&status);
    McheckErr(status, "Error getting lev_Mfreq data handle\n");
    double lev_Mfreq = lev_MfreqData.asDouble();

    MDataHandle levelsData = block.inputValue(levels,&status);
    McheckErr(status, "Error getting frequency data handle\n");
    short levels = levelsData.asShort();

    MDataHandle scaleData = block.inputValue(scale,&status);
    McheckErr(status, "Error getting scale data handle\n");
    double scale = scaleData.asDouble();

    MDataHandle scaleAmpXData = block.inputValue(scaleAmpX,&status);
    McheckErr(status, "Error getting scaleAmpX data handle\n");
    double scaleAmpX = scaleAmpXData.asDouble();

    MDataHandle scaleAmpYData = block.inputValue(scaleAmpY,&status);
    McheckErr(status, "Error getting scaleAmpY data handle\n");
    double scaleAmpY = scaleAmpYData.asDouble();

    MDataHandle scaleAmpZData = block.inputValue(scaleAmpZ,&status);
    McheckErr(status, "Error getting scaleAmpZ data handle\n");
    double scaleAmpZ = scaleAmpZData.asDouble();

    MDataHandle scaleFreqXData = block.inputValue(scaleFreqX,&status);
    McheckErr(status, "Error getting scaleFreqX data handle\n");
    double scaleFreqX = scaleFreqXData.asDouble();

    MDataHandle scaleFreqYData = block.inputValue(scaleFreqY,&status);
    McheckErr(status, "Error getting scaleFreqY data handle\n");
    double scaleFreqY = scaleFreqYData.asDouble();

    MDataHandle scaleFreqZData = block.inputValue(scaleFreqZ,&status);
    McheckErr(status, "Error getting scaleFreqZ data handle\n");
    double scaleFreqZ = scaleFreqZData.asDouble();

    MDataHandle variationData = block.inputValue(variation,&status);
    McheckErr(status, "Error getting variation data handle\n");
    double variation = variationData.asDouble();

    MDataHandle envData = block.inputValue(envelope,&status);
    McheckErr(status, "Error getting envelope data handle\n");
    double env = envData.asDouble();

    MDataHandle amplitudeData = block.inputValue(amplitude,&status);
    McheckErr(status, "Error getting amplitude data handle\n");
    double amplitude = amplitudeData.asDouble();

    MDataHandle frequencyData = block.inputValue(frequency,&status);
    McheckErr(status, "Error getting frequency data handle\n");
    double frequency = frequencyData.asDouble();

    amplitude = amplitude * scale;
    frequency = frequency * 0.01 / scale;


    for ( ; !iter.isDone(); iter.next()) {

        MPoint pt = iter.position();
        vector noisePnt;
        noisePnt.x = 0;
        noisePnt.y = 0;
        noisePnt.z = 0;

        double l_amp = amplitude;

        double x = scaleFreqX * pt.x * frequency;
        double y = scaleFreqY * pt.y * frequency;
        double z = scaleFreqZ * pt.z * frequency;

        for( int lev = 0; lev < levels; lev++)
        {
            x *= lev_Mfreq;
            y *= lev_Mfreq;
            z *= lev_Mfreq;
            vector lev_Pnt = INoise::noise4d_v(x, y, z, variation);
            noisePnt.x += lev_Pnt.x * l_amp;
            noisePnt.y += lev_Pnt.y * l_amp;
            noisePnt.z += lev_Pnt.z * l_amp;
            l_amp *= _lev_Mamp;
        }

        pt.x += noisePnt.x * scaleAmpX;
        pt.y += noisePnt.y * scaleAmpY;
        pt.z += noisePnt.z * scaleAmpZ;

        iter.setPosition(pt);
    }
    return status;
}
Exemplo n.º 11
0
MStatus pointOnSubd::initialize()
//
//	Description:
//		This method is called to create and initialize all of the attributes
//      and attribute dependencies for this node type.  This is only called 
//		once when the node type is registered with Maya.
//
//	Return Values:
//		MS::kSuccess
//		MS::kFailure
//		
{
	MStatus stat;

	MFnTypedAttribute subdAttr;
	aSubd = subdAttr.create( "subd", "s", MFnSubdData::kSubdSurface, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aSubd" );
 	subdAttr.setStorable(true);
 	subdAttr.setKeyable(false);
	subdAttr.setReadable( true );
	subdAttr.setWritable( true );
	subdAttr.setCached( false );
	stat = addAttribute( pointOnSubd::aSubd );
	McheckErr( stat, "cannot add pointOnSubd::aSubd" );

	MFnNumericAttribute faceFirstAttr;
	aFaceFirst = faceFirstAttr.create( "faceFirst", "ff",
									   MFnNumericData::kLong, 0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aFaceFirst" );
 	faceFirstAttr.setStorable(true);
 	faceFirstAttr.setKeyable(true);
	faceFirstAttr.setSoftMin( 0.0 );
	faceFirstAttr.setReadable( true );
	faceFirstAttr.setWritable( true );
	faceFirstAttr.setCached( false );
	stat = addAttribute( pointOnSubd::aFaceFirst );
	McheckErr( stat, "cannot add pointOnSubd::aFaceFirst" );

	MFnNumericAttribute faceSecondAttr;
	aFaceSecond = faceSecondAttr.create( "faceSecond", "fs",
										 MFnNumericData::kLong, 0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aFaceSecond" );
 	faceSecondAttr.setStorable(true);
 	faceSecondAttr.setKeyable(true);
	faceSecondAttr.setSoftMin( 0.0 );
	faceSecondAttr.setReadable( true );
	faceSecondAttr.setWritable( true );
	faceSecondAttr.setCached( false );
	stat = addAttribute( pointOnSubd::aFaceSecond );
	McheckErr( stat, "cannot add pointOnSubd::aFaceSecond" );

	MFnNumericAttribute uAttr;
	aU = uAttr.create( "uValue", "u", MFnNumericData::kDouble,
					   0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aU" );
 	uAttr.setStorable(true);
 	uAttr.setKeyable(true);
	uAttr.setSoftMin( 0.0 );
	uAttr.setSoftMax( 1.0 );
	uAttr.setReadable( true );
	uAttr.setWritable( true );
	uAttr.setCached( false );
	stat = addAttribute( aU );
	McheckErr( stat, "cannot add pointOnSubd::aU" );

	MFnNumericAttribute vAttr;
	aV = vAttr.create( "vValue", "v", MFnNumericData::kDouble,
					   0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aV" );
 	vAttr.setStorable(true);
 	vAttr.setKeyable(true);
	vAttr.setSoftMin( 0.0 );
	vAttr.setSoftMax( 1.0 );
	vAttr.setReadable( true );
	vAttr.setWritable( true );
	vAttr.setCached( false );
	stat = addAttribute( aV );
	McheckErr( stat, "cannot add pointOnSubd::aV" );

	MFnNumericAttribute relAttr;
	aRelativeUV = relAttr.create( "relative", "rel", MFnNumericData::kBoolean,
								  0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aRelativeUV" );
 	relAttr.setStorable(true);
 	relAttr.setKeyable(true);
	relAttr.setSoftMin( 0.0 );
	relAttr.setSoftMax( 1.0 );
	relAttr.setReadable( true );
	relAttr.setWritable( true );
	relAttr.setCached( false );
	stat = addAttribute( pointOnSubd::aRelativeUV );
	McheckErr( stat, "cannot add pointOnSubd::aRelativeUV" );

	MFnNumericAttribute pointXAttr;
	aPointX = pointXAttr.create( "pointX", "px", MFnNumericData::kDouble,
								0.0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aPointX" );
	pointXAttr.setWritable(false);
	pointXAttr.setStorable(false);
	pointXAttr.setReadable( true );
	pointXAttr.setCached( true );
	stat = addAttribute( aPointX );
	McheckErr( stat, "cannot add pointOnSubd::aPointX" );

	MFnNumericAttribute pointYAttr;
	aPointY = pointYAttr.create( "pointY", "py", MFnNumericData::kDouble,
								0.0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aPointY" );
	pointYAttr.setWritable(false);
	pointYAttr.setStorable(false);
	pointYAttr.setReadable( true );
	pointYAttr.setCached( true );
	stat = addAttribute( aPointY );
	McheckErr( stat, "cannot add pointOnSubd::aPointY" );

	MFnNumericAttribute pointZAttr;
	aPointZ = pointZAttr.create( "pointZ", "pz", MFnNumericData::kDouble,
								0.0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aPointZ" );
	pointZAttr.setWritable(false);
	pointZAttr.setStorable(false);
	pointZAttr.setReadable( true );
	pointZAttr.setCached( true );
	stat = addAttribute( aPointZ );
	McheckErr( stat, "cannot add pointOnSubd::aPointZ" );

	MFnNumericAttribute pointAttr;
	aPoint = pointAttr.create( "point", "p", aPointX, aPointY, aPointZ, &stat);
	McheckErr( stat, "cannot create pointOnSubd::aPoint" );
	pointAttr.setWritable(false);
	pointAttr.setStorable(false);
	pointAttr.setReadable( true );
	pointAttr.setCached( true );
	stat = addAttribute( aPoint );
	McheckErr( stat, "cannot add pointOnSubd::aPoint" );

	MFnNumericAttribute normalXAttr;
	aNormalX = normalXAttr.create( "normalX", "nx", MFnNumericData::kDouble,
								   0.0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aNormal" );
	normalXAttr.setWritable(false);
	normalXAttr.setStorable(false);
	normalXAttr.setReadable( true );
	normalXAttr.setCached( true );
	stat = addAttribute( aNormalX );
	McheckErr( stat, "cannot add pointOnSubd::aNormalX" );

	MFnNumericAttribute normalYAttr;
	aNormalY = normalYAttr.create( "normalY", "ny", MFnNumericData::kDouble,
								   0.0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aNormal" );
	normalYAttr.setWritable(false);
	normalYAttr.setStorable(false);
	normalYAttr.setReadable( true );
	normalYAttr.setCached( true );
	stat = addAttribute( aNormalY );
	McheckErr( stat, "cannot add pointOnSubd::aNormalY" );

	MFnNumericAttribute normalZAttr;
	aNormalZ = normalZAttr.create( "normalZ", "nz", MFnNumericData::kDouble,
								   0.0, &stat );
	McheckErr( stat, "cannot create pointOnSubd::aNormal" );
	normalZAttr.setWritable(false);
	normalZAttr.setStorable(false);
	normalZAttr.setReadable( true );
	normalZAttr.setCached( true );
	stat = addAttribute( aNormalZ );
	McheckErr( stat, "cannot add pointOnSubd::aNormalZ" );

	MFnNumericAttribute normalAttr;
	aNormal = normalAttr.create("normal","n",aNormalX,aNormalY,aNormalZ,&stat);
	McheckErr( stat, "cannot create pointOnSubd::aNormal" );
	normalAttr.setWritable(false);
	normalAttr.setStorable(false);
	normalAttr.setReadable( true );
	normalAttr.setCached( true );
	stat = addAttribute( aNormal );
	McheckErr( stat, "cannot add pointOnSubd::aNormal" );


	// Set up a dependency between the input and the output.  This will cause
	// the output to be marked dirty when the input changes.  The output will
	// then be recomputed the next time the value of the output is requested.
	//
	stat = attributeAffects( aSubd, aPoint );
	stat = attributeAffects( aSubd, aPointX );
	stat = attributeAffects( aSubd, aPointY );
	stat = attributeAffects( aSubd, aPointZ );
	stat = attributeAffects( aSubd, aNormal );
	stat = attributeAffects( aSubd, aNormalX );
	stat = attributeAffects( aSubd, aNormalY );
	stat = attributeAffects( aSubd, aNormalZ );

	stat = attributeAffects( aFaceFirst, aPoint );
	stat = attributeAffects( aFaceFirst, aPointX );
	stat = attributeAffects( aFaceFirst, aPointY );
	stat = attributeAffects( aFaceFirst, aPointZ );
	stat = attributeAffects( aFaceFirst, aNormal );
	stat = attributeAffects( aFaceFirst, aNormalX );
	stat = attributeAffects( aFaceFirst, aNormalY );
	stat = attributeAffects( aFaceFirst, aNormalZ );

	stat = attributeAffects( aFaceSecond, aPoint );
	stat = attributeAffects( aFaceSecond, aPointX );
	stat = attributeAffects( aFaceSecond, aPointY );
	stat = attributeAffects( aFaceSecond, aPointZ );
	stat = attributeAffects( aFaceSecond, aNormal );
	stat = attributeAffects( aFaceSecond, aNormalX );
	stat = attributeAffects( aFaceSecond, aNormalY );
	stat = attributeAffects( aFaceSecond, aNormalZ );

	stat = attributeAffects( aU, aPoint );
	stat = attributeAffects( aU, aPointX );
	stat = attributeAffects( aU, aPointY );
	stat = attributeAffects( aU, aPointZ );
	stat = attributeAffects( aU, aNormal );
	stat = attributeAffects( aU, aNormalX );
	stat = attributeAffects( aU, aNormalY );
	stat = attributeAffects( aU, aNormalZ );

	stat = attributeAffects( aV, aPoint );
	stat = attributeAffects( aV, aPointX );
	stat = attributeAffects( aV, aPointY );
	stat = attributeAffects( aV, aPointZ );
	stat = attributeAffects( aV, aNormal );
	stat = attributeAffects( aV, aNormalX );
	stat = attributeAffects( aV, aNormalY );
	stat = attributeAffects( aV, aNormalZ );

	stat = attributeAffects( aRelativeUV, aPoint );
	stat = attributeAffects( aRelativeUV, aPointX );
	stat = attributeAffects( aRelativeUV, aPointY );
	stat = attributeAffects( aRelativeUV, aPointZ );
	stat = attributeAffects( aRelativeUV, aNormal );
	stat = attributeAffects( aRelativeUV, aNormalX );
	stat = attributeAffects( aRelativeUV, aNormalY );
	stat = attributeAffects( aRelativeUV, aNormalZ );

	return MS::kSuccess;

}
Exemplo n.º 12
0
MStatus LSSolverNode::compute(const MPlug& plug, MDataBlock& data)
{
	MStatus stat;
	
	if( plug == deformed)
	{
		MDataHandle tetWorldMatrixData = data.inputValue(tetWorldMatrix, &returnStatus);
		McheckErr(returnStatus, "Error getting tetWorldMatrix data handle\n");

		MDataHandle restShapeData = data.inputValue(restShape, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restVerticesData = data.inputValue(restVertices, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restElementsData = data.inputValue(restElements, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedConstraintVertsData = data.inputValue(selectedConstraintVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedForceVertsData = data.inputValue(selectedForceVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle timeData = data.inputValue(time, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle outputMeshData = data.outputValue(deformed, &returnStatus);
		McheckErr(returnStatus, "Error getting outputMesh data handle\n");
		
		MMatrix twmat = tetWorldMatrixData.asMatrix();
		MObject rs = restShapeData.asMesh();
		double t = timeData.asDouble();

		MDataHandle poissonRatioData = data.inputValue(poissonRatio, &returnStatus);
		McheckErr(returnStatus, "Error getting poissonRatio data handle\n");

		MDataHandle youngsModulusData = data.inputValue(youngsModulus, &returnStatus);
		McheckErr(returnStatus, "Error getting youngsmodulus data handle\n");

		MDataHandle objectDensityData = data.inputValue(objectDensity, &returnStatus);
		McheckErr(returnStatus, "Error getting objectDensity data handle\n");

		MDataHandle frictionData = data.inputValue(friction, &returnStatus);
		McheckErr(returnStatus, "Error getting friction data handle\n");

		MDataHandle restitutionData = data.inputValue(restitution, &returnStatus);
		McheckErr(returnStatus, "Error getting restitution data handle\n");

		MDataHandle dampingData = data.inputValue(damping, &returnStatus);
		McheckErr(returnStatus, "Error getting damping data handle\n");

		MDataHandle userSuppliedDtData = data.inputValue(userSuppliedDt, &returnStatus);
		McheckErr(returnStatus, "Error getting user supplied dt data handle\n");


		MDataHandle integrationTypeData = data.inputValue(integrationType, &returnStatus);
		McheckErr(returnStatus, "Error getting user integrationTypeData\n");

		MDataHandle forceModelTypeData = data.inputValue(forceModelType, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceModelTypeData\n");

		MDataHandle forceApplicationTimeData = data.inputValue(forceApplicationTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceApplicationTime\n");
	
		MDataHandle forceReleasedTimeData = data.inputValue(forceReleasedTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceReleasedTime\n");

		MDataHandle forceIncrementTimeData = data.inputValue(forceIncrementTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIncrementTime\n");

		MDataHandle forceStartTimeData = data.inputValue(forceStartTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStartTime\n");

		MDataHandle forceStopTimeData = data.inputValue(forceStopTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStopTime\n");

		MDataHandle forceMagnitudeData = data.inputValue(forceMagnitude, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedForceData = data.inputValue(useSuppliedForce, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedConstraintsData = data.inputValue(useSuppliedConstraints, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle forceDirectionData = data.inputValue(forceDirection, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MDataHandle contactKsData = data.inputValue(contactKs, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");	

		MDataHandle contactKdData = data.inputValue(contactKd, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MTime currentTime, maxTime;
		currentTime = MAnimControl::currentTime();
		maxTime = MAnimControl::maxTime();
					
		if (currentTime == MAnimControl::minTime())
		{
			// retrive restVertices and restElements
			sTime=0;

			MFnDoubleArrayData restVertArrayData(restVerticesData.data());
			MDoubleArray verts = restVertArrayData.array();
			int vertArrayLen = verts.length();
			double *vertArray = new double[vertArrayLen];
			verts.get(vertArray);

			for(int v=0;v<vertArrayLen;v=v+3)
			{
				MPoint mpoint = MPoint(vertArray[v],vertArray[v+1],vertArray[v+2])*twmat;
				vertArray[v] = mpoint.x;
				vertArray[v+1] = mpoint.y;
				vertArray[v+2] = mpoint.z;
			}

			MFnIntArrayData restEleArrayData(restElementsData.data());
			MIntArray ele = restEleArrayData.array();
			int eleArrayLen = ele.length();
			int *eleArray = new int[eleArrayLen];
			ele.get(eleArray);

			MFnIntArrayData selectedConstraintVertsArrayData(selectedConstraintVertsData.data());
			MIntArray sv = selectedConstraintVertsArrayData.array();

			// building selectedConstraintVerts
			vector<int> selectedConstraintVertIndices;
			for (int i = 0 ; i < sv.length() ; i++)
			{
				selectedConstraintVertIndices.push_back(sv[i]);
			}
			MGlobal::displayInfo("!!!!!");
			//std::string tmp=std::to_string((long double)selectedConstraintVertIndices.size());
			//MGlobal::displayInfo(MString(tmp.c_str()));
			//std::cout<<currentConstriant<<" up"<<std::endl;
			for(int i=0;i<constraintIndex[currentConstriant].size();i++){
				if(domainParentIndex[currentConstriant]==-1)
					selectedConstraintVertIndices.push_back(constraintIndex[currentConstriant][i]);
				//std::cout<<constraintIndex[currentConstriant][i]<<std::endl;
			}
			//std::cout<<currentConstriant<<" up"<<std::endl;

			/*for(int i=0;i<10;i++){
				selectedConstraintVertIndices.push_back(i+1);
			}*/

			MFnIntArrayData selectedForceVertsArrayData(selectedForceVertsData.data());
			MIntArray sf = selectedForceVertsArrayData.array();

			vector<int> selectedForceVertIndices;
			for (int i = 0 ; i < sf.length() ; i++)
			{
				selectedForceVertIndices.push_back(sf[i]);
			}


			// temporarily create force direction vector
			double *forceDir = forceDirectionData.asDouble3();

	
			vector<double> dir;
			dir.push_back(forceDir[0]); dir.push_back(forceDir[1]);dir.push_back(forceDir[2]);

			prevDeformed = 0;
			double youngsModulusDouble = youngsModulusData.asDouble();
			double poissonRatioDouble = poissonRatioData.asDouble();
			double objectDensityDouble = objectDensityData.asDouble();
			double frictionDouble = frictionData.asDouble();
			double restitutionDouble = restitutionData.asDouble();
			double dampingDouble = dampingData.asDouble();
			double userSuppliedDtDouble = userSuppliedDtData.asDouble();
			double forceMagnitudeDouble = forceMagnitudeData.asDouble();
			int fAppT = forceApplicationTimeData.asInt();
			int fReleasedT = forceReleasedTimeData.asInt();
			int fIncT = forceIncrementTimeData.asInt();
			int fStartT = forceStartTimeData.asInt();
			int fStopT = forceStopTimeData.asInt();
			int integrationTypeInt = integrationTypeData.asShort();
			int forceModelTypeInt = forceModelTypeData.asShort();

			bool useSuppliedForceBool = useSuppliedForceData.asBool();
			bool useSuppliedConstraintsBool = useSuppliedConstraintsData.asBool();

			double contactKs = contactKsData.asDouble();
			double contactKd = contactKdData.asDouble();

			if( sm)
			{
				delete sm;
			}
			sm = new SoftBodySim(youngsModulusDouble,poissonRatioDouble,objectDensityDouble,
				frictionDouble,restitutionDouble,dampingDouble, eleArrayLen, eleArray, vertArrayLen, vertArray,integrationTypeInt,forceModelTypeInt);
			sm->setContactAttributes(contactKs,contactKd);
			if (useSuppliedConstraintsBool)
				sm->initialize("",userSuppliedDtDouble, selectedConstraintVertIndices);
			else
			{
				vector<int> empty;
				sm->initialize("",userSuppliedDtDouble, empty);
			}
			
			if (useSuppliedForceBool)
				sm->setUserForceAttributes(forceMagnitudeDouble, dir,selectedForceVertIndices,fAppT,fReleasedT,fIncT,fStartT,fStopT);

			std::vector<int> childList=fdg.GetDomainChild(currentConstriant);
			if(childList.size()!=0){//not the root
				for(int i=0;i<childList.size();i++){
					int childIndex=-1;
					for(int j=0;j<fdomain_list.size();j++){
						if(fdomain_list[j]->index==childList[i]){
							childIndex=j;
						}
					}//j
					glm::dvec3 oldPos=glm::dvec3(0,0,0);
					for(int j=0;j<parentConstraintIndex[childIndex].size();j++){
						int index=3*parentConstraintIndex[childIndex][j];
						oldPos.x+=sm->m_vertices[index];
						oldPos.y+=sm->m_vertices[index+1];
						oldPos.z+=sm->m_vertices[index+2];
					}
					oldPos=oldPos*(1.0/parentConstraintIndex[childIndex].size());
					parentLastPosOld[childIndex]=oldPos;
					parentLastPosNew[childIndex]=oldPos;
				}//i
			}
			domainID=currentConstriant;
			currentConstriant++;
			if(currentConstriant==fdomain_list.size()) currentConstriant=0;
		}

		else
		{
			std::vector<int> childList=fdg.GetDomainChild(domainID);
			if(childList.size()!=0){//not the root
				for(int i=0;i<childList.size();i++){
					int childIndex=-1;
					for(int j=0;j<fdomain_list.size();j++){
						if(fdomain_list[j]->index==childList[i]){
							childIndex=j;
						}
					}//j
					glm::dvec3 newPos=glm::dvec3(0,0,0);
					for(int j=0;j<parentConstraintIndex[childIndex].size();j++){
						int index=3*parentConstraintIndex[childIndex][j];
						newPos.x+=sm->m_vertices[index];
						newPos.y+=sm->m_vertices[index+1];
						newPos.z+=sm->m_vertices[index+2];
					}
					//std::cout<<newPos.x<<","<<newPos.y<<","<<newPos.z<<std::endl;
					newPos=newPos*(1.0/parentConstraintIndex[childIndex].size());
					parentLastPosOld[childIndex]=parentLastPosNew[childIndex];
					parentLastPosNew[childIndex]=newPos;
				}//i
			}
			//update the parents' fixed point moving distance
			std::vector<float> pos;
			int num=0;
			if(domainParentIndex[domainID]!=-1){//has parent
				for(int i=0;i<constraintIndex[domainID].size();i++){
					int index=3*constraintIndex[domainID][i];
					pos.push_back(sm->m_vertices[index]);
					pos.push_back(sm->m_vertices[index+1]);
					pos.push_back(sm->m_vertices[index+2]);
				}
			}
			sm->update(sTime);
			sTime++;
			if(domainParentIndex[domainID]!=-1){//has parent
				//std::cout<<sm->numOfVertices<<std::endl;
				for(int i=0;i<constraintIndex[domainID].size();i++){
					int index=3*constraintIndex[domainID][i];
					if(index>3*sm->numOfVertices) std::cout<<index-3*sm->numOfVertices<<"big "<<currentConstriant<<std::endl;
					glm::dvec3 movePos=parentLastPosNew[domainID]-parentLastPosOld[domainID];
					//std::cout<<sm->m_vertices[index]<<","<<sm->m_vertices[index+1]<<","<<sm->m_vertices[index+2]<<std::endl;
					sm->m_vertices[index]=pos[num++]+movePos.x;
					sm->m_vertices[index+1]=pos[num++]+movePos.y;
					sm->m_vertices[index+2]=pos[num++]+movePos.z;
					//std::cout<<sm->m_vertices[index]<<","<<sm->m_vertices[index+1]<<","<<sm->m_vertices[index+2]<<"end"<<std::endl;
					//std::cout<<constraintIndex[domainID][i]<<std::endl;
				}
			}
		}

		MFnMesh surfFn(rs,&stat);
		McheckErr( stat, "compute - MFnMesh error" );

		MFnMeshData ouputMeshDataCreator;
		MObject oMesh = ouputMeshDataCreator.create(&stat);
		buildOutputMesh(surfFn, sm->m_vertices,oMesh);
		outputMeshData.set(oMesh);
		data.setClean(plug);

	}

	else
		stat = MS::kUnknownParameter;

	return stat;
}
MStatus LSSolverNode::compute(const MPlug& plug, MDataBlock& data)
{
	MStatus stat;
	
	if( plug == deformed)
	{
		MDataHandle tetWorldMatrixData = data.inputValue(tetWorldMatrix, &returnStatus);
		McheckErr(returnStatus, "Error getting tetWorldMatrix data handle\n");

		MDataHandle restShapeData = data.inputValue(restShape, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restVerticesData = data.inputValue(restVertices, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restElementsData = data.inputValue(restElements, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedConstraintVertsData = data.inputValue(selectedConstraintVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedForceVertsData = data.inputValue(selectedForceVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle timeData = data.inputValue(time, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle outputMeshData = data.outputValue(deformed, &returnStatus);
		McheckErr(returnStatus, "Error getting outputMesh data handle\n");
		
		MMatrix twmat = tetWorldMatrixData.asMatrix();
		MObject rs = restShapeData.asMesh();
		double t = timeData.asDouble();

		MDataHandle poissonRatioData = data.inputValue(poissonRatio, &returnStatus);
		McheckErr(returnStatus, "Error getting poissonRatio data handle\n");

		MDataHandle youngsModulusData = data.inputValue(youngsModulus, &returnStatus);
		McheckErr(returnStatus, "Error getting youngsmodulus data handle\n");

		MDataHandle objectDensityData = data.inputValue(objectDensity, &returnStatus);
		McheckErr(returnStatus, "Error getting objectDensity data handle\n");

		MDataHandle frictionData = data.inputValue(friction, &returnStatus);
		McheckErr(returnStatus, "Error getting friction data handle\n");

		MDataHandle restitutionData = data.inputValue(restitution, &returnStatus);
		McheckErr(returnStatus, "Error getting restitution data handle\n");

		MDataHandle dampingData = data.inputValue(damping, &returnStatus);
		McheckErr(returnStatus, "Error getting damping data handle\n");

		MDataHandle userSuppliedDtData = data.inputValue(userSuppliedDt, &returnStatus);
		McheckErr(returnStatus, "Error getting user supplied dt data handle\n");


		MDataHandle integrationTypeData = data.inputValue(integrationType, &returnStatus);
		McheckErr(returnStatus, "Error getting user integrationTypeData\n");

		MDataHandle forceModelTypeData = data.inputValue(forceModelType, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceModelTypeData\n");

		MDataHandle forceApplicationTimeData = data.inputValue(forceApplicationTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceApplicationTime\n");
	
		MDataHandle forceReleasedTimeData = data.inputValue(forceReleasedTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceReleasedTime\n");

		MDataHandle forceIncrementTimeData = data.inputValue(forceIncrementTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIncrementTime\n");

		MDataHandle forceStartTimeData = data.inputValue(forceStartTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStartTime\n");

		MDataHandle forceStopTimeData = data.inputValue(forceStopTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStopTime\n");

		MDataHandle forceMagnitudeData = data.inputValue(forceMagnitude, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedForceData = data.inputValue(useSuppliedForce, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedConstraintsData = data.inputValue(useSuppliedConstraints, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle forceDirectionData = data.inputValue(forceDirection, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MDataHandle contactKsData = data.inputValue(contactKs, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");	

		MDataHandle contactKdData = data.inputValue(contactKd, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MTime currentTime, maxTime;
		currentTime = MAnimControl::currentTime();
		maxTime = MAnimControl::maxTime();
					
		if (currentTime == MAnimControl::minTime())
		{
			// retrive restVertices and restElements
			MFnDoubleArrayData restVertArrayData(restVerticesData.data());
			MDoubleArray verts = restVertArrayData.array();
			int vertArrayLen = verts.length();
			double *vertArray = new double[vertArrayLen];
			verts.get(vertArray);

			for(int v=0;v<vertArrayLen;v=v+3)
			{
				MPoint mpoint = MPoint(vertArray[v],vertArray[v+1],vertArray[v+2])*twmat;
				vertArray[v] = mpoint.x;
				vertArray[v+1] = mpoint.y;
				vertArray[v+2] = mpoint.z;
			}

			MFnIntArrayData restEleArrayData(restElementsData.data());
			MIntArray ele = restEleArrayData.array();
			int eleArrayLen = ele.length();
			int *eleArray = new int[eleArrayLen];
			ele.get(eleArray);

			MFnIntArrayData selectedConstraintVertsArrayData(selectedConstraintVertsData.data());
			MIntArray sv = selectedConstraintVertsArrayData.array();

			// building selectedConstraintVerts
			vector<int> selectedConstraintVertIndices;
			for (int i = 0 ; i < sv.length() ; i++)
			{
				selectedConstraintVertIndices.push_back(sv[i]);
			}

			MFnIntArrayData selectedForceVertsArrayData(selectedForceVertsData.data());
			MIntArray sf = selectedForceVertsArrayData.array();

			vector<int> selectedForceVertIndices;
			for (int i = 0 ; i < sf.length() ; i++)
			{
				selectedForceVertIndices.push_back(sf[i]);
			}


			// temporarily create force direction vector
			double *forceDir = forceDirectionData.asDouble3();

	
			vector<double> dir;
			dir.push_back(forceDir[0]); dir.push_back(forceDir[1]);dir.push_back(forceDir[2]);

			prevDeformed = 0;
			double youngsModulusDouble = youngsModulusData.asDouble();
			double poissonRatioDouble = poissonRatioData.asDouble();
			double objectDensityDouble = objectDensityData.asDouble();
			double frictionDouble = frictionData.asDouble();
			double restitutionDouble = restitutionData.asDouble();
			double dampingDouble = dampingData.asDouble();
			double userSuppliedDtDouble = userSuppliedDtData.asDouble();
			double forceMagnitudeDouble = forceMagnitudeData.asDouble();
			int fAppT = forceApplicationTimeData.asInt();
			int fReleasedT = forceReleasedTimeData.asInt();
			int fIncT = forceIncrementTimeData.asInt();
			int fStartT = forceStartTimeData.asInt();
			int fStopT = forceStopTimeData.asInt();
			int integrationTypeInt = integrationTypeData.asShort();
			int forceModelTypeInt = forceModelTypeData.asShort();

			bool useSuppliedForceBool = useSuppliedForceData.asBool();
			bool useSuppliedConstraintsBool = useSuppliedConstraintsData.asBool();

			double contactKs = contactKsData.asDouble();
			double contactKd = contactKdData.asDouble();

			if( sm)
			{
				delete sm;
			}
			sm = new SoftBodySim(youngsModulusDouble,poissonRatioDouble,objectDensityDouble,
				frictionDouble,restitutionDouble,dampingDouble, eleArrayLen, eleArray, vertArrayLen, vertArray,integrationTypeInt,forceModelTypeInt);
			sm->setContactAttributes(contactKs,contactKd);
			if (useSuppliedConstraintsBool)
				sm->initialize("",userSuppliedDtDouble, selectedConstraintVertIndices);
			else
			{
				vector<int> empty;
				sm->initialize("",userSuppliedDtDouble, empty);
			}
			
			if (useSuppliedForceBool)
				sm->setUserForceAttributes(forceMagnitudeDouble, dir,selectedForceVertIndices,fAppT,fReleasedT,fIncT,fStartT,fStopT);
		}

		else
		{
			sm->update();
		}

		MFnMesh surfFn(rs,&stat);
		McheckErr( stat, "compute - MFnMesh error" );

		MFnMeshData ouputMeshDataCreator;
		MObject oMesh = ouputMeshDataCreator.create(&stat);
		buildOutputMesh(surfFn, sm->m_vertices,oMesh);
		outputMeshData.set(oMesh);
		data.setClean(plug);

	}

	else
		stat = MS::kUnknownParameter;

	return stat;
}
Exemplo n.º 14
0
// add some additional inputs
MStatus HRBFSkinCluster::initialize()
{
	std::cout << "called initialize" << std::endl;

	MFnNumericAttribute numAttr;
	MFnTypedAttribute typedAttr;
	//MFnCompoundAttribute cmpdAttr;

	MStatus returnStatus;
	HRBFSkinCluster::rebuildHRBF = numAttr.create("RebuildHRBF", "rbld", MFnNumericData::kInt,
		0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating rbld attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::rebuildHRBF);
	McheckErr(returnStatus, "ERROR adding rbld attribute\n");

	HRBFSkinCluster::exportComposition = numAttr.create("ExportComp", "exprtC", MFnNumericData::kInt,
		0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating exprtC attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::exportComposition);
	McheckErr(returnStatus, "ERROR adding exprtC attribute\n");

	HRBFSkinCluster::exportHRBFSamples = typedAttr.create("ExportHRBFs", "exprtS", MFnNumericData::kString,
		&returnStatus);
	McheckErr(returnStatus, "ERROR creating exprtS attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::exportHRBFSamples);
	McheckErr(returnStatus, "ERROR adding exprtS attribute\n");

	HRBFSkinCluster::exportHRBFValues = typedAttr.create("ExportHRBFv", "exprtV", MFnNumericData::kString,
		&returnStatus);
	McheckErr(returnStatus, "ERROR creating exprtV attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::exportHRBFValues);
	McheckErr(returnStatus, "ERROR adding exprtV attribute\n");

	HRBFSkinCluster::useDQ = numAttr.create("UseDualQuaternions", "useDQ", MFnNumericData::kInt,
		0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating useDQ attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::useDQ);
	McheckErr(returnStatus, "ERROR adding useDQ attribute\n");

	HRBFSkinCluster::useHRBF = numAttr.create("UseHRBFCorrection", "useHRBF", MFnNumericData::kInt,
		0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating useHRBF attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::useHRBF);
	McheckErr(returnStatus, "ERROR adding useHRBF attribute\n");

	HRBFSkinCluster::checkHRBFAt = numAttr.create("checkHRBFAt", "chkHRBF", MFnNumericData::k3Double,
		0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating checkHRBFAt attribute\n");
	returnStatus = addAttribute(HRBFSkinCluster::checkHRBFAt);
	McheckErr(returnStatus, "ERROR adding checkHRBFAt attribute\n");

	// hierarchy information
	// http://download.autodesk.com/us/maya/2011help/API/weight_list_node_8cpp-example.html#a15
	HRBFSkinCluster::jointParentIdcs = numAttr.create("parentJointIDCS", "pJIDCS", MFnNumericData::kInt,
		0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating pIDCS attribute\n");
	numAttr.setArray(true);
	returnStatus = addAttribute(HRBFSkinCluster::jointParentIdcs);
	McheckErr(returnStatus, "ERROR adding pIDCS attribute\n");

	// joint names
	HRBFSkinCluster::jointNames = typedAttr.create("jointNames", "jNms", MFnData::kString,
		&returnStatus);
	McheckErr(returnStatus, "ERROR creating pIDCS attribute\n");
	typedAttr.setArray(true);
	returnStatus = addAttribute(HRBFSkinCluster::jointNames);
	McheckErr(returnStatus, "ERROR adding jNms attribute\n");

	// set up affects
	returnStatus = attributeAffects(HRBFSkinCluster::rebuildHRBF,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with rebuildHRBF\n");

	returnStatus = attributeAffects(HRBFSkinCluster::exportComposition,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with exportComposition\n");

	returnStatus = attributeAffects(HRBFSkinCluster::exportHRBFSamples,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with exportHRBFSamples\n");

	returnStatus = attributeAffects(HRBFSkinCluster::exportHRBFValues,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with exportHRBFValues\n");

	returnStatus = attributeAffects(HRBFSkinCluster::useDQ,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with useDQ\n");

	returnStatus = attributeAffects(HRBFSkinCluster::useHRBF,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with useHRBF\n");

	returnStatus = attributeAffects(HRBFSkinCluster::jointParentIdcs,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with jointParentIdcs\n");

	returnStatus = attributeAffects(HRBFSkinCluster::checkHRBFAt,
		HRBFSkinCluster::outputGeom);
	McheckErr(returnStatus, "ERROR in attributeAffects with checkHRBFAt\n");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

	return returnStatus;
}
Exemplo n.º 16
0
MStatus sweptEmitter::compute(const MPlug& plug, MDataBlock& block)
//
//	Descriptions:
//		Call emit emit method to generate new particles.
//
{
	MStatus status;

	// Determine if we are requesting the output plug for this emitter node.
	//
	if( !(plug == mOutput) )
        return( MS::kUnknownParameter );

	// Get the logical index of the element this plug refers to,
	// because the node can be emitting particles into more 
    // than one particle shape.
	//
	int multiIndex = plug.logicalIndex( &status );
	McheckErr(status, "ERROR in plug.logicalIndex.\n");

	// Get output data arrays (position, velocity, or parentId)
	// that the particle shape is holding from the previous frame.
	//
	MArrayDataHandle hOutArray = block.outputArrayValue(mOutput, &status);
	McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n");

	// Create a builder to aid in the array construction efficiently.
	//
	MArrayDataBuilder bOutArray = hOutArray.builder( &status );
	McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n");

	// Get the appropriate data array that is being currently evaluated.
	//
	MDataHandle hOut = bOutArray.addElement(multiIndex, &status);
	McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n");

    // Get the data and apply the function set.
    //
    MFnArrayAttrsData fnOutput;
    MObject dOutput = fnOutput.create ( &status );
    McheckErr(status, "ERROR in fnOutput.create.\n");

	// Check if the particle object has reached it's maximum,
	// hence is full. If it is full then just return with zero particles.
	//
	bool beenFull = isFullValue( multiIndex, block );
	if( beenFull )
	{
		return( MS::kSuccess );
	}

	// Get deltaTime, currentTime and startTime.
	// If deltaTime <= 0.0, or currentTime <= startTime,
	// do not emit new pariticles and return.
	//
	MTime cT = currentTimeValue( block );
	MTime sT = startTimeValue( multiIndex, block );
	MTime dT = deltaTimeValue( multiIndex, block );
	if( (cT <= sT) || (dT <= 0.0) )
	{
		// We do not emit particles before the start time, 
		// and do not emit particles when moving backwards in time.
		// 

		// This code is necessary primarily the first time to 
		// establish the new data arrays allocated, and since we have 
		// already set the data array to length zero it does 
		// not generate any new particles.
		// 
		hOut.set( dOutput );
		block.setClean( plug );

		return( MS::kSuccess );
	}

	// Get speed, direction vector, and inheritFactor attributes.
	//
	double speed = speedValue( block );
	MVector dirV = directionVector( block );
	double inheritFactor = inheritFactorValue( multiIndex, block );

	// Get the position and velocity arrays to append new particle data.
	//
	MVectorArray fnOutPos = fnOutput.vectorArray("position", &status);
	MVectorArray fnOutVel = fnOutput.vectorArray("velocity", &status);

	// Convert deltaTime into seconds.
	//
	double dt = dT.as( MTime::kSeconds );
	
	// Apply rotation to the direction vector
	MVector rotatedV = useRotation ( dirV );


	// position,
	MVectorArray inPosAry;
	// velocity
	MVectorArray inVelAry;
	// emission rate
	MIntArray emitCountPP;


	// Get the swept geometry data
	//
	MObject thisObj = this->thisMObject();
	MPlug sweptPlug( thisObj, mSweptGeometry );

	if ( sweptPlug.isConnected() ) 
	{
		MDataHandle sweptHandle = block.inputValue( mSweptGeometry );
		// MObject sweptData = sweptHandle.asSweptGeometry();
		MObject sweptData = sweptHandle.data();
		MFnDynSweptGeometryData fnSweptData( sweptData );


		// Curve emission
		//
		if (fnSweptData.lineCount() > 0) {
			int numLines = fnSweptData.lineCount();
		
			for ( int i=0; i<numLines; i++ )
			{
				inPosAry.clear();
				inVelAry.clear();
				emitCountPP.clear();

				MDynSweptLine line = fnSweptData.sweptLine( i );

				// ... process current line ...
				MVector p1 = line.vertex( 0 );
				MVector p2 = line.vertex( 1 );

				inPosAry.append( p1 );
				inPosAry.append( p2 );

				inVelAry.append( MVector( 0,0,0 ) );
				inVelAry.append( MVector( 0,0,0 ) );

				// emit Rate for two points on line
				emitCountPP.clear();
				status = emitCountPerPoint( plug, block, 2, emitCountPP );

				emit( inPosAry, inVelAry, emitCountPP,
					dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel );

			}
		}

		// Surface emission (nurb or polygon)
		//
		if (fnSweptData.triangleCount() > 0) {
			int numTriangles = fnSweptData.triangleCount();
		
			for ( int i=0; i<numTriangles; i++ )
			{
				inPosAry.clear();
				inVelAry.clear();
				emitCountPP.clear();

				MDynSweptTriangle tri = fnSweptData.sweptTriangle( i );

				// ... process current triangle ...
				MVector p1 = tri.vertex( 0 );
				MVector p2 = tri.vertex( 1 );
				MVector p3 = tri.vertex( 2 );

				MVector center = p1 + p2 + p3;
				center /= 3.0;

				inPosAry.append( center );

				inVelAry.append( MVector( 0,0,0 ) );

				// emit Rate for two points on line
				emitCountPP.clear();
				status = emitCountPerPoint( plug, block, 1, emitCountPP );

				emit( inPosAry, inVelAry, emitCountPP,
					dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel );

			}
		}
	}

	// Update the data block with new dOutput and set plug clean.
	//
	hOut.set( dOutput );
	block.setClean( plug );

	return( MS::kSuccess );
}
Exemplo n.º 17
0
MStatus TCC::createSubdividedMesh(int sdRes, int sdRefRes, MFnMesh &srcMesh, TCCData &tccData, MDataHandle outMeshHandle, float lineThickness, MStatus& stat)
{   
    HDS hds;
    bool shouldCreateUVs = true;
    
    size_t nV = srcMesh.numVertices();
    size_t nF = srcMesh.numPolygons();
    size_t nIHE = tccData.F.length();
    
    bool consistentSizes= (tccData.pole.length()==nV) && (tccData.T.length()==nIHE) && (tccData.itv.length()==nIHE) & (tccData.corner.length()==nV);
    
    if ((nV==0)||(nF==0)||(!consistentSizes)) return MS::kFailure;

    MFloatArray uArray, vArray, sc_uArray, sc_vArray;
    MIntArray uvIdx;
    if (shouldCreateUVs)
    {
        createUVset(tccData, sdRes, uArray, vArray, sc_uArray, sc_vArray, uvIdx, lineThickness);
    }
    
    
    MFloatPointArray points;
    srcMesh.getPoints(points);
    
    store_in_hds(hds, points, tccData.nFV, tccData.F);     // convert to HDS

    finalize_HDS(hds);
    size_t nHE = hds.nHE();

    hds.T.setDims(1, nHE);
    hds.itv.setDims(1, nHE);
    hds.corner.setDims(1, nV);
    
    // interior halfedge tags
    for (size_t k=0; k<nV; k++) 
    {
        hds.corner[k] = tccData.corner[k];
    }

    // interior halfedge tags
    for (size_t k=0; k<nIHE; k++) 
    {
        hds.T[k] = tccData.T[k];
        hds.itv[k] = tccData.itv[k];
    }
    
    // border halfedge tags
    for (size_t k=nIHE; k<nHE; k++) 
    {
        hds.T[k] = false;
        hds.itv[k] = hds.itv[hds.twin[k]];
    }
        
    TCC_MAX::subdivide(hds, sdRes);
    
    if (sdRefRes>0)
    {
        HDS hds2;
        copy_HDS(hds, hds2);
        TCC_MAX::subdivide(hds2, sdRefRes);
        memcpy(&hds.V[0], &hds2.V[0], hds.V.size() * sizeof(double));
    }
    

    
    MObject outMeshObj = outMeshHandle.asMesh();
    MFnMesh outMeshFn(outMeshObj);
    
    // if no topology change necessary, just update points!
    if ( (outMeshFn.numFaceVertices() == hds.nIHE()) && (outMeshFn.numPolygons() == hds.nF()) )
    {
        size_t nV   = hds.nV();
        points.setLength(nV);
        for (size_t k=0; k<nV; k++) 
        {
            points[k](0) = hds.V[3*k+0];
            points[k](1) = hds.V[3*k+1];
            points[k](2) = hds.V[3*k+2];
        }
        stat = outMeshFn.setPoints(points); McheckErr(stat, "ERROR creating outputData");
        
        if (shouldCreateUVs)
        {
            MString uvSet = "UnitPatchUVs";
            MString sc_uvSet = "ScaledPatchUVs";
            stat = outMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
            stat = outMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        }
        
        return MS::kSuccess;
    }

    
    // Have to update connectivity and geometry

    load_from_hds(hds, points, tccData.nFV, tccData.F);

    nV = points.length();
    nF = tccData.nFV.length();
    
    MFnMeshData dataCreator;
    MObject newOutputData = dataCreator.create(&stat); McheckErr(stat, "ERROR creating outputData");
    MFnMesh newOutMeshFn;
    
    MObject newMesh;
    
    newMesh = newOutMeshFn.create(nV, nF, points, tccData.nFV, tccData.F, newOutputData, &stat); McheckErr(stat, "ERROR in MFnMesh.create\n");

    if (shouldCreateUVs)
    {
        MString uvSet = "UnitPatchUVs";
        MString sc_uvSet = "ScaledPatchUVs";
        
        uvSet = newOutMeshFn.createUVSetDataMeshWithName(uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&uvSet);
        stat = newOutMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &uvSet); McheckErr(stat, "ERROR assigning UVs");
        
        sc_uvSet = newOutMeshFn.createUVSetDataMeshWithName(sc_uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&sc_uvSet);
        stat = newOutMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &sc_uvSet); McheckErr(stat, "ERROR assigning UVs");
    }
    
    
    if (stat == MS::kSuccess)
    {
        outMeshHandle.set(newOutputData);
    }
    
    
    return MS::kSuccess;
}
Exemplo n.º 18
0
MStatus TCC::initialize()
{
    MFnNumericAttribute numAttr;
    MFnTypedAttribute attrFn;

    MFnIntArrayData defaultIArrayDataFn; 
    MFnDoubleArrayData defaultDArrayDataFn; 
    
    MStatus stat;

    aRes = numAttr.create( "SubdivisionResolution", "res", MFnNumericData::kInt, 3 );
    aRefRes = numAttr.create( "SubdivisionRefinementResolution", "refres", MFnNumericData::kInt, 0 );
    aLineThickness = numAttr.create( "UVLineThickness", "th", MFnNumericData::kFloat, 0 );
    
    
    aInputMesh = attrFn.create("inputMesh", "inMesh", MFnMeshData::kMesh);
    
    defaultIArrayDataFn.create( );
    anFVc = attrFn.create("nFVcached", "nFVc", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);

    defaultIArrayDataFn.create( );
    aFc = attrFn.create("Fcached", "Fc", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);

    defaultIArrayDataFn.create( );
    aPole = attrFn.create("pole", "pole", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);
    
    defaultIArrayDataFn.create( );
    aCorner = attrFn.create("corner", "corner", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);
    
    defaultIArrayDataFn.create( );
    aT = attrFn.create("T", "T", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);
    
    defaultIArrayDataFn.create( );
    aEqc = attrFn.create("eqc", "eqc", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);

    defaultDArrayDataFn.create( );
    aItv = attrFn.create("itv", "itv", MFnData::kDoubleArray, defaultDArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);
    
    defaultIArrayDataFn.create( );
    
    aErr = attrFn.create("err", "err", MFnData::kIntArray, defaultIArrayDataFn.object());
    attrFn.setConnectable(false);
    attrFn.setStorable(true);
    
    aOutputMesh = attrFn.create( "outputMesh", "out", MFnData::kMesh);
    attrFn.setStorable(false);
    attrFn.setWritable(false);

    stat = addAttribute(aRes); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aRefRes); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aLineThickness); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aInputMesh); McheckErr(stat, "ERROR adding attribute\n");
    
    stat = addAttribute(anFVc); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aFc); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aPole); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aCorner); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aT); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aEqc); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aItv); McheckErr(stat, "ERROR adding attribute\n");
    stat = addAttribute(aErr); McheckErr(stat, "ERROR adding attribute\n");
    
    stat = addAttribute(aOutputMesh); McheckErr(stat, "ERROR adding attribute\n");

    stat = attributeAffects(aRes, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aRefRes, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aLineThickness, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aInputMesh, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    
    stat = attributeAffects(anFVc, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aFc, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aPole, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aCorner, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aT, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aEqc, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aItv, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");
    stat = attributeAffects(aErr, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n");

    return MS::kSuccess;
}
Exemplo n.º 19
0
MStatus LSSolverNode::initialize()
{
	MFnNumericAttribute nAttr;
	MFnUnitAttribute uAttr;
	MFnTypedAttribute tAttr;
	MFnEnumAttribute eAttr;
	MFnMatrixAttribute mAttr;

	tetWorldMatrix = mAttr.create("tet_world_matrix","twm",MFnMatrixAttribute::kDouble,&returnStatus);
	McheckErr(returnStatus, "ERROR creating LSTetgenNode worldMatrix attribute\n");
	MAKE_INPUT(mAttr);
	mAttr.setHidden(true);

	restShape = tAttr.create("restShape", "rs", MFnMeshData::kMesh, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode restShape attribute\n");
	MAKE_INPUT(tAttr);

	restElements = tAttr.create("restElements", "re", MFnData::kIntArray, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode restShape attribute\n");
	MAKE_INPUT(tAttr);

	restVertices = tAttr.create("restVertices", "rv", MFnData::kDoubleArray, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode restShape attribute\n");
	MAKE_INPUT(tAttr);

	selectedConstraintVerts = tAttr.create("selectedConstraintVerts", "scv", MFnData::kIntArray, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode selectedConstraintVerts attribute\n");
	MAKE_INPUT(tAttr);

	selectedForceVerts = tAttr.create("selectedForceVerts", "sfv", MFnData::kIntArray, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode selectedForceVerts attribute\n");
	MAKE_INPUT(tAttr);

	time = uAttr.create("time", "t", MFnUnitAttribute::kTime,0.0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode time attribute\n");
	MAKE_INPUT(uAttr);

	deformed = tAttr.create("deformed", "d", MFnMeshData::kMesh, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode deformed attribute\n");
	MAKE_OUTPUT(tAttr);

	poissonRatio = nAttr.create("poissonRatio", "pr", MFnNumericData::kDouble, 0.45, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode poisson ratio\n");
	MAKE_INPUT(nAttr);
	nAttr.setMax(0.45);
	nAttr.setMin(0);

	youngsModulus = nAttr.create("youngsModulus", "ym", MFnNumericData::kDouble, 90000000000, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode youngsModulus\n");
	MAKE_INPUT(nAttr);
	//nAttr.setMax(50000);
	//nAttr.setMin(1);

	objectDensity = nAttr.create("density", "objd", MFnNumericData::kDouble, 1000, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode objectDensity\n");
	MAKE_INPUT(nAttr);
	nAttr.setMax(10000);
	nAttr.setMin(1);

	friction = nAttr.create("friction", "f", MFnNumericData::kDouble, 0.98, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode friction\n");
	MAKE_INPUT(nAttr);
	nAttr.setMax(1);
	nAttr.setMin(0);

	restitution = nAttr.create("restitution", "r", MFnNumericData::kDouble, 0.4, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode restitution\n");
	MAKE_INPUT(nAttr);
	nAttr.setMax(1);
	nAttr.setMin(0);

	damping = nAttr.create("damping", "dmp", MFnNumericData::kDouble, 0.0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode damping\n");
	MAKE_INPUT(nAttr);
	nAttr.setMax(1);
	nAttr.setMin(0);

	userSuppliedDt = nAttr.create("timeStep","ts",MFnNumericData::kDouble,0.01, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode userSuppliedDt\n");
	MAKE_INPUT(nAttr);
	nAttr.setMax(1);
	nAttr.setMin(0.00001);

	forceApplicationTime = nAttr.create("forceApplicationTime", "fat", MFnNumericData::kInt, 50, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceApplicationTime ratio\n");
	MAKE_INPUT(nAttr);

	forceReleasedTime = nAttr.create("forceReleasedTime", "frt", MFnNumericData::kInt, 100, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceReleasedTime ratio\n");
	MAKE_INPUT(nAttr);

	forceIncrementTime = nAttr.create("forceIncrementTime", "fit", MFnNumericData::kInt, 10, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceIncrementTime ratio\n");
	MAKE_INPUT(nAttr);

	forceStartTime = nAttr.create("forceStartTime", "fst", MFnNumericData::kInt,100, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceStartTime\n");
	MAKE_INPUT(nAttr);

	forceStopTime = nAttr.create("forceStopTime", "fet", MFnNumericData::kInt, 200, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceStopTime\n");
	MAKE_INPUT(nAttr);

	forceMagnitude = nAttr.create("forceMagnitude", "fm", MFnNumericData::kDouble, 10.0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceIdleTime ratio\n");
	MAKE_INPUT(nAttr);

	forceDirection = nAttr.create("forceDirection", "fd", MFnNumericData::k3Double, 0.0 , &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceIdleTime ratio\n");
	MAKE_INPUT(nAttr);

	useSuppliedConstraints = nAttr.create("useSuppliedConstraints", "usc", MFnNumericData::kBoolean,1, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode useSuppliedConstraints ratio\n");
	MAKE_INPUT(nAttr);

	useSuppliedForce = nAttr.create("useSuppliedForce", "usf", MFnNumericData::kBoolean, 0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode useSuppliedForces ratio\n");
	MAKE_INPUT(nAttr);




	integrationType = eAttr.create("timeIntegrationMethod","it",0,&returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode integrationType\n");
	eAttr.addField("Implicit Backward Euler",0);
	eAttr.addField("Implicit Newmark",1);
	eAttr.addField("Central Differences",2);
	eAttr.addField("Symplectic Euler",3);
	MAKE_INPUT(eAttr);

	forceModelType = eAttr.create("system","ft",0,&returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode forceModelType\n");
	eAttr.addField("Corotational Linear FEM",0);
	eAttr.addField("Mass Spring System",1);
	MAKE_INPUT(eAttr);
	
	contactKs = nAttr.create("contactSpringForce", "cKs", MFnNumericData::kDouble, 1000.0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode contactSpringForces\n");
	MAKE_INPUT(nAttr);

	contactKd = nAttr.create("contactDampForce", "cKd", MFnNumericData::kDouble, 50.0, &returnStatus);
	McheckErr(returnStatus, "ERROR creating LSSolverNode contactDampForces\n");
	MAKE_INPUT(nAttr);

	returnStatus = addAttribute(tetWorldMatrix);
	McheckErr(returnStatus, "ERROR adding LSSolverNode world matrix attribute\n");

	returnStatus = addAttribute(restShape);
	McheckErr(returnStatus, "ERROR adding LSSolverNode step attribute\n");
	
	returnStatus = addAttribute(restElements);
	McheckErr(returnStatus, "ERROR adding LSSolverNode restElements attribute\n");

	returnStatus = addAttribute(restVertices);
	McheckErr(returnStatus, "ERROR adding LSSolverNode restVertices attribute\n");

	returnStatus = addAttribute(selectedConstraintVerts);
	McheckErr(returnStatus, "ERROR adding LSSolverNode selectedConstraintVerts attribute\n");

	returnStatus = addAttribute(selectedForceVerts);
	McheckErr(returnStatus, "ERROR adding LSSolverNode selectedForceVerts attribute\n");

	returnStatus = addAttribute(time);
	McheckErr(returnStatus, "ERROR adding LSSolverNode time attribute\n");

	returnStatus = addAttribute(deformed);
	McheckErr(returnStatus, "ERROR adding LSSolverNode deformed attribute\n");

	returnStatus = addAttribute(youngsModulus);
	McheckErr(returnStatus, "ERROR adding LSSolverNode youngsModulus\n");

	returnStatus = addAttribute(poissonRatio);
	McheckErr(returnStatus, "ERROR adding LSSolverNode poissonRation\n");

	returnStatus = addAttribute(objectDensity);
	McheckErr(returnStatus, "ERROR adding LSSolverNode objectDensity\n");

	returnStatus = addAttribute(friction);
	McheckErr(returnStatus, "ERROR adding LSSolverNode friction\n");

	returnStatus = addAttribute(restitution);
	McheckErr(returnStatus, "ERROR adding LSSolverNode resitution\n");

	returnStatus = addAttribute(damping);
	McheckErr(returnStatus, "ERROR adding LSSolverNode damping\n");

	returnStatus = addAttribute(userSuppliedDt);
	McheckErr(returnStatus, "ERROR adding LSSolverNode userSuppliedDt\n");

	returnStatus = addAttribute(useSuppliedConstraints);
	McheckErr(returnStatus, "ERROR adding LSSolverNode useSuppliedConstraints\n");
	
	returnStatus = addAttribute(useSuppliedForce);
	McheckErr(returnStatus, "ERROR adding LSSolverNode useSuppliedForce\n");
	
	returnStatus = addAttribute(forceMagnitude);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceMagnitude\n");

	returnStatus = addAttribute(forceDirection);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceDirection\n");
	
	returnStatus = addAttribute(forceApplicationTime);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceApplicationTime\n");
	
	returnStatus = addAttribute(forceReleasedTime);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceReleasedTime\n");
	
	returnStatus = addAttribute(forceIncrementTime);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceIncrementTime\n");

	returnStatus = addAttribute(forceStartTime);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceIdleTime\n");
	
	returnStatus = addAttribute(forceStopTime);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceIdleTime\n");	

//	returnStatus = addAttribute(inputFilePath);
//	McheckErr(returnStatus, "ERROR adding LSSolverNode inputFilePath\n");

	returnStatus = addAttribute(integrationType);
	McheckErr(returnStatus, "ERROR adding LSSolverNode integrationType\n");

	returnStatus = addAttribute(forceModelType);
	McheckErr(returnStatus, "ERROR adding LSSolverNode forceModelType\n");

	returnStatus = addAttribute(contactKd);
	McheckErr(returnStatus, "ERROR adding LSSolverNode contactKd\n");

	returnStatus = addAttribute(contactKs);
	McheckErr(returnStatus, "ERROR adding LSSolverNode contactKs\n");

	returnStatus = attributeAffects(restShape, deformed);
	McheckErr(returnStatus, "ERROR in attributeAffects: restShape - deformed\n");
	
	returnStatus = attributeAffects(time, deformed);
	McheckErr(returnStatus, "ERROR in attributeAffects: time - deformed\n");
	

	return MS::kSuccess;
}
Exemplo n.º 20
0
MStatus latticeNoiseNode::compute( const MPlug& plug, MDataBlock& data )
{ 
	MStatus returnStatus;

	float noiseAmplitude;
	float noiseFreq;
 
	if( plug == output )
	{
		// Get the lattice data from the input attribute.  First get the 
		// data object, and then use the lattice data function set to extract
		// the actual lattice.
		//

		// Get the data handle
		//
		MDataHandle inputData = data.inputValue( input, &returnStatus );
		McheckErr( returnStatus, "ERROR getting lattice data handle\n" ); 
		// Get the data object
		//
		MObject latticeData = inputData.data(); 
		MFnLatticeData dataFn( latticeData );
		// Get the actual geometry
		// 
		MObject lattice = dataFn.lattice();
		MFnLattice lattFn( lattice, &returnStatus );
		McheckErr( returnStatus, "ERROR getting lattice geometry\n" );  


		// Do the same for the output lattice
		//
		MDataHandle outputData = data.outputValue( output, &returnStatus ); 
		McheckErr( returnStatus, "ERROR getting lattice data handle\n" );
		// Get the data object
		//
		latticeData = outputData.data(); 
		if ( latticeData.isNull() ) { 
			// The data object for this attribute has not been created yet, so
			// we'll create it
			//
			latticeData = dataFn.create();
		} else {
			// Use the data object that is already there
			// 
			dataFn.setObject( latticeData );
		}
		// Get the actual geometry
		// 
		MObject outLattice = dataFn.lattice();
		MFnLattice outLattFn( outLattice, &returnStatus );
		McheckErr( returnStatus, "ERROR getting lattice geometry\n" );  

		// Get the amplitude and frequency
		//
		MDataHandle ampData = data.inputValue( amplitude, &returnStatus );
		McheckErr( returnStatus, "ERROR getting amplitude\n" );
		noiseAmplitude = ampData.asFloat(); 

		MDataHandle freqData = data.inputValue( frequency, &returnStatus );
		McheckErr( returnStatus, "ERROR getting frequency\n" );
		noiseFreq = freqData.asFloat(); 

		// Get the time.  
		//
		MDataHandle timeData = data.inputValue( time, &returnStatus ); 
		McheckErr( returnStatus, "ERROR getting time data handle\n" );
		MTime time = timeData.asTime();
		float seconds = (float)time.as( MTime::kSeconds );

		// Easiest way to modify frequency is by modifying the time
		//
		seconds = seconds * noiseFreq;

		// We have the information we need now.  We'll apply noise to the
		// points upon the lattice
		//
		unsigned s, t, u;
		lattFn.getDivisions( s, t, u );
		// match up the divisions in the lattices
		//
		outLattFn.setDivisions( s, t, u );   

		for ( unsigned i = 0; i < s; i++ ) {
			for ( unsigned j = 0; j < t; j++ ) {
				for ( unsigned k = 0; k < u; k++ ) {
					MPoint & point = lattFn.point( i, j, k );
					MPoint & outPoint = outLattFn.point( i, j, k );
					pnt noisePnt = noise::atPointAndTime( (float)point.x, (float)point.y, 
														  (float)point.z, seconds );
					// Make noise between -1 and 1 instead of 0 and 1
					//
					noisePnt.x =  ( noisePnt.x * 2.0F ) - 1.0F;
					noisePnt.y =  ( noisePnt.y * 2.0F ) - 1.0F;
					noisePnt.z =  ( noisePnt.z * 2.0F ) - 1.0F;

 					outPoint.x = point.x + ( noisePnt.x * noiseAmplitude );
 					outPoint.y = point.y + ( noisePnt.y * noiseAmplitude );
 					outPoint.z = point.z + ( noisePnt.z * noiseAmplitude );  
				}
			}
		} 
		outputData.set( latticeData );
		data.setClean(plug); 
	} else {
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
Exemplo n.º 21
0
MStatus dynExprField::compute(const MPlug& plug, MDataBlock& block)
//
//	Descriptions:
//		compute output force.
//
{
	MStatus status;

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

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

	// Get input data handle, use outputArrayValue since we do not
	// want to evaluate both inputs, only the one related to the
	// requested multiIndex. Evaluating both inputs at once would cause
	// a dependency graph loop.
	
	MArrayDataHandle hInputArray = block.outputArrayValue( mInputData, &status );
	McheckErr(status,"ERROR in hInputArray = block.outputArrayValue().\n");
	
	status = hInputArray.jumpToElement( multiIndex );
	McheckErr(status, "ERROR: hInputArray.jumpToElement failed.\n");
	
	// get children of aInputData.
	
	MDataHandle hCompond = hInputArray.inputValue( &status );
	McheckErr(status, "ERROR in hCompond=hInputArray.inputValue\n");
	
	MDataHandle hPosition = hCompond.child( mInputPositions );
	MObject dPosition = hPosition.data();
	MFnVectorArrayData fnPosition( dPosition );
	MVectorArray points = fnPosition.array( &status );
	McheckErr(status, "ERROR in fnPosition.array(), not find points.\n");
	
	// Comment out the following since velocity, and mass are 
	// not needed in this field.
	//
	// MDataHandle hVelocity = hCompond.child( mInputVelocities );
	// MObject dVelocity = hVelocity.data();
	// MFnVectorArrayData fnVelocity( dVelocity );
	// MVectorArray velocities = fnVelocity.array( &status );
	// McheckErr(status, "ERROR in fnVelocity.array(), not find velocities.\n");
	//
	// MDataHandle hMass = hCompond.child( mInputMass );
	// MObject dMass = hMass.data();
	// MFnDoubleArrayData fnMass( dMass );
	// MDoubleArray masses = fnMass.array( &status );
	// McheckErr(status, "ERROR in fnMass.array(), not find masses.\n");

	// The attribute mInputPPData contains the attribute in an array form 
	// parpared by the particleShape if the particleShape has per particle 
	// attribute fieldName_attrName.  
	//
	// Suppose a field with the name dynExprField1 is connecting to 
	// particleShape1, and the particleShape1 has per particle float attribute
	// dynExprField1_magnitude and vector attribute dynExprField1_direction,
	// then hInputPPArray will contains a MdoubleArray with the corresponding
	// name "magnitude" and a MvectorArray with the name "direction".  This 
	// is a mechanism to allow the field attributes being driven by dynamic 
	// expression.
	MArrayDataHandle mhInputPPData = block.inputArrayValue( mInputPPData, &status );
	McheckErr(status,"ERROR in mhInputPPData = block.inputArrayValue().\n");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return( MS::kSuccess );
}
Exemplo n.º 22
0
MStatus LSystemNode::compute(const MPlug& plug, MDataBlock& data)

{
	MStatus returnStatus;

	if (plug == outputMesh) {
		/* Get time */
		MDataHandle timeData = data.inputValue( time, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		MTime time = timeData.asTime();

		MDataHandle angleData = data.inputValue( angle, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		double angle_value = angleData.asDouble();

		MDataHandle stepsData = data.inputValue( steps, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		double steps_value = stepsData.asDouble();

		MDataHandle grammarData = data.inputValue( grammar, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		MString grammar_value = grammarData.asString();

		/* Get output object */

		MDataHandle outputHandle = data.outputValue(outputMesh, &returnStatus);
		McheckErr(returnStatus, "ERROR getting polygon data handle\n");

		MFnMeshData dataCreator;
		MObject newOutputData = dataCreator.create(&returnStatus);
		McheckErr(returnStatus, "ERROR creating outputData");

		MFnMesh	myMesh;
		MPointArray points;
		MIntArray faceCounts;
		MIntArray faceConnects;

		//MString grammar = ("F\\nF->F[+F]F[-F]F");

		CylinderMesh *cm;


		LSystem system;
		system.loadProgramFromString(grammar_value.asChar());
		system.setDefaultAngle(angle_value);
		system.setDefaultStep(steps_value);



			std::vector<LSystem::Branch> branches;
			system.process(time.value(), branches);

			int k = branches.size();
			for(int j = 0; j < branches.size(); j++)
			{
				//1. find the position for start and end point of current branch
				//2. generate a cylinder
				MPoint start(branches[j].first[0],branches[j].first[1],branches[j].first[2]);
				MPoint end(branches[j].second[0],branches[j].second[1],branches[j].second[2]);
				cm = new CylinderMesh(start, end);
				cm->appendToMesh(points, faceCounts, faceConnects); 
			}

		MObject newMesh = myMesh.create(points.length(), faceCounts.length(),
			points, faceCounts, faceConnects,
			newOutputData, &returnStatus);

		McheckErr(returnStatus, "ERROR creating new mesh");

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

	return MS::kSuccess;
}
Exemplo n.º 23
0
MStatus pointOnSubd::compute( const MPlug& plug, MDataBlock& data )
//
//	Description:
//		This method computes the value of the given output plug based
//		on the values of the input attributes.
//
//	Arguments:
//		plug - the plug to compute
//		data - object that provides access to the attributes for this node
//
{
	MStatus returnStatus;
 
	// Check which output attribute we have been asked to compute.  If this 
	// node doesn't know how to compute it, we must return 
	// MS::kUnknownParameter.
	// 
	if( (plug == aPoint) || (plug == aNormal) ||
		(plug == aPointX) || (plug == aNormalX) ||
		(plug == aPointY) || (plug == aNormalY) ||
		(plug == aPointZ) || (plug == aNormalZ) ) {

		// Get a handle to the input attribute that we will need for the
		// computation.  If the value is being supplied via a connection 
		// in the dependency graph, then this call will cause all upstream  
		// connections to be evaluated so that the correct value is supplied.
		// 
		do {
			MDataHandle subdHandle = data.inputValue( aSubd, &returnStatus );
			if( returnStatus != MS::kSuccess ) {
				MGlobal::displayError( "ERROR: cannot get subd\n" );
				break;
			}
			
			MDataHandle faceFirstHandle =
				data.inputValue( aFaceFirst, &returnStatus );
			if( returnStatus != MS::kSuccess ) {
				MGlobal::displayError( "ERROR: cannot get face first\n" );
				break;
			}
			
			MDataHandle faceSecondHandle =
				data.inputValue( aFaceSecond, &returnStatus );
			if( returnStatus != MS::kSuccess ) {
				MGlobal::displayError( "ERROR: cannot get face2\n" );
				break;
			}
			
			MDataHandle uHandle = data.inputValue( aU, &returnStatus );
			if( returnStatus != MS::kSuccess ) {
				MGlobal::displayError( "ERROR: cannot get u\n" );
				break;
			}
			
			MDataHandle vHandle = data.inputValue( aV, &returnStatus );
			if( returnStatus != MS::kSuccess ) {
				MGlobal::displayError( "ERROR: cannot get v\n" );
				break;
			}

			MDataHandle relHandle = data.inputValue( aRelativeUV, &returnStatus );
			if( returnStatus != MS::kSuccess ) {
				MGlobal::displayError( "ERROR: cannot get relative UV\n" );
				break;
			}
			
			// Read the input value from the handle.
			//
			MStatus stat;
			MObject subdValue = subdHandle.asSubdSurface();
			MFnSubd subdFn( subdValue, &stat );
			McheckErr(stat,"ERROR creating subd function set"); 

			int faceFirstValue = faceFirstHandle.asLong();
			int faceSecondValue = faceSecondHandle.asLong();
			double uValue = uHandle.asDouble();
			double vValue = vHandle.asDouble();
			bool relUV = relHandle.asBool();

			MPoint point;
			MVector normal;

			MUint64 polyId;
			stat = MFnSubdNames::fromSelectionIndices( polyId, faceFirstValue,
													   faceSecondValue );
			McheckErr(stat,"ERROR converting indices"); 


			stat = subdFn.evaluatePositionAndNormal( polyId, uValue, vValue,
													 relUV, point, normal );
			normal.normalize();
			McheckErr(stat,"ERROR evaluating the position and the normal"); 

			// Get handles to the output attributes.  This is similar to the
			// "inputValue" call above except that no dependency graph 
			// computation will be done as a result of this call.
			// 
			MDataHandle pointHandle = data.outputValue( aPoint );
			pointHandle.set( point.x, point.y, point.z );
			data.setClean(plug);

			MDataHandle normalHandle = data.outputValue( aNormal );
			normalHandle.set( normal.x, normal.y, normal.z );
			data.setClean(plug);

		} while( false );
	}
	else {
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
Exemplo n.º 24
0
MStatus LSystemNode::initialize()
{
	MFnUnitAttribute unitAttr;
	MFnTypedAttribute typedAttr;

	MFnNumericAttribute angleNumAttr;
	MFnNumericAttribute stepNumAttr;

	MFnTypedAttribute grammarTypedAttr;

	MStatus returnStatus;

	LSystemNode::time = unitAttr.create( "time", "tm",
		MFnUnitAttribute::kTime,
		0.0, &returnStatus );
	McheckErr(returnStatus, "ERROR creating LSystemNode time attribute\n");


	LSystemNode::outputMesh = typedAttr.create( "outputMesh", "out",
		MFnData::kMesh,
		&returnStatus ); 
	McheckErr(returnStatus, "ERROR creating LSystemNode output attribute\n");
	typedAttr.setStorable(false);

	LSystemNode::angle = angleNumAttr.create( "angle", "a",
		MFnNumericData::kDouble, 90.0 );
	McheckErr(returnStatus, "ERROR creating LSystemNode angle attribute\n");

	LSystemNode::steps = stepNumAttr.create( "steps", "s",
		MFnNumericData::kDouble, 1.0 );
	McheckErr(returnStatus, "ERROR creating LSystemNode step size attribute\n");

	LSystemNode::grammar = grammarTypedAttr.create( "grammar", "g",
		MFnData::kString, &returnStatus );
	McheckErr(returnStatus, "ERROR creating LSystemNode grammar attribute\n");
	grammarTypedAttr.setStorable(false);


	returnStatus = addAttribute(LSystemNode::time);
	McheckErr(returnStatus, "ERROR adding time attribute\n");

	returnStatus = addAttribute(LSystemNode::outputMesh);
	McheckErr(returnStatus, "ERROR adding outputMesh attribute\n");

	returnStatus = addAttribute(LSystemNode::angle);
	McheckErr(returnStatus, "ERROR adding angle attribute\n");

	returnStatus = addAttribute(LSystemNode::steps);
	McheckErr(returnStatus, "ERROR adding steps attribute\n");

	returnStatus = addAttribute(LSystemNode::grammar);
	McheckErr(returnStatus, "ERROR adding grammar attribute\n");



	returnStatus = attributeAffects(LSystemNode::time,
		LSystemNode::outputMesh);
	returnStatus = attributeAffects(LSystemNode::angle,
		LSystemNode::outputMesh);
	returnStatus = attributeAffects(LSystemNode::grammar,
		LSystemNode::outputMesh);
	returnStatus = attributeAffects(LSystemNode::steps,
		LSystemNode::outputMesh);
	McheckErr(returnStatus, "ERROR in attributeAffects\n");

	return MS::kSuccess;
}
Exemplo n.º 25
0
MStatus tm_noisePerlin::initialize()
{
    MStatus status = MS::kSuccess;
    MFnNumericAttribute nAttr;

    amplitude=nAttr.create( "amplitude", "amp", MFnNumericData::kDouble, 1.0, &status );
    McheckErr(status, "Error creating amplitude attribute\n");
//	nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( amplitude);

    frequency=nAttr.create( "frequency", "freq", MFnNumericData::kDouble, 1.0, &status );
    McheckErr(status, "Error creating frequency attribute\n");
//	nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( frequency);

    levels=nAttr.create( "levels", "lev", MFnNumericData::kShort, 2.0, &status );
    McheckErr(status, "Error creating levels attribute\n");
//	nAttr.setDefault(2);
    nAttr.setKeyable(true);
    addAttribute( levels);

    lev_Mamp=nAttr.create( "lev_Mamp", "levma", MFnNumericData::kDouble, 0.25, &status );
    McheckErr(status, "Error creating lev_Mamp attribute\n");
//	nAttr.setDefault(0.25);
    nAttr.setKeyable(true);
    addAttribute( lev_Mamp);

    lev_Mfreq=nAttr.create( "lev_Mfreq", "levmf", MFnNumericData::kDouble );
    nAttr.setDefault(4.0);
    nAttr.setKeyable(true);
    addAttribute( lev_Mfreq);

    scale=nAttr.create( "scale", "sc", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scale);

    scaleAmpX=nAttr.create( "scaleAmpX", "sx", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scaleAmpX);

    scaleAmpY=nAttr.create( "scaleAmpY", "sy", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scaleAmpY);

    scaleAmpZ=nAttr.create( "scaleAmpZ", "sz", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scaleAmpZ);

    scaleFreqX=nAttr.create( "scaleFreqX", "sfx", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scaleFreqX);

    scaleFreqY=nAttr.create( "scaleFreqY", "sfy", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scaleFreqY);

    scaleFreqZ=nAttr.create( "scaleFreqZ", "sfz", MFnNumericData::kDouble );
    nAttr.setDefault(1.0);
    nAttr.setKeyable(true);
    addAttribute( scaleFreqZ);

    variation=nAttr.create( "variation", "var", MFnNumericData::kDouble );
    nAttr.setDefault(0.0);
    nAttr.setKeyable(true);
    addAttribute( variation);

    attributeAffects( tm_noisePerlin::amplitude, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::frequency, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::levels, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::lev_Mamp, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::lev_Mfreq, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scale, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scaleAmpX, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scaleAmpY, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scaleAmpZ, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scaleFreqX, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scaleFreqY, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::scaleFreqZ, tm_noisePerlin::outputGeom );
    attributeAffects( tm_noisePerlin::variation, tm_noisePerlin::outputGeom );

    return MS::kSuccess;
}
Exemplo n.º 26
0
MStatus buildRotation::compute( const MPlug& plug, MDataBlock& data )
{
	
	MStatus returnStatus;
 
	if ((plug == rotate) || (plug.parent() == rotate) || (plug == rotateMatrix)) {
		MDataHandle upData = data.inputValue( up, &returnStatus );
		McheckErr(returnStatus,"ERROR getting up vector data");

		MDataHandle forwardData = data.inputValue( forward, &returnStatus );
		McheckErr(returnStatus,"ERROR getting forward vector data");

		MVector up = upData.asVector();
		MVector forward = forwardData.asVector();

		// Make sure that the up and forward vectors are orthogonal
		//
		if ( fabs( up * forward ) > EPSILON ) {
			// Non-zero dot product
			//
			MVector orthoVec = up ^ forward;
			MVector newForward = orthoVec ^ up;
			if ( forward * newForward < 0.0 ) {
				// Reverse the vector
				//
				newForward *= -1.0;
			}
			forward = newForward;
		}

		// Calculate the rotation required to align the y-axis with the up
		// vector
		//
		MTransformationMatrix firstRot;
		MVector rotAxis = MVector::yAxis ^ up;
		rotAxis.normalize();
		firstRot.setToRotationAxis( rotAxis, MVector::yAxis.angle( up ) );
		
		// Calculate the second rotation required to align the forward vector
		//
		MTransformationMatrix secondRot;
		MVector transformedForward = firstRot.asMatrix() * forward;
		transformedForward.normalize();
		double angle = transformedForward.angle( MVector::zAxis );
		if ( transformedForward.x < 0.0 ) {
			// Compensate for the fact that the angle method returns
			// the absolute value
			//
			angle *= -1.0;
		}
		secondRot.setToRotationAxis( up, angle );

		// Get the requested rotation order
		//
		MDataHandle orderHandle = data.inputValue( rotateOrder );
		short order = orderHandle.asShort();
		MTransformationMatrix::RotationOrder rotOrder;
		switch ( order ) {
			case ROTATE_ORDER_XYZ:
				rotOrder = MTransformationMatrix::kXYZ; break;
			case ROTATE_ORDER_YZX:
				rotOrder = MTransformationMatrix::kYZX; break;
			case ROTATE_ORDER_ZXY:
				rotOrder = MTransformationMatrix::kZXY; break;
			case ROTATE_ORDER_XZY:
				rotOrder = MTransformationMatrix::kXZY; break;
			case ROTATE_ORDER_YXZ:
				rotOrder = MTransformationMatrix::kYXZ; break;
			case ROTATE_ORDER_ZYX:
				rotOrder = MTransformationMatrix::kZYX; break;
			default:
				rotOrder = MTransformationMatrix::kInvalid; break;
		}

		MTransformationMatrix result = firstRot.asMatrix() * secondRot.asMatrix();
		result.reorderRotation( rotOrder );

		double rotation[3];
		result.getRotation( rotation, rotOrder, MSpace::kTransform );
		
		MDataHandle outputRot = data.outputValue( rotate );
		outputRot.set( rotation[0], rotation[1], rotation[2] );
		outputRot.setClean();

		MDataHandle outputMatrix = data.outputValue( rotateMatrix );
		outputMatrix.set( result.asMatrix() );
		outputMatrix.setClean();
	} else
		return MS::kUnknownParameter;

	return MS::kSuccess;
}