Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Transforms DataTrees in Grasshopper to nestings of lists, and vice versa
def list_to_tree(input, none_and_holes=True, source=[0]):
"""Transforms nestings of lists or tuples to a Grasshopper DataTree"""
from Grasshopper import DataTree as Tree
from Grasshopper.Kernel.Data import GH_Path as Path
from System import Array
def proc(input,tree,track):
path = Path(Array[int](track))
if len(input) == 0 and none_and_holes: tree.EnsurePath(path); return
for i,item in enumerate(input):
if hasattr(item, '__iter__'): #if list or tuple
track.append(i); proc(item,tree,track); track.pop()
else:
if none_and_holes: tree.Insert(item,path,i)
elif item is not None: tree.Add(item,path)
if input is not None: t=Tree[object]();proc(input,t,source[:]);return t
# written by Giulio Piacentino, giulio@mcneel.com
def tree_to_list(input, retrieve_base = lambda x: x[0]):
"""Returns a list representation of a Grasshopper DataTree"""
def extend_at(path, index, simple_input, rest_list):
target = path[index]
if len(rest_list) <= target: rest_list.extend([None]*(target-len(rest_list)+1))
if index == path.Length - 1:
rest_list[target] = list(simple_input)
else:
if rest_list[target] is None: rest_list[target] = []
extend_at(path, index+1, simple_input, rest_list[target])
all = []
for i in range(input.BranchCount):
path = input.Path(i)
extend_at(path, 0, input.Branch(path), all)
return retrieve_base(all)
@piac

This comment has been minimized.

@piac

This comment has been minimized.

Copy link
Owner Author

commented Feb 16, 2015

This is an extension of a sample by Benjamin Golder posted on the GH forum. The original sample worked on a single list with lists inside (2D); this sample works on arbitrarily nested lists of lists (nD).

@epignatelli

This comment has been minimized.

Copy link

commented Apr 6, 2017

Hi Giulio, i would like to report an issue.
Simplifying the input breaks the code. Usually it backs up to the previous dimension of the nested array.

image

@piac

This comment has been minimized.

Copy link
Owner Author

commented Jun 22, 2017

@epignatelli

Hi, do you see those "source"/"retrieve_base " parameters in the two functions? They refer exactly to aberrant trees that actually represent "forests". (two tree that have {1} and {2} paths actually are not one "tree", but two different "trees")

@piac

This comment has been minimized.

Copy link
Owner Author

commented Jun 22, 2017

Also, in Rhino WIP and Rhino 6, it will be possible to use

import ghpythonlib.treehelpers as th

a_tree = th.list_to_tree(a_list)
a_list = th.tree_to_list(a_tree)

that contain improved versions of the script above.

@xarthurx

This comment has been minimized.

Copy link

commented Mar 16, 2019

This function doesn't work when the tree index doesn't start on 0.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.