Skip to content

Commit 287423e

Browse files
author
Meng ZHU
committed
Improved vtkCellDataToPointData for vtkUnstructuredGrid datasets.
vtkCellDataToPointData creates cell links when it traverses the datasets which is an expensive operation for vtkUnstructuredGrid datasets. The improved vtkCellDataToPointData behaves identically for all other types of datasets as befores with the only differences working with vtkUnstructuredGrid. For a vtkUnstructuredGrid, it traverses the cell array directly and keeps two auxiliary arrays holding the accumulated quantity in question and the number of cells sharing each point. After the traverse is done, it dose an extra division pass to get the average of the tracked quantity which returns exact the same results as before.
1 parent b9b9f60 commit 287423e

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

Graphics/vtkCellDataToPointData.cxx

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
#include "vtkCellDataToPointData.h"
1616

1717
#include "vtkCellData.h"
18+
#include "vtkCell.h"
1819
#include "vtkDataSet.h"
1920
#include "vtkIdList.h"
2021
#include "vtkInformation.h"
2122
#include "vtkInformationVector.h"
23+
#include "vtkUnstructuredGrid.h"
24+
#include "vtkSmartPointer.h"
25+
#include "vtkUnsignedIntArray.h"
2226
#include "vtkObjectFactory.h"
2327
#include "vtkPointData.h"
28+
#include <algorithm>
2429

2530
vtkStandardNewMacro(vtkCellDataToPointData);
2631

@@ -47,6 +52,14 @@ int vtkCellDataToPointData::RequestData(
4752
vtkDataSet *input = vtkDataSet::SafeDownCast(
4853
inInfo->Get(vtkDataObject::DATA_OBJECT()));
4954

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+
5063
vtkIdType cellId, ptId;
5164
vtkIdType numCells, numPts;
5265
vtkCellData *inPD=input->GetCellData();
@@ -129,3 +142,162 @@ void vtkCellDataToPointData::PrintSelf(ostream& os, vtkIndent indent)
129142

130143
os << indent << "Pass Cell Data: " << (this->PassCellData ? "On\n" : "Off\n");
131144
}
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+

Graphics/vtkCellDataToPointData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class VTK_GRAPHICS_EXPORT vtkCellDataToPointData : public vtkDataSetAlgorithm
6060
vtkInformationVector** inputVector,
6161
vtkInformationVector* outputVector);
6262

63+
// Special traversal algorithm for unstructured grid
64+
int RequestDataForUnstructuredGrid
65+
(vtkInformation*, vtkInformationVector**, vtkInformationVector*);
66+
6367
int PassCellData;
6468
private:
6569
vtkCellDataToPointData(const vtkCellDataToPointData&); // Not implemented.

0 commit comments

Comments
 (0)