How to access geometry Guids in Grasshopper components
This month has been a nice month for software development in my research, working on creating new analysis for healthcare design. The majority of it has been relatively straight forward (except the interpolation issue) working in C++ to produce the analysis. However, to move towards a tool which can be used in industry, I have had need to venture into James’ realm of Grasshopper development in order to produce a Grasshopper component that can be used to analyse designs in Rhino.
This has been my first trip on creating my own Grasshopper component, but I would not consider myself to be a complete novice in the art. Primarily, it is still software development just with some different libraries and secondly, my work with James in traversing the Rhino/Grasshopper libraries and in supervising development of Smart Space Analyser.
That isn’t to say the venture has been without problems mind. One of the worst so far was trying to identify unique geometry coming in and circulating round my component. The most obvious way to do this is through the use of Guids, unique identifiers for objects. Unfortunately, accessing these identifiers in Rhino or Grasshopper geometry isn’t explicitly clear, and a Google search of the problem did not throw up much help. However, with some traversing of the libraries, discussions with James (including a half-hearted look at the Rhino Object Table), a solution was found.
Accessing Geometry Guids
Grasshopper does store the reference Guid of objects which have a link to Rhino – i.e. if a piece of Grasshopper geometry physically exists in Rhino, it has a copy of the Guid from the Rhino object. Geometry which inherits from GH_GeometricGoo can access this parameter.
Objects which are picked up by Grasshopper components can automatically be converted from Rhino geometry into Grasshopper geometry upon entry to the component. However, you do need to be careful with what type of geometry you have coming in, because if you collect a list of curves but polylines were input, you’re likely to end up with a runtime error. The easiest way of dealing with this is to use the parent class, following the rules of inheritance, allowing you to generalise your inputs.
Grasshopper Parent Object
For Grasshopper, the easiest option is to take inputs of type IGH_GeometricGoo. You can cast back from these to other specific types of geometry later as necessary.
Accessing the Guid
Once you have an object of type IGH_GeometricGoo, you can obtain the Guid very easily by calling for the reference ID, as shown in the example below.
protected override void SolveInstance(IGH_DataAccess DA) { Grasshopper.Kernel.Types.IGH_GeometricGoo geom = new Grasshopper.Kernel.Types.IGH_GeometricGoo(); DA.GetData(0, geom); System.Guid id = geom.ReferenceID; DA.SetData(0, id); }
Warnings
Obviously nothing comes without a few strings attached in Grasshopper development, and these are the ones I’ve found so far.
- If you internalise the data, you lose the Guid – the ReferenceID property is linked to the Guid of the object in Rhino. Thus, if you internalise the data, or create geometry within the Grasshopper canvas, this won’t have a Guid and you’ll obtain an empty Guid instead.
- The Guid is a C# System.Guid, not a C++ GUID. If you’re working between both languages, make sure to marshal your Guids appropriately.
- This one is pretty obvious, but sometimes it is the obvious things which elude us – if you’re using the unique identifiers across multiple types of geometry (e.g. you’re using a rectangle to define an analysis area, and an analysis obstacle) and you have measures preventing the inclusion of identical Guids in your code (in the C# or C++ if using an engine), then obviously you’ll end up not adding both even if you actually want or need to.
- At the moment, I haven’t found a way to make this work in the C# component of Grasshopper, it seems this only works with components which are built and compiled themselves.