`
schi
  • 浏览: 201360 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Helix2Cmd

阅读更多

不知道大家还记不记得之前的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]

 希望对你们有帮助

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics