2017-04-04 20:00:04 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
|
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
|
|
//
|
|
|
|
// Copyright 2015 Sandia Corporation.
|
|
|
|
// Copyright 2015 UT-Battelle, LLC.
|
|
|
|
// Copyright 2015 Los Alamos National Security.
|
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
|
|
// the U.S. Government retains certain rights in this software.
|
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
|
|
// this software.
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
#ifndef vtk_m_worklet_ExtractStructured_h
|
|
|
|
#define vtk_m_worklet_ExtractStructured_h
|
|
|
|
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
|
|
|
#include <vtkm/cont/CellSetStructured.h>
|
|
|
|
#include <vtkm/cont/DataSet.h>
|
|
|
|
#include <vtkm/cont/DeviceAdapter.h>
|
|
|
|
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ErrorBadValue.h>
|
|
|
|
#include <vtkm/cont/Field.h>
|
|
|
|
|
2017-04-06 19:34:06 +00:00
|
|
|
#include <vtkm/worklet/DispatcherMapField.h>
|
|
|
|
#include <vtkm/worklet/WorkletMapField.h>
|
|
|
|
#include <vtkm/worklet/ScatterCounting.h>
|
2017-04-04 20:00:04 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
#include <vtkm/Math.h>
|
|
|
|
|
2017-04-04 20:00:04 +00:00
|
|
|
namespace vtkm {
|
|
|
|
namespace worklet {
|
|
|
|
|
2017-04-06 19:34:06 +00:00
|
|
|
//
|
|
|
|
// Distribute input point/cell data to subset output point/cell data
|
|
|
|
//
|
|
|
|
struct DistributeData : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
typedef void ControlSignature(FieldIn<> inIndices,
|
|
|
|
FieldOut<> outIndices);
|
|
|
|
typedef void ExecutionSignature(_1, _2);
|
|
|
|
|
|
|
|
typedef vtkm::worklet::ScatterCounting ScatterType;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
ScatterType GetScatter() const { return this->Scatter; }
|
|
|
|
|
|
|
|
template <typename CountArrayType, typename DeviceAdapter>
|
|
|
|
VTKM_CONT
|
|
|
|
DistributeData(const CountArrayType &countArray,
|
|
|
|
DeviceAdapter device) :
|
|
|
|
Scatter(countArray, device) { }
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
VTKM_EXEC
|
|
|
|
void operator()(T inputIndex,
|
|
|
|
T &outputIndex) const
|
|
|
|
{
|
|
|
|
outputIndex = inputIndex;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
ScatterType Scatter;
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Extract subset of structured grid and/or resample
|
|
|
|
//
|
2017-04-04 20:00:04 +00:00
|
|
|
class ExtractStructured
|
|
|
|
{
|
|
|
|
public:
|
2017-04-13 18:36:53 +00:00
|
|
|
ExtractStructured() {}
|
2017-04-06 19:34:06 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-14 19:34:51 +00:00
|
|
|
// Determine if point index is within range of the subset and subsampling
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-14 19:34:51 +00:00
|
|
|
class CreatePointMap : public vtkm::worklet::WorkletMapField
|
2017-04-06 19:34:06 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef void ControlSignature(FieldIn<IdType> index,
|
|
|
|
FieldOut<IdComponentType> passValue);
|
2017-04-10 21:56:00 +00:00
|
|
|
typedef _2 ExecutionSignature(_1);
|
2017-04-06 19:34:06 +00:00
|
|
|
|
|
|
|
vtkm::Id RowSize;
|
|
|
|
vtkm::Id PlaneSize;
|
2017-04-13 20:45:53 +00:00
|
|
|
vtkm::Bounds OutBounds;
|
2017-04-13 18:36:53 +00:00
|
|
|
vtkm::Id3 Sample;
|
2017-04-06 19:34:06 +00:00
|
|
|
|
|
|
|
VTKM_CONT
|
2017-04-14 19:34:51 +00:00
|
|
|
CreatePointMap(const vtkm::Id3 inDimension,
|
|
|
|
const vtkm::Bounds &outBounds,
|
|
|
|
const vtkm::Id3 &sample) :
|
2017-04-13 18:36:53 +00:00
|
|
|
RowSize(inDimension[1]),
|
|
|
|
PlaneSize(inDimension[1] * inDimension[0]),
|
2017-04-13 20:45:53 +00:00
|
|
|
OutBounds(outBounds),
|
2017-04-13 18:36:53 +00:00
|
|
|
Sample(sample) {}
|
2017-04-06 19:34:06 +00:00
|
|
|
|
|
|
|
VTKM_EXEC
|
2017-04-10 21:56:00 +00:00
|
|
|
vtkm::IdComponent operator()(const vtkm::Id index) const
|
2017-04-06 19:34:06 +00:00
|
|
|
{
|
|
|
|
vtkm::IdComponent passValue = 0;
|
2017-04-13 18:36:53 +00:00
|
|
|
|
|
|
|
// Position of this point or cell in the grid
|
|
|
|
vtkm::IdComponent k = index / PlaneSize;
|
|
|
|
vtkm::IdComponent j = (index % PlaneSize) / RowSize;
|
|
|
|
vtkm::IdComponent i = index % RowSize;
|
|
|
|
|
|
|
|
// Within the subset range
|
2017-04-14 19:34:51 +00:00
|
|
|
vtkm::Id3 ijk = vtkm::Id3(i, j, k);
|
2017-04-13 20:45:53 +00:00
|
|
|
if (OutBounds.Contains(ijk))
|
2017-04-10 21:56:00 +00:00
|
|
|
{
|
2017-04-13 18:36:53 +00:00
|
|
|
// Within the subsampling criteria
|
2017-04-13 20:45:53 +00:00
|
|
|
vtkm::Id3 minPt = vtkm::make_Vec(OutBounds.X.Min,
|
|
|
|
OutBounds.Y.Min,
|
|
|
|
OutBounds.Z.Min);
|
|
|
|
if (((i - minPt[0]) % Sample[0]) == 0 &&
|
|
|
|
((j - minPt[1]) % Sample[1]) == 0 &&
|
|
|
|
((k - minPt[2]) % Sample[2]) == 0)
|
2017-04-13 18:36:53 +00:00
|
|
|
{
|
|
|
|
passValue = 1;
|
2017-04-14 19:34:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return passValue;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Determine if cell index is within range of the subset and subsampling
|
|
|
|
//
|
|
|
|
class CreateCellMap : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef void ControlSignature(FieldIn<IdType> index,
|
|
|
|
FieldOut<IdComponentType> passValue);
|
|
|
|
typedef _2 ExecutionSignature(_1);
|
|
|
|
|
|
|
|
vtkm::Id RowSize;
|
|
|
|
vtkm::Id PlaneSize;
|
|
|
|
vtkm::Bounds OutBounds;
|
|
|
|
vtkm::Id3 Sample;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
CreateCellMap(const vtkm::Id3 inDimension,
|
|
|
|
const vtkm::Bounds &outBounds,
|
|
|
|
const vtkm::Id3 &sample) :
|
|
|
|
RowSize(inDimension[1]),
|
|
|
|
PlaneSize(inDimension[1] * inDimension[0]),
|
|
|
|
OutBounds(outBounds),
|
|
|
|
Sample(sample) {}
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
vtkm::IdComponent operator()(const vtkm::Id index) const
|
|
|
|
{
|
|
|
|
vtkm::IdComponent passValue = 0;
|
|
|
|
|
|
|
|
// Position of this point or cell in the grid
|
|
|
|
vtkm::IdComponent k = index / PlaneSize;
|
|
|
|
vtkm::IdComponent j = (index % PlaneSize) / RowSize;
|
|
|
|
vtkm::IdComponent i = index % RowSize;
|
|
|
|
|
|
|
|
// Within the subset range and sample range
|
|
|
|
// Outer point of cell must be within range or is it not used
|
|
|
|
vtkm::Id3 ijk = vtkm::Id3(i, j, k);
|
|
|
|
vtkm::Id3 ijk1 = ijk + vtkm::Id3(1,1,1);
|
|
|
|
if (OutBounds.Contains(ijk))
|
|
|
|
{
|
|
|
|
if (Sample == vtkm::Id3(1,1,1))
|
|
|
|
{
|
|
|
|
passValue = 1;
|
|
|
|
}
|
|
|
|
else if (OutBounds.Contains(ijk1))
|
|
|
|
{
|
|
|
|
// Within the subsampling criteria
|
|
|
|
vtkm::Id3 minPt = vtkm::make_Vec(OutBounds.X.Min,
|
|
|
|
OutBounds.Y.Min,
|
|
|
|
OutBounds.Z.Min);
|
|
|
|
if (((i - minPt[0]) % Sample[0]) == 0 &&
|
|
|
|
((j - minPt[1]) % Sample[1]) == 0 &&
|
|
|
|
((k - minPt[2]) % Sample[2]) == 0)
|
|
|
|
{
|
|
|
|
passValue = 1;
|
|
|
|
}
|
2017-04-13 18:36:53 +00:00
|
|
|
}
|
2017-04-10 21:56:00 +00:00
|
|
|
}
|
2017-04-06 19:34:06 +00:00
|
|
|
return passValue;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-06 19:34:06 +00:00
|
|
|
// Create maps for mapping point and cell data to subset
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-06 19:34:06 +00:00
|
|
|
template <typename DeviceAdapter>
|
2017-04-13 18:36:53 +00:00
|
|
|
void CreateDataMaps(const vtkm::Id3 &pointDimension,
|
2017-04-06 19:34:06 +00:00
|
|
|
const vtkm::Id &numberOfPoints,
|
|
|
|
const vtkm::Id &numberOfCells,
|
2017-04-13 20:45:53 +00:00
|
|
|
const vtkm::Bounds &outBounds,
|
2017-04-13 18:36:53 +00:00
|
|
|
const vtkm::Id3 &sample,
|
2017-04-06 19:34:06 +00:00
|
|
|
const DeviceAdapter)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandleIndex pointIndices(numberOfPoints);
|
|
|
|
vtkm::cont::ArrayHandleIndex cellIndices(numberOfCells);
|
2017-04-14 19:34:51 +00:00
|
|
|
std::cout << "POINT DIMENSION " << pointDimension << std::endl;
|
2017-04-13 20:45:53 +00:00
|
|
|
std::cout << "POINT BOUNDS " << outBounds << std::endl;
|
2017-04-06 19:34:06 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
// Create the map for the input point data to output
|
2017-04-14 19:34:51 +00:00
|
|
|
CreatePointMap pointWorklet(pointDimension, outBounds, sample);
|
|
|
|
vtkm::worklet::DispatcherMapField<CreatePointMap> pointDispatcher(pointWorklet);
|
2017-04-06 19:34:06 +00:00
|
|
|
pointDispatcher.Invoke(pointIndices,
|
2017-04-13 18:36:53 +00:00
|
|
|
this->PointMap);
|
|
|
|
vtkm::Id count = 0;
|
2017-04-06 19:34:06 +00:00
|
|
|
for (vtkm::Id i = 0; i < numberOfPoints; i++)
|
2017-04-13 18:36:53 +00:00
|
|
|
{
|
2017-04-14 20:59:42 +00:00
|
|
|
if (PointMap.GetPortalControl().Get(i) == 1) count++;
|
2017-04-13 18:36:53 +00:00
|
|
|
}
|
2017-04-14 19:34:51 +00:00
|
|
|
std::cout << "Data Points " << count << std::endl;
|
2017-04-13 18:36:53 +00:00
|
|
|
|
|
|
|
// Create the map for the input cell data to output
|
|
|
|
vtkm::Id3 cellDimension = pointDimension - vtkm::Id3(1,1,1);
|
2017-04-13 20:45:53 +00:00
|
|
|
vtkm::Bounds cellBounds = outBounds;
|
2017-04-14 19:34:51 +00:00
|
|
|
if (cellBounds.X.Max > 1)
|
|
|
|
cellBounds.X.Max -= 1;
|
|
|
|
if (cellBounds.Y.Max > 1)
|
|
|
|
cellBounds.Y.Max -= 1;
|
|
|
|
if (cellBounds.Z.Max > 1)
|
|
|
|
cellBounds.Z.Max -= 1;
|
|
|
|
std::cout << "CELL DIMENSION " << cellDimension << std::endl;
|
2017-04-13 20:45:53 +00:00
|
|
|
std::cout << "CELL BOUNDS " << cellBounds << std::endl;
|
|
|
|
|
2017-04-14 19:34:51 +00:00
|
|
|
CreateCellMap cellWorklet(cellDimension, cellBounds, sample);
|
|
|
|
vtkm::worklet::DispatcherMapField<CreateCellMap> cellDispatcher(cellWorklet);
|
2017-04-06 19:34:06 +00:00
|
|
|
cellDispatcher.Invoke(cellIndices,
|
2017-04-13 18:36:53 +00:00
|
|
|
this->CellMap);
|
|
|
|
count = 0;
|
2017-04-06 19:34:06 +00:00
|
|
|
for (vtkm::Id i = 0; i < numberOfCells; i++)
|
2017-04-13 18:36:53 +00:00
|
|
|
{
|
2017-04-14 20:59:42 +00:00
|
|
|
if (CellMap.GetPortalControl().Get(i) == 1) count++;
|
2017-04-13 18:36:53 +00:00
|
|
|
}
|
2017-04-14 19:34:51 +00:00
|
|
|
std::cout << "Data Cells " << count << std::endl;
|
2017-04-06 19:34:06 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-05 15:36:25 +00:00
|
|
|
// Uniform Structured
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-04 20:00:04 +00:00
|
|
|
template <typename CellSetType,
|
|
|
|
typename DeviceAdapter>
|
2017-04-05 15:36:25 +00:00
|
|
|
vtkm::cont::DataSet ExtractUniform(
|
2017-04-13 18:36:53 +00:00
|
|
|
const vtkm::IdComponent outDim,
|
2017-04-05 15:36:25 +00:00
|
|
|
const CellSetType &cellSet,
|
2017-04-04 20:00:04 +00:00
|
|
|
const vtkm::cont::CoordinateSystem &coordinates,
|
2017-04-13 20:45:53 +00:00
|
|
|
const vtkm::Bounds outBounds,
|
2017-04-10 21:56:00 +00:00
|
|
|
const vtkm::Id3 &sample,
|
2017-04-04 20:00:04 +00:00
|
|
|
DeviceAdapter)
|
|
|
|
{
|
|
|
|
typedef vtkm::cont::ArrayHandleUniformPointCoordinates UniformArrayHandle;
|
|
|
|
typedef typename UniformArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst UniformConstPortal;
|
|
|
|
|
2017-04-05 15:36:25 +00:00
|
|
|
// Cast dynamic coordinate data to Uniform type
|
2017-04-14 20:06:28 +00:00
|
|
|
vtkm::cont::DynamicArrayHandleCoordinateSystem coordinateData = coordinates.GetData();
|
|
|
|
UniformArrayHandle inCoordinates;
|
|
|
|
inCoordinates = coordinateData.Cast<UniformArrayHandle>();
|
2017-04-05 15:36:25 +00:00
|
|
|
|
|
|
|
// Portal to access data in the input coordinate system
|
2017-04-14 20:06:28 +00:00
|
|
|
UniformConstPortal Coordinates = inCoordinates.PrepareForInput(DeviceAdapter());
|
2017-04-05 15:36:25 +00:00
|
|
|
|
|
|
|
// Sizes and values of input Uniform Structured
|
2017-04-13 18:36:53 +00:00
|
|
|
vtkm::Id3 inDimension = Coordinates.GetDimensions();
|
|
|
|
vtkm::Vec<vtkm::FloatDefault,3> inOrigin = Coordinates.GetOrigin();
|
|
|
|
vtkm::Vec<vtkm::FloatDefault,3> inSpacing = Coordinates.GetSpacing();
|
|
|
|
std::cout << "UNIFORM IN DIMENSION " << inDimension << std::endl;
|
|
|
|
std::cout << "UNIFORM IN ORIGIN " << inOrigin << std::endl;
|
|
|
|
std::cout << "UNIFORM IN SPACING " << inSpacing << std::endl;
|
2017-04-05 15:36:25 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
// Sizes of output Uniform with subsets and sampling
|
2017-04-13 20:45:53 +00:00
|
|
|
vtkm::Id3 outDimension = vtkm::make_Vec(outBounds.X.Max - outBounds.X.Min + 1,
|
|
|
|
outBounds.Y.Max - outBounds.Y.Min + 1,
|
|
|
|
outBounds.Z.Max - outBounds.Z.Min + 1);
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::IdComponent dim = 0; dim < outDim; dim++)
|
2017-04-10 21:56:00 +00:00
|
|
|
{
|
2017-04-13 18:36:53 +00:00
|
|
|
if (sample[dim] > 1)
|
|
|
|
{
|
|
|
|
outDimension[dim] = outDimension[dim] / sample[dim] + 1;
|
|
|
|
}
|
2017-04-10 21:56:00 +00:00
|
|
|
}
|
2017-04-14 19:34:51 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
vtkm::Vec<vtkm::FloatDefault,3> outOrigin = vtkm::make_Vec(0,0,0);
|
|
|
|
vtkm::Vec<vtkm::FloatDefault,3> outSpacing = vtkm::make_Vec(1,1,1);
|
|
|
|
std::cout << "UNIFORM OUT DIMENSION " << outDimension << std::endl;
|
|
|
|
std::cout << "UNIFORM OUT ORIGIN " << outOrigin << std::endl;
|
|
|
|
std::cout << "UNIFORM OUT SPACING " << outSpacing << std::endl;
|
|
|
|
|
|
|
|
// Create output dataset which needs modified coordinate system and cellset
|
2017-04-05 15:36:25 +00:00
|
|
|
vtkm::cont::DataSet output;
|
|
|
|
|
2017-04-05 18:33:05 +00:00
|
|
|
// Set the output CoordinateSystem information
|
2017-04-13 18:36:53 +00:00
|
|
|
UniformArrayHandle outCoordinateData(outDimension, outOrigin, outSpacing);
|
2017-04-05 15:36:25 +00:00
|
|
|
vtkm::cont::CoordinateSystem outCoordinates(coordinates.GetName(), outCoordinateData);
|
|
|
|
output.AddCoordinateSystem(outCoordinates);
|
|
|
|
|
2017-04-14 20:06:28 +00:00
|
|
|
// Set the output cellset
|
2017-04-14 19:34:51 +00:00
|
|
|
if (outDim == 3)
|
|
|
|
{
|
|
|
|
vtkm::cont::CellSetStructured<3> outCellSet(cellSet.GetName());
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[0],
|
|
|
|
outDimension[1],
|
|
|
|
outDimension[2]));
|
2017-04-05 15:36:25 +00:00
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
2017-04-14 19:34:51 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
else if (outDim == 2)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::CellSetStructured<2> outCellSet(cellSet.GetName());
|
2017-04-14 19:34:51 +00:00
|
|
|
if (outDimension[2] == 1) // XY plane
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[0],
|
|
|
|
outDimension[1]));
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[1] == 1) // XZ plane
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[0],
|
|
|
|
outDimension[2]));
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[0] == 1) // YZ plane
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[1],
|
|
|
|
outDimension[2]));
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
2017-04-14 19:34:51 +00:00
|
|
|
|
|
|
|
else if (outDim == 1)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
2017-04-14 19:34:51 +00:00
|
|
|
vtkm::cont::CellSetStructured<1> outCellSet(cellSet.GetName());
|
|
|
|
if (outDimension[1] == 1 && outDimension[2] == 1)
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(outDimension[0]);
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[0] == 1 && outDimension[2] == 1)
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(outDimension[1]);
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[0] == 1 && outDimension[1] == 1)
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(outDimension[2]);
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
2017-04-14 19:34:51 +00:00
|
|
|
std::cout << "Geometry Points " << output.GetCellSet(0).GetNumberOfPoints() << std::endl;
|
|
|
|
std::cout << "Geometry Cells " << output.GetCellSet(0).GetNumberOfCells() << std::endl;
|
2017-04-06 20:11:49 +00:00
|
|
|
|
2017-04-06 19:34:06 +00:00
|
|
|
// Calculate and save the maps of point and cell data to subset
|
2017-04-13 18:36:53 +00:00
|
|
|
CreateDataMaps(inDimension,
|
|
|
|
cellSet.GetNumberOfPoints(),
|
|
|
|
cellSet.GetNumberOfCells(),
|
2017-04-13 20:45:53 +00:00
|
|
|
outBounds,
|
2017-04-13 18:36:53 +00:00
|
|
|
sample,
|
|
|
|
DeviceAdapter());
|
2017-04-05 15:36:25 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-05 15:36:25 +00:00
|
|
|
// Rectilinear Structured
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
2017-04-05 15:36:25 +00:00
|
|
|
template <typename CellSetType,
|
|
|
|
typename DeviceAdapter>
|
|
|
|
vtkm::cont::DataSet ExtractRectilinear(
|
2017-04-13 18:36:53 +00:00
|
|
|
const vtkm::IdComponent outDim,
|
2017-04-05 15:36:25 +00:00
|
|
|
const CellSetType &cellSet,
|
|
|
|
const vtkm::cont::CoordinateSystem &coordinates,
|
2017-04-13 20:45:53 +00:00
|
|
|
const vtkm::Bounds &outBounds,
|
2017-04-10 21:56:00 +00:00
|
|
|
const vtkm::Id3 &sample,
|
2017-04-05 15:36:25 +00:00
|
|
|
DeviceAdapter)
|
|
|
|
{
|
2017-04-04 20:00:04 +00:00
|
|
|
typedef vtkm::cont::ArrayHandle<vtkm::FloatDefault> DefaultHandle;
|
|
|
|
typedef vtkm::cont::ArrayHandleCartesianProduct<DefaultHandle,DefaultHandle,DefaultHandle> CartesianArrayHandle;
|
|
|
|
typedef typename DefaultHandle::ExecutionTypes<DeviceAdapter>::PortalConst DefaultConstHandle;
|
|
|
|
typedef typename CartesianArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst CartesianConstPortal;
|
|
|
|
|
2017-04-05 15:36:25 +00:00
|
|
|
// Cast dynamic coordinate data to Rectilinear type
|
2017-04-14 20:06:28 +00:00
|
|
|
vtkm::cont::DynamicArrayHandleCoordinateSystem coordinateData = coordinates.GetData();
|
|
|
|
CartesianArrayHandle inCoordinates;
|
|
|
|
inCoordinates = coordinateData.Cast<CartesianArrayHandle>();
|
2017-04-05 15:36:25 +00:00
|
|
|
|
2017-04-14 20:06:28 +00:00
|
|
|
CartesianConstPortal Coordinates = inCoordinates.PrepareForInput(DeviceAdapter());
|
2017-04-05 15:36:25 +00:00
|
|
|
DefaultConstHandle X = Coordinates.GetFirstPortal();
|
|
|
|
DefaultConstHandle Y = Coordinates.GetSecondPortal();
|
|
|
|
DefaultConstHandle Z = Coordinates.GetThirdPortal();
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
vtkm::Id3 inDimension(X.GetNumberOfValues(),
|
|
|
|
Y.GetNumberOfValues(),
|
|
|
|
Z.GetNumberOfValues());
|
|
|
|
std::cout << "Number of x coordinates " << inDimension[0] << std::endl;
|
|
|
|
std::cout << "Number of y coordinates " << inDimension[1] << std::endl;
|
|
|
|
std::cout << "Number of z coordinates " << inDimension[2] << std::endl;
|
2017-04-05 15:36:25 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::Id x = 0; x < inDimension[0]; x++)
|
2017-04-05 15:36:25 +00:00
|
|
|
std::cout << "X " << x << " = " << X.Get(x) << std::endl;
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::Id y = 0; y < inDimension[1]; y++)
|
2017-04-05 15:36:25 +00:00
|
|
|
std::cout << "Y " << y << " = " << Y.Get(y) << std::endl;
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::Id z = 0; z < inDimension[2]; z++)
|
2017-04-05 15:36:25 +00:00
|
|
|
std::cout << "Z " << z << " = " << Z.Get(z) << std::endl;
|
|
|
|
|
|
|
|
vtkm::cont::DataSet output;
|
|
|
|
|
|
|
|
// Sizes and values of output Rectilinear Structured
|
2017-04-13 20:45:53 +00:00
|
|
|
vtkm::Id3 outDimension = vtkm::make_Vec(outBounds.X.Max - outBounds.X.Min + 1,
|
|
|
|
outBounds.Y.Max - outBounds.Y.Min + 1,
|
|
|
|
outBounds.Z.Max - outBounds.Z.Min + 1);
|
2017-04-14 20:06:28 +00:00
|
|
|
for (vtkm::IdComponent dim = 0; dim < outDim; dim++)
|
|
|
|
{
|
|
|
|
if (sample[dim] > 1)
|
|
|
|
{
|
|
|
|
outDimension[dim] = outDimension[dim] / sample[dim] + 1;
|
|
|
|
}
|
|
|
|
}
|
2017-04-13 18:36:53 +00:00
|
|
|
std::cout << "RECTILINEAR OUT DIMENSIONS " << outDimension << std::endl;
|
2017-04-05 15:36:25 +00:00
|
|
|
|
|
|
|
// Set output coordinate system
|
|
|
|
DefaultHandle Xc, Yc, Zc;
|
2017-04-13 18:36:53 +00:00
|
|
|
Xc.Allocate(outDimension[0]);
|
|
|
|
Yc.Allocate(outDimension[1]);
|
|
|
|
Zc.Allocate(outDimension[2]);
|
2017-04-05 15:36:25 +00:00
|
|
|
|
|
|
|
vtkm::Id indx = 0;
|
2017-04-14 20:06:28 +00:00
|
|
|
vtkm::Id3 minBound = vtkm::make_Vec(outBounds.X.Min, outBounds.Y.Min, outBounds.Z.Min);
|
|
|
|
vtkm::Id3 maxBound = vtkm::make_Vec(outBounds.X.Max, outBounds.Y.Max, outBounds.Z.Max);
|
2017-04-10 21:56:00 +00:00
|
|
|
for (vtkm::Id x = minBound[0]; x <= maxBound[0]; x++)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
2017-04-14 20:06:28 +00:00
|
|
|
if ((x % sample[0]) == 0)
|
|
|
|
{
|
|
|
|
Xc.GetPortalControl().Set(indx++, X.Get(x));
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
|
|
|
indx = 0;
|
2017-04-10 21:56:00 +00:00
|
|
|
for (vtkm::Id y = minBound[1]; y <= maxBound[1]; y++)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
2017-04-14 20:06:28 +00:00
|
|
|
if ((y % sample[1]) == 0)
|
|
|
|
{
|
|
|
|
Yc.GetPortalControl().Set(indx++, Y.Get(y));
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
|
|
|
indx = 0;
|
2017-04-10 21:56:00 +00:00
|
|
|
for (vtkm::Id z = minBound[2]; z <= maxBound[2]; z++)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
2017-04-14 20:06:28 +00:00
|
|
|
if ((z % sample[2]) == 0)
|
|
|
|
{
|
|
|
|
Zc.GetPortalControl().Set(indx++, Z.Get(z));
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::Id x = 0; x < outDimension[0]; x++)
|
2017-04-05 15:36:25 +00:00
|
|
|
std::cout << "Xc " << x << " = " << Xc.GetPortalControl().Get(x) << std::endl;
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::Id y = 0; y < outDimension[1]; y++)
|
2017-04-05 15:36:25 +00:00
|
|
|
std::cout << "Yc " << y << " = " << Yc.GetPortalControl().Get(y) << std::endl;
|
2017-04-13 18:36:53 +00:00
|
|
|
for (vtkm::Id z = 0; z < outDimension[2]; z++)
|
2017-04-05 15:36:25 +00:00
|
|
|
std::cout << "Zc " << z << " = " << Zc.GetPortalControl().Get(z) << std::endl;
|
2017-04-13 18:36:53 +00:00
|
|
|
|
2017-04-05 15:36:25 +00:00
|
|
|
CartesianArrayHandle outCoordinateData(Xc, Yc, Zc);
|
|
|
|
vtkm::cont::CoordinateSystem outCoordinates(coordinates.GetName(), outCoordinateData);
|
|
|
|
output.AddCoordinateSystem(outCoordinates);
|
|
|
|
|
2017-04-14 20:06:28 +00:00
|
|
|
// Set the output cellset
|
|
|
|
if (outDim == 3)
|
|
|
|
{
|
|
|
|
vtkm::cont::CellSetStructured<3> outCellSet(cellSet.GetName());
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[0],
|
|
|
|
outDimension[1],
|
|
|
|
outDimension[2]));
|
2017-04-05 15:36:25 +00:00
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
2017-04-14 20:06:28 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
else if (outDim == 2)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::CellSetStructured<2> outCellSet(cellSet.GetName());
|
2017-04-14 20:06:28 +00:00
|
|
|
if (outDimension[2] == 1) // XY plane
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[0],
|
|
|
|
outDimension[1]));
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[1] == 1) // XZ plane
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[0],
|
|
|
|
outDimension[2]));
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[0] == 1) // YZ plane
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(vtkm::make_Vec(outDimension[1],
|
|
|
|
outDimension[2]));
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
2017-04-14 20:06:28 +00:00
|
|
|
|
|
|
|
else if (outDim == 1)
|
2017-04-05 15:36:25 +00:00
|
|
|
{
|
2017-04-14 20:06:28 +00:00
|
|
|
vtkm::cont::CellSetStructured<1> outCellSet(cellSet.GetName());
|
|
|
|
if (outDimension[1] == 1 && outDimension[2] == 1)
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(outDimension[0]);
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[0] == 1 && outDimension[2] == 1)
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(outDimension[1]);
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
|
|
|
else if (outDimension[0] == 1 && outDimension[1] == 1)
|
|
|
|
{
|
|
|
|
outCellSet.SetPointDimensions(outDimension[2]);
|
|
|
|
output.AddCellSet(outCellSet);
|
|
|
|
}
|
2017-04-05 15:36:25 +00:00
|
|
|
}
|
2017-04-06 20:11:49 +00:00
|
|
|
std::cout << "Number of Cells " << output.GetCellSet(0).GetNumberOfCells() << std::endl;
|
|
|
|
std::cout << "Number of Points " << output.GetCellSet(0).GetNumberOfPoints() << std::endl;
|
|
|
|
|
|
|
|
// Calculate and save the maps of point and cell data to subset
|
2017-04-13 18:36:53 +00:00
|
|
|
CreateDataMaps(inDimension,
|
|
|
|
cellSet.GetNumberOfPoints(),
|
|
|
|
cellSet.GetNumberOfCells(),
|
2017-04-13 20:45:53 +00:00
|
|
|
outBounds,
|
2017-04-13 18:36:53 +00:00
|
|
|
sample,
|
|
|
|
DeviceAdapter());
|
2017-04-06 20:11:49 +00:00
|
|
|
|
2017-04-05 15:36:25 +00:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
|
|
|
// Run extract structured on uniform or rectilinear, subset and/or subsample
|
|
|
|
//
|
2017-04-05 18:33:05 +00:00
|
|
|
template <typename DeviceAdapter>
|
|
|
|
vtkm::cont::DataSet Run(const vtkm::cont::DynamicCellSet &cellSet,
|
2017-04-05 15:36:25 +00:00
|
|
|
const vtkm::cont::CoordinateSystem &coordinates,
|
2017-04-13 20:45:53 +00:00
|
|
|
const vtkm::Bounds &boundingBox,
|
2017-04-10 21:56:00 +00:00
|
|
|
const vtkm::Id3 &sample,
|
2017-04-05 15:36:25 +00:00
|
|
|
DeviceAdapter)
|
|
|
|
{
|
2017-04-13 18:36:53 +00:00
|
|
|
// Check legality of input cellset and set input dimension
|
|
|
|
vtkm::IdComponent inDim = 0;
|
2017-04-05 18:33:05 +00:00
|
|
|
if (cellSet.IsSameType(vtkm::cont::CellSetStructured<1>()))
|
|
|
|
{
|
2017-04-13 18:36:53 +00:00
|
|
|
inDim = 1;
|
2017-04-05 18:33:05 +00:00
|
|
|
}
|
|
|
|
else if (cellSet.IsSameType(vtkm::cont::CellSetStructured<2>()))
|
|
|
|
{
|
2017-04-13 18:36:53 +00:00
|
|
|
inDim = 2;
|
2017-04-05 18:33:05 +00:00
|
|
|
}
|
|
|
|
else if (cellSet.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
|
|
|
{
|
2017-04-13 18:36:53 +00:00
|
|
|
inDim = 3;
|
2017-04-05 18:33:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadType("Only Structured cell sets allowed");
|
|
|
|
return vtkm::cont::DataSet();
|
|
|
|
}
|
2017-04-13 20:45:53 +00:00
|
|
|
std::cout << "INPUT DIMENSION " << inDim << std::endl;
|
2017-04-05 18:33:05 +00:00
|
|
|
|
2017-04-13 20:45:53 +00:00
|
|
|
// Check legality of requested bounds
|
|
|
|
if (boundingBox.IsNonEmpty() == false)
|
2017-04-10 21:56:00 +00:00
|
|
|
{
|
2017-04-13 20:45:53 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue("Requested bounding box is not valid");
|
|
|
|
return vtkm::cont::DataSet();
|
2017-04-10 21:56:00 +00:00
|
|
|
}
|
2017-04-13 20:45:53 +00:00
|
|
|
|
|
|
|
// Check legality of sampling
|
|
|
|
if (sample[0] < 1 || sample[1] < 1 || sample[2] < 1)
|
2017-04-10 21:56:00 +00:00
|
|
|
{
|
2017-04-13 20:45:53 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue("Requested sampling is not valid");
|
|
|
|
return vtkm::cont::DataSet();
|
2017-04-13 18:36:53 +00:00
|
|
|
}
|
2017-04-13 20:45:53 +00:00
|
|
|
|
|
|
|
// Requested bounding box intersection with input bounding box
|
|
|
|
vtkm::Bounds inBounds = coordinates.GetBounds();
|
|
|
|
vtkm::Bounds outBounds = boundingBox;
|
|
|
|
std::cout << "INPUT BOUNDING BOX " << inBounds << std::endl;
|
|
|
|
std::cout << "ORIGINAL BOUNDING BOX " << boundingBox << std::endl;
|
|
|
|
std::cout << "SAMPLE " << sample << std::endl;
|
|
|
|
|
|
|
|
if (outBounds.X.Min < inBounds.X.Min)
|
|
|
|
outBounds.X.Min = inBounds.X.Min;
|
|
|
|
if (outBounds.X.Max > inBounds.X.Max)
|
|
|
|
outBounds.X.Max = inBounds.X.Max;
|
|
|
|
if (outBounds.Y.Min < inBounds.Y.Min)
|
|
|
|
outBounds.Y.Min = inBounds.Y.Min;
|
|
|
|
if (outBounds.Y.Max > inBounds.Y.Max)
|
|
|
|
outBounds.Y.Max = inBounds.Y.Max;
|
|
|
|
if (outBounds.Z.Min < inBounds.Z.Min)
|
|
|
|
outBounds.Z.Min = inBounds.Z.Min;
|
|
|
|
if (outBounds.Z.Max > inBounds.Z.Max)
|
|
|
|
outBounds.Z.Max = inBounds.Z.Max;
|
2017-04-14 19:34:51 +00:00
|
|
|
std::cout << "OUTPUT BOUNDING BOX " << outBounds << std::endl;
|
2017-04-13 20:45:53 +00:00
|
|
|
|
|
|
|
// Bounding box intersects
|
|
|
|
if (outBounds.IsNonEmpty() == false)
|
2017-04-13 18:36:53 +00:00
|
|
|
{
|
2017-04-13 20:45:53 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue("Bounding box does not intersect input");
|
|
|
|
return vtkm::cont::DataSet();
|
2017-04-10 21:56:00 +00:00
|
|
|
}
|
|
|
|
|
2017-04-14 19:34:51 +00:00
|
|
|
// Set output dimension based on bounding box and input dimension
|
|
|
|
vtkm::IdComponent outDim = 0;
|
|
|
|
if (outBounds.X.Min < outBounds.X.Max)
|
|
|
|
outDim++;
|
|
|
|
if (outBounds.Y.Min < outBounds.Y.Max)
|
|
|
|
outDim++;
|
|
|
|
if (outBounds.Z.Min < outBounds.Z.Max)
|
|
|
|
outDim++;
|
|
|
|
if (outDim > inDim)
|
|
|
|
outDim = inDim;
|
|
|
|
std::cout << "OUTPUT DIMENSION " << outDim << std::endl;
|
|
|
|
|
2017-04-13 20:45:53 +00:00
|
|
|
// Uniform, Regular or Rectilinear
|
2017-04-05 15:36:25 +00:00
|
|
|
typedef vtkm::cont::ArrayHandleUniformPointCoordinates UniformArrayHandle;
|
2017-04-05 18:33:05 +00:00
|
|
|
bool IsUniformDataSet = 0;
|
2017-04-04 20:00:04 +00:00
|
|
|
if (coordinates.GetData().IsSameType(UniformArrayHandle()))
|
|
|
|
{
|
|
|
|
IsUniformDataSet = true;
|
|
|
|
}
|
|
|
|
if (IsUniformDataSet)
|
|
|
|
{
|
2017-04-14 19:34:51 +00:00
|
|
|
return ExtractUniform(outDim,
|
2017-04-05 18:33:05 +00:00
|
|
|
cellSet,
|
2017-04-05 15:36:25 +00:00
|
|
|
coordinates,
|
2017-04-13 20:45:53 +00:00
|
|
|
outBounds,
|
2017-04-05 15:36:25 +00:00
|
|
|
sample,
|
|
|
|
DeviceAdapter());
|
2017-04-04 20:00:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-14 19:34:51 +00:00
|
|
|
return ExtractRectilinear(outDim,
|
2017-04-05 18:33:05 +00:00
|
|
|
cellSet,
|
2017-04-05 15:36:25 +00:00
|
|
|
coordinates,
|
2017-04-13 20:45:53 +00:00
|
|
|
outBounds,
|
2017-04-05 15:36:25 +00:00
|
|
|
sample,
|
|
|
|
DeviceAdapter());
|
2017-04-04 20:00:04 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-06 19:34:06 +00:00
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
|
|
|
// Subset and/or subsampling of Point Data
|
|
|
|
//
|
2017-04-06 19:34:06 +00:00
|
|
|
template <typename T,
|
|
|
|
typename StorageType,
|
|
|
|
typename DeviceAdapter>
|
|
|
|
vtkm::cont::ArrayHandle<T, StorageType> ProcessPointField(
|
|
|
|
const vtkm::cont::ArrayHandle<T, StorageType> &input,
|
|
|
|
const DeviceAdapter& device)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<T, StorageType> output;
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
DistributeData distribute(this->PointMap, device);
|
|
|
|
vtkm::worklet::DispatcherMapField<DistributeData, DeviceAdapter> dispatch(distribute);
|
|
|
|
dispatch.Invoke(input, output);
|
2017-04-06 19:34:06 +00:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
//
|
|
|
|
// Subset and/or subsampling of Cell Data
|
|
|
|
//
|
2017-04-06 19:34:06 +00:00
|
|
|
template <typename T,
|
|
|
|
typename StorageType,
|
|
|
|
typename DeviceAdapter>
|
|
|
|
vtkm::cont::ArrayHandle<T, StorageType> ProcessCellField(
|
|
|
|
const vtkm::cont::ArrayHandle<T, StorageType> &input,
|
|
|
|
const DeviceAdapter& device)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<T, StorageType> output;
|
|
|
|
|
2017-04-13 18:36:53 +00:00
|
|
|
DistributeData distribute(this->CellMap, device);
|
|
|
|
vtkm::worklet::DispatcherMapField<DistributeData, DeviceAdapter> dispatch(distribute);
|
|
|
|
dispatch.Invoke(input, output);
|
2017-04-06 19:34:06 +00:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-04-13 18:36:53 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> PointMap;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> CellMap;
|
2017-04-04 20:00:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
} // namespace vtkm::worklet
|
|
|
|
|
|
|
|
#endif // vtk_m_worklet_ExtractStructured_h
|