I had another play with this too. :)
Getting maya to do the wildcard matching still takes about 27 seconds
with the new method.
Was curious how slow/fast it'd be if I did the wildcard match myself.
I get all the shapes, get each shapes dagPath, test it with the re
module, and run my setAttr if it matches. Doing this, the time comes
down to 0.5 of a second. Tried a few runs with matching half the
shapes, all the shapes, and no shapes, performance beats the builtin
wildcard by a huge margin.
search = nurbsSphereShape*
pattern = |set|*|*|nurbsSphereShape*
api = 0.460000038147 sec, 8016 shapes modified
cmds = 26.9750001431 sec, 8016 shapes modified
search = nurbsSphereShape*
pattern = |set|a|*|nurbsSphereShape*
repattern = [|]set[|]a[|].*[|]nurbsSphereShape.*
api = 0.319000005722 sec, 4323 shapes modified
cmds = 14.5989999771 sec, 4323 shapes modified
search = nurbsSphereShape*
pattern = |set|*|*|badmatch*
api = 0.182000160217 sec, 0 shapes modified
cmds = 11.1970000267 sec, 0 shapes modified
here's my fugly test code:
import maya.OpenMaya as om
import maya.cmds as cmds
import time
import re
search = "nurbsSphereShape*"
pattern = "|set|*|*|badmatch*"
# change the maya pattern to a re friendly pattern; | becomes [|], and
* becomes .*
repattern = re.sub('[|]',r'[|]',pattern)
repattern = re.sub('\*',r'.*',repattern)
print ("search = %s" % search )
print ("pattern = %s" % pattern )
print ("repattern = %s" % repattern)
# API based
start = time.time()
sel = om.MSelectionList()
om.MGlobal.getSelectionListByName(search, sel)
iter = om.MItSelectionList(sel)
depFn = om.MFnDependencyNode()
mObj = om.MObject()
dPath = om.MDagPath()
count = 0
while not iter.isDone():
iter.getDependNode( mObj )
depFn.setObject(mObj)
om.MDagPath.getAPathTo(mObj, dPath)
path = dPath.fullPathName()
if ( re.search(repattern, path)):
depFn.findPlug("castsShadows").setBool(True)
count = count + 1
iter.next()
end = time.time()-start
print ('api = %s sec, %s shapes modified' % (end, count))
# maya.cmds based
start = time.time()
sel = cmds.ls( pattern )
count = len(sel)
for each in sel:
cmds.setAttr("{0}.castsShadows".format(each), 1)
end = time.time()-start
print ('cmds = %s sec, %s shapes modified' % (end, count))
On Tue, Aug 7, 2012 at 11:55 AM, Justin Israel <[email protected]> wrote:
>
> I've been playing with cython lately on another project, and I decided to see
> what would happen if I did some Maya operations with it.
> I made a really contrived example of wildcard selecting over 5000 spheres and
> doing some string filtering to the results before returning a list.
> Interestingly, cython gave at least a 35% speedup over the Maya Python API
> 2.0 approach.
>
> Makes me think that a lot of more specialized operations could be heavily
> sped up that way by moving them over into a C++ environment of execution.
>
>
>
> On Sun, Aug 5, 2012 at 8:52 PM, Matt Estela <[email protected]> wrote:
>>
>> Damnit. :/
>>
>>
>> On Monday, August 6, 2012, Justin Israel wrote:
>>>
>>> Yea, it was introduced after Maya 2012. Marco is right though, it is even
>>> faster:
>>>
>>> import maya.api.OpenMaya as om2
>>>
>>> start = time.time()
>>>
>>> search = "nurbsSphereShape*"
>>> sel = om2.MGlobal.getSelectionListByName(search)
>>> depFn = om2.MFnDependencyNode()
>>>
>>> for i in xrange(sel.length()):
>>> mObj = sel.getDependNode(i)
>>> depNode = depFn.setObject(mObj)
>>> depNode.findPlug("castsShadows", True).setBool(True)
>>>
>>> end = time.time()-start
>>> print ('api2.0 = %s' % end)
>>>
>>> # api2.0 = 0.123915910721
>>>
>>>
>>>
>>>
>>>
>>> On Aug 5, 2012, at 7:31 PM, Matt Estela wrote:
>>>
>>> We're locked to maya2011, API2.0 is a 2012 thing right?
>>>
>>>
>>> On Monday, August 6, 2012, Marco D'Ambros wrote:
>>>
>>> the first question is:
>>>
>>> did you use the api 2.0 or the "normal one"?
>>> the new api suppose to be faster ( almost 3 times more ).
>>> --------------------------------
>>> Marco D'Ambros
>>> phone : (+61) (0) 435809628
>>> web : www.marcodambros.com
>>> mail : [email protected]
>>>
>>>
>>>
>>> On Mon, Aug 6, 2012 at 11:00 AM, Justin Israel <[email protected]>
>>> wrote:
>>>
>>> Ah, I figured it out. The 'add' method using a wildcard on a MSelectionList
>>> is super slow. If you use MGlobal to fill the list for you, it apparently
>>> does it more efficiently:
>>>
>>>
>>> start = time.time()
>>>
>>> search = "nurbsSphereShape*"
>>> sel = om.MSelectionList()
>>> om.MGlobal.getSelectionListByName(search, sel)
>>> iter = om.MItSelectionList(sel)
>>> depFn = om.MFnDependencyNode()
>>> mObj = om.MObject()
>>>
>>> while not iter.isDone():
>>> iter.getDependNode( mObj )
>>> depFn.setObject(mObj)
>>> depFn.findPlug("castsShadows").setBool(True)
>>> iter.next()
>>>
>>> end = time.time()-start
>>> print ('api = %s' % end)
>>> # api = 0.212560892105
>>>
>>>
>>>
>>> On Aug 5, 2012, at 5:36 PM, Justin Israel wrote:
>>>
>>> This is an interesting approach:
>>>
>>> start = time.time()
>>>
>>> cmds.select('nurbsSphereShape*')
>>> size = len(cmds.ls(sl=True))
>>> cmds.setAttr(".castsShadows", *(1 for _ in xrange(size)))
>>>
>>> end = time.time()-start
>>> print end
>>> # 0.243406057358
>>>
>>> ... Though an extra slow down happens if you have to deselect.
>>>
>>>
>>> On Aug 5, 2012, at 5:17 PM, Matt Estela wrote:
>>>
>>> (cc my reply to the group)
>>>
>>>
>>>
>>> On Mon, Aug 6, 2012 at 9:16 AM, Matt Estela <[email protected]> wrote:
>>>
>>> Yeah, again it was a contrived example, in production lighters will
>>> definitely be using whatever bizarro wildcards they can muster.
>>>
>>> As you say it appears to be a core limitation of wildcards, will have to
>>> rethink how we let lighters define object selections. In this case maybe we
>>> just can't let lighters use wildcards, instead they'll have to pre-define
>>> it using sets. Or possibly pre-filtering to specific object types, and
>>> running list comprehensions on that.
>>>
>>> Hmm, houdini's smart bundles would come in handy here... (dynamic sets
>>> based on wildcards, they run surprisingly fast)
>>>
>>> Thanks again for the help Justin, you saved me several days worth of
>>> research. :)
>>>
>>>
>>>
>>>
>>> On Mon, Aug 6, 2012 at 5:15 AM, Justin Israel <[email protected]>
>>> wrote:
>>>
>>> Ya, in some cases you can't beat the python commands module if you are only
>>> doing a single command. Most of the work is happening behind the scenes in
>>> C++. The wildcard searches just appear to be beasty no matter what.
>>>
>>> But considering you didn't need a wildcard pattern, and instead just want
>>> to say "Apply to all nurbsSurface objects under this root:
>>>
>>> #
>>> # cmds
>>> #
>>> start = time.time()
>>> sel =cmds.listRelatives('|set', ad=True, type="nurbsSurface")
>>> for each in sel:
>>> cmds.setAttr("{0}.castsShadows".format(each), 1)
>>> end = time.time()-start
>>> print ('cmds = %s' % end)
>>> # ** cmds = 0.290652990341 **
>>>
>>> #
>>> # api
>>> #
>>> start = time.time()
>>>
>>> sel = om.MSelectionList()
>>>
>>> --
>>> view archives: http://groups.google.com/group/python_inside_maya
>>> change your subscription settings:
>>> http://groups.google.com/group/python_inside_maya/subscribe
>>
>> --
>> view archives: http://groups.google.com/group/python_inside_maya
>> change your subscription settings:
>> http://groups.google.com/group/python_inside_maya/subscribe
>
>
> --
> view archives: http://groups.google.com/group/python_inside_maya
> change your subscription settings:
> http://groups.google.com/group/python_inside_maya/subscribe
--
view archives: http://groups.google.com/group/python_inside_maya
change your subscription settings:
http://groups.google.com/group/python_inside_maya/subscribe