I mentioned in the comments to one of Tom's posts a few weeks ago I've been trying to transmogrify myself into a technical artist -- i.e. one of the guys on a production team artists go to for help with tool deficiencies, automation or to help translate artist-speak to engineer-ese and vice versa. Part of that has been to learn Python and, particularly, PyMEL: the Maya-specific melding of Python with Maya Embedded Language (MEL). It's been a challenging, often-frustrating, but ultimately rewarding experience thus far. I'm heads-down in a lot of books that do their best to make the abstract tangible and the complicated simple. I started learning Python last year and I guess I would say I was a baby in the world of programming then. Now, I'm kind of a toddler looking forward to preschool (not yet ready for kindergarten, I think).
One angle to help me learn has been to take tools written by other techincal artist types and put them through their paces. You'd be surprised what's out there and what has been done with them. I came across the website of Matthew Breit a few years ago. He's a professional game artist who has made several community-celebrated Quake III maps as side projects. One of his maps is a cubist dream set in the sky. While it's a beautiful map in its own right (and fun to play, too), it's also a testament to leveraging technical know-how inside an ancient (in terms of game technology) engine. The Quake III engine (or idTech 3) is 16 years old and certainly not cutting edge. But Breit was able to squeeze out an amazing looking map by using Python inside Maya to supplement Radiant, the spartan toolset used to make levels for Quake. You can read about his design theory here and the technical postmortem here.
Breit released his workhorse script, CubeSpew.py, to the public after he was done with the map for anyone interested in how it worked or who wanted to learn. Curious, I downloaded the script and thought I'd give it a spin to see what I could produce. Breit freely admits the script is presented as-is, with no GUI or documentation other than the comments in the code. I contacted him directly through email a couple of times and he's been nice enough to answer questions, although it's been three years since he's touched the script and has moved on to other things. I only hit him up for bread-crumb clues whenever I was completely and utterly stumped. His answers were not of the 'here's how it works' variety, but were helpful and offered insights into the various functions and methods, which gave me something to chew on as I tried to reverse engineer the methodology.
I've persevered and been able to figure most of it out - but it has been a mind-bending butt-kicker. The script itself is quite organically complex (Breit said it just evolved over the years). It's some 1200 lines of code and not all of it is about building little cubes (although that is the bulk of it). The script evaluates an imported Quake brush (the basic building element of a Quake level) and generates little instanced cuboids of random size on the surface of the brush. Each instanced cuboid is a chunk held in memory inside Maya. You have to manually 'dimensionalize' that chunk (and all subsequent chunks) as a Maya 'polyCube' that can be digested back into a Quake brush when you export your work back to Radiant for an eventual playable Quake build. Each cuboid-turned-polyCube will be flush to whatever side/surface of the larger block you specify as reference. The little cuboids are randomized, yet all fit together like Tetris-pieces on the surface.
When creating the cuboid with the Python script, the instance that is created also stores texture alignment data which can be filtered via command line. The resultant output is five coordinate values you input into Radiant's texture alignment tool if you want to mimic the kind of precise UV alignment you would get using Maya's UV editor. That's only necessary if you are trying to get better edge definition with Quake III's shader system. This is all very Quake-and-Radiant-specific workflow stuff. You probably wouldn't do the texture alignment this way in another engine. You're kind of forced to do it this way with Quake III as it doesn't treat brushes the same way Maya handles polygonal meshes.
Parts of the script are for importing/export brushes from Radiant, and I had to figure out how that works. Parts of the script generate the coordinates for surface texture alignment inside Radiant - had to also figure out how that works. My initial discovery was that I had to fall back to an older version of Maya. Maya 2016 uses a different version of Python which breaks the math in the script. Luckily, I have Maya 2012 and the script runs there, so that's what I've been using.
So...I don't really have any sweet screenshots or anything to show (yet) but I'll post one that shows that I can now spew cubes with the best of them:
This has been a very rewarding (and often frustrating) experience. It really forced me to dig in and think. Ultimately, I feel I did learn a LOT - and I'm still learning. And now I have a greater appreciation for more advanced and user-friendly tools like Unreal 4 and Unity that are more powerful and have easier workflows.