C# matching data trees in grasshopper

Hi everybody,

I am struggling with data trees in Grasshopper trying to match two data trees in input. What I need to know is the list of object of the tree T2 correspondent to any given object of the tree T1. I have been looking for a function in the SDK but I could not find it. I have developed a script to do it but it is very inefficient and still I do not know how to handle trees with short paths. Also I understand that the criterion is the longest list on the paths and again in the matching branches but I am not sure.
Is there any function that can be used for this task? At least to find matching paths.
Thanks in advance,

Gennaro

Does the problem reduce to iterating over all the values in one tree and seeing if they are present in some other collection? Or do you specifically need to figure out the loci of both values in both trees when they are identical?

What data type?

Sorry I might have been unclear.
I have a component with two inputs. Let’s say in the input 1 a tree of points and in the input 2 a tree of colors. I need to get for each point which is the correspondent color with the logic that Grasshopper would use.
You spoke about it in this discussion https://www.grasshopper3d.com/forum/topics/how-does-grasshopper-solve-the-intersection-of-two-data-trees.

Ah I see. The default Grasshopper tree iterator which components use to match up input data fully ignores the paths themselves and only concerns itself with the order of paths.

If the number of paths differs, then the last branch is used over and over again to match the subsequent branches in the other tree. The same goes for items. If your path counts and list lengths are the same between both trees, it will significantly simplify the looping.

var treeA = ColourTree;
var treeB = PointTree;

int maxPathCount = Math.Max(treeA.PathCount, treeB.PathCount);
for (int k = 0; k < maxPathCount; k++)
{
  int kA = Math.Min(k, treeA.PathCount - 1);
  int kB = Math.Min(k, treeB.PathCount - 1);
  var listA = treeA.Branch[kA];
  var listB = treeB.Branch[kB]

  int maxListLength = Math.Max(listA.Count, listB.Count);
  for (int i = 0; i < maxListLength; i++)
  {
    int iA = Math.Min(i, listA.Count - 1);
    int iB = Math.Min(i, listB.Count - 1);
    var colour = listA[iA];
    var point = listB[iB];
    // (colour, point) is the matched pair.
  }
} 
1 Like

If the trees have the same topology, it simplifies to this:

var treeA = ColourTree;
var treeB = PointTree;

for (int k = 0; k < treeA.PathCount; k++)
{
  var listA = treeA.Branch[k];
  var listB = treeB.Branch[k]

  for (int i = 0; i < listA.Count; i++)
  {
    var colour = listA[i];
    var point = listB[i];
    // (colour, point) is the matched pair.
  }
} 
1 Like

Sorry for late reply. That’s what I was looking for… Thank you very much!

@DavidRutten Could you help me to deal with more complex structure than in this example, please? I would like to learn how to iterate through complex data trees. Is there some routine to learn? A “universal” input script that matches relevant data together? I have a script that works just for exact data structure. How to make the script more robust and universal so it works for different structures as well?

I know that I can repeat “G” and “RP” input trees to march “TP” tree, but I guess that it should be simpler than that.

InputTreeMatching.gh (33.0 KB)


(Just to provide the context: I am trying to create “Map to twisted prism” function)

My code tries to get a dictionary with branch ID and subbranch count:

Dictionary<int, int> pathNavigation = new Dictionary<int, int>();

for (int i = 0; i < TP.BranchCount; i++) {

  int pathIndex = TP.Path(i).Indices[0];

  if (pathNavigation.ContainsKey(pathIndex)) {
    pathNavigation[pathIndex] = pathNavigation[pathIndex] + 1;
  }
  else {
    pathNavigation.Add(pathIndex, 1);
  }
} // code continues...