Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1131 lines
32 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkAbstractTransform.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkAbstractTransform.h"
#include "vtkCriticalSection.h"
#include "vtkDataArray.h"
#include "vtkDebugLeaks.h"
#include "vtkHomogeneousTransform.h"
#include "vtkMath.h"
#include "vtkMatrix4x4.h"
#include "vtkPoints.h"
vtkCxxRevisionMacro(vtkAbstractTransform, "$Revision: 1.26 $");
//----------------------------------------------------------------------------
vtkAbstractTransform::vtkAbstractTransform()
{
this->MyInverse = NULL;
this->DependsOnInverse = 0;
this->InUnRegister = 0;
this->UpdateMutex = vtkSimpleCriticalSection::New();
this->InverseMutex = vtkSimpleCriticalSection::New();
}
//----------------------------------------------------------------------------
vtkAbstractTransform::~vtkAbstractTransform()
{
if (this->MyInverse)
{
this->MyInverse->Delete();
}
if (this->UpdateMutex)
{
this->UpdateMutex->Delete();
}
if (this->InverseMutex)
{
this->InverseMutex->Delete();
}
}
//----------------------------------------------------------------------------
void vtkAbstractTransform::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Inverse: (" << this->MyInverse << ")\n";
}
//----------------------------------------------------------------------------
void vtkAbstractTransform::TransformNormalAtPoint(const double point[3],
const double in[3],
double out[3])
{
this->Update();
double matrix[3][3];
double coord[3];
this->InternalTransformDerivative(point,coord,matrix);
vtkMath::Transpose3x3(matrix,matrix);
vtkMath::LinearSolve3x3(matrix,in,out);
vtkMath::Normalize(out);
}
void vtkAbstractTransform::TransformNormalAtPoint(const float point[3],
const float in[3],
float out[3])
{
double coord[3];
double normal[3];
coord[0] = point[0];
coord[1] = point[1];
coord[2] = point[2];
normal[0] = in[0];
normal[1] = in[1];
normal[2] = in[2];
this->TransformNormalAtPoint(coord,normal,normal);
out[0] = normal[0];
out[1] = normal[1];
out[2] = normal[2];
}
//----------------------------------------------------------------------------
void vtkAbstractTransform::TransformVectorAtPoint(const double point[3],
const double in[3],
double out[3])
{
this->Update();
double matrix[3][3];
double coord[3];
this->InternalTransformDerivative(point,coord,matrix);
vtkMath::Multiply3x3(matrix,in,out);
}
void vtkAbstractTransform::TransformVectorAtPoint(const float point[3],
const float in[3],
float out[3])
{
double coord[3];
double vector[3];
coord[0] = point[0];
coord[1] = point[1];
coord[2] = point[2];
vector[0] = in[0];
vector[1] = in[1];
vector[2] = in[2];
this->TransformVectorAtPoint(coord,vector,vector);
out[0] = vector[0];
out[1] = vector[1];
out[2] = vector[2];
}
//----------------------------------------------------------------------------
// Transform a series of points.
void vtkAbstractTransform::TransformPoints(vtkPoints *in, vtkPoints *out)
{
this->Update();
double point[3];
vtkIdType i;
vtkIdType n = in->GetNumberOfPoints();
for (i = 0; i < n; i++)
{
in->GetPoint(i,point);
this->InternalTransformPoint(point,point);
out->InsertNextPoint(point);
}
}
//----------------------------------------------------------------------------
// Transform the normals and vectors using the derivative of the
// transformation. Either inNms or inVrs can be set to NULL.
// Normals are multiplied by the inverse transpose of the transform
// derivative, while vectors are simply multiplied by the derivative.
// Note that the derivative of the inverse transform is simply the
// inverse of the derivative of the forward transform.
void vtkAbstractTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkPoints *outPts,
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs)
{
this->Update();
double matrix[3][3];
double coord[3];
vtkIdType i;
vtkIdType n = inPts->GetNumberOfPoints();
for (i = 0; i < n; i++)
{
inPts->GetPoint(i,coord);
this->InternalTransformDerivative(coord,coord,matrix);
outPts->InsertNextPoint(coord);
if (inVrs)
{
inVrs->GetTuple(i,coord);
vtkMath::Multiply3x3(matrix,coord,coord);
outVrs->InsertNextTuple(coord);
}
if (inNms)
{
inNms->GetTuple(i,coord);
vtkMath::Transpose3x3(matrix,matrix);
vtkMath::LinearSolve3x3(matrix,coord,coord);
vtkMath::Normalize(coord);
outNms->InsertNextTuple(coord);
}
}
}
//----------------------------------------------------------------------------
vtkAbstractTransform *vtkAbstractTransform::GetInverse()
{
this->InverseMutex->Lock();
if (this->MyInverse == NULL)
{
// we create a circular reference here, it is dealt with in UnRegister
this->MyInverse = this->MakeTransform();
this->MyInverse->SetInverse(this);
}
this->InverseMutex->Unlock();
return this->MyInverse;
}
//----------------------------------------------------------------------------
void vtkAbstractTransform::SetInverse(vtkAbstractTransform *transform)
{
if (this->MyInverse == transform)
{
return;
}
// check type first
if (!transform->IsA(this->GetClassName()))
{
vtkErrorMacro("SetInverse: requires a " << this->GetClassName() << ", a "
<< transform->GetClassName() << " is not compatible.");
return;
}
if (transform->CircuitCheck(this))
{
vtkErrorMacro("SetInverse: this would create a circular reference.");
return;
}
if (this->MyInverse)
{
this->MyInverse->Delete();
}
transform->Register(this);
this->MyInverse = transform;
// we are now a special 'inverse transform'
this->DependsOnInverse = (transform != 0);
this->Modified();
}
//----------------------------------------------------------------------------
void vtkAbstractTransform::DeepCopy(vtkAbstractTransform *transform)
{
// check whether we're trying to copy a transform to itself
if (transform == this)
{
return;
}
// check to see if the transform is the same type as this one
if (!transform->IsA(this->GetClassName()))
{
vtkErrorMacro("DeepCopy: can't copy a " << transform->GetClassName()
<< " into a " << this->GetClassName() << ".");
return;
}
if (transform->CircuitCheck(this))
{
vtkErrorMacro("DeepCopy: this would create a circular reference.");
return;
}
// call InternalDeepCopy for subtype
this->InternalDeepCopy(transform);
this->Modified();
}
//----------------------------------------------------------------------------
void vtkAbstractTransform::Update()
{
// locking is require to ensure that the class is thread-safe
this->UpdateMutex->Lock();
// check to see if we are a special 'inverse' transform
if (this->DependsOnInverse &&
this->MyInverse->GetMTime() >= this->UpdateTime.GetMTime())
{
vtkDebugMacro("Updating transformation from its inverse");
this->InternalDeepCopy(this->MyInverse);
this->Inverse();
vtkDebugMacro("Calling InternalUpdate on the transformation");
this->InternalUpdate();
}
// otherwise just check our MTime against our last update
else if (this->GetMTime() >= this->UpdateTime.GetMTime())
{
// do internal update for subclass
vtkDebugMacro("Calling InternalUpdate on the transformation");
this->InternalUpdate();
}
this->UpdateTime.Modified();
this->UpdateMutex->Unlock();
}
//----------------------------------------------------------------------------
int vtkAbstractTransform::CircuitCheck(vtkAbstractTransform *transform)
{
return (transform == this || (this->DependsOnInverse &&
this->MyInverse->CircuitCheck(transform)));
}
//----------------------------------------------------------------------------
// Need to check inverse's MTime if we are an inverse transform
unsigned long vtkAbstractTransform::GetMTime()
{
unsigned long mtime = this->vtkObject::GetMTime();
if (this->DependsOnInverse)
{
unsigned long inverseMTime = this->MyInverse->GetMTime();
if (inverseMTime > mtime)
{
return inverseMTime;
}
}
return mtime;
}
//----------------------------------------------------------------------------
// We need to handle the circular reference between a transform and its
// inverse.
void vtkAbstractTransform::UnRegister(vtkObjectBase *o)
{
if (this->InUnRegister)
{ // we don't want to go into infinite recursion...
vtkDebugMacro(<<"UnRegister: circular reference eliminated");
this->ReferenceCount--;
return;
}
// check to see if the only reason our reference count is not 1
// is the circular reference from MyInverse
if (this->MyInverse && this->ReferenceCount == 2 &&
this->MyInverse->ReferenceCount == 1)
{ // break the cycle
vtkDebugMacro(<<"UnRegister: eliminating circular reference");
this->InUnRegister = 1;
this->MyInverse->UnRegister(this);
this->MyInverse = NULL;
this->InUnRegister = 0;
}
this->vtkObject::UnRegister(o);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// All of the following methods are for vtkTransformConcatenation
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// A very, very minimal transformation
class vtkSimpleTransform : public vtkHomogeneousTransform
{
public:
vtkTypeRevisionMacro(vtkSimpleTransform,vtkHomogeneousTransform);
static vtkSimpleTransform *New() {
#ifdef VTK_DEBUG_LEAKS
vtkDebugLeaks::ConstructClass("vtkSimpleTransform");
#endif
return new vtkSimpleTransform; };
vtkAbstractTransform *MakeTransform() { return vtkSimpleTransform::New(); };
void Inverse() { this->Matrix->Invert(); this->Modified(); };
protected:
vtkSimpleTransform() {};
vtkSimpleTransform(const vtkSimpleTransform&);
void operator=(const vtkSimpleTransform&);
};
vtkCxxRevisionMacro(vtkSimpleTransform, "$Revision: 1.26 $");
//----------------------------------------------------------------------------
vtkTransformConcatenation::vtkTransformConcatenation()
{
this->PreMatrix = NULL;
this->PostMatrix = NULL;
this->PreMatrixTransform = NULL;
this->PostMatrixTransform = NULL;
this->PreMultiplyFlag = 1;
this->InverseFlag = 0;
this->NumberOfTransforms = 0;
this->NumberOfPreTransforms = 0;
this->MaxNumberOfTransforms = 0;
// The transform list is the list of the transforms to be concatenated.
this->TransformList = NULL;
}
//----------------------------------------------------------------------------
vtkTransformConcatenation::~vtkTransformConcatenation()
{
if (this->NumberOfTransforms > 0)
{
for (int i = 0; i < this->NumberOfTransforms; i++)
{
vtkTransformPair *tuple = &this->TransformList[i];
if (tuple->ForwardTransform)
{
tuple->ForwardTransform->Delete();
}
if (tuple->InverseTransform)
{
tuple->InverseTransform->Delete();
}
}
}
if (this->TransformList)
{
delete [] this->TransformList;
}
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Concatenate(vtkAbstractTransform *trans)
{
// in case either PreMatrix or PostMatrix is going to be pushed
// into the concatenation from their position at the end
if (this->PreMultiplyFlag && this->PreMatrix)
{
this->PreMatrix = NULL;
this->PreMatrixTransform = NULL;
}
else if (!this->PreMultiplyFlag && this->PostMatrix)
{
this->PostMatrix = NULL;
this->PostMatrixTransform = NULL;
}
vtkTransformPair *transList = this->TransformList;
int n = this->NumberOfTransforms;
this->NumberOfTransforms++;
// check to see if we need to allocate more space
if (this->NumberOfTransforms > this->MaxNumberOfTransforms)
{
int nMax = this->MaxNumberOfTransforms + 5;
transList = new vtkTransformPair[nMax];
for (int i = 0; i < n; i++)
{
transList[i].ForwardTransform = this->TransformList[i].ForwardTransform;
transList[i].InverseTransform = this->TransformList[i].InverseTransform;
}
if (this->TransformList)
{
delete [] this->TransformList;
}
this->TransformList = transList;
this->MaxNumberOfTransforms = nMax;
}
// add the transform either the beginning or end of the list,
// according to flags
if (this->PreMultiplyFlag ^ this->InverseFlag)
{
for (int i = n; i > 0; i--)
{
transList[i].ForwardTransform = transList[i-1].ForwardTransform;
transList[i].InverseTransform = transList[i-1].InverseTransform;
}
n = 0;
this->NumberOfPreTransforms++;
}
trans->Register(NULL);
if (this->InverseFlag)
{
transList[n].ForwardTransform = NULL;
transList[n].InverseTransform = trans;
}
else
{
transList[n].ForwardTransform = trans;
transList[n].InverseTransform = NULL;
}
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Concatenate(const double elements[16])
{
// concatenate the matrix with either the Pre- or PostMatrix
if (this->PreMultiplyFlag)
{
if (this->PreMatrix == NULL)
{
// add the matrix to the concatenation
vtkSimpleTransform *mtrans = vtkSimpleTransform::New();
this->Concatenate(mtrans);
mtrans->Delete();
this->PreMatrixTransform = mtrans;
this->PreMatrix = mtrans->GetMatrix();
}
vtkMatrix4x4::Multiply4x4(*this->PreMatrix->Element, elements,
*this->PreMatrix->Element);
this->PreMatrix->Modified();
this->PreMatrixTransform->Modified();
}
else
{
if (this->PostMatrix == NULL)
{
// add the matrix to the concatenation
vtkSimpleTransform *mtrans = vtkSimpleTransform::New();
this->Concatenate(mtrans);
mtrans->Delete();
this->PostMatrixTransform = mtrans;
this->PostMatrix = mtrans->GetMatrix();
}
vtkMatrix4x4::Multiply4x4(elements, *this->PostMatrix->Element,
*this->PostMatrix->Element);
this->PostMatrix->Modified();
this->PostMatrixTransform->Modified();
}
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Translate(double x, double y, double z)
{
if (x == 0.0 && y == 0.0 && z == 0.0)
{
return;
}
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
matrix[0][3] = x;
matrix[1][3] = y;
matrix[2][3] = z;
this->Concatenate(*matrix);
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Rotate(double angle,
double x, double y, double z)
{
if (angle == 0.0 || (x == 0.0 && y == 0.0 && z == 0.0))
{
return;
}
// convert to radians
angle = angle*vtkMath::DoubleDegreesToRadians();
// make a normalized quaternion
double w = cos(0.5*angle);
double f = sin(0.5*angle)/sqrt(x*x+y*y+z*z);
x *= f;
y *= f;
z *= f;
// convert the quaternion to a matrix
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
double ww = w*w;
double wx = w*x;
double wy = w*y;
double wz = w*z;
double xx = x*x;
double yy = y*y;
double zz = z*z;
double xy = x*y;
double xz = x*z;
double yz = y*z;
double s = ww - xx - yy - zz;
matrix[0][0] = xx*2 + s;
matrix[1][0] = (xy + wz)*2;
matrix[2][0] = (xz - wy)*2;
matrix[0][1] = (xy - wz)*2;
matrix[1][1] = yy*2 + s;
matrix[2][1] = (yz + wx)*2;
matrix[0][2] = (xz + wy)*2;
matrix[1][2] = (yz - wx)*2;
matrix[2][2] = zz*2 + s;
this->Concatenate(*matrix);
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Scale(double x, double y, double z)
{
if (x == 1.0 && y == 1.0 && z == 1.0)
{
return;
}
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
matrix[0][0] = x;
matrix[1][1] = y;
matrix[2][2] = z;
this->Concatenate(*matrix);
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Inverse()
{
// invert the matrices
if (this->PreMatrix)
{
this->PreMatrix->Invert();
this->PreMatrixTransform->Modified();
int i = (this->InverseFlag ? this->NumberOfTransforms-1 : 0);
this->TransformList[i].SwapForwardInverse();
}
if (this->PostMatrix)
{
this->PostMatrix->Invert();
this->PostMatrixTransform->Modified();
int i = (this->InverseFlag ? 0 : this->NumberOfTransforms-1);
this->TransformList[i].SwapForwardInverse();
}
// swap the pre- and post-matrices
vtkMatrix4x4 *tmp = this->PreMatrix;
vtkAbstractTransform *tmp2 = this->PreMatrixTransform;
this->PreMatrix = this->PostMatrix;
this->PreMatrixTransform = this->PostMatrixTransform;
this->PostMatrix = tmp;
this->PostMatrixTransform = tmp2;
// what used to be pre-transforms are now post-transforms
this->NumberOfPreTransforms =
this->NumberOfTransforms - this->NumberOfPreTransforms;
this->InverseFlag = !this->InverseFlag;
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::Identity()
{
// forget the Pre- and PostMatrix
this->PreMatrix = NULL;
this->PostMatrix = NULL;
this->PreMatrixTransform = NULL;
this->PostMatrixTransform = NULL;
// delete all the transforms
if (this->NumberOfTransforms > 0)
{
for (int i = 0; i < this->NumberOfTransforms; i++)
{
vtkTransformPair *tuple = &this->TransformList[i];
if (tuple->ForwardTransform)
{
tuple->ForwardTransform->Delete();
}
if (tuple->InverseTransform)
{
tuple->InverseTransform->Delete();
}
}
}
this->NumberOfTransforms = 0;
this->NumberOfPreTransforms = 0;
}
//----------------------------------------------------------------------------
vtkAbstractTransform *vtkTransformConcatenation::GetTransform(int i)
{
// we walk through the list in reverse order if InverseFlag is set
if (this->InverseFlag)
{
int j = this->NumberOfTransforms-i-1;
vtkTransformPair *tuple = &this->TransformList[j];
// if inverse is NULL, then get it from the forward transform
if (tuple->InverseTransform == NULL)
{
tuple->InverseTransform = tuple->ForwardTransform->GetInverse();
tuple->InverseTransform->Register(NULL);
}
return tuple->InverseTransform;
}
else
{
vtkTransformPair *tuple = &this->TransformList[i];
// if transform is NULL, then get it from its inverse
if (tuple->ForwardTransform == NULL)
{
tuple->ForwardTransform = tuple->InverseTransform->GetInverse();
tuple->ForwardTransform->Register(NULL);
}
return tuple->ForwardTransform;
}
}
//----------------------------------------------------------------------------
unsigned long vtkTransformConcatenation::GetMaxMTime()
{
unsigned long result = 0;
unsigned long mtime;
for (int i = 0; i < this->NumberOfTransforms; i++)
{
vtkTransformPair *tuple = &this->TransformList[i];
if (tuple->ForwardTransform)
{
mtime = tuple->ForwardTransform->GetMTime();
}
else
{
mtime = tuple->InverseTransform->GetMTime();
}
if (mtime > result)
{
result = mtime;
}
}
return result;
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::DeepCopy(vtkTransformConcatenation *concat)
{
// allocate a larger list if necessary
if (this->MaxNumberOfTransforms < concat->NumberOfTransforms)
{
int newMax = concat->NumberOfTransforms;
vtkTransformPair *newList = new vtkTransformPair[newMax];
// copy items onto new list
int i = 0;
for (; i < this->NumberOfTransforms; i++)
{
newList[i].ForwardTransform = this->TransformList[i].ForwardTransform;
newList[i].InverseTransform = this->TransformList[i].InverseTransform;
}
for (; i < concat->NumberOfTransforms; i++)
{
newList[i].ForwardTransform = NULL;
newList[i].InverseTransform = NULL;
}
if (this->TransformList)
{
delete [] this->TransformList;
}
this->MaxNumberOfTransforms = newMax;
this->TransformList = newList;
}
// save the PreMatrix and PostMatrix in case they can be re-used
vtkSimpleTransform *oldPreMatrixTransform = NULL;
vtkSimpleTransform *oldPostMatrixTransform = NULL;
if (this->PreMatrix)
{
vtkTransformPair *tuple;
if (this->InverseFlag)
{
tuple = &this->TransformList[this->NumberOfTransforms-1];
tuple->SwapForwardInverse();
}
else
{
tuple = &this->TransformList[0];
}
tuple->ForwardTransform = NULL;
if (tuple->InverseTransform)
{
tuple->InverseTransform->Delete();
tuple->InverseTransform = NULL;
}
oldPreMatrixTransform = (vtkSimpleTransform *)this->PreMatrixTransform;
this->PreMatrixTransform = NULL;
this->PreMatrix = NULL;
}
if (this->PostMatrix)
{
vtkTransformPair *tuple;
if (this->InverseFlag)
{
tuple = &this->TransformList[0];
tuple->SwapForwardInverse();
}
else
{
tuple = &this->TransformList[this->NumberOfTransforms-1];
}
tuple->ForwardTransform = NULL;
if (tuple->InverseTransform)
{
tuple->InverseTransform->Delete();
tuple->InverseTransform = NULL;
}
oldPostMatrixTransform = (vtkSimpleTransform *)this->PostMatrixTransform;
this->PostMatrixTransform = NULL;
this->PostMatrix = NULL;
}
// the PreMatrix and PostMatrix transforms must be DeepCopied,
// not copied by reference, so adjust the copy loop accordingly
int i = 0;
int n = concat->NumberOfTransforms;
if (concat->PreMatrix)
{
if (concat->InverseFlag) { n--; } else { i++; }
}
if (concat->PostMatrix)
{
if (concat->InverseFlag) { i++; } else { n--; }
}
// copy the transforms by reference
for (; i < n; i++)
{
vtkTransformPair *pair = &this->TransformList[i];
vtkTransformPair *pair2 = &concat->TransformList[i];
if (pair->ForwardTransform != pair2->ForwardTransform)
{
if (pair->ForwardTransform && i < this->NumberOfTransforms)
{
pair->ForwardTransform->Delete();
}
pair->ForwardTransform = pair2->ForwardTransform;
if (pair->ForwardTransform)
{
pair->ForwardTransform->Register(NULL);
}
}
if (pair->InverseTransform != pair2->InverseTransform)
{
if (pair->InverseTransform && i < this->NumberOfTransforms)
{
pair->InverseTransform->Delete();
}
pair->InverseTransform = pair2->InverseTransform;
if (pair->InverseTransform)
{
pair->InverseTransform->Register(NULL);
}
}
}
// delete surplus items from the list
for (i = concat->NumberOfTransforms; i < this->NumberOfTransforms; i++)
{
if (this->TransformList[i].ForwardTransform)
{
this->TransformList[i].ForwardTransform->Delete();
}
if (this->TransformList[i].InverseTransform)
{
this->TransformList[i].InverseTransform->Delete();
}
}
// make a DeepCopy of the PreMatrix transform
if (concat->PreMatrix)
{
i = (concat->InverseFlag ? concat->NumberOfTransforms-1 : 0);
vtkTransformPair *pair = &this->TransformList[i];
vtkSimpleTransform *mtrans;
if (concat->InverseFlag == this->InverseFlag)
{
mtrans = (oldPreMatrixTransform ? oldPreMatrixTransform :
vtkSimpleTransform::New());
oldPreMatrixTransform = NULL;
}
else
{
mtrans = (oldPostMatrixTransform ? oldPostMatrixTransform :
vtkSimpleTransform::New());
oldPostMatrixTransform = NULL;
}
this->PreMatrix = mtrans->GetMatrix();
this->PreMatrix->DeepCopy(concat->PreMatrix);
this->PreMatrixTransform = mtrans;
this->PreMatrixTransform->Modified();
if (pair->ForwardTransform)
{
pair->ForwardTransform->Delete();
pair->ForwardTransform = NULL;
}
if (pair->InverseTransform)
{
pair->InverseTransform->Delete();
pair->InverseTransform = NULL;
}
if (concat->InverseFlag)
{
pair->ForwardTransform = NULL;
pair->InverseTransform = this->PreMatrixTransform;
}
else
{
pair->ForwardTransform = this->PreMatrixTransform;
pair->InverseTransform = NULL;
}
}
// make a DeepCopy of the PostMatrix transform
if (concat->PostMatrix)
{
i = (concat->InverseFlag ? 0 : concat->NumberOfTransforms-1);
vtkTransformPair *pair = &this->TransformList[i];
vtkSimpleTransform *mtrans;
if (concat->InverseFlag == this->InverseFlag)
{
mtrans = (oldPostMatrixTransform ? oldPostMatrixTransform :
vtkSimpleTransform::New());
oldPostMatrixTransform = NULL;
}
else
{
mtrans = (oldPreMatrixTransform ? oldPreMatrixTransform :
vtkSimpleTransform::New());
oldPreMatrixTransform = NULL;
}
this->PostMatrix = mtrans->GetMatrix();
this->PostMatrix->DeepCopy(concat->PostMatrix);
this->PostMatrixTransform = mtrans;
this->PostMatrixTransform->Modified();
if (pair->ForwardTransform)
{
pair->ForwardTransform->Delete();
pair->ForwardTransform = NULL;
}
if (pair->InverseTransform)
{
pair->InverseTransform->Delete();
pair->InverseTransform = NULL;
}
if (concat->InverseFlag)
{
pair->ForwardTransform = NULL;
pair->InverseTransform = this->PostMatrixTransform;
}
else
{
pair->ForwardTransform = this->PostMatrixTransform;
pair->InverseTransform = NULL;
}
}
// delete the old PreMatrix and PostMatrix transforms if not re-used
if (oldPreMatrixTransform)
{
oldPreMatrixTransform->Delete();
}
if (oldPostMatrixTransform)
{
oldPostMatrixTransform->Delete();
}
// copy misc. ivars
this->InverseFlag = concat->InverseFlag;
this->PreMultiplyFlag = concat->PreMultiplyFlag;
this->NumberOfTransforms = concat->NumberOfTransforms;
this->NumberOfPreTransforms = concat->NumberOfPreTransforms;
}
//----------------------------------------------------------------------------
void vtkTransformConcatenation::PrintSelf(ostream& os, vtkIndent indent)
{
os << indent << "InverseFlag: " << this->InverseFlag << "\n";
os << indent << (this->PreMultiplyFlag ? "PreMultiply\n" : "PostMultiply\n");
os << indent << "NumberOfPreTransforms: " <<
this->GetNumberOfPreTransforms() << "\n";
os << indent << "NumberOfPostTransforms: " <<
this->GetNumberOfPostTransforms() << "\n";
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// All of the following methods are for vtkTransformConcatenationStack
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
vtkTransformConcatenationStack::vtkTransformConcatenationStack()
{
this->StackSize = 0;
this->StackBottom = NULL;
this->Stack = NULL;
}
//----------------------------------------------------------------------------
vtkTransformConcatenationStack::~vtkTransformConcatenationStack()
{
int n = this->Stack-this->StackBottom;
for (int i = 0; i < n; i++)
{
this->StackBottom[i]->Delete();
}
if (this->StackBottom)
{
delete [] this->StackBottom;
}
}
//----------------------------------------------------------------------------
void vtkTransformConcatenationStack::Pop(vtkTransformConcatenation **concat)
{
// if we're at the bottom of the stack, don't pop
if (this->Stack == this->StackBottom)
{
return;
}
// get the previous PreMultiplyFlag
int preMultiplyFlag = (*concat)->GetPreMultiplyFlag();
// delete the previous item
(*concat)->Delete();
// pop new item off the stack
*concat = *--this->Stack;
// re-set the PreMultiplyFlag
(*concat)->SetPreMultiplyFlag(preMultiplyFlag);
}
//----------------------------------------------------------------------------
void vtkTransformConcatenationStack::Push(vtkTransformConcatenation **concat)
{
// check stack size and grow if necessary
if ((this->Stack - this->StackBottom) == this->StackSize)
{
int newStackSize = this->StackSize + 10;
vtkTransformConcatenation **newStackBottom =
new vtkTransformConcatenation *[newStackSize];
for (int i = 0; i < this->StackSize; i++)
{
newStackBottom[i] = this->StackBottom[i];
}
if (this->StackBottom)
{
delete [] this->StackBottom;
}
this->StackBottom = newStackBottom;
this->Stack = this->StackBottom+this->StackSize;
this->StackSize = newStackSize;
}
// add item to the stack
*this->Stack++ = *concat;
// make a copy of that item the current item
*concat = vtkTransformConcatenation::New();
(*concat)->DeepCopy(*(this->Stack-1));
}
//----------------------------------------------------------------------------
void vtkTransformConcatenationStack::DeepCopy(
vtkTransformConcatenationStack *stack)
{
int n = stack->Stack - stack->StackBottom;
int m = this->Stack - this->StackBottom;
// check to see if we have to grow the stack
if (n > this->StackSize)
{
int newStackSize = n + n%10;
vtkTransformConcatenation **newStackBottom =
new vtkTransformConcatenation *[newStackSize];
for (int j = 0; j < m; j++)
{
newStackBottom[j] = this->StackBottom[j];
}
if (this->StackBottom)
{
delete [] this->StackBottom;
}
this->StackBottom = newStackBottom;
this->Stack = this->StackBottom+this->StackSize;
this->StackSize = newStackSize;
}
// delete surplus items
for (int l = n; l < m; l++)
{
(*--this->Stack)->Delete();
}
// allocate new items
for (int i = m; i < n; i++)
{
*this->Stack++ = vtkTransformConcatenation::New();
}
// deep copy the items
for (int k = 0; k < n; k++)
{
this->StackBottom[k]->DeepCopy(stack->StackBottom[k]);
}
}
#ifndef VTK_LEGACY_REMOVE
void vtkAbstractTransform::Identity()
{
vtkWarningMacro("vtkAbstractTransform::Identity() is deprecated");
}
#endif