source: branches/vtkvis_threaded/RpPseudoColor.cpp @ 2495

Last change on this file since 2495 was 2459, checked in by ldelgass, 13 years ago

LIC fixes: mask out out-of-bounds sample points from probe filter, run a cutter
before probing to make the probe run faster. A few other misc. cleanups.

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2011, Purdue Research Foundation
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <cassert>
9
10#include <vtkDataSet.h>
11#include <vtkPointData.h>
12#include <vtkDataSetMapper.h>
13#include <vtkUnstructuredGrid.h>
14#include <vtkProperty.h>
15#include <vtkImageData.h>
16#include <vtkLookupTable.h>
17#include <vtkTransform.h>
18#include <vtkDelaunay2D.h>
19#include <vtkDelaunay3D.h>
20#include <vtkGaussianSplatter.h>
21#include <vtkExtractVOI.h>
22#include <vtkDataSetSurfaceFilter.h>
23
24#include "RpPseudoColor.h"
25#include "Trace.h"
26
27#define MESH_POINT_CLOUDS
28
29using namespace Rappture::VtkVis;
30
31PseudoColor::PseudoColor() :
32    VtkGraphicsObject(),
33    _colorMap(NULL)
34{
35}
36
37PseudoColor::~PseudoColor()
38{
39#ifdef WANT_TRACE
40    if (_dataSet != NULL)
41        TRACE("Deleting PseudoColor for %s", _dataSet->getName().c_str());
42    else
43        TRACE("Deleting PseudoColor with NULL DataSet");
44#endif
45}
46
47/**
48 * \brief Internal method to set up pipeline after a state change
49 */
50void PseudoColor::update()
51{
52    if (_dataSet == NULL)
53        return;
54
55    vtkDataSet *ds = _dataSet->getVtkDataSet();
56
57    // Mapper, actor to render color-mapped data set
58    if (_dsMapper == NULL) {
59        _dsMapper = vtkSmartPointer<vtkDataSetMapper>::New();
60        // Map scalars through lookup table regardless of type
61        _dsMapper->SetColorModeToMapScalars();
62    }
63
64    vtkPolyData *pd = vtkPolyData::SafeDownCast(ds);
65    if (pd) {
66        // DataSet is a vtkPolyData
67        if (pd->GetNumberOfLines() == 0 &&
68            pd->GetNumberOfPolys() == 0 &&
69            pd->GetNumberOfStrips() == 0) {
70            // DataSet is a point cloud
71            DataSet::PrincipalPlane plane;
72            double offset;
73            if (_dataSet->is2D(&plane, &offset)) {
74#ifdef MESH_POINT_CLOUDS
75                vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
76                if (plane == DataSet::PLANE_ZY) {
77                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
78                    trans->RotateWXYZ(90, 0, 1, 0);
79                    if (offset != 0.0) {
80                        trans->Translate(-offset, 0, 0);
81                    }
82                    mesher->SetTransform(trans);
83                } else if (plane == DataSet::PLANE_XZ) {
84                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
85                    trans->RotateWXYZ(-90, 1, 0, 0);
86                    if (offset != 0.0) {
87                        trans->Translate(0, -offset, 0);
88                    }
89                    mesher->SetTransform(trans);
90                } else if (offset != 0.0) {
91                    // XY with Z offset
92                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
93                    trans->Translate(0, 0, -offset);
94                    mesher->SetTransform(trans);
95                }
96                mesher->SetInput(pd);
97                _dsMapper->SetInputConnection(mesher->GetOutputPort());
98#else
99                vtkSmartPointer<vtkGaussianSplatter> splatter = vtkSmartPointer<vtkGaussianSplatter>::New();
100                vtkSmartPointer<vtkExtractVOI> slicer = vtkSmartPointer<vtkExtractVOI>::New();
101                splatter->SetInput(pd);
102                int dims[3];
103                splatter->GetSampleDimensions(dims);
104                TRACE("Sample dims: %d %d %d", dims[0], dims[1], dims[2]);
105                if (plane == DataSet::PLANE_ZY) {
106                    dims[0] = 3;
107                    slicer->SetVOI(1, 1, 0, dims[1]-1, 0, dims[1]-1);
108                } else if (plane == DataSet::PLANE_XZ) {
109                    dims[1] = 3;
110                    slicer->SetVOI(0, dims[0]-1, 1, 1, 0, dims[2]-1);
111                } else {
112                    dims[2] = 3;
113                    slicer->SetVOI(0, dims[0]-1, 0, dims[1]-1, 1, 1);
114                }
115                splatter->SetSampleDimensions(dims);
116                double bounds[6];
117                splatter->Update();
118                splatter->GetModelBounds(bounds);
119                TRACE("Model bounds: %g %g %g %g %g %g",
120                      bounds[0], bounds[1],
121                      bounds[2], bounds[3],
122                      bounds[4], bounds[5]);
123                slicer->SetInputConnection(splatter->GetOutputPort());
124                slicer->SetSampleRate(1, 1, 1);
125                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
126                gf->UseStripsOn();
127                gf->SetInputConnection(slicer->GetOutputPort());
128                _dsMapper->SetInputConnection(gf->GetOutputPort());
129#endif
130            } else {
131                vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
132                mesher->SetInput(pd);
133                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
134                gf->SetInputConnection(mesher->GetOutputPort());
135                _dsMapper->SetInputConnection(gf->GetOutputPort());
136             }
137        } else {
138            // DataSet is a vtkPolyData with lines and/or polygons
139            _dsMapper->SetInput(ds);
140        }
141    } else {
142        TRACE("Generating surface for data set");
143        // DataSet is NOT a vtkPolyData
144        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
145        gf->SetInput(ds);
146        _dsMapper->SetInputConnection(gf->GetOutputPort());
147    }
148
149    if (_lut == NULL) {
150        setColorMap(ColorMap::getDefault());
151    }
152    //_dsMapper->InterpolateScalarsBeforeMappingOn();
153
154    initProp();
155    getActor()->SetMapper(_dsMapper);
156    _dsMapper->Update();
157}
158
159void PseudoColor::updateRanges(bool useCumulative,
160                               double scalarRange[2],
161                               double vectorMagnitudeRange[2],
162                               double vectorComponentRange[3][2])
163{
164    if (useCumulative) {
165        _dataRange[0] = scalarRange[0];
166        _dataRange[1] = scalarRange[1];
167    } else if (_dataSet != NULL) {
168        _dataSet->getScalarRange(_dataRange);
169    }
170
171    if (_lut != NULL) {
172        _lut->SetRange(_dataRange);
173    }
174}
175
176/**
177 * \brief Called when the color map has been edited
178 */
179void PseudoColor::updateColorMap()
180{
181    setColorMap(_colorMap);
182}
183
184/**
185 * \brief Associate a colormap lookup table with the DataSet
186 */
187void PseudoColor::setColorMap(ColorMap *cmap)
188{
189    if (cmap == NULL)
190        return;
191
192    _colorMap = cmap;
193 
194    if (_lut == NULL) {
195        _lut = vtkSmartPointer<vtkLookupTable>::New();
196        if (_dsMapper != NULL) {
197            _dsMapper->UseLookupTableScalarRangeOn();
198            _dsMapper->SetLookupTable(_lut);
199        }
200    }
201
202    _lut->DeepCopy(cmap->getLookupTable());
203    _lut->SetRange(_dataRange);
204}
205
206/**
207 * \brief Set a group of world coordinate planes to clip rendering
208 *
209 * Passing NULL for planes will remove all cliping planes
210 */
211void PseudoColor::setClippingPlanes(vtkPlaneCollection *planes)
212{
213    if (_dsMapper != NULL) {
214        _dsMapper->SetClippingPlanes(planes);
215    }
216}
Note: See TracBrowser for help on using the repository browser.