(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() >> dagFn = om.MFnDagNode() >> mObj = om.MObject() >> dagIt = om.MItDag() >> >> sel.add("|set") >> sel.getDependNode(0, mObj) >> dagIt.traverseUnderWorld(True) >> dagIt.reset(mObj, dagIt.kDepthFirst, om.MFn.kNurbsSurface) >> >> while not dagIt.isDone(): >> curr = dagIt.currentItem() >> dagFn.setObject(curr) >> dagFn.findPlug("castsShadows").setBool(False) >> dagIt.next() >> >> end = time.time()-start >> print ('api = %s' % end) >> # ** api = 0.117326021194 ** >> >> >> >> >> On Aug 5, 2012, at 7:01 AM, matt wrote: >> >> Hmm... did some experimenting. Using your example as a base, I compared >> modifying the castsShadows attr on 8000 spheres. I have them grouped in the >> following way: >> >> `-- set >> |-- a >> | |-- nurbsSphere0001 >> | |-- ... >> | `-- nurbsSphere4000 >> `-- b >> |-- nurbsSphere4001 >> |-- ... >> `-- nurbsSphere8000 >> >> I get very similar results for both api and maya.cmds. Interestingly, I >> get an incredible slowdown depending on how specific/general I am with the >> search: >> >> search = set|*|*|nurbsSphereShape* >> >> api = 27.6180000305 >> >> cmds = 27.018999815 >> >> >> vs >> >> >> >> search = nurbsSphereShape* >> >> api = 0.956000089645 >> >> cmds = 0.403000116348 >> >> >> This is my first few hours playing with openmaya, already made some silly >> mistakes (defining function-sets inside the loop is waaaay slower than >> outside the loop), but wondering if there's something else I'm missing... >> would appear wildcards should just be avoided at all costs. Here's my >> contrived example: >> >> >> >> import maya.OpenMaya as om >> >> import maya.cmds as cmds >> >> import time >> >> >> #search = "set|*|*|nurbsSphereShape*" >> >> search = "nurbsSphereShape*" >> >> >> print ("search = %s" % search ) >> >> >> # API based >> >> start = time.time() >> >> >> sel = om.MSelectionList() >> >> sel.add( search ) >> >> 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) >> >> >> # maya.cmds based >> >> start = time.time() >> >> sel = cmds.ls( search ) >> >> for each in sel: >> >> cmds.setAttr("{0}.castsShadows".format(each), 1) >> >> end = time.time()-start >> >> print ('cmds = %s' % end) >> >> >> >> >> >> On Sunday, August 5, 2012 9:14:06 AM UTC+10, matt wrote: >>> >>> Wow, definitely seems worth investigating. Thanks for the code snippet >>> and timing info! >>> >>> On Sunday, August 5, 2012, Justin Israel wrote: >>> >>>> As a random example...I created a nurbsSphere, and just simulated >>>> looping over 5000 objects and setting and attrib. >>>> >>>> import maya.OpenMaya as om >>>> import time >>>> import maya.cmds as cmds >>>> >>>> sel = om.MSelectionList() >>>> om.MGlobal.**getActiveSelectionList(sel) >>>> iter = om.MItSelectionList(sel) >>>> >>>> obj = om.MObject() >>>> depFn = om.MFnDependencyNode() >>>> >>>> start = time.time() >>>> for i in xrange(5000): >>>> iter.getDependNode(obj) >>>> depFn.setObject(obj) >>>> depFn.findPlug("tx").setInt(4) >>>> end = time.time()-start >>>> print end >>>> # 0.0979061126709 seconds >>>> >>>> start = time.time() >>>> for i in xrange(5000): >>>> name = "nurbsSphere1" >>>> cmds.setAttr("{0}.tx".format(**name), 4) >>>> end = time.time()-start >>>> print end >>>> # 0.261173009872 seconds >>>> >>>> >>>> >>>> >>>> On Aug 4, 2012, at 12:22 PM, Justin Israel wrote: >>>> >>>> Some of the big speed increases are using the iterators and not having >>>> to do a bunch of string operations on dag paths. And the math speedups from >>>> using the OpenMaya objects with operators. >>>> >>>> Your best bet it to just profile some small tests. You can easily make >>>> use of the python `timeit` module to check the difference in speed of >>>> operations. >>>> >>>> >>>> >>>> On Aug 4, 2012, at 10:53 AM, matt wrote: >>>> >>>> Apologies for the crosspost for anyone on maya_he3d, only remembered >>>> this group existed seconds after I posted over there... Have tried to edit >>>> and re-word for you smart people. :) >>>> >>>> Short version: >>>> Would using the python OpenMaya module give big speed gains for selecting >>>> thousands of objects and modifying their attributes? >>>> >>>> Long version: >>>> We have a python based, text based render pass submission tool for >>>> lighters at work. One of its core functions is grabbing whatever >>>> geometry is defined by a lighter, and setting attributes. This >>>> sometimes means adding attributes first (or connecting our custom attribute >>>> node), then setting them. >>>> >>>> We're getting into the situation where we have _very_ heavy scenes, with >>>> thousands of objects. Normally our system will process these scenes within >>>> a minute or two per frame, if lighters use wildcards, eg 'set:tree*', >>>> that can jump to maybe 6 mins per frame. Not too bad. >>>> >>>> Things get messy with our alembic style heirachical geo format. It can >>>> contain many sub-objects, which our maya plugin doesn't allow us to list or >>>> search for sub-objects names easily. Thus, if a lighter wildcards to the >>>> sub-object level, eg "set:*|leaves*", the only safe way to do that is to >>>> process every object, then every sub-object, unsetting atts those objects >>>> which AREN'T leaves, and setting attrs on those objects which ARE leaves. >>>> When this happens, processing jumps to 3 hours per frame. Yuck! >>>> >>>> In the short term we're getting lighters to be more careful with >>>> wildcards, in the mid term getting assets collapsed down so they're not so >>>> name and sub-object heavy, and in the long term getting our geo plugin more >>>> inspectable. So that's good. >>>> >>>> I was curious though.... could this be helped in the short(ish) term by >>>> re-writing that part of the code with the OpenMaya module? I recall >>>> reading there's many things which are faster, a few which are slower, >>>> and fewer still which have no OpenMaya equivalent and can only be done in >>>> mel/python. I have a sneaking suspicion one of those slow things was >>>> something fundamental like selection, but I'm hoping I'm wrong. >>>> >>>> Was curious if the basic idea of 'yeah, manipulating hundreds of >>>> objects and their attributes is N times faster with OpenMaya' is worth >>>> pursuing. >>>> >>>> -matt >>>> >>>> -- >>>> view archives: >>>> http://groups.google.com/**group/python_inside_maya<http://groups.google.com/group/python_inside_maya> >>>> change your subscription settings: http://groups.google.com/** >>>> group/python_inside_maya/**subscribe<http://groups.google.com/group/python_inside_maya/subscribe> >>>> >>>> >>>> >>>> >>>> -- >>>> view archives: >>>> http://groups.google.com/**group/python_inside_maya<http://groups.google.com/group/python_inside_maya> >>>> change your subscription settings: http://groups.google.com/** >>>> group/python_inside_maya/**subscribe<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
