Giter Site home page Giter Site logo

pymel's Introduction

Python in Maya Done Right

PyMEL makes python scripting with Maya work the way it should.

Maya's command module is a direct translation of mel commands into python commands. The result is a very awkward and unpythonic syntax which does not take advantage of python's strengths -- particulary, a flexible, object-oriented design. PyMEL builds on the maya.cmds module by organizing its commands into a class hierarchy, and by customizing them to operate in a more succinct and intuitive way.

Project Goals

  • Create an open-source python module for Maya that is intuitive to MEL users and python users alike
  • Fix bugs and design limitations in Maya's python modues, maya.cmds and maya.mel
  • Keep code concise and readable
  • Add organization through class hierarchy and sub-modules
  • Provide documentation accessible via html and the builtin `help() function
  • Make it "just work"

Supported Maya Versions

PyMEL supports four major versions of Maya:

  • 2020
  • 2022
  • 2023
  • 2024

See the full changelog.

Production Proven

Since its release in 2008, PyMEL has accumulated an impressive resume in both feature films and games, and is now bundled with every release of Maya.

Here's what Seth Gibson of Bungie Studios, makers of Halo, has to say:

Having done production python code myself for many years, wrapping my head around Maya's native implementation took a little bit of time. With PyMel, I can think and write the python code and syntax I'm already used to, which speeds up my development time considerably. It's also going to help our other Technical Artists with their Python learning curve, since PyMEL's syntax is consistent with most other python packages. Kudos to the PyMel team for such a well thought out project!

BSD License

PyMEL is released under the BSD license, which is as open as open source gets. Your studio can freely use, contribute to, and modify this module with no strings attached.

Features

API Hybridization

PyMEL harnesses the API to create a name-independent representation of your object. This means that the annoying inconsistencies of string comparisons are over: no more worrying about short names versus long names, DAG paths, unique paths, instance paths... it's all handled intelligently for you. And what's more, if anything causes the name of your object to change it will automatically be reflected in your python object.

PyMEL node classes now include hundreds of new methods derived from the API, but with the same intuitive and unified design as before. With PyMEL you get the benefits of API speed and versatility without the advanced learning curve.

Improved Batch / Standalone Support

Ever wonder why python scripts that work in the Maya UI or in Maya batch don't work in Maya's python interpreter? Here's a possible explanation: in both GUI and batch modes Maya sources all of its lowest-level MEL scripts, like those that load user plugins, whereas mayapy and maya.initialize does not.

PyMEL ensures that Maya is properly initialized when used from Maya's python interpreter, which makes runtime environments more consistent and your scripts more portable, which adds up to fewer bugs.

Tighter MEL Integration

Executing a MEL script with arguments can be an unsightly mess when done the default way:

default

values = ['one', 'two', 'three', 'four']
maya.mel.eval('stringArrayRemoveDuplicates({"'+'","'.join(values)+'"})')

So PyMEL provides a handy interface which makes calling MEL procedures just like calling a python function:

PyMEL

values = ['one', 'two', 'three', 'four']
pm.mel.stringArrayRemoveDuplicates(values)

Also, unlike maya.mel.eval, PyMEL will give you the specific MEL error message in a python traceback, along with line numbers:

>>> mel.myScript('foo', [])
Traceback (most recent call last):
    ...
MelConversionError: Error occurred during execution of MEL script: line 2: Cannot convert data of type string[] to type float.

Also, getting and setting MEL global variables is as easy as working with a dictionary:

print(pm.melGlobals['gMainFileMenu'])
pm.melGlobals['gGridDisplayGridLinesDefault'] = 2

Powerful Classes

Nodes

camTrans, cam = pm.camera()  # create a new camera
cam.setFocalLength(100)
fov = cam.getHorizontalFieldOfView()
cam.dolly(-3)
cam.track(left=10)
cam.addBookmark('new')

Attributes

s = pm.polySphere()[0]
if s.visibility.isKeyable() and not s.visibility.isLocked():
    s.visibility.set(True)
    s.visibility.lock()
    print(s.visibility.type())

File paths

backup all mb files in the current scene's directory

basedir = pm.sceneName().parent
backupDir = basedir / "backup" #slash op joins paths
if not backupDir.exists:
    backupDir.mkdir()
for path in basedir.files('*.mb'):
    print("backing up: ", path.name)
    path.copy(backupDir / (path.namebase + ".old"))

Shape components and vectors/matrices

select all faces that point up in world space

s = pm.polySphere()[0]
for face in s.faces:
    if face.getNormal('world').y > 0.0:
       pm.select(face, add=1)

optionVars dictionary

if 'numbers' not in pm.optionVar:
    pm.optionVar['numbers'] = [1, 24, 47]
pm.optionVar['numbers'].append(9)
numArray = pm.optionVar.pop('numbers')

Who is PyMEL for?

For the Novice

Object-oriented programming, like that provided by PyMEL, is more intuitive to learn because the functionality of an object is directly associated with the object itself.

For an artist starting to program in Maya, the first question you might ask is "what can I do with this node?" Using a procedural approach, like that offered by MEL or maya.cmds, you'll have to dig through the thousands of MEL commands looking for the one that you want. For a camera node, the camera MEL command is easy to find, but did you find orbit, track, dolly, and tumble, which also work on cameras? What about the API methods?

In PyMEL, all you have to do is type help(nt.Camera) in the python script editor to find out all the things a camera node can do, or just look up the Camera class in the PyMEL docs.

For the MEL Scripter

When we say PyMEL is concise and easy to read, we mean it.

MEL

string $sel[] = `ls -sl`;
string $shapes[] = `listRelatives -s $sel[0]`;
string $conn[] = `listConnections -s 1 -d 0 $shapes[0]`;
setAttr ( $conn[0] + ".radius") 3;

PyMEL

pm.selected()[0].getShape().inputs()[0].radius.set(3)

For the Technical Director

For those looking to master python in a production environment, PyMEL is more than a module for Maya scripting, it is a repository of example python code -- a self-contained pipeline demonstrating advanced python concepts like function factories, metaclasses, and decorators, as well as essential production practices such as parsing, pickling, logging, and unit testing.

For those who are already masters of python and who naturally expect more out of a python package, PyMEL is for you, too. It was written for use in production by experienced programmers with a vision for how to add object-oriented design to Maya.

Code Comparison

with Mel

string $objs[] = `ls -type transform`;
for ($x in $objs) {
    print (longNameOf($x)); print "\n";

    // make and break some connections
    connectAttr( $x + ".sx") ($x + ".sy");
    connectAttr( $x + ".sx") ($x + ".sz");

    // disconnect all connections to .sx
    string $conn[] = `listConnections -s 0 -d 1 -p 1 ($x + ".sx")`;
    for ($inputPlug in $conn)
        disconnectAttr ($x + ".sx") $inputPlug;

    // add and set a string array attribute with the history of this transform's shape
    if ( !`attributeExists "newAt" $x`)
        addAttr -ln newAt -dataType stringArray $x;
    string $shape[] = `listRelatives -s $x`;
    string $history[] = `listHistory $shape[0]`;
    string $elements = "";
    for ($elem in $history)
        $elements += """ + $elem + "" ";
    eval ("setAttr -type stringArray " + $x + ".newAt " + `size $history` + $elements);
    print `getAttr ( $x + ".newAt" )`;

    // get and set some attributes
    setAttr ($x + ".rotate") 1 1 1;
    float $trans[] = `getAttr ($x + ".translate")`;
    float $scale[] = `getAttr ($x + ".scale")`;
    $trans[0] *= $scale[0];
    $trans[1] *= $scale[1];
    $trans[2] *= $scale[2];
    setAttr ($x + ".scale") $trans[0] $trans[1] $trans[2];

    // call a mel procedure
    myMelScript( `nodeType $x`, $trans );
}

with default Python

import maya.cmds as cmds
objs = cmds.ls(type='transform')
# returns None when it finds no matches
if objs is not None:
    for x in objs:
        print(mm.eval('longNameOf("%s")' % x))

        # make and break some connections
        cmds.connectAttr('%s.sx' % x,  '%s.sy' % x)
        cmds.connectAttr('%s.sx' % x,  '%s.sz' % x)

        # disconnect all connections to .sx
        conn = cmds.listConnections(x + ".sx", s=0, d=1, p=1)
        # returns None when it finds no match:
        if conn is not None:
            for inputPlug in conn:
                cmds.disconnectAttr(x + ".sx", inputPlug)

        # add and set a string array attribute with the history of this transform's shape
        if not mm.eval('attributeExists "newAt" "%s"' % x):
            cmds.addAttr(x, ln='newAt', dataType='stringArray')
        shape = cmds.listRelatives(x, s=1 )
        if shape is not None:
            history = cmds.listHistory( shape[0] )
        else:
            history = []
        args = tuple(['%s.newAt' % x, len(history)] + history)
        cmds.setAttr(*args,  type='stringArray' )

        # get and set some attributes
        cmds.setAttr('%s.rotate' % x, 1, 1, 1)
        scale = cmds.getAttr('%s.scale' % x)
        # maya packs the previous result in a list for no apparent reason:
        scale = scale[0]
        # the tuple must be converted to a list for item assignment:
        trans = list(cmds.getAttr('%s.translate' % x )[0])  
        trans[0] *= scale[0]
        trans[1] *= scale[1]
        trans[2] *= scale[2]
        cmds.setAttr('%s.scale' % x, trans[0], trans[1], trans[2])
        # call a mel procedure
        mm.eval('myMelScript("%s",{%s,%s,%s})' % (cmds.nodeType(x), trans[0], trans[1], trans[2]))

with Pymel

# safe to import into main namespace (but only recommended when scripting interactively)
from pymel import *
for x in ls(type='transform'):
    # object oriented design
    print(x.longName())

    # make and break some connections
    x.sx.connect(x.sy)
    x.sx.connect(x.sz)
    # disconnect all connections to .sx
    x.sx.disconnect()

    # add and set a string array attribute with the history of this transform's shape
    x.setAttr('newAt', x.getShape().history(), force=1)

    # get and set some attributes
    x.rotate.set([1, 1, 1])
    trans = x.translate.get()
    # vector math:
    trans *= x.scale.get()
    # ability to pass list/vector args
    x.translate.set(trans)
    # call a mel procedure
    mel.myMelScript(x.type(), trans)

With PyMEL, python and maya play well together.

Installation

To install, use pip with the mayapy interpreter.

Installing into Maya's site-packages directory

The following commands will install PyMEL into the site-packages of the Maya application directory:

On MacOS:

/Applications/Autodesk/maya<Version>/Maya.app/Contents/bin/mayapy -m pip install pymel

On Linux:

sudo /usr/autodesk/maya<Version>/bin/mayapy -m pip install pymel

On Windows:

(from a command window running as Administrator)

/Applications/Autodesk/maya<Version>/Maya.app/Contents/bin/mayapy -m pip install pymel

Installing into your user's site-packages directory

If you do not have permissions to install into Maya's site-packages, you can install into your user site-packages by adding the --user flag, e.g.

/usr/autodesk/maya<Version>/bin/mayapy -m pip install pymel --user

To see where pymel was installed you can run:

mayapy -c "import pymel;print(pymel.__file__)"

Caveats

Older versions of Maya (2021 and earlier) may require installing pip before running pip install:

On Linux and Mac:

curl https://bootstrap.pypa.io/get-pip.py | /usr/autodesk/maya2021/bin/mayapy

PyMEL is developed and maintained by Luma Pictures.

pymel's People

Contributors

arnolduser avatar assumptionsoup avatar bob-white avatar chadrik avatar david-lassonde-adsk avatar eoyilmaz avatar fenderog avatar j0yu avatar juggernate avatar kartikg3 avatar kinetifex avatar koreno avatar laslavinco avatar mjmvisser avatar mrharris avatar orenouard avatar pmolodo avatar pythonindy avatar sambvfx avatar sopvop avatar tonybarbieri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pymel's Issues

ValueError when creating custom node with pm.nt.CustomNode()

In our studio we have some custom nodes (manip).
With the new version 1.06 it reconizes the pm.nt.CustomNode, but when I try " pm.nt.CustomNode()" I get this error:

Error: ValueError: file pymel\core\general.py line 2143: unexpect result locator1 returned by spaceLocator

pm.createNode(pm.nt.CustomNode) works fine though..

Crash when MPlug referring to deleted node is used

If an Attribute referring to a multi attribute element is referenced after the node is deleted in some circumstances, it can crash Maya.

My reproduction case:

import pymel.core as pm
node = pm.createNode('transform')
pm.addAttr(node, ln='test', at='double', m=True)
attr = node.test[0]
pm.newFile(force=True)
attr.isConnected()

Crashes using PyMEL 1.0.5 under Maya 2014. Apparently it must be a multi attribute, and you have to create a new file instead of simply deleting the node. You also must call one of the built-in MPlug functions instead of any of the PyMEL functions (as the PyMEL functions tend to end up testing the validity of the MObjectHandle before actually doing anything, which is sufficient to avoid crashing).

Might qualify as a Maya bug given the oddly specific reproduction, but I'm not sure that MPlug is guaranteed safe if the underlying node has been deleted.

Working with locators

Creating a locator gives an error but the locator is created

import pymel.core as pm
pm.nodetypes.Locator()
# Error: ValueError: file ...\pymel\core\general.py line 2143: unexpect result locator1 returned by spaceLocator # 

Seems like the pm.nt.Locator is only the shape node.. pity

pm.nt.Locator('locator1') # Fails
pm.nt.Locator('locatorShape1') # Works

Transform getRotation

As opposed to what docs say, the getRotation method from Transforms returns a MEulerRotation type (bleh!) and not a MQuaternion (which would be more consistent)

no access to file query flags (eg: -amf) via pymel?

From [email protected] on April 10, 2008 09:32:58

0.7.8, Maya 2008, CentOS-4.5

asked about this on python_inside_maya, did not receive an intelligible
answer, so I'm asking here:

is there the pymel equivalent to 'file -q -sn' or 'file -q -amf'? I can
always use the maya.cmds.file function, but...

With the file cmd being broken up into multiple functions inside pymel.io,
it seems that there's no method for doing these types of queries that I can
find.

Original issue: http://code.google.com/p/pymel/issues/detail?id=34

Implement Component1D.fullPath()

Hi PyMEL team!

There doesn't seems to have a way to retrieve the full path to a Component1D:

ls -sl -long
// Result: |path|to|something.vtx[3] //
pymel.core.general.ls( selection=True, long=True )[0].name()
# Result: u'something.vtx[3]' #

[0] is a MeshVertex of course.

It's missing a way to do something like:

pymel.core.general.ls( selection=True, long=True )[0].fullPath()
# Result: u'|path|to|something.vtx[3]' #

Keep the good job! :)

node.shortName() returns a pymel.node instance, and not a unicode string

From [email protected] on April 07, 2008 12:51:01

0.7.8, maya 2008, CentOS 4-5

don't know if this is considered a bug, or if I'm simply misusing the
methods...

.nodeName() returns a unicode string, but it seems that the other
*Name() methods return a pymel.node instance. Is this expected?

as far as I can tell, shortName(), longName(), nextName(),
nextUniqueName(), and prevName() all return an instance.

Original issue: http://code.google.com/p/pymel/issues/detail?id=31

rename() and <node>.rename() does not update data returned by node's *Name() or __repro

From [email protected] on April 04, 2008 12:57:17

0.7.8, maya 2008, CentOS 4.5

it would also appear that renaming a node causes .longName() to throw an
exception.

running this:

ball = polySphere()[0]
print ' nodeName: %s' % ball.nodeName()
print 'shortName: %s' % ball.shortName()
print ' longName: %s' % ball.longName()

print 'renaming...'

ball.rename('foo')
print ' nodeName: %s' % ball.nodeName()
print 'shortName: %s' % ball.shortName()
try:
print ' longName: %s' % ball.longName()
except:
import traceback as tb
print tb.print_exc()

print ls(type='transform')

returns this:

nodeName: pSphere1
shortName: pSphere1
longName: |pSphere1
renaming...
nodeName: pSphere1
shortName: pSphere1

Traceback (most recent call last):

File "", line 13, in

File

"/mainframe/share/internal/devMaya/2008/release/python/pymel/node.py", line
1390, in longName

return self.class( cmds.ls( self, long=True )[0] )

IndexError: list index out of range

None
[Transform('foo'), Transform('front'), Transform('persp'),
Transform('side'), Transform('top')]

Original issue: http://code.google.com/p/pymel/issues/detail?id=29

unable to set fileRule using workspace.fileRules class variable

From [email protected] on April 02, 2008 16:19:16

0.7.8, Maya 2008, Linux (CentOS-4.5)

print ws.fileRules['particles']
particles
ws.fileRules['particles'] = 'foobar'

Error: Flag 'fileRule' must be passed a boolean argument when query flag

is set

Traceback (most recent call last):

File "", line 1, in

File

"/mainframe/share/internal/devMaya/2008/release/python/pymel/core.py", line
157, in setitem

return cmds.workspace( item, **{'q' : 1, self.entryType: [item,

value] } )

TypeError: Flag 'fileRule' must be passed a boolean argument when query

flag is set #

Original issue: http://code.google.com/p/pymel/issues/detail?id=28

melparse - lambdas converted from mel command strings assume 'mm' (maya.mel) is in the global namespace

From [email protected] on March 28, 2008 00:46:37

melparse.py (#1751):

if commandFlag:
token = 'lambda *args: mm.eval(%s)' % token

It would be wrong to assume "mm" is available. An ugly solution would be:
token = 'lambda *args: import("maya.mel",fromlist=['']).eval(%s)' % token

This would make sure the code works, but would be quite incomprehensible
for the common user trying to convert his mel code...

Original issue: http://code.google.com/p/pymel/issues/detail?id=26

mel2py failes when pass with a script name that resolves to a fullpath with spaces in it

From [email protected] on January 23, 2008 23:11:53

---Failes:---
mp.mel2py("myScript",verbosity=1)

Error: (2, 'No such file or directory',

path(u'Documents/maya/scripts/myScript.mel'))

Traceback (most recent call last):

File "", line 1, in

File "C:\My Documents\PythonPackages\pymel\mel2py.py", line 255, in mel2py

data = melfile.bytes()

File "C:\Program

Files\Autodesk\Maya2008\Python\lib\site-packages\pymel\path.py", line 525,
in bytes

File "C:\Program

Files\Autodesk\Maya2008\Python\lib\site-packages\pymel\path.py", line 521,
in open

IOError: (2, 'No such file or directory',

path(u'Documents/maya/scripts/myScript.mel')) #

----Works:---
mp.mel2py("C:/My Documents/maya/scripts/myScript.mel",verbosity=1)
converting mel script C:/My Documents/maya/scripts/myScript.mel

Original issue: http://code.google.com/p/pymel/issues/detail?id=16

Importing pymel outside of Maya for the benefit of context-specific auto-completion in a python text editor.

From [email protected] on November 19, 2007 12:03:29

When attempting to import pymel outside of maya on Windows XP:

import pymel
Traceback (most recent call last):
File "", line 1, in
File "C:\Program Files\Autodesk\Maya2008\Python\lib\site-
packages\pymel__init__.py", line 341, in
del(eval)
NameError: name 'eval' is not defined

Original issue: http://code.google.com/p/pymel/issues/detail?id=1

Vector Improvements

From [email protected] on April 07, 2008 17:29:45

Posted on behalf of guy_smiley (talha.ahmed at gmail.com)

I have just started using python in maya extensively, and I spent
about a couple of days trying to write wrappers for the existing
maya.cmds module before somebody told me about this. So this is simply
awesome.

Just seeing the the pymel.vector module in version 0.7.8, I have found
a couple of problems like the pow fuction and atan2 function are
missing some return statements. I came to know about this problem
while writing a couple of functions that I miss from mel, such as
"angle", "rot" and "cross"
I would like to propose the following functions for inclusion in the
module.

Vector.unit() function that doesnt do inplace modification of values

like normalize does but simply returns the unit vector

   def unit(self):
           mag = self.norm()
           if mag > 0:
                   return self/mag
           else:
                   return self.__class__([0,0,0])

other utility functions such as

def cross(a, b):
"""
cross Product of Two MVecs
"""
try:
return Vector([a.y_b.z - a.z_b.y, a.z_b.x-a.x_b.z,
a.x_b.y-a.y_b.x])
except:
raise TypeError, 'Vector::FAILURE in cross'

def angle(a,b):
"""
Determine the angle between two MVecs
"""
try:
return acos(dot(a.unit(),b.unit()))
except:
raise TypeError, 'Vector::FAILURE in angle'

def rot(v, axis, theta):
"""
Rotate MVec v around MVec axis by angle
based on http://www.cprogramming.com/tutorial/3d/rotation.html """
axis.normalize()
c = cos(theta)
s = sin(theta)
t = 1 - c
try:
rotationMatrix = Matrix([[t*pow(axis.x, 2) + c, t * axis.x

  • axis.y - s * axis.z, t * axis.x * axis.z + s * axis.y, 0],
    [t _axis.x * axis.y + s *
    axis.z, t_pow(axis.y,2) + c, t *
    axis.y * axis.z - s * axis.x, 0],
    [t * axis.x * axis.z - s*
    axis.y, t * axis.y * axis.z + s *
    axis.x, t * pow(axis.z,2) + c, 0],
    [0,0,0,1]])
    return (v * rotationMatrix)

    except:
    raise TypeError, 'Vector::FAILURE in rot'

def deg_to_rad(a):
return a * pi / 180

def rad_to_deg(b):
return a * 180 / pi

##########
I would also like to see more functions added to the pymel math
library, atleast the ones that were part of mel math library

Original issue: http://code.google.com/p/pymel/issues/detail?id=32

pymel.core.system.ReferenceEdit.remove() tries to call a dict

When I call pymel.core.system.ReferenceEdit.remove() I get this error:

# Error: TypeError: file C:\Program Files\Autodesk\Maya2015\Python\lib\site-packages\pymel\core\system.py line 1643: 'dict' object is not callable #

system.py line 1643 is:

editData = self.rawEditData()

rawEditData() is not a function of a pymel.core.system.ReferenceEdit and therefore should be called like this:

editData = self.rawEditData

pymel is using OpenMaya 1.0 API, 2.0 is reputedly much faster

Overview

The Maya Python API 2.0 is a new version of the Maya Python API which provides a more Pythonic workflow and improved performance. Both the new and old APIs can co-exist in the same script but objects from the two different APIs cannot be used interchangeably.

The Python API 2.0 has a number of advantages over the original API:

  • Array types are full Python sequences, including slice support.
  • Methods which take Maya array parameters will usually also take native Python sequences, such as arrays and tuples. Exceptions are made in some case for performance reasons.
  • The outputs of methods are usually returned in their return values, not through their parameter lists. Exceptions are made in some cases for performance reasons.
  • Methods which return multiple values (e.g. MFnFluid.getResolution) return them as a tuple or list, eliminating the need for MScriptUtil.
    Object attributes are preferred over rather than set/get methods. For example you can now write array.sizeIncrement=64.
  • There are more types of exceptions used when methods fail. Not everything is a RuntimeError, as was the case in the old API.
    The new API is generally faster than the old. Up to three times faster in some cases.

-- http://docs.autodesk.com/MAYAUL/2013/ENU/Maya-API-Documentation/python-api/

'addAttr' fails when the 'at' flag is supplied

From [email protected] on February 06, 2008 23:15:18

Error: global name 'Vector' is not defined

Seems that the Vector class isn't imported into the pymel.node module. I
suspect that the cause of this is that there is a cyclical importing
situation between pymel.node and pymel.vector, where each module imports
the other. I tried moving the import line into the addAttr function
definition, so that the import occurs when needed, and it seems to have
solved the problem.

def addAttr( _args, *_kwargs ):
...
from vector import Vector
at = kwargs.pop('attributeType', ...

Original issue: http://code.google.com/p/pymel/issues/detail?id=20

constraint "getWeight" method doesn't accept target list

From [email protected] on January 16, 2008 11:25:17

Create two objects and an orientConstraint, cannot seem to get the
getWeight method to work :

cons = PyNode('pCube2_orientConstraint1')
type(cons)

Result: <class 'pymel.node.OrientConstraint'>

cons.getWeight('pCube1')

Error: f() takes exactly 1 argument (2 given)

Traceback (most recent call last):

File "", line 1, in

TypeError: f() takes exactly 1 argument (2 given)

cons.getWeight()

Error: Target list was empty or contained no valid targets.

Traceback (most recent call last):

File "", line 1, in

File "/usr/local/lib/python2.5/site-packages/pymel/factories.py", line

491, in f

return inFunc( self, **kwargs )

RuntimeError: Target list was empty or contained no valid targets.

Original issue: http://code.google.com/p/pymel/issues/detail?id=8

remove from set raises

Is this the right place for this?

import pymel.core as pm            
t,h = pm.polySphere()            
pm.SCENE.initialShadingGroup.remove(t)

# ,Error:, in method 'MFnSet_removeMember', argument 2 of type 'MPlug const &'
# Traceback (most recent call last):
#   File "<maya console>", line 3, in <module>
#   File "/v/work/main/build/debug/runTime/Maya.app/Contents/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/pymel/core/nodetypes.py", line 5680, in remove
#     return self.__apimfn__().removeMember(item.__apiobject__())
# TypeError: in method 'MFnSet_removeMember', argument 2 of type 'MPlug const &' # 

# but this works
pm.sets(pm.SCENE.initialShadingGroup,e=True,remove=t)

Update docs for sets(): need set creation example

From [email protected] on March 20, 2008 15:41:57

v0.7.8

Just about lost my mind when trying to create a new set with sets(). Have
to pass in 'None' as the non-kw arg normally used designate the operating
set (objectSet arg in function definition).

Can the docs be updated with a creation example? Or create a list of
createFlags, and pass in objectSet via sets(*args)?

newSet1 = sets( name='new1', empty=True )

Error: sets() takes exactly 1 non-keyword argument (0 given)

Traceback (most recent call last):

File "", line 1, in

TypeError: sets() takes exactly 1 non-keyword argument (0 given)

newSet2 = sets( '', name='new2', empty=True )

Error: Object is invalid

Traceback (most recent call last):

File "", line 1, in

File "/corp/home/jburk/maya/scripts/pymel/core.py", line 1140, in sets

return cmds.sets( _args, *_kwargs )

TypeError: Object is invalid

newSet3 = sets( None, name='new3', empty=True )
print type(PyNode(newSet3))
<class 'pymel.node.ObjectSet'>

Original issue: http://code.google.com/p/pymel/issues/detail?id=25

DependNode._numPartReg regex fails where node_number is preceeded by '_'

From [email protected] on April 07, 2008 12:04:15

0.7.8, Maya 2008, CentOS-4.5

our modelers often use an '_' to visually distinguish the instance number
from the name: foo_12. This causes a bit of grief in both pymel and
apparently in maya's native 'duplicate' command...

attempting a work-around in pymel revealed this issue with the regex
defined in pymel's DependNode._numPartReg:

print re.search( DependNode._numPartReg, 'foo12' ).groups()
('foo', '12')

print re.search( DependNode._numPartReg, 'foo_12' ).groups()

Error: 'NoneType' object has no attribute 'groups'

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'NoneType' object has no attribute 'groups'

DependNode.numPartReg is:
([a-zA-Z|]+[a-zA-Z0-9
|]*[a-zA-Z]+)([0-9]+)$

regex works better with the underscore in the third character class:
([a-zA-Z|]+[a-zA-Z0-9_|]*[a-zA-Z_]+)([0-9]+)$

<< side note >>
It would also seem that trying to catch an exception raised by this is
problematic; a string exception is raised instead of an Exception object.
I often use 'except Exception, e:', and got tripped up over this.

# DeprecationWarning: raising a string exception is deprecated

at line: 1308 in

/mainframe/share/internal/devMaya/2008/release/python/pymel/node.py

Original issue: http://code.google.com/p/pymel/issues/detail?id=30

TypeError when using Assembly nodes.

Assembly nodes are failing when trying to internally create their MFn object.

Repro (tested with the master branch of pymel on 201459):

import pymel.core as pm
pm.loadPlugin('sceneAssembly')
asm = pm.assembly(type='assemblyDefinition')
asm.tx

Fails with a TypeError here because the MFnAssemby constructor can only take an MObject, and it's being passed a MDagObject.

Sadly I can't take this any farther and try to fix the problem myself because my hands are tied legally (for now) =[

Implement MeshEdge.toVector()

Hi and thanks for the hard work. PyMEL make geometric manipulation in Maya easy!

I just realize PyMEL didn't have any method to get a vector from a edge. I had to create one:

pt1 = edge.getPoint(0, space='world')
pt2 = edge.getPoint(1, space='world')
return pymel.core.dt.Vector( pt2.x - pt1.x , pt2.y - pt1.y , pt2.z - pt1.z )

I'm surprise no one ever asked for this. It's damn useful when you need to match "similar" (but not perfectly identical) geometries.

Keep the good job! :)

setAttr -type "matrix" mysteriously fails

From [email protected] on February 11, 2008 22:40:02

I think it's a maya.cmds bug, but I can implement a fix by running it via
mel:
def setMatrix(attr, mtx):
pm.setMelGlobal("float[]","$g_matrix",mtx.toList())
pm.mel.eval("""setAttr "%s" -type "matrix" $g_matrix[0] $g_matrix[1]
$g_matrix[2] $g_matrix[3]
$g_matrix[4] $g_matrix[5] $g_matrix[6] $g_matrix[7]
$g_matrix[8] $g_matrix[9] $g_matrix[10] $g_matrix
[11]
$g_matrix[12] $g_matrix[13] $g_matrix[14] $g_matrix
[15];""" % attr)

I'm wondering if it's a good idea to implement this directly into the
Attribute.set method

Original issue: http://code.google.com/p/pymel/issues/detail?id=21

listConnections with the 'plugs' flag should return plugs (pymel name Attributes) and not nodes (PyNodes) logically ?

From [email protected] on January 28, 2008 11:33:11

Try this

conn =
ShadingEngine('initialShadingGroup').attr('partition').listConnections(source=True,
destination=True, plugs=True)
part = conn[0]
print part
part.listConnections(source=True, destination=True, plugs=True)
part.plugAttr()
part.plugNode()
part.node()
Attribute(part).plugAttr()
Attribute(part).plugNode()

Original issue: http://code.google.com/p/pymel/issues/detail?id=19

workspace getcwd() does not return project dir as intended

Hello !

I have been using the old way to get the current project directory:

    import pymel.core as pm
    pm.workspace(q=True, rd=True)

Which works very well.
It outputs my current project directory : /Users/username/3D/Animations/Seq02/

But wit the new way, maybe i misunderstood how to use it...

    import pymel.core as pm
    pm.workspace.getcwd()

Which output the default Maya's directory: /Users/username/Documents/maya/projects/

Is it what was intended ?
Thank you.

toMObjectName not defined

MItDag in allapi.py makes reference to 'toMobjectName' that is defined nowhere I can see in pymel.

Feature request - the pymel classes should be able to create their respective maya node types

From [email protected] on January 23, 2008 22:53:02

By adding the new method to the DependNode class definition we can add
a "create" flag, which would allow the creation a a new node in the scene
according to the class we're instantiating. The return value would
reference that new maya node with the proper name, which (depending on the
implementation) could actually be different from the supplied string
(similar to how maya's 'createNode' works)

Here's an example of implementation, and example usage:

class DependNode( _BaseObj ):

def __new__(cls,name,create=False):
    if create:
        ntype = cls.__name__[0].lower() + cls.__name__[1:]
        name = createNode(ntype,n=name,ss=1)
    return _BaseObj.__new__(cls,name)

...

n = pm.Transform("persp",create=True)
n.repr()

Result: Transform('persp1')


Original issue: http://code.google.com/p/pymel/issues/detail?id=15

What happened to the rename() function??

From [email protected] on March 20, 2008 15:29:47

It fails finding a name() method on the object it is trying to rename...

(core.py, line 1138)

def rename( obj, newname, **kwargs):
"""
Modifications:
- if the full path to an object is passed as the new name, the
shortname of the object will automatically be used
"""
# added catch to use object name explicitely when object is a Pymel Node
if isinstance( newname, node.DependNode ):
newname = newname.name()
if isinstance (obj, node.DependNode) :
obj = obj.name()

return node.PyNode( cmds.rename( obj.name(), newname, **kwargs ) )

Original issue: http://code.google.com/p/pymel/issues/detail?id=24

degree on NurbsCurve name clash

It looks like the NurbsCurve class has a degree() method, which clashes with the degree attribute of a NurbsCurve in maya.

its causing UN-expected results.

curve = pm.PyNode('curve1')
deg = curve.degree.get()

causes a error in Maya 2014 since it says im trying to run a function on a function object.

that same code works in Maya 2012 and returns the expected result.

while

curve = pm.PyNode('curve1')
deg = curve.degree()

works perfectly in maya 2014, while failing in maya 2012.

duplicate() raises MayaNodeError

Maya 2012 SAP SP1 : cutID - 201201180158-821180

duplicate() raises MayaNodeError when an object's transform and shape node share the same name.

One way to reproduce:

-create a sphere
-rename the shape node to the same name as its xform.
-select the parent xform of the renamed shape
-execute the following commands:
import pymel.all as pm
some_xform = pm.ls(sl=True)[0]
pm.duplicate(some_xform, upstreamNodes=True)

The heir looks like this:

pSphere1
__pSphere1

Trunk doesn't work with 2013.5

2013.5 ships with its own pymel that works where'as the trunk doesn't. We've had issues with 2013.5 anyway because 'getAplicationVeriosnAsFloat' is returning 2013 and not 2013.5. I've looked at the cache files for pymel in the maya install and they also don't include the .5 in the name. Making me wonder if this is the source of a potential problem and the reason why I can't run the latest.

PyNode fails to identify attributes

From [email protected] on January 14, 2008 23:26:04

type(pymel.PyNode("persp.visibility"))

Result: <class 'pymel.node.Transform'> # Should've been an Attribute class

type(pymel.PyNode("non.existent"))

Result: <class 'pymel.node.Attribute'> # Expected result

The code for the PyNode function (in node.py) first checks cmds.nodeType
and uses that if successful; nodeType(node.attribute)==nodeType(node);
PyNode should first check for a "." in strObj, and only if that test is
false use nodeType:

def PyNode(strObj, nodeType=None):
"""Casts a string to a pymel class. Use this function if you are unsure
which class is the right one to use
for your object."""

try:
    if '.' in strObj:
        return Attribute(strObj)
except TypeError:
    raise 'PyNode: expected a string or unicode object, got &#37;s' &#37; type(strObj)

try:
    if not nodeType:
        nodeType = cmds.nodeType(strObj)
    return getattr(_thisModule, util.capitalize(nodeType) )(strObj)
except (AttributeError, TypeError): pass

return DependNode(strObj)

Original issue: http://code.google.com/p/pymel/issues/detail?id=2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.