C# Cleaning Tree in Visual Studio

unhandled

(Tao) #1

So I have a tree with points, some entries are null.
Inside GH you can use the clean tree component to cull all null items. How to do it in visual studio?
I’ve tried removing all null items like so

for (int k = 0; k < cleanedIntersects.get_Branch(pth).Count; k++)
{
if (cleanedIntersects.get_DataItem(pth,k) == null)
cleanedIntersects.RemoveData(cleanedIntersects.get_DataItem(pth, k));
}

and it seems to work for the most part. however, when I try to remove all branches that are empty, it doesn’t work because tree.Branch(pth).Count doesn’t return 0 (even though the branch is empty!).

image shows original tree > cleaned tree (code doesn’t remove all nulls from last branch, weird!) > branch.Count output

So, my question is basically how to recreate the function of the cleanTree Component? Couldn’t find anything on the web.


(qythium) #2

I suppose you are referring to GH_Structure and not DataTree? It’s not a good idea to modify a data collection while you are enumerating over it, that might be leading to some off-by-one errors that you are seeing.

You could instead construct a new structure and clone the non-null items over to it, something like:

GH_Structure<T> tree;

GH_Structure<T> cleanedTree = new GH_Structure<T>();

foreach(GH_Path path in tree.Paths){
    cleanedBranch = tree.get_Branch(path).Where(t => t != null);
    if (cleanedBranch.Count > 0){
        cleanedTree.AddRange(cleanedBranch, path);
    }
}

(not tested, could have typos / bugs)


(Tao) #3

Yeah, GH_Structure, sorry if that caused any confusion.
Cool, your solution worked, but I changed it a bit, since I haven’t gotten to learn lambda expression yet.
Here’s my version:
GH_Structure<GH_Point> cleanedIntersects = new GH_Structure<GH_Point>();
for (int i = 0; i < Utility.GetMainBranchCount(intersections.Paths); i++)
{
for (int j = 0; j < Utility.GetSecondaryBranchCount(intersections.Paths, i); j++)
{
GH_Path pth = new GH_Path(i, j);
List<GH_Point> tempBranch = new List<GH_Point>();
for (int k = 0; k < intersections.get_Branch(pth).Count; k++)
{
if (intersections.get_DataItem(pth, k) != null)
{
tempBranch.Add(intersections.get_DataItem(pth, k));
}
}
if (tempBranch.Count > 0)
cleanedIntersects.AppendRange(tempBranch, pth);
}
}

Didn’t know that modifying the list while enumerating is bad, reading up on it now.