2015-07-31 14:33:54 +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.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
2015-07-31 14:33:54 +00:00
|
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
|
|
// Copyright 2014 Los Alamos National Security.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
2015-07-31 14:33:54 +00:00
|
|
|
// 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 vtkm_m_worklet_Clip_h
|
|
|
|
#define vtkm_m_worklet_Clip_h
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
#include <vtkm/worklet/DispatcherMapField.h>
|
2015-07-31 14:33:54 +00:00
|
|
|
#include <vtkm/worklet/DispatcherMapTopology.h>
|
2018-12-07 15:09:21 +00:00
|
|
|
#include <vtkm/worklet/DispatcherReduceByKey.h>
|
|
|
|
#include <vtkm/worklet/Keys.h>
|
|
|
|
#include <vtkm/worklet/WorkletMapField.h>
|
2015-07-31 14:33:54 +00:00
|
|
|
#include <vtkm/worklet/WorkletMapTopology.h>
|
2018-12-07 15:09:21 +00:00
|
|
|
#include <vtkm/worklet/WorkletReduceByKey.h>
|
2018-12-18 04:27:00 +00:00
|
|
|
#include <vtkm/worklet/clip/ClipTables.h>
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
#include <vtkm/cont/Algorithm.h>
|
|
|
|
#include <vtkm/cont/ArrayCopy.h>
|
2017-06-12 16:04:11 +00:00
|
|
|
#include <vtkm/cont/ArrayHandlePermutation.h>
|
2018-11-29 14:19:30 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleVariant.h>
|
2018-08-30 15:53:18 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleView.h>
|
2015-07-31 14:33:54 +00:00
|
|
|
#include <vtkm/cont/CellSetExplicit.h>
|
2015-10-08 16:12:51 +00:00
|
|
|
#include <vtkm/cont/CoordinateSystem.h>
|
2015-07-31 14:33:54 +00:00
|
|
|
#include <vtkm/cont/DynamicCellSet.h>
|
2017-10-23 13:38:33 +00:00
|
|
|
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
2015-09-11 21:13:23 +00:00
|
|
|
#include <vtkm/cont/Timer.h>
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-05-02 16:06:20 +00:00
|
|
|
#include <utility>
|
2015-07-31 14:33:54 +00:00
|
|
|
#include <vtkm/exec/FunctorBase.h>
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
#if defined(THRUST_MAJOR_VERSION) && THRUST_MAJOR_VERSION == 1 && THRUST_MINOR_VERSION == 8 && \
|
|
|
|
THRUST_SUBMINOR_VERSION < 3
|
2015-09-15 15:07:39 +00:00
|
|
|
// Workaround a bug in thrust 1.8.0 - 1.8.2 scan implementations which produces
|
|
|
|
// wrong results
|
2017-09-21 14:33:17 +00:00
|
|
|
VTKM_THIRDPARTY_PRE_INCLUDE
|
2015-09-15 15:07:39 +00:00
|
|
|
#include <thrust/detail/type_traits.h>
|
2017-09-21 14:33:17 +00:00
|
|
|
VTKM_THIRDPARTY_POST_INCLUDE
|
2015-09-15 15:07:39 +00:00
|
|
|
#define THRUST_SCAN_WORKAROUND
|
|
|
|
#endif
|
2015-09-11 21:13:23 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace worklet
|
|
|
|
{
|
2018-05-02 16:06:20 +00:00
|
|
|
struct ClipStats
|
|
|
|
{
|
|
|
|
vtkm::Id NumberOfCells = 0;
|
|
|
|
vtkm::Id NumberOfIndices = 0;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id NumberOfEdgeIndices = 0;
|
|
|
|
|
|
|
|
// Stats for interpolating new points within cell.
|
|
|
|
vtkm::Id NumberOfInCellPoints = 0;
|
|
|
|
vtkm::Id NumberOfInCellIndices = 0;
|
|
|
|
vtkm::Id NumberOfInCellInterpPoints = 0;
|
|
|
|
vtkm::Id NumberOfInCellEdgeIndices = 0;
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-05-02 16:06:20 +00:00
|
|
|
struct SumOp
|
|
|
|
{
|
|
|
|
VTKM_EXEC_CONT
|
2018-12-07 15:09:21 +00:00
|
|
|
ClipStats operator()(const ClipStats& stat1, const ClipStats& stat2) const
|
2018-05-02 16:06:20 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
ClipStats sum = stat1;
|
|
|
|
sum.NumberOfCells += stat2.NumberOfCells;
|
|
|
|
sum.NumberOfIndices += stat2.NumberOfIndices;
|
|
|
|
sum.NumberOfEdgeIndices += stat2.NumberOfEdgeIndices;
|
|
|
|
sum.NumberOfInCellPoints += stat2.NumberOfInCellPoints;
|
|
|
|
sum.NumberOfInCellIndices += stat2.NumberOfInCellIndices;
|
|
|
|
sum.NumberOfInCellInterpPoints += stat2.NumberOfInCellInterpPoints;
|
|
|
|
sum.NumberOfInCellEdgeIndices += stat2.NumberOfInCellEdgeIndices;
|
2018-05-02 16:06:20 +00:00
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
2018-12-07 15:09:21 +00:00
|
|
|
|
|
|
|
struct EdgeInterpolation
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id Vertex1 = -1;
|
|
|
|
vtkm::Id Vertex2 = -1;
|
|
|
|
vtkm::Float64 Weight = 0;
|
|
|
|
|
|
|
|
struct LessThanOp
|
|
|
|
{
|
|
|
|
VTKM_EXEC
|
|
|
|
bool operator()(const EdgeInterpolation& v1, const EdgeInterpolation& v2) const
|
|
|
|
{
|
|
|
|
return (v1.Vertex1 < v2.Vertex1) || (v1.Vertex1 == v2.Vertex1 && v1.Vertex2 < v2.Vertex2);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct EqualToOp
|
|
|
|
{
|
|
|
|
VTKM_EXEC
|
|
|
|
bool operator()(const EdgeInterpolation& v1, const EdgeInterpolation& v2) const
|
|
|
|
{
|
|
|
|
return v1.Vertex1 == v2.Vertex1 && v1.Vertex2 == v2.Vertex2;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
namespace internal
|
|
|
|
{
|
2018-05-02 16:06:20 +00:00
|
|
|
|
2015-11-10 17:24:45 +00:00
|
|
|
template <typename T>
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC_CONT T Scale(const T& val, vtkm::Float64 scale)
|
2015-11-10 17:24:45 +00:00
|
|
|
{
|
|
|
|
return static_cast<T>(scale * static_cast<vtkm::Float64>(val));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, vtkm::IdComponent NumComponents>
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC_CONT vtkm::Vec<T, NumComponents> Scale(const vtkm::Vec<T, NumComponents>& val,
|
|
|
|
vtkm::Float64 scale)
|
2015-11-10 17:24:45 +00:00
|
|
|
{
|
|
|
|
return val * scale;
|
|
|
|
}
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-05-02 16:06:20 +00:00
|
|
|
template <typename Device>
|
2018-12-07 15:09:21 +00:00
|
|
|
class ExecutionConnectivityExplicit
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
private:
|
2018-02-22 13:29:13 +00:00
|
|
|
using UInt8Portal =
|
2018-05-02 16:06:20 +00:00
|
|
|
typename vtkm::cont::ArrayHandle<vtkm::UInt8>::template ExecutionTypes<Device>::Portal;
|
|
|
|
using IdComponentPortal =
|
|
|
|
typename vtkm::cont::ArrayHandle<vtkm::IdComponent>::template ExecutionTypes<Device>::Portal;
|
2018-02-22 13:29:13 +00:00
|
|
|
using IdPortal =
|
2018-05-02 16:06:20 +00:00
|
|
|
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::Portal;
|
2015-07-31 14:33:54 +00:00
|
|
|
|
|
|
|
public:
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-12-07 15:09:21 +00:00
|
|
|
ExecutionConnectivityExplicit() = default;
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-12-07 15:09:21 +00:00
|
|
|
ExecutionConnectivityExplicit(vtkm::cont::ArrayHandle<vtkm::UInt8> shapes,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> numberOfIndices,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> connectivity,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> offsets,
|
|
|
|
ClipStats stats)
|
|
|
|
: Shapes(shapes.PrepareForOutput(stats.NumberOfCells, Device()))
|
|
|
|
, NumberOfIndices(numberOfIndices.PrepareForOutput(stats.NumberOfCells, Device()))
|
|
|
|
, Connectivity(connectivity.PrepareForOutput(stats.NumberOfIndices, Device()))
|
|
|
|
, Offsets(offsets.PrepareForOutput(stats.NumberOfCells, Device()))
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
}
|
2018-12-07 15:09:21 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC
|
2017-05-18 14:29:41 +00:00
|
|
|
void SetCellShape(vtkm::Id cellIndex, vtkm::UInt8 shape) { this->Shapes.Set(cellIndex, shape); }
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC
|
2015-09-01 21:51:21 +00:00
|
|
|
void SetNumberOfIndices(vtkm::Id cellIndex, vtkm::IdComponent numIndices)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
this->NumberOfIndices.Set(cellIndex, numIndices);
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC
|
2015-07-31 14:33:54 +00:00
|
|
|
void SetIndexOffset(vtkm::Id cellIndex, vtkm::Id indexOffset)
|
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
this->Offsets.Set(cellIndex, indexOffset);
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC
|
2015-07-31 14:33:54 +00:00
|
|
|
void SetConnectivity(vtkm::Id connectivityIndex, vtkm::Id pointIndex)
|
|
|
|
{
|
|
|
|
this->Connectivity.Set(connectivityIndex, pointIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-09-01 21:51:21 +00:00
|
|
|
UInt8Portal Shapes;
|
2018-12-07 15:09:21 +00:00
|
|
|
IdComponentPortal NumberOfIndices;
|
2015-07-31 14:33:54 +00:00
|
|
|
IdPortal Connectivity;
|
2018-12-07 15:09:21 +00:00
|
|
|
IdPortal Offsets;
|
2015-07-31 14:33:54 +00:00
|
|
|
};
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
class ConnectivityExplicit : vtkm::cont::ExecutionObjectBase
|
2018-03-05 23:26:12 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT
|
2018-12-07 15:09:21 +00:00
|
|
|
ConnectivityExplicit() = default;
|
2018-03-05 23:26:12 +00:00
|
|
|
|
|
|
|
VTKM_CONT
|
2018-12-07 15:09:21 +00:00
|
|
|
ConnectivityExplicit(const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numberOfIndices,
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
|
|
|
const ClipStats& stats)
|
2018-03-05 23:26:12 +00:00
|
|
|
: Shapes(shapes)
|
2018-12-07 15:09:21 +00:00
|
|
|
, NumberOfIndices(numberOfIndices)
|
2018-03-05 23:26:12 +00:00
|
|
|
, Connectivity(connectivity)
|
2018-12-07 15:09:21 +00:00
|
|
|
, Offsets(offsets)
|
|
|
|
, Stats(stats)
|
2018-03-05 23:26:12 +00:00
|
|
|
{
|
|
|
|
}
|
2018-05-02 16:06:20 +00:00
|
|
|
|
2018-03-05 23:26:12 +00:00
|
|
|
template <typename Device>
|
2018-12-07 15:09:21 +00:00
|
|
|
VTKM_CONT ExecutionConnectivityExplicit<Device> PrepareForExecution(Device) const
|
2018-03-05 23:26:12 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
ExecutionConnectivityExplicit<Device> execConnectivity(
|
|
|
|
this->Shapes, this->NumberOfIndices, this->Connectivity, this->Offsets, this->Stats);
|
|
|
|
return execConnectivity;
|
2018-03-05 23:26:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-05-02 16:06:20 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::UInt8> Shapes;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> NumberOfIndices;
|
2018-05-02 16:06:20 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> Connectivity;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> Offsets;
|
|
|
|
vtkm::worklet::ClipStats Stats;
|
2018-03-05 23:26:12 +00:00
|
|
|
};
|
|
|
|
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
} // namespace internal
|
2015-07-31 14:33:54 +00:00
|
|
|
|
|
|
|
class Clip
|
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
// Add support for invert
|
2015-07-31 14:33:54 +00:00
|
|
|
public:
|
2017-05-18 14:29:41 +00:00
|
|
|
struct TypeClipStats : vtkm::ListTagBase<ClipStats>
|
|
|
|
{
|
|
|
|
};
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
struct TypeEdgeInterp : vtkm::ListTagBase<EdgeInterpolation>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
2015-10-22 00:09:58 +00:00
|
|
|
class ComputeStats : public vtkm::worklet::WorkletMapPointToCell
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
public:
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-12-07 17:58:31 +00:00
|
|
|
ComputeStats(vtkm::Float64 value, bool invert)
|
|
|
|
: Value(value)
|
|
|
|
, Invert(invert)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
using ControlSignature = void(CellSetIn,
|
|
|
|
FieldInPoint<ScalarAll>,
|
|
|
|
ExecObject clippingData,
|
|
|
|
FieldOutCell<TypeClipStats>,
|
|
|
|
FieldOutCell<IdType>);
|
|
|
|
|
2018-12-07 17:58:31 +00:00
|
|
|
using ExecutionSignature = void(CellShape, PointCount, _2, _3, _4, _5);
|
2018-12-07 15:09:21 +00:00
|
|
|
|
|
|
|
using InputDomain = _1;
|
|
|
|
|
2018-12-07 17:58:31 +00:00
|
|
|
template <typename CellShapeTag, typename ScalarFieldVec, typename DeviceAdapter>
|
2018-12-07 15:09:21 +00:00
|
|
|
VTKM_EXEC void operator()(const CellShapeTag shape,
|
2018-12-07 17:58:31 +00:00
|
|
|
const vtkm::IdComponent pointCount,
|
2018-12-07 15:09:21 +00:00
|
|
|
const ScalarFieldVec& scalars,
|
|
|
|
const internal::ClipTables::DevicePortal<DeviceAdapter>& clippingData,
|
|
|
|
ClipStats& clipStat,
|
|
|
|
vtkm::Id& clipDataIndex) const
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2017-09-21 14:33:17 +00:00
|
|
|
(void)shape; // C4100 false positive workaround
|
2015-07-31 14:33:54 +00:00
|
|
|
vtkm::Id caseId = 0;
|
2018-12-07 15:09:21 +00:00
|
|
|
for (vtkm::IdComponent iter = pointCount - 1; iter >= 0; iter--)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 17:58:31 +00:00
|
|
|
if (!this->Invert && static_cast<vtkm::Float64>(scalars[iter]) <= this->Value)
|
2018-12-08 06:27:34 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
caseId++;
|
2018-12-08 06:27:34 +00:00
|
|
|
}
|
|
|
|
else if (this->Invert && static_cast<vtkm::Float64>(scalars[iter]) >= this->Value)
|
|
|
|
{
|
|
|
|
caseId++;
|
|
|
|
}
|
2018-12-07 15:09:21 +00:00
|
|
|
if (iter > 0)
|
|
|
|
caseId *= 2;
|
|
|
|
}
|
|
|
|
vtkm::Id index = clippingData.GetCaseIndex(shape.Id, caseId);
|
|
|
|
clipDataIndex = index;
|
|
|
|
vtkm::Id numberOfCells = clippingData.ValueAt(index++);
|
2018-12-19 05:21:16 +00:00
|
|
|
clipStat.NumberOfCells = numberOfCells;
|
2018-12-07 15:09:21 +00:00
|
|
|
for (vtkm::IdComponent shapes = 0; shapes < numberOfCells; shapes++)
|
|
|
|
{
|
|
|
|
vtkm::Id cellShape = clippingData.ValueAt(index++);
|
|
|
|
vtkm::Id numberOfIndices = clippingData.ValueAt(index++);
|
|
|
|
if (cellShape == 0)
|
2018-03-09 02:28:08 +00:00
|
|
|
{
|
2018-12-19 05:21:16 +00:00
|
|
|
--clipStat.NumberOfCells;
|
2018-12-07 15:09:21 +00:00
|
|
|
// Shape is 0, which is a case of interpolating new point within a cell
|
|
|
|
// Gather stats for later operation.
|
2018-12-19 05:21:16 +00:00
|
|
|
clipStat.NumberOfInCellPoints = 1;
|
|
|
|
clipStat.NumberOfInCellInterpPoints = numberOfIndices;
|
2018-12-07 15:09:21 +00:00
|
|
|
for (vtkm::IdComponent points = 0; points < numberOfIndices; points++, index++)
|
|
|
|
{
|
|
|
|
//Find how many points need to be calculated using edge interpolation.
|
|
|
|
vtkm::Id element = clippingData.ValueAt(index);
|
2018-12-19 05:21:16 +00:00
|
|
|
clipStat.NumberOfInCellEdgeIndices += (element < 100) ? 1 : 0;
|
2018-12-07 15:09:21 +00:00
|
|
|
}
|
2018-03-09 02:28:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
// Collect number of indices required for storing current shape
|
2018-12-19 05:21:16 +00:00
|
|
|
clipStat.NumberOfIndices += numberOfIndices;
|
2018-12-07 15:09:21 +00:00
|
|
|
// Collect number of new points
|
|
|
|
for (vtkm::IdComponent points = 0; points < numberOfIndices; points++, index++)
|
|
|
|
{
|
|
|
|
//Find how many points need to found using edge interpolation.
|
|
|
|
vtkm::Id element = clippingData.ValueAt(index);
|
|
|
|
if (element == 255)
|
|
|
|
{
|
2018-12-19 05:21:16 +00:00
|
|
|
clipStat.NumberOfInCellIndices++;
|
2018-12-07 15:09:21 +00:00
|
|
|
}
|
|
|
|
else if (element < 100)
|
|
|
|
{
|
2018-12-19 05:21:16 +00:00
|
|
|
clipStat.NumberOfEdgeIndices++;
|
2018-12-07 15:09:21 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
vtkm::Float64 Value;
|
2018-12-07 17:58:31 +00:00
|
|
|
bool Invert;
|
2015-07-31 14:33:54 +00:00
|
|
|
};
|
|
|
|
|
2015-10-22 00:09:58 +00:00
|
|
|
class GenerateCellSet : public vtkm::worklet::WorkletMapPointToCell
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
public:
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-08-30 15:53:18 +00:00
|
|
|
GenerateCellSet(vtkm::Float64 value)
|
2017-05-18 14:29:41 +00:00
|
|
|
: Value(value)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
using ControlSignature = void(CellSetIn,
|
|
|
|
FieldInPoint<ScalarAll>,
|
|
|
|
FieldInCell<IdType> clipTableIndices,
|
|
|
|
FieldInCell<TypeClipStats> clipStats,
|
|
|
|
ExecObject clipTables,
|
|
|
|
ExecObject connectivityObject,
|
|
|
|
WholeArrayOut<IdType> edgePointReverseConnectivity,
|
|
|
|
WholeArrayOut<TypeEdgeInterp> edgePointInterpolation,
|
|
|
|
WholeArrayOut<IdType> inCellReverseConnectivity,
|
|
|
|
WholeArrayOut<IdType> inCellEdgeReverseConnectivity,
|
|
|
|
WholeArrayOut<TypeEdgeInterp> inCellEdgeInterpolation,
|
|
|
|
WholeArrayOut<IdType> inCellInterpolationKeys,
|
|
|
|
WholeArrayOut<IdType> inCellInterpolationInfo,
|
|
|
|
WholeArrayOut<IdType> cellMapOutputToInput);
|
|
|
|
|
|
|
|
using ExecutionSignature = void(CellShape,
|
|
|
|
WorkIndex,
|
|
|
|
FromIndices,
|
|
|
|
_2,
|
|
|
|
_3,
|
|
|
|
_4,
|
|
|
|
_5,
|
|
|
|
_6,
|
|
|
|
_7,
|
|
|
|
_8,
|
|
|
|
_9,
|
|
|
|
_10,
|
|
|
|
_11,
|
|
|
|
_12,
|
|
|
|
_13,
|
|
|
|
_14);
|
|
|
|
|
2017-05-26 17:53:28 +00:00
|
|
|
template <typename CellShapeTag,
|
2018-12-07 15:09:21 +00:00
|
|
|
typename PointVecType,
|
|
|
|
typename ScalarVecType,
|
|
|
|
typename ConnectivityObject,
|
|
|
|
typename IdArrayType,
|
|
|
|
typename EdgeInterpolationPortalType,
|
2018-08-30 15:53:18 +00:00
|
|
|
typename DeviceAdapter>
|
2018-12-07 15:09:21 +00:00
|
|
|
VTKM_EXEC void operator()(const CellShapeTag shape,
|
2018-12-08 08:47:28 +00:00
|
|
|
const vtkm::Id workIndex,
|
2018-12-07 15:09:21 +00:00
|
|
|
const PointVecType points,
|
|
|
|
const ScalarVecType scalars,
|
|
|
|
const vtkm::Id clipDataIndex,
|
|
|
|
const ClipStats clipStats,
|
|
|
|
const internal::ClipTables::DevicePortal<DeviceAdapter>& clippingData,
|
|
|
|
ConnectivityObject& connectivityObject,
|
|
|
|
IdArrayType& edgePointReverseConnectivity,
|
|
|
|
EdgeInterpolationPortalType& edgePointInterpolation,
|
|
|
|
IdArrayType& inCellReverseConnectivity,
|
|
|
|
IdArrayType& inCellEdgeReverseConnectivity,
|
|
|
|
EdgeInterpolationPortalType& inCellEdgeInterpolation,
|
|
|
|
IdArrayType& inCellInterpolationKeys,
|
|
|
|
IdArrayType& inCellInterpolationInfo,
|
|
|
|
IdArrayType& cellMapOutputToInput) const
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
(void)shape;
|
|
|
|
vtkm::Id clipIndex = clipDataIndex;
|
|
|
|
|
|
|
|
// Start index for the cells of this case.
|
|
|
|
vtkm::Id cellIndex = clipStats.NumberOfCells;
|
|
|
|
// Start index to store connevtivity of this case.
|
|
|
|
vtkm::Id connectivityIndex = clipStats.NumberOfIndices;
|
|
|
|
// Start indices for reverse mapping into connectivity for this case.
|
|
|
|
vtkm::Id edgeIndex = clipStats.NumberOfEdgeIndices;
|
|
|
|
vtkm::Id inCellIndex = clipStats.NumberOfInCellIndices;
|
|
|
|
vtkm::Id inCellPoints = clipStats.NumberOfInCellPoints;
|
|
|
|
// Start Indices to keep track of interpolation points for new cell.
|
|
|
|
vtkm::Id inCellInterpPointIndex = clipStats.NumberOfInCellInterpPoints;
|
|
|
|
vtkm::Id inCellEdgeInterpIndex = clipStats.NumberOfInCellEdgeIndices;
|
|
|
|
|
|
|
|
// Iterate over the shapes for the current cell and begin to fill connectivity.
|
|
|
|
vtkm::Id numberOfCells = clippingData.ValueAt(clipIndex++);
|
|
|
|
for (vtkm::Id cell = 0; cell < numberOfCells; ++cell)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 17:58:31 +00:00
|
|
|
vtkm::UInt8 cellShape = clippingData.ValueAt(clipIndex++);
|
|
|
|
vtkm::IdComponent numberOfPoints = clippingData.ValueAt(clipIndex++);
|
2018-12-07 15:09:21 +00:00
|
|
|
if (cellShape == 0)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
// Case for a new cell point.
|
|
|
|
|
|
|
|
// 1. Output the input cell id for which we need to generate new point.
|
|
|
|
// 2. Output number of points used for interpolation.
|
|
|
|
// 3. If vertex
|
|
|
|
// - Add vertex to connectivity interpolation information.
|
|
|
|
// 4. If edge
|
|
|
|
// - Add edge interpolation information for new points.
|
|
|
|
// - Reverse connectivity map for new points.
|
|
|
|
// Make an array which has all the elements that need to be used
|
|
|
|
// for interpolation.
|
|
|
|
for (vtkm::IdComponent point = 0; point < numberOfPoints;
|
|
|
|
point++, inCellInterpPointIndex++, clipIndex++)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::IdComponent entry =
|
|
|
|
static_cast<vtkm::IdComponent>(clippingData.ValueAt(clipIndex));
|
|
|
|
inCellInterpolationKeys.Set(inCellInterpPointIndex, workIndex);
|
|
|
|
if (entry >= 100)
|
|
|
|
{
|
|
|
|
inCellInterpolationInfo.Set(inCellInterpPointIndex, points[entry - 100]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
internal::ClipTables::EdgeVec edge = clippingData.GetEdge(shape.Id, entry);
|
|
|
|
VTKM_ASSERT(edge[0] != 255);
|
|
|
|
VTKM_ASSERT(edge[1] != 255);
|
|
|
|
EdgeInterpolation ei;
|
|
|
|
ei.Vertex1 = points[edge[0]];
|
|
|
|
ei.Vertex2 = points[edge[1]];
|
|
|
|
// For consistency purposes keep the points ordered.
|
|
|
|
if (ei.Vertex1 > ei.Vertex2)
|
|
|
|
{
|
|
|
|
this->swap(ei.Vertex1, ei.Vertex2);
|
|
|
|
this->swap(edge[0], edge[1]);
|
|
|
|
}
|
2018-12-08 08:47:28 +00:00
|
|
|
ei.Weight = (static_cast<vtkm::Float64>(scalars[edge[0]]) - this->Value) /
|
2018-12-07 15:09:21 +00:00
|
|
|
static_cast<vtkm::Float64>(scalars[edge[1]] - scalars[edge[0]]);
|
|
|
|
|
|
|
|
inCellEdgeReverseConnectivity.Set(inCellEdgeInterpIndex, inCellInterpPointIndex);
|
|
|
|
inCellEdgeInterpolation.Set(inCellEdgeInterpIndex, ei);
|
|
|
|
inCellEdgeInterpIndex++;
|
|
|
|
}
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
2018-12-07 15:09:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Just a normal cell, generate edge representations,
|
|
|
|
|
|
|
|
// 1. Add cell type to connectivity information.
|
|
|
|
// 2. If vertex
|
|
|
|
// - Add vertex to connectivity information.
|
|
|
|
// 3. If edge point
|
|
|
|
// - Add edge to edge points
|
|
|
|
// - Add edge point index to edge point reverse connectivity.
|
|
|
|
// 4. If cell point
|
|
|
|
// - Add cell point index to connectivity
|
|
|
|
// (as there is only one cell point per required cell)
|
|
|
|
// 5. Store input cell index against current cell for mapping cell data.
|
|
|
|
connectivityObject.SetCellShape(cellIndex, cellShape);
|
|
|
|
connectivityObject.SetNumberOfIndices(cellIndex, numberOfPoints);
|
|
|
|
connectivityObject.SetIndexOffset(cellIndex, connectivityIndex);
|
|
|
|
for (vtkm::IdComponent point = 0; point < numberOfPoints; point++, clipIndex++)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::IdComponent entry =
|
|
|
|
static_cast<vtkm::IdComponent>(clippingData.ValueAt(clipIndex));
|
|
|
|
if (entry == 255) // case of cell point interpolation
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
// Add index of the corresponding cell point.
|
|
|
|
inCellReverseConnectivity.Set(inCellIndex++, connectivityIndex);
|
|
|
|
connectivityObject.SetConnectivity(connectivityIndex, inCellPoints);
|
|
|
|
connectivityIndex++;
|
|
|
|
}
|
|
|
|
else if (entry >= 100) // existing vertex
|
|
|
|
{
|
|
|
|
connectivityObject.SetConnectivity(connectivityIndex++, points[entry - 100]);
|
|
|
|
}
|
|
|
|
else // case of a new edge point
|
|
|
|
{
|
|
|
|
internal::ClipTables::EdgeVec edge = clippingData.GetEdge(shape.Id, entry);
|
|
|
|
VTKM_ASSERT(edge[0] != 255);
|
|
|
|
VTKM_ASSERT(edge[1] != 255);
|
|
|
|
EdgeInterpolation ei;
|
|
|
|
ei.Vertex1 = points[edge[0]];
|
|
|
|
ei.Vertex2 = points[edge[1]];
|
|
|
|
// For consistency purposes keep the points ordered.
|
|
|
|
if (ei.Vertex1 > ei.Vertex2)
|
|
|
|
{
|
|
|
|
this->swap(ei.Vertex1, ei.Vertex2);
|
|
|
|
this->swap(edge[0], edge[1]);
|
|
|
|
}
|
2018-12-08 09:11:59 +00:00
|
|
|
ei.Weight = (static_cast<vtkm::Float64>(scalars[edge[0]]) - this->Value) /
|
2018-12-07 15:09:21 +00:00
|
|
|
static_cast<vtkm::Float64>(scalars[edge[1]] - scalars[edge[0]]);
|
|
|
|
//Add to set of new edge points
|
|
|
|
//Add reverse connectivity;
|
|
|
|
edgePointReverseConnectivity.Set(edgeIndex, connectivityIndex++);
|
|
|
|
edgePointInterpolation.Set(edgeIndex, ei);
|
|
|
|
edgeIndex++;
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
|
|
|
}
|
2018-12-07 15:09:21 +00:00
|
|
|
cellMapOutputToInput.Set(cellIndex, workIndex);
|
|
|
|
++cellIndex;
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
VTKM_EXEC void swap(T& v1, T& v2) const
|
|
|
|
{
|
|
|
|
T temp = v1;
|
|
|
|
v1 = v2;
|
|
|
|
v2 = temp;
|
|
|
|
}
|
2016-08-12 16:38:58 +00:00
|
|
|
|
2015-07-31 14:33:54 +00:00
|
|
|
private:
|
|
|
|
vtkm::Float64 Value;
|
|
|
|
};
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
class ScatterEdgeConnectivity : public vtkm::worklet::WorkletMapField
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
public:
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-12-07 15:09:21 +00:00
|
|
|
ScatterEdgeConnectivity(vtkm::Id edgePointOffset)
|
|
|
|
: EdgePointOffset(edgePointOffset)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
using ControlSignature = void(FieldIn<IdType> sourceValue,
|
|
|
|
FieldIn<IdType> destinationIndices,
|
|
|
|
WholeArrayOut<IdType> destinationData);
|
|
|
|
|
|
|
|
using ExecutionSignature = void(_1, _2, _3);
|
|
|
|
|
|
|
|
using InputDomain = _1;
|
|
|
|
|
|
|
|
template <typename ConnectivityDataType>
|
|
|
|
VTKM_EXEC void operator()(const vtkm::Id sourceValue,
|
|
|
|
const vtkm::Id destinationIndex,
|
|
|
|
ConnectivityDataType& destinationData) const
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
destinationData.Set(destinationIndex, (sourceValue + EdgePointOffset));
|
|
|
|
}
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
private:
|
|
|
|
vtkm::Id EdgePointOffset;
|
|
|
|
};
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
class ScatterInCellConnectivity : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT
|
|
|
|
ScatterInCellConnectivity(vtkm::Id inCellPointOffset)
|
|
|
|
: InCellPointOffset(inCellPointOffset)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
using ControlSignature = void(FieldIn<IdType> destinationIndices,
|
|
|
|
WholeArrayOut<IdType> destinationData);
|
|
|
|
|
|
|
|
using ExecutionSignature = void(_1, _2);
|
|
|
|
|
|
|
|
using InputDomain = _1;
|
|
|
|
|
|
|
|
template <typename ConnectivityDataType>
|
|
|
|
VTKM_EXEC void operator()(const vtkm::Id destinationIndex,
|
|
|
|
ConnectivityDataType& destinationData) const
|
|
|
|
{
|
|
|
|
auto sourceValue = destinationData.Get(destinationIndex);
|
|
|
|
destinationData.Set(destinationIndex, (sourceValue + InCellPointOffset));
|
2015-07-31 14:33:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id InCellPointOffset;
|
2015-07-31 14:33:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Clip()
|
2017-05-18 14:29:41 +00:00
|
|
|
: ClipTablesInstance()
|
2018-12-07 15:09:21 +00:00
|
|
|
, EdgePointsInterpolation()
|
|
|
|
, InCellInterpolationKeys()
|
|
|
|
, InCellInterpolationInfo()
|
|
|
|
, CellMapOutputToInput()
|
|
|
|
, EdgePointsOffset()
|
|
|
|
, InCellPointsOffset()
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
template <typename CellSetList, typename ScalarsArrayHandle>
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::CellSetExplicit<> Run(const vtkm::cont::DynamicCellSetBase<CellSetList>& cellSet,
|
2017-05-26 17:53:28 +00:00
|
|
|
const ScalarsArrayHandle& scalars,
|
|
|
|
vtkm::Float64 value,
|
2018-08-30 15:53:18 +00:00
|
|
|
bool invert)
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
// Create the required output fields.
|
|
|
|
vtkm::cont::ArrayHandle<ClipStats> clipStats;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> clipTableIndices;
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-12-07 17:58:31 +00:00
|
|
|
ComputeStats statsWorklet(value, invert);
|
2018-12-07 15:09:21 +00:00
|
|
|
//Send this CellSet to process
|
|
|
|
vtkm::worklet::DispatcherMapTopology<ComputeStats> statsDispatcher(statsWorklet);
|
|
|
|
statsDispatcher.Invoke(cellSet, scalars, this->ClipTablesInstance, clipStats, clipTableIndices);
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2018-02-16 15:10:21 +00:00
|
|
|
ClipStats zero;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<ClipStats> cellSetStats;
|
2018-08-30 15:53:18 +00:00
|
|
|
ClipStats total =
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::Algorithm::ScanExclusive(clipStats, cellSetStats, ClipStats::SumOp(), zero);
|
|
|
|
clipStats.ReleaseResources();
|
2015-07-31 14:33:54 +00:00
|
|
|
|
2015-09-01 21:51:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> numberOfIndices;
|
2015-07-31 14:33:54 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
|
|
|
|
internal::ConnectivityExplicit connectivityObject(
|
|
|
|
shapes, numberOfIndices, connectivity, offsets, total);
|
|
|
|
|
|
|
|
//Begin Process of Constructing the new CellSet.
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> edgePointReverseConnectivity;
|
|
|
|
edgePointReverseConnectivity.Allocate(total.NumberOfEdgeIndices);
|
|
|
|
vtkm::cont::ArrayHandle<EdgeInterpolation> edgeInterpolation;
|
|
|
|
edgeInterpolation.Allocate(total.NumberOfEdgeIndices);
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> cellPointReverseConnectivity;
|
|
|
|
cellPointReverseConnectivity.Allocate(total.NumberOfInCellIndices);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> cellPointInterpolationKeys;
|
|
|
|
cellPointInterpolationKeys.Allocate(total.NumberOfInCellInterpPoints);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> cellPointInterpolationInfo;
|
|
|
|
cellPointInterpolationInfo.Allocate(total.NumberOfInCellInterpPoints);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> cellPointEdgeReverseConnectivity;
|
|
|
|
cellPointEdgeReverseConnectivity.Allocate(total.NumberOfInCellEdgeIndices);
|
|
|
|
vtkm::cont::ArrayHandle<EdgeInterpolation> cellPointEdgeInterpolation;
|
|
|
|
cellPointEdgeInterpolation.Allocate(total.NumberOfInCellEdgeIndices);
|
|
|
|
|
|
|
|
this->CellMapOutputToInput.Allocate(total.NumberOfCells);
|
|
|
|
|
|
|
|
GenerateCellSet cellSetWorklet(value);
|
|
|
|
//Send this CellSet to process
|
|
|
|
vtkm::worklet::DispatcherMapTopology<GenerateCellSet> cellSetDispatcher(cellSetWorklet);
|
|
|
|
cellSetDispatcher.Invoke(cellSet,
|
|
|
|
scalars,
|
|
|
|
clipTableIndices,
|
|
|
|
cellSetStats,
|
|
|
|
this->ClipTablesInstance,
|
|
|
|
connectivityObject,
|
|
|
|
edgePointReverseConnectivity,
|
|
|
|
edgeInterpolation,
|
|
|
|
cellPointReverseConnectivity,
|
|
|
|
cellPointEdgeReverseConnectivity,
|
|
|
|
cellPointEdgeInterpolation,
|
|
|
|
this->InCellInterpolationKeys,
|
|
|
|
this->InCellInterpolationInfo,
|
|
|
|
this->CellMapOutputToInput);
|
|
|
|
|
|
|
|
// Get unique EdgeInterpolation : unique edge points.
|
|
|
|
// LowerBound for edgeInterpolation : get index into new edge points array.
|
|
|
|
// LowerBound for cellPoitnEdgeInterpolation : get index into new edge points array.
|
|
|
|
//vtkm::cont::ArrayHandle<clipping::EdgeInterpolation> uniqueEdgeInterpolations;
|
2018-08-30 15:53:18 +00:00
|
|
|
vtkm::cont::Algorithm::SortByKey(
|
2018-12-07 15:09:21 +00:00
|
|
|
edgeInterpolation, edgePointReverseConnectivity, EdgeInterpolation::LessThanOp());
|
|
|
|
vtkm::cont::Algorithm::Copy(edgeInterpolation, this->EdgePointsInterpolation);
|
|
|
|
vtkm::cont::Algorithm::Unique(this->EdgePointsInterpolation, EdgeInterpolation::EqualToOp());
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> edgeInterpolationIndexToUnique;
|
|
|
|
vtkm::cont::Algorithm::LowerBounds(this->EdgePointsInterpolation,
|
|
|
|
edgeInterpolation,
|
|
|
|
edgeInterpolationIndexToUnique,
|
|
|
|
EdgeInterpolation::LessThanOp());
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> cellInterpolationIndexToUnique;
|
|
|
|
vtkm::cont::Algorithm::LowerBounds(this->EdgePointsInterpolation,
|
|
|
|
cellPointEdgeInterpolation,
|
|
|
|
cellInterpolationIndexToUnique,
|
|
|
|
EdgeInterpolation::LessThanOp());
|
|
|
|
|
|
|
|
this->EdgePointsOffset = scalars.GetNumberOfValues();
|
|
|
|
this->InCellPointsOffset =
|
|
|
|
this->EdgePointsOffset + this->EdgePointsInterpolation.GetNumberOfValues();
|
|
|
|
|
|
|
|
// Scatter these values into the connectivity array,
|
|
|
|
// scatter indices are given in reverse connectivity.
|
|
|
|
ScatterEdgeConnectivity scatterEdgePointConnectivity(this->EdgePointsOffset);
|
|
|
|
vtkm::worklet::DispatcherMapField<ScatterEdgeConnectivity> scatterEdgeDispatcher(
|
|
|
|
scatterEdgePointConnectivity);
|
|
|
|
scatterEdgeDispatcher.Invoke(
|
|
|
|
edgeInterpolationIndexToUnique, edgePointReverseConnectivity, connectivity);
|
|
|
|
scatterEdgeDispatcher.Invoke(
|
|
|
|
cellInterpolationIndexToUnique, cellPointEdgeReverseConnectivity, cellPointInterpolationInfo);
|
|
|
|
//Add offset in connectivity of all new in-cell points.
|
|
|
|
ScatterInCellConnectivity scatterInCellPointConnectivity(this->InCellPointsOffset);
|
|
|
|
vtkm::worklet::DispatcherMapField<ScatterInCellConnectivity> scatterInCellDispatcher(
|
|
|
|
scatterInCellPointConnectivity);
|
|
|
|
scatterInCellDispatcher.Invoke(cellPointReverseConnectivity, connectivity);
|
2015-09-16 14:24:54 +00:00
|
|
|
|
2015-07-31 14:33:54 +00:00
|
|
|
vtkm::cont::CellSetExplicit<> output;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id numberOfPoints = scalars.GetNumberOfValues() +
|
|
|
|
this->EdgePointsInterpolation.GetNumberOfValues() + total.NumberOfInCellPoints;
|
|
|
|
output.Fill(numberOfPoints, shapes, numberOfIndices, connectivity);
|
2015-07-31 14:33:54 +00:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
template <typename DynamicCellSet>
|
2015-10-08 16:12:51 +00:00
|
|
|
class ClipWithImplicitFunction
|
|
|
|
{
|
|
|
|
public:
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-26 17:53:28 +00:00
|
|
|
ClipWithImplicitFunction(Clip* clipper,
|
|
|
|
const DynamicCellSet& cellSet,
|
2018-08-30 15:53:18 +00:00
|
|
|
const vtkm::cont::ImplicitFunctionHandle& function,
|
2018-03-09 02:28:08 +00:00
|
|
|
const bool invert,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::CellSetExplicit<>* result)
|
|
|
|
: Clipper(clipper)
|
|
|
|
, CellSet(&cellSet)
|
|
|
|
, Function(function)
|
2018-03-09 02:28:08 +00:00
|
|
|
, Invert(invert)
|
2017-05-18 14:29:41 +00:00
|
|
|
, Result(result)
|
|
|
|
{
|
|
|
|
}
|
2015-10-08 16:12:51 +00:00
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT void operator()(const ArrayHandleType& handle) const
|
2015-10-08 16:12:51 +00:00
|
|
|
{
|
2017-04-18 15:01:17 +00:00
|
|
|
// Evaluate the implicit function on the input coordinates using
|
|
|
|
// ArrayHandleTransform
|
2018-08-30 15:53:18 +00:00
|
|
|
vtkm::cont::ArrayHandleTransform<ArrayHandleType, vtkm::cont::ImplicitFunctionValueHandle>
|
|
|
|
clipScalars(handle, this->Function);
|
2015-10-08 16:12:51 +00:00
|
|
|
|
2017-03-29 16:11:09 +00:00
|
|
|
// Clip at locations where the implicit function evaluates to 0
|
2018-08-30 15:53:18 +00:00
|
|
|
*this->Result = this->Clipper->Run(*this->CellSet, clipScalars, 0.0, this->Invert);
|
2015-10-08 16:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-05-18 14:29:41 +00:00
|
|
|
Clip* Clipper;
|
|
|
|
const DynamicCellSet* CellSet;
|
2018-08-30 15:53:18 +00:00
|
|
|
vtkm::cont::ImplicitFunctionHandle Function;
|
2018-03-09 02:28:08 +00:00
|
|
|
bool Invert;
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::CellSetExplicit<>* Result;
|
2015-10-08 16:12:51 +00:00
|
|
|
};
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
template <typename CellSetList>
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::CellSetExplicit<> Run(const vtkm::cont::DynamicCellSetBase<CellSetList>& cellSet,
|
2017-10-23 13:38:33 +00:00
|
|
|
const vtkm::cont::ImplicitFunctionHandle& clipFunction,
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::cont::CoordinateSystem& coords,
|
2018-08-30 15:53:18 +00:00
|
|
|
const bool invert)
|
2015-10-08 16:12:51 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::CellSetExplicit<> output;
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
ClipWithImplicitFunction<vtkm::cont::DynamicCellSetBase<CellSetList>> clip(
|
|
|
|
this, cellSet, clipFunction, invert, &output);
|
2017-05-05 19:31:27 +00:00
|
|
|
|
2017-03-29 16:11:09 +00:00
|
|
|
CastAndCall(coords, clip);
|
2015-10-08 16:12:51 +00:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
template <typename ArrayHandleType>
|
2015-10-08 16:12:51 +00:00
|
|
|
class InterpolateField
|
|
|
|
{
|
|
|
|
public:
|
2017-06-12 16:04:11 +00:00
|
|
|
using ValueType = typename ArrayHandleType::ValueType;
|
2018-12-07 15:09:21 +00:00
|
|
|
struct TypeMappedValue : vtkm::ListTagBase<ValueType>
|
|
|
|
{
|
|
|
|
};
|
2017-06-12 16:04:11 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
InterpolateField(vtkm::cont::ArrayHandle<EdgeInterpolation> edgeInterpolationArray,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> inCellInterpolationKeys,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> inCellInterpolationInfo,
|
|
|
|
vtkm::Id edgePointsOffset,
|
|
|
|
vtkm::Id inCellPointsOffset,
|
|
|
|
ArrayHandleType* output)
|
|
|
|
: EdgeInterpolationArray(edgeInterpolationArray)
|
|
|
|
, InCellInterpolationKeys(inCellInterpolationKeys)
|
|
|
|
, InCellInterpolationInfo(inCellInterpolationInfo)
|
|
|
|
, EdgePointsOffset(edgePointsOffset)
|
|
|
|
, InCellPointsOffset(inCellPointsOffset)
|
|
|
|
, Output(output)
|
2015-10-08 16:12:51 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
}
|
2018-08-30 15:53:18 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
class PerformEdgeInterpolations : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PerformEdgeInterpolations(vtkm::Id edgePointsOffset)
|
|
|
|
: EdgePointsOffset(edgePointsOffset)
|
2015-10-08 16:12:51 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
using ControlSignature = void(FieldIn<TypeEdgeInterp> edgeInterpolations,
|
|
|
|
WholeArrayInOut<> outputField);
|
|
|
|
|
|
|
|
using ExecutionSignature = void(_1, _2, WorkIndex);
|
|
|
|
|
|
|
|
template <typename EdgeInterp, typename OutputFieldPortal>
|
|
|
|
VTKM_EXEC void operator()(const EdgeInterp& ei,
|
|
|
|
OutputFieldPortal& field,
|
|
|
|
const vtkm::Id workIndex) const
|
2015-10-08 16:12:51 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
using T = typename OutputFieldPortal::ValueType;
|
2018-08-30 15:53:18 +00:00
|
|
|
T v1 = field.Get(ei.Vertex1);
|
|
|
|
T v2 = field.Get(ei.Vertex2);
|
2018-12-07 15:09:21 +00:00
|
|
|
field.Set(this->EdgePointsOffset + workIndex,
|
|
|
|
static_cast<T>(internal::Scale(T(v1 - v2), ei.Weight) + v1));
|
2015-10-08 16:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id EdgePointsOffset;
|
2015-10-08 16:12:51 +00:00
|
|
|
};
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
class PerformInCellInterpolations : public vtkm::worklet::WorkletReduceByKey
|
2016-08-12 16:38:58 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
public:
|
|
|
|
using ControlSignature = void(KeysIn keys,
|
|
|
|
ValuesIn<TypeMappedValue> toReduce,
|
|
|
|
ReducedValuesOut<TypeMappedValue> centroid);
|
|
|
|
|
2018-12-07 17:58:31 +00:00
|
|
|
using ExecutionSignature = void(_2, _3);
|
2018-12-07 15:09:21 +00:00
|
|
|
|
|
|
|
using ScatterType = vtkm::worklet::ScatterIdentity;
|
|
|
|
|
|
|
|
template <typename MappedValueVecType, typename MappedValueType>
|
2018-12-07 17:58:31 +00:00
|
|
|
VTKM_EXEC void operator()(const MappedValueVecType& toReduce, MappedValueType& centroid) const
|
2018-12-07 15:09:21 +00:00
|
|
|
{
|
|
|
|
vtkm::IdComponent numValues = toReduce.GetNumberOfComponents();
|
|
|
|
MappedValueType sum = toReduce[0];
|
|
|
|
for (vtkm::IdComponent i = 1; i < numValues; i++)
|
|
|
|
{
|
|
|
|
MappedValueType value = toReduce[i];
|
|
|
|
sum = sum + value;
|
|
|
|
}
|
2018-12-08 02:44:05 +00:00
|
|
|
centroid = internal::Scale(sum, 1. / static_cast<vtkm::Float64>(numValues));
|
2018-12-07 15:09:21 +00:00
|
|
|
}
|
|
|
|
};
|
2016-08-12 16:38:58 +00:00
|
|
|
|
2017-06-12 16:04:11 +00:00
|
|
|
template <typename Storage>
|
|
|
|
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<ValueType, Storage>& field) const
|
2015-10-08 16:12:51 +00:00
|
|
|
{
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::worklet::Keys<vtkm::Id> interpolationKeys(InCellInterpolationKeys);
|
2015-10-08 16:12:51 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id numberOfOriginalValues = field.GetNumberOfValues();
|
|
|
|
vtkm::Id numberOfEdgePoints = EdgeInterpolationArray.GetNumberOfValues();
|
|
|
|
vtkm::Id numberOfInCellPoints = interpolationKeys.GetUniqueKeys().GetNumberOfValues();
|
2015-10-08 16:12:51 +00:00
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
ArrayHandleType result;
|
|
|
|
result.Allocate(numberOfOriginalValues + numberOfEdgePoints + numberOfInCellPoints);
|
|
|
|
vtkm::cont::Algorithm::CopySubRange(field, 0, numberOfOriginalValues, result);
|
|
|
|
|
|
|
|
PerformEdgeInterpolations edgeInterpWorklet(numberOfOriginalValues);
|
|
|
|
vtkm::worklet::DispatcherMapField<PerformEdgeInterpolations> edgeInterpDispatcher(
|
|
|
|
edgeInterpWorklet);
|
|
|
|
edgeInterpDispatcher.Invoke(this->EdgeInterpolationArray, result);
|
|
|
|
|
|
|
|
// Perform a gather on output to get all required values for calculation of
|
|
|
|
// centroids using the interpolation info array.
|
2018-12-07 17:58:31 +00:00
|
|
|
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id>;
|
|
|
|
using ValueHandle = vtkm::cont::ArrayHandle<ValueType>;
|
|
|
|
vtkm::cont::ArrayHandlePermutation<IdHandle, ValueHandle> toReduceValues(
|
|
|
|
InCellInterpolationInfo, result);
|
2018-12-07 15:09:21 +00:00
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<ValueType> reducedValues;
|
|
|
|
vtkm::worklet::DispatcherReduceByKey<PerformInCellInterpolations>
|
|
|
|
inCellInterpolationDispatcher;
|
2018-12-07 17:58:31 +00:00
|
|
|
inCellInterpolationDispatcher.Invoke(interpolationKeys, toReduceValues, reducedValues);
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::Id inCellPointsOffset = numberOfOriginalValues + numberOfEdgePoints;
|
|
|
|
vtkm::cont::Algorithm::CopySubRange(
|
|
|
|
reducedValues, 0, reducedValues.GetNumberOfValues(), result, inCellPointsOffset);
|
2017-06-12 16:04:11 +00:00
|
|
|
*(this->Output) = result;
|
2015-10-08 16:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<EdgeInterpolation> EdgeInterpolationArray;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationKeys;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationInfo;
|
|
|
|
vtkm::Id EdgePointsOffset;
|
|
|
|
vtkm::Id InCellPointsOffset;
|
2017-06-12 16:04:11 +00:00
|
|
|
ArrayHandleType* Output;
|
2015-10-08 16:12:51 +00:00
|
|
|
};
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
template <typename ValueType, typename StorageType>
|
2017-06-12 16:04:11 +00:00
|
|
|
vtkm::cont::ArrayHandle<ValueType> ProcessPointField(
|
2018-08-30 15:53:18 +00:00
|
|
|
const vtkm::cont::ArrayHandle<ValueType, StorageType>& fieldData) const
|
2015-07-31 14:33:54 +00:00
|
|
|
{
|
2017-06-12 16:04:11 +00:00
|
|
|
using ResultType = vtkm::cont::ArrayHandle<ValueType>;
|
2018-08-30 15:53:18 +00:00
|
|
|
using Worker = InterpolateField<ResultType>;
|
2017-06-12 16:04:11 +00:00
|
|
|
|
|
|
|
ResultType output;
|
|
|
|
|
2018-12-07 15:09:21 +00:00
|
|
|
Worker worker = Worker(this->EdgePointsInterpolation,
|
|
|
|
this->InCellInterpolationKeys,
|
|
|
|
this->InCellInterpolationInfo,
|
|
|
|
this->EdgePointsOffset,
|
|
|
|
this->InCellPointsOffset,
|
|
|
|
&output);
|
2017-06-12 16:04:11 +00:00
|
|
|
worker(fieldData);
|
|
|
|
|
2015-07-31 14:33:54 +00:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2018-08-30 15:53:18 +00:00
|
|
|
template <typename ValueType, typename StorageType>
|
2017-06-12 16:04:11 +00:00
|
|
|
vtkm::cont::ArrayHandle<ValueType> ProcessCellField(
|
2018-08-30 15:53:18 +00:00
|
|
|
const vtkm::cont::ArrayHandle<ValueType, StorageType>& fieldData) const
|
2017-06-12 16:04:11 +00:00
|
|
|
{
|
|
|
|
// Use a temporary permutation array to simplify the mapping:
|
2018-12-07 15:09:21 +00:00
|
|
|
auto tmp = vtkm::cont::make_ArrayHandlePermutation(this->CellMapOutputToInput, fieldData);
|
2017-06-12 16:04:11 +00:00
|
|
|
|
|
|
|
// Copy into an array with default storage:
|
|
|
|
vtkm::cont::ArrayHandle<ValueType> result;
|
2018-08-30 15:53:18 +00:00
|
|
|
vtkm::cont::ArrayCopy(tmp, result);
|
2017-06-12 16:04:11 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-07-31 14:33:54 +00:00
|
|
|
private:
|
|
|
|
internal::ClipTables ClipTablesInstance;
|
2018-12-07 15:09:21 +00:00
|
|
|
vtkm::cont::ArrayHandle<EdgeInterpolation> EdgePointsInterpolation;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationKeys;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationInfo;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> CellMapOutputToInput;
|
|
|
|
vtkm::Id EdgePointsOffset;
|
|
|
|
vtkm::Id InCellPointsOffset;
|
2015-07-31 14:33:54 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
} // namespace vtkm::worklet
|
|
|
|
|
2015-09-15 15:07:39 +00:00
|
|
|
#if defined(THRUST_SCAN_WORKAROUND)
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace thrust
|
|
|
|
{
|
|
|
|
namespace detail
|
|
|
|
{
|
2015-09-15 15:07:39 +00:00
|
|
|
|
|
|
|
// causes a different code path which does not have the bug
|
2017-05-18 14:29:41 +00:00
|
|
|
template <>
|
|
|
|
struct is_integral<vtkm::worklet::ClipStats> : public true_type
|
|
|
|
{
|
|
|
|
};
|
2015-09-15 15:07:39 +00:00
|
|
|
}
|
|
|
|
} // namespace thrust::detail
|
|
|
|
#endif
|
|
|
|
|
2015-07-31 14:33:54 +00:00
|
|
|
#endif // vtkm_m_worklet_Clip_h
|