source: trunk/packages/vizservers/vtkvis/Glyphs.cpp @ 3616

Last change on this file since 3616 was 3616, checked in by ldelgass, 11 years ago

Remove Rp from vtkvis filenames

  • Property svn:eol-style set to native
File size: 23.0 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2012  HUBzero Foundation, LLC
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 "Glyphs.h"
30#include "VtkRenderer.h"
31#include "Trace.h"
32
33using namespace 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    if (_glyphMapper != NULL) {
174        _glyphMapper->SetSourceConnection(_glyphSource->GetOutputPort());
175    }
176
177    //setQuality(0.8);
178}
179
180void Glyphs::setQuality(double quality)
181{
182    switch (_glyphShape) {
183    case ARROW: {
184        vtkSmartPointer<vtkArrowSource> arrow = vtkArrowSource::SafeDownCast(_glyphSource);
185        int res = (int)(quality * 25);
186        if (res < 5) res = 5;
187        arrow->SetTipResolution(res);
188        arrow->SetShaftResolution(res);
189    }
190        break;
191    case CONE: {
192        vtkSmartPointer<vtkConeSource> cone = vtkConeSource::SafeDownCast(_glyphSource);
193        int res = (int)(quality * 25);
194        if (res < 5) res = 5;
195        cone->SetResolution(res);
196    }
197        break;
198    case SPHERE: {
199        vtkSmartPointer<vtkSphereSource> sphere = vtkSphereSource::SafeDownCast(_glyphSource);
200        int res = (int)(quality * 50);
201        if (res < 5) res = 5;
202        sphere->SetThetaResolution(res);
203        sphere->SetPhiResolution(res);
204    }
205        break;
206    case CYLINDER: {
207        assert(vtkTransformPolyDataFilter::SafeDownCast(_glyphSource) != NULL);
208        assert(vtkTransformPolyDataFilter::SafeDownCast(_glyphSource)->GetInputConnection(0, 0) != NULL);
209        vtkSmartPointer<vtkCylinderSource> csource = vtkCylinderSource::SafeDownCast(vtkTransformPolyDataFilter::SafeDownCast(_glyphSource)->GetInputConnection(0, 0));
210        int res = (int)(quality * 25);
211        if (res < 5) res = 5;
212        csource->SetResolution(res);
213    }
214        break;
215    default:
216        break;
217    }
218}
219
220/**
221 * \brief Internal method to set up pipeline after a state change
222 */
223void Glyphs::update()
224{
225    if (_dataSet == NULL) {
226        return;
227    }
228
229    vtkDataSet *ds = _dataSet->getVtkDataSet();
230
231    if (_glyphMapper == NULL) {
232        _glyphMapper = vtkSmartPointer<vtkGlyph3DMapper>::New();
233        _glyphMapper->SetResolveCoincidentTopologyToPolygonOffset();
234        _glyphMapper->ScalarVisibilityOn();
235    }
236
237    initProp();
238
239    setGlyphShape(_glyphShape);
240
241    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
242
243    if (ds->GetPointData() == NULL ||
244        ds->GetPointData()->GetScalars() == NULL) {
245        if (ds->GetCellData() != NULL &&
246            ds->GetCellData()->GetScalars() != NULL) {
247            TRACE("Generating point data scalars from cell data for: %s", _dataSet->getName().c_str());
248            cellToPtData =
249                vtkSmartPointer<vtkCellDataToPointData>::New();
250#ifdef USE_VTK6
251            cellToPtData->SetInputData(ds);
252#else
253            cellToPtData->SetInput(ds);
254#endif
255            //cellToPtData->PassCellDataOn();
256            cellToPtData->Update();
257            ds = cellToPtData->GetOutput();
258        } else {
259            TRACE("No scalar data in dataset %s", _dataSet->getName().c_str());
260        }
261    }
262
263#ifdef USE_VTK6
264    _glyphMapper->SetInputData(ds);
265#else
266    _glyphMapper->SetInputConnection(ds->GetProducerPort());
267#endif
268
269    if (ds->GetPointData()->GetVectors() != NULL) {
270        TRACE("Setting scale mode to vector magnitude");
271        setScalingMode(SCALE_BY_VECTOR_MAGNITUDE);
272    } else {
273        TRACE("Setting scale mode to scalar");
274        setScalingMode(SCALE_BY_SCALAR);
275    }
276
277    double cellSizeRange[2];
278    double avgSize;
279    _dataSet->getCellSizeRange(cellSizeRange, &avgSize);
280    //_dataScale = cellSizeRange[0] + (cellSizeRange[1] - cellSizeRange[0])/2.;
281    _dataScale = avgSize;
282
283    TRACE("Cell size range: %g,%g, Data scale factor: %g",
284          cellSizeRange[0], cellSizeRange[1], _dataScale);
285
286    // Normalize sizes to [0,1] * ScaleFactor
287    _glyphMapper->SetClamping(_normalizeScale ? 1 : 0);
288    _glyphMapper->SetScaleFactor(_scaleFactor * _dataScale);
289    _glyphMapper->ScalingOn();
290
291    if (_lut == NULL) {
292        setColorMap(ColorMap::getDefault());
293    }
294
295    if (ds->GetPointData()->GetScalars() == NULL) {
296        TRACE("Setting color mode to vector magnitude");
297        setColorMode(COLOR_BY_VECTOR_MAGNITUDE);
298    } else {
299        TRACE("Setting color mode to scalar");
300        setColorMode(COLOR_BY_SCALAR);
301    }
302
303    getActor()->SetMapper(_glyphMapper);
304    _glyphMapper->Update();
305}
306
307/**
308 * \brief Control if field data range is normalized to [0,1] before
309 * applying scale factor
310 */
311void Glyphs::setNormalizeScale(bool normalize)
312{
313    if (_normalizeScale != normalize) {
314        _normalizeScale = normalize;
315        if (_glyphMapper != NULL) {
316            _glyphMapper->SetClamping(_normalizeScale ? 1 : 0);
317        }
318    }
319}
320
321/**
322 * \brief Turn on/off orienting glyphs from a vector field
323 */
324void Glyphs::setOrientMode(bool mode, const char *name)
325{
326    if (_glyphMapper != NULL) {
327        _glyphMapper->SetOrient(mode ? 1 : 0);
328        if (name != NULL && strlen(name) > 0) {
329            _glyphMapper->SetOrientationArray(name);
330        } else {
331            _glyphMapper->SetOrientationArray(vtkDataSetAttributes::VECTORS);
332        }
333    }
334}
335
336/**
337 * \brief Control how glyphs are scaled
338 */
339void Glyphs::setScalingMode(ScalingMode mode, const char *name, double range[2])
340{
341    _scalingMode = mode;
342
343    if (_dataSet == NULL || _glyphMapper == NULL)
344        return;
345
346    if (name != NULL && strlen(name) > 0) {
347        if (!_dataSet->hasField(name, DataSet::POINT_DATA)) {
348            ERROR("Field not found: %s", name);
349            return;
350        }
351        _scalingFieldName = name;
352    } else
353        _scalingFieldName.clear();
354    if (range == NULL) {
355        _scalingFieldRange[0] = DBL_MAX;
356        _scalingFieldRange[1] = -DBL_MAX;
357    } else {
358        memcpy(_scalingFieldRange, range, sizeof(double)*2);
359    }
360
361    if (name != NULL && strlen(name) > 0) {
362        _glyphMapper->SetScaleArray(name);
363    } else {
364        if (mode == SCALE_BY_SCALAR) {
365            _glyphMapper->SetScaleArray(vtkDataSetAttributes::SCALARS);
366        } else {
367            _glyphMapper->SetScaleArray(vtkDataSetAttributes::VECTORS);
368        }
369    }
370
371    if (range != NULL) {
372        TRACE("Setting size range to: %g,%g", range[0], range[1]);
373        _glyphMapper->SetRange(range);
374    } else if (name != NULL && strlen(name) > 0) {
375        double r[2];
376        DataSet::DataAttributeType type = DataSet::POINT_DATA;
377        int comp = -1;
378
379        if (_renderer->getUseCumulativeRange()) {
380            int numComponents;
381            if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
382                ERROR("Field not found: %s, type: %d", name, type);
383                return;
384            } else if (mode == SCALE_BY_VECTOR_COMPONENTS && numComponents < 3) {
385                ERROR("Field %s needs 3 components but has only %d components",
386                      name, numComponents);
387                return;
388            }
389            if (mode == SCALE_BY_VECTOR_COMPONENTS) {
390                double tmpR[2];
391                _renderer->getCumulativeDataRange(tmpR, name, type, numComponents, 0);
392                r[0] = tmpR[0];
393                r[1] = tmpR[1];
394                _renderer->getCumulativeDataRange(tmpR, name, type, numComponents, 1);
395                r[0] = min2(r[0], tmpR[0]);
396                r[1] = max2(r[1], tmpR[1]);
397                _renderer->getCumulativeDataRange(tmpR, name, type, numComponents, 2);
398                r[0] = min2(r[0], tmpR[0]);
399                r[1] = max2(r[1], tmpR[1]);
400            } else {
401                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
402            }
403        } else {
404            if (mode == SCALE_BY_VECTOR_COMPONENTS) {
405                double tmpR[2];
406                _dataSet->getDataRange(tmpR, name, type, 0);
407                r[0] = tmpR[0];
408                r[1] = tmpR[1];
409                _dataSet->getDataRange(tmpR, name, type, 1);
410                r[0] = min2(r[0], tmpR[0]);
411                r[1] = max2(r[1], tmpR[1]);
412                _dataSet->getDataRange(tmpR, name, type, 2);
413                r[0] = min2(r[0], tmpR[0]);
414                r[1] = max2(r[1], tmpR[1]);
415            } else {
416                _dataSet->getDataRange(r, name, type, comp);
417            }
418        }
419        TRACE("Setting size range to: %g,%g", r[0], r[1]);
420        _glyphMapper->SetRange(r);
421    } else {
422        switch (mode) {
423        case SCALE_BY_SCALAR:
424            TRACE("Setting size range to: %g,%g", _dataRange[0], _dataRange[1]);
425            _glyphMapper->SetRange(_dataRange);
426            break;
427        case SCALE_BY_VECTOR_MAGNITUDE:
428            TRACE("Setting size range to: %g,%g", _vectorMagnitudeRange[0], _vectorMagnitudeRange[1]);
429            _glyphMapper->SetRange(_vectorMagnitudeRange);
430            break;
431        case SCALE_BY_VECTOR_COMPONENTS: {
432            double sizeRange[2];
433            sizeRange[0] = _vectorComponentRange[0][0];
434            sizeRange[1] = _vectorComponentRange[0][1];
435            sizeRange[0] = min2(sizeRange[0], _vectorComponentRange[1][0]);
436            sizeRange[1] = max2(sizeRange[1], _vectorComponentRange[1][1]);
437            sizeRange[0] = min2(sizeRange[0], _vectorComponentRange[2][0]);
438            sizeRange[1] = max2(sizeRange[1], _vectorComponentRange[2][1]);
439            TRACE("Setting size range to: %g,%g", sizeRange[0], sizeRange[1]);
440            _glyphMapper->SetRange(sizeRange);
441        }
442            break;
443        case SCALING_OFF:
444        default:
445            ;
446        }
447    }
448
449    switch (mode) {
450    case SCALE_BY_SCALAR:
451    case SCALE_BY_VECTOR_MAGNITUDE:
452        _glyphMapper->SetScaleModeToScaleByMagnitude();
453        break;
454    case SCALE_BY_VECTOR_COMPONENTS:
455        _glyphMapper->SetScaleModeToScaleByVectorComponents();
456        break;
457    case SCALING_OFF:
458    default:
459        _glyphMapper->SetScaleModeToNoDataScaling();
460    }
461}
462
463void Glyphs::setScalingMode(ScalingMode mode)
464{
465    setScalingMode(mode, NULL, NULL);
466}
467
468void Glyphs::setColorMode(ColorMode mode,
469                          const char *name, double range[2])
470{
471    _colorMode = mode;
472    if (name == NULL)
473        _colorFieldName.clear();
474    else
475        _colorFieldName = name;
476    if (range == NULL) {
477        _colorFieldRange[0] = DBL_MAX;
478        _colorFieldRange[1] = -DBL_MAX;
479    } else {
480        memcpy(_colorFieldRange, range, sizeof(double)*2);
481    }
482
483    if (_dataSet == NULL || _glyphMapper == NULL)
484        return;
485
486    if (name != NULL && strlen(name) > 0) {
487        _glyphMapper->SetScalarModeToUsePointFieldData();
488        _glyphMapper->SelectColorArray(name);
489    } else {
490        _glyphMapper->SetScalarModeToDefault();
491    }
492
493    if (_lut != NULL) {
494        if (range != NULL) {
495            _lut->SetRange(range);
496        } else if (name != NULL && strlen(name) > 0) {
497            double r[2];
498            int comp = -1;
499            if (mode == COLOR_BY_VECTOR_X)
500                comp = 0;
501            else if (mode == COLOR_BY_VECTOR_Y)
502                comp = 1;
503            else if (mode == COLOR_BY_VECTOR_Z)
504                comp = 2;
505
506            DataSet::DataAttributeType type = DataSet::POINT_DATA;
507
508            if (_renderer->getUseCumulativeRange()) {
509                int numComponents;
510                if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
511                    ERROR("Field not found: %s, type: %d", name, type);
512                    return;
513                } else if (numComponents < comp+1) {
514                    ERROR("Request for component %d in field with %d components",
515                          comp, numComponents);
516                    return;
517                }
518                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
519            } else {
520                _dataSet->getDataRange(r, name, type, comp);
521            }
522            TRACE("Setting lut range to: %g,%g", r[0], r[1]);
523            _lut->SetRange(r);
524        }
525    }
526
527    switch (mode) {
528    case COLOR_BY_SCALAR:
529        _glyphMapper->ScalarVisibilityOn();
530        break;
531    case COLOR_BY_VECTOR_MAGNITUDE:
532        _glyphMapper->ScalarVisibilityOn();
533        if (_lut != NULL) {
534            _lut->SetVectorModeToMagnitude();
535        }
536        break;
537    case COLOR_BY_VECTOR_X:
538        _glyphMapper->ScalarVisibilityOn();
539        if (_lut != NULL) {
540            _lut->SetVectorModeToComponent();
541            _lut->SetVectorComponent(0);
542        }
543        break;
544    case COLOR_BY_VECTOR_Y:
545        _glyphMapper->ScalarVisibilityOn();
546        if (_lut != NULL) {
547            _lut->SetVectorModeToComponent();
548            _lut->SetVectorComponent(1);
549        }
550        break;
551    case COLOR_BY_VECTOR_Z:
552        _glyphMapper->ScalarVisibilityOn();
553        if (_lut != NULL) {
554            _lut->SetVectorModeToComponent();
555            _lut->SetVectorComponent(2);
556        }
557        break;
558    case COLOR_CONSTANT:
559    default:
560        _glyphMapper->ScalarVisibilityOff();
561        break;
562    }
563}
564
565void Glyphs::setColorMode(ColorMode mode)
566{
567    _colorMode = mode;
568    if (_dataSet == NULL)
569        return;
570
571    switch (mode) {
572    case COLOR_BY_SCALAR:
573        setColorMode(mode,
574                     _dataSet->getActiveScalarsName(),
575                     _dataRange);
576        break;
577    case COLOR_BY_VECTOR_MAGNITUDE:
578        setColorMode(mode,
579                     _dataSet->getActiveVectorsName(),
580                     _vectorMagnitudeRange);
581        break;
582    case COLOR_BY_VECTOR_X:
583        setColorMode(mode,
584                     _dataSet->getActiveVectorsName(),
585                     _vectorComponentRange[0]);
586        break;
587    case COLOR_BY_VECTOR_Y:
588        setColorMode(mode,
589                     _dataSet->getActiveVectorsName(),
590                     _vectorComponentRange[1]);
591        break;
592    case COLOR_BY_VECTOR_Z:
593        setColorMode(mode,
594                     _dataSet->getActiveVectorsName(),
595                     _vectorComponentRange[2]);
596        break;
597    case COLOR_CONSTANT:
598    default:
599        setColorMode(mode, NULL, NULL);
600        break;
601    }
602}
603
604/**
605 * \brief Turn on/off orienting glyphs from a vector field
606 */
607void Glyphs::setOrient(bool state)
608{
609    if (_glyphMapper != NULL) {
610        _glyphMapper->SetOrient(state ? 1 : 0);
611    }
612}
613
614/**
615 * \brief Controls relative scaling of glyphs
616 */
617void Glyphs::setScaleFactor(double scale)
618{
619    _scaleFactor = scale;
620    if (_glyphMapper != NULL) {
621        _glyphMapper->SetScaleFactor(_scaleFactor * _dataScale);
622    }
623}
624
625void Glyphs::updateRanges(Renderer *renderer)
626{
627    if (_dataSet == NULL) {
628        ERROR("called before setDataSet");
629        return;
630    }
631
632    if (renderer->getUseCumulativeRange()) {
633        renderer->getCumulativeDataRange(_dataRange,
634                                         _dataSet->getActiveScalarsName(),
635                                         1);
636        renderer->getCumulativeDataRange(_vectorMagnitudeRange,
637                                         _dataSet->getActiveVectorsName(),
638                                         3);
639        for (int i = 0; i < 3; i++) {
640            renderer->getCumulativeDataRange(_vectorComponentRange[i],
641                                             _dataSet->getActiveVectorsName(),
642                                             3, i);
643        }
644    } else {
645        _dataSet->getScalarRange(_dataRange);
646        _dataSet->getVectorRange(_vectorMagnitudeRange);
647        for (int i = 0; i < 3; i++) {
648            _dataSet->getVectorRange(_vectorComponentRange[i], i);
649        }
650    }
651
652    // Need to update color map ranges and/or active vector field
653    double *rangePtr = _colorFieldRange;
654    if (_colorFieldRange[0] > _colorFieldRange[1]) {
655        rangePtr = NULL;
656    }
657    setColorMode(_colorMode, _colorFieldName.c_str(), rangePtr);
658
659    rangePtr = _scalingFieldRange;
660    if (_scalingFieldRange[0] > _scalingFieldRange[1]) {
661        rangePtr = NULL;
662    }
663    setScalingMode(_scalingMode, _scalingFieldName.c_str(), rangePtr);
664}
665
666/**
667 * \brief Called when the color map has been edited
668 */
669void Glyphs::updateColorMap()
670{
671    setColorMap(_colorMap);
672}
673
674/**
675 * \brief Associate a colormap lookup table with the DataSet
676 */
677void Glyphs::setColorMap(ColorMap *cmap)
678{
679    if (cmap == NULL)
680        return;
681
682    _colorMap = cmap;
683 
684    if (_lut == NULL) {
685        _lut = vtkSmartPointer<vtkLookupTable>::New();
686        if (_glyphMapper != NULL) {
687            _glyphMapper->UseLookupTableScalarRangeOn();
688            _glyphMapper->SetLookupTable(_lut);
689        }
690        _lut->DeepCopy(cmap->getLookupTable());
691        switch (_colorMode) {
692        case COLOR_CONSTANT:
693        case COLOR_BY_SCALAR:
694            _lut->SetRange(_dataRange);
695            break;
696        case COLOR_BY_VECTOR_MAGNITUDE:
697            _lut->SetRange(_vectorMagnitudeRange);
698            break;
699        case COLOR_BY_VECTOR_X:
700            _lut->SetRange(_vectorComponentRange[0]);
701            break;
702        case COLOR_BY_VECTOR_Y:
703            _lut->SetRange(_vectorComponentRange[1]);
704            break;
705        case COLOR_BY_VECTOR_Z:
706            _lut->SetRange(_vectorComponentRange[2]);
707            break;
708        default:
709            break;
710        }
711    } else {
712        double range[2];
713        _lut->GetTableRange(range);
714        _lut->DeepCopy(cmap->getLookupTable());
715        _lut->SetRange(range);
716        _lut->Modified();
717    }
718
719    switch (_colorMode) {
720    case COLOR_BY_VECTOR_MAGNITUDE:
721        _lut->SetVectorModeToMagnitude();
722        break;
723    case COLOR_BY_VECTOR_X:
724        _lut->SetVectorModeToComponent();
725        _lut->SetVectorComponent(0);
726        break;
727    case COLOR_BY_VECTOR_Y:
728        _lut->SetVectorModeToComponent();
729        _lut->SetVectorComponent(1);
730        break;
731    case COLOR_BY_VECTOR_Z:
732        _lut->SetVectorModeToComponent();
733        _lut->SetVectorComponent(2);
734        break;
735    default:
736        break;
737    }
738}
739
740/**
741 * \brief Set a group of world coordinate planes to clip rendering
742 *
743 * Passing NULL for planes will remove all cliping planes
744 */
745void Glyphs::setClippingPlanes(vtkPlaneCollection *planes)
746{
747    if (_glyphMapper != NULL) {
748        _glyphMapper->SetClippingPlanes(planes);
749    }
750}
Note: See TracBrowser for help on using the repository browser.