Commit ecccb150 authored by Mathieu Westphal's avatar Mathieu Westphal
Browse files

Adding a vector array parameter to the transform method

This add a way to transform multiples vectors instead of one
while keeping retrocompatibility
parent 4dd4a33f
......@@ -157,7 +157,10 @@ void vtkAbstractTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs)
vtkDataArray *outVrs,
int nOptionalVectors,
vtkDataArray** inVrsArr,
vtkDataArray** outVrsArr)
{
this->Update();
......@@ -179,7 +182,15 @@ void vtkAbstractTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkMath::Multiply3x3(matrix,coord,coord);
outVrs->InsertNextTuple(coord);
}
if (inVrsArr)
{
for (int iArr = 0; iArr < nOptionalVectors; iArr++)
{
inVrsArr[iArr]->GetTuple(i,coord);
vtkMath::Multiply3x3(matrix,coord,coord);
outVrsArr[iArr]->InsertNextTuple(coord);
}
}
if (inNms)
{
inNms->GetTuple(i,coord);
......
......@@ -204,7 +204,10 @@ public:
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs);
vtkDataArray *outVrs,
int nOptionalVectors = 0,
vtkDataArray** inVrsArr = nullptr,
vtkDataArray** outVrsArr = nullptr);
/**
* Get the inverse of this transform. If you modify this transform,
......
......@@ -18,7 +18,23 @@
#include "vtkMatrix4x4.h"
#include "vtkPoints.h"
namespace
{
void TransformVector(double M [4][4], double* outPnt, double f, double* inVec, double* outVec)
{
// do the linear homogeneous transformation
outVec[0] = M[0][0]*inVec[0] + M[0][1]*inVec[1] + M[0][2]*inVec[2];
outVec[1] = M[1][0]*inVec[0] + M[1][1]*inVec[1] + M[1][2]*inVec[2];
outVec[2] = M[2][0]*inVec[0] + M[2][1]*inVec[1] + M[2][2]*inVec[2];
double w = M[3][0]*inVec[0] + M[3][1]*inVec[1] + M[3][2]*inVec[2];
// apply homogeneous correction: note that the f we are using
// is the one we calculated in the point transformation
outVec[0] = (outVec[0]-w*outPnt[0])*f;
outVec[1] = (outVec[1]-w*outPnt[1])*f;
outVec[2] = (outVec[2]-w*outPnt[2])*f;
}
}
//----------------------------------------------------------------------------
vtkHomogeneousTransform::vtkHomogeneousTransform()
{
......@@ -142,7 +158,10 @@ void vtkHomogeneousTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs)
vtkDataArray *outVrs,
int nOptionalVectors,
vtkDataArray** inVrsArr,
vtkDataArray** outVrsArr)
{
vtkIdType n = inPts->GetNumberOfPoints();
double (*M)[4] = this->Matrix->Element;
......@@ -170,22 +189,20 @@ void vtkHomogeneousTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
if (inVrs)
{
inVrs->GetTuple(i,inVec);
// do the linear homogeneous transformation
outVec[0] = M[0][0]*inVec[0] + M[0][1]*inVec[1] + M[0][2]*inVec[2];
outVec[1] = M[1][0]*inVec[0] + M[1][1]*inVec[1] + M[1][2]*inVec[2];
outVec[2] = M[2][0]*inVec[0] + M[2][1]*inVec[1] + M[2][2]*inVec[2];
w = M[3][0]*inVec[0] + M[3][1]*inVec[1] + M[3][2]*inVec[2];
// apply homogeneous correction: note that the f we are using
// is the one we calculated in the point transformation
outVec[0] = (outVec[0]-w*outPnt[0])*f;
outVec[1] = (outVec[1]-w*outPnt[1])*f;
outVec[2] = (outVec[2]-w*outPnt[2])*f;
TransformVector(M, outPnt, f, inVec, outVec);
outVrs->InsertNextTuple(outVec);
}
if (inVrsArr)
{
for (int iArr = 0; iArr < nOptionalVectors; iArr++)
{
inVrsArr[iArr]->GetTuple(i,inVec);
TransformVector(M, outPnt, f, inVec, outVec);
outVrsArr[iArr]->InsertNextTuple(outVec);
}
}
if (inNms)
{
inNms->GetTuple(i,inNrm);
......
......@@ -53,7 +53,10 @@ public:
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs) override;
vtkDataArray *outVrs,
int nOptionalVectors = 0,
vtkDataArray** inVrsArr = nullptr,
vtkDataArray** outVrsArr = nullptr) override;
/**
* Get a copy of the internal transformation matrix. The
......
......@@ -142,7 +142,10 @@ void vtkIdentityTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs)
vtkDataArray *outVrs,
int nOptionalVectors,
vtkDataArray** inVrsArr,
vtkDataArray** outVrsArr)
{
this->TransformPoints(inPts,outPts);
if (inNms)
......@@ -153,6 +156,13 @@ void vtkIdentityTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
{
this->TransformVectors(inVrs,outVrs);
}
if (inVrsArr)
{
for(int iArr = 0; iArr < nOptionalVectors; iArr++)
{
this->TransformVectors(inVrsArr[iArr], outVrsArr[iArr]);
}
}
}
//----------------------------------------------------------------------------
......
......@@ -64,7 +64,10 @@ public:
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs) override;
vtkDataArray *outVrs,
int nOptionalVectors = 0,
vtkDataArray** inVrsArr = nullptr,
vtkDataArray** outVrsArr = nullptr) override;
// Invert the transformation. This doesn't do anything to the
// identity transformation.
......
......@@ -203,7 +203,10 @@ void vtkLinearTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs)
vtkDataArray *outVrs,
int nOptionalVectors,
vtkDataArray** inVrsArr,
vtkDataArray** outVrsArr)
{
this->TransformPoints(inPts, outPts);
if (inNms)
......@@ -214,6 +217,13 @@ void vtkLinearTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
{
this->TransformVectors(inVrs, outVrs);
}
if (inVrsArr)
{
for(int iArr = 0; iArr < nOptionalVectors; iArr++)
{
this->TransformVectors(inVrsArr[iArr], outVrsArr[iArr]);
}
}
}
//----------------------------------------------------------------------------
......
......@@ -168,7 +168,10 @@ public:
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs) override;
vtkDataArray *outVrs,
int nOptionalVectors = 0,
vtkDataArray** inVrsArr = nullptr,
vtkDataArray** outVrsArr = nullptr) override;
/**
* Just like GetInverse, but it includes a typecast to
......
......@@ -15,6 +15,7 @@
#include "vtkTransformFilter.h"
#include "vtkCellData.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkImageData.h"
#include "vtkImageDataToPointSet.h"
......@@ -38,6 +39,7 @@ vtkTransformFilter::vtkTransformFilter()
{
this->Transform = nullptr;
this->OutputPointsPrecision = vtkAlgorithm::DEFAULT_PRECISION;
this->TransformAllInputVectors = false;
}
vtkTransformFilter::~vtkTransformFilter()
......@@ -124,9 +126,9 @@ int vtkTransformFilter::RequestData(
vtkPoints *inPts;
vtkPoints *newPts;
vtkDataArray *inVectors, *inCellVectors;;
vtkFloatArray *newVectors=nullptr, *newCellVectors=nullptr;
vtkDataArray *newVectors=nullptr, *newCellVectors=nullptr;
vtkDataArray *inNormals, *inCellNormals;
vtkFloatArray *newNormals=nullptr, *newCellNormals=nullptr;
vtkDataArray *newNormals=nullptr, *newCellNormals=nullptr;
vtkIdType numPts, numCells;
vtkPointData *pd=input->GetPointData(), *outPD=output->GetPointData();
vtkCellData *cd=input->GetCellData(), *outCD=output->GetCellData();
......@@ -177,14 +179,14 @@ int vtkTransformFilter::RequestData(
newPts->Allocate(numPts);
if ( inVectors )
{
newVectors = vtkFloatArray::New();
newVectors = this->CreateNewDataArray();
newVectors->SetNumberOfComponents(3);
newVectors->Allocate(3*numPts);
newVectors->SetName(inVectors->GetName());
}
if ( inNormals )
{
newNormals = vtkFloatArray::New();
newNormals = this->CreateNewDataArray();
newNormals->SetNumberOfComponents(3);
newNormals->Allocate(3*numPts);
newNormals->SetName(inNormals->GetName());
......@@ -194,17 +196,46 @@ int vtkTransformFilter::RequestData(
// Loop over all points, updating position
//
if ( inVectors || inNormals )
int nArrays = pd->GetNumberOfArrays();
vtkDataArray** inVrsArr = new vtkDataArray* [nArrays];
vtkDataArray** outVrsArr = new vtkDataArray* [nArrays];
int nInputVectors = 0;
if (this->TransformAllInputVectors)
{
for(int i = 0; i < nArrays; i++)
{
vtkDataArray* tmpArray = pd->GetArray(i);
if (tmpArray != inVectors && tmpArray != inNormals && tmpArray->GetNumberOfComponents() == 3)
{
inVrsArr[nInputVectors] = tmpArray;
vtkDataArray* tmpOutArray = this->CreateNewDataArray();
tmpOutArray->SetNumberOfComponents(3);
tmpOutArray->Allocate(3 * numPts);
tmpOutArray->SetName(tmpArray->GetName());
outVrsArr[nInputVectors] = tmpOutArray;
outPD->AddArray(tmpOutArray);
nInputVectors++;
tmpOutArray->Delete();
}
}
}
if ( inVectors || inNormals || nInputVectors > 0)
{
this->Transform->TransformPointsNormalsVectors(inPts,newPts,
inNormals,newNormals,
inVectors,newVectors);
inVectors,newVectors,
nInputVectors,
inVrsArr, outVrsArr);
}
else
{
this->Transform->TransformPoints(inPts,newPts);
}
delete[] inVrsArr;
delete[] outVrsArr;
this->UpdateProgress (.6);
// Can only transform cell normals/vectors if the transform
......@@ -214,15 +245,32 @@ int vtkTransformFilter::RequestData(
{
if ( inCellVectors )
{
newCellVectors = vtkFloatArray::New();
newCellVectors = this->CreateNewDataArray();
newCellVectors->SetNumberOfComponents(3);
newCellVectors->Allocate(3*numCells);
newCellVectors->SetName( inCellVectors->GetName() );
lt->TransformVectors(inCellVectors,newCellVectors);
}
if (this->TransformAllInputVectors)
{
for(int i = 0; i < cd->GetNumberOfArrays(); i++)
{
vtkDataArray* tmpArray = cd->GetArray(i);
if (tmpArray != inCellVectors && tmpArray != inCellNormals && tmpArray->GetNumberOfComponents() == 3)
{
vtkDataArray* tmpOutArray = this->CreateNewDataArray();
tmpOutArray->SetNumberOfComponents(3);
tmpOutArray->Allocate(3 * numCells);
tmpOutArray->SetName(tmpArray->GetName());
lt->TransformVectors(tmpArray, tmpOutArray);
outCD->AddArray(tmpOutArray);
tmpOutArray->Delete();
}
}
}
if ( inCellNormals )
{
newCellNormals = vtkFloatArray::New();
newCellNormals = this->CreateNewDataArray();
newCellNormals->SetNumberOfComponents(3);
newCellNormals->Allocate(3*numCells);
newCellNormals->SetName( inCellNormals->GetName() );
......@@ -264,9 +312,29 @@ int vtkTransformFilter::RequestData(
newCellVectors->Delete();
outCD->CopyVectorsOff();
}
outPD->PassData(pd);
outCD->PassData(cd);
if (this->TransformAllInputVectors)
{
for (int i = 0; i < pd->GetNumberOfArrays(); i++)
{
if(!outPD->GetArray(pd->GetArray(i)->GetName()))
{
outPD->AddArray(pd->GetArray(i));
}
}
for (int i = 0; i < cd->GetNumberOfArrays(); i++)
{
if(!outCD->GetArray(cd->GetArray(i)->GetName()))
{
outCD->AddArray(cd->GetArray(i));
}
}
//TODO does order matters ?
}
else
{
outPD->PassData(pd);
outCD->PassData(cd);
}
vtkFieldData* inFD = input->GetFieldData();
if (inFD)
......@@ -300,6 +368,20 @@ vtkMTimeType vtkTransformFilter::GetMTime()
return mTime;
}
vtkDataArray* vtkTransformFilter::CreateNewDataArray()
{
switch(this->OutputPointsPrecision)
{
case vtkAlgorithm::DOUBLE_PRECISION:
return vtkDoubleArray::New();
break;
case vtkAlgorithm::SINGLE_PRECISION:
default:
return vtkFloatArray::New();
break;
}
}
void vtkTransformFilter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
......
......@@ -17,8 +17,11 @@
* @brief transform points and associated normals and vectors
*
* vtkTransformFilter is a filter to transform point coordinates, and
* associated point normals and vectors. Other point data is passed
* through the filter.
* associated point normals and vectors, as well as cell normals and vectors.
* Transformed data array will be stored in a float array or a double array.
* Other point and cel data are passed through the filter, unless TransformAllInputVectors
* is set to true, in this case all other 3 components arrays from point and cell data
* will be transformed as well.
*
* An alternative method of transformation is to use vtkActor's methods
* to scale, rotate, and translate objects. The difference between the
......@@ -72,6 +75,17 @@ public:
vtkGetMacro(OutputPointsPrecision,int);
//@}
//@{
/**
* If off (the default), only Vectors and Normals will be transformed.
* If on, all 3-component data arrays ( considered as 3D vectors) will be transformed
* All other won't be flipped and will only be copied.
*/
vtkSetMacro(TransformAllInputVectors, bool);
vtkGetMacro(TransformAllInputVectors, bool);
vtkBooleanMacro(TransformAllInputVectors, bool);
//@}
protected:
vtkTransformFilter();
~vtkTransformFilter() override;
......@@ -83,8 +97,12 @@ protected:
vtkInformationVector **,
vtkInformationVector *) override;
vtkDataArray* CreateNewDataArray();
vtkAbstractTransform *Transform;
int OutputPointsPrecision;
bool TransformAllInputVectors;
private:
vtkTransformFilter(const vtkTransformFilter&) = delete;
void operator=(const vtkTransformFilter&) = delete;
......
......@@ -121,6 +121,9 @@ public:
vtkDataArray* outNms;
vtkDataArray* inVcs;
vtkDataArray* outVcs;
int nOptionalVectors;
vtkDataArray** inVrsArr;
vtkDataArray** outVrsArr;
double (*matrix)[4];
double (*matrixInvTr)[4];
void operator()( vtkIdType begin, vtkIdType end ) const
......@@ -137,6 +140,15 @@ public:
vtkSMPTransformVector(matrix, point, point);
outVcs->SetTuple(id, point);
}
if (inVrsArr)
{
for (int iArr = 0; iArr < nOptionalVectors; iArr++)
{
inVrsArr[iArr]->GetTuple(id, point);
vtkSMPTransformVector(matrix, point, point);
outVrsArr[iArr]->SetTuple(id, point);
}
}
if (inNms)
{
inNms->GetTuple(id, point);
......@@ -153,7 +165,10 @@ void vtkSMPTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs)
vtkDataArray *outVrs,
int nOptionalVectors,
vtkDataArray** inVrsArr,
vtkDataArray** outVrsArr)
{
vtkIdType n = inPts->GetNumberOfPoints();
double matrix[4][4];
......@@ -166,6 +181,9 @@ void vtkSMPTransform::TransformPointsNormalsVectors(vtkPoints *inPts,
functor.outNms = outNms;
functor.inVcs = inVrs;
functor.outVcs = outVrs;
functor.nOptionalVectors = nOptionalVectors;
functor.inVrsArr = inVrsArr;
functor.outVrsArr = outVrsArr;
functor.matrix = this->Matrix->Element;
if (inNms)
{
......
......@@ -65,7 +65,10 @@ class VTKFILTERSSMP_EXPORT vtkSMPTransform : public vtkTransform
vtkDataArray *inNms,
vtkDataArray *outNms,
vtkDataArray *inVrs,
vtkDataArray *outVrs) override;
vtkDataArray *outVrs,
int nOptionalVectors = 0,
vtkDataArray** inVrsArr = nullptr,
vtkDataArray** outVrsArr = nullptr) override;
protected:
vtkSMPTransform ();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment