AppendCustomGeometry <-> AppendCustomGeometry

I have a component that inherits GH_CustomPreviewComponent, in Rhino7, we could define override AppendRenderGeometry to change the render behaviour. in Rhino8, this is deprecated.

Looking at the new implementation of GH_CustomPreviewComponent, it uses IGH_CustomPreviewObject and AppendCustomGeometry, but these are internal and private respectively. How do we do custom rendering in Rhino 8 GH components?

1 Like

Hi there,

I have the same question. @nathanletwory, or @andy could you kindly enlighten us?
Cheers

I think @kike is the better person to answer this.

Hi @victorlin,

GH_CustomPreviewComponent.AppendRenderGeometry is not obsolete.
You can override it and it will be called.

Is there anything not working on your component in v8 that was working in v7?

Thanks for the swift response!

I could have dug a bit deeper before asking, but here’s how I achieved adding objects to the render pipeline in Rhino 8: I did inherit from GH_CustomPreviewComponent and overrode GH_CustomPreviewComponent.AppendRenderGeometry. However, from some reading other posts I thought I’d just have to add objects to args.Geomety, but that doesn’t work (my guess it’s been changed with Rhino8?). Instead call PushToRenderPipeline on a GH_CustomPreviewItem.
Full sample below. It should be very similar for other types of geometry.

    Mesh someMesh;
    DisplayMaterial someMaterial;
    public override void AppendRenderGeometry(GH_RenderArgs args)
    {
            args.Geomety.Add(someMesh); // <-- will not work, bc args.Geomety is null and exposes no setter

            //instead do this
            var prevItem = new GH_CustomPreviewItem();
            prevItem.Geometry = new GH_Mesh(someMesh);
            prevItem.Material = new GH_Material(someMaterial);
            prevItem.Shader = someMaterial;
            prevItem.Colour = someMaterial.Diffuse;
            
            prevItem.PushToRenderPipeline(args); // <--- this seems to be new in Rhino8?
    }

Thanks again have a nice day
Ben

1 Like

Looking into the v7 code PushToRenderPipeline was already there.
So this code should work on v7 and v8.

1 Like

Actually I ran into another problem.
Somehow AppendRenderGeometry doesn’t get called anymore. To be more precise: it gets called only once, when the component recomputes (i.e. I change the input to the GH component and it recomputes). But upon rotating the object, AppendRenderGeometry does not get called. I am in Render mode in the viewport. It was working before, and I’m not sure what I changed. I also set IncludeInRender to true in the constructor.

Did anyone experience this too and can give some insight into when and why AppendRenderGeometry gets called?

It should be called once every time the input changes, but not while you are orbiting the viewport.

Is it what you see on your side?

That is what I see on my side. Sorry I assumed it would be called everytime I change the view and a render needs to be done. (Smh I thought I observed such a behavior earlier).

So now my problem is that I make changes to my GH_CustomPreviewItems in between component solutions. Is there a way to instruct GH_CustomPreviewComponent to trigger AppendRenderGeometry (without the costly ExpireSolution)? I tried ExpirePreview without success.

The only way is calling ExpireSolution on your component.
This should be fast, it will not expire the entire document solution but only your component and your outputs if you have any output.

1 Like

Thanks! Although my component does some heavy lifting in addition to display, but I’ll find a way to reduce overhead.

Thanks again, problem solved.