100% found this document useful (3 votes)
104 views71 pages

Get Maya Python for Games and Film A Complete Reference for Maya Python and the Maya Python API 1st Edition Adam Mechtley free all chapters

Maya

Uploaded by

alecosbongco
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
100% found this document useful (3 votes)
104 views71 pages

Get Maya Python for Games and Film A Complete Reference for Maya Python and the Maya Python API 1st Edition Adam Mechtley free all chapters

Maya

Uploaded by

alecosbongco
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 71

Visit https://ebookgate.

com to download the full version and


explore more ebooks

Maya Python for Games and Film A Complete Reference


for Maya Python and the Maya Python API 1st Edition
Adam Mechtley

_____ Click the link below to download _____


https://ebookgate.com/product/maya-python-for-games-
and-film-a-complete-reference-for-maya-python-and-the-
maya-python-api-1st-edition-adam-mechtley/

Explore and download more ebooks at ebookgate.com


Here are some recommended products that might interest you.
You can download now and explore!

Practical Maya Programming with Python 1st Edition


Galanakis

https://ebookgate.com/product/practical-maya-programming-with-
python-1st-edition-galanakis/

ebookgate.com

Python The Complete Manual The essential handbook for


Python users Master Python today First Edition Unknown

https://ebookgate.com/product/python-the-complete-manual-the-
essential-handbook-for-python-users-master-python-today-first-edition-
unknown/
ebookgate.com

Black hat Python Python programming for hackers and


pentesters 1st Edition Seitz

https://ebookgate.com/product/black-hat-python-python-programming-for-
hackers-and-pentesters-1st-edition-seitz/

ebookgate.com

Python for Beginners 2018 Edition Learn to Code with


Python Mark Lassoff

https://ebookgate.com/product/python-for-beginners-2018-edition-learn-
to-code-with-python-mark-lassoff/

ebookgate.com
Python Essential Reference 3rd Edition Beazley

https://ebookgate.com/product/python-essential-reference-3rd-edition-
beazley/

ebookgate.com

MEL Scripting for Maya Animators 1st Edition Mark R.


Wilkins

https://ebookgate.com/product/mel-scripting-for-maya-animators-1st-
edition-mark-r-wilkins/

ebookgate.com

Python pocket reference 5ed. Edition Mark Lutz

https://ebookgate.com/product/python-pocket-reference-5ed-edition-
mark-lutz/

ebookgate.com

Python for Finance 1st Edition Yuxing Yan

https://ebookgate.com/product/python-for-finance-1st-edition-yuxing-
yan/

ebookgate.com

Python Tricks A Buffet of Awesome Python Features Dan


Bader

https://ebookgate.com/product/python-tricks-a-buffet-of-awesome-
python-features-dan-bader/

ebookgate.com
Chapter

Maya Command Engine


1
and User Interface

CHAPTER OUTLINE
Interacting with Maya 4
Maya Embedded Language 5
Python 5
C++ Application Programming Interface 6
Python API 6
Executing Python in Maya 6
Command Line 6
Script Editor 8
Maya Shelf 10
Maya Commands and the Dependency Graph 11
Introduction to Python Commands 15
Flag Arguments and Python Core Object Types 19
Numbers 20
Strings 20
Lists 20
Tuples 21
Booleans 21
Flag = Object Type 21
Command Modes and Command Arguments 22
Create Mode 22
Edit Mode 23
Query Mode 23
Python Command Reference 24
Synopsis 25
Return Value 25
Related 25
Flags 25
Python Examples 26
Python Version 26
Python Online Documentation 26
Concluding Remarks 27
Maya Python for Games and Film. DOI: 10.1016/B978-0-12-378578-7.00001-6
© 2012 Elsevier Inc. All rights reserved. 3
4 CHAPTER 1 Maya Command Engine and User Interface

BY THE END OF THIS CHAPTER, YOU WILL BE ABLE TO:


■ Compare and contrast the four Maya programming interfaces.
■ Use the Command Line and Script Editor to execute Python commands.
■ Create a button in the Maya GUI to execute custom scripts.
■ Describe how Python interacts with Maya commands.
■ Define nodes and connections.
■ Describe Maya’s command architecture.
■ Learn how to convert MEL commands into Python.
■ Locate help for Python commands.
■ Compare and contrast command arguments and flag arguments.
■ Define the set of core Python data types that work with Maya commands.
■ Compare and contrast the three modes for using commands.
■ Identify the version of Python that Maya is using.
■ Locate important Python resources online.

To fully understand what can be done with Python in Maya, we must first
discuss how Maya has been designed. There are several ways that users
can interact with or modify Maya. The standard method is to create content
using Maya’s graphical user interface (GUI). This interaction works like any
other software application: Users press buttons or select menu items that
create or modify their documents or workspaces. Despite how similar Maya
is to other software, however, its underlying design paradigm is unique in
many ways. Maya is an open product, built from the ground up to be capable
of supporting new features designed by users. Any Maya user can modify or
add new features, which can include a drastic redesign of the main interface
or one line of code that prints the name of the selected object.
In this chapter, we will explore these topics as you begin programming in
Python. First, we briefly describe Maya’s different programming options and
how they fit into Maya’s user interface. Next, we jump into Python by exploring
different means of executing Python code in Maya. Finally, we explore some
basic Maya commands, the primary means of modifying the Maya scene.

INTERACTING WITH MAYA


Although the focus of this book is on using Python to interact with Maya,
we should briefly examine all of Maya’s programming interfaces to better
understand why Python is so unique. Autodesk has created four different
Interacting with Maya 5

Maya user interface

MEL Python C++

Maya Command Engine Maya API

Maya application core

■ FIGURE 1.1 The architecture of Maya’s programming interfaces.

programming interfaces to interact with Maya, using three different pro-


gramming languages. Anything done in Maya will use some combination
of these interfaces to create the result seen in the workspace. Figure 1.1
illustrates how these interfaces interact with Maya.

Maya Embedded Language


Maya Embedded Language (MEL) was developed for use with Maya and is
used extensively throughout the program. MEL scripts fundamentally define
and create the Maya GUI. Maya’s GUI executes MEL instructions and Maya
commands. Users can also write their own MEL scripts to perform most
common tasks. MEL is relatively easy to create, edit, and execute, but it is
also only used in Maya and has a variety of technical limitations. Namely,
MEL has no support for object-oriented programming. MEL can only com-
municate with Maya through a defined set of interfaces in the Command
Engine (or by calling Python). We will talk more about the Command
Engine later in this chapter.

Python
Python is a scripting language that was formally introduced to Maya in
version 8.5. Python can execute the same Maya commands as MEL using
Maya’s Command Engine. However, Python is also more robust than MEL
because it is an object-oriented language. Moreover, Python has existed
since 1980 and has an extensive library of built-in features as well as a
large community outside of Maya users.
6 CHAPTER 1 Maya Command Engine and User Interface

C++ Application Programming Interface


The Maya C++ application programming interface (API) is the most
flexible way to add features to Maya. Users can add new Maya objects
and features that can execute substantially faster than MEL alternatives.
However, tools developed using the C++ API must be compiled for new
versions of Maya and also for each different target platform. Because of
its compilation requirements, the C++ API cannot be used interactively
with the Maya user interface, so it can be tedious to test even small bits
of code. C++ also has a much steeper learning curve than MEL or Python.

Python API
When Autodesk introduced Python into Maya, they also created wrappers
for many of the classes in the Maya C++ API. As such, developers can use
much of the API functionality from Python. The total scope of classes acces-
sible to the Python API has grown and improved with each new version of
Maya. This powerful feature allows users to manipulate Maya API objects
in ordinary scripts, as well as to create plug-ins that add new features to Maya.
In this book, we focus on the different uses of Python in Maya, including
commands, user interfaces, and the Python API. Before we begin our
investigation, we will first look at the key tools that Maya Python program-
mers have at their disposal.

EXECUTING PYTHON IN MAYA


Maya has many tools built into its GUI that allow users to execute Python
code. Before you begin programming Python code in Maya, you should
familiarize yourself with these tools so that you know not only what tool
is best for your current task, but also where to look for feedback from your
scripts.

Command Line
The first tool of interest is the Command Line. It is located along the
bottom of the Maya GUI. You can see the Command Line highlighted in
Figure 1.2.
The Command Line should appear in the Maya GUI by default. If you
cannot see the Command Line, you can enable it from the Maya main
menu by selecting Display → UI Elements → Command Line.
The far left side of the Command Line has a toggle button, which says
“MEL” by default. If you press this button it will display “Python.”
Executing Python in Maya 7

■ FIGURE 1.2 Programming interfaces in the Maya GUI.

The language displayed on this toggle button tells Maya which scripting
language to use when executing commands entered in the text field imme-
diately to the right of the button. The right half of the Command Line, a
gray bar, displays the results of the commands that were entered in the text
field. Let’s create a polygon sphere using the Command Line.
1. Switch the Command Line button to “Python.” The button is located on
the left side of the Command Line.
2. Click on the text field in the Command Line and enter the following
line of text.
import maya.cmds;

3. Press Enter.
4. Next enter the following line of code in the text field.
maya.cmds.polySphere();

5. Press Enter. The above command will create a polygon sphere object
in the viewport and will print the following results on the right side
of the Command Line.
# Result: [u'pSphere1', u'polySphere1']
8 CHAPTER 1 Maya Command Engine and User Interface

You can use the Command Line any time you need to quickly execute a
command. The Command Line will only let you enter one line of code at
a time though, which will not do you much good if you want to write a
complicated script. To perform more complex operations, you need the
Script Editor.

Script Editor
One of the most important tools for the Maya Python programmer is the Script
Editor. The Script Editor is an interface for creating short scripts to interact
with Maya. The Script Editor (shown on the right side in Figure 1.2) consists
of two panels. The top panel is called the History Panel and the bottom panel
is called the Input Panel. Let’s open the Script Editor and execute a command
to make a sphere.
1. Open a new scene by pressing Ctrl + N.
2. Open the Script Editor using either the button located near the bottom
right corner of Maya’s GUI, on the right side of the Command Line
(highlighted in Figure 1.2), or by navigating to Window → General
Editors → Script Editor in Maya’s main menu. By default the Script
Editor displays two tabs above the Input Panel. One tab says “MEL”
and the other tab says “Python.”
3. Select the Python tab in the Script Editor.
4. Click somewhere inside the Input Panel and type the following lines of
code.
import maya.cmds;
maya.cmds.polySphere();

5. When you are finished press the Enter key on your numeric keypad. If
you do not have a numeric keypad, press Ctrl + Return.
The Enter key on the numeric keypad and the Ctrl + Return shortcut are
used only for executing code when working in the Script Editor. The reg-
ular Return key simply moves the input cursor to the next line in the Input
Panel. This convention allows you to enter scripts that contain more than
one line without executing them prematurely.
Just as in the Command Line example, the code you just executed created a
generic polygon sphere. You can see the code you executed in the History
Panel, but you do not see the same result line that you saw when using the
Command Line. In the Script Editor, you will only see a result line printed
when you execute a single line of code at a time.
6. Enter the same lines from step 4 into the Input Panel, but do not execute
them.
Executing Python in Maya 9

7. Highlight the second line with your cursor by triple-clicking it and then
press Ctrl + Return. The results from the last command entered should
now be shown in the History Panel.
# Result: [u'pSphere2', u'polySphere2']

Apart from printing results, there are two important things worth noting
about the previous step. First, highlighting a portion of code and then press-
ing Ctrl + Return will execute only the highlighted code. Second, high-
lighting code in this way before executing it prevents the contents of the
Input Panel from emptying out.
Another useful feature of the Script Editor is that it has support for marking
menus. Marking menus are powerful, context-sensitive, gesture-based
menus that appear throughout the Maya application. If you are unfamiliar
with marking menus in general, we recommend consulting any basic Maya
user’s guide.
To access the Script Editor’s marking menu, click and hold the right mouse
button (RMB) anywhere in the Script Editor window. If you have nothing
selected inside the Script Editor, the marking menu will allow you to
quickly create new tabs (for either MEL or Python) as well as navigate
between the tabs. As you can see, clicking the RMB, quickly flicking to
the left or right, and releasing the RMB allows you to rapidly switch
between your active tabs, no matter where your cursor is in the Script Edi-
tor window. However, the marking menu can also supply you with context-
sensitive operations, as in the following brief example.

1. Type the following code into the Input Panel of the Script Editor, but
do not execute it.
maya.cmds.polySphere()

2. Use the left mouse button (LMB) to highlight the word polySphere in
the Input Panel.
3. Click and hold the RMB to open the Script Editor’s marking menu. You
should see a new set of options in the bottom part of the marking menu.
4. Move your mouse over the Command Documentation option in the
bottom of the marking menu and release the RMB. Maya should
now open a web browser displaying the help documentation for the
polySphere command.

As you can see, the Script Editor is a very useful tool not only for creating
and executing Python scripts in Maya, but also for quickly pulling up infor-
mation about commands in your script. We will look at the command
documentation later in this chapter.
10 CHAPTER 1 Maya Command Engine and User Interface

At this point, it is worth mentioning that it can be very tedious to continually


type common operations into the Script Editor. While the Script Editor
does allow you to save and load scripts, you may want to make your script
part of the Maya GUI. As we indicated earlier, clicking GUI controls
in Maya simply calls commands or executes scripts that call commands.
Another tool in the Maya GUI, the Shelf, allows you to quickly make a
button out of any script.

Maya Shelf
Now that you understand how to use the Command Line and the Script
Editor, it is worth examining one final tool in the Maya GUI that will be
valuable to you. Let’s say you write a few lines of code in the Script Editor
and you want to use that series of commands later. Maya has a location for
storing custom buttons at the top of the main interface, called the Shelf,
which you can see in Figure 1.3. If you do not see the Shelf in your GUI
layout, you can enable it from Maya’s main menu using the Display →
UI Elements → Shelf option.
You can highlight lines of code in the Script Editor or Command Line and
drag them onto the Shelf for later use with the middle mouse button

■ FIGURE 1.3 The Shelf.


Maya Commands and the Dependency Graph 11

(MMB). In the following example, you will create a short script and save it
to the Shelf.
1. Type in the following code into the Script Editor, but do not execute
it (when executed, this script will create a polygon sphere and then
change the sphere’s vertex colors to red).
import maya.cmds;
maya.cmds.polySphere(radius=5);
maya.cmds.polyColorPerVertex(
colorRGB=[1,0,0],
colorDisplayOption=True
);

2. Click the Custom tab in the Shelf. You can add buttons to any shelf, but
the Custom shelf is a convenient place for users to store their own
group of buttons.
3. Click and drag the LMB over the script you typed into the Script Editor
to highlight all of its lines.
4. With your cursor positioned over the highlighted text, click and hold
the MMB to drag the contents of your script onto the Shelf.
5. If you are using Maya 2010 or an earlier version, a dialog box will
appear. If you see this dialog box, select “Python” to tell Maya that
the script you are pasting is written using Python rather than MEL.
6. You will now see a new button appear in your Custom tab. Left-click on
your new button and you should see a red sphere appear in your viewport
as in Figure 1.3. If you are in wireframe mode, make sure you enter shaded
mode by clicking anywhere in your viewport and pressing the number 5 key.
You can edit your Shelf, including tabs and icons, by accessing the
Window → Settings/Preferences → Shelf Editor option from the main
Maya window. For more information on editing your Shelf, consult the
Maya documentation or a basic Maya user’s guide. Now that you have an
understanding of the different tools available in the Maya GUI, we can start
exploring Maya commands in greater detail.

MAYA COMMANDS AND THE DEPENDENCY GRAPH


To create a polygonal sphere with Python, the polySphere command must
be executed in some way or other. The polySphere command is part of the
Maya Command Engine. As we noted previously, the Maya Command
Engine includes a set of commands accessible to both MEL and Python.
As we briefly discussed previously, Maya is fundamentally composed of a core
and a set of interfaces for communicating with that core (see Figure 1.1).
The core contains all the data in a scene and regulates all operations on these
12 CHAPTER 1 Maya Command Engine and User Interface

data—creation, destruction, editing, and so on. All of the data in the core are
represented by a set of objects called nodes and a series of connections that
establish relationships among these nodes. Taken together, this set of relation-
ships among nodes is called the Dependency Graph (DG).
For example, the polygon sphere object you created earlier returned the
names of two nodes when you created it: a node that describes the geome-
try of the sphere and a transform node that determines the configuration of
the sphere shape in space. You can see information on nodes in an object’s
network using the Attribute Editor (Window → Attribute Editor in the
main menu) or as a visual representation in the Hypergraph (Window →
Hypergraph: Connections in the main menu). Because this point is so
important, it is worth looking at a brief example.
1. If you no longer have a polygon sphere in your scene, create one.
2. With your sphere object selected, open the Hypergraph displaying
connections by using the Window → Hypergraph: Connections option
from the main menu.
3. By default, the Hypergraph should display the connections for your
currently selected sphere as in Figure 1.4. If you do not see anything,

■ FIGURE 1.4 The Hypergraph.


Maya Commands and the Dependency Graph 13

then select the option Graph → Input and Output Connections from
the Hypergraph window’s menu.
As you can see, a default polygon sphere consists of four basic nodes
connected by a sequence of arrows that show the flow of information. The
first node in the network is a polySphere node, which contains the para-
meters and functionality for outputting spherical geometry (e.g., the radius,
the number of subdivisions, and so on). In fact, if you highlight the arrow
showing the connection to the next node, a shape node, you can see what
data are being sent. In this case, the polySphere node’s output attribute is
piped into the inMesh attribute of the shape node.
If you were to delete the construction history of this polygonal sphere
(Edit → Delete by Type → History from the main menu), the polySphere
node would disappear and the sphere’s geometry would then be statically
stored in the shape node (pSphereShape1 in Figure 1.4). In short, if the
polySphere node were destroyed, its mesh information would be copied into
the pSphereShape node, and you would no longer be able to edit the radius
or number of subdivisions parametrically; you would have to use modeling
tools to do everything by hand.
While you can also see that information is piped from the shape node into a
shadingGroup node (to actually render the shape), there is a node that
appears to be floating on its own (pSphere1 in Figure 1.4). This separate
node is a special kind of object, a transform node, which describes the posi-
tion, scale, and orientation of the polygonal sphere’s geometry in space. The
reason why this node is not connected is because it belongs to a special part
of the DG, called the Directed Acyclic Graph (DAG). For right now, it suf-
fices to say that the DAG essentially describes the hierarchical relationship of
objects that have transform nodes, including what nodes are their parents
and what transformations they inherit from their parents.
The Maya DG is discussed in greater detail in Chapter 11 in the context of
the Maya API, yet this principle is critical for understanding how Maya
works. We strongly recommend consulting a Maya user guide if you feel
like you need further information in the meantime.
Although Maya is, as we pointed out, an open product, the data in the core
are closed to users at all times. Autodesk engineers may make changes
to the core from one version to another, but users may only communicate
with the application core through a defined set of interfaces that Autodesk
provides.
One such interface that can communicate with the core is the Command
Engine. In the past, Maya commands have often been conflated with
14 CHAPTER 1 Maya Command Engine and User Interface

Maya user interface

MEL Python C++

Maya Command Engine Maya API

Maya application core

■ FIGURE 1.5 Python’s interaction with the Maya Command Engine.

MEL. Indeed, commands in Maya may be issued using MEL in either


scripts or GUI elements like buttons. However, with the inclusion of
Python scripting in Maya, there are now two different ways to issue Maya
commands, which more clearly illustrates the distinction.
Figure 1.5 highlights how Python interacts with the Maya Command
Engine. While Python can use built-in commands to retrieve data from
the core, it can also call custom, user-made commands that use API inter-
faces to manipulate and retrieve data in the core. These data can then be
returned to a scripting interface via the Command Engine. This abstraction
allows users to invoke basic commands (which have complex underlying
interfaces to the core) via a scripting language.
MEL has access to over 1,000 commands that ship with Maya and has been
used to create almost all of Maya’s GUI. While Python has access to nearly
all the same commands (and could certainly also be used to create Maya’s
GUI) there is a subset of commands unavailable to Python. The commands
unavailable to Python include those specifically related to MEL or that deal
with the operating system. Because Python has a large library of utilities
that have grown over the years as the language has matured outside of
Maya, this disparity is not a limitation.
Maya has documentation for all Python commands so it is easy to look up
which commands are available. In addition to absent commands mentioned
previously, there are some MEL scripts that appear in MEL command doc-
umentation as though they were commands. Because these are scripts
rather than commands, they do not appear in the Python command
Introduction to Python Commands 15

documentation and are not directly available to Python. Again, this absence
is also not a limitation, as it is possible to execute MEL scripts with Python
when needed. Likewise, MEL can call Python commands and scripts when
required.1
Another important feature of the Maya Command Engine is how easy it is to
create commands that work for MEL and Python. Maya was designed so that
any new command added will be automatically available to both MEL and
Python. New commands can be created with the Maya C++ API or the Python
API. Now that you have a firmer understanding of how Maya commands fit
into the program’s architecture, we can go back to using some commands.

INTRODUCTION TO PYTHON COMMANDS


Let’s return to Maya and open up the Script Editor. As discussed earlier in
this chapter, the top panel of the Script Editor is called the History Panel.
This panel can be very useful for those just learning how to script or even
for advanced users who want to figure out what commands are being
executed. By default, the History Panel will echo (print) most Maya
commands being executed. You can also make the History Panel show
all commands being executed, including commands called by the GUI
when you press a button or open a menu. To see all commands being exe-
cuted, select the History → Echo All Commands option from the Script
Editor’s menu. While this option can be helpful when learning, it is gener-
ally inadvisable to leave it enabled during normal work, as it can degrade
Maya’s performance. Right now, we will go through the process of creating
a cube and look at the results in the History Panel (Figure 1.6).
1. In the menu for the Script Editor window, select Edit → Clear History
to clear the History Panel’s contents.
2. In the main Maya window, navigate to the menu option Create →
Polygon Primitives → Cube.
3. Check the History Panel in the Script Editor and confirm that you see
something like the following results.
polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
// Result: pCube1 polyCube1 //

The first line shown is the polyCube MEL command, which is very similar
to the polySphere command we used earlier in this chapter. As you can see,

1
MEL can call Python code using the python command. Python can call MEL code
using the eval function in the maya.mel module. Note that using the python command
in MEL executes statements in the namespace of the __main__ module. For more infor-
mation on namespaces and modules, see Chapter 4.
16 CHAPTER 1 Maya Command Engine and User Interface

■ FIGURE 1.6 The results of creating a polygon cube.

a MEL command was called when you selected the Cube option in the
Polygon Primitives menu. That MEL command was displayed in the
Script Editor’s History Panel.
Because Maya’s entire interface is written with MEL, the History Panel
always echoes MEL commands when using the default Maya interface.
Custom user interfaces could call the Python version of a command, in
which case the History Panel would display the Python command.
This problem is not terribly troublesome for Python users though. It does
not take much effort to convert a MEL command into Python syntax, so
this feature can still help you learn which commands to use. The following
example shows what the polyCube command looks like with Python.
import maya.cmds;
maya.cmds.polyCube(
w=1, h=1, d=1, sx=1, sy=1, sz=1,
ax=(0, 1, 0), cuv=4, ch=1
);

If you execute these lines of Python code they will produce the same result as
the MEL version. However, we need to break down the Python version of the
command so we can understand what is happening. Consider the first line:
import maya.cmds;
Introduction to Python Commands 17

This line of code imports a Python module that allows you to use any Maya
command available to Python. There is only one module that holds all
Maya commands and you only need to import it once per Maya session.
Once it is in memory you don’t need to import it again (we only have
you reimport it for each example in case you’re picking the book back
up after a break from Maya). We will discuss modules in greater depth in
Chapter 4. The next line of code is the Python command.
maya.cmds.polyCube(
w=1, h=1, d=1, sx=1, sy=1, sz=1,
ax=(0, 1, 0), cuv=4, ch=1
);

As you can see, the name of the command, polyCube, is prefixed by the
name of the module, maya.cmds. The period between them represents that
this command belongs to the Maya commands module. We then supply the
command several flag arguments inside of parentheses. A key-value pair
separated by the equals sign, such as w=1, represents the name and value
for the flag argument, and each of these pairs is separated by a comma.

Each flag may be added using a shorthand abbreviation or long version of


the flag name. Although many Maya programmers tend to use the shorthand
flag names in their code, it can make the code more difficult to read later. In
the previous example, the command is using the shorthand flags so it is hard
to understand what they mean. Here is the same version of the command
with long flag names.
maya.cmds.polyCube(
width=1,
height=1,
depth=1,
subdivisionsX=1,
subdivisionsY=1,
subdivisionsZ=1,
axis=(0, 1, 0),
createUVs=4,
constructionHistory=1
);

The long names are easier to read and so it can be good practice to use them
when scripting. Code that is easier to read can be much easier to work with—
especially if you or a coworker has to make any changes several months later!
You may now be wondering how to find the long flag names in the future.

1. Type the following lines into the Script Editor and press Ctrl + Return
to execute them.
import maya.cmds;
print(maya.cmds.help('polyCube'));
18 CHAPTER 1 Maya Command Engine and User Interface

2. Look for the results in the History Panel, which should look like the
following lines.
Synopsis: polyCube [flags] [String...]
Flags:
–e –edit
–q –query
–ax –axis Length Length Length
–cch –caching on|off
–ch –constructionHistory on|off
–cuv –createUVs Int
–d –depth Length
–h –height Length
–n –name String
–nds –nodeState Int
–o –object on|off
–sd –subdivisionsDepth Int
–sh –subdivisionsHeight Int
–sw –subdivisionsWidth Int
–sx –subdivisionsX Int
–sy –subdivisionsY Int
–sz –subdivisionsZ Int
–tx –texture Int
–w –width Length

Command Type: Command

As you can see, the result first displays the command for which help was
requested—polyCube in this case. The following items in brackets, [flags]
and [String...], show MEL syntax for executing the command. In
MEL, the command is followed by any number of flag arguments and then
any number of command arguments. We’ll differentiate these two items
momentarily.
Next, the output shows the list of flags for the command, displaying the
short name on the left, followed by the long name in the middle column.
Each flag is prefixed by a minus symbol, which is required to indicate a
flag in MEL syntax, but which you can ignore in Python. To the very right
of each flag name is the data type for each argument, which tells us what
kind of value each flag requires.
We can see how flags work with the polyCube command. Consider the
following example.
import maya.cmds;
maya.cmds.polyCube();
Executing this command causes Maya to create a polygon cube with default
properties. The parentheses at the end of the command basically indicate that
Flag Arguments and Python Core Object Types 19

we want Maya to do something—execute a command in this case. Without


them, the command will not execute. We will discuss this topic further in
Chapter 3 when we introduce functions. For now, it suffices to say that
any command arguments we wish to specify must be typed inside of the
parentheses, as in the following alternative example.
import maya.cmds;
maya.cmds.polyCube(name='myCube', depth=12.5, height=5);

If you execute the previous lines, Maya will create a polygon cube named
“myCube” with a depth of 12.5 units and a height of 5 units. The first flag
we set, name, is a string, as indicated in the help results. A string is a sequence
of letters and numbers inside of quotation marks, and is used to represent a
word or words. Immediately afterward is a comma before the next flag, depth.
We specify that the depth should be the decimal number 12.5. Such values are
listed as type Length in the help results. Last, we provided the height flag and
supplied a value of 5. In this case, we used the long names of the flags, but we
could also have used the short ones to do the same thing.
import maya.cmds;
maya.cmds.polyCube(n='myCube', d=12.5, h=5);

Looking at the help results, you can see that the axis flag takes three decimal
numbers. To specify this kind of argument in Python, we use what is called
a tuple. A tuple is basically a sequence of objects inside of parentheses, sepa-
rated by commas. The following lines show an example of the same command
using a tuple to specify a different axis.
import maya.cmds;
maya.cmds.polyCube(
name='myCube',
depth=12.5,
height=5,
axis=(1,1,0)
);

FLAG ARGUMENTS AND PYTHON CORE


OBJECT TYPES
As you have seen, most Maya Python commands have flags, which allow
you to change the default settings of the command being executed. Each flag
argument must be passed a value. A flag’s value can be one of several
different built-in Python types. Table 1.1 lists Python’s core object types
that are used by Maya commands.
Note that Table 1.1 is not a complete list of Python core object types—
there are many others that you may use for other purposes in your scripts.
20 CHAPTER 1 Maya Command Engine and User Interface

Table 1.1 Python Core Object Types Used by Maya Commands


Type Examples

Numbers 1
−5
3.14159
9.67
Strings "Maya"
'ate'
"my dog's"
"""homework"""
Lists [1, "horse", 'town']
Tuples (1, "two", 'three')
Booleans True
False
1
0

However, the core object types in this list are the only ones that Maya
commands have been designed to use, so we may ignore the others for now.
Other Python data types are discussed in Chapter 2. Let’s focus for now on
the five types in this list.

Numbers
Maya commands expecting Python numbers will accept any real number.
Examples could include integer as well as decimal numbers, which corre-
spond to int/long and float/double types, respectively, in other languages.

Strings
The string type is any sequence of letters or numbers enclosed in single quota-
tion marks, double quotation marks, or a matching pair of triple quotation
marks of either type. For instance, “boat”, “house”, and “car” are equivalent
to ‘boat’, ‘house’, and ‘car’ as well as to “““boat”””, “““house”””, and
“““car”””. However, the string “3” is different from the number object 3.
Strings are typically used to name objects or parameters that are accessible
from the Maya user interface.

Lists
A list is a sequence of any number of Python objects contained within the
bracket characters [ and ]. A comma separates each object in the list. Any
Python object may be in a list, including another list!
Flag Arguments and Python Core Object Types 21

Tuples
The Python tuple is very similar to the list type except that it is not muta-
ble, which means it cannot be changed. We discuss mutability in greater
detail in Chapter 2. Tuples are contained inside of ordinary parentheses,
( and ).

Booleans
A Boolean value in Python can be the word True or False (which must
have the first letter capitalized), or the numbers 1 and 0 (which correspond
to the values True and False, respectively). These values are typically used
to represent states or toggle certain command modes or flags.

Flag = Object Type


To find out what type of object a command flag requires, you can use the
help command. As you saw earlier in this chapter it will give you a list of
the command flags and what type of value they require. The argument type
is not an option—you must pass a value of the required type or you will get
an error. Using the polyCube command as an example, let’s look at its
width flag and pass it correct and incorrect argument types.

1. Create a new scene by pressing Ctrl + N.


2. Execute the Maya help command for the polyCube command in the
Script Editor:
import maya.cmds;
print(maya.cmds.help('polyCube'));

3. Look for the width flag in the results displayed in the History Panel
and find its argument type on the right side:
–w –width Length

As you can see, the width flag requires a Length type argument, as shown
to the right of the flag name. This is technically not a Python type but we
can deduce that Length means a number, so we should pass this flag some
sort of number. If the number needed to be a whole number, the flag would
specify Int to the right of the flag instead of Length. We can therefore also
deduce that the flag may be passed a decimal number in this case. Let’s
first pass a correct argument.
4. Type the following command into the Script Editor and press Ctrl +
Return to execute it.
maya.cmds.polyCube(width=10);
22 CHAPTER 1 Maya Command Engine and User Interface

You should see the following result in the Script Editor’s History Panel.
# Result: [u'pCube1', u'polyCube1'] #

The result lets us know that the command succeeded and also shows that the
command returned a Python list containing the names of two new nodes that
have been created to make our cube object: “pCube1” (a transform node)
and “polyCube1” (a shape node). Now, let’s see what happens when we inten-
tionally supply the width flag with the wrong data type.
5. Type the following command into the Script Editor and press Ctrl +
Return to execute it.
maya.cmds.polyCube(width='ten');

This time the command returns an error.


# Error: TypeError: file <maya console> line 1: Invalid
arguments for flag 'width'. Expected distance, got str #

The error tells you that the argument for the width flag was incorrect and it
expected a distance value. Even though the help command showed the
width flag needed a Length type, Maya is now calling it a distance type.
This can be confusing at first but most of the time it is very clear what
the flag argument requires simply by looking at the flag in context. The
help command does not describe what each flag does, but you can get
more detailed descriptions using the Python Command Reference, which
we will examine shortly.

COMMAND MODES AND COMMAND ARGUMENTS


Maya commands often have more than one mode in which they can work.
Some commands may be available to use in create mode, edit mode, and/or
query mode, while certain flags may only be available in certain modes.

Create Mode
Most commands at least have a create mode. This mode allows users to
create new objects in the scene and specify any optional parameters. By
default, the polyCube command operates in create mode.
1. Create a new Maya scene.
2. Execute the following lines in the Script Editor to create a new cube.
import maya.cmds;
maya.cmds.polyCube();

Note that you do not have to do anything special to execute commands in


create mode. Leave the cube in your scene for the next steps.
Command Modes and Command Arguments 23

Edit Mode
Another mode that many commands support is edit mode. This mode
allows users to edit something the command has created.
3. Execute the following line in the Script Editor to change the cube’s
width.
maya.cmds.polyCube('pCube1', edit=True, width=10);

As you can see, you specified that the command should operate in edit
mode by setting the edit flag with a value of True. In edit mode, you were
able to change the width of the object named “pCube1” to a value of 10. It
is worth mentioning that some flags in MEL do not require an argument,
such as the edit flag (see help output previously). Such flags, when
invoked from Python, simply require that you set some value (True) to
indicate their presence.
Another important point worth noting is the syntax for operating in edit and
query modes. The first argument we pass to the command is called a
command argument, and specifies the name of the node on which to operate.
As we saw in the help output previously, MEL syntax expects command
arguments to follow flag arguments, while Python requires the opposite
order. The reason for Python’s syntax requirement will be discussed in
greater detail in Chapter 3. Leave the cube in the scene for the next step.

Query Mode
The last mode that many commands support is query mode. This mode
permits users to request information about something the command has
already created.
4. Execute the following line in the Script Editor to print the cube’s width.
maya.cmds.polyCube('pCube1', query=True, width=True);

The result in the History Panel should display something like the
following line.
# Result: 10.0 #

As with edit mode, query mode requires that you specify a command argu-
ment first and then set the query flag with a value of True. Another point
worth noting is that, although the width flag normally requires a decimal
number (when being invoked from create or edit mode), you simply pass
it a value of True in query mode. The basic idea is that in this case, the
Command Engine is only interested in whether or not the flag has been
set, and so it will not validate the value you are passing it.
24 CHAPTER 1 Maya Command Engine and User Interface

As you can see, these three modes allowed you to create an object, change
it, and finally pull up information about its current state. We also noted at
the outset of this section that some flags are only compatible with certain
command modes. While the help command will not give you this informa-
tion, the Command Reference documentation will.

PYTHON COMMAND REFERENCE


Another place you can get more help on a command is from the Maya help
documents. These documents detail every Python command available. The
Python Command Reference is shown in Figure 1.7. Let’s browse the Python
Command Reference to find more information on the polyCube command.
1. In the main Maya window select the menu item Help → Python Com-
mand Reference.
2. At the top of the page is a text field. Click in the search field and enter
the word polyCube.
3. The page will update to show you only the polyCube command. Select the
polyCube command from the list under the label “Substring: polyCube”.
Clicking this link will show you detailed information for the polyCube

■ FIGURE 1.7 Python Command Reference.


Python Command Reference 25

command. As you can see, the Command Reference documents break up


information for all commands into different sections, which we will
now look at in more detail.

Synopsis
The synopsis provides a short description of what the command does. In
this case the synopsis states:
polyCube is undoable, queryable, and editable.
The cube command creates a new polygonal cube.

Return Value
The return value section describes what the command will return when it is
executed. In this case the documentation states:
string[] Object name and node name.
This description shows us that it returns a list of string type objects, which
will be the name of the object (transform node) and the (polyCube) node
that were created.

Related
This section can help you with finding commands that are similar to the
command at which you are looking. For the polyCube command, this
section lists other commands for creating primitive polygon objects:
polyCone, polyCylinder, polyPlane, polySphere, polyTorus

Flags
For the polyCube command, the axis flag is listed first. It shows a short
description of what the flag does and then it lists the argument type to pass
to it. The documentation shows the following text:
[linear, linear, linear]
The command requires a Python list (or tuple) type and that list should hold
three real numbers. If int is not specified for an argument type, then the argu-
ment may be a decimal number, though integer numbers are still valid. In
this case, if we were to define the argument for the flag it could be something
like [1.00, 0, 0].
As we noted earlier, the documentation also displays icons to represent the
command mode(s) with which each flag is compatible.
26 CHAPTER 1 Maya Command Engine and User Interface

■ C (Create): The flag can appear in the create mode.


■ E (Edit): The flag can appear in the edit mode.
■ Q (Query): The flag can appear in the query mode.
■ M (Multiuse): The flag can be used multiple times.
In MEL, multiuse flags are invoked by appending them multiple times after a
command. In Python, however, you can only specify a flag once. As such,
Python requires that you pass a tuple or list argument for a multiuse flag,
where each element in the tuple or list represents a separate use of the flag.

Python Examples
This section can be very useful for those just learning how to script with
Python or those learning how to work with Maya using Python. Here
you can find working examples of the command in use. Some example
sections can have several different samples to help you understand how
the command works. The example for the polyCube command in the docu-
ments shows you how to create a polygon cube and also how to query an
existing cube’s width.

PYTHON VERSION
One final point that is worth discussing is how to locate which version of
Python your copy of Maya is using. Python has been integrated into Maya
since version 8.5, and each new version of Maya typically integrates the
newest stable version of Python as well. Since newer versions of Python
will have new features, you may want to investigate them. First, find out
what version of Python your version of Maya is using.
1. Open up the Script Editor and execute the following lines.
import sys;
print(sys.version);

You should see a result print in the Script Editor’s History Panel that looks
something like the following lines.
2.6.4 (r264:75706, Nov 3 2009, 11:26:40)
[GCC 4.0.1 (Apple Inc. build 5493)]

In this example, our copy of Maya is running Python version 2.6.4.

PYTHON ONLINE DOCUMENTATION


Once you know what version of Python you are running, you can look up
the Python documentation online. The Python web site is located at
Concluding Remarks 27

http://www.python.org/. If you navigate to the Documentation section,


you should see documentation for multiple versions of Python.
As you learn to program using Python you might also be interested in down-
loading Python for your operating system if it does not already include it.
You can find the latest versions of Python at the Python web site. If you plan
to write Python scripts that interact with Maya, it is advisable that you install
the same version that Maya is using. For the most part, many versions of
Python that you will see in Maya are almost identical. However, a newer
version of Python, 3.x, may break a few things that work in older versions.
If you choose to install Python for your operating system, you will be able
to use a Python interpreter, such as the Python IDLE, which acts just like
the Maya Script Editor but for your operating system. This can be useful
for creating tools outside of Maya that communicate with Maya using
Python. Moreover, you could write tools using Python that have nothing
to do with Maya, yet may be helpful for your project’s organization or
interaction with other software like MotionBuilder.

CONCLUDING REMARKS
In this chapter you have learned how Maya commands and Python work
within Maya’s architecture. We have introduced a few methods of entering
Maya commands with Python to modify Maya scenes. We have also
explained how to look up help and read the Python Command Reference doc-
umentation and how to find information about your version of Python. In the
chapters that immediately follow, we will further explain some of the underly-
ing mechanics and syntax of Python and then start creating more complicated
scripts to use in Maya.
Chapter
2
Python Data Basics

CHAPTER OUTLINE
Variables and Data 30
Variables in MEL 33
Keywords 33
Python’s Data Model 34
Mutability 35
Reference Counting 36
del() 37
The None Type 37
Using Variables with Maya Commands 37
Capturing Results 39
getAttr and setAttr 40
Compound Attributes 40
connectAttr and disconnectAttr 41
Working with Numbers 43
Number Types 43
Basic Operators 44
Working with Booleans 45
Boolean and Bitwise Operators 45
Working with Sequence Types 46
Operators 46
Concatenation 47
Indexing and Slicing 47
String Types 50
Escape Sequences and Multiline Strings 50
Raw Strings 51
Unicode Strings 51
Formatting Strings 52
More on Lists 53
del() 54
Nested Lists 54
Other Container Types 56
Sets 57
Operators 57
Dictionaries 58
Operators 59
Dictionaries in Practice 60
Concluding Remarks 62
Maya Python for Games and Film. DOI: 10.1016/B978-0-12-378578-7.00002-8
© 2012 Elsevier Inc. All rights reserved. 29
30 CHAPTER 2 Python Data Basics

BY THE END OF THIS CHAPTER, YOU WILL BE ABLE TO:


■ Define and manipulate data in variables.
■ Compare and contrast Python’s and MEL’s typing systems.
■ Recast variables as different data types.
■ Prevent naming conflicts with built-in keywords.
■ Explain how Python manages memory.
■ Compare and contrast mutable and immutable types.
■ Use variables in conjunction with commands to manipulate attributes.
■ Describe the different numeric types in Python.
■ Use mathematical operators with numeric types.
■ Use logical and bitwise operators with Boolean variables.
■ Use common operators with sequence types.
■ Manipulate nested lists.
■ Create Unicode and raw strings.
■ Format strings that contain variable values.
■ Compare and contrast sets and dictionaries with sequence types.

In Chapter 1, we covered executing commands in Maya using Python. To do


anything interesting, however, we need more tools to create programs. In this
chapter we will explore some of the basics for working with variables in
Python. Because much of this information is available in the online Python
documentation, we will not belabor it a great deal. However, because we
make use of certain techniques throughout the text, it is critical that you have
an overview here.
We begin by discussing variables in the context of the data types you learned
in Chapter 1, and show how you can use variables along with some basic
Maya commands. Thereafter, we discuss some more interesting properties
of the basic sequence types we discussed in Chapter 1. Finally, we discuss
two additional, useful container types.

VARIABLES AND DATA


The basic unit of data storage in any programming language is a variable.
A variable is a name that points to some specific data type. The mechanism
for creating a variable in Python is the assignment operator (=). Because
Python does not require (or allow) declaration without an assignment,
Variables and Data 31

creating a variable is as simple as separating a name and a value with the


assignment operator.
1. Execute the following line in a Python tab in the Script Editor, or from
the Command Line. This line simply creates a variable named contents,
and assigns a string value to it.
contents = 'toys';

2. Once you create this variable, you can substitute in this name anywhere
you would like this value to appear. Execute the following line of code.
You should see the string “toys in the box” print on the next line.
print(contents+' in the box');

3. You can change the value assigned to this variable at any time, which
will substitute in the new value anywhere the name appears. Execute
the following lines of code, which should print “shoes in the box” in
the History Panel.
contents = 'shoes';
print(contents+' in the box');

4. You can also assign completely different types of values to the variable.
Execute the following line of code.
contents = 6;
Python is what is called a strong, dynamically typed language. The line of
code in step 4 demonstrates dynamic typing. You are able to change the type
of any Python variable on-the-fly, simply by changing its assignment value.
However, because it is strongly typed, you cannot simply add this new value
to a string.
5. Try to execute the following statement.
print('there are '+contents+' things in the box');
The console should supply an error message like the following one.
# Error: TypeError: file <maya console> line 1: cannot
concatenate 'str' and 'int' objects #

Because Python is strongly typed, you cannot so easily intermix different


types of variables. However, you can now perform addition with another
number.
6. Execute the following line of code, which should print the number 16.
print(contents+10);

In Python, to intermix types, you must explicitly recast variables as the


expected type.
32 CHAPTER 2 Python Data Basics

7. Execute the following line in Python to cast the number stored in


contents to its string representation. You should see “there are 6
things in the box” in the History Panel.

print('there are '+str(contents)+' things in the box');

In this case, we called the str() function to recast contents as a string. We


discuss functions in greater detail in Chapter 3. Table 2.1 lists some other
built-in functions for recasting variables.
Python provides a built-in function, type(), which allows you to determine
the type of a variable at any point.
8. Execute the following line to confirm the type of the contents variable.
type(contents);

You should see the following line in the History Panel, which indicates
that the variable is currently pointing to an integer.

# Result: <type 'int'> #

As you can see, casting the variable to a string as you did in step 7 did not
change its inherent type, but only converted the value we retrieved from the
variable. As such, you would still be able to add and subtract to and from
this variable as a number. You could also reassign a string representation to
it by assigning the recast value.
9. Execute the following lines to convert the variable to a string.
contents = str(contents);
print(type(contents));

You should see the following output in the History Panel.

<type 'str'>

Table 2.1 Python Functions for Recasting Variable Types


Function Casts To Notes

float() Decimal number If argument is string, raises ValueError if not properly formatted
int() Integer number If argument is string, raises ValueError if not properly formatted
If argument is decimal number, result is truncated toward 0
Allows optional argument to specify non-base 10
str() String
unicode() Unicode string Allows optional argument to specify encoding
Variables and Data 33

Variables in MEL
Variables in Python are incredibly flexible. Compare the previous example
with a comparable MEL snippet.
1. Enter the following lines in a MEL tab in the Script Editor. You should
again see the output “toys in the box” in the History Panel.
$contents = "toys";
print($contents+" in the box");

While MEL allows—but does not require—that you explicitly provide the
variable’s type, the variable $contents is statically typed at this point. It is
a string, and so cannot now become a number. Those unfamiliar with MEL
should also note that it requires variable names to be prefixed with a dollar
sign ($).
2. Execute the following lines in MEL.
$contents = 6;
print("there are "+$contents+" things in the box");

Because you get the output you expect (“there are 6 things in the box”), you
may think that MEL has implicitly handled a conversion in the print call. How-
ever, the number 6 stored in $contents is not in fact a number, but is a string.
You can confirm this fact by trying to perform addition with another number.
3. Execute the following line in MEL.
print($contents+10);

Whereas the Python example printed the number 16 in this case, MEL has
printed 610! In MEL, because the type of the variable cannot change, MEL
implicitly assumed that the number 10 following the addition operator (+)
was to be converted to a string, and the two were to be concatenated. While sea-
soned MEL developers should be well aware of this phenomenon, readers who
are new to Maya will benefit from understanding this difference between MEL
and Python, as you may occasionally need or want to call statements in MEL.
On the other hand, all readers who are as yet unfamiliar with Python would
do well to remember that variable types could change on-the-fly. This
feature offers you a great deal of flexibility, but can also cause problems
if you’re frequently reusing vague, unimaginative variable names.

Keywords
Apart from issues that may arise from vague variable names, Python users
have some further restrictions on names available for use. Like any other
language, Python has a set of built-in keywords that have special meanings.
34 CHAPTER 2 Python Data Basics

You saw one of these keywords—import—in Chapter 1. To see a list of


reserved keywords, you can execute the following lines in a Python tab
in the Script Editor.

import keyword;
for kw in keyword.kwlist: print(kw);

The list of reserved keywords printed out are used for various purposes,
including defining new types of objects and controlling program flow.
We will be covering a number of these keywords throughout the text, but
it is always a good idea to refer to the Python documentation if you would
like more information. The important point right now is that these words all
have special meanings, and you cannot give any of these names to your
variables.

Python’s Data Model


It is now worth highlighting a few points about Python’s data model, as it
has some bearing on other topics in this chapter (as well as many topics we
discuss later in this book). Although we must be brief, we recommend
consulting Section 3.1 of Python Language Reference online if you are
interested in more information.
To maximize efficiency, statically typed languages allocate a specific
amount of memory for different types of variables. Because this amount
of memory is specified in advance, you cannot simply assign a new
type to a name at some later point. On the other hand, as you have
seen in this chapter, Python lets you change the type of a variable at
any point. However, the underlying mechanisms are actually somewhat
subtler.
In Python, variables are just names that point to data. All data are objects,
and each object has an identity, a type, and a value.
■ An object’s identity describes its address in memory.
■ An object’s type (which is itself an object) describes the data type it
references.
■ An object’s value describes the actual contents of its data.
While we will discuss objects in greater detail in Chapter 5, programmers
coming from other languages may find this principle novel.
When you create a new variable and assign it a value, your variable is
simply a name pointing to an object with these three properties: an identity,
Variables and Data 35

a type, and a value.1 Consider a situation where you cast an integer to a


string, such as the following lines.
var = 5;
var = str(var);

In this case, you are not actually altering the data’s underlying type, but are
pointing to some different piece of data altogether. You can confirm this
fact by using the built-in id() function, which provides the address to the
data. For instance, printing the identity at different points in the following
short sample will show you different addresses when the variable is an inte-
ger and when it is a string.
var = 5;
print('int id',id(var));
var = str(var);
print('str id',id(var));

Mutability
In Python, objects can be either mutable or immutable. Briefly construed,
mutable objects can have their values changed (mutated), while immutable
objects cannot.2 We briefly mentioned this concept in Chapter 1 when com-
paring lists and tuples.
In fact, tuples, strings, and numbers are all immutable. As a consequence,
when you assign a new integer value to a variable, instead of changing
the underlying value of the object to which the variable is pointing, the
variable instead points to another piece of data. You can see the effects
of this concept in the following short code example, which will print the
identity for the variable after different integer assignments.
var = 5;
print('5 id',id(var));
var = 6;
print('6 id',id(var));

1
C++ programmers should note that although Python variables are references to data, they
cannot simply be used like pointers. To shoehorn Python into the language of C++, it
always passes parameters by value, but the value of a variable in Python is a reference.
The consequence is that reassigning a variable inside of a function has no effect on its
value outside the function. Chapter 9 discusses these consequences of Python’s data
model in Maya’s API.
2
Immutable containers that reference mutable objects can have their values changed if the
value of one of the mutable objects in the container changes. These containers are still
considered immutable, however, because identities to which they refer do not change.
See the “Nested Lists” section in this chapter for more information.
36 CHAPTER 2 Python Data Basics

Variables Data objects


type: int
value: 10

■ FIGURE 2.1 Two variables may point to the same object.

We examine the effects of mutability on sequence types later in this


chapter.

Reference Counting
As part of its data model, Python uses a system known as reference count-
ing to manage its memory. The basic idea is that rather than requiring
developers to manually allocate and deallocate memory, data are garbage
collected when there are no more names referencing them.
An interesting side effect of this paradigm is that two immutable variables
with the same assignment (e.g., data with the same type and value) may in
fact be pointing to the same data in memory (Figure 2.1). You can see this
principle in action by assigning the same numeric value to two different
variables and printing their identities.
v1 = 10;
v2 = 10;
print('v1 id', id(v1));
print('v2 id', id(v2));

In this case, both v1 and v2 are pointing to the same piece of data. If these
two variables are assigned different data (e.g., some other number, a string,
etc.), then the reference count for their previous data (the integer 10) drops
to zero. When the reference count for objects drops to zero, Python nor-
mally automatically garbage collects the data to free up memory as needed.
Although this concept has only a few consequences for our current discus-
sion, it becomes more important in later chapters as we discuss modules,
classes, and using the API.
It is important to note that while variables pointing to data with an immu-
table type may show this behavior, two separate assignments to mutable
objects with the same type and value are always guaranteed to be different.
For example, even though the following lists contain the same items, they
will be guaranteed to have unique identities.
Using Variables with Maya Commands 37

list1 = [1, 2, 3];


list2 = [1, 2, 3];
print('list1 id', id(list1));
print('list2 id', id(list2));

The assignment of one variable to another variable pointing to a mutable


object, however, results in both pointing to the same data.
list1 = [1, 2, 3];
list2 = list1;
print('list1 id', id(list1));
print('list2 id', id(list2));

This concept has important consequences that we will cover later.

del()
Python has a built-in function, del(), which allows you to delete variables.
Note that this process is not the same as deleting the data referenced by the
variable: Python’s garbage collector will still manage those data. Using this
function with a variable name simply clears the name (and thus eliminates a
reference to its data). The following example illustrates that, even though
v1 and v2 will reference the same data, deleting v1 has no effect on v2.
Trying to access v1 after this point would result in a NameError.
v1 = 5;
v2 = 5;
del(v1);
print(v2);

The None Type


Because we use it throughout the text in some cases, it is worth noting that,
because of how Python’s variables work, Python also implements a None type.
var = None;

One use of this type is to initialize a name without wastefully allocating


memory if it is unnecessary. For instance, many of our API examples in
this text use the None type to declare names for class objects whose values
are initialized elsewhere. We will talk more about class objects starting in
Chapter 5.

USING VARIABLES WITH MAYA COMMANDS


As we noted in Chapter 1, a Maya scene is fundamentally composed of
nodes and connections. Each node has a number of different attributes, such
as the radius of a polySphere, the height of a polyCube, or the maximum
38 CHAPTER 2 Python Data Basics

number of influences in a skinCluster. Although we will talk about


attributes in much greater detail when we introduce the API in later chapters,
it suffices for now to say that they describe the actual data housed in a node.
You have already seen some multimodal, built-in commands designed to
work with different node types. For example, the polySphere command
not only creates nodes for a polygon sphere, but also allows you to query
and edit polySphere nodes. You can use these commands along with
variables very easily. Let’s work through a quick example.
1. Create a new Maya scene and execute the following lines in the Script
Editor.
import maya.cmds;
sphereNodes = maya.cmds.polySphere();

Recall that the results of the polySphere command return a list of object
names (a transform node and a shape node). You can store this result in
a variable when you create a cube. The sphereNodes list now contains
the names of the two objects that were created. If you were to print this list,
you would see something like the following line.
[u'pSphere1', u'polySphere1']

Note that this list does not contain the Maya nodes themselves, but simply
contains their names. For example, using the del() function on this list
would not actually delete Maya nodes, but would simply delete a list with
two strings in it.
2. We will discuss this syntax later in this chapter, but you can use square
bracket characters to access items in this list. For example, you can store
the name of the polySphere node (“polySphere1”) in another variable.
sphereShape = sphereNodes[1];

3. Now that you have stored the name of the shape in a variable, you can
use the variable in conjunction with the polySphere command to query
and edit values. For example, the following lines will store the sphere’s
radius in a variable, and then multiply the sphere’s radius by 2. Remem-
ber that in each flag argument, the first name is the flag, and the second
name is the value for the flag.
rad = maya.cmds.polySphere(
sphereShape, q=True, radius=True
);
maya.cmds.polySphere(sphereShape, e=True, radius=rad*2);

4. You could now reread the radius attribute from the sphere and store it
in a variable to create a cube the same size as your sphere.
Using Variables with Maya Commands 39

rad = maya.cmds.polySphere(
sphereShape, q=True, radius=True
);
maya.cmds.polyCube(
width=rad*2,
height=rad*2,
depth=rad*2
);

Hopefully you see just how easy it is to use variables in conjunction with
Maya commands.

Capturing Results
In practice, it is critical that you always capture the results of your commands
in variables rather than making assumptions about the current state of your
nodes’ attributes. For example, Maya will sometimes perform validation
on your data, such as automatically renaming nodes to avoid conflicts.
Some Maya users may insist that this behavior makes certain tools impos-
sible without advanced, object-oriented programming techniques. In reality,
you simply need to take care that you use variables to store your com-
mands’ results, and do not simply insert literal values—especially object
names—into your code. The following example illustrates this point.
1. Create a new Maya scene and execute the following lines in the Script
Editor. This code will create a sphere named “head.”
import maya.cmds;
maya.cmds.polySphere(name='head');

2. Now execute the following line to try to make a cube with the same name.
maya.cmds.polyCube(name='head');

If you actually look at your cube in the scene, you can see that Maya has
automatically renamed it to “head1” so it will not conflict with the name
you gave the sphere. However, if you were writing a standalone tool that
creates objects with specific names and then tries to use those specific
names, your artists may run into problems if they already have objects in
the scene with conflicting names.
3. Try to execute the following line, and you will get an error.
maya.cmds.polyCube('head', q=True, height=True);

Always remember that Maya commands work with nodes and attributes on
the basis of their names, which are simply strings. When using ordinary
Maya commands, you should always capture the results of your commands
40 CHAPTER 2 Python Data Basics

since there is no default mechanism for maintaining a reference to a specific


node. In Chapter 5 we will see how the pymel module provides an alterna-
tive solution to this problem.

getAttr and setAttr


While there are many commands that pair with common node types, not all
nodes have such commands (and sometimes not all attributes have flags).
It may also become tedious to memorize and use commands with modes,
flags, and so on. Fortunately, Maya provides two universal commands for
getting and setting attribute values that will work with any nodes: getAttr
and setAttr. We’ll demonstrate a quick example.
1. Open a new Maya scene and execute the following lines of code. These
lines will create a new locator and store the name of its transform node
in a variable called loc.
import maya.cmds;
loc = maya.cmds.spaceLocator()[0];

2. Execute the following lines to store the locator’s x-scale in a variable


and print the result, which will be 1 by default.
sx = maya.cmds.getAttr(loc+'.scaleX');
print(sx);

The getAttr command allows you to get the value of any attribute on any
node by simply passing in a string with the node’s name, a period, and the
attribute name. We’ll talk more about working with strings shortly, but the
complete string that we passed to the getAttr command was actually “loca-
tor1.scaleX” in this case.
3. Execute the following lines to double the sx value and assign the new
value to the node’s attribute.
sx *= 2;
maya.cmds.setAttr(loc+'.scaleX', sx);

The setAttr command works just like the getAttr command, and allows
you to set any attribute value on any node by passing a string with the
node’s name, a period, and the attribute name.

Compound Attributes
Many attributes will simply be a string, a Boolean, or a number value.
However, some attributes are called compound attributes, and may contain
several values. It is important to note that these attribute types work differ-
ently with the getAttr and setAttr commands compared to other built-in
commands.
Using Variables with Maya Commands 41

The reason for this difference is that the getAttr and setAttr commands do
not know what data type the particular attribute expects or contains until they
look it up by name. Other commands only work with specific attributes on
specific nodes, and so can work in a more straightforward way, as you will
see in the remainder of this example.
4. In the scene you created in the previous steps, execute the following
line to print the locator’s translation using the xform command.
print(maya.cmds.xform(loc, q=True, translation=True));

As you would expect the result is simply a list: [0.0, 0.0, 0.0].
5. Likewise, when using the xform command, you can set a new translation
value using a list, as in the following line.
maya.cmds.xform(loc, translation=[0,1,0]);

The xform command can work in this way because it is designed to work
exclusively with transform nodes, and the command internally knows
about the data type for the appropriate attribute. On the other hand,
getAttr and setAttr are not so straightforward.

6. Execute the following line to print the locator’s translation using the
getAttr command.

print(maya.cmds.getAttr(loc+'.translate'));

As you can see from the output, the command returns a list that contains
a tuple: [(0.0, 1.0, 0.0)].
7. Using setAttr for a compound attribute also uses a different paradigm.
Execute the following line to set a new translation value for the locator.
maya.cmds.setAttr(loc+'.translate', 1, 2, 3);

As you can see, setting a compound attribute like translation using setAttr
requires that you specify each value in order (x, y, z in this case).

connectAttr and disconnectAttr


The mechanism for transforming data in the Maya scene is to connect
attributes: an output of one node connects to some input on another node.
For instance, you saw in Chapter 1 how the output attribute of a polySphere
node is connected to the inMesh attribute of a shape node when you execute
the polySphere command. While Chapter 1 showed how you can delete
the construction history of an object to consolidate its node network, the
connectAttr and disconnectAttr commands allow you to reroute con-
nections in altogether new ways.
The basic requirement for attributes to be connected is that they be of the same
type. For example, you cannot connect a string attribute to a decimal number
42 CHAPTER 2 Python Data Basics

attribute. However, Maya does perform some built-in conversions for you
automatically, such as converting angle values into decimal numbers. The finer
distinctions between these types of values will be clearer when we discuss the
API later in this book. In the following short example, you will create a basic
connection to control one object’s translation with another object’s rotation.
1. Open a new Maya scene and execute the following lines to create a
sphere and a cube and store the names of their transform nodes.
import maya.cmds;
sphere = maya.cmds.polySphere()[0];
cube = maya.cmds.polyCube()[0];

2. Execute the following lines to connect the cube’s y-rotation to the


sphere’s y-translation.
maya.cmds.connectAttr(cube+'.ry', sphere+'.ty');
maya.cmds.select(cube);

Use the Rotate tool (E) to rotate the cube around its y-axis and observe the
behavior. The result is very dramatic! Because you are mapping a rotation
in degrees to a linear translation, small rotations of the cube result in large
translations in the sphere.
It is also worth mentioning that the connection is only one way. You cannot
translate the sphere to rotate the cube. In Maya, without some very compli-
cated hacks, connections can only flow in one direction. Note, too, that an
output attribute can be connected to as many inputs as you like, but an
input attribute can only have a single incoming connection.
3. Execute the following line to disconnect the two attributes you just
connected.
maya.cmds.disconnectAttr(cube+'.ry', sphere+'.ty');

The disconnectAttr command works very similarly to the connectAttr


command. It simply expects two strings that name the nodes and their attributes.
4. Execute the following lines to create a multiplyDivide node between
the two attributes to scale the effect.
mult = maya.cmds.createNode('multiplyDivide');
maya.cmds.connectAttr(cube+'.ry', mult+'.input1X');
maya.cmds.setAttr(mult+'.input2X', 1.0/90.0);
maya.cmds.connectAttr(mult+'.outputX', sphere+'.ty');
maya.cmds.select(cube);

Now if you rotate the cube, the sphere translates 1 unit for every 90 degrees
of rotation.
Working with Numbers 43

WORKING WITH NUMBERS


In Chapter 1, we introduced some basic object types with which Maya
commands have been designed to work. Although we lumped numbers
together generally, they are actually decomposable into more specific types.
Because you may want to take advantage of these specific types’ features,
and because you may encounter them when testing the types of your
variables, it is worth briefly discussing them.

Number Types
Although you can often intermix different types of numbers in Python,
there are four types of numbers: integers, long integers, floating-point num-
bers, and complex numbers. We briefly cover them here, but you can read
more about these different types in Section 5.4 of Python Standard Library.
As you saw in the beginning of this chapter, an integer is simply a whole
(nonfractional) number. Integers can be positive or negative. The type of
an integer in Python is given as int, as the following code illustrates.
var = -5;
print(type(var));

A long integer differs from an integer only in that it occupies more space in
memory. In many cases, ordinary integers suffice and are more efficient, but
long integers may be useful for computation that deals with large numbers.
In a language like C or C++, a long integer occupies twice as many bits in
memory as an ordinary integer. In Python, a long integer can occupy as
much memory as you require. To create a long integer, you can simply
assign a really long value to your variable and it will become a long integer
automatically, or you can suffix the value with the character l or L. The type
in Python is given as long.
var = -5L;
print(type(var));

Floating-point numbers are any numbers, positive or negative, with digits


after a decimal point. You can explicitly indicate that a whole number value
is to be a floating-point number by adding a decimal point after it. The type
of a floating-point number is float.
var = -5.0;
print(type(var));

Finally, Python allows you to use complex numbers, which consist of both a
real and an imaginary component. It is highly unlikely that you will need to
work with complex numbers regularly. You can create a complex number by
44 CHAPTER 2 Python Data Basics

suffixing the imaginary part with the character j or J. The type is given as
complex.
var = -5+2j;
print(type(var));

You can also access the individual real and imaginary parts of complex
numbers using the real and imag attributes.
print(var.real, var.imag);

Basic Operators
Once you start creating variables, you will want to do things with them.
Operators are special symbols you can include in your code to perform spe-
cial functions. (Note that we also include some related built-in functions and
object methods in our tables.) Section 5 of Python Standard Library includes
information on various operators, and Section 3.4 of Python Language
Reference contains information on overloading operators, which allows
you to assign special functionality to these symbols. Here, we briefly review
some of the basic operators for working with numeric values.
Thus far, you’ve seen some of the basic math operators, such as + for addition
and – for subtraction or negation. Section 5.4 in Python Standard Library con-
tains a table of Python’s built-in operators for working with numeric types.
In Table 2.2 we have recreated the parts of this table containing the most
common operators.
Note that many of these operators also allow in-place operations when used
in conjunction with the assignment operator (=). For example, the following

Table 2.2 Important Numeric Operators


Operation Result Notes

x+y Sum of x and y


x−y Difference of x and y
x*y Product of x and y
x/y Quotient of x and y If x and y are integers, result is
rounded down
x // y Floored quotient of x and y Use with floating-point numbers
to return a decimal result identical
to x/y if x and y were integers
x%y Remainder of x / y
divmod(x, y) Tuple that is (x // y, x % y)
pow(x, y) x to the y power
x ** y x to the y power
Working with Booleans 45

lines create a variable, v1, with a value of 2, and then subtracts 4 from the
same variable, resulting in −2.
v1 = 2;
v1 -= 4;
print(v1);

Note that Python does not support incremental operators such as ++ and −−.
For those readers who are new to programming, it is important to point out
how division works with integer numbers. Remember that integers are
whole numbers. Consequently, the result is always rounded down. The fol-
lowing floating-point division results in 0.5.
1.0/2.0;

The following integer division results in 0.


1/2;

On the other hand, the following integer division results in −1.


-1/2;

You can also mix an integer and a floating-point number, in which case
both are treated as floats. The following division results in 0.5.
1.0/2;

It is also worth mentioning, for those unacquainted with the finer points of
computer arithmetic, that floating-point operations often result in minor
precision errors as a consequence of how they are represented internally.
It is not uncommon to see an infinitesimally small number where you might
actually expect zero. These numbers are given in scientific notation, such as
the following example.
-1.20552649145e-10

WORKING WITH BOOLEANS


Another basic type that is used with Maya commands is the Boolean type
(called bool in Python). Recall that in practice, Boolean values True and False
are interchangeable with 1 and 0, respectively. This principle becomes more
important when using conditional statements, as you will see in Chapter 3.

Boolean and Bitwise Operators


Some operators are especially important when you are working with
Boolean values. You will use these operators widely in Chapter 3 as we
discuss using conditional statements to control program flow. In Table 2.3
46 CHAPTER 2 Python Data Basics

Table 2.3 Important Boolean and Bitwise Operators


Operation Result Notes

x or y True if either x or y is True Only evaluates y if x is False


x and y True only if both x and y are True Only evaluates y if x is True
not x False if x is True; True if x is False
x|y Bitwise or of x and y
x&y Bitwise and of x and y
x^y Bitwise exclusive-or of x and y

we have consolidated the most common operators from tables in Sections


5.2 and 5.4.1 of Python Standard Library.
When working with Boolean variables, the bitwise operators for and (&)
and or (|) function just like their Boolean operator equivalents. The exclu-
sive-or operator (^), however, will only return True if either x or y is True,
but will return False if they are both True or both False.
There are more bitwise operators that we have not shown here only because
we do not use them throughout this text. Programmers who are comfortable
with binary number systems should be aware that bitwise operators also
work with int and long types.3

WORKING WITH SEQUENCE TYPES


In Chapter 1, three of the variable types introduced can be called sequence
types. Sequence types include strings, lists, and tuples. These types basically
contain a group of data in a linear sequence. While each of these types is
obviously unique, they also share some properties, which we briefly discuss
in this section.

Operators
As with numbers and Booleans, sequence types have a set of operators that
allow you to work with them conveniently. Section 5.6 of Python Standard
Library has a table of operations usable with sequence types. We have
selected the most common of these operations to display in Table 2.4.
Because they are perhaps not as immediately obvious as math operators,
some merit a bit of discussion.

3
It is also worth noting that the bitwise inversion operator (~) is not equivalent to the Boolean
not operator when working with Boolean variables. Booleans are not simply 1-bit values, but
are built on top of integers. Consequently, ~False is −1 and ~True is −2.
Working with Sequence Types 47

Table 2.4 Important Sequence Operators


Operation Result Notes

x in s True if x is in s Searches for item in lists/tuples


Searches for character sequence in strings
x not in s True if x is not in s (see in operator)
s+t Concatenation of s and t
s[i] ith item in s First index is 0
Negative value for i is relative to len(s)
s[i:j] Slice of s from i to j (see index operator)
i is starting index, j is end of slice
If i is omitted, i is 0
If j is omitted or greater than len(s), j is len(s)
s[i:j:k] Slice of s from i to j with step k (see index operator)
len(s) Length of s
min(s) Smallest item in s Corresponds to ASCII code for strings
max(s) Largest item in s Corresponds to ASCII code for strings
s.index(x) Index of first x in s
s.count(x) Total occurrences of x in s

Concatenation
The first operator worthy of a little discussion is the concatenation operator
(+). As you saw in the examples at the outset of this chapter, MEL concate-
nated two strings that we expected to be numbers. Python allows sequence
concatenation in the same way. Concatenation creates a new sequence com-
posed of all of the elements of the first sequence, followed by all of the ele-
ments in the second sequence. You can concatenate any sequence types, but
only with other sequences of the same type. You cannot concatenate a list with
a tuple, for instance.
The following line produces the string “Words make sentences.”
'Words' + ' ' + 'make' + ' ' + 'sentences.';

Likewise, the following line produces the list [1, 2, 3, 4, 5, 6].


[1,2,3] + [4,5,6];

Indexing and Slicing


An important operator for sequence types is the index operator, represented
by the square bracket characters ([ and ]). At its most basic, it corresponds
to the index operator found in most languages. Note also that sequence
types all use zero-based indices (Figure 2.2). For example, the following
line results in just the “c” character, as it occupies index 2 in the string.
48 CHAPTER 2 Python Data Basics

string value: a b c d e
indices: 0 1 2 3 4

■ FIGURE 2.2 Sequences use zero-based indices.

tuple elements: 1 2 3 4 5
negative indices: -5 -4 -3 -2 -1

■ FIGURE 2.3 Negative indices are relative to sequence length.

string value: H o l y c a t s , P y t h o n i s a w e s o m e
indices: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

■ FIGURE 2.4 Slicing a string from index 5 to 9.

'abcde'[2];

Because lists are mutable, you can also use this operator to set individual
values for a list. The following line would result in the list [0, 2, 3].
[1,2,3][0] = 0;

However, because they are immutable, you cannot use the index operator to
change individual items in a tuple or characters in a string. The following
two lines would fail.
'abcde'[2] = 'C';
(1,2,3)[0] = 0;

You can use a series of index operators to access elements from sequences
embedded in sequences. For instance, the following example will extract
just the “x” character.
('another', 'example')[1][1];

Another important feature of Python’s index operator is that it allows you to


supply a negative index. Supplying a negative index gives the result relative
to the length of the sequence (which is one index beyond the final element;
Figure 2.3). For example, the following line would print the number 4.
print((1,2,3,4,5)[-2]);

Python’s index operator also offers powerful, concise syntax for generating
slices from sequences. You can think of a slice as a chunk extracted from a
sequence. The most basic syntax for a slice includes two numbers inside
the square brackets, separated by a colon. The first number represents the
start index, and the second number represents the end index of the slice
(Figure 2.4). Consider the following example.
Random documents with unrelated
content Scribd suggests to you:
Carduus. C. arvense reproduces and passes the winter by means of suckers.—
Cynara (Artichoke) has a feathery pappus and large, solitary
capitulum, with broad involucral leaves; these have a fleshy base like
the receptacle (edible).—Silylum has united filaments. S. marianum (Milk-
thistle), has leaves with numerous white spots. Onopordon (Cotton-thistle). Cnicus
(C. benedictus) has a large, many-spined thorn on the involucral leaves; pappus
trimorphic.—Lappa (Burdock) is easily recognized by the hooked
involucral leaves, which assist in the distribution of the fruit; in this
respect it differs from the other inflorescences, and also in the fact
that the pappus is short, and quickly falls off, without serving as a
means of distribution.—Carlina; the external involucral leaves are leafy,
thorny, with branched or unbranched spines standing straight out or bent
backwards; the internal ones are dry, and prolonged as dry, coloured, radiating
scales. The well-developed bristles on the receptacle and edge of the calyx are
deeply cleft and lobed.—Centaurea (Knap-weed, Fig. 607). The ray-
flowers are neuter, and generally larger than the disc-flowers; the
involucral leaves are regularly imbricate, but are frequently provided
at the apex with a dry, chaffy, often lobed, fringed appendage. The
attachment of the fruit is lateral. Serratula (Saw-wort).—Carthamus, the
outer and inner involucral leaves differ very much.—Echinops (Globe-thistle)
is characterised by having “compound capitula,” i.e. there is only one
flower in each capitulum, but many such capitula are collected into a
spherical head, which at the base may also have a few involucral
leaves. The individual capitula have narrow, linear involucral leaves.
(There are altogether about 150 species of Compositæ with 1-flowered capitula, all
from warm countries.)—Xeranthemum, Staehelina, Jurinea, Saussurea,
etc.
2. Mutisieæ, Labiate-flowered Group. Tropical (S. American) forms whose
zygomorphic flowers have a bilabiate corolla (2/3). The involucre is nearly the
same as in the Thistles.
3. Cichorieæ, Chicory Group (or Ligulifloræ). The flowers are
all ☿ and have a ligulate, 5-dentate corolla. The stylar branches are
thin and prolonged (Fig. 609 B). Laticiferous vessels occur in the
majority (in this feature they resemble the Lobeliaceæ and
Campanulaceæ).
A. The pappus is wanting, or it is scale-like, but not long and hairy.
—Cichorium (Chicory); capitula with blue flowers, borne singly or a
few together in the leaf-axil; there are two whorls of involucral
leaves, an outer one of short and radiating, an inner of more
numerous, longer and erect leaves; pappus, scale-like.—Lapsana
(Nipplewort). The few involucral leaves are nearly of the same size,
and persist forming a sort of capsule round the fruits, which are
entirely without a pappus. There are only a few flowers in the small
capitula.—Arnoseris (Swine’s-succory), Catananche, etc.
B. The pappus is long and hairy (not branched), generally fine
and snowy-white. There are no scales on the receptacle. The two
genera first considered have beaked fruits.—Taraxacum (Dandelion)
(Fig. 606 a); the capitula are many-flowered, and borne singly on the
top of a leafless, hollow stalk.—Lactuca (Lettuce) has many small,
few-flowered capitula borne in panicles.—Crepis (Hawksbeard).—
Hieracium (Hawk-weed) has many imbricate involucral leaves, and a
stiff, brittle, brownish pappus.—Sonchus (Sow-thistle); the capitula,
when a little old, have a broad base, and are abstricted above in the
form of a jug; involucral leaves imbricate; the fruit is compressed,
without a beak, ridged. The soft, white pappus falls off collectively.
C. The pappus is feathery and branched; no scales on the
receptacle.—Tragopogon (Goat’s-beard) generally has 8 involucral
leaves in one whorl. The fruit has a long beak; the rays of the
pappus are interwoven in the form of an umbrella.—Scorzonera has
fruits like the preceding, but almost without any beak; involucral
leaves many, imbricate.—Leontodon (Hawkbit) has a slightly
feathery pappus, rays not interwoven; beak absent.—Picris.
D. Long, chaff-like, deciduous scales on the receptacle; pappus
feathery.—Hypochœris (Cat’s-ear).
4. Eupatorieæ, Hemp-agrimony Group. All the flowers are most
frequently ☿; corollas tubular and regular; the involucral leaves are
not stiff and spiny; the receptacle is not covered with stiff bristles.
The stylar branches are long, club-like, or gradually tapering. There
is no swelling below the stigma.
Eupatorium (Hemp-agrimony); all the flowers are ☿.—Petasites
(Butterbur); ray-flowers ♀, disc-flowers ☿ or ♂; sometimes diœcious.
Capitula in racemes or panicles. The leaves develop after the
flowering.—Tussilago (T. farfara, Colt’s-foot) has a solitary capitulum
borne on a scaly, scape-like stem; the ray-flowers are ♀ with ligulate
corollas, disc-flowers ♂ . The leaves unfold after the flowering.
Ageratum, Mikania, Vernonia.
5. Astereæ, Aster Group (or Radiatæ, Ray-flowered). The
flowers are of two forms and different sexes; the ray-flowers are ♀
(sometimes neuter), most frequently with irregular, falsely ligulate,
radiating corollas; the disc-flowers are ☿, regular, with tubular
corollas (Fig. 610). Sometimes only tubular flowers are present, as
e.g. in Senecio vulgaris (Groundsel), and the exterior of the
capitulum is then as in the Eupatorieæ. The stylar branches are
straight, more or less flat and short (Fig. 610).
A. Anthemideæ. Involucral leaves imbricate, generally
membranous at the edge; pappus wanting, or at most a
membranous margin to the calyx, but without hairs.
[+]. Chaff-like bracts on the receptacle are found in Anthemis
(Chamomile), Anacyclus (A. officinarum), Achillea (Milfoil, Fig. 610),
Santolina, etc.
[++]. A naked receptacle is found in the following: Bellis (Daisy)
has solitary capitula on leafless stalks with white ray-flowers.—
Matricaria (Wild Chamomile) has a conical receptacle. (M. chamomilla
has a very high, hollow receptacle; M. inodora has large, odourless capitula, and
the receptacle is not hollow.)—Chrysanthemum (Ox-eye) most frequently
large, solitary capitula; flat receptacle.—Pyrethrum; pappus scanty.
—With these are classed Tanacetum (Tansy) and Artemisia
(Wormwood) with tubular corollas only.
B. Heliantheæ. Most frequently a bract to each flower is found on
the receptacle. The pappus is never exactly hairy, but consists of
scales, spines, etc., and the fruits are most frequently compressed
(Fig. 606 c).—Helianthus (Sun-flower); H. tuberosus (Jerusalem
Artichoke) has tuberous underground stems. Dahlia has tuberous
roots (Am.). Bidens (Bur-marigold, Fig. 606 c); the fruits are
compressed with 2 (or more) spines provided with reflexed barbs.—
Calliopsis; Rudbeckia; Zinnia; Tagetes has united involucral leaves,
and yellow, transparent oil-glands. Spilanthes, Galinsoga,
Melampodium, Silphium (Compass-plant), Helenium, Gaillardia.
C. Calenduleæ have 1–2 rows of involucral leaves, a naked
receptacle, and large, crescent-shaped, irregularly warted fruits, of
different forms in the same capitulum; pappus absent (Fig. 605).—
Calendula (Marigold); ray-flowers ♀, disc-flowers ♂.
D. Senecioneæ, have a fine, hairy, white pappus; no bracts,
otherwise as in Anthemideæ. The involucral leaves are most
frequently in 1–2 rows.—Senecio (Groundsel) has two whorls of
involucral leaves, which most frequently have black tips, the external
being much shorter than the internal ones (S. vulgaris has all flowers
☿ and alike).—Cacalia, Doronicum, Cineraria, Ligularia, Arnica (A.
montana; large, long-stalked capitula; leaves opposite, forming a
kind of rosette).
E. Astereæ have a bristle-like, unbranched pappus, often of a
dingy brown; receptacle naked; involucral leaves numerous,
imbricate.—Solidago (Golden-rod); capitula small, yellow-flowered,
borne in panicles. Aster; disc-flowers most frequently yellow, ray-
flowers violet; Callistephus; Erigeron (Flea-bane)—Inula.—All the
corollas are tubular in: Gnaphalium (Cud-weed); involucral leaves
dry, rattling, often coloured; the foliage-leaves and stem often white
with woolly hairs; ray-flowers ♀ , with narrow, tubular corolla; disc-
flowers ☿ (few). Antennaria (Cat’s-foot; diœcious), Filago,
Helichrysum, Ammobium, Rhodanthe and others. Leontopodium (L.
alpinum, “Edelweiss”).
F. Ambrosieæ, a very reduced type of Compositæ, differing from the others in
having free anthers; the capitula are generally unisexual, monœcious, the ♂ borne
in a terminal inflorescence, the ♀ in the leaf-axils. In other respects they are most
closely related to Heliantheæ.—Xanthium. In the ♂ -capitula there are many
flowers without calyx, but with tubular corolla and free involucral leaves. In the ♀-
capitula there are only 2 flowers, which are entirely destitute of both calyx and
corolla; involucral leaves 2-spined, united to form an ovoid, bilocular envelope,
each compartment containing one flower. The envelope of involucral leaves unites
with the fruits, enclosing them at maturity with a hard covering from which
numerous hook-like spines project, assisting very greatly in the distribution of the
fruit. The whole structure thus finally becomes a 1- or 2-seeded false nut.—
Ambrosia, the ♀ capitulum 1-flowered.
Pollination. The flowers are somewhat insignificant, but become very
conspicuous owing to a number being crowded together in one inflorescence. The
corollas of the ray-flowers, being often very large (Astereæ; Centaurea), frequently
render the capitula still more conspicuous. The capitula display many biological
phenomena similar to those often shown by the individual flowers in other orders,
e.g. by periodically opening and closing, in which the involucral leaves resemble
the calyx in their action. (The name “Compositæ” originates from the term “flos
compositus,” composite flower). An abundance of honey is formed, which to some
extent fills up the corolla-tube, and since insects may visit a number of flowers in
the course of a short period they are very frequently visited, especially by
butterflies and bees. The pollination has been described on page 567. Protandry is
universal. In the bud the tips of the styles, covered by the sweeping-hairs, lie
closely enveloped by the anther-tube; in the next stage the style grows through the
tube and sweeps out the pollen as it proceeds; ultimately the stylar branches
expand and the stigma is then prepared to receive the pollen. In many, the
sensitiveness of the filaments assists in sweeping out the pollen at the exact
moment of the insect visit. Regular self-pollination is found e.g. in Senecio
vulgaris; wind-pollination e.g. in Artemisia and the plants related to it.
This extremely natural and well-defined order is the largest (and no doubt one
of the youngest?); it embraces 10–12,000 known species (in 770 genera), or about
one-tenth of all Flowering-plants. They are distributed over the whole globe, but
are most numerous in temperate countries; the majority prefer open spaces; a
smaller number are forest-forms. They abound especially in open districts in
America.
Among the substances frequently found may be mentioned: Inulin (especially
in the subterranean parts), Bitter materials, Tannin, volatile oils, fatty oils in the
fruits. Medicinal:[40] “Herba” of Artemisia absinthium (Wormwood) and
maritima[+] (Sea-wormwood), Achillea millefolium; the leaves of Cnicus benedictus
and Tussilago farfara; the unopened capitula of Artemisia maritima, var.
stechmanniana; the capitula of Tanacetum, Matricaria chamomilla[+] (wild
Chamomile), Anthemis nobilis[+] (common Chamomile); the separate flowers of
Arnica; the roots of Arnica montana[+], Taraxacum officinale[+], Anacyclus
officinarum[+], Lappa major, minor, nemorosa and tomentosa, Inula helenium and
Artemisia vulgaris; the latex of Lactuca virosa[+]. The following are cultivated for
food:—Lactuca sativa (Lettuce), Cichorium endivia (from E. Asia, for salads),
Cynara scolymus (Artichoke, Mediterranean), Scorzonera hispanica (S. Eur.),
Helianthus tuberosus (Jerusalem Artichoke, from N. Am., introduced into Europe
1616), Cichorium intybus (roots as “chicory,”) Tragopogon porrifolium (Salsafy),
Artemisia dracunculus. Oil is extracted from the following (the seeds): Helianthus
annuus (Peru), Madia sativa (Chili), Guizotia oleifera (Abyssinia). Dyes from:
Carthamus tinctorius (Safflower, used in the preparation of rouge; Egypt),
Serratula tinctoria. Insect-powder from: Pyrethrum cinerariifolium (Dalmatia) and
roseum (Persia, Caucasus). The following are cultivated in houses and gardens for
the sake of their scented leaves:—Tanacetum balsamita (Balsam), Artemisia
abrotanum (Southernwood) and A. argentea. A great many of the genera
enumerated are cultivated in dwelling-houses for the sake of the flowers; e.g.
Pericallis cruenta (generally termed “Cineraria”). Asteriscus pygmæus is supposed
to be the genuine “Rose of Jericho”; the involucral leaves envelop the fruits after
their ripening and keep them enclosed for 8–10 months until rain occurs.
APPENDIX ON THE CLASSIFICATION OF PLANTS.
By M. C. POTTER.
The earliest systems of classification were derived from the
properties and uses of plants; and it was not until some two
centuries ago that any scientific grouping of plants was attempted.
Aristotle and Theophrastus had adopted the groups of Trees, Shrubs
and Herbs as the chief divisions of the Vegetable Kingdom, a system
which persisted and was employed by Tournefort and Ray as late as
the end of the 17th century. The arrangement by which these three
divisions were separated into smaller divisions was often founded
upon a single character, such as the formation of the corolla, the
form of fruit, that of the calyx and corolla, etc. All these systems of
classification which brought into close proximity plants distinguished
by some one character alone, could only be considered as artificial,
since plants related to one another would not necessarily be
included in the same group. As the knowledge of the morphology,
physiology, and reproduction of plants increased, such systems were
recognised as unscientific, and it became the aim of botanists to
establish a natural system, founded upon mutual relationships, which
would associate together only those plants which are truly allied.
The following are some of the chief systems of classification
which will show the gradual development of the natural system, and
may be of service to students making use of this text-book.[41]
System of John Ray (1703).

I. Herbæ.
A. Imperfectæ (Flowerless).
B. Perfectæ (Flowering).
Dicotyledones.
Monocotyledones.
II. Arbores.
A. Monocotyledones.
B. Dicotyledones.
Ray was the first botanist who recognised the importance of the
one or two seed-leaves of the embryo, and initiated the division of
the Flowering-plants into Monocotyledons and Dicotyledons.
System of Linnæus (1733).
In his well known artificial system Linnæus divided the Vegetable
Kingdom into twenty-four classes, based upon the number, relative
position and union of the stamens with regard to each other, and
also to the gynœceum.
I. Monandria. Flowers 1 stamen.
Class
with
„ II. Diandria. „ „ 2 stamens.
„ III. Triandria. „ „ 3 „
„ IV. Tetrandria. „ „ 4 „
„ V. Pentandria. „ „ 5 „
„ VI. Hexandria. „ „ 6 „
„ VII. Heptandria. „ „ 7 „
„ VIII. Octandria. „ „ 8 „
„ IX. Enneandria. „ „ 9 „
„ X. Decandria. „ „ 10 „
„ XI. Dodecandria. „ „ 11 to 19 stamens.
XII. Icosandria. „ „ 20 or more stamens inserted on the

calyx.
XIII. Polyandria. „ „ 20 or more stamens inserted on the

receptacle.
„ XIV. Didynamia. Stamens didynamous.
„ XV. Tetradynamia. „ tetradynamous.
„ XVI. Monadelphia. Filaments united into 1 bundle.
„ XVII. Diadelphia. „ „ „ 2 bundles.
„ XVIII. Polyadelphia. „ „ „ several bundles.
„ XIX. Syngenesia. Anthers united together.
„ XX. Gynandria. Stamens and pistil united.
„ XXI. Monœcia. Flowers diclinous, ♂ and ♀ on the same plant.
„ XXII. Diœcia. „ „ ♂ and ♀ on different plants.
„ XXIII. Polygamia. ♂-, ♀-, and ☿-flowers on the same plant.
„ XXIV. Cryptogamia. Flowerless plants (Ferns, Mosses, Algæ, Fungi).
These classes were further divided into orders, according to the number of
styles, as Monogynia, flowers with 1 style; Digynia, with 2 styles, etc. Thus a Dock
(Rumex), having 6 stamens and 3 styles, would be placed in Class VI.,
Hexandria, and Order III., Trigynia.
Class XIV. was divided into two orders. Order I., Gymnospermia, with seeds
apparently naked, comprising the Labiatæ; and Order II., Angiospermia, with the
seeds enclosed in a capsule (Bartsia, Rhinanthus).
Class XV. was divided into two orders: Order I., Siliculosa, fruit a silicula
(Capsella); and Order II., Siliquosa, fruit a siliqua (Brassica).
Class XIX. was divided into Order I., Æqualis, all the flowers perfect (Sonchus);
Order II., Superflua, flowers in the centre perfect, those at the circumference with
pistils only (seemingly superfluous), e.g. Aster; Order III., Frustranea, flowers in
the centre perfect, those at the circumference neuter, e.g. Centaurea.
“Fragments” of a natural system have also come down to us from Linnæus, who
himself always recognised the imperfection of his artificial system.

System of Antoine Laurent de Jussieu (1789).


Class
Acotyledones. Plants without cotyledons: Fungi, Ferns, Mosses, I.
Algæ, Naiades
Monoctyledones. Plants with one cotyledon:—
1. Stamens hypogynous II.
2. „ perigynous III.
3. „ epigynous IV.
Dicotyledones. Plants with two cotyledons:—
Stamens epigynous V.
1. Apetalæ „ perigynous VI.
„ hypogynous VII.
2. Monopetalae Corolla hypogynous VIII.
„ perigynous IX.
anthers connate X.
„ epigynous,
„ free XI.
Stamens epigynous XII.
3. Polypetalæ „ hypogynous XIII.
„ perigynous XIV.
4. Diclines irregulares, male and female flowers on different plants,
corolla generally absent.

System of A. P. de Candolle (1819).


I. Vasculares. Plants with vascular bundles.
1. Exogenæ. Vascular bundles arranged in a ring.
A. Diplochlamydeæ. Calyx and corolla present.
a. Thalamifloræ. Corolla polypetalous and hypogynous.
b. Calycifloræ. Corolla perigynous or epigynous; stamens inserted on
the calyx.
c. Corollifloræ. Corolla gamopetalous; stamens inserted on the corolla.
B. Monochlamydeæ. Perianth simple.
2. Endogenæ. Vascular bundles scattered, the youngest in the centre.
A. Phanerogamæ. Flowers present.
B. Cryptogamæ. Flowers absent.
II. Cellulares. Vascular bundles absent.
1. Foliaceæ. Leaves present.
2. Aphyllæ. Leafless.

Robert Brown published in 1827 his discovery of the


gymnospermy of the ovules of the Coniferæ and Cycadeæ, and
showed that the Gymnosperms, which had previously been classed
with the Dicotyledons, must be regarded as an independent group.

System of Stephen Endlicher (1836–40).


I. Thallophyta. No differentiation into stem and root.
1. Protophyta. Class I., Algæ; Class II., Lichenes.
2. Hysterophyta. Class III., Fungi.
II. Cormophyta. Differentiated into stem and root.
1. Acrobrya. Stem growing at the point.
Anophyta (Hepaticæ, Musci).
Protophyta (Filices, etc.).
Hysterophyta (Balanophoreæ, etc.).
2. Amphibrya. Stem growing at the circumference (Monocotyledons).
3. Acramphibrya. Stem growing both at the point and circumference.
Gymnosperma (Coniferae).
Apetala. Perianth single or absent.
Gamopetala. Petals gamopetalous.
Dialypetala. Petals polypetalous.

System of A. Brongniart (1843).


I. Cryptogamæ. Plants without flowers.
1. Amphigenæ. Not differentiated into stem or leaf (Algæ, Fungi,
Lichenes).
2. Acrogenæ. Plants with stem and leaf (Muscineæ, Filicinæ).
II. Phanerogamæ. Plants with flowers.
3. Monocotyledones.
a. Albuminosæ. Seeds with endosperm.
b. Exalbuminosæ. Seeds without endosperm.
4. Dicotyledones.
a. Angiosepermæ.
α. Gamopetalæ.
β. Dialypetalæ.
b. Gymnospermæ.

System of John Lindley (Vegetable Kingdom, 1845).


Asexual, or Flowerless Plants.
Stem and leaves undistinguishable I. Thallogens.
Stem and leaves distinguishable II. Acrogens.
Sexual, or Flowering Plants.
Fructification springing from a thallus III. Rhizogens.
Fructification springing from a stem.
Wood of stem youngest in the centre; cotyledon single.
Leaves parallel-veined, permanent; wood of stem
always confused IV. Endogens.
Leaves net-veined, deciduous; wood of the stem, when
perennial, arranged in a circle with a central pith V. Dictyogens.
Wood of stem youngest at the circumference, always
concentric; cotyledons, 2 or more.
Seeds quite naked VI. Gymnogens.
Seeds inclosed in seed-vessels VII. Exogens.

System of Alexander Braun (1864).


I. Bryophyta.
1. Thallodea (Algæ, Fungi, Lichenes).
2. Thallophyllodea (Charas, Mosses).
II. Cormophyta.
1. Phyllopterides (Ferns, Equisetums).
2. Maschalopterides (Lycopods).
3. Hydropterides (Water-ferns).
III. Anthophyta.
Gymnospermæ.
1. Frondosæ (Cycadeæ).
2. Acerosæ (Coniferæ).
Angiospermæ.
1. Monocotyledones.
2. Dicotyledones.
Apetalæ.
Sympetalæ.
Eleutheropetalæ.

W. Hofmeister published from 1849 to 1851 his researches upon


the embryology of the Phanerogams, and upon the embryology and
life-history of the Vascular Cryptogams, and established the
phylogenetic connection existing between the Mosses, Vascular
Cryptogams and Phanerogams.
System of Hooker and Bentham (Genera plantarum, 1862–
1883).
DICOTYLEDONES.

I. POLYPETALÆ.
Series I. Thalamifloræ. Calyx most often free from the ovary.
Petals uniseriate or often 2–∞-seriate. Stamens ∞ or definite,
inserted on the receptacle, often small, or raised, or stipitate. Ovary
most frequently free.
Cohort I. Ranales. Stamens ∞, or if definite the perianth is 3–∞-
seriate. Carpels apocarpous, or immersed in the receptacle.
Endosperm usually abundant, fleshy.
Order 1. Ranunculaceæ.
„ 2. Dilleniaceæ.
„ 3. Calycanthaceæ.
„ 4. Magnoliaceæ.
„ 5. Anonaceæ.
„ 6. Menispermaceæ.
„ 7. Berberideæ.
„ 8. Nymphæaceæ.

Cohort II. Parietales. Stamens ∞ or definite. Ovary unilocular, or


divided into loculi by spurious dissepiments, with parietal
placentation. Endosperm absent or fleshy.
Order 9. Sarraceniaceæ.
„ 10. Papaveraceæ.
„ 11. Cruciferæ.
„ 12. Capparideæ.
„ 13. Resedaceæ.
„ 14. Cistineæ.
„ 15. Violarieæ.
„ 16. Canellaceæ.
„ 17. Bixineæ.

Cohort III. Polygalinæ. Stamens definite. Ovary usually perfectly


or imperfectly bilocular. Micropyle often superior. Fruit very often
compressed laterally. Endosperm very often abundant and fleshy.
Order 18. Pittosporeæ.
„ 19. Tremandreæ.
„ 20. Polygaleæ.
„ 20a. Vochysiaceæ.

Cohort IV. Caryophyllineæ. Stamens definite, or rarely ∞. Ovary


unilocular, or imperfectly septate. Placenta central, more rarely
parietal. Micropyle inferior. Embryo curved, rarely straight.
Endosperm farinaceous.
Order 21. Frankeniaceæ.
„ 22. Caryophylleæ.
„ 23. Portulaceæ.
„ 24. Tamariscineæ.

Cohort V. Guttiferales. Sepals inbricate. Stamens usually ∞.


Ovary septate, placentæ on the inner angles of the loculi.
Endosperm absent or fleshy.
Order 25. Elatineæ.
„ 26. Hypericineæ.
„ 27. Guttiferæ.
„ 28. Ternstrœmiaceæ.
„ 29. Dipterocarpeæ.
„ 30. Chlænaceæ.

Cohort VI. Malvales. Sepals valvate. Stamens usually ∞ or


monadelphous. Ovary septate, placentæ on the inner angles of the
loculi. Endosperm absent or fleshy.
Order 31. Malvaceæ.
„ 32. Sterculiaceae.
„ 33. Tiliaceæ.

Series II. Discifloræ. Calyx usually free from the ovary. Petals
uniseriate. Stamens usually definite, inserted within, or upon, or
around the receptacle, which is more often expanded as a disc.
Ovary usually free, or embedded in the disc.
Cohort VII. Geraniales. Disc usually as a ring between the
stamens, or adnate to the staminal tube, or reduced to glands
alternating with the petals, more rarely absent. Gynœceum entire, or
more often lobed, or sub-apocarpous. Ovules most often 1–2 in each
loculus, pendulous, raphe ventral. Leaves various.
Order 34. Lineæ.
„ 35. Humiriaceæ.
„ 36. Malpighiaceæ.
„ 37. Zygophylleæ.
„ 38. Geraniaceæ.
„ 39. Rutaceæ.
„ 40. Simarubeæ.
„ 41. Ochnaceæ.
„ 42. Burseraceæ.
„ 43. Meliaceæ.
„ 44. Chailletiaceæ.

Cohort VIII. Olacales. Disc cupular or annular, free, or bearing


the stamens and petals on its edge. Gynœceum entire. Ovules 1–3
in the unilocular ovaries, or 1–2 in each loculus, pendulous, raphe
dorsal. Leaves simple.
Order 45. Olacineæ.
„ 46. Ilicineæ.

Cohort IX. Celastrales. Disc tumid, adnate to the calyx, or


covering its base. Stamens inserted round the disc or affixed to its
margin. Gynœceum usually entire. Ovules most often two in each
loculus, erect, raphe ventral. Leaves simple, or rarely compound.
Order 47. Celastrineæ.
„ 48. Stackhousieæ.
„ 49. Rhamneæ.
„ 50. Ampelideæ.

Cohort X. Sapindales. Disc various. Stamens variously inserted


on the disc. Gynœceum entire, or more often lobed, or sub-
apocarpous. Ovules more often 1–2 in each loculus, ascending with
ventral raphe, or reversed, or solitary and pendulous from an
ascending funicle, or rarely ∞ horizontal. Leaves pinnate, or more
rarely simple or digitate.
Order 51. Sapindaceæ.
„ 52. Sabiaceæ.
„ 53. Anacardiaceæ.

Anomalous orders, or rather genera,—


Order 54. Coriarieæ.
„ 55. Moringeæ.

Series III. Calycifloræ. Calyx-tube usually surrounding the ovary,


or adnate to it. Petals uniseriate, inserted on the calyx-tube.
Stamens ∞ or definite, inserted on the calyx-tube, or most often on
the disc lining the calyx-tube. Ovary often enclosed by the calyx-
tube, or inferior.
Cohort XI. Rosales. Carpels solitary, or free, or united at the
base, more rarely at the apex; styles distinct, or very rarely united
into a column, and easily separated.
Order 56. Connaraceæ.
„ 57. Leguminosæ.
„ 58. Rosaceæ.
„ 59. Saxifrageæ.
„ 60. Crassulaceæ.
„ 61. Droseraceæ.
„ 62. Hamamelideæ.
„ 63. Bruniaceæ.
„ 64. Halorageæ.

Cohort XII. Myrtales. Ovary syncarpous, inferior, or enclosed in


the calyx-tube, usually divided into loculi; style undivided. Ovules 2–
∞ in the loculi.
Order 65. Rhizophoreæ.
„ 66. Combretaceæ.
„ 67. Myrtaceæ.
„ 68. Melastomaceæ.
„ 69. Lythrarieæ.
„ 70. Onagrarieæ.

Cohort XIII. Passiflorales. Ovary syncarpous, inferior or


superior, enclosed in the calyx-tube or exserted, unilocular with
parietal placentation, or divided into loculi; styles distinct, one style
divided, or undivided.
Order 71. Samydaceæ.
„ 72. Loaseæ.
„ 73. Turneraceæ.
„ 74. Passifloreæ.
„ 75. Cucurbitaceæ.
„ 76. Begoniaceæ.
„ 77. Datisceæ.

Cohort XIV. Ficoidales. Ovary syncarpous, inferior or superior,


divided into loculi with sub-basilar placentæ, or more rarely
unilocular with parietal placentæ. Styles distinct, or divided at the
apex. Embryo curved or excentric.
Order 78. Cacteæ.
„ 79. Ficoideæ.

Cohort XV. Umbrellales. Ovary syncarpous, inferior, crowned by


the disc, divided into loculi, or unicarpellate. Styles distinct or divided
at the apex. Ovules solitary and pendulous in the loculi.
Order 80. Umbelliferæ.
„ 81. Araliaceæ.
„ 82. Cornaceæ.

II. GAMOPETALÆ.
Series I. Inferæ. Ovary inferior. Stamens equal to the lobes of the
corolla, rarely fewer.
Cohort I. Rubiales. Stamens adnate to the corolla. Ovary 2–∞-
locular, loculi 1–∞-ovuled.
Order 83. Caprifoliaceæ.
„ 84. Rubiaceæ.

Cohort II. Asterales. Stamens adnate to the corolla. Ovary


formed of 2 carpels, unilocular and 1-ovuled.
Order 85. Valerianeæ.
„ 86. Dipsaceæ.
„ 87. Calycereæ.
„ 88. Compositæ.

Cohort III. Campanales. Stamens generally free from the corolla.


Ovary 2–6-locular, loculi most often ∞-ovuled.
Order 89. Stylidieæ.
„ 90. Goodenovieæ.
„ 91. Campanulaceæ.

Series II. Heteromeræ. Ovary most often superior. Stamens free


from the corolla, opposite to, or double the lobes of the corolla, or ∞,
or if epipetalous, equal and alternating with them. Carpels more than
2.
Cohort IV. Ericales. Stamens double the lobes of the corolla, or
alternating with them. Ovary 2–∞-locular. Seeds small, frequently
minute.
Order 92. Vacciniaceæ.
„ 93. Ericaceæ.
„ 94. Monotropeæ.
„ 95. Epacrideæ.
„ 96. Diapensiaceæ.
„ 97. Lennoaceæ.

Cohort V. Primulales. Stamens equal to and opposite the lobes


of the corolla. Ovary unilocular, with a free central placenta, 1–∞
ovules.
Order 98. Plumbagineæ
„ 99. Primulaceæ.
„ 100. Myrsineæ.

Cohort VI. Ebenales. Stamens equal to and opposite the lobes of


the corolla, or double, or ∞. Ovary 2–∞-locular. Seeds few and large.
Trees or shrubs.
Order 101. Sapotaceæ.
„ 102. Ebenaceæ.
„ 103. Styraceæ.

Series III. Bicarpellatæ. Ovary most often superior. Stamens


equal, or fewer than the lobes of the corolla, and alternating with
them. Carpels 2, rarely 1 or 3.
Cohort VII. Gentianales. Corolla regular. Stamens equal to the
lobes of the corolla, or if fewer, usually alternating with the carpels.
Leaves generally opposite.
Order 104. Oleaceæ.
„ 105. Salvadoraceæ.
„ 106. Apocynaceæ.
„ 107. Asclepiadeæ.
„ 108. Loganiaceæ.
„ 109. Gentianeæ.

Cohort VIII. Polemoniales. Corolla regular. Stamens equal to the


lobes of the corolla. Leaves generally alternate.
Order 110. Polemoniaceæ.
„ 111. Hydrophyllaceæ.
„ 112. Boragineæ.
„ 113. Convolvulaceæ.
„ 114. Solanaceæ.
Cohort IX. Personales. Corolla most often irregular or oblique.
Posterior stamen less than the others, more often reduced to a
staminode, or altogether absent. Ovary ∞-ovuled, or 2-ovuled.
Order 115. Scrophularineæ.
„ 116. Orobanchaceæ.
„ 117. Lentibularieæ.
„ 118. Columelliaceæ.
„ 119. Gesneraceæ.
„ 120. Bignoniaceæ.
„ 121. Pedalineæ.
„ 122. Acanthaceæ.

Cohort X. Lamiales. Corolla most often irregular or oblique.


Posterior stamen less than the others, most frequently reduced to a
staminode or absent. Carpels 1-ovuled or with 2 collateral ovules.
Fruit enclosed in the persistent calyx, indehiscent, and with one
seed, or dehiscing into 2 or 4, rarely ∞, 1-seeded nuts.
Order 123. Myoporineæ.
„ 124. Selagineæ.
„ 125. Verbenaceæ.
„ 126. Labiateæ.

Anomalous Order 127. Plantagineæ.


III. MONOCHLAMYDEÆ.
Perianth simple, lobes or segments 1–2-seriate and often
sepaloid, or small, or wanting.
Series I. Curvembryeæ. Endosperm frequently farinaceous.
Embryo curved, excentric, lateral or peripheral, rarely straight.
Ovules most frequently 1 in the ovary, or 1 in each loculus. Flowers
☿, in some genera unisexual or polygamous. Petals very rare.
Stamens equal to the segments of the perianth, rarely fewer or more.
Order 128. Nyctagineæ.
„ 129. Illecebraceæ.
„ 130. Amarantaceæ.
„ 131. Chenopodiaceæ.
„ 132. Phytolaccaceæ.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookgate.com

You might also like