C++ Ctrl+Z

Hi,

I would like to ask how can I enable undo in Rhino after I execute Rhino Command?

In the command I duplicate the mesh and modify it, then replace the input mesh with the modified one.
After the command line is executed and the mesh is replaced, Ctrl+Z does not do anything.

    const ON_Mesh* RhinoMesh_ = go.Object(0).Mesh(); //Get Mesh
    ON_Mesh RhinoMesh(*RhinoMesh_);//Copy Mesh
    RhinoMesh_->~ON_Mesh();//Delete user input
          
     CRhinoMeshObject* meshObjBaked = NULL;
    CRhinoObjRef objRef = NULL;
    
     // Do Something with it

     ////////////////////////////////////////////////////////////////
     // Bake Mesh
     ////////////////////////////////////////////////////////////////

     if (rhinoMesh.IsValid()) {
                if (meshObjBaked == NULL) {
                    meshObjBaked = context.m_doc.AddMeshObject(rhinoMesh);
                    objRef = CRhinoObjRef(meshObjBaked);
                }
                else {
                    context.m_doc.ReplaceObject(objRef, rhinoMesh);
                }
                context.m_doc.Redraw();
     }

I don’t think you should call the destructor on the input mesh, it is a const pointer, which indicates that it is “read-only”. I suspect that this may also break undo, as undo/redo should just work for modifications done by a command.

Thanks. I will try to replace the input mesh with modified one instead of deleting it.

How would you modify this mesh because it is const:
const ON_Mesh* RhinoMesh_ = go.Object(0).Mesh(); //Get Mesh

Do you replace it somehow?

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
  CRhinoGetObject go;
  go.SetCommandPrompt(L"Select mesh");
  go.SetGeometryFilter(CRhinoGetObject::mesh_object);
  go.EnableSubObjectSelect(false);
  go.GetObjects(1, 1);
  if (go.CommandResult() != CRhinoCommand::success)
    return go.CommandResult();

  const CRhinoObjRef& obj_ref = go.Object(0);
  const ON_Mesh* ptr_const_mesh = obj_ref.Mesh();
  if (nullptr == ptr_const_mesh)
    return CRhinoCommand::failure;

  ON_Mesh mesh_copy(*ptr_const_mesh);
  // todo: make fancy changes

  if (mesh_copy.IsValid())
  {
    context.m_doc.ReplaceObject(obj_ref, mesh_copy);
    context.m_doc.Redraw();
  }

  return CRhinoCommand::success;
}
1 Like

This in fact does the job:

    const ON_Mesh* RhinoMesh_ = go.Object(0).Mesh(); //Get Mesh
    CRhinoObjRef objRef = CRhinoObjRef(go.Object(0)); 
    //do something and then replace:
            if (rhinoMesh.IsValid()) {
                context.m_doc.ReplaceObject(objRef, rhinoMesh);
                context.m_doc.Redraw();
            }

Thanks @Dale