I am currently testing out FastModelAlign for affine transforms.
I see there are 3 transformation matrices created, I assume in this order:

scaling

rigid transformation

affine transformation

The resulting model is the result after these 3 transformations and looks as expected.

However, if I make a copy of the original model and apply the “scaling” transform to it, it already matches the FastModelAlign output.

I.e. selecting the “scaling” transform generated by FastModelAlign to a copy of the original model seems to apply the other two transformations (rigid and affine) as well.

Similarly, if I run the registration without the affine transform, applying the “scaling” transform to the original mesh it also translates/rotates it (seems to include rigid transformation too).

I see on the github repo that there is a comment " #Put affine transform node under scaling transform node, which has been put under the rigid transform node".

Does this mean that the scaling transform also contains the information of the affine transform?
The observed behavior would suggest this, but when I look at the actual values of the scaling transform it is just a scaling transform…

I am aware of the LPS/RAS and to/from parent distinctions in the transforms and the exports work well. I am just confused by the behaviour described above within Slicer.

@evaherbst transforms are nested, and they are nested in the order they are created. Each one only contains the transformation associated only with that specific step. In this example I am aligning small (source) model to a large model (target). First there is a linear scaling transform, then a rigid transform and finally an affine transform. Affine transform by itself probably has very little change associated with it because previous steps already taken care of the much larger scaling and alignment transform.

If you want to have a single transform that contains everything, just right-click and harden the transforms nested in the top transform (in this case small_affine). The resultant affine transform will contain everything. The final output (in this case Model), has all these transforms applied to the small model.

I am not sure what you mean by “select affine”, can you clarify? Selecting where?

What the transforms are doing to the model is that affine transform is transforming the rigid, which in return is transforming the scaling transform. So, if you put your original source model under the scaling transform, all other transforms will be automatically applied in the correct order and you should get the model transformed exactly in the same way as your output model.

Thanks Murat! By select I meant what you did in the subject hierarchy. I should have said “applying the transform”.

What the transforms are doing to the model is that affine transform is transforming the rigid, which in return is transforming the scaling transform

Yes, this makes sense now. I was just thinking the affine transform, being the last one applied, would contain all of the ones ^before and so I should apply that in the subject hierarchy. Now it makes sense why the scaling one does all of the transformations.

I was just initially confused because I thought the scaling transform only included scaling, etc. (as it does when you just look at the numbers under “transforms”). But the nesting structure now makes sense.

Thanks for the clarification!
And thanks for developing this tool, it is proving to be very useful already!
Eva

Glad to hear that the module works! We also have some explanation of the nested transformation matrices in the FastModelAlign tutorial at “4. Investigate and Visualize the scaling and rigid transformation process”: https://github.com/SlicerMorph/Tutorials/tree/main/FastModelAlign