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