操做流程:編程
1. VS運行代碼,生成插件函數
2. 打開Maya繪製曲線,加載插件spa
3. 選中繪製的曲線,運行插件插件
Posts1.0 命令行
代碼:code
#include <maya/MSimple.h> #include <maya/MGlobal.h> #include <maya/MFnPlugin.h> #include <maya/MPxCommand.h> #include <maya/MSelectionList.h> #include <maya/MDagPath.h> #include <maya/MFnNurbsCurve.h> #include <maya/MItSelectionList.h> #include <maya/MPoint.h>// 命令類 class PostsCmd : public MPxCommand { public : // 執行命令時調用,完成命令的實際工做 virtual MStatus doIt(const MArgList&); // 返回的是命令已分配過的一個實例 static void *creator() { return new PostsCmd; } }; MStatus PostsCmd::doIt(const MArgList&) { // 初始化數目、半徑、高度 const int nPosts = 5; const double radius = 0.5; const double height = 5.0; // 建立當前已選定對象的一個清單,Selection對象用語保存清單對象 MSelectionList selection; MGlobal::getActiveSelectionList(selection); MDagPath dagPath; MFnNurbsCurve curveFn; // cylinder不容許顯示設置其高度,必須經過heightRatio的值來設置 double heightRatio = height / radius; // 設置了一個過濾器的迭代器,排除不是NURBS曲線的全部其餘對象 MItSelectionList iter(selection, MFn::kNurbsCurve); MGlobal::displayInfo("Now...\n"); int it = 0; // 迭代NURBS曲線 for (; !iter.isDone(); iter.next()) { MGlobal::displayInfo("NURBS Curve " + it); it++; // 找出當前曲線的完整DAG路徑 iter.getDagPath(dagPath); // 將NURBS曲線函數集MFnNurbsCurve與DAG路徑相關聯 // 這樣就規定了之後的全部函數集操做均被應用到DAG路徑給出的對象上 curveFn.setObject(dagPath); // 獲得曲線參數範圍的始末值 double tStart, tEnd; curveFn.getKnotDomain(tStart, tEnd); MPoint pt; unsigned int i; double t; // 沿曲線長度建立了數目爲nPosts的圓柱,參數範圍按圓柱數目來分割 double tIncr = (tEnd - tStart) / (nPosts - 1); // t值沒變一步,就沿曲線生成一個圓柱 for (i = 0, t = tStart; i < nPosts; i++, t += tIncr) { // 返回曲線上的一個點(世界座標) curveFn.getPointAtParam(t, pt, MSpace::kWorld); // 中心點在軸心,作出調整使其地面位於曲線上 pt.y += 0.5 * height; // 執行MEL命令建立圓柱 // pivot-軸心 MGlobal::executeCommand(MString("cylinder -pivot ") + pt.x + " " + pt.y + " " + pt.z + " -radius " + radius + " -axis 0 1 0 -heightRatio " + heightRatio); } } return MS::kSuccess; } // 初始化 // obj指向有關插件類型的maya內部數據的一個句柄 MStatus initializePlugin(MObject obj) { // 將MFnPlugin關聯到MObject上 MFnPlugin pluginFn(obj, "Amber W", "1.0"); MStatus stat; stat = pluginFn.registerCommand("Posts", PostsCmd::creator); if (!stat) { stat.perror("registerCommand failed"); } return stat; } // 卸載 MStatus uninitializePlugin(MObject obj) { MFnPlugin pluginFn(obj); MStatus stat; stat = pluginFn.deregisterCommand("Posts"); if (!stat) { stat.perror("deregisterCommand failed"); } return stat; }
其中大部分代碼都是建立命令必須的,能夠用一句話來代替:對象
DeclareSimpleCommand( Posts, "", "2018");
所以,最終代碼簡化版爲blog
#include <maya/MSimple.h> #include <maya/MGlobal.h> #include <maya/MFnPlugin.h> #include <maya/MPxCommand.h> #include <maya/MSelectionList.h> #include <maya/MDagPath.h> #include <maya/MFnNurbsCurve.h> #include <maya/MItSelectionList.h> #include <maya/MPoint.h> DeclareSimpleCommand( Posts, "", "2018"); MStatus PostsCmd::doIt(const MArgList&) { // 初始化數目、半徑、高度 const int nPosts = 5; const double radius = 0.5; const double height = 5.0; // 建立當前已選定對象的一個清單,Selection對象用語保存清單對象 MSelectionList selection; MGlobal::getActiveSelectionList(selection); MDagPath dagPath; MFnNurbsCurve curveFn; // cylinder不容許顯示設置其高度,必須經過heightRatio的值來設置 double heightRatio = height / radius; // 設置了一個過濾器的迭代器,排除不是NURBS曲線的全部其餘對象 MItSelectionList iter(selection, MFn::kNurbsCurve); MGlobal::displayInfo("Now...\n"); int it = 0; // 迭代NURBS曲線 for (; !iter.isDone(); iter.next()) { MGlobal::displayInfo("NURBS Curve " + it); it++; // 找出當前曲線的完整DAG路徑 iter.getDagPath(dagPath); // 將NURBS曲線函數集MFnNurbsCurve與DAG路徑相關聯 // 這樣就規定了之後的全部函數集操做均被應用到DAG路徑給出的對象上 curveFn.setObject(dagPath); // 獲得曲線參數範圍的始末值 double tStart, tEnd; curveFn.getKnotDomain(tStart, tEnd); MPoint pt; unsigned int i; double t; // 沿曲線長度建立了數目爲nPosts的圓柱,參數範圍按圓柱數目來分割 double tIncr = (tEnd - tStart) / (nPosts - 1); // t值沒變一步,就沿曲線生成一個圓柱 for (i = 0, t = tStart; i < nPosts; i++, t += tIncr) { // 返回曲線上的一個點(世界座標) curveFn.getPointAtParam(t, pt, MSpace::kWorld); // 中心點在軸心,作出調整使其地面位於曲線上 pt.y += 0.5 * height; // 執行MEL命令建立圓柱 // pivot-軸心 MGlobal::executeCommand(MString("cylinder -pivot ") + pt.x + " " + pt.y + " " + pt.z + " -radius " + radius + " -axis 0 1 0 -heightRatio " + heightRatio); } } return MS::kSuccess; }
Posts2.0索引
能夠在命令行出現參數,執行時輸入:get
Posts -r 1.0 -n 6 -h 10.0;
修改doIt前面一部分的代碼爲:
MStatus Posts::doIt(const MArgList& args) { // 初始化的數目、半徑、高度 int nPosts = 5; double radius = 0.5; double height = 5.0; // 從命令行中獲取參數值 unsigned index; // 返回含有給定標記的參數的索引(兩種標記) index = args.flagIndex("n", "number"); // 若是命令行中沒有設置該值,index就被設置爲MArgList::kInvalidArgIndex if (MArgList::kInvalidArgIndex != index) { args.get(index + 1, nPosts); } index = args.flagIndex("r", "radius"); if (MArgList::kInvalidArgIndex != index) { args.get(index + 1, radius); } index = args.flagIndex("h", "height"); if (MArgList::kInvalidArgIndex != index) { args.get(index + 1, height); } .......
}
Posts3.0
使用MSyntax和MArgsDatabase類。這兩個類在能夠使用的參數數目和類型方面帶來了更大的靈活性。並且提供了更好的參數,類型檢查機制。
MSyntax類提供了一種簡便的方法來爲你的命令行指定全部可能的參數。
MArgsDatabase類被用來分析和分隔不一樣的標記和它們的值。
#include <maya/MSimple.h> #include <maya/MGlobal.h> #include <maya/MFnPlugin.h> #include <maya/MPxCommand.h> #include <maya/MSelectionList.h> #include <maya/MDagPath.h> #include <maya/MFnNurbsCurve.h> #include <maya/MItSelectionList.h> #include <maya/MPoint.h> #include <maya/MSyntax.h> #include <maya/MArgDatabase.h> const char *numberFlag = "-n", *numberLongFlag = "-number"; const char *radiusFlag = "-r", *radiusLongFlag = "-radius"; const char *heightFlag = "-h", *heightLongFlag = "-height"; class PostsCmd : public MPxCommand { public: // 執行命令時調用,完成命令的實際工做 virtual MStatus doIt(const MArgList&); // 返回的是命令已分配過的一個實例 static void *creator() { return new PostsCmd; } static MSyntax newSyntax(); }; // 指定標記的參數的數據類型 MSyntax PostsCmd::newSyntax() { MSyntax syntax; syntax.addFlag(numberFlag, numberLongFlag, MSyntax::kLong); syntax.addFlag(radiusFlag, radiusLongFlag, MSyntax::kDouble); syntax.addFlag(heightFlag, heightLongFlag, MSyntax::kDouble); return syntax; } MStatus PostsCmd::doIt(const MArgList& args) { // 初始化的數目、半徑、高度 int nPosts = 5; double radius = 0.5; double height = 5.0; MArgDatabase argData(syntax(), args); // 依次檢查每一個標記,看其值是否已經設置 if (argData.isFlagSet(numberFlag)) { argData.getFlagArgument(numberFlag, 0, nPosts); } if (argData.isFlagSet(radiusFlag)) { argData.getFlagArgument(radiusFlag, 0, radius); } if (argData.isFlagSet(heightFlag)) { argData.getFlagArgument(heightFlag, 0, height); } // 建立當前已選定對象的一個清單,Selection對象用語保存清單對象 MSelectionList selection; MGlobal::getActiveSelectionList(selection); MDagPath dagPath; MFnNurbsCurve curveFn; // cylinder不容許顯示設置其高度,必須經過heightRatio的值來設置 double heightRatio = height / radius; // 設置了一個過濾器的迭代器,排除不是NURBS曲線的全部其餘對象 MItSelectionList iter(selection, MFn::kNurbsCurve); int it = 0; // 迭代NURBS曲線 for (; !iter.isDone(); iter.next()) { MGlobal::displayInfo("NURBS Curve " + it); it++; // 找出當前曲線的完整DAG路徑 iter.getDagPath(dagPath); // 將NURBS曲線函數集MFnNurbsCurve與DAG路徑相關聯 // 這樣就規定了之後的全部函數集操做均被應用到DAG路徑給出的對象上 curveFn.setObject(dagPath); // 獲得曲線參數範圍的始末值 double tStart, tEnd; curveFn.getKnotDomain(tStart, tEnd); MPoint pt; unsigned int i; double t; // 沿曲線長度建立了數目爲nPosts的圓柱,參數範圍按圓柱數目來分割 double tIncr = (tEnd - tStart) / (nPosts - 1); // t值沒變一步,就沿曲線生成一個圓柱 for (i = 0, t = tStart; i < nPosts; i++, t += tIncr) { // 返回曲線上的一個點(世界座標) curveFn.getPointAtParam(t, pt, MSpace::kWorld); // 中心點在軸心,作出調整使其地面位於曲線上 pt.y += 0.5 * height; // 執行MEL命令建立圓柱 // pivot-軸心 MGlobal::executeCommand(MString("cylinder -pivot ") + pt.x + " " + pt.y + " " + pt.z + " -radius " + radius + " -axis 0 1 0 -heightRatio " + heightRatio); } } return MS::kSuccess; } // 初始化 // obj指向有關插件類型的maya內部數據的一個句柄 MStatus initializePlugin(MObject obj) { // 將MFnPlugin關聯到MObject上 MFnPlugin pluginFn(obj, "Amber W", "1.0"); MStatus stat; // 爲了讓maya知道要使用自定義的MSyntax對象 stat = pluginFn.registerCommand("Posts", PostsCmd::creator, PostsCmd::newSyntax ); if (!stat) { stat.perror("registerCommand failed"); } return stat; } // 卸載 MStatus uninitializePlugin(MObject obj) { MFnPlugin pluginFn(obj); MStatus stat; stat = pluginFn.deregisterCommand("Posts"); if (!stat) { stat.perror("deregisterCommand failed"); } return stat; }
Posts4.0
參考:《Maya5.0編程全攻略》