2

I'm a beginner in Python and have a question about converting data structure, for using it in Grasshopper.

As an output from my python code, I have a grid of cubes (GUID's), layered up in what I call 'generations'. Besides that, it outputs a grid of data, which contains the information about what color each cube should get.

For example: for j=5 in i=3, in generation=5, I have a cube. In the other list, for j=5 in i=3 , in generation=5, I have 'green' as a string. In grasshopper, I want to link this 'green' value to a swatch, and then color the right cube with it.

The problem is that Python outputs a three-dimensional array, while Grasshopper works in trees. So, I have to convert my outputs to a tree structure in which the first level is 'generations', the second level is 'i' and the third is 'j'.

A friend sent me this piece of code, so I guess that is how to begin:

import clr clr.AddReference("Grasshopper") from Grasshopper.Kernel.Data import GH_Path from Grasshopper import DataTree

I hope you guys can help! Tessa

This is my mainfunction:

def Main():
    intLength = input1
    intWidth  = input2
    intGen    = input3
arrValues = randomizeArray01(intLength,intWidth)        
arrDensity = densityfunction(arrValues)
arrMeshes = render(arrValues,-1)                        
for k in range(intGen):
    arrValues = applyGOL(arrValues,arrDensity)          
    arrDensity = densityfunction(arrValues)
    genC = colorObject(arrValues)
    colorList.append(genC)
    genR = render(arrValues,k)   
    renderList.append(genR)

In which this is the renderfunction:

def render(arrValues, z):
    rs.EnableRedraw(False)
    arrMeshes = []
    for i in range(len(arrValues)):
        arrRow = []
        for j in range(len(arrValues[i])):
            box = addMeshBox([(i-0.5),(len(arrValues[i])-j-0.5),z-0.5], [(i+0.5),(len(arrValues[i])-j+0.5),z+0.5])
            arrRow.append(box)
        arrMeshes.append(arrRow)
    rs.EnableRedraw(True)                               
    return arrMeshes

And this is the colorfunction:

def colorObject(arrValues):
    arrColor = []
    for i in range(len(arrValues)):
        rowColor= []
        for j in range(len(arrValues[i])):
            if arrValues[i][j] == 0:
                color = green
                rowColor.append(color)
            elif arrValues[i][j] ==1:
                color = residential
                rowColor.append(color)
            elif arrValues[i][j] ==100:
                color = retail
                rowColor.append(color)
            elif arrValues[i][j] ==1000:
                color = road
                rowColor.append(color)
        arrColor.append(rowColor)
    return arrColor

And in the end, this is what I output to Grasshopper:

a = renderList
b = colorList

In grasshopper, this gives me a list of 'Iron.Python.Runtime.List'.

Brian Gillespie
  • 3,213
  • 5
  • 27
  • 37
user2115063
  • 23
  • 1
  • 5
  • It's not clear to me what you mean by *As an output from my python code, I have a grid of cubes (GUID's), layered up in what I call 'generations'. Besides that, it outputs a grid of data, which contains the information about what color each cube should get.* or what you mean in your following two paragraphs. If you added example data that you want to convert (you can just type an artificial example in manually) as Python code that we can work with that would help anyone trying to answer – YXD Feb 27 '13 at 11:41
  • 1
    Thanks for your answer! I've added the code, I hope that makes things more clear. Please tell me if you need more! – user2115063 Feb 27 '13 at 12:09

1 Answers1

1

I don't have a working version of grasshopper to hand, but my code for doing this is:

import rhinoscriptsyntax as rs

import Rhino.Geometry as rg
from clr import AddReference as addr
addr("Grasshopper")

from System import Object
from Grasshopper import DataTree
from Grasshopper.Kernel.Data import GH_Path


def raggedListToDataTree(raggedList):
    rl = raggedList
    result = DataTree[object]()
    for i in range(len(rl)):
        temp = []
        for j in range(len(rl[i])):
            temp.append(rl[i][j])
        #print i, " - ",temp
        path = GH_Path(i)
        result.AddRange(temp, path)
    return result

There is a gist of this here that also has a function that turns trees into lists.

There's still quite a lot wrong with this, no recursion, no error checking, no branch magic, but it does the job in most cases. I'd love to see it improved!

In your case you can just pipe the output that would otherwise give you a runtime list into the raggedListToDataTree function.

Ben
  • 12,614
  • 4
  • 37
  • 69
  • I'd love it if someone with a better understanding of this process wanted to have a go at refactoring this. Nested for loops feels so bad. – Ben Feb 09 '14 at 03:50