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

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

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

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

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

	return( MS::kSuccess );
}
Ejemplo n.º 2
0
//
// Evaluate the curve at the given time.
//
double interpHalf::evaluate(const MTime &val)
{
	// Interpolate the before and after values.
	double sec = val.as(MTime::kSeconds);
	double alpha = (sec-sTime) / range;
	return (1.0 - alpha) * beforeVal + alpha * afterVal;
}
Ejemplo n.º 3
0
ConstObjectPtr SceneShape::readSceneShapeAttribute( const MDagPath &p, SceneInterface::Name attributeName )
{
	MDagPath dagPath;
	SceneShape *sceneShape = findScene( p, false, &dagPath );
	if ( !sceneShape )
	{
		return 0;
	}
	
	MFnDagNode fnChildDag( dagPath );
	if( attributeName == LinkedScene::linkAttribute )
	{
		if( !fnChildDag.isIntermediateObject() )
		{
			return readSceneShapeLink(p);
		}
	}
	
	ConstSceneInterfacePtr scene = sceneShape->getSceneInterface();
	if ( !scene )
	{
		return 0;
	}
	
	MPlug timePlug = fnChildDag.findPlug( aTime );
	MTime time;
	timePlug.getValue( time );
	return scene->readAttribute( attributeName, time.as( MTime::kSeconds ) );
}
Ejemplo n.º 4
0
MObject animCube::createMesh(const MTime& time,
							  MObject& outData,
							  MStatus& stat)

{
	int				numVertices, frame;
	float			cubeSize;
	MFloatPointArray		points;
	MFnMesh			meshFS;

	// Scale the cube on the frame number, wrap every 10 frames.
	frame = (int)time.as( MTime::kFilm );
	if (frame == 0)
	  frame = 1;
	cubeSize		    		= 0.5f * (float)( frame % 10);

	const int numFaces			= 6;
	numVertices					= 8;
	const int numFaceConnects	= 24;

	MFloatPoint vtx_1( -cubeSize, -cubeSize, -cubeSize );
	MFloatPoint vtx_2(  cubeSize, -cubeSize, -cubeSize );
	MFloatPoint vtx_3(  cubeSize, -cubeSize,  cubeSize );
	MFloatPoint vtx_4( -cubeSize, -cubeSize,  cubeSize );
	MFloatPoint vtx_5( -cubeSize,  cubeSize, -cubeSize );
	MFloatPoint vtx_6( -cubeSize,  cubeSize,  cubeSize );
	MFloatPoint vtx_7(  cubeSize,  cubeSize,  cubeSize );
	MFloatPoint vtx_8(  cubeSize,  cubeSize, -cubeSize );
	points.append( vtx_1 );
	points.append( vtx_2 );
	points.append( vtx_3 );
	points.append( vtx_4 );
	points.append( vtx_5 );
	points.append( vtx_6 );
	points.append( vtx_7 );
	points.append( vtx_8 );

	// Set up an array containing the number of vertices
	// for each of the 6 cube faces (4 verticies per face)
	//
	int face_counts[numFaces] = { 4, 4, 4, 4, 4, 4 };
	MIntArray faceCounts( face_counts, numFaces );

	// Set up and array to assign vertices from points to each face 
	//
	int face_connects[ numFaceConnects ] = {	0, 1, 2, 3,
												4, 5, 6, 7,
												3, 2, 6, 5,
												0, 3, 5, 4,
												0, 4, 7, 1,
												1, 7, 6, 2	};
	MIntArray faceConnects( face_connects, numFaceConnects );

	MObject newMesh = meshFS.create(numVertices, numFaces,
									points, faceCounts, faceConnects,
									outData, &stat);

	return newMesh;
}
Ejemplo n.º 5
0
static void restoreOldTime(MTime &start, MTime &end, MTime &curr, MTime &minT,
                           MTime &maxT)
{
  const double st = start.as(start.unit()), en = end.as(end.unit()),
               cu = curr.as(curr.unit()), mi = minT.as(minT.unit()),
               ma = maxT.as(maxT.unit());

  MString inst = "playbackOptions -ast ";
  inst += st;
  inst += " -aet ";
  inst += en;
  inst += " -min ";
  inst += mi;
  inst += " -max ";
  inst += ma;
  inst += ";\ncurrentTime ";
  inst += cu;
  inst += ";";

  MGlobal::executeCommand(inst);
}
    // -------------------------------------------
    void AnimationHelper::generateSamplingFunction()
    {
        mSamplingTimes.clear();

        // Avoid any potential precision accumulation problems by using the MTime class as an iterator
        MTime startT = animationStartTime();
        MTime endT = animationEndTime();
        for ( MTime currentT = startT; currentT <= endT; ++currentT )
        {
            mSamplingTimes.push_back ( ( float ) currentT.as ( MTime::kSeconds ) );
        }
    }
Ejemplo n.º 7
0
MObject AniMesh::readFrame(const MTime& time,MObject& outData,MStatus& stat)

{
	MFloatPointArray points;
	MFnMesh         meshFS;
	int frame = (int)time.as( MTime::kFilm );
	if (frame == 0)
		frame = 1; 
	vector<size_t> face_v;
	vector<double> points_v;
	char cfilename[256];
	sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),frame);
	//sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0);
	string filename = string(cfilename);
	fstream fp;
	fp.open(filename,ios::in);
	if (fp)
	{
		ImportVrml2 (filename, face_v, points_v);
	}else{
		sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0);
		string filename = string(cfilename); 
		ImportVrml2(filename,face_v,points_v);
	}
	
	size_t numVertices = points_v.size()/3;
	size_t numFaces = face_v.size()/3;
	for(vector<double>::const_iterator it = points_v.begin();it != points_v.end();it+=3) {
		MFloatPoint vtx(*it,*(it+1),*(it+2));
		points.append(vtx);
	}

	vector<int> face_count;
	for(int i=0;i<numFaces;i++) {
		face_count.push_back(3);
	}
	MIntArray faceCounts(&face_count[0],numFaces);

	vector<int> face_connects;
	face_connects.resize(face_v.size());
	for(int i=0;i<face_v.size();++i)
	{
		face_connects[i] = face_v[i];
	}

	MIntArray faceConnects( &face_connects[0], face_connects.size() );
	MObject newMesh=meshFS.create(numVertices, numFaces,points, faceCounts, faceConnects,outData,&stat);
	return newMesh;

}
Ejemplo n.º 8
0
ConstObjectPtr SceneShape::readSceneShapeObject( const MDagPath &p )
{
	SceneShape *sceneShape = findScene( p, true );
	if ( !sceneShape )
	{
		return 0;
	}

	MPlug pTime( sceneShape->thisMObject(), aTime );
	MTime time;
	pTime.getValue( time );
	double t = time.as( MTime::kSeconds );
	return sceneShape->getSceneInterface()->readObject( t );
}
Ejemplo n.º 9
0
ConstObjectPtr SceneShape::readSceneShapeLink( const MDagPath &p )
{
	MDagPath dagPath;
	SceneShape *sceneShape = findScene( p, true, &dagPath );
	if ( !sceneShape )
	{
		throw Exception("readSceneShapeLink: Could not find SceneShape!");
	}

	ConstSceneInterfacePtr scene = sceneShape->getSceneInterface();
	if ( !scene )
	{
		throw Exception( "Empty scene!");
	}

	MFnDagNode fnChildDag( dagPath );
	MStatus st;
	MPlug timePlug = fnChildDag.findPlug( aTime, &st );
	if( !st )
	{
		throw Exception( "Could not find 'time' plug in SceneShape!");
	}

	// if time plug is connected to maya global time, then we assume there's no time remapping between the Maya scene and the loaded scene.
	MPlugArray array;
	timePlug.connectedTo( array, true, false, &st );
	if( !st )
	{
		throw Exception( "Could not find 'time' plug connections in SceneShape!");
	}

	for ( unsigned int i = 0; i < array.length(); i++ )
	{
		if ( array[i].name() == "time1.outTime" )
		{
			/// connected to time, so no time remapping between maya scene and loaded scene.
			return LinkedScene::linkAttributeData( scene.get() );
		}
	}
	/// couldn't find connection to maya time, so this node is mapping the time some other way.
	MTime time;
	timePlug.getValue( time );
	return LinkedScene::linkAttributeData( scene.get(), time.as( MTime::kSeconds ) );
}
Ejemplo n.º 10
0
/**
 *	Build the animation from a Maya generic animated Transform
 */
osg::ref_ptr<osg::AnimationPath> Transform::animatedTransform2AnimationPath(MObject &obj)
{
	osg::ref_ptr<osg::AnimationPath> anim = new osg::AnimationPath();

	MTime start = MAnimControl::animationStartTime();
	MTime end = MAnimControl::animationEndTime();
	for( MTime t = start ; t <= end ; t += Config::instance()->getAnimSampleBy() ) {
		// Set the right time in Maya timeline so all properties are updated
		MAnimControl::setCurrentTime(t);

		anim->insert(t.as(MTime::kSeconds), osg::AnimationPath::ControlPoint(
			getCPPosition(obj),
			getCPRotation(obj),
			getCPScale(obj)
			));
	}

	return anim;
}
Ejemplo n.º 11
0
//
//      Deform computation
//
MStatus jhMeshBlur::deform( MDataBlock& block,MItGeometry& iter,const MMatrix& m,unsigned int multiIndex)
{
    MStatus returnStatus;

    // Envelope
    float envData = block.inputValue(envelope, &returnStatus).asFloat();
	CHECK_MSTATUS(returnStatus);

    if(envData == 0)
		return MS::kFailure;

    /*
     VARIABLES
     */
    //float factor = block.inputValue(aShapeFactor, &returnStatus).asFloat();
    float fStrength = block.inputValue(aStrength, &returnStatus).asFloat();
	CHECK_MSTATUS(returnStatus);
	
	if (fStrength == 0)
		return MS::kFailure;
	
    float fThreshold = block.inputValue(aTreshhold, &returnStatus).asFloat();
	CHECK_MSTATUS(returnStatus);
    float fW = 0.0f; // weight
    float fDistance;
    fStrength *= envData;

    double dKracht = block.inputValue(aInterpPower, &returnStatus).asDouble();
	CHECK_MSTATUS(returnStatus);
    double dDotProduct;  // Dotproduct of the point

    bool bTweakblur = block.inputValue(aTweakBlur, &returnStatus).asBool();
	CHECK_MSTATUS(returnStatus);
	
    bool bQuad = block.inputValue(aQuadInterp, &returnStatus).asBool();
	CHECK_MSTATUS(returnStatus);
	
	MTime inTime = block.inputValue(aTime).asTime();
    int nTijd = (int)inTime.as(MTime::kFilm);


    MFloatVectorArray currentNormals;   // normals of mesh
    MFnPointArrayData fnPoints;         // help converting to MPointArrays
    MFloatVector dirVector;             // direction vector of the point
    MFloatVector normal;                // normal of the point
    MPointArray savedPoints;            // save all point before edited
    MMatrix matInv = m.inverse();       // inversed matrix
    MPoint ptA;                         // current point (iter mesh)
    MPoint ptB;                         // previous point (iter mesh)
    MPoint ptC;                         // mesh before previous point (iter mesh)

    // get node, use node to get inputGeom, use inputGeom to get mesh data, use mesh data to get normal data
    MFnDependencyNode nodeFn(this->thisMObject());

    MPlug inGeomPlug(nodeFn.findPlug(this->inputGeom,true));
    MObject inputObject(inGeomPlug.asMObject());
    MFnMesh inMesh(inputObject);

    inMesh.getVertexNormals(true, currentNormals);

    // get the previous mesh data
    MPlug oldMeshPlug = nodeFn.findPlug(MString("oldMesh"));
    MPlug oldMeshPositionsAPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 0);
    MPlug oldMeshPositionsBPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 1);
    MPlug oldMeshPositionsCPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 2); // cache for tweak mode
    MPlug oldMeshPositionsDPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 3); // cache for tweak mode

    // convert to MPointArrays
    MObject objOldMeshA;
    MObject objOldMeshB;
    MObject objOldMeshC; // cache
    MObject objOldMeshD; // cache

    oldMeshPositionsAPlug.getValue(objOldMeshA);
    oldMeshPositionsBPlug.getValue(objOldMeshB);
    oldMeshPositionsCPlug.getValue(objOldMeshC); // cache
    oldMeshPositionsDPlug.getValue(objOldMeshD); // cache

    fnPoints.setObject(objOldMeshA);
    MPointArray oldMeshPositionsA = fnPoints.array();
    
    fnPoints.setObject(objOldMeshB);
    MPointArray oldMeshPositionsB = fnPoints.array();
    
    fnPoints.setObject(objOldMeshC);
    MPointArray oldMeshPositionsC = fnPoints.array(); // cache
    
    fnPoints.setObject(objOldMeshD);
    MPointArray oldMeshPositionsD = fnPoints.array(); // cache

    
    
    // If mesh position variables are empty,fill them with default values
    if(oldMeshPositionsA.length() == 0 || nTijd <= 1){
        iter.allPositions(oldMeshPositionsA);

        for(int i=0; i < oldMeshPositionsA.length(); i++)
        {
            // convert to world
            oldMeshPositionsA[i] = oldMeshPositionsA[i] * m;
        }
		
        oldMeshPositionsB.copy(oldMeshPositionsA);
        oldMeshPositionsC.copy(oldMeshPositionsA); // cache
        oldMeshPositionsD.copy(oldMeshPositionsA); // cache
    }
	
	// get back old date again
	if (bTweakblur == true) { // restore cache
		oldMeshPositionsA.copy(oldMeshPositionsC);
		oldMeshPositionsB.copy(oldMeshPositionsD);
	}
    
    
    iter.allPositions(savedPoints);
    for(int i=0; i < savedPoints.length(); i++)
    {
        // convert points to world points
        savedPoints[i] = savedPoints[i] * m;
    }

    // Actual Iteration through points
    for (; !iter.isDone(); iter.next()){
        // get current position
        ptA = iter.position();
        // get old positions
        ptB = oldMeshPositionsA[iter.index()] * matInv;
        ptC = oldMeshPositionsB[iter.index()] * matInv;

        fDistance = ptA.distanceTo(ptB);
        fW = weightValue(block,multiIndex,iter.index());


        if (fDistance * (fStrength*fW) < fThreshold && fThreshold > 0){
            iter.setPosition(ptA);
        } else {
            // aim/direction vector to calculate strength
            dirVector = (ptA - ptB); // (per punt)
            dirVector.normalize();

            normal = currentNormals[iter.index()];

            dDotProduct = normal.x * dirVector.x + normal.y * dirVector.y + normal.z * dirVector.z;

            
            if(bQuad == true){
                MVector vecA(((ptB - ptC) + (ptA - ptB)) / 2);
                vecA.normalize();

                MPoint hiddenPt(ptB + (vecA * fDistance) * dKracht);
                ptA = quadInterpBetween(ptB, hiddenPt, ptA, (1 - fStrength * fW) + (linearInterp(dDotProduct, -1, 1) * (fStrength * fW) ) );
            } else {
                MPoint halfway = (ptA - ptB) * 0.5;
                MPoint offset = halfway * dDotProduct * (fStrength*fW);
                ptA = ptA - ((halfway * (fStrength*fW)) - offset); // + (offset * strength);
            }
            // set new value

            iter.setPosition(ptA);
        }
    }
    if(bTweakblur == false){
        oldMeshPositionsD.copy(oldMeshPositionsB);
        oldMeshPositionsC.copy(oldMeshPositionsA);
        oldMeshPositionsB.copy(oldMeshPositionsA);
        oldMeshPositionsA.copy(savedPoints);

        // Save back to plugs
        objOldMeshA = fnPoints.create(oldMeshPositionsA);
        objOldMeshB = fnPoints.create(oldMeshPositionsB);
        objOldMeshC = fnPoints.create(oldMeshPositionsC);
        objOldMeshD = fnPoints.create(oldMeshPositionsD);
		
        oldMeshPositionsAPlug.setValue(objOldMeshA);
        oldMeshPositionsBPlug.setValue(objOldMeshB);
        oldMeshPositionsCPlug.setValue(objOldMeshC);
        oldMeshPositionsDPlug.setValue(objOldMeshD);
    }
    
    return returnStatus;
}
Ejemplo n.º 12
0
float convert( const MTime &from )
{
	return from.as( MTime::kSeconds );
}
Ejemplo n.º 13
0
	void ParamList::parseArgs(const MArgList &args)
	{
		MStatus stat;
		// Parse arguments from command line
		for (unsigned int i = 0; i < args.length(); i++ )
		{
			if ((MString("-all") == args.asString(i,&stat)) && (MS::kSuccess == stat))
				exportAll = true;
			else if ((MString("-world") == args.asString(i,&stat)) && (MS::kSuccess == stat))
				exportWorldCoords = true;
			else if ((MString("-mesh") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportMesh = true;
				meshFilename = args.asString(++i,&stat);
			}
			else if ((MString("-mat") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportMaterial = true;
				materialFilename = args.asString(++i,&stat);
			}
			else if ((MString("-matPrefix") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				matPrefix = args.asString(++i,&stat);
			}
			else if ((MString("-copyTex") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				copyTextures = true;
				texOutputDir = args.asString(++i,&stat);
			}
			else if ((MString("-lightOff") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				lightingOff = true;
			}
			else if ((MString("-skel") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportSkeleton = true;
				skeletonFilename = args.asString(++i,&stat);
			}
			else if ((MString("-anims") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportAnims = true;
			}
			else if ((MString("-animCur") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportAnimCurves = true;
				animFilename = args.asString(++i,&stat);
			}
			else if ((MString("-cam") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportCameras = true;
				camerasFilename = args.asString(++i,&stat);
			}
			else if ((MString("-v") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportVBA = true;
			}
			else if ((MString("-n") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportVertNorm = true;
			}
			else if ((MString("-c") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportVertCol = true;
			}
			else if ((MString("-cw") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportVertCol = true;
				exportVertColWhite = true;
			}
			else if ((MString("-t") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportTexCoord = true;
			}
			else if ((MString("-camAnim") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportCamerasAnim = true;
			}
			else if ((MString("-meshbin") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportMeshBin = true;
			}
			else if ((MString("-skelbin") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportSkelBin = true;
			}
			else if ((MString("-particles") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				exportParticles = true;
				particlesFilename = args.asString(++i,&stat);
			}
			else if ((MString("-shared") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				useSharedGeom = true;
			}
			else if ((MString("-np") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				MString npType = args.asString(i,&stat);
				if (npType == "curFrame")
					neutralPoseType = NPT_CURFRAME;
				else if (npType == "bindPose")
					neutralPoseType = NPT_BINDPOSE;
				else if (npType == "frame")
				{
					neutralPoseType = NPT_FRAME;
					neutralPoseFrame = args.asInt(++i,&stat);
				}
			}
			else if ((MString("-clip") == args.asString(i,&stat)) && (MS::kSuccess == stat))
			{
				//get clip name
				MString clipName = args.asString(++i,&stat);
				//get clip range
				MString clipRangeType = args.asString(++i,&stat);
				double startTime, stopTime;
				if (clipRangeType == "startEnd")
				{
					startTime = args.asDouble(++i,&stat);
					stopTime = args.asDouble(++i,&stat);
					MString rangeUnits = args.asString(++i,&stat);
					if (rangeUnits == "frames")
					{
						//range specified in frames => convert to seconds
						MTime t1(startTime, MTime::uiUnit());
						MTime t2(stopTime, MTime::uiUnit());
						startTime = t1.as(MTime::kSeconds);
						stopTime = t2.as(MTime::kSeconds);
					}
				}
				else
				{
					//range specified by time slider
					MTime t1 = MAnimControl::minTime();
					MTime t2 = MAnimControl::maxTime();
					startTime = t1.as(MTime::kSeconds);
					stopTime = t2.as(MTime::kSeconds);
				}
				// get sample rate
				double rate;
				MString sampleRateType = args.asString(++i,&stat);
				if (sampleRateType == "sampleByFrames")
				{
					// rate specified in frames
					int intRate = args.asInt(++i,&stat);
					MTime t = MTime(intRate, MTime::uiUnit());
					rate = t.as(MTime::kSeconds);
				}
				else
				{
					// rate specified in seconds
					rate = args.asDouble(++i,&stat);
				}
				//add clip info
				clipInfo clip;
				clip.name = clipName;
				clip.start = startTime;
				clip.stop = stopTime;
				clip.rate = rate;
				clipList.push_back(clip);
				std::cout << "clip " << clipName.asChar() << "\n";
				std::cout << "start: " << startTime << ", stop: " << stopTime << "\n";
				std::cout << "rate: " << rate << "\n";
				std::cout << "-----------------\n";
			}
		}
	/*	// Read options from exporter window
		// Gather clips data
		// Read info about the clips we have to transform
		int numClips,exportClip,rangeType,rateType,rangeUnits;
		double startTime,stopTime,rate;
		MString clipName;
		//read number of clips
		MGlobal::executeCommand("eval \"$numClips+=0\"",numClips,false);
		//read clips data
		for (int i=1; i<=numClips; i++)
		{
			MString command = "checkBox -q -v ExportClip";
			command += i;
			MGlobal::executeCommand(command,exportClip,false);
			if (exportClip)
			{
				//get clip name
				command = "textField -q -tx ClipName";
				command += i;
				MGlobal::executeCommand(command,clipName,false);
				//get clip range
				command = "radioButtonGrp -q -sl ClipRangeRadio";
				command += i;
				MGlobal::executeCommand(command,rangeType,false);
				if (rangeType == 1)
				{	//range specified from user
					command = "floatField -q -v ClipRangeStart";
					command += i;
					MGlobal::executeCommand(command,startTime,false);
					command = "floatField -q -v ClipRangeEnd";
					command += i;
					MGlobal::executeCommand(command,stopTime,false);
					//get range units
					command = "radioButtonGrp -q -sl ClipRangeUnits";
					command += i;
					MGlobal::executeCommand(command,rangeUnits,false);
					if (rangeUnits == 1)
					{	//range specified in frames => convert to seconds
						MTime t1(startTime, MTime::uiUnit());
						MTime t2(stopTime, MTime::uiUnit());
						startTime = t1.as(MTime::kSeconds);
						stopTime = t2.as(MTime::kSeconds);
					}
				}
				else
				{	//range specified by time slider
					MTime t1 = MAnimControl::minTime();
					MTime t2 = MAnimControl::maxTime();
					startTime = t1.as(MTime::kSeconds);
					stopTime = t2.as(MTime::kSeconds);
				}
				//get sample rate
				command = "radioButtonGrp -q -sl ClipRateType";
				command += i;
				MGlobal::executeCommand(command,rateType,false);
				MTime t;
				switch (rateType)
				{
				case 1:	//rate specified in frames
					command = "intField -q -v ClipRateFrames";
					command += i;
					MGlobal::executeCommand(command,rate,false);
					t = MTime(rate, MTime::uiUnit());
					rate = t.as(MTime::kSeconds);
					break;
				case 2:	//rate specified in seconds
					command = "floatField -q -v ClipRateSeconds";
					command += i;
					MGlobal::executeCommand(command,rate,false);
					break;
				default://rate not specified, get from time slider
					rate = -1;
					break;
				}
				//add clip info
				clipInfo clip;
				clip.name = clipName;
				clip.start = startTime;
				clip.stop = stopTime;
				clip.rate = rate;
				clipList.push_back(clip);
				std::cout << "clip " << clipName.asChar() << "\n";
				std::cout << "start: " << startTime << ", stop: " << stopTime << "\n";
				std::cout << "rate: " << rate << "\n";
				std::cout << "-----------------\n";
			}
		}*/
	}
Ejemplo n.º 14
0
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock)
{
    MStatus status;

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

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

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

    double fps = getFPS();

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

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

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

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

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

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

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

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

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


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

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

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

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

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

    if (plug == mOutPropArrayAttr)
    {

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

        mOutRead[0] = true;

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

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

            unsigned int outHandleIndex = 0;
            MDataHandle outHandle;

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

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

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

        mOutRead[1] = true;

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

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

            MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

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

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

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

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

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

        mOutRead[8] = true;

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

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

            MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

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

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

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

        mOutRead[2] = true;

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

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

            MDataHandle outHandle;

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

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

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

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

        mOutRead[3] = true;

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

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

            MDataHandle outHandle;

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

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

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

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

        mOutRead[4] = true;

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

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

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

            MDataHandle outHandle;
            unsigned int index = 0;

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

                read(mCurTime, cam, array);

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

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

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

        mOutRead[5] = true;

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

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

            MDataHandle outHandle;

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

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

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

        mOutRead[6] = true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		return( MS::kSuccess );
	}

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

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

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


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


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

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


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

				MDynSweptLine line = fnSweptData.sweptLine( i );

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

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

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

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

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

			}
		}

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

				MDynSweptTriangle tri = fnSweptData.sweptTriangle( i );

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

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

				inPosAry.append( center );

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

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

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

			}
		}
	}

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

	return( MS::kSuccess );
}
MStatus NuiMayaDeviceGrabber::compute( const MPlug& plug, MDataBlock& datablock )
//
//	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
//
{
	assert(m_pCache);
	if(!m_pCache)
		return MS::kFailure;

	MStatus returnStatus;
	/* Get time */
	MDataHandle timeData = datablock.inputValue( aTime, &returnStatus ); 
	MCHECKERROR(returnStatus, "Error getting time data handle\n")
	MTime time = timeData.asTime();
	//!< 30 frames per second
	int	  frame = (int)time.as( MTime::kNTSCFrame ) - 1;//Noted: The first frame in MAYA is 1;

	if(m_pDevice)
	{
		std::shared_ptr<NuiCompositeFrame> pFrame = m_pDevice->popFrame();
		if(pFrame)
		{
			pFrame->m_depthFrame.SetMinDepth(getShortValue(aMinDepth));
			pFrame->m_depthFrame.SetMaxDepth(getShortValue(aMaxDepth));

			if(m_pSLAM /*&& m_pSLAM->m_tracker.isThreadOn()*/)
			{
				std::shared_ptr<NuiVisualFrame> pVisualFrame = std::make_shared<NuiVisualFrame>();
				pVisualFrame->acquireFromCompositeFrame(pFrame.get());
				m_pSLAM->m_tracker.pushbackFrame(pVisualFrame);
				pVisualFrame.reset();
			}
			m_pCache->pushbackFrame(pFrame);
			pFrame.reset();
		}
	}

	std::shared_ptr<NuiCompositeFrame> pCurrentFrame = m_pCache->getLatestFrame();
		
	if ( plug == aOutputMappable )
	{
		std::shared_ptr<NuiCLMappableData> clData(nullptr);
		MDataHandle outHandle = datablock.outputValue( aOutputMappable );
		NuiMayaMappableData* clmData = static_cast<NuiMayaMappableData*>(outHandle.asPluginData());
		if(!clmData)
		{
			// Create some user defined geometry data and access the
			// geometry so we can set it
			//
			MFnPluginData fnDataCreator;
			MTypeId tmpid( NuiMayaMappableData::id );

			fnDataCreator.create( tmpid, &returnStatus );
			MCHECKERROR( returnStatus, "compute : error creating mappableData")

			clmData = (NuiMayaMappableData*)fnDataCreator.data( &returnStatus );
			MCHECKERROR( returnStatus, "compute : error gettin at proxy mappableData object")

			clData = std::shared_ptr<NuiCLMappableData>(new NuiCLMappableData());
			clmData->setData(clData);

			returnStatus = outHandle.set( clmData );
			MCHECKERROR( returnStatus, "compute : error gettin at proxy mappableData object")
		}
Ejemplo n.º 17
0
// return seconds per frame
double util::spf()
{
    static const MTime sec(1.0, MTime::kSeconds);
    return 1.0 / sec.as(MTime::uiUnit());
}
Ejemplo n.º 18
0
MObject ClothSimMayaPlugin::createMesh(const MTime& time,
	MObject& outData,
	MStatus& stat)

{
	double t = time.as(MTime::kSeconds);
	if (t <= 1.0 / 24 && m_prevTime > 1.0/24)
	{
		m_simMesh.reset(0);
	}

	int nx = 60;
	int ny = 60;

	if (!m_simMesh.get())
	{

		Eigen::VectorXf v((nx+1) * (ny+1) * 3);
		Eigen::VectorXf x((nx + 1) * (ny + 1) * 3);
		Eigen::VectorXf uv((nx + 1) * (ny + 1) * 2);

		for (int i = 0; i <= nx; ++i)
		{
			for (int j = 0; j <= ny; ++j)
			{
				int base = i + (nx+1) * j;
				uv[2 * base + 0] = (float)i / nx - 0.5f;
				uv[2 * base + 1] = (float)j / ny - 0.5f;

				x[3 * base + 0] = uv[2 * base + 0];
				x[3 * base + 1] = 0;
				x[3 * base + 2] = uv[2 * base + 1];

				v[3 * base + 0] = v[3 * base + 1] = v[3 * base + 2] = 0;
			}
		}

		std::vector<int> triangleInds;
		for (int i = 0; i < nx; ++i)
		{
			for (int j = 0; j < ny; ++j)
			{
				int base = i + (nx + 1) * j;

				triangleInds.push_back(base + 0);
				triangleInds.push_back(base + 1);
				triangleInds.push_back(base + (nx + 1));

				triangleInds.push_back(base + 1);
				triangleInds.push_back(base + (nx + 2));
				triangleInds.push_back(base + (nx + 1));

			}
		}

		m_simMesh.reset(
			new ClothMesh<float>(
				x, v, uv, triangleInds,
				0.01f, 1000000.0f, 1000000.0f,
				0.01f, 1000.0f, 1000.0f,
				1.0f
			)
		);
	}

	std::vector<int> constraintIndices;
	std::vector< Eigen::Matrix3f > constraintMatrices;

	
	Eigen::VectorXf constraintVelocityDeltas(m_simMesh->x().size());
	constraintVelocityDeltas.setConstant(0);

	for (int i = 0; i <= nx; ++i)
	{
		for (int j = 0; j <= ny; ++j)
		{
			int idx = i + (nx + 1) * j;
			float x = (float)i / nx - 0.5f;
			float y = (float)j / ny - 0.5f;

			if (x * x + y * y < 0.3 * 0.3)
			{
				constraintIndices.push_back(idx);
				constraintMatrices.push_back(Eigen::Matrix3f::Zero());
			}
		}
	}

	if (t > m_prevTime)
	{
		ConstrainedCGSolver<float> solver(
			constraintIndices,
			constraintMatrices,
			constraintVelocityDeltas,
			0.01f,
			400
		);

		GravityField<float> g( m_simMesh->m(), Eigen::Vector3f( 0,-9.8f, 0 ) );
		std::vector< ForceField<float>* > forceFields;
		forceFields.push_back( &g );

		try
		{
			std::cerr << "advance" << std::endl;
			m_simMesh->advance(forceFields, float(t - m_prevTime)*0.5f, solver);
			m_simMesh->advance(forceFields, float(t - m_prevTime)*0.5f, solver);
			std::cerr << "done" << std::endl;
		}
		catch (const std::exception &e)
		{
			std::cerr << e.what() << std::endl;
			stat = MStatus::kFailure;
			return MObject();
		}
		catch (...)
		{
			std::cerr << "unknown exception" << std::endl;
			stat = MStatus::kFailure;
			return MObject();
		}
	}

	m_prevTime = t;

	MFloatPointArray points;
	for (int i = 0; i < m_simMesh->x().size(); i += 3)
	{
		MFloatPoint p(m_simMesh->x()[i], m_simMesh->x()[i + 1], m_simMesh->x()[i + 2]);
		points.append(p);
	}

	MFnMesh meshFS;
	MIntArray faceCounts((int)m_simMesh->triangleIndices().size()/3, 3);
	MIntArray faceConnects;
	for (unsigned i = 0; i < m_simMesh->triangleIndices().size(); ++i)
	{
		faceConnects.append(m_simMesh->triangleIndices()[i]);
	}

	MObject newMesh = meshFS.create((int)m_simMesh->x().size() / 3, (int)m_simMesh->triangleIndices().size() / 3, points, faceCounts, faceConnects, outData, &stat);

	return newMesh;
}
                virtual void ExportProcedural( AtNode *node )
                {
                        // do basic node export
                        ExportMatrix( node, 0 );

                        // AiNodeSetPtr( node, "shader", arnoldShader(node) );


                        AiNodeSetInt( node, "visibility", ComputeVisibility() );

                        MPlug plug = FindMayaObjectPlug( "receiveShadows" );
                        if( !plug.isNull() )
                        {
                                AiNodeSetBool( node, "receive_shadows", plug.asBool() );
                        }

                        plug = FindMayaObjectPlug( "aiSelfShadows" );
                        if( !plug.isNull() )
                        {
                                AiNodeSetBool( node, "self_shadows", plug.asBool() );
                        }

                        plug = FindMayaObjectPlug( "aiOpaque" );
                        if( !plug.isNull() )
                        {
                                AiNodeSetBool( node, "opaque", plug.asBool() );
                        }

                        // now set the procedural-specific parameters

                        AiNodeSetBool( node, "load_at_init", true ); // just for now so that it can load the shaders at the right time

                        MFnDagNode fnDagNode( m_dagPath );
                        MBoundingBox bound = fnDagNode.boundingBox();

                        AiNodeSetPnt( node, "min", bound.min().x-m_dispPadding, bound.min().y-m_dispPadding, bound.min().z-m_dispPadding );
                        AiNodeSetPnt( node, "max", bound.max().x+m_dispPadding, bound.max().y, bound.max().z+m_dispPadding );

                        const char *dsoPath = getenv( "ALEMBIC_ARNOLD_PROCEDURAL_PATH" );
                        AiNodeSetStr( node, "dso",  dsoPath ? dsoPath : "bb_AlembicArnoldProcedural.so" );

                        // Set the parameters for the procedural

                        //abcFile path
                        MString abcFile = fnDagNode.findPlug("cacheFileName").asString().expandEnvironmentVariablesAndTilde();

                        //object path
                        MString objectPath = fnDagNode.findPlug("cacheGeomPath").asString();

                        //object pattern
                        MString objectPattern = "*";

                        plug = FindMayaObjectPlug( "objectPattern" );
                        if (!plug.isNull() )
                        {
                              if (plug.asString() != "")
                              {
                                objectPattern = plug.asString();
                              }
                        }

                        //object pattern
                        MString excludePattern = "";

                        plug = FindMayaObjectPlug( "excludePattern" );
                        if (!plug.isNull() )
                        {
                              if (plug.asString() != "")
                              {
                                excludePattern = plug.asString();
                              }
                        }

                        float shutterOpen = 0.0;
                        plug = FindMayaObjectPlug( "shutterOpen" );
                        if (!plug.isNull() )
                        {
                                shutterOpen = plug.asFloat();
                        }

                        float shutterClose = 0.0;
                        plug = FindMayaObjectPlug( "shutterClose" );
                        if (!plug.isNull() )
                        {
                                shutterClose = plug.asFloat();
                        }

                        float timeOffset = 0.0;
                        plug = FindMayaObjectPlug( "timeOffset" );
                        if (!plug.isNull() )
                        {
                                timeOffset = plug.asFloat();
                        }

                        int subDIterations = 0;
                        plug = FindMayaObjectPlug( "ai_subDIterations" );
                        if (!plug.isNull() )
                        {
                                subDIterations = plug.asInt();
                        }

                        MString nameprefix = "";
                        plug = FindMayaObjectPlug( "namePrefix" );
                        if (!plug.isNull() )
                        {
                                nameprefix = plug.asString();
                        }

                        // bool exportFaceIds = fnDagNode.findPlug("exportFaceIds").asBool();

                        bool makeInstance = true; // always on for now
                        plug = FindMayaObjectPlug( "makeInstance" );
                        if (!plug.isNull() )
                        {
                                makeInstance = plug.asBool();
                        }
                        
                        bool flipv = false; 
                        plug = FindMayaObjectPlug( "flipv" );
                        if (!plug.isNull() )
                        {
                                flipv = plug.asBool();
                        }

                        bool invertNormals = false; 
                        plug = FindMayaObjectPlug( "invertNormals" );
                        if (!plug.isNull() )
                        {
                                invertNormals = plug.asBool();
                        }
                        
                        short i_subDUVSmoothing = 1;
                        plug = FindMayaObjectPlug( "ai_subDUVSmoothing" );
                        if (!plug.isNull() )
                        {
                                i_subDUVSmoothing = plug.asShort();
                        }

                        MString  subDUVSmoothing;

                        switch (i_subDUVSmoothing)
                        {
                          case 0:
                            subDUVSmoothing = "pin_corners";
                            break;
                          case 1:
                            subDUVSmoothing = "pin_borders";
                            break;
                          case 2:
                            subDUVSmoothing = "linear";
                            break;
                          case 3:
                            subDUVSmoothing = "smooth";
                            break;
                          default :
                            subDUVSmoothing = "pin_corners";
                            break;
                        }

                        MTime curTime = MAnimControl::currentTime();
                        // fnDagNode.findPlug("time").getValue( frame );

                        // MTime frameOffset;
                        // fnDagNode.findPlug("timeOffset").getValue( frameOffset );

                        float time = curTime.as(MTime::kFilm)+timeOffset;

                        MString argsString;
                        if (objectPath != "|"){
                                argsString += "-objectpath ";
                                // convert "|" to "/"

                                argsString += MString(replace_all(objectPath,"|","/").c_str());
                        }
                        if (objectPattern != "*"){
                                argsString += "-pattern ";
                                argsString += objectPattern;
                        }
                        if (excludePattern != ""){
                                argsString += "-excludepattern ";
                                argsString += excludePattern;
                        }
                        if (shutterOpen != 0.0){
                                argsString += " -shutteropen ";
                                argsString += shutterOpen;
                        }
                        if (shutterClose != 0.0){
                                argsString += " -shutterclose ";
                                argsString += shutterClose;
                        }
                        if (subDIterations != 0){
                                argsString += " -subditerations ";
                                argsString += subDIterations;
                                argsString += " -subduvsmoothing ";
                                argsString += subDUVSmoothing;
                        }
                        if (makeInstance){
                                argsString += " -makeinstance ";
                        }
                        if (nameprefix != ""){
                                argsString += " -nameprefix ";
                                argsString += nameprefix;
                        }
                        if (flipv){
                                argsString += " -flipv ";
                        }
                        if (invertNormals){
                                argsString += " -invertNormals ";
                        }
                        argsString += " -filename ";
                        argsString += abcFile;
                        argsString += " -frame ";
                        argsString += time;

                        if (m_displaced){

                            argsString += " -disp_map ";
                            argsString += AiNodeGetName(m_dispNode);

                        }

                        AiNodeSetStr(node, "data", argsString.asChar());

                        ExportUserAttrs(node);

                        // Export light linking per instance
                        ExportLightLinking(node);

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

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

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

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

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

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

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

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

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

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

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

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

    return status;
}
Ejemplo n.º 21
0
MStatus latticeNoiseNode::compute( const MPlug& plug, MDataBlock& data )
{ 
	MStatus returnStatus;

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

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


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

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

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

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

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

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

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

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

	return MS::kSuccess;
}
Ejemplo n.º 22
0
/**
 *	Build the animation from Maya MotionPath
 */
osg::ref_ptr<osg::AnimationPath> Transform::motionPath2AnimationPath(MObject &obj)
{
	osg::ref_ptr<osg::AnimationPath> anim = new osg::AnimationPath();

	// STEP 1. Get the animation curve from this MotionPath
	MFnMotionPath motion;

	MFnDependencyNode dn(obj);
	MPlugArray conns;
	dn.getConnections(conns);
	for(int i=0; i<conns.length(); i++){
		MPlug conn = conns[i];
		MPlugArray connectedTo;
		// Get the connections having this node as destination
		conn.connectedTo(connectedTo, true, false);
		for(int j=0; j<connectedTo.length(); j++){
			MPlug origin = connectedTo[j];
			MObject origin_node = origin.node();
			if(origin_node.hasFn(MFn::kMotionPath)){
				motion.setObject(origin_node);
				break;
			}
		}
	}

	MFnAnimCurve anim_curve;
	dn.setObject(motion.object());
	dn.getConnections(conns);
	for(int i=0; i<conns.length(); i++){
		MPlug conn = conns[i];
		MPlugArray connectedTo;
		// Get the connections having this node as destination
		conn.connectedTo(connectedTo, true, false);
		for(int j=0; j<connectedTo.length(); j++){
			MPlug origin = connectedTo[j];
			MObject origin_node = origin.node();
			if(origin_node.hasFn(MFn::kAnimCurve)){
				anim_curve.setObject(origin_node);
				break;
			}
		}
	}


	// STEP 2 ...


	// STEP 3. Benefits!

	for(int i=0; i<anim_curve.numKeys(); i++){

		MTime t = anim_curve.time(i);
		double time = t.as(MTime::kSeconds);

		MAnimControl::setCurrentTime(MTime(time,MTime::kSeconds));

		anim->insert(time, osg::AnimationPath::ControlPoint(
			getCPPosition(obj),
			getCPRotation(obj),
			getCPScale(obj)
			));
	}

	return anim;
}
 // -------------------------------------------
 void AnimationHelper::setAnimationEndTime ( float _time )
 {
     MTime time ( _time, MTime::kSeconds );
     double t = time.as ( MTime::uiUnit() );
     MGlobal::executeCommand ( MString ( "playbackOptions -" TEND " " ) + t );
 }