]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Class VTKViewer_Glyph3D (for GUITHARE issue 0001112: External 20480: evolution 3D...
authorouv <ouv@opencascade.com>
Mon, 18 Jun 2012 09:46:42 +0000 (09:46 +0000)
committerouv <ouv@opencascade.com>
Mon, 18 Jun 2012 09:46:42 +0000 (09:46 +0000)
src/VTKViewer/Makefile.am
src/VTKViewer/VTKViewer_Glyph3D.cxx [new file with mode: 0644]
src/VTKViewer/VTKViewer_Glyph3D.h [new file with mode: 0644]

index 567d46e763e7710073061290065817eef4f345c0..dda59b7f3325a9f1fd4e4b436d73328bce8023e6 100755 (executable)
@@ -49,6 +49,7 @@ salomeinclude_HEADERS =                               \
        VTKViewer_Functor.h                     \
         VTKViewer_MergeFilter.h                        \
         VTKViewer_PassThroughFilter.h          \
+        VTKViewer_Glyph3D.h                    \
        vtkArcSource.h
 
 dist_libVTKViewer_la_SOURCES =                 \
@@ -73,6 +74,7 @@ dist_libVTKViewer_la_SOURCES =                        \
        VTKViewer_ViewWindow.cxx                \
         VTKViewer_MergeFilter.cxx              \
         VTKViewer_PassThroughFilter.cxx                \
+        VTKViewer_Glyph3D.cxx                  \
        vtkArcSource.cxx
 
 MOC_FILES =                                            \
diff --git a/src/VTKViewer/VTKViewer_Glyph3D.cxx b/src/VTKViewer/VTKViewer_Glyph3D.cxx
new file mode 100644 (file)
index 0000000..3777c7f
--- /dev/null
@@ -0,0 +1,638 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "VTKViewer_Glyph3D.h"
+
+#include <vtkCellData.h>
+#include <vtkCell.h>
+#include <vtkDataSet.h>
+#include <vtkFloatArray.h>
+#include <vtkIdList.h>
+#include <vtkIdTypeArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkMath.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkTransform.h>
+#include <vtkUnsignedCharArray.h>
+
+vtkStandardNewMacro(VTKViewer_Glyph3D);
+
+//----------------------------------------------------------------------------
+// Construct object with scaling on, scaling mode is by scalar value,
+// scale factor = 1.0, the range is (0,1), orient geometry is on, and
+// orientation is by vector. Clamping and indexing are turned off. No
+// initial sources are defined.
+VTKViewer_Glyph3D::VTKViewer_Glyph3D()
+{
+  this->FillCellData = 0;
+}
+
+//----------------------------------------------------------------------------
+VTKViewer_Glyph3D::~VTKViewer_Glyph3D()
+{
+  if (this->PointIdsName)
+    {
+    delete []PointIdsName;
+    }
+}
+
+//----------------------------------------------------------------------------
+int VTKViewer_Glyph3D::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and ouptut
+  vtkDataSet *input = vtkDataSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkPointData *pd;
+  vtkDataArray *inSScalars; // Scalars for Scaling
+  vtkDataArray *inCScalars; // Scalars for Coloring
+  vtkDataArray *inVectors;
+  int requestedGhostLevel;
+  unsigned char* inGhostLevels=0;
+  vtkDataArray *inNormals, *sourceNormals = NULL;
+  vtkDataArray *sourceTCoords = NULL;
+  vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i;
+  int index;
+  vtkPoints *sourcePts = NULL;
+  vtkPoints *newPts;
+  vtkDataArray *newScalars=NULL;
+  vtkDataArray *newVectors=NULL;
+  vtkDataArray *newNormals=NULL;
+  vtkDataArray *newTCoords = NULL;
+  double x[3], v[3], vNew[3], s = 0.0, vMag = 0.0, value, tc[3];
+  vtkTransform *trans = vtkTransform::New();
+  vtkCell *cell;
+  vtkIdList *cellPts;
+  int npts;
+  vtkIdList *pts;
+  vtkIdType ptIncr, cellIncr, cellId;
+  int haveVectors, haveNormals, haveTCoords = 0;
+  double scalex,scaley,scalez, den;
+  vtkPointData *outputPD = output->GetPointData();
+  vtkCellData* outputCD = output->GetCellData();
+  int numberOfSources = this->GetNumberOfInputConnections(1);
+  vtkPolyData *defaultSource = NULL;
+  vtkIdTypeArray *pointIds=0;
+  vtkPolyData *source = 0;
+
+  vtkDebugMacro(<<"Generating glyphs");
+
+  pts = vtkIdList::New();
+  pts->Allocate(VTK_CELL_SIZE);
+
+  pd = input->GetPointData();
+  inSScalars = this->GetInputArrayToProcess(0,inputVector);
+  inVectors = this->GetInputArrayToProcess(1,inputVector);
+  inNormals = this->GetInputArrayToProcess(2,inputVector);
+  inCScalars = this->GetInputArrayToProcess(3,inputVector);
+  if (inCScalars == NULL)
+    {
+    inCScalars = inSScalars;
+    }
+  
+  vtkDataArray* temp = 0;
+  if (pd)
+    {
+    temp = pd->GetArray("vtkGhostLevels");
+    }
+  if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
+    || (temp->GetNumberOfComponents() != 1))
+    {
+    vtkDebugMacro("No appropriate ghost levels field available.");
+    }
+  else
+    {
+    inGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
+    }
+
+  requestedGhostLevel =
+    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
+  
+  numPts = input->GetNumberOfPoints();
+  if (numPts < 1)
+    {
+    vtkDebugMacro(<<"No points to glyph!");
+    pts->Delete();
+    trans->Delete();
+    return 1;
+    }
+
+  // Check input for consistency
+  //
+  if ( (den = this->Range[1] - this->Range[0]) == 0.0 )
+    {
+    den = 1.0;
+    }
+  if ( this->VectorMode != VTK_VECTOR_ROTATION_OFF &&
+       ((this->VectorMode == VTK_USE_VECTOR && inVectors != NULL) ||
+        (this->VectorMode == VTK_USE_NORMAL && inNormals != NULL)) )
+    {
+    haveVectors = 1;
+    }
+  else
+    {
+    haveVectors = 0;
+    }
+
+  if ( (this->IndexMode == VTK_INDEXING_BY_SCALAR && !inSScalars) ||
+       (this->IndexMode == VTK_INDEXING_BY_VECTOR &&
+       ((!inVectors && this->VectorMode == VTK_USE_VECTOR) ||
+        (!inNormals && this->VectorMode == VTK_USE_NORMAL))) )
+    {
+    if ( this->GetSource(0, inputVector[1]) == NULL )
+      {
+      vtkErrorMacro(<<"Indexing on but don't have data to index with");
+      pts->Delete();
+      trans->Delete();
+      return 1;
+      }
+    else
+      {
+      vtkWarningMacro(<<"Turning indexing off: no data to index with");
+      this->IndexMode = VTK_INDEXING_OFF;
+      }
+    }
+
+  // Allocate storage for output PolyData
+  //
+  outputPD->CopyVectorsOff();
+  outputPD->CopyNormalsOff();
+  outputPD->CopyTCoordsOff();
+
+  if (!this->GetSource(0, inputVector[1]))
+    {
+    defaultSource = vtkPolyData::New();
+    defaultSource->Allocate();
+    vtkPoints *defaultPoints = vtkPoints::New();
+    defaultPoints->Allocate(6);
+    defaultPoints->InsertNextPoint(0, 0, 0);
+    defaultPoints->InsertNextPoint(1, 0, 0);
+    vtkIdType defaultPointIds[2];
+    defaultPointIds[0] = 0;
+    defaultPointIds[1] = 1;
+    defaultSource->SetPoints(defaultPoints);
+    defaultSource->InsertNextCell(VTK_LINE, 2, defaultPointIds);
+    defaultSource->SetUpdateExtent(0, 1, 0);
+    this->SetSource(defaultSource);
+    defaultSource->Delete();
+    defaultSource = NULL;
+    defaultPoints->Delete();
+    defaultPoints = NULL;
+    }
+  
+  if ( this->IndexMode != VTK_INDEXING_OFF )
+    {
+    pd = NULL;
+    haveNormals = 1;
+    for (numSourcePts=numSourceCells=i=0; i < numberOfSources; i++)
+      {
+      source = this->GetSource(i, inputVector[1]);
+      if ( source != NULL )
+        {
+        if (source->GetNumberOfPoints() > numSourcePts)
+          {
+          numSourcePts = source->GetNumberOfPoints();
+          }
+        if (source->GetNumberOfCells() > numSourceCells)
+          {
+          numSourceCells = source->GetNumberOfCells();
+          }
+        if ( !(sourceNormals = source->GetPointData()->GetNormals()) )
+          {
+          haveNormals = 0;
+          }
+        }
+      }
+    }
+  else
+    {
+    source = this->GetSource(0, inputVector[1]);
+    sourcePts = source->GetPoints();
+    numSourcePts = sourcePts->GetNumberOfPoints();
+    numSourceCells = source->GetNumberOfCells();
+
+    sourceNormals = source->GetPointData()->GetNormals();
+    if ( sourceNormals )
+      {
+      haveNormals = 1;
+      }
+    else
+      {
+      haveNormals = 0;
+      }
+
+    sourceTCoords = source->GetPointData()->GetTCoords();
+    if (sourceTCoords)
+      {
+      haveTCoords = 1;
+      }
+    else
+      {
+      haveTCoords = 0;
+      }
+    
+    // Prepare to copy output.
+    pd = input->GetPointData();
+    outputPD->CopyAllocate(pd,numPts*numSourcePts);
+    if (this->FillCellData)
+      {
+      outputCD->CopyAllocate(pd,numPts*numSourceCells);
+      }
+    }
+
+  newPts = vtkPoints::New();
+  newPts->Allocate(numPts*numSourcePts);
+  if ( this->GeneratePointIds )
+    {
+    pointIds = vtkIdTypeArray::New();
+    pointIds->SetName(this->PointIdsName);
+    pointIds->Allocate(numPts*numSourcePts);
+    outputPD->AddArray(pointIds);
+    pointIds->Delete();
+    }
+  if ( this->ColorMode == VTK_COLOR_BY_SCALAR && inCScalars )
+    {
+    newScalars = inCScalars->NewInstance();
+    newScalars->SetNumberOfComponents(inCScalars->GetNumberOfComponents());
+    newScalars->Allocate(inCScalars->GetNumberOfComponents()*numPts*numSourcePts);
+    newScalars->SetName(inCScalars->GetName());
+    }
+  else if ( (this->ColorMode == VTK_COLOR_BY_SCALE) && inSScalars)
+    {
+    newScalars = vtkFloatArray::New();
+    newScalars->Allocate(numPts*numSourcePts);
+    newScalars->SetName("GlyphScale");
+    if (this->ScaleMode == VTK_SCALE_BY_SCALAR)
+      {
+      newScalars->SetName(inSScalars->GetName());
+      }
+    }
+  else if ( (this->ColorMode == VTK_COLOR_BY_VECTOR) && haveVectors)
+    {
+    newScalars = vtkFloatArray::New();
+    newScalars->Allocate(numPts*numSourcePts);
+    newScalars->SetName("VectorMagnitude");
+    }
+  if ( haveVectors )
+    {
+    newVectors = vtkFloatArray::New();
+    newVectors->SetNumberOfComponents(3);
+    newVectors->Allocate(3*numPts*numSourcePts);
+    newVectors->SetName("GlyphVector");
+    }
+  if ( haveNormals )
+    {
+    newNormals = vtkFloatArray::New();
+    newNormals->SetNumberOfComponents(3);
+    newNormals->Allocate(3*numPts*numSourcePts);
+    newNormals->SetName("Normals");
+    }
+  if (haveTCoords)
+    {
+    newTCoords = vtkFloatArray::New();
+    int numComps = sourceTCoords->GetNumberOfComponents();
+    newTCoords->SetNumberOfComponents(numComps);
+    newTCoords->Allocate(numComps*numPts*numSourcePts);
+    newTCoords->SetName("TCoords");
+    }
+    
+  // Setting up for calls to PolyData::InsertNextCell()
+  if (this->IndexMode != VTK_INDEXING_OFF )
+    {
+    output->Allocate(3*numPts*numSourceCells,numPts*numSourceCells);
+    }
+  else
+    {
+    output->Allocate(this->GetSource(0, inputVector[1]),
+                     3*numPts*numSourceCells, numPts*numSourceCells);
+    }
+
+  // Traverse all Input points, transforming Source points and copying
+  // point attributes.
+  //
+  ptIncr=0;
+  cellIncr=0;
+  for (inPtId=0; inPtId < numPts; inPtId++)
+    {
+    scalex = scaley = scalez = 1.0;
+    if ( ! (inPtId % 10000) )
+      {
+      this->UpdateProgress ((double)inPtId/numPts);
+      if (this->GetAbortExecute())
+        {
+        break;
+        }
+      }
+
+    // Get the scalar and vector data
+    if ( inSScalars )
+      {
+      s = inSScalars->GetComponent(inPtId, 0);
+      if ( this->ScaleMode == VTK_SCALE_BY_SCALAR ||
+           this->ScaleMode == VTK_DATA_SCALING_OFF )
+        {
+        scalex = scaley = scalez = s;
+        }
+      }
+    
+    if ( haveVectors )
+      {
+      if ( this->VectorMode == VTK_USE_NORMAL )
+        {
+        inNormals->GetTuple(inPtId, v);
+        }
+      else
+        {
+        inVectors->GetTuple(inPtId, v);
+        }
+      vMag = vtkMath::Norm(v);
+      if ( this->ScaleMode == VTK_SCALE_BY_VECTORCOMPONENTS )
+        {
+        scalex = v[0];
+        scaley = v[1];
+        scalez = v[2];
+        }
+      else if ( this->ScaleMode == VTK_SCALE_BY_VECTOR )
+        {
+        scalex = scaley = scalez = vMag;
+        }
+      }
+    
+    // Clamp data scale if enabled
+    if ( this->Clamping )
+      {
+      scalex = (scalex < this->Range[0] ? this->Range[0] :
+                (scalex > this->Range[1] ? this->Range[1] : scalex));
+      scalex = (scalex - this->Range[0]) / den;
+      scaley = (scaley < this->Range[0] ? this->Range[0] :
+                (scaley > this->Range[1] ? this->Range[1] : scaley));
+      scaley = (scaley - this->Range[0]) / den;
+      scalez = (scalez < this->Range[0] ? this->Range[0] :
+                (scalez > this->Range[1] ? this->Range[1] : scalez));
+      scalez = (scalez - this->Range[0]) / den;
+      }
+    
+    // Compute index into table of glyphs
+    if ( this->IndexMode == VTK_INDEXING_OFF )
+      {
+      index = 0;
+      }
+    else 
+      {
+      if ( this->IndexMode == VTK_INDEXING_BY_SCALAR )
+        {
+        value = s;
+        }
+      else
+        {
+        value = vMag;
+        }
+      
+      index = (int) ((double)(value - this->Range[0]) * numberOfSources / den);
+      index = (index < 0 ? 0 :
+              (index >= numberOfSources ? (numberOfSources-1) : index));
+      
+      source = this->GetSource(index, inputVector[1]);
+      if ( source != NULL )
+        {
+        sourcePts = source->GetPoints();
+        sourceNormals = source->GetPointData()->GetNormals();
+        numSourcePts = sourcePts->GetNumberOfPoints();
+        numSourceCells = source->GetNumberOfCells();
+        }
+      }
+
+    // Make sure we're not indexing into empty glyph
+    if ( this->GetSource(index, inputVector[1]) == NULL )
+      {
+      continue;
+      }
+
+    // Check ghost points.
+    // If we are processing a piece, we do not want to duplicate 
+    // glyphs on the borders.  The corrct check here is:
+    // ghostLevel > 0.  I am leaving this over glyphing here because
+    // it make a nice example (sphereGhost.tcl) to show the 
+    // point ghost levels with the glyph filter.  I am not certain 
+    // of the usefullness of point ghost levels over 1, but I will have
+    // to think about it.
+    if (inGhostLevels && inGhostLevels[inPtId] > requestedGhostLevel)
+      {
+      continue;
+      }
+
+    if (!this->IsPointVisible(input, inPtId))
+      {
+      continue;
+      }
+    
+    // Now begin copying/transforming glyph
+    trans->Identity();
+    
+    // Copy all topology (transformation independent)
+    for (cellId=0; cellId < numSourceCells; cellId++)
+      {
+      cell = this->GetSource(index, inputVector[1])->GetCell(cellId);
+      cellPts = cell->GetPointIds();
+      npts = cellPts->GetNumberOfIds();
+      for (pts->Reset(), i=0; i < npts; i++) 
+        {
+        pts->InsertId(i,cellPts->GetId(i) + ptIncr);
+        }
+      output->InsertNextCell(cell->GetCellType(),pts);
+      }
+    
+    // translate Source to Input point
+    input->GetPoint(inPtId, x);
+    trans->Translate(x[0], x[1], x[2]);
+    
+    if ( haveVectors )
+      {
+      // Copy Input vector
+      for (i=0; i < numSourcePts; i++) 
+        {
+        newVectors->InsertTuple(i+ptIncr, v);
+        }
+      if (this->Orient && (vMag > 0.0))
+        {
+        // if there is no y or z component
+        if ( v[1] == 0.0 && v[2] == 0.0 )
+          {
+          if (v[0] < 0) //just flip x if we need to
+            {
+            trans->RotateWXYZ(180.0,0,1,0);
+            }
+          }
+        else
+          {
+          vNew[0] = (v[0]+vMag) / 2.0;
+          vNew[1] = v[1] / 2.0;
+          vNew[2] = v[2] / 2.0;
+          trans->RotateWXYZ((double)180.0,vNew[0],vNew[1],vNew[2]);
+          }
+        }
+      }
+    
+    if (haveTCoords)
+      {
+      for (i = 0; i < numSourcePts; i++)
+        {
+        sourceTCoords->GetTuple(i, tc);
+        newTCoords->InsertTuple(i+ptIncr, tc);
+        }
+      }
+    
+    // determine scale factor from scalars if appropriate
+    // Copy scalar value
+    if (inSScalars && (this->ColorMode == VTK_COLOR_BY_SCALE))
+      {
+      for (i=0; i < numSourcePts; i++)
+        {
+        newScalars->InsertTuple(i+ptIncr, &scalex); // = scaley = scalez
+        }
+      }
+    else if (inCScalars && (this->ColorMode == VTK_COLOR_BY_SCALAR))
+      {
+      for (i=0; i < numSourcePts; i++)
+        {
+        outputPD->CopyTuple(inCScalars, newScalars, inPtId, ptIncr+i);
+        }
+      }
+    if (haveVectors && this->ColorMode == VTK_COLOR_BY_VECTOR)
+      {
+      for (i=0; i < numSourcePts; i++) 
+        {
+        newScalars->InsertTuple(i+ptIncr, &vMag);
+        }
+      }
+    
+    // scale data if appropriate
+    if ( this->Scaling )
+      {
+      if ( this->ScaleMode == VTK_DATA_SCALING_OFF )
+        {
+        scalex = scaley = scalez = this->ScaleFactor;
+        }
+      else
+        {
+        scalex *= this->ScaleFactor;
+        scaley *= this->ScaleFactor;
+        scalez *= this->ScaleFactor;
+        }
+      
+      if ( scalex == 0.0 )
+        {
+        scalex = 1.0e-10;
+        }
+      if ( scaley == 0.0 )
+        {
+        scaley = 1.0e-10;
+        }
+      if ( scalez == 0.0 )
+        {
+        scalez = 1.0e-10;
+        }
+      trans->Scale(scalex,scaley,scalez);
+      }
+    
+    // multiply points and normals by resulting matrix
+    trans->TransformPoints(sourcePts,newPts);
+    
+    if ( haveNormals )
+      {
+      trans->TransformNormals(sourceNormals,newNormals);
+      }
+    
+    // Copy point data from source (if possible)
+    if ( pd ) 
+      {
+      for (i=0; i < numSourcePts; i++)
+        {
+        outputPD->CopyData(pd,inPtId,ptIncr+i);
+        }
+      if (this->FillCellData)
+        {
+        for (i=0; i < numSourceCells; i++)
+          {
+          outputCD->CopyData(pd,inPtId,cellIncr+i);
+          }
+        }
+      }
+
+    // If point ids are to be generated, do it here
+    if ( this->GeneratePointIds )
+      {
+      for (i=0; i < numSourcePts; i++)
+        {
+        pointIds->InsertNextValue(inPtId);
+        }
+      }
+
+    ptIncr += numSourcePts;
+    cellIncr += numSourceCells;
+    } 
+  
+  // Update ourselves and release memory
+  //
+  output->SetPoints(newPts);
+  newPts->Delete();
+
+  if (newScalars)
+    {
+    int idx = outputPD->AddArray(newScalars);
+    outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
+    newScalars->Delete();
+    }
+
+  if (newVectors)
+    {
+    outputPD->SetVectors(newVectors);
+    newVectors->Delete();
+    }
+
+  if (newNormals)
+    {
+    outputPD->SetNormals(newNormals);
+    newNormals->Delete();
+    }
+
+  if (newTCoords)
+    {
+    outputPD->SetTCoords(newTCoords);
+    newTCoords->Delete();
+    }
+  
+  output->Squeeze();
+  trans->Delete();
+  pts->Delete();
+
+  return 1;
+}
diff --git a/src/VTKViewer/VTKViewer_Glyph3D.h b/src/VTKViewer/VTKViewer_Glyph3D.h
new file mode 100644 (file)
index 0000000..77cc0b0
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef VTKVIEWER_GLYPH3D_H
+#define VTKVIEWER_GLYPH3D_H
+
+#include "VTKViewer.h"
+
+#include <vtkGlyph3d.h>
+
+class VTKVIEWER_EXPORT VTKViewer_Glyph3D : public vtkGlyph3D
+{
+public:
+  vtkTypeMacro(VTKViewer_Glyph3D,vtkGlyph3D);
+
+  // Description
+  // Construct object with scaling on, scaling mode is by scalar value,
+  // scale factor = 1.0, the range is (0,1), orient geometry is on, and
+  // orientation is by vector. Clamping and indexing are turned off. No
+  // initial sources are defined.
+  static VTKViewer_Glyph3D *New();
+
+  // Description:
+  // Enable/disable the generation of cell data as part of the output.
+  // The cell data at each cell will match the point data of the input
+  // at the glyphed point.
+  vtkSetMacro(FillCellData,int);
+  vtkGetMacro(FillCellData,int);
+  vtkBooleanMacro(FillCellData,int);
+
+protected:
+  VTKViewer_Glyph3D();
+  ~VTKViewer_Glyph3D();
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  //virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  //virtual int FillInputPortInformation(int, vtkInformation *);
+
+  int FillCellData; // whether to fill output cell data
+
+private:
+  VTKViewer_Glyph3D(const VTKViewer_Glyph3D&);  // Not implemented.
+  void operator=(const VTKViewer_Glyph3D&);  // Not implemented.
+};
+
+#endif