source: vtkvis/trunk/Warp.cpp @ 6369

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

merge r5843:5844 from 1.8 branch

  • Property svn:eol-style set to native
File size: 16.5 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        }
423    }
424
425    switch (mode) {
426    case COLOR_BY_SCALAR:
427        _mapper->ScalarVisibilityOn();
428        break;
429    case COLOR_BY_VECTOR_MAGNITUDE:
430        _mapper->ScalarVisibilityOn();
431        if (_lut != NULL) {
432            _lut->SetVectorModeToMagnitude();
433        }
434        break;
435    case COLOR_BY_VECTOR_X:
436        _mapper->ScalarVisibilityOn();
437        if (_lut != NULL) {
438            _lut->SetVectorModeToComponent();
439            _lut->SetVectorComponent(0);
440        }
441        break;
442    case COLOR_BY_VECTOR_Y:
443        _mapper->ScalarVisibilityOn();
444        if (_lut != NULL) {
445            _lut->SetVectorModeToComponent();
446            _lut->SetVectorComponent(1);
447        }
448        break;
449    case COLOR_BY_VECTOR_Z:
450        _mapper->ScalarVisibilityOn();
451        if (_lut != NULL) {
452            _lut->SetVectorModeToComponent();
453            _lut->SetVectorComponent(2);
454        }
455        break;
456    case COLOR_CONSTANT:
457    default:
458        _mapper->ScalarVisibilityOff();
459        break;
460    }
461}
462
463/**
464 * \brief Called when the color map has been edited
465 */
466void Warp::updateColorMap()
467{
468    setColorMap(_colorMap);
469}
470
471/**
472 * \brief Associate a colormap lookup table with the DataSet
473 */
474void Warp::setColorMap(ColorMap *cmap)
475{
476    if (cmap == NULL)
477        return;
478
479    _colorMap = cmap;
480 
481    if (_lut == NULL) {
482        _lut = vtkSmartPointer<vtkLookupTable>::New();
483        if (_mapper != NULL) {
484            _mapper->UseLookupTableScalarRangeOn();
485            _mapper->SetLookupTable(_lut);
486        }
487        _lut->DeepCopy(cmap->getLookupTable());
488        switch (_colorMode) {
489        case COLOR_CONSTANT:
490        case COLOR_BY_SCALAR:
491            _lut->SetRange(_dataRange);
492            break;
493        case COLOR_BY_VECTOR_MAGNITUDE:
494            _lut->SetRange(_vectorMagnitudeRange);
495            break;
496        case COLOR_BY_VECTOR_X:
497            _lut->SetRange(_vectorComponentRange[0]);
498            break;
499        case COLOR_BY_VECTOR_Y:
500            _lut->SetRange(_vectorComponentRange[1]);
501            break;
502        case COLOR_BY_VECTOR_Z:
503            _lut->SetRange(_vectorComponentRange[2]);
504            break;
505        default:
506            break;
507        }
508    } else {
509        double range[2];
510        _lut->GetTableRange(range);
511        _lut->DeepCopy(cmap->getLookupTable());
512        _lut->SetRange(range);
513        _lut->Modified();
514    }
515
516    switch (_colorMode) {
517    case COLOR_BY_VECTOR_MAGNITUDE:
518        _lut->SetVectorModeToMagnitude();
519        break;
520    case COLOR_BY_VECTOR_X:
521        _lut->SetVectorModeToComponent();
522        _lut->SetVectorComponent(0);
523        break;
524    case COLOR_BY_VECTOR_Y:
525        _lut->SetVectorModeToComponent();
526        _lut->SetVectorComponent(1);
527        break;
528    case COLOR_BY_VECTOR_Z:
529        _lut->SetVectorModeToComponent();
530        _lut->SetVectorComponent(2);
531        break;
532    default:
533         break;
534    }
535}
536
537/**
538 * \brief Set a group of world coordinate planes to clip rendering
539 *
540 * Passing NULL for planes will remove all cliping planes
541 */
542void Warp::setClippingPlanes(vtkPlaneCollection *planes)
543{
544    if (_mapper != NULL) {
545        _mapper->SetClippingPlanes(planes);
546    }
547}
Note: See TracBrowser for help on using the repository browser.