void AlembicWriteJob::createArchive(const char *sceneFileName)
{
  const std::string expName =
      getExporterName("Maya " EC_QUOTE(crate_Maya_Version));
  const std::string expFileName = getExporterFileName(sceneFileName);
  if (useOgawa) {
    mArchive = CreateArchiveWithInfo(
        Alembic::AbcCoreOgawa::WriteArchive(), mFileName.asChar(),
        expName.c_str(), expFileName.c_str(), Abc::ErrorHandler::kThrowPolicy);
  }
  else {
    mArchive = CreateArchiveWithInfo(
        Alembic::AbcCoreHDF5::WriteArchive(true), mFileName.asChar(),
        expName.c_str(), expFileName.c_str(), Abc::ErrorHandler::kThrowPolicy);
  }
}
Example #2
0
bool AbcWriteJob::eval(double iFrame)
{
	if (iFrame == mFirstFrame)
	{
		// check if the shortnames of any two nodes are the same
		// if so, exit here
		hasDuplicates(mArgs.dagPaths, mArgs.stripNamespace);

		std::string appWriter = "Maya ";
		appWriter += MGlobal::mayaVersion().asChar();
		appWriter += " AbcBullet v";
		appWriter += ABCBULLET_VERSION;

		std::string userInfo = "Exported from: ";
		userInfo += MFileIO::currentFile().asChar();

		// these symbols can't be in the meta data
		if (userInfo.find('=') != std::string::npos ||
			userInfo.find(';') != std::string::npos)
		{
			userInfo = "";
		}

		mRoot = CreateArchiveWithInfo(Alembic::AbcCoreHDF5::WriteArchive(),
			mFileName, appWriter, userInfo,
			Alembic::Abc::ErrorHandler::kThrowPolicy);
		mTransTimeIndex = mRoot.addTimeSampling(*mTransTime);

		mBoxProp =  Alembic::AbcGeom::CreateOArchiveBounds(mRoot,
			mTransTimeIndex);

		if (!mRoot.valid())
		{
			std::string theError = "Unable to create abc file";
			throw std::runtime_error(theError);
		}

		util::ShapeSet::const_iterator end = mArgs.dagPaths.end();
		util::GetMembersMap gmMap;
		for (util::ShapeSet::const_iterator it = mArgs.dagPaths.begin();
			it != end; ++it)
		{
			mCurDag = *it;
			setup(iFrame * util::spf(), MayaTransformWriterPtr(), gmMap);
		}
		perFrameCallback(iFrame);
	}
	else
	{
		std::set<double>::iterator checkFrame = mTransFrames.find(iFrame);
		bool foundTransFrame = false;
		if (checkFrame != mTransFrames.end())
		{
			assert(mRoot.valid());
			foundTransFrame = true;
			mTransSamples ++;

			// write out transforms
			{
				std::vector< MayaTransformWriterPtr >::iterator tcur =
					mTransList.begin();

				std::vector< MayaTransformWriterPtr >::iterator tend =
					mTransList.end();

				for (; tcur != tend; tcur++)
				{
					(*tcur)->write();
				}

				std::vector< AttributesWriterPtr >::iterator tattrCur =
					mTransAttrList.begin();

				std::vector< AttributesWriterPtr >::iterator tattrEnd =
					mTransAttrList.end();

				for(; tattrCur != tattrEnd; tattrCur++)
				{
					(*tattrCur)->write();
				}
			}

			// write out transform collections
			{
				std::vector< MayaTransformCollectionWriterPtr >::iterator tcur =
					mTransColList.begin();

				std::vector< MayaTransformCollectionWriterPtr >::iterator tend =
					mTransColList.end();

				for (; tcur != tend; tcur++)
				{
					(*tcur)->write(iFrame);
				}

				std::vector< AttributesWriterPtr >::iterator tattrCur =
					mTransColAttrList.begin();

				std::vector< AttributesWriterPtr >::iterator tattrEnd =
					mTransColAttrList.end();

				for(; tattrCur != tattrEnd; tattrCur++)
				{
					(*tattrCur)->write();
				}
			}
		}
		if (foundTransFrame)
			perFrameCallback(iFrame);
	}

	if (iFrame == mLastFrame)
	{
		postCallback(iFrame);
		return true;
	}

	return false;
}
bool AbcWriteJob::eval(double iFrame)
{
    if (iFrame == mFirstFrame)
    {
        // check if the shortnames of any two nodes are the same
        // if so, exit here
        hasDuplicates(mArgs.dagPaths, mArgs.stripNamespace);

        std::string appWriter = "Maya ";
        appWriter += MGlobal::mayaVersion().asChar();
        appWriter += " AbcExport v";
        appWriter += ABCEXPORT_VERSION;

        std::string userInfo = "Exported from: ";
        userInfo += MFileIO::currentFile().asChar();

        // these symbols can't be in the meta data
        if (userInfo.find('=') != std::string::npos ||
            userInfo.find(';') != std::string::npos)
        {
            userInfo = "";
        }

#ifdef ALEMBIC_WITH_HDF5
        if (mAsOgawa)
        {
            mRoot = CreateArchiveWithInfo(Alembic::AbcCoreOgawa::WriteArchive(),
                mFileName, appWriter, userInfo,
                Alembic::Abc::ErrorHandler::kThrowPolicy);
        }
        else
        {
            mRoot = CreateArchiveWithInfo(Alembic::AbcCoreHDF5::WriteArchive(),
                mFileName, appWriter, userInfo,
                Alembic::Abc::ErrorHandler::kThrowPolicy);
        }
#else
        // just write it out as Ogawa
        mRoot = CreateArchiveWithInfo(Alembic::AbcCoreOgawa::WriteArchive(),
            mFileName, appWriter, userInfo,
            Alembic::Abc::ErrorHandler::kThrowPolicy);
#endif

        mShapeTimeIndex = mRoot.addTimeSampling(*mShapeTime);
        mTransTimeIndex = mRoot.addTimeSampling(*mTransTime);

        mBoxProp =  Alembic::AbcGeom::CreateOArchiveBounds(mRoot,
            mTransTimeIndex);

        if (!mRoot.valid())
        {
            std::string theError = "Unable to create abc file";
            throw std::runtime_error(theError);
        }

        mArgs.setFirstAnimShape = (iFrame == *mShapeFrames.begin());

        util::ShapeSet::const_iterator end = mArgs.dagPaths.end();
        GetMembersMap gmMap;
        for (util::ShapeSet::const_iterator it = mArgs.dagPaths.begin();
            it != end; ++it)
        {
            mCurDag = *it;
            setup(iFrame * util::spf(), MayaTransformWriterPtr(), gmMap);
        }
        perFrameCallback(iFrame);
    }
    else
    {
        std::set<double>::iterator checkFrame = mShapeFrames.find(iFrame);
        bool foundShapeFrame = false;
        if (checkFrame != mShapeFrames.end())
        {
            assert(mRoot != NULL);
            foundShapeFrame = true;
            mShapeSamples ++;
            double curTime = iFrame * util::spf();

            std::vector< MayaCameraWriterPtr >::iterator camIt, camEnd;
            camEnd = mCameraList.end();
            for (camIt = mCameraList.begin(); camIt != camEnd; camIt++)
            {
                (*camIt)->write();
            }

            std::vector< MayaMeshWriterPtr >::iterator meshIt, meshEnd;
            meshEnd = mMeshList.end();
            for (meshIt = mMeshList.begin(); meshIt != meshEnd; meshIt++)
            {
                (*meshIt)->write();
                if ((*meshIt)->isSubD())
                {
                    mStats.mSubDAnimCVs += (*meshIt)->getNumCVs();
                }
                else
                {
                    mStats.mPolyAnimCVs += (*meshIt)->getNumCVs();
                }
            }

            std::vector< MayaNurbsCurveWriterPtr >::iterator curveIt, curveEnd;
            curveEnd = mCurveList.end();
            for (curveIt = mCurveList.begin(); curveIt != curveEnd; curveIt++)
            {
                (*curveIt)->write();
                mStats.mCurveAnimCVs += (*curveIt)->getNumCVs();
            }

            std::vector< MayaNurbsSurfaceWriterPtr >::iterator nurbsIt,nurbsEnd;
            nurbsEnd = mNurbsList.end();
            for (nurbsIt = mNurbsList.begin(); nurbsIt != nurbsEnd; nurbsIt++)
            {
                (*nurbsIt)->write();
                mStats.mNurbsAnimCVs += (*nurbsIt)->getNumCVs();
            }

            std::vector< MayaLocatorWriterPtr >::iterator locIt, locEnd;
            locEnd = mLocatorList.end();
            for (locIt = mLocatorList.begin(); locIt != locEnd; locIt++)
            {
                (*locIt)->write();
            }

            std::vector< MayaPointPrimitiveWriterPtr >::iterator ptIt, ptEnd;
            ptEnd = mPointList.end();
            for (ptIt = mPointList.begin(); ptIt != ptEnd; ptIt++)
            {
                (*ptIt)->write(curTime);
                mStats.mPointAnimCVs += (*ptIt)->getNumCVs();
            }

            std::vector< AttributesWriterPtr >::iterator sattrCur =
                mShapeAttrList.begin();

            std::vector< AttributesWriterPtr >::iterator sattrEnd =
                mShapeAttrList.end();

            for(; sattrCur != sattrEnd; sattrCur++)
            {
                (*sattrCur)->write();
            }
        }

        checkFrame = mTransFrames.find(iFrame);
        bool foundTransFrame = false;
        if (checkFrame != mTransFrames.end())
        {
            assert(mRoot.valid());
            foundTransFrame = true;
            mTransSamples ++;
            std::vector< MayaTransformWriterPtr >::iterator tcur =
                mTransList.begin();

            std::vector< MayaTransformWriterPtr >::iterator tend =
                mTransList.end();

            for (; tcur != tend; tcur++)
            {
                (*tcur)->write();
            }

            std::vector< AttributesWriterPtr >::iterator tattrCur =
                mTransAttrList.begin();

            std::vector< AttributesWriterPtr >::iterator tattrEnd =
                mTransAttrList.end();

            for(; tattrCur != tattrEnd; tattrCur++)
            {
                (*tattrCur)->write();
            }
        }

        if (foundTransFrame || foundShapeFrame)
            perFrameCallback(iFrame);
    }

    if (iFrame == mLastFrame)
    {
        postCallback(iFrame);
        return true;
    }

    return false;
}
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;
}