Here is a example that vtkTransform object failed to deep copy the other one.
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkTransform.h>
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
int main()
{
setbuf( stdout, nullptr );
vtkSPtrNew( trans, vtkTransform );
auto matrix = trans->GetMatrix();
matrix->SetElement( 1, 1, -1 );
matrix->SetElement( 1, 2, 2 );
matrix->SetElement( 2, 3, 3 );
trans->Update();
vtkSPtrNew( trans1, vtkTransform );
trans1->DeepCopy( trans );
trans1->GetMatrix()->PrintSelf( std::cout, vtkIndent() );
return 0;
}
Output
Debug: Off
Modified Time: 26
Reference Count: 1
Registered Events: (none)
Elements:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
The interface vtkTransform::InternalUpdate
works in many places. It also updates the internal matrix when we call the function vtkHomogeneousTransform::GetMatrix
.
The both values this->Matrix->GetMTime()
and this->MatrixUpdateMTime
are same in our case. Add this->Input
is null pointer, so we will go to the logic branch we start with the identity transform as our base
.
Finally, the internal matrix will be updated in vtkTransform::DeepCopy
but it wii become identity matrix E after Update <- InternalUpdate
.
void vtkTransform::InternalUpdate()
{
int i;
int nTransforms = this->Concatenation->GetNumberOfTransforms();
int nPreTransforms = this->Concatenation->GetNumberOfPreTransforms();
// check to see whether someone has been fooling around with our matrix
int doTheLegacyHack = 0;
if (this->Matrix->GetMTime() > this->MatrixUpdateMTime)
{
vtkDebugMacro(<<"InternalUpdate: this->Matrix was modified by something other than 'this'");
// check to see if we have any inputs or concatenated transforms
int isPipelined = (this->Input != nullptr);
for (i = 0; i < nTransforms && !isPipelined; i++)
{ // the vtkSimpleTransform is just a matrix placeholder,
// it is not a real transform
isPipelined =
!this->Concatenation->GetTransform(i)->IsA("vtkSimpleTransform");
}
// do the legacy hack only if we have no input transforms
doTheLegacyHack = !isPipelined;
}
// copy matrix from input
if (this->Input)
{
this->Matrix->DeepCopy(this->Input->GetMatrix());
// if inverse flag is set, invert the matrix
if (this->Concatenation->GetInverseFlag())
{
this->Matrix->Invert();
}
}
else if (doTheLegacyHack)
{
vtkWarningMacro("InternalUpdate: doing hack to support legacy code. "
"This is deprecated in VTK 4.2. May be removed in a "
"future version.");
// this heuristic works perfectly if GetMatrix() or GetMatrixPointer()
// was called immediately prior to the matrix modifications
// (fortunately, this is almost always the case)
if (this->Matrix->GetMTime() > this->Concatenation->GetMaxMTime())
{ // don't apply operations that occurred after matrix modification
nPreTransforms = nTransforms = 0;
}
}
else
{ // otherwise, we start with the identity transform as our base
this->Matrix->Identity();
}
// concatenate PreTransforms
for (i = nPreTransforms-1; i >= 0; i--)
{
vtkHomogeneousTransform *transform =
static_cast<vtkHomogeneousTransform *>(this->Concatenation->GetTransform(i));
vtkMatrix4x4::Multiply4x4(this->Matrix,transform->GetMatrix(),
this->Matrix);
}
// concatenate PostTransforms
for (i = nPreTransforms; i < nTransforms; i++)
{
vtkHomogeneousTransform *transform =
static_cast<vtkHomogeneousTransform *>(this->Concatenation->GetTransform(i));
vtkMatrix4x4::Multiply4x4(transform->GetMatrix(),this->Matrix,
this->Matrix);
}
if (doTheLegacyHack)
{ // the transform operations have been incorporated into the matrix,
// so delete them
this->Concatenation->Identity();
}
else
{ // having this in the 'else' forces the legacy flag to be sticky
this->MatrixUpdateMTime = this->Matrix->GetMTime();
}
}
Let’s use a new way to copy matrix as the following code snippet. We will get the correct result.
vtkSPtrNew( trans1, vtkTransform );
trans1->SetInput( trans );
trans1->GetMatrix()->PrintSelf( std::cout, vtkIndent() );
Or like this way.
vtkSPtrNew( trans1, vtkTransform );
vtkSPtrNew( matrix1, vtkMatrix4x4 );
matrix1->DeepCopy( matrix );
trans1->SetMatrix( matrix1 );
trans1->Update();
trans1->GetMatrix()->PrintSelf( std::cout, vtkIndent() );