操作流程:

1. VS运行代码,生成插件

2. 打开Maya绘制曲线,加载插件

3. 选中绘制的曲线,运行插件

Posts1.0

代码:

#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 = ;
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 = ;
// 迭代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 - );
// t值没变一步,就沿曲线生成一个圆柱
for (i = , 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, "", "");

因此,最终代码简化版为

#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, "", ""); MStatus PostsCmd::doIt(const MArgList&)
{
// 初始化数目、半径、高度
const int nPosts = ;
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 = ;
// 迭代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 - );
// t值没变一步,就沿曲线生成一个圆柱
for (i = , 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

可以在命令行出现参数,执行时输入:

Posts -r 1.0 -n  -h 10.0;

修改doIt前面一部分的代码为:

MStatus Posts::doIt(const MArgList& args)
{
// 初始化的数目、半径、高度
int nPosts = ;
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 + , nPosts);
} index = args.flagIndex("r", "radius");
if (MArgList::kInvalidArgIndex != index) {
args.get(index + , radius);
} index = args.flagIndex("h", "height");
if (MArgList::kInvalidArgIndex != index) {
args.get(index + , 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 = ;
double radius = 0.5;
double height = 5.0; MArgDatabase argData(syntax(), args); // 依次检查每个标记,看其值是否已经设置
if (argData.isFlagSet(numberFlag))
{
argData.getFlagArgument(numberFlag, , nPosts);
}
if (argData.isFlagSet(radiusFlag))
{
argData.getFlagArgument(radiusFlag, , radius);
}
if (argData.isFlagSet(heightFlag))
{
argData.getFlagArgument(heightFlag, , 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 = ;
// 迭代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 - );
// t值没变一步,就沿曲线生成一个圆柱
for (i = , 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编程全攻略》

最新文章

  1. 『.NET Core CLI工具文档』(十一)dotnet-test
  2. centos 安装redis并加入系统服务
  3. [转]sed命令详解
  4. 算法求和sum问题
  5. Java使用ZXing生成二维码条形码
  6. winform中treeview中节点选中的技巧
  7. Long与long的比较
  8. 本地化web开发的一个例子-jquery.i18n.properties
  9. BZOJ 1563 诗人小G
  10. BitmapFactory.decodeResource(res, id); 第一个参数跟第二个参数有什么关系?
  11. DevExpress之进度条
  12. 序列化layer创建的弹出表单并ajax提交
  13. Angular中ngModel的$render的详解
  14. windows c++程序移植到linux的要点
  15. jest 自动化测试
  16. python中防止字符串转义
  17. 关于Selenium WebDriver的geckodriver
  18. [angularjs] 前端路由实现单页跳转
  19. DAY7 字符编码和文件操作
  20. 配置 Nginx 的目录浏览功能

热门文章

  1. Spring @Autowired 注解 学习资料
  2. Easyui 验证验证扩展,限制combobox 只能输入选项内容
  3. 【Javascript】数组之二
  4. spark读写Oracle、hive的艰辛之路(二)-Oracle的date类型
  5. js的类型系统--js基于原型的基石是所有对象最终都能够类型自证
  6. (转)虚拟文件系统(VFS)浅析
  7. selenium 2 设置浏览器安装路径
  8. count to any
  9. 在阿里云CentOS服务器上安装Python3.7并设置为默认Python
  10. java的多线程之入门