Let's look at matrix multiplication first
vtkNew<vtkTransform> transformA;
transformA->Translate(10, 0, 0);
std::cout<<"matrixA="<<std::endl<<*transformA->GetMatrix()<<std::endl;
vtkNew<vtkTransform> transformB;
transformB->RotateZ(90);
std::cout<<"matrixB="<<std::endl<<*transformB->GetMatrix()<<std::endl;
vtkNew<vtkMatrix4x4> matrixC;
vtkNew<vtkMatrix4x4> matrixD;
vtkMatrix4x4::Multiply4x4(transformA->GetMatrix(), transformB->GetMatrix(), matrixC);
vtkMatrix4x4::Multiply4x4(transformB->GetMatrix(), transformA->GetMatrix(), matrixD);
std::cout<<"C = A x B"<<std::endl<<*matrixC<<std::endl;
std::cout<<"D = B x A"<<std::endl<<*matrixD<<std::endl;
Output
Pre Multiple
// Default operation is premultiple
vtkNew<vtkTransform> transformE;
transformE->Translate(10, 0, 0);
transformE->RotateZ(90);
std::cout<<"transformE="<<std::endl<<*transformE->GetMatrix()<<std::endl;
Output
Post multiple
vtkNew<vtkTransform> transformF;
transformF->PostMultiply();
transformF->Translate(10, 0, 0);
transformF->RotateZ(90);
std::cout<<"transformF="<<std::endl<<*transformF->GetMatrix()<<std::endl;
Output
If we combine an object, it will be clearer
Default
Pre Multiple
rotateZ(90) --> translate(10, 0, 0)
Post Multiple
translate(10, 0, 0) --> rotateZ(90)
In conclusion
The order of pre-multiplication is the same as the order of matrix multiplication, but contrary to the actual reading order. In other words, the operation of the earlier transformation should be placed at the end.
The order of post-multiplication is opposite to the order of matrix multiplication, but it is the same as the actual reading order, and the operation of the earlier transformation should be placed in front