Help Visual Studio - VB Tree Operations (.Append, .Insert)

Hi All,
I’ve just started learning Grasshopper component development in Visual Studio VB and I’m a bit stuck.

I want to create a component with two inputs (datatree, key-string) - search the first branch of the datatree for a match with the key-string, then export the same index of the remaining branches.

I started simple, and at this stage I’m just trying to loop through an input tree, and manual copy data into the output tree but running into errors.

I think I’ve create the inputs OK, hopefully got the access right, and got the loop working. I can make the input = output - but for some reason when i try and loop and use Insert or Append, I’m getting errors:

Code is as follows:

INPUTS:
Protected Overrides Sub RegisterInputParams(pManager As GH_Component.GH_InputParamManager)

    pManager.AddGenericParameter("Tree", "A", "Titled data tree to search and return data from", GH_ParamAccess.tree)
    pManager.AddGenericParameter("Key", "B", "Key to search for and return data on", GH_ParamAccess.item)

End Sub

OUTPUTS
Protected Overrides Sub RegisterOutputParams(pManager As GH_Component.GH_OutputParamManager)

    pManager.AddGenericParameter("Data", "C", "Dataset matching search key", GH_ParamAccess.tree)

End Sub

And the SolveInstance:
Protected Overrides Sub SolveInstance(DA As IGH_DataAccess)

    ' Declares variables for internal code
    Dim i As Int32 = 0
    Dim j As Int32 = 0
    Dim searchterm As Grasshopper.Kernel.Types.GH_String
    Dim output As Grasshopper.Kernel.Data.GH_Structure(Of Grasshopper.Kernel.Types.IGH_Goo)
    Dim searchtree As Grasshopper.Kernel.Data.GH_Structure(Of Grasshopper.Kernel.Types.IGH_Goo)

    ' Checks that key inputs are present, if not, terminates

    If (Not DA.GetDataTree(0, searchtree)) Then Return
    If (Not DA.GetData(1, searchterm)) Then Return

    For i = 0 To searchtree.Count - 1

        'output.Insert(searchtree.Branch(i).Item(0), searchtree.Path(i), 0)
        'output.Append(searchtree.Branch(i).Item(0))
        output.AppendRange(searchtree.Branch(i), searchtree.Path(i))

    Next

    DA.SetDataTree(0, output)

End Sub

If anyone can help point me in the right direction, I would be very grateful.

Thanks in advance.
Lyndonj

TL;DR

output.AppendRange(,)
DA.SetDataTree(0, output)

https://developer.rhino3d.com/api/grasshopper/html/T_Grasshopper_Kernel_Data_GH_Structure_1.htm

Thanks @Dani_Abalde

Your right, the post was to long. I have re-written a bit more succinctly.

I attempted to use the:

Output.AppendRange method - but i’m throwing a System.NullReferenceException. I’ve included this code in the revised first post. If you can see where i’ve gone wrong, that would be appreciated.

Is still hard to figure out what is wrong, but I can see this:

For i = 0 To searchtree.PathCount - 1

and

dim path = searchtree.Paths(i);
output.AppendRange(searchtree.Branch(path), path)

It’s a very long time ago I have written VB.Net. What I see is that you declare ‘output’, but you are not initializing it. So ‘output’ is null. Now, when appending data to it, it will throw a null exception. So something like this is missing:

output = New GH_Structure(Of IGH_Goo)()

2 Likes

@Tomtom, thank you.

I had no idea it needed to be initialised to run! That got it working nicely! I’ve got the subsequent search working in the first branch of the datatree, so just need to get the nested loop to return the correct index of subsequent branches and I think ill be there :slight_smile:

One other thing I do keep running into (which i think I’m starting to grasp… just) is datatypes, and trying to compare datatypes that are not the same.

Reading the Grasshopper API, i noted there are a number of Cast To, Cast from functions etc. - Are these generally used to attempt to change inputs into other data types? I.e. - If i used a panel to input a series of strings I could Cast TO GH_Double or something similar to attempt a conversion?

Thanks again for the help!

‘Declaring’ an object just means you create a reference to a special type of object. That reference/pointer points to memory but can also be null. ‘Initializing’ an object (in .Net) means you allocate memory on the heap to store value types (int, bool …) or other reference pointer to other places in memory (e.g. for dynamic collections such as lists or GH_Structures). Without allocating memory you obviously cannot store anything because there is no place to put values in. Allocation of memory is indicated by the “new” keyword, both in C# and VBNet. It likely comes from a C naming convention where the “new” function would call the malloc() function to reserve some memory for a c struct (There are no constructors in C).

I think you should dive deeper into basic coding at first. The Grasshopper API is not easy to understand, for various of reasons. E.g. GH_Double is a simple wrapper around the Double type. It has some internal purposes. The best is you get the underlying value and in the end of your script you wrap it back into a new GH_Double. For computation, I would just work with doubles. Only if you deal with very large data and memory consumption is a topic, then you should work with GH_Doubles all the way.

1 Like