bool validateCurveData(Abc::P3fArraySamplePtr pCurvePos,
                       Abc::Int32ArraySamplePtr pCurveNbVertices,
                       Abc::UInt16ArraySamplePtr pOrders,
                       Abc::FloatArraySamplePtr pKnotVec, AbcG::CurveType type)
{
  ESS_PROFILE_FUNC();

  int nDefaultOrder = 4;
  const int numCurves = (int)pCurveNbVertices->size();
  const int numControl = (int)pCurvePos->size();

  int numControlNB = 0;

  for (int i = 0; i < pCurveNbVertices->size(); i++) {
    numControlNB += pCurveNbVertices->get()[i];
  }

  if (numControl != numControlNB) {
    ESS_LOG_ERROR(
        "Size mismatch between vertices and nbVertices. Cannot load curve.");
    return false;
  }

  if (pOrders && pCurveNbVertices->size() != pOrders->size()) {
    ESS_LOG_ERROR(
        "Size mismatch between numOrders and nbVertices. Cannot load curve.");
    return false;
  }

  if (pKnotVec) {
    int abcTotalKnots = 0;  // numControl + numCurves * (nDefaultOrder - 2) ;

    if (pOrders) {
      // calculate the expected knot vec size
      for (int i = 0; i < pCurveNbVertices->size(); i++) {
        abcTotalKnots += pCurveNbVertices->get()[i] + pOrders->get()[i] - 2;
      }
    }
    else {  // single order
      int nOrder = 0;
      if (type == AbcG::kCubic) {
        nOrder = 4;
      }
      else if (type == AbcG::kLinear) {
        nOrder = 2;
      }

      abcTotalKnots = numControl + numCurves * (nOrder - 2);
    }

    if (abcTotalKnots != pKnotVec->size()) {
      ESS_LOG_ERROR("Knot vector has the wrong size. Cannot load curve.");
    }
  }

  return true;
}
示例#2
0
	string replace(const string &str)
	{
		vector<std::string> parts;
		boost::split(parts, str, boost::is_any_of("%"));
		if (parts.size() == 1)
			return str;
		if (parts.size() & 0x1 == 0)
		{
			ESS_LOG_ERROR("Need an even number of % in the string to delimit environment variables properly! Nothing is replaced in the string");
			return str;
		}

		// replace every odd-positioned string with the environment variable value!
		size_t finalSize = 2;
		bool isEnvVarRound = false;
		for (std::vector<std::string>::iterator beg = parts.begin(); beg != parts.end(); ++beg, isEnvVarRound=!isEnvVarRound)
		{
			if (isEnvVarRound)
			{
				if (beg->size())
					*beg = readEnvVar(*beg);
				else
					*beg = "%";
			}
			finalSize += beg->size();
		}

		// concat the vector!
		string ret;
		ret.reserve(finalSize);
		for (std::vector<std::string>::iterator beg = parts.begin(); beg != parts.end(); ++beg)
			ret += *beg;
		return ret;
	}
int createAlembicObject(AbcG::IObject &iObj, INode **pMaxNode,
                        alembic_importoptions &options, std::string &file)
{
  AbcA::MetaData mdata = iObj.getMetaData();

  int ret = alembic_success;
  // if(AbcG::IXform::matches(iObj.getMetaData())) //Transform
  //{
  //	ESS_LOG_INFO( "AlembicImport_XForm: " << objects[j].getFullName() );
  //	int ret = AlembicImport_PolyMesh(file, iObj, options, pMaxNode);
  //}
  if (AbcG::IPolyMesh::matches(mdata) ||
      AbcG::ISubD::matches(mdata)) {  // PolyMesh / SubD
    ESS_LOG_INFO("AlembicImport_PolyMesh: " << iObj.getFullName());
    ret = AlembicImport_PolyMesh(file, iObj, options, pMaxNode);
  }
  else if (AbcG::ICamera::matches(mdata)) {  // Camera
    ESS_LOG_INFO("AlembicImport_Camera: " << iObj.getFullName());
    ret = AlembicImport_Camera(file, iObj, options, pMaxNode);
  }
  else if (AbcG::IPoints::matches(mdata)) {  // Points
    ESS_LOG_INFO("AlembicImport_Points: " << iObj.getFullName());
    ret = AlembicImport_Points(file, iObj, options, pMaxNode);
  }
  else if (AbcG::ICurves::matches(mdata)) {  // Curves
    if (options.loadCurvesAsNurbs) {
      ESS_LOG_INFO("AlembicImport_Nurbs: " << iObj.getFullName());
      ret = AlembicImport_NURBS(file, iObj, options, pMaxNode);
    }
    else {
      ESS_LOG_INFO("AlembicImport_Shape: " << iObj.getFullName());
      ret = AlembicImport_Shape(file, iObj, options, pMaxNode);
    }
  }
  else if (AbcG::ILight::matches(mdata)) {  // Light
    ESS_LOG_INFO("AlembicImport_Light: " << iObj.getFullName());
    ret = AlembicImport_Light(file, iObj, options, pMaxNode);
  }
  else if (AbcM::IMaterial::matches(mdata)) {
    ESS_LOG_WARNING(
        "Alembic IMaterial not yet supported: " << iObj.getFullName());
  }
  else {  // NURBS
    if (options.failOnUnsupported) {
      ESS_LOG_ERROR("Alembic data type not supported: " << iObj.getFullName());
      return alembic_failure;
    }
    else {
      ESS_LOG_WARNING(
          "Alembic data type not supported: " << iObj.getFullName());
    }
  }
  return ret;
}
Alembic::Abc::IArchive* getArchiveFromID(std::string const& path)
{
  ESS_PROFILE_SCOPE("getArchiveFromID-1");
  std::map<std::string, AlembicArchiveInfo>::iterator it;
  std::string resolvedPath = resolvePath(path);
  it = gArchives.find(resolvedPath);
  if (it == gArchives.end()) {
    // check if the file exists

    if (!boost::filesystem::exists(resolvedPath.c_str())) {
      ESS_LOG_ERROR("Can't find Alembic file.  Path: "
                    << path << "  Resolved path: " << resolvedPath);
      return NULL;
    }

    FILE* file = fopen(resolvedPath.c_str(), "rb");
    if (file == NULL) {
      return NULL;
    }
    else {
      fclose(file);

      AbcF::IFactory iFactory;
      AbcF::IFactory::CoreType oType;
      addArchive(new Abc::IArchive(iFactory.getArchive(resolvedPath, oType)));

      // addArchive(new Abc::IArchive( Alembic::AbcCoreHDF5::ReadArchive(),
      // resolvedPath));

      Abc::IArchive* pArchive = gArchives.find(resolvedPath)->second.archive;
      EC_LOG_INFO("Opening Abc Archive: " << pArchive->getName());
      return pArchive;
    }
  }
  return it->second.archive;
}
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;
}
void AlembicFloatController::GetValueLocalTime(TimeValue t, void* ptr,
                                               Interval& valid,
                                               GetSetMethod method)
{
  ESS_CPP_EXCEPTION_REPORTING_START

  Interval interval = FOREVER;

  MCHAR const* strPath = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_PATH, t, strPath, interval);

  MCHAR const* strIdentifier = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_IDENTIFIER, t,
                         strIdentifier, interval);

  MCHAR const* strCategory = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_CATEGORY, t, strCategory,
                         interval);

  MCHAR const* strProperty = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_PROPERTY, t, strProperty,
                         interval);

  float fTime;
  this->pblock->GetValue(AlembicFloatController::ID_TIME, t, fTime, interval);

  BOOL bMuted;
  this->pblock->GetValue(AlembicFloatController::ID_MUTED, t, bMuted, interval);

  extern bool g_bVerboseLogging;

  if (g_bVerboseLogging) {
    ESS_LOG_WARNING("Param block at tick " << t << "-----------------------");
    ESS_LOG_WARNING("PATH: " << strPath);
    ESS_LOG_WARNING("IDENTIFIER: " << strIdentifier);
    ESS_LOG_WARNING("PROPERTY: " << strProperty);
    ESS_LOG_WARNING("TIME: " << fTime);
    ESS_LOG_WARNING("MUTED: " << bMuted);
    ESS_LOG_WARNING("Param block end -------------");
  }

  const float fDefaultVal = -1.0;

  std::string szPath = EC_MCHAR_to_UTF8(strPath);
  std::string szIdentifier = EC_MCHAR_to_UTF8(strIdentifier);
  std::string szProperty = EC_MCHAR_to_UTF8(strProperty);
  std::string szCategory = EC_MCHAR_to_UTF8(strCategory);

  if (szCategory.empty()) {  // default to standard properties for backwards
    // compatibility
    szCategory = std::string("standardProperties");
  }

  if (!strProperty || !strPath || !strIdentifier /*|| !strCategory*/) {
    return setController("1", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  if (bMuted) {
    return setController("2", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  // if( szCategory.size() == 0 ) {
  //   ESS_LOG_ERROR( "No category specified." );
  //   return setController("3a", szProperty, valid, interval,   method,   ptr,
  //   fDefaultVal);
  //}

  if (szProperty.size() == 0) {
    ESS_LOG_ERROR("No property specified.");
    return setController("3b", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  AbcG::IObject iObj = getObjectFromArchive(szPath, szIdentifier);

  if (!iObj.valid()) {
    return setController("4", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  TimeValue dTicks = GetTimeValueFromSeconds(fTime);
  double sampleTime = GetSecondsFromTimeValue(dTicks);

  float fSampleVal = fDefaultVal;

  if (boost::iequals(szCategory, "standardProperties")) {
    if (Alembic::AbcGeom::ICamera::matches(
            iObj.getMetaData())) {  // standard camera properties

      Alembic::AbcGeom::ICamera objCamera =
          Alembic::AbcGeom::ICamera(iObj, Alembic::Abc::kWrapExisting);

      SampleInfo sampleInfo =
          getSampleInfo(sampleTime, objCamera.getSchema().getTimeSampling(),
                        objCamera.getSchema().getNumSamples());
      Alembic::AbcGeom::CameraSample sample;
      objCamera.getSchema().get(sample, sampleInfo.floorIndex);

      double sampleVal;
      if (!getCameraSampleVal(objCamera, sampleInfo, sample, szProperty,
                              sampleVal)) {
        return setController("5", szProperty, valid, interval, method, ptr,
                             fDefaultVal);
      }

      // Blend the camera values, if necessary
      if (sampleInfo.alpha != 0.0) {
        objCamera.getSchema().get(sample, sampleInfo.ceilIndex);
        double sampleVal2 = 0.0;
        if (getCameraSampleVal(objCamera, sampleInfo, sample, szProperty,
                               sampleVal2)) {
          sampleVal = (1.0 - sampleInfo.alpha) * sampleVal +
                      sampleInfo.alpha * sampleVal2;
        }
      }

      fSampleVal = (float)sampleVal;
    }
    else if (Alembic::AbcGeom::ILight::matches(
                 iObj.getMetaData())) {  // ILight material properties

      ESS_PROFILE_SCOPE(
          "AlembicFloatController::GetValueLocalTime - read ILight shader "
          "parameter");

      Alembic::AbcGeom::ILight objLight =
          Alembic::AbcGeom::ILight(iObj, Alembic::Abc::kWrapExisting);

      SampleInfo sampleInfo =
          getSampleInfo(sampleTime, objLight.getSchema().getTimeSampling(),
                        objLight.getSchema().getNumSamples());

      AbcM::IMaterialSchema matSchema = getMatSchema(objLight);

      std::string strProp = szProperty;

      std::vector<std::string> parts;
      boost::split(parts, strProp, boost::is_any_of("."));

      if (parts.size() == 3) {
        const std::string& target = parts[0];
        const std::string& type = parts[1];
        const std::string& prop = parts[2];

        Abc::IFloatProperty fProp = readShaderScalerProp<Abc::IFloatProperty>(
            matSchema, target, type, prop);
        if (fProp.valid()) {
          fProp.get(fSampleVal, sampleInfo.floorIndex);
        }
        else {
          ESS_LOG_WARNING("Float Controller Error: could find shader parameter "
                          << strProp);
        }
      }
      else if (parts.size() == 5) {
        const std::string& target = parts[0];
        const std::string& type = parts[1];
        const std::string& prop = parts[2];
        const std::string& propInterp = parts[3];
        const std::string& propComp = parts[4];

        // ESS_LOG_WARNING("propInterp: "<<propInterp);

        if (propInterp == "rgb") {
          Abc::IC3fProperty fProp = readShaderScalerProp<Abc::IC3fProperty>(
              matSchema, target, type, prop);
          if (fProp.valid()) {
            Abc::C3f v3f;
            fProp.get(v3f, sampleInfo.floorIndex);
            if (propComp == "x") {
              fSampleVal = v3f.x;
            }
            else if (propComp == "y") {
              fSampleVal = v3f.y;
            }
            else if (propComp == "z") {
              fSampleVal = v3f.z;
            }
            else {
              ESS_LOG_WARNING(
                  "Float Controller Error: invalid component: " << propComp);
            }
          }
          else {
            ESS_LOG_WARNING(
                "Float Controller Error: could find shader parameter "
                << strProp);
          }
        }
        else {
          ESS_LOG_WARNING(
              "Float Controller Error: unrecognized parameter interpretation: "
              << propInterp);
        }
      }
      else {
        ESS_LOG_WARNING(
            "Float Controller Error: could not parse property field: "
            << strProperty);
      }
    }
  }
  else if (boost::iequals(szCategory, "userProperties")) {
    // AbcA::TimeSamplingPtr timeSampling = obj.getSchema().getTimeSampling();
    // int nSamples = (int)obj.getSchema().getNumSamples();

    AbcA::TimeSamplingPtr timeSampling;
    int nSamples = 0;
    Abc::ICompoundProperty propk =
        AbcNodeUtils::getUserProperties(iObj, timeSampling, nSamples);

    if (propk.valid()) {
      SampleInfo sampleInfo = getSampleInfo(sampleTime, timeSampling, nSamples);

      std::vector<std::string> parts;
      boost::split(parts, szProperty, boost::is_any_of("."));

      if (parts.size() == 1) {
        Abc::IFloatProperty fProp =
            readScalarProperty<Abc::IFloatProperty>(propk, szProperty);
        if (fProp.valid()) {
          fProp.get(fSampleVal, sampleInfo.floorIndex);
        }
        else {
          Abc::IInt32Property intProp =
              readScalarProperty<Abc::IInt32Property>(propk, szProperty);
          if (intProp.valid()) {
            int intVal;
            intProp.get(intVal, sampleInfo.floorIndex);
            fSampleVal = (float)intVal;
          }
          else {
            ESS_LOG_WARNING(
                "Float Controller Error: could not read user property "
                << szProperty);
          }
        }
      }
      else if (parts.size() == 3) {
        const std::string& prop = parts[0];
        const std::string& propInterp = parts[1];
        const std::string& propComp = parts[2];

        // ESS_LOG_WARNING("interpretation: "<<propInterp);

        if (propInterp == "rgb") {
          fSampleVal = readScalarPropertyExt3<Abc::IC3fProperty, Abc::C3f>(
              propk, sampleInfo, prop, propComp);
        }
        else if (propInterp == "vector") {
          fSampleVal = readScalarPropertyExt3<Abc::IV3fProperty, Abc::V3f>(
              propk, sampleInfo, prop, propComp);
        }
        else {
          ESS_LOG_WARNING(
              "Float Controller Error: unrecognized parameter interpretation: "
              << propInterp);
        }
      }
    }
  }
  // else if( boost::iequals(szCategory, "arbGeomParams") ){

  //}

  return setController("6", szProperty, valid, interval, method, ptr,
                       fSampleVal);

  ESS_CPP_EXCEPTION_REPORTING_END
}
示例#7
0
bool AlembicWriteJob::PreProcess()
{
    // check filenames
    if(mFileName.empty())
    {
        ESS_LOG_WARNING("[alembic] No filename specified.");
        return false;
    }

    //// check objects
    //if(mSelection.Count() == 0)
    //{
    //    ESS_LOG_WARNING("[alembic] No objects specified.");
    //    return false;
    //}

    // check frames
    if(mFrames.size() == 0)
    {
        ESS_LOG_WARNING("[alembic] No frames specified.");
        return false;
    }


	const bool bParticleMesh = GetOption("exportParticlesAsMesh");
   bool bMergePolyMeshSubtree = GetOption("mergePolyMeshSubtree");

   bool bSelectParents = GetOption("includeParentNodes");/*|| !bFlattenHierarchy || bTransformCache*/
   const bool bSelectChildren = false;
   bool bTransformCache = GetOption("transformCache");
   const bool bFlattenHierarchy = GetOption("flattenHierarchy");

   if(bMergePolyMeshSubtree){
      bTransformCache = false;
      //bSelectParents = true;
   }

   bcsgSelection::types buildSelection = bcsgSelection::ALL;

   const bool bExportSelected = GetOption("exportSelected");
   const bool bObjectsParameterExists = GetOption("objectsParameterExists");
   if(bExportSelected){
      //copy max selection
      buildSelection = bcsgSelection::APP;
   }
   else if(bObjectsParameterExists){
      //select nothing when building, fill in later from parameter data
      buildSelection = bcsgSelection::NONE;
   }
   else{
      //select everything
   }

   int nNumNodes = 0;
   exoSceneRoot = buildCommonSceneGraph(nNumNodes, true, buildSelection);
   //WARNING ILM robot right crashes when printing
   //printSceneGraph(exoSceneRoot, false);


   if(bObjectsParameterExists){
      //Might be better to use refineSelection here, but call a function that sets up dccSelected flag first, then delete this function from codebase
      selectNodes(exoSceneRoot, mObjectsMap,  bSelectParents, bSelectChildren, !bTransformCache);

      bool bAllResolved = true;

      if(bObjectsParameterExists){
         for(SceneNode::SelectionT::iterator it = mObjectsMap.begin(); it != mObjectsMap.end(); it++){
            if(it->second == false){
               bAllResolved = false;
               ESS_LOG_ERROR("Could not resolve objects identifier: "<<it->first);
            }
         }
      }

      if(bAllResolved){
         removeUnselectedNodes(exoSceneRoot);
      }
      else{
         return false;
      }
   }
   else if(bExportSelected){
      refineSelection(exoSceneRoot, bSelectParents, bSelectChildren, !bTransformCache);
      removeUnselectedNodes(exoSceneRoot);
   }
   

   if(bMergePolyMeshSubtree){
      replacePolyMeshSubtree<SceneNodeMaxPtr, SceneNodeMax>(exoSceneRoot);
   }

   if(bFlattenHierarchy){
      nNumNodes = 0;
      flattenSceneGraph(exoSceneRoot, nNumNodes);
   }

   
  
   if(GetOption("renameConflictingNodes")){
      renameConflictingNodes(exoSceneRoot, false);
   }
   else{
      int nRenameCount = renameConflictingNodes(exoSceneRoot, true);
      if(nRenameCount){
         ESS_LOG_ERROR("Can not export due sibling node naming conflict. Consider exporting with renameConflictingNodes=true");
         return false;
      }
   }

    const bool bUseOgawa = (bool)GetOption("useOgawa");

    // init archive (use a locally scoped archive)
    std::string sceneFileName = "";
    sceneFileName.append( EC_MSTR_to_UTF8( mApplication->GetCurFilePath() ) );
    try
    {
       if(bUseOgawa){
        mArchive = CreateArchiveWithInfo(
            Alembic::AbcCoreOgawa::WriteArchive(),
			mFileName.c_str(),
			getExporterName( "3DS Max " EC_QUOTE( crate_Max_Version ) ).c_str(),
			getExporterFileName( sceneFileName ).c_str(),
			Abc::ErrorHandler::kThrowPolicy);
       }
       else{
        mArchive = CreateArchiveWithInfo(
			Alembic::AbcCoreHDF5::WriteArchive( true ),
			mFileName.c_str(),
			getExporterName( "3DS Max " EC_QUOTE( crate_Max_Version ) ).c_str(),
			getExporterFileName( sceneFileName ).c_str(),
			Abc::ErrorHandler::kThrowPolicy);
       }

    }
    catch(Alembic::Util::Exception& e)
    {
        std::string exc(e.what());
		    ESS_LOG_ERROR("[alembic] Error writing to file: "<<e.what());
        return false;
    }

    // get the frame rate
    mFrameRate = static_cast<float>(GetFrameRate());
    if(mFrameRate == 0.0f)
    {
        mFrameRate = 25.0f;
    }

    std::vector<AbcA::chrono_t> frames;
    for(LONG i=0;i<mFrames.size();i++)
    {
        frames.push_back(mFrames[i] / mFrameRate);
    }

    // create the sampling
    double timePerSample = 1.0 / mFrameRate;
    if(frames.size() > 1)
    {
		 if( ! HasAlembicWriterLicense() )
		 {
       if( HasAlembicInvalidLicense() ) {
          ESS_LOG_ERROR("[alembic] No license available and EXOCORTEX_ALEMBIC_NO_DEMO defined, aborting." );
          return false;
       }
			 if(frames.size() > 75)
			 {
				frames.resize(75);
				ESS_LOG_WARNING("[ExocortexAlembic] Writer license not found: Maximum exportable samplecount is 75!");
			 }
		 }
		 
	    double timePerCycle = frames[frames.size()-1] - frames[0];
        AbcA::TimeSamplingType samplingType((boost::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);
    }

    m_ArchiveBoxProp = AbcG::CreateOArchiveBounds(mArchive,mTs);



   std::list<PreProcessStackElement> sceneStack;
   
   sceneStack.push_back(PreProcessStackElement(exoSceneRoot, mArchive.getTop()));

   try{

   while( !sceneStack.empty() )
   {

      PreProcessStackElement sElement = sceneStack.back();
      SceneNodePtr eNode = sElement.eNode;
      sceneStack.pop_back();
      
      Abc::OObject oParent = sElement.oParent;
      Abc::OObject oNewParent;

      AlembicObjectPtr pNewObject;

      if(eNode->type == SceneNode::SCENE_ROOT){
         //we do not want to export the Scene_Root (the alembic archive has one already)
      }
      else if(eNode->type == SceneNode::ITRANSFORM || eNode->type == SceneNode::ETRANSFORM){
         pNewObject.reset(new AlembicXForm(eNode, this, oParent));
      }
      else if(eNode->type == SceneNode::CAMERA){
         pNewObject.reset(new AlembicCamera(eNode, this, oParent));
      }
      else if(eNode->type == SceneNode::POLYMESH || eNode->type == SceneNode::POLYMESH_SUBTREE){
         pNewObject.reset(new AlembicPolyMesh(eNode, this, oParent));
      }
      //TODO: as far I recall we dont support SUBD. verify...
      //else if(eNode->type == SceneNode::SUBD){
      //   pNewObject.reset(new AlembicSubD(eNode, this, oParent));
      //}
      else if(eNode->type == SceneNode::CURVES){
         pNewObject.reset(new AlembicCurves(eNode, this, oParent));
      }
      else if(eNode->type == SceneNode::PARTICLES || eNode->type == SceneNode::PARTICLES_TP){
         if(bParticleMesh){
            pNewObject.reset(new AlembicPolyMesh(eNode, this, oParent));
         }
         else{
            pNewObject.reset(new AlembicPoints(eNode, this, oParent));
         }
      }
      //else{
      //   ESS_LOG_WARNING("Unknown type: not exporting "<<eNode->name);//Export as transform, and give warning?
      //}

      if(pNewObject){
         //add the AlembicObject to export list if it is not being skipped
         AddObject(pNewObject);
      }

      if(pNewObject){
         oNewParent = oParent.getChild(eNode->name);
      }
      else{ //this case should be unecessary
         //if we skip node A, we parent node A's children to the parent of A
         oNewParent = oParent;
      }

      if(oNewParent.valid()){
         for( std::list<SceneNodePtr>::iterator it = eNode->children.begin(); it != eNode->children.end(); it++){
            sceneStack.push_back(PreProcessStackElement(*it, oNewParent));
         }
      }
      else{
         ESS_LOG_ERROR("Do not have refernce to parent.");
         return false;
      }
   }

   }catch( std::exception& exp ){
      ESS_LOG_ERROR("An std::exception occured: "<<exp.what());
      return false;
   }catch(...){
      ESS_LOG_ERROR("Exception ecountered when exporting.");
   }

   if(mObjects.empty()){
      ESS_LOG_ERROR("No objects specified.");
      return false;
   }

   return true;
}