SetMatrixTransformToParent consume much time

There are a problem about my application when i invoke the method SetMatrixTransformToParent of vtkMRMLLinearTransformNode every times. In my MRMLScene there are more than 500 nodes, and executing the method SetMatrixTransformToParent consumes 330 ms.

There must be something else going on in the code, because setting the matrix should not add new nodes. Please provide exact steps to reproduce what you are seeing.

As I understand it, there are 500 nodes in the scene, intentionally (that are probably all being transformed).

There are many ways to improve the performance and the best solution depends on what you would like to achieve.

Can you tell a bit more about your use case?
What kind of nodes are those 500 nodes and what do they represent?
What do you use the transform for?

THANKS FOR YOUR REPLYING!! My case description below.
step 1. In my application, there are only one vtkMRMLScene, and six qMRMLThreeDWidget which reference the same vtkMRMLScene.
step 2. In the scene, i create 126 vtkSphereSource instance, each corresponding one vtkMRMLModelNode, one vtkMRMLModelDisplayNode, one vtkMRMLLinearTransformNode. so all of these will create 378 vtkMRMLNode in the scene. Every vtkMRMLModelNode observes the vtkMRMLLinearTransformNode and vtkMRMLModelDisplayNode.

step 3. i read 7 stl format files from local, each corresponding one vtkMRMLModelNode, one vtkMRMLModelDisplayNode, one vtkMRMLLinearTransformNode. so all of these will create 21 vtkMRMLNode in the scene. Every vtkMRMLModelNode observes the vtkMRMLLinearTransformNode and vtkMRMLModelDisplayNode.

step 4 And there are more than 100 vtkMRMLNode created by vtkMRMLScene default. so there are more than 500 vtkMRMLNodes in the scene totally.

step 5. When i trigger the button which will make some linear transform about position and rotation for vtkMRMLLinearTransformNode in step 3. when invokes the method SetMatrixTransformToParent of vtkMRMLLinearTransformNode which will always consume much time.

step6. I print the time consumed for every calls, found this invoke consume more than 300ms. picture below:
file:///home/qxe-work/Pictures/Screenshot%20from%202021-09-02%2001-36-22.png

Screenshot from 2021-09-02 01-36-22
supplied for step 6

Normally you don’t create 126 actors for 126 spheres, but you render them all using a single vtkMRMLMarkupsFiducialNode.

You may call slicer.app.pauseRender() before changing the transform and call slicer.app.resumeRender() after it is changed to ensure no rendering is started while the transform is being updated.

If you need more ideas for optimization then run your code with a profiler and let us know which lines in the code are the performance bottlenecks. A profiler can point out what exactly takes time, not just identify a very high-level calls, such as EndModify().

This is mine conclusion for SetMatrixTransformToParent function:

step1: current transform node block the event response

step2: current transform node set the parent node matrix

step3: parent node sent the modified event (TransformModifiedEvent) event id = 15000

step4: current node receive the modified event and cache it

step5: current node modify himself maxtrix (TransformToParent)

step6: current node turn on the event response

step7: current node response the cached event in step4 which is (TransformModifiedEvent) for all observers interesting for this event.

AND the step 7 will consume much time now, i don’t know what’s the reason. Is it i add to many nodes which are more than 500 in the scene ?

Yes, you definitely much more than the average amount of nodes in your scene, so you run into performance issues that normally we just don’t notice. There are many ways to optimize it but it is quite likely that you can just rearrange the information so that it is more efficiently represented in the scene.

Can you tell a bit more about your use case?
What kind of nodes are those 500 nodes? What do they represent?
What do you use the transform for?

there are 126 fiducial point and 7 bone model, every one corresponding one transform node, one display node, one model node, and the model node observes transform node and display node.

transform is about translation and rotation.

there are a question confusing me when i make some transform for transform node, in my view , only the node who observes this transform node will be modify. so why other nodes will response this transform node?

Do you have 126 fiducial nodes, each containing a single point? Why don’t you store all the points in one fiducial node?

What do you use the 126 fiducial points for?

Since we don’t know what your overall goal is, it is very hard to help you effectively. We are bogged down with discussing small details, which may not be relevant at all if the problem was approached in a different way. If you tell us what you want to achieve and then we can tell you how it was addressed in the past by others.

Only those transformable nodes will be notified about transform changes that the transform is applied to. What makes you think that there are more observations?

1 Like

Thanks a lot, I have find the reason for the problem and fix the bug. the reason for that is I instance too many transform node, actually, i just need to instance one transform node in application.

1 Like