不知道大家还记不记得之前的helixCmd,这个helix2Cmd是从C++转成python的版本,与helixCmd不同的是它不是创建曲线,而是更改曲线,使给定的曲线变成helix曲线,并且支持返回和重做。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
This example takes a curve and changes it into a helix.
"""
import sys
import math
import maya.OpenMaya as om
import maya.OpenMayaMPx as ompx
kPluginCmdName = 'spHelix2'
kPitchFlag = "-p"
kPitchLongFlag = "-pitch"
kRadiusFlag = "-r"
kRadiusLongFlag = "-radius"
# command
class Helix2(ompx.MPxCommand):
def __init__(self):
super(Helix2, self).__init__()
self.__fDagPath = om.MDagPath()
self.__fComponent = om.MObject()
self.__fCVs = om.MPointArray()
self.__radius = 4.0
self.__pitch = 0.5
def doIt(self, args):
"""
doIt用来完成所有的准备工作,最后才执行实际工作.
"""
argData = om.MArgDatabase(self.syntax(), args)
if argData.isFlagSet(kPitchFlag):
self.__pitch = argData.flagArgumentDouble(kPitchFlag, 0)
if argData.isFlagSet(kRadiusFlag):
self.__radius = argData.flagArgumentDouble(kRadiusFlag, 0)
# Get the first selected curve from the selection list.
# 获取所选的nurbsCurve曲线
slist = om.MSelectionList()
om.MGlobal.getActiveSelectionList(slist)
mitList = om.MItSelectionList(slist, om.MFn.kNurbsCurve)
# 如果所选物体不是nurbsCurve曲线,引发错误
if mitList.isDone():
sys.stderr.write('doIt: no curve has been selected\n')
raise
mitList.getDagPath(self.__fDagPath, self.__fComponent)
return self.redoIt()
def redoIt(self):
"""
redoIt来完成实际的工作
"""
curveFn = om.MFnNurbsCurve(self.__fDagPath)
# 获取曲线的cv数
numCVs = curveFn.numCVs()
# 获取所有cv点的坐标
curveFn.getCVs(self.__fCVs)
# 定义新的cv点的坐标
points = om.MPointArray(self.__fCVs)
for i in range(numCVs):
# Maya python API不支持列表直接赋值,需要使用set()
#points[i] = om.MPoint(self.__radius * math.cos(i),
#self.__pitch * i,
#self.__radius * math.sin(i))
points.set(om.MPoint(self.__radius * math.cos(i),
self.__pitch * i,
self.__radius * math.sin(i)), i)
# 将新的cv点坐标,赋予曲线
curveFn.setCVs(points)
# 更新曲线
curveFn.updateCurve()
return om.MStatus.kSuccess
def undoIt(self):
"""
undoIt用来还原nurbsCurve曲线
"""
curveFn = om.MFnNurbsCurve(self.__fDagPath)
curveFn.setCVs(self.__fCVs)
curveFn.updateCurve()
self.__fCVs.clear()
return om.MStatus.kSuccess
def isUndoable(self):
return True
def cmdCreator():
return ompx.asMPxPtr(Helix2())
def syntaxCreator():
syntax = om.MSyntax()
syntax.addFlag(kPitchFlag, kPitchLongFlag, om.MSyntax.kDouble)
syntax.addFlag(kRadiusFlag, kRadiusLongFlag, om.MSyntax.kDouble)
return syntax
def initializePlugin(mobject):
mplugin = ompx.MFnPlugin(mobject, 'Mack Stone', '1.0', 'Any')
try:
mplugin.registerCommand(kPluginCmdName, cmdCreator, syntaxCreator)
except:
sys.stderr.write('Failed to register command: %s\n' % kPluginCmdName)
raise
def uninitializePlugin(mobject):
mplugin = ompx.MFnPlugin(mobject)
try:
mplugin.deregisterCommand(kPluginCmdName)
except:
sys.stderr.write('Failed to unregister comman: %s\n' % kPluginCmdName)
raise
使用方法:
在插件面板加载helix2cmd.py,创建或选择一条曲线,执行命令
import maya.cmds as cmds
cmds.spHelix2()
# 或
cmds.spHelix2(r=3.0, p=2.0)
或
spHelix2; // 或 spHelix2 -r 5.0 -p 2.0;
但需要注意的是如果你输入的参数不是浮点值,如输入3,而不是3.0,可能会导致该参数失效而使用上一次的参数,不知道为什么,可能是maya python API对数据的转换还不够健全,或是数据类型十分敏感。
你可以在maya安装目录下的devkit/plug-ins找到helix2Cmd.cpp
。
在线版
http://download.autodesk.com/us/maya/2011help/API/helix2_cmd_8cpp-example.html
最后是pymel的版本,再次感受到pymel的强大
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import math
from pymel.core import *
def helix2(r=4, p=0.5):
# 获取所选物体
objs = ls(sl=1, long=1)
if not objs:
return False
# 获取物体的shape
shape = objs[0].getChildren()[0]
# 如果所选物体不是nurbsCurve曲线,引发错误
if not isinstance(shape, nodetypes.NurbsCurve):
raise Exception('No curve has been selected or must select nurbsCurve first.')
# 获取曲线的cv数
numCVs = shape.numCVs()
# 获取所有cv点的坐标
CVs = shape.getCVs()
# 定义新的cv点的坐标
newCVs = CVs
for i in range(numCVs):
newCVs[i] = dt.Point(r * math.cos(i),
p * i,
r * math.sin(i))
# 将新的cv点坐标,赋予曲线
shape.setCVs(newCVs)
# 更新曲线
shape.updateCurve()
return "Curve %s is turn to helix" % objs[0]
希望对你们有帮助