algorithmic modeling for Rhino

how to invoke "update" and "internalise" of a referenced cluster?

Hi, I was wondering how one can programmatically invoke the "internalise" and "update" options found in the context menu of a referenced cluster.

I found an undocumented class property Grasshopper.Kernel.Special.GH_Cluster.Synchronisation that contains the state like e.g. "OutOfDate" or "NotReferenced". 

Is "update" the same as invoking GH_Cluster.ReadGhClusterFile?  


Is "internalise" the same is reading the internal document of the definition and referencing the component cluster document somehow to that? I've seen a byte array in the xml version of a definition that contains a referenced cluster component, which I presume is an internal copy of the content of the reference cluster file. However, I can't figure out how to get access to that.

In any case I'm stuck.

Views: 850

Replies to This Discussion

GH_Synchronisation is an enum which lists all the possible synchronisation states a cluster can be in. The values are:

  1. Unset (synchronisation state unknown, this should never happen)
  2. NotReferenced (cluster is not referenced and thus cannot be out of sync)
  3. MissingReference (cluster is referenced but the file it is referenced with has gone missing)
  4. OutOfDate (cluster is referenced to a file, but the file is newer and this cluster is out of sync)
  5. UpToDate (cluster is referenced and everything is hunky dory)

If the cluster is OutOfDate and the 'Update' menu is clicked, the following code runs:

Dim record As New GH_UndoRecord("Update Cluster")
For Each cluster As GH_Cluster In ClusterFamily()
  record.AddAction(New GH_GenericObjectAction(cluster))

Which means, in English:

  1. Create a new undo record.
  2. Iterate over all clusters in the current document that reference the same file as this cluster does
  3. Add each cluster current state to the unto record.
  4. Update the cluster (ie. recreate it anew from the file)
  5. Add the finished undo record to the stack.
  6. Trigger a new solution.

If you're only looking to do this on a per-cluster basis and you don't care about undo, then the CreateFromFilePath() method is all you need.

CreateFromFilePath() eventually calls ReadClusterFile(), but it does one or two additional bookkeeping tasks, so you're better off calling the high level method rather than ReadClusterFile().

Dear David,

I was wondering what are the necessary steps needed to make a battery that would update all non-updated clusters inside a file. Ideally with a trigger button.

I have tried to make a VB battery with the code that you have provided but I am getting all sorts of errors. I am quite new to VB.

Do you have any suggestions?

When you say VB, are you talking a VB scripting component, or a VB project in Visual Studio?


I mean a scripting component.

I will then make a user object out of it.

Its important to notice that in my definition I have Clusters inside of Clusters, I am not sure if this will have any implications.


what I am asking is probability super easy to do.

Can you at least direct me in the right direction?

Thanks for your help.

Hi David,

Currently, working on automated testing of definition releases. Now we're looking back to this thread and somehow the enum below doesnt exist anymore. We iterate over the document activeobjects, test whether it has a igh_cluster interface, but with the found clusters reflection doesn't show this and therefore we can't compile. What are we doing wrong?


Also, why is grasshopper.kernel.special not documented?

Regards, Wei Pien
Update: apparently one needs System.Windows.Form to get the reflection of grasshopper to work. Now we can navigate through the "undocumented" special module.

The 'Internalise' menu runs the following code:

Dim newID As Guid = Guid.NewGuid()
Dim record As New GH_UndoRecord("Cluster Frabbing")
For Each cluster As GH_Cluster In ClusterFamily()
  record.AddAction(New GH_ClusterReferenceAction(cluster))
  record.AddAction(New GH_ClusterDocumentIdAction(cluster))

  cluster.DocumentId = newID
  cluster.m_file.Path = Nothing

Which means, in English:

  1. Create a new ID we'll use for the new cluster document.
  2. Begin an aggregate undo record.
  3. Again iterate over all clusters in the document that have the same referencing state as the current cluster.
  4. Overwrite the cluster document Id with our newly invented one.
  5. Make the cluster forget it was associated with a specific file.
  6. Add the undo event to the stack.
  7. Update the canvas (but not the solution).

You can again get rid of the loop and the undo code if you only care about a single cluster.

Hi David, I will have a look at it. I would never come up with the undo record and have to get familiar with that concept. Also it seems that there are different ways to obtain certain info (e.g. m_file.Path). I don't know whether it's due to the different languages we use or just different interfaces.
In any way, tnx for the reply. Cheers WP






  • Add Photos
  • View All


  • Add Videos
  • View All

© 2022   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service