Data Stability Problem

Hi All,

This seems like it’s a C# / .NET problem, but I can’t find any answers in the wider community. Thanks in advance for your patience with my ineptitude.

I have a component Lattice Generator which feeds two sets of information into another component, Cell Generator

  1. a GH_Structure<GH_Point> with one point per branch.
  2. a List with eight vectors on it.

Cell Generator is then to take each Point and apply the List to it, making eight points from the one it was given, on a GH_Structure with the same branch address as the Point came in on. This isn’t quite working yet, but I have a bigger, nastier looking problem I need to sort out first.

This Cell Generator component has a couple other functionalities that come from the same component, each as a single string of information.

So - every time I plug something new into the Cell Generator, it causes the GH_Structure<GH_Point> values to increase.

I’ll get to code soon if necessary. Mine is so in progress and I’m still learning, so it’s a huge mess - probably less confusing for such a general question if I post screenshots…

Edited to add: in the CellGenerator component I am using a “foreach” loop to iterate over each GH_Point in the GH_Structure individually. I commented this out and the upstream problem goes away. Is there a good guide anyone can think of for using foreach statements on GH_Structures?

Thanks in advance for any help you can offer. Sorry for making such dumb problems!

Regards,

Duane

Hi All, just an update - I sorted it out I think. It was just a matter of having the right variables in the right places.

And because of haste in coding right before a long layoff to shift the classes I teach online, I used some similar names for local variables and class properties.

Additionally - I finally made peace with GH_Structures. They ain’t perfect. But I understand them much better now.

Anyway - if anyone runs into similar problems, ping me and I’ll try to advise.

Thanks for your thoughts, in case anyone was formulating a reply.

Once this thing’s not an embarrassment, I’ll be sharing code.

Congrats on your solving the issue. GH’s tree structure can be annoying from time to time.

I’d point out, especially for those who are new to manipulate GH_Structure programatically, that it’s not a nested structure, but a flattened list of paths and a list of values for each path.

1 Like

Thanks, @gankeyu!

And yeah - once I read closer in the GH_Structure documentation and realized you didn’t have to do any Tree operations to it to iterate through, it made more sense.

@gankeyu I think that your affirmation is not precise

GH_Structure and DataTree are are simply, to be more general in C# terms List of Lists List<List> data structure under the hood . If it was just a list, as you are suggesting here, there should be no need to iterate a GH_Structure or DataTree with a nested forloop.

When you are iterating through a Tree the first loop will always access its corresponding List the inner forloop will iterate through the contents of that List.

In Grasshopper terms: The first forloop will access its corresponding Branch, the second forloop will iterate thorugh the items of that Branch.

Just check this simple example.


 GH_Structure<GH_Number> r = new GH_Structure<GH_Number>();

    for (int i = 0; i < 5; i++)
    {
      for (int j = 0; j < 3; j++)
      {
        r.Insert(new GH_Number(i + j*2), new GH_Path(i), j);
      }
    }
        
    PrintTreeStructure(r);
      
//////////////////////////////////////////////////////////////////

  public void PrintTreeStructure(GH_Structure<GH_Number> tree)
  {
    for (int i = 0; i < tree.Branches.Count; i++)
    {
      for (int j = 0; j < tree.Branches[i].Count; j++)     
        Print("Branch {0} : {1}", i, tree.Branches[i][j].ToString());     
      Print(Environment.NewLine);
    }
  }
    
// OUTPUT: 
Branch 0 : 0
Branch 0 : 2
Branch 0 : 4

Branch 1 : 1
Branch 1 : 3
Branch 1 : 5

Branch 2 : 2
Branch 2 : 4
Branch 2 : 6

Branch 3 : 3
Branch 3 : 5
Branch 3 : 7

Branch 4 : 4
Branch 4 : 6
Branch 4 : 8




Moreover, when you graft for example, what this really is doing is creating a new List<List> object simply with only 1 element per List

OK I didn’t precisely word my reply :cold_sweat:

By not nested, I mean a GH_Structure with {0;1} data is not sth like, {0} contains another GH_Structure containing {1} , as it’s shown on Param Viewer, e.g.:

:sunglasses: indeed

Wow, thanks for all the insightful input! I feel like I know C# for Grasshopper 10x better now that GH_Structures aren’t as opaque to me.

Back to the original issue, not a code-sample worthy issue, but I have observed with the same component - which is otherwise working perfect to design - that sometimes changing input values does not destroy the old inputs. Anyone have clues, as a general class of problem, what causes this issue?

Thanks in advance for any thoughts.

Hi Duan, If you provide a minimal reproducible example it would be much easier for the community to help you.

PS: there is also no such thing as C# for grasshopper, I personally think it helps much more to think about C# just as a programming language that is platform independent. It just happens to be that you can program in C# within Rhino.

Hi @rawitscher-torres - thank you so much. As is usually the case, writing the Minimal Reproducible Example is what helped me solve the root issue.

I am pretty sure GH_Structure is conceptionally like a SortedList, David Rutten mentioned that some time ago. The Key is of type GH_Path, the Value is of type List, so a SortedList<GH_Path, List>.
As in every dictionary you can access the key list (i.E. the paths) and the value list (i.E. the Branches). Also every key is unique, as every path should be.
The Branches behave as a list of lists (as any Valuelist of a a dictionary would do if the Valuetype is some IEnumerable.

1 Like

Yes, that was what was missing from my understanding. Thank you for putting it in such clear terms!

1 Like