Errors displaying an array of ON_Mesh elements

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?

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?

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.

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.

This is working with DrawShadedMesh:

This is working with DrawShadedMeshes:

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

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.

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.

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.

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

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.

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

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

Before changing (using DrawShadedMesh):

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):

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:

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:

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

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