source: branches/blt4/packages/vizservers/vtkvis/RpPolyData.cpp @ 2302

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

update from trunk

File size: 7.1 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 <vtkPolyData.h>
12#include <vtkUnstructuredGrid.h>
13#include <vtkPolyDataMapper.h>
14#include <vtkActor.h>
15#include <vtkProperty.h>
16#include <vtkDelaunay2D.h>
17#include <vtkDelaunay3D.h>
18#include <vtkDataSetSurfaceFilter.h>
19
20#include "RpPolyData.h"
21#include "Trace.h"
22
23using namespace Rappture::VtkVis;
24
25PolyData::PolyData() :
26    _dataSet(NULL),
27    _edgeWidth(1.0),
28    _opacity(1.0),
29    _lighting(true)
30{
31    _color[0] = 0.0;
32    _color[1] = 0.0;
33    _color[2] = 1.0;
34    _edgeColor[0] = 0.0;
35    _edgeColor[1] = 0.0;
36    _edgeColor[2] = 0.0;
37}
38
39PolyData::~PolyData()
40{
41#ifdef WANT_TRACE
42    if (_dataSet != NULL)
43        TRACE("Deleting PolyData for %s", _dataSet->getName().c_str());
44    else
45        TRACE("Deleting PolyData with NULL DataSet");
46#endif
47}
48
49/**
50 * \brief Get the VTK Prop for the mesh
51 */
52vtkProp *PolyData::getProp()
53{
54    return _pdActor;
55}
56
57/**
58 * \brief Create and initialize a VTK Prop to render a mesh
59 */
60void PolyData::initProp()
61{
62    if (_pdActor == NULL) {
63        _pdActor = vtkSmartPointer<vtkActor>::New();
64        _pdActor->GetProperty()->EdgeVisibilityOn();
65        _pdActor->GetProperty()->SetColor(_color[0], _color[1], _color[2]);
66        _pdActor->GetProperty()->SetEdgeColor(_edgeColor[0], _edgeColor[1], _edgeColor[2]);
67        _pdActor->GetProperty()->SetLineWidth(_edgeWidth);
68        _pdActor->GetProperty()->SetOpacity(_opacity);
69        if (!_lighting)
70            _pdActor->GetProperty()->LightingOff();
71    }
72}
73
74/**
75 * \brief Specify input DataSet (PolyData)
76 *
77 * The DataSet must be a PolyData object
78 */
79void PolyData::setDataSet(DataSet *dataSet)
80{
81    if (_dataSet != dataSet) {
82        _dataSet = dataSet;
83        update();
84    }
85}
86
87/**
88 * \brief Returns the DataSet this PolyData renders
89 */
90DataSet *PolyData::getDataSet()
91{
92    return _dataSet;
93}
94
95/**
96 * \brief Internal method to re-compute contours after a state change
97 */
98void PolyData::update()
99{
100    if (_dataSet == NULL) {
101        return;
102    }
103
104    if (_pdMapper == NULL) {
105        _pdMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
106        _pdMapper->SetResolveCoincidentTopologyToPolygonOffset();
107        _pdMapper->ScalarVisibilityOff();
108    }
109
110    vtkDataSet *ds = _dataSet->getVtkDataSet();
111    vtkPolyData *pd = vtkPolyData::SafeDownCast(ds);
112    if (pd) {
113        TRACE("Verts: %d Lines: %d Polys: %d Strips: %d",
114                  pd->GetNumberOfVerts(),
115                  pd->GetNumberOfLines(),
116                  pd->GetNumberOfPolys(),
117                  pd->GetNumberOfStrips());
118        // DataSet is a vtkPolyData
119        if (pd->GetNumberOfLines() == 0 &&
120            pd->GetNumberOfPolys() == 0 &&
121            pd->GetNumberOfStrips() == 0) {
122            // DataSet is a point cloud
123            if (_dataSet->is2D()) {
124                vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
125                mesher->SetInput(pd);
126#if defined(DEBUG) && defined(WANT_TRACE)
127                mesher->Update();
128                vtkPolyData *outpd = mesher->GetOutput();
129                TRACE("Delaunay2D Verts: %d Lines: %d Polys: %d Strips: %d",
130                      outpd->GetNumberOfVerts(),
131                      outpd->GetNumberOfLines(),
132                      outpd->GetNumberOfPolys(),
133                      outpd->GetNumberOfStrips());
134#endif
135                _pdMapper->SetInputConnection(mesher->GetOutputPort());
136            } else {
137                vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
138                mesher->SetInput(pd);
139                // Delaunay3D returns an UnstructuredGrid, so feed it through a surface filter
140                // to get the grid boundary as a PolyData
141                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
142                gf->SetInputConnection(mesher->GetOutputPort());
143                _pdMapper->SetInputConnection(gf->GetOutputPort());
144            }
145        } else {
146            // DataSet is a vtkPolyData with lines and/or polygons
147            _pdMapper->SetInput(pd);
148        }
149    } else {
150        // DataSet is NOT a vtkPolyData
151        WARN("DataSet is not a PolyData");
152        vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
153        gf->SetInput(ds);
154        _pdMapper->SetInputConnection(gf->GetOutputPort());
155    }
156
157    initProp();
158    _pdActor->SetMapper(_pdMapper);
159    _pdMapper->Update();
160}
161
162/**
163 * \brief Turn on/off rendering of this mesh
164 */
165void PolyData::setVisibility(bool state)
166{
167    if (_pdActor != NULL) {
168        _pdActor->SetVisibility((state ? 1 : 0));
169    }
170}
171
172/**
173 * \brief Get visibility state of the mesh
174 *
175 * \return Is mesh visible?
176 */
177bool PolyData::getVisibility()
178{
179    if (_pdActor == NULL) {
180        return false;
181    } else {
182        return (_pdActor->GetVisibility() != 0);
183    }
184}
185
186/**
187 * \brief Set opacity used to render the mesh
188 */
189void PolyData::setOpacity(double opacity)
190{
191    _opacity = opacity;
192    if (_pdActor != NULL)
193        _pdActor->GetProperty()->SetOpacity(opacity);
194}
195
196/**
197 * \brief Switch between wireframe and surface representations
198 */
199void PolyData::setWireframe(bool state)
200{
201    if (_pdActor != NULL) {
202        if (state) {
203            _pdActor->GetProperty()->SetRepresentationToWireframe();
204            _pdActor->GetProperty()->LightingOff();
205        } else {
206            _pdActor->GetProperty()->SetRepresentationToSurface();
207            _pdActor->GetProperty()->SetLighting((_lighting ? 1 : 0));
208        }
209    }
210}
211
212/**
213 * \brief Set RGB color of polygon faces
214 */
215void PolyData::setColor(float color[3])
216{
217    _color[0] = color[0];
218    _color[1] = color[1];
219    _color[2] = color[2];
220    if (_pdActor != NULL)
221        _pdActor->GetProperty()->SetColor(_color[0], _color[1], _color[2]);
222}
223
224/**
225 * \brief Turn on/off rendering of mesh edges
226 */
227void PolyData::setEdgeVisibility(bool state)
228{
229    if (_pdActor != NULL) {
230        _pdActor->GetProperty()->SetEdgeVisibility((state ? 1 : 0));
231    }
232}
233
234/**
235 * \brief Set RGB color of polygon edges
236 */
237void PolyData::setEdgeColor(float color[3])
238{
239    _edgeColor[0] = color[0];
240    _edgeColor[1] = color[1];
241    _edgeColor[2] = color[2];
242    if (_pdActor != NULL)
243        _pdActor->GetProperty()->SetEdgeColor(_edgeColor[0], _edgeColor[1], _edgeColor[2]);
244}
245
246/**
247 * \brief Set pixel width of polygon edges (may be a no-op)
248 */
249void PolyData::setEdgeWidth(float edgeWidth)
250{
251    _edgeWidth = edgeWidth;
252    if (_pdActor != NULL)
253        _pdActor->GetProperty()->SetLineWidth(_edgeWidth);
254}
255
256/**
257 * \brief Set a group of world coordinate planes to clip rendering
258 *
259 * Passing NULL for planes will remove all cliping planes
260 */
261void PolyData::setClippingPlanes(vtkPlaneCollection *planes)
262{
263    if (_pdMapper != NULL) {
264        _pdMapper->SetClippingPlanes(planes);
265    }
266}
267
268/**
269 * \brief Turn on/off lighting of this object
270 */
271void PolyData::setLighting(bool state)
272{
273    _lighting = state;
274    if (_pdActor != NULL)
275        _pdActor->GetProperty()->SetLighting((state ? 1 : 0));
276}
Note: See TracBrowser for help on using the repository browser.