Access number of nested branches within a given branch c#?

unhandled
branches

(Tao) #1

Hi,

I have a question concerning handling DataTrees within the Grasshopper C# Component.

So, I have a given set of planes that is structured as followed:
{0;0}
{0;1}
{0;2}
{0;3}

{1;0}
{1;1}
{1;2}
{1;3}
.
.
.
etc

where each of the branches holds a collection of geometry (so 3 dimensions in total).

I have created a DataTree as well as a 3-dimensional List<> structure for comparison like so:

DataTree < Plane > jointsTree = new DataTree();
List<List<List>> jointsList = new List<List<List>>();

I’m running into trouble when I try to iterate with for-loops using the datatree.
for example:
Assuming I have 2 joints each with 4 members as illustrated above, If I access the property jointsList.Count it returns the value of 2.
Calling jointsList[0].Count returns 4, which is the number of members of that joint.

However, using the DataTree structure there is no way to get the same counting method. if I call the property jointsTree .BranchCount, it returns the value of 8, which is the total number of members rather than the number of joints.
Calling jointsTree.Branch(0).Count returns the length of {0,0}, the number of geometry in that particular branch rather than the number of members, and calling **jointslist[4].Count returns the number of members of {1;0}, which basically means that the tree is somehow collapsed into two levels?

Using joints.Branch(i,j) i can access the data in multiple dimensions, but that assumes I have a way to calculate the max value for i and j …

So, either I am missing something vital (I hope thats the case) or the DataTree structure seems unable to handle multidimensional data.

Thanks in advance for solving this mystery…


#2

DataTree is a SortedList<GH_Path, List< object>>, so is just two dimensional, not a real tree structure. It’s like a container of labeled lists.
To count the number of nested branches you must create your own implementation, it is not difficult if you understand the GH_Path (a list of numbers).


(Pfotiad0) #3

Data Trees is a thingy that manages Lists via an indexing system (i.e. paths with any dimension).

For a given GH_Path path: int[] indices = path.Indices; (where indices[0] the first dimension, indices[1] the second etc etc.

So for instance:

int countPathsWith3orMoreDims = 0;
foreach(GH_Path path in someTree.Paths){
if(path.Indices.Length < 3) continue;
if(path.Indices[0] == someValue && path.Indices[1] == someOtherValue){
countPathsWith3orMoreDims++;
}
}

Speaking about path dimensions … see attached and have some fun.

Dice_on_trees_V1.gh (130.2 KB)


(Tao) #4

I did not know about the SortedList, thanks for pointing that out, @Dani_Abalde! Learned something new.
Also thanks for the brief demonstration and the gh file, both very helpful @PeterFotiadis

here’s my attempt at counting the branches:
//count branches, should be 27
int currentBranch = 0;
int branchCount= 1;
foreach (GH_Path path in x.Paths)
{
if (path[0] != currentBranch)
{
branchCount++;
currentBranch = path[0];
}
}

//count sub branches in branch 0, should be 4
int subBranchCount = 0;
foreach (GH_Path path in x.Paths)
{
  if (path[0] == 0)
  {
    subBranchCount++;
  }
}
Print("first level branches count: " + branchCount.ToString());
Print("second level branches of branch 0: " + subBranchCount);

I’m sure there’s more efficient ways to count it, but at least I understand what’s going on.


#5

You can also use a SortedList to perform that search.

 private void RunScript(DataTree<System.Object> T, ref object A)
  {
    SortedList<GH_Path, int> dic = new SortedList<GH_Path, int>();
    foreach(GH_Path path in T.Paths){
      GH_Path parent = path.CullElement();
      if(dic.ContainsKey(parent)){
        dic[parent] += 1;
      } else {
        dic.Add(parent, 1);
      }
    }
    A = dic;
    //A = dic[SomePathOfT.CullElement()]; //gives you the number of subbranches of parent of dimension 1 using a subbranch in dimension 2.
  }

(Pfotiad0) #6

For counting the beans we use often a HashSet as well

HashSet mainBranches = new … blah, blah

foreach(GH_Path path in tree.Paths){
mainBranches.Add(path.Indices[0]);
}

Print(“Main branches: {0}”, mainBranches.Count);

etc etc etc


(Pfotiad0) #7

And this … well … has 8 challenging DT questions > only for the brave > answer them all (most notably Q8) and become a DataTree Master.

Random_depth_DataTrees_The8Questions_V1.gh (124.0 KB)


(Tao) #8

Splendid. Suggestions work well, particularly like the HashSet method!
@PeterFotiadis thanks for posting these strange, but informative scripts. Are these part of a class?


(Pfotiad0) #9

Er … well … if we can call my people in the practice a class of some sort … then yes.