Grasshopper

algorithmic modeling for Rhino

Hi all, I'm learning about deep copy, but I dont know if that is what I need to do:

I'm using only the custom VB.net components in GH. I would open up the script editor and type my own stuff. I realized that when an object is passed outside that component, the object is pass as reference.

The object's variable is not behaving what I would expect.

For example, I created a class in one VB component:

Public Class NumberObj
Public X As Integer
Public Sub New()
X = 0
End Sub
End Class

I then created that object and passed it out from the component:

I modified that object in another component, changing X to something else.

In the code shown below (just as example). I slide the slider around, and every time I move the slider, the value keep adding up. Obviously the programme keeps all objects in memory. It is not until I press recompute that everything reset.

What should the proper way of handling this? Should I do a deep copy every time I take an object into an VB component before making changes. I don't know how to do that yet.

Views: 1817

Replies to This Discussion

In my normal use, my object are actually in a List (of myObjects), I'm assuming to make a deep copy of that is more difficult. 

Thanks in adv.

Hi Victor,

typical .NET classes do not have a standard mechanism for creating duplicates. This is one of the reasons why all data in Grasshopper needs to implement the IGH_Goo interface, because IGH_Goo specifically declares a Duplicate function that allows me to pass safe instances of data to different components in the knowledge that changes to one instance will not 'contaminate' other instances elsewhere, i.e. exactly what you are seeing.

The reason you're seeing it is because your class NumberObj does not implement IGH_Goo and therefore must be wrapped at the last possible moment into a class that does (one of my own, used only as a last resort). This wrapper class however does not know how to duplicate your NumberObj instance, so you end up with the same instance being shared amongst all components and all iterations.

Sharing classes between VB components is actually quite a fragile approach anyway because Script #2 doesn't actually 'know' about the class as it wasn't defined within scope. The only reason it works is because VB is trying to be helpful and interpret your code as best it can.

If you want your own data type, I highly recommend one of two approaches:

  1. Write a GHA library that properly implements your data type as an IGH_Goo (or GH_Goo<T>) type. Then you can pass them between components safely.
  2. Store your data in an xml string which is deserialized inside your Script components. This allows you to pass data around using the Grasshopper GH_String type which is already safe. Alternatively, if your data is very simple you don't need to use xml but can get away with a custom formatting of your choice.

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Hi David, thank you for the explanation, I have never written a GHA library, but now I decide to learn. My objects are far more complex then that example, so serialization is a bit difficult. I noticed the GHA assembly wizard, and I'll give it a try. I have some experience writing VB.net stuff in Visual Studio Express. 

Is there any description of the interface IGH_Goo or GH_Goo<T>, I'm downloading the GrasshopperSDK.chm


By the way, is it true that if I write my GHA library, when I update a new component, changed the code, I have a way to use the tool "Upgrade Legacy Component" to upgrade components that are old? I'm now having to change them one by one if I made changes.

Yes, the SDK helpfile has a help topic on "Simple Data Types" which deals with IGH_Goo and GH_Goo<T>.

Yes, it is possible to write an automatic upgrader, but it's still quite difficult. I'm looking for ways to make it easier to use as a developer.

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Hi David and all,

I have tried both option you suggested, I have two concerns.

1. I tried writing a custom class definition in VisualStudio and compiling it to a GHA library, however I realized that I wont be able to use that class in the custom VB component in GH. Since I find the VB component much quicker to be modified and I need to work with other people. I want other to access that class without touching the GHA Library. Is it possible to access those classes inside GH, within those custom VB component?

What I did is:

Public Class MyCustomClass

Inherits Grasshopper.Kernel.Types.GH_Goo(Of MyCustomClass)

...

Public Overrides Function Duplicate() As Grasshopper.Kernel.Types.IGH_Goo

Public Overrides ReadOnly Property IsValid As Boolean

Public Overrides Function ToString() As String

Public Overrides ReadOnly Property TypeDescription As String

Public Overrides ReadOnly Property TypeName As String

2. I also tried the XMLSerializer method,. I wrote my class definition inside GH custom VB component. I can serialize them into xml streams and deserialize them in another custom VB component. However, I will have to paste my class definition everywhere in all the custom VB components, and that cause a maintenance issue when I have to change them. Any suggestion?


Thanks a lot.

Victor

An update of this : 

I have find a work around that worked for me, creating a custom class and duplicating it. In case anyone whats to do something similar this might be helpful. 

  1. My concern is I'm writing custom classes to hole a collection of variables.
  2. I do not want to write it as a gha library because I'll make changes often.
  3. I have the problem of objects being contaminated up-stream.

The workaround is simple, you need to write your own duplicate function inside your class, to handle the deep copy.


Public Class car

  Public Name As String
  Public Year As Integer

  Public Sub New()

  End Sub

  Public ReadOnly Property Age As Integer
    Get
      Return datetime.Now.Year - Year
    End Get
  End Property

  Public Function Duplicate() As car

    Dim duplicatedCar As New car
    duplicatedCar.Name = Name
    duplicatedCar.Year = Year
    Return duplicatedCar

  End Function

End Class

Then, whenever you use the object in another VB component, do the duplicate first.

Attached is an example file.

Attachments:

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service