66 vtkInformationVector** inputVector,
67 vtkInformationVector* outputVector)
70 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
71 vtkInformation* sourceInfo = inputVector[1]->GetInformationObject(0);
72 vtkInformation* outInfo = outputVector->GetInformationObject(0);
74 if (sourceInfo !=
nullptr) {
75 sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), 0);
76 sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(), 1);
77 sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
80 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
81 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
82 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
83 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
84 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
85 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
86 inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
93 vtkInformationVector** inputVector,
94 vtkInformationVector* outputVector)
97 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
98 vtkInformation* sourceInfo = inputVector[1]->GetInformationObject(0);
99 vtkInformation* outInfo = outputVector->GetInformationObject(0);
102 vtkDataSet* input = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
103 vtkPolyData* source = vtkPolyData::SafeDownCast(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
104 vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
106 vtkDataArray* inTensors;
108 vtkDataArray* inScalars;
109 vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i;
111 vtkPoints* sourcePts;
112 vtkDataArray* sourceNormals;
113 vtkCellArray *sourceCells, *cells;
115 vtkFloatArray* newScalars =
nullptr;
116 vtkFloatArray* newNormals =
nullptr;
123 vtkIdType ptIncr, cellId;
125 int numDirs, dir, eigen_dir, symmetric_dir;
126 vtkMatrix4x4* matrix;
127 double *m[3], w[3], *v[3];
128 double m0[3], m1[3], m2[3];
129 double v0[3], v1[3], v2[3];
130 double xv[3], yv[3], zv[3];
143 vtkDebugMacro(<<
"Generating tensor glyphs");
145 vtkPointData* outPD = output->GetPointData();
146 inTensors = this->GetInputArrayToProcess(0, inputVector);
147 inScalars = this->GetInputArrayToProcess(1, inputVector);
148 numPts = input->GetNumberOfPoints();
150 if ((inTensors ==
nullptr) || numPts < 1) {
151 vtkErrorMacro(<<
"No data to glyph!");
155 pts =
new vtkIdType[source->GetMaxCellSize()];
156 trans = vtkTransform::New();
157 matrix = vtkMatrix4x4::New();
162 sourcePts = source->GetPoints();
163 numSourcePts = sourcePts->GetNumberOfPoints();
164 numSourceCells = source->GetNumberOfCells();
166 newPts = vtkPoints::New();
167 newPts->Allocate(numDirs * numPts * numSourcePts);
170 if ((sourceCells = source->GetVerts())->GetNumberOfCells() > 0) {
171 cells = vtkCellArray::New();
172 cells->Allocate(numDirs * numPts * sourceCells->GetSize());
173 output->SetVerts(cells);
176 if ((sourceCells = this->
GetSource()->GetLines())->GetNumberOfCells() > 0) {
177 cells = vtkCellArray::New();
178 cells->Allocate(numDirs * numPts * sourceCells->GetSize());
179 output->SetLines(cells);
182 if ((sourceCells = this->
GetSource()->GetPolys())->GetNumberOfCells() > 0) {
183 cells = vtkCellArray::New();
184 cells->Allocate(numDirs * numPts * sourceCells->GetSize());
185 output->SetPolys(cells);
188 if ((sourceCells = this->
GetSource()->GetStrips())->GetNumberOfCells() > 0) {
189 cells = vtkCellArray::New();
190 cells->Allocate(numDirs * numPts * sourceCells->GetSize());
191 output->SetStrips(cells);
196 vtkPointData* pd = this->
GetSource()->GetPointData();
202 newScalars = vtkFloatArray::New();
203 newScalars->SetNumberOfComponents(4);
204 newScalars->Allocate(numDirs * numPts * numSourcePts);
206 newScalars->SetName(
"MaxEigenvalue");
209 newScalars->SetName(inScalars->GetName());
214 outPD->CopyScalarsOn();
215 outPD->CopyAllocate(pd, numDirs * numPts * numSourcePts);
217 if ((sourceNormals = pd->GetNormals()) !=
nullptr) {
218 newNormals = vtkFloatArray::New();
219 newNormals->SetNumberOfComponents(3);
220 newNormals->SetName(
"Normals");
221 newNormals->Allocate(numDirs * 3 * numPts * numSourcePts);
226 for (inPtId = 0; inPtId < numPts; inPtId++) {
227 ptIncr = numDirs * inPtId * numSourcePts;
228 for (cellId = 0; cellId < numSourceCells; cellId++) {
229 cell = this->
GetSource()->GetCell(cellId);
230 cellPts = cell->GetPointIds();
231 npts = (int)cellPts->GetNumberOfIds();
232 for (dir = 0; dir < numDirs; dir++) {
235 subIncr = ptIncr + dir * numSourcePts;
236 for (i = 0; i < npts; i++) {
237 pts[i] = cellPts->GetId(i) + subIncr;
239 output->InsertNextCell(cell->GetCellType(), npts, pts);
246 trans->PreMultiply();
248 for (inPtId = 0; inPtId < numPts; inPtId++) {
249 ptIncr = numDirs * inPtId * numSourcePts;
253 inTensors->GetTuple(inPtId, tensor);
254 if (inTensors->GetNumberOfComponents() == 6) {
255 vtkMath::TensorFromSymmetricTensor(tensor);
263 for (j = 0; j < 3; j++) {
264 for (i = 0; i < 3; i++) {
265 m[i][j] = 0.5 * (tensor[i + 3 * j] + tensor[j + 3 * i]);
268 vtkMath::Jacobi(m, w, v);
283 for (i = 0; i < 3; i++) {
285 yv[i] = tensor[i + 3];
286 zv[i] = tensor[i + 6];
288 w[0] = vtkMath::Normalize(xv);
289 w[1] = vtkMath::Normalize(yv);
290 w[2] = vtkMath::Normalize(zv);
299 for (maxScale = 0.0, i = 0; i < 3; i++) {
300 if (maxScale < fabs(w[i])) {
301 maxScale = fabs(w[i]);
306 for (i = 0; i < 3; i++) {
315 for (maxScale = 0.0, i = 0; i < 3; i++) {
316 if (w[i] > maxScale) {
320 if (maxScale == 0.0) {
323 for (i = 0; i < 3; i++) {
325 w[i] = maxScale * 1.0e-06;
331 for (dir = 0; dir < numDirs; dir++) {
332 eigen_dir = dir % (this->
ThreeGlyphs != 0 ? 3 : 1);
333 symmetric_dir = dir / (this->
ThreeGlyphs != 0 ? 3 : 1);
339 input->GetPoint(inPtId, x);
340 trans->Translate(x[0], x[1], x[2]);
343 matrix->Element[0][0] = xv[0];
344 matrix->Element[0][1] = yv[0];
345 matrix->Element[0][2] = zv[0];
346 matrix->Element[1][0] = xv[1];
347 matrix->Element[1][1] = yv[1];
348 matrix->Element[1][2] = zv[1];
349 matrix->Element[2][0] = xv[2];
350 matrix->Element[2][1] = yv[2];
351 matrix->Element[2][2] = zv[2];
352 trans->Concatenate(matrix);
354 if (eigen_dir == 1) {
355 trans->RotateZ(90.0);
358 if (eigen_dir == 2) {
359 trans->RotateY(-90.0);
366 trans->Scale(w[0], w[1], w[2]);
370 if (symmetric_dir == 1) {
371 trans->Scale(-1., 1., 1.);
378 if (w[eigen_dir] < 0 && numDirs > 1) {
379 trans->Translate(-this->
Length, 0., 0.);
384 trans->TransformPoints(sourcePts, newPts);
388 if (newNormals !=
nullptr) {
393 if (trans->GetMatrix()->Determinant() < 0) {
394 trans->Scale(-1.0, -1.0, -1.0);
396 trans->TransformNormals(sourceNormals, newNormals);
400 if ((this->
ColorGlyphs != 0) && (inScalars !=
nullptr)
403 for (i = 0; i < numSourcePts; i++) {
404 auto st = inScalars->GetTuple(inPtId);
405 newScalars->InsertTuple4(ptIncr + i, st[0], st[1], st[2], st[3]);
412 for (i = 0; i < numSourcePts; i++) {
413 newScalars->InsertTuple(ptIncr + i, &s);
417 for (i = 0; i < numSourcePts; i++) {
418 outPD->CopyData(pd, i, ptIncr + i);
421 ptIncr += numSourcePts;
424 vtkDebugMacro(<<
"Generated " << numPts <<
" tensor glyphs");
430 output->SetPoints(newPts);
433 if (newScalars !=
nullptr) {
434 int idx = outPD->AddArray(newScalars);
435 outPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
436 newScalars->Delete();
439 if (newNormals !=
nullptr) {
440 outPD->SetNormals(newNormals);
441 newNormals->Delete();