source: vtkvis/trunk/Cutplane.cpp @ 4783

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

Improved cloud support in vtkvis: handle ugrids with no cells as well as
polydata clouds, add cloudstyle options to some graphics objects.

  • Property svn:eol-style set to native
File size: 29.6 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 <cassert>
9#include <cfloat>
10#include <cstring>
11
12#include <vtkDataSet.h>
13#include <vtkPointData.h>
14#include <vtkCellData.h>
15#include <vtkPolyDataMapper.h>
16#include <vtkUnstructuredGrid.h>
17#include <vtkProperty.h>
18#include <vtkImageData.h>
19#include <vtkLookupTable.h>
20#include <vtkTransform.h>
21#include <vtkDelaunay2D.h>
22#include <vtkDelaunay3D.h>
23#include <vtkGaussianSplatter.h>
24#include <vtkExtractVOI.h>
25#include <vtkCutter.h>
26#include <vtkDataSetSurfaceFilter.h>
27
28#include "Cutplane.h"
29#include "Renderer.h"
30#include "Trace.h"
31
32using namespace VtkVis;
33
34Cutplane::Cutplane() :
35    GraphicsObject(),
36    _pipelineInitialized(false),
37    _cloudStyle(CLOUD_MESH),
38    _colorMap(NULL),
39    _colorMode(COLOR_BY_SCALAR),
40    _colorFieldType(DataSet::POINT_DATA),
41    _renderer(NULL)
42{
43    _colorFieldRange[0] = DBL_MAX;
44    _colorFieldRange[1] = -DBL_MAX;
45}
46
47Cutplane::~Cutplane()
48{
49#ifdef WANT_TRACE
50    if (_dataSet != NULL)
51        TRACE("Deleting Cutplane for %s", _dataSet->getName().c_str());
52    else
53        TRACE("Deleting Cutplane with NULL DataSet");
54#endif
55}
56
57void Cutplane::setDataSet(DataSet *dataSet,
58                          Renderer *renderer)
59{
60    if (_dataSet != dataSet) {
61        _dataSet = dataSet;
62
63        _renderer = renderer;
64
65        if (renderer->getUseCumulativeRange()) {
66            renderer->getCumulativeDataRange(_dataRange,
67                                             _dataSet->getActiveScalarsName(),
68                                             1);
69            renderer->getCumulativeDataRange(_vectorMagnitudeRange,
70                                             _dataSet->getActiveVectorsName(),
71                                             3);
72            for (int i = 0; i < 3; i++) {
73                renderer->getCumulativeDataRange(_vectorComponentRange[i],
74                                                 _dataSet->getActiveVectorsName(),
75                                                 3, i);
76            }
77        } else {
78            _dataSet->getScalarRange(_dataRange);
79            _dataSet->getVectorRange(_vectorMagnitudeRange);
80            for (int i = 0; i < 3; i++) {
81                _dataSet->getVectorRange(_vectorComponentRange[i], i);
82            }
83        }
84
85        update();
86    }
87}
88
89/**
90 * \brief Create and initialize a VTK Prop to render the object
91 */
92void Cutplane::initProp()
93{
94    if (_prop == NULL) {
95        _prop = vtkSmartPointer<vtkAssembly>::New();
96
97        for (int i = 0; i < 3; i++) {
98            _actor[i] = vtkSmartPointer<vtkActor>::New();
99            _borderActor[i] = vtkSmartPointer<vtkActor>::New();
100            //_actor[i]->VisibilityOff();
101            vtkProperty *property = _actor[i]->GetProperty();
102            property->SetColor(_color[0], _color[1], _color[2]);
103            property->SetEdgeColor(_edgeColor[0], _edgeColor[1], _edgeColor[2]);
104            property->SetLineWidth(_edgeWidth);
105            property->SetPointSize(_pointSize);
106            property->EdgeVisibilityOff();
107            property->SetOpacity(_opacity);
108            property->SetAmbient(.2);
109            if (!_lighting)
110                property->LightingOff();
111            if (_faceCulling && _opacity == 1.0) {
112                setCulling(property, true);
113            }
114            property = _borderActor[i]->GetProperty();
115            property->SetColor(_color[0], _color[1], _color[2]);
116            property->SetEdgeColor(_edgeColor[0], _edgeColor[1], _edgeColor[2]);
117            property->SetLineWidth(_edgeWidth);
118            property->SetPointSize(_pointSize);
119            property->EdgeVisibilityOff();
120            property->SetOpacity(_opacity);
121            property->SetAmbient(.2);
122            property->LightingOff();
123           
124            getAssembly()->AddPart(_borderActor[i]);
125        }
126    } else {
127        for (int i = 0; i < 3; i++) {
128            getAssembly()->RemovePart(_actor[i]);
129        }
130    }
131}
132
133/**
134 * \brief Set the material color (sets ambient, diffuse, and specular)
135 */
136void Cutplane::setColor(float color[3])
137{
138    for (int i = 0; i < 3; i++)
139        _color[i] = color[i];
140
141    for (int i = 0; i < 3; i++) {
142        if (_borderActor[i] != NULL) {
143            _borderActor[i]->GetProperty()->SetColor(color[0], color[1], color[2]);
144        }
145    }
146}
147
148void Cutplane::update()
149{
150    if (_dataSet == NULL)
151        return;
152
153    vtkDataSet *ds = _dataSet->getVtkDataSet();
154
155    double bounds[6];
156    _dataSet->getBounds(bounds);
157    // Mapper, actor to render color-mapped data set
158    for (int i = 0; i < 3; i++) {
159        if (_mapper[i] == NULL) {
160            _mapper[i] = vtkSmartPointer<vtkPolyDataMapper>::New();
161            // Map scalars through lookup table regardless of type
162            _mapper[i]->SetColorModeToMapScalars();
163        }
164        if (_cutPlane[i] == NULL) {
165            _cutPlane[i] = vtkSmartPointer<vtkPlane>::New();
166            switch (i) {
167            case 0:
168                _cutPlane[i]->SetNormal(1, 0, 0);
169                _cutPlane[i]->SetOrigin(bounds[0] + (bounds[1]-bounds[0])/2.,
170                                        0,
171                                        0);
172                break;
173            case 1:
174                _cutPlane[i]->SetNormal(0, 1, 0);
175                _cutPlane[i]->SetOrigin(0,
176                                        bounds[2] + (bounds[3]-bounds[2])/2.,
177                                        0);
178                break;
179            case 2:
180            default:
181                _cutPlane[i]->SetNormal(0, 0, 1);
182                _cutPlane[i]->SetOrigin(0,
183                                        0,
184                                        bounds[4] + (bounds[5]-bounds[4])/2.);
185                break;
186            }
187        }
188        if (_cutter[i] == NULL) {
189            _cutter[i] = vtkSmartPointer<vtkCutter>::New();
190            _cutter[i]->SetCutFunction(_cutPlane[i]);
191        }
192    }
193
194    initProp();
195
196    if (!_pipelineInitialized) {
197        _splatter = NULL;
198        if (_dataSet->isCloud()) {
199            // DataSet is a point cloud
200            PrincipalPlane plane;
201            double offset;
202            if (_dataSet->is2D(&plane, &offset)) {
203                // DataSet is a 2D point cloud
204                if (_cloudStyle == CLOUD_MESH) {
205                    vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
206                    if (plane == PLANE_ZY) {
207                        vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
208                        trans->RotateWXYZ(90, 0, 1, 0);
209                        if (offset != 0.0) {
210                            trans->Translate(-offset, 0, 0);
211                        }
212                        mesher->SetTransform(trans);
213                        _actor[1]->VisibilityOff();
214                        _actor[2]->VisibilityOff();
215                    } else if (plane == PLANE_XZ) {
216                        vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
217                        trans->RotateWXYZ(-90, 1, 0, 0);
218                        if (offset != 0.0) {
219                            trans->Translate(0, -offset, 0);
220                        }
221                        mesher->SetTransform(trans);
222                        _actor[0]->VisibilityOff();
223                        _actor[2]->VisibilityOff();
224                    } else if (offset != 0.0) {
225                        // XY with Z offset
226                        vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
227                        trans->Translate(0, 0, -offset);
228                        mesher->SetTransform(trans);
229                        _actor[0]->VisibilityOff();
230                        _actor[1]->VisibilityOff();
231                    }
232#ifdef USE_VTK6
233                    mesher->SetInputData(ds);
234#else
235                    mesher->SetInput(ds);
236#endif
237                    for (int i = 0; i < 3; i++) {
238                        _mapper[i]->SetInputConnection(mesher->GetOutputPort());
239                    }
240                } else {
241                    // _cloudStyle == CLOUD_SPLAT
242                    if (_splatter == NULL) {
243                        _splatter = vtkSmartPointer<vtkGaussianSplatter>::New();
244                    }
245#ifdef USE_VTK6
246                    _splatter->SetInputData(ds);
247#else
248                    _splatter->SetInput(ds);
249#endif
250                    int dims[3];
251                    _splatter->GetSampleDimensions(dims);
252                    TRACE("Sample dims: %d %d %d", dims[0], dims[1], dims[2]);
253                    if (plane == PLANE_ZY) {
254                        dims[0] = 3;
255                    } else if (plane == PLANE_XZ) {
256                        dims[1] = 3;
257                    } else {
258                        dims[2] = 3;
259                    }
260                    _splatter->SetSampleDimensions(dims);
261                    for (int i = 0; i < 3; i++) {
262                        _cutter[i]->SetInputConnection(_splatter->GetOutputPort());
263                        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
264                        gf->UseStripsOn();
265                        gf->SetInputConnection(_cutter[i]->GetOutputPort());
266                        _mapper[i]->SetInputConnection(gf->GetOutputPort());
267                    }
268                }
269            } else {
270                if (_cloudStyle == CLOUD_MESH) {
271                    // Data Set is a 3D point cloud
272                    // Result of Delaunay3D mesher is unstructured grid
273                    vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
274#ifdef USE_VTK6
275                    mesher->SetInputData(ds);
276#else
277                    mesher->SetInput(ds);
278#endif
279                    // Sample a plane within the grid bounding box
280                    for (int i = 0; i < 3; i++) {
281                        _cutter[i]->SetInputConnection(mesher->GetOutputPort());
282                        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
283                        gf->UseStripsOn();
284                        gf->SetInputConnection(_cutter[i]->GetOutputPort());
285                        _mapper[i]->SetInputConnection(gf->GetOutputPort());
286                    }
287                } else {
288                    // _cloudStyle == CLOUD_SPLAT
289                    if (_splatter == NULL) {
290                        _splatter = vtkSmartPointer<vtkGaussianSplatter>::New();
291                    }
292#ifdef USE_VTK6
293                    _splatter->SetInputData(ds);
294#else
295                    _splatter->SetInput(ds);
296#endif
297                    int dims[3];
298                    dims[0] = dims[1] = dims[2] = 64;
299                    TRACE("Generating volume with dims (%d,%d,%d) from point cloud",
300                          dims[0], dims[1], dims[2]);
301                    _splatter->SetSampleDimensions(dims);
302                    for (int i = 0; i < 3; i++) {
303                        _cutter[i]->SetInputConnection(_splatter->GetOutputPort());
304                        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
305                        gf->UseStripsOn();
306                        gf->SetInputConnection(_cutter[i]->GetOutputPort());
307                        _mapper[i]->SetInputConnection(gf->GetOutputPort());
308                    }
309                }
310            }
311        } else {
312            // DataSet can be: image/volume/uniform grid, structured grid, unstructured grid, rectilinear grid, or
313            // PolyData with cells other than points
314            PrincipalPlane plane;
315            double offset;
316            if (!_dataSet->is2D(&plane, &offset)) {
317                // Sample a plane within the grid bounding box
318                for (int i = 0; i < 3; i++) {
319#ifdef USE_VTK6
320                    _cutter[i]->SetInputData(ds);
321#else
322                    _cutter[i]->SetInput(ds);
323#endif
324                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
325                    gf->UseStripsOn();
326                    gf->SetInputConnection(_cutter[i]->GetOutputPort());
327                    _mapper[i]->SetInputConnection(gf->GetOutputPort());
328                }
329            } else {
330                // 2D data
331                if (plane == PLANE_ZY) {
332                    _actor[1]->VisibilityOff();
333                    _actor[2]->VisibilityOff();
334                } else if (plane == PLANE_XZ) {
335                    _actor[0]->VisibilityOff();
336                    _actor[2]->VisibilityOff();
337                } else if (offset != 0.0) {
338                    // XY with Z offset
339                    _actor[0]->VisibilityOff();
340                    _actor[1]->VisibilityOff();
341                }
342                for (int i = 0; i < 3; i++) {
343                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
344                    gf->UseStripsOn();
345#ifdef USE_VTK6
346                    gf->SetInputData(ds);
347#else
348                    gf->SetInput(ds);
349#endif
350                    _mapper[i]->SetInputConnection(gf->GetOutputPort());
351                }
352            }
353        }
354    }
355
356    for (int i = 0; i < 3; i++) {
357        if (_mapper[i] != NULL && _borderMapper[i] == NULL) {
358            _borderMapper[i] = vtkSmartPointer<vtkPolyDataMapper>::New();
359#ifdef CUTPLANE_TIGHT_OUTLINE
360            _outlineFilter[i] = vtkSmartPointer<vtkOutlineFilter>::New();
361            _outlineFilter[i]->SetInputConnection(_mapper[i]->GetInputConnection(0, 0));
362            _borderMapper[i]->SetInputConnection(_outlineFilter[i]->GetOutputPort());
363#else
364            _outlineSource[i] = vtkSmartPointer<vtkOutlineSource>::New();
365            switch (i) {
366            case 0:
367                _outlineSource[i]->SetBounds(bounds[0] + (bounds[1]-bounds[0])/2.,
368                                             bounds[0] + (bounds[1]-bounds[0])/2.,
369                                             bounds[2], bounds[3],
370                                             bounds[4], bounds[5]);
371                break;
372            case 1:
373                _outlineSource[i]->SetBounds(bounds[0], bounds[1],
374                                             bounds[2] + (bounds[3]-bounds[2])/2.,
375                                             bounds[2] + (bounds[3]-bounds[2])/2.,
376                                             bounds[4], bounds[5]);
377                break;
378            case 2:
379                _outlineSource[i]->SetBounds(bounds[0], bounds[1],
380                                             bounds[2], bounds[3],
381                                             bounds[4] + (bounds[5]-bounds[4])/2.,
382                                             bounds[4] + (bounds[5]-bounds[4])/2.);
383                break;
384            default:
385                ;
386            }
387            _borderMapper[i]->SetInputConnection(_outlineSource[i]->GetOutputPort());
388#endif
389            _borderMapper[i]->SetResolveCoincidentTopologyToPolygonOffset();
390        }
391    }
392
393    setInterpolateBeforeMapping(true);
394
395    if (_lut == NULL) {
396        setColorMap(ColorMap::getDefault());
397        if (ds->GetPointData()->GetScalars() == NULL &&
398            ds->GetPointData()->GetVectors() != NULL) {
399            TRACE("Setting color mode to vector magnitude");
400            setColorMode(COLOR_BY_VECTOR_MAGNITUDE);
401        } else {
402            TRACE("Setting color mode to scalar");
403            setColorMode(COLOR_BY_SCALAR);
404        }
405    } else if (!_pipelineInitialized) {
406        double *rangePtr = _colorFieldRange;
407        if (_colorFieldRange[0] > _colorFieldRange[1]) {
408            rangePtr = NULL;
409        }
410        setColorMode(_colorMode, _colorFieldType, _colorFieldName.c_str(), rangePtr);
411    }
412
413    _pipelineInitialized = true;
414
415    for (int i = 0; i < 3; i++) {
416        if (_mapper[i] != NULL) {
417            _actor[i]->SetMapper(_mapper[i]);
418            _mapper[i]->Update();
419        }
420        if (_borderMapper[i] != NULL) {
421            _borderActor[i]->SetMapper(_borderMapper[i]);
422            _borderMapper[i]->Update();
423        }
424        // Only add cutter actor to assembly if geometry was
425        // produced, in order to prevent messing up assembly bounds
426        double bounds[6];
427        _actor[i]->GetBounds(bounds);
428        if (bounds[0] <= bounds[1]) {
429            getAssembly()->AddPart(_actor[i]);
430        }
431    }
432}
433
434void Cutplane::setCloudStyle(CloudStyle style)
435{
436    if (style != _cloudStyle) {
437        _cloudStyle = style;
438        if (_dataSet != NULL) {
439            _pipelineInitialized = false;
440            update();
441        }
442    }
443}
444
445void Cutplane::setInterpolateBeforeMapping(bool state)
446{
447    for (int i = 0; i < 3; i++) {
448        if (_mapper[i] != NULL) {
449            _mapper[i]->SetInterpolateScalarsBeforeMapping((state ? 1 : 0));
450        }
451    }
452}
453
454/**
455 * \brief Select a 2D slice plane from a 3D DataSet
456 *
457 * \param[in] axis Axis of slice plane
458 * \param[in] ratio Position [0,1] of slice plane along axis
459 */
460void Cutplane::selectVolumeSlice(Axis axis, double ratio)
461{
462    if (_dataSet->is2D()) {
463        WARN("DataSet not 3D, returning");
464        return;
465    }
466
467    if ((axis == X_AXIS &&_cutPlane[0] == NULL) ||
468        (axis == Y_AXIS &&_cutPlane[1] == NULL) ||
469        (axis == Z_AXIS &&_cutPlane[2] == NULL)) {
470        WARN("Called before update() or DataSet is not a volume");
471        return;
472    }
473
474    double bounds[6];
475    _dataSet->getBounds(bounds);
476#if 0
477    if (ratio == 0.0)
478        ratio = 0.001;
479    if (ratio == 1.0)
480        ratio = 0.999;
481#endif
482    switch (axis) {
483    case X_AXIS:
484        _cutPlane[0]->SetOrigin(bounds[0] + (bounds[1]-bounds[0]) * ratio,
485                                0,
486                                0);
487#ifndef CUTPLANE_TIGHT_OUTLINE
488        _outlineSource[0]->SetBounds(bounds[0] + (bounds[1]-bounds[0]) * ratio,
489                                     bounds[0] + (bounds[1]-bounds[0]) * ratio,
490                                     bounds[2], bounds[3],
491                                     bounds[4], bounds[5]);
492#endif
493        break;
494    case Y_AXIS:
495        _cutPlane[1]->SetOrigin(0,
496                                bounds[2] + (bounds[3]-bounds[2]) * ratio,
497                                0);
498#ifndef CUTPLANE_TIGHT_OUTLINE
499        _outlineSource[1]->SetBounds(bounds[0], bounds[1],
500                                     bounds[2] + (bounds[3]-bounds[2]) * ratio,
501                                     bounds[2] + (bounds[3]-bounds[2]) * ratio,
502                                     bounds[4], bounds[5]);
503#endif
504        break;
505    case Z_AXIS:
506        _cutPlane[2]->SetOrigin(0,
507                                0,
508                                bounds[4] + (bounds[5]-bounds[4]) * ratio);
509#ifndef CUTPLANE_TIGHT_OUTLINE
510        _outlineSource[2]->SetBounds(bounds[0], bounds[1],
511                                     bounds[2], bounds[3],
512                                     bounds[4] + (bounds[5]-bounds[4]) * ratio,
513                                     bounds[4] + (bounds[5]-bounds[4]) * ratio);
514#endif
515        break;
516    default:
517        ERROR("Invalid Axis");
518        return;
519    }
520    update();
521}
522
523void Cutplane::updateRanges(Renderer *renderer)
524{
525    if (_dataSet == NULL) {
526        ERROR("called before setDataSet");
527        return;
528    }
529
530    if (renderer->getUseCumulativeRange()) {
531        renderer->getCumulativeDataRange(_dataRange,
532                                         _dataSet->getActiveScalarsName(),
533                                         1);
534        renderer->getCumulativeDataRange(_vectorMagnitudeRange,
535                                         _dataSet->getActiveVectorsName(),
536                                         3);
537        for (int i = 0; i < 3; i++) {
538            renderer->getCumulativeDataRange(_vectorComponentRange[i],
539                                             _dataSet->getActiveVectorsName(),
540                                             3, i);
541        }
542    } else {
543        _dataSet->getScalarRange(_dataRange);
544        _dataSet->getVectorRange(_vectorMagnitudeRange);
545        for (int i = 0; i < 3; i++) {
546            _dataSet->getVectorRange(_vectorComponentRange[i], i);
547        }
548    }
549
550    // Need to update color map ranges
551    double *rangePtr = _colorFieldRange;
552    if (_colorFieldRange[0] > _colorFieldRange[1]) {
553        rangePtr = NULL;
554    }
555    setColorMode(_colorMode, _colorFieldType, _colorFieldName.c_str(), rangePtr);
556}
557
558void Cutplane::setColorMode(ColorMode mode)
559{
560    _colorMode = mode;
561    if (_dataSet == NULL)
562        return;
563
564    switch (mode) {
565    case COLOR_BY_SCALAR:
566        setColorMode(mode,
567                     _dataSet->getActiveScalarsType(),
568                     _dataSet->getActiveScalarsName(),
569                     _dataRange);
570        break;
571    case COLOR_BY_VECTOR_MAGNITUDE:
572        setColorMode(mode,
573                     _dataSet->getActiveVectorsType(),
574                     _dataSet->getActiveVectorsName(),
575                     _vectorMagnitudeRange);
576        break;
577    case COLOR_BY_VECTOR_X:
578        setColorMode(mode,
579                     _dataSet->getActiveVectorsType(),
580                     _dataSet->getActiveVectorsName(),
581                     _vectorComponentRange[0]);
582        break;
583    case COLOR_BY_VECTOR_Y:
584        setColorMode(mode,
585                     _dataSet->getActiveVectorsType(),
586                     _dataSet->getActiveVectorsName(),
587                     _vectorComponentRange[1]);
588        break;
589    case COLOR_BY_VECTOR_Z:
590        setColorMode(mode,
591                     _dataSet->getActiveVectorsType(),
592                     _dataSet->getActiveVectorsName(),
593                     _vectorComponentRange[2]);
594        break;
595    default:
596        ;
597    }
598}
599
600void Cutplane::setColorMode(ColorMode mode,
601                            const char *name, double range[2])
602{
603    if (_dataSet == NULL)
604        return;
605    DataSet::DataAttributeType type;
606    int numComponents;
607    if (!_dataSet->getFieldInfo(name, &type, &numComponents)) {
608        ERROR("Field not found: %s", name);
609        return;
610    }
611    setColorMode(mode, type, name, range);
612}
613
614void Cutplane::setColorMode(ColorMode mode,
615                            DataSet::DataAttributeType type,
616                            const char *name, double range[2])
617{
618    _colorMode = mode;
619    _colorFieldType = type;
620    if (name == NULL)
621        _colorFieldName.clear();
622    else
623        _colorFieldName = name;
624    if (range == NULL) {
625        _colorFieldRange[0] = DBL_MAX;
626        _colorFieldRange[1] = -DBL_MAX;
627    } else {
628        memcpy(_colorFieldRange, range, sizeof(double)*2);
629    }
630
631    if (_dataSet == NULL ||
632        _mapper[0] == NULL ||
633        _mapper[1] == NULL ||
634        _mapper[2] == NULL)
635        return;
636
637    switch (type) {
638    case DataSet::POINT_DATA:
639        for (int i = 0; i < 3; i++) {
640            _mapper[i]->SetScalarModeToUsePointFieldData();
641        }
642        break;
643    case DataSet::CELL_DATA:
644        for (int i = 0; i < 3; i++) {
645            _mapper[i]->SetScalarModeToUseCellFieldData();
646        }
647        break;
648    default:
649        ERROR("Unsupported DataAttributeType: %d", type);
650        return;
651    }
652
653    if (_splatter != NULL) {
654        if (name != NULL && strlen(name) > 0) {
655            _splatter->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, name);
656        }
657        for (int i = 0; i < 3; i++) {
658            _mapper[i]->SelectColorArray("SplatterValues");
659        }
660    } else if (name != NULL && strlen(name) > 0) {
661        for (int i = 0; i < 3; i++) {
662            _mapper[i]->SelectColorArray(name);
663        }
664    } else {
665        for (int i = 0; i < 3; i++) {
666            _mapper[i]->SetScalarModeToDefault();
667        }
668    }
669
670    if (_lut != NULL) {
671        if (range != NULL) {
672            _lut->SetRange(range);
673        } else if (name != NULL && strlen(name) > 0) {
674            double r[2];
675            int comp = -1;
676            if (mode == COLOR_BY_VECTOR_X)
677                comp = 0;
678            else if (mode == COLOR_BY_VECTOR_Y)
679                comp = 1;
680            else if (mode == COLOR_BY_VECTOR_Z)
681                comp = 2;
682
683            if (_renderer->getUseCumulativeRange()) {
684                int numComponents;
685                if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
686                    ERROR("Field not found: %s, type: %d", name, type);
687                    return;
688                } else if (numComponents < comp+1) {
689                    ERROR("Request for component %d in field with %d components",
690                          comp, numComponents);
691                    return;
692                }
693                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
694            } else {
695                _dataSet->getDataRange(r, name, type, comp);
696            }
697            _lut->SetRange(r);
698        }
699    }
700
701
702    switch (mode) {
703    case COLOR_BY_SCALAR:
704        for (int i = 0; i < 3; i++) {
705            _mapper[i]->ScalarVisibilityOn();
706        }
707        break;
708    case COLOR_BY_VECTOR_MAGNITUDE:
709        for (int i = 0; i < 3; i++) {
710            _mapper[i]->ScalarVisibilityOn();
711        }
712        if (_lut != NULL) {
713            _lut->SetVectorModeToMagnitude();
714        }
715        break;
716    case COLOR_BY_VECTOR_X:
717        for (int i = 0; i < 3; i++) {
718            _mapper[i]->ScalarVisibilityOn();
719        }
720        if (_lut != NULL) {
721            _lut->SetVectorModeToComponent();
722            _lut->SetVectorComponent(0);
723        }
724        break;
725    case COLOR_BY_VECTOR_Y:
726        for (int i = 0; i < 3; i++) {
727            _mapper[i]->ScalarVisibilityOn();
728        }
729        if (_lut != NULL) {
730            _lut->SetVectorModeToComponent();
731            _lut->SetVectorComponent(1);
732        }
733        break;
734    case COLOR_BY_VECTOR_Z:
735        for (int i = 0; i < 3; i++) {
736            _mapper[i]->ScalarVisibilityOn();
737        }
738        if (_lut != NULL) {
739            _lut->SetVectorModeToComponent();
740            _lut->SetVectorComponent(2);
741        }
742        break;
743    default:
744        for (int i = 0; i < 3; i++) {
745            _mapper[i]->ScalarVisibilityOff();
746        }
747        break;
748    }
749}
750
751/**
752 * \brief Called when the color map has been edited
753 */
754void Cutplane::updateColorMap()
755{
756    setColorMap(_colorMap);
757}
758
759/**
760 * \brief Associate a colormap lookup table with the DataSet
761 */
762void Cutplane::setColorMap(ColorMap *cmap)
763{
764    if (cmap == NULL)
765        return;
766
767    _colorMap = cmap;
768 
769    if (_lut == NULL) {
770        _lut = vtkSmartPointer<vtkLookupTable>::New();
771        for (int i = 0; i < 3; i++) {
772            if (_mapper[i] != NULL) {
773                _mapper[i]->UseLookupTableScalarRangeOn();
774                _mapper[i]->SetLookupTable(_lut);
775            }
776        }
777        _lut->DeepCopy(cmap->getLookupTable());
778        switch (_colorMode) {
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        _lut->Modified();
803    }
804
805    switch (_colorMode) {
806    case COLOR_BY_VECTOR_MAGNITUDE:
807        _lut->SetVectorModeToMagnitude();
808        break;
809    case COLOR_BY_VECTOR_X:
810        _lut->SetVectorModeToComponent();
811        _lut->SetVectorComponent(0);
812        break;
813    case COLOR_BY_VECTOR_Y:
814        _lut->SetVectorModeToComponent();
815        _lut->SetVectorComponent(1);
816        break;
817    case COLOR_BY_VECTOR_Z:
818        _lut->SetVectorModeToComponent();
819        _lut->SetVectorComponent(2);
820        break;
821    default:
822         break;
823    }
824}
825
826/**
827 * \brief Turn on/off lighting of this object
828 */
829void Cutplane::setLighting(bool state)
830{
831    _lighting = state;
832    for (int i = 0; i < 3; i++) {
833        if (_actor[i] != NULL)
834            _actor[i]->GetProperty()->SetLighting((state ? 1 : 0));
835    }
836}
837
838/**
839 * \brief Turn on/off rendering of mesh edges
840 */
841void Cutplane::setEdgeVisibility(bool state)
842{
843    for (int i = 0; i < 3; i++) {
844        if (_actor[i] != NULL) {
845            _actor[i]->GetProperty()->SetEdgeVisibility((state ? 1 : 0));
846        }
847    }
848}
849
850/**
851 * \brief Turn on/off rendering of outlines
852 */
853void Cutplane::setOutlineVisibility(bool state)
854{
855    for (int i = 0; i < 3; i++) {
856        if (_borderActor[i] != NULL) {
857            _borderActor[i]->SetVisibility((state ? 1 : 0));
858        }
859    }
860}
861
862/**
863 * \brief Set visibility of cutplane on specified axis
864 */
865void Cutplane::setSliceVisibility(Axis axis, bool state)
866{
867    switch (axis) {
868    case X_AXIS:
869        if (_actor[0] != NULL)
870            _actor[0]->SetVisibility((state ? 1 : 0));
871        if (_borderActor[0] != NULL)
872            _borderActor[0]->SetVisibility((state ? 1 : 0));
873        break;
874    case Y_AXIS:
875        if (_actor[1] != NULL)
876            _actor[1]->SetVisibility((state ? 1 : 0));
877        if (_borderActor[1] != NULL)
878            _borderActor[1]->SetVisibility((state ? 1 : 0));
879        break;
880    case Z_AXIS:
881    default:
882        if (_actor[2] != NULL)
883            _actor[2]->SetVisibility((state ? 1 : 0));
884        if (_borderActor[2] != NULL)
885            _borderActor[2]->SetVisibility((state ? 1 : 0));
886        break;
887    }
888}
889
890/**
891 * \brief Set a group of world coordinate planes to clip rendering
892 *
893 * Passing NULL for planes will remove all cliping planes
894 */
895void Cutplane::setClippingPlanes(vtkPlaneCollection *planes)
896{
897    for (int i = 0; i < 3; i++) {
898        if (_mapper[i] != NULL) {
899            _mapper[i]->SetClippingPlanes(planes);
900        }
901        if (_borderMapper[i] != NULL) {
902            _borderMapper[i]->SetClippingPlanes(planes);
903        }
904    }
905}
Note: See TracBrowser for help on using the repository browser.