source: branches/blt4/packages/vizservers/vtkvis/RpContour2D.cpp @ 2681

Last change on this file since 2681 was 2681, checked in by gah, 12 years ago
File size: 7.3 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 <vtkStripper.h>
16#include <vtkPolyDataMapper.h>
17#include <vtkUnstructuredGrid.h>
18#include <vtkProperty.h>
19#include <vtkTransform.h>
20#include <vtkDelaunay2D.h>
21#include <vtkDelaunay3D.h>
22#include <vtkDataSetSurfaceFilter.h>
23
24#include "RpContour2D.h"
25#include "Trace.h"
26
27using namespace Rappture::VtkVis;
28
29Contour2D::Contour2D(int numContours) :
30    VtkGraphicsObject(),
31    _numContours(numContours)
32{
33    _edgeColor[0] = _color[0];
34    _edgeColor[1] = _color[0];
35    _edgeColor[2] = _color[0];
36    _lighting = false;
37}
38
39Contour2D::Contour2D(const std::vector<double>& contours) :
40    VtkGraphicsObject(),
41    _numContours(contours.size()),
42    _contours(contours)
43{
44    _edgeColor[0] = _color[0];
45    _edgeColor[1] = _color[0];
46    _edgeColor[2] = _color[0];
47    _lighting = false;
48}
49
50Contour2D::~Contour2D()
51{
52#ifdef WANT_TRACE
53    if (_dataSet != NULL)
54        TRACE("Deleting Contour2D for %s", _dataSet->getName().c_str());
55    else
56        TRACE("Deleting Contour2D with NULL DataSet");
57#endif
58}
59
60/**
61 * \brief Internal method to re-compute contours after a state change
62 */
63void Contour2D::update()
64{
65    if (_dataSet == NULL) {
66        return;
67    }
68    vtkDataSet *ds = _dataSet->getVtkDataSet();
69
70    initProp();
71
72    // Contour filter to generate isolines
73    if (_contourFilter == NULL) {
74        _contourFilter = vtkSmartPointer<vtkContourFilter>::New();
75    }
76
77    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
78
79    if (ds->GetPointData() == NULL ||
80        ds->GetPointData()->GetScalars() == NULL) {
81        WARN("No scalar point data in dataset %s", _dataSet->getName().c_str());
82        if (ds->GetCellData() != NULL &&
83            ds->GetCellData()->GetScalars() != NULL) {
84            cellToPtData =
85                vtkSmartPointer<vtkCellDataToPointData>::New();
86            cellToPtData->SetInput(ds);
87            //cellToPtData->PassCellDataOn();
88            cellToPtData->Update();
89            ds = cellToPtData->GetOutput();
90        } else {
91            ERROR("No scalar cell data in dataset %s", _dataSet->getName().c_str());
92        }
93    }
94
95    vtkPolyData *pd = vtkPolyData::SafeDownCast(ds);
96    if (pd) {
97        // DataSet is a vtkPolyData
98        if (pd->GetNumberOfLines() == 0 &&
99            pd->GetNumberOfPolys() == 0 &&
100            pd->GetNumberOfStrips() == 0) {
101            // DataSet is a point cloud
102            PrincipalPlane plane;
103            double offset;
104            if (_dataSet->is2D(&plane, &offset)) {
105                vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
106                if (plane == PLANE_ZY) {
107                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
108                    trans->RotateWXYZ(90, 0, 1, 0);
109                    if (offset != 0.0) {
110                        trans->Translate(-offset, 0, 0);
111                    }
112                    mesher->SetTransform(trans);
113                } else if (plane == PLANE_XZ) {
114                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
115                    trans->RotateWXYZ(-90, 1, 0, 0);
116                    if (offset != 0.0) {
117                        trans->Translate(0, -offset, 0);
118                    }
119                    mesher->SetTransform(trans);
120                } else if (offset != 0.0) {
121                    // XY with Z offset
122                    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
123                    trans->Translate(0, 0, -offset);
124                    mesher->SetTransform(trans);
125                }
126                mesher->SetInput(pd);
127                _contourFilter->SetInputConnection(mesher->GetOutputPort());
128            } else {
129                vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
130                mesher->SetInput(pd);
131                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
132                gf->SetInputConnection(mesher->GetOutputPort());
133                _contourFilter->SetInputConnection(gf->GetOutputPort());
134            }
135        } else {
136            // DataSet is a vtkPolyData with lines and/or polygons
137            _contourFilter->SetInput(ds);
138        }
139    } else {
140        TRACE("Generating surface for data set");
141        // DataSet is NOT a vtkPolyData
142        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
143        gf->SetInput(ds);
144        _contourFilter->SetInputConnection(gf->GetOutputPort());
145    }
146
147    _contourFilter->ComputeNormalsOff();
148    _contourFilter->ComputeGradientsOff();
149
150    // Speed up multiple contour computation at cost of extra memory use
151    if (_numContours > 1) {
152        _contourFilter->UseScalarTreeOn();
153    } else {
154        _contourFilter->UseScalarTreeOff();
155    }
156
157    _contourFilter->SetNumberOfContours(_numContours);
158
159    if (_contours.empty()) {
160        // Evenly spaced isovalues
161        _contourFilter->GenerateValues(_numContours, _dataRange[0], _dataRange[1]);
162    } else {
163        // User-supplied isovalues
164        for (int i = 0; i < _numContours; i++) {
165            _contourFilter->SetValue(i, _contours[i]);
166        }
167    }
168    if (_contourMapper == NULL) {
169        _contourMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
170        _contourMapper->SetResolveCoincidentTopologyToPolygonOffset();
171        _contourMapper->ScalarVisibilityOff();
172        vtkSmartPointer<vtkStripper> stripper = vtkSmartPointer<vtkStripper>::New();
173        stripper->SetInputConnection(_contourFilter->GetOutputPort());
174        _contourMapper->SetInputConnection(stripper->GetOutputPort());
175        getActor()->SetMapper(_contourMapper);
176    }
177
178    _contourMapper->Update();
179}
180
181void Contour2D::updateRanges(Renderer *renderer)
182{
183    VtkGraphicsObject::updateRanges(renderer);
184 
185    if (_contours.empty() && _numContours > 0) {
186        // Contour isovalues need to be recomputed
187        update();
188    }
189}
190
191/**
192 * \brief Specify number of evenly spaced contour lines to render
193 *
194 * Will override any existing contours
195 */
196void Contour2D::setContours(int numContours)
197{
198    _contours.clear();
199    _numContours = numContours;
200
201    update();
202}
203
204/**
205 * \brief Specify an explicit list of contour isovalues
206 *
207 * Will override any existing contours
208 */
209void Contour2D::setContourList(const std::vector<double>& contours)
210{
211    _contours = contours;
212    _numContours = (int)_contours.size();
213
214    update();
215}
216
217/**
218 * \brief Get the number of contours
219 */
220int Contour2D::getNumContours() const
221{
222    return _numContours;
223}
224
225/**
226 * \brief Get the contour list (may be empty if number of contours
227 * was specified in place of a list)
228 */
229const std::vector<double>& Contour2D::getContourList() const
230{
231    return _contours;
232}
233
234/**
235 * \brief Set a group of world coordinate planes to clip rendering
236 *
237 * Passing NULL for planes will remove all cliping planes
238 */
239void Contour2D::setClippingPlanes(vtkPlaneCollection *planes)
240{
241    if (_contourMapper != NULL) {
242        _contourMapper->SetClippingPlanes(planes);
243    }
244}
Note: See TracBrowser for help on using the repository browser.