Event about vtkMRMLModelNode

In the logic of my custom module, I can know that a new node has been added to the scene by OnMRMLSceneNodeAdded. For example, vtkMRMLModelNode, I can tell that a vtkMRMLMOdelNode was created and its displayNode was created, but they are not bound together at this point, So I can’t get displayNode from vtkMRMLModelNode in OnMRMLSceneNodeAdded or vtkMRMLDisplayableNode from displayNode. What event should I use to get a vtkMRMLModelNode that has completed initialization。 thaks。


displayNode and displayableNode are nullptr

In your case what adds new nodes to the scene? What is the use case?

I wanted to make it possible to move when a model was added, so I added the following code to logic.

	void vtkSlicerMaterialDatabaseLogic
::OnMRMLSceneNodeAdded(vtkMRMLNode* node)
{
	auto modelNode = vtkMRMLModelNode::SafeDownCast(node);
	if (nullptr != modelNode)
	{
		auto* transform = vtkMRMLTransformNode::SafeDownCast(node->GetScene()->AddNewNodeByClass("vtkMRMLTransformNode"));
		if (nullptr != transform)
		{
			transform->CreateDefaultDisplayNodes();
			modelNode->SetAndObserveTransformNodeID(transform->GetID());
			auto transformDisplay = vtkMRMLTransformDisplayNode::SafeDownCast(transform->GetDisplayNode());
			if (nullptr != transformDisplay)
			{
				transformDisplay->SetEditorVisibility(true);
				transformDisplay->UpdateEditorBounds();
			}
		}
	}
}

But when I call UpdateEditorBounds, modelNode doesn’t have a displayNode yet.
But I am now using vtkMRMLModelNode: : DisplayModifiedEvent solved the problem。

void qSlicerMaterialDatabaseModule::onVtkMRMLModelDisplayNodeAdd(vtkMRMLModelNode* node)
{
	Q_D(qSlicerMaterialDatabaseModule);

	if (nullptr != node && nullptr != d->Widget && 0 != d->Widget->getLastDorpAction())
	{
		d->Widget->resetLastDropAction();

		d->ModelNode = node;
		this->qvtkConnect(d->ModelNode, vtkMRMLModelNode::DisplayModifiedEvent, this, SLOT(onDisplayModifiedEvent()));
	}
}

void qSlicerMaterialDatabaseModule::onDisplayModifiedEvent()
{
	Q_D(qSlicerMaterialDatabaseModule);
	if (nullptr != d->ModelNode)
	{
		this->qvtkDisconnect(d->ModelNode, vtkMRMLModelNode::DisplayModifiedEvent, this, SLOT(onDisplayModifiedEvent()));

		auto* transform = vtkMRMLTransformNode::SafeDownCast(d->ModelNode->GetScene()->AddNewNodeByClass("vtkMRMLTransformNode"));
		if (nullptr != transform)
		{
			transform->CreateDefaultDisplayNodes();
			d->ModelNode->SetAndObserveTransformNodeID(transform->GetID());
			auto transformDisplay = vtkMRMLTransformDisplayNode::SafeDownCast(transform->GetDisplayNode());
			if (nullptr != transformDisplay)
			{
				transformDisplay->SetEditorVisibility(true);
				transformDisplay->UpdateEditorBounds();
			}
		}

		d->ModelNode = nullptr;
	}
}

It probably makes sense to not react immediately when the new node is created but when the application has performed all the processing and becomes idle. You can do that by using QTimer as shown in this script repository example.