source: trunk/packages/vizservers/vtkvis/RpGlyphs.cpp @ 2290

Last change on this file since 2290 was 2290, checked in by ldelgass, 13 years ago
  • Add contour3d (isosurface geometry) command to vtkvis
  • Use depth peeling algorithm (order independent transparency) by default, add 'renderer depthpeel' command to toggle.
  • Use tri strips in some geometry generators for better performance
  • Heightmap: 2D slice resampling of non-image 3D datasets (e.g. points, ugrids) Set a default scaling based on data range. Still some problems where images from resampling have zero values in out-of-bounds pixels (probe filter creates a mask array that could be used). Still need a method/heuristic to select image resolution when resampling.
  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2011, Purdue Research Foundation
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <vtkDataSet.h>
9#include <vtkPointData.h>
10#include <vtkCellData.h>
11#include <vtkCellDataToPointData.h>
12#include <vtkProp.h>
13#include <vtkActor.h>
14#include <vtkProperty.h>
15#include <vtkGlyph3D.h>
16#include <vtkArrowSource.h>
17#include <vtkConeSource.h>
18#include <vtkCylinderSource.h>
19#include <vtkPlatonicSolidSource.h>
20#include <vtkSphereSource.h>
21#include <vtkPolyDataMapper.h>
22
23#include "RpGlyphs.h"
24#include "Trace.h"
25
26using namespace Rappture::VtkVis;
27
28Glyphs::Glyphs() :
29    _dataSet(NULL),
30    _opacity(1.0),
31    _lighting(true),
32    _glyphShape(ARROW),
33    _scaleFactor(1.0)
34{
35}
36
37Glyphs::~Glyphs()
38{
39}
40
41/**
42 * \brief Get the VTK Prop for the Glyphs
43 */
44vtkProp *Glyphs::getProp()
45{
46    return _prop;
47}
48
49/**
50 * \brief Create and initialize a VTK Prop to render Glyphs
51 */
52void Glyphs::initProp()
53{
54    if (_prop == NULL) {
55        _prop = vtkSmartPointer<vtkActor>::New();
56        _prop->GetProperty()->EdgeVisibilityOff();
57        _prop->GetProperty()->SetOpacity(_opacity);
58        if (!_lighting)
59            _prop->GetProperty()->LightingOff();
60    }
61}
62
63/**
64 * \brief Specify input DataSet
65 *
66 * The DataSet must be a PolyData point set
67 * with vectors and/or scalars
68 */
69void Glyphs::setDataSet(DataSet *dataSet)
70{
71    if (_dataSet != dataSet) {
72        _dataSet = dataSet;
73        update();
74    }
75}
76
77/**
78 * \brief Returns the DataSet this Glyphs renders
79 */
80DataSet *Glyphs::getDataSet()
81{
82    return _dataSet;
83}
84
85/**
86 * \brief Set the shape of the glyphs
87 */
88void Glyphs::setGlyphShape(GlyphShape shape)
89{
90    _glyphShape = shape;
91    switch (_glyphShape) {
92    case ARROW:
93        _glyphSource = vtkSmartPointer<vtkArrowSource>::New();
94        break;
95    case CONE:
96        _glyphSource = vtkSmartPointer<vtkConeSource>::New();
97        break;
98    case CUBE:
99        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
100        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToCube();
101        break;
102    case CYLINDER:
103        _glyphSource = vtkSmartPointer<vtkCylinderSource>::New();
104        break;
105    case DODECAHEDRON:
106        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
107        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToDodecahedron();
108        break;
109    case ICOSAHEDRON:
110        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
111        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToIcosahedron();
112        break;
113    case OCTAHEDRON:
114        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
115        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToOctahedron();
116        break;
117    case SPHERE:
118        _glyphSource = vtkSmartPointer<vtkSphereSource>::New();
119        break;
120    case TETRAHEDRON:
121        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
122        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToTetrahedron();
123        break;
124    default:
125        ERROR("Unknown glyph shape: %d", _glyphShape);
126        return;
127    }
128    if (_glyphGenerator != NULL) {
129        _glyphGenerator->SetSourceConnection(_glyphSource->GetOutputPort());
130    }
131}
132
133void Glyphs::update()
134{
135    if (_dataSet == NULL) {
136        return;
137    }
138
139    vtkDataSet *ds = _dataSet->getVtkDataSet();
140    double dataRange[2];
141    _dataSet->getDataRange(dataRange);
142
143    if (_glyphGenerator == NULL) {
144        _glyphGenerator = vtkSmartPointer<vtkGlyph3D>::New();
145    }
146
147    setGlyphShape(_glyphShape);
148
149    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
150
151    if (ds->GetPointData() == NULL ||
152        ds->GetPointData()->GetScalars() == NULL) {
153        WARN("No scalar point data in dataset %s", _dataSet->getName().c_str());
154        if (ds->GetCellData() != NULL &&
155            ds->GetCellData()->GetScalars() != NULL) {
156            cellToPtData =
157                vtkSmartPointer<vtkCellDataToPointData>::New();
158            cellToPtData->SetInput(ds);
159            //cellToPtData->PassCellDataOn();
160            cellToPtData->Update();
161            ds = cellToPtData->GetOutput();
162        } else {
163            ERROR("No scalar cell data in dataset %s", _dataSet->getName().c_str());
164        }
165    }
166
167    _glyphGenerator->SetInput(ds);
168    if (ds->GetPointData()->GetVectors() != NULL) {
169        _glyphGenerator->SetScaleModeToScaleByVector();
170    } else {
171        _glyphGenerator->SetScaleModeToScaleByScalar();
172    }
173    _glyphGenerator->SetScaleFactor(_scaleFactor);
174    _glyphGenerator->ScalingOn();
175    _glyphGenerator->SetColorModeToColorByScalar();
176    if (_glyphShape == SPHERE) {
177        _glyphGenerator->OrientOff();
178    }
179
180    if (_pdMapper == NULL) {
181        _pdMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
182        _pdMapper->SetResolveCoincidentTopologyToPolygonOffset();
183        _pdMapper->ScalarVisibilityOn();
184    }
185
186    _pdMapper->SetInputConnection(_glyphGenerator->GetOutputPort());
187
188    if (ds->GetPointData() == NULL ||
189        ds->GetPointData()->GetScalars() == NULL) {
190        if (_lut == NULL) {
191            _lut = vtkSmartPointer<vtkLookupTable>::New();
192        }
193    } else {
194        vtkLookupTable *lut = ds->GetPointData()->GetScalars()->GetLookupTable();
195        TRACE("Data set scalars lookup table: %p\n", lut);
196        if (_lut == NULL) {
197            if (lut)
198                _lut = lut;
199            else
200                _lut = vtkSmartPointer<vtkLookupTable>::New();
201        }
202    }
203
204    _lut->SetRange(dataRange);
205
206    _pdMapper->UseLookupTableScalarRangeOn();
207    _pdMapper->SetLookupTable(_lut);
208
209    initProp();
210
211    _prop->SetMapper(_pdMapper);
212    _pdMapper->Update();
213}
214
215void Glyphs::setScaleFactor(double scale)
216{
217    _scaleFactor = scale;
218    if (_glyphGenerator != NULL) {
219        _glyphGenerator->SetScaleFactor(scale);
220    }
221}
222
223/**
224 * \brief Get the VTK colormap lookup table in use
225 */
226vtkLookupTable *Glyphs::getLookupTable()
227{
228    return _lut;
229}
230
231/**
232 * \brief Associate a colormap lookup table with the DataSet
233 */
234void Glyphs::setLookupTable(vtkLookupTable *lut)
235{
236    if (lut == NULL) {
237        _lut = vtkSmartPointer<vtkLookupTable>::New();
238    } else {
239        _lut = lut;
240    }
241
242    if (_pdMapper != NULL) {
243        _pdMapper->UseLookupTableScalarRangeOn();
244        _pdMapper->SetLookupTable(_lut);
245    }
246}
247
248/**
249 * \brief Turn on/off rendering of this Glyphs
250 */
251void Glyphs::setVisibility(bool state)
252{
253    if (_prop != NULL) {
254        _prop->SetVisibility((state ? 1 : 0));
255    }
256}
257
258/**
259 * \brief Get visibility state of the Glyphs
260 *
261 * \return Are the glyphs visible?
262 */
263bool Glyphs::getVisibility()
264{
265    if (_prop == NULL) {
266        return false;
267    } else {
268        return (_prop->GetVisibility() != 0);
269    }
270}
271
272/**
273 * \brief Set opacity used to render the Glyphs
274 */
275void Glyphs::setOpacity(double opacity)
276{
277    _opacity = opacity;
278    if (_prop != NULL)
279        _prop->GetProperty()->SetOpacity(opacity);
280}
281
282/**
283 * \brief Get opacity used to render the Glyphs
284 */
285double Glyphs::getOpacity()
286{
287    return _opacity;
288}
289
290/**
291 * \brief Set a group of world coordinate planes to clip rendering
292 *
293 * Passing NULL for planes will remove all cliping planes
294 */
295void Glyphs::setClippingPlanes(vtkPlaneCollection *planes)
296{
297    if (_pdMapper != NULL) {
298        _pdMapper->SetClippingPlanes(planes);
299    }
300}
301
302/**
303 * \brief Turn on/off lighting of this object
304 */
305void Glyphs::setLighting(bool state)
306{
307    _lighting = state;
308    if (_prop != NULL)
309        _prop->GetProperty()->SetLighting((state ? 1 : 0));
310}
Note: See TracBrowser for help on using the repository browser.