Example #1
0
MStatus sgBDataCmd_key::startExport( MString pathFolder )
{
	MStatus status;

	m_filePaths.clear();
	for( unsigned int i=0; i< m_pathArrExport.length(); i++ )
	{
		MFnDagNode fnNode( m_pathArrExport[i], &status );
		if( !status ) continue;
		MString targetName = fnNode.partialPathName();
		targetName.substitute( ":", "_" );
		targetName.substitute( "|", "_" );
		m_filePaths.append( pathFolder + "\\" + targetName + ".sgKeyData" );
	}

	m_objectKeyDatasExport.setLength( m_pathArrExport.length() );

	for( unsigned int i=0; i< m_pathArrExport.length(); i++ )
	{
		setObjectKeyDataDefault( m_objectKeyDatasExport[i], m_pathArrExport[i], m_exportByMatrix );

		unsigned int unit = MTime().unit();
		MString  nameTarget = MFnDagNode( m_pathArrExport[i] ).fullPathName();

		std::ofstream outFile( m_filePaths[i].asChar(), ios::binary );

		writeString( nameTarget, outFile );
		writeUnsignedInt( unit, outFile );
		writeStringArray( m_objectKeyDatasExport[i].namesAttribute, outFile );

		outFile.close();
	}
	return MS::kSuccess;
}
Example #2
0
bool cStructLoader::CheckUnmodified(void)
{
  time_t curr_mtime=MTime(false);
  if(mtime && mtime<curr_mtime && SL_TSTFLAG(SL_WATCH)) {
     PRINTF(L_CORE_LOAD,"abort save as file %s has been changed externaly",path);
     return false;
     }
  return true;
}
Example #3
0
MStatus sgBDataCmd_key::importData()
{
	MStatus status;

	MTime::Unit currentUnit = MTime().unit();

	MPlugArray connections;

	sgObject_keyData& objectKeyData = m_objectKeyDataImport;
	MObject& oTarget = objectKeyData.oTargetNode;
	MDoubleArray& dArrTime = objectKeyData.dArrTime;
	MTime::Unit unit = (MTime::Unit)objectKeyData.unit;
	MFnDagNode fnNode = oTarget;

	MPlugArray targetPlugs;

	unsigned int numAttr = objectKeyData.namesAttribute.length();
	unsigned int lengthTime = dArrTime.length();

	for( unsigned int j=0; j<numAttr; j++ )
	{
		if( numAttr <= j ) break;
		MPlug targetPlug = fnNode.findPlug( objectKeyData.namesAttribute[j] );
		
		targetPlug.connectedTo( connections, true, false );
		if( connections.length() ){
			m_dgMod_connection.disconnect( connections[0], targetPlug );
			m_dgMod_delete.deleteNode( connections[0].node() );
		}
		m_dgMod_connection.doIt();
		m_dgMod_delete.doIt();

		MObject oAnimCurve = MFnAnimCurve().create( targetPlug );
		m_oArrKeyAfter.append( oAnimCurve );
		MFnAnimCurve fnAnimCurve( oAnimCurve );
		for( unsigned int k=0; k<lengthTime; k++ )
		{
			double& dTime  = dArrTime[k];
			double& dValue = objectKeyData.dArrValuesArray[ k*numAttr+j ];

			MTime mTime( dTime, unit );
			mTime.setUnit( currentUnit );
			fnAnimCurve.addKeyframe( mTime, dValue );
		}
	}

	return MS::kSuccess;
};
static
bool
_GetTimeAndValueArrayForUsdAttribute(
        const UsdAttribute& usdAttr,
        const GfInterval& timeInterval,
        MTimeArray* timeArray,
        MDoubleArray* valueArray,
        const MDistance::Unit convertToUnit = MDistance::kMillimeters)
{
    static const TfType& floatType = TfType::Find<float>();
    std::vector<double> timeSamples;

    if (!_CheckUsdTypeAndResizeArrays(usdAttr,
                                      floatType,
                                      timeInterval,
                                      &timeSamples,
                                      timeArray,
                                      valueArray)) {
        return false;
    }

    size_t numTimeSamples = timeSamples.size();

    for (size_t i = 0; i < numTimeSamples; ++i) {
        const double timeSample = timeSamples[i];
        float attrValue;
        if (!usdAttr.Get(&attrValue, timeSample)) {
            return false;
        }

        switch (convertToUnit) {
            case MDistance::kInches:
                attrValue = UsdMayaUtil::ConvertMMToInches(attrValue);
                break;
            case MDistance::kCentimeters:
                attrValue = UsdMayaUtil::ConvertMMToCM(attrValue);
                break;
            default:
                // The input is expected to be in millimeters.
                break;
        }

        timeArray->set(MTime(timeSample), i);
        valueArray->set(attrValue, i);
    }

    return true;
}
Example #5
0
void cStructLoader::Save(void)
{
  if(CheckDoSave()) {
    cSafeFile f(path);
    if(f.Open()) {
      ListLock(false);
      for(cStructItem *it=First(); it; it=Next(it))
        if(!it->Deleted() && !it->Save(f)) break;
      f.Close();
      mtime=MTime(true);
      Modified(false);
      ListUnlock();
      PRINTF(L_CORE_LOAD,"saved %s to %s",type,path);
      }
    }
}
Example #6
0
	// Load a blend shape animation track
	Track BlendShape::loadTrack(float start,float stop,float rate,ParamList& params,int targetIndex,int startPoseId)
	{
		MStatus stat;
		MString msg;
		std::vector<float> times;
		// Create a track for current clip
		Track t;
		t.m_type = TT_POSE;
		t.m_target = m_target;
		t.m_index = targetIndex;
		t.m_vertexKeyframes.clear();
		// Calculate times from clip sample rate
		times.clear();
		if (rate <= 0)
		{
			std::cout << "invalid sample rate for the clip (must be >0), we skip it\n";
			std::cout.flush();
			return t;
		}
		for (float time=start; time<stop; time+=rate)
			times.push_back(time);
		times.push_back(stop);
		// Get animation length
		float length=0;
		if (times.size() >= 0)
			length = times[times.size()-1] - times[0];
		if (length < 0)
		{
			std::cout << "invalid time range for the clip, we skip it\n";
			std::cout.flush();
			return t;
		}
		// Evaluate animation curves at selected times
		for (int i=0; i<times.size(); i++)
		{
			// Set time to wanted sample time
			MAnimControl::setCurrentTime(MTime(times[i],MTime::kSeconds));
			// Load a keyframe at current time
			vertexKeyframe key = loadKeyframe(times[i]-times[0],params,targetIndex, startPoseId);
			// Add keyframe to joint track
			if (key.poserefs.size() > 0)
				t.addVertexKeyframe(key);
		}
		// Clip successfully loaded
		return t;
	}
Example #7
0
static
bool
_GetTimeAndValueArrayForUsdAttribute(
        const UsdAttribute& usdAttr,
        const PxrUsdMayaPrimReaderArgs& args,
        MTimeArray* timeArray,
        MDoubleArray* valueArray,
        bool millimetersToInches=false)
{
    static const TfType& floatType = TfType::Find<float>();
    std::vector<double> timeSamples;

    if (!_CheckUsdTypeAndResizeArrays(usdAttr,
                                         floatType,
                                         args,
                                         &timeSamples,
                                         timeArray,
                                         valueArray)) {
        return false;
    }

    size_t numTimeSamples = timeSamples.size();

    for (size_t i = 0; i < numTimeSamples; ++i) {
        const double timeSample = timeSamples[i];
        float attrValue;
        if (!usdAttr.Get(&attrValue, timeSample)) {
            return false;
        }
        if (millimetersToInches) {
            attrValue = PxrUsdMayaUtil::ConvertMMToInches(attrValue);
        }
        timeArray->set(MTime(timeSample), i);
        valueArray->set(attrValue, i);
    }

    return true;
}
// This is primarily intended for use in translating the clippingRange
// USD attribute which is stored in USD as a single GfVec2f value but
// in Maya as separate nearClipPlane and farClipPlane attributes.
static
bool
_GetTimeAndValueArraysForUsdAttribute(
        const UsdAttribute& usdAttr,
        const GfInterval& timeInterval,
        MTimeArray* timeArray,
        MDoubleArray* valueArray1,
        MDoubleArray* valueArray2)
{
    static const TfType& vec2fType = TfType::Find<GfVec2f>();
    std::vector<double> timeSamples;

    if (!_CheckUsdTypeAndResizeArrays(usdAttr,
                                      vec2fType,
                                      timeInterval,
                                      &timeSamples,
                                      timeArray,
                                      valueArray1)) {
        return false;
    }

    size_t numTimeSamples = timeSamples.size();
    valueArray2->setLength(numTimeSamples);

    for (size_t i = 0; i < numTimeSamples; ++i) {
        const double timeSample = timeSamples[i];
        GfVec2f attrValue;
        if (!usdAttr.Get(&attrValue, timeSample)) {
            return false;
        }
        timeArray->set(MTime(timeSample), i);
        valueArray1->set(attrValue[0], i);
        valueArray2->set(attrValue[1], i);
    }

    return true;
}
MStatus AlembicExportCommand::doIt(const MArgList &args)
{
  ESS_PROFILE_SCOPE("AlembicExportCommand::doIt");

  MStatus status = MS::kFailure;

  MTime currentAnimStartTime = MAnimControl::animationStartTime(),
        currentAnimEndTime = MAnimControl::animationEndTime(),
        oldCurTime = MAnimControl::currentTime(),
        curMinTime = MAnimControl::minTime(),
        curMaxTime = MAnimControl::maxTime();
  MArgParser argData(syntax(), args, &status);

  if (argData.isFlagSet("help")) {
    // TODO: implement help for this command
    // MGlobal::displayInfo(util::getHelpText());
    return MS::kSuccess;
  }

  unsigned int jobCount = argData.numberOfFlagUses("jobArg");
  MStringArray jobStrings;
  if (jobCount == 0) {
    // TODO: display dialog
    MGlobal::displayError("[ExocortexAlembic] No jobs specified.");
    MPxCommand::setResult(
        "Error caught in AlembicExportCommand::doIt: no job specified");
    return status;
  }
  else {
    // get all of the jobstrings
    for (unsigned int i = 0; i < jobCount; i++) {
      MArgList jobArgList;
      argData.getFlagArgumentList("jobArg", i, jobArgList);
      jobStrings.append(jobArgList.asString(0));
    }
  }

  // create a vector to store the jobs
  std::vector<AlembicWriteJob *> jobPtrs;
  double minFrame = 1000000.0;
  double maxFrame = -1000000.0;
  double maxSteps = 1;
  double maxSubsteps = 1;

  // init the curve accumulators
  AlembicCurveAccumulator::Initialize();

  try {
    // for each job, check the arguments
    bool failure = false;
    for (unsigned int i = 0; i < jobStrings.length(); ++i) {
      double frameIn = 1.0;
      double frameOut = 1.0;
      double frameSteps = 1.0;
      double frameSubSteps = 1.0;
      MString filename;
      bool purepointcache = false;
      bool normals = true;
      bool uvs = true;
      bool facesets = true;
      bool bindpose = true;
      bool dynamictopology = false;
      bool globalspace = false;
      bool withouthierarchy = false;
      bool transformcache = false;
      bool useInitShadGrp = false;
      bool useOgawa = false;  // Later, will need to be changed!

      MStringArray objectStrings;
      std::vector<std::string> prefixFilters;
      std::set<std::string> attributes;
      std::vector<std::string> userPrefixFilters;
      std::set<std::string> userAttributes;
      MObjectArray objects;
      std::string search_str, replace_str;

      // process all tokens of the job
      MStringArray tokens;
      jobStrings[i].split(';', tokens);
      for (unsigned int j = 0; j < tokens.length(); j++) {
        MStringArray valuePair;
        tokens[j].split('=', valuePair);
        if (valuePair.length() != 2) {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }

        const MString &lowerValue = valuePair[0].toLowerCase();
        if (lowerValue == "in") {
          frameIn = valuePair[1].asDouble();
        }
        else if (lowerValue == "out") {
          frameOut = valuePair[1].asDouble();
        }
        else if (lowerValue == "step") {
          frameSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "substep") {
          frameSubSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "normals") {
          normals = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "uvs") {
          uvs = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "facesets") {
          facesets = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "bindpose") {
          bindpose = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "purepointcache") {
          purepointcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "dynamictopology") {
          dynamictopology = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "globalspace") {
          globalspace = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "withouthierarchy") {
          withouthierarchy = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "transformcache") {
          transformcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "filename") {
          filename = valuePair[1];
        }
        else if (lowerValue == "objects") {
          // try to find each object
          valuePair[1].split(',', objectStrings);
        }
        else if (lowerValue == "useinitshadgrp") {
          useInitShadGrp = valuePair[1].asInt() != 0;
        }

        // search/replace
        else if (lowerValue == "search") {
          search_str = valuePair[1].asChar();
        }
        else if (lowerValue == "replace") {
          replace_str = valuePair[1].asChar();
        }
        else if (lowerValue == "ogawa") {
          useOgawa = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "attrprefixes") {
          splitListArg(valuePair[1], prefixFilters);
        }
        else if (lowerValue == "attrs") {
          splitListArg(valuePair[1], attributes);
        }
        else if (lowerValue == "userattrprefixes") {
          splitListArg(valuePair[1], userPrefixFilters);
        }
        else if (lowerValue == "userattrs") {
          splitListArg(valuePair[1], userAttributes);
        }
        else {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }
      }

      // now check the object strings
      for (unsigned int k = 0; k < objectStrings.length(); k++) {
        MSelectionList sl;
        MString objectString = objectStrings[k];
        sl.add(objectString);
        MDagPath dag;
        for (unsigned int l = 0; l < sl.length(); l++) {
          sl.getDagPath(l, dag);
          MObject objRef = dag.node();
          if (objRef.isNull()) {
            MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" +
                                    objectStrings[k] + "', not found.");
            break;
          }

          // get all parents
          MObjectArray parents;

          // check if this is a camera
          bool isCamera = false;
          for (unsigned int m = 0; m < dag.childCount(); ++m) {
            MFnDagNode child(dag.child(m));
            MFn::Type ctype = child.object().apiType();
            if (ctype == MFn::kCamera) {
              isCamera = true;
              break;
            }
          }

          if (dag.node().apiType() == MFn::kTransform && !isCamera &&
              !globalspace && !withouthierarchy) {
            MDagPath ppath = dag;
            while (!ppath.node().isNull() && ppath.length() > 0 &&
                   ppath.isValid()) {
              parents.append(ppath.node());
              if (ppath.pop() != MStatus::kSuccess) {
                break;
              }
            }
          }
          else {
            parents.append(dag.node());
          }

          // push all parents in
          while (parents.length() > 0) {
            bool found = false;
            for (unsigned int m = 0; m < objects.length(); m++) {
              if (objects[m] == parents[parents.length() - 1]) {
                found = true;
                break;
              }
            }
            if (!found) {
              objects.append(parents[parents.length() - 1]);
            }
            parents.remove(parents.length() - 1);
          }

          // check all of the shapes below
          if (!transformcache) {
            sl.getDagPath(l, dag);
            for (unsigned int m = 0; m < dag.childCount(); m++) {
              MFnDagNode child(dag.child(m));
              if (child.isIntermediateObject()) {
                continue;
              }
              objects.append(child.object());
            }
          }
        }
      }

      // check if we have incompatible subframes
      if (maxSubsteps > 1.0 && frameSubSteps > 1.0) {
        const double part = (frameSubSteps > maxSubsteps)
                                ? (frameSubSteps / maxSubsteps)
                                : (maxSubsteps / frameSubSteps);
        if (abs(part - floor(part)) > 0.001) {
          MString frameSubStepsStr, maxSubstepsStr;
          frameSubStepsStr.set(frameSubSteps);
          maxSubstepsStr.set(maxSubsteps);
          MGlobal::displayError(
              "[ExocortexAlembic] You cannot combine substeps " +
              frameSubStepsStr + " and " + maxSubstepsStr +
              " in one export. Aborting.");
          return MStatus::kInvalidParameter;
        }
      }

      // remember the min and max values for the frames
      if (frameIn < minFrame) {
        minFrame = frameIn;
      }
      if (frameOut > maxFrame) {
        maxFrame = frameOut;
      }
      if (frameSteps > maxSteps) {
        maxSteps = frameSteps;
      }
      if (frameSteps > 1.0) {
        frameSubSteps = 1.0;
      }
      if (frameSubSteps > maxSubsteps) {
        maxSubsteps = frameSubSteps;
      }

      // check if we have a filename
      if (filename.length() == 0) {
        MGlobal::displayError("[ExocortexAlembic] No filename specified.");
        for (size_t k = 0; k < jobPtrs.size(); k++) {
          delete (jobPtrs[k]);
        }
        MPxCommand::setResult(
            "Error caught in AlembicExportCommand::doIt: no filename "
            "specified");
        return MStatus::kFailure;
      }

      // construct the frames
      MDoubleArray frames;
      {
        const double frameIncr = frameSteps / frameSubSteps;
        for (double frame = frameIn; frame <= frameOut; frame += frameIncr) {
          frames.append(frame);
        }
      }

      AlembicWriteJob *job =
          new AlembicWriteJob(filename, objects, frames, useOgawa,
              prefixFilters, attributes, userPrefixFilters, userAttributes);
      job->SetOption("exportNormals", normals ? "1" : "0");
      job->SetOption("exportUVs", uvs ? "1" : "0");
      job->SetOption("exportFaceSets", facesets ? "1" : "0");
      job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0");
      job->SetOption("exportBindPose", bindpose ? "1" : "0");
      job->SetOption("exportPurePointCache", purepointcache ? "1" : "0");
      job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0");
      job->SetOption("indexedNormals", "1");
      job->SetOption("indexedUVs", "1");
      job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0");
      job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0");
      job->SetOption("transformCache", transformcache ? "1" : "0");

      // check if the search/replace strings are valid!
      if (search_str.length() ? !replace_str.length()
                              : replace_str.length())  // either search or
                                                       // replace string is
                                                       // missing or empty!
      {
        ESS_LOG_WARNING(
            "Missing search or replace parameter. No strings will be "
            "replaced.");
        job->replacer = SearchReplace::createReplacer();
      }
      else {
        job->replacer = SearchReplace::createReplacer(search_str, replace_str);
      }

      // check if the job is satifsied
      if (job->PreProcess() != MStatus::kSuccess) {
        MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied.");
        delete (job);
        failure = true;
        break;
      }

      // push the job to our registry
      MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" +
                           jobStrings[i]);
      jobPtrs.push_back(job);
    }

    if (failure) {
      for (size_t k = 0; k < jobPtrs.size(); k++) {
        delete (jobPtrs[k]);
      }
      return MS::kFailure;
    }

    // compute the job count
    unsigned int jobFrameCount = 0;
    for (size_t i = 0; i < jobPtrs.size(); i++)
      jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() *
                       (unsigned int)jobPtrs[i]->GetFrames().size();

    // now, let's run through all frames, and process the jobs
    const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit());
    const double incrSteps = maxSteps / maxSubsteps;
    double nextFrame = minFrame + incrSteps;

    for (double frame = minFrame; frame <= maxFrame;
         frame += incrSteps, nextFrame += incrSteps) {
      MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds));
      MAnimControl::setAnimationEndTime(
          MTime(nextFrame / frameRate, MTime::kSeconds));
      MAnimControl::playForward();  // this way, it forces Maya to play exactly
      // one frame! and particles are updated!

      AlembicCurveAccumulator::StartRecordingFrame();
      for (size_t i = 0; i < jobPtrs.size(); i++) {
        MStatus status = jobPtrs[i]->Process(frame);
        if (status != MStatus::kSuccess) {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :" +
                                jobPtrs[i]->GetFileName());
          for (size_t k = 0; k < jobPtrs.size(); k++) {
            delete (jobPtrs[k]);
          }
          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                         curMinTime, curMaxTime);
          return status;
        }
      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
  }
  catch (...) {
    MGlobal::displayError(
        "[ExocortexAlembic] Jobs aborted, force closing all archives!");
    for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin();
         beg != jobPtrs.end(); ++beg) {
      (*beg)->forceCloseArchive();
    }
    restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                   curMinTime, curMaxTime);
    MPxCommand::setResult("Error caught in AlembicExportCommand::doIt");
    status = MS::kFailure;
  }
  MAnimControl::stop();
  AlembicCurveAccumulator::Destroy();

  // restore the animation start/end time and the current time!
  restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                 curMinTime, curMaxTime);

  // delete all jobs
  for (size_t k = 0; k < jobPtrs.size(); k++) {
    delete (jobPtrs[k]);
  }

  // remove all known archives
  deleteAllArchives();
  return status;
}
MStatus AlembicWriteJob::PreProcess()
{
  ESS_PROFILE_SCOPE("AlembicWriteJob::PreProcess");
  // check filenames
  if (mFileName.length() == 0) {
    MGlobal::displayError("[ExocortexAlembic] No filename specified.");
    MPxCommand::setResult(
        "Error caught in AlembicWriteJob::PreProcess: no filename specified");
    return MStatus::kInvalidParameter;
  }

  // check objects
  if (mSelection.length() == 0) {
    MGlobal::displayError("[ExocortexAlembic] No objects specified.");
    MPxCommand::setResult(
        "Error caught in AlembicWriteJob::PreProcess: no objects specified");
    return MStatus::kInvalidParameter;
  }

  // check frames
  if (mFrames.size() == 0) {
    MGlobal::displayError("[ExocortexAlembic] No frames specified.");
    MPxCommand::setResult(
        "Error caught in AlembicWriteJob::PreProcess: no frame specified");
    return MStatus::kInvalidParameter;
  }

  // check if the file is currently in use
  if (getRefArchive(mFileName) > 0) {
    MGlobal::displayError("[ExocortexAlembic] Error writing to file '" +
                          mFileName + "'. File currently in use.");
    MPxCommand::setResult(
        "Error caught in AlembicWriteJob::PreProcess: no filename already in "
        "use");
    return MStatus::kInvalidParameter;
  }

  // init archive (use a locally scoped archive)
  // TODO: determine how to access the current maya scene path
  // MString sceneFileName = "Exported from:
  // "+Application().GetActiveProject().GetActiveScene().GetParameterValue("FileName").GetAsText();
  try {
    createArchive("Exported from Maya.");

    mTop = mArchive.getTop();

    // get the frame rate
    mFrameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit());
    const double timePerSample = 1.0 / mFrameRate;
    std::vector<AbcA::chrono_t> frames;
    for (LONG i = 0; i < mFrames.size(); i++) {
      frames.push_back(mFrames[i] * timePerSample);
    }

    // create the sampling
    if (frames.size() > 1) {
      const double timePerCycle = frames[frames.size() - 1] - frames[0];
      AbcA::TimeSamplingType samplingType((Abc::uint32_t)frames.size(),
                                          timePerCycle);
      AbcA::TimeSampling sampling(samplingType, frames);
      mTs = mArchive.addTimeSampling(sampling);
    }
    else {
      AbcA::TimeSampling sampling(1.0, frames[0]);
      mTs = mArchive.addTimeSampling(sampling);
    }
    Abc::OBox3dProperty boxProp = AbcG::CreateOArchiveBounds(mArchive, mTs);

    MDagPath dagPath;
    {
      MItDag().getPath(dagPath);
    }
    SceneNodePtr exoSceneRoot = buildMayaSceneGraph(dagPath, this->replacer);
    const bool bFlattenHierarchy = GetOption("flattenHierarchy") == "1";
    const bool bTransformCache = GetOption("transformCache") == "1";
    const bool bSelectChildren = false;
    {
      std::map<std::string, bool> selectionMap;
      for (int i = 0; i < (int)mSelection.length(); ++i) {
        MFnDagNode dagNode(mSelection[i]);
        selectionMap[dagNode.fullPathName().asChar()] = true;
      }
      selectNodes(exoSceneRoot, selectionMap,
                  !bFlattenHierarchy || bTransformCache, bSelectChildren,
                  !bTransformCache, true);
    }

    // create object for each
    MProgressWindow::reserve();
    MProgressWindow::setTitle("Alembic Export: Listing objects");
    MProgressWindow::setInterruptable(true);
    MProgressWindow::setProgressRange(0, mSelection.length());
    MProgressWindow::setProgress(0);

    MProgressWindow::startProgress();
    int interrupt = 20;
    bool processStopped = false;
    std::deque<PreProcessStackElement> sceneStack;

    sceneStack.push_back(PreProcessStackElement(exoSceneRoot, mTop));

    while (!sceneStack.empty()) {
      if (--interrupt == 0) {
        interrupt = 20;
        if (MProgressWindow::isCancelled()) {
          processStopped = true;
          break;
        }
      }

      PreProcessStackElement &sElement = sceneStack.back();
      SceneNodePtr eNode = sElement.eNode;
      sceneStack.pop_back();

      Abc::OObject oParent = sElement.oParent;
      Abc::OObject oNewParent;

      AlembicObjectPtr pNewObject;
      if (eNode->selected) {
        switch (eNode->type) {
          case SceneNode::SCENE_ROOT:
            break;
          case SceneNode::ITRANSFORM:
          case SceneNode::ETRANSFORM:
            pNewObject.reset(new AlembicXform(eNode, this, oParent));
            break;
          case SceneNode::CAMERA:
            pNewObject.reset(new AlembicCamera(eNode, this, oParent));
            break;
          case SceneNode::POLYMESH:
            pNewObject.reset(new AlembicPolyMesh(eNode, this, oParent));
            break;
          case SceneNode::SUBD:
            pNewObject.reset(new AlembicSubD(eNode, this, oParent));
            break;
          case SceneNode::CURVES:
            pNewObject.reset(new AlembicCurves(eNode, this, oParent));
            break;
          case SceneNode::PARTICLES:
            pNewObject.reset(new AlembicPoints(eNode, this, oParent));
            break;
          case SceneNode::HAIR:
            pNewObject.reset(new AlembicHair(eNode, this, oParent));
            break;
          default:
            ESS_LOG_WARNING("Unknown type: not exporting " << eNode->name);
        }
      }

      if (pNewObject) {
        AddObject(pNewObject);
        oNewParent = oParent.getChild(eNode->name);
      }
      else {
        oNewParent = oParent;
      }

      if (oNewParent.valid()) {
        for (std::list<SceneNodePtr>::iterator it = eNode->children.begin();
             it != eNode->children.end(); ++it) {
          if (!bFlattenHierarchy ||
              (bFlattenHierarchy && eNode->type == SceneNode::ETRANSFORM &&
               isShapeNode((*it)->type))) {
            // If flattening the hierarchy, we want to attach each external
            // transform to its corresponding geometry node.
            // All internal transforms should be skipped. Geometry nodes will
            // never have children (If and XSI geonode is parented
            // to another geonode, each will be parented to its extracted
            // transform node, and one node will be parented to the
            // transform of the other.
            sceneStack.push_back(PreProcessStackElement(*it, oNewParent));
          }
          else {
            // if we skip node A, we parent node A's children to the parent of A
            sceneStack.push_back(PreProcessStackElement(*it, oParent));
          }
        }
      }
      //*
      else {
        ESS_LOG_ERROR("Do not have reference to parent.");
        MPxCommand::setResult(
            "Error caught in AlembicWriteJob::PreProcess: do not have "
            "reference to parent");
        return MS::kFailure;
      }
      //*/
    }

    MProgressWindow::endProgress();
    return processStopped ? MStatus::kEndOfFile : MStatus::kSuccess;
  }
  catch (AbcU::Exception &e) {
    this->forceCloseArchive();
    MString exc(e.what());
    MGlobal::displayError("[ExocortexAlembic] Error writing to file '" +
                          mFileName + "' (" + exc +
                          "). Do you still have it opened?");
    MPxCommand::setResult(
        "Error caught in AlembicWriteJob::PreProcess: error writing file");
  }

  return MS::kFailure;
}
Example #11
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;
}
Example #12
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";
			}
		}*/
	}
Example #13
0
//-*****************************************************************************
MStatus AbcExportSelected( const Parameters &iConfig )
{
    // Abc::Init();
    
    //-*************************************************************************
    // CREATE SELECTION LIST
    //-*************************************************************************
    MSelectionList slist;
    MGlobal::getActiveSelectionList( slist );
    if ( slist.length() == 0 )
    {
        MGlobal::displayError( "Nothing selected." );
        return MS::kFailure;
    }

    //-*************************************************************************
    // CREATE THE ARCHIVE
    //-*************************************************************************
    if ( iConfig.fileName == "UNSPECIFIED_FILE_NAME.abc" ||
         iConfig.fileName == "" )
    {
        MGlobal::displayError( "No filename specified." );
        return MStatus::kFailure;
    }
        
    // Create the time sampling.
    Abc::TimeSamplingType tSmpType;
    if ( iConfig.endFrame > iConfig.startFrame )
    {
        tSmpType = Abc::TimeSamplingType(
                
            // Increment, in seconds, between samples.
            ( Abc::chrono_t )
            MTime( 1.0, MTime::uiUnit() ).as( MTime::kSeconds ) );
    }

    // Get FPS
    Abc::chrono_t fps =
        MTime( 1.0, MTime::kSeconds ).as( MTime::uiUnit() );
        
    Top top( iConfig.fileName, tSmpType, fps );
        
    std::cout << "AlembicSimpleAbcExport: Opened Alembic Archive: "
              << top.getName()
              << " for writing." << std::endl;
        
    // Build comments
    std::string comments = "AlembicSimpleAbcExport v0.1.1";
    comments += "\n";
    MString exportedFromStr =
        "(Exported from " + MFileIO::currentFile() + ")";
    comments += exportedFromStr.asChar();
    comments += "\n";
    // top.setComments( comments );


    //-*********************************************************************
    // BUILD TREE OF NODE:OBJECT PAIRS TO EXPORT
    //-*********************************************************************
    
    // Create the factory
    Factory factory( iConfig );
    
    for ( MItSelectionList liter( slist ); !liter.isDone(); liter.next() )
    {
        MDagPath dagPath;
        MObject component;
        liter.getDagPath( dagPath, component );
            
        // This will skip nodes we've already visited. HAVE NO
        // FEAR.
        factory.makeTree( top, dagPath, 1000000, tSmpType );
    }
    std::cout << "AlembicSimpleAbcExport: Created DAG Tree to export."
              << std::endl;

    //-*********************************************************************
    // EXPORT SAMPLES PER FRAME
    //-*********************************************************************
    
    // Loop over time
    MComputation computation;
    computation.beginComputation();
    for ( int frame = iConfig.startFrame;
          frame <= iConfig.endFrame; ++frame )
    {   
        // Get a time.
        MTime thisTime( ( double )frame, MTime::uiUnit() );
            
        // Set the time.
        MAnimControl::setCurrentTime( thisTime );
            
        // Get the chrono and the index
        Abc::index_t frameIndex =
            ( Abc::index_t )( frame - iConfig.startFrame );
        Abc::chrono_t frameTime =
            ( Abc::chrono_t )thisTime.as( MTime::kSeconds );
        
        // Is this necessary to force an eval?  Sometimes?
        // MGlobal::viewFrame( t );
        // M3dView currentView = M3dView::active3dView();
        // currentView.refresh( true, true, true );
            
        // Write the frame.
        top.writeSample( Abc::OSampleSelector( frameIndex, frameTime ) );
        std::cout << "AlembicSimpleAbcExport: Wrote frame: "
                  << frame << std::endl;
            
        if ( computation.isInterruptRequested() )
        {
            break;
        }
    }
        
    top.close();
    computation.endComputation();
    // H5close();

    std::cout << "AlembicSimpleAbcExport: Closed Archive." << std::endl;
    return MS::kSuccess;
}
Example #14
0
/* static */
bool
PxrUsdMayaTranslatorCurves::Create(
        const UsdGeomCurves& curves,
        MObject parentNode,
        const PxrUsdMayaPrimReaderArgs& args,
        PxrUsdMayaPrimReaderContext* context)
{
    if (not curves) {
        return false;
    }

    const UsdPrim& prim = curves.GetPrim();

    MStatus status;

    // Create node (transform)
    MObject mayaNodeTransformObj;
    if (not PxrUsdMayaTranslatorUtil::CreateTransformNode(prim,
                                                          parentNode,
                                                          args,
                                                          context,
                                                          &status,
                                                          &mayaNodeTransformObj)) {
        return false;
    }

    VtArray<GfVec3f> points;
    VtArray<int>     curveOrder;
    VtArray<int>     curveVertexCounts;
    VtArray<float>   curveWidths;
    VtArray<GfVec2d> curveRanges;
    VtArray<double>  curveKnots;

    // LIMITATION:  xxx REVISIT xxx
    //   Non-animated Attrs
    //   Assuming that a number of these USD attributes are assumed to not be animated
    //   Some we may want to expose as animatable later.
    //
    curves.GetCurveVertexCountsAttr().Get(&curveVertexCounts); // not animatable

    // XXX:
    // Only supporting single curve for now.
    // Sanity Checks
    if (curveVertexCounts.size() == 0) {
        MGlobal::displayError(
            TfStringPrintf("VertexCount arrays is empty on NURBS curves <%s>. Skipping...", 
                            prim.GetPath().GetText()).c_str());
        return false; // No verts for the curve, so exit
    } else if (curveVertexCounts.size() > 1) {
        MGlobal::displayWarning(
            TfStringPrintf("Multiple curves in <%s>. Reading first one...", 
                            prim.GetPath().GetText()).c_str());
    }

    int curveIndex = 0;
    curves.GetWidthsAttr().Get(&curveWidths); // not animatable

    // Gather points. If args.GetReadAnimData() is TRUE,
    // pick the first avaiable sample or default
    UsdTimeCode pointsTimeSample=UsdTimeCode::EarliestTime();
    std::vector<double> pointsTimeSamples;
    size_t numTimeSamples = 0;
    if (args.GetReadAnimData()) {
        curves.GetPointsAttr().GetTimeSamples(&pointsTimeSamples);
        numTimeSamples = pointsTimeSamples.size();
        if (numTimeSamples>0) {
            pointsTimeSample = pointsTimeSamples[0];
        }
    }
    curves.GetPointsAttr().Get(&points, pointsTimeSample);
    
    if (points.size() == 0) {
        MGlobal::displayError(
            TfStringPrintf("Points arrays is empty on NURBS curves <%s>. Skipping...", 
                            prim.GetPath().GetText()).c_str());
        return false; // invalid nurbscurves, so exit
    }

    if (UsdGeomNurbsCurves nurbsSchema = UsdGeomNurbsCurves(prim)) {
        nurbsSchema.GetOrderAttr().Get(&curveOrder);   // not animatable
        nurbsSchema.GetKnotsAttr().Get(&curveKnots);   // not animatable
        nurbsSchema.GetRangesAttr().Get(&curveRanges); // not animatable
    } else {

        // Handle basis curves originally modelled in Maya as nurbs.

        curveOrder.resize(1);
        UsdGeomBasisCurves basisSchema = UsdGeomBasisCurves(prim);
        TfToken typeToken;
        basisSchema.GetTypeAttr().Get(&typeToken);
        if (typeToken == UsdGeomTokens->linear) {
            curveOrder[0] = 2;
            curveKnots.resize(points.size());
            for (size_t i=0; i < curveKnots.size(); ++i) {
                curveKnots[i] = i;
            }
        } else {
            curveOrder[0] = 4;

            // Strip off extra end points; assuming this is non-periodic.
            VtArray<GfVec3f> tmpPts(points.size() - 2);
            std::copy(points.begin() + 1, points.end() - 1, tmpPts.begin());
            points.swap(tmpPts);

            // Cubic curves in Maya have numSpans + 2*3 - 1, and for geometry
            // that came in as basis curves, we have numCV's - 3 spans.  See the
            // MFnNurbsCurve documentation and the nurbs curve export
            // implementation in mojitoplugmaya for more details.
            curveKnots.resize(points.size() -3 + 5);
            int knotIdx = 0;
            for (size_t i=0; i < curveKnots.size(); ++i) {
                if (i < 3) {
                    curveKnots[i] = 0.0;
                } else {
                    if (i <= curveKnots.size() - 3) {
                        ++knotIdx;
                    }
                    curveKnots[i] = double(knotIdx);
                } 
            }
        }
    }

    // == Convert data
    size_t mayaNumVertices = points.size();
    MPointArray mayaPoints(mayaNumVertices);
    for (size_t i=0; i < mayaNumVertices; i++) {
        mayaPoints.set( i, points[i][0], points[i][1], points[i][2] );
    }

    double *knots=curveKnots.data();
    MDoubleArray mayaKnots( knots, curveKnots.size());

    int mayaDegree = curveOrder[curveIndex] - 1;

    MFnNurbsCurve::Form mayaCurveForm = MFnNurbsCurve::kOpen; // HARDCODED
    bool mayaCurveCreate2D = false;
    bool mayaCurveCreateRational = true;

    // == Create NurbsCurve Shape Node
    MFnNurbsCurve curveFn;
    MObject curveObj = curveFn.create(mayaPoints, 
                                     mayaKnots,
                                     mayaDegree,
                                     mayaCurveForm,
                                     mayaCurveCreate2D,
                                     mayaCurveCreateRational,
                                     mayaNodeTransformObj,
                                     &status
                                     );
     if (status != MS::kSuccess) {
         return false;
     }
    MString nodeName( prim.GetName().GetText() );
    nodeName += "Shape";
    curveFn.setName(nodeName, false, &status);

    std::string nodePath( prim.GetPath().GetText() );
    nodePath += "/";
    nodePath += nodeName.asChar();
    if (context) {
        context->RegisterNewMayaNode( nodePath, curveObj ); // used for undo/redo
    }

    // == Animate points ==
    //   Use blendShapeDeformer so that all the points for a frame are contained in a single node
    //   Almost identical code as used with MayaMeshReader.cpp
    //
    if (numTimeSamples > 0) {
        MPointArray mayaPoints(mayaNumVertices);
        MObject curveAnimObj;

        MFnBlendShapeDeformer blendFn;
        MObject blendObj = blendFn.create(curveObj);
        if (context) {
            context->RegisterNewMayaNode(blendFn.name().asChar(), blendObj ); // used for undo/redo
        }
        
        for (unsigned int ti=0; ti < numTimeSamples; ++ti) {
             curves.GetPointsAttr().Get(&points, pointsTimeSamples[ti]);

            for (unsigned int i=0; i < mayaNumVertices; i++) {
                mayaPoints.set( i, points[i][0], points[i][1], points[i][2] );
            }

            // == Create NurbsCurve Shape Node
            MFnNurbsCurve curveFn;
            if ( curveAnimObj.isNull() ) {
                curveAnimObj = curveFn.create(mayaPoints, 
                                     mayaKnots,
                                     mayaDegree,
                                     mayaCurveForm,
                                     mayaCurveCreate2D,
                                     mayaCurveCreateRational,
                                     mayaNodeTransformObj,
                                     &status
                                     );
                if (status != MS::kSuccess) {
                    continue;
                }
            }
            else {
                // Reuse the already created curve by copying it and then setting the points
                curveAnimObj = curveFn.copy(curveAnimObj, mayaNodeTransformObj, &status);
                curveFn.setCVs(mayaPoints);
            }
            blendFn.addTarget(curveObj, ti, curveAnimObj, 1.0);
            curveFn.setIntermediateObject(true);
            if (context) {
                context->RegisterNewMayaNode( curveFn.fullPathName().asChar(), curveAnimObj ); // used for undo/redo
            }
        }

        // Animate the weights so that curve0 has a weight of 1 at frame 0, etc.
        MFnAnimCurve animFn;

        // Construct the time array to be used for all the keys
        MTimeArray timeArray;
        timeArray.setLength(numTimeSamples);
        for (unsigned int ti=0; ti < numTimeSamples; ++ti) {
            timeArray.set( MTime(pointsTimeSamples[ti]), ti);
        }

        // Key/Animate the weights
        MPlug plgAry = blendFn.findPlug( "weight" );
        if ( !plgAry.isNull() && plgAry.isArray() ) {
            for (unsigned int ti=0; ti < numTimeSamples; ++ti) {
                MPlug plg = plgAry.elementByLogicalIndex(ti, &status);
                MDoubleArray valueArray(numTimeSamples, 0.0);
                valueArray[ti] = 1.0; // Set the time value where this curve's weight should be 1.0
                MObject animObj = animFn.create(plg, NULL, &status);
                animFn.addKeys(&timeArray, &valueArray);
                if (context) {
                    context->RegisterNewMayaNode(animFn.name().asChar(), animObj ); // used for undo/redo
                }
            }
        }
    }

    return true;
}
Example #15
0
// Load an animation clip
MStatus skeleton::loadClip(MString clipName,int start,int stop,int rate)
{
	uint fps = getFps();
	float frameTime = 1000.0f / fps;

	MStatus stat;
	int i,j;
	std::vector<int> times;
	if (m_joints.size() < 0)
		return MS::kFailure;

	times.clear();
	for (int t=start; t<stop; t+=rate)
		times.push_back(t);
	times.push_back(stop);

	// create the animation
	animation a;
	a.name = clipName.asChar();
	
	if(m_animations.size() == 0)
	{
		a.startTime = 0;
		a.endTime = times[times.size()-1] - times[0];
	}
	else
	{
		a.startTime = m_animations[m_animations.size()-1].endTime + 1;
		a.endTime = a.startTime + times[times.size()-1] - times[0];
	}

	m_animations.push_back(a);
	int animIdx = m_animations.size() - 1;

	for (i=0; i<times.size(); i++)
	{
		MAnimControl::setCurrentTime(MTime(times[i],MTime::uiUnit()));
		for (j=0; j<m_joints.size(); j++)
		{
			keyframeTranslation translation;
			keyframeRotation rotation;
			keyframeScale scale;

			joint &jt = m_joints[j];
			int time = times[i] - times[0] + a.startTime;
			loadKeyframe(m_joints[j],time,translation,rotation,scale);
			translation.time *= frameTime;
			rotation.time *= frameTime;
			scale.time *= frameTime;

			size_t size = jt.keyframesTranslation.size();
			if(size > 0)
			{
				keyframeTranslation& t = jt.keyframesTranslation[size - 1];
				if(!equal(translation.v[0],t.v[0]) || !equal(translation.v[1],t.v[1]) || !equal(translation.v[2],t.v[2]))
				{
					//如果跟上一次不一样,并且跨越了桢,那么需要补一桢
					int lastTime = Round(t.time / frameTime);
					if(time - 1 > lastTime)
					{
						keyframeTranslation temp = t;
						temp.time = (time - 1) * frameTime;
						jt.keyframesTranslation.push_back(temp);
					}
					jt.keyframesTranslation.push_back(translation);
				}
			}
			else
			{
				jt.keyframesTranslation.push_back(translation);
			}

			MFnIkJoint jn(jt.jointDag);
			if(jn.name() == "Hips")
			{
//				breakable;
			}
			size = jt.keyframesRotation.size();
			if(size > 0)
			{
				keyframeRotation& r = jt.keyframesRotation[size - 1];
				if(!equal(rotation.q[0],r.q[0]) || !equal(rotation.q[1],r.q[1]) || !equal(rotation.q[2],r.q[2]) || !equal(rotation.q[3],r.q[3]))
				{
					//如果跟上一次不一样,并且跨越了桢,那么需要补一桢
					int lastTime = Round(r.time / frameTime);
					if(time - 1 > lastTime)
					{
						keyframeRotation temp = r;
						temp.time = (time - 1) * frameTime;
						jt.keyframesRotation.push_back(temp);
					}
					jt.keyframesRotation.push_back(rotation);
				}
			}
			else
			{
				jt.keyframesRotation.push_back(rotation);
			}
			size = jt.keyframesScale.size();
			if(size > 0)
			{
				keyframeScale& s = jt.keyframesScale[size - 1];
				if(!equal(scale.v[0],s.v[0]) || !equal(scale.v[1],s.v[1]) || !equal(scale.v[2],s.v[2]))
				{
					//如果跟上一次不一样,并且跨越了桢,那么需要补一桢
					int lastTime = Round(s.time / frameTime);
					if(time - 1 > lastTime)
					{
						keyframeScale temp = s;
						temp.time = (time - 1) * frameTime;
						jt.keyframesScale.push_back(temp);
					}
					jt.keyframesScale.push_back(scale);
				}
			}
			else
			{
				jt.keyframesScale.push_back(scale);
			}

			if(jt.hasRibbonSystem)
			{
				keyframeT<bool> keyframeVisible;
				keyframeT<float> keyframeAbove;
				keyframeT<float> keyframeBelow;
				keyframeT<short> keyframeSlot;
				keyframeT<float3> keyframeColor;
				keyframeT<float> keyframeAlpha;

				MFnIkJoint jointFn(jt.jointDag);
				MPlug plug;

				plug = jointFn.findPlug("unRibbonVisible");
				bool visible;
				plug.getValue(visible);
				plug = jointFn.findPlug("unRibbonAbove");
				float above;
				plug.getValue(above);
				plug = jointFn.findPlug("unRibbonBelow");
				float below;
				plug.getValue(below);
				plug = jointFn.findPlug("unRibbonTextureSlot");
				short slot;
				plug.getValue(slot);
				plug = jointFn.findPlug("unRibbonVertexColor");
				MObject object;
				plug.getValue(object);
				MFnNumericData data(object);
				float r,g,b;
				data.getData(r,g,b);
				plug = jointFn.findPlug("unRibbonVertexAlpha");
				float alpha;
				plug.getValue(alpha);

				keyframeVisible.time = time * frameTime;
				keyframeAbove.time = time * frameTime;
				keyframeBelow.time = time * frameTime;
				keyframeSlot.time = time * frameTime;
				keyframeColor.time = time * frameTime;
				keyframeAlpha.time = time * frameTime;

				keyframeVisible.data = visible;
				keyframeAbove.data = above;
				keyframeBelow.data = below;
				keyframeSlot.data = slot;
				keyframeColor.data[0] = r;
				keyframeColor.data[1] = g;
				keyframeColor.data[2] = b;
				keyframeAlpha.data = alpha;

				addKeyFramesBool(&jt.ribbon.keyframesVisible,&keyframeVisible);
				addKeyFramesFloat(&jt.ribbon.keyframeAbove,&keyframeAbove);
				addKeyFramesFloat(&jt.ribbon.keyframeBelow,&keyframeBelow);
				size = jt.ribbon.keyframeSlot.size();
				if(size > 0)
				{
					keyframeT<short>& s = jt.ribbon.keyframeSlot[size - 1];
					if(s.data == slot)
					{
						jt.ribbon.keyframeSlot.push_back(keyframeSlot);
					}
				}
				else
				{
					jt.ribbon.keyframeSlot.push_back(keyframeSlot);
				}
				size = jt.ribbon.keyframeColor.size();
				if(size > 0)
				{
					keyframeT<float3>& s = jt.ribbon.keyframeColor[size - 1];
					if(!equal(s.data[0],r) || !equal(s.data[1],g) || !equal(s.data[2],b))
					{
						jt.ribbon.keyframeColor.push_back(keyframeColor);
					}
				}
				else
				{
					jt.ribbon.keyframeColor.push_back(keyframeColor);
				}
				addKeyFramesFloat(&jt.ribbon.keyframeAlpha,&keyframeAlpha);
			}
			if(jt.hasParticleSystem)
			{
				keyframeT<bool> keyframeVisible;
				keyframeT<float> keyframeSpeed;
				keyframeT<float> keyframeVariation;
				keyframeT<float> keyframeConeAngle;
				keyframeT<float> keyframeGravity;
				keyframeT<float> keyframeExplosiveForce;
				keyframeT<float> keyframeEmissionRate;
				keyframeT<float> keyframeWidth;
				keyframeT<float> keyframeLength;
				keyframeT<float> keyframeHeight;

				MFnIkJoint jointFn(jt.jointDag);
				MPlug plug;

				plug = jointFn.findPlug("unParticleVisible");
				bool visible;
				plug.getValue(visible);
				plug = jointFn.findPlug("unParticleSpeed");
				float speed;
				plug.getValue(speed);
				plug = jointFn.findPlug("unParticleVariationPercent");
				float variation;
				plug.getValue(variation);
				plug = jointFn.findPlug("unParticleConeAngle");
				float coneAngle;
				plug.getValue(coneAngle);
				plug = jointFn.findPlug("unParticleGravity");
				float gravity;
				plug.getValue(gravity);
				plug = jointFn.findPlug("unParticleExplosiveForce");
				float explosiveForce = 0.0f;
				if(!plug.isNull())
				{
					plug.getValue(explosiveForce);
				}
				plug = jointFn.findPlug("unParticleEmissionRate");
				float emissionRate;
				plug.getValue(emissionRate);
				plug = jointFn.findPlug("unParticleEmitterWidth");
				float width;
				plug.getValue(width);
				plug = jointFn.findPlug("unParticleEmitterLength");
				float length;
				plug.getValue(length);
				plug = jointFn.findPlug("unParticleEmitterHeight");
				float height = 0.0f;
				if(!plug.isNull())
				{
					plug.getValue(height);
				}

				keyframeVisible.time = time * frameTime;
				keyframeSpeed.time = time * frameTime;
				keyframeVariation.time = time * frameTime;
				keyframeConeAngle.time = time * frameTime;
				keyframeGravity.time = time * frameTime;
				keyframeExplosiveForce.time = time * frameTime;
				keyframeEmissionRate.time = time * frameTime;
				keyframeWidth.time = time * frameTime;
				keyframeLength.time = time * frameTime;
				keyframeHeight.time = time * frameTime;

				keyframeVisible.data = visible;
				keyframeSpeed.data = speed;
				keyframeVariation.data = variation / 100.0f;
				keyframeConeAngle.data = coneAngle;
				keyframeGravity.data = gravity;
				keyframeExplosiveForce.data = explosiveForce;
				keyframeEmissionRate.data = emissionRate;
				keyframeWidth.data = width;
				keyframeLength.data = length;
				keyframeHeight.data = height;

				addKeyFramesBool(&jt.particle.keyframesVisible,&keyframeVisible);
				addKeyFramesFloat(&jt.particle.keyframesSpeed,&keyframeSpeed);
				addKeyFramesFloat(&jt.particle.keyframesVariation,&keyframeVariation);
				addKeyFramesFloat(&jt.particle.keyframesConeAngle,&keyframeConeAngle);
				addKeyFramesFloat(&jt.particle.keyframesGravity,&keyframeGravity);
				addKeyFramesFloat(&jt.particle.keyframesExplosiveForce,&keyframeExplosiveForce);
				addKeyFramesFloat(&jt.particle.keyframesEmissionRate,&keyframeEmissionRate);
				addKeyFramesFloat(&jt.particle.keyframesWidth,&keyframeWidth);
				addKeyFramesFloat(&jt.particle.keyframesLength,&keyframeLength);
				addKeyFramesFloat(&jt.particle.keyframesHeight,&keyframeHeight);
			}
		}
	}

	return MS::kSuccess;
}
void NifAnimationImporter::ImportControllers( NiAVObjectRef niAVObj, MDagPath & path ) {
	list<NiTimeControllerRef> controllers = niAVObj->GetControllers();

	//Iterate over the controllers, reacting properly to each type
	for ( list<NiTimeControllerRef>::iterator it = controllers.begin(); it != controllers.end(); ++it ) {
		if ( (*it)->IsDerivedType( NiKeyframeController::TYPE ) ) {
			//--NiKeyframeController--//
			NiKeyframeControllerRef niKeyCont = DynamicCast<NiKeyframeController>(*it);

			NiKeyframeDataRef niKeyData = niKeyCont->GetData();

			MFnTransform transFn( path.node() );

			MFnAnimCurve traXFn;
			MFnAnimCurve traYFn;
			MFnAnimCurve traZFn;

			MObject traXcurve = traXFn.create( transFn.findPlug("translateX") );
			MObject traYcurve = traYFn.create( transFn.findPlug("translateY") );
			MObject traZcurve = traZFn.create( transFn.findPlug("translateZ") );

			MTimeArray traTimes;
			MDoubleArray traXValues;
			MDoubleArray traYValues;
			MDoubleArray traZValues;

			vector<Key<Vector3> > tra_keys = niKeyData->GetTranslateKeys();

			for ( size_t i = 0; i < tra_keys.size(); ++i) {
				traTimes.append( MTime( tra_keys[i].time, MTime::kSeconds ) );
				traXValues.append( tra_keys[i].data.x );
				traYValues.append( tra_keys[i].data.y );
				traZValues.append( tra_keys[i].data.z );

				//traXFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.x );
				//traYFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.y );
				//traZFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.z );
			}

			traXFn.addKeys( &traTimes, &traXValues );
			traYFn.addKeys( &traTimes, &traYValues );
			traZFn.addKeys( &traTimes, &traZValues );

			KeyType kt = niKeyData->GetRotateType();

			if ( kt != XYZ_ROTATION_KEY ) {
				vector<Key<Quaternion> > rot_keys = niKeyData->GetQuatRotateKeys();

				MFnAnimCurve rotXFn;
				MFnAnimCurve rotYFn;
				MFnAnimCurve rotZFn;

				MObject rotXcurve = rotXFn.create( transFn.findPlug("rotateX") );
				//rotXFn.findPlug("rotationInterpolation").setValue(3);
				MObject rotYcurve = rotYFn.create( transFn.findPlug("rotateY") );
				//rotYFn.findPlug("rotationInterpolation").setValue(3);
				MObject rotZcurve = rotZFn.create( transFn.findPlug("rotateZ") );
				//rotZFn.findPlug("rotationInterpolation").setValue(3);

				MTimeArray rotTimes;
				MDoubleArray rotXValues;
				MDoubleArray rotYValues;
				MDoubleArray rotZValues;

				MEulerRotation mPrevRot;
				for( size_t i = 0; i < rot_keys.size(); ++i ) {
					Quaternion niQuat = rot_keys[i].data;

					MQuaternion mQuat( niQuat.x, niQuat.y, niQuat.z, niQuat.w );
					MEulerRotation mRot = mQuat.asEulerRotation();
					MEulerRotation mAlt;
					mAlt[0] = PI + mRot[0];
					mAlt[1] = PI - mRot[1];
					mAlt[2] = PI + mRot[2];

					for ( size_t j = 0; j < 3; ++j ) {
						double prev_diff = abs(mRot[j] - mPrevRot[j]);
						//Try adding and subtracting multiples of 2 pi radians to get
						//closer to the previous angle
						while (true) {
							double new_angle = mRot[j] - (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mRot[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
						while (true) {
							double new_angle = mRot[j] + (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mRot[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
					}

					for ( size_t j = 0; j < 3; ++j ) {
						double prev_diff = abs(mAlt[j] - mPrevRot[j]);
						//Try adding and subtracting multiples of 2 pi radians to get
						//closer to the previous angle
						while (true) {
							double new_angle = mAlt[j] - (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mAlt[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
						while (true) {
							double new_angle = mAlt[j] + (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mAlt[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
					}


					//Try taking advantage of the fact that:
					//Rotate(x,y,z) = Rotate(pi + x, pi - y, pi +z)
					double rot_diff = ( (abs(mRot[0] - mPrevRot[0]) + abs(mRot[1] - mPrevRot[1]) + abs(mRot[2] - mPrevRot[2]) ) / 3.0 );
					double alt_diff = ( (abs(mAlt[0] - mPrevRot[0]) + abs(mAlt[1] - mPrevRot[1]) + abs(mAlt[2] - mPrevRot[2]) ) / 3.0 );

					if ( alt_diff < rot_diff ) {
						mRot = mAlt;
					}

					mPrevRot = mRot;

					rotTimes.append( MTime(rot_keys[i].time, MTime::kSeconds) );
					rotXValues.append( mRot[0] );
					rotYValues.append( mRot[1] );
					rotZValues.append( mRot[2] );
				}


				rotXFn.addKeys( &rotTimes, &rotXValues );
				rotYFn.addKeys( &rotTimes, &rotYValues );
				rotZFn.addKeys( &rotTimes, &rotZValues );
			}
		}
	}
}
Example #17
0
void cStructLoader::Load(bool reload)
{
  if(SL_TSTFLAG(SL_DISABLED) || (reload && !SL_TSTFLAG(SL_WATCH))) return;
  FILE *f=fopen(path,"r");
  if(f) {
    PreLoad();
    int curr_mtime=MTime(true);
    ListLock(true);
    bool doload=false;
    if(!reload) {
      Clear(); Modified(false);
      mtime=curr_mtime;
      doload=true;
      }
    else if(mtime<curr_mtime) {
      PRINTF(L_CORE_LOAD,"detected change of %s",path);
      if(IsModified())
        PRINTF(L_CORE_LOAD,"discarding in-memory changes");
      for(cStructItem *a=First(); a; a=Next(a)) DelItem(a);
      Modified(false);
      mtime=curr_mtime;
      doload=true;
      }
    if(doload) {
      SL_SETFLAG(SL_LOADED);
      PRINTF(L_GEN_INFO,"loading %s from %s",type,path);
      CheckAccess();
      int lineNum=0, num=0;
      char buff[4096];
      while(fgets(buff,sizeof(buff),f)) {
        lineNum++;
        if(!index(buff,'\n') && !feof(f)) {
          PRINTF(L_GEN_ERROR,"file %s readbuffer overflow line#%d",path,lineNum);
          SL_CLRFLAG(SL_LOADED);
          break;
          }
        strreplace(buff,'\n',0); strreplace(buff,'\r',0); // chomp
        bool hasContent=false;
        char *ls;
        for(ls=buff; *ls; ls++) {
          if(*ls==';' || *ls=='#') {		  // comment
            if(hasContent)
              while(ls>buff && ls[-1]<=' ') ls--; // search back to non-whitespace
            break;
            }
          if(*ls>' ') hasContent=true;		  // line contains something usefull
          }
        cStructItem *it=0;
        if(hasContent) {
          char save=*ls;
          *ls=0; it=ParseLine(skipspace(buff)); *ls=save;
          if(!it) {
            PRINTF(L_GEN_ERROR,"file %s has error in line #%d",path,lineNum);
            ls=buff;
            }
          else num++;
          }
        else ls=buff;
        if(!it) it=new cCommentItem;
        if(it) {
          it->SetComment(ls);
          Add(it);
          }
        else {
          PRINTF(L_GEN_ERROR,"out of memory loading file %s",path);
          SL_CLRFLAG(SL_LOADED);
          break;
          }
        }
      ListUnlock();
      PRINTF(L_CORE_LOAD,"loaded %d %s from %s",num,type,path);
      PostLoad();
      }
    else ListUnlock();

    fclose(f);
    LoadFinished();
    }
  else
    OpenFailed();
}
Example #18
0
bool
atomExport::setUpCache(MSelectionList &sList, std::vector<atomCachedPlugs *> &cachedPlugs,atomAnimLayers &animLayers,
						bool sdk, bool constraint, bool layers,
						std::set<std::string> &attrStrings, atomTemplateReader &templateReader,
						MTime &startTime, MTime &endTime, MAngle::Unit angularUnit,
						MDistance::Unit	linearUnit)
{
	if(endTime<startTime)
		return false; //should never happen but just in case.
	unsigned int numObjects = sList.length();
	cachedPlugs.resize(numObjects);

	double dStart = startTime.value();
	double dEnd = endTime.value() +  (.0000001); //little nudge in case of round off errors
	MTime::Unit unit = startTime.unit();
	double tickStep = MTime(1.0,unit).value();
	unsigned int numItems = ((unsigned int)((dEnd - dStart)/tickStep)) + 1;
	bool somethingIsCached = false; //if nothing get's cached no reason to run computation loop
	for (unsigned int i = 0; i < numObjects; i++) 
	{
		atomCachedPlugs *plug = NULL;
		//make sure it's a NULL, and preset it in case we skip this node
		cachedPlugs[i] = plug;

		MDagPath path;
		MObject node;
		MString name;
		if (sList.getDagPath (i, path) == MS::kSuccess) 
		{
			node = path.node();
			name = path.partialPathName();
		}
		else if (sList.getDependNode (i, node) == MS::kSuccess) {
			
			if (!node.hasFn (MFn::kDependencyNode)) {
				continue;
			}
			MFnDependencyNode fnNode (node);
			name = fnNode.name();
		}
		if(node.isNull()==false)
		{
			if(i< animLayers.length())
			{
				MPlugArray plugs;
				animLayers.getPlugs(i,plugs);
				std::set<std::string> tempAttrStrings;
				atomTemplateReader tempTemplateReader;
				plug = new atomCachedPlugs(name,node,plugs,sdk,constraint,layers,
					tempAttrStrings,tempTemplateReader,numItems,angularUnit,
				linearUnit);
				if(plug->hasCached() ==false)
					delete plug;
				else
				{
					cachedPlugs[i] = plug;
					somethingIsCached = true;
				}
			}
			else
			{
				if(templateReader.findNode(name)== false)
				{
					continue;
				}
				MSelectionList localList;
				localList.add(node);
				MPlugArray animatablePlugs;
				MAnimUtil::findAnimatablePlugs(localList,animatablePlugs);
				plug = new atomCachedPlugs(name,node,animatablePlugs,sdk,constraint,layers,attrStrings,templateReader,numItems,angularUnit,
					linearUnit);
				if(plug->hasCached() ==false)
					delete plug;
				else
				{
					cachedPlugs[i] = plug;
					somethingIsCached = true;
				}
			}
		}
	}
	
	bool computationFinished = true; //if no interrupt happens we will finish the computation
	if(somethingIsCached)
	{
		bool hasActiveProgress = false;
		if (MProgressWindow::reserve()) {
			hasActiveProgress = true;
			MProgressWindow::setInterruptable(true);
   			MProgressWindow::startProgress();
    		MProgressWindow::setProgressRange(0, numObjects);
			MProgressWindow::setProgress(0);
			MStatus stringStat;
			MString msg = MStringResource::getString(kBakingProgress, stringStat);
			if(stringStat == MS::kSuccess)
				MProgressWindow::setTitle(msg);
		}

		unsigned int count =0;
		for(double tick = dStart; tick <= dEnd; tick += tickStep)
		{
			if(hasActiveProgress)
				MProgressWindow::setProgress(count);
			MTime time(tick,unit);
			MDGContext ctx(time);
			for(unsigned int z = 0; z< cachedPlugs.size(); ++z)
			{
				if(cachedPlugs[z])
					cachedPlugs[z]->calculateValue(ctx,count);
			}

			if  (hasActiveProgress && MProgressWindow::isCancelled())
			{
				computationFinished = false;
				break;
			}
			++count;
		}
		if(hasActiveProgress)
			MProgressWindow::endProgress();
	}
	return computationFinished;

}
Example #19
0
MStatus atomExport::writer(	const MFileObject& file,
								const MString& options,
								FileAccessMode mode)
{
	MStatus status = MS::kFailure;


	MString fileName = file.fullName();
#if defined (OSMac_)
	char fname[MAXPATHLEN];
	strcpy (fname, fileName.asChar());
	ofstream animFile(fname);
#else
	ofstream animFile(fileName.asChar());
#endif
	//	Defaults.
	//
	MString copyFlags("copyKey -cb api -fea 1 ");
	int precision = kDefaultPrecision;
	bool statics = false;
	bool includeChildren = false;
	std::set<std::string> attrStrings;
	//	Parse the options. The options syntax is in the form of
	//	"flag=val;flag1=val;flag2=val"
	//
	bool useSpecifiedRange = false;
	bool useTemplate = false;
	bool cached = false;
	bool constraint = false;
	bool sdk = false;
	bool animLayers = true;
	MString templateName;
	MString viewName;
	MTime startTime = MAnimControl::animationStartTime();
	MTime endTime = MAnimControl::animationEndTime();
	MString	exportEditsFile;

	MString exportFlags;
	if (options.length() > 0) {
		const MString flagPrecision("precision");
		const MString flagStatics("statics");
		const MString flagConstraint("constraint");
		const MString flagSDK("sdk");
		const MString flagAnimLayers("animLayers");
		const MString flagCopyKeyCmd("copyKeyCmd");
		const MString flagSelected("selected");
		const MString flagTemplate("template");
		const MString flagView("view");
		const MString optionChildrenToo("childrenToo");
		const MString optionTemplate("template");
		const MString flagAttr("at");
		const MString flagWhichRange("whichRange");
		const MString flagRange("range");
		const MString flagExportEdits("exportEdits");		
		const MString flagCached("baked");		
		
		//	Start parsing.
		//
		MStringArray optionList;
		MStringArray theOption;
		options.split(';', optionList);

		unsigned nOptions = optionList.length();
		for (unsigned i = 0; i < nOptions; i++) {
			theOption.clear();
			optionList[i].split('=', theOption);
			if (theOption.length() < 1) {
				continue;
			}

			if (theOption[0] == flagPrecision && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					precision = theOption[1].asInt();
				}
			} 
			else if( theOption[0] == flagTemplate && theOption.length() > 1)
			{
				templateName = theOption[1];
			}
			else if( theOption[0] == flagView && theOption.length() > 1)
			{
				viewName = theOption[1];
			}
			else if (	theOption[0] == 
						flagWhichRange && theOption.length() > 1) {
				if (theOption[1].isInt()) 
					useSpecifiedRange = (theOption[1].asInt() ==1) ? false : true;
			}
			else if (	theOption[0] == 
						flagRange && theOption.length() > 1) 
			{
				MStringArray rangeArray;
				theOption[1].split(':',rangeArray);
				if(rangeArray.length()==2)
				{
					if(rangeArray[0].isDouble())
					{
						double val = rangeArray[0].asDouble();
						startTime = MTime(val,MTime::uiUnit());
					}
					else if(rangeArray[0].isInt())
					{
						double val = (double)rangeArray[0].asInt();
						startTime = MTime(val,MTime::uiUnit());
					}
					if(rangeArray[1].isDouble())
					{
						double val = rangeArray[1].asDouble();
						endTime = MTime(val,MTime::uiUnit());
					}
					else if(rangeArray[1].isInt())
					{
						double val = (double)rangeArray[1].asInt();
						endTime = MTime(val,MTime::uiUnit());
					}
				}
			}
			else if (	theOption[0] == 
						flagStatics && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					statics = (theOption[1].asInt()) ? true : false;
				}
			}
			else if (	theOption[0] == 
						flagSDK && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					sdk = (theOption[1].asInt()) ? true : false;
				}
			}
			else if (	theOption[0] == 
						flagConstraint && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					constraint = (theOption[1].asInt()) ? true : false;
				}
			}
			else if (	theOption[0] == 
						flagAnimLayers && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					animLayers = (theOption[1].asInt()) ? true : false;
				}
			}
			else if (	theOption[0] == 
						flagCached && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					cached = (theOption[1].asInt()) ? true : false;
				}
			}
			else if (theOption[0] == flagSelected && theOption.length() > 1) {
				includeChildren = (theOption[1] == optionChildrenToo) ? true : false;
				if(theOption[1] == optionTemplate)
					useTemplate = true;
			} 
			else if (theOption[0] == flagAttr && theOption.length() > 1) {
				std::string str(theOption[1].asChar());
				attrStrings.insert(str);
			} 
			else if (	theOption[0] == 
						flagCopyKeyCmd && theOption.length() > 1) {

				//	Replace any '>' characters with '"'. This is needed
				//	since the file translator option boxes do not handle
				//	escaped quotation marks.
				//
				const char *optStr = theOption[1].asChar();
				size_t nChars = strlen(optStr);
				char *copyStr = new char[nChars+1];

				copyStr = strcpy(copyStr, optStr);
				for (size_t j = 0; j < nChars; j++) {
					if (copyStr[j] == '>') {
						copyStr[j] = '"';
					}
				}
		
				copyFlags += copyStr;
				delete [] copyStr;
			}
			else if (theOption[0] == flagExportEdits && theOption.length() > 1)
			{
				exportEditsFile =  theOption[1];
			}
		}
	}
	
	//	Set the precision of the ofstream.
	//
	animFile.precision(precision);


	atomTemplateReader templateReader;
	if(useTemplate == true)
	{
		includeChildren = false;
		templateReader.setTemplate(templateName,viewName);
		templateReader.selectNodes(); //make the template nodes be the selection
	}
	status = exportSelected(animFile, copyFlags, attrStrings, includeChildren,
							useSpecifiedRange, startTime, endTime, statics,
							cached,sdk,constraint, animLayers, exportEditsFile,templateReader);

	animFile.flush();
	animFile.close();

	return status;
}
Example #20
0
MTime convert( const double &from )
{
	return MTime( from, MTime::kSeconds );
}
Example #21
0
PXR_NAMESPACE_OPEN_SCOPE



/* static */
bool 
PxrUsdMayaTranslatorMesh::Create(
        const UsdGeomMesh& mesh,
        MObject parentNode,
        const PxrUsdMayaPrimReaderArgs& args,
        PxrUsdMayaPrimReaderContext* context)
{
    if (!mesh) {
        return false;
    }

    const UsdPrim& prim = mesh.GetPrim();

    MStatus status;

    // Create node (transform)
    MObject mayaNodeTransformObj;
    if (!PxrUsdMayaTranslatorUtil::CreateTransformNode(prim,
                                                          parentNode,
                                                          args,
                                                          context,
                                                          &status,
                                                          &mayaNodeTransformObj)) {
        return false;
    }

    VtArray<GfVec3f> points;
    VtArray<GfVec3f> normals;
    VtArray<int>     faceVertexCounts;
    VtArray<int>     faceVertexIndices;
    
    UsdAttribute fvc = mesh.GetFaceVertexCountsAttr();
    if (fvc.ValueMightBeTimeVarying()){
        // at some point, it would be great, instead of failing, to create a usd/hydra proxy node
        // for the mesh, perhaps?  For now, better to give a more specific error
        MGlobal::displayError(
            TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexCounts). Skipping...", 
                prim.GetPath().GetText()).c_str());
        return false;
    } else {
        // for any non-topo-varying mesh, sampling at zero will get us the right answer
        fvc.Get(&faceVertexCounts, 0);
    }

    UsdAttribute fvi = mesh.GetFaceVertexIndicesAttr();
    if (fvi.ValueMightBeTimeVarying()){
        // at some point, it would be great, instead of failing, to create a usd/hydra proxy node
        // for the mesh, perhaps?  For now, better to give a more specific error
        MGlobal::displayError(
            TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexIndices). Skipping...", 
                prim.GetPath().GetText()).c_str());
        return false;
    } else {
        // for any non-topo-varying mesh, sampling at zero will get us the right answer
        fvi.Get(&faceVertexIndices, 0);
    }
        
    // Sanity Checks. If the vertex arrays are empty, skip this mesh
    if (faceVertexCounts.size() == 0 || faceVertexIndices.size() == 0) {
        MGlobal::displayError(
            TfStringPrintf("FaceVertex arrays are empty [Count:%zu Indices:%zu] on Mesh <%s>. Skipping...", 
                faceVertexCounts.size(), faceVertexIndices.size(), 
                prim.GetPath().GetText()).c_str());
        return false; // invalid mesh, so exit
    }

    // Gather points and normals
    // If args.GetReadAnimData() is TRUE,
    // pick the first avaiable sample or default
    UsdTimeCode pointsTimeSample=UsdTimeCode::EarliestTime();
    UsdTimeCode normalsTimeSample=UsdTimeCode::EarliestTime();
    std::vector<double> pointsTimeSamples;
    size_t pointsNumTimeSamples = 0;
    if (args.GetReadAnimData()) {
        PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetPointsAttr(), args,
                &pointsTimeSamples);
        pointsNumTimeSamples = pointsTimeSamples.size();
        if (pointsNumTimeSamples>0) {
            pointsTimeSample = pointsTimeSamples[0];
        }
    	std::vector<double> normalsTimeSamples;
        PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetNormalsAttr(), args,
                &normalsTimeSamples);
        if (normalsTimeSamples.size()) {
            normalsTimeSample = normalsTimeSamples[0];
        }
    }
    mesh.GetPointsAttr().Get(&points, pointsTimeSample);
    mesh.GetNormalsAttr().Get(&normals, normalsTimeSample);
    
    if (points.size() == 0) {
        MGlobal::displayError(
            TfStringPrintf("Points arrays is empty on Mesh <%s>. Skipping...", 
                prim.GetPath().GetText()).c_str());
        return false; // invalid mesh, so exit
    }


    // == Convert data
    size_t mayaNumVertices = points.size();
    MPointArray mayaPoints(mayaNumVertices);
    for (size_t i=0; i < mayaNumVertices; i++) {
        mayaPoints.set( i, points[i][0], points[i][1], points[i][2] );
    }

    MIntArray polygonCounts( faceVertexCounts.cdata(),  faceVertexCounts.size() );
    MIntArray polygonConnects( faceVertexIndices.cdata(), faceVertexIndices.size() );

    // == Create Mesh Shape Node
    MFnMesh meshFn;
    MObject meshObj = meshFn.create(mayaPoints.length(), 
                           polygonCounts.length(), 
                           mayaPoints, 
                           polygonCounts, 
                           polygonConnects,
                           mayaNodeTransformObj,
                           &status
                           );
                           
    if (status != MS::kSuccess) {
        return false;
    }

    // Since we are "decollapsing", we will create a xform and a shape node for each USD prim
    std::string usdPrimName(prim.GetName().GetText());
    std::string shapeName(usdPrimName); shapeName += "Shape";
    // Set mesh name and register
    meshFn.setName(MString(shapeName.c_str()), false, &status);
    if (context) {
        std::string usdPrimPath(prim.GetPath().GetText());
        std::string shapePath(usdPrimPath);
        shapePath += "/";
        shapePath += shapeName;
        context->RegisterNewMayaNode( shapePath, meshObj ); // used for undo/redo
    }

    // If a material is bound, create (or reuse if already present) and assign it
    // If no binding is present, assign the mesh to the default shader    
    const TfToken& shadingMode = args.GetShadingMode();
    PxrUsdMayaTranslatorMaterial::AssignMaterial(shadingMode, mesh, meshObj,
            context);
    
    // Mesh is a shape, so read Gprim properties
    PxrUsdMayaTranslatorGprim::Read(mesh, meshObj, context);

    // Set normals if supplied
    MIntArray normalsFaceIds;
    if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) {

        for (size_t i=0; i < polygonCounts.length(); i++) {
            for (int j=0; j < polygonCounts[i]; j++) {
                normalsFaceIds.append(i);
            }
        }
        if (normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) {
            MVectorArray mayaNormals(normals.size());
            for (size_t i=0; i < normals.size(); i++) {
                mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i);
            }
            if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) {
            }
        }
     }

    // Determine if PolyMesh or SubdivMesh
    TfToken subdScheme = PxrUsdMayaMeshUtil::setSubdivScheme(mesh, meshFn, args.GetDefaultMeshScheme());

    // If we are dealing with polys, check if there are normals
    // If we are dealing with SubdivMesh, read additional attributes and SubdivMesh properties
    if (subdScheme == UsdGeomTokens->none) {
        if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) {
            PxrUsdMayaMeshUtil::setEmitNormals(mesh, meshFn, UsdGeomTokens->none);
        }
    } else {
        PxrUsdMayaMeshUtil::setSubdivInterpBoundary(mesh, meshFn, UsdGeomTokens->edgeAndCorner);
        PxrUsdMayaMeshUtil::setSubdivFVLinearInterpolation(mesh, meshFn);
        _AssignSubDivTagsToMesh(mesh, meshObj, meshFn);
    }
 
    // Set Holes
    VtArray<int> holeIndices;
    mesh.GetHoleIndicesAttr().Get(&holeIndices);   // not animatable
    if ( holeIndices.size() != 0 ) {
        MUintArray mayaHoleIndices;
        mayaHoleIndices.setLength( holeIndices.size() );
        for (size_t i=0; i < holeIndices.size(); i++) {
            mayaHoleIndices[i] = holeIndices[i];
        }
        if (meshFn.setInvisibleFaces(mayaHoleIndices) == MS::kFailure) {
            MGlobal::displayError(TfStringPrintf("Unable to set Invisible Faces on <%s>", 
                            meshFn.fullPathName().asChar()).c_str());
        }
    }

    // GETTING PRIMVARS
    std::vector<UsdGeomPrimvar> primvars = mesh.GetPrimvars();
    TF_FOR_ALL(iter, primvars) {
        const UsdGeomPrimvar& primvar = *iter;
        const TfToken& name = primvar.GetBaseName();
        const SdfValueTypeName& typeName = primvar.GetTypeName();

        // If the primvar is called either displayColor or displayOpacity check
        // if it was really authored from the user.  It may not have been
        // authored by the user, for example if it was generated by shader
        // values and not an authored colorset/entity.
        // If it was not really authored, we skip the primvar.
        if (name == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName || 
                name == PxrUsdMayaMeshColorSetTokens->DisplayOpacityColorSetName) {
            if (!PxrUsdMayaRoundTripUtil::IsAttributeUserAuthored(primvar)) {
                continue;
            }
        }

        // XXX: Maya stores UVs in MFloatArrays and color set data in MColors
        // which store floats, so we currently only import primvars holding
        // float-typed arrays. Should we still consider other precisions
        // (double, half, ...) and/or numeric types (int)?
        if (typeName == SdfValueTypeNames->Float2Array) {
            // We assume that Float2Array primvars are UV sets.
            if (!_AssignUVSetPrimvarToMesh(primvar, meshFn)) {
                MGlobal::displayWarning(
                    TfStringPrintf("Unable to retrieve and assign data for UV set <%s> on mesh <%s>", 
                                   name.GetText(),
                                   mesh.GetPrim().GetPath().GetText()).c_str());
            }
        } else if (typeName == SdfValueTypeNames->FloatArray   || 
                   typeName == SdfValueTypeNames->Float3Array  || 
                   typeName == SdfValueTypeNames->Color3fArray ||
                   typeName == SdfValueTypeNames->Float4Array  || 
                   typeName == SdfValueTypeNames->Color4fArray) {
            if (!_AssignColorSetPrimvarToMesh(mesh, primvar, meshFn)) {
                MGlobal::displayWarning(
                    TfStringPrintf("Unable to retrieve and assign data for color set <%s> on mesh <%s>",
                                   name.GetText(),
                                   mesh.GetPrim().GetPath().GetText()).c_str());
            }
        }
    }

    // We only vizualize the colorset by default if it is "displayColor".  
    MStringArray colorSetNames;
    if (meshFn.getColorSetNames(colorSetNames)==MS::kSuccess) {
        for (unsigned int i=0; i < colorSetNames.length(); i++) {
            const MString colorSetName = colorSetNames[i];
            if (std::string(colorSetName.asChar()) 
                    == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetString()) {
                MFnMesh::MColorRepresentation csRep=
                    meshFn.getColorRepresentation(colorSetName);
                if (csRep==MFnMesh::kRGB || csRep==MFnMesh::kRGBA) {

                    // both of these are needed to show the colorset.
                    MPlug plg=meshFn.findPlug("displayColors");
                    if ( !plg.isNull() ) {
                        plg.setBool(true);
                    }
                    meshFn.setCurrentColorSetName(colorSetName);
                }
                break;
            }
        }
    }
    
    // == Animate points ==
    //   Use blendShapeDeformer so that all the points for a frame are contained in a single node
    //
    if (pointsNumTimeSamples > 0) {
        MPointArray mayaPoints(mayaNumVertices);
        MObject meshAnimObj;

        MFnBlendShapeDeformer blendFn;
        MObject blendObj = blendFn.create(meshObj);
        if (context) {
            context->RegisterNewMayaNode( blendFn.name().asChar(), blendObj ); // used for undo/redo
        }

        for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) {
             mesh.GetPointsAttr().Get(&points, pointsTimeSamples[ti]);

            for (unsigned int i=0; i < mayaNumVertices; i++) {
                mayaPoints.set( i, points[i][0], points[i][1], points[i][2] );
            }

            // == Create Mesh Shape Node
            MFnMesh meshFn;
            if ( meshAnimObj.isNull() ) {
                meshAnimObj = meshFn.create(mayaPoints.length(), 
                                       polygonCounts.length(), 
                                       mayaPoints, 
                                       polygonCounts, 
                                       polygonConnects,
                                       mayaNodeTransformObj,
                                       &status
                                       );
                if (status != MS::kSuccess) {
                    continue;
                }
            }
            else {
                // Reuse the already created mesh by copying it and then setting the points
                meshAnimObj = meshFn.copy(meshAnimObj, mayaNodeTransformObj, &status);
                meshFn.setPoints(mayaPoints);
            }

            // Set normals if supplied
            //
            // NOTE: This normal information is not propagated through the blendShapes, only the controlPoints.
            //
             mesh.GetNormalsAttr().Get(&normals, pointsTimeSamples[ti]);
             if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices()) &&
                normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) {

                MVectorArray mayaNormals(normals.size());
                for (size_t i=0; i < normals.size(); i++) {
                    mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i);
                }
                if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) {
                }
             }

            // Add as target and set as an intermediate object
            blendFn.addTarget(meshObj, ti, meshAnimObj, 1.0);
            meshFn.setIntermediateObject(true);
            if (context) {
                context->RegisterNewMayaNode( meshFn.fullPathName().asChar(), meshAnimObj ); // used for undo/redo
            }
        }

        // Animate the weights so that mesh0 has a weight of 1 at frame 0, etc.
        MFnAnimCurve animFn;

        // Construct the time array to be used for all the keys
        MTimeArray timeArray;
        timeArray.setLength(pointsNumTimeSamples);
        for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) {
            timeArray.set( MTime(pointsTimeSamples[ti]), ti);
        }

        // Key/Animate the weights
        MPlug plgAry = blendFn.findPlug( "weight" );
        if ( !plgAry.isNull() && plgAry.isArray() ) {
            for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) {
                MPlug plg = plgAry.elementByLogicalIndex(ti, &status);
                MDoubleArray valueArray(pointsNumTimeSamples, 0.0);
                valueArray[ti] = 1.0; // Set the time value where this mesh's weight should be 1.0
                MObject animObj = animFn.create(plg, NULL, &status);
                animFn.addKeys(&timeArray, &valueArray);
                if (context) {
                    context->RegisterNewMayaNode(animFn.name().asChar(), animObj ); // used for undo/redo
                }
            }
        }
    }

    return true;
}
Example #22
0
MStatus simulateBoids::doIt( const MArgList& args )
{
	
	//	Description: implements the MEL boids command
	//	Arguments: args - the argument list that was passes to the command from MEL

	MStatus status = MS::kSuccess;

	
    /****************************************
	*	building thread/dll data structure  *
	****************************************/

	InfoCache infoCache;
	SimulationParameters simParams;
	RulesParameters *applyingRules;
	double progressBar=0;
	double aov=pi/3;
	int i,numberOfDesires=0;
	
	// params retrievement
	MSelectionList sel;
	MObject node;
	MFnDependencyNode nodeFn;
	MFnTransform locatorFn;
	MPlug plug;

	// simulation params
	int simulationLengthValue;		// [int] in seconds
	int framesPerSecondValue;		// [int]
	int startFrameValue;			// [int]
	int boidsNumberValue;			// [int]
	// export params
	MString logFilePathValue;		// [char *]
	MString logFileNameValue;		// [char *]
	int logFileTypeValue;			// 0 = nCache; 1 = log file; 2 = XML; 
	// locomotion params
	int locomotionModeValue;		// [int]
	double maxSpeedValue;			// [double]
	double maxForceValue;			// [double]

	// double mass=1;				// [double]

	MTime currentTime, maxTime;
	MPlug plugX, plugY, plugZ;
	double tx, ty, tz;
	int frameLength ;
	Vector * leader = NULL;

	MStatus leaderFound=MStatus::kFailure;

	MGlobal::getActiveSelectionList(sel);
	for ( MItSelectionList listIter(sel); !listIter.isDone(); listIter.next() )
	{
		listIter.getDependNode(node);
		switch(node.apiType())
		{
			case MFn::kTransform:
				// get locator transform to follow
				leaderFound=locatorFn.setObject(node);
				cout << locatorFn.name().asChar() << " is selected as locator" << endl;
				break;
			case MFn::kPluginDependNode:
				nodeFn.setObject(node);
				cout << nodeFn.name().asChar() << " is selected as brain" << endl;
				break;
			default:
				break;
		}
		cout<< node.apiTypeStr()<<endl;
	}

	// rules params
	setRuleVariables(alignment);
	setRuleVariables(cohesion);
	setRuleVariables(separation);
	setRuleVariables(follow);

	getPlugValue(simulationLength);
	getPlugValue(framesPerSecond);
	getPlugValue(startFrame);
	getPlugValue(boidsNumber);
	getPlugValue(logFileType);
	getRulePlugValue(alignment);
	getRulePlugValue(cohesion);
	getRulePlugValue(separation);
	getRulePlugValue(follow);
	getPlugValue(locomotionMode);
	getPlugValue(maxSpeed);
	getPlugValue(maxForce);
	getTypePlugValue(logFilePath);
	getTypePlugValue(logFileName);
		// counting active rules number
	if(alignmentActiveValue)
		numberOfDesires++;
	if(cohesionActiveValue)
		numberOfDesires++;
	if(separationActiveValue)
		numberOfDesires++;
	if(followActiveValue)
		numberOfDesires++;


	currentTime = MTime((double)startFrameValue);														// MAnimControl::minTime();
	maxTime = MTime((double)(startFrameValue + (simulationLengthValue * framesPerSecondValue)));		// MAnimControl::maxTime();
	cout << "time unit enum (6 is 24 fps): " << currentTime.unit() << endl;	
	plugX = locatorFn.findPlug( MString( "translateX" ), &status );
	plugY = locatorFn.findPlug( MString( "translateY" ), &status );
	plugZ = locatorFn.findPlug( MString( "translateZ" ), &status );
	frameLength = simulationLengthValue * framesPerSecondValue;
	
	if(leaderFound==MS::kSuccess)
	{
		leader = new Vector[frameLength];	
		while ( currentTime < maxTime )
		{
			{
				int index = (int)currentTime.value() - startFrameValue;
				/*
				MGlobal::viewFrame(currentTime);
				pos = locatorFn.getTranslation(MSpace::kWorld);
				cout << "pos: " << pos.x << " " << pos.y << " " << pos.z << endl;
				*/
				status = plugX.getValue( tx, MDGContext(currentTime) );
				status = plugY.getValue( ty, MDGContext(currentTime) );
				status = plugZ.getValue( tz, MDGContext(currentTime) );

				leader[index].x = tx;
				leader[index].y = ty;
				leader[index].z = tz;
				//cout << "pos at time " << currentTime.value() << " has x: " << tx << " y: " << ty << " z: " << tz << endl;
				currentTime++;
			}	
		}
	}

	simParams.fps=framesPerSecondValue;
	simParams.lenght=simulationLengthValue;
	simParams.numberOfBoids=boidsNumberValue;
	simParams.maxAcceleration=maxForceValue;
	simParams.maxVelocity=maxSpeedValue;
	simParams.simplifiedLocomotion=TRUE;


	
	
	applyingRules=new RulesParameters[numberOfDesires];
	

	// cache settings
	MString saveString;
	saveString = logFilePathValue+"/"+logFileNameValue;
	infoCache.fileName=new char[saveString.length()+1];
	memcpy(infoCache.fileName,saveString.asChar(),sizeof(char)*(saveString.length()+1));
	infoCache.cacheFormat=ONEFILE;
	infoCache.fps=framesPerSecondValue;
	infoCache.start=startFrameValue/framesPerSecondValue;
	infoCache.end=simulationLengthValue+infoCache.start;	
	infoCache.loging=FALSE;
	infoCache.option=POSITIONVELOCITY;
	infoCache.particleSysName="BoidsNParticles";
	infoCache.saveMethod=MAYANCACHE;

	for(i=0;i<numberOfDesires;i++)
	{
		applyingRules[i].enabled=TRUE;
		applyingRules[i].precedence=1;
		applyingRules[i].aov=aov;
		applyingRules[i].visibilityOption=FALSE;
	}	

	if(cohesionActiveValue==0)
		applyingRules[COHESIONRULE].enabled=FALSE;
	else
	{
		applyingRules[COHESIONRULE].ruleName=COHESIONRULE;
		applyingRules[COHESIONRULE].ruleFactor=cohesionFactorValue;
		applyingRules[COHESIONRULE].ruleRadius=cohesionRadiusValue;
		applyingRules[COHESIONRULE].ruleWeight=cohesionWeightValue;
	}

	if(separationActiveValue==0)
		applyingRules[SEPARATIONRULE].enabled=FALSE;
	else
	{
		applyingRules[SEPARATIONRULE].ruleName=SEPARATIONRULE;
		applyingRules[SEPARATIONRULE].ruleFactor=separationFactorValue;
		applyingRules[SEPARATIONRULE].ruleRadius=separationRadiusValue;
		applyingRules[SEPARATIONRULE].ruleWeight=separationWeightValue;
	}

	if(alignmentActiveValue==0)
		applyingRules[ALIGNMENTRULE].enabled=FALSE;
	else
	{
		applyingRules[ALIGNMENTRULE].ruleName=ALIGNMENTRULE;
		applyingRules[ALIGNMENTRULE].ruleFactor=alignmentFactorValue;
		applyingRules[ALIGNMENTRULE].ruleRadius=alignmentRadiusValue;
		applyingRules[ALIGNMENTRULE].ruleWeight=alignmentWeightValue;
	}
	
	if(followActiveValue==0)
		applyingRules[FOLLOWRULE].enabled=FALSE;
	else
	{
		applyingRules[FOLLOWRULE].ruleName=FOLLOWRULE;
		applyingRules[FOLLOWRULE].ruleRadius=followRadiusValue;
		applyingRules[FOLLOWRULE].ruleFactor=followFactorValue;
		applyingRules[FOLLOWRULE].ruleWeight=followWeightValue;
	}
	

	// initializing simulation parameters
	boidInit(numberOfDesires, applyingRules, simParams , infoCache, leader);

	DLLData datadll;
	// preparing threads pool
	status = MThreadPool::init();
	
	if (status==MStatus::kSuccess)
	{
		MThreadPool::newParallelRegion(ThreadsCreator, &datadll);
		setResult( "Command executed!\n" );
		CHECK_MSTATUS(MProgressWindow::endProgress());
		MThreadPool::release();
	}

	switch(datadll.result)
	{
	case 0:
		status=MS::kSuccess;
		break;

	default:
		status=MS::kFailure;
	}

	MThreadPool::release();
	return status;
}
Example #23
0
MTime convert( const float &from )
{
	return MTime( from, MTime::kSeconds );
}
Example #24
0
/**
 *	Build the animation from Maya AnimCurves
 */
osg::ref_ptr<osg::AnimationPath> Transform::animCurve2AnimationPath(MObject &obj)
{
	osg::ref_ptr<osg::AnimationPath> anim = new osg::AnimationPath();

	// STEP 1. Get the animation curves
	MFnAnimCurve tx, ty, tz, rx, ry, rz, sx, sy, sz;

	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::kAnimCurve)){
				if(conn.name() == dn.name() + ".translateX" ){
					tx.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".translateY" ){
					ty.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".translateZ" ){
					tz.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".rotateX" ){
					rx.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".rotateY" ){
					ry.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".rotateZ" ){
					rz.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".scaleX" ){
					sx.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".scaleY" ){
					sy.setObject(origin_node);
				}
				else if(conn.name() == dn.name() + ".scaleZ" ){
					sz.setObject(origin_node);
				}
				else {
					std::cout << "Animation curve connected to parameter " << conn.name().asChar() << " (not supported)" << std::endl;
				}
			}
		}
	}

	// STEP 2. Build the AnimationPath from animation curves

	// Search the first key in time from all the AnimCurves

	bool t_present=false;
	double mint=0;

#define VALID_CURVE(f)	( f.object() != MObject::kNullObj )

#define GETMIN(f)	if(VALID_CURVE(f)) { \
									double t = f.time(0).as(MTime::kSeconds); \
									if( !t_present || t < mint ) \
										mint = t; \
									t_present = true; \
								}

	GETMIN(tx);	GETMIN(ty);	GETMIN(tz);	GETMIN(rx);	GETMIN(ry);	GETMIN(rz);	GETMIN(sx);	GETMIN(sy);	GETMIN(sz);

	// Set the right time in Maya timeline so all properties are updated
	MAnimControl::setCurrentTime(MTime(mint,MTime::kSeconds));

	// Create ControlPoint for initial time
	anim->insert(mint, osg::AnimationPath::ControlPoint(
					getCPPosition(obj),
					getCPRotation(obj),
					getCPScale(obj)
					));

	double t_prev = mint;

	// Locate the time of the next key (in any curve)

#define GET_NEXT(f)	if(VALID_CURVE(f)) { \
									for(int c=0; c<f.numKeys(); c++){ \
										double t = f.time(c).as(MTime::kSeconds); \
										if(t > t_prev && !t_present){ \
											t_now = t; \
											t_present = true; \
											break; \
										} \
										else if(t > t_prev && t < t_now) { \
											t_now = t; \
											break; \
										} \
									} \
								}

	// Get next keys cronologically
	double t_now = t_prev;
	t_present=false;
	GET_NEXT(tx); GET_NEXT(ty); GET_NEXT(tz); 
	GET_NEXT(rx); GET_NEXT(ry); GET_NEXT(rz); 
	GET_NEXT(sx); GET_NEXT(sy); GET_NEXT(sz);
	while(t_now != t_prev){

		// Set the right time in Maya timeline so all properties are updated
		MAnimControl::setCurrentTime(MTime(t_now,MTime::kSeconds));

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

		t_prev = t_now;
		t_present=false;
		GET_NEXT(tx); GET_NEXT(ty); GET_NEXT(tz); 
		GET_NEXT(rx); GET_NEXT(ry); GET_NEXT(rz); 
		GET_NEXT(sx); GET_NEXT(sy); GET_NEXT(sz);
	}

	return anim;
}