MStatus GetShapeNode(MDagPath& path, bool intermediate) { MStatus status; if (IsShapeNode(path)) { // Start at the transform so we can honor the intermediate flag. path.pop(); } if (path.hasFn(MFn::kTransform)) { unsigned int shapeCount = path.childCount(); for (unsigned int i = 0; i < shapeCount; ++i) { status = path.push(path.child(i)); CHECK_MSTATUS_AND_RETURN_IT(status); if (!IsShapeNode(path)) { path.pop(); continue; } MFnDagNode fnNode(path, &status); CHECK_MSTATUS_AND_RETURN_IT(status); if ((!fnNode.isIntermediateObject() && !intermediate) || (fnNode.isIntermediateObject() && intermediate)) { return MS::kSuccess; } // Go to the next shape path.pop(); } } // No valid shape node found. return MS::kFailure; }
MStatus sgCurveEditBrush_context::getShapeNode( MDagPath& path ) { MStatus status; if ( path.apiType() == MFn::kNurbsCurve ) { return MS::kSuccess; } unsigned int numShapes; status = path.numberOfShapesDirectlyBelow( numShapes ); CHECK_MSTATUS_AND_RETURN_IT( status ); for ( unsigned int i = 0; i < numShapes; ++i ) { status = path.extendToShapeDirectlyBelow( i ); CHECK_MSTATUS_AND_RETURN_IT( status ); if ( !path.hasFn( MFn::kNurbsCurve ) ) { path.pop(); continue; } MFnDagNode fnNode( path, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); if ( !fnNode.isIntermediateObject() ) { return MS::kSuccess; } path.pop(); } return MS::kFailure; }
bool IsLayerVisible(MDagPath& dp) { MStatus stat = MStatus::kSuccess; MDagPath dagPath = dp; while (stat == MStatus::kSuccess) { MFnDependencyNode node(dagPath.node()); MPlug doPlug = node.findPlug("drawOverride", &stat); if (stat) { MObject layer = getOtherSideNode(doPlug); MFnDependencyNode layerNode(layer, &stat); if (stat) { bool visibility = true; if (getBool("visibility", layerNode, visibility)) if (!visibility) return false; if (getEnumInt("displayType", layerNode) == 1) // template return false; } } stat = dagPath.pop(); } return true; }
bool IsLayerVisible(MDagPath& dp) { MStatus stat = MStatus::kSuccess; MDagPath dagPath = dp; while (stat == MStatus::kSuccess) { MFnDependencyNode node(dagPath.node()); MPlug doPlug = node.findPlug("drawOverride", &stat); if( stat ) { MObject layer = getOtherSideNode(doPlug); MFnDependencyNode layerNode(layer, &stat); if( stat ) { MGlobal::displayInfo(MString("check layer ") + layerNode.name() + " for node " + dagPath.fullPathName()); bool visibility = true; if(getBool("visibility", layerNode, visibility)) if(!visibility) return false; } } stat = dagPath.pop(); } return true; }
MVector swissArmyLocatorManip::nodeTranslation() const { MFnDagNode dagFn(fNodePath); MDagPath path; dagFn.getPath(path); path.pop(); // pop from the shape to the transform MFnTransform transformFn(path); return transformFn.translation(MSpace::kWorld); }
//----------------------------------------------------------------------------- // // Purpose: Determine if a given Maya Dag path is visible through // Simply makes sure the node and all of its ancestors are visible // Input: mDagPath The node to check for visibility // Output: templateAsInvisible If true, template objects are considered to be invisible // //----------------------------------------------------------------------------- bool ValveMaya::IsPathVisible( MDagPath mDagPath, bool bTemplateAsInvisible ) { for ( ; mDagPath.length(); mDagPath.pop() ) { if ( !IsNodeVisible( mDagPath, bTemplateAsInvisible ) ) return false; } return true; }
AbcWriteJob::AbcWriteJob(const char * iFileName, std::set<double> & iTransFrames, Alembic::AbcCoreAbstract::TimeSamplingPtr iTransTime, const JobArgs & iArgs) { MStatus status; mFileName = iFileName; mBoxIndex = 0; mArgs = iArgs; mTransSamples = 1; if (mArgs.useSelectionList) { bool emptyDagPaths = mArgs.dagPaths.empty(); // get the active selection MSelectionList activeList; MGlobal::getActiveSelectionList(activeList); mSList = activeList; unsigned int selectionSize = activeList.length(); for (unsigned int index = 0; index < selectionSize; index ++) { MDagPath dagPath; status = activeList.getDagPath(index, dagPath); if (status == MS::kSuccess) { unsigned int length = dagPath.length(); while (--length) { dagPath.pop(); mSList.add(dagPath, MObject::kNullObj, true); } if (emptyDagPaths) { mArgs.dagPaths.insert(dagPath); } } } } mTransFrames = iTransFrames; // only needed during creation of the transforms mTransTime = iTransTime; mTransTimeIndex = 0; // should have at least 1 value assert(!mTransFrames.empty()); mFirstFrame = *(mTransFrames.begin()); std::set<double>::iterator last = mTransFrames.end(); last--; mLastFrame = *last; }
bool IsPathTemplated(MDagPath& path) { MStatus stat = MStatus::kSuccess; while (stat == MStatus::kSuccess) { MFnDagNode node; node.setObject(path.node()); if (IsTemplated(node)) return true; stat = path.pop(); } return false; }
MMatrix HesperisIO::GetParentTransform(const MDagPath & path) { MMatrix m; MDagPath parentPath = path; parentPath.pop(); MStatus stat; MFnTransform ft(parentPath, &stat); if(!stat) { MGlobal::displayWarning(MString("hesperis io cannot create transform func by paht ")+path.fullPathName()); return m; } m = ft.transformation().asMatrix(); return m; }
bool IsPathVisible(MDagPath& dp) { MStatus stat = MStatus::kSuccess; MDagPath dagPath = dp; while (stat == MStatus::kSuccess) { MFnDagNode node(dagPath.node()); if (!IsVisible(node)) { return false; } stat = dagPath.pop(); } return true; }
MMatrix HesperisIO::GetWorldTransform(const MDagPath & path) { MMatrix m; MDagPath parentPath = path; MStatus stat; for(;;) { stat = parentPath.pop(); if(!stat) break; MFnTransform ft(parentPath, &stat); if(!stat) { return m; } m *= ft.transformation().asMatrix(); } return m; }
// Remove any DAG object not in the selectedObjects list. void ShapeMonitor::stopWatchingUnselectedDagObjects(MSelectionList& selectedObjects) { // For each monitored object... for (int i = monitoredObjectsPtrArray.length()-1; i >= 0; i--) { MonitoredObject *pMonObject = monitoredObjectsPtrArray[i]; MStatus stat; // Get an MObject for the MonitoredObject->mayaNodeName. MDagPath dagpath; MSelectionList selList; selList.add(pMonObject->mayaNodeName); stat = selList.getDagPath(0, dagpath); // If the MObject is a DAG node... if (stat) { bool found = false; // Check if the dag path is included in the selectedObjects list. // For example, say that dagpath = "|group1|group2|pSphere|pSphereShape", // selectedObjects contains "|group1|group2". // We first check if dagpath is included in selectedObjects. If that's not the // case, we pop() one component, so that dagpath = "|group1|group2|pSphere", then // check again. We do that until either the dagpath is found to be included in // the selectedObjects list, or until there's no component left in dagpath. while (!found && dagpath.length() > 0) { // Since we store the shape name (as opposed to the parent transform dagpath), // we need to pop() to get the parent transform dagpath. dagpath.pop(); MObject component; // Check if the dag path is included in the objects list. if (selectedObjects.hasItemPartly(dagpath, component)) found = true; } // If the object was not in the selectedObjects list, stop watching it. if (!found) stopWatching(pMonObject->mayaNodeName); } } }
bool OpenSubdivDrawOverride::getSelectionStatus(const MDagPath& objPath) const { // retrieve the selection status of the node MStatus status; MSelectionList selectedList; status = MGlobal::getActiveSelectionList(selectedList); if(!status) return false; MDagPath pathCopy = objPath; do { if(selectedList.hasItem(pathCopy)) return true; status = pathCopy.pop(); } while(status); return false; }
// ------------------------------------------------------------ void SceneGraph::appendForcedNodeToList ( const MDagPath& dagPath ) { // Attach a function set MFnDependencyNode fn ( dagPath.node() ); String theNodeName = fn.name().asChar(); MDagPath dagPathCopy = dagPath; while ( dagPathCopy.length() > 0 && !isForcedNode ( dagPathCopy ) ) { // Attach a function set MFnDependencyNode fn ( dagPathCopy.node() ); String theNodeName = fn.name().asChar(); mForcedNodes.append ( dagPathCopy ); dagPathCopy.pop(); } }
MStatus V3Manipulator::connectToDependNode( const MObject & node ) { MFnDagNode dagFn( node ); MDagPath nodePath; dagFn.getPath( nodePath ); MStatus status; m_translatePlug = dagFn.findPlug( m_plug.partialName(), &status ); if( !status ) { return MStatus::kFailure; } MFnFreePointTriadManip translateFn( m_translateManip ); translateFn.connectToPointPlug( m_translatePlug ); addManipToPlugConversionCallback( m_translatePlug, (manipToPlugConversionCallback)&V3Manipulator::vectorManipToPlugConversion ); addPlugToManipConversionCallback( translateFn.pointIndex(), (plugToManipConversionCallback)&V3Manipulator::vectorPlugToManipConversion ); MStatus stat = finishAddingManips(); if( stat == MStatus::kFailure ) { return MStatus::kFailure; } MPxManipContainer::connectToDependNode( node ); readParameterOptions( dagFn ); if( m_worldSpace) { m_localMatrix.setToIdentity(); m_localMatrixInv.setToIdentity(); } else { // Inherit any transform to the parent MDagPath transformPath = nodePath; transformPath.pop(); MFnTransform transformFn( transformPath ); m_localMatrix = transformPath.inclusiveMatrix(); m_localMatrixInv = transformPath.inclusiveMatrixInverse(); } return stat; }
// check if the node or any of its parents has a animated visibility bool MayaObject::isVisiblityAnimated() { MStatus stat = MStatus::kSuccess; bool visibility = true; MDagPath dp = this->dagPath; while (stat == MStatus::kSuccess) { MFnDependencyNode depFn(dp.node()); MPlug vplug = depFn.findPlug("visibility"); if(vplug.isConnected()) { Logging::debug(MString("Object: ") + vplug.name() + " has animated visibility"); return true; } stat = dp.pop(); } return false; }
static MObject EntityNodeParent( MDagPath& path ) { if( path.hasFn( MFn::kDagNode ) ) { MDagPath parentPath; MFnDependencyNode nodeFn; while( path.pop( 1 ) != MS::kInvalidParameter ) { nodeFn.setObject( path.node() ); if( nodeFn.typeId() == EntityInstanceNode::s_TypeID ) { return nodeFn.object(); } } } return MObject::kNullObj; }
MStatus CMayaManager::BindViewerToPanel (const char* strView) { //HRESULT hr= S_OK; HWND renderwnd= NULL; MDagPath MayaCamera; if(strView == NULL) strView= ""; StringCchCopyA(m_ViewerBinding, MAX_PATH, strView); if(strView && (strView[0] != '\0')) { if(0 == lstrcmpiA(strView, "floating")) { g_Viewer.BindToWindow(NULL, true); } else { M3dView ourView; M3dView::get3dView(0,ourView); for(UINT iView= 0; iView < M3dView::numberOf3dViews(); iView++) { M3dView::get3dView(iView, ourView); ourView.getCamera(MayaCamera); MayaCamera.pop(); if(MayaCamera.partialPathName() == MString(strView)) { renderwnd= (HWND)ourView.window(); g_Viewer.BindToWindow(ourView.window(), true); break; } } } } //e_Exit: return MS::kSuccess; }
HRESULT CMayaManager::PerspectiveCamera_Synchronize() { MDagPath MayaCamera; M3dView panel; for(UINT iView= 0; iView < M3dView::numberOf3dViews(); iView++) { D3DXMATRIX mCamera; M3dView::get3dView(iView, panel); panel.getCamera(MayaCamera); MayaCamera.pop(); MString perspNameStr( "persp" ); MString cameraNameStr = MayaCamera.partialPathName(); cameraNameStr = cameraNameStr.substring(0, perspNameStr.length()-1 ); const char* cameraName= cameraNameStr.asChar(); if(cameraNameStr == perspNameStr ) { MayaCamera.extendToShape(); MFloatMatrix fView(MayaCamera.inclusiveMatrix().matrix ); ConvertWorldMatrix(mCamera, fView); panel.getCamera(MayaCamera); MFnCamera fnMayaCamera(MayaCamera.node()); MVector mUp= fnMayaCamera.upDirection(); MVector mAt= fnMayaCamera.viewDirection(); MPoint mEye= fnMayaCamera.eyePoint(MSpace::kWorld); D3DXVECTOR3 dxEye( (float)mEye.x, (float)mEye.y, (float)-mEye.z ); D3DXVECTOR3 dxAt( (float)mAt.x, (float)mAt.y, (float)-mAt.z ); D3DXVECTOR3 dxUp( (float)mUp.x, (float)mUp.y, (float)-mUp.z ); D3DXVECTOR4 fEye; D3DXVECTOR4 fAt; D3DXVECTOR3 fUp; D3DXVec3Transform(&fEye, &dxEye,(D3DXMATRIX*)&mCamera); D3DXVec3Transform(&fAt, &dxAt,(D3DXMATRIX*)&mCamera); D3DXVec3TransformNormal(&fUp, &dxUp,(D3DXMATRIX*)&mCamera); D3DXMatrixLookAtLH(&PerspectiveCamera_View, (D3DXVECTOR3*)&fEye, (D3DXVECTOR3*)&fAt, &fUp); // Projection matrix float zNear = (float)fnMayaCamera.nearClippingPlane(); float zFar = (float)fnMayaCamera.farClippingPlane(); float hFOV = (float)fnMayaCamera.horizontalFieldOfView(); float f = (float) (1.0f / (float) tan( hFOV / 2.0f )); ZeroMemory( &PerspectiveCamera_Projection, sizeof(PerspectiveCamera_Projection) ); PerspectiveCamera_Projection._11 = f; PerspectiveCamera_Projection._22 = f; PerspectiveCamera_Projection._33 = (zFar+zNear) / (zFar-zNear); PerspectiveCamera_Projection._34 = 1.0f; PerspectiveCamera_Projection._43 = -2 * (zFar*zNear)/(zFar-zNear); break; } } return S_OK; }
MStatus AlembicExportCommand::doIt(const MArgList &args) { ESS_PROFILE_SCOPE("AlembicExportCommand::doIt"); MStatus status = MS::kFailure; MTime currentAnimStartTime = MAnimControl::animationStartTime(), currentAnimEndTime = MAnimControl::animationEndTime(), oldCurTime = MAnimControl::currentTime(), curMinTime = MAnimControl::minTime(), curMaxTime = MAnimControl::maxTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { // TODO: implement help for this command // MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } unsigned int jobCount = argData.numberOfFlagUses("jobArg"); MStringArray jobStrings; if (jobCount == 0) { // TODO: display dialog MGlobal::displayError("[ExocortexAlembic] No jobs specified."); MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no job specified"); return status; } else { // get all of the jobstrings for (unsigned int i = 0; i < jobCount; i++) { MArgList jobArgList; argData.getFlagArgumentList("jobArg", i, jobArgList); jobStrings.append(jobArgList.asString(0)); } } // create a vector to store the jobs std::vector<AlembicWriteJob *> jobPtrs; double minFrame = 1000000.0; double maxFrame = -1000000.0; double maxSteps = 1; double maxSubsteps = 1; // init the curve accumulators AlembicCurveAccumulator::Initialize(); try { // for each job, check the arguments bool failure = false; for (unsigned int i = 0; i < jobStrings.length(); ++i) { double frameIn = 1.0; double frameOut = 1.0; double frameSteps = 1.0; double frameSubSteps = 1.0; MString filename; bool purepointcache = false; bool normals = true; bool uvs = true; bool facesets = true; bool bindpose = true; bool dynamictopology = false; bool globalspace = false; bool withouthierarchy = false; bool transformcache = false; bool useInitShadGrp = false; bool useOgawa = false; // Later, will need to be changed! MStringArray objectStrings; std::vector<std::string> prefixFilters; std::set<std::string> attributes; std::vector<std::string> userPrefixFilters; std::set<std::string> userAttributes; MObjectArray objects; std::string search_str, replace_str; // process all tokens of the job MStringArray tokens; jobStrings[i].split(';', tokens); for (unsigned int j = 0; j < tokens.length(); j++) { MStringArray valuePair; tokens[j].split('=', valuePair); if (valuePair.length() != 2) { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } const MString &lowerValue = valuePair[0].toLowerCase(); if (lowerValue == "in") { frameIn = valuePair[1].asDouble(); } else if (lowerValue == "out") { frameOut = valuePair[1].asDouble(); } else if (lowerValue == "step") { frameSteps = valuePair[1].asDouble(); } else if (lowerValue == "substep") { frameSubSteps = valuePair[1].asDouble(); } else if (lowerValue == "normals") { normals = valuePair[1].asInt() != 0; } else if (lowerValue == "uvs") { uvs = valuePair[1].asInt() != 0; } else if (lowerValue == "facesets") { facesets = valuePair[1].asInt() != 0; } else if (lowerValue == "bindpose") { bindpose = valuePair[1].asInt() != 0; } else if (lowerValue == "purepointcache") { purepointcache = valuePair[1].asInt() != 0; } else if (lowerValue == "dynamictopology") { dynamictopology = valuePair[1].asInt() != 0; } else if (lowerValue == "globalspace") { globalspace = valuePair[1].asInt() != 0; } else if (lowerValue == "withouthierarchy") { withouthierarchy = valuePair[1].asInt() != 0; } else if (lowerValue == "transformcache") { transformcache = valuePair[1].asInt() != 0; } else if (lowerValue == "filename") { filename = valuePair[1]; } else if (lowerValue == "objects") { // try to find each object valuePair[1].split(',', objectStrings); } else if (lowerValue == "useinitshadgrp") { useInitShadGrp = valuePair[1].asInt() != 0; } // search/replace else if (lowerValue == "search") { search_str = valuePair[1].asChar(); } else if (lowerValue == "replace") { replace_str = valuePair[1].asChar(); } else if (lowerValue == "ogawa") { useOgawa = valuePair[1].asInt() != 0; } else if (lowerValue == "attrprefixes") { splitListArg(valuePair[1], prefixFilters); } else if (lowerValue == "attrs") { splitListArg(valuePair[1], attributes); } else if (lowerValue == "userattrprefixes") { splitListArg(valuePair[1], userPrefixFilters); } else if (lowerValue == "userattrs") { splitListArg(valuePair[1], userAttributes); } else { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } } // now check the object strings for (unsigned int k = 0; k < objectStrings.length(); k++) { MSelectionList sl; MString objectString = objectStrings[k]; sl.add(objectString); MDagPath dag; for (unsigned int l = 0; l < sl.length(); l++) { sl.getDagPath(l, dag); MObject objRef = dag.node(); if (objRef.isNull()) { MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" + objectStrings[k] + "', not found."); break; } // get all parents MObjectArray parents; // check if this is a camera bool isCamera = false; for (unsigned int m = 0; m < dag.childCount(); ++m) { MFnDagNode child(dag.child(m)); MFn::Type ctype = child.object().apiType(); if (ctype == MFn::kCamera) { isCamera = true; break; } } if (dag.node().apiType() == MFn::kTransform && !isCamera && !globalspace && !withouthierarchy) { MDagPath ppath = dag; while (!ppath.node().isNull() && ppath.length() > 0 && ppath.isValid()) { parents.append(ppath.node()); if (ppath.pop() != MStatus::kSuccess) { break; } } } else { parents.append(dag.node()); } // push all parents in while (parents.length() > 0) { bool found = false; for (unsigned int m = 0; m < objects.length(); m++) { if (objects[m] == parents[parents.length() - 1]) { found = true; break; } } if (!found) { objects.append(parents[parents.length() - 1]); } parents.remove(parents.length() - 1); } // check all of the shapes below if (!transformcache) { sl.getDagPath(l, dag); for (unsigned int m = 0; m < dag.childCount(); m++) { MFnDagNode child(dag.child(m)); if (child.isIntermediateObject()) { continue; } objects.append(child.object()); } } } } // check if we have incompatible subframes if (maxSubsteps > 1.0 && frameSubSteps > 1.0) { const double part = (frameSubSteps > maxSubsteps) ? (frameSubSteps / maxSubsteps) : (maxSubsteps / frameSubSteps); if (abs(part - floor(part)) > 0.001) { MString frameSubStepsStr, maxSubstepsStr; frameSubStepsStr.set(frameSubSteps); maxSubstepsStr.set(maxSubsteps); MGlobal::displayError( "[ExocortexAlembic] You cannot combine substeps " + frameSubStepsStr + " and " + maxSubstepsStr + " in one export. Aborting."); return MStatus::kInvalidParameter; } } // remember the min and max values for the frames if (frameIn < minFrame) { minFrame = frameIn; } if (frameOut > maxFrame) { maxFrame = frameOut; } if (frameSteps > maxSteps) { maxSteps = frameSteps; } if (frameSteps > 1.0) { frameSubSteps = 1.0; } if (frameSubSteps > maxSubsteps) { maxSubsteps = frameSubSteps; } // check if we have a filename if (filename.length() == 0) { MGlobal::displayError("[ExocortexAlembic] No filename specified."); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no filename " "specified"); return MStatus::kFailure; } // construct the frames MDoubleArray frames; { const double frameIncr = frameSteps / frameSubSteps; for (double frame = frameIn; frame <= frameOut; frame += frameIncr) { frames.append(frame); } } AlembicWriteJob *job = new AlembicWriteJob(filename, objects, frames, useOgawa, prefixFilters, attributes, userPrefixFilters, userAttributes); job->SetOption("exportNormals", normals ? "1" : "0"); job->SetOption("exportUVs", uvs ? "1" : "0"); job->SetOption("exportFaceSets", facesets ? "1" : "0"); job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0"); job->SetOption("exportBindPose", bindpose ? "1" : "0"); job->SetOption("exportPurePointCache", purepointcache ? "1" : "0"); job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0"); job->SetOption("indexedNormals", "1"); job->SetOption("indexedUVs", "1"); job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0"); job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0"); job->SetOption("transformCache", transformcache ? "1" : "0"); // check if the search/replace strings are valid! if (search_str.length() ? !replace_str.length() : replace_str.length()) // either search or // replace string is // missing or empty! { ESS_LOG_WARNING( "Missing search or replace parameter. No strings will be " "replaced."); job->replacer = SearchReplace::createReplacer(); } else { job->replacer = SearchReplace::createReplacer(search_str, replace_str); } // check if the job is satifsied if (job->PreProcess() != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied."); delete (job); failure = true; break; } // push the job to our registry MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" + jobStrings[i]); jobPtrs.push_back(job); } if (failure) { for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } return MS::kFailure; } // compute the job count unsigned int jobFrameCount = 0; for (size_t i = 0; i < jobPtrs.size(); i++) jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() * (unsigned int)jobPtrs[i]->GetFrames().size(); // now, let's run through all frames, and process the jobs const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit()); const double incrSteps = maxSteps / maxSubsteps; double nextFrame = minFrame + incrSteps; for (double frame = minFrame; frame <= maxFrame; frame += incrSteps, nextFrame += incrSteps) { MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds)); MAnimControl::setAnimationEndTime( MTime(nextFrame / frameRate, MTime::kSeconds)); MAnimControl::playForward(); // this way, it forces Maya to play exactly // one frame! and particles are updated! AlembicCurveAccumulator::StartRecordingFrame(); for (size_t i = 0; i < jobPtrs.size(); i++) { MStatus status = jobPtrs[i]->Process(frame); if (status != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job aborted :" + jobPtrs[i]->GetFileName()); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); return status; } } AlembicCurveAccumulator::StopRecordingFrame(); } } catch (...) { MGlobal::displayError( "[ExocortexAlembic] Jobs aborted, force closing all archives!"); for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin(); beg != jobPtrs.end(); ++beg) { (*beg)->forceCloseArchive(); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); MPxCommand::setResult("Error caught in AlembicExportCommand::doIt"); status = MS::kFailure; } MAnimControl::stop(); AlembicCurveAccumulator::Destroy(); // restore the animation start/end time and the current time! restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); // delete all jobs for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } // remove all known archives deleteAllArchives(); return status; }
void exportF3d::setF3dField(MFnFluid &fluidFn, const char *outputPath, const MDagPath &dagPath) { try { MStatus stat; unsigned int i, xres = 0, yres = 0, zres = 0; double xdim,ydim,zdim; // Get the resolution of the fluid container stat = fluidFn.getResolution(xres, yres, zres); stat = fluidFn.getDimensions(xdim, ydim, zdim); V3d size(xdim,ydim,zdim); const V3i res(xres, yres, zres); int psizeTot = fluidFn.gridSize(); /// get the transform and rotation MObject parentObj = fluidFn.parent(0, &stat); if (stat != MS::kSuccess) { MGlobal::displayError("Can't find fluid's parent node"); return; } MDagPath parentPath = dagPath; parentPath.pop(); MTransformationMatrix tmatFn(dagPath.inclusiveMatrix()); if (stat != MS::kSuccess) { MGlobal::displayError("Failed to get transformation matrix of fluid's parent node"); return; } MFnTransform fnXform(parentPath, &stat); if (stat != MS::kSuccess) { MGlobal::displayError("Can't create a MFnTransform from fluid's parent node"); return; } if (m_verbose) { fprintf(stderr, "cellnum: %dx%dx%d = %d\n", xres, yres, zres,psizeTot); } float *density(NULL), *temp(NULL), *fuel(NULL); float *pressure(NULL), *falloff(NULL); density = fluidFn.density( &stat ); if ( stat.error() ) m_density = false; temp = fluidFn.temperature( &stat ); if ( stat.error() ) m_temperature = false; fuel = fluidFn.fuel( &stat ); if ( stat.error() ) m_fuel = false; pressure= fluidFn.pressure( &stat ); if ( stat.error() ) m_pressure = false; falloff = fluidFn.falloff( &stat ); if ( stat.error() ) m_falloff = false; float *r,*g,*b; if (m_color) { stat = fluidFn.getColors(r,b,g); if ( stat.error() ) m_color = false; }else m_color = false; float *u,*v,*w; if (m_texture) { stat = fluidFn.getCoordinates(u,v,w); if ( stat.error() ) m_texture = false; }else m_texture = false; /// velocity info float *Xvel(NULL),*Yvel(NULL), *Zvel(NULL); if (m_vel) { stat = fluidFn.getVelocity( Xvel,Yvel,Zvel ); if ( stat.error() ) m_vel = false; } if (m_density == false && m_temperature==false && m_fuel==false && m_pressure==false && m_falloff==false && m_vel == false && m_color == false && m_texture==false) { MGlobal::displayError("No fluid attributes found for writing, please check fluids settings"); return; } /// Fields DenseFieldf::Ptr densityFld, tempFld, fuelFld, pressureFld, falloffFld; DenseField3f::Ptr CdFld, uvwFld; MACField3f::Ptr vMac; MPlug autoResizePlug = fluidFn.findPlug("autoResize", &stat); bool autoResize; autoResizePlug.getValue(autoResize); // maya's fluid transformation V3d dynamicOffset(0); M44d localToWorld; MatrixFieldMapping::Ptr mapping(new MatrixFieldMapping()); M44d fluid_mat(tmatFn.asMatrix().matrix); if(autoResize) { fluidFn.findPlug("dofx").getValue(dynamicOffset[0]); fluidFn.findPlug("dofy").getValue(dynamicOffset[1]); fluidFn.findPlug("dofz").getValue(dynamicOffset[2]); } Box3i extents; extents.max = res - V3i(1); extents.min = V3i(0); mapping->setExtents(extents); localToWorld.setScale(size); localToWorld *= M44d().setTranslation( -(size*0.5) ); localToWorld *= M44d().setTranslation( dynamicOffset ); localToWorld *= fluid_mat; mapping->setLocalToWorld(localToWorld); if (m_density){ densityFld = new DenseFieldf; densityFld->setSize(res); densityFld->setMapping(mapping); } if (m_fuel){ fuelFld = new DenseFieldf; fuelFld->setSize(res); fuelFld->setMapping(mapping); } if (m_temperature){ tempFld = new DenseFieldf; tempFld->setSize(res); tempFld->setMapping(mapping); } if (m_pressure){ pressureFld = new DenseFieldf; pressureFld->setSize(res); pressureFld->setMapping(mapping); } if (m_falloff){ falloffFld = new DenseFieldf; falloffFld->setSize(res); falloffFld->setMapping(mapping); } if (m_vel){ vMac = new MACField3f; vMac->setSize(res); vMac->setMapping(mapping); } if (m_color){ CdFld = new DenseField3f; CdFld->setSize(res); CdFld->setMapping(mapping); } if (m_texture){ uvwFld = new DenseField3f; uvwFld->setSize(res); uvwFld->setMapping(mapping); } size_t iX, iY, iZ; for( iZ = 0; iZ < zres; iZ++ ) { for( iX = 0; iX < xres; iX++ ) { for( iY = 0; iY < yres ; iY++ ) { /// data is in x major but we are writting in z major order i = fluidFn.index( iX, iY, iZ); if ( m_density ) densityFld->lvalue(iX, iY, iZ) = density[i]; if ( m_temperature ) tempFld->lvalue(iX, iY, iZ) = temp[i]; if ( m_fuel ) fuelFld->lvalue(iX, iY, iZ) = fuel[i]; if ( m_pressure ) pressureFld->lvalue(iX, iY, iZ) = pressure[i]; if ( m_falloff ) falloffFld->lvalue(iX, iY, iZ) = falloff[i]; if (m_color) CdFld->lvalue(iX, iY, iZ) = V3f(r[i], g[i], b[i]); if (m_texture) uvwFld->lvalue(iX, iY, iZ) = V3f(u[i], v[i], w[i]); } } } if (m_vel) { unsigned x,y,z; for(z=0;z<zres;++z) for(y=0;y<yres;++y) for(x=0;x<xres+1;++x) { vMac->u(x,y,z) = *Xvel++; } for(z=0;z<zres;++z) for(y=0;y<yres+1;++y) for(x=0;x<xres;++x) { vMac->v(x,y,z) = *Yvel++; } for(z=0;z<zres+1;++z) for(y=0;y<yres;++y) for(x=0;x<xres;++x) { vMac->w(x,y,z) = *Zvel++; } } Field3DOutputFile out; if (!out.create(outputPath)) { MGlobal::displayError("Couldn't create file: "+ MString(outputPath)); return; } string fieldname("maya"); if (m_density){ out.writeScalarLayer<float>(fieldname, "density", densityFld); } if (m_fuel) { out.writeScalarLayer<float>(fieldname,"fuel", fuelFld); } if (m_temperature){ out.writeScalarLayer<float>(fieldname,"temperature", tempFld); } if (m_color) { out.writeVectorLayer<float>(fieldname,"Cd", CdFld); } if (m_vel) out.writeVectorLayer<float>(fieldname,"v_mac", vMac); out.close(); } catch(const std::exception &e) { MGlobal::displayError( MString(e.what()) ); return; } }
// ------------------------------------------------------------ bool SceneGraph::retrieveExportNodes() { // Create a selection list containing only the root nodes (implies export all!) MSelectionList allTargets; for ( MItDag it ( MItDag::kBreadthFirst ); it.depth()<=1 && it.item()!=MObject::kNullObj; it.next() ) { MDagPath path; MStatus status = it.getPath ( path ); String pathName = path.fullPathName().asChar(); // Attach a function set MFnDependencyNode fn ( path.node() ); String theNodeName = fn.name().asChar(); // Check if it's the world node if ( it.depth() == 0 ) continue; if ( status == MStatus::kSuccess ) { if ( mExportSelectedOnly ) allTargets.add ( path ); else mTargets.add ( path ); } } // now fill in the targets, either the same as allTargets, or it is export selection only if ( mExportSelectedOnly ) { // Export the selection: // Grab the selected DAG components if ( MStatus::kFailure == MGlobal::getActiveSelectionList ( mTargets ) ) { std::cerr << "MGlobal::getActiveSelectionList" << std::endl; return false; } // For all the non-transforms selected, make sure to extend to the transforms underneath. MDagPathArray additions; MIntArray removals; for ( uint32 i = 0; i < mTargets.length(); ++i ) { MDagPath itemPath; mTargets.getDagPath ( i, itemPath ); if ( !itemPath.node().hasFn ( MFn::kTransform ) ) { MDagPath transformPath = itemPath; while ( transformPath.length() > 0 ) { transformPath.pop(); if ( !mTargets.hasItem ( transformPath ) ) { additions.append ( transformPath ); break; } } removals.append ( i ); } } for ( uint32 i = 0; i < removals.length(); ++i ) mTargets.remove ( removals[i] - i ); for ( uint32 i = 0; i < additions.length(); ++i ) mTargets.add ( additions[i] ); // Add all the forced nodes to the list. uint32 forceNodeCount = mForcedNodes.length(); for ( uint32 i = 0; i < forceNodeCount; ++i ) { MDagPath p = mForcedNodes[i]; if ( mTargets.hasItem ( p ) ) continue; mTargets.add ( p ); } // Add additional selection paths for any objects in our // selection which have been instanced (either directly, or // via instancing of an ancestor) - as otherwise, the selection // will only include ONE of the DAG paths // addInstancedDagPaths ( mTargets ); // remove any selected nodes CONTAINED within other selected // hierarchies (to ensure we don't export subtrees multiple times) // removeMultiplyIncludedDagPaths ( mTargets ); } return true; }
MStatus CIKSolverNode::doSimpleSolver() { MStatus stat; // Get the handle and create a function set for it // MIkHandleGroup* handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } MObject handle = handle_group->handle(0); MDagPath handlePath = MDagPath::getAPathTo(handle); MFnIkHandle fnHandle(handlePath, &stat); // End-Effector MDagPath endEffectorPath; fnHandle.getEffector(endEffectorPath); MFnIkEffector fnEffector(endEffectorPath); MPoint effectorPos = fnEffector.rotatePivot(MSpace::kWorld); unsigned int numJoints = endEffectorPath.length(); std::vector<MDagPath> jointsDagPaths; jointsDagPaths.reserve(numJoints); while (endEffectorPath.length() > 1) { endEffectorPath.pop(); jointsDagPaths.push_back( endEffectorPath ); } std::reverse(jointsDagPaths.begin(), jointsDagPaths.end()); static bool builtLocalSkeleton = false; if (builtLocalSkeleton == false) { for (int jointIdx = 0; jointIdx < jointsDagPaths.size(); ++jointIdx) { MFnIkJoint curJoint(jointsDagPaths[jointIdx]); m_localJointsPos.push_back( curJoint.getTranslation(MSpace::kWorld) ); } m_localJointsPos.push_back(effectorPos ); builtLocalSkeleton = true; } MPoint startJointPos = MFnIkJoint(jointsDagPaths.front()).getTranslation(MSpace::kWorld); MVector startToEndEff = m_localJointsPos.back() - m_localJointsPos.front(); double curveLength = (getPosition(1.0) - getPosition(0.0)).length(); double chainLength = startToEndEff.length(); // in local space. double stretchFactor = curveLength / chainLength; double uVal = 0.0f; MVector jointPosL = m_localJointsPos[0]; for (int jointIdx = 0; jointIdx < jointsDagPaths.size(); ++jointIdx) { MFnIkJoint curJoint(jointsDagPaths[jointIdx]); MVector curJointPosL = m_localJointsPos[jointIdx]; double dist = stretchFactor * (curJointPosL - jointPosL).length(); uVal = uVal + dist / curveLength; MVector curCurveJointPos = getPosition(uVal); curJoint.setTranslation(curCurveJointPos, MSpace::kWorld); jointPosL = curJointPosL; } MVector effectorCurvePos = getPosition(1.0); MVector curCurveJointPos = getPosition(uVal); MVector effectorVec = (effectorCurvePos - curCurveJointPos).normal(); double endJointAngle[3]; MVector effectorVecXY = MVector(effectorVec(0), effectorVec(1), 0.0); endJointAngle[2] = effectorVecXY.angle(MVector(1, 0, 0)); if ((MVector(1, 0, 0) ^ effectorVecXY) * MVector(0, 0, 1) < 0.0) { endJointAngle[2] = -endJointAngle[2]; } MVector effectorVecXZ = MVector(effectorVec(0), 0.0, effectorVec(2)); endJointAngle[1] = effectorVecXZ.angle(MVector(1, 0, 0)); if ((MVector(1, 0, 0) ^ effectorVecXZ) * MVector(0, 1, 0) < 0.0) { endJointAngle[1] = -endJointAngle[1]; } endJointAngle[0] = 0.0; MFnIkJoint curJoint(jointsDagPaths.back()); curJoint.setRotation(endJointAngle, curJoint.rotationOrder()); return MS::kSuccess; }
// -------------------------------------------------------------------- MStatus SceneGraph::removeMultiplyIncludedDagPaths ( MSelectionList& selectionList ) { // As we're potentially deleting elements out of the selection list // it's easiest to avoid array bound check issues by walking the // list backwards. MStatus status; int length=selectionList.length ( &status ); if ( status != MStatus::kSuccess ) return MStatus::kFailure; for ( int i = length - 1; i >= 0; --i ) { MDagPath dagIPath; if ( selectionList.getDagPath ( i, dagIPath ) != MStatus::kSuccess ) return MStatus::kFailure; uint dagIdepth = dagIPath.length(); for ( int j = i - 1; j >= 0; --j ) { MDagPath dagJPath; if ( selectionList.getDagPath ( j, dagJPath ) != MStatus::kSuccess ) return MStatus::kFailure; // Test if the longer of these two dag paths contains the shorter ... uint dagJdepth = dagJPath.length(); if ( dagJdepth >= dagIdepth ) { bool isParent = false; for ( int depth = dagIdepth - 1; depth > 0 && !isParent; --depth ) { dagJPath.pop(); isParent = dagJPath.node() == dagIPath.node(); } if ( isParent ) { selectionList.remove ( j ); i--; } } else { bool isParent = false; MDagPath dagIt = dagIPath; for ( int depth = dagIdepth - 1; depth > 0 && !isParent; --depth ) { dagIt.pop(); isParent = dagJPath.node() == dagIt.node(); } if ( isParent ) { selectionList.remove ( i ); break; } } } } return MStatus::kSuccess; }
MStatus ik2Bsolver::doSolve() // // This is the doSolve method which calls solveIK. // { MStatus stat; // Handle Group // MIkHandleGroup * handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } // Handle // // For single chain types of solvers, get the 0th handle. // Single chain solvers are solvers which act on one handle only, // i.e. the handle group for a single chain solver // has only one handle // MObject handle = handle_group->handle(0); MDagPath handlePath = MDagPath::getAPathTo(handle); MFnIkHandle handleFn(handlePath, &stat); // Effector // MDagPath effectorPath; handleFn.getEffector(effectorPath); // MGlobal::displayInfo(effectorPath.fullPathName()); MFnIkEffector effectorFn(effectorPath); // Mid Joint // effectorPath.pop(); MFnIkJoint midJointFn(effectorPath); // End Joint // MDagPath endJointPath; bool hasEndJ = findFirstJointChild(effectorPath, endJointPath); // if(hasEndJ) MGlobal::displayInfo(endJointPath.fullPathName()); MFnIkJoint endJointFn(endJointPath); // Start Joint // MDagPath startJointPath; handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn(startJointPath); // Preferred angles // double startJointPrefAngle[3]; double midJointPrefAngle[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJointFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder()); midJointFn.setRotation(midJointPrefAngle, midJointFn.rotationOrder()); MPoint handlePos = handleFn.rotatePivot(MSpace::kWorld); MPoint effectorPos = effectorFn.rotatePivot(MSpace::kWorld); MPoint midJointPos = midJointFn.rotatePivot(MSpace::kWorld); MPoint startJointPos = startJointFn.rotatePivot(MSpace::kWorld); MVector poleVector = poleVectorFromHandle(handlePath); poleVector *= handlePath.exclusiveMatrix(); double twistValue = twistFromHandle(handlePath); MObject thisNode = thisMObject(); MVector localEndJointT = endJointFn.getTranslation(MSpace::kTransform); MVector worldEndJointT = endJointFn.rotatePivot(MSpace::kWorld) - midJointPos; double scaling = worldEndJointT.length() / ( localEndJointT.length() + 1e-6); // MGlobal::displayInfo(MString(" scaling ")+scaling); // get rest length // double restL1, restL2; MPlug(thisNode, arestLength1).getValue(restL1); MPlug(thisNode, arestLength2).getValue(restL2); // get soft distance // MPlug plug( thisNode, asoftDistance ); double softD = 0.0; plug.getValue(softD); restL1 *= scaling; restL2 *= scaling; softD *= scaling; // get max stretching double maxStretching = 0.0; MPlug(thisNode, amaxStretching).getValue(maxStretching); MQuaternion qStart, qMid; double stretching = 0.0; solveIK(startJointPos, midJointPos, effectorPos, handlePos, poleVector, twistValue, qStart, qMid, softD, restL1, restL2, stretching); midJointFn.rotateBy(qMid, MSpace::kWorld); startJointFn.rotateBy(qStart, MSpace::kWorld); midJointFn.setTranslation(MVector(restL1 / scaling, 0.0, 0.0), MSpace::kTransform); endJointFn.setTranslation(MVector(restL2 / scaling, 0.0, 0.0), MSpace::kTransform); // if(stretching > maxStretching) stretching = maxStretching; if(maxStretching > 0.0) { MVector vstretch(stretching* 0.5 / scaling, 0.0, 0.0); midJointFn.translateBy(vstretch, MSpace::kTransform); endJointFn.translateBy(vstretch, MSpace::kTransform); } return MS::kSuccess; }
MStatus splineSolverNode::preSolve() { MStatus stat; setRotatePlane(false); setSingleChainOnly(true); setPositionOnly(false); //Get Handle MIkHandleGroup * handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } MObject handle = handle_group->handle( 0 ); MDagPath handlePath = MDagPath::getAPathTo( handle ); fnHandle.setObject( handlePath ); //Get Curve MPlug inCurvePlug = fnHandle.findPlug( "inCurve" ); MDataHandle curveHandle = inCurvePlug.asMDataHandle(); MObject inputCurveObject = curveHandle.asNurbsCurveTransformed(); curveFn.setObject( inputCurveObject ); float initCurveLength = curveFn.length(); MVector initNormal = curveFn.normal(0); MVector initTangent = curveFn.tangent(0); float stretchRatio = 1; // Get the position of the end_effector // MDagPath effectorPath; fnHandle.getEffector(effectorPath); tran.setObject( effectorPath ); // Get the start joint position // MDagPath startJointPath; fnHandle.getStartJoint( startJointPath ); joints.clear(); //Get Joints while (true) { effectorPath.pop(); joints.push_back( effectorPath ); if (effectorPath == startJointPath) break; } std::reverse(joints.begin(), joints.end()); if (!fnHandle.hasAttribute("str")) { //Add Custom Attributes to Handle MFnNumericAttribute fnAttr; MObject attr = fnAttr.create("stretchRatio", "str", MFnNumericData::kDouble, stretchRatio); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setMin(0); fnAttr.setMax(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("anchorPosition", "ancp", MFnNumericData::kDouble, 0.0); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setMin(0); fnAttr.setMax(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("curveLength", "cvLen", MFnNumericData::kDouble, initCurveLength); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("initNormal", "norm", MFnNumericData::k3Double); fnAttr.setDefault(initNormal.x, initNormal.y, initNormal.z); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("initTangent", "tang", MFnNumericData::k3Double); fnAttr.setDefault(initTangent.x, initTangent.y, initTangent.z); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("jointsLength", "jsLen", MFnNumericData::kDouble, getJointsTotalLenght()); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("startTwist", "strtw", MFnNumericData::kDouble, 0.0); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("endTwist", "endtw", MFnNumericData::kDouble, 0.0); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); MObject twistRamp = MRampAttribute::createCurveRamp("twistRamp", "twr"); fnHandle.addAttribute(twistRamp, MFnDependencyNode::kLocalDynamicAttr); MObject scaleRamp = MRampAttribute::createCurveRamp("scaleRamp", "scr"); fnHandle.addAttribute(scaleRamp, MFnDependencyNode::kLocalDynamicAttr); } else { MPlug strPlug = fnHandle.findPlug("str"); stretchRatio = strPlug.asDouble(); } return MS::kSuccess; }
bool usdWriteJob::beginJob(const std::string &iFileName, bool append, double startTime, double endTime) { // Check for DAG nodes that are a child of an already specified DAG node to export // if that's the case, report the issue and skip the export PxrUsdMayaUtil::ShapeSet::const_iterator m, n; PxrUsdMayaUtil::ShapeSet::const_iterator endPath = mArgs.dagPaths.end(); for (m = mArgs.dagPaths.begin(); m != endPath; ) { MDagPath path1 = *m; m++; for (n = m; n != endPath; n++) { MDagPath path2 = *n; if (PxrUsdMayaUtil::isAncestorDescendentRelationship(path1,path2)) { MString errorMsg = path1.fullPathName(); errorMsg += " and "; errorMsg += path2.fullPathName(); errorMsg += " have an ancestor relationship. Skipping USD Export."; MGlobal::displayError(errorMsg); return false; } } // for n } // for m // Make sure the file name is a valid one with a proper USD extension. const std::string iFileExtension = TfStringGetSuffix(iFileName, '.'); if (iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionDefault || iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionASCII || iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionCrate) { mFileName = iFileName; } else { mFileName = TfStringPrintf("%s.%s", iFileName.c_str(), PxrUsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText()); } MGlobal::displayInfo("usdWriteJob::beginJob: Create stage file "+MString(mFileName.c_str())); ArResolverContext resolverCtx = ArGetResolver().GetCurrentContext(); if (append) { mStage = UsdStage::Open(SdfLayer::FindOrOpen(mFileName), resolverCtx); if (!mStage) { MGlobal::displayError("Failed to open stage file "+MString(mFileName.c_str())); return false; } } else { mStage = UsdStage::CreateNew(mFileName, resolverCtx); if (!mStage) { MGlobal::displayError("Failed to create stage file "+MString(mFileName.c_str())); return false; } } // Set time range for the USD file mStage->SetStartTimeCode(startTime); mStage->SetEndTimeCode(endTime); mModelKindWriter.Reset(); // Setup the requested render layer mode: // defaultLayer - Switch to the default render layer before exporting, // then switch back afterwards (no layer switching if // the current layer IS the default layer). // currentLayer - No layer switching before or after exporting. Just // use whatever is the current render layer for export. // modelingVariant - Switch to the default render layer before exporting, // and export each render layer in the scene as a // modeling variant, then switch back afterwards (no // layer switching if the current layer IS the default // layer). The default layer will be made the default // modeling variant. MFnRenderLayer currentLayer(MFnRenderLayer::currentLayer()); mCurrentRenderLayerName = currentLayer.name(); if (mArgs.renderLayerMode == PxUsdExportJobArgsTokens->modelingVariant) { // Handle usdModelRootOverridePath for USD Variants MFnRenderLayer::listAllRenderLayers(mRenderLayerObjs); if (mRenderLayerObjs.length() > 1) { mArgs.usdModelRootOverridePath = SdfPath("/_BaseModel_"); } } // Switch to the default render layer unless the renderLayerMode is // 'currentLayer', or the default layer is already the current layer. if (mArgs.renderLayerMode != PxUsdExportJobArgsTokens->currentLayer && MFnRenderLayer::currentLayer() != MFnRenderLayer::defaultRenderLayer()) { // Set the RenderLayer to the default render layer MFnRenderLayer defaultLayer(MFnRenderLayer::defaultRenderLayer()); MGlobal::executeCommand(MString("editRenderLayerGlobals -currentRenderLayer ")+ defaultLayer.name(), false, false); } // Pre-process the argument dagPath path names into two sets. One set // contains just the arg dagPaths, and the other contains all parents of // arg dagPaths all the way up to the world root. Partial path names are // enough because Maya guarantees them to still be unique, and they require // less work to hash and compare than full path names. TfHashSet<std::string, TfHash> argDagPaths; TfHashSet<std::string, TfHash> argDagPathParents; PxrUsdMayaUtil::ShapeSet::const_iterator end = mArgs.dagPaths.end(); for (PxrUsdMayaUtil::ShapeSet::const_iterator it = mArgs.dagPaths.begin(); it != end; ++it) { MDagPath curDagPath = *it; std::string curDagPathStr(curDagPath.partialPathName().asChar()); argDagPaths.insert(curDagPathStr); while (curDagPath.pop() && curDagPath.length() >= 0) { curDagPathStr = curDagPath.partialPathName().asChar(); if (argDagPathParents.find(curDagPathStr) != argDagPathParents.end()) { // We've already traversed up from this path. break; } argDagPathParents.insert(curDagPathStr); } } // Now do a depth-first traversal of the Maya DAG from the world root. // We keep a reference to arg dagPaths as we encounter them. MDagPath curLeafDagPath; for (MItDag itDag(MItDag::kDepthFirst, MFn::kInvalid); !itDag.isDone(); itDag.next()) { MDagPath curDagPath; itDag.getPath(curDagPath); std::string curDagPathStr(curDagPath.partialPathName().asChar()); if (argDagPathParents.find(curDagPathStr) != argDagPathParents.end()) { // This dagPath is a parent of one of the arg dagPaths. It should // be included in the export, but not necessarily all of its // children should be, so we continue to traverse down. } else if (argDagPaths.find(curDagPathStr) != argDagPaths.end()) { // This dagPath IS one of the arg dagPaths. It AND all of its // children should be included in the export. curLeafDagPath = curDagPath; } else if (!MFnDagNode(curDagPath).hasParent(curLeafDagPath.node())) { // This dagPath is not a child of one of the arg dagPaths, so prune // it and everything below it from the traversal. itDag.prune(); continue; } MayaPrimWriterPtr primWriter = nullptr; if (!createPrimWriter(curDagPath, &primWriter) && curDagPath.length() > 0) { // This dagPath and all of its children should be pruned. itDag.prune(); continue; } if (primWriter) { mMayaPrimWriterList.push_back(primWriter); // Write out data (non-animated/default values). if (UsdPrim usdPrim = primWriter->write(UsdTimeCode::Default())) { MDagPath dag = primWriter->getDagPath(); mDagPathToUsdPathMap[dag] = usdPrim.GetPath(); // If we are merging transforms and the object derives from // MayaTransformWriter but isn't actually a transform node, we // need to add its parent. if (mArgs.mergeTransformAndShape) { MayaTransformWriterPtr xformWriter = boost::dynamic_pointer_cast<MayaTransformWriter>( primWriter); if (xformWriter) { MDagPath xformDag = xformWriter->getTransformDagPath(); mDagPathToUsdPathMap[xformDag] = usdPrim.GetPath(); } } mModelKindWriter.OnWritePrim(usdPrim, primWriter); if (primWriter->shouldPruneChildren()) { itDag.prune(); } } } } // Writing Materials/Shading PxrUsdMayaTranslatorMaterial::ExportShadingEngines( mStage, mArgs.dagPaths, mArgs.shadingMode, mArgs.mergeTransformAndShape, mArgs.usdModelRootOverridePath); if (!mModelKindWriter.MakeModelHierarchy(mStage)) { return false; } // now we populate the chasers and run export default mChasers.clear(); PxrUsdMayaChaserRegistry::FactoryContext ctx(mStage, mDagPathToUsdPathMap, mArgs); for (const std::string& chaserName : mArgs.chaserNames) { if (PxrUsdMayaChaserRefPtr fn = PxrUsdMayaChaserRegistry::GetInstance().Create(chaserName, ctx)) { mChasers.push_back(fn); } else { std::string error = TfStringPrintf("Failed to create chaser: %s", chaserName.c_str()); MGlobal::displayError(MString(error.c_str())); } } for (const PxrUsdMayaChaserRefPtr& chaser : mChasers) { if (!chaser->ExportDefault()) { return false; } } return true; }
MStatus ik2Bsolver::doSolve() // // This is the doSolve method which calls solveIK. // { MStatus stat; // Handle Group // MIkHandleGroup * handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } // Handle // // For single chain types of solvers, get the 0th handle. // Single chain solvers are solvers which act on one handle only, // i.e. the handle group for a single chain solver // has only one handle // MObject handle = handle_group->handle(0); MDagPath handlePath = MDagPath::getAPathTo(handle); MFnIkHandle handleFn(handlePath, &stat); // Effector // MDagPath effectorPath; handleFn.getEffector(effectorPath); MFnIkEffector effectorFn(effectorPath); // Mid Joint // effectorPath.pop(); MFnIkJoint midJointFn(effectorPath); // Start Joint // MDagPath startJointPath; handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn(startJointPath); // Preferred angles // double startJointPrefAngle[3]; double midJointPrefAngle[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJointFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder()); midJointFn.setRotation(midJointPrefAngle, midJointFn.rotationOrder()); AwPoint handlePos = handleFn.rotatePivot(MSpace::kWorld); AwPoint effectorPos = effectorFn.rotatePivot(MSpace::kWorld); AwPoint midJointPos = midJointFn.rotatePivot(MSpace::kWorld); AwPoint startJointPos = startJointFn.rotatePivot(MSpace::kWorld); AwVector poleVector = poleVectorFromHandle(handlePath); poleVector *= handlePath.exclusiveMatrix(); double twistValue = twistFromHandle(handlePath); AwQuaternion qStart, qMid; solveIK(startJointPos, midJointPos, effectorPos, handlePos, poleVector, twistValue, qStart, qMid); midJointFn.rotateBy(qMid, MSpace::kWorld); startJointFn.rotateBy(qStart, MSpace::kWorld); return MS::kSuccess; }
void maTranslator::writeDagNodes(fstream& f) { fParentingRequired.clear(); MItDag dagIter; dagIter.traverseUnderWorld(true); MDagPath worldPath; dagIter.getPath(worldPath); // // We step over the world node before starting the loop, because it // doesn't get written out. // for (dagIter.next(); !dagIter.isDone(); dagIter.next()) { MDagPath path; dagIter.getPath(path); // // If the node has already been written, then all of its descendants // must have been written, or at least checked, as well, so prune // this branch of the tree from the iteration. // MFnDagNode dagNodeFn(path); if (dagNodeFn.isFlagSet(fCreateFlag)) { dagIter.prune(); continue; } // // If this is a default node, it will be written out later, so skip // it. // if (dagNodeFn.isDefaultNode()) continue; // // If this node is not writable, and is not a shared node, then mark // it as having been written, and skip it. // if (!dagNodeFn.canBeWritten() && !dagNodeFn.isShared()) { dagNodeFn.setFlag(fCreateFlag, true); continue; } unsigned int numParents = dagNodeFn.parentCount(); if (dagNodeFn.isFromReferencedFile()) { // // We don't issue 'creatNode' commands for nodes from referenced // files, but if the node has any parents which are not from // referenced files, other than the world, then make a note that // we'll need to issue extra 'parent' commands for it later on. // unsigned int i; for (i = 0; i < numParents; i++) { MObject altParent = dagNodeFn.parent(i); MFnDagNode altParentFn(altParent); if (!altParentFn.isFromReferencedFile() && (altParentFn.object() != worldPath.node())) { fParentingRequired.append(path); break; } } } else { // // Find the node's parent. // MDagPath parentPath = worldPath; if (path.length() > 1) { // // Get the parent's path. // parentPath = path; parentPath.pop(); // // If the parent is in the underworld, then find the closest // ancestor which is not. // if (parentPath.pathCount() > 1) { // // The first segment of the path contains whatever // portion of the path exists in the world. So the closest // worldly ancestor is simply the one at the end of that // first path segment. // path.getPath(parentPath, 0); } } MFnDagNode parentNodeFn(parentPath); if (parentNodeFn.isFromReferencedFile()) { // // We prefer to parent to a non-referenced node. So if this // node has any other parents, which are not from referenced // files and have not already been processed, then we'll // skip this instance and wait for an instance through one // of those parents. // unsigned i; for (i = 0; i < numParents; i++) { if (dagNodeFn.parent(i) != parentNodeFn.object()) { MObject altParent = dagNodeFn.parent(i); MFnDagNode altParentFn(altParent); if (!altParentFn.isFromReferencedFile() && !altParentFn.isFlagSet(fCreateFlag)) { break; } } } if (i < numParents) continue; // // This node only has parents within referenced files, so // create it without a parent and note that we need to issue // 'parent' commands for it later on. // writeCreateNode(f, path, worldPath); fParentingRequired.append(path); } else { writeCreateNode(f, path, parentPath); // // Let's see if this node has any parents from referenced // files, or any parents other than this one which are not // from referenced files. // unsigned int i; bool hasRefParents = false; bool hasOtherNonRefParents = false; for (i = 0; i < numParents; i++) { if (dagNodeFn.parent(i) != parentNodeFn.object()) { MObject altParent = dagNodeFn.parent(i); MFnDagNode altParentFn(altParent); if (altParentFn.isFromReferencedFile()) hasRefParents = true; else hasOtherNonRefParents = true; // // If we've already got positives for both tests, // then there's no need in continuing. // if (hasRefParents && hasOtherNonRefParents) break; } } // // If this node has parents from referenced files, then // make note that we will have to issue 'parent' commands // later on. // if (hasRefParents) fParentingRequired.append(path); // // If this node has parents other than this one which are // not from referenced files, then make note that the // parenting for the other instances still has to be done. // if (hasOtherNonRefParents) { fInstanceChildren.append(path); fInstanceParents.append(parentPath); } } // // Write out the node's 'addAttr', 'setAttr' and 'lockNode' // commands. // writeNodeAttrs(f, path.node(), true); writeLockNode(f, path.node()); } // // Mark the node as having been written. // dagNodeFn.setFlag(fCreateFlag, true); } // // Write out the parenting for instances. // writeInstances(f); }