-----Mel-----
Float - Decimal
Integer - Whole Number
Relational Operators:
< less than
<= less than or equal to
> greater than
>= greater than or equal to
== equal to
!= not equal to
Logical Operators:
&& and - both first and second
conditions will be tested
|| or
! not
Arithmetic Operators:
+ Add two elements together
- Subtract two elements
* Multiply two elements
% Find the fractional remainder of the
division
^ Find the cross product of two
vectors
++ increment values by 1
-- decrement values by 1
Boolean Operators:
true, yes, on, 1
false, no, off, 0
Order of Precedence in which they
are evaluated:
PEMDAS
( ), [ ], !, ++,
--
*, /, %, ^
+, -
<, <=, >,
>=
==, !=
&&
||
?:
=, +=, -=, *=, /=
Variables:
int
float
string
vector
array
matrix
Delimiters that MEL recognizes:
( ) Used for
grouping and to denote argument or parameter lists
[ ] Used for
array and matrix declaration and their indexing
{ } Used for
procedure definitions, code blocks, and literal array values
" " Used
for string literals
\ Used for
special characters (aka "escape characters")
in string
literals (\", \n, \r, \t, \\, \<Enter>)
` ` Evaluates an
imperative command or procedure call as a MEL expression.
$ Used to
indicate variable names and array names.
<< >> Used
to delimit vector literals and matrix literals.
, Delimiter
arguments, parameters, and items in literal array, vector, or
matrix.
; Statement
delimiter, also used in literal matrix values and for loops.
: Used to
delimit cases in switch... case statements, default branching, and
in the "? :" operator.
// Used for
single-line comments.
/* */ Used for
multi-line comments.
Values:
False is given a value of 0 and True is
given a value of 1
A single = sets the variable and does
not test for equality use == to test for equality
Example:
//
gotcha prints "Match Found" when the argument's value
equals 4
global proc gotcha(int $theNum) { if ($theNum = 4) { print ("Match Found!\n"); } } |
--------Python Keywords--------
|
These
31 keywords are built right into the language, and the vast majority
of them are statements and statement modifiers, with about six of
them being keyword operators rather than full-fledged statements in
their own right. We made a big deal about distinguishing statements
from expressions in MEL, because MEL is strict about only having
certain expressions qualify as statements. In Python, any expression
can be treated as a statement, and that distinction is no longer so
important.
The
nine Python keywords that we've already seen in MEL are indicated
above in
blue.
There
are eight more which are slight syntactic variations from MEL or
which do something equivalent to a common MEL command, indicated
above in
teal.
Python's
scope management and error handling mechanisms are much more
sophisticated than MEL's, and there are nine such keywords have no
direct MEL counterpart. They are indicated in
dark
red for
scope and context management, and the ones related to error handling
appear in
bright
red.
The
remaining five pertain to classes, functions, and objects. One of
them is
grayed
out because
it's particularly obscure, but the final four, shown above in black,
are very basic and very important.
The Python keywords fall into the
following groups:
class & function
definition class, lambda, def,
return, yield
flow control: branching if, elif,
else
flow control: looping for,
in while, continue, break, pass
import, scope, and context from,
import, as global,
with
exception handling raise,
assert, try, except, finally
handy utility statements del,
print,
exec
Boolean operators is, and,
or,
not,
in
|
The
arithmetic operators are the same ones we saw in MEL, with two new
additions and one removal. The additions are the power raising
operator (**)
and the floor division operator (//).
(Floor division is like regular division, but it casts the result to
an integer value.) Python does not have the ^
symbol
as a vector cross product.
The
shift
and
bitwise
operators
are some features from C and C++ that were not included in MEL
because they are not relevant to Maya. They work only on integer
types, treating the values of their operands as binary data. You
probably won't ever use them, but if you need more information, look
in the Python Language Reference at www.python.org.
The
relational operators are the same as MEL's, with one very marginal
addition, which is that the test for inequality to can be written in
either of two ways, !=
or
<>.
(Even so, <
> is
antiquated, and you should never use it the code you write.)
The other
delimiters that Python uses for various purposes are as follows:
|
() []
{} "" '' \ `` @ . , ; : # ''' """
|
Gone
are the << and >>, which in Python are used for a
different purpose. Also gone is the $, which Python allows only in
comments and string literals.
In
Python, function parameters have no type declared with them, and as a
result, type conversion is somewhat less of an issue. Types maintain
their compatibility in all results, except when they are explicitly
converted to a lower type. I refer you to the copious online Python
documentation, if you really want to know more about how it all
works. We've already said plenty about variable scoping and exception
handling, and both of these are much cleaner in Python than they are
in MEL. However, just like MEL, when you operate in script editor or
command line, all the variables that you introduce become global,
except when you contain them in some kind of object.
Here is a python script that I have been working on for a class assignment. Still a work in progress.
|
# This script works with Maya 2015 and has not been tested with previous versions.
# No new commands were used in thsi script. If you test it, please let me know if it works.
# I do have dyslexia so if you find certain words misspelled please let me know at glen@robotracingmadness.com
# Copyright Glen Debello 2014
import maya.cmds as cmds
def gd_cameraBox():
window_name = "CameraBox"
window_title = "Create Camera Box"
if cmds.window("CameraBox", q=True, exists=True):
cmds.deleteUI("CameraBox")
winName = cmds.window(title="gd_CameraBox")
cmds.columnLayout()
cmds.separator(height=5, style='none')
cmds.text(label="Camera Visualizer")
cmds.separator(height=5, style='none')
cmds.text(label='Create Camera with default settings')
cmds.button(label = "Create Camera", command = "gd_createCameraBox()")
cmds.separator(height=20, style='none')
# A new window will be created since the camera has not been created yet. The clipping controls window
# cannot be opened until it creates a camera. This has to do with certain sliders connecting to the cameras
# attributes.
cmds.text(label='Will open new window')
cmds.button(label="Camera Controls", command = "clippingControls()")
cmds.separator(height=10, style='none')
cmds.showWindow(winName)
# Creates the main window for creating the camera box
def gd_createCameraBox():
cameraName = cmds.camera(fcp ='250')
cameraShape = cameraName[1]
cmds.textCurves(f='Times-Roman', t='camera',)
cmds.polyPlane(ax = [0,0,1], n='nearClipPlane')
cmds.polyPlane(ax = [0,0,1], n='farClipPlane')
# creates a reverse node that is has an input from the camera and outputs to the nearClipReverse shape.
# If you do not create and connect the reverse node, the shape will always go in reverse. This only
# creates the revers node, it does not connect any attributes
cmds.shadingNode('reverse', asUtility = True, n='nearClipReverse')
cmds.shadingNode('reverse', asUtility = True, n='farClipReverse')
# creates a custom resolution node that connects the render resolution
# to the far clipping plane shape.
cmds.shadingNode('resolution', asUtility=True, n='resolutionCustom1')
# connects the attributes associated with the resolution node and connects them
# to the width and height of the farclipping plane.
cmds.connectAttr('resolutionCustom1.width', 'polyPlane2.width')
cmds.connectAttr('resolutionCustom1.height', 'polyPlane2.height')
# connects the camera shape near clip plane to the reverse node. The reverse node was created
# earlier. We use the cmds.connectAttr to connect them to the reverse node.
cmds.connectAttr('cameraShape1.nearClipPlane', 'nearClipReverse.input.inputZ')
cmds.connectAttr('nearClipReverse.outputZ', 'nearClipPlane.translateZ')
cmds.connectAttr('cameraShape1.farClipPlane', 'farClipReverse.input.inputZ')
cmds.connectAttr('farClipReverse.outputZ', 'farClipPlane.translateZ')
#cmds.connectAttr('resolution1.width.', 'farClipPlane.scaleZ')
# Parents the the camera, far and near clipping planes, camera text, and creates a group.
cmds.parent('nearClipPlane', 'camera1', relative=True)
cmds.parent('farClipPlane', 'camera1', relative=True)
cmds.group('camera1', 'nearClipPlane', n='gd_visualGroup1')
cmds.parent('Text_camera_1', 'gd_visualGroup1')
def clippingControls():
if cmds.window("CameraBox", q=True, exists=True):
cmds.deleteUI("CameraBox")
window_name = "CamControls"
window_title = "Camera Controls"
if cmds.window("CamControls", q=True, exists=True):
cmds.deleteUI("CamControls")
winName = cmds.window(title="clippingControls")
cmds.columnLayout()
cmds.text(label="Camera Resolution Controls")
cmds.separator(height=10, style='none')
# to connect an attribute to a slider, you must find the attribute name to connect. This can be found
# easily using the Node Editor under Windows --> Node Editor and then with the tab button type in the name
# of the node you want to find. Select the radial button with the node and check for the attribute.
# Use echo all comands to find the actual name you connected the node to. This works for some but not all.
cmds.attrFieldSliderGrp(l='Far Clipping Plane Height', min=1, max=1080, at='resolutionCustom1.height')
cmds.attrFieldSliderGrp(l='Far Clipping Plane Width', min=1, max=1920, at='resolutionCustom1.width')
cmds.separator(height=10, style='none')
cmds.text(label="Near and Far Clipping Plane Controls")
# The near and far clipping planes attributes are then added to the Sliders.
cmds.attrFieldSliderGrp(l='Near Clipping Plane', min=1, max=50, at='cameraShape1.nearClipPlane')
cmds.attrFieldSliderGrp(l='Far Clipping Plane Controls', min=50, max=1200, at='cameraShape1.farClipPlane')
cmds.separator(height=10, style='none')
cmds.text(label="Create New Camera")
cmds.separator(height=5, style='none')
cmds.button(label = "Create Camera", command = "gd_CameraBox()")
cmds.showWindow(winName)
gd_cameraBox()