mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
adding more ray tracing files
This commit is contained in:
parent
1c2f78ca92
commit
6362978ab2
442
vtkm/rendering/Cylinderizer.h
Normal file
442
vtkm/rendering/Cylinderizer.h
Normal file
@ -0,0 +1,442 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_Cylinderizer_h
|
||||
#define vtk_m_rendering_Cylinderizer_h
|
||||
|
||||
#include <typeinfo>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/CellSetPermutation.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
|
||||
#define SEG_PER_TRI 3
|
||||
//CSS is CellSetStructured
|
||||
#define TRI_PER_CSS 12
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
class Cylinderizer
|
||||
{
|
||||
public:
|
||||
class CountSegments : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountSegments() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldOut<>);
|
||||
typedef void ExecutionSignature(CellShape, _2);
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagGeneric shapeType, vtkm::Id& segments) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_LINE)
|
||||
segments = 1;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_TRIANGLE)
|
||||
segments = 3;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
segments = 4;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_TETRA)
|
||||
segments = 12;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_WEDGE)
|
||||
segments = 24;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_PYRAMID)
|
||||
segments = 18;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_HEXAHEDRON)
|
||||
segments = 36;
|
||||
else
|
||||
segments = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType), vtkm::Id& segments) const
|
||||
{
|
||||
segments = 36;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagQuad shapeType, vtkm::Id& segments) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
segments = 4;
|
||||
else
|
||||
segments = 0;
|
||||
}
|
||||
}; //class CountSegments
|
||||
|
||||
template <int DIM>
|
||||
class SegmentedStructured : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInTo<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(FromIndices, _2, _3);
|
||||
//typedef _1 InputDomain;
|
||||
VTKM_CONT
|
||||
SegmentedStructured() {}
|
||||
|
||||
#if defined(VTKM_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127) //conditional expression is constant
|
||||
#endif
|
||||
template <typename CellNodeVecType, typename OutIndicesPortal>
|
||||
VTKM_EXEC void cell2seg(vtkm::Id3 idx,
|
||||
vtkm::Vec<Id, 3>& segment,
|
||||
const vtkm::Id offset,
|
||||
const CellNodeVecType& cellIndices,
|
||||
OutIndicesPortal& outputIndices) const
|
||||
{
|
||||
|
||||
segment[1] = cellIndices[vtkm::IdComponent(idx[0])];
|
||||
segment[2] = cellIndices[vtkm::IdComponent(idx[1])];
|
||||
outputIndices.Set(offset, segment);
|
||||
|
||||
segment[1] = cellIndices[vtkm::IdComponent(idx[1])];
|
||||
segment[2] = cellIndices[vtkm::IdComponent(idx[2])];
|
||||
outputIndices.Set(offset + 1, segment);
|
||||
|
||||
segment[1] = cellIndices[vtkm::IdComponent(idx[2])];
|
||||
segment[2] = cellIndices[vtkm::IdComponent(idx[0])];
|
||||
outputIndices.Set(offset + 2, segment);
|
||||
}
|
||||
template <typename CellNodeVecType, typename OutIndicesPortal>
|
||||
VTKM_EXEC void operator()(const CellNodeVecType& cellIndices,
|
||||
const vtkm::Id& cellIndex,
|
||||
OutIndicesPortal& outputIndices) const
|
||||
{
|
||||
if (DIM == 2)
|
||||
{
|
||||
// Do nothing mark says
|
||||
}
|
||||
else if (DIM == 3)
|
||||
{
|
||||
vtkm::Id offset = cellIndex * TRI_PER_CSS * SEG_PER_TRI;
|
||||
vtkm::Vec<vtkm::Id, 3> segment;
|
||||
segment[0] = cellIndex;
|
||||
vtkm::Id3 idx;
|
||||
idx[0] = 0;
|
||||
idx[1] = 1;
|
||||
idx[2] = 5;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 0;
|
||||
idx[1] = 5;
|
||||
idx[2] = 4;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 1;
|
||||
idx[1] = 2;
|
||||
idx[2] = 6;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 1;
|
||||
idx[1] = 6;
|
||||
idx[2] = 5;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 3;
|
||||
idx[1] = 7;
|
||||
idx[2] = 6;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 3;
|
||||
idx[1] = 6;
|
||||
idx[2] = 2;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 0;
|
||||
idx[1] = 4;
|
||||
idx[2] = 7;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 0;
|
||||
idx[1] = 7;
|
||||
idx[2] = 3;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 0;
|
||||
idx[1] = 3;
|
||||
idx[2] = 2;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 0;
|
||||
idx[1] = 2;
|
||||
idx[2] = 1;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 4;
|
||||
idx[1] = 5;
|
||||
idx[2] = 6;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
idx[0] = 4;
|
||||
idx[1] = 6;
|
||||
idx[2] = 7;
|
||||
offset += 3;
|
||||
cell2seg(idx, segment, offset, cellIndices, outputIndices);
|
||||
}
|
||||
}
|
||||
#if defined(VTKM_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class Cylinderize : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Cylinderize() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInCell<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(_2, CellShape, PointIndices, WorkIndex, _3);
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void tri2seg(vtkm::Id& offset,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
const vtkm::Id Id0,
|
||||
const vtkm::Id Id1,
|
||||
const vtkm::Id Id2,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = vtkm::Id(cellIndices[vtkm::IdComponent(Id0)]);
|
||||
segment[2] = vtkm::Id(cellIndices[vtkm::IdComponent(Id1)]);
|
||||
outputIndices.Set(offset++, segment);
|
||||
|
||||
segment[1] = vtkm::Id(cellIndices[vtkm::IdComponent(Id1)]);
|
||||
segment[2] = vtkm::Id(cellIndices[vtkm::IdComponent(Id2)]);
|
||||
outputIndices.Set(offset++, segment);
|
||||
|
||||
segment[1] = vtkm::Id(cellIndices[vtkm::IdComponent(Id2)]);
|
||||
segment[2] = vtkm::Id(cellIndices[vtkm::IdComponent(Id0)]);
|
||||
outputIndices.Set(offset++, segment);
|
||||
}
|
||||
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& offset,
|
||||
vtkm::CellShapeTagQuad shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(offset, segment);
|
||||
|
||||
segment[1] = cellIndices[1];
|
||||
segment[2] = cellIndices[2];
|
||||
outputIndices.Set(offset + 1, segment);
|
||||
|
||||
segment[1] = cellIndices[2];
|
||||
segment[2] = cellIndices[3];
|
||||
outputIndices.Set(offset + 2, segment);
|
||||
|
||||
segment[1] = cellIndices[3];
|
||||
segment[2] = cellIndices[0];
|
||||
outputIndices.Set(offset + 3, segment);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
tri2seg(offset, cellIndices, cellId, 0, 1, 5, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 5, 4, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 2, 6, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 6, 5, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 7, 6, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 6, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 4, 7, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 7, 3, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 3, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 2, 1, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 4, 5, 6, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 4, 6, 7, outputIndices);
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagGeneric shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_LINE)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(pointOffset, segment);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_TRIANGLE)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(pointOffset, segment);
|
||||
|
||||
segment[1] = cellIndices[1];
|
||||
segment[2] = cellIndices[2];
|
||||
outputIndices.Set(pointOffset + 1, segment);
|
||||
|
||||
segment[1] = cellIndices[2];
|
||||
segment[2] = cellIndices[0];
|
||||
outputIndices.Set(pointOffset + 2, segment);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(pointOffset, segment);
|
||||
|
||||
segment[1] = cellIndices[1];
|
||||
segment[2] = cellIndices[2];
|
||||
outputIndices.Set(pointOffset + 1, segment);
|
||||
|
||||
segment[1] = cellIndices[2];
|
||||
segment[2] = cellIndices[3];
|
||||
outputIndices.Set(pointOffset + 2, segment);
|
||||
|
||||
segment[1] = cellIndices[3];
|
||||
segment[2] = cellIndices[0];
|
||||
outputIndices.Set(pointOffset + 3, segment);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_TETRA)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
tri2seg(offset, cellIndices, cellId, 0, 3, 1, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 2, 3, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 2, 3, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 2, 1, outputIndices);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_HEXAHEDRON)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
tri2seg(offset, cellIndices, cellId, 0, 1, 5, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 5, 4, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 2, 6, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 6, 5, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 7, 6, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 6, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 4, 7, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 7, 3, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 3, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 2, 1, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 4, 5, 6, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 4, 6, 7, outputIndices);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_WEDGE)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
tri2seg(offset, cellIndices, cellId, 0, 1, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 5, 4, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 0, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 2, 5, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 4, 5, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 5, 2, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 3, 4, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 4, 1, outputIndices);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_PYRAMID)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
|
||||
tri2seg(offset, cellIndices, cellId, 0, 4, 1, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 1, 2, 4, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 2, 3, 4, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 0, 4, 3, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 2, 1, outputIndices);
|
||||
tri2seg(offset, cellIndices, cellId, 3, 1, 0, outputIndices);
|
||||
}
|
||||
}
|
||||
|
||||
}; //class cylinderize
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Cylinderizer() {}
|
||||
|
||||
VTKM_CONT
|
||||
void Run(const vtkm::cont::DynamicCellSet& cellset,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>>& outputIndices,
|
||||
vtkm::Id& output)
|
||||
{
|
||||
if (cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
||||
{
|
||||
vtkm::cont::CellSetStructured<3> cellSetStructured3D =
|
||||
cellset.Cast<vtkm::cont::CellSetStructured<3>>();
|
||||
const vtkm::Id numCells = cellSetStructured3D.GetNumberOfCells();
|
||||
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, numCells);
|
||||
outputIndices.Allocate(numCells * TRI_PER_CSS * SEG_PER_TRI);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<SegmentedStructured<3>> segInvoker;
|
||||
segInvoker.Invoke(cellSetStructured3D, cellIdxs, outputIndices);
|
||||
|
||||
output = numCells * TRI_PER_CSS * SEG_PER_TRI;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> segmentsPerCell;
|
||||
vtkm::worklet::DispatcherMapTopology<CountSegments> countInvoker;
|
||||
countInvoker.Invoke(cellset, segmentsPerCell);
|
||||
|
||||
vtkm::Id total = 0;
|
||||
total = vtkm::cont::Algorithm::Reduce(segmentsPerCell, vtkm::Id(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
vtkm::cont::Algorithm::ScanExclusive(segmentsPerCell, cellOffsets);
|
||||
outputIndices.Allocate(total);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<Cylinderize> cylInvoker;
|
||||
cylInvoker.Invoke(cellset, cellOffsets, outputIndices);
|
||||
|
||||
output = total;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
249
vtkm/rendering/MapperCylinder.cxx
Normal file
249
vtkm/rendering/MapperCylinder.cxx
Normal file
@ -0,0 +1,249 @@
|
||||
//============================================================================
|
||||
// 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/MapperCylinder.h>
|
||||
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/Cylinderizer.h>
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/CylinderExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/CylinderIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/QuadExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/QuadIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/SphereExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/Worklets.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
class CalcDistance : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CalcDistance(const vtkm::Vec<vtkm::Float32, 3>& _eye_pos)
|
||||
: eye_pos(_eye_pos)
|
||||
{
|
||||
}
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
template <typename VecType, typename OutType>
|
||||
VTKM_EXEC inline void operator()(const VecType& pos, OutType& out) const
|
||||
{
|
||||
VecType tmp = eye_pos - pos;
|
||||
out = vtkm::Sqrt(vtkm::dot(tmp, tmp));
|
||||
}
|
||||
|
||||
const vtkm::Vec<vtkm::Float32, 3> eye_pos;
|
||||
}; //class CalcDistance
|
||||
|
||||
struct MapperCylinder::InternalsType
|
||||
{
|
||||
vtkm::rendering::CanvasRayTracer* Canvas;
|
||||
vtkm::rendering::raytracing::RayTracer Tracer;
|
||||
vtkm::rendering::raytracing::Camera RayCamera;
|
||||
vtkm::rendering::raytracing::Ray<vtkm::Float32> Rays;
|
||||
bool CompositeBackground;
|
||||
vtkm::Float32 Radius;
|
||||
vtkm::Float32 Delta;
|
||||
bool UseVariableRadius;
|
||||
VTKM_CONT
|
||||
InternalsType()
|
||||
: Canvas(nullptr)
|
||||
, CompositeBackground(true)
|
||||
, Radius(-1.0f)
|
||||
, Delta(0.5)
|
||||
, UseVariableRadius(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
MapperCylinder::MapperCylinder()
|
||||
: Internals(new InternalsType)
|
||||
{
|
||||
}
|
||||
|
||||
MapperCylinder::~MapperCylinder()
|
||||
{
|
||||
}
|
||||
|
||||
void MapperCylinder::SetCanvas(vtkm::rendering::Canvas* canvas)
|
||||
{
|
||||
if (canvas != nullptr)
|
||||
{
|
||||
this->Internals->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
|
||||
if (this->Internals->Canvas == nullptr)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Ray Tracer: bad canvas type. Must be CanvasRayTracer");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Internals->Canvas = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::rendering::Canvas* MapperCylinder::GetCanvas() const
|
||||
{
|
||||
return this->Internals->Canvas;
|
||||
}
|
||||
|
||||
void MapperCylinder::UseVariableRadius(bool useVariableRadius)
|
||||
{
|
||||
this->Internals->UseVariableRadius = useVariableRadius;
|
||||
}
|
||||
|
||||
void MapperCylinder::SetRadius(const vtkm::Float32& radius)
|
||||
{
|
||||
if (radius <= 0.f)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("MapperCylinder: radius must be positive");
|
||||
}
|
||||
this->Internals->Radius = radius;
|
||||
}
|
||||
void MapperCylinder::SetRadiusDelta(const vtkm::Float32& delta)
|
||||
{
|
||||
this->Internals->Delta = delta;
|
||||
}
|
||||
|
||||
void MapperCylinder::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& scalarField,
|
||||
const vtkm::cont::ColorTable& vtkmNotUsed(colorTable),
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
raytracing::Logger* logger = raytracing::Logger::GetInstance();
|
||||
logger->OpenLogEntry("mapper_cylinder");
|
||||
vtkm::cont::Timer<> tot_timer;
|
||||
vtkm::cont::Timer<> timer;
|
||||
|
||||
|
||||
vtkm::Bounds shapeBounds;
|
||||
raytracing::CylinderExtractor cylExtractor;
|
||||
|
||||
vtkm::Float32 baseRadius = this->Internals->Radius;
|
||||
if (baseRadius == -1.f)
|
||||
{
|
||||
// set a default radius
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> dist;
|
||||
vtkm::worklet::DispatcherMapField<CalcDistance>(CalcDistance(camera.GetPosition()))
|
||||
.Invoke(coords, dist);
|
||||
|
||||
|
||||
vtkm::Float32 min_dist =
|
||||
vtkm::cont::Algorithm::Reduce(dist, vtkm::Infinity<vtkm::Float32>(), vtkm::Minimum());
|
||||
|
||||
baseRadius = 0.576769694f * min_dist - 0.603522029f * vtkm::Pow(vtkm::Float32(min_dist), 2.f) +
|
||||
0.232171175f * vtkm::Pow(vtkm::Float32(min_dist), 3.f) -
|
||||
0.038697244f * vtkm::Pow(vtkm::Float32(min_dist), 4.f) +
|
||||
0.002366979f * vtkm::Pow(vtkm::Float32(min_dist), 5.f);
|
||||
baseRadius /= min_dist;
|
||||
vtkm::worklet::DispatcherMapField<vtkm::rendering::raytracing::MemSet<vtkm::Float32>>(
|
||||
vtkm::rendering::raytracing::MemSet<vtkm::Float32>(baseRadius))
|
||||
.Invoke(cylExtractor.GetRadii());
|
||||
}
|
||||
|
||||
if (this->Internals->UseVariableRadius)
|
||||
{
|
||||
vtkm::Float32 minRadius = baseRadius - baseRadius * this->Internals->Delta;
|
||||
vtkm::Float32 maxRadius = baseRadius + baseRadius * this->Internals->Delta;
|
||||
|
||||
cylExtractor.ExtractCells(cellset, scalarField, minRadius, maxRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
cylExtractor.ExtractCells(cellset, baseRadius);
|
||||
}
|
||||
|
||||
//
|
||||
// Add supported shapes
|
||||
//
|
||||
|
||||
if (cylExtractor.GetNumberOfCylinders() > 0)
|
||||
{
|
||||
raytracing::CylinderIntersector* cylIntersector = new raytracing::CylinderIntersector();
|
||||
cylIntersector->SetData(coords, cylExtractor.GetCylIds(), cylExtractor.GetRadii());
|
||||
this->Internals->Tracer.AddShapeIntersector(cylIntersector);
|
||||
shapeBounds.Include(cylIntersector->GetShapeBounds());
|
||||
}
|
||||
//
|
||||
// Create rays
|
||||
//
|
||||
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
|
||||
cam.SetParameters(camera, *this->Internals->Canvas);
|
||||
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
|
||||
|
||||
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
|
||||
this->Internals->Rays.Buffers.at(0).InitConst(0.f);
|
||||
raytracing::RayOperations::MapCanvasToRays(
|
||||
this->Internals->Rays, camera, *this->Internals->Canvas);
|
||||
|
||||
|
||||
|
||||
this->Internals->Tracer.SetField(scalarField, scalarRange);
|
||||
|
||||
this->Internals->Tracer.SetColorMap(this->ColorMap);
|
||||
this->Internals->Tracer.Render(this->Internals->Rays);
|
||||
|
||||
timer.Reset();
|
||||
this->Internals->Canvas->WriteToCanvas(
|
||||
this->Internals->Rays, this->Internals->Rays.Buffers.at(0).Buffer, camera);
|
||||
|
||||
if (this->Internals->CompositeBackground)
|
||||
{
|
||||
this->Internals->Canvas->BlendBackground();
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("write_to_canvas", time);
|
||||
time = tot_timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
|
||||
void MapperCylinder::SetCompositeBackground(bool on)
|
||||
{
|
||||
this->Internals->CompositeBackground = on;
|
||||
}
|
||||
|
||||
void MapperCylinder::StartScene()
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
void MapperCylinder::EndScene()
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
vtkm::rendering::Mapper* MapperCylinder::NewCopy() const
|
||||
{
|
||||
return new vtkm::rendering::MapperCylinder(*this);
|
||||
}
|
||||
}
|
||||
} // vtkm::rendering
|
246
vtkm/rendering/MapperPoint.cxx
Normal file
246
vtkm/rendering/MapperPoint.cxx
Normal file
@ -0,0 +1,246 @@
|
||||
//============================================================================
|
||||
// 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/MapperPoint.h>
|
||||
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/internal/RunTriangulator.h>
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/SphereExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleExtractor.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
struct MapperPoint::InternalsType
|
||||
{
|
||||
vtkm::rendering::CanvasRayTracer* Canvas;
|
||||
vtkm::rendering::raytracing::RayTracer Tracer;
|
||||
vtkm::rendering::raytracing::Camera RayCamera;
|
||||
vtkm::rendering::raytracing::Ray<vtkm::Float32> Rays;
|
||||
bool CompositeBackground;
|
||||
vtkm::Float32 PointRadius;
|
||||
bool UseNodes;
|
||||
vtkm::Float32 PointDelta;
|
||||
bool UseVariableRadius;
|
||||
|
||||
VTKM_CONT
|
||||
InternalsType()
|
||||
: Canvas(nullptr)
|
||||
, CompositeBackground(true)
|
||||
, PointRadius(-1.f)
|
||||
, UseNodes(true)
|
||||
, PointDelta(0.5f)
|
||||
, UseVariableRadius(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
MapperPoint::MapperPoint()
|
||||
: Internals(new InternalsType)
|
||||
{
|
||||
}
|
||||
|
||||
MapperPoint::~MapperPoint()
|
||||
{
|
||||
}
|
||||
|
||||
void MapperPoint::SetCanvas(vtkm::rendering::Canvas* canvas)
|
||||
{
|
||||
if (canvas != nullptr)
|
||||
{
|
||||
this->Internals->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
|
||||
if (this->Internals->Canvas == nullptr)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("MapperPoint: bad canvas type. Must be CanvasRayTracer");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Internals->Canvas = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::rendering::Canvas* MapperPoint::GetCanvas() const
|
||||
{
|
||||
return this->Internals->Canvas;
|
||||
}
|
||||
|
||||
void MapperPoint::UseCells()
|
||||
{
|
||||
this->Internals->UseNodes = false;
|
||||
}
|
||||
void MapperPoint::UseNodes()
|
||||
{
|
||||
this->Internals->UseNodes = true;
|
||||
}
|
||||
|
||||
void MapperPoint::SetRadius(const vtkm::Float32& radius)
|
||||
{
|
||||
if (radius <= 0.f)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("MapperPoint: point radius must be positive");
|
||||
}
|
||||
this->Internals->PointRadius = radius;
|
||||
}
|
||||
|
||||
void MapperPoint::SetRadiusDelta(const vtkm::Float32& delta)
|
||||
{
|
||||
this->Internals->PointDelta = delta;
|
||||
}
|
||||
|
||||
void MapperPoint::UseVariableRadius(bool useVariableRadius)
|
||||
{
|
||||
this->Internals->UseVariableRadius = useVariableRadius;
|
||||
}
|
||||
|
||||
void MapperPoint::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& scalarField,
|
||||
const vtkm::cont::ColorTable& vtkmNotUsed(colorTable),
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
raytracing::Logger* logger = raytracing::Logger::GetInstance();
|
||||
|
||||
// make sure we start fresh
|
||||
this->Internals->Tracer.Clear();
|
||||
|
||||
logger->OpenLogEntry("mapper_ray_tracer");
|
||||
vtkm::cont::Timer<> tot_timer;
|
||||
vtkm::cont::Timer<> timer;
|
||||
|
||||
vtkm::Bounds coordBounds = coords.GetBounds();
|
||||
vtkm::Float32 baseRadius = this->Internals->PointRadius;
|
||||
if (baseRadius == -1.f)
|
||||
{
|
||||
// set a default radius
|
||||
vtkm::Float64 lx = coordBounds.X.Length();
|
||||
vtkm::Float64 ly = coordBounds.Y.Length();
|
||||
vtkm::Float64 lz = coordBounds.Z.Length();
|
||||
vtkm::Float64 mag = vtkm::Sqrt(lx * lx + ly * ly + lz * lz);
|
||||
// same as used in vtk ospray
|
||||
constexpr vtkm::Float64 heuristic = 500.;
|
||||
baseRadius = static_cast<vtkm::Float32>(mag / heuristic);
|
||||
}
|
||||
|
||||
vtkm::Bounds shapeBounds;
|
||||
|
||||
raytracing::SphereExtractor sphereExtractor;
|
||||
|
||||
if (this->Internals->UseVariableRadius)
|
||||
{
|
||||
vtkm::Float32 minRadius = baseRadius - baseRadius * this->Internals->PointDelta;
|
||||
vtkm::Float32 maxRadius = baseRadius + baseRadius * this->Internals->PointDelta;
|
||||
if (this->Internals->UseNodes)
|
||||
{
|
||||
|
||||
sphereExtractor.ExtractCoordinates(coords, scalarField, minRadius, maxRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
sphereExtractor.ExtractCells(cellset, scalarField, minRadius, maxRadius);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->Internals->UseNodes)
|
||||
{
|
||||
|
||||
sphereExtractor.ExtractCoordinates(coords, baseRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
sphereExtractor.ExtractCells(cellset, baseRadius);
|
||||
}
|
||||
}
|
||||
|
||||
if (sphereExtractor.GetNumberOfSpheres() > 0)
|
||||
{
|
||||
raytracing::SphereIntersector* sphereIntersector = new raytracing::SphereIntersector();
|
||||
sphereIntersector->SetData(coords, sphereExtractor.GetPointIds(), sphereExtractor.GetRadii());
|
||||
this->Internals->Tracer.AddShapeIntersector(sphereIntersector);
|
||||
shapeBounds.Include(sphereIntersector->GetShapeBounds());
|
||||
}
|
||||
|
||||
//
|
||||
// Create rays
|
||||
//
|
||||
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
|
||||
cam.SetParameters(camera, *this->Internals->Canvas);
|
||||
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
|
||||
|
||||
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
|
||||
this->Internals->Rays.Buffers.at(0).InitConst(0.f);
|
||||
raytracing::RayOperations::MapCanvasToRays(
|
||||
this->Internals->Rays, camera, *this->Internals->Canvas);
|
||||
|
||||
|
||||
|
||||
this->Internals->Tracer.SetField(scalarField, scalarRange);
|
||||
|
||||
this->Internals->Tracer.SetColorMap(this->ColorMap);
|
||||
this->Internals->Tracer.Render(this->Internals->Rays);
|
||||
|
||||
timer.Reset();
|
||||
this->Internals->Canvas->WriteToCanvas(
|
||||
this->Internals->Rays, this->Internals->Rays.Buffers.at(0).Buffer, camera);
|
||||
|
||||
if (this->Internals->CompositeBackground)
|
||||
{
|
||||
this->Internals->Canvas->BlendBackground();
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("write_to_canvas", time);
|
||||
time = tot_timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
|
||||
void MapperPoint::SetCompositeBackground(bool on)
|
||||
{
|
||||
this->Internals->CompositeBackground = on;
|
||||
}
|
||||
|
||||
void MapperPoint::StartScene()
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
void MapperPoint::EndScene()
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
vtkm::rendering::Mapper* MapperPoint::NewCopy() const
|
||||
{
|
||||
return new vtkm::rendering::MapperPoint(*this);
|
||||
}
|
||||
}
|
||||
} // vtkm::rendering
|
99
vtkm/rendering/MapperPoint.h
Normal file
99
vtkm/rendering/MapperPoint.h
Normal file
@ -0,0 +1,99 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_MapperPoint_h
|
||||
#define vtk_m_rendering_MapperPoint_h
|
||||
|
||||
#include <vtkm/cont/ColorTable.h>
|
||||
#include <vtkm/rendering/Camera.h>
|
||||
#include <vtkm/rendering/Mapper.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT MapperPoint : public Mapper
|
||||
{
|
||||
public:
|
||||
MapperPoint();
|
||||
|
||||
~MapperPoint();
|
||||
|
||||
void SetCanvas(vtkm::rendering::Canvas* canvas) override;
|
||||
virtual vtkm::rendering::Canvas* GetCanvas() const override;
|
||||
|
||||
/**
|
||||
* \brief render points based on cell shape point
|
||||
*
|
||||
*/
|
||||
void UseCells();
|
||||
/**
|
||||
* \brief render points using the nodes of the mesh.
|
||||
* This is the default.
|
||||
*/
|
||||
void UseNodes();
|
||||
|
||||
/**
|
||||
* \brief render points using a variable radius based on
|
||||
* the scalar field.
|
||||
* The default is false.
|
||||
*/
|
||||
void UseVariableRadius(bool useVariableRadius);
|
||||
|
||||
/**
|
||||
* \brief Set a base raidus for all points. If a
|
||||
* radius is never specified the default heuristic
|
||||
* is used.
|
||||
*/
|
||||
void SetRadius(const vtkm::Float32& radius);
|
||||
/**
|
||||
* \brief When using a variable raidus for all points, the
|
||||
* radius delta controls how much larger and smaller
|
||||
* radii become based on the scalar field. If the delta
|
||||
* is 0 all points will have the same radius. If the delta
|
||||
* is 0.5 then the max/min scalar values would have a radii
|
||||
* of base +/- base * 0.5.
|
||||
*/
|
||||
void SetRadiusDelta(const vtkm::Float32& delta);
|
||||
|
||||
void RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& scalarField,
|
||||
const vtkm::cont::ColorTable& colorTable,
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
virtual void StartScene() override;
|
||||
virtual void EndScene() override;
|
||||
void SetCompositeBackground(bool on);
|
||||
vtkm::rendering::Mapper* NewCopy() const override;
|
||||
|
||||
private:
|
||||
struct InternalsType;
|
||||
std::shared_ptr<InternalsType> Internals;
|
||||
|
||||
struct RenderFunctor;
|
||||
};
|
||||
}
|
||||
} //namespace vtkm::rendering
|
||||
|
||||
#endif //vtk_m_rendering_MapperPoint_h
|
170
vtkm/rendering/MapperQuad.cxx
Normal file
170
vtkm/rendering/MapperQuad.cxx
Normal file
@ -0,0 +1,170 @@
|
||||
//============================================================================
|
||||
// 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/MapperQuad.h>
|
||||
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/Cylinderizer.h>
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/CylinderExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/CylinderIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/QuadExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/QuadIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/SphereExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
struct MapperQuad::InternalsType
|
||||
{
|
||||
vtkm::rendering::CanvasRayTracer* Canvas;
|
||||
vtkm::rendering::raytracing::RayTracer Tracer;
|
||||
vtkm::rendering::raytracing::Camera RayCamera;
|
||||
vtkm::rendering::raytracing::Ray<vtkm::Float32> Rays;
|
||||
bool CompositeBackground;
|
||||
VTKM_CONT
|
||||
InternalsType()
|
||||
: Canvas(nullptr)
|
||||
, CompositeBackground(true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
MapperQuad::MapperQuad()
|
||||
: Internals(new InternalsType)
|
||||
{
|
||||
}
|
||||
|
||||
MapperQuad::~MapperQuad()
|
||||
{
|
||||
}
|
||||
|
||||
void MapperQuad::SetCanvas(vtkm::rendering::Canvas* canvas)
|
||||
{
|
||||
if (canvas != nullptr)
|
||||
{
|
||||
this->Internals->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
|
||||
if (this->Internals->Canvas == nullptr)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Ray Tracer: bad canvas type. Must be CanvasRayTracer");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Internals->Canvas = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::rendering::Canvas* MapperQuad::GetCanvas() const
|
||||
{
|
||||
return this->Internals->Canvas;
|
||||
}
|
||||
|
||||
void MapperQuad::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& scalarField,
|
||||
const vtkm::cont::ColorTable& vtkmNotUsed(colorTable),
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
raytracing::Logger* logger = raytracing::Logger::GetInstance();
|
||||
logger->OpenLogEntry("mapper_ray_tracer");
|
||||
vtkm::cont::Timer<> tot_timer;
|
||||
vtkm::cont::Timer<> timer;
|
||||
|
||||
|
||||
//
|
||||
// Add supported shapes
|
||||
//
|
||||
vtkm::Bounds shapeBounds;
|
||||
raytracing::QuadExtractor quadExtractor;
|
||||
quadExtractor.ExtractCells(cellset);
|
||||
if (quadExtractor.GetNumberOfQuads() > 0)
|
||||
{
|
||||
raytracing::QuadIntersector* quadIntersector = new raytracing::QuadIntersector();
|
||||
quadIntersector->SetData(coords, quadExtractor.GetQuadIds());
|
||||
this->Internals->Tracer.AddShapeIntersector(quadIntersector);
|
||||
shapeBounds.Include(quadIntersector->GetShapeBounds());
|
||||
}
|
||||
|
||||
//
|
||||
// Create rays
|
||||
//
|
||||
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
|
||||
cam.SetParameters(camera, *this->Internals->Canvas);
|
||||
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
|
||||
|
||||
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
|
||||
this->Internals->Rays.Buffers.at(0).InitConst(0.f);
|
||||
raytracing::RayOperations::MapCanvasToRays(
|
||||
this->Internals->Rays, camera, *this->Internals->Canvas);
|
||||
|
||||
|
||||
|
||||
this->Internals->Tracer.SetField(scalarField, scalarRange);
|
||||
|
||||
this->Internals->Tracer.SetColorMap(this->ColorMap);
|
||||
this->Internals->Tracer.Render(this->Internals->Rays);
|
||||
|
||||
timer.Reset();
|
||||
this->Internals->Canvas->WriteToCanvas(
|
||||
this->Internals->Rays, this->Internals->Rays.Buffers.at(0).Buffer, camera);
|
||||
|
||||
if (this->Internals->CompositeBackground)
|
||||
{
|
||||
this->Internals->Canvas->BlendBackground();
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("write_to_canvas", time);
|
||||
time = tot_timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
|
||||
void MapperQuad::SetCompositeBackground(bool on)
|
||||
{
|
||||
this->Internals->CompositeBackground = on;
|
||||
}
|
||||
|
||||
void MapperQuad::StartScene()
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
void MapperQuad::EndScene()
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
vtkm::rendering::Mapper* MapperQuad::NewCopy() const
|
||||
{
|
||||
return new vtkm::rendering::MapperQuad(*this);
|
||||
}
|
||||
}
|
||||
} // vtkm::rendering
|
65
vtkm/rendering/MapperQuad.h
Normal file
65
vtkm/rendering/MapperQuad.h
Normal file
@ -0,0 +1,65 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_MapperQuad_h
|
||||
#define vtk_m_rendering_MapperQuad_h
|
||||
|
||||
#include <vtkm/cont/ColorTable.h>
|
||||
#include <vtkm/rendering/Camera.h>
|
||||
#include <vtkm/rendering/Mapper.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT MapperQuad : public Mapper
|
||||
{
|
||||
public:
|
||||
MapperQuad();
|
||||
|
||||
~MapperQuad();
|
||||
|
||||
void SetCanvas(vtkm::rendering::Canvas* canvas) override;
|
||||
virtual vtkm::rendering::Canvas* GetCanvas() const override;
|
||||
|
||||
void RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& scalarField,
|
||||
const vtkm::cont::ColorTable& colorTable,
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
virtual void StartScene() override;
|
||||
virtual void EndScene() override;
|
||||
void SetCompositeBackground(bool on);
|
||||
vtkm::rendering::Mapper* NewCopy() const override;
|
||||
|
||||
private:
|
||||
struct InternalsType;
|
||||
std::shared_ptr<InternalsType> Internals;
|
||||
|
||||
struct RenderFunctor;
|
||||
};
|
||||
}
|
||||
} //namespace vtkm::rendering
|
||||
|
||||
#endif //vtk_m_rendering_MapperQuad_h
|
331
vtkm/rendering/Quadralizer.h
Normal file
331
vtkm/rendering/Quadralizer.h
Normal file
@ -0,0 +1,331 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_Quadralizer_h
|
||||
#define vtk_m_rendering_Quadralizer_h
|
||||
|
||||
#include <typeinfo>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/CellSetPermutation.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
|
||||
|
||||
#define QUAD_PER_CSS 6
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
class Quadralizer
|
||||
{
|
||||
public:
|
||||
class CountQuads : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountQuads() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldOut<>);
|
||||
typedef void ExecutionSignature(CellShape, _2);
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagGeneric shapeType, vtkm::Id& quads) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
quads = 1;
|
||||
else if (shapeType.Id == CELL_SHAPE_HEXAHEDRON)
|
||||
quads = 6;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_WEDGE)
|
||||
quads = 3;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_PYRAMID)
|
||||
quads = 1;
|
||||
|
||||
else
|
||||
quads = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType), vtkm::Id& quads) const
|
||||
{
|
||||
quads = 6;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagQuad shapeType, vtkm::Id& quads) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
quads = 1;
|
||||
else
|
||||
quads = 0;
|
||||
}
|
||||
}; //class CountQuads
|
||||
|
||||
template <int DIM>
|
||||
class SegmentedStructured : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInTo<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(FromIndices, _2, _3);
|
||||
//typedef _1 InputDomain;
|
||||
VTKM_CONT
|
||||
SegmentedStructured() {}
|
||||
|
||||
#if defined(VTKM_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127) //conditional expression is constant
|
||||
#endif
|
||||
template <typename CellNodeVecType, typename OutIndicesPortal>
|
||||
VTKM_EXEC void cell2quad(vtkm::Vec<vtkm::Id, 4> idx,
|
||||
vtkm::Vec<Id, 5>& quad,
|
||||
const vtkm::Id offset,
|
||||
const CellNodeVecType& cellIndices,
|
||||
OutIndicesPortal& outputIndices) const
|
||||
{
|
||||
|
||||
quad[1] = cellIndices[vtkm::IdComponent(idx[0])];
|
||||
quad[2] = cellIndices[vtkm::IdComponent(idx[1])];
|
||||
quad[3] = cellIndices[vtkm::IdComponent(idx[2])];
|
||||
quad[4] = cellIndices[vtkm::IdComponent(idx[3])];
|
||||
outputIndices.Set(offset, quad);
|
||||
}
|
||||
|
||||
template <typename CellNodeVecType, typename OutIndicesPortal>
|
||||
VTKM_EXEC void operator()(const CellNodeVecType& cellIndices,
|
||||
const vtkm::Id& cellIndex,
|
||||
OutIndicesPortal& outputIndices) const
|
||||
{
|
||||
if (DIM == 2)
|
||||
{
|
||||
// Do nothing mark says
|
||||
}
|
||||
else if (DIM == 3)
|
||||
{
|
||||
vtkm::Id offset = cellIndex * QUAD_PER_CSS;
|
||||
vtkm::Vec<vtkm::Id, 5> quad;
|
||||
quad[0] = cellIndex;
|
||||
vtkm::Vec<vtkm::Id, 4> idx;
|
||||
idx[0] = 0;
|
||||
idx[1] = 1;
|
||||
idx[2] = 5, idx[3] = 4;
|
||||
cell2quad(idx, quad, offset, cellIndices, outputIndices);
|
||||
|
||||
idx[0] = 1;
|
||||
idx[1] = 2;
|
||||
idx[2] = 6;
|
||||
idx[3] = 5;
|
||||
offset++;
|
||||
cell2quad(idx, quad, offset, cellIndices, outputIndices);
|
||||
|
||||
idx[0] = 3;
|
||||
idx[1] = 7;
|
||||
idx[2] = 6;
|
||||
idx[3] = 2;
|
||||
offset++;
|
||||
cell2quad(idx, quad, offset, cellIndices, outputIndices);
|
||||
|
||||
idx[0] = 0;
|
||||
idx[1] = 4;
|
||||
idx[2] = 7;
|
||||
idx[3] = 3;
|
||||
offset++;
|
||||
cell2quad(idx, quad, offset, cellIndices, outputIndices);
|
||||
|
||||
idx[0] = 0;
|
||||
idx[1] = 3;
|
||||
idx[2] = 2;
|
||||
idx[3] = 1;
|
||||
offset++;
|
||||
cell2quad(idx, quad, offset, cellIndices, outputIndices);
|
||||
|
||||
idx[0] = 4;
|
||||
idx[1] = 5;
|
||||
idx[2] = 6;
|
||||
idx[3] = 7;
|
||||
offset++;
|
||||
cell2quad(idx, quad, offset, cellIndices, outputIndices);
|
||||
}
|
||||
}
|
||||
#if defined(VTKM_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class Quadralize : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Quadralize() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInCell<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(_2, CellShape, PointIndices, WorkIndex, _3);
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void cell2quad(vtkm::Id& offset,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
const vtkm::Id Id0,
|
||||
const vtkm::Id Id1,
|
||||
const vtkm::Id Id2,
|
||||
const vtkm::Id Id3,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 5> quad;
|
||||
quad[0] = cellId;
|
||||
quad[1] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id0)]);
|
||||
quad[2] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id1)]);
|
||||
quad[3] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id2)]);
|
||||
quad[4] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id3)]);
|
||||
outputIndices.Set(offset++, quad);
|
||||
}
|
||||
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& offset,
|
||||
vtkm::CellShapeTagQuad shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 5> quad;
|
||||
quad[0] = cellId;
|
||||
quad[1] = static_cast<vtkm::Id>(cellIndices[0]);
|
||||
quad[2] = static_cast<vtkm::Id>(cellIndices[1]);
|
||||
quad[3] = static_cast<vtkm::Id>(cellIndices[2]);
|
||||
quad[4] = static_cast<vtkm::Id>(cellIndices[3]);
|
||||
outputIndices.Set(offset, quad);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
cell2quad(offset, cellIndices, cellId, 0, 1, 5, 4, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 1, 2, 6, 5, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 3, 7, 6, 2, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 4, 7, 3, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 3, 2, 1, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 4, 5, 6, 7, outputIndices);
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagGeneric shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 5> quad;
|
||||
quad[0] = cellId;
|
||||
quad[1] = cellIndices[0];
|
||||
quad[2] = cellIndices[1];
|
||||
quad[3] = cellIndices[2];
|
||||
quad[4] = cellIndices[3];
|
||||
outputIndices.Set(pointOffset, quad);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_HEXAHEDRON)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
cell2quad(offset, cellIndices, cellId, 0, 1, 5, 4, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 1, 2, 6, 5, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 3, 7, 6, 2, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 4, 7, 3, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 3, 2, 1, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 4, 5, 6, 7, outputIndices);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_WEDGE)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
|
||||
cell2quad(offset, cellIndices, cellId, 3, 0, 2, 5, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 1, 4, 5, 2, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 3, 4, 1, outputIndices);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_PYRAMID)
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
|
||||
cell2quad(offset, cellIndices, cellId, 3, 2, 1, 0, outputIndices);
|
||||
}
|
||||
}
|
||||
|
||||
}; //class Quadralize
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Quadralizer() {}
|
||||
|
||||
VTKM_CONT
|
||||
void Run(const vtkm::cont::DynamicCellSet& cellset,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>>& outputIndices,
|
||||
vtkm::Id& output)
|
||||
{
|
||||
if (cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
||||
{
|
||||
vtkm::cont::CellSetStructured<3> cellSetStructured3D =
|
||||
cellset.Cast<vtkm::cont::CellSetStructured<3>>();
|
||||
const vtkm::Id numCells = cellSetStructured3D.GetNumberOfCells();
|
||||
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, numCells);
|
||||
outputIndices.Allocate(numCells * QUAD_PER_CSS);
|
||||
vtkm::worklet::DispatcherMapTopology<SegmentedStructured<3>> segInvoker;
|
||||
segInvoker.Invoke(cellSetStructured3D, cellIdxs, outputIndices);
|
||||
|
||||
output = numCells * QUAD_PER_CSS;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> quadsPerCell;
|
||||
vtkm::worklet::DispatcherMapTopology<CountQuads> countInvoker;
|
||||
countInvoker.Invoke(cellset, quadsPerCell);
|
||||
|
||||
vtkm::Id total = 0;
|
||||
total = vtkm::cont::Algorithm::Reduce(quadsPerCell, vtkm::Id(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
vtkm::cont::Algorithm::ScanExclusive(quadsPerCell, cellOffsets);
|
||||
outputIndices.Allocate(total);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<Quadralize> quadInvoker;
|
||||
quadInvoker.Invoke(cellset, cellOffsets, outputIndices);
|
||||
|
||||
output = total;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
267
vtkm/rendering/raytracing/BVHTraverser.h
Normal file
267
vtkm/rendering/raytracing/BVHTraverser.h
Normal file
@ -0,0 +1,267 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_BVH_Traverser_h
|
||||
#define vtk_m_rendering_raytracing_BVH_Traverser_h
|
||||
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
#define END_FLAG -1000000000
|
||||
|
||||
template <typename BVHPortalType, typename Precision>
|
||||
VTKM_EXEC inline bool IntersectAABB(const BVHPortalType& bvh,
|
||||
const vtkm::Int32& currentNode,
|
||||
const vtkm::Vec<Precision, 3>& originDir,
|
||||
const vtkm::Vec<Precision, 3>& invDir,
|
||||
const Precision& closestDistance,
|
||||
bool& hitLeftChild,
|
||||
bool& hitRightChild,
|
||||
const Precision& minDistance) //Find hit after this distance
|
||||
{
|
||||
vtkm::Vec<vtkm::Float32, 4> first4 = bvh.Get(currentNode);
|
||||
vtkm::Vec<vtkm::Float32, 4> second4 = bvh.Get(currentNode + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> third4 = bvh.Get(currentNode + 2);
|
||||
|
||||
Precision xmin0 = first4[0] * invDir[0] - originDir[0];
|
||||
Precision ymin0 = first4[1] * invDir[1] - originDir[1];
|
||||
Precision zmin0 = first4[2] * invDir[2] - originDir[2];
|
||||
Precision xmax0 = first4[3] * invDir[0] - originDir[0];
|
||||
Precision ymax0 = second4[0] * invDir[1] - originDir[1];
|
||||
Precision zmax0 = second4[1] * invDir[2] - originDir[2];
|
||||
|
||||
Precision min0 = vtkm::Max(
|
||||
vtkm::Max(vtkm::Max(vtkm::Min(ymin0, ymax0), vtkm::Min(xmin0, xmax0)), vtkm::Min(zmin0, zmax0)),
|
||||
minDistance);
|
||||
Precision max0 = vtkm::Min(
|
||||
vtkm::Min(vtkm::Min(vtkm::Max(ymin0, ymax0), vtkm::Max(xmin0, xmax0)), vtkm::Max(zmin0, zmax0)),
|
||||
closestDistance);
|
||||
hitLeftChild = (max0 >= min0);
|
||||
|
||||
Precision xmin1 = second4[2] * invDir[0] - originDir[0];
|
||||
Precision ymin1 = second4[3] * invDir[1] - originDir[1];
|
||||
Precision zmin1 = third4[0] * invDir[2] - originDir[2];
|
||||
Precision xmax1 = third4[1] * invDir[0] - originDir[0];
|
||||
Precision ymax1 = third4[2] * invDir[1] - originDir[1];
|
||||
Precision zmax1 = third4[3] * invDir[2] - originDir[2];
|
||||
|
||||
Precision min1 = vtkm::Max(
|
||||
vtkm::Max(vtkm::Max(vtkm::Min(ymin1, ymax1), vtkm::Min(xmin1, xmax1)), vtkm::Min(zmin1, zmax1)),
|
||||
minDistance);
|
||||
Precision max1 = vtkm::Min(
|
||||
vtkm::Min(vtkm::Min(vtkm::Max(ymin1, ymax1), vtkm::Max(xmin1, xmax1)), vtkm::Max(zmin1, zmax1)),
|
||||
closestDistance);
|
||||
hitRightChild = (max1 >= min1);
|
||||
return (min0 > min1);
|
||||
}
|
||||
|
||||
template <template <typename> class LeafIntersectorType>
|
||||
class BVHTraverser
|
||||
{
|
||||
public:
|
||||
template <typename Device>
|
||||
class Intersector : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef typename vtkm::cont::ArrayHandle<Vec<vtkm::Float32, 4>> Float4ArrayHandle;
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 2>> Int2Handle;
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
|
||||
typedef typename Float4ArrayHandle::ExecutionTypes<Device>::PortalConst Float4ArrayPortal;
|
||||
typedef typename Int2Handle::ExecutionTypes<Device>::PortalConst Int2ArrayPortal;
|
||||
typedef typename IdHandle::ExecutionTypes<Device>::PortalConst IdArrayPortal;
|
||||
typedef typename Id4Handle::ExecutionTypes<Device>::PortalConst Id4ArrayPortal;
|
||||
|
||||
private:
|
||||
bool Occlusion;
|
||||
Float4ArrayPortal FlatBVH;
|
||||
IdArrayPortal Leafs;
|
||||
LeafIntersectorType<Device> LeafIntersector;
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float32 rcp(vtkm::Float32 f) const { return 1.0f / f; }
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float32 rcp_safe(vtkm::Float32 f) const
|
||||
{
|
||||
return rcp((vtkm::Abs(f) < 1e-8f) ? 1e-8f : f);
|
||||
}
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float64 rcp(vtkm::Float64 f) const { return 1.0 / f; }
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float64 rcp_safe(vtkm::Float64 f) const
|
||||
{
|
||||
return rcp((vtkm::Abs(f) < 1e-8f) ? 1e-8f : f);
|
||||
}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Intersector(bool occlusion, LinearBVH& bvh, LeafIntersectorType<Device>& leafIntersector)
|
||||
: Occlusion(occlusion)
|
||||
, FlatBVH(bvh.FlatBVH.PrepareForInput(Device()))
|
||||
, Leafs(bvh.Leafs.PrepareForInput(Device()))
|
||||
, LeafIntersector(leafIntersector)
|
||||
{
|
||||
}
|
||||
using ControlSignature = void(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7, _8, _9);
|
||||
|
||||
|
||||
template <typename PointPortalType, typename Precision>
|
||||
VTKM_EXEC void operator()(const vtkm::Vec<Precision, 3>& dir,
|
||||
const vtkm::Vec<Precision, 3>& origin,
|
||||
Precision& distance,
|
||||
const Precision& minDistance,
|
||||
const Precision& maxDistance,
|
||||
Precision& minU,
|
||||
Precision& minV,
|
||||
vtkm::Id& hitIndex,
|
||||
const PointPortalType& points) const
|
||||
{
|
||||
Precision closestDistance = maxDistance;
|
||||
distance = maxDistance;
|
||||
hitIndex = -1;
|
||||
|
||||
vtkm::Vec<Precision, 3> invDir;
|
||||
invDir[0] = rcp_safe(dir[0]);
|
||||
invDir[1] = rcp_safe(dir[1]);
|
||||
invDir[2] = rcp_safe(dir[2]);
|
||||
vtkm::Int32 currentNode;
|
||||
|
||||
vtkm::Int32 todo[64];
|
||||
vtkm::Int32 stackptr = 0;
|
||||
vtkm::Int32 barrier = (vtkm::Int32)END_FLAG;
|
||||
currentNode = 0;
|
||||
|
||||
todo[stackptr] = barrier;
|
||||
|
||||
vtkm::Vec<Precision, 3> originDir = origin * invDir;
|
||||
|
||||
while (currentNode != END_FLAG)
|
||||
{
|
||||
if (currentNode > -1)
|
||||
{
|
||||
|
||||
|
||||
bool hitLeftChild, hitRightChild;
|
||||
bool rightCloser = IntersectAABB(FlatBVH,
|
||||
currentNode,
|
||||
originDir,
|
||||
invDir,
|
||||
closestDistance,
|
||||
hitLeftChild,
|
||||
hitRightChild,
|
||||
minDistance);
|
||||
|
||||
if (!hitLeftChild && !hitRightChild)
|
||||
{
|
||||
currentNode = todo[stackptr];
|
||||
stackptr--;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::Vec<vtkm::Float32, 4> children =
|
||||
FlatBVH.Get(currentNode + 3); //Children.Get(currentNode);
|
||||
vtkm::Int32 leftChild;
|
||||
memcpy(&leftChild, &children[0], 4);
|
||||
vtkm::Int32 rightChild;
|
||||
memcpy(&rightChild, &children[1], 4);
|
||||
currentNode = (hitLeftChild) ? leftChild : rightChild;
|
||||
if (hitLeftChild && hitRightChild)
|
||||
{
|
||||
if (rightCloser)
|
||||
{
|
||||
currentNode = rightChild;
|
||||
stackptr++;
|
||||
todo[stackptr] = leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
stackptr++;
|
||||
todo[stackptr] = rightChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if inner node
|
||||
|
||||
if (currentNode < 0 && currentNode != barrier) //check register usage
|
||||
{
|
||||
currentNode = -currentNode - 1; //swap the neg address
|
||||
LeafIntersector.IntersectLeaf(currentNode,
|
||||
origin,
|
||||
dir,
|
||||
points,
|
||||
hitIndex,
|
||||
closestDistance,
|
||||
minU,
|
||||
minV,
|
||||
Leafs,
|
||||
minDistance);
|
||||
currentNode = todo[stackptr];
|
||||
stackptr--;
|
||||
} // if leaf node
|
||||
|
||||
} //while
|
||||
|
||||
if (hitIndex != -1)
|
||||
distance = closestDistance;
|
||||
} // ()
|
||||
};
|
||||
|
||||
|
||||
template <typename Precision, typename Device>
|
||||
VTKM_CONT void IntersectRays(Ray<Precision>& rays,
|
||||
LinearBVH& bvh,
|
||||
LeafIntersectorType<Device> leafIntersector,
|
||||
vtkm::cont::CoordinateSystem& coordsHandle,
|
||||
Device vtkmNotUsed(Device))
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<Intersector<Device>> intersectDispatch(
|
||||
Intersector<Device>(false, bvh, leafIntersector));
|
||||
intersectDispatch.SetDevice(Device());
|
||||
intersectDispatch.Invoke(rays.Dir,
|
||||
rays.Origin,
|
||||
rays.Distance,
|
||||
rays.MinDistance,
|
||||
rays.MaxDistance,
|
||||
rays.U,
|
||||
rays.V,
|
||||
rays.HitIdx,
|
||||
coordsHandle);
|
||||
}
|
||||
}; // BVHTraverser
|
||||
#undef END_FLAG
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_BVHTraverser_h
|
326
vtkm/rendering/raytracing/CylinderExtractor.cxx
Normal file
326
vtkm/rendering/raytracing/CylinderExtractor.cxx
Normal file
@ -0,0 +1,326 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/raytracing/CylinderExtractor.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/Cylinderizer.h>
|
||||
#include <vtkm/rendering/raytracing/Worklets.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class CountSegments : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountSegments() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldOut<>);
|
||||
typedef void ExecutionSignature(CellShape, _2);
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagGeneric shapeType, vtkm::Id& segments) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_LINE)
|
||||
segments = 1;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_TRIANGLE)
|
||||
segments = 3;
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
segments = 4;
|
||||
else
|
||||
segments = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType), vtkm::Id& points) const
|
||||
{
|
||||
points = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagQuad vtkmNotUsed(shapeType), vtkm::Id& points) const
|
||||
{
|
||||
points = 0;
|
||||
}
|
||||
|
||||
}; // ClassCountSegments
|
||||
|
||||
class Pointify : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Pointify() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInCell<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(_2, CellShape, PointIndices, WorkIndex, _3);
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
|
||||
vtkm::CellShapeTagQuad vtkmNotUsed(shapeType),
|
||||
const VecType& vtkmNotUsed(cellIndices),
|
||||
const vtkm::Id& vtkmNotUsed(cellId),
|
||||
OutputPortal& vtkmNotUsed(outputIndices)) const
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
|
||||
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),
|
||||
const VecType& vtkmNotUsed(cellIndices),
|
||||
const vtkm::Id& vtkmNotUsed(cellId),
|
||||
OutputPortal& vtkmNotUsed(outputIndices)) const
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagGeneric shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_LINE)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(pointOffset, segment);
|
||||
|
||||
//outputIndices.Set(pointOffset, cellId);
|
||||
//outputId2.Set(pointOffset, vtkm::Id2(cellId, cellId));
|
||||
}
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_TRIANGLE)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(pointOffset, segment);
|
||||
|
||||
segment[1] = cellIndices[1];
|
||||
segment[2] = cellIndices[2];
|
||||
outputIndices.Set(pointOffset + 1, segment);
|
||||
|
||||
segment[1] = cellIndices[2];
|
||||
segment[2] = cellIndices[0];
|
||||
outputIndices.Set(pointOffset + 2, segment);
|
||||
}
|
||||
else if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
vtkm::Id3 segment;
|
||||
segment[0] = cellId;
|
||||
segment[1] = cellIndices[0];
|
||||
segment[2] = cellIndices[1];
|
||||
outputIndices.Set(pointOffset, segment);
|
||||
|
||||
segment[1] = cellIndices[1];
|
||||
segment[2] = cellIndices[2];
|
||||
outputIndices.Set(pointOffset + 1, segment);
|
||||
|
||||
segment[1] = cellIndices[2];
|
||||
segment[2] = cellIndices[3];
|
||||
outputIndices.Set(pointOffset + 2, segment);
|
||||
|
||||
segment[1] = cellIndices[3];
|
||||
segment[2] = cellIndices[0];
|
||||
outputIndices.Set(pointOffset + 3, segment);
|
||||
}
|
||||
}
|
||||
}; //class pointify
|
||||
|
||||
class Iterator : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Iterator() {}
|
||||
typedef void ControlSignature(FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, WorkIndex);
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::Id2& index, const vtkm::Id2& idx) const { index = idx; }
|
||||
}; //class Iterator
|
||||
|
||||
class FieldRadius : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
protected:
|
||||
vtkm::Float32 MinRadius;
|
||||
vtkm::Float32 RadiusDelta;
|
||||
vtkm::Float32 MinValue;
|
||||
vtkm::Float32 InverseDelta;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
FieldRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::Range scalarRange)
|
||||
: MinRadius(minRadius)
|
||||
, RadiusDelta(maxRadius - minRadius)
|
||||
, MinValue(static_cast<vtkm::Float32>(scalarRange.Min))
|
||||
{
|
||||
vtkm::Float32 delta = static_cast<vtkm::Float32>(scalarRange.Max - scalarRange.Min);
|
||||
if (delta != 0.f)
|
||||
InverseDelta = 1.f / (delta);
|
||||
else
|
||||
InverseDelta = 0.f; // just map scalar to 0;
|
||||
}
|
||||
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>, WholeArrayIn<Scalar>);
|
||||
typedef void ExecutionSignature(_1, _2, _3);
|
||||
|
||||
template <typename ScalarPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id3& cylId,
|
||||
vtkm::Float32& radius,
|
||||
const ScalarPortalType& scalars) const
|
||||
{
|
||||
vtkm::Float32 scalar = static_cast<vtkm::Float32>(scalars.Get(cylId[0]));
|
||||
vtkm::Float32 t = (scalar - MinValue) * InverseDelta;
|
||||
radius = MinRadius + t * RadiusDelta;
|
||||
}
|
||||
|
||||
}; //class FieldRadius
|
||||
|
||||
} //namespace detail
|
||||
|
||||
//void CylinderExtractor::ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords,
|
||||
// const vtkm::Float32 radius)
|
||||
//{
|
||||
// this->SetPointIdsFromCoords(coords);
|
||||
// this->SetUniformRadius(radius);
|
||||
//}
|
||||
|
||||
//TODO: I don't think I need varying radius
|
||||
//void CylinderExtractor::ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords,
|
||||
// const vtkm::cont::Field& field,
|
||||
// const vtkm::Float32 minRadius,
|
||||
// const vtkm::Float32 maxRadius)
|
||||
//{
|
||||
// this->SetPointIdsFromCoords(coords);
|
||||
// this->SetVaryingRadius(minRadius, maxRadius, field);
|
||||
//}
|
||||
|
||||
void CylinderExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
|
||||
const vtkm::Float32 radius)
|
||||
{
|
||||
vtkm::Id numOfSegments;
|
||||
vtkm::rendering::Cylinderizer geometrizer;
|
||||
geometrizer.Run(cells, this->CylIds, numOfSegments);
|
||||
|
||||
//this->SetCylinderIdsFromCells(cells);
|
||||
this->SetUniformRadius(radius);
|
||||
}
|
||||
|
||||
void CylinderExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
|
||||
const vtkm::cont::Field& field,
|
||||
const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius)
|
||||
{
|
||||
vtkm::Id numOfSegments;
|
||||
vtkm::rendering::Cylinderizer geometrizer;
|
||||
geometrizer.Run(cells, this->CylIds, numOfSegments);
|
||||
|
||||
//this->SetCylinderIdsFromCells(cells);
|
||||
this->SetVaryingRadius(minRadius, maxRadius, field);
|
||||
}
|
||||
|
||||
void CylinderExtractor::SetUniformRadius(const vtkm::Float32 radius)
|
||||
{
|
||||
const vtkm::Id size = this->CylIds.GetNumberOfValues();
|
||||
Radii.Allocate(size);
|
||||
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Float32> radiusHandle(radius, size);
|
||||
vtkm::cont::Algorithm::Copy(radiusHandle, Radii);
|
||||
}
|
||||
|
||||
void CylinderExtractor::SetCylinderIdsFromCells(const vtkm::cont::DynamicCellSet& cells)
|
||||
{
|
||||
vtkm::Id numCells = cells.GetNumberOfCells();
|
||||
if (numCells == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//
|
||||
// look for points in the cell set
|
||||
//
|
||||
if (cells.IsSameType(vtkm::cont::CellSetExplicit<>()))
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> points;
|
||||
vtkm::worklet::DispatcherMapTopology<detail::CountSegments>(detail::CountSegments())
|
||||
.Invoke(cells, points);
|
||||
|
||||
vtkm::Id totalPoints = 0;
|
||||
totalPoints = vtkm::cont::Algorithm::Reduce(points, vtkm::Id(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
vtkm::cont::Algorithm::ScanExclusive(points, cellOffsets);
|
||||
CylIds.Allocate(totalPoints);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<detail::Pointify>(detail::Pointify())
|
||||
.Invoke(cells, cellOffsets, this->CylIds);
|
||||
}
|
||||
}
|
||||
|
||||
void CylinderExtractor::SetVaryingRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::cont::Field& field)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray = field.GetRange();
|
||||
if (rangeArray.GetNumberOfValues() != 1)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Cylinder Extractor: scalar field must have one component");
|
||||
}
|
||||
|
||||
vtkm::Range range = rangeArray.GetPortalConstControl().Get(0);
|
||||
|
||||
Radii.Allocate(this->CylIds.GetNumberOfValues());
|
||||
vtkm::worklet::DispatcherMapField<detail::FieldRadius>(
|
||||
detail::FieldRadius(minRadius, maxRadius, range))
|
||||
.Invoke(this->CylIds, this->Radii, field);
|
||||
}
|
||||
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> CylinderExtractor::GetCylIds()
|
||||
{
|
||||
return this->CylIds;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> CylinderExtractor::GetRadii()
|
||||
{
|
||||
return this->Radii;
|
||||
}
|
||||
|
||||
vtkm::Id CylinderExtractor::GetNumberOfCylinders() const
|
||||
{
|
||||
return this->CylIds.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
84
vtkm/rendering/raytracing/CylinderExtractor.h
Normal file
84
vtkm/rendering/raytracing/CylinderExtractor.h
Normal file
@ -0,0 +1,84 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Cylinder_Extractor_h
|
||||
#define vtk_m_rendering_raytracing_Cylinder_Extractor_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class CylinderExtractor
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> CylIds;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> Radii;
|
||||
|
||||
public:
|
||||
//
|
||||
// Extract all nodes using a constant radius
|
||||
//
|
||||
// void ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords, const vtkm::Float32 radius);
|
||||
|
||||
// //
|
||||
// // Set radius based on scalar field values. Each is interpolated from min to max
|
||||
// //
|
||||
// void ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords,
|
||||
// const vtkm::cont::Field& field,
|
||||
// const vtkm::Float32 minRadius,
|
||||
// const vtkm::Float32 maxRadius);
|
||||
|
||||
//
|
||||
// Extract all vertex shapes with constant radius
|
||||
//
|
||||
void ExtractCells(const vtkm::cont::DynamicCellSet& cells, vtkm::Float32 radius);
|
||||
|
||||
//
|
||||
// Extract all vertex elements with radius based on scalar values
|
||||
//
|
||||
void ExtractCells(const vtkm::cont::DynamicCellSet& cells,
|
||||
const vtkm::cont::Field& field,
|
||||
const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius);
|
||||
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> GetCylIds();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> GetRadii();
|
||||
vtkm::Id GetNumberOfCylinders() const;
|
||||
|
||||
protected:
|
||||
void SetUniformRadius(const vtkm::Float32 radius);
|
||||
void SetVaryingRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::cont::Field& field);
|
||||
|
||||
// void SetPointIdsFromCoords(const vtkm::cont::CoordinateSystem& coords);
|
||||
void SetCylinderIdsFromCells(const vtkm::cont::DynamicCellSet& cells);
|
||||
|
||||
}; // class ShapeIntersector
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Shape_Extractor_h
|
378
vtkm/rendering/raytracing/CylinderIntersector.cxx
Normal file
378
vtkm/rendering/raytracing/CylinderIntersector.cxx
Normal file
@ -0,0 +1,378 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/raytracing/BVHTraverser.h>
|
||||
#include <vtkm/rendering/raytracing/CylinderIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Device>
|
||||
class CylinderLeafIntersector : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id3>;
|
||||
using IdArrayPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using FloatHandle = vtkm::cont::ArrayHandle<vtkm::Float32>;
|
||||
using FloatPortal = typename FloatHandle::ExecutionTypes<Device>::PortalConst;
|
||||
IdArrayPortal CylIds;
|
||||
FloatPortal Radii;
|
||||
|
||||
CylinderLeafIntersector(const IdHandle& cylIds, const FloatHandle& radii)
|
||||
: CylIds(cylIds.PrepareForInput(Device()))
|
||||
, Radii(radii.PrepareForInput(Device()))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename vec3>
|
||||
VTKM_EXEC vec3 cylinder(const vec3& ray_start,
|
||||
const vec3& ray_direction,
|
||||
const vec3& p,
|
||||
const vec3& q,
|
||||
float r) const
|
||||
{
|
||||
float t = 0;
|
||||
vec3 d = q - p;
|
||||
vec3 m = ray_start - p;
|
||||
|
||||
vec3 s = ray_start - q;
|
||||
|
||||
vtkm::Float32 mdotm = vtkm::Float32(vtkm::dot(m, m));
|
||||
vec3 n = ray_direction * (vtkm::Max(mdotm, static_cast<vtkm::Float32>(vtkm::dot(s, s))) + r);
|
||||
|
||||
vtkm::Float32 mdotd = vtkm::Float32(vtkm::dot(m, d));
|
||||
vtkm::Float32 ndotd = vtkm::Float32(vtkm::dot(n, d));
|
||||
vtkm::Float32 ddotd = vtkm::Float32(vtkm::dot(d, d));
|
||||
if ((mdotd < 0.0f) && (mdotd + ndotd < 0.0f))
|
||||
{
|
||||
return vec3(0.f, 0.f, 0.f);
|
||||
}
|
||||
if ((mdotd > ddotd) && (mdotd + ndotd > ddotd))
|
||||
{
|
||||
return vec3(0.f, 0.f, 0.f);
|
||||
}
|
||||
vtkm::Float32 ndotn = vtkm::Float32(vtkm::dot(n, n));
|
||||
vtkm::Float32 nlen = vtkm::Float32(sqrt(ndotn));
|
||||
vtkm::Float32 mdotn = vtkm::Float32(vtkm::dot(m, n));
|
||||
vtkm::Float32 a = ddotd * ndotn - ndotd * ndotd;
|
||||
vtkm::Float32 k = mdotm - r * r;
|
||||
vtkm::Float32 c = ddotd * k - mdotd * mdotd;
|
||||
|
||||
if (fabs(a) < 1e-6)
|
||||
{
|
||||
if (c > 0.0)
|
||||
{
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
if (mdotd < 0.0f)
|
||||
{
|
||||
t = -mdotn / ndotn;
|
||||
}
|
||||
else if (mdotd > ddotd)
|
||||
{
|
||||
t = (ndotd - mdotn) / ndotn;
|
||||
}
|
||||
else
|
||||
t = 0;
|
||||
|
||||
return vec3(1, t * nlen, 0);
|
||||
}
|
||||
vtkm::Float32 b = ddotd * mdotn - ndotd * mdotd;
|
||||
vtkm::Float32 discr = b * b - a * c;
|
||||
if (discr < 0.0f)
|
||||
{
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
t = (-b - vtkm::Sqrt(discr)) / a;
|
||||
if (t < 0.0f || t > 1.0f)
|
||||
{
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
vtkm::Float32 u = mdotd + t * ndotd;
|
||||
|
||||
if (u > ddotd)
|
||||
{
|
||||
if (ndotd >= 0.0f)
|
||||
{
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
t = (ddotd - mdotd) / ndotd;
|
||||
|
||||
return vec3(
|
||||
k + ddotd - 2 * mdotd + t * (2 * (mdotn - ndotd) + t * ndotn) <= 0.0f, t * nlen, 0);
|
||||
}
|
||||
else if (u < 0.0f)
|
||||
{
|
||||
if (ndotd <= 0.0f)
|
||||
{
|
||||
return vec3(0.0, 0.0, 0);
|
||||
}
|
||||
t = -mdotd / ndotd;
|
||||
|
||||
return vec3(k + 2 * t * (mdotn + t * ndotn) <= 0.0f, t * nlen, 0);
|
||||
}
|
||||
return vec3(1, t * nlen, 0);
|
||||
}
|
||||
|
||||
template <typename PointPortalType, typename LeafPortalType, typename Precision>
|
||||
VTKM_EXEC inline void IntersectLeaf(
|
||||
const vtkm::Int32& currentNode,
|
||||
const vtkm::Vec<Precision, 3>& origin,
|
||||
const vtkm::Vec<Precision, 3>& dir,
|
||||
const PointPortalType& points,
|
||||
vtkm::Id& hitIndex,
|
||||
Precision& closestDistance, // closest distance in this set of primitives
|
||||
Precision& vtkmNotUsed(minU),
|
||||
Precision& vtkmNotUsed(minV),
|
||||
LeafPortalType leafs,
|
||||
const Precision& minDistance) const // report intesections past this distance
|
||||
{
|
||||
const vtkm::Id cylCount = leafs.Get(currentNode);
|
||||
for (vtkm::Id i = 1; i <= cylCount; ++i)
|
||||
{
|
||||
const vtkm::Id cylIndex = leafs.Get(currentNode + i);
|
||||
if (cylIndex < CylIds.GetNumberOfValues())
|
||||
{
|
||||
vtkm::Id3 pointIndex = CylIds.Get(cylIndex);
|
||||
vtkm::Float32 radius = Radii.Get(cylIndex);
|
||||
vtkm::Vec<Precision, 3> bottom, top;
|
||||
bottom = vtkm::Vec<Precision, 3>(points.Get(pointIndex[1]));
|
||||
top = vtkm::Vec<Precision, 3>(points.Get(pointIndex[2]));
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 3> ret;
|
||||
ret = cylinder(origin, dir, bottom, top, radius);
|
||||
if (ret[0] > 0)
|
||||
{
|
||||
if (ret[1] < closestDistance && ret[1] > minDistance)
|
||||
{
|
||||
//matid = vtkm::Vec<, 3>(points.Get(cur_offset + 2))[0];
|
||||
closestDistance = ret[1];
|
||||
hitIndex = cylIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for
|
||||
}
|
||||
};
|
||||
|
||||
struct IntersectFunctor
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
CylinderIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRaysImp(Device(), rays, returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CalculateNormals : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CalculateNormals() {}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7);
|
||||
template <typename Precision, typename PointPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& hitIndex,
|
||||
const vtkm::Vec<Precision, 3>& intersection,
|
||||
Precision& normalX,
|
||||
Precision& normalY,
|
||||
Precision& normalZ,
|
||||
const PointPortalType& points,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Id3 cylId = indicesPortal.Get(hitIndex);
|
||||
|
||||
vtkm::Vec<Precision, 3> a, b;
|
||||
a = points.Get(cylId[1]);
|
||||
b = points.Get(cylId[2]);
|
||||
|
||||
vtkm::Vec<Precision, 3> ap, ab;
|
||||
ap = intersection - a;
|
||||
ab = b - a;
|
||||
|
||||
Precision mag2 = vtkm::Magnitude(ab);
|
||||
Precision len = vtkm::dot(ab, ap);
|
||||
Precision t = len / mag2;
|
||||
|
||||
vtkm::Vec<Precision, 3> center;
|
||||
center = a + t * ab;
|
||||
|
||||
vtkm::Vec<Precision, 3> normal = intersection - center;
|
||||
vtkm::Normalize(normal);
|
||||
|
||||
//flip the normal if its pointing the wrong way
|
||||
normalX = normal[0];
|
||||
normalY = normal[1];
|
||||
normalZ = normal[2];
|
||||
}
|
||||
}; //class CalculateNormals
|
||||
|
||||
template <typename Precision>
|
||||
class GetScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
GetScalar(const vtkm::Float32& minScalar, const vtkm::Float32& maxScalar)
|
||||
: MinScalar(minScalar)
|
||||
{
|
||||
//Make sure the we don't divide by zero on
|
||||
//something like an iso-surface
|
||||
if (maxScalar - MinScalar != 0.f)
|
||||
invDeltaScalar = 1.f / (maxScalar - MinScalar);
|
||||
else
|
||||
invDeltaScalar = 1.f / minScalar;
|
||||
}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldInOut<>,
|
||||
WholeArrayIn<ScalarRenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4);
|
||||
template <typename ScalarPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
||||
Precision& scalar,
|
||||
const ScalarPortalType& scalars,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
//TODO: this should be interpolated?
|
||||
vtkm::Id3 pointId = indicesPortal.Get(hitIndex);
|
||||
|
||||
scalar = Precision(scalars.Get(pointId[0]));
|
||||
//normalize
|
||||
scalar = (scalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class GetScalar
|
||||
|
||||
} // namespace detail
|
||||
|
||||
CylinderIntersector::CylinderIntersector()
|
||||
: ShapeIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
CylinderIntersector::~CylinderIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CylinderIntersector::IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
void CylinderIntersector::IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void CylinderIntersector::IntersectRaysImp(Device,
|
||||
Ray<Precision>& rays,
|
||||
bool vtkmNotUsed(returnCellIndex))
|
||||
{
|
||||
|
||||
detail::CylinderLeafIntersector<Device> leafIntersector(this->CylIds, Radii);
|
||||
|
||||
BVHTraverser<detail::CylinderLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
void CylinderIntersector::IntersectionDataImp(Ray<Precision>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
ShapeIntersector::IntersectionPoint(rays);
|
||||
|
||||
// TODO: if this is nodes of a mesh, support points
|
||||
bool isSupportedField =
|
||||
(scalarField->GetAssociation() == vtkm::cont::Field::Association::POINTS ||
|
||||
scalarField->GetAssociation() == vtkm::cont::Field::Association::CELL_SET);
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Field not accociated with a cell set");
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::CalculateNormals>(detail::CalculateNormals())
|
||||
.Invoke(rays.HitIdx,
|
||||
rays.Intersection,
|
||||
rays.NormalX,
|
||||
rays.NormalY,
|
||||
rays.NormalZ,
|
||||
CoordsHandle,
|
||||
CylIds);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::GetScalar<Precision>>(
|
||||
detail::GetScalar<Precision>(vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)))
|
||||
.Invoke(rays.HitIdx, rays.Scalar, *scalarField, CylIds);
|
||||
}
|
||||
|
||||
void CylinderIntersector::IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
void CylinderIntersector::IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
vtkm::Id CylinderIntersector::GetNumberOfShapes() const
|
||||
{
|
||||
return CylIds.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
325
vtkm/rendering/raytracing/MeshConnectivityBase.h
Normal file
325
vtkm/rendering/raytracing/MeshConnectivityBase.h
Normal file
@ -0,0 +1,325 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_MeshConnectivityBase
|
||||
#define vtk_m_rendering_raytracing_MeshConnectivityBase
|
||||
|
||||
#include <sstream>
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/VirtualObjectBase.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/VirtualObjectHandle.h>
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
#include <vtkm/rendering/raytracing/CellTables.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class VTKM_ALWAYS_EXPORT MeshConnectivityBase : public VirtualObjectBase
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
virtual vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const = 0;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
virtual vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const = 0;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
virtual vtkm::UInt8 GetCellShape(const vtkm::Id& cellId) const = 0;
|
||||
};
|
||||
|
||||
class VTKM_ALWAYS_EXPORT MeshConnStructured : public MeshConnectivityBase
|
||||
{
|
||||
protected:
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
|
||||
vtkm::Id3 CellDims;
|
||||
vtkm::Id3 PointDims;
|
||||
|
||||
VTKM_CONT MeshConnStructured() = default;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MeshConnStructured(const vtkm::Id3& cellDims, const vtkm::Id3& pointDims)
|
||||
: CellDims(cellDims)
|
||||
, PointDims(pointDims)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const override
|
||||
{
|
||||
//TODO: there is probably a better way to do this.
|
||||
vtkm::Id3 logicalCellId;
|
||||
logicalCellId[0] = cellId % CellDims[0];
|
||||
logicalCellId[1] = (cellId / CellDims[0]) % CellDims[1];
|
||||
logicalCellId[2] = cellId / (CellDims[0] * CellDims[1]);
|
||||
if (face == 0)
|
||||
logicalCellId[1] -= 1;
|
||||
if (face == 2)
|
||||
logicalCellId[1] += 1;
|
||||
if (face == 1)
|
||||
logicalCellId[0] += 1;
|
||||
if (face == 3)
|
||||
logicalCellId[0] -= 1;
|
||||
if (face == 4)
|
||||
logicalCellId[2] -= 1;
|
||||
if (face == 5)
|
||||
logicalCellId[2] += 1;
|
||||
vtkm::Id nextCell =
|
||||
(logicalCellId[2] * CellDims[1] + logicalCellId[1]) * CellDims[0] + logicalCellId[0];
|
||||
bool validCell = true;
|
||||
if (logicalCellId[0] >= CellDims[0])
|
||||
validCell = false;
|
||||
if (logicalCellId[1] >= CellDims[1])
|
||||
validCell = false;
|
||||
if (logicalCellId[2] >= CellDims[2])
|
||||
validCell = false;
|
||||
vtkm::Id minId = vtkm::Min(logicalCellId[0], vtkm::Min(logicalCellId[1], logicalCellId[2]));
|
||||
if (minId < 0)
|
||||
validCell = false;
|
||||
if (!validCell)
|
||||
nextCell = -1;
|
||||
return nextCell;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellIndex) const override
|
||||
{
|
||||
vtkm::Id3 cellId;
|
||||
cellId[0] = cellIndex % CellDims[0];
|
||||
cellId[1] = (cellIndex / CellDims[0]) % CellDims[1];
|
||||
cellId[2] = cellIndex / (CellDims[0] * CellDims[1]);
|
||||
cellIndices[0] = (cellId[2] * PointDims[1] + cellId[1]) * PointDims[0] + cellId[0];
|
||||
cellIndices[1] = cellIndices[0] + 1;
|
||||
cellIndices[2] = cellIndices[1] + PointDims[0];
|
||||
cellIndices[3] = cellIndices[2] - 1;
|
||||
cellIndices[4] = cellIndices[0] + PointDims[0] * PointDims[1];
|
||||
cellIndices[5] = cellIndices[4] + 1;
|
||||
cellIndices[6] = cellIndices[5] + PointDims[0];
|
||||
cellIndices[7] = cellIndices[6] - 1;
|
||||
return 8;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
vtkm::UInt8 GetCellShape(const vtkm::Id& vtkmNotUsed(cellId)) const override
|
||||
{
|
||||
return vtkm::UInt8(CELL_SHAPE_HEXAHEDRON);
|
||||
}
|
||||
}; // MeshConnStructured
|
||||
|
||||
template <typename Device>
|
||||
class VTKM_ALWAYS_EXPORT MeshConnUnstructured : public MeshConnectivityBase
|
||||
{
|
||||
protected:
|
||||
using IdHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using UCharHandle = typename vtkm::cont::ArrayHandle<vtkm::UInt8>;
|
||||
using IdConstPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using UCharConstPortal = typename UCharHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
// Constant Portals for the execution Environment
|
||||
//FaceConn
|
||||
IdConstPortal FaceConnPortal;
|
||||
IdConstPortal FaceOffsetsPortal;
|
||||
//Cell Set
|
||||
IdConstPortal CellConnPortal;
|
||||
IdConstPortal CellOffsetsPortal;
|
||||
UCharConstPortal ShapesPortal;
|
||||
|
||||
VTKM_CONT MeshConnUnstructured() = default;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MeshConnUnstructured(const IdHandle& faceConnectivity,
|
||||
const IdHandle& faceOffsets,
|
||||
const IdHandle& cellConn,
|
||||
const IdHandle& cellOffsets,
|
||||
const UCharHandle& shapes)
|
||||
: FaceConnPortal(faceConnectivity.PrepareForInput(Device()))
|
||||
, FaceOffsetsPortal(faceOffsets.PrepareForInput(Device()))
|
||||
, CellConnPortal(cellConn.PrepareForInput(Device()))
|
||||
, CellOffsetsPortal(cellOffsets.PrepareForInput(Device()))
|
||||
, ShapesPortal(shapes.PrepareForInput(Device()))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const override
|
||||
{
|
||||
BOUNDS_CHECK(FaceOffsetsPortal, cellId);
|
||||
vtkm::Id cellStartIndex = FaceOffsetsPortal.Get(cellId);
|
||||
BOUNDS_CHECK(FaceConnPortal, cellStartIndex + face);
|
||||
return FaceConnPortal.Get(cellStartIndex + face);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const override
|
||||
{
|
||||
const vtkm::Int32 shapeId = static_cast<vtkm::Int32>(ShapesPortal.Get(cellId));
|
||||
CellTables tables;
|
||||
const vtkm::Int32 numIndices = tables.FaceLookUp(tables.CellTypeLookUp(shapeId), 2);
|
||||
BOUNDS_CHECK(CellOffsetsPortal, cellId);
|
||||
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
|
||||
|
||||
for (vtkm::Int32 i = 0; i < numIndices; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(CellConnPortal, cellOffset + i);
|
||||
cellIndices[i] = CellConnPortal.Get(cellOffset + i);
|
||||
}
|
||||
return numIndices;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
vtkm::UInt8 GetCellShape(const vtkm::Id& cellId) const override
|
||||
{
|
||||
BOUNDS_CHECK(ShapesPortal, cellId)
|
||||
return ShapesPortal.Get(cellId);
|
||||
}
|
||||
|
||||
}; // MeshConnUnstructured
|
||||
|
||||
template <typename Device>
|
||||
class MeshConnSingleType : public MeshConnectivityBase
|
||||
{
|
||||
protected:
|
||||
using IdHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using IdConstPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
using CountingHandle = typename vtkm::cont::ArrayHandleCounting<vtkm::Id>;
|
||||
using CountingPortal = typename CountingHandle::ExecutionTypes<Device>::PortalConst;
|
||||
// Constant Portals for the execution Environment
|
||||
IdConstPortal FaceConnPortal;
|
||||
IdConstPortal CellConnectivityPortal;
|
||||
CountingPortal CellOffsetsPortal;
|
||||
|
||||
vtkm::Int32 ShapeId;
|
||||
vtkm::Int32 NumIndices;
|
||||
vtkm::Int32 NumFaces;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
MeshConnSingleType() {}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MeshConnSingleType(IdHandle& faceConn,
|
||||
IdHandle& cellConn,
|
||||
CountingHandle& cellOffsets,
|
||||
vtkm::Int32 shapeId,
|
||||
vtkm::Int32 numIndices,
|
||||
vtkm::Int32 numFaces)
|
||||
: FaceConnPortal(faceConn.PrepareForInput(Device()))
|
||||
, CellConnectivityPortal(cellConn.PrepareForInput(Device()))
|
||||
, CellOffsetsPortal(cellOffsets.PrepareForInput(Device()))
|
||||
, ShapeId(shapeId)
|
||||
, NumIndices(numIndices)
|
||||
, NumFaces(numFaces)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Execution Environment Methods
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const override
|
||||
{
|
||||
BOUNDS_CHECK(CellOffsetsPortal, cellId);
|
||||
vtkm::Id cellStartIndex = cellId * NumFaces;
|
||||
BOUNDS_CHECK(FaceConnPortal, cellStartIndex + face);
|
||||
return FaceConnPortal.Get(cellStartIndex + face);
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const override
|
||||
{
|
||||
BOUNDS_CHECK(CellOffsetsPortal, cellId);
|
||||
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
|
||||
|
||||
for (vtkm::Int32 i = 0; i < NumIndices; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(CellConnectivityPortal, cellOffset + i);
|
||||
cellIndices[i] = CellConnectivityPortal.Get(cellOffset + i);
|
||||
}
|
||||
|
||||
return NumIndices;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
vtkm::UInt8 GetCellShape(const vtkm::Id& vtkmNotUsed(cellId)) const override
|
||||
{
|
||||
return vtkm::UInt8(ShapeId);
|
||||
}
|
||||
|
||||
}; //MeshConn Single type specialization
|
||||
|
||||
class VTKM_ALWAYS_EXPORT MeshConnHandle
|
||||
: public vtkm::cont::VirtualObjectHandle<MeshConnectivityBase>
|
||||
{
|
||||
private:
|
||||
using Superclass = vtkm::cont::VirtualObjectHandle<MeshConnectivityBase>;
|
||||
|
||||
public:
|
||||
MeshConnHandle() = default;
|
||||
|
||||
template <typename MeshConnType,
|
||||
typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
explicit MeshConnHandle(MeshConnType* meshConn,
|
||||
bool aquireOwnership = true,
|
||||
DeviceAdapterList devices = DeviceAdapterList())
|
||||
: Superclass(meshConn, aquireOwnership, devices)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MeshConnType, typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
VTKM_CONT MeshConnHandle make_MeshConnHandle(MeshConnType&& func,
|
||||
DeviceAdapterList devices = DeviceAdapterList())
|
||||
{
|
||||
using IFType = typename std::remove_reference<MeshConnType>::type;
|
||||
return MeshConnHandle(new IFType(std::forward<MeshConnType>(func)), true, devices);
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
|
||||
#ifdef VTKM_CUDA
|
||||
|
||||
// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer
|
||||
// to be instantiated in a consitent order among all the translation units of an
|
||||
// executable. Failing to do so results in random crashes and incorrect results.
|
||||
// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for
|
||||
// all the implicit functions here.
|
||||
|
||||
#include <vtkm/cont/cuda/internal/VirtualObjectTransferCuda.h>
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::rendering::raytracing::MeshConnStructured);
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
||||
vtkm::rendering::raytracing::MeshConnUnstructured<vtkm::cont::DeviceAdapterTagCuda>);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MeshConnectivityBase
|
285
vtkm/rendering/raytracing/MeshConnectivityContainers.cxx
Normal file
285
vtkm/rendering/raytracing/MeshConnectivityContainers.cxx
Normal file
@ -0,0 +1,285 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
#include <sstream>
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterListHelpers.h>
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBase.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityContainers.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
MeshConnContainer::MeshConnContainer(){};
|
||||
MeshConnContainer::~MeshConnContainer(){};
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT void MeshConnContainer::FindEntryImpl(Ray<T>& rays,
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
bool getCellIndex = true;
|
||||
|
||||
Intersector.SetUseWaterTight(true);
|
||||
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
Intersector.IntersectRays(rays, vtkm::cont::DeviceAdapterTagTBB(), getCellIndex);
|
||||
break;
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_CUDA
|
||||
case VTKM_DEVICE_ADAPTER_CUDA:
|
||||
Intersector.IntersectRays(rays, vtkm::cont::DeviceAdapterTagCuda(), getCellIndex);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Intersector.IntersectRays(rays, vtkm::cont::DeviceAdapterTagSerial(), getCellIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshConnContainer::FindEntry(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
this->FindEntryImpl(rays, deviceId);
|
||||
}
|
||||
|
||||
void MeshConnContainer::FindEntry(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
this->FindEntryImpl(rays, deviceId);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
UnstructuredContainer::UnstructuredContainer(const vtkm::cont::CellSetExplicit<>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
IdHandle& faceOffsets,
|
||||
Id4Handle& externalTriangles)
|
||||
: FaceConnectivity(faceConn)
|
||||
, FaceOffsets(faceOffsets)
|
||||
, Cellset(cellset)
|
||||
, Coords(coords)
|
||||
{
|
||||
this->ExternalTriangles = externalTriangles;
|
||||
//
|
||||
// Grab the cell arrays
|
||||
//
|
||||
CellConn =
|
||||
Cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
CellOffsets =
|
||||
Cellset.GetIndexOffsetArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
Shapes = Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
Intersector.SetData(Coords, ExternalTriangles);
|
||||
}
|
||||
|
||||
UnstructuredContainer::~UnstructuredContainer(){};
|
||||
|
||||
const MeshConnectivityBase* UnstructuredContainer::Construct(
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
using TBB = vtkm::cont::DeviceAdapterTagTBB;
|
||||
{
|
||||
MeshConnUnstructured<TBB> conn(this->FaceConnectivity,
|
||||
this->FaceOffsets,
|
||||
this->CellConn,
|
||||
this->CellOffsets,
|
||||
this->Shapes);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(TBB());
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_CUDA
|
||||
case VTKM_DEVICE_ADAPTER_CUDA:
|
||||
using CUDA = vtkm::cont::DeviceAdapterTagCuda;
|
||||
{
|
||||
MeshConnUnstructured<CUDA> conn(this->FaceConnectivity,
|
||||
this->FaceOffsets,
|
||||
this->CellConn,
|
||||
this->CellOffsets,
|
||||
this->Shapes);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(CUDA());
|
||||
#endif
|
||||
default:
|
||||
using SERIAL = vtkm::cont::DeviceAdapterTagSerial;
|
||||
{
|
||||
MeshConnUnstructured<SERIAL> conn(this->FaceConnectivity,
|
||||
this->FaceOffsets,
|
||||
this->CellConn,
|
||||
this->CellOffsets,
|
||||
this->Shapes);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(SERIAL());
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
UnstructuredSingleContainer::UnstructuredSingleContainer()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
UnstructuredSingleContainer::UnstructuredSingleContainer(
|
||||
const vtkm::cont::CellSetSingleType<>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
Id4Handle& externalTriangles)
|
||||
: FaceConnectivity(faceConn)
|
||||
, Coords(coords)
|
||||
, Cellset(cellset)
|
||||
{
|
||||
|
||||
this->ExternalTriangles = externalTriangles;
|
||||
|
||||
this->Intersector.SetUseWaterTight(true);
|
||||
|
||||
CellConnectivity =
|
||||
Cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
|
||||
Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
ShapeId = shapes.GetPortalConstControl().Get(0);
|
||||
CellTables tables;
|
||||
NumIndices = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 2);
|
||||
|
||||
if (NumIndices == 0)
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Unstructured Mesh Connecitity Single type Error: unsupported cell type: ";
|
||||
message << ShapeId;
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
vtkm::Id start = 0;
|
||||
NumFaces = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 1);
|
||||
vtkm::Id numCells = CellConnectivity.GetPortalConstControl().GetNumberOfValues();
|
||||
CellOffsets = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(start, NumIndices, numCells);
|
||||
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("mesh_conn_construction");
|
||||
vtkm::cont::Timer<cont::DeviceAdapterTagSerial> timer;
|
||||
|
||||
Intersector.SetData(Coords, ExternalTriangles);
|
||||
}
|
||||
|
||||
const MeshConnectivityBase* UnstructuredSingleContainer::Construct(
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
using TBB = vtkm::cont::DeviceAdapterTagTBB;
|
||||
{
|
||||
MeshConnSingleType<TBB> conn(this->FaceConnectivity,
|
||||
this->CellConnectivity,
|
||||
this->CellOffsets,
|
||||
this->ShapeId,
|
||||
this->NumIndices,
|
||||
this->NumFaces);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(TBB());
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_CUDA
|
||||
case VTKM_DEVICE_ADAPTER_CUDA:
|
||||
using CUDA = vtkm::cont::DeviceAdapterTagCuda;
|
||||
{
|
||||
MeshConnSingleType<CUDA> conn(this->FaceConnectivity,
|
||||
this->CellConnectivity,
|
||||
this->CellOffsets,
|
||||
this->ShapeId,
|
||||
this->NumIndices,
|
||||
this->NumFaces);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(CUDA());
|
||||
#endif
|
||||
default:
|
||||
using SERIAL = vtkm::cont::DeviceAdapterTagSerial;
|
||||
{
|
||||
MeshConnSingleType<SERIAL> conn(this->FaceConnectivity,
|
||||
this->CellConnectivity,
|
||||
this->CellOffsets,
|
||||
this->ShapeId,
|
||||
this->NumIndices,
|
||||
this->NumFaces);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(SERIAL());
|
||||
}
|
||||
}
|
||||
|
||||
StructuredContainer::StructuredContainer(const vtkm::cont::CellSetStructured<3>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
Id4Handle& externalTriangles)
|
||||
: Coords(coords)
|
||||
, Cellset(cellset)
|
||||
{
|
||||
|
||||
ExternalTriangles = externalTriangles;
|
||||
Intersector.SetUseWaterTight(true);
|
||||
|
||||
PointDims = Cellset.GetPointDimensions();
|
||||
CellDims = Cellset.GetCellDimensions();
|
||||
|
||||
this->Intersector.SetData(Coords, ExternalTriangles);
|
||||
}
|
||||
|
||||
const MeshConnectivityBase* StructuredContainer::Construct(
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
|
||||
MeshConnStructured conn(CellDims, PointDims);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagTBB());
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_CUDA
|
||||
case VTKM_DEVICE_ADAPTER_CUDA:
|
||||
return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagCuda());
|
||||
#endif
|
||||
default:
|
||||
return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagSerial());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
155
vtkm/rendering/raytracing/MeshConnectivityContainers.h
Normal file
155
vtkm/rendering/raytracing/MeshConnectivityContainers.h
Normal file
@ -0,0 +1,155 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_MeshConnectivityContainer_h
|
||||
#define vtk_m_rendering_raytracing_MeshConnectivityContainer_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBase.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class MeshConnContainer
|
||||
{
|
||||
public:
|
||||
MeshConnContainer();
|
||||
virtual ~MeshConnContainer();
|
||||
|
||||
virtual const MeshConnectivityBase* Construct(const vtkm::cont::DeviceAdapterId deviceId) = 0;
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT void FindEntryImpl(Ray<T>& rays, const vtkm::cont::DeviceAdapterId deviceId);
|
||||
|
||||
void FindEntry(Ray<vtkm::Float32>& rays, const vtkm::cont::DeviceAdapterId deviceId);
|
||||
|
||||
void FindEntry(Ray<vtkm::Float64>& rays, const vtkm::cont::DeviceAdapterId deviceId);
|
||||
|
||||
protected:
|
||||
using Id4Handle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
// Mesh Boundary
|
||||
Id4Handle ExternalTriangles;
|
||||
TriangleIntersector Intersector;
|
||||
MeshConnHandle Handle;
|
||||
};
|
||||
|
||||
class UnstructuredContainer : public MeshConnContainer
|
||||
{
|
||||
public:
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::UInt8> UCharHandle;
|
||||
// Control Environment Handles
|
||||
// FaceConn
|
||||
IdHandle FaceConnectivity;
|
||||
IdHandle FaceOffsets;
|
||||
//Cell Set
|
||||
IdHandle CellConn;
|
||||
IdHandle CellOffsets;
|
||||
UCharHandle Shapes;
|
||||
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
vtkm::cont::CellSetExplicit<> Cellset;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
UnstructuredContainer(){};
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
UnstructuredContainer(const vtkm::cont::CellSetExplicit<>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
IdHandle& faceOffsets,
|
||||
Id4Handle& externalTriangles);
|
||||
|
||||
virtual ~UnstructuredContainer();
|
||||
|
||||
const MeshConnectivityBase* Construct(const vtkm::cont::DeviceAdapterId deviceId);
|
||||
};
|
||||
|
||||
class StructuredContainer : public MeshConnContainer
|
||||
{
|
||||
protected:
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
|
||||
vtkm::Id3 CellDims;
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
vtkm::cont::CellSetStructured<3> Cellset;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
StructuredContainer() {}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
StructuredContainer(const vtkm::cont::CellSetStructured<3>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
Id4Handle& externalTriangles);
|
||||
|
||||
const MeshConnectivityBase* Construct(const vtkm::cont::DeviceAdapterId deviceId) override;
|
||||
|
||||
}; //structure mesh conn
|
||||
|
||||
class UnstructuredSingleContainer : public MeshConnContainer
|
||||
{
|
||||
public:
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
|
||||
typedef vtkm::cont::ArrayHandleCounting<vtkm::Id> CountingHandle;
|
||||
typedef vtkm::cont::ArrayHandleConstant<vtkm::UInt8> ShapesHandle;
|
||||
typedef vtkm::cont::ArrayHandleConstant<vtkm::IdComponent> NumIndicesHandle;
|
||||
// Control Environment Handles
|
||||
IdHandle FaceConnectivity;
|
||||
CountingHandle CellOffsets;
|
||||
IdHandle CellConnectivity;
|
||||
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
vtkm::cont::CellSetSingleType<> Cellset;
|
||||
|
||||
vtkm::Int32 ShapeId;
|
||||
vtkm::Int32 NumIndices;
|
||||
vtkm::Int32 NumFaces;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
UnstructuredSingleContainer();
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
UnstructuredSingleContainer(const vtkm::cont::CellSetSingleType<>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
Id4Handle& externalFaces);
|
||||
|
||||
const MeshConnectivityBase* Construct(const vtkm::cont::DeviceAdapterId deviceId) override;
|
||||
|
||||
}; //UnstructuredSingleContainer
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif
|
249
vtkm/rendering/raytracing/QuadExtractor.cxx
Normal file
249
vtkm/rendering/raytracing/QuadExtractor.cxx
Normal file
@ -0,0 +1,249 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/raytracing/QuadExtractor.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/Quadralizer.h>
|
||||
#include <vtkm/rendering/raytracing/Worklets.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class CountQuads : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountQuads() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldOut<>);
|
||||
typedef void ExecutionSignature(CellShape, _2);
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagGeneric shapeType, vtkm::Id& quads) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
quads = 1;
|
||||
else
|
||||
quads = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType), vtkm::Id& quads) const
|
||||
{
|
||||
quads = 6;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagQuad vtkmNotUsed(shapeType), vtkm::Id& points) const
|
||||
{
|
||||
points = 1;
|
||||
}
|
||||
|
||||
}; // ClassCountquads
|
||||
|
||||
class Pointify : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Pointify() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInCell<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(_2, CellShape, PointIndices, WorkIndex, _3);
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void cell2quad(vtkm::Id& offset,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
const vtkm::Id Id0,
|
||||
const vtkm::Id Id1,
|
||||
const vtkm::Id Id2,
|
||||
const vtkm::Id Id3,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 5> quad;
|
||||
quad[0] = cellId;
|
||||
quad[1] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id0)]);
|
||||
quad[2] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id1)]);
|
||||
quad[3] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id2)]);
|
||||
quad[4] = static_cast<vtkm::Id>(cellIndices[vtkm::IdComponent(Id3)]);
|
||||
outputIndices.Set(offset++, quad);
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
|
||||
vtkm::CellShapeTagQuad vtkmNotUsed(shapeType),
|
||||
const VecType& vtkmNotUsed(cellIndices),
|
||||
const vtkm::Id& vtkmNotUsed(cellId),
|
||||
OutputPortal& vtkmNotUsed(outputIndices)) const
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
|
||||
{
|
||||
vtkm::Id offset = pointOffset;
|
||||
cell2quad(offset, cellIndices, cellId, 0, 1, 5, 4, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 1, 2, 6, 5, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 3, 7, 6, 2, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 4, 7, 3, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 0, 3, 2, 1, outputIndices);
|
||||
cell2quad(offset, cellIndices, cellId, 4, 5, 6, 7, outputIndices);
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagGeneric shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 5> quad;
|
||||
quad[0] = cellId;
|
||||
quad[1] = cellIndices[0];
|
||||
quad[2] = cellIndices[1];
|
||||
quad[3] = cellIndices[2];
|
||||
quad[4] = cellIndices[3];
|
||||
outputIndices.Set(pointOffset, quad);
|
||||
}
|
||||
}
|
||||
}; //class pointify
|
||||
|
||||
class Iterator : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Iterator() {}
|
||||
typedef void ControlSignature(FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, WorkIndex);
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::Id2& index, const vtkm::Id2& idx) const { index = idx; }
|
||||
}; //class Iterator
|
||||
|
||||
class FieldRadius : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
protected:
|
||||
vtkm::Float32 MinRadius;
|
||||
vtkm::Float32 RadiusDelta;
|
||||
vtkm::Float32 MinValue;
|
||||
vtkm::Float32 InverseDelta;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
FieldRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::Range scalarRange)
|
||||
: MinRadius(minRadius)
|
||||
, RadiusDelta(maxRadius - minRadius)
|
||||
, MinValue(static_cast<vtkm::Float32>(scalarRange.Min))
|
||||
{
|
||||
vtkm::Float32 delta = static_cast<vtkm::Float32>(scalarRange.Max - scalarRange.Min);
|
||||
if (delta != 0.f)
|
||||
InverseDelta = 1.f / (delta);
|
||||
else
|
||||
InverseDelta = 0.f; // just map scalar to 0;
|
||||
}
|
||||
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>, WholeArrayIn<Scalar>);
|
||||
typedef void ExecutionSignature(_1, _2, _3);
|
||||
|
||||
template <typename ScalarPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointId,
|
||||
vtkm::Float32& radius,
|
||||
const ScalarPortalType& scalars) const
|
||||
{
|
||||
vtkm::Float32 scalar = static_cast<vtkm::Float32>(scalars.Get(pointId));
|
||||
vtkm::Float32 t = (scalar - MinValue) * InverseDelta;
|
||||
radius = MinRadius + t * RadiusDelta;
|
||||
}
|
||||
|
||||
}; //class FieldRadius
|
||||
|
||||
} //namespace detail
|
||||
|
||||
void QuadExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells)
|
||||
{
|
||||
vtkm::Id numOfQuads;
|
||||
vtkm::rendering::Quadralizer quadrizer;
|
||||
quadrizer.Run(cells, this->QuadIds, numOfQuads);
|
||||
|
||||
//this->SetPointIdsFromCells(cells);
|
||||
}
|
||||
|
||||
|
||||
void QuadExtractor::SetQuadIdsFromCells(const vtkm::cont::DynamicCellSet& cells)
|
||||
{
|
||||
vtkm::Id numCells = cells.GetNumberOfCells();
|
||||
if (numCells == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//
|
||||
// look for points in the cell set
|
||||
//
|
||||
if (cells.IsSameType(vtkm::cont::CellSetExplicit<>()))
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> points;
|
||||
vtkm::worklet::DispatcherMapTopology<detail::CountQuads>(detail::CountQuads())
|
||||
.Invoke(cells, points);
|
||||
|
||||
vtkm::Id total = 0;
|
||||
total = vtkm::cont::Algorithm::Reduce(points, vtkm::Id(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
vtkm::cont::Algorithm::ScanExclusive(points, cellOffsets);
|
||||
QuadIds.Allocate(total);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<detail::Pointify>(detail::Pointify())
|
||||
.Invoke(cells, cellOffsets, this->QuadIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> QuadExtractor::GetQuadIds()
|
||||
{
|
||||
return this->QuadIds;
|
||||
}
|
||||
|
||||
|
||||
vtkm::Id QuadExtractor::GetNumberOfQuads() const
|
||||
{
|
||||
return this->QuadIds.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
52
vtkm/rendering/raytracing/QuadExtractor.h
Normal file
52
vtkm/rendering/raytracing/QuadExtractor.h
Normal file
@ -0,0 +1,52 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Quad_Extractor_h
|
||||
#define vtk_m_rendering_raytracing_Quad_Extractor_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class QuadExtractor
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> QuadIds;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> Radii;
|
||||
|
||||
public:
|
||||
void ExtractCells(const vtkm::cont::DynamicCellSet& cells);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> GetQuadIds();
|
||||
|
||||
vtkm::Id GetNumberOfQuads() const;
|
||||
|
||||
protected:
|
||||
void SetQuadIdsFromCells(const vtkm::cont::DynamicCellSet& cells);
|
||||
|
||||
}; // class ShapeIntersector
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Shape_Extractor_h
|
410
vtkm/rendering/raytracing/QuadIntersector.cxx
Normal file
410
vtkm/rendering/raytracing/QuadIntersector.cxx
Normal file
@ -0,0 +1,410 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/raytracing/BVHTraverser.h>
|
||||
#include <vtkm/rendering/raytracing/QuadIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Device>
|
||||
class QuadLeafIntersector : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
using IdType = vtkm::Vec<vtkm::Id, 5>;
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>>;
|
||||
using IdArrayPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using FloatHandle = vtkm::cont::ArrayHandle<vtkm::Float32>;
|
||||
using FloatPortal = typename FloatHandle::ExecutionTypes<Device>::PortalConst;
|
||||
IdArrayPortal QuadIds;
|
||||
|
||||
QuadLeafIntersector(const IdHandle& quadIds)
|
||||
: QuadIds(quadIds.PrepareForInput(Device()))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename vec3, typename Precision>
|
||||
VTKM_EXEC bool quad(const vec3& ray_origin,
|
||||
const vec3& ray_direction,
|
||||
const vec3& v00,
|
||||
const vec3& v10,
|
||||
const vec3& v11,
|
||||
const vec3& v01,
|
||||
Precision& u,
|
||||
Precision& v,
|
||||
Precision& t) const
|
||||
{
|
||||
|
||||
/* An Efficient Ray-Quadrilateral Intersection Test
|
||||
Ares Lagae Philip Dutr´e
|
||||
http://graphics.cs.kuleuven.be/publications/LD05ERQIT/index.html
|
||||
|
||||
v01 *------------ * v11
|
||||
|\ |
|
||||
| \ |
|
||||
| \ |
|
||||
| \ |
|
||||
| \ |
|
||||
| \ |
|
||||
v00 *------------* v10
|
||||
*/
|
||||
// Rejects rays that are parallel to Q, and rays that intersect the plane of
|
||||
// Q either on the left of the line V00V01 or on the right of the line V00V10.
|
||||
|
||||
vec3 E03 = v01 - v00;
|
||||
vec3 P = vtkm::Cross(ray_direction, E03);
|
||||
vec3 E01 = v10 - v00;
|
||||
Precision det = vtkm::dot(E01, P);
|
||||
|
||||
if (vtkm::Abs(det) < vtkm::Epsilon<Precision>())
|
||||
return false;
|
||||
Precision inv_det = 1.0f / det;
|
||||
vec3 T = ray_origin - v00;
|
||||
Precision alpha = vtkm::dot(T, P) * inv_det;
|
||||
if (alpha < 0.0)
|
||||
return false;
|
||||
vec3 Q = vtkm::Cross(T, E01);
|
||||
Precision beta = vtkm::dot(ray_direction, Q) * inv_det;
|
||||
if (beta < 0.0)
|
||||
return false;
|
||||
|
||||
if ((alpha + beta) > 1.0f)
|
||||
{
|
||||
|
||||
// Rejects rays that intersect the plane of Q either on the
|
||||
// left of the line V11V10 or on the right of the line V11V01.
|
||||
|
||||
vec3 E23 = v01 - v11;
|
||||
vec3 E21 = v10 - v11;
|
||||
vec3 P_prime = vtkm::Cross(ray_direction, E21);
|
||||
Precision det_prime = vtkm::dot(E23, P_prime);
|
||||
if (vtkm::Abs(det_prime) < vtkm::Epsilon<Precision>())
|
||||
return false;
|
||||
Precision inv_det_prime = 1.0f / det_prime;
|
||||
vec3 T_prime = ray_origin - v11;
|
||||
Precision alpha_prime = vtkm::dot(T_prime, P_prime) * inv_det_prime;
|
||||
if (alpha_prime < 0.0f)
|
||||
return false;
|
||||
vec3 Q_prime = vtkm::Cross(T_prime, E23);
|
||||
Precision beta_prime = vtkm::dot(ray_direction, Q_prime) * inv_det_prime;
|
||||
if (beta_prime < 0.0f)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute the ray parameter of the intersection point, and
|
||||
// reject the ray if it does not hit Q.
|
||||
|
||||
t = vtkm::dot(E03, Q) * inv_det;
|
||||
if (t < 0.0)
|
||||
return false;
|
||||
|
||||
|
||||
// Compute the barycentric coordinates of V11
|
||||
Precision alpha_11, beta_11;
|
||||
vec3 E02 = v11 - v00;
|
||||
vec3 n = vtkm::Cross(E01, E02);
|
||||
|
||||
if ((vtkm::Abs(n[0]) >= vtkm::Abs(n[1])) && (vtkm::Abs(n[0]) >= vtkm::Abs(n[2])))
|
||||
{
|
||||
|
||||
alpha_11 = ((E02[1] * E03[2]) - (E02[2] * E03[1])) / n[0];
|
||||
beta_11 = ((E01[1] * E02[2]) - (E01[2] * E02[1])) / n[0];
|
||||
}
|
||||
else if ((vtkm::Abs(n[1]) >= vtkm::Abs(n[0])) && (vtkm::Abs(n[1]) >= vtkm::Abs(n[2])))
|
||||
{
|
||||
|
||||
alpha_11 = ((E02[2] * E03[0]) - (E02[0] * E03[2])) / n[1];
|
||||
beta_11 = ((E01[2] * E02[0]) - (E01[0] * E02[2])) / n[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
alpha_11 = ((E02[0] * E03[1]) - (E02[1] * E03[0])) / n[2];
|
||||
beta_11 = ((E01[0] * E02[1]) - (E01[1] * E02[0])) / n[2];
|
||||
}
|
||||
|
||||
// Compute the bilinear coordinates of the intersection point.
|
||||
if (vtkm::Abs(alpha_11 - 1.0f) < vtkm::Epsilon<Precision>())
|
||||
{
|
||||
|
||||
u = alpha;
|
||||
if (vtkm::Abs(beta_11 - 1.0f) < vtkm::Epsilon<Precision>())
|
||||
v = beta;
|
||||
else
|
||||
v = beta / ((u * (beta_11 - 1.0f)) + 1.0f);
|
||||
}
|
||||
else if (vtkm::Abs(beta_11 - 1.0) < vtkm::Epsilon<Precision>())
|
||||
{
|
||||
|
||||
v = beta;
|
||||
u = alpha / ((v * (alpha_11 - 1.0f)) + 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Precision A = 1.0f - beta_11;
|
||||
Precision B = (alpha * (beta_11 - 1.0f)) - (beta * (alpha_11 - 1.0f)) - 1.0f;
|
||||
Precision C = alpha;
|
||||
Precision D = (B * B) - (4.0f * A * C);
|
||||
Precision QQ = -0.5f * (B + ((B < 0.0f ? -1.0f : 1.0f) * vtkm::Sqrt(D)));
|
||||
u = QQ / A;
|
||||
if ((u < 0.0f) || (u > 1.0f))
|
||||
u = C / QQ;
|
||||
v = beta / ((u * (beta_11 - 1.0f)) + 1.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PointPortalType, typename LeafPortalType, typename Precision>
|
||||
VTKM_EXEC inline void IntersectLeaf(
|
||||
const vtkm::Int32& currentNode,
|
||||
const vtkm::Vec<Precision, 3>& origin,
|
||||
const vtkm::Vec<Precision, 3>& dir,
|
||||
const PointPortalType& points,
|
||||
vtkm::Id& hitIndex,
|
||||
Precision& closestDistance, // closest distance in this set of primitives
|
||||
Precision& minU,
|
||||
Precision& minV,
|
||||
LeafPortalType leafs,
|
||||
const Precision& minDistance) const // report intesections past this distance
|
||||
{
|
||||
const vtkm::Id quadCount = leafs.Get(currentNode);
|
||||
for (vtkm::Id i = 1; i <= quadCount; ++i)
|
||||
{
|
||||
const vtkm::Id quadIndex = leafs.Get(currentNode + i);
|
||||
if (quadIndex < QuadIds.GetNumberOfValues())
|
||||
{
|
||||
IdType pointIndex = QuadIds.Get(quadIndex);
|
||||
Precision dist;
|
||||
vtkm::Vec<Precision, 3> q, r, s, t;
|
||||
q = vtkm::Vec<Precision, 3>(points.Get(pointIndex[1]));
|
||||
r = vtkm::Vec<Precision, 3>(points.Get(pointIndex[2]));
|
||||
s = vtkm::Vec<Precision, 3>(points.Get(pointIndex[3]));
|
||||
t = vtkm::Vec<Precision, 3>(points.Get(pointIndex[4]));
|
||||
Precision u, v;
|
||||
|
||||
bool ret = quad(origin, dir, q, r, s, t, u, v, dist);
|
||||
if (ret)
|
||||
{
|
||||
if (dist < closestDistance && dist > minDistance)
|
||||
{
|
||||
//matid = vtkm::Vec<, 3>(points.Get(cur_offset + 2))[0];
|
||||
closestDistance = dist;
|
||||
hitIndex = quadIndex;
|
||||
minU = u;
|
||||
minV = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for
|
||||
}
|
||||
};
|
||||
|
||||
struct IntersectFunctor
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
QuadIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRaysImp(Device(), rays, returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CalculateNormals : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CalculateNormals() {}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7);
|
||||
template <typename Precision, typename PointPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& hitIndex,
|
||||
const vtkm::Vec<Precision, 3>& rayDir,
|
||||
Precision& normalX,
|
||||
Precision& normalY,
|
||||
Precision& normalZ,
|
||||
const PointPortalType& points,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Vec<vtkm::Id, 5> quadId = indicesPortal.Get(hitIndex);
|
||||
|
||||
vtkm::Vec<Precision, 3> a, b, c;
|
||||
a = points.Get(quadId[1]);
|
||||
b = points.Get(quadId[2]);
|
||||
c = points.Get(quadId[3]);
|
||||
|
||||
vtkm::Vec<Precision, 3> normal = vtkm::TriangleNormal(a, b, c);
|
||||
vtkm::Normalize(normal);
|
||||
|
||||
//flip the normal if its pointing the wrong way
|
||||
if (vtkm::dot(normal, rayDir) > 0.f)
|
||||
normal = -normal;
|
||||
|
||||
normalX = normal[0];
|
||||
normalY = normal[1];
|
||||
normalZ = normal[2];
|
||||
}
|
||||
}; //class CalculateNormals
|
||||
|
||||
template <typename Precision>
|
||||
class GetScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
GetScalar(const vtkm::Float32& minScalar, const vtkm::Float32& maxScalar)
|
||||
: MinScalar(minScalar)
|
||||
{
|
||||
//Make sure the we don't divide by zero on
|
||||
//something like an iso-surface
|
||||
if (maxScalar - MinScalar != 0.f)
|
||||
invDeltaScalar = 1.f / (maxScalar - MinScalar);
|
||||
else
|
||||
invDeltaScalar = 1.f / minScalar;
|
||||
}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldInOut<>,
|
||||
WholeArrayIn<ScalarRenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4);
|
||||
template <typename ScalarPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
||||
Precision& scalar,
|
||||
const ScalarPortalType& scalars,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
//TODO: this should be interpolated?
|
||||
vtkm::Vec<vtkm::Id, 5> pointId = indicesPortal.Get(hitIndex);
|
||||
|
||||
scalar = Precision(scalars.Get(pointId[0]));
|
||||
//normalize
|
||||
scalar = (scalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class GetScalar
|
||||
|
||||
} // namespace detail
|
||||
|
||||
QuadIntersector::QuadIntersector()
|
||||
: ShapeIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
QuadIntersector::~QuadIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void QuadIntersector::IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
void QuadIntersector::IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void QuadIntersector::IntersectRaysImp(Device,
|
||||
Ray<Precision>& rays,
|
||||
bool vtkmNotUsed(returnCellIndex))
|
||||
{
|
||||
|
||||
detail::QuadLeafIntersector<Device> leafIntersector(this->QuadIds);
|
||||
|
||||
BVHTraverser<detail::QuadLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
void QuadIntersector::IntersectionDataImp(Ray<Precision>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
ShapeIntersector::IntersectionPoint(rays);
|
||||
|
||||
// TODO: if this is nodes of a mesh, support points
|
||||
bool isSupportedField =
|
||||
(scalarField->GetAssociation() == vtkm::cont::Field::Association::POINTS ||
|
||||
scalarField->GetAssociation() == vtkm::cont::Field::Association::CELL_SET);
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Field not accociated with a cell set");
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::CalculateNormals>(detail::CalculateNormals())
|
||||
.Invoke(rays.HitIdx, rays.Dir, rays.NormalX, rays.NormalY, rays.NormalZ, CoordsHandle, QuadIds);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::GetScalar<Precision>>(
|
||||
detail::GetScalar<Precision>(vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)))
|
||||
.Invoke(rays.HitIdx, rays.Scalar, *scalarField, QuadIds);
|
||||
}
|
||||
|
||||
void QuadIntersector::IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
void QuadIntersector::IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
vtkm::Id QuadIntersector::GetNumberOfShapes() const
|
||||
{
|
||||
return QuadIds.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
176
vtkm/rendering/raytracing/QuadIntersector.h
Normal file
176
vtkm/rendering/raytracing/QuadIntersector.h
Normal file
@ -0,0 +1,176 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Quad_Intersector_h
|
||||
#define vtk_m_rendering_raytracing_Quad_Intersector_h
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/raytracing/ShapeIntersector.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#define AABB_EPSILON 1.0e-4f
|
||||
class FindQuadAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
FindQuadAABBs() {}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7, _8);
|
||||
template <typename PointPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Vec<vtkm::Id, 5> quadId,
|
||||
vtkm::Float32& xmin,
|
||||
vtkm::Float32& ymin,
|
||||
vtkm::Float32& zmin,
|
||||
vtkm::Float32& xmax,
|
||||
vtkm::Float32& ymax,
|
||||
vtkm::Float32& zmax,
|
||||
const PointPortalType& points) const
|
||||
{
|
||||
// cast to Float32
|
||||
vtkm::Vec<vtkm::Float32, 3> q, r, s, t;
|
||||
|
||||
q = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(quadId[1]));
|
||||
r = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(quadId[2]));
|
||||
s = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(quadId[3]));
|
||||
t = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(quadId[4]));
|
||||
|
||||
xmin = q[0];
|
||||
ymin = q[1];
|
||||
zmin = q[2];
|
||||
xmax = xmin;
|
||||
ymax = ymin;
|
||||
zmax = zmin;
|
||||
xmin = vtkm::Min(xmin, r[0]);
|
||||
ymin = vtkm::Min(ymin, r[1]);
|
||||
zmin = vtkm::Min(zmin, r[2]);
|
||||
xmax = vtkm::Max(xmax, r[0]);
|
||||
ymax = vtkm::Max(ymax, r[1]);
|
||||
zmax = vtkm::Max(zmax, r[2]);
|
||||
xmin = vtkm::Min(xmin, s[0]);
|
||||
ymin = vtkm::Min(ymin, s[1]);
|
||||
zmin = vtkm::Min(zmin, s[2]);
|
||||
xmax = vtkm::Max(xmax, s[0]);
|
||||
ymax = vtkm::Max(ymax, s[1]);
|
||||
zmax = vtkm::Max(zmax, s[2]);
|
||||
xmin = vtkm::Min(xmin, t[0]);
|
||||
ymin = vtkm::Min(ymin, t[1]);
|
||||
zmin = vtkm::Min(zmin, t[2]);
|
||||
xmax = vtkm::Max(xmax, t[0]);
|
||||
ymax = vtkm::Max(ymax, t[1]);
|
||||
zmax = vtkm::Max(zmax, t[2]);
|
||||
|
||||
vtkm::Float32 xEpsilon, yEpsilon, zEpsilon;
|
||||
const vtkm::Float32 minEpsilon = 1e-6f;
|
||||
xEpsilon = vtkm::Max(minEpsilon, AABB_EPSILON * (xmax - xmin));
|
||||
yEpsilon = vtkm::Max(minEpsilon, AABB_EPSILON * (ymax - ymin));
|
||||
zEpsilon = vtkm::Max(minEpsilon, AABB_EPSILON * (zmax - zmin));
|
||||
|
||||
xmin -= xEpsilon;
|
||||
ymin -= yEpsilon;
|
||||
zmin -= zEpsilon;
|
||||
xmax += xEpsilon;
|
||||
ymax += yEpsilon;
|
||||
zmax += zEpsilon;
|
||||
}
|
||||
|
||||
}; //class FindAABBs
|
||||
}
|
||||
class QuadIntersector : public ShapeIntersector
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> QuadIds;
|
||||
|
||||
public:
|
||||
QuadIntersector();
|
||||
virtual ~QuadIntersector() override;
|
||||
|
||||
|
||||
void SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> quadIds)
|
||||
{
|
||||
|
||||
this->QuadIds = quadIds;
|
||||
this->CoordsHandle = coords;
|
||||
AABBs AABB;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::FindQuadAABBs> faabbsInvoker;
|
||||
faabbsInvoker.Invoke(this->QuadIds,
|
||||
AABB.xmins,
|
||||
AABB.ymins,
|
||||
AABB.zmins,
|
||||
AABB.xmaxs,
|
||||
AABB.ymaxs,
|
||||
AABB.zmaxs,
|
||||
CoordsHandle);
|
||||
|
||||
//vtkm::worklet::DispatcherMapField<detail::FindQuadAABBs> faabbsInvoker(detail::FindQuadAABBs())
|
||||
// .Invoke(this->QuadIds,
|
||||
// AABB.xmins,
|
||||
// AABB.ymins,
|
||||
// AABB.zmins,
|
||||
// AABB.xmaxs,
|
||||
// AABB.ymaxs,
|
||||
// AABB.zmaxs,
|
||||
// CoordsHandle);
|
||||
|
||||
this->SetAABBs(AABB);
|
||||
}
|
||||
void IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex = false) override;
|
||||
|
||||
|
||||
void IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex = false) override;
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void IntersectRaysImp(Device, Ray<Precision>& rays, bool returnCellIndex);
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
void IntersectionDataImp(Ray<Precision>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange);
|
||||
|
||||
void IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
void IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
vtkm::Id GetNumberOfShapes() const override;
|
||||
}; // class ShapeIntersector
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Shape_Intersector_h
|
112
vtkm/rendering/raytracing/ShapeIntersector.cxx
Normal file
112
vtkm/rendering/raytracing/ShapeIntersector.cxx
Normal file
@ -0,0 +1,112 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
#include <vtkm/rendering/raytracing/ShapeIntersector.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
class IntersectionPointMap : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
IntersectionPointMap() {}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldInOut<>,
|
||||
FieldInOut<>,
|
||||
FieldInOut<>,
|
||||
FieldInOut<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7, _8);
|
||||
template <typename Precision>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& hitIndex,
|
||||
const Precision& distance,
|
||||
const vtkm::Vec<Precision, 3>& rayDir,
|
||||
const vtkm::Vec<Precision, 3>& rayOrigin,
|
||||
Precision& intersectionX,
|
||||
Precision& intersectionY,
|
||||
Precision& intersectionZ,
|
||||
Precision& maxDistance) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
intersectionX = rayOrigin[0] + rayDir[0] * distance;
|
||||
intersectionY = rayOrigin[1] + rayDir[1] * distance;
|
||||
intersectionZ = rayOrigin[2] + rayDir[2] * distance;
|
||||
maxDistance = distance;
|
||||
}
|
||||
}; //class IntersectionPoint
|
||||
} // anon namespace
|
||||
|
||||
ShapeIntersector::ShapeIntersector()
|
||||
{
|
||||
}
|
||||
ShapeIntersector::~ShapeIntersector(){};
|
||||
|
||||
void ShapeIntersector::IntersectionPoint(Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
this->IntersectionPointImp(rays);
|
||||
}
|
||||
|
||||
void ShapeIntersector::IntersectionPoint(Ray<vtkm::Float64>& rays)
|
||||
{
|
||||
this->IntersectionPointImp(rays);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
void ShapeIntersector::IntersectionPointImp(Ray<Precision>& rays)
|
||||
{
|
||||
rays.EnableIntersectionData();
|
||||
// Find the intersection point from hit distance
|
||||
// and set the new max distance
|
||||
vtkm::worklet::DispatcherMapField<IntersectionPointMap>(IntersectionPointMap())
|
||||
.Invoke(rays.HitIdx,
|
||||
rays.Distance,
|
||||
rays.Dir,
|
||||
rays.Origin,
|
||||
rays.IntersectionX,
|
||||
rays.IntersectionY,
|
||||
rays.IntersectionZ,
|
||||
rays.MaxDistance);
|
||||
}
|
||||
|
||||
vtkm::Bounds ShapeIntersector::GetShapeBounds() const
|
||||
{
|
||||
return ShapeBounds;
|
||||
}
|
||||
|
||||
void ShapeIntersector::SetAABBs(AABBs& aabbs)
|
||||
{
|
||||
this->BVH.SetData(aabbs);
|
||||
this->BVH.Construct();
|
||||
this->ShapeBounds = this->BVH.TotalBounds;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
85
vtkm/rendering/raytracing/ShapeIntersector.h
Normal file
85
vtkm/rendering/raytracing/ShapeIntersector.h
Normal file
@ -0,0 +1,85 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Shape_Intersector_h
|
||||
#define vtk_m_rendering_raytracing_Shape_Intersector_h
|
||||
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DynamicCellSet.h>
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT ShapeIntersector
|
||||
{
|
||||
protected:
|
||||
LinearBVH BVH;
|
||||
vtkm::cont::CoordinateSystem CoordsHandle;
|
||||
vtkm::Bounds ShapeBounds;
|
||||
void SetAABBs(AABBs& aabbs);
|
||||
|
||||
public:
|
||||
ShapeIntersector();
|
||||
virtual ~ShapeIntersector();
|
||||
|
||||
//
|
||||
// Intersect Rays finds the nearest intersection shape contained in the derived
|
||||
// class in between min and max distances. HitIdx will be set to the local
|
||||
// primitive id unless returnCellIndex is set to true. Cells are often
|
||||
// decomposed into triangles and setting returnCellIndex to true will set
|
||||
// HitIdx to the id of the cell.
|
||||
//
|
||||
virtual void IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex = false) = 0;
|
||||
|
||||
|
||||
virtual void IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex = false) = 0;
|
||||
|
||||
//
|
||||
// Calling intersection data directly after IntersectRays popoulates
|
||||
// ray data: intersection point, surface normal, and interpolated scalar
|
||||
// value at the intersection location. Additionally, distance to intersection
|
||||
// becomes the new max distance.
|
||||
//
|
||||
virtual void IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) = 0;
|
||||
|
||||
virtual void IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) = 0;
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
void IntersectionPointImp(Ray<Precision>& rays);
|
||||
void IntersectionPoint(Ray<vtkm::Float32>& rays);
|
||||
void IntersectionPoint(Ray<vtkm::Float64>& rays);
|
||||
|
||||
vtkm::Bounds GetShapeBounds() const;
|
||||
virtual vtkm::Id GetNumberOfShapes() const = 0;
|
||||
}; // class ShapeIntersector
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Shape_Intersector_h
|
285
vtkm/rendering/raytracing/SphereExtractor.cxx
Normal file
285
vtkm/rendering/raytracing/SphereExtractor.cxx
Normal file
@ -0,0 +1,285 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/raytracing/SphereExtractor.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/raytracing/Worklets.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class CountPoints : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountPoints() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldOut<>);
|
||||
typedef void ExecutionSignature(CellShape, _2);
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagGeneric shapeType, vtkm::Id& points) const
|
||||
{
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_VERTEX)
|
||||
points = 1;
|
||||
else
|
||||
points = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType), vtkm::Id& points) const
|
||||
{
|
||||
points = 0;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::CellShapeTagQuad vtkmNotUsed(shapeType), vtkm::Id& points) const
|
||||
{
|
||||
points = 0;
|
||||
}
|
||||
|
||||
}; // ClassCountPoints
|
||||
|
||||
class Pointify : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Pointify() {}
|
||||
typedef void ControlSignature(CellSetIn cellset, FieldInCell<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(_2, CellShape, PointIndices, WorkIndex, _3);
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
|
||||
vtkm::CellShapeTagQuad vtkmNotUsed(shapeType),
|
||||
const VecType& vtkmNotUsed(cellIndices),
|
||||
const vtkm::Id& vtkmNotUsed(cellId),
|
||||
OutputPortal& vtkmNotUsed(outputIndices)) const
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
|
||||
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),
|
||||
const VecType& vtkmNotUsed(cellIndices),
|
||||
const vtkm::Id& vtkmNotUsed(cellId),
|
||||
OutputPortal& vtkmNotUsed(outputIndices)) const
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
|
||||
vtkm::CellShapeTagGeneric shapeType,
|
||||
const VecType& vtkmNotUsed(cellIndices),
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_VERTEX)
|
||||
{
|
||||
outputIndices.Set(pointOffset, cellId);
|
||||
}
|
||||
}
|
||||
}; //class pointify
|
||||
|
||||
class Iterator : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Iterator() {}
|
||||
typedef void ControlSignature(FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, WorkIndex);
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::Id& index, const vtkm::Id& idx) const { index = idx; }
|
||||
}; //class Iterator
|
||||
|
||||
class FieldRadius : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
protected:
|
||||
vtkm::Float32 MinRadius;
|
||||
vtkm::Float32 RadiusDelta;
|
||||
vtkm::Float32 MinValue;
|
||||
vtkm::Float32 InverseDelta;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
FieldRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::Range scalarRange)
|
||||
: MinRadius(minRadius)
|
||||
, RadiusDelta(maxRadius - minRadius)
|
||||
, MinValue(static_cast<vtkm::Float32>(scalarRange.Min))
|
||||
{
|
||||
vtkm::Float32 delta = static_cast<vtkm::Float32>(scalarRange.Max - scalarRange.Min);
|
||||
if (delta != 0.f)
|
||||
InverseDelta = 1.f / (delta);
|
||||
else
|
||||
InverseDelta = 0.f; // just map scalar to 0;
|
||||
}
|
||||
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>, WholeArrayIn<Scalar>);
|
||||
typedef void ExecutionSignature(_1, _2, _3);
|
||||
|
||||
template <typename ScalarPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& pointId,
|
||||
vtkm::Float32& radius,
|
||||
const ScalarPortalType& scalars) const
|
||||
{
|
||||
vtkm::Float32 scalar = static_cast<vtkm::Float32>(scalars.Get(pointId));
|
||||
vtkm::Float32 t = (scalar - MinValue) * InverseDelta;
|
||||
radius = MinRadius + t * RadiusDelta;
|
||||
}
|
||||
|
||||
}; //class FieldRadius
|
||||
|
||||
} //namespace detail
|
||||
|
||||
void SphereExtractor::ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::Float32 radius)
|
||||
{
|
||||
this->SetPointIdsFromCoords(coords);
|
||||
this->SetUniformRadius(radius);
|
||||
}
|
||||
|
||||
void SphereExtractor::ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& field,
|
||||
const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius)
|
||||
{
|
||||
this->SetPointIdsFromCoords(coords);
|
||||
this->SetVaryingRadius(minRadius, maxRadius, field);
|
||||
}
|
||||
|
||||
void SphereExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
|
||||
const vtkm::Float32 radius)
|
||||
{
|
||||
this->SetPointIdsFromCells(cells);
|
||||
this->SetUniformRadius(radius);
|
||||
}
|
||||
void SphereExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
|
||||
const vtkm::cont::Field& field,
|
||||
const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius)
|
||||
{
|
||||
this->SetPointIdsFromCells(cells);
|
||||
this->SetVaryingRadius(minRadius, maxRadius, field);
|
||||
}
|
||||
|
||||
void SphereExtractor::SetUniformRadius(const vtkm::Float32 radius)
|
||||
{
|
||||
const vtkm::Id size = this->PointIds.GetNumberOfValues();
|
||||
Radii.Allocate(size);
|
||||
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Float32> radiusHandle(radius, size);
|
||||
vtkm::cont::Algorithm::Copy(radiusHandle, Radii);
|
||||
}
|
||||
|
||||
void SphereExtractor::SetPointIdsFromCoords(const vtkm::cont::CoordinateSystem& coords)
|
||||
{
|
||||
vtkm::Id size = coords.GetData().GetNumberOfValues();
|
||||
this->PointIds.Allocate(size);
|
||||
vtkm::worklet::DispatcherMapField<detail::Iterator>(detail::Iterator()).Invoke(this->PointIds);
|
||||
}
|
||||
|
||||
void SphereExtractor::SetPointIdsFromCells(const vtkm::cont::DynamicCellSet& cells)
|
||||
{
|
||||
using SingleType = vtkm::cont::CellSetSingleType<>;
|
||||
vtkm::Id numCells = cells.GetNumberOfCells();
|
||||
if (numCells == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//
|
||||
// look for points in the cell set
|
||||
//
|
||||
if (cells.IsSameType(vtkm::cont::CellSetExplicit<>()))
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> points;
|
||||
vtkm::worklet::DispatcherMapTopology<detail::CountPoints>(detail::CountPoints())
|
||||
.Invoke(cells, points);
|
||||
|
||||
vtkm::Id totalPoints = 0;
|
||||
totalPoints = vtkm::cont::Algorithm::Reduce(points, vtkm::Id(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
vtkm::cont::Algorithm::ScanExclusive(points, cellOffsets);
|
||||
PointIds.Allocate(totalPoints);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<detail::Pointify>(detail::Pointify())
|
||||
.Invoke(cells, cellOffsets, this->PointIds);
|
||||
}
|
||||
else if (cells.IsSameType(SingleType()))
|
||||
{
|
||||
SingleType pointCells = cells.Cast<SingleType>();
|
||||
vtkm::UInt8 shape_id = pointCells.GetCellShape(0);
|
||||
if (shape_id == vtkm::CELL_SHAPE_VERTEX)
|
||||
{
|
||||
this->PointIds.Allocate(numCells);
|
||||
vtkm::worklet::DispatcherMapField<detail::Iterator>(detail::Iterator())
|
||||
.Invoke(this->PointIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SphereExtractor::SetVaryingRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::cont::Field& field)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray = field.GetRange();
|
||||
if (rangeArray.GetNumberOfValues() != 1)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Sphere Extractor: scalar field must have one component");
|
||||
}
|
||||
|
||||
vtkm::Range range = rangeArray.GetPortalConstControl().Get(0);
|
||||
|
||||
Radii.Allocate(this->PointIds.GetNumberOfValues());
|
||||
vtkm::worklet::DispatcherMapField<detail::FieldRadius>(
|
||||
detail::FieldRadius(minRadius, maxRadius, range))
|
||||
.Invoke(this->PointIds, this->Radii, field);
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> SphereExtractor::GetPointIds()
|
||||
{
|
||||
return this->PointIds;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> SphereExtractor::GetRadii()
|
||||
{
|
||||
return this->Radii;
|
||||
}
|
||||
|
||||
vtkm::Id SphereExtractor::GetNumberOfSpheres() const
|
||||
{
|
||||
return this->PointIds.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
83
vtkm/rendering/raytracing/SphereExtractor.h
Normal file
83
vtkm/rendering/raytracing/SphereExtractor.h
Normal file
@ -0,0 +1,83 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Sphere_Extractor_h
|
||||
#define vtk_m_rendering_raytracing_Sphere_Extractor_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class SphereExtractor
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> PointIds;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> Radii;
|
||||
|
||||
public:
|
||||
//
|
||||
// Extract all nodes using a constant radius
|
||||
//
|
||||
void ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords, const vtkm::Float32 radius);
|
||||
|
||||
//
|
||||
// Set radius based on scalar field values. Each is interpolated from min to max
|
||||
//
|
||||
void ExtractCoordinates(const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& field,
|
||||
const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius);
|
||||
|
||||
//
|
||||
// Extract all vertex shapes with constant radius
|
||||
//
|
||||
void ExtractCells(const vtkm::cont::DynamicCellSet& cells, vtkm::Float32 radius);
|
||||
|
||||
//
|
||||
// Extract all vertex elements with radius based on scalar values
|
||||
//
|
||||
void ExtractCells(const vtkm::cont::DynamicCellSet& cells,
|
||||
const vtkm::cont::Field& field,
|
||||
const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius);
|
||||
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetPointIds();
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> GetRadii();
|
||||
vtkm::Id GetNumberOfSpheres() const;
|
||||
|
||||
protected:
|
||||
void SetUniformRadius(const vtkm::Float32 radius);
|
||||
void SetVaryingRadius(const vtkm::Float32 minRadius,
|
||||
const vtkm::Float32 maxRadius,
|
||||
const vtkm::cont::Field& field);
|
||||
|
||||
void SetPointIdsFromCoords(const vtkm::cont::CoordinateSystem& coords);
|
||||
void SetPointIdsFromCells(const vtkm::cont::DynamicCellSet& cells);
|
||||
|
||||
}; // class ShapeIntersector
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Shape_Extractor_h
|
394
vtkm/rendering/raytracing/SphereIntersector.cxx
Normal file
394
vtkm/rendering/raytracing/SphereIntersector.cxx
Normal file
@ -0,0 +1,394 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/rendering/raytracing/BVHTraverser.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class FindSphereAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
FindSphereAABBs() {}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7, _8, _9);
|
||||
template <typename PointPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id pointId,
|
||||
const vtkm::Float32& radius,
|
||||
vtkm::Float32& xmin,
|
||||
vtkm::Float32& ymin,
|
||||
vtkm::Float32& zmin,
|
||||
vtkm::Float32& xmax,
|
||||
vtkm::Float32& ymax,
|
||||
vtkm::Float32& zmax,
|
||||
const PointPortalType& points) const
|
||||
{
|
||||
// cast to Float32
|
||||
vtkm::Vec<vtkm::Float32, 3> point;
|
||||
vtkm::Vec<vtkm::Float32, 3> temp;
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(pointId));
|
||||
|
||||
temp[0] = radius;
|
||||
temp[1] = 0.f;
|
||||
temp[2] = 0.f;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 3> p = point + temp;
|
||||
//set first point to max and min
|
||||
xmin = p[0];
|
||||
xmax = p[0];
|
||||
ymin = p[1];
|
||||
ymax = p[1];
|
||||
zmin = p[2];
|
||||
zmax = p[2];
|
||||
|
||||
p = point - temp;
|
||||
xmin = vtkm::Min(xmin, p[0]);
|
||||
xmax = vtkm::Max(xmax, p[0]);
|
||||
ymin = vtkm::Min(ymin, p[1]);
|
||||
ymax = vtkm::Max(ymax, p[1]);
|
||||
zmin = vtkm::Min(zmin, p[2]);
|
||||
zmax = vtkm::Max(zmax, p[2]);
|
||||
|
||||
temp[0] = 0.f;
|
||||
temp[1] = radius;
|
||||
temp[2] = 0.f;
|
||||
|
||||
p = point + temp;
|
||||
xmin = vtkm::Min(xmin, p[0]);
|
||||
xmax = vtkm::Max(xmax, p[0]);
|
||||
ymin = vtkm::Min(ymin, p[1]);
|
||||
ymax = vtkm::Max(ymax, p[1]);
|
||||
zmin = vtkm::Min(zmin, p[2]);
|
||||
zmax = vtkm::Max(zmax, p[2]);
|
||||
|
||||
p = point - temp;
|
||||
xmin = vtkm::Min(xmin, p[0]);
|
||||
xmax = vtkm::Max(xmax, p[0]);
|
||||
ymin = vtkm::Min(ymin, p[1]);
|
||||
ymax = vtkm::Max(ymax, p[1]);
|
||||
zmin = vtkm::Min(zmin, p[2]);
|
||||
zmax = vtkm::Max(zmax, p[2]);
|
||||
|
||||
temp[0] = 0.f;
|
||||
temp[1] = 0.f;
|
||||
temp[2] = radius;
|
||||
|
||||
p = point + temp;
|
||||
xmin = vtkm::Min(xmin, p[0]);
|
||||
xmax = vtkm::Max(xmax, p[0]);
|
||||
ymin = vtkm::Min(ymin, p[1]);
|
||||
ymax = vtkm::Max(ymax, p[1]);
|
||||
zmin = vtkm::Min(zmin, p[2]);
|
||||
zmax = vtkm::Max(zmax, p[2]);
|
||||
|
||||
p = point - temp;
|
||||
xmin = vtkm::Min(xmin, p[0]);
|
||||
xmax = vtkm::Max(xmax, p[0]);
|
||||
ymin = vtkm::Min(ymin, p[1]);
|
||||
ymax = vtkm::Max(ymax, p[1]);
|
||||
zmin = vtkm::Min(zmin, p[2]);
|
||||
zmax = vtkm::Max(zmax, p[2]);
|
||||
}
|
||||
}; //class FindAABBs
|
||||
|
||||
template <typename Device>
|
||||
class SphereLeafIntersector
|
||||
{
|
||||
public:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using IdArrayPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using FloatHandle = vtkm::cont::ArrayHandle<vtkm::Float32>;
|
||||
using FloatPortal = typename FloatHandle::ExecutionTypes<Device>::PortalConst;
|
||||
IdArrayPortal PointIds;
|
||||
FloatPortal Radii;
|
||||
|
||||
SphereLeafIntersector(const IdHandle& pointIds, const FloatHandle& radii)
|
||||
: PointIds(pointIds.PrepareForInput(Device()))
|
||||
, Radii(radii.PrepareForInput(Device()))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename PointPortalType, typename LeafPortalType, typename Precision>
|
||||
VTKM_EXEC inline void IntersectLeaf(
|
||||
const vtkm::Int32& currentNode,
|
||||
const vtkm::Vec<Precision, 3>& origin,
|
||||
const vtkm::Vec<Precision, 3>& dir,
|
||||
const PointPortalType& points,
|
||||
vtkm::Id& hitIndex,
|
||||
Precision& closestDistance, // closest distance in this set of primitives
|
||||
Precision& vtkmNotUsed(minU),
|
||||
Precision& vtkmNotUsed(minV),
|
||||
LeafPortalType leafs,
|
||||
const Precision& minDistance) const // report intesections past this distance
|
||||
{
|
||||
const vtkm::Id sphereCount = leafs.Get(currentNode);
|
||||
for (vtkm::Id i = 1; i <= sphereCount; ++i)
|
||||
{
|
||||
const vtkm::Id sphereIndex = leafs.Get(currentNode + i);
|
||||
vtkm::Id pointIndex = PointIds.Get(sphereIndex);
|
||||
vtkm::Float32 radius = Radii.Get(sphereIndex);
|
||||
vtkm::Vec<Precision, 3> center = vtkm::Vec<Precision, 3>(points.Get(pointIndex));
|
||||
|
||||
vtkm::Vec<Precision, 3> l = center - origin;
|
||||
|
||||
Precision dot1 = vtkm::dot(l, dir);
|
||||
|
||||
if (dot1 >= 0)
|
||||
{
|
||||
Precision d = vtkm::dot(l, l) - dot1 * dot1;
|
||||
Precision r2 = radius * radius;
|
||||
if (d <= r2)
|
||||
{
|
||||
Precision tch = vtkm::Sqrt(r2 - d);
|
||||
Precision t0 = dot1 - tch;
|
||||
//float t1 = dot1+tch; /* if t1 is > 0 and t0<0 then the ray is inside the sphere.
|
||||
|
||||
if (t0 < closestDistance && t0 > minDistance)
|
||||
{
|
||||
hitIndex = pointIndex;
|
||||
closestDistance = t0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for
|
||||
}
|
||||
};
|
||||
|
||||
struct IntersectFunctor
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
SphereIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRaysImp(Device(), rays, returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CalculateNormals : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CalculateNormals() {}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7);
|
||||
template <typename Precision, typename PointPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& hitIndex,
|
||||
const vtkm::Vec<Precision, 3>& intersection,
|
||||
Precision& normalX,
|
||||
Precision& normalY,
|
||||
Precision& normalZ,
|
||||
const PointPortalType& points,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Id pointId = indicesPortal.Get(hitIndex);
|
||||
vtkm::Vec<Precision, 3> center = points.Get(pointId);
|
||||
|
||||
vtkm::Vec<Precision, 3> normal = intersection - center;
|
||||
vtkm::Normalize(normal);
|
||||
|
||||
//flip the normal if its pointing the wrong way
|
||||
normalX = normal[0];
|
||||
normalY = normal[1];
|
||||
normalZ = normal[2];
|
||||
}
|
||||
}; //class CalculateNormals
|
||||
|
||||
template <typename Precision>
|
||||
class GetScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
GetScalar(const vtkm::Float32& minScalar, const vtkm::Float32& maxScalar)
|
||||
: MinScalar(minScalar)
|
||||
{
|
||||
//Make sure the we don't divide by zero on
|
||||
//something like an iso-surface
|
||||
if (maxScalar - MinScalar != 0.f)
|
||||
invDeltaScalar = 1.f / (maxScalar - MinScalar);
|
||||
else
|
||||
invDeltaScalar = 1.f / minScalar;
|
||||
}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldInOut<>,
|
||||
WholeArrayIn<ScalarRenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4);
|
||||
template <typename ScalarPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
||||
Precision& scalar,
|
||||
const ScalarPortalType& scalars,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Id pointId = indicesPortal.Get(hitIndex);
|
||||
|
||||
scalar = Precision(scalars.Get(pointId));
|
||||
//normalize
|
||||
scalar = (scalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class GetScalar
|
||||
|
||||
} // namespace detail
|
||||
|
||||
SphereIntersector::SphereIntersector()
|
||||
: ShapeIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
SphereIntersector::~SphereIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
void SphereIntersector::SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> pointIds,
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> radii)
|
||||
{
|
||||
this->PointIds = pointIds;
|
||||
this->Radii = radii;
|
||||
this->CoordsHandle = coords;
|
||||
AABBs AABB;
|
||||
vtkm::worklet::DispatcherMapField<detail::FindSphereAABBs>(detail::FindSphereAABBs())
|
||||
.Invoke(PointIds,
|
||||
Radii,
|
||||
AABB.xmins,
|
||||
AABB.ymins,
|
||||
AABB.zmins,
|
||||
AABB.xmaxs,
|
||||
AABB.ymaxs,
|
||||
AABB.zmaxs,
|
||||
CoordsHandle);
|
||||
|
||||
this->SetAABBs(AABB);
|
||||
}
|
||||
|
||||
void SphereIntersector::IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
void SphereIntersector::IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void SphereIntersector::IntersectRaysImp(Device,
|
||||
Ray<Precision>& rays,
|
||||
bool vtkmNotUsed(returnCellIndex))
|
||||
{
|
||||
|
||||
detail::SphereLeafIntersector<Device> leafIntersector(this->PointIds, Radii);
|
||||
|
||||
BVHTraverser<detail::SphereLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
void SphereIntersector::IntersectionDataImp(Ray<Precision>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
ShapeIntersector::IntersectionPoint(rays);
|
||||
|
||||
bool isSupportedField =
|
||||
(scalarField->GetAssociation() == vtkm::cont::Field::Association::POINTS ||
|
||||
scalarField->GetAssociation() == vtkm::cont::Field::Association::CELL_SET);
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"SphereIntersector: Field not accociated with a cell set or field");
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::CalculateNormals>(detail::CalculateNormals())
|
||||
.Invoke(rays.HitIdx,
|
||||
rays.Intersection,
|
||||
rays.NormalX,
|
||||
rays.NormalY,
|
||||
rays.NormalZ,
|
||||
CoordsHandle,
|
||||
PointIds);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::GetScalar<Precision>>(
|
||||
detail::GetScalar<Precision>(vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)))
|
||||
.Invoke(rays.HitIdx, rays.Scalar, *scalarField, PointIds);
|
||||
}
|
||||
|
||||
void SphereIntersector::IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
void SphereIntersector::IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
vtkm::Id SphereIntersector::GetNumberOfShapes() const
|
||||
{
|
||||
return PointIds.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
73
vtkm/rendering/raytracing/SphereIntersector.h
Normal file
73
vtkm/rendering/raytracing/SphereIntersector.h
Normal file
@ -0,0 +1,73 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Sphere_Intersector_h
|
||||
#define vtk_m_rendering_raytracing_Sphere_Intersector_h
|
||||
|
||||
#include <vtkm/rendering/raytracing/ShapeIntersector.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class SphereIntersector : public ShapeIntersector
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> PointIds;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> Radii;
|
||||
|
||||
public:
|
||||
SphereIntersector();
|
||||
virtual ~SphereIntersector() override;
|
||||
|
||||
void SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> pointIds,
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> radii);
|
||||
|
||||
void IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex = false) override;
|
||||
|
||||
|
||||
void IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex = false) override;
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void IntersectRaysImp(Device, Ray<Precision>& rays, bool returnCellIndex);
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
void IntersectionDataImp(Ray<Precision>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange);
|
||||
|
||||
void IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
void IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
vtkm::Id GetNumberOfShapes() const override;
|
||||
}; // class ShapeIntersector
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Shape_Intersector_h
|
48
vtkm/rendering/raytracing/TriangleExtractor.cxx
Normal file
48
vtkm/rendering/raytracing/TriangleExtractor.cxx
Normal file
@ -0,0 +1,48 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/internal/RunTriangulator.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleExtractor.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
void TriangleExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells)
|
||||
{
|
||||
vtkm::Id numberOfTriangles;
|
||||
vtkm::rendering::internal::RunTriangulator(cells, this->Triangles, numberOfTriangles);
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> TriangleExtractor::GetTriangles()
|
||||
{
|
||||
return this->Triangles;
|
||||
}
|
||||
|
||||
vtkm::Id TriangleExtractor::GetNumberOfTriangles() const
|
||||
{
|
||||
return this->Triangles.GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
46
vtkm/rendering/raytracing/TriangleExtractor.h
Normal file
46
vtkm/rendering/raytracing/TriangleExtractor.h
Normal file
@ -0,0 +1,46 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Triangle_Extractor_h
|
||||
#define vtk_m_rendering_raytracing_Triangle_Extractor_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT TriangleExtractor
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Triangles; // (cellid, v0, v1, v2)
|
||||
public:
|
||||
void ExtractCells(const vtkm::cont::DynamicCellSet& cells);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles();
|
||||
vtkm::Id GetNumberOfTriangles() const;
|
||||
}; // class TriangleExtractor
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif //vtk_m_rendering_raytracing_Triangle_Extractor_h
|
68
vtkm/rendering/testing/UnitTestMapperPoints.cxx
Normal file
68
vtkm/rendering/testing/UnitTestMapperPoints.cxx
Normal file
@ -0,0 +1,68 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
#include <vtkm/rendering/Actor.h>
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/MapperPoint.h>
|
||||
#include <vtkm/rendering/Scene.h>
|
||||
#include <vtkm/rendering/View3D.h>
|
||||
#include <vtkm/rendering/testing/RenderTest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void RenderTests()
|
||||
{
|
||||
using M = vtkm::rendering::MapperPoint;
|
||||
using C = vtkm::rendering::CanvasRayTracer;
|
||||
using V3 = vtkm::rendering::View3D;
|
||||
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::ColorTable colorTable("inferno");
|
||||
|
||||
M mapper;
|
||||
std::cout << "Testing uniform delta raduis\n";
|
||||
mapper.SetRadiusDelta(4.0f);
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
mapper, maker.Make3DUniformDataSet1(), "pointvar", colorTable, "points_vr_reg3D.pnm");
|
||||
|
||||
// restore defaults
|
||||
mapper.SetRadiusDelta(0.5f);
|
||||
mapper.UseVariableRadius(false);
|
||||
|
||||
mapper.SetRadius(0.2f);
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
mapper, maker.Make3DUniformDataSet1(), "pointvar", colorTable, "points_reg3D.pnm");
|
||||
|
||||
mapper.UseCells();
|
||||
mapper.SetRadius(1.f);
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
mapper, maker.Make3DExplicitDataSet7(), "cellvar", colorTable, "spheres.pnm");
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
int UnitTestMapperPoints(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(RenderTests);
|
||||
}
|
64
vtkm/rendering/testing/UnitTestMapperQuads.cxx
Normal file
64
vtkm/rendering/testing/UnitTestMapperQuads.cxx
Normal file
@ -0,0 +1,64 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
#include <vtkm/rendering/Actor.h>
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/MapperQuad.h>
|
||||
#include <vtkm/rendering/Scene.h>
|
||||
#include <vtkm/rendering/View3D.h>
|
||||
#include <vtkm/rendering/testing/RenderTest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void RenderTests()
|
||||
{
|
||||
typedef vtkm::rendering::MapperQuad M;
|
||||
typedef vtkm::rendering::CanvasRayTracer C;
|
||||
typedef vtkm::rendering::View3D V3;
|
||||
typedef vtkm::rendering::View2D V2;
|
||||
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::ColorTable colorTable("inferno");
|
||||
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
maker.Make3DRegularDataSet0(), "pointvar", colorTable, "rt_reg3D.pnm");
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
maker.Make3DRectilinearDataSet0(), "pointvar", colorTable, "rt_rect3D.pnm");
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
maker.Make3DExplicitDataSet4(), "pointvar", colorTable, "rt_expl3D.pnm");
|
||||
|
||||
vtkm::rendering::testing::Render<M, C, V2>(
|
||||
maker.Make2DUniformDataSet1(), "pointvar", colorTable, "uni2D.pnm");
|
||||
|
||||
//hexahedron, wedge, pyramid, tetrahedron
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
maker.Make3DExplicitDataSet5(), "cellvar", colorTable, "rt_hex3d.pnm");
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
int UnitTestMapperQuads(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(RenderTests);
|
||||
}
|
Loading…
Reference in New Issue
Block a user