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 <cstring> |
---|
9 | |
---|
10 | #include <vtkCharArray.h> |
---|
11 | #include <vtkDataSetReader.h> |
---|
12 | #include <vtkPolyData.h> |
---|
13 | #include <vtkStructuredPoints.h> |
---|
14 | #include <vtkStructuredGrid.h> |
---|
15 | #include <vtkRectilinearGrid.h> |
---|
16 | #include <vtkUnstructuredGrid.h> |
---|
17 | #include <vtkProperty.h> |
---|
18 | #include <vtkPointData.h> |
---|
19 | #include <vtkLookupTable.h> |
---|
20 | |
---|
21 | #include "RpVtkDataSet.h" |
---|
22 | #include "Trace.h" |
---|
23 | |
---|
24 | using namespace Rappture::VtkVis; |
---|
25 | |
---|
26 | DataSet::DataSet(const std::string& name) : |
---|
27 | _name(name), |
---|
28 | _visible(true) |
---|
29 | { |
---|
30 | _dataRange[0] = 0; |
---|
31 | _dataRange[1] = 1; |
---|
32 | for (int i = 0; i < 6; i++) { |
---|
33 | _bounds[i] = 0; |
---|
34 | } |
---|
35 | } |
---|
36 | |
---|
37 | DataSet::~DataSet() |
---|
38 | { |
---|
39 | } |
---|
40 | |
---|
41 | /** |
---|
42 | * \brief Set visibility flag in DataSet |
---|
43 | * |
---|
44 | * This method is used for record-keeping. The renderer controls |
---|
45 | * the visibility of related graphics objects. |
---|
46 | */ |
---|
47 | void DataSet::setVisibility(bool state) |
---|
48 | { |
---|
49 | _visible = state; |
---|
50 | } |
---|
51 | |
---|
52 | /** |
---|
53 | * \brief Get visibility flag in DataSet |
---|
54 | * |
---|
55 | * This method is used for record-keeping. The renderer controls |
---|
56 | * the visibility of related graphics objects. |
---|
57 | */ |
---|
58 | bool DataSet::getVisibility() const |
---|
59 | { |
---|
60 | return _visible; |
---|
61 | } |
---|
62 | |
---|
63 | /** |
---|
64 | * \brief Read a VTK data file |
---|
65 | */ |
---|
66 | bool DataSet::setDataFile(const char *filename) |
---|
67 | { |
---|
68 | vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New(); |
---|
69 | |
---|
70 | #if defined(WANT_TRACE) && defined(DEBUG) |
---|
71 | reader->DebugOn(); |
---|
72 | #endif |
---|
73 | |
---|
74 | reader->SetFileName(filename); |
---|
75 | reader->ReadAllScalarsOn(); |
---|
76 | reader->ReadAllVectorsOn(); |
---|
77 | return setData(reader); |
---|
78 | } |
---|
79 | |
---|
80 | /** |
---|
81 | * \brief Read a VTK data file from a memory buffer |
---|
82 | */ |
---|
83 | bool DataSet::setData(char *data, int nbytes) |
---|
84 | { |
---|
85 | TRACE("Entering"); |
---|
86 | |
---|
87 | vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New(); |
---|
88 | vtkSmartPointer<vtkCharArray> dataSetString = vtkSmartPointer<vtkCharArray>::New(); |
---|
89 | |
---|
90 | #if defined(WANT_TRACE) && defined(DEBUG) |
---|
91 | reader->DebugOn(); |
---|
92 | dataSetString->DebugOn(); |
---|
93 | #endif |
---|
94 | |
---|
95 | dataSetString->SetArray(data, nbytes, 1); |
---|
96 | reader->SetInputArray(dataSetString); |
---|
97 | reader->ReadFromInputStringOn(); |
---|
98 | reader->ReadAllScalarsOn(); |
---|
99 | reader->ReadAllVectorsOn(); |
---|
100 | |
---|
101 | bool status = setData(reader); |
---|
102 | |
---|
103 | TRACE("Leaving"); |
---|
104 | return status; |
---|
105 | } |
---|
106 | |
---|
107 | /** |
---|
108 | * \brief Read dataset using supplied reader |
---|
109 | * |
---|
110 | * Pipeline information is removed from the resulting |
---|
111 | * vtkDataSet, so that the reader and its data can be |
---|
112 | * released |
---|
113 | */ |
---|
114 | bool DataSet::setData(vtkDataSetReader *reader) |
---|
115 | { |
---|
116 | // Force reading data set |
---|
117 | reader->SetLookupTableName(""); |
---|
118 | reader->Update(); |
---|
119 | |
---|
120 | _dataSet = reader->GetOutput(); |
---|
121 | _dataSet->SetPipelineInformation(NULL); |
---|
122 | |
---|
123 | _dataSet->GetScalarRange(_dataRange); |
---|
124 | _dataSet->GetBounds(_bounds); |
---|
125 | |
---|
126 | TRACE("DataSet class: %s", _dataSet->GetClassName()); |
---|
127 | TRACE("Scalar Range: %.12e, %.12e", _dataRange[0], _dataRange[1]); |
---|
128 | TRACE("DataSet bounds: %g %g %g %g %g %g", |
---|
129 | _bounds[0], _bounds[1], |
---|
130 | _bounds[2], _bounds[3], |
---|
131 | _bounds[4], _bounds[5]); |
---|
132 | return true; |
---|
133 | } |
---|
134 | |
---|
135 | /** |
---|
136 | * \brief Set DataSet from existing vtkDataSet object |
---|
137 | * |
---|
138 | * Pipeline information is removed from the supplied vtkDataSet |
---|
139 | */ |
---|
140 | bool DataSet::setData(vtkDataSet *ds) |
---|
141 | { |
---|
142 | _dataSet = ds; |
---|
143 | _dataSet->SetPipelineInformation(NULL); |
---|
144 | _dataSet->GetScalarRange(_dataRange); |
---|
145 | _dataSet->GetBounds(_bounds); |
---|
146 | |
---|
147 | TRACE("DataSet class: %s", _dataSet->GetClassName()); |
---|
148 | TRACE("Scalar Range: %.12e, %.12e", _dataRange[0], _dataRange[1]); |
---|
149 | TRACE("DataSet bounds: %g %g %g %g %g %g", |
---|
150 | _bounds[0], _bounds[1], |
---|
151 | _bounds[2], _bounds[3], |
---|
152 | _bounds[4], _bounds[5]); |
---|
153 | return true; |
---|
154 | } |
---|
155 | |
---|
156 | /** |
---|
157 | * \brief Copy an existing vtkDataSet object |
---|
158 | * |
---|
159 | * Pipeline information is not copied from the supplied vtkDataSet |
---|
160 | * into this DataSet, but pipeline information in the supplied |
---|
161 | * vtkDataSet is not removed |
---|
162 | */ |
---|
163 | vtkDataSet *DataSet::copyData(vtkDataSet *ds) |
---|
164 | { |
---|
165 | if (vtkPolyData::SafeDownCast(ds) != NULL) { |
---|
166 | _dataSet = vtkSmartPointer<vtkPolyData>::New(); |
---|
167 | _dataSet->DeepCopy(vtkPolyData::SafeDownCast(ds)); |
---|
168 | } else if (vtkStructuredPoints::SafeDownCast(ds) != NULL) { |
---|
169 | _dataSet = vtkSmartPointer<vtkStructuredPoints>::New(); |
---|
170 | _dataSet->DeepCopy(vtkStructuredPoints::SafeDownCast(ds)); |
---|
171 | } else if (vtkStructuredGrid::SafeDownCast(ds) != NULL) { |
---|
172 | _dataSet = vtkSmartPointer<vtkStructuredGrid>::New(); |
---|
173 | _dataSet->DeepCopy(vtkStructuredGrid::SafeDownCast(ds)); |
---|
174 | } else if (vtkRectilinearGrid::SafeDownCast(ds) != NULL) { |
---|
175 | _dataSet = vtkSmartPointer<vtkRectilinearGrid>::New(); |
---|
176 | _dataSet->DeepCopy(vtkRectilinearGrid::SafeDownCast(ds)); |
---|
177 | } else if (vtkUnstructuredGrid::SafeDownCast(ds) != NULL) { |
---|
178 | _dataSet = vtkSmartPointer<vtkUnstructuredGrid>::New(); |
---|
179 | _dataSet->DeepCopy(vtkUnstructuredGrid::SafeDownCast(ds)); |
---|
180 | } else { |
---|
181 | ERROR("Unknown data type"); |
---|
182 | return NULL; |
---|
183 | } |
---|
184 | _dataSet->GetScalarRange(_dataRange); |
---|
185 | _dataSet->GetBounds(_bounds); |
---|
186 | |
---|
187 | TRACE("DataSet class: %s", _dataSet->GetClassName()); |
---|
188 | TRACE("Scalar Range: %.12e, %.12e", _dataRange[0], _dataRange[1]); |
---|
189 | return _dataSet; |
---|
190 | } |
---|
191 | |
---|
192 | /** |
---|
193 | * \brief Does DataSet lie in the XY plane (z = 0) |
---|
194 | */ |
---|
195 | bool DataSet::is2D() const |
---|
196 | { |
---|
197 | return (_bounds[4] == 0. && _bounds[4] == _bounds[5]); |
---|
198 | } |
---|
199 | |
---|
200 | /** |
---|
201 | * \brief Get the name/id of this dataset |
---|
202 | */ |
---|
203 | const std::string& DataSet::getName() const |
---|
204 | { |
---|
205 | return _name; |
---|
206 | } |
---|
207 | |
---|
208 | /** |
---|
209 | * \brief Get the underlying VTK DataSet object |
---|
210 | */ |
---|
211 | vtkDataSet *DataSet::getVtkDataSet() |
---|
212 | { |
---|
213 | return _dataSet; |
---|
214 | } |
---|
215 | |
---|
216 | /** |
---|
217 | * \brief Get the underlying VTK DataSet subclass class name |
---|
218 | */ |
---|
219 | const char *DataSet::getVtkType() |
---|
220 | { |
---|
221 | return _dataSet->GetClassName(); |
---|
222 | } |
---|
223 | |
---|
224 | /** |
---|
225 | * \brief Get the range of scalar values in the DataSet |
---|
226 | */ |
---|
227 | void DataSet::getDataRange(double minmax[2]) |
---|
228 | { |
---|
229 | memcpy(minmax, _dataRange, sizeof(double)*2); |
---|
230 | } |
---|
231 | |
---|
232 | /** |
---|
233 | * \brief Get the bounds the DataSet |
---|
234 | */ |
---|
235 | void DataSet::getBounds(double bounds[6]) |
---|
236 | { |
---|
237 | memcpy(bounds, _bounds, sizeof(double)*6); |
---|
238 | } |
---|
239 | |
---|
240 | /** |
---|
241 | * \brief Get nearest data value given world coordinates x,y,z |
---|
242 | * |
---|
243 | * Note: no interpolation is performed on data |
---|
244 | * |
---|
245 | * \return the value of the nearest point or 0 if no scalar data available |
---|
246 | */ |
---|
247 | double DataSet::getDataValue(double x, double y, double z) |
---|
248 | { |
---|
249 | if (_dataSet == NULL) |
---|
250 | return 0; |
---|
251 | if (_dataSet->GetPointData() == NULL || |
---|
252 | _dataSet->GetPointData()->GetScalars() == NULL) { |
---|
253 | return 0.0; |
---|
254 | } |
---|
255 | vtkIdType pt = _dataSet->FindPoint(x, y, z); |
---|
256 | return _dataSet->GetPointData()->GetScalars()->GetComponent(pt, 0); |
---|
257 | } |
---|