コード例 #1
0
//standard attributes
void nailConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
{
   // std::cout << "nailConstraintNode::computeConstraint" << std::endl;

    MObject thisObject(thisMObject());
    MPlug plgRigidBody(thisObject, ia_rigidBody);
    MObject update;
    //force evaluation of the rigidBody
    plgRigidBody.getValue(update);

    rigid_body_t::pointer  rigid_body;
    if(plgRigidBody.isConnected()) {
        MPlugArray connections;
        plgRigidBody.connectedTo(connections, true, true);
        if(connections.length() != 0) {
            MFnDependencyNode fnNode(connections[0].node());
            if(fnNode.typeId() == rigidBodyNode::typeId) {
                rigidBodyNode *pRigidBodyNode = static_cast<rigidBodyNode*>(fnNode.userNode());
                rigid_body = pRigidBodyNode->rigid_body();    
            } else {
                std::cout << "nailConstraintNode connected to a non-rigidbody node!" << std::endl;
            }
        }
    }

    if(rigid_body) {
        //not connected to a rigid body, put a default one
        constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::remove_constraint(constraint);
        m_constraint = solver_t::create_nail_constraint(rigid_body);
        constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::add_constraint(constraint);
    }

    data.outputValue(ca_constraint).set(true);
    data.setClean(plug);
}
コード例 #2
0
ファイル: fullLoftNode.cpp プロジェクト: BigRoy/Maya-devkit
MStatus fullLoft::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus stat;

	if ( plug == outputSurface )	// loft inputCurves into surface
	{
		MArrayDataHandle inputArrayData = data.inputArrayValue( inputCurve,
																&stat );
		PERRORfail("fullLoft::compute getting input array data");
		MDataHandle surfHandle = data.outputValue( fullLoft::outputSurface );
		PERRORfail("fullLoft::compute getting output data handle");
		
		MFnNurbsSurfaceData dataCreator;
		MObject newSurfData = dataCreator.create( &stat );
		PERRORfail("fullLoft::compute creating new nurbs surface data block");
		
		/* MObject newSurf = */ loft(inputArrayData, newSurfData,  stat );
		// No error message is needed - fullLoft::loft will output one
		if (!stat)
			return stat;
		
		// newSurf is the new surface object, but it has been packed
		// into the datablock we created for it, and the data block
		// is what we must put onto the plug.
		stat = surfHandle.set( newSurfData );
		PERRORfail("fullLoft::compute setting surface handle");
		
		stat = data.setClean( plug );
		PERRORfail("fullLoft::compute cleaning outputSurface plug");
	}
	else
	{
		return MS::kUnknownParameter;
	}
	
	return MS::kSuccess;
}
コード例 #3
0
ファイル: octreeVizNode.cpp プロジェクト: saggita/makoto
MStatus octreeVizNode::compute( const MPlug& plug, MDataBlock& data )
{ 
	MStatus status;
	if(plug == aoutput) {
		double time = data.inputValue(acurrenttime).asTime().value();
		int frame_lo = time + 0.005;
		if(frame_lo < 3) frame_lo = 3;
		
		if(frame_lo >60) frame_lo = 60;
		
		MString sname = data.inputValue(aHDRName).asString();
		sname = "/Users/jianzhang/Documents/maya/projects/default/data/untitled";
		char filename[512];
		sprintf( filename, "%s.%d.pmap", sname.asChar(), frame_lo );
		
		sname = filename;	
		
		MGlobal::displayInfo(sname);
		if(sname != m_gridname)	{
			m_gridname = sname;
			if(m_pTex) delete m_pTex;
			
			m_pTex = new Z3DTexture;
			if(m_pTex->load(m_gridname.asChar())) {
				
				zDisplayFloat(m_pTex->getNumGrid());
				zDisplayFloat(m_pTex->getNumVoxel());
				zDisplayFloat(m_pTex->getMaxLevel());
				
				m_pTex->setDraw();
			}
		}
		data.setClean(plug);
	}
	return MS::kUnknownParameter;
}
コード例 #4
0
ファイル: sineNode.cpp プロジェクト: renc/coding_exercises
MStatus sine::compute( const MPlug& plug, MDataBlock& data )
{
	
	MStatus returnStatus;
 
	if( plug == output )
	{
		MDataHandle inputData = data.inputValue( input, &returnStatus );

		if( returnStatus != MS::kSuccess )
			cerr << "ERROR getting data" << endl;
		else
		{
			float result = sinf( inputData.asFloat() ) * 10.0f;
			MDataHandle outputHandle = data.outputValue( sine::output );
			outputHandle.set( result );
			data.setClean(plug);
		}
	} else {
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
コード例 #5
0
//standard attributes
void sixdofConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
{
   // std::cout << "sixdofConstraintNode::computeConstraint" << std::endl;

    MObject thisObject(thisMObject());
    MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
    MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
    MObject update;
    //force evaluation of the rigidBody
    plgRigidBodyA.getValue(update);
    plgRigidBodyB.getValue(update);

    rigid_body_t::pointer  rigid_bodyA;
    if(plgRigidBodyA.isConnected()) {
        MPlugArray connections;
        plgRigidBodyA.connectedTo(connections, true, true);
        if(connections.length() != 0) {
            MFnDependencyNode fnNodeA(connections[0].node());
            if(fnNodeA.typeId() == boingRBNode::typeId) {
                boingRBNode *pRigidBodyNodeA = static_cast<boingRBNode*>(fnNodeA.userNode());
                rigid_bodyA = pRigidBodyNodeA->rigid_body();    
            } else {
                std::cout << "sixdofConstraintNode connected to a non-rigidbody node!" << std::endl;
            }
        }
    }

    rigid_body_t::pointer  rigid_bodyB;
        if(plgRigidBodyB.isConnected()) {
        MPlugArray connections;
        plgRigidBodyB.connectedTo(connections, true, true);
        if(connections.length() != 0) {
            MFnDependencyNode fnNodeB(connections[0].node());
            if(fnNodeB.typeId() == boingRBNode::typeId) {
                boingRBNode *pRigidBodyNodeB = static_cast<boingRBNode*>(fnNodeB.userNode());
                rigid_bodyB = pRigidBodyNodeB->rigid_body();    
            } else {
                std::cout << "sixdofConstraintNode connected to a non-rigidbody node!" << std::endl;
            }
        }
    }

        vec3f pivInA, pivInB;

        if((rigid_bodyA != NULL) && (rigid_bodyB != NULL))
        {
        constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::remove_constraint(constraint);
                float3& mPivInA = data.inputValue(ia_pivotInA).asFloat3();
                float3& mPivInB = data.inputValue(ia_pivotInB).asFloat3();
                for(int i = 0; i < 3; i++)
                {
                        pivInA[i] = (float)mPivInA[i];
                        pivInB[i] = (float)mPivInB[i];
                }
                float3& mRotInA = data.inputValue(ia_rotationInA).asFloat3();
        MEulerRotation meulerA(deg2rad(mRotInA[0]), deg2rad(mRotInA[1]), deg2rad(mRotInA[2]));
        MQuaternion mquatA = meulerA.asQuaternion();
                quatf rotA((float)mquatA.w, (float)mquatA.x, (float)mquatA.y, (float)mquatA.z);
                float3& mRotInB = data.inputValue(ia_rotationInB).asFloat3();
        MEulerRotation meulerB(deg2rad(mRotInB[0]), deg2rad(mRotInB[1]), deg2rad(mRotInB[2]));
        MQuaternion mquatB = meulerB.asQuaternion();
                quatf rotB((float)mquatB.w, (float)mquatB.x, (float)mquatB.y, (float)mquatB.z);
        m_constraint = solver_t::create_sixdof_constraint(rigid_bodyA, pivInA, rotA, rigid_bodyB, pivInB, rotB);
        constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::add_constraint(constraint, data.inputValue(ia_disableCollide).asBool());
        }
    else if(rigid_bodyA != NULL) 
        {
        //not connected to a rigid body, put a default one
        constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::remove_constraint(constraint);
                float3& mPivInA = data.inputValue(ia_pivotInA).asFloat3();
                for(int i = 0; i < 3; i++)
                {
                        pivInA[i] = (float)mPivInA[i];
                }
                float3& mRotInA = data.inputValue(ia_rotationInA).asFloat3();
        MEulerRotation meuler(deg2rad(mRotInA[0]), deg2rad(mRotInA[1]), deg2rad(mRotInA[2]));
        MQuaternion mquat = meuler.asQuaternion();
                quatf rotA((float)mquat.w, (float)mquat.x, (float)mquat.y, (float)mquat.z);
        m_constraint = solver_t::create_sixdof_constraint(rigid_bodyA, pivInA, rotA);
        constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::add_constraint(constraint, data.inputValue(ia_disableCollide).asBool());
    }


	if (m_constraint)
	{
		m_constraint->get_local_frameA(m_PivInA, m_RotInA);
		m_constraint->get_local_frameB(m_PivInB, m_RotInB);
	}
    data.outputValue(ca_constraint).set(true);
    data.setClean(plug);
}
コード例 #6
0
//standard attributes
void sixdofConstraintNode::reComputeConstraint(const MPlug& plug, MDataBlock& data1)
{
	if (!m_initialized)
		return;
		
   // std::cout << "sixdofConstraintNode::computeConstraint" << std::endl;

	m_disableCollision = data1.inputValue(ia_disableCollide).asBool();


    MObject thisObject(thisMObject());
    MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
    MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
    MObject update;
    //force evaluation of the rigidBody
    plgRigidBodyA.getValue(update);
    plgRigidBodyB.getValue(update);

    rigid_body_t::pointer  rigid_bodyA;
    if(plgRigidBodyA.isConnected()) {
        MPlugArray connections;
        plgRigidBodyA.connectedTo(connections, true, true);
        if(connections.length() != 0) {
            MFnDependencyNode fnNodeA(connections[0].node());
            if(fnNodeA.typeId() == boingRBNode::typeId) {
                boingRBNode *pRigidBodyNodeA = static_cast<boingRBNode*>(fnNodeA.userNode());
                rigid_bodyA = pRigidBodyNodeA->rigid_body();    
            } else {
                std::cout << "sixdofConstraintNode connected to a non-rigidbody node!" << std::endl;
            }
        }
    }

    rigid_body_t::pointer  rigid_bodyB;
	if(plgRigidBodyB.isConnected()) {
        MPlugArray connections;
        plgRigidBodyB.connectedTo(connections, true, true);
        if(connections.length() != 0) {
            MFnDependencyNode fnNodeB(connections[0].node());
            if(fnNodeB.typeId() == boingRBNode::typeId) {
                boingRBNode *pRigidBodyNodeB = static_cast<boingRBNode*>(fnNodeB.userNode());
                rigid_bodyB = pRigidBodyNodeB->rigid_body();    
            } else {
                std::cout << "sixdofConstraintNode connected to a non-rigidbody node!" << std::endl;
            }
        }
    }


	if((rigid_bodyA != NULL) && (rigid_bodyB != NULL))
	{
        constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
		bt_sixdof_constraint_t* sixdof_impl = dynamic_cast<bt_sixdof_constraint_t*>(constraint->pubImpl());
		rigid_bodyA->remove_constraint(sixdof_impl);
		rigid_bodyB->remove_constraint(sixdof_impl);
        solver_t::remove_constraint(constraint);
		
		 m_constraint = solver_t::create_sixdof_constraint(rigid_bodyA, m_PivInA, m_RotInA, rigid_bodyB, m_PivInB, m_RotInB);
        constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::add_constraint(constraint, m_disableCollision);
	}
    else if(rigid_bodyA != NULL) 
	{
        //not connected to a rigid body, put a default one
        constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
		bt_sixdof_constraint_t* sixdof_impl = dynamic_cast<bt_sixdof_constraint_t*>(constraint->pubImpl());
		rigid_bodyA->remove_constraint(sixdof_impl);
		solver_t::remove_constraint(constraint);
		
         m_constraint = solver_t::create_sixdof_constraint(rigid_bodyA, m_PivInB, m_RotInB);
        constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::add_constraint(constraint, m_disableCollision);
    }else if(rigid_bodyB != NULL) 
	{
        //not connected to a rigid body, put a default one
        constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
		bt_sixdof_constraint_t* sixdof_impl = dynamic_cast<bt_sixdof_constraint_t*>(constraint->pubImpl());
		rigid_bodyB->remove_constraint(sixdof_impl);
		solver_t::remove_constraint(constraint);
		
         m_constraint = solver_t::create_sixdof_constraint(rigid_bodyB, m_PivInA, m_RotInA);
        constraint = static_cast<constraint_t::pointer>(m_constraint);
        solver_t::add_constraint(constraint, m_disableCollision);
    }



	float val = 0.f;
	MPlug(thisObject, sixdofConstraintNode::ia_damping).getValue(val);
	m_constraint->set_damping(val);

	MPlug(thisObject, sixdofConstraintNode::ia_breakThreshold).getValue(val);
	m_constraint->set_breakThreshold(val);

	vec3f lowLin, uppLin, lowAng, uppAng;

	for (int i=0;i<3;i++)
	{
		lowLin[i] = 0.f;
		uppLin[i] = 0.f;
		lowAng[i] = 0.f;
		uppAng[i] = 0.f;
	}

	{
		MPlug ll(thisObject, sixdofConstraintNode::ia_lowerLinLimit);
		if (ll.isCompound())
		{
			for (int i=0;i<3;i++)
			{
				ll.child(i).getValue(lowLin[i]);
			}
		}
	}
	{
		MPlug ul(thisObject, sixdofConstraintNode::ia_upperLinLimit);
		if (ul.isCompound())
		{
			for (int i=0;i<3;i++)
			{
				ul.child(i).getValue(uppLin[i]);
			}
		}
	}
	{
		MPlug all(thisObject, sixdofConstraintNode::ia_lowerAngLimit);
		if (all.isCompound())
		{
			for (int i=0;i<3;i++)
			{
				float f;
				all.child(i).getValue(f);
				lowAng[i] = deg2rad(f);
			}
		}
	}
	{
		MPlug aul(thisObject, sixdofConstraintNode::ia_upperAngLimit);
		if (aul.isCompound())
		{
			for (int i=0;i<3;i++)
			{
				float f;
				aul.child(i).getValue(f);
				uppAng[i] = deg2rad(f);
			}
		}

	}
	m_constraint->set_LinLimit(lowLin, uppLin);
	m_constraint->set_AngLimit(lowAng, uppAng);

    data1.outputValue(ca_constraint).set(true);
    data1.setClean(plug);
}
コード例 #7
0
ファイル: HesMeshNode.cpp プロジェクト: spinos/aphid
MStatus HesMeshNode::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus stat;
	
	MPlug pnames(thisMObject(), ameshname);
	const unsigned numMeshes = pnames.numElements();
    
	MString cacheName =  data.inputValue( input ).asString();
	std::string substitutedCacheName(cacheName.asChar());
	EnvVar::replace(substitutedCacheName);
	
	MArrayDataHandle meshNameArray = data.inputArrayValue( ameshname );
	MArrayDataHandle meshArry = data.outputArrayValue(outMesh, &stat);
	
    bool hesStat = false;
	if( plug.array() == outMesh ) {
		const unsigned idx = plug.logicalIndex();
		if(BaseUtil::IsImporting)
            hesStat = true;
        else {
            if(idx == 0) 
                AHelper::Info<std::string>(" hes mesh open file ", substitutedCacheName );
            hesStat = BaseUtil::OpenHes(substitutedCacheName, HDocument::oReadOnly);
        }
		
		if(!hesStat) {
			AHelper::Info<std::string >("hes mesh cannot open file ", substitutedCacheName);
			return MS::kFailure;
		}
        
        meshNameArray.jumpToElement(idx);
		const MString meshName = meshNameArray.inputValue().asString();
		
        if(!BaseUtil::HesDoc->find(meshName.asChar())) {
            AHelper::Info<MString>(" hes cannot find mesh ", meshName );
            return MS::kFailure;
		}
        
		meshArry.jumpToElement(idx);
		MDataHandle hmesh = meshArry.outputValue();

		HPolygonalMesh entryMesh(meshName.asChar() );
        
        APolygonalMesh dataMesh;
		entryMesh.load(&dataMesh);
        entryMesh.close();
        
        MFnMeshData dataCreator;
		MObject outMeshData = dataCreator.create(&stat);
			
		if( !stat ) {
			MGlobal::displayWarning("hes mesh cannot create " + meshName);
			return MS::kFailure;
		}
		
        AHelper::Info<MString>(" hes init mesh ", meshName);
		HesperisPolygonalMeshCreator::create(&dataMesh, outMeshData);

		hmesh.set(outMeshData);
	    
		data.setClean(plug);
		
		if( (idx+1)>=numMeshes ) {
			if(!BaseUtil::IsImporting) {
                AHelper::Info<std::string>(" hes mesh close file ", substitutedCacheName );
				BaseUtil::CloseHes();
			}
		}
	} 
	else {
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
コード例 #8
0
ファイル: retargetLocator.cpp プロジェクト: jonntd/mayadev-1
MStatus  retargetLocator::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

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

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

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

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

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

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

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

		hArrArrow.next();
	}

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

	return MS::kSuccess;
}
コード例 #9
0
void collisionShapeNode::computeCollisionShape(const MPlug& plug, MDataBlock& data)
{
  //  std::cout << "collisionShapeNode::computeCollisionShape" << std::endl;

    MObject thisObject(thisMObject());

    MPlug plgInShape(thisObject, ia_shape);

    MPlug plgType(thisObject, ia_type);
    int type;
    plgType.getValue(type);
    switch(type) {
    case 0:  
        {
        //convex hull
        MPlugArray plgaConnectedTo;
        plgInShape.connectedTo(plgaConnectedTo, true, true);
        if(plgaConnectedTo.length() > 0) {
            MObject node = plgaConnectedTo[0].node();
            if(node.hasFn(MFn::kMesh)) {
                MDagPath dagPath;
                MDagPath::getAPathTo(node, dagPath);
                MFnMesh fnMesh(dagPath);
                MFloatPointArray mpoints;
                MFloatVectorArray mnormals;
                MIntArray mtrianglecounts;
                MIntArray mtrianglevertices;
                fnMesh.getPoints(mpoints, MSpace::kObject);
                fnMesh.getNormals(mnormals, MSpace::kObject);
                fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                std::vector<vec3f> vertices(mpoints.length());
                std::vector<vec3f> normals(mpoints.length());
                std::vector<unsigned int> indices(mtrianglevertices.length());

                for(size_t i = 0; i < vertices.size(); ++i) {
                    vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                    normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                }
                for(size_t i = 0; i < indices.size(); ++i) {
                    indices[i] = mtrianglevertices[i];
                }
                m_collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                                                                       &(indices[0]), indices.size());
            }
        }
        }
        break;
    case 1:
        //mesh
        {
        //convex hull
        MPlugArray plgaConnectedTo;
        plgInShape.connectedTo(plgaConnectedTo, true, true);
        if(plgaConnectedTo.length() > 0) {
            MObject node = plgaConnectedTo[0].node();
            if(node.hasFn(MFn::kMesh)) {
                MDagPath dagPath;
                MDagPath::getAPathTo(node, dagPath);
                MFnMesh fnMesh(dagPath);
                MFloatPointArray mpoints;
                MFloatVectorArray mnormals;
                MIntArray mtrianglecounts;
                MIntArray mtrianglevertices;
                fnMesh.getPoints(mpoints, MSpace::kObject);
                fnMesh.getNormals(mnormals, MSpace::kObject);
                fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                std::vector<vec3f> vertices(mpoints.length());
                std::vector<vec3f> normals(mpoints.length());
                std::vector<unsigned int> indices(mtrianglevertices.length());

                for(size_t i = 0; i < vertices.size(); ++i) {
                    vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                    normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                }
                for(size_t i = 0; i < indices.size(); ++i) {
                    indices[i] = mtrianglevertices[i];
                }
                m_collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                                                                &(indices[0]), indices.size());
            }
        }
        }
        break;
    case 2:
        //cylinder
        break;
    case 3:
        //capsule
        break;
    case 4:
        //box
        m_collision_shape = solver_t::create_box_shape();
        break;
    case 5:
        //sphere
        m_collision_shape = solver_t::create_sphere_shape();
        break;
    case 6:
        //plane
        m_collision_shape = solver_t::create_plane_shape();
        break;
    }

    assert(m_collision_shape);

    data.setClean(plug);
}
コード例 #10
0
ファイル: dynExprField.cpp プロジェクト: BigRoy/Maya-devkit
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 );
}
コード例 #11
0
ファイル: ProxyVizNode.cpp プロジェクト: spinos/aphid
MStatus ProxyViz::compute( const MPlug& plug, MDataBlock& block )
{
	if(!m_enableCompute) return MS::kSuccess;
	if( plug == outValue ) {
		
		updateWorldSpace(thisMObject() );
		
		MStatus status;

		ExampVox * defBox = plantExample(0);
		
		defBox->setGeomSizeMult(block.inputValue(aradiusMult).asFloat() );
		
		defBox->setGeomBox(block.inputValue(abboxminx).asFloat(),
			block.inputValue(abboxminy).asFloat(), 
			block.inputValue(abboxminz).asFloat(), 
			block.inputValue(abboxmaxx).asFloat(), 
			block.inputValue(abboxmaxy).asFloat(), 
			block.inputValue(abboxmaxz).asFloat());
		
		float grdsz = defBox->geomExtent() * 32.f ;
		if(grdsz < 32.f) {
			AHelper::Info<float>(" ProxyViz input box is too small", grdsz);
			grdsz = 32.f;
			AHelper::Info<float>(" trancated to", grdsz);
		}
		
		if(m_toSetGrid) {
			m_toSetGrid = false;
			resetGrid(grdsz);
		}
		
		if(_firstLoad) {
/// internal cache only, initializing from external cache is obsolete 
			if(!loadInternal(block) )
				std::cout<<"\n ERROR proxviz cannot load internal cache";

			_firstLoad = 0;
		}
        
		if(!m_toCheckVisibility) {
			MArrayDataHandle groundMeshArray = block.inputArrayValue(agroundMesh );
			MArrayDataHandle groundSpaceArray = block.inputArrayValue(agroundSpace );
/// in case no ground is connected
            if(updateGround(groundMeshArray, groundSpaceArray )) {
                moveWithGround();
                AHelper::Info<std::string>(" ProxyViz ground ", groundBuildLog() );
            }
		}
		
		if(!m_hasParticle) {
			block.setClean(plug);
            return MS::kSuccess;
		}
		
		const int ngroups = block.inputValue(agroupcount).asInt();
		
		MDataHandle hdata = block.inputValue(outPositionPP, &status);
        MFnVectorArrayData farray(hdata.data(), &status);
        if(!status) {
            MGlobal::displayInfo("proxy viz is not properly connected to a particle system");
			block.setClean(plug);
            return MS::kSuccess;
        }
    
        MDataHandle scaledata = block.inputValue(outScalePP, &status);
        MFnVectorArrayData scalearray(scaledata.data(), &status);
        if(!status) {
            MGlobal::displayInfo("proxy viz is not properly connected to a particle system");
			block.setClean(plug);
            return MS::kSuccess;
        }
		
		MDataHandle rotatedata = block.inputValue(outRotationPP, &status);
        MFnVectorArrayData rotatearray(rotatedata.data(), &status);
        if(!status) {
            MGlobal::displayInfo("proxy viz is not properly connected to a particle system");
			block.setClean(plug);
            return MS::kSuccess;
        }
		
		MDataHandle replaceData = block.inputValue(outReplacePP, &status);
        MFnDoubleArrayData replaceArrayFn(replaceData.data(), &status);
        if(!status) {
            MGlobal::displayInfo("proxy viz is not properly connected to a particle system, needs userScalarPP");
			block.setClean(plug);
            return MS::kSuccess;
        }
		
		MVectorArray outPosArray = farray.array();	
        MVectorArray outScaleArray = scalearray.array();
		MVectorArray outRotateArray = rotatearray.array();
		MDoubleArray outReplaceArray = replaceArrayFn.array();
		
		if( outPosArray.length() < 1) {
			block.setClean(plug);
			return MS::kSuccess;
		}
		
		computePPAttribs(outPosArray, outRotateArray, outScaleArray, outReplaceArray,
						ngroups);

        float result = outPosArray.length();

		MDataHandle outputHandle = block.outputValue( outValue );
		outputHandle.set( result );
		block.setClean(plug);
    }
	if(plug == outValue1) {
		
		MArrayDataHandle hArray = block.inputArrayValue(ainexamp);
		updateExamples(hArray);

		float result = 91.f;

		MDataHandle outputHandle = block.outputValue( outValue1 );
		outputHandle.set( result );
		block.setClean(plug);
	}

	return MS::kSuccess;
}
コード例 #12
0
MStatus   clusterControledCurve::compute( const MPlug& plug, MDataBlock& data )
{
	//MFnDependencyNode thisNode( thisMObject() );
	//cout << thisNode.name() << ", start" << endl;

	MStatus status;

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

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

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

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

	MObject oInputCurve = hInputCurve.asNurbsCurve();

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

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

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

	MPointArray inputCvPoints;
	MPointArray outputCvPoints;

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

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

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

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

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

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

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

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

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

	fnInputCurve.copy( oInputCurve, oOutputCurve );

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

	hOutputCurve.set( oOutputCurve );

	data.setClean( plug );

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

	return status;
}
コード例 #13
0
MStatus anisotropicShaderNode::compute( const MPlug& plug, MDataBlock& block )
{
    if ((plug == aOutColor) || (plug.parent() == aOutColor))
	{
        MFloatVector resultColor(0.0,0.0,0.0);
        MFloatVector diffuseColor( 0.0,0.0,0.0 );
        MFloatVector specularColor( 0.0,0.0,0.0 );
        MFloatVector ambientColor( 0.0,0.0,0.0 );

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


                    // Beckmann function

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return MS::kSuccess;
}
コード例 #14
0
MStatus sgHair_controlJoint::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

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

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

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

	setOutput();

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

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

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

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

	data.setClean( plug );

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

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

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

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

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

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

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

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

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

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

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

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

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

    return status;
}
コード例 #16
0
ファイル: LSsystemNode.cpp プロジェクト: sibiv/Atomos_mymaya
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;
}
コード例 #17
0
void sixdofConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
{
    MObject thisObject(thisMObject());
    MFnDagNode fnDagNode(thisObject);

    MObject update;
    MPlug(thisObject, ca_constraint).getValue(update);
    MPlug(thisObject, ca_constraintParam).getValue(update);

    MStatus status;
    MFnTransform fnParentTransform(fnDagNode.parent(0, &status));
	double fixScale[3] = { 1., 1., 1. };  // lock scale
	fnParentTransform.setScale(fixScale);
    MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status);

	if(bSolverNode::isStartTime)
	{	// allow to edit pivots
		MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
		MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
		MObject update;
		//force evaluation of the rigidBody
		plgRigidBodyA.getValue(update);
		if(plgRigidBodyA.isConnected()) 
		{
			MPlugArray connections;
			plgRigidBodyA.connectedTo(connections, true, true);
			if(connections.length() != 0) 
			{
				MFnDependencyNode fnNode(connections[0].node());
				if(fnNode.typeId() == boingRBNode::typeId) 
				{
					MObject rbAObj = fnNode.object();
					boingRBNode *pRigidBodyNodeA = static_cast<boingRBNode*>(fnNode.userNode());
					MPlug(rbAObj, pRigidBodyNodeA->worldMatrix).elementByLogicalIndex(0).getValue(update);
				}
			}
		}
		plgRigidBodyB.getValue(update);
		if(plgRigidBodyB.isConnected()) 
		{
			MPlugArray connections;
			plgRigidBodyB.connectedTo(connections, true, true);
			if(connections.length() != 0) 
			{
	            MFnDependencyNode fnNode(connections[0].node());
				if(fnNode.typeId() == boingRBNode::typeId) 
				{
					MObject rbBObj = fnNode.object();
					boingRBNode *pRigidBodyNodeB = static_cast<boingRBNode*>(fnNode.userNode());
					MPlug(rbBObj, pRigidBodyNodeB->worldMatrix).elementByLogicalIndex(0).getValue(update);
				}
			}
		}
		if(m_constraint) 
		{
			MQuaternion mrotation;
			fnParentTransform.getRotation(mrotation, MSpace::kTransform);
			bool doUpdatePivot = m_constraint->getPivotChanged();
			if(!doUpdatePivot)
			{
				vec3f worldP;
				quatf worldR;
				m_constraint->get_world(worldP, worldR);
				float deltaPX = worldP[0] - float(mtranslation.x);
				float deltaPY = worldP[1] - float(mtranslation.y);
				float deltaPZ = worldP[2] - float(mtranslation.z);
				float deltaRX = (float)mrotation.x - worldR[1];
				float deltaRY = (float)mrotation.y - worldR[2];
				float deltaRZ = (float)mrotation.z - worldR[3];
				float deltaRW = (float)mrotation.w - worldR[0];
				float deltaSq = deltaPX * deltaPX + deltaPY * deltaPY  + deltaPZ * deltaPZ 
								+ deltaRX * deltaRX + deltaRY * deltaRY + deltaRZ * deltaRZ + deltaRW * deltaRW;
				doUpdatePivot = (deltaSq > FLT_EPSILON);
			}
			if(doUpdatePivot)
			{
				m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2]),
										quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z));
				vec3f pivInA, pivInB;
				quatf rotInA, rotInB;
				m_constraint->get_frameA(pivInA, rotInA);
				m_constraint->get_frameB(pivInB, rotInB);
				MDataHandle hPivInA = data.outputValue(ia_pivotInA);
				float3 &ihPivInA = hPivInA.asFloat3();
				MDataHandle hPivInB = data.outputValue(ia_pivotInB);
				float3 &ihPivInB = hPivInB.asFloat3();
				for(int i = 0; i < 3; i++) 
				{ 
					ihPivInA[i]  = pivInA[i]; 
					ihPivInB[i]  = pivInB[i]; 
				}
				MDataHandle hRotInA = data.outputValue(ia_rotationInA);
				float3 &hrotInA = hRotInA.asFloat3();
				MQuaternion mrotA(rotInA[1], rotInA[2], rotInA[3], rotInA[0]);
				MEulerRotation newrotA(mrotA.asEulerRotation());
				hrotInA[0] = rad2deg((float)newrotA.x);
				hrotInA[1] = rad2deg((float)newrotA.y);
				hrotInA[2] = rad2deg((float)newrotA.z);
				MDataHandle hRotInB = data.outputValue(ia_rotationInB);
				float3 &hrotInB = hRotInB.asFloat3();
				MQuaternion mrotB(rotInB[1], rotInB[2], rotInB[3], rotInB[0]);
				MEulerRotation newrotB(mrotB.asEulerRotation());
				hrotInB[0] = rad2deg((float)newrotB.x);
				hrotInB[1] = rad2deg((float)newrotB.y);
				hrotInB[2] = rad2deg((float)newrotB.z);
				m_constraint->setPivotChanged(false);

				m_constraint->get_local_frameA(m_PivInA, m_RotInA);
				m_constraint->get_local_frameB(m_PivInB, m_RotInB);
			}
		}
	}
	else
	{ // if not start time, lock position and rotation
		if(m_constraint) 
		{
			vec3f worldP;
			quatf worldR;
			m_constraint->get_world(worldP, worldR);
            fnParentTransform.setTranslation(MVector(worldP[0], worldP[1], worldP[2]), MSpace::kTransform);
			fnParentTransform.setRotation(MQuaternion(worldR[1], worldR[2], worldR[3], worldR[0])); 
		}
	}
	
	m_initialized = true;
    data.setClean(plug);
}
コード例 #18
0
ファイル: AlembicNode.cpp プロジェクト: matsbtegner/alembic
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock)
{
    MStatus status;

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

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

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

    double fps = getFPS();

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

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

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

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

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

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

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

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

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


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

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

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

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

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

    if (plug == mOutPropArrayAttr)
    {

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

        mOutRead[0] = true;

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

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

            unsigned int outHandleIndex = 0;
            MDataHandle outHandle;

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

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

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

        mOutRead[1] = true;

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

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

            MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

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

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

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

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

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

        mOutRead[8] = true;

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

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

            MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

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

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

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

        mOutRead[2] = true;

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

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

            MDataHandle outHandle;

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

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

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

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

        mOutRead[3] = true;

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

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

            MDataHandle outHandle;

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

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

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

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

        mOutRead[4] = true;

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

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

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

            MDataHandle outHandle;
            unsigned int index = 0;

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

                read(mCurTime, cam, array);

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

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

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

        mOutRead[5] = true;

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

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

            MDataHandle outHandle;

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

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

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

        mOutRead[6] = true;

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

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

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

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

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

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

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

    dataBlock.setClean(plug);
    return status;
}
コード例 #19
0
MStatus DA_GridGenerator::compute(const MPlug &plug, MDataBlock &data)
{
    MStatus stat;
    if (plug != aOutDynamicArray)
        return MS::kFailure;

    //
    // Control Inputs
    //
    double dWidth = data.inputValue(aWidth).asDouble();
    double dHeight = data.inputValue(aHeight).asDouble();

    int iResolutionX = data.inputValue(aResolutionX).asInt();
    int iResolutionY = data.inputValue(aResolutionY).asInt();

    short ePattern = data.inputValue(aPattern).asShort();

    // Create output
    MFnArrayAttrsData fnOutDynamicArray;
    fnOutDynamicArray.create();

    // Create position data
    MVectorArray outPositionPP = fnOutDynamicArray.vectorArray("position");

    //
    // Create grid
    //
    double xOffset = dWidth / ((double)iResolutionX - 1);
    double yOffset = dHeight / ((double)iResolutionY - 1);

    // Keep brick pattern in range
    if (ePattern == 1)
        xOffset -= (xOffset/2) / double(iResolutionX);
    if (ePattern == 2)
        yOffset -= (yOffset/2) / double(iResolutionY);

    // Generate grid
    for(int i = 0; i < iResolutionX; i++)
    {
        for(int j = 0; j < iResolutionY; j++)
        {
            MVector position;
            position.x = -dWidth / 2;
            position.y = 0;
            position.z = -dHeight / 2;

            // Pattern offset
            if (ePattern == 1)
                position.x += (xOffset/2) * double(j % 2);
            if (ePattern == 2)
                position.z += (yOffset/2) * double(i % 2);

            position.x += xOffset * i;
            position.z += yOffset * j;

            outPositionPP.append( position );
        }
    }


    //
    // Set output data
    //
    MDataHandle outArray = data.outputValue(aOutDynamicArray);
    outArray.set(fnOutDynamicArray.object());

    // Set plug to clean
    data.setClean(aOutDynamicArray);

    // Done
    return MS::kSuccess;
}
コード例 #20
0
ファイル: osdPolySmooth.cpp プロジェクト: janba/OpenSubdiv
// ====================================
// Compute
// ====================================
//
//  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 OsdPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {

    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 == a_output ) {
        bool createdSubdMesh = false;

        int subdivisionLevel = data.inputValue(a_subdivisionLevels).asInt();
        short stateH = data.inputValue(state).asShort();

        if ((subdivisionLevel > 0) and (stateH !=1)) {

            // == Retrieve input mesh ====================================
            // Get attr values
            MObject inMeshObj        = data.inputValue(a_inputPolymesh).asMesh();
            short vertBoundaryMethod = data.inputValue(a_vertBoundaryMethod).asShort();
            short fvarBoundaryMethod = data.inputValue(a_fvarBoundaryMethod).asShort();
            bool  fvarPropCorners    = data.inputValue(a_fvarPropagateCorners).asBool();
            bool  smoothTriangles    = data.inputValue(a_smoothTriangles).asBool();
            short creaseMethodVal    = data.inputValue(a_creaseMethod).asShort();

            // Convert attr values to OSD enums
            HMesh::InterpolateBoundaryMethod vertInterpBoundaryMethod =
                ConvertMayaBoundaryMethodShortToOsdInterpolateBoundaryMethod(vertBoundaryMethod);

            HMesh::InterpolateBoundaryMethod fvarInterpBoundaryMethod =
                ConvertMayaBoundaryMethodShortToOsdInterpolateBoundaryMethod(fvarBoundaryMethod);

            HCatmark::CreaseSubdivision creaseMethod =
                (creaseMethodVal == k_creaseMethod_chaikin) ?
                    HCatmark::k_CreaseChaikin : HCatmark::k_CreaseNormal;

            HCatmark::TriangleSubdivision triangleSubdivision =
                smoothTriangles ? HCatmark::k_New : HCatmark::k_Normal;

            // == Get Mesh Functions and Iterators ==========================
            MFnMeshData inMeshDat(inMeshObj);
            MFnMesh inMeshFn(inMeshObj, &returnStatus);
            MCHECKERR(returnStatus, "ERROR getting inMeshFn\n");
            MItMeshPolygon inMeshItPolygon(inMeshObj, &returnStatus);
            MCHECKERR(returnStatus, "ERROR getting inMeshItPolygon\n");

            // == Convert MFnMesh to OpenSubdiv =============================
            // Create the hbrMesh
            // Note: These fvar values only need to be kept alive through the life of the farMesh
            std::vector<int> fvarIndices;
            std::vector<int> fvarWidths;

            HMesh *hbrMesh = createOsdHbrFromPoly(
                inMeshFn, inMeshItPolygon, fvarIndices, fvarWidths);
            assert(hbrMesh);

            // Create the farMesh if successfully created the hbrMesh

            if (hbrMesh) {
                // Set Boundary methods and other hbr paramters
                hbrMesh->SetInterpolateBoundaryMethod( vertInterpBoundaryMethod );
                hbrMesh->SetFVarInterpolateBoundaryMethod( fvarInterpBoundaryMethod );
                hbrMesh->SetFVarPropagateCorners(fvarPropCorners);
                hbrMesh->GetSubdivision()->SetCreaseSubdivisionMethod(creaseMethod);

                // Set HBR Catmark Subdivision parameters
                HCatmark *catmarkSubdivision = dynamic_cast<HCatmark *>(hbrMesh->GetSubdivision());
                if (catmarkSubdivision) {
                    catmarkSubdivision->SetTriangleSubdivisionMethod(triangleSubdivision);
                }

                // Finalize subd calculations -- apply boundary interpolation rules and resolves singular verts, etc.
                // NOTE: This HAS to be called after all HBR parameters are set
                hbrMesh->Finish();

                int ncoarseverts = hbrMesh->GetNumVertices();

                // Create a FarMesh from the HBR mesh and pass into
                // It will be owned by the OsdMesh and deleted in the ~OsdMesh()
                FMeshFactory meshFactory(hbrMesh, subdivisionLevel, false);

                FMesh *farMesh = meshFactory.Create((hbrMesh->GetTotalFVarWidth() > 0));

                // == Setup OSD Data Structures =========================
                int numVertexElements  = 3; // only track vertex positions
                int numVaryingElements = 0; // XXX Future: Revise to include varying ColorSets
                int numVertices = inMeshFn.numVertices();

                int numFarVerts = farMesh->GetNumVertices();

                static OpenSubdiv::OsdCpuComputeController computeController = OpenSubdiv::OsdCpuComputeController();

                OpenSubdiv::OsdCpuComputeController::ComputeContext *computeContext =
                    OpenSubdiv::OsdCpuComputeController::ComputeContext::Create(farMesh);

                OpenSubdiv::OsdCpuVertexBuffer *vertexBuffer =
                    OpenSubdiv::OsdCpuVertexBuffer::Create(numVertexElements, numFarVerts );

                OpenSubdiv::OsdCpuVertexBuffer *varyingBuffer =
                    (numVaryingElements) ? OpenSubdiv::OsdCpuVertexBuffer::Create(numVaryingElements, numFarVerts) : NULL;

                // == UPDATE VERTICES (can be done after farMesh generated from topology) ==
                float const * vertex3fArray = inMeshFn.getRawPoints(&returnStatus);
                vertexBuffer->UpdateData(vertex3fArray, 0, numVertices );

                // Hbr dupes singular vertices during Mesh::Finish() - we need
                // to duplicate their positions in the vertex buffer.
                if (ncoarseverts > numVertices) {

                    MIntArray polyverts;

                    for (int i=numVertices; i<ncoarseverts; ++i) {

                        HVertex const * v = hbrMesh->GetVertex(i);

                        HFace const * f = v->GetIncidentEdge()->GetFace();

                        int vidx = -1;
                        for (int j=0; j<f->GetNumVertices(); ++j) {
                            if (f->GetVertex(j)==v) {
                                vidx = j;
                                break;
                            }
                        }
                        assert(vidx>-1);

                        inMeshFn.getPolygonVertices(f->GetID(), polyverts);

                        int vert = polyverts[vidx];

                        vertexBuffer->UpdateData(&vertex3fArray[0]+vert*numVertexElements, i, 1);
                    }
                }

                // == Delete HBR
                // Can now delete the hbrMesh as we will only be referencing the farMesh from this point on
                delete hbrMesh;
                hbrMesh = NULL;

                // == Subdivide OpenSubdiv mesh ==========================
                computeController.Refine(computeContext, farMesh->GetKernelBatches(), vertexBuffer, varyingBuffer);
                computeController.Synchronize();

                // == Convert subdivided OpenSubdiv mesh to MFnMesh Data outputMesh =============

                // Create New Mesh Data Object
                MFnMeshData newMeshData;
                MObject     newMeshDataObj = newMeshData.create(&returnStatus);
                MCHECKERR(returnStatus, "ERROR creating outputData");

                // Create out mesh
                returnStatus = convertOsdFarToMayaMeshData(farMesh, vertexBuffer, subdivisionLevel, inMeshFn, newMeshDataObj);
                MCHECKERR(returnStatus, "ERROR convertOsdFarToMayaMesh");

                // Propagate objectGroups from inMesh to outMesh (for per-facet shading, etc)
                returnStatus = createSmoothMesh_objectGroups(inMeshDat, subdivisionLevel, newMeshData );

                // Write to output plug
                MDataHandle outMeshH = data.outputValue(a_output, &returnStatus);
                MCHECKERR(returnStatus, "ERROR getting polygon data handle\n");
                outMeshH.set(newMeshDataObj);

                // == Cleanup OSD ============================================
                // REVISIT: Re-add these deletes
                delete(vertexBuffer);
                delete(varyingBuffer);
                delete(computeContext);
                delete(farMesh);

                // note that the subd mesh was created (see the section below if !createdSubdMesh)
                createdSubdMesh = true;
            }
        }

        // Pass-through inMesh to outMesh if not created the subd mesh
        if (!createdSubdMesh) {
            MDataHandle outMeshH = data.outputValue(a_output, &returnStatus);
            returnStatus = outMeshH.copy(data.outputValue(a_inputPolymesh, &returnStatus));
            MCHECKERR(returnStatus, "ERROR getting polygon data handle\n");
        }

        // Clean up Maya Plugs
        data.setClean(plug);
    }
    else {
        // Unhandled parameter in this compute function, so return MS::kUnknownParameter
        // so it is handled in a parent compute() function.
        return MS::kUnknownParameter;
    }
    return MS::kSuccess;
}
コード例 #21
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;
}
コード例 #22
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
			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;
}
コード例 #23
0
ファイル: quatcurve.cpp プロジェクト: jonntd/Public
MStatus n_tentacle::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus returnStatus;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

					MVector outPos, outRot;

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

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

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

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

				}

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

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

		}
		else
		{
			return MS::kUnknownParameter;
		}
	}

	return MS::kSuccess;
}
コード例 #24
0
ファイル: mayaPolySmooth.cpp プロジェクト: AiYong/OpenSubdiv
MStatus
MayaPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {

    MStatus status;

    // 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 == a_output ) {

        bool createdSubdMesh = false;

        int subdivisionLevel = data.inputValue(a_subdivisionLevels).asInt();
        short stateH = data.inputValue(state).asShort();

        if ((subdivisionLevel > 0) and (stateH !=1)) {

            // == Retrieve input mesh ====================================
            // Get attr values
            MObject inMeshObj        = data.inputValue(a_inputPolymesh).asMesh();
            short vertBoundaryMethod = data.inputValue(a_vertBoundaryMethod).asShort();
            short fvarBoundaryMethod = data.inputValue(a_fvarBoundaryMethod).asShort();
            bool  fvarPropCorners    = data.inputValue(a_fvarPropagateCorners).asBool();
            bool  smoothTriangles    = data.inputValue(a_smoothTriangles).asBool();
            short creaseMethodVal    = data.inputValue(a_creaseMethod).asShort();

            // == Get Mesh Functions and Iterators ==========================
            MFnMeshData inMeshDat(inMeshObj);
            MFnMesh inMeshFn(inMeshObj, &status);
            MCHECKERR(status, "ERROR getting inMeshFn\n");
            MItMeshPolygon inMeshItPolygon(inMeshObj, &status);
            MCHECKERR(status, "ERROR getting inMeshItPolygon\n");

            // Convert attr values to OSD enums
            OpenSubdiv::Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK;

            // == Create Far topology ==========================
            OpenSubdiv::Sdc::Options options;
            options.SetVtxBoundaryInterpolation(ConvertMayaVtxBoundary(vertBoundaryMethod));
            options.SetFVarLinearInterpolation(ConvertMayaFVarBoundary(fvarBoundaryMethod, fvarPropCorners));
            options.SetCreasingMethod(creaseMethodVal ?
                 OpenSubdiv::Sdc::Options::CREASE_CHAIKIN : OpenSubdiv::Sdc::Options::CREASE_UNIFORM);
            options.SetTriangleSubdivision(smoothTriangles ?
                 OpenSubdiv::Sdc::Options::TRI_SUB_SMOOTH : OpenSubdiv::Sdc::Options::TRI_SUB_CATMARK);

            // Storage for face-varying values (UV sets, vertex colors...)
            std::vector<MFloatArray> uvSet_uCoords;
            std::vector<MFloatArray> uvSet_vCoords;
            std::vector<MColorArray> colorSet_colors;

            bool hasUVs = false, hasColors = false;
            float maxCreaseSharpness=0.0f;
            OpenSubdiv::Far::TopologyRefiner * refiner = gatherTopology(
                inMeshFn, inMeshItPolygon, type, options, &hasUVs, &hasColors,
                uvSet_uCoords, uvSet_vCoords, colorSet_colors, &maxCreaseSharpness);

            assert(refiner);

            // == Refine & Interpolate ==========================
            refiner->RefineUniform(OpenSubdiv::Far::TopologyRefiner::UniformOptions(subdivisionLevel));

            // Prepare vertex information
            Vertex const * initialVerts = 
                reinterpret_cast<Vertex const *>(inMeshFn.getRawPoints(&status));
            std::vector<Vertex> refinedVerts(
                refiner->GetNumVerticesTotal() - refiner->GetLevel(0).GetNumVertices());
            Vertex const * srcVerts = &initialVerts[0];
            Vertex * dstVerts = &refinedVerts[0];
           
            // Verify the refiner has the correct number of values 
            // needed to interpolate the different channels
            int numInitialUVs = refiner->GetLevel(0).GetNumFVarValues(CHANNELUV);
            int numInitialColors = refiner->GetLevel(0).GetNumFVarValues(CHANNELCOLOR);

            if (hasUVs && numInitialUVs <= 0) {
                hasUVs = false;
                MGlobal::displayError("Model with incorrect data, the UV channel will not be interpolated.");
            }

            if (hasColors && numInitialColors <= 0) {
                hasColors = false;  
                MGlobal::displayError("Model with incorrect data, the color channel will not be interpolated.");
            } 

            // Prepare UV information if needed
            std::vector<FVarVertexUV> initialUVs, refinedUVs;
            FVarVertexUV const * srcUV = NULL;
            FVarVertexUV * dstUV = NULL;
            if(hasUVs) {
                initialUVs.resize(numInitialUVs);
                refinedUVs.resize(refiner->GetNumFVarValuesTotal(CHANNELUV));
                for (int i=0; i<numInitialUVs; ++i) {
                    initialUVs[i].u = uvSet_uCoords[0][i];
                    initialUVs[i].v = uvSet_vCoords[0][i];
                }
                srcUV = &initialUVs[0];
                dstUV = &refinedUVs[0];
            }

            // Prepare color information if needed
            std::vector<FVarVertexColor> initialColors, refinedColors;
            FVarVertexColor const * srcColor = NULL;
            FVarVertexColor * dstColor = NULL;
            if(hasColors) {
                initialColors.resize(numInitialColors);
                refinedColors.resize(refiner->GetNumFVarValuesTotal(CHANNELCOLOR));
                for (int i=0; i<numInitialColors; ++i) {
                    initialColors[i].r = colorSet_colors[0][i].r;
                    initialColors[i].g = colorSet_colors[0][i].g;
                    initialColors[i].b = colorSet_colors[0][i].b;
                    initialColors[i].a = colorSet_colors[0][i].a;
                }
                srcColor = &initialColors[0];
                dstColor = &refinedColors[0];
            }

            // Interpolate the vertices and the different channels
            OpenSubdiv::Far::PrimvarRefiner primvarRefiner(*refiner); 
            
            for (int level = 1; level <= subdivisionLevel; ++level) {
                
                // Interpolate vertices
                primvarRefiner.Interpolate(level, srcVerts, dstVerts);
                srcVerts = dstVerts;
                dstVerts += refiner->GetLevel(level).GetNumVertices();

                // Interpolate the uv set
                if(hasUVs) {
                    primvarRefiner.InterpolateFaceVarying(level, srcUV, dstUV, CHANNELUV);
                    srcUV = dstUV;
                    dstUV += refiner->GetLevel(level).GetNumFVarValues(CHANNELUV);
                }

                // Interpolate any color set
                if(hasColors) {
                    primvarRefiner.InterpolateFaceVarying(level, srcColor, dstColor, CHANNELCOLOR);
                    srcColor = dstColor;
                    dstColor += refiner->GetLevel(level).GetNumFVarValues(CHANNELCOLOR);
                }
            }

            // == Convert subdivided OpenSubdiv mesh to MFnMesh Data outputMesh =============

            // Create New Mesh Data Object
            MFnMeshData newMeshData;
            MObject     newMeshDataObj = newMeshData.create(&status);
            MCHECKERR(status, "ERROR creating outputData");

            // Create out mesh
            status = convertToMayaMeshData(*refiner, refinedVerts, hasUVs, 
                refinedUVs, hasColors, refinedColors, inMeshFn, newMeshDataObj);
            MCHECKERR(status, "ERROR convertOsdFarToMayaMesh");

            // Propagate objectGroups from inMesh to outMesh (for per-facet shading, etc)
            status = createSmoothMesh_objectGroups(inMeshFn, inMeshDat,
                newMeshData, subdivisionLevel, refiner->GetLevel(subdivisionLevel).GetNumFaces());

            // Write to output plug
            MDataHandle outMeshH = data.outputValue(a_output, &status);
            MCHECKERR(status, "ERROR getting polygon data handle\n");
            outMeshH.set(newMeshDataObj);

            int isolation = std::min(10,(int)ceil(maxCreaseSharpness)+1);
            data.outputValue(a_recommendedIsolation).set(isolation);

            // == Cleanup OSD ============================================

            // REVISIT: Re-add these deletes
            delete refiner;

            // note that the subd mesh was created (see the section below if !createdSubdMesh)
            createdSubdMesh = true;
        }

        // Pass-through inMesh to outMesh if not created the subd mesh
        if (!createdSubdMesh) {
            MDataHandle outMeshH = data.outputValue(a_output, &status);
            status = outMeshH.copy(data.outputValue(a_inputPolymesh, &status));
            MCHECKERR(status, "ERROR getting polygon data handle\n");
        }

        // Clean up Maya Plugs
        data.setClean(plug);

    } else {
        // Unhandled parameter in this compute function, so return MS::kUnknownParameter
        // so it is handled in a parent compute() function.
        return MS::kUnknownParameter;
    }
    return MS::kSuccess;
}
コード例 #25
0
ファイル: wingVizNode.cpp プロジェクト: saggita/makoto
MStatus wingVizNode::compute( const MPlug& plug, MDataBlock& data )
{ 
	MStatus status;
	if(plug == aoutval)
	{
		//double dtime = data.inputValue( aframe ).asDouble();
		MTime currentTime = data.inputValue(atime, &status).asTime();
		float ns = data.inputValue(anoisize).asFloat();
		float nf = data.inputValue(anoifreq).asFloat();
		int nd = data.inputValue(anoiseed).asInt();
		
		MObject ogrow = data.inputValue(agrowth).asNurbsSurfaceTransformed();
		//MArrayDataHandle hArray = data.inputArrayValue(agrowth);
		
		//int n_obs = hArray.elementCount();
		//MObjectArray obslist;
		//for(int iter=0; iter<n_obs; iter++)
		//{
		//	obslist.append(hArray.inputValue().asNurbsSurfaceTransformed());
		//	hArray.next();
		//}
		//if(!ogrow.isNull()) m_base->setGrow(ogrow);
		m_base->setNoise(ns, nf, nd);
		m_base->setTime(currentTime.value());
		m_base->setNurbs(ogrow);
		//m_base->setWind(m_wind);
		
		/*int frame = (int)currentTime.value();
		i_show_v = 0;
		if(data.inputValue(amaxframe, &status).asInt() == 1)
		{
			i_show_v = 1;
			char file_name[512];
			sprintf( file_name, "%s/%s.%d.xvn", m_cachename.asChar(), MFnDependencyNode(thisMObject()).name().asChar(), frame );
			int start = data.inputValue(aminframe, &status).asInt();
			if(start == frame) 
			{
				m_frame_pre = start;
				//m_base->init();
				m_base->save(file_name);
			}
			else if(m_frame_pre+1 == frame)
			{
				m_frame_pre++;
				//m_base->update();
				m_base->save(file_name);
			}
		}*/
	}
	
	if(plug== outMesh)
	{
		MObject ogrow = data.inputValue(agrowth).asNurbsSurfaceTransformed();
		m_base->setNurbs(ogrow);
		
		float w0 = data.inputValue(ashaft0).asFloat();
		float w1 = data.inputValue(ashaft1).asFloat();
		
		float fw0 = data.inputValue(awidth0).asFloat();
		float fw1 = data.inputValue(awidth1).asFloat();
		
		float e0 = data.inputValue(aedge0).asFloat();
		float e1 = data.inputValue(aedge1).asFloat();
		
		float t0 = data.inputValue(atwist0).asFloat();
		float t1 = data.inputValue(atwist1).asFloat();
		
		int r = data.inputValue(areverse).asInt();
		int s = data.inputValue(astep).asInt();
		m_base->setReverse(r);
		m_base->setFeatherWidth(fw0, fw1);
		m_base->setFeatherEdge(e0, e1);
		m_base->setShaftWidth(w0, w1);
		m_base->setFeatherTwist(t0, t1);
		m_base->setStep(s);

		MObject outMeshData = m_base->createFeather();
		
		//zDisplayFloat3(m_base->getSeed(), m_base->getSeed1(), m_base->getFract());
		
		MDataHandle meshh = data.outputValue(outMesh, &status);
		meshh.set(outMeshData);
	    
		data.setClean(plug);
	}
	
	if(plug== aouttexcoordoffsetpp)
	{
		MDoubleArray coeff_array;
		
		m_base->getTexcoordOffset(coeff_array);
		
		MFnDoubleArrayData coeffFn;
		MObject coeffOutputData = coeffFn.create( coeff_array, &status );
		MDataHandle coeffh = data.outputValue( plug, &status);
		coeffh.set(coeffOutputData);
	    
		data.setClean(plug);
	}
	return MS::kUnknownParameter;
}
コード例 #26
0
MStatus closestPointOnCurveNode::compute(const MPlug &plug, MDataBlock &data)

{

   // DO THE COMPUTE ONLY FOR THE *OUTPUT* PLUGS THAT ARE DIRTIED:

   if ((plug == aPosition)  || (plug == aPositionX)  || (plug == aPositionY)  || (plug == aPositionZ)

    || (plug == aNormal) || (plug == aNormalX) || (plug == aNormalY) || (plug == aNormalZ)

    || (plug == aTangent) || (plug == aTangentX) || (plug == aTangentY) || (plug == aTangentZ)

	|| (plug == aParamU) || (plug == aDistance))

   {

      // READ IN ".inCurve" DATA:

      MDataHandle inCurveDataHandle = data.inputValue(aInCurve);

      MObject inCurve = inCurveDataHandle.asNurbsCurve();



      // READ IN ".inPositionX" DATA:

      MDataHandle inPositionXDataHandle = data.inputValue(aInPositionX);

      double inPositionX = inPositionXDataHandle.asDouble();



      // READ IN ".inPositionY" DATA:

      MDataHandle inPositionYDataHandle = data.inputValue(aInPositionY);

      double inPositionY = inPositionYDataHandle.asDouble();



      // READ IN ".inPositionZ" DATA:

      MDataHandle inPositionZDataHandle = data.inputValue(aInPositionZ);

      double inPositionZ = inPositionZDataHandle.asDouble();



      // GET THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE:

      MPoint inPosition(inPositionX, inPositionY, inPositionZ), position;

      MVector normal, tangent;

      double paramU, distance;

      MDagPath dummyDagPath;

      closestTangentUAndDistance(dummyDagPath, inPosition, position, normal, tangent, paramU, distance, inCurve);



      // WRITE OUT ".position" DATA:

      MDataHandle positionDataHandle = data.outputValue(aPosition);

      positionDataHandle.set(position.x, position.y, position.z);

      data.setClean(plug);



      // WRITE OUT ".normal" DATA:

      MDataHandle normalDataHandle = data.outputValue(aNormal);

      normalDataHandle.set(normal.x, normal.y, normal.z);

      data.setClean(plug);



      // WRITE OUT ".tangent" DATA:

      MDataHandle tangentDataHandle = data.outputValue(aTangent);

      tangentDataHandle.set(tangent.x, tangent.y, tangent.z);

      data.setClean(plug);



      // WRITE OUT ".paramU" DATA:

      MDataHandle paramUDataHandle = data.outputValue(aParamU);

      paramUDataHandle.set(paramU);

      data.setClean(plug);



      // WRITE OUT ".distance" DATA:

      MDataHandle distanceDataHandle = data.outputValue(aDistance);

      distanceDataHandle.set(distance);

      data.setClean(plug);

   }

   else

   {

      return MS::kUnknownParameter;

   }



   return MS::kSuccess;

}
コード例 #27
0
MStatus NeuronForMayaDevice::compute( const MPlug& plug, MDataBlock& block )
{
    MStatus status;
    if( plug == outputTranslate || plug == outputTranslateX || plug == outputTranslateY || plug == outputTranslateZ 
        || plug == outputLeftCameraPosition || plug == outputLeftCameraPositionX || plug == outputLeftCameraPositionY || plug == outputLeftCameraPositionZ
        || plug == outputLeftCameraRotation || plug == outputLeftCameraRotationX || plug == outputLeftCameraRotationY || plug == outputLeftCameraRotationZ
        || plug == outputRightCameraPosition || plug == outputRightCameraPositionX || plug == outputRightCameraPositionY || plug == outputRightCameraPositionZ
        || plug == outputRightCameraRotation || plug == outputRightCameraRotationX || plug == outputRightCameraRotationY || plug == outputRightCameraRotationZ
        )
    {
        MCharBuffer buffer;
        if ( popThreadData(buffer) )
        {
            double* doubleData = reinterpret_cast<double*>(buffer.ptr());

            int i = 0;
            MDataHandle outputLeftCameraPositionHandle = block.outputValue( outputLeftCameraPosition, &status );
            MCHECKERROR(status, "Error in block.outputValue for outputLeftCameraPosition");

            double3& outputLeftCameraPosition = outputLeftCameraPositionHandle.asDouble3();
            outputLeftCameraPosition[0] = doubleData[i++];
            outputLeftCameraPosition[1] = doubleData[i++];
            outputLeftCameraPosition[2] = doubleData[i++];


            MDataHandle outputLeftCameraRotationHandle = block.outputValue( outputLeftCameraRotation, &status );
            MCHECKERROR(status, "Error in block.outputValue for outputLeftCameraRotation");

            double3& outputLeftCameraRotation = outputLeftCameraRotationHandle.asDouble3();
            outputLeftCameraRotation[0] = doubleData[i++];
            outputLeftCameraRotation[1] = doubleData[i++];
            outputLeftCameraRotation[2] = doubleData[i++];


            MDataHandle outputRightCameraPositionHandle = block.outputValue( outputRightCameraPosition, &status );
            MCHECKERROR(status, "Error in block.outputValue for outputRightCameraPosition");

            double3& outputRightCameraPosition = outputRightCameraPositionHandle.asDouble3();
            outputRightCameraPosition[0] = doubleData[i++];
            outputRightCameraPosition[1] = doubleData[i++];
            outputRightCameraPosition[2] = doubleData[i++];

            MDataHandle outputRightCameraRotationHandle = block.outputValue( outputRightCameraRotation, &status );
            MCHECKERROR(status, "Error in block.outputValue for outputRightCameraRotation");

            double3& outputRightCameraRotation = outputRightCameraRotationHandle.asDouble3();
            outputRightCameraRotation[0] = doubleData[i++];
            outputRightCameraRotation[1] = doubleData[i++];
            outputRightCameraRotation[2] = doubleData[i++];


            MDataHandle outputTranslateHandle = block.outputValue( outputTranslate, &status );
            MCHECKERROR(status, "Error in block.outputValue for outputTranslate");

            double3& outputTranslate = outputTranslateHandle.asDouble3();
            outputTranslate[0] = doubleData[i++];
            outputTranslate[1] = doubleData[i++];
            outputTranslate[2] = doubleData[i++];

            block.setClean( plug );

            releaseDataStorage(buffer);
            return ( MS::kSuccess );
        }
        else
        {
            return MS::kFailure;
        }
    }

    return ( MS::kUnknownParameter );
}
コード例 #28
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;
}
コード例 #29
0
ファイル: cgfxVector.cpp プロジェクト: DimondTheCat/xray
/* virtual */
MStatus cgfxVector::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MFnData::Type dataType = MFnData::kInvalid;
 
	if( plug == sWorldVector ||
		plug == sWorldVectorX ||
		plug == sWorldVectorY ||
		plug == sWorldVectorZ ||
		plug == sWorldVectorW)
	{
		// We do isDirection first simply because if there is an
		// error, the isDirection error is more legible than the
		// vector or matrix error.
		//
		MDataHandle dhIsDirection = data.inputValue(sIsDirection, &status);
		if (!status)
		{
			status.perror("cgfxVector: isDirection handle");
			return status;
		}

		dataType = dhIsDirection.type();

		MDataHandle dhVector = data.inputValue(sVector, &status);
		if (!status)
		{
			status.perror("cgfxVector: vector handle");
			return status;
		}

		dataType = dhVector.type();

		MMatrix matrix;

		MPlug matrixPlug(thisMObject(), sMatrix);
		if (matrixPlug.isNull())
		{
			OutputDebugString("matrixPlug is NULL!\n");
		}

		// TODO: Fix this kludge.
		//
		// We should not have to do this but for some reason, 
		// using data.inputValue() fails for the sMatrix attribute.
		// Instead, we get a plug to the attribute and then get
		// the value directly.
		//
		MObject oMatrix;

		matrixPlug.getValue(oMatrix);

		MFnMatrixData fndMatrix(oMatrix, &status);
		if (!status)
		{
			status.perror("cgfxVector: matrix data");
		}

		matrix= fndMatrix.matrix(&status);
		if (!status)
		{
			status.perror("cgfxVector: get matrix");
		}

#if 0
		// TODO: This is how we are supposed to do it.  (I think).
		//
		MDataHandle dhMatrix = data.inputValue(sMatrix, &status);
		if (!status)
		{
			status.perror("cgfxVector: matrix handle");
		}

		dataType = dhMatrix.type();

		oMatrix			= dhMatrix.data();
		MFnMatrixData fnMatrix(oMatrix, &status);
		if (!status)
		{
			status.perror("cgfxVector: matrix function set");
		}

		matrix = fnMatrix.matrix();
#endif /* 0 */

		bool	 isDirection	= dhIsDirection.asBool();
		double3& vector			= dhVector.asDouble3();

		double mat[4][4];
		matrix.get(mat);

		double ix, iy, iz, iw;	// Input vector
		float  ox, oy, oz, ow;	// Output vector

		ix = vector[0];
		iy = vector[1];
		iz = vector[2];
		iw = isDirection ? 0.0 : 1.0;

		ox = (float)(mat[0][0] * ix +
					 mat[1][0] * iy +
					 mat[2][0] * iz +
					 mat[3][0] * iw);

		oy = (float)(mat[0][1] * ix +
					 mat[1][1] * iy +
					 mat[2][1] * iz +
					 mat[3][1] * iw);

		oz = (float)(mat[0][2] * ix +
					 mat[1][2] * iy +
					 mat[2][2] * iz +
					 mat[3][2] * iw);

		ow = (float)(mat[0][3] * ix +
					 mat[1][3] * iy +
					 mat[2][3] * iz +
					 mat[3][3] * iw);

		MDataHandle dhWVector = data.outputValue(sWorldVector, &status);
		if (!status)
		{
			status.perror("cgfxVector: worldVector handle");
			return status;
		}

		MDataHandle dhWVectorW = data.outputValue(sWorldVectorW, &status);
		if (!status)
		{
			status.perror("cgfxVector: worldVectorW handle");
			return status;
		}

		dhWVector.set(ox, oy, oz);
		dhWVectorW.set(ow);
		data.setClean(sWorldVector);
		data.setClean(sWorldVectorW);
	}
	else
	{
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
コード例 #30
0
//----------------------------------------------------------------------------------------------------------------------
// This method should be overridden in user defined nodes.
// Recompute the given output based on the nodes inputs.
// The plug represents the data value that needs to be recomputed, and the data block holds the storage
// for all of the node'_scale attributes.
//----------------------------------------------------------------------------------------------------------------------
MStatus OceanNode::compute( const MPlug &_plug , MDataBlock &_data ){
    MStatus status;
    // see if we get the output plug
    if( _plug == m_output){    

        MDataHandle dataHandle;

        dataHandle = _data.inputValue(m_resolution, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for resolution plug");

        if (m_res != dataHandle.asInt()){
            switch(dataHandle.asInt()){
                case 0:
                    m_ocean->setResolution(128);
                    MGlobal::displayInfo("Resolution: 128");
                    break;
                case 1:
                    m_ocean->setResolution(256);
                    MGlobal::displayInfo("Resolution: 256");
                    break;
                case 2:
                    m_ocean->setResolution(512);
                    MGlobal::displayInfo("Resolution: 512");
                    break;
                case 3:
                    m_ocean->setResolution(1024);
                    MGlobal::displayInfo("Resolution: 1024");
                    break;
                default:
                    break;
            }
            m_res = dataHandle.asInt();
        }

        dataHandle = _data.inputValue( m_amplitude , &status );
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL( status , "Unable to get data handle for amplitude plug" );
        // now get the value for the data handle as a double
        double amp = dataHandle.asDouble();
        m_ocean->setAmplitude(amp);

        dataHandle = _data.inputValue(m_frequency, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get handle for \"frequency\" plug");
        double freq = dataHandle.asDouble();
        m_ocean->setFrequency(freq);

        dataHandle = _data.inputValue(m_windDirectionX, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for windDirectionX plug");
        // now get value for data handle
        double wdx = dataHandle.asDouble();
        dataHandle = _data.inputValue(m_windDirectionZ, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for windDirectionY plug");
        // now get value for data handle
        double wdz = dataHandle.asDouble();
        m_ocean->setWindVector(make_float2(wdx, wdz));

        dataHandle = _data.inputValue(m_windSpeed, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for windSpeed plug");
        // now get value for data handle
        double ws = dataHandle.asDouble();
        m_ocean->setWindSpeed(ws);

        // Only create a new frequency domain if either amplitude or the wind vecotr has changed
        if (m_amp != amp || m_wdx != wdx || m_wdz != wdz || m_ws != ws ){
            MGlobal::displayInfo("here");
            m_ocean->createH0();
            m_amp = amp;
            m_wdx = wdx;
            m_wdz = wdz;
            m_ws = ws;
        }

        dataHandle = _data.inputValue(m_choppiness, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for the choppiness plug");
        double choppiness = dataHandle.asDouble();

        dataHandle = _data.inputValue(m_time, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for time plug");
        MTime time = dataHandle.asTime();

        MDataHandle outputData = _data.outputValue(m_output, &status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL( status , "Unable to get data handle for output plug" );

        MFnMeshData mesh;
        MObject outputObject = mesh.create(&status);
        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to create output mesh");

        // Find the current frame number we're on and create the grid based on this
        MAnimControl anim;
        anim.setMinTime(time);

        createGrid((int)pow(2.0, m_res+7), anim.currentTime().value()/24, choppiness, outputObject, status);

        CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to to create grid");

        outputData.set(outputObject);

        // clean the output plug, ie unset it from dirty so that maya does not re-evaluate it
        _data.setClean( _plug );

        return MStatus::kSuccess;
    }

    return MStatus::kUnknownParameter;
}