GhPython: Multiple Inputs are all given same list length when input to functions

I am struggling to understand how Grasshopper and GHPython are handling multiple inputs. I need to understand this before I can really build out a lot of my script.

Context

  • I want to build a function (example: area calculations) that can be used across multiple inputs: devs, plots, buildings.
  • I will be writing a bunch of similar functions that need to be applied in a similar way across all the geometry inputs.

Problem:

  • The 3 inputs are all “cycled” over in the ghPython component to the longest list length.
  • example: devs = 3 items, plots = 4 items, buildings = 8 items. But They all get the function applied 8 times (longest set of items) meaning that the last item is duplicated repeatedly.

Hunch
I suspect I’m misunderstanding something fundamental about multiple input treatment in the ghPython component. I’ve written the function to be encapsulated, but this might not be working. Do i need to make it a class in python?

I already referred to the post by @piac about accessing item/list/tree. However I tried writing functions for ITEM and LIST and the problem wasn’t solved.


MassDataMaker_SentOut.gh (20.7 KB)

Are you looking for something like this:

import Rhino as rc
def rcArea(c):
    if c:
        rcAreas = rc.Geometry.AreaMassProperties.Compute(c)
        return rcAreas.Area

dev_areas = []
for dev in devs:
    dev_areas.append(rcArea(dev))
plot_areas = []
for plot in plots:
    plot_areas.append(rcArea(plot))
building_areas = []
for building in buildings:
    building_areas.append(rcArea(building))


MassDataMaker_SentOutRe.gh (17.2 KB)

Hi @D.Ronald,

The problem is that you input a lists of data, in your case curves, with your inputs all set to Item Access, which leads to the GHPyhton component executing your script for every item separately! Switch the inputs where that you provide lists to, to List Access.
Also in Python 2.7, print is not a function. It’s written print "Print me, daddy".

Hi Darrel

this is standard Grasshopper “longest list matching”, and the rules have been applied to this since Grasshopper inception*.

For multiple inputs, Grasshopper always provides the 1st item of the 1st branch of the 1st input, together with the 1st item of the 1st branch of the 2nd input, together the 1st item of the 1st branch of the 3rd input, etc. Then, it proceeds to the 2nd item of each branch, 3rd item, all the way till items are finished in the current branch. Then, it picks the next branch, and it proceeds again along items in the same manner. If items are missing for this proceeding, the last one is repeated.
If you want to escape from this, you need to request items in lists, or items in trees.

If you request everything in lists (branches), if you have multiple lists running togehter (trees), the component will execute multiple times, once for each path. This might be useful if you have different groups of (for example, buildings in your code) that need to have their areas computed separately.

If you request everything in trees, then the code will run once.

If you mix, you can experiment what happens. For lists and items, for example, each item provokes a cycling, and the list is repeated. The same concept can be applied to more convoluted cases.

One last warning: Grasshopper does not accept lists of lists as outputs, but requires Trees. If you create lists of lists, you can use the ghpytonlib.treehelpers functions to convert a nested list to a corresponding tree. The other way around is also available.

Thanks, I hope this helps,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

* In earlier Grasshopper times, there used to be 2 additional pattern matching strategies that the user could pick: Cross reference, and Shortest list. Now, it’s always Longest list.

Thank you everyone!

I’ve changed all the inputs into lists and reworked the functions to operate on list inputs. So far so good. I remember when GH had shortest and longest list components…

Since I’m building out a script for urban design use:
Next up I need to work on the treehelpers as Giulio suggested. Then I can start combining the data into trees where where groups of geometry are clustered into Development areas > Plots > Buildings . I suspect this will be difficult since I need to calculate which geometries are “within” the others. If anyone has experience with this, I would appreciate a tip on how best to do this.

thanks!