Maya编程——沿Curve绘制圆柱
操作流程:
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编程全攻略》
Maya编程——沿Curve绘制圆柱的更多相关文章
- Directx 3D编程实例:绘制3DMesh
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档.于是我也觉的有这个必要.写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客 ...
- 学习windows编程 day4 之 绘制随机矩形和peekMessage
#include <windows.h> #include <strsafe.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT messa ...
- Directx 3D编程实例:绘制可变速旋转的三角形
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档.于是我也觉的有这个必要. 写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博 ...
- cesium编程入门(五)绘制形状
通过Entity添加形状 先来看一个添加立方体的例子 var viewer = new Cesium.Viewer('cesiumContainer'); var redBox = **viewer. ...
- Maya编程——节点&命令
代码写完出现问题: 查了一下原因:
- OpenGL基础图形编程
一.OpenGL与3D图形世界1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个充 ...
- 【转】OpenGL基础图形编程(一)
原文:http://blog.chinaunix.net/uid-20638550-id-1909183.html 分类: 一.OpenGL与3D图形世界 1.1.OpenGL使人们进入三维图形世界 ...
- CG资源网 - Maya教程
Maya中mentalray灯光渲染终极训练视频教程 http://www.cgtsj.com/cg/f/vx3627/index.html Maya无人机建模制作训练视频教程第一季 http://w ...
- Maya FEM节点框架完成
这几天把物理模拟框架移植到maya之中了. maya编程有一点比较关键,就是要让自己的程序逻辑适应maya的节点求值机制.在物理模拟中,往往需要进行时间积分,对此我的解决办法是,写一个节点rigSim ...
随机推荐
- Kotlin匿名函数与闭包详解
Lambda表达式实例演练: 继续先来编写一些Lambda表达式相关的代码: 接下来想从上面的字符串数组中找到带有"h"的字符串并打印出来: 如果学习了Java8的Lambda表达 ...
- JMeter的执行顺序
JMeter执行顺序如下:1.配置元件2.前置处理器3.定时器4.采样器5.后置处理器(除非服务器响应为空)6.断言(除非服务器响应为空)7.监听器(除非服务器响应为空) 只有当作用域内存在采样器时, ...
- 将公式直接转化为Latex代码的神器-snip
经常用latex写论文,免不了要敲各种公式,今天和大家分享一个神器-snip,它可以直接将公式转化为代码,不需要我们自己编写公式代码,方便快捷,准确率极高.该神器的下载地址为:https://math ...
- HTTP协议通信过程
1. 了解HTTP HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器 ...
- Linux 中 Buffer/Cache内存占用过高解决方法
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: 这里的默认显示单位是kb,我的服务器是128G内存,所以数字显 ...
- Numpy | 08 切片和索引
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样. (1)ndarray 数组索引可以基于 0 - n 的下标进行: (2)切片对象可以通过内置的 ...
- 面试题必备-web页面基础
html标签是由<>包围的关键词 html标签是成对出现的 有部分标签是没有结束标签的,叫单标签, 页面中所有的内容,都是要放在HTML标签中的 HTML标签分三部分: 标签名称 标签内容 ...
- 04-树6 Complete Binary Search Tree (30 分)
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...
- DNN的BP算法Python简单实现
BP算法是神经网络的基础,也是最重要的部分.由于误差反向传播的过程中,可能会出现梯度消失或者爆炸,所以需要调整损失函数.在LSTM中,通过sigmoid来实现三个门来解决记忆问题,用tensorflo ...
- nginx if配置说明
格式:if (条件判断) { 具体的rewrite规则 } 条件举例: 条件判断语句由Nginx内置变量.逻辑判断符号和目标字符串三部分组成. 其中,内置变量是Nginx固定的非自定义的变量,如,$r ...