15
15
#include " vtkCellDataToPointData.h"
16
16
17
17
#include " vtkCellData.h"
18
+ #include " vtkCell.h"
18
19
#include " vtkDataSet.h"
19
20
#include " vtkIdList.h"
20
21
#include " vtkInformation.h"
21
22
#include " vtkInformationVector.h"
23
+ #include " vtkUnstructuredGrid.h"
24
+ #include " vtkSmartPointer.h"
25
+ #include " vtkUnsignedIntArray.h"
22
26
#include " vtkObjectFactory.h"
23
27
#include " vtkPointData.h"
28
+ #include < algorithm>
24
29
25
30
vtkStandardNewMacro (vtkCellDataToPointData);
26
31
@@ -47,6 +52,14 @@ int vtkCellDataToPointData::RequestData(
47
52
vtkDataSet *input = vtkDataSet::SafeDownCast (
48
53
inInfo->Get (vtkDataObject::DATA_OBJECT ()));
49
54
55
+ vtkDebugMacro (<<" Mapping cell data to point data" );
56
+
57
+ // Special traversal algorithm for unstructured grid
58
+ if (input->IsA (" vtkUnstructuredGrid" ))
59
+ {
60
+ return this ->RequestDataForUnstructuredGrid (0 , inputVector, outputVector);
61
+ }
62
+
50
63
vtkIdType cellId, ptId;
51
64
vtkIdType numCells, numPts;
52
65
vtkCellData *inPD=input->GetCellData ();
@@ -129,3 +142,162 @@ void vtkCellDataToPointData::PrintSelf(ostream& os, vtkIndent indent)
129
142
130
143
os << indent << " Pass Cell Data: " << (this ->PassCellData ? " On\n " : " Off\n " );
131
144
}
145
+
146
+ // ----------------------------------------------------------------------------
147
+ // Helper template function that implement the major part of the algorighm
148
+ // which will be expanded by the vtkTemplateMacro. The template function is
149
+ // provided so that coverage test can cover this function.
150
+ namespace
151
+ {
152
+ template <typename T>
153
+ void __spread (vtkUnstructuredGrid* const src, vtkUnsignedIntArray* const num,
154
+ vtkDataArray* const srcarray, vtkDataArray* const dstarray,
155
+ vtkIdType ncells, vtkIdType npoints, vtkIdType ncomps)
156
+ {
157
+ T const * const srcptr = static_cast <T const *>(srcarray->GetVoidPointer (0 ));
158
+ T * const dstptr = static_cast <T *>(dstarray->GetVoidPointer (0 ));
159
+
160
+ // zero initialization
161
+ vtkstd::fill_n (dstptr, npoints*ncomps, T (0 ));
162
+
163
+ // accumulate
164
+ T const * srcbeg = srcptr;
165
+ for (vtkIdType cid = 0 ; cid < ncells; ++cid, srcbeg += ncomps)
166
+ {
167
+ vtkIdList* const pids = src->GetCell (cid)->GetPointIds ();
168
+ for (vtkIdType i = 0 , I = pids->GetNumberOfIds (); i < I; ++i)
169
+ {
170
+ T* const dstbeg = dstptr + pids->GetId (i)*ncomps;
171
+ // accumulate cell data to point data <==> point_data += cell_data
172
+ vtkstd::transform (srcbeg,srcbeg+ncomps,dstbeg,dstbeg,vtkstd::plus<T>());
173
+ }
174
+ }
175
+
176
+ // average
177
+ T* dstbeg = dstptr;
178
+ for (vtkIdType pid = 0 ; pid < npoints; ++pid, dstbeg += ncomps)
179
+ {
180
+ // guard against divide by zero
181
+ if (unsigned int const denum = num->GetValue (pid))
182
+ {
183
+ // divide point data by the number of cells using it <==>
184
+ // point_data /= denum
185
+ vtkstd::transform (dstbeg, dstbeg+ncomps, dstbeg,
186
+ vtkstd::bind2nd (vtkstd::divides<T>(), denum));
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ // ----------------------------------------------------------------------------
193
+ int vtkCellDataToPointData::RequestDataForUnstructuredGrid
194
+ (vtkInformation*,
195
+ vtkInformationVector** inputVector,
196
+ vtkInformationVector* outputVector)
197
+ {
198
+ vtkUnstructuredGrid* const src = vtkUnstructuredGrid::SafeDownCast (
199
+ inputVector[0 ]->GetInformationObject (0 )->Get (vtkDataObject::DATA_OBJECT ()));
200
+ vtkUnstructuredGrid* const dst = vtkUnstructuredGrid::SafeDownCast (
201
+ outputVector->GetInformationObject (0 )->Get (vtkDataObject::DATA_OBJECT ()));
202
+
203
+ vtkIdType const ncells = src->GetNumberOfCells ();
204
+ vtkIdType const npoints = src->GetNumberOfPoints ();
205
+ if (ncells < 1 || npoints < 1 )
206
+ {
207
+ vtkDebugMacro (<<" No input data!" );
208
+ return 1 ;
209
+ }
210
+
211
+ // count the number of cells associated with each point
212
+ vtkSmartPointer<vtkUnsignedIntArray> num
213
+ = vtkSmartPointer<vtkUnsignedIntArray>::New ();
214
+ num->SetNumberOfComponents (1 );
215
+ num->SetNumberOfTuples (npoints);
216
+ vtkstd::fill_n (num->GetPointer (0 ), npoints, 0u );
217
+ for (vtkIdType cid = 0 ; cid < ncells; ++cid)
218
+ {
219
+ vtkIdList* const pids = src->GetCell (cid)->GetPointIds ();
220
+ for (vtkIdType i = 0 , I = pids->GetNumberOfIds (); i < I; ++i)
221
+ {
222
+ vtkIdType const pid = pids->GetId (i);
223
+ num->SetValue (pid, num->GetValue (pid)+1 );
224
+ }
225
+ }
226
+
227
+ // First, copy the input to the output as a starting point
228
+ dst->CopyStructure (src);
229
+ vtkPointData* const opd = dst->GetPointData ();
230
+
231
+ // Pass the point data first. The fields and attributes
232
+ // which also exist in the cell data of the input will
233
+ // be over-written during CopyAllocate
234
+ opd->CopyGlobalIdsOff ();
235
+ opd->PassData (src->GetPointData ());
236
+ opd->CopyFieldOff (" vtkGhostLevels" );
237
+
238
+ // Copy all existing cell fields into a temporary cell data array
239
+ vtkSmartPointer<vtkCellData> clean = vtkSmartPointer<vtkCellData>::New ();
240
+ clean->PassData (src->GetCellData ());
241
+
242
+ // Remove all fields that are not a data array.
243
+ for (vtkIdType fid = clean->GetNumberOfArrays (); fid--;)
244
+ {
245
+ if (!clean->GetAbstractArray (fid)->IsA (" vtkDataArray" ))
246
+ {
247
+ clean->RemoveArray (fid);
248
+ }
249
+ }
250
+
251
+ // Cell field list constructed from the filtered cell data array
252
+ vtkDataSetAttributes::FieldList cfl (1 );
253
+ cfl.InitializeFieldList (clean);
254
+ opd->InterpolateAllocate (cfl, npoints, npoints);
255
+
256
+ for (int fid = 0 , nfields = cfl.GetNumberOfFields (); fid < nfields; ++fid)
257
+ {
258
+ // update progress and check for an abort request.
259
+ this ->UpdateProgress ((fid+1 .)/nfields);
260
+ if (this ->GetAbortExecute ())
261
+ {
262
+ break ;
263
+ }
264
+
265
+ // indices into the field arrays associated with the cell and the point
266
+ // respectively
267
+ int const srcid = cfl.GetFieldIndex (fid);
268
+ int const dstid = cfl.GetDSAIndex (0 ,fid);
269
+ if (srcid < 0 || dstid < 0 )
270
+ {
271
+ continue ;
272
+ }
273
+
274
+ vtkCellData * const srccelldata = src->GetCellData ();
275
+ vtkPointData* const dstpointdata = dst->GetPointData ();
276
+
277
+ if (!srccelldata || !dstpointdata)
278
+ {
279
+ continue ;
280
+ }
281
+
282
+ vtkDataArray* const srcarray = srccelldata ->GetArray (srcid);
283
+ vtkDataArray* const dstarray = dstpointdata->GetArray (dstid);
284
+ dstarray->SetNumberOfTuples (npoints);
285
+
286
+ vtkIdType const ncomps = srcarray->GetNumberOfComponents ();
287
+ switch (srcarray->GetDataType ())
288
+ {
289
+ vtkTemplateMacro
290
+ (__spread<VTK_TT>(src,num,srcarray,dstarray,ncells,npoints,ncomps));
291
+ }
292
+ }
293
+
294
+ if (!this ->PassCellData )
295
+ {
296
+ dst->GetCellData ()->CopyAllOff ();
297
+ dst->GetCellData ()->CopyFieldOn (" vtkGhostLevels" );
298
+ }
299
+ dst->GetCellData ()->PassData (src->GetCellData ());
300
+
301
+ return 1 ;
302
+ }
303
+
0 commit comments