-
Notifications
You must be signed in to change notification settings - Fork 17
Projections
Most of the work you do with streams is filtering: winnowing down a long list of candidates to a shorter one by by checking the members against some kind of test. However there are also a lot of common Maya tasks that require traversing through the Maya scene graph: finding the children of a transform, for example, finding the construction history of a mesh, or finding the bones driven by a constraint are all examples of tasks that swap out the existing stream for new information.
The generic database term for this kind of query is a 'projection' - but that's just a somewhat arbitrary way of saying 'an operation which replaces the contents of a stream with new data based on the existing data'.
Projection operations are all triggered with the get()
function on a stream. For example if you had a stream that contained the names of some camera transforms, you could get the camera shapes themselves like this:
using('top', 'side', 'persp').get(Children)
The first using()
clause on its own will execute as
u'|top', u'|side', u'|persp'
but adding the get()
clause will cause the result to become
u'|top|topShape', u'|side|sideShape', u'|persp|perspShape'
In general any get()
query will replace the incoming stream with a new stream
Sometimes you'll want to keep the stream you have before transforming it with a projection. In the above example, you might want to keep the camera transforms as well as the camera shapes. The append()
function will perform the same operation (since the operator here is Children
, that's basically cmds.listRelatives, c=True
) and add it on to the stream already there:
print using('top', 'side', 'persp').append(Children)
Stream([u'|top', u'|side', u'|persp', u'|top|topShape', u'|side|sideShape', u'|persp|perspShape'])
Sometimes you'll want to use some code of your own to transform a stream. The foreach()
function applies a one-argument callable to every item in the stream and returns the result, which can be anything the functions returns. An impractical example might be:
print Cameras().short().foreach(lambda p: p.upper())
# Stream([u'FRONTSHAPE', u'PERSPSHAPE', u'SIDESHAPE', u'TOPSHAPE'])
A more practical example for PyMel users would be
print Cameras().foreach(pm.PyNode)
Stream([nt.Camera(u'frontShape'), nt.Camera(u'perspShape'), nt.Camera(u'sideShape'), nt.Camera(u'topShape')])
which converts Maya string names into PyNodes. In general, foreach()
will be slower than the native minq equivalent: For example, you would prefer Meshes().get(History)
to Meshes().foreach(cmds.listHistory)
since the former executes only one function call and the latter does one for each item in the stream.
Here are all of the operations which can be used with get()
and append()
:
Operator | arguments? | flags? | Notes |
---|---|---|---|
Parents | Returns the parents of every item in the stream which has a transform parent | ||
Children | Returns the immediate children of every item in the stream which has a transform child | ||
AllParents | Returns all of the parents of all items in the stream with parents, up to their root nodes | ||
AllChildren | Returns all of the children of all items in the stream (essentially, listRelatives(ad=True) ) |
||
History | y | Get the incoming history connections of all items in the stream (= listHistory() ) |
|
Future | y | Get the outgoing history connections of all items in the stream (= listHistory(f=True)
|
|
Connections | y | Get the node connections for all items in the stream (= listConnections() ) |
|
Attribute | y | Get an attribute string for each item. Pass in the attribute string as an argument | |
Values | If the incoming stream contains attributes (see above), returns a stream of the corresponding values | ||
AttribValues | y | Combines Attributes and Values into one operation: pass in the attribute name(s) as arguments |
|
WorldPositions | Gets the worldspace positions of incoming transforms as tuples. | ||
LocalPositions | Gets the local positions of incoming transforms as tuples | ||
LocalAxis | Y | Y | Gets the local x, y or z axis of incoming trandforms. Keyword "local" allows choice between world and local values. Defaults to world values |
Yields a stream of attribute names for the incoming streams. For example
Cameras().get(Attribute, 'orthographic')
will produce something like
Stream([u'topShape.orthographic', u'sideShape.orthographic', ...])
This can be filtered to objects that have actually have the attribute by passing it to an ObjectsOnly:
Shapes().get(Attributes, 'orthographic').only(ObjectsOnly)
If you pass multiple attributes your stream will expand:
print using('top').get(Attributes, 'tx', 'ty')
Stream([u'|top.tx', u'|top.ty'])
Returns all of the values for a stream of attributes (see above). For example
Transforms().get(Attribute, 'tx').get(Values)
will yield a stream of all the translateX values in the scene. The values will be returned in the same order as the incoming stream (so they can, for example, be turned into a table). If an attribute string in the stream does not exist an exception will be raised.
Note that Values
and AttribValues
are significantly faster that calling getAttr()
in a loop, since all of the queries will execute in one stroke.
Combines a call to Attribute() and Values() into one operation for convenience
Transforms().get(AttribValues, 'tx')
is equivalent to
Transforms().get(Attribute, 'tx').get(Values)
There are several related classes which use the same strategy as AttribValues
to get the size of array attributes, particularly commonly used ones like vertex or face counts. Generically they'll look likes this:
Meshes().get(VertCount)
#Stream([245, 123, 595,...])
The available count operations are:
#####VertCount Get the vertex counts of a mesh stream
Get the poly face counts of a mesh stream
#####ColorCount Get color vertex count of a mesh stream
#####TweakCount Get the number of tweakss (the .pnts attribuute) on a shape steam
#####CVCount Gets the cv counts on a nurbs stream
#####UVSetCount Gets the count of uv sets in a mesh stream
#####UVPointCount Gets the count of uv vertices in the current uv set of a mesh stream
###Types
Returns a stream of tuples (object, nodeType) for every object in the incoming stream. This is mostly useful for tabulating data: to find items by type its more appropriate to use an only()
query with a NodeType filter.