source: branches/nanovis2/packages/vizservers/vtkvis/RpWarp.cpp @ 3305

Last change on this file since 3305 was 3305, checked in by ldelgass, 11 years ago

sync with trunk

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