Hey guys,
I am implementing a Grasshopper plugin that generates building geometry given an initial shape and a file containing rules that leads the generation. In these rules can be defined report values that are used to analyze the generated buildings. These report values could be anything like the area of each floors, number of floors, the usage of the building and so on.They are computed during the geometry generation process and passed to the plugin in the form of a two level map that looks like this:
{ InitialShapeID → { reportKey → reportValue } }.
The objects don’t necessarily have the same number of keys and it should be clear to which object corresponds each key and value.
I explored several ways to output these values but I am not sure about the best way to do it yet. So my question is: is there a typical way to outputs these kind of data structures in grasshopper?
Here is a screenshot of how these values are outputted for now:
In this case there are two initial shapes as input. I processed the map to group the values by reportKey. I created an output for each key and assigned a list of value, each value corresponding to a single initial shape.
The issues with this approach are that the number of outputs can be quite high, leading to a very big component. Moreover, when there is a lot of initial shapes, it is not clear which value corresponds to which shape.
Another solution could be to output a single DataTree, each branch being the reports of one initial shape. But again, it would be difficult to read for the user.
I think this particular problem is not really a problem, since it’s the “standard” way of dealing with multiple data in grasshopper. If an index 0 of an input is also index 0 of the output, then that is as good as it gets.
When you get into really big problems is instead if/when you mix the “pure data processing” with the UI presentation.
In the case above, keeping indices (input - output) in balance, then you - as a plugin developer - can do more smart things down-streams with your data. If you mix that “pure” data with UI tricks (to become human readable), then you will quickly find yourself at the “end of the rope” and further development based on the raw data will be more difficult.
What you can do instead is to make additional components to handle the “human readable” part, like pairing together input with several outputs so that the user knows what output data belongs to what input data. In this way the data processing and the presentation of the data are not messed up making it difficult to further develop your system.
This approach is BTW also an option for all the outputs shown in the image above, namely that you can create your own internal data structure and then sending the whole structure to one single output (as a big “blob”), and then have several small components reading data from that big blob and presenting a subset of the outputs. Those outputs components can probably be grouped by some semantics into separate output categories/components. And so on, and so on.
In any case, I would handle the UI friendliness in separate components and keep the raw data as clean and structured as possible, not messing it up with UI stuff.
I’m not entirely clear how the inputs and outputs relate to each other here, but the usual way to reduce the number of inputs/outputs is to create a custom data type which wraps up a bunch of values. For example to keep the Loft component small, I added a special Loft Properties data type. Then you’ll also have to create additional components for constructing these value aggregates.
Looking at your component, it seems as though it would make sense to wrap up the [Average, Max, Min, N, Sum] values into a single block, and then your output count drops by a factor of five. You’ll need an additional component which accepts one of these aggregate values and breaks it down further into actual numbers.