vtk-m2/vtkm/rendering/Triangulator.h

568 lines
20 KiB
C
Raw Normal View History

2016-01-20 22:40: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.
//
// 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_rendering_Triangulator_h
#define vtk_m_rendering_Triangulator_h
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
2017-05-18 14:29:41 +00:00
namespace vtkm
{
namespace rendering
{
2016-01-20 22:40:54 +00:00
/// \brief Triangulator creates a minimal set of triangles from a cell set.
///
/// This class creates a array of triangle indices from both 3D and 2D
/// explicit cell sets. This list can serve as input to opengl and the
2016-01-20 22:40:54 +00:00
/// ray tracer scene renderers. TODO: Add regular grid support
///
2017-05-18 14:29:41 +00:00
template <typename DeviceAdapter>
2016-01-20 22:40:54 +00:00
class Triangulator
{
private:
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
2017-05-18 14:29:41 +00:00
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Vec4ArrayHandle;
2016-01-20 22:40:54 +00:00
typedef typename Vec4ArrayHandle::ExecutionTypes<DeviceAdapter>::Portal Vec4ArrayPortalType;
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalConstType;
2017-05-18 14:29:41 +00:00
2016-01-20 22:40:54 +00:00
public:
2017-05-18 14:29:41 +00:00
template <class T>
2016-01-20 22:40:54 +00:00
class MemSet : public vtkm::worklet::WorkletMapField
{
T Value;
2017-05-18 14:29:41 +00:00
2016-01-20 22:40:54 +00:00
public:
VTKM_CONT
2016-01-20 22:40:54 +00:00
MemSet(T value)
: Value(value)
2017-05-18 14:29:41 +00:00
{
}
2016-01-20 22:40:54 +00:00
typedef void ControlSignature(FieldOut<>);
typedef void ExecutionSignature(_1);
VTKM_EXEC
2017-05-18 14:29:41 +00:00
void operator()(T& outValue) const { outValue = Value; }
2016-01-20 22:40:54 +00:00
}; //class MemSet
class CountTriangles : public vtkm::worklet::WorkletMapField
{
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
CountTriangles() {}
typedef void ControlSignature(FieldIn<>, FieldOut<>);
typedef void ExecutionSignature(_1, _2);
VTKM_EXEC
2017-05-18 14:29:41 +00:00
void operator()(const vtkm::Id& shapeType, vtkm::Id& triangles) const
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
if (shapeType == vtkm::CELL_SHAPE_TRIANGLE)
triangles = 1;
else if (shapeType == vtkm::CELL_SHAPE_QUAD)
triangles = 2;
else if (shapeType == vtkm::CELL_SHAPE_TETRA)
triangles = 4;
else if (shapeType == vtkm::CELL_SHAPE_HEXAHEDRON)
triangles = 12;
else if (shapeType == vtkm::CELL_SHAPE_WEDGE)
triangles = 8;
else if (shapeType == vtkm::CELL_SHAPE_PYRAMID)
triangles = 6;
else
triangles = 0;
2016-01-20 22:40:54 +00:00
}
}; //class CountTriangles
2016-04-14 21:04:58 +00:00
template <int DIM>
2017-05-18 14:29:41 +00:00
class TrianglulateStructured : public vtkm::worklet::WorkletMapPointToCell
2016-01-20 22:40:54 +00:00
{
private:
Vec4ArrayPortalType OutputIndices;
2017-05-18 14:29:41 +00:00
2016-01-20 22:40:54 +00:00
public:
2017-05-18 14:29:41 +00:00
typedef void ControlSignature(CellSetIn cellset, FieldInTo<>);
2016-01-20 22:40:54 +00:00
typedef void ExecutionSignature(FromIndices, _2);
//typedef _1 InputDomain;
VTKM_CONT
2017-05-18 14:29:41 +00:00
TrianglulateStructured(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& outputIndices)
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
this->OutputIndices =
outputIndices.PrepareForOutput(outputIndices.GetNumberOfValues(), DeviceAdapter());
2016-01-20 22:40:54 +00:00
}
2016-04-14 21:04:58 +00:00
//TODO: Remove the if/then with templates.
2017-05-18 14:29:41 +00:00
template <typename CellNodeVecType>
VTKM_EXEC void operator()(const CellNodeVecType& cellIndices, const vtkm::Id& cellIndex) const
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
vtkm::Vec<vtkm::Id, 4> triangle;
2016-06-01 17:37:03 +00:00
if (DIM == 2)
{
const vtkm::Id triangleOffset = cellIndex * 2;
// 0-1-2
triangle[1] = cellIndices[0];
triangle[2] = cellIndices[1];
triangle[3] = cellIndices[2];
triangle[0] = cellIndex;
OutputIndices.Set(triangleOffset, triangle);
// 0-3-2
triangle[2] = cellIndices[3];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 1, triangle);
2016-06-01 17:37:03 +00:00
}
else if (DIM == 3)
{
const vtkm::Id triangleOffset = cellIndex * 12;
// 0-1-2
triangle[1] = cellIndices[0];
triangle[2] = cellIndices[1];
triangle[3] = cellIndices[2];
triangle[0] = cellIndex;
OutputIndices.Set(triangleOffset, triangle);
// 0-3-2
triangle[2] = cellIndices[3];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 1, triangle);
2016-06-01 17:37:03 +00:00
// 0-3-7
triangle[3] = cellIndices[7];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 2, triangle);
2016-06-01 17:37:03 +00:00
// 0-4-7
triangle[2] = cellIndices[4];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 3, triangle);
2016-06-01 17:37:03 +00:00
// 5-4-7
triangle[1] = cellIndices[5];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 4, triangle);
2016-06-01 17:37:03 +00:00
// 5-6-7
triangle[2] = cellIndices[6];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 5, triangle);
2016-06-01 17:37:03 +00:00
// 3-6-7
triangle[1] = cellIndices[3];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 6, triangle);
2016-06-01 17:37:03 +00:00
// 3-6-2
triangle[3] = cellIndices[2];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 7, triangle);
2016-06-01 17:37:03 +00:00
// 1-6-2
triangle[1] = cellIndices[1];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 8, triangle);
2016-06-01 17:37:03 +00:00
// 1-6-5
triangle[3] = cellIndices[5];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 9, triangle);
2016-06-01 17:37:03 +00:00
// 1-4-5
triangle[2] = cellIndices[4];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 10, triangle);
2016-06-01 17:37:03 +00:00
// 1-4-0
triangle[3] = cellIndices[0];
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 11, triangle);
2016-06-01 17:37:03 +00:00
}
2016-01-20 22:40:54 +00:00
}
};
class IndicesSort : public vtkm::worklet::WorkletMapField
{
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
IndicesSort() {}
2016-01-20 22:40:54 +00:00
typedef void ControlSignature(FieldInOut<>);
typedef void ExecutionSignature(_1);
VTKM_EXEC
2017-05-18 14:29:41 +00:00
void operator()(vtkm::Vec<vtkm::Id, 4>& triangleIndices) const
2016-01-20 22:40:54 +00:00
{
// first field contains the id of the cell the
// trianlge belongs to
vtkm::Id temp;
if (triangleIndices[1] > triangleIndices[3])
{
2017-05-18 14:29:41 +00:00
temp = triangleIndices[1];
triangleIndices[1] = triangleIndices[3];
triangleIndices[3] = temp;
2016-01-20 22:40:54 +00:00
}
if (triangleIndices[1] > triangleIndices[2])
{
2017-05-18 14:29:41 +00:00
temp = triangleIndices[1];
triangleIndices[1] = triangleIndices[2];
triangleIndices[2] = temp;
2016-01-20 22:40:54 +00:00
}
if (triangleIndices[2] > triangleIndices[3])
{
2017-05-18 14:29:41 +00:00
temp = triangleIndices[2];
triangleIndices[2] = triangleIndices[3];
triangleIndices[3] = temp;
2016-01-20 22:40:54 +00:00
}
}
}; //class IndicesSort
struct IndicesLessThan
{
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
bool operator()(const vtkm::Vec<vtkm::Id, 4>& a, const vtkm::Vec<vtkm::Id, 4>& b) const
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
if (a[1] < b[1])
return true;
if (a[1] > b[1])
return false;
if (a[2] < b[2])
return true;
if (a[2] > b[2])
return false;
if (a[3] < b[3])
return true;
2016-01-20 22:40:54 +00:00
return false;
}
};
class UniqueTriangles : public vtkm::worklet::WorkletMapField
{
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
UniqueTriangles() {}
typedef void ControlSignature(ExecObject, ExecObject);
typedef void ExecutionSignature(_1, _2, WorkIndex);
VTKM_EXEC
2017-05-18 14:29:41 +00:00
bool IsTwin(const vtkm::Vec<vtkm::Id, 4>& a, const vtkm::Vec<vtkm::Id, 4>& b) const
2016-01-20 22:40:54 +00:00
{
return (a[1] == b[1] && a[2] == b[2] && a[3] == b[3]);
}
VTKM_EXEC
2017-05-18 14:29:41 +00:00
void operator()(vtkm::exec::ExecutionWholeArrayConst<vtkm::Vec<vtkm::Id, 4>>& indices,
vtkm::exec::ExecutionWholeArray<vtkm::UInt8>& outputFlags,
const vtkm::Id& index) const
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
if (index == 0)
return;
2016-01-20 22:40:54 +00:00
//if we are a shared face, mark ourself and neighbor for desctruction
2017-05-18 14:29:41 +00:00
if (IsTwin(indices.Get(index), indices.Get(index - 1)))
2016-01-20 22:40:54 +00:00
{
outputFlags.Set(index, 0);
outputFlags.Set(index - 1, 0);
}
}
}; //class UniqueTriangles
class Trianglulate : public vtkm::worklet::WorkletMapField
{
private:
IdPortalConstType Indices;
Vec4ArrayPortalType OutputIndices;
vtkm::Int32 TRIANGLE_INDICES;
vtkm::Int32 QUAD_INDICES;
vtkm::Int32 TETRA_INDICES;
vtkm::Int32 HEX_INDICES;
vtkm::Int32 WEDGE_INDICES;
vtkm::Int32 PYRAMID_INDICES;
2017-05-18 14:29:41 +00:00
2016-01-20 22:40:54 +00:00
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
Trianglulate(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& outputIndices,
const vtkm::cont::ArrayHandle<vtkm::Id>& indices, const vtkm::Id& size)
: Indices(indices.PrepareForInput(DeviceAdapter()))
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
this->OutputIndices = outputIndices.PrepareForOutput(size, DeviceAdapter());
2016-01-20 22:40:54 +00:00
TRIANGLE_INDICES = 3;
QUAD_INDICES = 4;
TETRA_INDICES = 4;
HEX_INDICES = 8;
WEDGE_INDICES = 6;
PYRAMID_INDICES = 5;
}
2017-05-18 14:29:41 +00:00
typedef void ControlSignature(FieldIn<>, FieldIn<>, FieldIn<>);
typedef void ExecutionSignature(_1, _2, _3, WorkIndex);
VTKM_EXEC
2017-05-18 14:29:41 +00:00
void operator()(const vtkm::Id& shapeType, const vtkm::Id& indexOffset,
const vtkm::Id& triangleOffset, const vtkm::Id& cellId) const
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
vtkm::Vec<vtkm::Id, 4> triangle;
if (shapeType == vtkm::CELL_SHAPE_TRIANGLE)
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 0);
triangle[2] = Indices.Get(indexOffset + 1);
triangle[3] = Indices.Get(indexOffset + 2);
triangle[0] = cellId;
OutputIndices.Set(triangleOffset, triangle);
2016-01-20 22:40:54 +00:00
}
2017-05-18 14:29:41 +00:00
if (shapeType == vtkm::CELL_SHAPE_QUAD)
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 0);
triangle[2] = Indices.Get(indexOffset + 1);
triangle[3] = Indices.Get(indexOffset + 2);
2016-01-20 22:40:54 +00:00
triangle[0] = cellId;
OutputIndices.Set(triangleOffset, triangle);
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 1, triangle);
2016-01-20 22:40:54 +00:00
}
2017-05-18 14:29:41 +00:00
if (shapeType == vtkm::CELL_SHAPE_TETRA)
2016-01-20 22:40:54 +00:00
{
// 0-1-2
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 1);
triangle[2] = Indices.Get(indexOffset + 0);
triangle[3] = Indices.Get(indexOffset + 2);
2016-01-20 22:40:54 +00:00
triangle[0] = cellId;
OutputIndices.Set(triangleOffset, triangle);
// 0-1-3
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 1);
triangle[2] = Indices.Get(indexOffset + 0);
triangle[3] = Indices.Get(indexOffset + 3);
2016-01-20 22:40:54 +00:00
2017-05-18 14:29:41 +00:00
OutputIndices.Set(triangleOffset + 1, triangle);
2016-01-20 22:40:54 +00:00
// 2-1-3
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 1);
triangle[2] = Indices.Get(indexOffset + 2);
triangle[3] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 2, triangle);
2016-01-20 22:40:54 +00:00
// 2-0-3
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 2);
triangle[2] = Indices.Get(indexOffset + 0);
triangle[3] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 3, triangle);
2016-01-20 22:40:54 +00:00
}
2017-05-18 14:29:41 +00:00
if (shapeType == vtkm::CELL_SHAPE_HEXAHEDRON)
2016-01-20 22:40:54 +00:00
{
// 0-1-2
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 0);
triangle[2] = Indices.Get(indexOffset + 1);
triangle[3] = Indices.Get(indexOffset + 2);
2016-01-20 22:40:54 +00:00
triangle[0] = cellId;
OutputIndices.Set(triangleOffset, triangle);
// 0-3-2
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 1, triangle);
2016-01-20 22:40:54 +00:00
// 0-3-7
2017-05-18 14:29:41 +00:00
triangle[3] = Indices.Get(indexOffset + 7);
OutputIndices.Set(triangleOffset + 2, triangle);
2016-01-20 22:40:54 +00:00
// 0-4-7
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 4);
OutputIndices.Set(triangleOffset + 3, triangle);
2016-01-20 22:40:54 +00:00
// 5-4-7
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 5);
OutputIndices.Set(triangleOffset + 4, triangle);
2016-01-20 22:40:54 +00:00
// 5-6-7
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 6);
OutputIndices.Set(triangleOffset + 5, triangle);
2016-01-20 22:40:54 +00:00
// 3-6-7
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 6, triangle);
2016-01-20 22:40:54 +00:00
// 3-6-2
2017-05-18 14:29:41 +00:00
triangle[3] = Indices.Get(indexOffset + 2);
OutputIndices.Set(triangleOffset + 7, triangle);
2016-01-20 22:40:54 +00:00
// 1-6-2
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 1);
OutputIndices.Set(triangleOffset + 8, triangle);
2016-01-20 22:40:54 +00:00
// 1-6-5
2017-05-18 14:29:41 +00:00
triangle[3] = Indices.Get(indexOffset + 5);
OutputIndices.Set(triangleOffset + 9, triangle);
2016-01-20 22:40:54 +00:00
// 1-4-5
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 4);
OutputIndices.Set(triangleOffset + 10, triangle);
2016-01-20 22:40:54 +00:00
// 1-4-0
2017-05-18 14:29:41 +00:00
triangle[3] = Indices.Get(indexOffset + 0);
OutputIndices.Set(triangleOffset + 11, triangle);
2016-01-20 22:40:54 +00:00
}
2017-05-18 14:29:41 +00:00
if (shapeType == vtkm::CELL_SHAPE_WEDGE)
2016-01-20 22:40:54 +00:00
{
// 0-1-2
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 0);
triangle[2] = Indices.Get(indexOffset + 1);
triangle[3] = Indices.Get(indexOffset + 2);
2016-01-20 22:40:54 +00:00
triangle[0] = cellId;
OutputIndices.Set(triangleOffset, triangle);
// 0-3-2
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 1, triangle);
2016-01-20 22:40:54 +00:00
// 5-3-2
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 5);
OutputIndices.Set(triangleOffset + 2, triangle);
2016-01-20 22:40:54 +00:00
// 5-3-4
2017-05-18 14:29:41 +00:00
triangle[3] = Indices.Get(indexOffset + 4);
OutputIndices.Set(triangleOffset + 3, triangle);
2016-01-20 22:40:54 +00:00
// 5-2-4
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 2);
OutputIndices.Set(triangleOffset + 4, triangle);
2016-01-20 22:40:54 +00:00
// 5-1-4
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 1);
OutputIndices.Set(triangleOffset + 5, triangle);
2016-01-20 22:40:54 +00:00
}
2017-05-18 14:29:41 +00:00
if (shapeType == vtkm::CELL_SHAPE_PYRAMID)
2016-01-20 22:40:54 +00:00
{
// 0-1-2
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 0);
triangle[2] = Indices.Get(indexOffset + 1);
triangle[3] = Indices.Get(indexOffset + 2);
2016-01-20 22:40:54 +00:00
triangle[0] = cellId;
OutputIndices.Set(triangleOffset, triangle);
// 0-3-2
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 3);
OutputIndices.Set(triangleOffset + 1, triangle);
2016-01-20 22:40:54 +00:00
// 0-3-4
2017-05-18 14:29:41 +00:00
triangle[3] = Indices.Get(indexOffset + 4);
OutputIndices.Set(triangleOffset + 2, triangle);
2016-01-20 22:40:54 +00:00
// 2-3-4
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 2);
OutputIndices.Set(triangleOffset + 3, triangle);
2016-01-20 22:40:54 +00:00
// 2-1-4
2017-05-18 14:29:41 +00:00
triangle[2] = Indices.Get(indexOffset + 1);
OutputIndices.Set(triangleOffset + 4, triangle);
2016-01-20 22:40:54 +00:00
// 0-3-4
2017-05-18 14:29:41 +00:00
triangle[1] = Indices.Get(indexOffset + 0);
OutputIndices.Set(triangleOffset + 5, triangle);
2016-01-20 22:40:54 +00:00
}
}
}; //class Trianglulate
public:
VTKM_CONT
2016-01-20 22:40:54 +00:00
Triangulator() {}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void ExternalTrianlges(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& outputIndices,
vtkm::Id& outputTriangles)
2016-01-20 22:40:54 +00:00
{
//Eliminate unseen triangles
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapField<IndicesSort>().Invoke(outputIndices);
2016-01-20 22:40:54 +00:00
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Sort(outputIndices, IndicesLessThan());
vtkm::cont::ArrayHandle<vtkm::UInt8> flags;
flags.Allocate(outputTriangles);
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapField<MemSet<vtkm::UInt8>>(MemSet<vtkm::UInt8>(1)).Invoke(flags);
2016-01-20 22:40:54 +00:00
//Unique triangles will have a flag = 1
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapField<UniqueTriangles>().Invoke(
vtkm::exec::ExecutionWholeArrayConst<vtkm::Vec<vtkm::Id, 4>>(outputIndices),
vtkm::exec::ExecutionWholeArray<vtkm::UInt8>(flags));
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> subset;
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::CopyIf(outputIndices, flags, subset);
2016-02-12 17:14:19 +00:00
outputIndices = subset;
outputTriangles = subset.GetNumberOfValues();
2016-01-20 22:40:54 +00:00
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void Run(const vtkm::cont::DynamicCellSet& cellset,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& outputIndices,
vtkm::Id& outputTriangles)
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
if (cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
vtkm::cont::CellSetStructured<3> cellSetStructured3D =
cellset.Cast<vtkm::cont::CellSetStructured<3>>();
2016-01-20 22:40:54 +00:00
const vtkm::Id numCells = cellSetStructured3D.GetNumberOfCells();
2017-05-18 14:29:41 +00:00
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, numCells);
2016-01-20 22:40:54 +00:00
outputIndices.Allocate(numCells * 12);
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapTopology<TrianglulateStructured<3>>(
TrianglulateStructured<3>(outputIndices))
.Invoke(cellSetStructured3D, cellIdxs);
2016-01-20 22:40:54 +00:00
outputTriangles = numCells * 12;
}
2017-05-18 14:29:41 +00:00
else if (cellset.IsSameType(vtkm::cont::CellSetStructured<2>()))
2016-04-14 21:04:58 +00:00
{
2017-05-18 14:29:41 +00:00
vtkm::cont::CellSetStructured<2> cellSetStructured2D =
cellset.Cast<vtkm::cont::CellSetStructured<2>>();
const vtkm::Id numCells = cellSetStructured2D.GetNumberOfCells();
2016-04-14 21:04:58 +00:00
2017-05-18 14:29:41 +00:00
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, numCells);
outputIndices.Allocate(numCells * 2);
vtkm::worklet::DispatcherMapTopology<TrianglulateStructured<2>>(
TrianglulateStructured<2>(outputIndices))
.Invoke(cellSetStructured2D, cellIdxs);
2016-04-14 21:04:58 +00:00
2017-05-18 14:29:41 +00:00
outputTriangles = numCells * 2;
2016-04-14 21:04:58 +00:00
}
2017-05-18 14:29:41 +00:00
else if (cellset.IsSameType(vtkm::cont::CellSetExplicit<>()))
2016-01-20 22:40:54 +00:00
{
2017-05-18 14:29:41 +00:00
vtkm::cont::CellSetExplicit<> cellSetExplicit = cellset.Cast<vtkm::cont::CellSetExplicit<>>();
const vtkm::cont::ArrayHandle<vtkm::UInt8> shapes = cellSetExplicit.GetShapesArray(
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
const vtkm::cont::ArrayHandle<vtkm::Int32> indices = cellSetExplicit.GetNumIndicesArray(
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandle<vtkm::Id> conn = cellSetExplicit.GetConnectivityArray(
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandle<vtkm::Id> offsets = cellSetExplicit.GetIndexOffsetArray(
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
2016-01-20 22:40:54 +00:00
// We need to somehow force the data set to build the index offsets
//vtkm::IdComponent c = indices.GetPortalControl().Get(0);
2017-05-18 14:29:41 +00:00
vtkm::Vec<vtkm::Id, 3> forceBuildIndices;
cellSetExplicit.GetIndices(0, forceBuildIndices);
2016-01-20 22:40:54 +00:00
vtkm::cont::ArrayHandle<vtkm::Id> trianglesPerCell;
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapField<CountTriangles>(CountTriangles())
.Invoke(shapes, trianglesPerCell);
2016-01-20 22:40:54 +00:00
vtkm::Id totalTriangles = 0;
2017-05-18 14:29:41 +00:00
totalTriangles =
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Reduce(trianglesPerCell, vtkm::Id(0));
2016-01-20 22:40:54 +00:00
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::ScanExclusive(trianglesPerCell,
cellOffsets);
outputIndices.Allocate(totalTriangles);
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapField<Trianglulate>(
Trianglulate(outputIndices, conn, totalTriangles))
.Invoke(shapes, offsets, cellOffsets);
2016-01-20 22:40:54 +00:00
outputTriangles = totalTriangles;
}
2017-05-18 14:29:41 +00:00
else if (cellset.IsSameType(vtkm::cont::CellSetSingleType<>()))
{
typedef vtkm::TopologyElementTagPoint PointTag;
typedef vtkm::TopologyElementTagCell CellTag;
2017-05-18 14:29:41 +00:00
vtkm::cont::CellSetSingleType<> cellSetSingleType =
cellset.Cast<vtkm::cont::CellSetSingleType<>>();
//fetch and see if we are all triangles, that currently is the only
//cell set single type we support.
vtkm::Id shapeTypeAsId = cellSetSingleType.GetCellShape(0);
2017-05-18 14:29:41 +00:00
if (shapeTypeAsId == vtkm::CellShapeTagTriangle::Id)
2016-06-01 17:37:03 +00:00
{
//generate the outputIndices
vtkm::Id totalTriangles = cellSetSingleType.GetNumberOfCells();
2017-05-18 14:29:41 +00:00
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, totalTriangles);
outputIndices.Allocate(totalTriangles);
2017-05-18 14:29:41 +00:00
vtkm::worklet::DispatcherMapField<Trianglulate>(
Trianglulate(outputIndices, cellSetSingleType.GetConnectivityArray(PointTag(), CellTag()),
totalTriangles))
.Invoke(cellSetSingleType.GetShapesArray(PointTag(), CellTag()),
cellSetSingleType.GetIndexOffsetArray(PointTag(), CellTag()), cellIdxs);
outputTriangles = totalTriangles;
2016-06-01 17:37:03 +00:00
}
else
2016-06-01 17:37:03 +00:00
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadType(
"Unsupported cell type for trianglulation with CellSetSingleType");
2016-06-01 17:37:03 +00:00
}
}
else
{
throw vtkm::cont::ErrorBadType("Unsupported cell set type for trianglulation");
}
2016-01-20 22:40:54 +00:00
//get rid of any triagles we cannot see
ExternalTrianlges(outputIndices, outputTriangles);
}
}; // class Triangulator
2017-05-18 14:29:41 +00:00
}
} //namespace vtkm::rendering
2016-03-02 17:20:09 +00:00
#endif //vtk_m_rendering_Triangulator_h