source: vtkvis/trunk/Warp.cpp

Last change on this file was 6458, checked in by ldelgass, 8 years ago

Apply fix from r6408 (setting colormode with empty field name) across all
graphics objects.

  • Property svn:eol-style set to native
File size: 17.2 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 <vtkCellDataToPointData.h>
16#include <vtkPolyDataMapper.h>
17#include <vtkUnstructuredGrid.h>
18#include <vtkProperty.h>
19#include <vtkImageData.h>
20#include <vtkLookupTable.h>
21#include <vtkTransform.h>
22#include <vtkDelaunay2D.h>
23#include <vtkDelaunay3D.h>
24#include <vtkGaussianSplatter.h>
25#include <vtkExtractVOI.h>
26#include <vtkDataSetSurfaceFilter.h>
27#include <vtkVertexGlyphFilter.h>
28
29#include "Warp.h"
30#include "Renderer.h"
31#include "Trace.h"
32
33using namespace VtkVis;
34
35Warp::Warp() :
36    GraphicsObject(),
37    _warpScale(1.0),
38    _cloudStyle(CLOUD_MESH),
39    _colorMap(NULL),
40    _colorMode(COLOR_BY_SCALAR),
41    _colorFieldType(DataSet::POINT_DATA),
42    _renderer(NULL)
43{
44    _colorFieldRange[0] = DBL_MAX;
45    _colorFieldRange[1] = -DBL_MAX;
46}
47
48Warp::~Warp()
49{
50#ifdef WANT_TRACE
51    if (_dataSet != NULL)
52        TRACE("Deleting Warp for %s", _dataSet->getName().c_str());
53    else
54        TRACE("Deleting Warp with NULL DataSet");
55#endif
56}
57
58void Warp::setDataSet(DataSet *dataSet,
59                      Renderer *renderer)
60{
61    if (_dataSet != dataSet) {
62        _dataSet = dataSet;
63
64        _renderer = renderer;
65
66        if (renderer->getUseCumulativeRange()) {
67            renderer->getCumulativeDataRange(_dataRange,
68                                             _dataSet->getActiveScalarsName(),
69                                             1);
70            renderer->getCumulativeDataRange(_vectorMagnitudeRange,
71                                             _dataSet->getActiveVectorsName(),
72                                             3);
73            for (int i = 0; i < 3; i++) {
74                renderer->getCumulativeDataRange(_vectorComponentRange[i],
75                                                 _dataSet->getActiveVectorsName(),
76                                                 3, i);
77            }
78        } else {
79            _dataSet->getScalarRange(_dataRange);
80            _dataSet->getVectorRange(_vectorMagnitudeRange);
81            for (int i = 0; i < 3; i++) {
82                _dataSet->getVectorRange(_vectorComponentRange[i], i);
83            }
84        }
85
86        update();
87    }
88}
89
90/**
91 * \brief Internal method to set up pipeline after a state change
92 */
93void Warp::update()
94{
95    if (_dataSet == NULL)
96        return;
97
98    vtkDataSet *ds = _dataSet->getVtkDataSet();
99
100    if (_warp == NULL) {
101        _warp = vtkSmartPointer<vtkWarpVector>::New();
102    }
103
104    // Mapper, actor to render color-mapped data set
105    if (_mapper == NULL) {
106        _mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
107        // Map scalars through lookup table regardless of type
108        _mapper->SetColorModeToMapScalars();
109    }
110
111    vtkAlgorithmOutput *dsOutput = NULL;
112    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
113    if (ds->GetPointData() == NULL ||
114        ds->GetPointData()->GetVectors() == NULL) {
115        TRACE("No vector point data in dataset %s", _dataSet->getName().c_str());
116        if (ds->GetCellData() != NULL &&
117            ds->GetCellData()->GetVectors() != NULL) {
118            cellToPtData =
119                vtkSmartPointer<vtkCellDataToPointData>::New();
120            cellToPtData->SetInputData(ds);
121            cellToPtData->PassCellDataOn();
122            dsOutput = cellToPtData->GetOutputPort();
123        } else {
124            USER_ERROR("No vector field was found in the data set");
125            return;
126        }
127    } else {
128        dsOutput = _dataSet->getProducerPort();
129    }
130
131    if (_dataSet->isCloud()) {
132        // DataSet is a point cloud
133        if (_cloudStyle == CLOUD_POINTS) {
134            vtkSmartPointer<vtkVertexGlyphFilter> vgf = vtkSmartPointer<vtkVertexGlyphFilter>::New();
135            vgf->SetInputConnection(dsOutput);
136            vtkAlgorithmOutput *warpOutput = initWarp(vgf->GetOutputPort());
137            _mapper->SetInputConnection(warpOutput);
138        } else {
139            PrincipalPlane plane;
140            double offset;
141            if (_dataSet->is2D(&plane, &offset)) {
142                //_cloudStyle == CLOUD_MESH
143                vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
144                if (plane == PLANE_ZY) {
145                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
146                    trans->RotateWXYZ(90, 0, 1, 0);
147                    if (offset != 0.0) {
148                        trans->Translate(-offset, 0, 0);
149                    }
150                    mesher->SetTransform(trans);
151                } else if (plane == PLANE_XZ) {
152                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
153                    trans->RotateWXYZ(-90, 1, 0, 0);
154                    if (offset != 0.0) {
155                        trans->Translate(0, -offset, 0);
156                    }
157                    mesher->SetTransform(trans);
158                } else if (offset != 0.0) {
159                    // XY with Z offset
160                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
161                    trans->Translate(0, 0, -offset);
162                    mesher->SetTransform(trans);
163                }
164                mesher->SetInputConnection(dsOutput);
165                vtkAlgorithmOutput *warpOutput = initWarp(mesher->GetOutputPort());
166                _mapper->SetInputConnection(warpOutput);
167            } else {
168                // Data Set is a 3D point cloud and _cloudStyle == CLOUD_MESH
169                vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
170                mesher->SetInputConnection(dsOutput);
171                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
172                gf->SetInputConnection(mesher->GetOutputPort());
173                vtkAlgorithmOutput *warpOutput = initWarp(gf->GetOutputPort());
174                _mapper->SetInputConnection(warpOutput);
175            }
176        }
177    } else if (vtkPolyData::SafeDownCast(ds) != NULL) {
178        // DataSet is a vtkPolyData with lines and/or polygons
179        vtkAlgorithmOutput *warpOutput = initWarp(dsOutput);
180        _mapper->SetInputConnection(warpOutput);
181    } else {
182        TRACE("Generating surface for data set");
183        // DataSet is NOT a vtkPolyData
184        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
185        gf->SetInputConnection(dsOutput);
186        vtkAlgorithmOutput *warpOutput = initWarp(gf->GetOutputPort());
187        _mapper->SetInputConnection(warpOutput);
188    }
189
190    setInterpolateBeforeMapping(true);
191
192    if (_lut == NULL) {
193        setColorMap(ColorMap::getDefault());
194    }
195
196    if (_dataSet->getActiveScalarsName() != NULL) {
197        TRACE("Setting color mode to scalar");
198        setColorMode(COLOR_BY_SCALAR);
199    } else {
200        TRACE("Setting color mode to vector magnitude");
201        setColorMode(COLOR_BY_VECTOR_MAGNITUDE);
202    }
203
204    initProp();
205    getActor()->SetMapper(_mapper);
206    _mapper->Update();
207}
208
209void Warp::setCloudStyle(CloudStyle style)
210{
211    if (style != _cloudStyle) {
212        _cloudStyle = style;
213        if (_dataSet != NULL) {
214            update();
215        }
216    }
217}
218
219void Warp::setInterpolateBeforeMapping(bool state)
220{
221    if (_mapper != NULL) {
222        _mapper->SetInterpolateScalarsBeforeMapping((state ? 1 : 0));
223    }
224}
225
226vtkAlgorithmOutput *Warp::initWarp(vtkAlgorithmOutput *input)
227{
228    TRACE("Warp scale: %g", _warpScale);
229    if (_warpScale == 0.0) {
230        _warp = NULL;
231        return input;
232    } else if (input == NULL) {
233        ERROR("NULL input");
234        return input;
235    } else {
236        if (_warp == NULL)
237            _warp = vtkSmartPointer<vtkWarpVector>::New();
238        _warp->SetScaleFactor(_warpScale);
239        _warp->SetInputConnection(input);
240        return _warp->GetOutputPort();
241    }
242}
243
244/**
245 * \brief Controls relative scaling of deformation
246 */
247void Warp::setWarpScale(double scale)
248{
249    if (_warpScale == scale)
250        return;
251
252    _warpScale = scale;
253    if (_warp == NULL) {
254        vtkAlgorithmOutput *warpOutput = initWarp(_mapper->GetInputConnection(0, 0));
255        _mapper->SetInputConnection(warpOutput);
256    } else if (scale == 0.0) {
257        vtkAlgorithmOutput *warpInput = _warp->GetInputConnection(0, 0);
258        _mapper->SetInputConnection(warpInput);
259        _warp = NULL;
260    } else {
261        _warp->SetScaleFactor(_warpScale);
262    }
263
264    if (_mapper != NULL)
265        _mapper->Update();
266}
267
268void Warp::updateRanges(Renderer *renderer)
269{
270    if (_dataSet == NULL) {
271        ERROR("called before setDataSet");
272        return;
273    }
274
275    if (renderer->getUseCumulativeRange()) {
276        renderer->getCumulativeDataRange(_dataRange,
277                                         _dataSet->getActiveScalarsName(),
278                                         1);
279        renderer->getCumulativeDataRange(_vectorMagnitudeRange,
280                                         _dataSet->getActiveVectorsName(),
281                                         3);
282        for (int i = 0; i < 3; i++) {
283            renderer->getCumulativeDataRange(_vectorComponentRange[i],
284                                             _dataSet->getActiveVectorsName(),
285                                             3, i);
286        }
287    } else {
288        _dataSet->getScalarRange(_dataRange);
289        _dataSet->getVectorRange(_vectorMagnitudeRange);
290        for (int i = 0; i < 3; i++) {
291            _dataSet->getVectorRange(_vectorComponentRange[i], i);
292        }
293    }
294
295    // Need to update color map ranges
296    double *rangePtr = _colorFieldRange;
297    if (_colorFieldRange[0] > _colorFieldRange[1]) {
298        rangePtr = NULL;
299    }
300    setColorMode(_colorMode, _colorFieldType, _colorFieldName.c_str(), rangePtr);
301}
302
303void Warp::setColorMode(ColorMode mode)
304{
305    _colorMode = mode;
306    if (_dataSet == NULL)
307        return;
308
309    switch (mode) {
310    case COLOR_BY_SCALAR:
311        setColorMode(mode,
312                     _dataSet->getActiveScalarsType(),
313                     _dataSet->getActiveScalarsName());
314        break;
315    case COLOR_BY_VECTOR_MAGNITUDE:
316        setColorMode(mode,
317                     _dataSet->getActiveVectorsType(),
318                     _dataSet->getActiveVectorsName());
319        break;
320    case COLOR_BY_VECTOR_X:
321        setColorMode(mode,
322                     _dataSet->getActiveVectorsType(),
323                     _dataSet->getActiveVectorsName());
324        break;
325    case COLOR_BY_VECTOR_Y:
326        setColorMode(mode,
327                     _dataSet->getActiveVectorsType(),
328                     _dataSet->getActiveVectorsName());
329        break;
330    case COLOR_BY_VECTOR_Z:
331        setColorMode(mode,
332                     _dataSet->getActiveVectorsType(),
333                     _dataSet->getActiveVectorsName());
334        break;
335    case COLOR_CONSTANT:
336    default:
337        setColorMode(mode, DataSet::POINT_DATA, NULL, NULL);
338        break;
339    }
340}
341
342void Warp::setColorMode(ColorMode mode,
343                        const char *name, double range[2])
344{
345    if (_dataSet == NULL)
346        return;
347    DataSet::DataAttributeType type = DataSet::POINT_DATA;
348    int numComponents = 1;
349    if (name != NULL && strlen(name) > 0 &&
350        !_dataSet->getFieldInfo(name, &type, &numComponents)) {
351        ERROR("Field not found: %s", name);
352        return;
353    }
354    setColorMode(mode, type, name, range);
355}
356
357void Warp::setColorMode(ColorMode mode, DataSet::DataAttributeType type,
358                        const char *name, double range[2])
359{
360    _colorMode = mode;
361    _colorFieldType = type;
362    if (name == NULL)
363        _colorFieldName.clear();
364    else
365        _colorFieldName = name;
366    if (range == NULL) {
367        _colorFieldRange[0] = DBL_MAX;
368        _colorFieldRange[1] = -DBL_MAX;
369    } else {
370        memcpy(_colorFieldRange, range, sizeof(double)*2);
371    }
372
373    if (_dataSet == NULL || _mapper == NULL)
374        return;
375
376    switch (type) {
377    case DataSet::POINT_DATA:
378        _mapper->SetScalarModeToUsePointFieldData();
379        break;
380    case DataSet::CELL_DATA:
381        _mapper->SetScalarModeToUseCellFieldData();
382        break;
383    default:
384        ERROR("Unsupported DataAttributeType: %d", type);
385        return;
386    }
387
388    if (name != NULL && strlen(name) > 0) {
389        _mapper->SelectColorArray(name);
390    } else {
391        _mapper->SetScalarModeToDefault();
392    }
393
394    if (_lut != NULL) {
395        if (range != NULL) {
396            _lut->SetRange(range);
397        } else if (name != NULL && strlen(name) > 0) {
398            double r[2];
399            int comp = -1;
400            if (mode == COLOR_BY_VECTOR_X)
401                comp = 0;
402            else if (mode == COLOR_BY_VECTOR_Y)
403                comp = 1;
404            else if (mode == COLOR_BY_VECTOR_Z)
405                comp = 2;
406
407            if (_renderer->getUseCumulativeRange()) {
408                int numComponents;
409                if  (!_dataSet->getFieldInfo(name, type, &numComponents)) {
410                    ERROR("Field not found: %s, type: %d", name, type);
411                    return;
412                } else if (numComponents < comp+1) {
413                    ERROR("Request for component %d in field with %d components",
414                          comp, numComponents);
415                    return;
416                }
417                _renderer->getCumulativeDataRange(r, name, type, numComponents, comp);
418            } else {
419                _dataSet->getDataRange(r, name, type, comp);
420            }
421            _lut->SetRange(r);
422        } else {
423            switch (mode) {
424            case COLOR_CONSTANT:
425            case COLOR_BY_SCALAR:
426                _lut->SetRange(_dataRange);
427                break;
428            case COLOR_BY_VECTOR_MAGNITUDE:
429                _lut->SetRange(_vectorMagnitudeRange);
430                break;
431            case COLOR_BY_VECTOR_X:
432                _lut->SetRange(_vectorComponentRange[0]);
433                break;
434            case COLOR_BY_VECTOR_Y:
435                _lut->SetRange(_vectorComponentRange[1]);
436                break;
437            case COLOR_BY_VECTOR_Z:
438                _lut->SetRange(_vectorComponentRange[2]);
439                break;
440            default:
441                break;
442            }
443        }
444    }
445
446    switch (mode) {
447    case COLOR_BY_SCALAR:
448        _mapper->ScalarVisibilityOn();
449        break;
450    case COLOR_BY_VECTOR_MAGNITUDE:
451        _mapper->ScalarVisibilityOn();
452        if (_lut != NULL) {
453            _lut->SetVectorModeToMagnitude();
454        }
455        break;
456    case COLOR_BY_VECTOR_X:
457        _mapper->ScalarVisibilityOn();
458        if (_lut != NULL) {
459            _lut->SetVectorModeToComponent();
460            _lut->SetVectorComponent(0);
461        }
462        break;
463    case COLOR_BY_VECTOR_Y:
464        _mapper->ScalarVisibilityOn();
465        if (_lut != NULL) {
466            _lut->SetVectorModeToComponent();
467            _lut->SetVectorComponent(1);
468        }
469        break;
470    case COLOR_BY_VECTOR_Z:
471        _mapper->ScalarVisibilityOn();
472        if (_lut != NULL) {
473            _lut->SetVectorModeToComponent();
474            _lut->SetVectorComponent(2);
475        }
476        break;
477    case COLOR_CONSTANT:
478    default:
479        _mapper->ScalarVisibilityOff();
480        break;
481    }
482}
483
484/**
485 * \brief Called when the color map has been edited
486 */
487void Warp::updateColorMap()
488{
489    setColorMap(_colorMap);
490}
491
492/**
493 * \brief Associate a colormap lookup table with the DataSet
494 */
495void Warp::setColorMap(ColorMap *cmap)
496{
497    if (cmap == NULL)
498        return;
499
500    _colorMap = cmap;
501 
502    if (_lut == NULL) {
503        _lut = vtkSmartPointer<vtkLookupTable>::New();
504        if (_mapper != NULL) {
505            _mapper->UseLookupTableScalarRangeOn();
506            _mapper->SetLookupTable(_lut);
507        }
508        _lut->DeepCopy(cmap->getLookupTable());
509        switch (_colorMode) {
510        case COLOR_CONSTANT:
511        case COLOR_BY_SCALAR:
512            _lut->SetRange(_dataRange);
513            break;
514        case COLOR_BY_VECTOR_MAGNITUDE:
515            _lut->SetRange(_vectorMagnitudeRange);
516            break;
517        case COLOR_BY_VECTOR_X:
518            _lut->SetRange(_vectorComponentRange[0]);
519            break;
520        case COLOR_BY_VECTOR_Y:
521            _lut->SetRange(_vectorComponentRange[1]);
522            break;
523        case COLOR_BY_VECTOR_Z:
524            _lut->SetRange(_vectorComponentRange[2]);
525            break;
526        default:
527            break;
528        }
529    } else {
530        double range[2];
531        _lut->GetTableRange(range);
532        _lut->DeepCopy(cmap->getLookupTable());
533        _lut->SetRange(range);
534        _lut->Modified();
535    }
536
537    switch (_colorMode) {
538    case COLOR_BY_VECTOR_MAGNITUDE:
539        _lut->SetVectorModeToMagnitude();
540        break;
541    case COLOR_BY_VECTOR_X:
542        _lut->SetVectorModeToComponent();
543        _lut->SetVectorComponent(0);
544        break;
545    case COLOR_BY_VECTOR_Y:
546        _lut->SetVectorModeToComponent();
547        _lut->SetVectorComponent(1);
548        break;
549    case COLOR_BY_VECTOR_Z:
550        _lut->SetVectorModeToComponent();
551        _lut->SetVectorComponent(2);
552        break;
553    default:
554         break;
555    }
556}
557
558/**
559 * \brief Set a group of world coordinate planes to clip rendering
560 *
561 * Passing NULL for planes will remove all cliping planes
562 */
563void Warp::setClippingPlanes(vtkPlaneCollection *planes)
564{
565    if (_mapper != NULL) {
566        _mapper->SetClippingPlanes(planes);
567    }
568}
Note: See TracBrowser for help on using the repository browser.