With the wife so busy lately putting together her website I’ve had some time to download Maya 2016 ext 2 and play with the new MASH system.
I’m still very much in the learning stage so not a lot to say other than you should have a play with it, it’s super powerful and a lot more fun than writing endless (and sometimes complex) expressions to achieve simple tasks in MASH.
This post is an update to particlesToBubble which was a script that would build nCloth bubbles from a particle system. The new version isn’t finished yet but here is one of the R&D tests I just finished. This is currently only using one Alembic cache to process the 200+ bubble systems with 36 bubbles per system running with a random offset. The repetition is noticeable but this could be offset by a longer cache or multiple caches. One of the more interesting tests was figuring out how to capture the nCloth tear into a cache file since the nCloth shape layer has ever changing vertex values. I will post more about the process soon as well as the python script, but for now here is a quick playblast of the progress so far.
I go back and forth between the default Maya Marquee and Drag tools with camera based selection so often that I thought I’d write a quick run-time command to make a hotkey. Here is a quick video to demonstrate how you could do this. I was talking to an old colleague the other day who asked if Maya had gotten rid of the component selection, which I believe it was on by default when you moved the mouse over an edge, vertex, or face in older versions of Maya. It’s still there, but now found under the ‘drag’ option’ which you also have the ability to toggle.
I find that a lot of people write about a final outcome, or maybe a thought, so this time I figured I’d look at a process that I went through today, which isn’t dissimilar to processes that I go through everyday to make tasks in my life simpler. I just thought this was a good example of one idea being worked on and then presented to an outsider and seeing how we can make a working solution better.
During my typical workflow I try to break a big project into several smaller tasks to simplify complicated jobs. While breaking down a task today I ran into another issue – the time it takes to complete that task. Here’s the breakdown: I have 50 blend shapes with very complicated parts and pieces. On each of those blend shapes I need to grab the same vertices every time, then manipulate the verts. For the first round I decide that I will make my selection and save it as a ‘SET’ (Quick Selection Set) so that I have all the data available later.
The beauty of blendshapes is that you have to have the same vert count which means they have the same vert ID too. So with that in mind your verts end up with a name like myVert.vtx – myVert.vtx (assuming you had 100 verts). I had around 40k+ verts in each selection. My first thought was to take the set that I had created and split apart the ‘myVert’ and ‘vtx’ from myVert.vtx, giving me the ability to add something new to the front of ‘vtx’. With the split command in python this is very simple, you can then replace ‘myVert’ with something else (like ‘otherObj’), which could also be the name of the next blendshape I want to edit. Pretty simple, right?
The code worked fine, the problem was that it took 25 mins to parse through the whole set of 40k verts, break the name apart, assign the name of the new object and then individually select each and every vert on that object.
In the background this is what is being selected in the UI:
theList = [u’myVert.vtx’, u’myVert.vtx’,…]
Because this is selected the getList variable will pick this up and assign the list to that variable.
import maya.cmds as mc getList = mc.ls(sl=True, fl=True) getObj = mc.ls(sl=True, tr=True) for obj in getList: vertNum = obj.split('.') mc.select(getObj + "." + vertNum, add=True)
Looking at the list you'll see 40k objects in it. Maya will do a clever thing (and I use that word sparingly with Maya as the user usually has to out wit the program...) - if it sees that there are long lists of values that are sequential it will concatenate them into something like this:
theList = [u'myVert.vtx[0:50]', u'myVert.vtx[51:99]']
Your result is that rather than having 100 objects in the list it now has 2.
So now you ask, why this didn't happen in the list above? It's because in the past I've had issues when I don't use the 'fl=True' flag in the ls command. For those who don't know, ls is short for List and fl is short for Flatten. What this does is look at each and every item in an array. I've had plenty of situations where an element runs through a loop and doesn't get processed correctly, so my brain has since been hard-wired to always add this flag.
Another question you might ask is what happens when you remove:
getList = mc.ls(sl=True, fl=True)
Well, the process time goes from 25 mins to 25 seconds. The list did shrink from 40k to 70 which means that it had less to iterate through in terms of physical list items. It did however still have to calculate all the values that get truncated. That means that the values between the ':' get calculated faster or differently then listed values, the answer may lie in the API or even something deeper within python. I had time to solve one issue today but unfortunately not enough to look through this one. I'll save it for a rainy day 😉
Let me back up for a second. I wouldn't have come to this conclusion had it not been for a colleague of mine - I have the luxury of working around a group of very talented developers (non 3D developers), something I'm not all that accustomed too. While explaining what was going on I stumbled across the flag, and so removed and tested it to explain what it did. As a result with such a significant time difference after taking the flag out of the code we sort of left the conversation as it stood.
With my times dropping from 25 minutes to 25 seconds I thought I would just ask someone else to see if they could come up with an even faster solution (hey, why not?). Really at this stage it was just trivial but I wanted to see if there was something a bit more elegant. As it turned out my supervisor had another view to the solution:
import maya.cmds as mc object_name = mc.ls(sl=True, tr=True) mc.select('test') verts = mc.ls(sl=True) #select the verts from list verts = mc.select('test') vertnums =  for vert in verts: tmp,v = vert.split('.') vertnums.append(object_name + '.' + v) mc.sets(*vertnums, n='newSet') mc.select('newSet') mc.delete('newSet')
I had to stop him here as he was already opening the docs for the Maya API, determined he could make it even faster. This almost does the same thing, except that rather than splitting the values apart and then selecting each vert he pushed all the new data into a new list and applied it to a set. The code selects the set and then deletes itself for it's next use. Amazingly this dropped the time to about 1 second of processing. Not a bad turn around for 30 minutes of goofing around with some code! It also proves an interesting point I commonly see online where users ask if there is a faster way to approach a problem, granted this is a simple obstacle. In my experience when you're up against a brutal deadline you just try to find a solution and use it - so even if it took me 25 minutes to make the selection I probably wouldn't go back to solve the issue because I don't know how long that would take. It's still a faster process than selecting each vert on a complex item (not to mention it takes the absolute boredom out of a mundane process!).
I guess the reason why most people don't write about the process they go through to solve problems like this is that it generally takes longer to explain the process than the evolution of the process. After working in CG for almost a decade now it's fun to look back and try and remember how or why I needed to solve these problems. It all merges into a blur with a bad diet and lack of sleep, as I'm sure anyone in this profession would agree!
Sometimes when I’m working along in Maya I come across some little issue that could easily be resolved if the object was either transparent or another color, enabling me to view it against a background or objects in the scene. In this particular case I was trying to learn about xGen’s hair system and applying different dynamic properties to it. My object was blue, and the Maya work-space color is blue(ish), and deselected curves are again, blue, so it can get pretty muddy.
To fix this I will often grab all the objects and do a mass change on them while working to make it easier to see what I’m doing. In this case I only had about 20+ hair curves to update, but obviously I still didn’t want to go through and do it manually! Using python or MEL I can write a bit of code and loop through all the hair curves colors to see what works best. The result makes it very simple to see all the dynamic changes being applied.
Use the code below to change the colors of a lot of curves all at once. This will also change poly edge colors (and I’m sure many other objects as long as it’s shape layer has the attribute “Drawing Overrides” in it):
#change all curves to a new color import maya.cmds as mc getCurves = mc.ls(sl=True, o=True, dag=True, s=True) for curve in getCurves: mc.setAttr(curve + ".overrideEnabled", 1) #overrideColor is the command to change the color value, 13 red. mc.setAttr(curve + ".overrideColor", 13)
If you copy and apply this in the script editor in Maya you might find it doesn't work because of the formatting. Start by removing the indent in the loop and adding it again.
Tags3D 360 Pano After Effects ATOM Batch Render Options Bottle Jack Press Breakdown Compositing computer concept Dig-It! Fluids Games Grenada Gui Boratto Hair System hardware HDRI Houdini Illustration Mantra Maxwell Render Maya MEL Mental Ray Mudbox Natron new build Nodal Node Editor Particles PFTrack Photography Ptex Pyro Python Render Current Frame Options Road Trip Scripting Tips Toon Shader VFX Wireframe Work xGen