source: vtkvis/trunk/Warp.cpp @ 5835

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

Require VTK >= 6.0.0

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