17#include "vtkStreamingDemandDrivenPipeline.h" 
   19#include "vtkCellArray.h" 
   20#include "vtkDataSet.h" 
   21#include "vtkExecutive.h" 
   22#include "vtkFloatArray.h" 
   23#include "vtkDoubleArray.h" 
   25#include "vtkInformation.h" 
   26#include "vtkInformationVector.h" 
   27#include "vtkObjectFactory.h" 
   28#include "vtkPointData.h" 
   29#include "vtkPolyData.h" 
   30#include "vtkTransform.h" 
   50  this->SetNumberOfInputPorts(2);
 
   53  this->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS,
 
   54                               vtkDataSetAttributes::TENSORS);
 
   57  this->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS,
 
   58                               vtkDataSetAttributes::SCALARS);
 
   66  vtkInformation *vtkNotUsed(request),
 
   67    vtkInformationVector **inputVector,
 
   68      vtkInformationVector *outputVector)
 
   71  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 
   72  vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
 
   73  vtkInformation *outInfo = outputVector->GetInformationObject(0);
 
   77    sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
 
   79    sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
 
   81    sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
 
   85  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
 
   86  outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
 
   87  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
 
   88  outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
 
   89  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
 
   90  outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
 
   91  inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
 
   98  vtkInformation *vtkNotUsed(request),
 
   99  vtkInformationVector **inputVector,
 
  100  vtkInformationVector *outputVector)
 
  103  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 
  104  vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
 
  105  vtkInformation *outInfo = outputVector->GetInformationObject(0);
 
  108  vtkDataSet *input = vtkDataSet::SafeDownCast(
 
  109    inInfo->Get(vtkDataObject::DATA_OBJECT()));
 
  110  vtkPolyData *
source = vtkPolyData::SafeDownCast(
 
  111    sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
 
  112  vtkPolyData *output = vtkPolyData::SafeDownCast(
 
  113    outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
  115  vtkDataArray *inTensors;
 
  117  vtkDataArray *inScalars;
 
  118  vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i;
 
  120  vtkPoints *sourcePts;
 
  121  vtkDataArray *sourceNormals;
 
  122  vtkCellArray *sourceCells, *cells;
 
  124  vtkFloatArray *newScalars=
nullptr;
 
  125  vtkFloatArray *newNormals=
nullptr;
 
  132  vtkIdType ptIncr, cellId;
 
  134  int numDirs, dir, eigen_dir, symmetric_dir;
 
  135  vtkMatrix4x4 *matrix;
 
  136  double *
m[3], w[3], *v[3];
 
  137  double m0[3], m1[3], 
m2[3];
 
  138  double v0[3], v1[3], v2[3];
 
  139  double xv[3], yv[3], zv[3];
 
  145  m[0] = m0; 
m[1] = m1; 
m[2] = 
m2;
 
  146  v[0] = v0; v[1] = v1; v[2] = v2;
 
  148  vtkDebugMacro(<<
"Generating tensor glyphs");
 
  150  vtkPointData *outPD = output->GetPointData();
 
  151  inTensors = this->GetInputArrayToProcess(0, inputVector);
 
  152  inScalars = this->GetInputArrayToProcess(1, inputVector);
 
  153  numPts = input->GetNumberOfPoints();
 
  155  if ( !inTensors || numPts < 1 )
 
  157    vtkErrorMacro(<<
"No data to glyph!");
 
  161  pts = 
new vtkIdType[
source->GetMaxCellSize()];
 
  162  trans = vtkTransform::New();
 
  163  matrix = vtkMatrix4x4::New();
 
  168  sourcePts = 
source->GetPoints();
 
  169  numSourcePts = sourcePts->GetNumberOfPoints();
 
  170  numSourceCells = 
source->GetNumberOfCells();
 
  172  newPts = vtkPoints::New();
 
  173  newPts->Allocate(numDirs*numPts*numSourcePts);
 
  176  if ( (sourceCells=
source->GetVerts())->GetNumberOfCells() > 0 )
 
  178    cells = vtkCellArray::New();
 
  179    cells->Allocate(numDirs*numPts*sourceCells->GetSize());
 
  180    output->SetVerts(cells);
 
  183  if ( (sourceCells=this->
GetSource()->GetLines())->GetNumberOfCells() > 0 )
 
  185    cells = vtkCellArray::New();
 
  186    cells->Allocate(numDirs*numPts*sourceCells->GetSize());
 
  187    output->SetLines(cells);
 
  190  if ( (sourceCells=this->
GetSource()->GetPolys())->GetNumberOfCells() > 0 )
 
  192    cells = vtkCellArray::New();
 
  193    cells->Allocate(numDirs*numPts*sourceCells->GetSize());
 
  194    output->SetPolys(cells);
 
  197  if ( (sourceCells=this->
GetSource()->GetStrips())->GetNumberOfCells() > 0 )
 
  199    cells = vtkCellArray::New();
 
  200    cells->Allocate(numDirs*numPts*sourceCells->GetSize());
 
  201    output->SetStrips(cells);
 
  206  vtkPointData *pd = this->
GetSource()->GetPointData();
 
  212    newScalars = vtkFloatArray::New();
 
  213    newScalars->SetNumberOfComponents(4);
 
  214    newScalars->Allocate(numDirs*numPts*numSourcePts);
 
  217      newScalars->SetName(
"MaxEigenvalue");
 
  221      newScalars->SetName(inScalars->GetName());
 
  227    outPD->CopyScalarsOn();
 
  228    outPD->CopyAllocate(pd,numDirs*numPts*numSourcePts);
 
  230  if ( (sourceNormals = pd->GetNormals()) )
 
  232    newNormals = vtkFloatArray::New();
 
  233    newNormals->SetNumberOfComponents(3);
 
  234    newNormals->SetName(
"Normals");
 
  235    newNormals->Allocate(numDirs*3*numPts*numSourcePts);
 
  240  for (inPtId=0; inPtId < numPts; inPtId++)
 
  242    ptIncr = numDirs * inPtId * numSourcePts;
 
  243    for (cellId=0; cellId < numSourceCells; cellId++)
 
  245      cell = this->
GetSource()->GetCell(cellId);
 
  246      cellPts = cell->GetPointIds();
 
  247      npts = cellPts->GetNumberOfIds();
 
  248      for (dir=0; dir < numDirs; dir++)
 
  252        subIncr = ptIncr + dir*numSourcePts;
 
  253        for (i=0; i < npts; i++)
 
  255          pts[i] = cellPts->GetId(i) + subIncr;
 
  257        output->InsertNextCell(cell->GetCellType(),npts,pts);
 
  264  trans->PreMultiply();
 
  266  for (inPtId=0; inPtId < numPts; inPtId++)
 
  268    ptIncr = numDirs * inPtId * numSourcePts;
 
  272    inTensors->GetTuple(inPtId, tensor);
 
  273    if (inTensors->GetNumberOfComponents() == 6)
 
  275      vtkMath::TensorFromSymmetricTensor(tensor);
 
  287          m[i][j] = 0.5 * (tensor[i + 3 * j] + tensor[j + 3 * i]);
 
  290      vtkMath::Jacobi(
m, w, v);
 
  293      xv[0] = v[0][0]; xv[1] = v[1][0]; xv[2] = v[2][0];
 
  294      yv[0] = v[0][1]; yv[1] = v[1][1]; yv[2] = v[2][1];
 
  295      zv[0] = v[0][2]; zv[1] = v[1][2]; zv[2] = v[2][2];
 
  305      w[0] = vtkMath::Normalize(xv);
 
  306      w[1] = vtkMath::Normalize(yv);
 
  307      w[2] = vtkMath::Normalize(zv);
 
  317      for (maxScale=0.0, i=0; i<3; i++)
 
  319        if ( maxScale < fabs(w[i]) )
 
  321          maxScale = fabs(w[i]);
 
  337    for (maxScale=0.0, i=0; i<3; i++)
 
  339      if ( w[i] > maxScale )
 
  344    if ( maxScale == 0.0 )
 
  352        w[i] = maxScale * 1.0e-06;
 
  358    for (dir=0; dir < numDirs; dir++)
 
  367      input->GetPoint(inPtId, x);
 
  368      trans->Translate(x[0], x[1], x[2]);
 
  371      matrix->Element[0][0] = xv[0];
 
  372      matrix->Element[0][1] = yv[0];
 
  373      matrix->Element[0][2] = zv[0];
 
  374      matrix->Element[1][0] = xv[1];
 
  375      matrix->Element[1][1] = yv[1];
 
  376      matrix->Element[1][2] = zv[1];
 
  377      matrix->Element[2][0] = xv[2];
 
  378      matrix->Element[2][1] = yv[2];
 
  379      matrix->Element[2][2] = zv[2];
 
  380      trans->Concatenate(matrix);
 
  384        trans->RotateZ(90.0);
 
  389        trans->RotateY(-90.0);
 
  398        trans->Scale(w[0], w[1], w[2]);
 
  402      if (symmetric_dir == 1)
 
  404        trans->Scale(-1.,1.,1.);
 
  411      if (w[eigen_dir] < 0 && numDirs > 1)
 
  413        trans->Translate(-this->
Length, 0., 0.);
 
  418      trans->TransformPoints(sourcePts,newPts);
 
  428        if (trans->GetMatrix()->Determinant() < 0)
 
  430          trans->Scale(-1.0,-1.0,-1.0);
 
  432        trans->TransformNormals(sourceNormals,newNormals);
 
  439        for (i=0; i < numSourcePts; i++)
 
  441          auto st = inScalars->GetTuple(inPtId);
 
  442          newScalars->InsertTuple4(ptIncr+i,st[0],st[1],st[2],st[3]);
 
  451        for (i=0; i < numSourcePts; i++)
 
  453          newScalars->InsertTuple(ptIncr+i, &
s);
 
  458        for (i=0; i < numSourcePts; i++)
 
  460          outPD->CopyData(pd,i,ptIncr+i);
 
  463      ptIncr += numSourcePts;
 
  466  vtkDebugMacro(<<
"Generated " << numPts <<
" tensor glyphs");
 
  472  output->SetPoints(newPts);
 
  477    int idx = outPD->AddArray(newScalars);
 
  478    outPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
 
  479    newScalars->Delete();
 
  484    outPD->SetNormals(newNormals);
 
  485    newNormals->Delete();
 
  500    vtkErrorMacro(
"Bad index " << 
id << 
" for source.");
 
  504  int numConnections = this->GetNumberOfInputConnections(1);
 
  505  if (
id < numConnections)
 
  507    this->SetNthInputConnection(1, 
id, algOutput);
 
  509  else if (
id == numConnections && algOutput)
 
  511    this->AddInputConnection(1, algOutput);
 
  515    vtkWarningMacro(
"The source id provided is larger than the maximum " 
  516                    "source id, using " << numConnections << 
" instead.");
 
  517    this->AddInputConnection(1, algOutput);
 
  524  this->SetInputData(1, 
source);
 
  530  if (this->GetNumberOfInputConnections(1) < 1)
 
  534  return vtkPolyData::SafeDownCast(this->GetExecutive()->GetInputData(1, 0));
 
  542    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), 
"vtkPolyData");
 
  545  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), 
"vtkDataSet");
 
  550void vtkTensorGlyphColor::PrintSelf(ostream& os, vtkIndent indent)
 
  552  this->Superclass::PrintSelf(os,indent);
 
  554  os << indent << 
"Source: " << this->
GetSource() << 
"\n";
 
  555  os << indent << 
"Scaling: " << (this->
Scaling ? 
"On\n" : 
"Off\n");
 
  556  os << indent << 
"Scale Factor: " << this->
ScaleFactor << 
"\n";
 
  557  os << indent << 
"Extract Eigenvalues: " << (this->
ExtractEigenvalues ? 
"On\n" : 
"Off\n");
 
  558  os << indent << 
"Color Glyphs: " << (this->
ColorGlyphs ? 
"On\n" : 
"Off\n");
 
  559  os << indent << 
"Color Mode: " << this->
ColorMode << endl;
 
  560  os << indent << 
"Clamp Scaling: " << (this->
ClampScaling ? 
"On\n" : 
"Off\n");
 
  561  os << indent << 
"Max Scale Factor: " << this->
MaxScaleFactor << 
"\n";
 
  562  os << indent << 
"Three Glyphs: " << (this->
ThreeGlyphs ? 
"On\n" : 
"Off\n");
 
  563  os << indent << 
"Symmetric: " << (this->
Symmetric ? 
"On\n" : 
"Off\n");
 
  564  os << indent << 
"Length: " << this->
Length << 
"\n";
 
static constexpr double m
static constexpr double s
static constexpr double m2
scale and orient glyph(s) according to eigenvalues and eigenvectors of symmetrical part of tensor
vtkPolyData * GetSource()
int FillInputPortInformation(int port, vtkInformation *info) override
~vtkTensorGlyphColor() override
void SetSourceData(vtkPolyData *source)
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
vtkTypeBool ExtractEigenvalues
void SetSourceConnection(int id, vtkAlgorithmOutput *algOutput)
vtkStandardNewMacro(vtkTensorGlyphColor) vtkTensorGlyphColor