Scene initialization and modified state

In my application, at startup or after a scene change, I do some initialization tasks for some of my modules. After this is finished, the scene of course is always marked as modified and when I try to close the application, it asks me whether I want to save the scene. For the user, however, the scene is empty and untouched. Is there a way to reset the modified state of all the nodes in the scene (including storage nodes) without actually saving the scene?

You can close the scence(shortcut:ctrl+w) in the “file” of the manu but not close the slicer app .

You can iterate through all storage nodes and call storageNode.GetStoredTime().Modified() to indicate that changes has been already stored, so there is no need to save the node. I don’t think StoredTime attribute of vtkMRMLScene is exposed publicly, so you may need to call Commit method to write the scene to some dummy file (if it does not work then we can add a method to allow marking the scene object as “stored”).

1 Like

Thanks for the hint. I managed to achieve what I need in this way:

// create default storage nodes for all storables
std::vector<vtkMRMLNode*> storableNodes;
mrmlScene->GetNodesByClass("vtkMRMLStorableNode", storableNodes);
for (auto&& storableNode : storableNodes)
{
  vtkMRMLStorableNode::SafeDownCast(storableNode)->AddDefaultStorageNode();
}

// set the stored time of all storage nodes to now
std::vector<vtkMRMLNode*> storageNodes;
qSlicerApplication::application()->mrmlScene()->GetNodesByClass("vtkMRMLStorageNode", storageNodes);
for (auto&& storageNode : storageNodes)
{
  vtkMRMLStorageNode::SafeDownCast(storageNode)->GetStoredTimePtr()->Modified();
}

// set stored time of scene to now
mrmlScene->GetStoredTimePtr()->Modified();

In my fork, I added:

//------------------------------------------------------------------------------
vtkTimeStamp vtkMRMLStorageNode::GetStoredTime()
{
  return *this->StoredTime;
}

//------------------------------------------------------------------------------
// Added method that returns pointer to StoredTime
vtkTimeStamp* vtkMRMLStorageNode::GetStoredTimePtr()
{
  return this->StoredTime;
}

and

//-----------------------------------------------------------------------------
vtkTimeStamp* vtkMRMLScene::GetStoredTimePtr()
{
  return &this->StoredTime;
}
1 Like

Thanks for sharing. FYI, in custom applications we usually override the entire save dialog.

Thank you, yes, I alredy did this, however I still use

if (scene->GetStorableNodesModifiedSinceRead() || scene->GetModifiedSinceRead())

for determining whether there were changes to the scene.

1 Like