source: vtkvis/trunk/Cutplane.cpp @ 5073

Last change on this file since 5073 was 5073, checked in by ldelgass, 5 years ago

merge r5072 from release branch

  • Property svn:eol-style set to native
File size: 29.4 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        break;
570    case COLOR_BY_VECTOR_MAGNITUDE:
571        setColorMode(mode,
572                     _dataSet->getActiveVectorsType(),
573                     _dataSet->getActiveVectorsName());
574        break;
575    case COLOR_BY_VECTOR_X:
576        setColorMode(mode,
577                     _dataSet->getActiveVectorsType(),
578                     _dataSet->getActiveVectorsName());
579        break;
580    case COLOR_BY_VECTOR_Y:
581        setColorMode(mode,
582                     _dataSet->getActiveVectorsType(),
583                     _dataSet->getActiveVectorsName());
584        break;
585    case COLOR_BY_VECTOR_Z:
586        setColorMode(mode,
587                     _dataSet->getActiveVectorsType(),
588                     _dataSet->getActiveVectorsName());
589        break;
590    default:
591        ;
592    }
593}
594
595void Cutplane::setColorMode(ColorMode mode,
596                            const char *name, double range[2])
597{
598    if (_dataSet == NULL)
599        return;
600    DataSet::DataAttributeType type;
601    int numComponents;
602    if (!_dataSet->getFieldInfo(name, &type, &numComponents)) {
603        ERROR("Field not found: %s", name);
604        return;
605    }
606    setColorMode(mode, type, name, range);
607}
608
609void Cutplane::setColorMode(ColorMode mode,
610                            DataSet::DataAttributeType type,
611                            const char *name, double range[2])
612{
613    _colorMode = mode;
614    _colorFieldType = type;
615    if (name == NULL)
616        _colorFieldName.clear();
617    else
618        _colorFieldName = name;
619    if (range == NULL) {
620        _colorFieldRange[0] = DBL_MAX;
621        _colorFieldRange[1] = -DBL_MAX;
622    } else {
623        memcpy(_colorFieldRange, range, sizeof(double)*2);
624    }
625
626    if (_dataSet == NULL ||
627        _mapper[0] == NULL ||
628        _mapper[1] == NULL ||
629        _mapper[2] == NULL)
630        return;
631
632    switch (type) {
633    case DataSet::POINT_DATA:
634        for (int i = 0; i < 3; i++) {
635            _mapper[i]->SetScalarModeToUsePointFieldData();
636        }
637        break;
638    case DataSet::CELL_DATA:
639        for (int i = 0; i < 3; i++) {
640            _mapper[i]->SetScalarModeToUseCellFieldData();
641        }
642        break;
643    default:
644        ERROR("Unsupported DataAttributeType: %d", type);
645        return;
646    }
647
648    if (_splatter != NULL) {
649        if (name != NULL && strlen(name) > 0) {
650            _splatter->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, name);
651        }
652        for (int i = 0; i < 3; i++) {
653            _mapper[i]->SelectColorArray("SplatterValues");
654        }
655    } else if (name != NULL && strlen(name) > 0) {
656        for (int i = 0; i < 3; i++) {
657            _mapper[i]->SelectColorArray(name);
658        }
659    } else {
660        for (int i = 0; i < 3; i++) {
661            _mapper[i]->SetScalarModeToDefault();
662        }
663    }
664
665    if (_lut != NULL) {
666        if (range != NULL) {
667            _lut->SetRange(range);
668        } else if (name != NULL && strlen(name) > 0) {
669            double r[2];
670            int comp = -1;
671            if (mode == COLOR_BY_VECTOR_X)
672                comp = 0;
673            else if (mode == COLOR_BY_VECTOR_Y)
674                comp = 1;
675            else if (mode == COLOR_BY_VECTOR_Z)
676                comp = 2;
677
678            if (_renderer->getUseCumulativeRange()) {
679                int numComponents;
680                if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
681                    ERROR("Field not found: %s, type: %d", name, type);
682                    return;
683                } else if (numComponents < comp+1) {
684                    ERROR("Request for component %d in field with %d components",
685                          comp, numComponents);
686                    return;
687                }
688                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
689            } else {
690                _dataSet->getDataRange(r, name, type, comp);
691            }
692            _lut->SetRange(r);
693        }
694    }
695
696
697    switch (mode) {
698    case COLOR_BY_SCALAR:
699        for (int i = 0; i < 3; i++) {
700            _mapper[i]->ScalarVisibilityOn();
701        }
702        break;
703    case COLOR_BY_VECTOR_MAGNITUDE:
704        for (int i = 0; i < 3; i++) {
705            _mapper[i]->ScalarVisibilityOn();
706        }
707        if (_lut != NULL) {
708            _lut->SetVectorModeToMagnitude();
709        }
710        break;
711    case COLOR_BY_VECTOR_X:
712        for (int i = 0; i < 3; i++) {
713            _mapper[i]->ScalarVisibilityOn();
714        }
715        if (_lut != NULL) {
716            _lut->SetVectorModeToComponent();
717            _lut->SetVectorComponent(0);
718        }
719        break;
720    case COLOR_BY_VECTOR_Y:
721        for (int i = 0; i < 3; i++) {
722            _mapper[i]->ScalarVisibilityOn();
723        }
724        if (_lut != NULL) {
725            _lut->SetVectorModeToComponent();
726            _lut->SetVectorComponent(1);
727        }
728        break;
729    case COLOR_BY_VECTOR_Z:
730        for (int i = 0; i < 3; i++) {
731            _mapper[i]->ScalarVisibilityOn();
732        }
733        if (_lut != NULL) {
734            _lut->SetVectorModeToComponent();
735            _lut->SetVectorComponent(2);
736        }
737        break;
738    default:
739        for (int i = 0; i < 3; i++) {
740            _mapper[i]->ScalarVisibilityOff();
741        }
742        break;
743    }
744}
745
746/**
747 * \brief Called when the color map has been edited
748 */
749void Cutplane::updateColorMap()
750{
751    setColorMap(_colorMap);
752}
753
754/**
755 * \brief Associate a colormap lookup table with the DataSet
756 */
757void Cutplane::setColorMap(ColorMap *cmap)
758{
759    if (cmap == NULL)
760        return;
761
762    _colorMap = cmap;
763 
764    if (_lut == NULL) {
765        _lut = vtkSmartPointer<vtkLookupTable>::New();
766        for (int i = 0; i < 3; i++) {
767            if (_mapper[i] != NULL) {
768                _mapper[i]->UseLookupTableScalarRangeOn();
769                _mapper[i]->SetLookupTable(_lut);
770            }
771        }
772        _lut->DeepCopy(cmap->getLookupTable());
773        switch (_colorMode) {
774        case COLOR_BY_SCALAR:
775            _lut->SetRange(_dataRange);
776            break;
777        case COLOR_BY_VECTOR_MAGNITUDE:
778            _lut->SetRange(_vectorMagnitudeRange);
779            break;
780        case COLOR_BY_VECTOR_X:
781            _lut->SetRange(_vectorComponentRange[0]);
782            break;
783        case COLOR_BY_VECTOR_Y:
784            _lut->SetRange(_vectorComponentRange[1]);
785            break;
786        case COLOR_BY_VECTOR_Z:
787            _lut->SetRange(_vectorComponentRange[2]);
788            break;
789        default:
790            break;
791        }
792    } else {
793        double range[2];
794        _lut->GetTableRange(range);
795        _lut->DeepCopy(cmap->getLookupTable());
796        _lut->SetRange(range);
797        _lut->Modified();
798    }
799
800    switch (_colorMode) {
801    case COLOR_BY_VECTOR_MAGNITUDE:
802        _lut->SetVectorModeToMagnitude();
803        break;
804    case COLOR_BY_VECTOR_X:
805        _lut->SetVectorModeToComponent();
806        _lut->SetVectorComponent(0);
807        break;
808    case COLOR_BY_VECTOR_Y:
809        _lut->SetVectorModeToComponent();
810        _lut->SetVectorComponent(1);
811        break;
812    case COLOR_BY_VECTOR_Z:
813        _lut->SetVectorModeToComponent();
814        _lut->SetVectorComponent(2);
815        break;
816    default:
817         break;
818    }
819}
820
821/**
822 * \brief Turn on/off lighting of this object
823 */
824void Cutplane::setLighting(bool state)
825{
826    _lighting = state;
827    for (int i = 0; i < 3; i++) {
828        if (_actor[i] != NULL)
829            _actor[i]->GetProperty()->SetLighting((state ? 1 : 0));
830    }
831}
832
833/**
834 * \brief Turn on/off rendering of mesh edges
835 */
836void Cutplane::setEdgeVisibility(bool state)
837{
838    for (int i = 0; i < 3; i++) {
839        if (_actor[i] != NULL) {
840            _actor[i]->GetProperty()->SetEdgeVisibility((state ? 1 : 0));
841        }
842    }
843}
844
845/**
846 * \brief Turn on/off rendering of outlines
847 */
848void Cutplane::setOutlineVisibility(bool state)
849{
850    for (int i = 0; i < 3; i++) {
851        if (_borderActor[i] != NULL) {
852            _borderActor[i]->SetVisibility((state ? 1 : 0));
853        }
854    }
855}
856
857/**
858 * \brief Set visibility of cutplane on specified axis
859 */
860void Cutplane::setSliceVisibility(Axis axis, bool state)
861{
862    switch (axis) {
863    case X_AXIS:
864        if (_actor[0] != NULL)
865            _actor[0]->SetVisibility((state ? 1 : 0));
866        if (_borderActor[0] != NULL)
867            _borderActor[0]->SetVisibility((state ? 1 : 0));
868        break;
869    case Y_AXIS:
870        if (_actor[1] != NULL)
871            _actor[1]->SetVisibility((state ? 1 : 0));
872        if (_borderActor[1] != NULL)
873            _borderActor[1]->SetVisibility((state ? 1 : 0));
874        break;
875    case Z_AXIS:
876    default:
877        if (_actor[2] != NULL)
878            _actor[2]->SetVisibility((state ? 1 : 0));
879        if (_borderActor[2] != NULL)
880            _borderActor[2]->SetVisibility((state ? 1 : 0));
881        break;
882    }
883}
884
885/**
886 * \brief Set a group of world coordinate planes to clip rendering
887 *
888 * Passing NULL for planes will remove all cliping planes
889 */
890void Cutplane::setClippingPlanes(vtkPlaneCollection *planes)
891{
892    for (int i = 0; i < 3; i++) {
893        if (_mapper[i] != NULL) {
894            _mapper[i]->SetClippingPlanes(planes);
895        }
896        if (_borderMapper[i] != NULL) {
897            _borderMapper[i]->SetClippingPlanes(planes);
898        }
899    }
900}
Note: See TracBrowser for help on using the repository browser.