Adding Tree to Tree (of type GH_Structure<GH_Point>)

OK, so if I have a list of tree (of type GH_Structure<GH_Point>) and want to add them into another tree, is that possible? I’ve tried defining nested structures, but that doesn’t seem to work, kind of like so:

    var deep_tree = new GH_Structure<GH_Structure<GH_Point>>();
    for (var i = 0; i < small_tree.Count; i++)
    {
        deep_tree.Append( small_tree[i], new GH_Path(i) );
    }

… but this doesn’t work, and if I use deep_tree.AppendRange(arr, path), then the tree doesn’t separate the added “small_trees” into different branches.

Do I really have to unpack the samllest items and put them into an entirely new tree structure to get a “deep_tree” structure?

(for now I did just that, but it means I have to “redo” trees that already exist)

// Rolf

As long as both have the same type constraint, you can use MergeStructure() on one of the trees.

Hm. Yes, that compiles and runs, but it flattens the added “small trees”, so I end up with the added trees as “flat” branches.

bild

The trees which I add (or in this case, merge) into the main tree are created in this way:

public static GH_Structure<GH_Point> Point2DArrayToTree(Point3d[][] arr)
{
    var tree = new GH_Structure<GH_Point>();
    for (var i = 0; i < arr.Length; i++)
    {
        var path = new GH_Path(0, i);
        for (var j = 0; j < arr[i].Length; j++)
        {
            // Append only valid points, break at first occurence
            if (arr[i][j] == Point3d.Unset)
            {
                break;
            }
            tree.Append(new GH_Point(arr[i][j]), path);
        }
    }
    return tree;
}

The main tree was merged together like so:

// using RILGeometry.Meshes;

var tree = new GH_Structure<GH_Point>();
for (var i = 0; i < indexes.Count; i++)
{
    // collects "vertice stars" around index[i]
    var arr = Meshes.ConnectedTopologyVertices(mesh, indexes[i]); 
    tree.MergeStructure(Meshes.Point2DArrayToTree(arr));
}
DA.SetDataTree(OUT_Tree, tree); 

… but the added “small trees” appear as “flattened lists” in the screenshot above.

// Rolf

I see, looks like you need to prefix all your paths with an additional integer which comes out of the outer loop.

public static GH_Structure<GH_Point> Point2DArrayToTree(int prefix, Point3d[][] arr)
{
  ...
  var path = new GH_Path(prefix, i);
  ...
}
for (var i = 0; i < indexes.Count; i++)
{
  var arr = Meshes.ConnectedTopologyVertices(i, mesh, indexes[i]); 
  ...
}

That was better, much better, thanks!

Now one last Q; When I have the datatree on the canvas, how do I merge the second path (after I have picked the first item in each branch, which are the red balls pictured)

bild

Like so: (all paths can be of different length)

Some kind of path mapper pattern perhaps can do the trick?

// Rolf

OK, I found that the following mapping chunks together the small branches to their parent branch :

bild

What are the proper terms? Good to know when searching for examples if Branch and Path are the same thing (?)

// Rolf

You don’t need the (i) in the source mapping if you’re not going to use it in the target mapping, so {A;B} -> {A} should do it.

Technically the terminology for GH1 is:

  • Tree (a sorted dictionary of Path keys and Branch values)
  • Path (a non-empty, ordered collection of non-negative integers)
  • Branch (an ordered indexed list of values)

Ok. I will have to read up on this. :slight_smile: .

Branches holding the values makes sense.

Have a good one

// Rolf

I changed my mind about that, in actual trees branches give way to yet more branches. It’s twigs that eventually provide you with leaves. The nomenclature in gh2 will be; tree, path, twig, item, leaf, pair, and meta. I admit that it gives me a sense of satisfaction that they are all four letter words.

So item and leaf would be the same thing?

// Rolf

A pair is an item plus its meta-data, a leaf is a pair plus its location within the tree. Sadly a location is a five letter word; “locus” and it consists of a path plus an index.