C# editor problem and datatree problem

Hey,

I have situation where the C# editor is reformatting and deleting parts of my code. In the first image, the component executes properly when the play button is pressed with the editor open. The code executes properly even when the editor is closed (by pressing the OK button) and the inputs are tweaked. But when the editor is reopened (second image), the code becomes altered and the component fails to execute properly. Lines 75-79 are dedented various times. And in line 78, mylist[i] is shortened to t[i]. This problem has been replicated on another machine running this code.

My datatree problem has to do with the output. The C# component is taking a list from number and a list from dup and creating a datatree. The component should run twice since each input has two list branches. I was expecting the component to output a tree with six branches (see desired output panel). I understand the datatree that I construct in the script is only one level deep. I was expecting the output to automatically tack on a 0 or 1 to the front of the path (like (0;0),(0;1),(0;2),(1;0),(1;1),(1;2)). If it is on me to be more prescriptive about the datatree path, how can I identify which iteration is being executed so I can assign data to a more specific path?

I often see ‘array[]’ names being truncated to its last letter (’y[]’), or like in your case, to (’t[]’).

I’ve seen this happen sometimes when I copy and paste the rows containing the array or list names, but I’ve not seen it due to (re)opening the editor, and not with trees. I think it has something to do with the syntax. Perhaps some new syntax which is not supported by this editor(?)

Unfortunately I can’t read you screenshots (too blurred). Top get more focused screenshots you can press WIN+SHIFT+S and draw a smaller window around exactly the parts that are relevant.

// Rolf

Is it blurry if you click on the image to expand it?

I tried your solution. It partially worked. I changed mylist to just y , so now it does not change at all. These problems are occuring in my methods section only. I have variables in RunScript named mylist and templist. The code still dedents upon reopening of the editor.

Here are screenshots showing the new code and the new code reopened:


Yes. Unreadble.

// Rolf

Providing a screenshot is a very poor indication of the situation.

ALWAYS post a representative portion of the code in trouble with some test data (either internalized of contained in a R file (the safest way: case Breps and the likes)).

That’s weird. When I click on the images they go full screen (they are 4k screenshots).

Here is the code:

  private void RunScript(List<int> number, List<int> dup, ref object A)
  {
    List<List<int>> mylist = new List<List<int>>();

    for (int i = 0; i < number.Count; i++)
    {
      List<int> templist = new List<int>();
      for (int j = 0; j < dup[i]; j++)
      {
        templist.Add(number[i]);
      }
      mylist.Add(templist);
    }
    DataTree<int> mytree = ListToTree(mylist);
    A = mytree;
  }

  // <Custom additional code> 
  public DataTree<T> ListToTree<T>(List<List<T>> x)
  {
    DataTree<T> y = new DataTree<T>();
    for (int i = 0; i < x.Count; i++)
    {
      y.AddRange(x[i], new GH_Path(i));
    }
    return(y);
  }

200111 Editor Problem.gh (7.3 KB)

It is exactly this syntax which causes formatting errors in the ListToTree method. This editor obviously doesn’t support that syntax. But the truncating of array names sometimes happens also when copy-pasting.

image

// Rolf

I used T because it was used in another GH/C# post I saw. What type do I use if I want this method to work for all types? I might need to convert a list of integers now, but maybe a list of points later.

Try this:

Dupes_V1.gh (4.1 KB)

As a challenge further refine the thing: what if the data don’t match 1:1 ??

BTW: unboxing (for some other Method) an object has a time cost … but no pain no gain. On the other hand we frequently use object type of Trees for collecting different types (for some sort of “clarity” if you have lot’s and lot’s of Trees around).

1 Like

Once you start trying to modify DataTrees, I think for using the C# component in Grasshopper, Peter’s solution is probably the most painless way to go. Mixing item/list inputs with targeted modification to data paths is doable, but more cumbersome in general than just relying on DataTree inputs to begin with.

That said, the C# component exposes all sorts of ways to get under the hood if that’s what your after. An easy way to explore these is to use intellisense and start by typing this. into the component. Here, for example, this.iteration will give you an integer that will increment with each solution (as you asked in your OP).

Okay, this.Iteration solved the problem of assigning items to the right branch.

public DataTree<int> ListToTree(List<List<int>> mylist)
  {
    DataTree<int> mytree = new DataTree<int>();
    for (int i = 0; i < mylist.Count; i++)
    {
      mytree.AddRange(mylist[i], new GH_Path(this.Iteration, i));
    }
    return(mytree);
  }

However, I had to specify the types as int. If I change the types to object, I get errors.

  public DataTree<object> ListToTree(List<List<object>> mylist)
  {
    DataTree<object> mytree = new DataTree<object>();
    for (int i = 0; i < mylist.Count; i++)
    {
      mytree.AddRange(mylist[i], new GH_Path(this.Iteration, i));
    }
    return(mytree);
  }

The error message:

Error (CS1502): The best overloaded method match for 'Script_Instance.ListToTree(System.Collections.Generic.List<System.Collections.Generic.List<object>>)' has some invalid arguments (line 68)
Error (CS1503): Argument 1: cannot convert from 'System.Collections.Generic.List<System.Collections.Generic.List<int>>' to 'System.Collections.Generic.List<System.Collections.Generic.List<object>>' (line 68)

Line 68 is in RunScript where the method is called: DataTree<object> mytree = ListToTree(mylist);

I want to compute each iteration separately, which is why I am not going the DataTree input route.

200111 Editor Problem.gh (9.2 KB)

This is because you’re mixing types in your collections. You should make pretty much everything that you want sorted an object, including setting your input as a System.Object:

Grasshopper will handle the casting going out.

Thanks for clarifying. I’ve only just started learning C# recently. Is object sort of like var then?

Is there anyway to keep everything as int above Line 68, but convert mylist (which is a List<List<int>>) to List<List<object> right before calling the ListToTree method? Like a one line convert function?

object is really just any type at all. Because object is pretty much anything .NET assumes that you as the programmer - when you need your object to be something more specific - are going to handle in some way converting your own type instance from a generic object type to something like an int or string or Point3d or whatever it may be. The problem for you comes in because you want to have methods that rely on collections, and these automatically become more specific. Even though you can add an int to a List<object> one by one, you can’t give a List<int> to a method that’s asking for a List<object>.

Using the <T> approach as you did in your original approach is really the ideal when you want to have a function that can handle any type…But here you are entirely limited by the IDE (integrated developer environment) used for the C# and VB.NET components in Grasshopper, which is super crappy, and results in the errors you’re getting. If you were developing in Visual Studio and compiling your own components, you wouldn’t be having this problem, but because you’re using the C# component in GH, you have to consider these annoying little workarounds.

2 Likes

Thanks for the explanation.

The <T> approach definitely works if you don’t reopen the editor. It is only a problem when you open it to edit the script. Should McNeel be made aware of this? Maybe they can fix the problem. I could imagine many functions where I would just reorder and/or sort a collection agnostic of the elements’ type.

In the case of the ListToTree method, I may want to use it again in a future C# script. Is there anyway to save this method to a library that I can access later?

Yes, make a project in Visual Studio and make a class “TreeConversions” (or whatever name) with your static methods in it, compile an find the folder of the resulting .dll, place the .dll in your own Components folder and add the .dll to your script component(s) (via the capsule) which needs any of the methods.

I just did that on one of my own script components (I added my own library “RILGH_Geometry.dll” to the script component), like so:

image

I place my own library RILGH_Geometry.dll in a folder under the Grasshopper\Library (where plugins are located).

// Rolf

3 Likes

They are well aware of all of the shortcomings of the .NET IDE in GH, but as I understand don’t plan on fixing it…the focus is on GH2 development, which I believe will have much better code integration.

Also, Rolf’s suggestion to use an external code editor like Visual Studio - and compiling your own helper libraries - is I think a very good one.