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 = (int)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";
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