Commit d7f5a38a authored by Will Schroeder's avatar Will Schroeder
Browse files

Initial revision

parent 2f167e31
/*=========================================================================
Program: Visualization Library
Module: TenGlyph.hh
Language: C++
Date: $Date$
Version: $Revision$
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994
=========================================================================*/
// .NAME vtkTensorGlyph - scale and orient glyph according to tensor eigenvalues and eigenvectors
// .SECTION Description
// vtkTensorGlyph is a filter that copies a geometric representation (specified
// as polygonal data) to every input point. The geometric representation, or
// glyph, can be scaled and/or rotated according to the tensor at the input
// point. Scaling and rotation is controlled by the eigenvalues/eigenvectors
// of the tensor as follows. For each tensor, the eigenvalues (and associated
// eigenvectors) are sorted to determine the major, medium, and minor
// eigenvalues/eigenvectors. The major eigenvalue scales the glyph in the
// x-direction, the medium in the y-direction, and the minor in the
// z-direction. Then, the glyph is rotated so that the glyph's local x-axis
// lies along the major eigenvector, y-axis along the medium eigenvector, and
// z-axis along the minor.
// A scale factor is provided to control the amount of scaling. Also, you
// can turn off scaling completely if desired.
// Another instance variable, ExtractEigenvalues, has been provided to
// control extraction of eigenvalues/eigenvectors. If this boolean is false,
// then eigenvalues/eigenvectors are not extracted, and the columns of the
// matrix are taken as the eigenvectors (norm of column is eigenvalue).
// This allows additional capability over the vtkGlyph3D object. That is, the
// glyph can be oriented in three directions instead of one.
// .SECTION See Also
// vtkGlyph3D
#ifndef __vtkTensorGlyph_h
#define __vtkTensorGlyph_h
#include "DS2PolyF.hh"
class vtkTensorGlyph : public vtkDataSetToPolyFilter
{
public:
vtkTensorGlyph();
~vtkTensorGlyph();
char *GetClassName() {return "vtkTensorGlyph";};
void PrintSelf(ostream& os, vtkIndent indent);
void Update();
// Description:
// Specify the geometry to copy to each point.
vtkSetObjectMacro(Source,vtkPolyData);
vtkGetObjectMacro(Source,vtkPolyData);
// Description:
// Turn on/off scaling of glyph with eigenvalues.
vtkSetMacro(Scaling,int);
vtkBooleanMacro(Scaling,int);
vtkGetMacro(Scaling,int);
// Description:
// Specify scale factor to scale object by. (Scale factor always affects
// output even if scaling is off).
vtkSetMacro(ScaleFactor,float);
vtkGetMacro(ScaleFactor,float);
// Description:
// Turn on/off extraction of eigenvalues from tensor.
vtkSetMacro(ExtractEigenvalues,int);
vtkBooleanMacro(ExtractEigenvalues,int);
vtkGetMacro(ExtractEigenvalues,int);
protected:
void Execute();
vtkPolyData *Source; // Geometry to copy to each point
int Scaling; // Determine whether scaling of geometry is performed
float ScaleFactor; // Scale factor to use to scale geometry
int ExtractEigenvalues; // Boolean controls eigenfunction extraction
};
#endif
/*=========================================================================
Program: Visualization Library
Module: TenGlyph.cc
Language: C++
Date: $Date$
Version: $Revision$
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994
=========================================================================*/
#include "TenGlyph.hh"
#include "Trans.hh"
#include "FVectors.hh"
#include "FNormals.hh"
#include "vtkMath.hh"
// Description
// Construct object with scaling on and scale factor 1.0.
vtkTensorGlyph::vtkTensorGlyph()
{
this->Source = NULL;
this->Scaling = 1;
this->ScaleFactor = 1.0;
this->ExtractEigenvalues = 1;
}
vtkTensorGlyph::~vtkTensorGlyph()
{
}
void vtkTensorGlyph::Execute()
{
vtkPointData *pd;
vtkTensors *inTensors;
int numPts, numSourcePts, numSourceCells;
int inPtId, i;
vtkPoints *sourcePts;
vtkCellArray *sourceCells;
vtkFloatPoints *newPts;
float *x;
vtkTransform trans;
vtkCell *cell;
vtkIdList *cellPts;
int npts, pts[MAX_CELL_SIZE];
int ptIncr, cellId;
vtkMath math;
vtkDebugMacro(<<"Generating tensor glyphs");
this->Initialize();
pd = this->Input->GetPointData();
inTensors = pd->GetTensors();
numPts = this->Input->GetNumberOfPoints();
if ( !inTensors || numPts < 1 )
{
vtkErrorMacro(<<"No data to glyph!");
return;
}
//
// Allocate storage for output PolyData
//
sourcePts = this->Source->GetPoints();
numSourcePts = sourcePts->GetNumberOfPoints();
numSourceCells = this->Source->GetNumberOfCells();
newPts = new vtkFloatPoints(numPts*numSourcePts);
// Setting up for calls to PolyData::InsertNextCell()
if ( (sourceCells=this->Source->GetVerts())->GetNumberOfCells() > 0 )
{
this->SetVerts(new vtkCellArray(numPts*sourceCells->GetSize()));
}
if ( (sourceCells=this->Source->GetLines())->GetNumberOfCells() > 0 )
{
this->SetLines(new vtkCellArray(numPts*sourceCells->GetSize()));
}
if ( (sourceCells=this->Source->GetPolys())->GetNumberOfCells() > 0 )
{
this->SetPolys(new vtkCellArray(numPts*sourceCells->GetSize()));
}
if ( (sourceCells=this->Source->GetStrips())->GetNumberOfCells() > 0 )
{
this->SetStrips(new vtkCellArray(numPts*sourceCells->GetSize()));
}
// only copy scalar data through
pd = this->Source->GetPointData();
this->PointData.CopyAllOff();
this->PointData.CopyScalarsOn();
this->PointData.CopyAllocate(pd,numPts*numSourcePts);
//
// First copy all topology (transformation independent)
//
for (inPtId=0; inPtId < numPts; inPtId++)
{
ptIncr = inPtId * numSourcePts;
for (cellId=0; cellId < numSourceCells; cellId++)
{
cell = this->Source->GetCell(cellId);
cellPts = cell->GetPointIds();
npts = cellPts->GetNumberOfIds();
for (i=0; i < npts; i++) pts[i] = cellPts->GetId(i) + ptIncr;
this->InsertNextCell(cell->GetCellType(),npts,pts);
}
}
//
// Traverse all Input points, transforming glyph at Source points
//
for (inPtId=0; inPtId < numPts; inPtId++)
{
ptIncr = inPtId * numSourcePts;
trans.Identity();
// translate Source to Input point
x = this->Input->GetPoint(inPtId);
trans.Translate(x[0], x[1], x[2]);
// extract appropriate eigenfunctions
// eigenvectors (assumed normalized) rotate object
// if scaling modify matrix to scale according to eigenvalues
// multiply points by resulting matrix
trans.MultiplyPoints(sourcePts,newPts);
// Copy point data from source
for (i=0; i < numSourcePts; i++)
this->PointData.CopyData(pd,i,ptIncr+i);
}
//
// Update ourselves
//
this->SetPoints(newPts);
this->Squeeze();
}
// Description:
// Override update method because execution can branch two ways (Input
// and Source)
void vtkTensorGlyph::Update()
{
// make sure input is available
if ( this->Input == NULL || this->Source == NULL )
{
vtkErrorMacro(<< "No input!");
return;
}
// prevent chasing our tail
if (this->Updating) return;
this->Updating = 1;
this->Input->Update();
this->Source->Update();
this->Updating = 0;
if (this->Input->GetMTime() > this->GetMTime() ||
this->Source->GetMTime() > this->GetMTime() ||
this->GetMTime() > this->ExecuteTime || this->GetDataReleased() )
{
if ( this->StartMethod ) (*this->StartMethod)(this->StartMethodArg);
this->Execute();
this->ExecuteTime.Modified();
this->SetDataReleased(0);
if ( this->EndMethod ) (*this->EndMethod)(this->EndMethodArg);
}
if ( this->Input->ShouldIReleaseData() ) this->Input->ReleaseData();
if ( this->Source->ShouldIReleaseData() ) this->Source->ReleaseData();
}
void vtkTensorGlyph::PrintSelf(ostream& os, vtkIndent indent)
{
vtkDataSetToPolyFilter::PrintSelf(os,indent);
os << indent << "Source: " << this->Source << "\n";
os << indent << "Scaling: " << (this->Scaling ? "On\n" : "Off\n");
os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
}
Supports Markdown
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