Attached Files | tensors_vtk_bug_norms.png [^] (82,166 bytes) 2011-05-10 20:40

tensors_vtk_fix_norms.png [^] (90,146 bytes) 2011-05-10 20:40

test_tensor.tar.gz [^] (237,180 bytes) 2011-05-10 20:53
0002-Bug-fixes-for-vtkTensorGlyph.patch [^] (9,802 bytes) 2011-05-11 15:54 [Show Content] [Hide Content]From 57a7ccfbb7c3f601276e84c23452b278a0dbaef2 Mon Sep 17 00:00:00 2001
From: Burlen Loring <bloring@lbl.gov>
Date: Wed, 11 May 2011 12:39:48 -0700
Subject: [PATCH 2/2] Bug fixes for vtkTensorGlyph
1) fix orientation inversion causing flipped surface normals. When the
determinant of the transformation matrix is < 0 surface normals are
flipped. The patch fizes it by testing for this condition and applying
an additional scale(-1,-1,-1) to the surface normal transform, leaving
the surface inverted but with outward pointing normals.
2) Added names to generated output arrays so that they are recongnized
by ParaView.
3) Override RequestUpdateExtent so that glyph source generates an whole
glyph when running in parallel, with out this only a piece of the glyph
is generated.
note: The test needs to be updated as well, as it takes measures to hide
bug 1, commments in the existing test describe this.
---
Graphics/vtkTensorGlyph.cxx | 107 +++++++++++++++++++++++++++++++-----------
Graphics/vtkTensorGlyph.h | 1 +
2 files changed, 80 insertions(+), 28 deletions(-)
diff --git a/Graphics/vtkTensorGlyph.cxx b/Graphics/vtkTensorGlyph.cxx
index d69da35..949a874 100644
--- a/Graphics/vtkTensorGlyph.cxx
+++ b/Graphics/vtkTensorGlyph.cxx
@@ -14,6 +14,8 @@
=========================================================================*/
#include "vtkTensorGlyph.h"
+
+#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkCell.h"
#include "vtkCellArray.h"
#include "vtkDataSet.h"
@@ -62,6 +64,38 @@ vtkTensorGlyph::~vtkTensorGlyph()
}
//----------------------------------------------------------------------------
+int vtkTensorGlyph::RequestUpdateExtent(
+ vtkInformation *vtkNotUsed(request),
+ vtkInformationVector **inputVector,
+ vtkInformationVector *outputVector)
+{
+ // get the info objects
+ vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+ vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
+ vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+ if (sourceInfo)
+ {
+ sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
+ 0);
+ sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
+ 1);
+ sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
+ 0);
+ }
+
+ inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
+ outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
+ inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
+ outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
+ inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
+ outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
+ inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
int vtkTensorGlyph::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
@@ -87,7 +121,7 @@ int vtkTensorGlyph::RequestData(
int j;
vtkPoints *sourcePts;
vtkDataArray *sourceNormals;
- vtkCellArray *sourceCells, *cells;
+ vtkCellArray *sourceCells, *cells;
vtkPoints *newPts;
vtkFloatArray *newScalars=NULL;
vtkFloatArray *newNormals=NULL;
@@ -109,14 +143,14 @@ int vtkTensorGlyph::RequestData(
vtkPointData *pd, *outPD;
numDirs = (this->ThreeGlyphs?3:1)*(this->Symmetric+1);
-
+
pts = new vtkIdType[source->GetMaxCellSize()];
trans = vtkTransform::New();
matrix = vtkMatrix4x4::New();
-
+
// set up working matrices
- m[0] = m0; m[1] = m1; m[2] = m2;
- v[0] = v0; v[1] = v1; v[2] = v2;
+ m[0] = m0; m[1] = m1; m[2] = m2;
+ v[0] = v0; v[1] = v1; v[2] = v2;
vtkDebugMacro(<<"Generating tensor glyphs");
@@ -174,12 +208,20 @@ int vtkTensorGlyph::RequestData(
// only copy scalar data through
pd = this->GetSource()->GetPointData();
// generate scalars if eigenvalues are chosen or if scalars exist.
- if (this->ColorGlyphs &&
- ((this->ColorMode == COLOR_BY_EIGENVALUES) ||
+ if (this->ColorGlyphs &&
+ ((this->ColorMode == COLOR_BY_EIGENVALUES) ||
(inScalars && (this->ColorMode == COLOR_BY_SCALARS)) ) )
{
newScalars = vtkFloatArray::New();
newScalars->Allocate(numDirs*numPts*numSourcePts);
+ if (this->ColorMode == COLOR_BY_EIGENVALUES)
+ {
+ newScalars->SetName("MaxEigenvalue");
+ }
+ else
+ {
+ newScalars->SetName(inScalars->GetName());
+ }
}
else
{
@@ -191,6 +233,7 @@ int vtkTensorGlyph::RequestData(
{
newNormals = vtkFloatArray::New();
newNormals->SetNumberOfComponents(3);
+ newNormals->SetName("Normals");
newNormals->Allocate(numDirs*3*numPts*numSourcePts);
}
//
@@ -206,7 +249,7 @@ int vtkTensorGlyph::RequestData(
npts = cellPts->GetNumberOfIds();
for (dir=0; dir < numDirs; dir++)
{
- // This variable may be removed, but that
+ // This variable may be removed, but that
// will not improve readability
subIncr = ptIncr + dir*numSourcePts;
for (i=0; i < npts; i++)
@@ -252,7 +295,7 @@ int vtkTensorGlyph::RequestData(
for (i=0; i<3; i++)
{
xv[i] = tensor[i];
- yv[i] = tensor[i+3];
+ yv[i] = tensor[i+3];
zv[i] = tensor[i+6];
}
w[0] = vtkMath::Normalize(xv);
@@ -264,7 +307,7 @@ int vtkTensorGlyph::RequestData(
w[0] *= this->ScaleFactor;
w[1] *= this->ScaleFactor;
w[2] *= this->ScaleFactor;
-
+
if ( this->ClampScaling )
{
for (maxScale=0.0, i=0; i<3; i++)
@@ -308,11 +351,11 @@ int vtkTensorGlyph::RequestData(
// Now do the real work for each "direction"
- for (dir=0; dir < numDirs; dir++)
+ for (dir=0; dir < numDirs; dir++)
{
eigen_dir = dir%(this->ThreeGlyphs?3:1);
symmetric_dir = dir/(this->ThreeGlyphs?3:1);
-
+
// Remove previous scales ...
trans->Identity();
@@ -331,8 +374,8 @@ int vtkTensorGlyph::RequestData(
matrix->Element[2][1] = yv[2];
matrix->Element[2][2] = zv[2];
trans->Concatenate(matrix);
-
- if (eigen_dir == 1)
+
+ if (eigen_dir == 1)
{
trans->RotateZ(90.0);
}
@@ -342,7 +385,7 @@ int vtkTensorGlyph::RequestData(
trans->RotateY(-90.0);
}
- if (this->ThreeGlyphs)
+ if (this->ThreeGlyphs)
{
trans->Scale(w[eigen_dir], this->ScaleFactor, this->ScaleFactor);
}
@@ -358,49 +401,57 @@ int vtkTensorGlyph::RequestData(
}
// if the eigenvalue is negative, shift to reverse direction.
- // The && is there to ensure that we do not change the
- // old behaviour of vtkTensorGlyphs (which only used one dir),
+ // The && is there to ensure that we do not change the
+ // old behaviour of vtkTensorGlyphs (which only used one dir),
// in case there is an oriented glyph, e.g. an arrow.
- if (w[eigen_dir] < 0 && numDirs > 1)
+ if (w[eigen_dir] < 0 && numDirs > 1)
{
trans->Translate(-this->Length, 0., 0.);
}
-
+
// multiply points (and normals if available) by resulting
// matrix
- trans->TransformPoints(sourcePts,newPts);
+ trans->TransformPoints(sourcePts,newPts);
- // Apply the transformation to a series of points,
+ // Apply the transformation to a series of points,
// and append the results to outPts.
if ( newNormals )
{
+ // a negative determinant means the transform turns the
+ // glyph surface inside out, and its surface normals all
+ // point inward. The following scale corrects the surface
+ // normals to point outward.
+ if (trans->GetMatrix()->Determinant() < 0)
+ {
+ trans->Scale(-1.0,-1.0,-1.0);
+ }
trans->TransformNormals(sourceNormals,newNormals);
}
-
+
// Copy point data from source
- if ( this->ColorGlyphs && inScalars &&
+ if ( this->ColorGlyphs && inScalars &&
(this->ColorMode == COLOR_BY_SCALARS) )
{
s = inScalars->GetComponent(inPtId, 0);
- for (i=0; i < numSourcePts; i++)
+ for (i=0; i < numSourcePts; i++)
{
newScalars->InsertTuple(ptIncr+i, &s);
}
}
- else if (this->ColorGlyphs &&
+ else if (this->ColorGlyphs &&
(this->ColorMode == COLOR_BY_EIGENVALUES) )
{
- // If ThreeGlyphs is false we use the first (largest)
+ // If ThreeGlyphs is false we use the first (largest)
// eigenvalue as scalar.
s = w[eigen_dir];
- for (i=0; i < numSourcePts; i++)
+ for (i=0; i < numSourcePts; i++)
{
newScalars->InsertTuple(ptIncr+i, &s);
}
}
else
{
- for (i=0; i < numSourcePts; i++)
+ for (i=0; i < numSourcePts; i++)
{
outPD->CopyData(pd,i,ptIncr+i);
}
diff --git a/Graphics/vtkTensorGlyph.h b/Graphics/vtkTensorGlyph.h
index 65edcfe..f6eacb6 100644
--- a/Graphics/vtkTensorGlyph.h
+++ b/Graphics/vtkTensorGlyph.h
@@ -194,6 +194,7 @@ protected:
vtkTensorGlyph();
~vtkTensorGlyph();
+ virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
virtual int FillInputPortInformation(int port, vtkInformation *info);
--
1.7.0.4
|