Skip to content
theodox edited this page Apr 24, 2016 · 5 revisions

The most common activity in a minq query is filtering: winnowing a stream down to a more precisely targeted selection on of objects.

There are a couple of distinct types of filtering.

only() to filter by type

The only() function of a stream filters by Maya node types. For example

 Scene().only(Meshes)

will yield only mesh nodes: it's equivalent to cmds.ls(type=mesh`)

where() to filter by a condition

where accepts a one-argument callable as an argument. It will call that function on every element in the stream, passing only those values which return a True or truthy value for the filter function. For example:

def has_p(name):
    return 'p' in name

print Cameras().get(Parents).where(has_p)
# Stream([u'|persp', u'|top'])

The function can do anything it wants -- the only requirement is that it accepts a single argument. For convenience you can use where_not() to negate a filter function:

print Cameras().get(Parents).where_not(has_p)
# Stream([u'|front', u'|side'])

For the common case of querying maya node attributes, there's a special syntax that allows you to avoid writing a function just to call and test getAttr. The minq keyword item is actually a query factory which creates getAttr tests for you, so you can write

Cameras().where(item.orthographic == True)
# Result: Stream([u'|front|frontShape', u'|side|sideShape', u'|top|topShape']) # 

instead of

def is_ortho(cam):
    return cmds.getAttr(cam + ".orthographic")    
Cameras().where(is_ortho)

Using item is also faster than a getAttr filter function as well: see Atribute Queries for more details.

like() to filter by name

like() is used to filter object names as strings. In its simplest form it simply does a case insensitive partial match: if you pass in a sub-string as an argument, it will match any occurrence:

 Cameras().like('r')
 # Result: Stream([u'|front|frontShape', u'|persp|perspShape']) # 

You can however force like to require an exact match by passing the exact flag. Thus:

 Cameras().like('r', exact=True)
 # Result: Stream([]) # 
 # no match because 'r' by itself is not a regex match
 # but add in the necessary wildcards...
 Cameras().like('.*r.*', exact=True)
 # Result: Stream([u'|front|frontShape', u'|persp|perspShape']) # 

It's important to remember that by default, minq streams contain full path names, so objects deep in a hierarchy will still be found by like if one of their parents are! Sometimes that's a very useful feature -- you can find everything under 'r_shoulder' with a single like() query -- but sometimes it produces false positives. Since like is a regular expression, however, you can limit matches to the end of a path name using the $. In this example a plain check on 'arm' would collect hands and fingers because of the path name, but arm$ only collects items which end with "arm".

Joints().like('arm$')
# Result: Stream([u'LeftArm', u'LeftForeArm', u'RightArm', u'RightForeArm']) # 

You can use any Python regular expression as an argument; for example Joints().like('spine[24]$') will find Spine2 and Spine4 but not Spine1 or Spine3 (for a great python regex tester, check out Pythex.org).

Clone this wiki locally