vtk-m/vtkm/worklet/StreamSurface.h
Kenneth Moreland 8b133288ce Fix deprecation warnings
There was an error that caused deprecation warnings in VTK-m to be
suppressed, which meant that many uses of deprecated features went
unnoticed. This fixes those deprecation warnings.

The majority of the warnings were caused by the use of the deprecated
`Cast`, `CopyTo`, and `ResetTypes` methods of `UnknownArrayHandle` (or
`VariantArrayHandle`). Both `Cast` and `CopyTo` have been subsumed by
`AsArrayHandle` (to make the functionality more clear). `ResetTypes` now
requires a second template argument to define the storage types to try.

Also fixed some issues with `SerializableField` being deprecated.
This class is no longer necessary because `Field` can now be directly
serialized.
2021-01-26 07:56:39 -07:00

283 lines
9.6 KiB
C++

//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_worklet_streamsurface_h
#define vtk_m_worklet_streamsurface_h
#include <typeinfo>
#include <vtkm/VectorAnalysis.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
namespace vtkm
{
namespace worklet
{
class StreamSurface
{
public:
//Helper worklet to count various things in each polyline.
class CountPolylines : public vtkm::worklet::WorkletVisitCellsWithPoints
{
public:
VTKM_CONT
CountPolylines() {}
using ControlSignature = void(CellSetIn, WholeArrayInOut invalidCell, FieldOut ptsPerPolyline);
using ExecutionSignature = void(CellShape shapeType,
PointCount numPoints,
_2 isValid,
_3 ptsPerPolyline);
using InputDomain = _1;
template <typename CellShapeTag, typename InValidType>
VTKM_EXEC void operator()(const CellShapeTag& shapeType,
const vtkm::IdComponent& numPoints,
InValidType& invalidCell,
vtkm::Id& ptsPerPolyline) const
{
// We only support polylines that contain 2 or more points.
if (shapeType.Id == vtkm::CELL_SHAPE_POLY_LINE && numPoints > 1)
ptsPerPolyline = numPoints;
else
{
invalidCell.Set(0, 1);
ptsPerPolyline = 0;
}
}
private:
};
//Helper worklet to determine number of triangles for each pair of polylines
class CountTriangleConn : public vtkm::worklet::WorkletMapField
{
public:
VTKM_CONT
CountTriangleConn() {}
using ControlSignature = void(FieldIn numPts0, FieldIn numPts1, FieldOut outConnCount);
using ExecutionSignature = void(_1 numPts0, _2 numPts1, _3 outConnCount);
using InputDomain = _1;
VTKM_EXEC void operator()(const vtkm::Id& numPts0,
const vtkm::Id& numPts1,
vtkm::Id& outConnCount) const
{
if (numPts0 == numPts1)
outConnCount = (numPts0 - 1) * 2 * 3;
else if (numPts1 < numPts0)
outConnCount = (numPts0 - 1) * 2 * 3 + (numPts1 - numPts0) * 3;
else
outConnCount = (numPts1 - 1) * 2 * 3 + (numPts0 - numPts1) * 3;
}
private:
};
//Helper worklet to generate the stream surface cells
class GenerateCells : public vtkm::worklet::WorkletMapField
{
public:
VTKM_CONT
GenerateCells() {}
using ControlSignature = void(FieldIn numPts0,
FieldIn numPts1,
FieldIn offset0,
FieldIn offset1,
FieldIn connOffset,
WholeArrayOut outConn);
using ExecutionSignature =
void(_1 numPts0, _2 numPts1, _3 ptOffset0, _4 offset1, _5 connOffset, _6 outConn);
using InputDomain = _1;
template <typename OutConnType>
VTKM_EXEC void operator()(const vtkm::Id& numPts0,
const vtkm::Id& numPts1,
const vtkm::Id& offset0,
const vtkm::Id& offset1,
const vtkm::Id& connOffset,
OutConnType& outConn) const
{
vtkm::Id idx0 = 0, idx1 = 0;
vtkm::Id nextToLastIdx0 = numPts0 - 1;
vtkm::Id nextToLastIdx1 = numPts1 - 1;
vtkm::Id outIdx = connOffset;
//There could be different numbers of points in the pairs of polylines.
//Create pairs of triangles as far as possible.
/* polyline0 polyline1
*
* idx0 + 1 x----------- x idx1 + 1
* | \ |
* | \ Tri2 |
* | \ |
* | \ |
* | Tri1 \ |
* | \|
* idx0 + 0 x ---------- x idx1 + 0
*
*/
while (idx0 < nextToLastIdx0 && idx1 < nextToLastIdx1)
{
//Tri 1
outConn.Set(outIdx + 0, offset0 + idx0 + 0);
outConn.Set(outIdx + 1, offset1 + idx1 + 0);
outConn.Set(outIdx + 2, offset0 + idx0 + 1);
//Tri 2
outConn.Set(outIdx + 3, offset0 + idx0 + 1);
outConn.Set(outIdx + 4, offset1 + idx1 + 0);
outConn.Set(outIdx + 5, offset1 + idx1 + 1);
idx0++;
idx1++;
outIdx += 6;
}
// Same number of points in both polylines. We are done.
if (numPts0 == numPts1)
return;
//If we have more points in one polyline, create a triangle fan
//to complete the triangulation.
//polyline0 is at the end, polyline1 still has more points.
/* polyline0 polyline1
*
* x idx1 + 1
* /|
* / |
* / |
* / |
* / Tri |
* / |
* idx0 + 0 x ---------- x idx1 + 0
*
*/
if (idx0 == nextToLastIdx0 && idx1 < nextToLastIdx1)
{
while (idx1 < nextToLastIdx1)
{
outConn.Set(outIdx + 0, offset0 + idx0 + 0);
outConn.Set(outIdx + 1, offset1 + idx1 + 0);
outConn.Set(outIdx + 2, offset1 + idx1 + 1);
idx1++;
outIdx += 3;
}
}
//polyline1 is at the end, polyline0 still has more points.
/* polyline0 polyline1
*
* idx0 + 1 x
* | \
* | \
* | \
* | \
* | Tri \
* | \
* idx0 + 0 x ---------- x idx1 + 0
*
*/
else
{
while (idx0 < nextToLastIdx0)
{
outConn.Set(outIdx + 0, offset0 + idx0 + 0);
outConn.Set(outIdx + 1, offset1 + idx1 + 0);
outConn.Set(outIdx + 2, offset0 + idx0 + 1);
idx0++;
outIdx += 3;
}
}
}
private:
};
VTKM_CONT
StreamSurface() {}
VTKM_CONT
void Run(const vtkm::cont::CoordinateSystem& coords,
const vtkm::cont::DynamicCellSet& cellset,
vtkm::cont::ArrayHandle<vtkm::Vec3f>& newPoints,
vtkm::cont::CellSetSingleType<>& newCells)
{
using ExplCoordsType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
if (!(coords.GetData().IsType<ExplCoordsType>() &&
(cellset.IsSameType(vtkm::cont::CellSetExplicit<>()) ||
cellset.IsSameType(vtkm::cont::CellSetSingleType<>()))))
{
throw vtkm::cont::ErrorBadValue("Stream surface requires polyline data.");
}
//Count number of polylines and make sure we ONLY have polylines
vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, invalidCell;
vtkm::worklet::DispatcherMapTopology<CountPolylines> countInvoker;
//We only care if there are ANY non-polyline cells. So use a one element array.
//Any non-polyline cell will set the value to 1. No need to worry about race conditions
//as the outcasts will all set it to the same value.
invalidCell.Allocate(1);
invalidCell.WritePortal().Set(0, 0);
countInvoker.Invoke(cellset, invalidCell, ptsPerPolyline);
if (invalidCell.ReadPortal().Get(0) == 1)
throw vtkm::cont::ErrorBadValue("Stream surface requires only polyline data.");
vtkm::Id numPolylines = cellset.GetNumberOfCells();
//Compute polyline offsets
vtkm::cont::ArrayHandle<vtkm::Id> polylineOffset;
vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylineOffset);
auto ptsPerPolyline0 = vtkm::cont::make_ArrayHandleView(ptsPerPolyline, 0, numPolylines - 1);
auto ptsPerPolyline1 = vtkm::cont::make_ArrayHandleView(ptsPerPolyline, 1, numPolylines - 1);
//Count the number of triangles to be generated
vtkm::cont::ArrayHandle<vtkm::Id> triangleConnCount, triangleConnOffset;
vtkm::worklet::DispatcherMapField<CountTriangleConn> countTriInvoker;
countTriInvoker.Invoke(ptsPerPolyline0, ptsPerPolyline1, triangleConnCount);
vtkm::cont::Algorithm::ScanExclusive(triangleConnCount, triangleConnOffset);
//Surface points are same as input points.
newPoints = coords.GetData().AsArrayHandle<ExplCoordsType>();
//Create surface triangles
vtkm::Id numConnIds = vtkm::cont::Algorithm::Reduce(triangleConnCount, vtkm::Id(0));
vtkm::cont::ArrayHandle<vtkm::Id> newConnectivity;
newConnectivity.Allocate(numConnIds);
vtkm::worklet::DispatcherMapField<GenerateCells> genCellsDisp;
genCellsDisp.Invoke(ptsPerPolyline0,
ptsPerPolyline1,
vtkm::cont::make_ArrayHandleView(polylineOffset, 0, numPolylines - 1),
vtkm::cont::make_ArrayHandleView(polylineOffset, 1, numPolylines - 1),
triangleConnOffset,
newConnectivity);
newCells.Fill(numConnIds, vtkm::CELL_SHAPE_TRIANGLE, 3, newConnectivity);
}
private:
};
}
}
#endif // vtk_m_worklet_streamsurface_h