source: branches/blt4/packages/vizservers/vtkvis/RpContour3D.cpp @ 2542

Last change on this file since 2542 was 2542, checked in by gah, 13 years ago

update from trunk

File size: 6.6 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 <vtkCellData.h>
13#include <vtkCellDataToPointData.h>
14#include <vtkContourFilter.h>
15#include <vtkPolyDataMapper.h>
16#include <vtkUnstructuredGrid.h>
17#include <vtkProperty.h>
18#include <vtkDelaunay2D.h>
19#include <vtkDelaunay3D.h>
20#include <vtkDataSetSurfaceFilter.h>
21
22#include "RpContour3D.h"
23#include "Trace.h"
24
25using namespace Rappture::VtkVis;
26
27Contour3D::Contour3D(int numContours) :
28    VtkGraphicsObject(),
29    _numContours(numContours),
30    _colorMap(NULL)
31{
32    _color[0] = 0.0f;
33    _color[1] = 0.0f;
34    _color[2] = 1.0f;
35}
36
37Contour3D::Contour3D(const std::vector<double>& contours) :
38    VtkGraphicsObject(),
39    _numContours(contours.size()),
40    _contours(contours),
41    _colorMap(NULL)
42{
43    _color[0] = 0.0f;
44    _color[1] = 0.0f;
45    _color[2] = 1.0f;
46}
47
48Contour3D::~Contour3D()
49{
50#ifdef WANT_TRACE
51    if (_dataSet != NULL)
52        TRACE("Deleting Contour3D for %s", _dataSet->getName().c_str());
53    else
54        TRACE("Deleting Contour3D with NULL DataSet");
55#endif
56}
57
58/**
59 * \brief Called when the color map has been edited
60 */
61void Contour3D::updateColorMap()
62{
63    setColorMap(_colorMap);
64}
65
66/**
67 * \brief Associate a colormap lookup table with the DataSet
68 */
69void Contour3D::setColorMap(ColorMap *cmap)
70{
71    if (cmap == NULL)
72        return;
73
74    _colorMap = cmap;
75 
76    if (_lut == NULL) {
77        _lut = vtkSmartPointer<vtkLookupTable>::New();
78        if (_contourMapper != NULL) {
79            _contourMapper->UseLookupTableScalarRangeOn();
80            _contourMapper->SetLookupTable(_lut);
81        }
82    }
83
84    _lut->DeepCopy(cmap->getLookupTable());
85    _lut->SetRange(_dataRange);
86}
87
88/**
89 * \brief Internal method to re-compute contours after a state change
90 */
91void Contour3D::update()
92{
93    if (_dataSet == NULL) {
94        return;
95    }
96    vtkDataSet *ds = _dataSet->getVtkDataSet();
97
98    initProp();
99
100    if (_dataSet->is2D()) {
101        ERROR("DataSet is 2D");
102        return;
103    }
104
105    // Contour filter to generate isosurfaces
106    if (_contourFilter == NULL) {
107        _contourFilter = vtkSmartPointer<vtkContourFilter>::New();
108    }
109
110    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
111
112    if (ds->GetPointData() == NULL ||
113        ds->GetPointData()->GetScalars() == NULL) {
114        WARN("No scalar point data in dataset %s", _dataSet->getName().c_str());
115        if (ds->GetCellData() != NULL &&
116            ds->GetCellData()->GetScalars() != NULL) {
117            cellToPtData =
118                vtkSmartPointer<vtkCellDataToPointData>::New();
119            cellToPtData->SetInput(ds);
120            //cellToPtData->PassCellDataOn();
121            cellToPtData->Update();
122            ds = cellToPtData->GetOutput();
123        } else {
124            ERROR("No scalar cell data in dataset %s", _dataSet->getName().c_str());
125        }
126    }
127
128    vtkPolyData *pd = vtkPolyData::SafeDownCast(ds);
129    if (pd) {
130        // DataSet is a vtkPolyData
131        if (pd->GetNumberOfLines() == 0 &&
132            pd->GetNumberOfPolys() == 0 &&
133            pd->GetNumberOfStrips() == 0) {
134            // DataSet is a point cloud
135            // Generate a 3D unstructured grid
136            vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
137            mesher->SetInput(pd);
138            _contourFilter->SetInputConnection(mesher->GetOutputPort());
139        } else {
140            // DataSet is a vtkPolyData with lines and/or polygons
141            ERROR("Not a 3D DataSet");
142            return;
143        }
144    } else {
145         // DataSet is NOT a vtkPolyData
146         _contourFilter->SetInput(ds);
147    }
148
149    _contourFilter->ComputeNormalsOn();
150    _contourFilter->ComputeGradientsOff();
151
152    // Speed up multiple contour computation at cost of extra memory use
153    if (_numContours > 1) {
154        _contourFilter->UseScalarTreeOn();
155    } else {
156        _contourFilter->UseScalarTreeOff();
157    }
158
159    _contourFilter->SetNumberOfContours(_numContours);
160
161    if (_contours.empty()) {
162        // Evenly spaced isovalues
163        _contourFilter->GenerateValues(_numContours, _dataRange[0], _dataRange[1]);
164    } else {
165        // User-supplied isovalues
166        for (int i = 0; i < _numContours; i++) {
167            _contourFilter->SetValue(i, _contours[i]);
168        }
169    }
170    if (_contourMapper == NULL) {
171        _contourMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
172        _contourMapper->SetResolveCoincidentTopologyToPolygonOffset();
173        _contourMapper->SetInputConnection(_contourFilter->GetOutputPort());
174        getActor()->SetMapper(_contourMapper);
175    }
176
177    if (_lut == NULL) {
178        setColorMap(ColorMap::getDefault());
179    }
180
181    _contourMapper->Update();
182    TRACE("Contour output %d polys, %d strips",
183          _contourFilter->GetOutput()->GetNumberOfPolys(),
184          _contourFilter->GetOutput()->GetNumberOfStrips());
185}
186
187void Contour3D::updateRanges(bool useCumulative,
188                             double scalarRange[2],
189                             double vectorMagnitudeRange[2],
190                             double vectorComponentRange[3][2])
191{
192    if (useCumulative) {
193        _dataRange[0] = scalarRange[0];
194        _dataRange[1] = scalarRange[1];
195    } else if (_dataSet != NULL) {
196        _dataSet->getScalarRange(_dataRange);
197    }
198
199    if (_lut != NULL) {
200        _lut->SetRange(_dataRange);
201    }
202
203    if (_contours.empty() && _numContours > 0) {
204        // Need to recompute isovalues
205        update();
206    }
207}
208
209/**
210 * \brief Specify number of evenly spaced isosurfaces to render
211 *
212 * Will override any existing contours
213 */
214void Contour3D::setContours(int numContours)
215{
216    _contours.clear();
217    _numContours = numContours;
218
219    update();
220}
221
222/**
223 * \brief Specify an explicit list of contour isovalues
224 *
225 * Will override any existing contours
226 */
227void Contour3D::setContourList(const std::vector<double>& contours)
228{
229    _contours = contours;
230    _numContours = (int)_contours.size();
231
232    update();
233}
234
235/**
236 * \brief Get the number of contours
237 */
238int Contour3D::getNumContours() const
239{
240    return _numContours;
241}
242
243/**
244 * \brief Get the contour list (may be empty if number of contours
245 * was specified in place of a list)
246 */
247const std::vector<double>& Contour3D::getContourList() const
248{
249    return _contours;
250}
251
252/**
253 * \brief Set a group of world coordinate planes to clip rendering
254 *
255 * Passing NULL for planes will remove all cliping planes
256 */
257void Contour3D::setClippingPlanes(vtkPlaneCollection *planes)
258{
259    if (_contourMapper != NULL) {
260        _contourMapper->SetClippingPlanes(planes);
261    }
262}
Note: See TracBrowser for help on using the repository browser.