Drawing large amount of mesh objects

Hi
I am working on merging our FEA application to Rhino.
Now it comes that I need to display the model and 2 routes seem to be the way:

  1. Draw the objects without baking them into Rhino
  2. Bake them int Rhino Layers

I am looking at option 1 to avoid baking-deleting objects when these are changed but the display
pipeline becomes quite slow with a large amount of data to display.
So the question is:
Do we have other ways to draw objects ? maybe a opengl display list ?

I see that grasshopper is quite fast in rendering objects so i assume its possible

thanks
gerry

here a image to show a model where the display becomes very slow,
clearly the reason is that objects get drawn at each render pass

gd

How many meshes are being drawn? Is all data cached? We have had similar issues when there was a lot of computation begin done to get the meshes. If you cache everything, the drawing should be come faster. If you’re already caching, there may be other tricks and openGL drawing is one of them.

This is a model built out of a fea model, so there are many meshes (all small pipes)
All computation has been done, I have a list of mesh objects to get displayed and using a pipeline to draw them but the viewport becomes very slow.
I have searched other tools in the Rhino.Display other than the DisplayConduit that I am using, the customDisplay object seemed to do the job but so far there is no AddMesh routine.
So the question is how can I make a OpenGL display list once and keep it alive ?

gd

OpenGL I have no experience with, but take a look at the DisplayPipeline class, it has a lot of useful methods. https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Display_DisplayPipeline.htm

Maybe if you join all meshes into one big mesh that already helps, i think I remember that.

Not feasible, i need to keep them separate to be able to change color and visibility
but it will not change so much if there is no display buffer.
When we draw objects these are sent in immediate mode to the graphic card, with display list they are compiled and kept in the graphic card memory, so it makes a huge difference in display speed,

At least using OpenGL .

gd

Hi @gerryark,

Of you load a large Rhino model, is the display still responsive?

There isn’t any reason why a custom, plug-in based display conduit, wouldn’t draw as fast what Rhino natively draws.

To provide assistance, we’ll need a code sample of your display conduit. Having a project that we can run here, to experience the slowness, would be a bonus deal.

Thanks,

– Dale

Hi dale
Let me explain what we are doing.
Our rhino plugin is in communication with our fem app. It reads all elements and creates a number of objects (meshes, extrusions etc), these are kept in a custom list (breps are meshed) and displayed in a displaycounduit.

Now if I bake these objects in rhino the difference in display speed is huge compared to the display conduit version, maybe I am doing something wrong, but I just go trough the list and use drawmesh on each object.

Monday will send you the code, to see what’s going on in real-time you should install our fem app since nothing is baked in the rhino database.
No problem if you want to test it.

Hi Dale
The code as You may see is quite simple. If I turn on shaded meshes the display rate gets slow.
All this compared to the same model baked in Rhino

   protected void DrawObjects(DrawEventArgs e, GroupData grp)
        {
            foreach (Rhino.Geometry.Curve c in grp.lingeom)
                e.Display.DrawCurve(c, grp.mColor);

            foreach (Rhino.Geometry.Mesh m in grp.linMesh)
                e.Display.DrawMeshWires(m, grp.mColor);
        }

        protected void DrawLayerItem(LayerItem it, DrawEventArgs e)
        {
            foreach (GroupData grp in it.mGroupItems)
            {
                DrawObjects(e, grp);
            }

            foreach (KeyValuePair<Guid, LayerItem> ch in it.mChilds )
            {
                DrawLayerItem(  ch.Value , e );
            }
        }


        protected override void PostDrawObjects(DrawEventArgs e)
        {
            foreach (LayerItem it in AracnidPlugIn.Instance.FeaModel.mLayers)
            {
                DrawLayerItem(it, e);
            }
        }
1 Like

Bumping this topic as we have a similar problem, we are drawing a preview with a number of meshes and it becomes really unresponsive. Is there a way to tell Rhino to either create a VBO or similar and use that for rendering the mesh?

Hi @Alberto,

Are you using Rhino 6 or 7? Can you post the SystemInfo on a system that becomes unresponsive? Also, are you working in C# or C++? Can you provide a way for us to repeat this?

Thanks,

– Dale

Would it be possible to let the developer make a mesh and control
the VBO create,delete and update phase ? I really find it uncomfortable that Rhino
wants to do all this in automatic. The reason is we (on this side of the wall) do not know whats going on and unable to detect bottlenecks. A kind of VBO_mesh object with visibility flags

I have understood that if we modify a mesh object the cache gets deleted and updated at the next redraw and this is what I really hate. I want to keep the cache object and update it when ready to do so (under my control).

simplification is good in most cases but here I find it breaking the rules for cache objects.

my2c

HI @dale we are using Rhino 6 (and testing on Rhino 7 does the same) we are writing C# code I am using a not so powerful laptop but if I add my meshes to the document then the view is super smooth. I therefore assumed that this is related to how the data is sent to the GPU. Here are my system info

Rhino 6 SR34 2021-2-3 (Rhino 6, 6.34.21034.07001, Git hash:master @ 2fec8130f097ca52a8bc9f334c3ed4a5921c5e30)
License type: Commercial, build 2021-02-03
License details: LAN Zoo Network Node Checked Out

Windows 10.0.0 SR0.0 or greater (Physical RAM: 16Gb)
Machine name: HAMILTON

Computer platform: LAPTOP - Plugged in [99% battery remaining]

Hybrid graphics configuration.
  Primary display: Intel(R) HD Graphics 630 (Intel) Memory: 1GB, Driver date: 7-8-2020 (M-D-Y).
    > Integrated graphics device with 3 adapter port(s)
        - Windows Main Display is laptop's integrated screen or built-in port
  Primary OpenGL: NVIDIA GeForce GTX 1050 (NVidia) Memory: 4GB, Driver date: 7-5-2020 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 451.67
    > Integrated acclerated graphics device (shares primary device ports)
        - Video pass-through to primary display device

Secondary graphics devices.
  DisplayLink USB Device (DisplayLink) Memory: 0MB, Driver date: 4-16-2020 (M-D-Y).
    > External USB display device with 2 adapter port(s)
        - Secondary monitor attached to adapter port #0
  DisplayLink USB Device (DisplayLink) Memory: 0MB, Driver date: 4-16-2020 (M-D-Y).
    > External USB display device with 0 adapter port(s)
        - There are no monitors attached to this device. Laptop lid is probably closed

OpenGL Settings
  Safe mode: Off
  Use accelerated hardware modes: On
  Redraw scene when viewports are exposed: On
  
  Anti-alias mode: 4x
  Mip Map Filtering: Linear
  Anisotropic Filtering Mode: High
  
  Vendor Name: NVIDIA Corporation
  Render version: 4.6
  Shading Language: 4.60 NVIDIA
  Driver Date: 7-5-2020
  Driver Version: 27.21.14.5167
  Maximum Texture size: 32768 x 32768
  Z-Buffer depth: 24 bits
  Maximum Viewport size: 32768 x 32768
  Total Video Memory: 4 GB

Rhino plugins
  C:\Program Files\Rhino 6\Plug-ins\Commands.rhp	"Commands"	6.34.21034.7001
  C:\Program Files\Rhino 6\Plug-ins\rdk.rhp	"Renderer Development Kit"	
  D:\workspace\crispin-replacement-sources\Sources\Output\Bin.R6\JPatternPlugin.Rhino6.rhp	"JPatternTech"	2021.1.0.0
  D:\workspace\crispin-replacement-sources\Sources\Output\Bin.R6\JPatternImport.Rhino6.rhp	"JPatternImport"	2021.1.0.0
  C:\Program Files\Rhino 6\Plug-ins\RhinoRender.rhp	"Rhino Render"	
  C:\Program Files\Rhino 6\Plug-ins\rdk_etoui.rhp	"RDK_EtoUI"	6.34.21034.7001
  C:\Program Files\Rhino 6\Plug-ins\rdk_ui.rhp	"Renderer Development Kit UI"	
  C:\Program Files\Rhino 6\Plug-ins\NamedSnapshots.rhp	"Snapshots"	
  D:\workspace\uvmtools\Output\Bin\UVMTools.rhp	"UVMTools"	2.4.0.0
  C:\Program Files\Rhino 6\Plug-ins\RhinoCycles.rhp	"RhinoCycles"	6.34.21034.7001
  C:\Users\Public\Documents\RFToolingRepair\RFToolingRepair.rhp	"RFToolingRepair"	0.8.0.0
  D:\workspace\last-exchange\Sources\Output\Bin\AdiLastExchange.rhp	"AdiLastExchange"	0.6.0.0
  D:\workspace\autotooling\Sources\Output\Bin.R6\AutoToolingPlugin.rhp	"AutoToolingRhino6"	0.6.0.0
  C:\Program Files\Rhino 6\Plug-ins\Toolbars\Toolbars.rhp	"Toolbars"	6.34.21034.7001
  C:\Program Files\Rhino 6\Plug-ins\3dxrhino.rhp	"3Dconnexion 3D Mouse"	
  D:\workspace\rhino-coasmap\Output\Bin\RhinoCoaster.rhp	"RhinoCoaster"	1.0.20.0
  C:\Program Files\Rhino 6\Plug-ins\Displacement.rhp	"Displacement"	

VBOs are created and cached on your mesh objects for display. If you modify these meshes, the VBOs will automatically get rebuilt the next time they are needed for a redraw. Where Rhino is slow with meshes from conduits is materials. Changing materials from one object to the next is expensive and Rhino does extra work when the objects are in the document to see if materials can be reused when iterating through objects. I added code to RhinoCommon’s display pipeline class to attempt to buffer up meshes until a material change is detected in an attempt to improve the situation for conduits drawing many meshes.

Are you drawing all of your meshes with a single material?

Hi Steve, for us it is all the same material. Good to know that it can be improved, I will try to check in our code for any potential pitfall that may degrade the performances and will let you know if I will be able to improve by smart material assignment.

Cheers
Alberto

I checked with VTune and you were right, the draw calls were not a problem but rather our code. We were generating meshes on the fly rather than caching them. So changing that helped quite a lot, now I am also pre-sorting per material so to avoid material changes while rendering.

Alberto

Can you explain what these visibility flags are? I’m having trouble understanding. I can expose our VBO object to RhinoCommon, but I don’t understand how what to really add to it for functions beyond Dispose for deleting the object.

Hi Steve
I have freezed this problem for the moment. Soon will be back on it and I will develop from scratch keeping in mind the fact that meshes are already a kind of cache, maybe it’s just my misunderstanding on how the rhino display works. I am used to generate vbo’s and then only update them (or redraw) when a update is needed,