Update Child After RemapObjectIds?

I’m updating a child obj’s parent.

  const CRhinoHistoryRecord* record = object->HistoryRecord();
  if (nullptr == record)
    return 0;
  ON_HistoryRecord* copy = doc->m_history_record_table.GetPrunedHistoryRecord(record->RecordIndex());
  if (nullptr == copy)
    return 0;

  ON_SimpleArray<ON_UuidPair> remap(1);
  ON_UuidPair& pair = remap.AppendNew();
  pair.m_uuid[0] = oldParentId;
  pair.m_uuid[1] = newParentId;
  copy->RemapObjectIds(remap);

  CRhinoHistory history(copy); 

  CRhinoHistoryManager* manager = RhinoHistoryManager();
  const bool bRecording = manager->HistoryRecordingEnabled();
  manager->EnableHistoryRecording(true);

  const bool rc = doc->m_history_record_table.CreateObjectHistory(
    const_cast<CRhinoObject*>(object), history);

  manager->EnableHistoryRecording(bRecording);

Afterward, how do I get history to replay with the new parent, as you would with _HistoryUpdate?

Hi @EricM,

You cannot update history as a command operation. That is, this is something you cannot trigger mid-command.

That said, you might be able to trigger an update in an idle event handler. In this case, this might work:

void HistoryUpdateDescendants(unsigned int docSerialNumber)
{
  CRhinoDoc* pDoc = CRhinoDoc::FromRuntimeSerialNumber(docSerialNumber);
  if (nullptr != pDoc && 0 == pDoc->InCommand(true))
  {
    CRhinoHistoryManager* pHistoryManager = RhinoHistoryManager(pDoc);
    if (pHistoryManager)
      pHistoryManager->UpdateDescendants(*pDoc);
  }
}

– Dale

Hmm…that’s not ideal. I was able to get it to update by treating it like a normal command. After the remap, I replaced the parent in doc objects with no changes, which triggered a history replay on the child. However, that also broke history on the parent.

What if after I remap the parent, I copy the parent’s history record, replace the parent obj in the doc, and then push that history record back into the table?

Oh, what about UpdateDescendants()? If you can’t update within a command, where is this meant to be run from?

Hi @EricM,

From rhinoSdkObjectHistory.h:

// Expert user tools 
//  - no support available 
//  - can change without notice
CRhinoCommand::result UpdateDescendants(class CRhinoDoc& doc);

I’ve already mentioned how you might use this.

Rhino’s command manager calls this after executing your command.

– Dale