I recently joined the team at Arup working on Speckle, so I’m very excited that I’ll be a lot more active within the community!
As the structural objects continue to develop and change, we are hoping to get some thoughts on the best way to represent these changes within grasshopper components. Presently, when placing a generated element component, there is no warning if the element does not match the latest structural object. Components in existing GH scripts would therefore need to be updated manually.
We were hoping to work towards a quality of life feature where we can use the built-in Solution > Upgrade Components to take care of this as components are updated. Are there any thoughts on how to best manage this?
Congratulations on the move! I believe @AlanRynne already did some magic thanks to which the Grasshopper BIM components can be automatically updated using the “Upgrade Components” function.
I’ll let him explain how it works as I have no idea
A warning would be nice though, could maybe be done caching locally the version of the objects kit.
Glad to hear about you joining the Arup Speckle team!
Auto-upgrading schema nodes is a bit tricky, and sadly it’s still a semi-manual process.
As you may have already noticed, all Schema nodes are generated using a t4 template file. This creates a .cs file with all the necessary classes inheriting from GH_Component. This basically searches for any constructor with the SchemaInfo attribute and generates a component for it.
Before I left on vacation, I added a new attribute to core → SchemaDeprecated, which when applied to a constructor with the Schema attribute, will flag it as deprecated in Grasshopper (adding the old tag in the icon) and will hide it from the ribbon and search too.
You can see it in action here:
This will only take care of flagging them as old, but not auto-upgrade them.
In order to do so, unfortunately for now it is a manual process (though, I’d be happy to hear ideas on this).
To add auto-upgrade functionality:
You must create a new class that implements IGH_UpgradeObject in the Grasshopper Connector for each of the constructors you add the SchemaDeprecated attribute.
It’s basically a class that tells Grasshopper which components are the “upgraded” version of another one, and allow you to re-adjust the input/outputs. For example, if an input changes from object to List<object>, you’ll have to update the access in the corresponding parameter.
This operations is quite delicate and needs to be done right on the first try, or it can corrupt your GH file, which is why it was left as a manual process.
Wrapping it up
So, in essence, every time you want to modify the constructor of a Schema class; instead of modifying the existing constructor, i’d suggest:
Flagging the constructor with SchemaDeprecated attribute, and update it’s implementation to work with the new changes (for backward compatibility)
Adding a new constructor with the necessary parameters and copy over the SchemaInfo attribute (updating any descriptions if needed)
Creating a class that implements IGH_UpgradeObject and update any changes in inputs or outputs.
I’m thinking this may need to go into our dev docs!
You can see some of our IGH_UpgradeObject implementations here:
Thanks for the detailed response. This was extremely helpful in implementing the upgrade component feature to some test structural objects.
We noticed that placing the upgraded classes in the Objects project causes issues in the T4 template generating the .cs file, so we are currently working by placing them within the Object folder that lives in the Grasshopper Connector - is this the most appropriate location to place these upgraded classes?
Secondly, I had success in changing a class property type (for instance from int to list), but notice that when I try and add an additional property, the upgrade function cannot handle this as the number of parameters of the new constructor does not match the number of inputs collected in the grasshopper component. This causes an index error in the SolveInstance method. Would it be appropriate for us to implement a change here to handle this case? It is likely properties for structural objects may grow or shrink over time.
As the structural objects are likely to evolve over time, it will be difficult and tedious to maintain these upgraded classes’ manually. Do you think implementing a T4 template to generate upgraded classes is a feasible solution to handle this?
I’m glad it helped! I must confess this is a feature I’ve discovered going through the Rhino forum, as it’s not really documented anywhere so my knowledge of it is quite limited. But here’s my understanding:
As far as I’m aware, these IGH_ObjectUpgrade classes need to live on the Connector itself, as that’s where Grasshopper will look for them (same namespace and dll where the GH_Component classes live.
This is the main reason I stuck to this being manual for now. The upgrade function implementation is the one in charge of performing any operations necessary for the “old” component to become the “new” one. Meaning any change of name, access, etc needs to be done manually. But also input/output additions, removals and re-ordering so that they are exactly as the new component expects.
As you may be guessing by now, some of these changes can be more easily automated than others.
A simple addition of a parameter is no problem
If there’s more than one change (like renaming some inputs and re-ordering them), then that could be tricky to properly implement.
If we manage to overcome this either by code or by enforcing some rules on how this should work, then a t4 template would be a good way to go. Although I fear we’re already on the very hacky side of things on our existing t4 template
One final thought
We implemented this upgrade behaviour initially for our main components (as it was a manageable task), and because it was a cool feature!
But, most other plugins never do this, and most Grasshopper user’s don’t even know this exists. So even when implementing an upgrade, my guess is most user’s will still manually swap them (I know I did…)
So it’s up to us to decide if this will bring more benefits than headaches I’ll be happy to hear your thoughts on my rambling (sorry for the long message!! ) Hope that solved most of your questions.