source: vtkvis/trunk/Cutplane.cpp @ 6307

Last change on this file since 6307 was 5835, checked in by ldelgass, 9 years ago

Require VTK >= 6.0.0

  • Property svn:eol-style set to native
File size: 29.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 <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                    mesher->SetInputData(ds);
233                    for (int i = 0; i < 3; i++) {
234                        _mapper[i]->SetInputConnection(mesher->GetOutputPort());
235                    }
236                } else {
237                    // _cloudStyle == CLOUD_SPLAT
238                    if (_splatter == NULL) {
239                        _splatter = vtkSmartPointer<vtkGaussianSplatter>::New();
240                    }
241                    _splatter->SetInputData(ds);
242                    int dims[3];
243                    _splatter->GetSampleDimensions(dims);
244                    TRACE("Sample dims: %d %d %d", dims[0], dims[1], dims[2]);
245                    if (plane == PLANE_ZY) {
246                        dims[0] = 3;
247                    } else if (plane == PLANE_XZ) {
248                        dims[1] = 3;
249                    } else {
250                        dims[2] = 3;
251                    }
252                    _splatter->SetSampleDimensions(dims);
253                    for (int i = 0; i < 3; i++) {
254                        _cutter[i]->SetInputConnection(_splatter->GetOutputPort());
255                        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
256                        gf->UseStripsOn();
257                        gf->SetInputConnection(_cutter[i]->GetOutputPort());
258                        _mapper[i]->SetInputConnection(gf->GetOutputPort());
259                    }
260                }
261            } else {
262                if (_cloudStyle == CLOUD_MESH) {
263                    // Data Set is a 3D point cloud
264                    // Result of Delaunay3D mesher is unstructured grid
265                    vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
266                    mesher->SetInputData(ds);
267                    // Sample a plane within the grid bounding box
268                    for (int i = 0; i < 3; i++) {
269                        _cutter[i]->SetInputConnection(mesher->GetOutputPort());
270                        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
271                        gf->UseStripsOn();
272                        gf->SetInputConnection(_cutter[i]->GetOutputPort());
273                        _mapper[i]->SetInputConnection(gf->GetOutputPort());
274                    }
275                } else {
276                    // _cloudStyle == CLOUD_SPLAT
277                    if (_splatter == NULL) {
278                        _splatter = vtkSmartPointer<vtkGaussianSplatter>::New();
279                    }
280                    _splatter->SetInputData(ds);
281                    int dims[3];
282                    dims[0] = dims[1] = dims[2] = 64;
283                    TRACE("Generating volume with dims (%d,%d,%d) from point cloud",
284                          dims[0], dims[1], dims[2]);
285                    _splatter->SetSampleDimensions(dims);
286                    for (int i = 0; i < 3; i++) {
287                        _cutter[i]->SetInputConnection(_splatter->GetOutputPort());
288                        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
289                        gf->UseStripsOn();
290                        gf->SetInputConnection(_cutter[i]->GetOutputPort());
291                        _mapper[i]->SetInputConnection(gf->GetOutputPort());
292                    }
293                }
294            }
295        } else {
296            // DataSet can be: image/volume/uniform grid, structured grid, unstructured grid, rectilinear grid, or
297            // PolyData with cells other than points
298            PrincipalPlane plane;
299            double offset;
300            if (!_dataSet->is2D(&plane, &offset)) {
301                // Sample a plane within the grid bounding box
302                for (int i = 0; i < 3; i++) {
303                    _cutter[i]->SetInputData(ds);
304                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
305                    gf->UseStripsOn();
306                    gf->SetInputConnection(_cutter[i]->GetOutputPort());
307                    _mapper[i]->SetInputConnection(gf->GetOutputPort());
308                }
309            } else {
310                // 2D data
311                if (plane == PLANE_ZY) {
312                    _actor[1]->VisibilityOff();
313                    _actor[2]->VisibilityOff();
314                } else if (plane == PLANE_XZ) {
315                    _actor[0]->VisibilityOff();
316                    _actor[2]->VisibilityOff();
317                } else if (offset != 0.0) {
318                    // XY with Z offset
319                    _actor[0]->VisibilityOff();
320                    _actor[1]->VisibilityOff();
321                }
322                for (int i = 0; i < 3; i++) {
323                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
324                    gf->UseStripsOn();
325                    gf->SetInputData(ds);
326                    _mapper[i]->SetInputConnection(gf->GetOutputPort());
327                }
328            }
329        }
330    }
331
332    for (int i = 0; i < 3; i++) {
333        if (_mapper[i] != NULL && _borderMapper[i] == NULL) {
334            _borderMapper[i] = vtkSmartPointer<vtkPolyDataMapper>::New();
335#ifdef CUTPLANE_TIGHT_OUTLINE
336            _outlineFilter[i] = vtkSmartPointer<vtkOutlineFilter>::New();
337            _outlineFilter[i]->SetInputConnection(_mapper[i]->GetInputConnection(0, 0));
338            _borderMapper[i]->SetInputConnection(_outlineFilter[i]->GetOutputPort());
339#else
340            _outlineSource[i] = vtkSmartPointer<vtkOutlineSource>::New();
341            switch (i) {
342            case 0:
343                _outlineSource[i]->SetBounds(bounds[0] + (bounds[1]-bounds[0])/2.,
344                                             bounds[0] + (bounds[1]-bounds[0])/2.,
345                                             bounds[2], bounds[3],
346                                             bounds[4], bounds[5]);
347                break;
348            case 1:
349                _outlineSource[i]->SetBounds(bounds[0], bounds[1],
350                                             bounds[2] + (bounds[3]-bounds[2])/2.,
351                                             bounds[2] + (bounds[3]-bounds[2])/2.,
352                                             bounds[4], bounds[5]);
353                break;
354            case 2:
355                _outlineSource[i]->SetBounds(bounds[0], bounds[1],
356                                             bounds[2], bounds[3],
357                                             bounds[4] + (bounds[5]-bounds[4])/2.,
358                                             bounds[4] + (bounds[5]-bounds[4])/2.);
359                break;
360            default:
361                ;
362            }
363            _borderMapper[i]->SetInputConnection(_outlineSource[i]->GetOutputPort());
364#endif
365            _borderMapper[i]->SetResolveCoincidentTopologyToPolygonOffset();
366        }
367    }
368
369    setInterpolateBeforeMapping(true);
370
371    if (_lut == NULL) {
372        setColorMap(ColorMap::getDefault());
373        if (ds->GetPointData()->GetScalars() == NULL &&
374            ds->GetPointData()->GetVectors() != NULL) {
375            TRACE("Setting color mode to vector magnitude");
376            setColorMode(COLOR_BY_VECTOR_MAGNITUDE);
377        } else {
378            TRACE("Setting color mode to scalar");
379            setColorMode(COLOR_BY_SCALAR);
380        }
381    } else if (!_pipelineInitialized) {
382        double *rangePtr = _colorFieldRange;
383        if (_colorFieldRange[0] > _colorFieldRange[1]) {
384            rangePtr = NULL;
385        }
386        setColorMode(_colorMode, _colorFieldType, _colorFieldName.c_str(), rangePtr);
387    }
388
389    _pipelineInitialized = true;
390
391    for (int i = 0; i < 3; i++) {
392        if (_mapper[i] != NULL) {
393            _actor[i]->SetMapper(_mapper[i]);
394            _mapper[i]->Update();
395        }
396        if (_borderMapper[i] != NULL) {
397            _borderActor[i]->SetMapper(_borderMapper[i]);
398            _borderMapper[i]->Update();
399        }
400        // Only add cutter actor to assembly if geometry was
401        // produced, in order to prevent messing up assembly bounds
402        double bounds[6];
403        _actor[i]->GetBounds(bounds);
404        if (bounds[0] <= bounds[1]) {
405            getAssembly()->AddPart(_actor[i]);
406        }
407    }
408}
409
410void Cutplane::setCloudStyle(CloudStyle style)
411{
412    if (style != _cloudStyle) {
413        _cloudStyle = style;
414        if (_dataSet != NULL) {
415            _pipelineInitialized = false;
416            update();
417        }
418    }
419}
420
421void Cutplane::setInterpolateBeforeMapping(bool state)
422{
423    for (int i = 0; i < 3; i++) {
424        if (_mapper[i] != NULL) {
425            _mapper[i]->SetInterpolateScalarsBeforeMapping((state ? 1 : 0));
426        }
427    }
428}
429
430/**
431 * \brief Select a 2D slice plane from a 3D DataSet
432 *
433 * \param[in] axis Axis of slice plane
434 * \param[in] ratio Position [0,1] of slice plane along axis
435 */
436void Cutplane::selectVolumeSlice(Axis axis, double ratio)
437{
438    if (_dataSet->is2D()) {
439        WARN("DataSet not 3D, returning");
440        return;
441    }
442
443    if ((axis == X_AXIS &&_cutPlane[0] == NULL) ||
444        (axis == Y_AXIS &&_cutPlane[1] == NULL) ||
445        (axis == Z_AXIS &&_cutPlane[2] == NULL)) {
446        WARN("Called before update() or DataSet is not a volume");
447        return;
448    }
449
450    double bounds[6];
451    _dataSet->getBounds(bounds);
452#if 0
453    if (ratio == 0.0)
454        ratio = 0.001;
455    if (ratio == 1.0)
456        ratio = 0.999;
457#endif
458    switch (axis) {
459    case X_AXIS:
460        _cutPlane[0]->SetOrigin(bounds[0] + (bounds[1]-bounds[0]) * ratio,
461                                0,
462                                0);
463#ifndef CUTPLANE_TIGHT_OUTLINE
464        _outlineSource[0]->SetBounds(bounds[0] + (bounds[1]-bounds[0]) * ratio,
465                                     bounds[0] + (bounds[1]-bounds[0]) * ratio,
466                                     bounds[2], bounds[3],
467                                     bounds[4], bounds[5]);
468#endif
469        break;
470    case Y_AXIS:
471        _cutPlane[1]->SetOrigin(0,
472                                bounds[2] + (bounds[3]-bounds[2]) * ratio,
473                                0);
474#ifndef CUTPLANE_TIGHT_OUTLINE
475        _outlineSource[1]->SetBounds(bounds[0], bounds[1],
476                                     bounds[2] + (bounds[3]-bounds[2]) * ratio,
477                                     bounds[2] + (bounds[3]-bounds[2]) * ratio,
478                                     bounds[4], bounds[5]);
479#endif
480        break;
481    case Z_AXIS:
482        _cutPlane[2]->SetOrigin(0,
483                                0,
484                                bounds[4] + (bounds[5]-bounds[4]) * ratio);
485#ifndef CUTPLANE_TIGHT_OUTLINE
486        _outlineSource[2]->SetBounds(bounds[0], bounds[1],
487                                     bounds[2], bounds[3],
488                                     bounds[4] + (bounds[5]-bounds[4]) * ratio,
489                                     bounds[4] + (bounds[5]-bounds[4]) * ratio);
490#endif
491        break;
492    default:
493        ERROR("Invalid Axis");
494        return;
495    }
496    update();
497}
498
499void Cutplane::updateRanges(Renderer *renderer)
500{
501    if (_dataSet == NULL) {
502        ERROR("called before setDataSet");
503        return;
504    }
505
506    if (renderer->getUseCumulativeRange()) {
507        renderer->getCumulativeDataRange(_dataRange,
508                                         _dataSet->getActiveScalarsName(),
509                                         1);
510        renderer->getCumulativeDataRange(_vectorMagnitudeRange,
511                                         _dataSet->getActiveVectorsName(),
512                                         3);
513        for (int i = 0; i < 3; i++) {
514            renderer->getCumulativeDataRange(_vectorComponentRange[i],
515                                             _dataSet->getActiveVectorsName(),
516                                             3, i);
517        }
518    } else {
519        _dataSet->getScalarRange(_dataRange);
520        _dataSet->getVectorRange(_vectorMagnitudeRange);
521        for (int i = 0; i < 3; i++) {
522            _dataSet->getVectorRange(_vectorComponentRange[i], i);
523        }
524    }
525
526    // Need to update color map ranges
527    double *rangePtr = _colorFieldRange;
528    if (_colorFieldRange[0] > _colorFieldRange[1]) {
529        rangePtr = NULL;
530    }
531    setColorMode(_colorMode, _colorFieldType, _colorFieldName.c_str(), rangePtr);
532}
533
534void Cutplane::setColorMode(ColorMode mode)
535{
536    _colorMode = mode;
537    if (_dataSet == NULL)
538        return;
539
540    switch (mode) {
541    case COLOR_BY_SCALAR:
542        setColorMode(mode,
543                     _dataSet->getActiveScalarsType(),
544                     _dataSet->getActiveScalarsName());
545        break;
546    case COLOR_BY_VECTOR_MAGNITUDE:
547        setColorMode(mode,
548                     _dataSet->getActiveVectorsType(),
549                     _dataSet->getActiveVectorsName());
550        break;
551    case COLOR_BY_VECTOR_X:
552        setColorMode(mode,
553                     _dataSet->getActiveVectorsType(),
554                     _dataSet->getActiveVectorsName());
555        break;
556    case COLOR_BY_VECTOR_Y:
557        setColorMode(mode,
558                     _dataSet->getActiveVectorsType(),
559                     _dataSet->getActiveVectorsName());
560        break;
561    case COLOR_BY_VECTOR_Z:
562        setColorMode(mode,
563                     _dataSet->getActiveVectorsType(),
564                     _dataSet->getActiveVectorsName());
565        break;
566    default:
567        ;
568    }
569}
570
571void Cutplane::setColorMode(ColorMode mode,
572                            const char *name, double range[2])
573{
574    if (_dataSet == NULL)
575        return;
576    DataSet::DataAttributeType type;
577    int numComponents;
578    if (!_dataSet->getFieldInfo(name, &type, &numComponents)) {
579        ERROR("Field not found: %s", name);
580        return;
581    }
582    setColorMode(mode, type, name, range);
583}
584
585void Cutplane::setColorMode(ColorMode mode,
586                            DataSet::DataAttributeType type,
587                            const char *name, double range[2])
588{
589    _colorMode = mode;
590    _colorFieldType = type;
591    if (name == NULL)
592        _colorFieldName.clear();
593    else
594        _colorFieldName = name;
595    if (range == NULL) {
596        _colorFieldRange[0] = DBL_MAX;
597        _colorFieldRange[1] = -DBL_MAX;
598    } else {
599        memcpy(_colorFieldRange, range, sizeof(double)*2);
600    }
601
602    if (_dataSet == NULL ||
603        _mapper[0] == NULL ||
604        _mapper[1] == NULL ||
605        _mapper[2] == NULL)
606        return;
607
608    switch (type) {
609    case DataSet::POINT_DATA:
610        for (int i = 0; i < 3; i++) {
611            _mapper[i]->SetScalarModeToUsePointFieldData();
612        }
613        break;
614    case DataSet::CELL_DATA:
615        for (int i = 0; i < 3; i++) {
616            _mapper[i]->SetScalarModeToUseCellFieldData();
617        }
618        break;
619    default:
620        ERROR("Unsupported DataAttributeType: %d", type);
621        return;
622    }
623
624    if (_splatter != NULL) {
625        if (name != NULL && strlen(name) > 0) {
626            _splatter->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, name);
627        }
628        for (int i = 0; i < 3; i++) {
629            _mapper[i]->SelectColorArray("SplatterValues");
630        }
631    } else if (name != NULL && strlen(name) > 0) {
632        for (int i = 0; i < 3; i++) {
633            _mapper[i]->SelectColorArray(name);
634        }
635    } else {
636        for (int i = 0; i < 3; i++) {
637            _mapper[i]->SetScalarModeToDefault();
638        }
639    }
640
641    if (_lut != NULL) {
642        if (range != NULL) {
643            _lut->SetRange(range);
644        } else if (name != NULL && strlen(name) > 0) {
645            double r[2];
646            int comp = -1;
647            if (mode == COLOR_BY_VECTOR_X)
648                comp = 0;
649            else if (mode == COLOR_BY_VECTOR_Y)
650                comp = 1;
651            else if (mode == COLOR_BY_VECTOR_Z)
652                comp = 2;
653
654            if (_renderer->getUseCumulativeRange()) {
655                int numComponents;
656                if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
657                    ERROR("Field not found: %s, type: %d", name, type);
658                    return;
659                } else if (numComponents < comp+1) {
660                    ERROR("Request for component %d in field with %d components",
661                          comp, numComponents);
662                    return;
663                }
664                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
665            } else {
666                _dataSet->getDataRange(r, name, type, comp);
667            }
668            _lut->SetRange(r);
669        }
670    }
671
672
673    switch (mode) {
674    case COLOR_BY_SCALAR:
675        for (int i = 0; i < 3; i++) {
676            _mapper[i]->ScalarVisibilityOn();
677        }
678        break;
679    case COLOR_BY_VECTOR_MAGNITUDE:
680        for (int i = 0; i < 3; i++) {
681            _mapper[i]->ScalarVisibilityOn();
682        }
683        if (_lut != NULL) {
684            _lut->SetVectorModeToMagnitude();
685        }
686        break;
687    case COLOR_BY_VECTOR_X:
688        for (int i = 0; i < 3; i++) {
689            _mapper[i]->ScalarVisibilityOn();
690        }
691        if (_lut != NULL) {
692            _lut->SetVectorModeToComponent();
693            _lut->SetVectorComponent(0);
694        }
695        break;
696    case COLOR_BY_VECTOR_Y:
697        for (int i = 0; i < 3; i++) {
698            _mapper[i]->ScalarVisibilityOn();
699        }
700        if (_lut != NULL) {
701            _lut->SetVectorModeToComponent();
702            _lut->SetVectorComponent(1);
703        }
704        break;
705    case COLOR_BY_VECTOR_Z:
706        for (int i = 0; i < 3; i++) {
707            _mapper[i]->ScalarVisibilityOn();
708        }
709        if (_lut != NULL) {
710            _lut->SetVectorModeToComponent();
711            _lut->SetVectorComponent(2);
712        }
713        break;
714    default:
715        for (int i = 0; i < 3; i++) {
716            _mapper[i]->ScalarVisibilityOff();
717        }
718        break;
719    }
720}
721
722/**
723 * \brief Called when the color map has been edited
724 */
725void Cutplane::updateColorMap()
726{
727    setColorMap(_colorMap);
728}
729
730/**
731 * \brief Associate a colormap lookup table with the DataSet
732 */
733void Cutplane::setColorMap(ColorMap *cmap)
734{
735    if (cmap == NULL)
736        return;
737
738    _colorMap = cmap;
739 
740    if (_lut == NULL) {
741        _lut = vtkSmartPointer<vtkLookupTable>::New();
742        for (int i = 0; i < 3; i++) {
743            if (_mapper[i] != NULL) {
744                _mapper[i]->UseLookupTableScalarRangeOn();
745                _mapper[i]->SetLookupTable(_lut);
746            }
747        }
748        _lut->DeepCopy(cmap->getLookupTable());
749        switch (_colorMode) {
750        case COLOR_BY_SCALAR:
751            _lut->SetRange(_dataRange);
752            break;
753        case COLOR_BY_VECTOR_MAGNITUDE:
754            _lut->SetRange(_vectorMagnitudeRange);
755            break;
756        case COLOR_BY_VECTOR_X:
757            _lut->SetRange(_vectorComponentRange[0]);
758            break;
759        case COLOR_BY_VECTOR_Y:
760            _lut->SetRange(_vectorComponentRange[1]);
761            break;
762        case COLOR_BY_VECTOR_Z:
763            _lut->SetRange(_vectorComponentRange[2]);
764            break;
765        default:
766            break;
767        }
768    } else {
769        double range[2];
770        _lut->GetTableRange(range);
771        _lut->DeepCopy(cmap->getLookupTable());
772        _lut->SetRange(range);
773        _lut->Modified();
774    }
775
776    switch (_colorMode) {
777    case COLOR_BY_VECTOR_MAGNITUDE:
778        _lut->SetVectorModeToMagnitude();
779        break;
780    case COLOR_BY_VECTOR_X:
781        _lut->SetVectorModeToComponent();
782        _lut->SetVectorComponent(0);
783        break;
784    case COLOR_BY_VECTOR_Y:
785        _lut->SetVectorModeToComponent();
786        _lut->SetVectorComponent(1);
787        break;
788    case COLOR_BY_VECTOR_Z:
789        _lut->SetVectorModeToComponent();
790        _lut->SetVectorComponent(2);
791        break;
792    default:
793         break;
794    }
795}
796
797/**
798 * \brief Turn on/off lighting of this object
799 */
800void Cutplane::setLighting(bool state)
801{
802    _lighting = state;
803    for (int i = 0; i < 3; i++) {
804        if (_actor[i] != NULL)
805            _actor[i]->GetProperty()->SetLighting((state ? 1 : 0));
806    }
807}
808
809/**
810 * \brief Turn on/off rendering of mesh edges
811 */
812void Cutplane::setEdgeVisibility(bool state)
813{
814    for (int i = 0; i < 3; i++) {
815        if (_actor[i] != NULL) {
816            _actor[i]->GetProperty()->SetEdgeVisibility((state ? 1 : 0));
817        }
818    }
819}
820
821/**
822 * \brief Turn on/off rendering of outlines
823 */
824void Cutplane::setOutlineVisibility(bool state)
825{
826    for (int i = 0; i < 3; i++) {
827        if (_borderActor[i] != NULL) {
828            _borderActor[i]->SetVisibility((state ? 1 : 0));
829        }
830    }
831}
832
833/**
834 * \brief Set visibility of cutplane on specified axis
835 */
836void Cutplane::setSliceVisibility(Axis axis, bool state)
837{
838    switch (axis) {
839    case X_AXIS:
840        if (_actor[0] != NULL)
841            _actor[0]->SetVisibility((state ? 1 : 0));
842        if (_borderActor[0] != NULL)
843            _borderActor[0]->SetVisibility((state ? 1 : 0));
844        break;
845    case Y_AXIS:
846        if (_actor[1] != NULL)
847            _actor[1]->SetVisibility((state ? 1 : 0));
848        if (_borderActor[1] != NULL)
849            _borderActor[1]->SetVisibility((state ? 1 : 0));
850        break;
851    case Z_AXIS:
852    default:
853        if (_actor[2] != NULL)
854            _actor[2]->SetVisibility((state ? 1 : 0));
855        if (_borderActor[2] != NULL)
856            _borderActor[2]->SetVisibility((state ? 1 : 0));
857        break;
858    }
859}
860
861/**
862 * \brief Set a group of world coordinate planes to clip rendering
863 *
864 * Passing NULL for planes will remove all cliping planes
865 */
866void Cutplane::setClippingPlanes(vtkPlaneCollection *planes)
867{
868    for (int i = 0; i < 3; i++) {
869        if (_mapper[i] != NULL) {
870            _mapper[i]->SetClippingPlanes(planes);
871        }
872        if (_borderMapper[i] != NULL) {
873            _borderMapper[i]->SetClippingPlanes(planes);
874        }
875    }
876}
Note: See TracBrowser for help on using the repository browser.