User functions FTW

Here I am, few days later talking about user functions in Janus again. Why not? It’s been giving me results and it’s fun to play with — as a TD, I mean.

Back at work I wanted to output an RGB matte for multiple instanced object. LW doesn’t have a way to do a scene-based surface override on an object (perhaps shaderMeister?– though I don’t know if it the Spot Instance node will work with it). Basically, I wanted an easy way of assigning RGB colours to items in a particular group.

Before, Janus’s item processing was strictly group-oriented, where group settings were simply propagated to the items. There was no way to individually and programmatically affect certain items within the group. So in the latest rev, I changed that. But the important bit was that I tied it (again) to user functions, and I embedded a new context — the group item context — through populating two constant variables relating to the group item’s index and name. In this way, the user function can be created that references the group item’s index, and based on that value, the command parameters can be changed on that particular item as it is being processed. It’s basically a ‘last minute’ change in the render pass settings just before the group item is applied its parent group settings.

Since user functions are basically string replacements from within the cmd line, there’s a lot of flexibility (but can also end up a heaping mess if the Janus user doesn’t watch it), so that I can dynamically various bits of settings; I’m not limited to adding one parameter, for example, because I can just concatenate the new subcommands in the return string; so as along as the final resulting cmd line is syntactically valid, Janus will grok it.

Janus for Mac

It’s a bit too early to shout out, so I’m whispering here in my little blog about Janus for Mac. I’ve restarted development for the Mac. It basically just took a weekend to hunker down and sort what was going with it.

The biggest issue that I came up with was the use of LScript’s store() and recall() functions, where in Windows it uses the registry to store the information. In the Mac, I’m not sure where it ends up, but apparently, calling it those functions multiple times seemed to put LW in a state where it could no longer stream more files into memory. It was as if the i/o was full.

I avoided this by redirecting the functions; this was already facilitated by the fact that they were already housed in custom functions, and all I had to do was make it everything cohesive. I also cleaned up the code so that the array that Janus uses to store settings were more consistent, and that the PC version should remain unaffected by the change.

At this point the Mac seems to be very workable, and I’m probably going to do a few iterations of tests in the coming weeks. And who knows? — it may come out officially soon after that.

User functions revisited

User functions have come back, and what seemed to me at the time an excuse to implement a structure that’s both ambitious (because it wishes to liken itself to Houdini) and hacky (because it ain’t Houdini), seems now to have been vindicated.

Talking about user functions is like talking about… well, nothing analogous I can pick out: no one relates to it, not because it isn’t uncommon — cg ops use it all the time in other progs — but because it’s in Janus, and thus LW, and among the LW crowd, it’s weird.

But then I contact this person asking for some scripting help; he’s made his assets and scenes, and needs a way to break out passes; I learn about what he particularly wants, and think Janus fits the bill, albeit requires a bit of modification to get the exact workflow. I ponder how much modification is needed. Then I realise that I already have a system of user customisation in Janus: user functions. But user functions, prior to this new development, was only in the realm of the more broad render pass settings (eg subcommands, and the cmd line). What was needed was to expand the same functionality to partial surface overrides, which were contained in text files.

This modification — user functions implemented in partial surface overrides — was done in one night, because there wasn’t much fudging of code; the functions were all there, and all I needed to do was apply the right timings so that the parsing functions didn’t fall on top of one another, and that the proper variables were being populated first before passing it on to the user function. So now, using the very system I made for Janus users, I’m using that system to get unique results instead of hard-coding things in.

I’m very grateful, and again, feel vindicated, that by not taking the easy route, by sticking to the vision I had for Janus, I am seeing the result of the flexibility, which I had hoped would be more evident to LW users. While I still inwardly bemoan the fact that Janus is not a very popular tool, it’s hard to feel sorry for it when its proving itself up to task in more and more situations.