Commit b975b6df authored by Mathieu Westphal's avatar Mathieu Westphal

Correcting multiple bugs with periodic data array

1. Bug because of confusion between Size and MaxId
2. Bug with dataset attributes
3. Bug with range computation
4. Bug with unormalized normals vectors
5. Bug with center of rotation with vectors
parent a9e29f43
......@@ -104,6 +104,10 @@ Transform(Scalar* pos)
static_cast<Scalar>(cosf(this->AngleInRadians) * posx - sinf(this->AngleInRadians) * posy);
pos[axis1] = this->Center[axis1] +
static_cast<Scalar>(sinf(this->AngleInRadians) * posx + cosf(this->AngleInRadians) * posy);
if (this->Normalize)
{
vtkMath::Normalize(pos);
}
}
else if (this->NumberOfComponents == 9)
{
......
......@@ -229,6 +229,11 @@ public:
// Read only container, not supported.
void InsertValue(vtkIdType idx, Scalar v);
// Description:
// Set/Get normalize flag. Default: false
vtkSetMacro(Normalize, bool);
vtkGetMacro(Normalize, bool);
protected:
vtkPeriodicDataArray();
~vtkPeriodicDataArray();
......@@ -238,8 +243,12 @@ protected:
virtual void Transform(Scalar* tuple) = 0;
// Description:
// Get The transformed range
virtual void ComputeRange(double range[2], int comp);
// Get the transformed range by components
virtual bool ComputeScalarRange(double* range);
// Description:
// Get the transformed range on all components
virtual bool ComputeVectorRange(double range[2]);
// Description:
// Update the transformed periodic range
......@@ -249,6 +258,8 @@ protected:
// Set the invalid range flag to false
void InvalidateRange();
bool Normalize; // If transformed vector must be normalized
private:
vtkPeriodicDataArray(const vtkPeriodicDataArray &); // Not implemented.
void operator=(const vtkPeriodicDataArray &); // Not implemented.
......
......@@ -45,6 +45,7 @@ template <class Scalar> void vtkPeriodicDataArray<Scalar>
this->MaxId = -1;
this->Size = 0;
this->InvalidRange = true;
this->Normalize = false;
this->Modified();
}
......@@ -68,7 +69,7 @@ template <class Scalar> void vtkPeriodicDataArray<Scalar>
this->NumberOfComponents = data->GetNumberOfComponents();
this->Size = data->GetSize();
this->MaxId = this->Size - 1;
this->MaxId = data->GetMaxId();
this->Data = data;
this->Data->Register(0);
this->TempScalarArray = new Scalar[this->NumberOfComponents];
......@@ -79,8 +80,8 @@ template <class Scalar> void vtkPeriodicDataArray<Scalar>
}
//------------------------------------------------------------------------------
template <class Scalar> void vtkPeriodicDataArray<Scalar>::
ComputeRange(double range[2], int comp)
template <class Scalar> bool vtkPeriodicDataArray<Scalar>::
ComputeScalarRange(double* range)
{
if (this->NumberOfComponents == 3)
{
......@@ -88,8 +89,43 @@ ComputeRange(double range[2], int comp)
{
this->ComputePeriodicRange();
}
range[0] = this->PeriodicRange[comp * 2 + 0];
range[1] = this->PeriodicRange[comp * 2 + 1];
for (int i = 0; i < 3; i++)
{
range[i * 2] = this->PeriodicRange[i * 2 + 0];
range[i * 2 + 1] = this->PeriodicRange[i * 2 + 1];
}
}
else
{
// Not implemented for tensor
for (int i = 0; i < this->NumberOfComponents; i++)
{
range[i * 2] = 0;
range[i * 2 + 1] = 1;
}
}
return true;
}
//------------------------------------------------------------------------------
template <class Scalar> bool vtkPeriodicDataArray<Scalar>::
ComputeVectorRange(double range[2])
{
if (this->NumberOfComponents == 3)
{
if (this->InvalidRange)
{
this->ComputePeriodicRange();
}
range[0] = vtkTypeTraits<Scalar>::Max();
range[1] = vtkTypeTraits<Scalar>::Min();
for (int i = 0; i < 3; i++)
{
range[0] = std::min(this->PeriodicRange[i * 2], range[0]);
range[1] = std::max(this->PeriodicRange[i * 2 + 1], range[1]);
}
}
else
{
......@@ -97,8 +133,8 @@ ComputeRange(double range[2], int comp)
range[0] = 0;
range[1] = 1;
}
return true;
}
//------------------------------------------------------------------------------
template <class Scalar> void vtkPeriodicDataArray<Scalar>::
ComputePeriodicRange()
......
......@@ -101,9 +101,10 @@ void vtkAngularPeriodicFilter::SetRotationAxisToZ()
}
//----------------------------------------------------------------------------
void vtkAngularPeriodicFilter::CreatePeriodicDataSet(vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
vtkCompositeDataSet* input)
void vtkAngularPeriodicFilter::CreatePeriodicDataSet(
vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
vtkCompositeDataSet* input)
{
vtkDataObject* inputNode = input->GetDataSet(loc);
if (inputNode == NULL)
......@@ -249,7 +250,7 @@ void vtkAngularPeriodicFilter::AppendPeriodicPiece(double angle,
//----------------------------------------------------------------------------
vtkDataArray* vtkAngularPeriodicFilter::TransformDataArray(
vtkDataArray* inputArray, double angle)
vtkDataArray* inputArray, double angle, bool useCenter, bool normalize)
{
vtkDataArray* periodicArray = 0;
switch (inputArray->GetDataType())
......@@ -260,7 +261,11 @@ vtkDataArray* vtkAngularPeriodicFilter::TransformDataArray(
vtkAngularPeriodicDataArray<float>::New();
pArray->SetAxis(this->RotationAxis);
pArray->SetAngle(angle);
pArray->SetCenter(this->Center);
if (useCenter)
{
pArray->SetCenter(this->Center);
}
pArray->SetNormalize(normalize);
pArray->InitializeArray(vtkFloatArray::SafeDownCast(inputArray));
periodicArray = pArray;
break;
......@@ -271,7 +276,11 @@ vtkDataArray* vtkAngularPeriodicFilter::TransformDataArray(
vtkAngularPeriodicDataArray<double>::New();
pArray->SetAxis(this->RotationAxis);
pArray->SetAngle(angle);
pArray->SetCenter(this->Center);
if (useCenter)
{
pArray->SetCenter(this->Center);
}
pArray->SetNormalize(normalize);
pArray->InitializeArray(vtkDoubleArray::SafeDownCast(inputArray));
periodicArray = pArray;
break;
......@@ -281,30 +290,38 @@ vtkDataArray* vtkAngularPeriodicFilter::TransformDataArray(
vtkErrorMacro("Unknown data type " << inputArray->GetDataType());
periodicArray = vtkDataArray::CreateDataArray(inputArray->GetDataType());
periodicArray->DeepCopy(inputArray);
break;
}
break;
}
return periodicArray;
}
//----------------------------------------------------------------------------
void vtkAngularPeriodicFilter::ComputeAngularPeriodicData(
vtkFieldData* data, vtkFieldData* transformedData, double angle)
vtkDataSetAttributes* data, vtkDataSetAttributes* transformedData, double angle)
{
// Shallow Copy all data
transformedData->ShallowCopy(data);
for (int i = 0; i < data->GetNumberOfArrays(); i++)
{
int attribute = data->IsArrayAnAttribute(i);
vtkDataArray* array = data->GetArray(i);
vtkDataArray* transformedArray;
// Perdiodic copy of vector (3 components) or tensor (9 components) data
if (array->GetNumberOfComponents() == 3 || array->GetNumberOfComponents() == 9)
{
vtkDataArray* transformedArray = this->TransformDataArray(array, angle);
transformedData->AddArray(transformedArray);
transformedArray->Delete();
transformedArray = this->TransformDataArray(array, angle, false,
attribute == vtkDataSetAttributes::NORMALS);
}
else
{
transformedArray = array;
array->Register(0);
}
transformedData->AddArray(transformedArray);
if (attribute >= 0)
{
transformedData->SetAttribute(transformedArray, attribute);
}
transformedArray->Delete();
}
}
......@@ -318,7 +335,7 @@ void vtkAngularPeriodicFilter::ComputePeriodicMesh(vtkPointSet* dataset,
// Transform points coordinates array
vtkDataArray* pointArray = dataset->GetPoints()->GetData();
vtkNew<vtkPoints> rotatedPoints;
vtkDataArray* transformedArray = this->TransformDataArray(pointArray, angle);
vtkDataArray* transformedArray = this->TransformDataArray(pointArray, angle, true);
rotatedPoints->SetData(transformedArray);
transformedArray->Delete();
// Set the points
......
......@@ -38,7 +38,7 @@
#include "vtkFiltersGeneralModule.h" // For export macro
#include "vtkPeriodicFilter.h"
class vtkFieldData;
class vtkDataSetAttributes;
class vtkMultiPieceDataSet;
class vtkPointSet;
......@@ -96,7 +96,10 @@ protected:
// Description:
// Create a transform copy of the provided data array
vtkDataArray* TransformDataArray(vtkDataArray* inputArray, double angle);
vtkDataArray* TransformDataArray(vtkDataArray* inputArray,
double angle,
bool useCenter = true,
bool normalize = false);
// Description:
// Append a periodic piece to dataset, by computing rotated mesh and data
......@@ -111,8 +114,9 @@ protected:
// Description:
// Compute periodic point/cell data, using provided angle
void ComputeAngularPeriodicData(vtkFieldData* data, vtkFieldData* rotatedData,
double angle);
void ComputeAngularPeriodicData(vtkDataSetAttributes* data,
vtkDataSetAttributes* rotatedData,
double angle);
// Description:
// Create a periodic data, leaf of the tree
......
......@@ -72,8 +72,8 @@ void vtkPeriodicFilter::RemoveAllIndices()
//----------------------------------------------------------------------------
void vtkPeriodicFilter::CreatePeriodicSubTree(vtkDataObjectTreeIterator* loc,
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* input)
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* input)
{
vtkDataObject* inputNode = input->GetDataSet(loc);
if (!inputNode)
......@@ -123,8 +123,8 @@ void vtkPeriodicFilter::CreatePeriodicSubTree(vtkDataObjectTreeIterator* loc,
//----------------------------------------------------------------------------
int vtkPeriodicFilter::RequestData(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
vtkMultiBlockDataSet *input = vtkMultiBlockDataSet::GetData(inputVector[0], 0);
vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::GetData(outputVector, 0);
......
......@@ -56,7 +56,8 @@ public:
// VTK_ITERATION_MODE_DIRECT_NB to specify the number of periods,
// VTK_ITERATION_MODE_MAX to generate a full period (default).
vtkSetClampMacro(IterationMode, int,
VTK_ITERATION_MODE_DIRECT_NB, VTK_ITERATION_MODE_MAX);
VTK_ITERATION_MODE_DIRECT_NB,
VTK_ITERATION_MODE_MAX);
vtkGetMacro(IterationMode, int);
void SetIterationModeToDirectNb()
{ this->SetIterationMode(VTK_ITERATION_MODE_DIRECT_NB); }
......@@ -97,20 +98,21 @@ protected:
// Description:
// Create the periodic sub tree
virtual void CreatePeriodicSubTree(vtkDataObjectTreeIterator* loc,
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* input);
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* input);
// Description:
// Create a periodic data, leaf of the tree
virtual void CreatePeriodicDataSet(vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
vtkCompositeDataSet* input) = 0;
vtkCompositeDataSet* output,
vtkCompositeDataSet* input) = 0;
// Description:
// Generate a name for a piece in the periodic dataset from the input dataset
virtual void GeneratePieceName(vtkCompositeDataSet* input,
vtkCompositeDataIterator* inputLoc,
vtkMultiPieceDataSet* output, vtkIdType outputId);
vtkCompositeDataIterator* inputLoc,
vtkMultiPieceDataSet* output,
vtkIdType outputId);
private:
vtkPeriodicFilter(const vtkPeriodicFilter&); // Not implemented.
......
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