4 #include "vtkDataSet.h"
5 #include "vtkFloatArray.h"
7 #include "vtkIdTypeArray.h"
8 #include "vtkInformation.h"
9 #include "vtkInformationVector.h"
11 #include "vtkObjectFactory.h"
12 #include "vtkPointData.h"
13 #include "vtkPolyData.h"
14 #include "vtkStreamingDemandDrivenPipeline.h"
15 #include "vtkTransform.h"
16 #include "vtkUnsignedCharArray.h"
18 vtkCxxRevisionMacro(vvGlyph2D, "DummyRevision");
19 vtkStandardNewMacro(vvGlyph2D);
21 vvGlyph2D::vvGlyph2D()
29 //----------------------------------------------------------------------------
30 int vvGlyph2D::RequestData(
31 vtkInformation *vtkNotUsed(request),
32 vtkInformationVector **inputVector,
33 vtkInformationVector *outputVector)
35 // get the info objects
36 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
37 vtkInformation *outInfo = outputVector->GetInformationObject(0);
39 // get the input and ouptut
40 vtkDataSet *input = vtkDataSet::SafeDownCast(
41 inInfo->Get(vtkDataObject::DATA_OBJECT()));
42 vtkPolyData *output = vtkPolyData::SafeDownCast(
43 outInfo->Get(vtkDataObject::DATA_OBJECT()));
46 vtkDataArray *inSScalars; // Scalars for Scaling
47 vtkDataArray *inCScalars; // Scalars for Coloring
48 vtkDataArray *inVectors;
49 int requestedGhostLevel;
50 unsigned char* inGhostLevels=0;
51 vtkDataArray *inNormals, *sourceNormals = NULL;
52 vtkDataArray *sourceTCoords = NULL;
53 vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i;
55 vtkPoints *sourcePts = NULL;
57 vtkDataArray *newScalars=NULL;
58 vtkDataArray *newVectors=NULL;
59 vtkDataArray *newNormals=NULL;
60 vtkDataArray *newTCoords = NULL;
61 double x[3], v[3], vNew[3], s = 0.0, vMag = 0.0, value, tc[3];
62 vtkTransform *trans = vtkTransform::New();
67 vtkIdType ptIncr, cellId;
68 int haveVectors, haveNormals, haveTCoords = 0;
69 double scalex,scaley,scalez, den;
70 vtkPointData *outputPD = output->GetPointData();
71 int numberOfSources = this->GetNumberOfInputConnections(1);
72 vtkPolyData *defaultSource = NULL;
73 vtkIdTypeArray *pointIds=0;
74 vtkPolyData *source = 0;
76 vtkDebugMacro(<<"Generating glyphs");
78 pts = vtkIdList::New();
79 pts->Allocate(VTK_CELL_SIZE);
81 pd = input->GetPointData();
82 inSScalars = this->GetInputArrayToProcess(0,inputVector);
83 inVectors = this->GetInputArrayToProcess(1,inputVector);
84 inNormals = this->GetInputArrayToProcess(2,inputVector);
85 inCScalars = this->GetInputArrayToProcess(3,inputVector);
86 if (inCScalars == NULL)
88 inCScalars = inSScalars;
91 vtkDataArray* temp = 0;
94 temp = pd->GetArray("vtkGhostLevels");
96 if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
97 || (temp->GetNumberOfComponents() != 1))
99 vtkDebugMacro("No appropriate ghost levels field available.");
103 inGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
106 requestedGhostLevel =
107 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
109 numPts = input->GetNumberOfPoints();
112 vtkDebugMacro(<<"No points to glyph!");
118 // Check input for consistency
120 if ( (den = this->Range[1] - this->Range[0]) == 0.0 )
124 if ( this->VectorMode != VTK_VECTOR_ROTATION_OFF &&
125 ((this->VectorMode == VTK_USE_VECTOR && inVectors != NULL) ||
126 (this->VectorMode == VTK_USE_NORMAL && inNormals != NULL)) )
135 if ( (this->IndexMode == VTK_INDEXING_BY_SCALAR && !inSScalars) ||
136 (this->IndexMode == VTK_INDEXING_BY_VECTOR &&
137 ((!inVectors && this->VectorMode == VTK_USE_VECTOR) ||
138 (!inNormals && this->VectorMode == VTK_USE_NORMAL))) )
140 if ( this->GetSource(0, inputVector[1]) == NULL )
142 vtkErrorMacro(<<"Indexing on but don't have data to index with");
149 vtkWarningMacro(<<"Turning indexing off: no data to index with");
150 this->IndexMode = VTK_INDEXING_OFF;
154 // Allocate storage for output PolyData
156 outputPD->CopyVectorsOff();
157 outputPD->CopyNormalsOff();
158 outputPD->CopyTCoordsOff();
160 if (!this->GetSource(0, inputVector[1]))
162 defaultSource = vtkPolyData::New();
163 defaultSource->Allocate();
164 vtkPoints *defaultPoints = vtkPoints::New();
165 defaultPoints->Allocate(6);
166 defaultPoints->InsertNextPoint(0, 0, 0);
167 defaultPoints->InsertNextPoint(1, 0, 0);
168 vtkIdType defaultPointIds[2];
169 defaultPointIds[0] = 0;
170 defaultPointIds[1] = 1;
171 defaultSource->SetPoints(defaultPoints);
172 defaultSource->InsertNextCell(VTK_LINE, 2, defaultPointIds);
173 defaultSource->SetUpdateExtent(0, 1, 0);
174 this->SetSource(defaultSource);
175 defaultSource->Delete();
176 defaultSource = NULL;
177 defaultPoints->Delete();
178 defaultPoints = NULL;
181 if ( this->IndexMode != VTK_INDEXING_OFF )
185 for (numSourcePts=numSourceCells=i=0; i < numberOfSources; i++)
187 source = this->GetSource(i, inputVector[1]);
188 if ( source != NULL )
190 if (source->GetNumberOfPoints() > numSourcePts)
192 numSourcePts = source->GetNumberOfPoints();
194 if (source->GetNumberOfCells() > numSourceCells)
196 numSourceCells = source->GetNumberOfCells();
198 if ( !(sourceNormals = source->GetPointData()->GetNormals()) )
207 source = this->GetSource(0, inputVector[1]);
208 sourcePts = source->GetPoints();
209 numSourcePts = sourcePts->GetNumberOfPoints();
210 numSourceCells = source->GetNumberOfCells();
212 sourceNormals = source->GetPointData()->GetNormals();
222 sourceTCoords = source->GetPointData()->GetTCoords();
232 // Prepare to copy output.
233 pd = input->GetPointData();
234 outputPD->CopyAllocate(pd,numPts*numSourcePts);
237 newPts = vtkPoints::New();
238 newPts->Allocate(numPts*numSourcePts);
239 if ( this->GeneratePointIds )
241 pointIds = vtkIdTypeArray::New();
242 pointIds->SetName(this->PointIdsName);
243 pointIds->Allocate(numPts*numSourcePts);
244 outputPD->AddArray(pointIds);
247 if ( this->ColorMode == VTK_COLOR_BY_SCALAR && inCScalars )
249 newScalars = inCScalars->NewInstance();
250 newScalars->SetNumberOfComponents(inCScalars->GetNumberOfComponents());
251 newScalars->Allocate(inCScalars->GetNumberOfComponents()*numPts*numSourcePts);
252 newScalars->SetName(inCScalars->GetName());
254 else if ( (this->ColorMode == VTK_COLOR_BY_SCALE) && inSScalars)
256 newScalars = vtkFloatArray::New();
257 newScalars->Allocate(numPts*numSourcePts);
258 newScalars->SetName("GlyphScale");
259 if (this->ScaleMode == VTK_SCALE_BY_SCALAR)
261 newScalars->SetName(inSScalars->GetName());
264 else if ( (this->ColorMode == VTK_COLOR_BY_VECTOR) && haveVectors)
266 newScalars = vtkFloatArray::New();
267 newScalars->Allocate(numPts*numSourcePts);
268 newScalars->SetName("VectorMagnitude");
272 newVectors = vtkFloatArray::New();
273 newVectors->SetNumberOfComponents(3);
274 newVectors->Allocate(3*numPts*numSourcePts);
275 newVectors->SetName("GlyphVector");
279 newNormals = vtkFloatArray::New();
280 newNormals->SetNumberOfComponents(3);
281 newNormals->Allocate(3*numPts*numSourcePts);
282 newNormals->SetName("Normals");
286 newTCoords = vtkFloatArray::New();
287 int numComps = sourceTCoords->GetNumberOfComponents();
288 newTCoords->SetNumberOfComponents(numComps);
289 newTCoords->Allocate(numComps*numPts*numSourcePts);
290 newTCoords->SetName("TCoords");
293 // Setting up for calls to PolyData::InsertNextCell()
294 if (this->IndexMode != VTK_INDEXING_OFF )
296 output->Allocate(3*numPts*numSourceCells,numPts*numSourceCells);
300 output->Allocate(this->GetSource(0, inputVector[1]),
301 3*numPts*numSourceCells, numPts*numSourceCells);
304 // Traverse all Input points, transforming Source points and copying
308 for (inPtId=0; inPtId < numPts; inPtId++)
310 scalex = scaley = scalez = 1.0;
311 if ( ! (inPtId % 10000) )
313 this->UpdateProgress ((double)inPtId/numPts);
314 if (this->GetAbortExecute())
320 // Get the scalar and vector data
323 s = inSScalars->GetComponent(inPtId, 0);
324 if ( this->ScaleMode == VTK_SCALE_BY_SCALAR ||
325 this->ScaleMode == VTK_DATA_SCALING_OFF )
327 scalex = scaley = scalez = s;
333 if ( this->VectorMode == VTK_USE_NORMAL )
335 inNormals->GetTuple(inPtId, v);
339 inVectors->GetTuple(inPtId, v);
342 vMag = vtkMath::Norm(v);
343 if ( this->ScaleMode == VTK_SCALE_BY_VECTORCOMPONENTS )
349 else if ( this->ScaleMode == VTK_SCALE_BY_VECTOR )
351 scalex = scaley = scalez = vMag;
355 // Clamp data scale if enabled
356 if ( this->Clamping )
358 scalex = (scalex < this->Range[0] ? this->Range[0] :
359 (scalex > this->Range[1] ? this->Range[1] : scalex));
360 scalex = (scalex - this->Range[0]) / den;
361 scaley = (scaley < this->Range[0] ? this->Range[0] :
362 (scaley > this->Range[1] ? this->Range[1] : scaley));
363 scaley = (scaley - this->Range[0]) / den;
364 scalez = (scalez < this->Range[0] ? this->Range[0] :
365 (scalez > this->Range[1] ? this->Range[1] : scalez));
366 scalez = (scalez - this->Range[0]) / den;
369 // Compute index into table of glyphs
370 if ( this->IndexMode == VTK_INDEXING_OFF )
376 if ( this->IndexMode == VTK_INDEXING_BY_SCALAR )
385 index = (int) ((double)(value - this->Range[0]) * numberOfSources / den);
386 index = (index < 0 ? 0 :
387 (index >= numberOfSources ? (numberOfSources-1) : index));
389 source = this->GetSource(index, inputVector[1]);
390 if ( source != NULL )
392 sourcePts = source->GetPoints();
393 sourceNormals = source->GetPointData()->GetNormals();
394 numSourcePts = sourcePts->GetNumberOfPoints();
395 numSourceCells = source->GetNumberOfCells();
399 // Make sure we're not indexing into empty glyph
400 if ( this->GetSource(index, inputVector[1]) == NULL )
405 // Check ghost points.
406 // If we are processing a piece, we do not want to duplicate
407 // glyphs on the borders. The corrct check here is:
408 // ghostLevel > 0. I am leaving this over glyphing here because
409 // it make a nice example (sphereGhost.tcl) to show the
410 // point ghost levels with the glyph filter. I am not certain
411 // of the usefullness of point ghost levels over 1, but I will have
412 // to think about it.
413 if (inGhostLevels && inGhostLevels[inPtId] > requestedGhostLevel)
418 if (!this->IsPointVisible(input, inPtId))
423 // Now begin copying/transforming glyph
426 // Copy all topology (transformation independent)
427 for (cellId=0; cellId < numSourceCells; cellId++)
429 cell = this->GetSource(index, inputVector[1])->GetCell(cellId);
430 cellPts = cell->GetPointIds();
431 npts = cellPts->GetNumberOfIds();
432 for (pts->Reset(), i=0; i < npts; i++)
434 pts->InsertId(i,cellPts->GetId(i) + ptIncr);
436 output->InsertNextCell(cell->GetCellType(),pts);
439 // translate Source to Input point
440 input->GetPoint(inPtId, x);
442 //projection on the plane orthogonale to the camera
443 trans->Scale(mOrientation[0],mOrientation[1],mOrientation[2]);
445 trans->Translate(x[0], x[1], x[2]);
450 for (i=0; i < numSourcePts; i++)
452 newVectors->InsertTuple(i+ptIncr, v);
454 if (this->Orient && (vMag > 0.0))
456 // if there is no y or z component
457 if ( v[1] == 0.0 && v[2] == 0.0 )
459 if (v[0] < 0) //just flip x if we need to
461 trans->RotateWXYZ(180.0,0,1,0);
466 vNew[0] = (v[0]+vMag) / 2.0;
467 vNew[1] = v[1] / 2.0;
468 vNew[2] = v[2] / 2.0;
469 trans->RotateWXYZ((double)180.0,vNew[0],vNew[1],vNew[2]);
476 for (i = 0; i < numSourcePts; i++)
478 sourceTCoords->GetTuple(i, tc);
479 newTCoords->InsertTuple(i+ptIncr, tc);
483 // determine scale factor from scalars if appropriate
485 if (inSScalars && (this->ColorMode == VTK_COLOR_BY_SCALE))
487 for (i=0; i < numSourcePts; i++)
489 newScalars->InsertTuple(i+ptIncr, &scalex); // = scaley = scalez
492 else if (inCScalars && (this->ColorMode == VTK_COLOR_BY_SCALAR))
494 for (i=0; i < numSourcePts; i++)
496 outputPD->CopyTuple(inCScalars, newScalars, inPtId, ptIncr+i);
499 if (haveVectors && this->ColorMode == VTK_COLOR_BY_VECTOR)
502 for (i=0; i < numSourcePts; i++)
504 newScalars->InsertTuple(i+ptIncr, &color);
508 // scale data if appropriate
511 if ( this->ScaleMode == VTK_DATA_SCALING_OFF )
513 scalex = scaley = scalez = this->ScaleFactor;
517 scalex *= this->ScaleFactor;
518 scaley *= this->ScaleFactor;
519 scalez *= this->ScaleFactor;
534 trans->Scale(scalex,scaley,scalez);
536 // multiply points and normals by resulting matrix
537 trans->TransformPoints(sourcePts,newPts);
541 trans->TransformNormals(sourceNormals,newNormals);
544 // Copy point data from source (if possible)
547 for (i=0; i < numSourcePts; i++)
549 outputPD->CopyData(pd,inPtId,ptIncr+i);
553 // If point ids are to be generated, do it here
554 if ( this->GeneratePointIds )
556 for (i=0; i < numSourcePts; i++)
558 pointIds->InsertNextValue(inPtId);
562 ptIncr += numSourcePts;
565 // Update ourselves and release memory
567 output->SetPoints(newPts);
572 int idx = outputPD->AddArray(newScalars);
573 outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
574 newScalars->Delete();
579 outputPD->SetVectors(newVectors);
580 newVectors->Delete();
585 outputPD->SetNormals(newNormals);
586 newNormals->Delete();
591 outputPD->SetTCoords(newTCoords);
592 newTCoords->Delete();
602 void vvGlyph2D::PrintSelf(ostream& os, vtkIndent indent)
604 this->Superclass::PrintSelf(os,indent);
607 void vvGlyph2D::SetOrientation(int x, int y, int z)
610 mOrientation[0] = 1.0e-10;
612 mOrientation[0] = 1.0;
614 mOrientation[1] = 1.0e-10;
616 mOrientation[1] = 1.0;
618 mOrientation[2] = 1.0e-10;
620 mOrientation[2] = 1.0;