//-***************************************************************************** // // Copyright (c) 2009-2012, // Sony Pictures Imageworks, Inc. and // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Sony Pictures Imageworks, nor // Industrial Light & Magic nor the names of their contributors may be used // to endorse or promote products derived from this software without specific // prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //-***************************************************************************** #include "util.h" #include #include #include #include #include #include #include #include #include #include #include #include #include MObject createShadingGroup(const MString& iName) { MStatus status; MFnSet fnSet; MSelectionList selList; MObject shadingGroup = fnSet.create(selList, MFnSet::kRenderableOnly, &status); if (status != MS::kSuccess) { MString theError("Could not create shading engine: "); theError += iName; MGlobal::displayError(theError); return shadingGroup; } fnSet.setName(iName); return shadingGroup; } MObjectArray getOutConnectedSG( const MDagPath &shapeDPath ) { MStatus status; // Array of connected Shaging Engines MObjectArray connSG; // Iterator through the dependency graph to find if there are // shading engines connected MObject obj(shapeDPath.node()); // non const MObject MItDependencyGraph itDG( obj, MFn::kShadingEngine, MItDependencyGraph::kDownstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status ); if( status == MS::kFailure ) return connSG; // we want to prune the iteration if the node is not a shading engine itDG.enablePruningOnFilter(); // iterate through the output connected shading engines for( ; itDG.isDone()!= true; itDG.next() ) connSG.append( itDG.currentItem() ); return connSG; } MStatus replaceDagObject(MObject & oldObject, MObject & newObject, const MString & name) { MStatus status; MFnDagNode mFnOld(oldObject, &status); if (status == MS::kSuccess) { unsigned int numChild = mFnOld.childCount(); std::vector children; children.reserve(numChild); for (unsigned int i = 0; i < numChild; i++) { MObject child = mFnOld.child(i, &status); if (status == MS::kSuccess) { children.push_back(child); } else { MString theError("Failed to get child "); theError += i; theError += " of "; theError += mFnOld.name(); theError += ", status = "; theError += status.errorString(); MGlobal::displayError(theError); } } MFnDagNode mFnNew(newObject, &status); if (status == MS::kSuccess) { for (unsigned int i = 0; i < numChild; i++) { status = mFnNew.addChild(children[i]); if (status != MS::kSuccess) { MString theError("Failed to add child "); theError += i; theError += " of "; theError += mFnOld.name(); theError += " to "; theError += name; theError += ", status = "; theError += status.errorString(); MGlobal::displayError(theError); } } } } return status; } void disconnectProps(MFnDependencyNode & iNode, std::vector & iSampledPropList, std::size_t iFirstProp) { // get prop names and make sure they are disconnected before // trying to connect to them std::size_t numProps = iSampledPropList.size(); for (std::size_t i = iFirstProp; i < numProps; ++i) { std::string propName; if (iSampledPropList[i].mArray.valid()) { propName = iSampledPropList[i].mArray.getName(); } else { propName = iSampledPropList[i].mScalar.getName(); } // disconnect connections to animated props MPlug dstPlug; if (propName == Alembic::AbcGeom::kVisibilityPropertyName) { dstPlug = iNode.findPlug("visibility", true); } else { dstPlug = iNode.findPlug(propName.c_str(), true); } // make sure the long name matches if (propName == Alembic::AbcGeom::kVisibilityPropertyName || dstPlug.partialName(false, false, false, false, false, true) == propName.c_str()) { disconnectAllPlugsTo(dstPlug); } } } MStatus disconnectAllPlugsTo(MPlug & dstPlug) { MStatus status = MS::kSuccess; MPlugArray array; dstPlug.connectedTo(array, true, false, &status); unsigned int arrayLength = array.length(); for (unsigned int i = 0; i < arrayLength; i++) { MPlug srcPlug = array[i]; if (status == MS::kSuccess) { MDGModifier modifier; status = modifier.disconnect(srcPlug, dstPlug); status = modifier.doIt(); if (status != MS::kSuccess) { MString theError("Disconnect "); theError += srcPlug.name(); theError += MString(" -> "); theError += dstPlug.name(); theError += MString(" failed, status = "); theError += status.errorString(); MGlobal::displayError(theError); return status; } } } return MS::kSuccess; } MStatus getDagPathListByName(const MString & objectNames, std::vector & dagPathList) { MStatus status; MStringArray theArray; status = objectNames.split(' ', theArray); if (status == MS::kSuccess) { unsigned int len = theArray.length(); for (unsigned int i = 0; i < len; i++) { MDagPath dagPath; status = getDagPathByName(theArray[i], dagPath); if (status == MS::kSuccess) dagPathList.push_back(dagPath); else { MString theError(theArray[i]); theError += MString(" doesn't exist"); MGlobal::displayError(theError); } } } return status; } MStatus getObjectByName(const MString & name, MObject & object) { object = MObject::kNullObj; MSelectionList sList; MStatus status = sList.add(name); if (status == MS::kSuccess) { status = sList.getDependNode(0, object); } return status; } MStatus getDagPathByName(const MString & name, MDagPath & dagPath) { MSelectionList sList; MStatus status = sList.add(name); if (status == MS::kSuccess) { status = sList.getDagPath(0, dagPath); } return status; } std::string stripPathAndNamespace(const std::string & iPath) { std::string childName; std::size_t lastPath = iPath.rfind('|'); if (lastPath != std::string::npos) { childName = iPath.substr(lastPath + 1); } else { childName = iPath; } std::size_t lastNamespace = childName.rfind(':'); if (lastNamespace != std::string::npos) { childName = childName.substr(lastNamespace+1); } return childName; } bool getDagPathByChildName(MDagPath & ioDagPath, const std::string & iChildName) { unsigned int numChildren = ioDagPath.childCount(); std::string strippedName = stripPathAndNamespace(iChildName); MObject closeMatch; for (unsigned int i = 0; i < numChildren; ++i) { MObject child = ioDagPath.child(i); MFnDagNode dagChild(child); std::string name = dagChild.partialPathName().asChar(); if (name == iChildName) { ioDagPath.push(child); return true; } if (closeMatch.isNull()) { if (strippedName == stripPathAndNamespace(name)) { closeMatch = child; } } } if (!closeMatch.isNull()) { ioDagPath.push(closeMatch); return true; } return false; } MStatus getPlugByName(const MString & objName, const MString & attrName, MPlug & plug) { MObject object = MObject::kNullObj; MStatus status = getObjectByName(objName, object); if (status == MS::kSuccess) { MFnDependencyNode mFn(object, &status); if (status == MS::kSuccess) plug = mFn.findPlug(attrName, true, &status); } return status; } MStatus setPlayback(double min, double max) { MStatus status = MS::kSuccess; MAnimControl anim; MTime minTime, maxTime, curTime; minTime.setValue(min); maxTime.setValue(max); status = anim.setMinTime(minTime); status = anim.setAnimationStartTime(minTime); if (max > 0) { status = anim.setMaxTime(maxTime); status = anim.setAnimationEndTime(maxTime); } return status; } MStatus setInitialShadingGroup(const MString & dagNodeName) { MObject initShader; MDagPath dagPath; if (getObjectByName("initialShadingGroup", initShader) == MS::kSuccess && getDagPathByName(dagNodeName, dagPath) == MS::kSuccess) { MFnSet set(initShader); set.addMember(dagPath); } else { MString theError("Error getting adding "); theError += dagNodeName; theError += MString(" to initalShadingGroup."); MGlobal::displayError(theError); return MS::kFailure; } return MS::kSuccess; } MStatus deleteDagNode(MDagPath & dagPath) { MObject obj = dagPath.node(); return MGlobal::deleteNode(obj); } MStatus deleteCurrentSelection() { MStatus status; MDGModifier modifier; status = modifier.commandToExecute("\ndelete;\n"); status = modifier.doIt(); return status; } bool stripFileName(const MString & filePath, MString & fileName) { std::string str(filePath.asChar()); size_t found; found = str.find_last_of("/\\"); str = str.substr(found+1); // str is now in the form of xxx.abc found = str.find_first_of("."); str = str.substr(0, found); fileName = MString(str.c_str()); return true; } double getWeightAndIndex(double iFrame, Alembic::AbcCoreAbstract::TimeSamplingPtr iTime, size_t numSamps, Alembic::AbcCoreAbstract::index_t & oIndex, Alembic::AbcCoreAbstract::index_t & oCeilIndex) { if (numSamps == 0) numSamps = 1; std::pair floorIndex = iTime->getFloorIndex(iFrame, numSamps); oIndex = floorIndex.first; oCeilIndex = oIndex; if (fabs(iFrame - floorIndex.second) < 0.0001) return 0.0; std::pair ceilIndex = iTime->getCeilIndex(iFrame, numSamps); if (oIndex == ceilIndex.first) return 0.0; oCeilIndex = ceilIndex.first; double alpha = (iFrame - floorIndex.second) / (ceilIndex.second - floorIndex.second); // we so closely match the ceiling so we'll just use it if (fabs(1.0 - alpha) < 0.0001) { oIndex = oCeilIndex; return 0.0; } return alpha; } bool isColorSet(const Alembic::AbcCoreAbstract::PropertyHeader & iHeader, bool iUnmarkedFaceVaryingColors) { bool isColor = Alembic::AbcGeom::IC3fGeomParam::matches(iHeader) || Alembic::AbcGeom::IC4fGeomParam::matches(iHeader); Alembic::AbcGeom::GeometryScope scope = Alembic::AbcGeom::GetGeometryScope(iHeader.getMetaData()); bool isScoped = (scope == Alembic::AbcGeom::kFacevaryingScope || scope == Alembic::AbcGeom::kVaryingScope || scope == Alembic::AbcGeom::kVertexScope); return (isColor && isScoped && (iUnmarkedFaceVaryingColors || iHeader.getMetaData().get("mayaColorSet") != "")); }