-
-
Save piac/ef91ac83cb5ee92a1294 to your computer and use it in GitHub Desktop.
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, [email protected] | |
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 yes, I wish I had found that earlier!
@cromlyngames what type are you passing to the script? Can you email me a sample?
Thank you! [email protected]
What can we do when the "tree" has been simplified and represents a forest?
(for example, it contains {0,1} and also {3,1}, which do not have a "trunk", or first index, in common).
You can use retrieve_base and source like this:
import ghpythonlib.treehelpers as TH
nested = TH.tree_to_list(data, retrieve_base=lambda x: x)
a = TH.list_to_tree(nested, False, source=[])
Background
The key here is to notice that Grasshopper will never create forests, when it does normal tree handling. Forests are "trees" that have distinct trunks, or first branch indices. That's why, the default of the functions does not create an empty list to hold these distinct trunks, -- otherwise, with standard components, there would be one more [0] to deal with all the time.
Please also note that trees that have overlapping branches, that is, a branch with a path that is equal to the beginning of the path to another branch, cannot be rendered as instances of this type of lists of lists. Just keeping paths to the same depth will fix this problem.
@laurend I think this topic:
https://discourse.mcneel.com/t/treehelpers-with-simplify/92531/2
will explain more in detail for you.