IGH_PreviewData vs IGH_PreviewObject?


I think I don’t properly understand the difference between previewing a GH data type (that implements IGH_PreviewData) and its corresponding GH parameter (that implements IGH_PreviewObject).

Can some one give me some precisions ? I don’t see where/how/when a GH data type might be involved in a viewport redraw and when the corresponding DrawViewportWires method is called.

Almost always previewable data knows how to draw itself. Points, lines, breps, meshes… however the grasshopper preview code doesn’t iterate over all the data instances in components and parameters, it only iterates over the canvas objects and tells them to draw their data.

Document; “hey there point parameter, time to draw your previews in this viewport.”
Parameter; “okay then, point #1 draw yourself in this viewport.”
Point data; “righty-ho, one cross coming up.”
Parameter; “Point #2 draw yourself in this viewport.”

Most parameters simply iterate over all items in their volatile data and call the Draw() method on each one, however this system allows for parameters to make optimizations. For example the point parameter may choose to build a single point array of all volatile data and draw it all at once, thus speeding up the process.

Oh I see David … Can you tell me if I am right or not ?

Let’s say I have my own C# type called MyType, the corresponding GH Type (GH_MyType : GH_Goo<MyType>) and the corresponding GH Param (Param_MyType : GH_Param<GH_MyType).

  1. Then If I implement DrawViewportWires(IGH_PreviewArgs args) for my custom parameter (through the IGH_PreviewObject interface) I don’t need to implement DrawViewportWires(GH_PreviewArgs args) (through the IGH_PreviewData interface) for my custom data as the redraw will never reach this method right ?

  2. If I don’t implement DrawViewportWires(IGH_PreviewArgs args) for my custom parameter but I implement DrawViewportWires(GH_PreviewArgs args) (through the IGH_PreviewData interface) for my custom data I will also get fully redrawing. And what happens is that Param_MyType calls internally Preview_DrawWires which will call DrawViewportWires(GH_PreviewArgs args) for each data it contains right ?

  3. Is there any cases it can by useful to implement both IGH_PreviewArgs for the parameter and IGH_PreviewData for the data type ?

  4. Would you recommend 1, 2 or both if my data display contains thousands of points (redraw speed might need to be optimized) ?

Yes correct, the parameter could do all the drawing itself. But if your type doesn’t implement any drawing code then other parameters such as Data or Geometry can’t draw your type.

No, only if you put your data into a Data or Geometry parameter. If you create your own parameter type to go along with your data, it will need to implement IGH_PreviewObject if it is to draw anything.

No, it won’t do that by default. You must implement IGH_PreviewObject or Grasshopper will not even look at your parameter when it’s time to draw previews. The implementation can be very minimal, all you really need is to call the Preview_DrawWires(args) utility method, but somebody has to call it and that somebody is going to have to be you.

I would always implement both. Keep the parameter simple, just call Preview_DrawWires(args) and build your clipping box, keep all the complicated drawing code in your data type.

Ok, thanks for your accurate answer David !

One more question:

I know if my data is selected in a param with Attributes.Selected so I can change the display accordingly.
How can I possibly do that from DrawViewportWires(GH_PreviewArgs args) inside my GH_MyType ?

For instance, if a list of my custom data is inputed in the List Item component, how I can change the display of my data if the component is selected or not ? There is no Attributes.Selected in there …