int removeUnselectedNodes(SceneNodePtr root) { ESS_PROFILE_FUNC(); int nNumNodes = 0; SceneNodePtr newRoot = root; std::list<FlattenStackElement> sceneStack; // push a reference to each child to the stack for (SceneChildIterator it = root->children.begin(); it != root->children.end(); it++) { SceneNodePtr fileNode = *it; sceneStack.push_back(FlattenStackElement(fileNode, root)); } // clear the children since we may be changing what is parented to it root->children.clear(); while (!sceneStack.empty()) { FlattenStackElement sElement = sceneStack.back(); SceneNodePtr fileNode = sElement.currNode; SceneNodePtr parentNode = sElement.currParentNode; // a node from the original tree, its // childrens will have been cleared // we will add child nodes to it that meet the correct criteria sceneStack.pop_back(); if (fileNode->selected) { parentNode->children.push_back(fileNode); fileNode->parent = parentNode.get(); fileNode->selected = false; nNumNodes++; for (SceneChildIterator it = fileNode->children.begin(); it != fileNode->children.end(); it++) { sceneStack.push_back(FlattenStackElement(*it, fileNode)); } } else { // if a shape node is not selected its parent transform should become an // ITRANSFORM if (isShapeNode(fileNode->type) && fileNode->parent && fileNode->parent->selected && fileNode->parent->type == SceneNode::ETRANSFORM) { fileNode->parent->type = SceneNode::ITRANSFORM; } for (SceneChildIterator it = fileNode->children.begin(); it != fileNode->children.end(); it++) { sceneStack.push_back(FlattenStackElement(*it, parentNode)); } } fileNode->children.clear(); } return nNumNodes; }
void Node::output(ostream& printStream, int indentLevet) { char *indentString = getIndentLevelString(indentLevet); if (isInstanceNode() == false) { outputHead(printStream, indentString); outputContext(printStream, indentString); if (!isElevationGridNode() && !isShapeNode() && !isSoundNode() && !isPointSetNode() && !isIndexedFaceSetNode() && !isIndexedLineSetNode() && !isTextNode() && !isAppearanceNode()) { if (getChildNodes() != NULL) { if (isLodNode()) printStream << indentString << "\tlevel [" << endl; else if (isSwitchNode()) printStream << indentString << "\tchoice [" << endl; else printStream << indentString <<"\tchildren [" << endl; for (Node *node = getChildNodes(); node; node = node->next()) { if (node->isInstanceNode() == false) node->output(printStream, indentLevet+2); else node->output(printStream, indentLevet+2); } printStream << indentString << "\t]" << endl; } } outputTail(printStream, indentString); } else printStream << indentString << "USE " << getName() << endl; delete indentString; }
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 flattenSceneGraph(SceneNodePtr root, int nNumNodes) { ESS_PROFILE_FUNC(); SceneNodePtr newRoot = root; std::list<FlattenStackElement> sceneStack; //push a reference to each child to the stack for(SceneChildIterator it = root->children.begin(); it != root->children.end(); it++){ SceneNodePtr fileNode = *it; sceneStack.push_back(FlattenStackElement(fileNode, root)); } //clear the children since we may be changing what is parented to it root->children.clear(); while( !sceneStack.empty() ) { FlattenStackElement sElement = sceneStack.back(); SceneNodePtr fileNode = sElement.currNode; SceneNodePtr parentNode = sElement.currParentNode;//a node from the original tree, its childrens will have been cleared //we will add child nodes to it that meet the correct criteria sceneStack.pop_back(); //a nodes that we want keep, so connect it to the parent if (fileNode->type == SceneNode::NAMESPACE_TRANSFORM || //namespace transform (XSI model) fileNode->type == SceneNode::ETRANSFORM || //shape node parent transform isShapeNode(fileNode->type) //shape node ) { //mergedpolymesh node would apply here parentNode->children.push_back(fileNode); fileNode->parent = parentNode.get(); nNumNodes++; } //here we set what the parent is going to be for the file node we pushing to the stack // - if parentNode is passed instead of fileNode, the subtree starting at fileNode is being skipped if(fileNode->type == SceneNode::NAMESPACE_TRANSFORM){ for(SceneChildIterator it = fileNode->children.begin(); it != fileNode->children.end(); it++){ sceneStack.push_back( FlattenStackElement( *it, fileNode ) ); } } else if(fileNode->type == SceneNode::ETRANSFORM){ for(SceneChildIterator it = fileNode->children.begin(); it != fileNode->children.end(); it++){ if(isShapeNode((*it)->type)){ sceneStack.push_back( FlattenStackElement( *it, fileNode ) ); } else{ sceneStack.push_back( FlattenStackElement( *it, parentNode ) ); } } } else{ for(SceneChildIterator it = fileNode->children.begin(); it != fileNode->children.end(); it++){ sceneStack.push_back( FlattenStackElement( *it, parentNode ) ); } } fileNode->children.clear(); } }
Node *Node::createInstanceNode() { Node *instanceNode = NULL; if (isAnchorNode()) instanceNode = new AnchorNode(); else if (isAppearanceNode()) instanceNode = new AppearanceNode(); else if (isAudioClipNode()) instanceNode = new AudioClipNode(); else if (isBackgroundNode()) instanceNode = new BackgroundNode(); else if (isBillboardNode()) instanceNode = new BillboardNode(); else if (isBoxNode()) instanceNode = new BoxNode(); else if (isCollisionNode()) instanceNode = new CollisionNode(); else if (isColorNode()) instanceNode = new ColorNode(); else if (isColorInterpolatorNode()) instanceNode = new ColorInterpolatorNode(); else if (isConeNode()) instanceNode = new ConeNode(); else if (isCoordinateNode()) instanceNode = new CoordinateNode(); else if (isCoordinateInterpolatorNode()) instanceNode = new CoordinateInterpolatorNode(); else if (isCylinderNode()) instanceNode = new CylinderNode(); else if (isCylinderSensorNode()) instanceNode = new CylinderSensorNode(); else if (isDirectionalLightNode()) instanceNode = new DirectionalLightNode(); else if (isElevationGridNode()) instanceNode = new ElevationGridNode(); else if (isExtrusionNode()) instanceNode = new ExtrusionNode(); else if (isFogNode()) instanceNode = new FogNode(); else if (isFontStyleNode()) instanceNode = new FontStyleNode(); else if (isGroupNode()) instanceNode = new GroupNode(); else if (isImageTextureNode()) instanceNode = new ImageTextureNode(); else if (isIndexedFaceSetNode()) instanceNode = new IndexedFaceSetNode(); else if (isIndexedLineSetNode()) instanceNode = new IndexedLineSetNode(); else if (isInlineNode()) instanceNode = new InlineNode(); else if (isLodNode()) instanceNode = new LodNode(); else if (isMaterialNode()) instanceNode = new MaterialNode(); else if (isMovieTextureNode()) instanceNode = new MovieTextureNode(); else if (isNavigationInfoNode()) instanceNode = new NavigationInfoNode(); else if (isNormalNode()) instanceNode = new NormalNode(); else if (isNormalInterpolatorNode()) instanceNode = new NormalInterpolatorNode(); else if (isOrientationInterpolatorNode()) instanceNode = new OrientationInterpolatorNode(); else if (isPixelTextureNode()) instanceNode = new PixelTextureNode(); else if (isPlaneSensorNode()) instanceNode = new PlaneSensorNode(); else if (isPointLightNode()) instanceNode = new PointLightNode(); else if (isPointSetNode()) instanceNode = new PointSetNode(); else if (isPositionInterpolatorNode()) instanceNode = new PositionInterpolatorNode(); else if (isProximitySensorNode()) instanceNode = new ProximitySensorNode(); else if (isScalarInterpolatorNode()) instanceNode = new ScalarInterpolatorNode(); else if (isScriptNode()) instanceNode = new ScriptNode(); else if (isShapeNode()) instanceNode = new ShapeNode(); else if (isSoundNode()) instanceNode = new SoundNode(); else if (isSphereNode()) instanceNode = new SphereNode(); else if (isSphereSensorNode()) instanceNode = new SphereSensorNode(); else if (isSpotLightNode()) instanceNode = new SpotLightNode(); else if (isSwitchNode()) instanceNode = new SwitchNode(); else if (isTextNode()) instanceNode = new TextNode(); else if (isTextureCoordinateNode()) instanceNode = new TextureCoordinateNode(); else if (isTextureTransformNode()) instanceNode = new TextureTransformNode(); else if (isTimeSensorNode()) instanceNode = new TimeSensorNode(); else if (isTouchSensorNode()) instanceNode = new TouchSensorNode(); else if (isTransformNode()) instanceNode = new TransformNode(); else if (isViewpointNode()) instanceNode = new ViewpointNode(); else if (isVisibilitySensorNode()) instanceNode = new VisibilitySensorNode(); else if (isWorldInfoNode()) instanceNode = new WorldInfoNode(); assert(instanceNode); if (instanceNode) { Node *refNode = this; while (refNode->isInstanceNode() == true) refNode = refNode->getReferenceNode(); instanceNode->setAsInstanceNode(refNode); for (Node *cnode=getChildNodes(); cnode; cnode = cnode->next()) { Node *childInstanceNode = cnode->createInstanceNode(); instanceNode->addChildNode(childInstanceNode); } } return instanceNode; }