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

Last change on this file since 3106 was 3106, checked in by ldelgass, 12 years ago

Reduce warning/errors about missing scalar data in glyphs dataset to info debug
traces, since glyphs can be created with just a single vector field (color is
then taken from vector magnitude).

  • Property svn:eol-style set to native
File size: 25.4 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 <cstring>
9#include <cfloat>
10
11#include <vtkDataSet.h>
12#include <vtkPointData.h>
13#include <vtkCellData.h>
14#include <vtkCellDataToPointData.h>
15#include <vtkProp.h>
16#include <vtkActor.h>
17#include <vtkProperty.h>
18#include <vtkGlyph3D.h>
19#include <vtkLineSource.h>
20#include <vtkArrowSource.h>
21#include <vtkConeSource.h>
22#include <vtkCylinderSource.h>
23#include <vtkPlatonicSolidSource.h>
24#include <vtkSphereSource.h>
25#include <vtkTransform.h>
26#include <vtkPolyDataMapper.h>
27#include <vtkTransformPolyDataFilter.h>
28
29#include "RpGlyphs.h"
30#include "RpVtkRenderer.h"
31#include "Trace.h"
32
33using namespace Rappture::VtkVis;
34
35Glyphs::Glyphs(GlyphShape shape) :
36    VtkGraphicsObject(),
37    _glyphShape(shape),
38    _scalingMode(SCALE_BY_VECTOR_MAGNITUDE),
39    _dataScale(1.0),
40    _scaleFactor(1.0),
41    _normalizeScale(true),
42    _colorMap(NULL),
43    _colorMode(COLOR_BY_SCALAR)
44{
45    _faceCulling = true;
46    _scalingFieldRange[0] = DBL_MAX;
47    _scalingFieldRange[1] = -DBL_MAX;
48    _colorFieldRange[0] = DBL_MAX;
49    _colorFieldRange[1] = -DBL_MAX;
50}
51
52Glyphs::~Glyphs()
53{
54#ifdef WANT_TRACE
55    if (_dataSet != NULL)
56        TRACE("Deleting Glyphs for %s", _dataSet->getName().c_str());
57    else
58        TRACE("Deleting Glyphs with NULL DataSet");
59#endif
60}
61
62void Glyphs::setDataSet(DataSet *dataSet,
63                        Renderer *renderer)
64{
65    if (_dataSet != dataSet) {
66        _dataSet = dataSet;
67
68        _renderer = renderer;
69
70        if (renderer->getUseCumulativeRange()) {
71            renderer->getCumulativeDataRange(_dataRange,
72                                             _dataSet->getActiveScalarsName(),
73                                             1);
74            renderer->getCumulativeDataRange(_vectorMagnitudeRange,
75                                             _dataSet->getActiveVectorsName(),
76                                             3);
77            for (int i = 0; i < 3; i++) {
78                renderer->getCumulativeDataRange(_vectorComponentRange[i],
79                                                 _dataSet->getActiveVectorsName(),
80                                                 3, i);
81            }
82        } else {
83            _dataSet->getScalarRange(_dataRange);
84            _dataSet->getVectorRange(_vectorMagnitudeRange);
85            for (int i = 0; i < 3; i++) {
86                _dataSet->getVectorRange(_vectorComponentRange[i], i);
87            }
88        }
89
90        update();
91    }
92}
93
94/**
95 * \brief Set the shape of the glyphs
96 */
97void Glyphs::setGlyphShape(GlyphShape shape)
98{
99    _glyphShape = shape;
100
101    // Note: using vtkTransformPolyDataFilter instead of the vtkGlyph3D's
102    // SourceTransform because of a bug: vtkGlyph3D doesn't transform normals
103    // by the SourceTransform, so the lighting would be wrong
104
105    switch (_glyphShape) {
106    case LINE:
107        _glyphSource = vtkSmartPointer<vtkLineSource>::New();
108        break;
109    case ARROW: {
110        _glyphSource = vtkSmartPointer<vtkArrowSource>::New();
111        vtkSmartPointer<vtkArrowSource> arrow = vtkArrowSource::SafeDownCast(_glyphSource);
112        arrow->SetTipResolution(8);
113        arrow->SetShaftResolution(8);
114    }
115        break;
116    case CONE: {
117        _glyphSource = vtkSmartPointer<vtkConeSource>::New();
118        vtkSmartPointer<vtkConeSource> cone = vtkConeSource::SafeDownCast(_glyphSource);
119        cone->SetResolution(8);
120    }
121        break;
122    case CUBE:
123        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
124        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToCube();
125        break;
126    case CYLINDER: {
127        vtkSmartPointer<vtkCylinderSource> csource = vtkSmartPointer<vtkCylinderSource>::New();
128        csource->SetResolution(8);
129        _glyphSource = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
130        _glyphSource->SetInputConnection(csource->GetOutputPort());
131        vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
132        trans->RotateZ(-90.0);
133        vtkTransformPolyDataFilter::SafeDownCast(_glyphSource)->SetTransform(trans);
134      }
135        break;
136    case DODECAHEDRON:
137        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
138        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToDodecahedron();
139        break;
140    case ICOSAHEDRON:
141        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
142        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToIcosahedron();
143        break;
144    case OCTAHEDRON:
145        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
146        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToOctahedron();
147        break;
148    case SPHERE: {
149        _glyphSource = vtkSmartPointer<vtkSphereSource>::New();
150        vtkSmartPointer<vtkSphereSource> sphere = vtkSphereSource::SafeDownCast(_glyphSource);
151        sphere->SetThetaResolution(14);
152        sphere->SetPhiResolution(14);
153    }
154        break;
155    case TETRAHEDRON:
156        // FIXME: need to rotate inital orientation
157        _glyphSource = vtkSmartPointer<vtkPlatonicSolidSource>::New();
158        vtkPlatonicSolidSource::SafeDownCast(_glyphSource)->SetSolidTypeToTetrahedron();
159        break;
160    default:
161        ERROR("Unknown glyph shape: %d", _glyphShape);
162        return;
163    }
164
165    if (_glyphShape == ICOSAHEDRON ||
166        _glyphShape == TETRAHEDRON) {
167        // These shapes are created with front faces pointing inside
168        setCullFace(CULL_FRONT);
169    } else {
170        setCullFace(CULL_BACK);
171    }
172
173#ifdef HAVE_GLYPH3D_MAPPER
174    if (_glyphMapper != NULL) {
175        _glyphMapper->SetSourceConnection(_glyphSource->GetOutputPort());
176    }
177#else
178    if (_glyphGenerator != NULL) {
179        _glyphGenerator->SetSourceConnection(_glyphSource->GetOutputPort());
180    }
181#endif
182
183}
184
185/**
186 * \brief Internal method to set up pipeline after a state change
187 */
188void Glyphs::update()
189{
190    if (_dataSet == NULL) {
191        return;
192    }
193
194    vtkDataSet *ds = _dataSet->getVtkDataSet();
195
196#ifdef HAVE_GLYPH3D_MAPPER
197    if (_glyphMapper == NULL) {
198        _glyphMapper = vtkSmartPointer<vtkGlyph3DMapper>::New();
199        _glyphMapper->SetResolveCoincidentTopologyToPolygonOffset();
200        _glyphMapper->ScalarVisibilityOn();
201    }
202#else
203    if (_glyphGenerator == NULL) {
204        _glyphGenerator = vtkSmartPointer<vtkGlyph3D>::New();
205    }
206    if (_pdMapper == NULL) {
207        _pdMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
208        _pdMapper->SetResolveCoincidentTopologyToPolygonOffset();
209        _pdMapper->ScalarVisibilityOn();
210        _pdMapper->SetInputConnection(_glyphGenerator->GetOutputPort());
211    }
212#endif
213
214    initProp();
215
216    setGlyphShape(_glyphShape);
217
218    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
219
220    if (ds->GetPointData() == NULL ||
221        ds->GetPointData()->GetScalars() == NULL) {
222        if (ds->GetCellData() != NULL &&
223            ds->GetCellData()->GetScalars() != NULL) {
224            TRACE("Generating point data scalars from cell data for: %s", _dataSet->getName().c_str());
225            cellToPtData =
226                vtkSmartPointer<vtkCellDataToPointData>::New();
227            cellToPtData->SetInput(ds);
228            //cellToPtData->PassCellDataOn();
229            cellToPtData->Update();
230            ds = cellToPtData->GetOutput();
231        } else {
232            TRACE("No scalar data in dataset %s", _dataSet->getName().c_str());
233        }
234    }
235
236#ifdef HAVE_GLYPH3D_MAPPER
237    _glyphMapper->SetInputConnection(ds->GetProducerPort());
238#else
239    _glyphGenerator->SetInput(ds);
240#endif
241
242    if (ds->GetPointData()->GetVectors() != NULL) {
243        TRACE("Setting scale mode to vector magnitude");
244        setScalingMode(SCALE_BY_VECTOR_MAGNITUDE);
245    } else {
246        TRACE("Setting scale mode to scalar");
247        setScalingMode(SCALE_BY_SCALAR);
248    }
249
250    double cellSizeRange[2];
251    double avgSize;
252    _dataSet->getCellSizeRange(cellSizeRange, &avgSize);
253    //_dataScale = cellSizeRange[0] + (cellSizeRange[1] - cellSizeRange[0])/2.;
254    _dataScale = avgSize;
255
256    TRACE("Cell size range: %g,%g, Data scale factor: %g",
257          cellSizeRange[0], cellSizeRange[1], _dataScale);
258
259    // Normalize sizes to [0,1] * ScaleFactor
260#ifdef HAVE_GLYPH3D_MAPPER
261    _glyphMapper->SetClamping(_normalizeScale ? 1 : 0);
262    _glyphMapper->SetScaleFactor(_scaleFactor * _dataScale);
263    _glyphMapper->ScalingOn();
264#else
265    _glyphGenerator->SetClamping(_normalizeScale ? 1 : 0);
266    _glyphGenerator->SetScaleFactor(_scaleFactor * _dataScale);
267    _glyphGenerator->ScalingOn();
268#endif
269
270    if (_lut == NULL) {
271        setColorMap(ColorMap::getDefault());
272    }
273
274    if (ds->GetPointData()->GetScalars() == NULL) {
275        TRACE("Setting color mode to vector magnitude");
276        setColorMode(COLOR_BY_VECTOR_MAGNITUDE);
277    } else {
278        TRACE("Setting color mode to scalar");
279        setColorMode(COLOR_BY_SCALAR);
280    }
281
282#ifdef HAVE_GLYPH3D_MAPPER
283    getActor()->SetMapper(_glyphMapper);
284    _glyphMapper->Update();
285#else
286    getActor()->SetMapper(_pdMapper);
287    _pdMapper->Update();
288#endif
289}
290
291/**
292 * \brief Control if field data range is normalized to [0,1] before
293 * applying scale factor
294 */
295void Glyphs::setNormalizeScale(bool normalize)
296{
297    if (_normalizeScale != normalize) {
298        _normalizeScale = normalize;
299#ifdef HAVE_GLYPH3D_MAPPER
300        if (_glyphMapper != NULL) {
301            _glyphMapper->SetClamping(_normalizeScale ? 1 : 0);
302        }
303#else
304        if (_glyphGenerator != NULL) {
305            _glyphGenerator->SetClamping(_normalizeScale ? 1 : 0);
306        }
307#endif
308    }
309}
310
311#ifdef HAVE_GLYPH3D_MAPPER
312/**
313 * \brief Turn on/off orienting glyphs from a vector field
314 */
315void Glyphs::setOrientMode(bool mode, const char *name)
316{
317    if (_glyphMapper != NULL) {
318        _glyphMapper->SetOrient(mode ? 1 : 0);
319        if (name != NULL && strlen(name) > 0) {
320            _glyphMapper->SetOrientationArray(name);
321        } else {
322            _glyphMapper->SetOrientationArray(vtkDataSetAttributes::VECTORS);
323        }
324    }
325}
326
327/**
328 * \brief Control how glyphs are scaled
329 */
330void Glyphs::setScalingMode(ScalingMode mode, const char *name, double range[2])
331{
332    _scalingMode = mode;
333
334    if (_dataSet == NULL || _glyphMapper == NULL)
335        return;
336
337    if (name != NULL && strlen(name) > 0) {
338        if (!_dataSet->hasField(name, DataSet::POINT_DATA)) {
339            ERROR("Field not found: %s", name);
340            return;
341        }
342        _scalingFieldName = name;
343    } else
344        _scalingFieldName.clear();
345    if (range == NULL) {
346        _scalingFieldRange[0] = DBL_MAX;
347        _scalingFieldRange[1] = -DBL_MAX;
348    } else {
349        memcpy(_scalingFieldRange, range, sizeof(double)*2);
350    }
351
352    if (name != NULL && strlen(name) > 0) {
353        _glyphMapper->SetScaleArray(name);
354    } else {
355        if (mode == SCALE_BY_SCALAR) {
356            _glyphMapper->SetScaleArray(vtkDataSetAttributes::SCALARS);
357        } else {
358            _glyphMapper->SetScaleArray(vtkDataSetAttributes::VECTORS);
359        }
360    }
361
362    if (range != NULL) {
363        TRACE("Setting size range to: %g,%g", range[0], range[1]);
364        _glyphMapper->SetRange(range);
365    } else if (name != NULL && strlen(name) > 0) {
366        double r[2];
367        DataSet::DataAttributeType type = DataSet::POINT_DATA;
368        int comp = -1;
369
370        if (_renderer->getUseCumulativeRange()) {
371            int numComponents;
372            if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
373                ERROR("Field not found: %s, type: %d", name, type);
374                return;
375            } else if (mode == SCALE_BY_VECTOR_COMPONENTS && numComponents < 3) {
376                ERROR("Field %s needs 3 components but has only %d components",
377                      name, numComponents);
378                return;
379            }
380            if (mode == SCALE_BY_VECTOR_COMPONENTS) {
381                double tmpR[2];
382                _renderer->getCumulativeDataRange(tmpR, name, type, numComponents, 0);
383                r[0] = tmpR[0];
384                r[1] = tmpR[1];
385                _renderer->getCumulativeDataRange(tmpR, name, type, numComponents, 1);
386                r[0] = min2(r[0], tmpR[0]);
387                r[1] = max2(r[1], tmpR[1]);
388                _renderer->getCumulativeDataRange(tmpR, name, type, numComponents, 2);
389                r[0] = min2(r[0], tmpR[0]);
390                r[1] = max2(r[1], tmpR[1]);
391            } else {
392                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
393            }
394        } else {
395            if (mode == SCALE_BY_VECTOR_COMPONENTS) {
396                double tmpR[2];
397                _dataSet->getDataRange(tmpR, name, type, 0);
398                r[0] = tmpR[0];
399                r[1] = tmpR[1];
400                _dataSet->getDataRange(tmpR, name, type, 1);
401                r[0] = min2(r[0], tmpR[0]);
402                r[1] = max2(r[1], tmpR[1]);
403                _dataSet->getDataRange(tmpR, name, type, 2);
404                r[0] = min2(r[0], tmpR[0]);
405                r[1] = max2(r[1], tmpR[1]);
406            } else {
407                _dataSet->getDataRange(r, name, type, comp);
408            }
409        }
410        TRACE("Setting size range to: %g,%g", r[0], r[1]);
411        _glyphMapper->SetRange(r);
412    } else {
413        switch (mode) {
414        case SCALE_BY_SCALAR:
415            TRACE("Setting size range to: %g,%g", _dataRange[0], _dataRange[1]);
416            _glyphMapper->SetRange(_dataRange);
417            break;
418        case SCALE_BY_VECTOR_MAGNITUDE:
419            TRACE("Setting size range to: %g,%g", _vectorMagnitudeRange[0], _vectorMagnitudeRange[1]);
420            _glyphMapper->SetRange(_vectorMagnitudeRange);
421            break;
422        case SCALE_BY_VECTOR_COMPONENTS: {
423            double sizeRange[2];
424            sizeRange[0] = _vectorComponentRange[0][0];
425            sizeRange[1] = _vectorComponentRange[0][1];
426            sizeRange[0] = min2(sizeRange[0], _vectorComponentRange[1][0]);
427            sizeRange[1] = max2(sizeRange[1], _vectorComponentRange[1][1]);
428            sizeRange[0] = min2(sizeRange[0], _vectorComponentRange[2][0]);
429            sizeRange[1] = max2(sizeRange[1], _vectorComponentRange[2][1]);
430            TRACE("Setting size range to: %g,%g", sizeRange[0], sizeRange[1]);
431            _glyphMapper->SetRange(sizeRange);
432        }
433            break;
434        case SCALING_OFF:
435        default:
436            ;
437        }
438    }
439
440    switch (mode) {
441    case SCALE_BY_SCALAR:
442    case SCALE_BY_VECTOR_MAGNITUDE:
443        _glyphMapper->SetScaleModeToScaleByMagnitude();
444        break;
445    case SCALE_BY_VECTOR_COMPONENTS:
446        _glyphMapper->SetScaleModeToScaleByVectorComponents();
447        break;
448    case SCALING_OFF:
449    default:
450        _glyphMapper->SetScaleModeToNoDataScaling();
451    }
452}
453
454void Glyphs::setScalingMode(ScalingMode mode)
455{
456    setScalingMode(mode, NULL, NULL);
457}
458
459void Glyphs::setColorMode(ColorMode mode,
460                          const char *name, double range[2])
461{
462    _colorMode = mode;
463    if (name == NULL)
464        _colorFieldName.clear();
465    else
466        _colorFieldName = name;
467    if (range == NULL) {
468        _colorFieldRange[0] = DBL_MAX;
469        _colorFieldRange[1] = -DBL_MAX;
470    } else {
471        memcpy(_colorFieldRange, range, sizeof(double)*2);
472    }
473
474    if (_dataSet == NULL || _glyphMapper == NULL)
475        return;
476
477    if (name != NULL && strlen(name) > 0) {
478        _glyphMapper->SetScalarModeToUsePointFieldData();
479        _glyphMapper->SelectColorArray(name);
480    } else {
481        _glyphMapper->SetScalarModeToDefault();
482    }
483
484    if (_lut != NULL) {
485        if (range != NULL) {
486            _lut->SetRange(range);
487        } else if (name != NULL && strlen(name) > 0) {
488            double r[2];
489            int comp = -1;
490            if (mode == COLOR_BY_VECTOR_X)
491                comp = 0;
492            else if (mode == COLOR_BY_VECTOR_Y)
493                comp = 1;
494            else if (mode == COLOR_BY_VECTOR_Z)
495                comp = 2;
496
497            DataSet::DataAttributeType type = DataSet::POINT_DATA;
498
499            if (_renderer->getUseCumulativeRange()) {
500                int numComponents;
501                if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
502                    ERROR("Field not found: %s, type: %d", name, type);
503                    return;
504                } else if (numComponents < comp+1) {
505                    ERROR("Request for component %d in field with %d components",
506                          comp, numComponents);
507                    return;
508                }
509                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
510            } else {
511                _dataSet->getDataRange(r, name, type, comp);
512            }
513            TRACE("Setting lut range to: %g,%g", r[0], r[1]);
514            _lut->SetRange(r);
515        }
516    }
517
518    switch (mode) {
519    case COLOR_BY_SCALAR:
520        _glyphMapper->ScalarVisibilityOn();
521        break;
522    case COLOR_BY_VECTOR_MAGNITUDE:
523        _glyphMapper->ScalarVisibilityOn();
524        if (_lut != NULL) {
525            _lut->SetVectorModeToMagnitude();
526        }
527        break;
528    case COLOR_BY_VECTOR_X:
529        _glyphMapper->ScalarVisibilityOn();
530        if (_lut != NULL) {
531            _lut->SetVectorModeToComponent();
532            _lut->SetVectorComponent(0);
533        }
534        break;
535    case COLOR_BY_VECTOR_Y:
536        _glyphMapper->ScalarVisibilityOn();
537        if (_lut != NULL) {
538            _lut->SetVectorModeToComponent();
539            _lut->SetVectorComponent(1);
540        }
541        break;
542    case COLOR_BY_VECTOR_Z:
543        _glyphMapper->ScalarVisibilityOn();
544        if (_lut != NULL) {
545            _lut->SetVectorModeToComponent();
546            _lut->SetVectorComponent(2);
547        }
548        break;
549    case COLOR_CONSTANT:
550    default:
551        _glyphMapper->ScalarVisibilityOff();
552        break;
553    }
554}
555
556void Glyphs::setColorMode(ColorMode mode)
557{
558    _colorMode = mode;
559    if (_dataSet == NULL)
560        return;
561
562    switch (mode) {
563    case COLOR_BY_SCALAR:
564        setColorMode(mode,
565                     _dataSet->getActiveScalarsName(),
566                     _dataRange);
567        break;
568    case COLOR_BY_VECTOR_MAGNITUDE:
569        setColorMode(mode,
570                     _dataSet->getActiveVectorsName(),
571                     _vectorMagnitudeRange);
572        break;
573    case COLOR_BY_VECTOR_X:
574        setColorMode(mode,
575                     _dataSet->getActiveVectorsName(),
576                     _vectorComponentRange[0]);
577        break;
578    case COLOR_BY_VECTOR_Y:
579        setColorMode(mode,
580                     _dataSet->getActiveVectorsName(),
581                     _vectorComponentRange[1]);
582        break;
583    case COLOR_BY_VECTOR_Z:
584        setColorMode(mode,
585                     _dataSet->getActiveVectorsName(),
586                     _vectorComponentRange[2]);
587        break;
588    case COLOR_CONSTANT:
589    default:
590        setColorMode(mode, NULL, NULL);
591        break;
592    }
593}
594
595#else
596
597/**
598 * \brief Control how glyphs are scaled
599 */
600void Glyphs::setScalingMode(ScalingMode mode)
601{
602    _scalingMode = mode;
603    if (_glyphGenerator != NULL) {
604        switch (mode) {
605        case SCALE_BY_SCALAR:
606            _glyphGenerator->SetRange(_dataRange);
607            _glyphGenerator->SetScaleModeToScaleByScalar();
608            break;
609        case SCALE_BY_VECTOR_MAGNITUDE:
610            _glyphGenerator->SetRange(_vectorMagnitudeRange);
611            _glyphGenerator->SetScaleModeToScaleByVector();
612            break;
613        case SCALE_BY_VECTOR_COMPONENTS: {
614            double sizeRange[2];
615            sizeRange[0] = _vectorComponentRange[0][0];
616            sizeRange[1] = _vectorComponentRange[0][1];
617            sizeRange[0] = min2(sizeRange[0], _vectorComponentRange[1][0]);
618            sizeRange[1] = max2(sizeRange[1], _vectorComponentRange[1][1]);
619            sizeRange[0] = min2(sizeRange[0], _vectorComponentRange[2][0]);
620            sizeRange[1] = max2(sizeRange[1], _vectorComponentRange[2][1]);
621            _glyphGenerator->SetRange(sizeRange);
622            _glyphGenerator->SetScaleModeToScaleByVectorComponents();
623        }
624            break;
625        case SCALING_OFF:
626        default:
627            _glyphGenerator->SetScaleModeToDataScalingOff();
628        }
629    }
630}
631
632/**
633 * \brief Control how glyphs are colored
634 */
635void Glyphs::setColorMode(ColorMode mode)
636{
637    _colorMode = mode;
638    if (_glyphGenerator != NULL) {
639        switch (mode) {
640        case COLOR_BY_VECTOR_MAGNITUDE:
641            _glyphGenerator->SetColorModeToColorByVector();
642            _pdMapper->ScalarVisibilityOn();
643            if (_lut != NULL) {
644                _lut->SetVectorModeToMagnitude();
645                _lut->SetRange(_vectorMagnitudeRange);
646            }
647            break;
648        case COLOR_BY_SCALAR:
649            _glyphGenerator->SetColorModeToColorByScalar();
650            _pdMapper->ScalarVisibilityOn();
651            if (_lut != NULL) {
652                _lut->SetRange(_dataRange);
653            }
654            break;
655        case COLOR_CONSTANT:
656            _pdMapper->ScalarVisibilityOff();
657            break;
658        default:
659            ERROR("Unsupported ColorMode: %d", mode);
660        }
661    }
662}
663
664#endif
665
666/**
667 * \brief Turn on/off orienting glyphs from a vector field
668 */
669void Glyphs::setOrient(bool state)
670{
671#ifdef HAVE_GLYPH3D_MAPPER
672    if (_glyphMapper != NULL) {
673        _glyphMapper->SetOrient(state ? 1 : 0);
674    }
675#else
676    if (_glyphGenerator != NULL) {
677        _glyphGenerator->SetOrient(state ? 1 : 0);
678    }
679#endif
680}
681
682/**
683 * \brief Controls relative scaling of glyphs
684 */
685void Glyphs::setScaleFactor(double scale)
686{
687    _scaleFactor = scale;
688#ifdef HAVE_GLYPH3D_MAPPER
689    if (_glyphMapper != NULL) {
690        _glyphMapper->SetScaleFactor(_scaleFactor * _dataScale);
691    }
692#else
693    if (_glyphGenerator != NULL) {
694        _glyphGenerator->SetScaleFactor(_scaleFactor * _dataScale);
695    }
696#endif
697}
698
699void Glyphs::updateRanges(Renderer *renderer)
700{
701    if (_dataSet == NULL) {
702        ERROR("called before setDataSet");
703        return;
704    }
705
706    if (renderer->getUseCumulativeRange()) {
707        renderer->getCumulativeDataRange(_dataRange,
708                                         _dataSet->getActiveScalarsName(),
709                                         1);
710        renderer->getCumulativeDataRange(_vectorMagnitudeRange,
711                                         _dataSet->getActiveVectorsName(),
712                                         3);
713        for (int i = 0; i < 3; i++) {
714            renderer->getCumulativeDataRange(_vectorComponentRange[i],
715                                             _dataSet->getActiveVectorsName(),
716                                             3, i);
717        }
718    } else {
719        _dataSet->getScalarRange(_dataRange);
720        _dataSet->getVectorRange(_vectorMagnitudeRange);
721        for (int i = 0; i < 3; i++) {
722            _dataSet->getVectorRange(_vectorComponentRange[i], i);
723        }
724    }
725
726    // Need to update color map ranges and/or active vector field
727#ifdef HAVE_GLYPH3D_MAPPER
728    double *rangePtr = _colorFieldRange;
729    if (_colorFieldRange[0] > _colorFieldRange[1]) {
730        rangePtr = NULL;
731    }
732    setColorMode(_colorMode, _colorFieldName.c_str(), rangePtr);
733
734    rangePtr = _scalingFieldRange;
735    if (_scalingFieldRange[0] > _scalingFieldRange[1]) {
736        rangePtr = NULL;
737    }
738    setScalingMode(_scalingMode, _scalingFieldName.c_str(), rangePtr);
739#else
740    setColorMode(_colorMode);
741    setScalingMode(_scalingMode);
742#endif
743}
744
745/**
746 * \brief Called when the color map has been edited
747 */
748void Glyphs::updateColorMap()
749{
750    setColorMap(_colorMap);
751}
752
753/**
754 * \brief Associate a colormap lookup table with the DataSet
755 */
756void Glyphs::setColorMap(ColorMap *cmap)
757{
758    if (cmap == NULL)
759        return;
760
761    _colorMap = cmap;
762 
763    if (_lut == NULL) {
764        _lut = vtkSmartPointer<vtkLookupTable>::New();
765#ifdef HAVE_GLYPH3D_MAPPER
766        if (_glyphMapper != NULL) {
767            _glyphMapper->UseLookupTableScalarRangeOn();
768            _glyphMapper->SetLookupTable(_lut);
769        }
770#else
771        if (_pdMapper != NULL) {
772            _pdMapper->UseLookupTableScalarRangeOn();
773            _pdMapper->SetLookupTable(_lut);
774        }
775#endif
776        _lut->DeepCopy(cmap->getLookupTable());
777        switch (_colorMode) {
778        case COLOR_CONSTANT:
779        case COLOR_BY_SCALAR:
780            _lut->SetRange(_dataRange);
781            break;
782        case COLOR_BY_VECTOR_MAGNITUDE:
783            _lut->SetRange(_vectorMagnitudeRange);
784            break;
785        case COLOR_BY_VECTOR_X:
786            _lut->SetRange(_vectorComponentRange[0]);
787            break;
788        case COLOR_BY_VECTOR_Y:
789            _lut->SetRange(_vectorComponentRange[1]);
790            break;
791        case COLOR_BY_VECTOR_Z:
792            _lut->SetRange(_vectorComponentRange[2]);
793            break;
794        default:
795            break;
796        }
797    } else {
798        double range[2];
799        _lut->GetTableRange(range);
800        _lut->DeepCopy(cmap->getLookupTable());
801        _lut->SetRange(range);
802    }
803
804    switch (_colorMode) {
805    case COLOR_BY_VECTOR_MAGNITUDE:
806        _lut->SetVectorModeToMagnitude();
807        break;
808    case COLOR_BY_VECTOR_X:
809        _lut->SetVectorModeToComponent();
810        _lut->SetVectorComponent(0);
811        break;
812    case COLOR_BY_VECTOR_Y:
813        _lut->SetVectorModeToComponent();
814        _lut->SetVectorComponent(1);
815        break;
816    case COLOR_BY_VECTOR_Z:
817        _lut->SetVectorModeToComponent();
818        _lut->SetVectorComponent(2);
819        break;
820    default:
821        break;
822    }
823}
824
825/**
826 * \brief Set a group of world coordinate planes to clip rendering
827 *
828 * Passing NULL for planes will remove all cliping planes
829 */
830void Glyphs::setClippingPlanes(vtkPlaneCollection *planes)
831{
832#ifdef HAVE_GLYPH3D_MAPPER
833    if (_glyphMapper != NULL) {
834        _glyphMapper->SetClippingPlanes(planes);
835    }
836#else
837    if (_pdMapper != NULL) {
838        _pdMapper->SetClippingPlanes(planes);
839    }
840#endif
841}
Note: See TracBrowser for help on using the repository browser.