Commit 171773d2 authored by Allison Vacanti's avatar Allison Vacanti Committed by Kitware Robot

Merge topic 'range_dispatch_general_1'

59db5d91 Use range/dispatch for vtkTemporalStatistics.
be50c68d Use range/dispatch for vtkSplitField.
e292be99 Use range/dispatch for vtkShrinkPolyData.
5fc8c0f1 Use range/dispatch for QuadraturePoints filters.
3307058d Use range/dispatch for vtkMergeCells.
d5fcc84d Use GetPointer instead of GetVoidPointer where possible.
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !6210
parents 925f0524 59db5d91
Pipeline #152895 passed with stage
in 0 seconds
This diff is collapsed.
......@@ -180,11 +180,6 @@ protected:
vtkIdType AddNewCellsUnstructuredGrid(vtkDataSet* set, vtkIdType* idMap);
vtkIdType AddNewCellsDataSet(vtkDataSet* set, vtkIdType* idMap);
vtkIdType GlobalCellIdAccessGetId(vtkIdType idx);
bool GlobalCellIdAccessStart(vtkDataSet* set);
vtkIdType GlobalNodeIdAccessGetId(vtkIdType idx);
bool GlobalNodeIdAccessStart(vtkDataSet* set);
int TotalNumberOfDataSets;
vtkIdType TotalNumberOfCells;
......@@ -193,13 +188,8 @@ protected:
vtkIdType NumberOfCells; // so far
vtkIdType NumberOfPoints;
int UseGlobalIds; // point, or node, IDs
int GlobalIdArrayType;
void* GlobalIdArray;
int UseGlobalIds; // point, or node, IDs
int UseGlobalCellIds; // cell IDs
int GlobalCellIdArrayType;
void* GlobalCellIdArray;
float PointMergeTolerance;
bool MergeDuplicatePoints;
......
......@@ -98,7 +98,7 @@ int vtkPointConnectivityFilter::RequestData(vtkInformation* vtkNotUsed(request),
vtkNew<vtkUnsignedIntArray> connCount;
connCount->SetNumberOfTuples(numPts);
connCount->SetName("Point Connectivity Count");
unsigned int* connPtr = static_cast<unsigned int*>(connCount->GetVoidPointer(0));
unsigned int* connPtr = connCount->GetPointer(0);
// Loop over all points, retrieving connectivity count
// The first GetPointCells() primes the pump (builds internal structures, etc.)
......
......@@ -16,6 +16,7 @@
#include "vtkQuadraturePointInterpolator.h"
#include "vtkQuadratureSchemeDefinition.h"
#include "vtkArrayDispatch.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCellType.h"
......@@ -35,6 +36,8 @@
#include "vtkUnstructuredGridAlgorithm.h"
#include <sstream>
#include <vector>
using std::ostringstream;
#include "vtkQuadraturePointsUtilities.hxx"
......@@ -134,9 +137,13 @@ int vtkQuadraturePointInterpolator::InterpolateFields(vtkUnstructuredGrid* usgOu
return 0;
}
if (offsets->GetNumberOfComponents() != 1)
{
vtkWarningMacro("expected Offset array to be single-component.");
return 0;
}
const char* arrayOffsetName = offsets->GetName();
void* pOffsets = offsets->GetVoidPointer(0);
int O_Type = offsets->GetDataType();
vtkInformation* info = offsets->GetInformation();
vtkInformationQuadratureSchemeDefinitionVectorKey* key =
......@@ -147,16 +154,14 @@ int vtkQuadraturePointInterpolator::InterpolateFields(vtkUnstructuredGrid* usgOu
return 0;
}
int dictSize = key->Size(info);
vtkQuadratureSchemeDefinition** dict = new vtkQuadratureSchemeDefinition*[dictSize];
key->GetRange(info, dict, 0, 0, dictSize);
std::vector<vtkQuadratureSchemeDefinition*> dict(dictSize);
key->GetRange(info, dict.data(), 0, 0, dictSize);
// interpolate the arrays
for (int arrayId = 0; arrayId < nArrays; ++arrayId)
{
// Grab the next array
vtkDataArray* V = usgOut->GetPointData()->GetArray(arrayId);
int V_type = V->GetDataType();
void* pV = V->GetVoidPointer(0);
// Use two arrays, one with the interpolated values,
// the other with offsets to the start of each cell's
......@@ -175,18 +180,18 @@ int vtkQuadraturePointInterpolator::InterpolateFields(vtkUnstructuredGrid* usgOu
interpolated->Delete();
// For all cells interpolate.
switch (V_type)
{
vtkTemplateMacro(
if (!vtkQuadraturePointsUtilities::Interpolate(usgOut, nCells, static_cast<VTK_TT*>(pV),
nComps, dict, interpolated, pOffsets, O_Type)) {
vtkWarningMacro("Failed to interpolate fields "
"to quadrature points. Aborting.");
return 0;
});
// Don't restrict the value array's type, but only use the fast path for
// integral offsets.
using vtkArrayDispatch::AllTypes;
using vtkArrayDispatch::Integrals;
using Dispatcher = vtkArrayDispatch::Dispatch2ByValueType<AllTypes, Integrals>;
vtkQuadraturePointsUtilities::InterpolateWorker worker;
if (!Dispatcher::Execute(V, offsets, worker, usgOut, nCells, dict, interpolated))
{ // fall back to slow path:
worker(V, offsets, usgOut, nCells, dict, interpolated);
}
}
delete[] dict;
return 1;
}
......
......@@ -15,10 +15,12 @@
#include "vtkQuadraturePointsGenerator.h"
#include "vtkArrayDispatch.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCellType.h"
#include "vtkDataArray.h"
#include "vtkDataArrayRange.h"
#include "vtkDataSetAttributes.h"
#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
......@@ -38,6 +40,8 @@
#include "vtkQuadratureSchemeDefinition.h"
#include <sstream>
#include <vector>
using std::ostringstream;
//-----------------------------------------------------------------------------
......@@ -89,6 +93,89 @@ int vtkQuadraturePointsGenerator::RequestData(
return 1;
}
namespace
{
struct GenerateWorker
{
template <typename OffsetArrayT>
void operator()(OffsetArrayT* offsetArray, vtkDataArray* data, vtkUnstructuredGrid* usgIn,
vtkPolyData* pdOut, std::vector<vtkQuadratureSchemeDefinition*>& dict)
{
const auto offsets = vtk::DataArrayValueRange<1>(offsetArray);
const vtkIdType numCells = usgIn->GetNumberOfCells();
const vtkIdType numVerts = pdOut->GetNumberOfPoints();
vtkIdType previous = -1;
bool shallowok = true;
for (vtkIdType cellId = 0; cellId < numCells; cellId++)
{
vtkIdType offset = static_cast<vtkIdType>(offsets[cellId]);
if (offset != previous + 1)
{
shallowok = false;
break;
}
const int cellType = usgIn->GetCellType(cellId);
if (dict[cellType] == nullptr)
{
previous = offset;
}
else
{
previous = offset + dict[cellType]->GetNumberOfQuadraturePoints();
}
}
if ((previous + 1) != numVerts)
{
shallowok = false;
}
if (shallowok)
{
// ok, all the original cells are here, we can shallow copy the array
// from input to output
pdOut->GetPointData()->AddArray(data);
}
else
{
// in this case, we have to duplicate the valid tuples
vtkDataArray* V_out = data->NewInstance();
V_out->SetName(data->GetName());
V_out->SetNumberOfComponents(data->GetNumberOfComponents());
V_out->CopyComponentNames(data);
for (vtkIdType cellId = 0; cellId < numCells; cellId++)
{
vtkIdType offset = static_cast<vtkIdType>(offsets[cellId]);
const int cellType = usgIn->GetCellType(cellId);
// a simple check to see if a scheme really exists for this cell type.
// should not happen if the cell type has not been modified.
if (dict[cellType] == nullptr)
{
continue;
}
int np = dict[cellType]->GetNumberOfQuadraturePoints();
for (int id = 0; id < np; id++)
{
V_out->InsertNextTuple(offset + id, data);
}
}
V_out->Squeeze();
pdOut->GetPointData()->AddArray(V_out);
V_out->Delete();
}
}
};
} // end anon namespace
// ----------------------------------------------------------------------------
int vtkQuadraturePointsGenerator::GenerateField(
vtkUnstructuredGrid* usgIn, vtkDataArray* data, vtkDataArray* offsets, vtkPolyData* pdOut)
......@@ -103,79 +190,26 @@ int vtkQuadraturePointsGenerator::GenerateField(
return 0;
}
int dictSize = key->Size(info);
vtkQuadratureSchemeDefinition** dict = new vtkQuadratureSchemeDefinition*[dictSize];
key->GetRange(info, dict, 0, 0, dictSize);
vtkIdType nVerts = pdOut->GetNumberOfPoints();
vtkIdType cellId;
vtkIdType ncell = usgIn->GetNumberOfCells();
int cellType;
// first loop through all cells to check if a shallow copy is possible
bool shallowok = true;
vtkIdType previous = -1;
int offsetType = offsets->GetDataType();
void* pOffsets = offsets->GetVoidPointer(0);
switch (offsetType)
if (offsets->GetNumberOfComponents() != 1)
{
vtkTemplateMacro(
for (cellId = 0; cellId < ncell; cellId++) {
vtkIdType offset = static_cast<vtkIdType>(((VTK_TT*)pOffsets)[cellId]);
if (offset != previous + 1)
{
shallowok = false;
break;
}
cellType = usgIn->GetCellType(cellId);
vtkErrorMacro("Expected offset array to only have a single component.");
return 0;
}
if (dict[cellType] == nullptr)
{
previous = offset;
}
else
{
previous = offset + dict[cellType]->GetNumberOfQuadraturePoints();
}
}
int dictSize = key->Size(info);
std::vector<vtkQuadratureSchemeDefinition*> dict(dictSize);
key->GetRange(info, dict.data(), 0, 0, dictSize);
if ((previous + 1) != nVerts) { shallowok = false; }
if (shallowok) {
// ok, all the original cells are here, we can shallow copy the array
// from input to output
pdOut->GetPointData()->AddArray(data);
} else {
// in this case, we have to duplicate the valid tuples
vtkDataArray* V_out = data->NewInstance();
V_out->SetName(data->GetName());
V_out->SetNumberOfComponents(data->GetNumberOfComponents());
V_out->CopyComponentNames(data);
for (cellId = 0; cellId < ncell; cellId++)
{
vtkIdType offset = static_cast<vtkIdType>(((VTK_TT*)pOffsets)[cellId]);
cellType = usgIn->GetCellType(cellId);
// a simple check to see if a scheme really exists for this cell type.
// should not happen if the cell type has not been modified.
if (dict[cellType] == nullptr)
{
continue;
}
int np = dict[cellType]->GetNumberOfQuadraturePoints();
for (int id = 0; id < np; id++)
{
V_out->InsertNextTuple(offset + id, data);
}
}
V_out->Squeeze();
pdOut->GetPointData()->AddArray(V_out);
V_out->Delete();
});
// Use a fast path that assumes the offsets are integral:
using vtkArrayDispatch::Integrals;
using Dispatcher = vtkArrayDispatch::DispatchByValueType<Integrals>;
GenerateWorker worker;
if (!Dispatcher::Execute(offsets, worker, data, usgIn, pdOut, dict))
{ // Fallback to slow path for other arrays:
worker(offsets, data, usgIn, pdOut, dict);
}
delete[] dict;
return 1;
}
......@@ -189,6 +223,12 @@ int vtkQuadraturePointsGenerator::Generate(
return 0;
}
if (offsets->GetNumberOfComponents() != 1)
{
vtkErrorMacro("Expected offsets array to have only a single component.");
return 0;
}
// Strategy:
// create the points then move the FieldData to PointData
......@@ -209,13 +249,11 @@ int vtkQuadraturePointsGenerator::Generate(
return 0;
}
int dictSize = key->Size(info);
vtkQuadratureSchemeDefinition** dict = new vtkQuadratureSchemeDefinition*[dictSize];
key->GetRange(info, dict, 0, 0, dictSize);
std::vector<vtkQuadratureSchemeDefinition*> dict(dictSize);
key->GetRange(info, dict.data(), 0, 0, dictSize);
// Grab the point set.
vtkDataArray* X = usgIn->GetPoints()->GetData();
int X_type = X->GetDataType();
void* pX = X->GetVoidPointer(0);
// Create the result array.
vtkDoubleArray* qPts = vtkDoubleArray::New();
......@@ -224,15 +262,12 @@ int vtkQuadraturePointsGenerator::Generate(
qPts->SetNumberOfComponents(3);
// For all cells interpolate.
switch (X_type)
{
vtkTemplateMacro(if (!vtkQuadraturePointsUtilities::Interpolate(
usgIn, nCells, (VTK_TT*)pX, 3, dict, qPts, (int*)nullptr)) {
vtkWarningMacro("Failed to interpolate cell vertices "
"to quadrature points. Aborting.");
});
using Dispatcher = vtkArrayDispatch::Dispatch;
vtkQuadraturePointsUtilities::InterpolateWorker worker;
if (!Dispatcher::Execute(X, worker, usgIn, nCells, dict, qPts))
{ // fall back to slow path:
worker(X, usgIn, nCells, dict, qPts);
}
delete[] dict;
// Add the interpolated quadrature points to the output
vtkIdType nVerts = qPts->GetNumberOfTuples();
......
......@@ -16,11 +16,14 @@
#ifndef vtkQuadraturePointsUtilities_hxx
#define vtkQuadraturePointsUtilities_hxx
#include "vtkDataArrayRange.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkQuadratureSchemeDefinition.h"
#include "vtkUnstructuredGrid.h"
#include <vector>
namespace vtkQuadraturePointsUtilities
{
......@@ -31,74 +34,80 @@ namespace vtkQuadraturePointsUtilities
// "indices" is not 0 then track the indices of where the
// values from each cell start as well. In the case of
// an error the return is 0.
template <class TV, class TI>
int Interpolate(vtkUnstructuredGrid* usg, const vtkIdType nCellsUsg, TV* pV, const int nCompsV,
vtkQuadratureSchemeDefinition** dict, vtkDoubleArray* interpolated, TI* indices)
struct InterpolateWorker
{
// Walk cells.
vtkIdType currentIndex = 0;
for (vtkIdType cellId = 0; cellId < nCellsUsg; ++cellId)
// Version without offsets:
template <typename ValueArrayT>
void operator()(ValueArrayT* valueArray, vtkUnstructuredGrid* usg, const vtkIdType nCellsUsg,
std::vector<vtkQuadratureSchemeDefinition*>& dict, vtkDoubleArray* interpolated)
{
// Point to the start of the data associated with this cell.
if (indices != nullptr)
{
indices[cellId] = static_cast<TI>(currentIndex);
}
// Grab the cell's associated shape function definition.
int cellType = usg->GetCellType(cellId);
vtkQuadratureSchemeDefinition* def = dict[cellType];
if (def == nullptr)
{
// no quadrature scheme been specified for this cell type
// skipping the cell.
continue;
}
vtkIdType nNodes = def->GetNumberOfNodes();
int nQPts = def->GetNumberOfQuadraturePoints();
// Grab the cell's node ids.
const vtkIdType* cellNodeIds = nullptr;
usg->GetCellPoints(cellId, nNodes, cellNodeIds);
// Walk quadrature points.
for (int qPtId = 0; qPtId < nQPts; ++qPtId)
this->operator()(valueArray, static_cast<vtkAOSDataArrayTemplate<vtkIdType>*>(nullptr), usg,
nCellsUsg, dict, interpolated);
}
// Version with offsets:
template <typename ValueArrayT, typename IndexArrayT>
void operator()(ValueArrayT* valueArray, IndexArrayT* indexArray, vtkUnstructuredGrid* usg,
const vtkIdType nCellsUsg, std::vector<vtkQuadratureSchemeDefinition*>& dict,
vtkDoubleArray* interpolated)
{
using IndexType = vtk::GetAPIType<IndexArrayT>;
const vtk::ComponentIdType nCompsV = valueArray->GetNumberOfComponents();
const auto valueTuples = vtk::DataArrayTupleRange(valueArray);
// Walk cells.
vtkIdType currentIndex = 0;
for (vtkIdType cellId = 0; cellId < nCellsUsg; ++cellId)
{
// Grab the result and initialize.
double* r = interpolated->WritePointer(currentIndex, nCompsV);
for (int q = 0; q < nCompsV; ++q)
if (indexArray)
{
r[q] = 0.0;
// Point to the start of the data associated with this cell.
auto indices = vtk::DataArrayValueRange<1>(indexArray);
indices[cellId] = static_cast<IndexType>(currentIndex);
}
// Grab shape function weights.
const double* N = def->GetShapeFunctionWeights(qPtId);
// Walk the cell's nodes.
for (int j = 0; j < nNodes; ++j)
// Grab the cell's associated shape function definition.
int cellType = usg->GetCellType(cellId);
vtkQuadratureSchemeDefinition* def = dict[cellType];
if (def == nullptr)
{
vtkIdType tupIdx = cellNodeIds[j] * nCompsV;
// Apply shape function weights.
// no quadrature scheme been specified for this cell type
// skipping the cell.
continue;
}
vtkIdType nNodes = def->GetNumberOfNodes();
int nQPts = def->GetNumberOfQuadraturePoints();
// Grab the cell's node ids.
const vtkIdType* cellNodeIds = nullptr;
usg->GetCellPoints(cellId, nNodes, cellNodeIds);
// Walk quadrature points.
for (int qPtId = 0; qPtId < nQPts; ++qPtId)
{
// Grab the result and initialize.
double* r = interpolated->WritePointer(currentIndex, nCompsV);
for (int q = 0; q < nCompsV; ++q)
{
r[q] += N[j] * pV[tupIdx + q];
r[q] = 0.0;
}
// Grab shape function weights.
const double* N = def->GetShapeFunctionWeights(qPtId);
// Walk the cell's nodes.
for (int j = 0; j < nNodes; ++j)
{
// Apply shape function weights.
const auto tuple = valueTuples[cellNodeIds[j]];
for (int q = 0; q < nCompsV; ++q)
{
r[q] += N[j] * tuple[q];
}
}
// Update the result index.
currentIndex += nCompsV;
}
// Update the result index.
currentIndex += nCompsV;
}
}
return 1;
}
// Description:
// Dispatch helper, decides what type of indices we are working with
template <class TV>
int Interpolate(vtkUnstructuredGrid* usg, const vtkIdType nCellsUsg, TV* pV, const int nCompsV,
vtkQuadratureSchemeDefinition** dict, vtkDoubleArray* interpolated, void* indices, int indexType)
{
switch (indexType)
{
vtkTemplateMacro(
return Interpolate(usg, nCellsUsg, pV, nCompsV, dict, interpolated, (VTK_TT*)indices););
}
return 0;
}
};
//------------------------------------------------------------------------------
template <class T>
......
This diff is collapsed.
......@@ -14,8 +14,10 @@
=========================================================================*/
#include "vtkSplitField.h"
#include "vtkArrayDispatch.h"
#include "vtkCellData.h"
#include "vtkDataArray.h"
#include "vtkDataArrayRange.h"
#include "vtkDataSet.h"
#include "vtkDataSetAttributes.h"
#include "vtkInformation.h"
......@@ -269,15 +271,30 @@ int vtkSplitField::RequestData(vtkInformation* vtkNotUsed(request),
return 1;
}
// fast pointer copy
template <class T>
void vtkSplitFieldCopyTuples(T* input, T* output, vtkIdType numTuples, int numComp, int component)
namespace
{
for (int i = 0; i < numTuples; i++)
struct ExtractComponentWorker
{
template <typename ArrayT>
void operator()(ArrayT* input, vtkDataArray* outputDA, vtk::ComponentIdType comp)
{
output[i] = input[numComp * i + component];
// We know these are the same array type:
ArrayT* output = vtkArrayDownCast<ArrayT>(outputDA);
assert(output);
const auto inTuples = vtk::DataArrayTupleRange(input);
auto outComps = vtk::DataArrayValueRange<1>(output);
using TupleCRefT = typename decltype(inTuples)::ConstTupleReferenceType;
using CompT = typename decltype(outComps)::ValueType;
std::transform(inTuples.cbegin(), inTuples.cend(), outComps.begin(),
[&](const TupleCRefT tuple) -> CompT { return tuple[comp]; });
}
}
};
} // end anon namespace
vtkDataArray* vtkSplitField::SplitArray(vtkDataArray* da, int component)
{
......@@ -289,28 +306,14 @@ vtkDataArray* vtkSplitField::SplitArray(vtkDataArray* da, int component)
vtkDataArray* output = da->NewInstance();
output->SetNumberOfComponents(1);
int numTuples = da->GetNumberOfTuples();
vtkIdType numTuples = da->GetNumberOfTuples();
output->SetNumberOfTuples(numTuples);
if (numTuples > 0)
{
switch (output->GetDataType())
{
vtkTemplateMacro(vtkSplitFieldCopyTuples((VTK_TT*)da->GetVoidPointer(0),
(VTK_TT*)output->GetVoidPointer(0), numTuples, da->GetNumberOfComponents(), component));
// This is not supported by the template macro.
// Switch to using the float interface.
case VTK_BIT:
{
for (int i = 0; i < numTuples; i++)
{
output->SetComponent(i, 0, da->GetComponent(i, component));
}
}
break;
default:
vtkErrorMacro(<< "Sanity check failed: Unsupported data type.");
return nullptr;
}
using Dispatcher = vtkArrayDispatch::Dispatch;
ExtractComponentWorker worker;
if (!Dispatcher::Execute(da, worker, output, component))
{ // fallback:
worker(da, output, component);
}
return output;
......
This diff is collapsed.
......@@ -17,6 +17,7 @@
#include "vtkAppendPolyData.h"
#include "vtkCellArray.h"
#include "vtkContourFilter.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
......@@ -514,7 +515,10 @@ int vtkVoxelContoursToSurfaceFilter::RequestData(vtkInformation* vtkNotUsed(requ
volume->SetDimensions(gridSize[0], gridSize[1], chunkSize);
volume->SetSpacing(this->Spacing);
volume->AllocateScalars(VTK_FLOAT, 1);
volumePtr = (float*)(volume->GetPointData()->GetScalars()->GetVoidPointer(0));
vtkDataArray* volumeArrayDA = volume->GetPointData()->GetScalars();
vtkFloatArray* volumeArray = vtkArrayDownCast<vtkFloatArray>(volumeArrayDA);
assert(volumeArray);
volumePtr = volumeArray->GetPointer(0);
contourFilter = vtkContourFilter::New();
contourFilter->SetInputData(volume);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment