GafferHQ / gaffer

Gaffer is a node-based application for lookdev, lighting and automation
http://www.gafferhq.org
BSD 3-Clause "New" or "Revised" License
958 stars 206 forks source link

Instancer enhancements #957

Open johnhaddon opened 10 years ago

johnhaddon commented 10 years ago

We could break these out into subtickets if we decide some are higher priority than others...

carstenkolve commented 10 years ago

another option might be to allow the instancer to recurse through a whole hierarchy (starting at a specific level) and then instance based on any pointsdata it might find

carstenkolve commented 10 years ago

pref for partitioning seems very inconvenient (most likely we are talking about fx generated data here, which might need lots of postprocessing to arrive at a good pref) - another option could be a 'cluster'/'partition' int attrib (assuming the partitioning is done in the source dcc); seems kind of the similar to traversing through a hierarchy of pointsprimitives, though

johnhaddon commented 10 years ago

Spatial partitioning would be very handy for layouts though. You'd just scatter a bunch of points on your surface, and the Instancer would automatically make partitions that are useful (so you can expand just the sections in your area of interest).

An int attribute (primitive variable) sounds like a useful feature too though - perhaps we'd just make a node which assigned partitions based on PRef, and then we could easily support both methods?

Do you see any need for partitioning multiple levels deep?

carstenkolve commented 10 years ago

partition primvar it is then :-)

what do you have in mind when partitioning multiple levels deep?

A) multiple primvars with a naming convention for levels ('partition_0', 'partition_1' etc) ? B) a hierarchy of pointsprimitives, all with a 'partition' primvar (and you do your instancing based on a parent level)?

can't see much of a use for A) that could not be addressed via a single primvar, but B) could be handy

johnhaddon commented 10 years ago

Well, my thinking all stems from thinking spatial partitioning is the most useful, because I'm coming at it from a layout rather than FX standpoint. With spatial partitioning it's fairly natural to use a KDTree or similar with a fixed size per leaf node, and then use the hierarchy of the tree as the hierarchy of instances (although it might be preferable to have more than 2 children for each of the intermediate levels).

If we do drive partitioning only with a primvar and we want to keep a natural hierarchy we'd have from the KDTree/PRef method, then we'll need a way of encoding the hierarchy into the primvar - so some form of A). If we have a limit on partition sizes and hierarchy depths then we could do it with a single int level0 * 1000000 + level1 * 1000 + level2?

I think B) is useful in its own right too - since the Instancer shares a base class with a bunch of other nodes, it'd mean that those nodes would gain the ability to target multiple locations as well. So you could potentially Parent, Seed and Duplicate under multiple locations - that would be very nice for procedural layout.

In approach B, will the hierarchy of PointsPrimitives be supplied by FX, or will Gaffer need to partition a single PointsPrimitive into the hierarchy before applying the Instancer? If the latter, then we'll need a node for applying partitions in both method A) and B) anyway.

carstenkolve commented 10 years ago

A) ok - I see where you are coming; though is the 'single int method' vs 'multtiple primvars' method generic enough (as you are limiting yourself to the levels you could put into an int - big as that range may be) ? ... this kind of plays into the idea of recursive setups that you might want to terminate not only based on a predefined hierarchy depth, but on a execution time decision (size of the bbox in screenspace etc.)

B) I think both can be true, FX (at least in Houdini) certainly has a number of tools to pre-partition points primitives based on arbitrary rules; but I can also see a potential for a node to do partitioning as well (maybe with different options serving all the use cases mentioned in this thread, or one that restructures an incoming points primitive based on a primvar attrib (basically what you said))

johnhaddon commented 10 years ago

I wasn't super happy about my encoding-multiple-levels-into-one-int idea for the same reason you mentioned - the limits. But I also find the one-primvar-per-level-in-the-hierarchy method to be pretty clunky and a bit wasteful.

A third option might be to actually use a string primvar /path/to/partition. We wouldn't want to store a string per point, but we could have an array of unique strings and index into those with an integer per point (i think houdini does this for string attributes anyway?). We could view this as an extension of the original partition index primvar idea - without the string array the integers specify the names of the partitions directly, and with the strings we can add control over the naming. It seems like we should be able to support both cases with the same code, so the strings would be optional. How does that sound?