For Loops in Janus

In the recent 1.7 release of Janus I’ve implemented For Loops, which is a way to get a looping construct in the Janus context. It’s rather interesting, and it all came because a prospective (Janus) client emailed me one day asking me if it was possible to procedurally tell Janus to replace objects in a specific directory. There was none at the time, and the solution to that was to either to create render passes dynamically via definition files, or use composite command types. He was happy enough for such a solution. But for my part I felt things could be done better: it was still not procedural insofar as the generation of the data strings was external to Janus: what I wanted to do was get something procedural so that extra scripting was not necessary to do these sort of things.

Enter For Loops, which are represented as subcommands. For Loops tell Janus to ‘recycle’ the render pass (similar to what composite command types already do). In For Loop ‘recycling’ the render pass is internally duplicated; this duplicate passes through a string filter and replaces variable names which are a specific subset for the given For Loop. This contextualises the data that is being accessed; if the loop is around a directory, for example, then you can’t use the variable to get file line information, etc. However, being a construct, they do share some data, such as the iterator; perhaps more can be added in the future.

The prospective client didn’t end up getting Janus, though, as it often happens. But the great thing about it is his question sparked a good idea in my brain. It may also have been through my exposure with Houdini and its Wedge ROP that I’ve implemented it the way I have. These emails from prospecting clients was the root of another less-known feature of Janus called Dynamic Mesh Combining, which combines two or more mesh items into one and it does so during breakout so that the master scene is not modified in any way. Dynamic Mesh Combining came because a person asked me how to prevent shadows from being cast by separate shadow catcher. The only solution to his specific problem was to combine all of his shadow catching objects into one and then turn the Self Shadow render flag off. Because combining meshes is a tedious task, why not implement it?