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); } }
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; }