]> Creatis software - clitk.git/blob - vv/vvGlyph2D.cxx
removed headers
[clitk.git] / vv / vvGlyph2D.cxx
1 #include "vvGlyph2D.h"
2
3 #include "vtkCell.h"
4 #include "vtkDataSet.h"
5 #include "vtkFloatArray.h"
6 #include "vtkIdList.h"
7 #include "vtkIdTypeArray.h"
8 #include "vtkInformation.h"
9 #include "vtkInformationVector.h"
10 #include "vtkMath.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"
17
18 vtkCxxRevisionMacro(vvGlyph2D, "DummyRevision");
19 vtkStandardNewMacro(vvGlyph2D);
20
21 vvGlyph2D::vvGlyph2D()
22 {
23     mOrientation[0] = 1;
24     mOrientation[1] = 1;
25     mOrientation[2] = 1;
26     mUseLog = 0;
27 }
28
29 //----------------------------------------------------------------------------
30 int vvGlyph2D::RequestData(
31     vtkInformation *vtkNotUsed(request),
32     vtkInformationVector **inputVector,
33     vtkInformationVector *outputVector)
34 {
35     // get the info objects
36     vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
37     vtkInformation *outInfo = outputVector->GetInformationObject(0);
38
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()));
44
45     vtkPointData *pd;
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;
54     int index;
55     vtkPoints *sourcePts = NULL;
56     vtkPoints *newPts;
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();
63     vtkCell *cell;
64     vtkIdList *cellPts;
65     int npts;
66     vtkIdList *pts;
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;
75
76     vtkDebugMacro(<<"Generating glyphs");
77
78     pts = vtkIdList::New();
79     pts->Allocate(VTK_CELL_SIZE);
80
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)
87     {
88         inCScalars = inSScalars;
89     }
90
91     vtkDataArray* temp = 0;
92     if (pd)
93     {
94         temp = pd->GetArray("vtkGhostLevels");
95     }
96     if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
97             || (temp->GetNumberOfComponents() != 1))
98     {
99         vtkDebugMacro("No appropriate ghost levels field available.");
100     }
101     else
102     {
103         inGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
104     }
105
106     requestedGhostLevel =
107         outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
108
109     numPts = input->GetNumberOfPoints();
110     if (numPts < 1)
111     {
112         vtkDebugMacro(<<"No points to glyph!");
113         pts->Delete();
114         trans->Delete();
115         return 1;
116     }
117
118     // Check input for consistency
119     //
120     if ( (den = this->Range[1] - this->Range[0]) == 0.0 )
121     {
122         den = 1.0;
123     }
124     if ( this->VectorMode != VTK_VECTOR_ROTATION_OFF &&
125             ((this->VectorMode == VTK_USE_VECTOR && inVectors != NULL) ||
126              (this->VectorMode == VTK_USE_NORMAL && inNormals != NULL)) )
127     {
128         haveVectors = 1;
129     }
130     else
131     {
132         haveVectors = 0;
133     }
134
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))) )
139     {
140         if ( this->GetSource(0, inputVector[1]) == NULL )
141         {
142             vtkErrorMacro(<<"Indexing on but don't have data to index with");
143             pts->Delete();
144             trans->Delete();
145             return 1;
146         }
147         else
148         {
149             vtkWarningMacro(<<"Turning indexing off: no data to index with");
150             this->IndexMode = VTK_INDEXING_OFF;
151         }
152     }
153
154     // Allocate storage for output PolyData
155     //
156     outputPD->CopyVectorsOff();
157     outputPD->CopyNormalsOff();
158     outputPD->CopyTCoordsOff();
159
160     if (!this->GetSource(0, inputVector[1]))
161     {
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;
179     }
180
181     if ( this->IndexMode != VTK_INDEXING_OFF )
182     {
183         pd = NULL;
184         haveNormals = 1;
185         for (numSourcePts=numSourceCells=i=0; i < numberOfSources; i++)
186         {
187             source = this->GetSource(i, inputVector[1]);
188             if ( source != NULL )
189             {
190                 if (source->GetNumberOfPoints() > numSourcePts)
191                 {
192                     numSourcePts = source->GetNumberOfPoints();
193                 }
194                 if (source->GetNumberOfCells() > numSourceCells)
195                 {
196                     numSourceCells = source->GetNumberOfCells();
197                 }
198                 if ( !(sourceNormals = source->GetPointData()->GetNormals()) )
199                 {
200                     haveNormals = 0;
201                 }
202             }
203         }
204     }
205     else
206     {
207         source = this->GetSource(0, inputVector[1]);
208         sourcePts = source->GetPoints();
209         numSourcePts = sourcePts->GetNumberOfPoints();
210         numSourceCells = source->GetNumberOfCells();
211
212         sourceNormals = source->GetPointData()->GetNormals();
213         if ( sourceNormals )
214         {
215             haveNormals = 1;
216         }
217         else
218         {
219             haveNormals = 0;
220         }
221
222         sourceTCoords = source->GetPointData()->GetTCoords();
223         if (sourceTCoords)
224         {
225             haveTCoords = 1;
226         }
227         else
228         {
229             haveTCoords = 0;
230         }
231
232         // Prepare to copy output.
233         pd = input->GetPointData();
234         outputPD->CopyAllocate(pd,numPts*numSourcePts);
235     }
236
237     newPts = vtkPoints::New();
238     newPts->Allocate(numPts*numSourcePts);
239     if ( this->GeneratePointIds )
240     {
241         pointIds = vtkIdTypeArray::New();
242         pointIds->SetName(this->PointIdsName);
243         pointIds->Allocate(numPts*numSourcePts);
244         outputPD->AddArray(pointIds);
245         pointIds->Delete();
246     }
247     if ( this->ColorMode == VTK_COLOR_BY_SCALAR && inCScalars )
248     {
249         newScalars = inCScalars->NewInstance();
250         newScalars->SetNumberOfComponents(inCScalars->GetNumberOfComponents());
251         newScalars->Allocate(inCScalars->GetNumberOfComponents()*numPts*numSourcePts);
252         newScalars->SetName(inCScalars->GetName());
253     }
254     else if ( (this->ColorMode == VTK_COLOR_BY_SCALE) && inSScalars)
255     {
256         newScalars = vtkFloatArray::New();
257         newScalars->Allocate(numPts*numSourcePts);
258         newScalars->SetName("GlyphScale");
259         if (this->ScaleMode == VTK_SCALE_BY_SCALAR)
260         {
261             newScalars->SetName(inSScalars->GetName());
262         }
263     }
264     else if ( (this->ColorMode == VTK_COLOR_BY_VECTOR) && haveVectors)
265     {
266         newScalars = vtkFloatArray::New();
267         newScalars->Allocate(numPts*numSourcePts);
268         newScalars->SetName("VectorMagnitude");
269     }
270     if ( haveVectors )
271     {
272         newVectors = vtkFloatArray::New();
273         newVectors->SetNumberOfComponents(3);
274         newVectors->Allocate(3*numPts*numSourcePts);
275         newVectors->SetName("GlyphVector");
276     }
277     if ( haveNormals )
278     {
279         newNormals = vtkFloatArray::New();
280         newNormals->SetNumberOfComponents(3);
281         newNormals->Allocate(3*numPts*numSourcePts);
282         newNormals->SetName("Normals");
283     }
284     if (haveTCoords)
285     {
286         newTCoords = vtkFloatArray::New();
287         int numComps = sourceTCoords->GetNumberOfComponents();
288         newTCoords->SetNumberOfComponents(numComps);
289         newTCoords->Allocate(numComps*numPts*numSourcePts);
290         newTCoords->SetName("TCoords");
291     }
292
293     // Setting up for calls to PolyData::InsertNextCell()
294     if (this->IndexMode != VTK_INDEXING_OFF )
295     {
296         output->Allocate(3*numPts*numSourceCells,numPts*numSourceCells);
297     }
298     else
299     {
300         output->Allocate(this->GetSource(0, inputVector[1]),
301                          3*numPts*numSourceCells, numPts*numSourceCells);
302     }
303
304     // Traverse all Input points, transforming Source points and copying
305     // point attributes.
306     //
307     ptIncr=0;
308     for (inPtId=0; inPtId < numPts; inPtId++)
309     {
310         scalex = scaley = scalez = 1.0;
311         if ( ! (inPtId % 10000) )
312         {
313             this->UpdateProgress ((double)inPtId/numPts);
314             if (this->GetAbortExecute())
315             {
316                 break;
317             }
318         }
319
320         // Get the scalar and vector data
321         if ( inSScalars )
322         {
323             s = inSScalars->GetComponent(inPtId, 0);
324             if ( this->ScaleMode == VTK_SCALE_BY_SCALAR ||
325                     this->ScaleMode == VTK_DATA_SCALING_OFF )
326             {
327                 scalex = scaley = scalez = s;
328             }
329         }
330
331         if ( haveVectors )
332         {
333             if ( this->VectorMode == VTK_USE_NORMAL )
334             {
335                 inNormals->GetTuple(inPtId, v);
336             }
337             else
338             {
339                 inVectors->GetTuple(inPtId, v);
340             }
341
342             vMag = vtkMath::Norm(v);
343             if ( this->ScaleMode == VTK_SCALE_BY_VECTORCOMPONENTS )
344             {
345                 scalex = v[0];
346                 scaley = v[1];
347                 scalez = v[2];
348             }
349             else if ( this->ScaleMode == VTK_SCALE_BY_VECTOR )
350             {
351                 scalex = scaley = scalez = vMag;
352             }
353         }
354
355         // Clamp data scale if enabled
356         if ( this->Clamping )
357         {
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;
367         }
368
369         // Compute index into table of glyphs
370         if ( this->IndexMode == VTK_INDEXING_OFF )
371         {
372             index = 0;
373         }
374         else
375         {
376             if ( this->IndexMode == VTK_INDEXING_BY_SCALAR )
377             {
378                 value = s;
379             }
380             else
381             {
382                 value = vMag;
383             }
384
385             index = (int) ((double)(value - this->Range[0]) * numberOfSources / den);
386             index = (index < 0 ? 0 :
387                      (index >= numberOfSources ? (numberOfSources-1) : index));
388
389             source = this->GetSource(index, inputVector[1]);
390             if ( source != NULL )
391             {
392                 sourcePts = source->GetPoints();
393                 sourceNormals = source->GetPointData()->GetNormals();
394                 numSourcePts = sourcePts->GetNumberOfPoints();
395                 numSourceCells = source->GetNumberOfCells();
396             }
397         }
398
399         // Make sure we're not indexing into empty glyph
400         if ( this->GetSource(index, inputVector[1]) == NULL )
401         {
402             continue;
403         }
404
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)
414         {
415             continue;
416         }
417
418         if (!this->IsPointVisible(input, inPtId))
419         {
420             continue;
421         }
422
423         // Now begin copying/transforming glyph
424         trans->Identity();
425
426         // Copy all topology (transformation independent)
427         for (cellId=0; cellId < numSourceCells; cellId++)
428         {
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++)
433             {
434                 pts->InsertId(i,cellPts->GetId(i) + ptIncr);
435             }
436             output->InsertNextCell(cell->GetCellType(),pts);
437         }
438
439         // translate Source to Input point
440         input->GetPoint(inPtId, x);
441
442         //projection on the plane orthogonale to the camera
443         trans->Scale(mOrientation[0],mOrientation[1],mOrientation[2]);
444
445         trans->Translate(x[0], x[1], x[2]);
446
447         if ( haveVectors )
448         {
449             // Copy Input vector
450             for (i=0; i < numSourcePts; i++)
451             {
452                 newVectors->InsertTuple(i+ptIncr, v);
453             }
454             if (this->Orient && (vMag > 0.0))
455             {
456                 // if there is no y or z component
457                 if ( v[1] == 0.0 && v[2] == 0.0 )
458                 {
459                     if (v[0] < 0) //just flip x if we need to
460                     {
461                         trans->RotateWXYZ(180.0,0,1,0);
462                     }
463                 }
464                 else
465                 {
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]);
470                 }
471             }
472         }
473
474         if (haveTCoords)
475         {
476             for (i = 0; i < numSourcePts; i++)
477             {
478                 sourceTCoords->GetTuple(i, tc);
479                 newTCoords->InsertTuple(i+ptIncr, tc);
480             }
481         }
482
483         // determine scale factor from scalars if appropriate
484         // Copy scalar value
485         if (inSScalars && (this->ColorMode == VTK_COLOR_BY_SCALE))
486         {
487             for (i=0; i < numSourcePts; i++)
488             {
489                 newScalars->InsertTuple(i+ptIncr, &scalex); // = scaley = scalez
490             }
491         }
492         else if (inCScalars && (this->ColorMode == VTK_COLOR_BY_SCALAR))
493         {
494             for (i=0; i < numSourcePts; i++)
495             {
496                 outputPD->CopyTuple(inCScalars, newScalars, inPtId, ptIncr+i);
497             }
498         }
499         if (haveVectors && this->ColorMode == VTK_COLOR_BY_VECTOR)
500         {
501             double color = 1;
502             for (i=0; i < numSourcePts; i++)
503             {
504                 newScalars->InsertTuple(i+ptIncr, &color);
505             }
506         }
507
508         // scale data if appropriate
509         if ( this->Scaling )
510         {
511             if ( this->ScaleMode == VTK_DATA_SCALING_OFF )
512             {
513                 scalex = scaley = scalez = this->ScaleFactor;
514             }
515             else
516             {
517                 scalex *= this->ScaleFactor;
518                 scaley *= this->ScaleFactor;
519                 scalez *= this->ScaleFactor;
520             }
521
522             if ( scalex == 0.0 )
523             {
524                 scalex = 1.0e-10;
525             }
526             if ( scaley == 0.0 )
527             {
528                 scaley = 1.0e-10;
529             }
530             if ( scalez == 0.0 )
531             {
532                 scalez = 1.0e-10;
533             }
534             trans->Scale(scalex,scaley,scalez);
535         }
536         // multiply points and normals by resulting matrix
537         trans->TransformPoints(sourcePts,newPts);
538
539         if ( haveNormals )
540         {
541             trans->TransformNormals(sourceNormals,newNormals);
542         }
543
544         // Copy point data from source (if possible)
545         if ( pd )
546         {
547             for (i=0; i < numSourcePts; i++)
548             {
549                 outputPD->CopyData(pd,inPtId,ptIncr+i);
550             }
551         }
552
553         // If point ids are to be generated, do it here
554         if ( this->GeneratePointIds )
555         {
556             for (i=0; i < numSourcePts; i++)
557             {
558                 pointIds->InsertNextValue(inPtId);
559             }
560         }
561
562         ptIncr += numSourcePts;
563     }
564
565     // Update ourselves and release memory
566     //
567     output->SetPoints(newPts);
568     newPts->Delete();
569
570     if (newScalars)
571     {
572         int idx = outputPD->AddArray(newScalars);
573         outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
574         newScalars->Delete();
575     }
576
577     if (newVectors)
578     {
579         outputPD->SetVectors(newVectors);
580         newVectors->Delete();
581     }
582
583     if (newNormals)
584     {
585         outputPD->SetNormals(newNormals);
586         newNormals->Delete();
587     }
588
589     if (newTCoords)
590     {
591         outputPD->SetTCoords(newTCoords);
592         newTCoords->Delete();
593     }
594
595     output->Squeeze();
596     trans->Delete();
597     pts->Delete();
598
599     return 1;
600 }
601
602 void vvGlyph2D::PrintSelf(ostream& os, vtkIndent indent)
603 {
604     this->Superclass::PrintSelf(os,indent);
605 }
606
607 void vvGlyph2D::SetOrientation(int x, int y, int z)
608 {
609     if (x == 0)
610         mOrientation[0] = 1.0e-10;
611     else
612         mOrientation[0] = 1.0;
613     if (y == 0)
614         mOrientation[1] = 1.0e-10;
615     else
616         mOrientation[1] = 1.0;
617     if (z == 0)
618         mOrientation[2] = 1.0e-10;
619     else
620         mOrientation[2] = 1.0;
621 }