# Errors displaying an array of ON\_Mesh elements

**URL:** <https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114>\
**Category:** Rhino Developer\
**Tags:** windows\
**Created:** [June 19, 2026, 12:25pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114 "2026-06-19T12:25:08Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 12:25pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/1 "2026-06-19T12:25:08Z")

</div>

I have an array of ON\_Mesh elements that intersect and overlap each other. This array represents the result of machining a workpiece with a tool. For display, the algorithm used the

> void CRhinoDisplayPipeline::DrawShadedMesh(const ON\_Mesh& mesh, const CDisplayPipelineMaterial\* = nullptr);

function, drawing each mesh one by one. But this approach was extremely time-consuming. I tried using

> void CRhinoDisplayPipeline::DrawShadedMeshes(const ON\_Mesh\* const\* meshes, int count, const CDisplayPipelineMaterial\* material, CRhinoCacheHandle\* const \* caches);

, which displays the entire array of meshes and caches their state. This became an order of magnitude faster.

However, during testing, I encountered an inexplicable problem.

If I use a cylinder as the initial workpiece, the meshes of the cylindrical shell do not disappear during the cutter’s pass. That is, the tool plunges into the cylindrical workpiece, moves, and the toolpath meshes are displayed, but the outer meshes of the workpiece shell do not disappear and continue to obscure the emerging toolpath meshes. To make this easier to understand, imagine a bolt being threaded with a tool. The tool plunges into the bolt initial workpiece and moves along it. Toolpaths are also generated - you can see them by zooming in on the initial workpiece. However, the toolpath remain hidden within the initial workpiece, not disappearing where the toolpath are. If I use a parallelepiped as the initial workpiece, everything works fine — the initial workpiece shell disappears above the toolpath.  
However, when using DrawShadedMesh, everything displays correctly for the same set of meshes from the cylindrical initial workpiece described above. So, as I understand it, Rhinoceros somehow automatically removes outer meshes if other meshes appear underneath them.

Does anyone know how this mechanism works and how to force it to work for DrawShadedMeshes? And why does it work for a parallelepiped with DrawShadedMeshes, but not for a cylinder?

---

<div class="post-metadata">

**Author:** ![menno](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/menno/32/770384_2.png) [@menno](https://discourse.mcneel.com/u/menno)\
**Post date:** [June 19, 2026, 1:47pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/2 "2026-06-19T13:47:15Z")

</div>

You should be able to merge all meshes of the array into one `ON_Mesh` with `ON_Mesh::Append`, then draw that single mesh. One mesh object can contain multiple disjoint pieces. Maybe this helps?

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 2:10pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/3 "2026-06-19T14:10:56Z")

</div>

Thank you for the advice, but it didn’t help unfortunately. The path of the tool remains hidden. Plus, the displaying became as slow as if I were displaying meshes one by one (as I did it using DrawShadedMesh). The beauty of using DrawShadedMeshes is the use of an array of buffer caches. As far as I understand, with this approach, optimization occurs at the hardware level and if the mesh has not changed, then the video card simply uses the data from the buffer cache, and thus there is no need to transfer data from these meshes through the data bus. Something happens when I output meshes one by one (using DrawShadedMesh), their visibility is recalculated.

---

<div class="post-metadata">

**Author:** ![menno](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/menno/32/770384_2.png) [@menno](https://discourse.mcneel.com/u/menno)\
**Post date:** [June 19, 2026, 2:19pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/4 "2026-06-19T14:19:08Z")

</div>

Could you maybe record a short screenshot video of what is happening both with drawing individual meshes, and drawing them with `DrawShadedMeshes` that takes the caches?  
Also, please for completeness sake, please share the output of the `SystemInfo` command.

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 3:28pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/5 "2026-06-19T15:28:27Z")

</div>

This is working with DrawShadedMesh:

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 3:29pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/6 "2026-06-19T15:29:00Z")

</div>

This is working with DrawShadedMeshes:

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 3:36pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/7 "2026-06-19T15:36:37Z")

</div>

This is working with DrawShadedMeshes, but I used a parallelepiped as the initial workpiece for the same machining:

---

<div class="post-metadata">

**Author:** ![stevebaer](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/stevebaer/32/473567_2.png) [@stevebaer](https://discourse.mcneel.com/u/stevebaer)\
**Post date:** [June 19, 2026, 3:46pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/8 "2026-06-19T15:46:11Z")

</div>

If a CRhinoCacheHandle is passed to these functions, it is assumed that the data in the cache handle is correct and should be used. If your geometry is changing, you need to reset the cache handle so the display knows it needs to rebuild the cache.

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 3:57pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/9 "2026-06-19T15:57:16Z")

</div>

Thank you for the advice Steve. I reset the cache correctly. Every time when I get a new ON\_Mesh I create a new CRhinoCacheHandle for it.

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 4:08pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/10 "2026-06-19T16:08:27Z")

</div>

As you can see on the last video I sent, the simulation with DrawShadedMeshes works fine in that case. All conditions are the same. The only different is using cubic initial workpiece instead of cylindrical.

---

<div class="post-metadata">

**Author:** ![stevebaer](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/stevebaer/32/473567_2.png) [@stevebaer](https://discourse.mcneel.com/u/stevebaer)\
**Post date:** [June 19, 2026, 4:13pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/11 "2026-06-19T16:13:56Z")

</div>

Do things work if you pass `nullptr` in for the cache argument? I’m trying to figure out if this is related to the CRhinoCacheHandle

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 19, 2026, 5:01pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/12 "2026-06-19T17:01:33Z")

</div>

I already tried it - it didn’t help, just the simulation become working more slowly. Meshes of toolpath remained hidden. This is the first thing I tried when I faced this problem.

---

<div class="post-metadata">

**Author:** ![stevebaer](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/stevebaer/32/473567_2.png) [@stevebaer](https://discourse.mcneel.com/u/stevebaer)\
**Post date:** [June 19, 2026, 6:37pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/13 "2026-06-19T18:37:03Z")

</div>

I might need a small code sample to be of any help. Maybe I can spot something that way

---

<div class="post-metadata">

**Author:** ![Andrey\_Angerchik](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andrey_angerchik/32/485728_2.png) [@Andrey\_Angerchik](https://discourse.mcneel.com/u/Andrey_Angerchik)\
**Post date:** [June 21, 2026, 6:02pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/14 "2026-06-21T18:02:35Z")

</div>

Ok Steve, I’ll try to post the most important moments:

Before changing (using DrawShadedMesh):

> ```cpp
> CRhinoDisplayPipeline* p_display_pipe_line = 
> m_p_rhino_viewport->DisplayPipeline();
> 
> if (p_display_pipe_line == NULL) 
> {
> return;
> }
> 
> if (m_rebuild_mesh) 
> {
> m_rebuild_mesh = false;
> 
> for (int i = 0; i < m_mesh_indexes_for_rebuild.Count(); i++) 
> {
> std::map<int, ON_Mesh*>::iterator it =
> m_mesh_map.find(m_mesh_indexes_for_rebuild[i]);
> if (it != m_mesh_map.end() && it->second == NULL) 
> {
> it->second = ConvertMWMeshToONMesh(m_mw_triangles[it->first]);
> }
> }
> m_mesh_indexes_for_rebuild.Destroy();
> 
> }
> 
> ON_Color t_color = ON_Color(0, 63, 106, 0);
> CDisplayPipelineMaterial t_mat;
> p_display_pipe_line->SetupDisplayMaterial(t_mat, t_color);
> 
> ON_Mesh** p_arrMesh = new ON_Mesh * [m_mesh_map.size()];
> 
> int i = 0;
> for (std::map<int, ON_Mesh*>::iterator it = m_mesh_map.begin(); 
> it != m_mesh_map.end(); 
> ++it) 
> {
> if (m_visible.find(it->first) == m_visible.end() || 
> m_visible[it->first] == true) 
> {
> if (it->second != NULL) 
> {
> p_display_pipe_line->DrawShadedMesh(*it->second, &t_mat);
> }
> }
> }
> 
> ```

After changing (using DrawShadedMeshes):

> ```cpp
> CRhinoDisplayPipeline* p_display_pipe_line = 
> m_p_rhino_viewport->DisplayPipeline();
> 
> if (p_display_pipe_line == NULL) 
> {
> return;
> }
> 
> ON_Color t_color = ON_Color(0, 63, 106, 0);
> CDisplayPipelineMaterial t_mat;
> p_display_pipe_line->SetupDisplayMaterial(t_mat, t_color);
> 
> if (m_rebuild_mesh) 
> {
> m_rebuild_mesh = false;
> 
> for (int i = 0; i < m_mesh_indexes_for_rebuild.Count(); i++) 
> {
> CachedMesh* p_CachedMesh = 
> m_mesh_map[m_mesh_indexes_for_rebuild[i]];
> 
> if (m_mesh_map.count(m_mesh_indexes_for_rebuild[i]) > 0 && 
> p_CachedMesh == nullptr) 
> {
> p_CachedMesh = new CachedMesh;
> p_CachedMesh->p_mesh = 
> ConvertMWMeshToONMesh(m_mw_triangles[m_mesh_indexes_for_rebuild[i]]);
> p_CachedMesh->p_cacheHandle = new CRhinoCacheHandle();
> m_mesh_map[m_mesh_indexes_for_rebuild[i]] = p_CachedMesh;
> }
> }
> 
> if (m_arrMesh.size() != 0)
> m_arrMesh.clear();
> 
> if (m_rhinoCache.size() != 0)
> m_rhinoCache.clear();
> 	
> m_arrMesh.reserve(m_mesh_map.size());
> m_rhinoCache.reserve(m_mesh_map.size());
> 
> for (std::map<int, CachedMesh*>::iterator it = m_mesh_map.begin(); 
> it != m_mesh_map.end(); 
> ++it) 
> {
> m_arrMesh.push_back(it->second->p_mesh);
> m_rhinoCache.push_back(it->second->p_cacheHandle);
> }
> 
> }
> 
> p_display_pipe_line->DrawShadedMeshes(m_arrMesh.data(), m_mesh_map.size(), &t_mat, m_rhinoCache.data());
> 
> m_mesh_indexes_for_rebuild.Destroy();
> 
> ```
> 
> }

Where CachedMesh is a struct:

```cpp
struct CachedMesh {
	ON_Mesh* p_mesh = nullptr;
	CRhinoCacheHandle* p_cacheHandle = nullptr;

	~CachedMesh() {
		if (p_mesh != nullptr) {
			delete p_mesh;
			p_mesh = nullptr;
		}
		if (p_cacheHandle != nullptr) {
			delete p_cacheHandle;
			p_cacheHandle = nullptr;
		}
	}
};

```

and vectors:

```cpp
std::vector<ON_Mesh*> m_arrMesh;
std::vector<CRhinoCacheHandle*> m_rhinoCache;

```

If it isn’t enaught I can add whatever you want

---

<div class="post-metadata">

**Author:** ![dale](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dale/32/685184_2.png) [@dale](https://discourse.mcneel.com/u/dale)\
**Post date:** [September 30, 2026, 10:47pm UTC](https://discourse.mcneel.com/t/errors-displaying-an-array-of-on-mesh-elements/220114/15 "2026-09-30T22:47:32Z")

</div>

Hi @Andrey_Angerchik,

I think I see the difference, unless I’m confused.

Your `DrawShadedMesh` loop skips meshes where `m_visible[index]` is `false`. Your `DrawShadedMeshes` version adds every mesh in `m_mesh_map` to the array, so the hidden meshes (probably the cylinder shell pieces) get drawn anyway.

Apply the same `m_visible` and `nullptr` checks when you fill `m_arrMesh` and `m_rhinoCache`. Also rebuild those arrays whenever visibility changes, not only when `m_rebuild_mesh` is set:

```csharp
for (auto it = m_mesh_map.begin(); it != m_mesh_map.end(); ++it)
{
  if (m_visible.find(it->first) != m_visible.end() && !m_visible[it->first])
    continue;
  if (it->second == nullptr || it->second->p_mesh == nullptr)
    continue;
  m_arrMesh.push_back(it->second->p_mesh);
  m_rhinoCache.push_back(it->second->p_cacheHandle);
}
...
p_display_pipe_line->DrawShadedMeshes(m_arrMesh.data(), (int)m_arrMesh.size(), &t_mat, m_rhinoCache.data());

```

Note the count now comes from `m_arrMesh.size()`, not `m_mesh_map.size()`.

– Dale
