DrawViewportWires Slow Performance

I have the following code in one of my components to preview some structural geometry, these are Breps that represent a structural beam or member for visualization:

        public override void DrawViewportMeshes(IGH_PreviewArgs args)
        {
            // Extrude elements
            if (extrude)
            {
                // let's create some BREPS for the beams
                List<Brep> extrudedBeams = Visualise.ViewElements.ViewBeams(this.unsolvedModel);
                foreach (Brep beamBrep in extrudedBeams)
                {
                    args.Display.DrawBrepWires(beamBrep, Visualise.Colours.colour_black);
                    args.Display.DrawBrepShaded(beamBrep, Visualise.Colours.colorMaterial);
                }
            }
            base.DrawViewportMeshes(args);
        }

As I move the viewport around in 3D or 2D, the above is called each time (as expected), but the viewing is very very choppy with slow redraw performance.

The Visual Studio profiler claims ~800ms on this line:
base.DrawViewportMeshes(args);

Other lines are <= 1ms. This includes this outside function call:
List<Brep> extrudedBeams = Visualise.ViewElements.ViewBeams(this.unsolvedModel);

For reference, that list has 51 items in it, each consisting of 3 Breps or so. However, this is a problem with any number of extrudedBeams above about 5.

I don’t know the inner workings of the base call so not sure on how to efficiently use it.

Am a bit surprised that the performance is this slow for previewed geometry. I’ve seen much more complicated models and Rhino handles those just fine.

I’ve tried:

  1. Moving List<Brep> extrudedBeams = Visualise.ViewElements.ViewBeams(this.unsolvedModel); to SolveInstance, no difference to performance.
  2. Merging the extrudedBeams list into a single Brep (in SolveInstance) and drawing that instead of the foreach loop. The merge operation was horrendously slow, and unfortunately once merged, the performance was just as choppy.

I could try:

  1. Some kind of RxC treatment where it redraws once the DrawViewportMeshes call is not called for last 800ms or something. Won’t look good on the end user’s screen, but at least they’ll be able to rotate and navigate without slowdowns. Not 100% sure how to implement this though.
  2. Temporarily bake the geometry to some temporary layer then delete layer and rebake when geometry updates.

What can be done here? Am expecting the performance to be close to baked geometry for this preview geometry.

Any ideas appreciated.

Update:
I’ve tried converting the Breps into Meshes instead. While the conversion step is slow, the args.Display.DrawMeshWires(mesh, Visualise.Colours.colour_black); is very fast and performant.

Any advice would be appreciated of course on how to make the Breps work.

Test with the following three scenarios:

  • comment out the call to DrawBrepWires
  • comment out the call to DrawBrepShaded
  • comment out the call to base.DrawViewportMeshes

Which scenario is taking the longest time to refresh frames? This should help us focus on one specific function.

1 Like

Thanks for the ideas. Have tried the following:

comment out the call to DrawBrepWires

Still slow.

comment out the call to DrawBrepShaded

A bit faster, but still choppy.

comment out the call to base.DrawViewportMeshes

I’m no expert, but I have a feeling that if this call is not written out in C#, then it is made implicitly, no?
Commenting this out, the performance is still slow. This is likely the culprit I feel.

Which function is the slow one? Try commenting out all combinations of two out of three.

Based on your comments, I can’t quite determine what is the “slow” one.

1 Like

base.DrawViewportMeshes(args) is the slow function from the above experiments.

If I convert all the Breps into meshes, that process also takes ~800ms but I can do that in the SolveInstance once. The way things are meshed is not 100% ideal as I’m translating too many times and things that used to be straight lines are now not straight lines.

Subsequent to the mesh conversion in SolveInstance, inside DrawViewportMeshes drawing Meshes rather than Breps is fast:
args.Display.DrawMeshShaded(mesh, Visualise.Colours.colorMaterial);

However, the problem is now I need to operate with meshes only and extrude my objects as meshes. Can’t use Breps as redrawing/conversion is too slow.

Which doesn’t seem right to me, I would’ve thought the code for drawings Breps wouldn’t be this slow.

Unless I’m missing some trick.