Commit bccb00df authored by Matt Larsen's avatar Matt Larsen

allow extract structured to output rectilinear coordinates

parent e0c0e4b3
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h> #include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/CellSetListTag.h> #include <vtkm/cont/CellSetListTag.h>
#include <vtkm/cont/CellSetStructured.h> #include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DynamicCellSet.h> #include <vtkm/cont/DynamicCellSet.h>
namespace vtkm namespace vtkm
...@@ -354,109 +355,90 @@ public: ...@@ -354,109 +355,90 @@ public:
} }
private: private:
class CoordinatesMapper using UniformCoordinatesArrayHandle = vtkm::cont::ArrayHandleUniformPointCoordinates::Superclass;
{
private:
using UniformCoordinatesArrayHandle =
vtkm::cont::ArrayHandleUniformPointCoordinates::Superclass;
template <typename T, typename Storage1, typename Storage2, typename Storage3>
using RectilinearCoordinatesArrayHandle = typename vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<T, Storage1>,
vtkm::cont::ArrayHandle<T, Storage2>,
vtkm::cont::ArrayHandle<T, Storage3>>::Superclass;
public:
CoordinatesMapper(const ExtractStructured* worklet,
vtkm::cont::ArrayHandleVirtualCoordinates& result)
: Worklet(worklet)
, Result(&result)
{
}
void operator()(const UniformCoordinatesArrayHandle& coords) const using RectilinearCoordinatesArrayHandle = vtkm::cont::ArrayHandleCartesianProduct<
{ vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
using CoordsArray = vtkm::cont::ArrayHandleUniformPointCoordinates; vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
using CoordType = CoordsArray::ValueType; vtkm::cont::ArrayHandle<vtkm::FloatDefault>>::Superclass;
using ValueType = CoordType::ComponentType;
const auto& portal = coords.GetPortalConstControl();
CoordType inOrigin = portal.GetOrigin();
CoordType inSpacing = portal.GetSpacing();
CoordType outOrigin = vtkm::make_Vec(
inOrigin[0] + static_cast<ValueType>(this->Worklet->VOI.X.Min) * inSpacing[0],
inOrigin[1] + static_cast<ValueType>(this->Worklet->VOI.Y.Min) * inSpacing[1],
inOrigin[2] + static_cast<ValueType>(this->Worklet->VOI.Z.Min) * inSpacing[2]);
CoordType outSpacing = inSpacing * static_cast<CoordType>(this->Worklet->SampleRate);
auto out = CoordsArray(this->Worklet->OutputDimensions, outOrigin, outSpacing);
*this->Result = vtkm::cont::ArrayHandleVirtualCoordinates(out);
}
template <typename T, typename Storage1, typename Storage2, typename Storage3>
void operator()(
const RectilinearCoordinatesArrayHandle<T, Storage1, Storage2, Storage3>& coords) const
{
vtkm::cont::ArrayHandle<T> xs, ys, zs;
// For structured datasets, the cellsets are of different types based on
// its dimensionality, but the coordinates are always 3 dimensional.
// We can map the axis of the cellset to the coordinates by looking at the
// length of a coordinate axis array.
const AxisIndexArrayPoints* validIds[3] = {
&this->Worklet->ValidPoints.GetStorage().GetFirstArray(),
&this->Worklet->ValidPoints.GetStorage().GetSecondArray(),
&this->Worklet->ValidPoints.GetStorage().GetThirdArray()
};
int dim = 0;
dim += RectilinearCoordsCopy(coords.GetStorage().GetFirstArray(), *validIds[dim], xs);
dim += RectilinearCoordsCopy(coords.GetStorage().GetSecondArray(), *validIds[dim], ys);
dim += RectilinearCoordsCopy(coords.GetStorage().GetThirdArray(), *validIds[dim], zs);
VTKM_ASSERT(dim == this->Worklet->InputDimensionality);
auto out = vtkm::cont::make_ArrayHandleCartesianProduct(xs, ys, zs);
*this->Result = vtkm::cont::ArrayHandleVirtualCoordinates(out);
}
template <typename T, typename Storage> vtkm::cont::ArrayHandleVirtualCoordinates MapCoordinatesUniform(
void operator()(const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, Storage>& coords) const const UniformCoordinatesArrayHandle& coords)
{ {
auto out = this->Worklet->ProcessPointField(coords); using CoordsArray = vtkm::cont::ArrayHandleUniformPointCoordinates;
*this->Result = vtkm::cont::ArrayHandleVirtualCoordinates(out); using CoordType = CoordsArray::ValueType;
} using ValueType = CoordType::ComponentType;
const auto& portal = coords.GetPortalConstControl();
CoordType inOrigin = portal.GetOrigin();
CoordType inSpacing = portal.GetSpacing();
CoordType outOrigin =
vtkm::make_Vec(inOrigin[0] + static_cast<ValueType>(this->VOI.X.Min) * inSpacing[0],
inOrigin[1] + static_cast<ValueType>(this->VOI.Y.Min) * inSpacing[1],
inOrigin[2] + static_cast<ValueType>(this->VOI.Z.Min) * inSpacing[2]);
CoordType outSpacing = inSpacing * static_cast<CoordType>(this->SampleRate);
auto out = CoordsArray(this->OutputDimensions, outOrigin, outSpacing);
return vtkm::cont::ArrayHandleVirtualCoordinates(out);
}
private: vtkm::cont::ArrayHandleVirtualCoordinates MapCoordinatesRectilinear(
template <typename T, typename Storage> const RectilinearCoordinatesArrayHandle& coords)
static int RectilinearCoordsCopy(const vtkm::cont::ArrayHandle<T, Storage>& coords, {
const AxisIndexArrayPoints& valid, // For structured datasets, the cellsets are of different types based on
vtkm::cont::ArrayHandle<T>& dest) // its dimensionality, but the coordinates are always 3 dimensional.
// We can map the axis of the cellset to the coordinates by looking at the
// length of a coordinate axis array.
AxisIndexArrayPoints validIds[3] = { this->ValidPoints.GetStorage().GetFirstArray(),
this->ValidPoints.GetStorage().GetSecondArray(),
this->ValidPoints.GetStorage().GetThirdArray() };
vtkm::cont::ArrayHandle<vtkm::FloatDefault> arrays[3] = { coords.GetStorage().GetFirstArray(),
coords.GetStorage().GetSecondArray(),
coords.GetStorage().GetThirdArray() };
vtkm::cont::ArrayHandle<vtkm::FloatDefault> xyzs[3];
int dim = 0;
for (int i = 0; i < 3; ++i)
{ {
if (coords.GetNumberOfValues() == 1) if (arrays[i].GetNumberOfValues() == 1)
{ {
dest.GetPortalControl().Set(0, coords.GetPortalConstControl().Get(0)); xyzs[i].Allocate(1);
return 0; xyzs[i].GetPortalControl().Set(0, arrays[i].GetPortalConstControl().Get(0));
} }
else else
{ {
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandlePermutation(valid, coords), dest); vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandlePermutation(validIds[i], arrays[i]),
return 1; xyzs[i]);
++dim;
} }
} }
VTKM_ASSERT(dim == this->InputDimensionality);
const ExtractStructured* Worklet; auto out = vtkm::cont::make_ArrayHandleCartesianProduct(xyzs[0], xyzs[1], xyzs[2]);
vtkm::cont::ArrayHandleVirtualCoordinates* Result; return vtkm::cont::ArrayHandleVirtualCoordinates(out);
}; }
public: public:
vtkm::cont::ArrayHandleVirtualCoordinates MapCoordinates( vtkm::cont::ArrayHandleVirtualCoordinates MapCoordinates(
const vtkm::cont::CoordinateSystem& coordinates) const vtkm::cont::CoordinateSystem& coordinates)
{ {
vtkm::cont::ArrayHandleVirtualCoordinates result; auto coArray = coordinates.GetData();
CoordinatesMapper mapper(this, result); if (coArray.IsType<UniformCoordinatesArrayHandle>())
vtkm::cont::CastAndCall(coordinates, mapper); {
return result; return this->MapCoordinatesUniform(coArray.Cast<UniformCoordinatesArrayHandle>());
}
else if (coArray.IsType<RectilinearCoordinatesArrayHandle>())
{
return this->MapCoordinatesRectilinear(coArray.Cast<RectilinearCoordinatesArrayHandle>());
}
else
{
auto out = this->ProcessPointField(coArray);
return vtkm::cont::ArrayHandleVirtualCoordinates(out);
}
} }
private: private:
......
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