updates to the connectivity tracer
This commit is contained in:
parent
8237db209e
commit
5a1685d8aa
@ -178,6 +178,7 @@ set(device_sources
|
||||
raytracing/SphereExtractor.cxx
|
||||
raytracing/SphereIntersector.cxx
|
||||
raytracing/TriangleExtractor.cxx
|
||||
raytracing/TriangleIntersector.cxx
|
||||
raytracing/VolumeRendererStructured.cxx
|
||||
)
|
||||
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
|
||||
~InternalsType() {}
|
||||
|
||||
VTKM_CONT
|
||||
void SetUnitScalar(vtkm::Float32 unitScalar) { Tracer.SetUnitScalar(unitScalar); }
|
||||
|
||||
void SetSampleDistance(const vtkm::Float32& distance)
|
||||
{
|
||||
if (Mode != VOLUME_MODE)
|
||||
@ -119,7 +122,12 @@ public:
|
||||
vtkm::Bounds GetSpatialBounds() const { return SpatialBounds; }
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Range GetScalarRange() const { return ScalarRange; }
|
||||
vtkm::Range GetScalarFieldRange()
|
||||
{
|
||||
const vtkm::cont::ArrayHandle<vtkm::Range> range = this->ScalarField.GetRange();
|
||||
ScalarRange = range.GetPortalConstControl().Get(0);
|
||||
return ScalarRange;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void SetScalarRange(const vtkm::Range& range) { ScalarRange = range; }
|
||||
@ -141,7 +149,7 @@ public:
|
||||
this->EmissionField);
|
||||
}
|
||||
|
||||
Tracer.Trace(rays);
|
||||
Tracer.FullTrace(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -160,7 +168,46 @@ public:
|
||||
this->EmissionField);
|
||||
}
|
||||
|
||||
Tracer.Trace(rays);
|
||||
Tracer.FullTrace(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartialVector64 PartialTrace(vtkm::rendering::raytracing::Ray<vtkm::Float64>& rays)
|
||||
{
|
||||
|
||||
if (Mode == VOLUME_MODE)
|
||||
{
|
||||
Tracer.SetVolumeData(this->ScalarField, this->ScalarRange, this->Cells, this->Coords);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracer.SetEnergyData(this->ScalarField,
|
||||
rays.Buffers.at(0).GetNumChannels(),
|
||||
this->Cells,
|
||||
this->Coords,
|
||||
this->EmissionField);
|
||||
}
|
||||
|
||||
return Tracer.PartialTrace(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartialVector32 PartialTrace(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
if (Mode == VOLUME_MODE)
|
||||
{
|
||||
Tracer.SetVolumeData(this->ScalarField, this->ScalarRange, this->Cells, this->Coords);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracer.SetEnergyData(this->ScalarField,
|
||||
rays.Buffers.at(0).GetNumChannels(),
|
||||
this->Cells,
|
||||
this->Coords,
|
||||
this->EmissionField);
|
||||
}
|
||||
|
||||
return Tracer.PartialTrace(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -188,7 +235,7 @@ public:
|
||||
throw vtkm::cont::ErrorBadValue("ENERGY MODE Not implemented for this use case\n");
|
||||
}
|
||||
|
||||
Tracer.Trace(rays);
|
||||
Tracer.FullTrace(rays);
|
||||
|
||||
canvas->WriteToCanvas(rays, rays.Buffers.at(0).Buffer, camera);
|
||||
if (CompositeBackground)
|
||||
@ -266,9 +313,9 @@ vtkm::Bounds ConnectivityProxy::GetSpatialBounds()
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Range ConnectivityProxy::GetScalarRange()
|
||||
vtkm::Range ConnectivityProxy::GetScalarFieldRange()
|
||||
{
|
||||
return Internals->GetScalarRange();
|
||||
return Internals->GetScalarFieldRange();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -301,6 +348,27 @@ void ConnectivityProxy::Trace(vtkm::rendering::raytracing::Ray<vtkm::Float64>& r
|
||||
logger->CloseLogEntry(-1.0);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartialVector32 ConnectivityProxy::PartialTrace(
|
||||
vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
raytracing::Logger* logger = raytracing::Logger::GetInstance();
|
||||
logger->OpenLogEntry("connectivity_trace_32");
|
||||
if (Internals->GetRenderMode() == VOLUME_MODE)
|
||||
{
|
||||
logger->AddLogData("volume_mode", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->AddLogData("volume_mode", "false");
|
||||
}
|
||||
|
||||
PartialVector32 res = Internals->PartialTrace(rays);
|
||||
|
||||
logger->CloseLogEntry(-1.0);
|
||||
return res;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ConnectivityProxy::Trace(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
@ -320,6 +388,27 @@ void ConnectivityProxy::Trace(vtkm::rendering::raytracing::Ray<vtkm::Float32>& r
|
||||
logger->CloseLogEntry(-1.0);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartialVector64 ConnectivityProxy::PartialTrace(
|
||||
vtkm::rendering::raytracing::Ray<vtkm::Float64>& rays)
|
||||
{
|
||||
raytracing::Logger* logger = raytracing::Logger::GetInstance();
|
||||
logger->OpenLogEntry("connectivity_trace_64");
|
||||
if (Internals->GetRenderMode() == VOLUME_MODE)
|
||||
{
|
||||
logger->AddLogData("volume_mode", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->AddLogData("volume_mode", "false");
|
||||
}
|
||||
|
||||
PartialVector64 res = Internals->PartialTrace(rays);
|
||||
|
||||
logger->CloseLogEntry(-1.0);
|
||||
return res;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ConnectivityProxy::Trace(const vtkm::rendering::Camera& camera,
|
||||
vtkm::rendering::CanvasRayTracer* canvas)
|
||||
@ -332,10 +421,17 @@ void ConnectivityProxy::Trace(const vtkm::rendering::Camera& camera,
|
||||
|
||||
logger->CloseLogEntry(-1.0);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ConnectivityProxy::SetDebugPrints(bool on)
|
||||
{
|
||||
Internals->SetDebugPrints(on);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ConnectivityProxy::SetUnitScalar(vtkm::Float32 unitScalar)
|
||||
{
|
||||
Internals->SetUnitScalar(unitScalar);
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::rendering
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <vtkm/rendering/Mapper.h>
|
||||
#include <vtkm/rendering/View.h>
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/PartialComposite.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -33,6 +34,9 @@ namespace vtkm
|
||||
namespace rendering
|
||||
{
|
||||
|
||||
using PartialVector64 = std::vector<vtkm::rendering::raytracing::PartialComposite<vtkm::Float64>>;
|
||||
using PartialVector32 = std::vector<vtkm::rendering::raytracing::PartialComposite<vtkm::Float32>>;
|
||||
|
||||
class VTKM_RENDERING_EXPORT ConnectivityProxy
|
||||
{
|
||||
public:
|
||||
@ -57,14 +61,18 @@ public:
|
||||
void SetColorMap(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colormap);
|
||||
void SetCompositeBackground(bool on);
|
||||
void SetDebugPrints(bool on);
|
||||
void SetUnitScalar(vtkm::Float32 unitScalar);
|
||||
|
||||
vtkm::Bounds GetSpatialBounds();
|
||||
vtkm::Range GetScalarRange();
|
||||
vtkm::Range GetScalarFieldRange();
|
||||
|
||||
void Trace(const vtkm::rendering::Camera& camera, vtkm::rendering::CanvasRayTracer* canvas);
|
||||
void Trace(vtkm::rendering::raytracing::Ray<vtkm::Float64>& rays);
|
||||
void Trace(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays);
|
||||
|
||||
PartialVector64 PartialTrace(vtkm::rendering::raytracing::Ray<vtkm::Float64>& rays);
|
||||
PartialVector32 PartialTrace(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays);
|
||||
|
||||
protected:
|
||||
struct InternalsType;
|
||||
struct BoundsFunctor;
|
||||
|
@ -29,12 +29,8 @@
|
||||
#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
|
||||
|
@ -21,7 +21,6 @@
|
||||
#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>
|
||||
@ -31,7 +30,6 @@
|
||||
#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
|
||||
{
|
||||
|
@ -26,15 +26,11 @@
|
||||
#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
|
||||
{
|
||||
|
@ -78,28 +78,13 @@ VTKM_EXEC inline bool IntersectAABB(const BVHPortalType& bvh,
|
||||
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; }
|
||||
@ -118,11 +103,8 @@ public:
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Intersector(bool occlusion, LinearBVH& bvh, LeafIntersectorType<Device>& leafIntersector)
|
||||
Intersector(bool occlusion)
|
||||
: Occlusion(occlusion)
|
||||
, FlatBVH(bvh.FlatBVH.PrepareForInput(Device()))
|
||||
, Leafs(bvh.Leafs.PrepareForInput(Device()))
|
||||
, LeafIntersector(leafIntersector)
|
||||
{
|
||||
}
|
||||
using ControlSignature = void(FieldIn<>,
|
||||
@ -133,11 +115,18 @@ public:
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7, _8, _9);
|
||||
WholeArrayIn<Vec3RenderingTypes>,
|
||||
ExecObject leafIntersector,
|
||||
WholeArrayIn<>,
|
||||
WholeArrayIn<>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12);
|
||||
|
||||
|
||||
template <typename PointPortalType, typename Precision>
|
||||
template <typename PointPortalType,
|
||||
typename Precision,
|
||||
typename LeafType,
|
||||
typename InnerNodePortalType,
|
||||
typename LeafPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Vec<Precision, 3>& dir,
|
||||
const vtkm::Vec<Precision, 3>& origin,
|
||||
Precision& distance,
|
||||
@ -146,7 +135,10 @@ public:
|
||||
Precision& minU,
|
||||
Precision& minV,
|
||||
vtkm::Id& hitIndex,
|
||||
const PointPortalType& points) const
|
||||
const PointPortalType& points,
|
||||
LeafType& leafIntersector,
|
||||
const InnerNodePortalType& flatBVH,
|
||||
const LeafPortalType& leafs) const
|
||||
{
|
||||
Precision closestDistance = maxDistance;
|
||||
distance = maxDistance;
|
||||
@ -174,7 +166,7 @@ public:
|
||||
|
||||
|
||||
bool hitLeftChild, hitRightChild;
|
||||
bool rightCloser = IntersectAABB(FlatBVH,
|
||||
bool rightCloser = IntersectAABB(flatBVH,
|
||||
currentNode,
|
||||
originDir,
|
||||
invDir,
|
||||
@ -191,7 +183,7 @@ public:
|
||||
else
|
||||
{
|
||||
vtkm::Vec<vtkm::Float32, 4> children =
|
||||
FlatBVH.Get(currentNode + 3); //Children.Get(currentNode);
|
||||
flatBVH.Get(currentNode + 3); //Children.Get(currentNode);
|
||||
vtkm::Int32 leftChild;
|
||||
memcpy(&leftChild, &children[0], 4);
|
||||
vtkm::Int32 rightChild;
|
||||
@ -217,7 +209,7 @@ public:
|
||||
if (currentNode < 0 && currentNode != barrier) //check register usage
|
||||
{
|
||||
currentNode = -currentNode - 1; //swap the neg address
|
||||
LeafIntersector.IntersectLeaf(currentNode,
|
||||
leafIntersector.IntersectLeaf(currentNode,
|
||||
origin,
|
||||
dir,
|
||||
points,
|
||||
@ -225,7 +217,7 @@ public:
|
||||
closestDistance,
|
||||
minU,
|
||||
minV,
|
||||
Leafs,
|
||||
leafs,
|
||||
minDistance);
|
||||
currentNode = todo[stackptr];
|
||||
stackptr--;
|
||||
@ -239,16 +231,13 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <typename Precision, typename Device>
|
||||
template <typename Precision, typename LeafIntersectorType>
|
||||
VTKM_CONT void IntersectRays(Ray<Precision>& rays,
|
||||
LinearBVH& bvh,
|
||||
LeafIntersectorType<Device> leafIntersector,
|
||||
vtkm::cont::CoordinateSystem& coordsHandle,
|
||||
Device vtkmNotUsed(Device))
|
||||
LeafIntersectorType& leafIntersector,
|
||||
vtkm::cont::CoordinateSystem& coordsHandle)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<Intersector<Device>> intersectDispatch(
|
||||
Intersector<Device>(false, bvh, leafIntersector));
|
||||
intersectDispatch.SetDevice(Device());
|
||||
vtkm::worklet::DispatcherMapField<Intersector> intersectDispatch(Intersector(false));
|
||||
intersectDispatch.Invoke(rays.Dir,
|
||||
rays.Origin,
|
||||
rays.Distance,
|
||||
@ -257,7 +246,10 @@ public:
|
||||
rays.U,
|
||||
rays.V,
|
||||
rays.HitIdx,
|
||||
coordsHandle);
|
||||
coordsHandle,
|
||||
leafIntersector,
|
||||
bvh.FlatBVH,
|
||||
bvh.Leafs);
|
||||
}
|
||||
}; // BVHTraverser
|
||||
#undef END_FLAG
|
||||
|
@ -35,6 +35,7 @@ set(headers
|
||||
MeshConnectivityContainers.h
|
||||
MeshConnectivityBase.h
|
||||
MortonCodes.h
|
||||
PartialComposite.h
|
||||
QuadExtractor.h
|
||||
QuadIntersector.h
|
||||
Ray.h
|
||||
@ -46,6 +47,7 @@ set(headers
|
||||
SphereExtractor.h
|
||||
SphereIntersector.h
|
||||
TriangleExtractor.h
|
||||
TriangleIntersections.h
|
||||
TriangleIntersector.h
|
||||
VolumeRendererStructured.h
|
||||
Worklets.h
|
||||
|
@ -20,8 +20,9 @@
|
||||
#ifndef vtk_m_rendering_raytracing_Cell_Intersector_h
|
||||
#define vtk_m_rendering_raytracing_Cell_Intersector_h
|
||||
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/rendering/raytracing/CellTables.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersections.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
@ -511,6 +511,15 @@ void ChannelBuffer<Precision>::SetNumChannels(const vtkm::Int32 numChannels)
|
||||
ResizeChannelFunctor<Precision> functor(this, numChannels);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
ChannelBuffer<Precision> ChannelBuffer<Precision>::Copy()
|
||||
{
|
||||
ChannelBuffer res(NumChannels, Size);
|
||||
vtkm::cont::Algorithm::Copy(this->Buffer, res.Buffer);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Instantiate supported types
|
||||
template class ChannelBuffer<vtkm::Float32>;
|
||||
template class ChannelBuffer<vtkm::Float64>;
|
||||
|
@ -83,6 +83,8 @@ public:
|
||||
const vtkm::Id outputSize,
|
||||
Precision initValue = 1.f);
|
||||
|
||||
ChannelBuffer<Precision> Copy();
|
||||
|
||||
void InitConst(const Precision value);
|
||||
void InitChannels(const vtkm::cont::ArrayHandle<Precision>& signature);
|
||||
void Normalize(bool invert);
|
||||
|
@ -103,23 +103,21 @@ public:
|
||||
class ChannelBufferOperations
|
||||
{
|
||||
public:
|
||||
template <typename Device, typename Precision>
|
||||
template <typename Precision>
|
||||
static void Compact(ChannelBuffer<Precision>& buffer,
|
||||
vtkm::cont::ArrayHandle<UInt8>& masks,
|
||||
const vtkm::Id& newSize,
|
||||
Device)
|
||||
const vtkm::Id& newSize)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
|
||||
offsets.PrepareForOutput(buffer.Size, Device());
|
||||
offsets.Allocate(buffer.Size);
|
||||
vtkm::cont::ArrayHandleCast<vtkm::Id, vtkm::cont::ArrayHandle<vtkm::UInt8>> castedMasks(masks);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(castedMasks, offsets);
|
||||
vtkm::cont::Algorithm::ScanExclusive(castedMasks, offsets);
|
||||
|
||||
vtkm::cont::ArrayHandle<Precision> compactedBuffer;
|
||||
compactedBuffer.PrepareForOutput(newSize * buffer.NumChannels, Device());
|
||||
compactedBuffer.Allocate(newSize * buffer.NumChannels);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::CompactBuffer> dispatcher(
|
||||
detail::CompactBuffer(buffer.NumChannels));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(masks, buffer.Buffer, offsets, compactedBuffer);
|
||||
buffer.Buffer = compactedBuffer;
|
||||
buffer.Size = newSize;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,18 +22,11 @@
|
||||
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityContainers.h>
|
||||
#include <vtkm/rendering/raytracing/PartialComposite.h>
|
||||
|
||||
#ifndef CELL_SHAPE_ZOO
|
||||
#define CELL_SHAPE_ZOO 255
|
||||
#endif
|
||||
|
||||
#ifndef CELL_SHAPE_STRUCTURED
|
||||
#define CELL_SHAPE_STRUCTURED 254
|
||||
#endif
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -68,26 +61,29 @@ public:
|
||||
ExitDist = &Distance2;
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
void Compact(vtkm::cont::ArrayHandle<FloatType>& compactedDistances,
|
||||
vtkm::cont::ArrayHandle<UInt8>& masks,
|
||||
Device);
|
||||
vtkm::cont::ArrayHandle<UInt8>& masks);
|
||||
|
||||
template <typename Device>
|
||||
void Init(const vtkm::Id size, vtkm::cont::ArrayHandle<FloatType>& distances, Device);
|
||||
void Init(const vtkm::Id size, vtkm::cont::ArrayHandle<FloatType>& distances);
|
||||
|
||||
void Swap();
|
||||
};
|
||||
|
||||
} //namespace detail
|
||||
|
||||
|
||||
class ConnectivityTracer
|
||||
/**
|
||||
* \brief ConnectivityTracer is volumetric ray tracer for unstructured
|
||||
* grids. Capabilities include volume rendering and integrating
|
||||
* absorption and emission of N energy groups for simulated
|
||||
* radiograhy.
|
||||
*/
|
||||
class VTKM_RENDERING_EXPORT ConnectivityTracer
|
||||
{
|
||||
public:
|
||||
ConnectivityTracer()
|
||||
: MeshContainer(nullptr)
|
||||
, CountRayStatus(false)
|
||||
, UnitScalar(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
@ -120,57 +116,75 @@ public:
|
||||
void SetSampleDistance(const vtkm::Float32& distance);
|
||||
void SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap);
|
||||
|
||||
void Trace(Ray<vtkm::Float32>& rays);
|
||||
|
||||
void Trace(Ray<vtkm::Float64>& rays);
|
||||
|
||||
MeshConnContainer* GetMeshContainer() { return MeshContainer; }
|
||||
|
||||
void Init();
|
||||
|
||||
void SetDebugOn(bool on) { CountRayStatus = on; }
|
||||
|
||||
void SetUnitScalar(const vtkm::Float32 unitScalar) { UnitScalar = unitScalar; }
|
||||
|
||||
|
||||
vtkm::Id GetNumberOfMeshCells() const;
|
||||
|
||||
void ResetTimers();
|
||||
void LogTimers();
|
||||
|
||||
///
|
||||
/// Traces rays fully through the mesh. Rays can exit and re-enter
|
||||
/// multiple times before leaving the domain. This is fast path for
|
||||
/// structured meshs or meshes that are not interlocking.
|
||||
/// Note: rays will be compacted
|
||||
///
|
||||
template <typename FloatType>
|
||||
void FullTrace(Ray<FloatType>& rays);
|
||||
|
||||
///
|
||||
/// Integrates rays through the mesh. If rays leave the mesh and
|
||||
/// re-enter, then those become two separate partial composites.
|
||||
/// This is need to support domain decompositions that are like
|
||||
/// puzzle pieces. Note: rays will be compacted
|
||||
///
|
||||
template <typename FloatType>
|
||||
std::vector<PartialComposite<FloatType>> PartialTrace(Ray<FloatType>& rays);
|
||||
|
||||
///
|
||||
/// Integrates the active rays though the mesh until all rays
|
||||
/// have exited.
|
||||
/// Precondition: rays.HitIdx is set to a valid mesh cell
|
||||
///
|
||||
template <typename FloatType>
|
||||
void IntegrateMeshSegment(Ray<FloatType>& rays);
|
||||
|
||||
///
|
||||
/// Find the entry point in the mesh
|
||||
///
|
||||
template <typename FloatType>
|
||||
void FindMeshEntry(Ray<FloatType>& rays);
|
||||
|
||||
private:
|
||||
friend struct detail::RenderFunctor;
|
||||
template <typename FloatType, typename Device>
|
||||
void IntersectCell(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device);
|
||||
template <typename FloatType>
|
||||
void IntersectCell(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void AccumulatePathLengths(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
template <typename FloatType>
|
||||
void AccumulatePathLengths(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void FindLostRays(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device);
|
||||
template <typename FloatType>
|
||||
void FindLostRays(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void SampleCells(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device);
|
||||
template <typename FloatType>
|
||||
void SampleCells(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void IntegrateCells(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
template <typename FloatType>
|
||||
void IntegrateCells(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void OffsetMinDistances(Ray<FloatType>& rays, Device);
|
||||
template <typename FloatType>
|
||||
void OffsetMinDistances(Ray<FloatType>& rays);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void PrintRayStatus(Ray<FloatType>& rays, Device);
|
||||
template <typename FloatType>
|
||||
void PrintRayStatus(Ray<FloatType>& rays);
|
||||
|
||||
protected:
|
||||
template <typename Device, typename FloatType>
|
||||
void RenderOnDevice(Ray<FloatType>& rays, Device);
|
||||
|
||||
// Data set info
|
||||
vtkm::cont::Field ScalarField;
|
||||
vtkm::cont::Field EmissionField;
|
||||
@ -180,7 +194,6 @@ protected:
|
||||
vtkm::Float32 BoundingBox[6];
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>> ColorMap;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> PreviousCellIds;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> BackgroundColor;
|
||||
vtkm::Float32 SampleDistance;
|
||||
@ -204,6 +217,7 @@ protected:
|
||||
vtkm::Float64 SampleTime;
|
||||
vtkm::Float64 LostRayTime;
|
||||
vtkm::Float64 MeshEntryTime;
|
||||
vtkm::Float32 UnitScalar;
|
||||
|
||||
}; // class ConnectivityTracer<CellType,ConnectivityType>
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,8 +34,126 @@ namespace raytracing
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class FindCylinderAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
FindCylinderAABBs() {}
|
||||
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::Id3 cylId,
|
||||
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> point1, point2;
|
||||
vtkm::Vec<vtkm::Float32, 3> temp;
|
||||
|
||||
point1 = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(cylId[1]));
|
||||
point2 = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(cylId[2]));
|
||||
|
||||
temp[0] = radius;
|
||||
temp[1] = 0.0f;
|
||||
temp[2] = 0.0f;
|
||||
xmin = ymin = zmin = vtkm::Infinity32();
|
||||
xmax = ymax = zmax = vtkm::NegativeInfinity32();
|
||||
|
||||
|
||||
//set first point to max and min
|
||||
Bounds(point1, radius, xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
|
||||
Bounds(point2, radius, xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
}
|
||||
|
||||
VTKM_EXEC void Bounds(const vtkm::Vec<vtkm::Float32, 3>& point,
|
||||
const vtkm::Float32& radius,
|
||||
vtkm::Float32& xmin,
|
||||
vtkm::Float32& ymin,
|
||||
vtkm::Float32& zmin,
|
||||
vtkm::Float32& xmax,
|
||||
vtkm::Float32& ymax,
|
||||
vtkm::Float32& zmax) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Float32, 3> temp, p;
|
||||
temp[0] = radius;
|
||||
temp[1] = 0.0f;
|
||||
temp[2] = 0.0f;
|
||||
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] = 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 CylinderLeafIntersector : public vtkm::cont::ExecutionObjectBase
|
||||
class CylinderLeafIntersector
|
||||
{
|
||||
public:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id3>;
|
||||
@ -45,6 +163,8 @@ public:
|
||||
IdArrayPortal CylIds;
|
||||
FloatPortal Radii;
|
||||
|
||||
CylinderLeafIntersector() {}
|
||||
|
||||
CylinderLeafIntersector(const IdHandle& cylIds, const FloatHandle& radii)
|
||||
: CylIds(cylIds.PrepareForInput(Device()))
|
||||
, Radii(radii.PrepareForInput(Device()))
|
||||
@ -183,17 +303,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct IntersectFunctor
|
||||
class CylinderLeafWrapper : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
CylinderIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
protected:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id3>;
|
||||
using FloatHandle = vtkm::cont::ArrayHandle<vtkm::Float32>;
|
||||
IdHandle CylIds;
|
||||
FloatHandle Radii;
|
||||
|
||||
public:
|
||||
CylinderLeafWrapper(IdHandle& cylIds, FloatHandle radii)
|
||||
: CylIds(cylIds)
|
||||
, Radii(radii)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRaysImp(Device(), rays, returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT CylinderLeafIntersector<Device> PrepareForExecution(Device) const
|
||||
{
|
||||
return CylinderLeafIntersector<Device>(CylIds, Radii);
|
||||
}
|
||||
};
|
||||
|
||||
@ -302,27 +430,47 @@ CylinderIntersector::~CylinderIntersector()
|
||||
{
|
||||
}
|
||||
|
||||
void CylinderIntersector::SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> cylIds,
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> radii)
|
||||
{
|
||||
this->Radii = radii;
|
||||
this->CylIds = cylIds;
|
||||
this->CoordsHandle = coords;
|
||||
AABBs AABB;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::FindCylinderAABBs>(detail::FindCylinderAABBs())
|
||||
.Invoke(this->CylIds,
|
||||
this->Radii,
|
||||
AABB.xmins,
|
||||
AABB.ymins,
|
||||
AABB.zmins,
|
||||
AABB.xmaxs,
|
||||
AABB.ymaxs,
|
||||
AABB.zmaxs,
|
||||
CoordsHandle);
|
||||
|
||||
this->SetAABBs(AABB);
|
||||
}
|
||||
|
||||
void CylinderIntersector::IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
IntersectRaysImp(rays, returnCellIndex);
|
||||
}
|
||||
|
||||
void CylinderIntersector::IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
IntersectRaysImp(rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void CylinderIntersector::IntersectRaysImp(Device,
|
||||
Ray<Precision>& rays,
|
||||
bool vtkmNotUsed(returnCellIndex))
|
||||
template <typename Precision>
|
||||
void CylinderIntersector::IntersectRaysImp(Ray<Precision>& rays, bool vtkmNotUsed(returnCellIndex))
|
||||
{
|
||||
|
||||
detail::CylinderLeafIntersector<Device> leafIntersector(this->CylIds, Radii);
|
||||
detail::CylinderLeafWrapper leafIntersector(this->CylIds, Radii);
|
||||
|
||||
BVHTraverser<detail::CylinderLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
BVHTraverser traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle);
|
||||
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
|
@ -31,125 +31,6 @@ namespace raytracing
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
||||
class FindCylinderAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
FindCylinderAABBs() {}
|
||||
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::Id3 cylId,
|
||||
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> point1, point2;
|
||||
vtkm::Vec<vtkm::Float32, 3> temp;
|
||||
|
||||
point1 = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(cylId[1]));
|
||||
point2 = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(cylId[2]));
|
||||
|
||||
temp[0] = radius;
|
||||
temp[1] = 0.0f;
|
||||
temp[2] = 0.0f;
|
||||
xmin = ymin = zmin = vtkm::Infinity32();
|
||||
xmax = ymax = zmax = vtkm::NegativeInfinity32();
|
||||
|
||||
|
||||
//set first point to max and min
|
||||
Bounds(point1, radius, xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
|
||||
Bounds(point2, radius, xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
}
|
||||
|
||||
VTKM_EXEC void Bounds(const vtkm::Vec<vtkm::Float32, 3>& point,
|
||||
const vtkm::Float32& radius,
|
||||
vtkm::Float32& xmin,
|
||||
vtkm::Float32& ymin,
|
||||
vtkm::Float32& zmin,
|
||||
vtkm::Float32& xmax,
|
||||
vtkm::Float32& ymax,
|
||||
vtkm::Float32& zmax) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Float32, 3> temp, p;
|
||||
temp[0] = radius;
|
||||
temp[1] = 0.0f;
|
||||
temp[2] = 0.0f;
|
||||
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] = 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
|
||||
}
|
||||
class CylinderIntersector : public ShapeIntersector
|
||||
{
|
||||
@ -164,33 +45,15 @@ public:
|
||||
|
||||
void SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> cylIds,
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> radii)
|
||||
{
|
||||
this->Radii = radii;
|
||||
this->CylIds = cylIds;
|
||||
this->CoordsHandle = coords;
|
||||
AABBs AABB;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> radii);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::FindCylinderAABBs>(detail::FindCylinderAABBs())
|
||||
.Invoke(this->CylIds,
|
||||
this->Radii,
|
||||
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 IntersectRaysImp(Ray<Precision>& rays, bool returnCellIndex);
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
|
@ -37,7 +37,10 @@ namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
//
|
||||
// Base class for different types of face-to-connecting-cell
|
||||
// and other mesh information
|
||||
//
|
||||
class VTKM_ALWAYS_EXPORT MeshConnectivityBase : public VirtualObjectBase
|
||||
{
|
||||
public:
|
||||
@ -51,6 +54,35 @@ public:
|
||||
virtual vtkm::UInt8 GetCellShape(const vtkm::Id& cellId) const = 0;
|
||||
};
|
||||
|
||||
// A simple concrete type to wrap MeshConnectivityBase so we can
|
||||
// pass an ExeObject to worklets.
|
||||
class MeshWrapper
|
||||
{
|
||||
private:
|
||||
MeshConnectivityBase* MeshConn;
|
||||
|
||||
public:
|
||||
MeshWrapper() {}
|
||||
|
||||
MeshWrapper(MeshConnectivityBase* meshConn)
|
||||
: MeshConn(meshConn){};
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
|
||||
{
|
||||
return MeshConn->GetConnectingCell(cellId, face);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const
|
||||
{
|
||||
return MeshConn->GetCellIndices(cellIndices, cellId);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::UInt8 GetCellShape(const vtkm::Id& cellId) const { return MeshConn->GetCellShape(cellId); }
|
||||
};
|
||||
|
||||
class VTKM_ALWAYS_EXPORT MeshConnStructured : public MeshConnectivityBase
|
||||
{
|
||||
protected:
|
||||
|
@ -40,10 +40,10 @@ namespace rendering
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
struct IsExternal
|
||||
struct IsUnique
|
||||
{
|
||||
VTKM_EXEC_CONT
|
||||
inline bool operator()(const vtkm::Id& x) const { return (x < 0); }
|
||||
inline bool operator()(const vtkm::Int32& x) const { return (x < 0); }
|
||||
}; //struct IsExternal
|
||||
|
||||
class CountFaces : public vtkm::worklet::WorkletMapField
|
||||
@ -93,8 +93,9 @@ public:
|
||||
WholeArrayIn<>,
|
||||
WholeArrayIn<>,
|
||||
WholeArrayIn<>,
|
||||
WholeArrayOut<>);
|
||||
using ExecutionSignature = void(_1, _2, WorkIndex, _3, _4, _5, _6);
|
||||
WholeArrayOut<>,
|
||||
WholeArrayInOut<>);
|
||||
using ExecutionSignature = void(_1, _2, WorkIndex, _3, _4, _5, _6, _7);
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Int32 GetShapeOffset(const vtkm::UInt8& shapeType) const
|
||||
@ -145,14 +146,16 @@ public:
|
||||
typename ConnPortalType,
|
||||
typename ShapePortalType,
|
||||
typename OffsetPortalType,
|
||||
typename ExternalFaceFlagType>
|
||||
typename ExternalFaceFlagType,
|
||||
typename UniqueFacesType>
|
||||
VTKM_EXEC inline void operator()(const MortonPortalType& mortonCodes,
|
||||
FaceIdPairsPortalType& faceIdPairs,
|
||||
const vtkm::Id& index,
|
||||
const ConnPortalType& connectivity,
|
||||
const ShapePortalType& shapes,
|
||||
const OffsetPortalType& offsets,
|
||||
ExternalFaceFlagType& flags) const
|
||||
ExternalFaceFlagType& flags,
|
||||
UniqueFacesType& uniqueFaces) const
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
@ -252,6 +255,10 @@ public:
|
||||
flags.Set(currentIndex, myCell);
|
||||
BOUNDS_CHECK(flags, index);
|
||||
flags.Set(index, connectedCell);
|
||||
|
||||
// for unstructured, we want all unique faces to intersect with
|
||||
// just choose one and mark as unique so the other gets culled.
|
||||
uniqueFaces.Set(index, 1);
|
||||
}
|
||||
}
|
||||
}; //class Neighbor
|
||||
@ -522,7 +529,8 @@ VTKM_CONT void GenerateFaceConnnectivity(
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& faceConnectivity,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>>& cellFaceId,
|
||||
vtkm::Float32 BoundingBox[6],
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& faceOffsets)
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& faceOffsets,
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32>& uniqueFaces)
|
||||
{
|
||||
|
||||
vtkm::cont::Timer<vtkm::cont::DeviceAdapterTagSerial> timer;
|
||||
@ -578,8 +586,8 @@ VTKM_CONT void GenerateFaceConnnectivity(
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt32> faceMortonCodes;
|
||||
cellFaceId.Allocate(totalFaces);
|
||||
faceMortonCodes.Allocate(totalFaces);
|
||||
//cellFaceId.PrepareForOutput(totalFaces, DeviceAdapter());
|
||||
//faceMortonCodes.PrepareForOutput(totalFaces, DeviceAdapter());
|
||||
uniqueFaces.Allocate(totalFaces);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<MortonCodeFace>(MortonCodeFace(inverseExtent, minPoint))
|
||||
.Invoke(cellSet, coordinates, cellOffsets, faceMortonCodes, cellFaceId);
|
||||
|
||||
@ -594,19 +602,21 @@ VTKM_CONT void GenerateFaceConnnectivity(
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> negOne(-1, totalFaces);
|
||||
vtkm::cont::Algorithm::Copy(negOne, faceConnectivity);
|
||||
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Int32> negOne32(-1, totalFaces);
|
||||
vtkm::cont::Algorithm::Copy(negOne32, uniqueFaces);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MortonNeighbor>(MortonNeighbor())
|
||||
.Invoke(faceMortonCodes, cellFaceId, conn, shapes, shapeOffsets, faceConnectivity);
|
||||
.Invoke(faceMortonCodes, cellFaceId, conn, shapes, shapeOffsets, faceConnectivity, uniqueFaces);
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
Logger::GetInstance()->AddLogData("gen_face_conn", time);
|
||||
}
|
||||
|
||||
template <typename ShapeHandleType, typename OffsetsHandleType, typename ConnHandleType>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Vec<Id, 4>> ExtractExternalFaces(
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Vec<Id, 4>> ExtractFaces(
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>>
|
||||
cellFaceId, // Map of cell, face, and connecting cell
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>
|
||||
faceConnectivity, // -1 if the face does not connect to any other face
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> uniqueFaces, // -1 if the face is unique
|
||||
const ShapeHandleType& shapes,
|
||||
const ConnHandleType& conn,
|
||||
const OffsetsHandleType& shapeOffsets)
|
||||
@ -614,7 +624,7 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Vec<Id, 4>> ExtractExternalFaces(
|
||||
|
||||
vtkm::cont::Timer<vtkm::cont::DeviceAdapterTagSerial> timer;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>> externalFacePairs;
|
||||
vtkm::cont::Algorithm::CopyIf(cellFaceId, faceConnectivity, externalFacePairs, IsExternal());
|
||||
vtkm::cont::Algorithm::CopyIf(cellFaceId, uniqueFaces, externalFacePairs, IsUnique());
|
||||
|
||||
// We need to count the number of triangle per external face
|
||||
// If it is a single cell type and it is a tet or hex, this is a special case
|
||||
@ -690,6 +700,7 @@ void MeshConnectivityBuilder::BuildConnectivity(
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> faceConnectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>> cellFaceId;
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> uniqueFaces;
|
||||
|
||||
GenerateFaceConnnectivity(cellSetUnstructured,
|
||||
shapes,
|
||||
@ -699,13 +710,13 @@ void MeshConnectivityBuilder::BuildConnectivity(
|
||||
faceConnectivity,
|
||||
cellFaceId,
|
||||
BoundingBox,
|
||||
FaceOffsets);
|
||||
FaceOffsets,
|
||||
uniqueFaces);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> externalTriangles;
|
||||
//External Faces
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles;
|
||||
//Faces
|
||||
|
||||
externalTriangles =
|
||||
ExtractExternalFaces(cellFaceId, faceConnectivity, shapes, conn, shapeOffsets);
|
||||
triangles = ExtractFaces(cellFaceId, uniqueFaces, shapes, conn, shapeOffsets);
|
||||
|
||||
|
||||
// scatter the coonectivity into the original order
|
||||
@ -713,7 +724,7 @@ void MeshConnectivityBuilder::BuildConnectivity(
|
||||
.Invoke(cellFaceId, this->FaceOffsets, faceConnectivity);
|
||||
|
||||
FaceConnectivity = faceConnectivity;
|
||||
OutsideTriangles = externalTriangles;
|
||||
Triangles = triangles;
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
@ -748,6 +759,7 @@ void MeshConnectivityBuilder::BuildConnectivity(
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> faceConnectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>> cellFaceId;
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> uniqueFaces;
|
||||
|
||||
GenerateFaceConnnectivity(cellSetUnstructured,
|
||||
shapes,
|
||||
@ -757,20 +769,20 @@ void MeshConnectivityBuilder::BuildConnectivity(
|
||||
faceConnectivity,
|
||||
cellFaceId,
|
||||
BoundingBox,
|
||||
FaceOffsets);
|
||||
FaceOffsets,
|
||||
uniqueFaces);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> externalTriangles;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles;
|
||||
//
|
||||
//External Faces
|
||||
externalTriangles =
|
||||
ExtractExternalFaces(cellFaceId, faceConnectivity, shapes, conn, shapeOffsets);
|
||||
//Faces
|
||||
triangles = ExtractFaces(cellFaceId, uniqueFaces, shapes, conn, shapeOffsets);
|
||||
|
||||
// scatter the coonectivity into the original order
|
||||
vtkm::worklet::DispatcherMapField<WriteFaceConn>(WriteFaceConn())
|
||||
.Invoke(cellFaceId, this->FaceOffsets, faceConnectivity);
|
||||
|
||||
FaceConnectivity = faceConnectivity;
|
||||
OutsideTriangles = externalTriangles;
|
||||
Triangles = triangles;
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
@ -829,9 +841,9 @@ vtkm::cont::ArrayHandle<vtkm::Id> MeshConnectivityBuilder::GetFaceOffsets()
|
||||
return FaceOffsets;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> MeshConnectivityBuilder::GetExternalTriangles()
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> MeshConnectivityBuilder::GetTriangles()
|
||||
{
|
||||
return OutsideTriangles;
|
||||
return Triangles;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -894,21 +906,20 @@ MeshConnContainer* MeshConnectivityBuilder::BuildConnectivity(
|
||||
{
|
||||
vtkm::cont::CellSetExplicit<> cells = cellset.Cast<vtkm::cont::CellSetExplicit<>>();
|
||||
this->BuildConnectivity(cells, coordinates.GetData(), coordBounds);
|
||||
meshConn = new UnstructuredContainer(
|
||||
cells, coordinates, FaceConnectivity, FaceOffsets, OutsideTriangles);
|
||||
meshConn =
|
||||
new UnstructuredContainer(cells, coordinates, FaceConnectivity, FaceOffsets, Triangles);
|
||||
}
|
||||
else if (type == UnstructuredSingle)
|
||||
{
|
||||
vtkm::cont::CellSetSingleType<> cells = cellset.Cast<vtkm::cont::CellSetSingleType<>>();
|
||||
this->BuildConnectivity(cells, coordinates.GetData(), coordBounds);
|
||||
meshConn =
|
||||
new UnstructuredSingleContainer(cells, coordinates, FaceConnectivity, OutsideTriangles);
|
||||
meshConn = new UnstructuredSingleContainer(cells, coordinates, FaceConnectivity, Triangles);
|
||||
}
|
||||
else if (type == Structured)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<3> cells = cellset.Cast<vtkm::cont::CellSetStructured<3>>();
|
||||
OutsideTriangles = this->ExternalTrianglesStructured(cells);
|
||||
meshConn = new StructuredContainer(cells, coordinates, OutsideTriangles);
|
||||
Triangles = this->ExternalTrianglesStructured(cells);
|
||||
meshConn = new StructuredContainer(cells, coordinates, Triangles);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetFaceOffsets();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetExternalTriangles();
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles();
|
||||
|
||||
protected:
|
||||
VTKM_CONT
|
||||
@ -63,7 +63,7 @@ protected:
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> FaceConnectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> FaceOffsets;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> OutsideTriangles;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Triangles;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -39,41 +39,28 @@ MeshConnContainer::MeshConnContainer(){};
|
||||
MeshConnContainer::~MeshConnContainer(){};
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT void MeshConnContainer::FindEntryImpl(Ray<T>& rays,
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
VTKM_CONT void MeshConnContainer::FindEntryImpl(Ray<T>& rays)
|
||||
{
|
||||
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;
|
||||
}
|
||||
Intersector.IntersectRays(rays, getCellIndex);
|
||||
}
|
||||
|
||||
void MeshConnContainer::FindEntry(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
MeshWrapper MeshConnContainer::PrepareForExecution(const vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
this->FindEntryImpl(rays, deviceId);
|
||||
return MeshWrapper(const_cast<MeshConnectivityBase*>(this->Construct(deviceId)));
|
||||
}
|
||||
|
||||
void MeshConnContainer::FindEntry(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::DeviceAdapterId deviceId)
|
||||
void MeshConnContainer::FindEntry(Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
this->FindEntryImpl(rays, deviceId);
|
||||
this->FindEntryImpl(rays);
|
||||
}
|
||||
|
||||
void MeshConnContainer::FindEntry(Ray<vtkm::Float64>& rays)
|
||||
{
|
||||
this->FindEntryImpl(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -81,13 +68,13 @@ UnstructuredContainer::UnstructuredContainer(const vtkm::cont::CellSetExplicit<>
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
IdHandle& faceOffsets,
|
||||
Id4Handle& externalTriangles)
|
||||
Id4Handle& triangles)
|
||||
: FaceConnectivity(faceConn)
|
||||
, FaceOffsets(faceOffsets)
|
||||
, Cellset(cellset)
|
||||
, Coords(coords)
|
||||
{
|
||||
this->ExternalTriangles = externalTriangles;
|
||||
this->Triangles = triangles;
|
||||
//
|
||||
// Grab the cell arrays
|
||||
//
|
||||
@ -97,7 +84,7 @@ UnstructuredContainer::UnstructuredContainer(const vtkm::cont::CellSetExplicit<>
|
||||
Cellset.GetIndexOffsetArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
Shapes = Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
Intersector.SetData(Coords, ExternalTriangles);
|
||||
Intersector.SetData(Coords, Triangles);
|
||||
}
|
||||
|
||||
UnstructuredContainer::~UnstructuredContainer(){};
|
||||
@ -107,6 +94,19 @@ const MeshConnectivityBase* UnstructuredContainer::Construct(
|
||||
{
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_OPENMP
|
||||
case VTKM_DEVICE_ADAPTER_OPENMP:
|
||||
using OMP = vtkm::cont::DeviceAdapterTagOpenMP;
|
||||
{
|
||||
MeshConnUnstructured<OMP> conn(this->FaceConnectivity,
|
||||
this->FaceOffsets,
|
||||
this->CellConn,
|
||||
this->CellOffsets,
|
||||
this->Shapes);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(OMP());
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
using TBB = vtkm::cont::DeviceAdapterTagTBB;
|
||||
@ -157,13 +157,13 @@ UnstructuredSingleContainer::UnstructuredSingleContainer(
|
||||
const vtkm::cont::CellSetSingleType<>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
Id4Handle& externalTriangles)
|
||||
Id4Handle& triangles)
|
||||
: FaceConnectivity(faceConn)
|
||||
, Coords(coords)
|
||||
, Cellset(cellset)
|
||||
{
|
||||
|
||||
this->ExternalTriangles = externalTriangles;
|
||||
this->Triangles = triangles;
|
||||
|
||||
this->Intersector.SetUseWaterTight(true);
|
||||
|
||||
@ -192,7 +192,7 @@ UnstructuredSingleContainer::UnstructuredSingleContainer(
|
||||
logger->OpenLogEntry("mesh_conn_construction");
|
||||
vtkm::cont::Timer<cont::DeviceAdapterTagSerial> timer;
|
||||
|
||||
Intersector.SetData(Coords, ExternalTriangles);
|
||||
Intersector.SetData(Coords, Triangles);
|
||||
}
|
||||
|
||||
const MeshConnectivityBase* UnstructuredSingleContainer::Construct(
|
||||
@ -200,6 +200,20 @@ const MeshConnectivityBase* UnstructuredSingleContainer::Construct(
|
||||
{
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_OPENMP
|
||||
case VTKM_DEVICE_ADAPTER_OPENMP:
|
||||
using OMP = vtkm::cont::DeviceAdapterTagOpenMP;
|
||||
{
|
||||
MeshConnSingleType<OMP> conn(this->FaceConnectivity,
|
||||
this->CellConnectivity,
|
||||
this->CellOffsets,
|
||||
this->ShapeId,
|
||||
this->NumIndices,
|
||||
this->NumFaces);
|
||||
Handle = make_MeshConnHandle(conn);
|
||||
}
|
||||
return Handle.PrepareForExecution(OMP());
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
using TBB = vtkm::cont::DeviceAdapterTagTBB;
|
||||
@ -245,18 +259,18 @@ const MeshConnectivityBase* UnstructuredSingleContainer::Construct(
|
||||
|
||||
StructuredContainer::StructuredContainer(const vtkm::cont::CellSetStructured<3>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
Id4Handle& externalTriangles)
|
||||
Id4Handle& triangles)
|
||||
: Coords(coords)
|
||||
, Cellset(cellset)
|
||||
{
|
||||
|
||||
ExternalTriangles = externalTriangles;
|
||||
Triangles = triangles;
|
||||
Intersector.SetUseWaterTight(true);
|
||||
|
||||
PointDims = Cellset.GetPointDimensions();
|
||||
CellDims = Cellset.GetCellDimensions();
|
||||
|
||||
this->Intersector.SetData(Coords, ExternalTriangles);
|
||||
this->Intersector.SetData(Coords, Triangles);
|
||||
}
|
||||
|
||||
const MeshConnectivityBase* StructuredContainer::Construct(
|
||||
@ -268,6 +282,10 @@ const MeshConnectivityBase* StructuredContainer::Construct(
|
||||
|
||||
switch (deviceId.GetValue())
|
||||
{
|
||||
#ifdef VTKM_ENABLE_OPENMP
|
||||
case VTKM_DEVICE_ADAPTER_OPENMP:
|
||||
return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagOpenMP());
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
case VTKM_DEVICE_ADAPTER_TBB:
|
||||
return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagTBB());
|
||||
|
@ -31,7 +31,7 @@ namespace rendering
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class MeshConnContainer
|
||||
class MeshConnContainer : vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
MeshConnContainer();
|
||||
@ -39,17 +39,19 @@ public:
|
||||
|
||||
virtual const MeshConnectivityBase* Construct(const vtkm::cont::DeviceAdapterId deviceId) = 0;
|
||||
|
||||
MeshWrapper PrepareForExecution(const vtkm::cont::DeviceAdapterId deviceId);
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT void FindEntryImpl(Ray<T>& rays, const vtkm::cont::DeviceAdapterId deviceId);
|
||||
VTKM_CONT void FindEntryImpl(Ray<T>& rays);
|
||||
|
||||
void FindEntry(Ray<vtkm::Float32>& rays, const vtkm::cont::DeviceAdapterId deviceId);
|
||||
void FindEntry(Ray<vtkm::Float32>& rays);
|
||||
|
||||
void FindEntry(Ray<vtkm::Float64>& rays, const vtkm::cont::DeviceAdapterId deviceId);
|
||||
void FindEntry(Ray<vtkm::Float64>& rays);
|
||||
|
||||
protected:
|
||||
using Id4Handle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
// Mesh Boundary
|
||||
Id4Handle ExternalTriangles;
|
||||
Id4Handle Triangles;
|
||||
TriangleIntersector Intersector;
|
||||
MeshConnHandle Handle;
|
||||
};
|
||||
@ -83,7 +85,7 @@ public:
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
IdHandle& faceConn,
|
||||
IdHandle& faceOffsets,
|
||||
Id4Handle& externalTriangles);
|
||||
Id4Handle& triangles);
|
||||
|
||||
virtual ~UnstructuredContainer();
|
||||
|
||||
@ -108,7 +110,7 @@ public:
|
||||
VTKM_CONT
|
||||
StructuredContainer(const vtkm::cont::CellSetStructured<3>& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
Id4Handle& externalTriangles);
|
||||
Id4Handle& triangles);
|
||||
|
||||
const MeshConnectivityBase* Construct(const vtkm::cont::DeviceAdapterId deviceId) override;
|
||||
|
||||
|
@ -34,17 +34,91 @@ namespace raytracing
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#define QUAD_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, QUAD_AABB_EPSILON * (xmax - xmin));
|
||||
yEpsilon = vtkm::Max(minEpsilon, QUAD_AABB_EPSILON * (ymax - ymin));
|
||||
zEpsilon = vtkm::Max(minEpsilon, QUAD_AABB_EPSILON * (zmax - zmin));
|
||||
|
||||
xmin -= xEpsilon;
|
||||
ymin -= yEpsilon;
|
||||
zmin -= zEpsilon;
|
||||
xmax += xEpsilon;
|
||||
ymax += yEpsilon;
|
||||
zmax += zEpsilon;
|
||||
}
|
||||
|
||||
}; //class FindAABBs
|
||||
|
||||
template <typename Device>
|
||||
class QuadLeafIntersector : public vtkm::cont::ExecutionObjectBase
|
||||
class QuadLeafIntersector
|
||||
{
|
||||
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() {}
|
||||
|
||||
QuadLeafIntersector(const IdHandle& quadIds)
|
||||
: QuadIds(quadIds.PrepareForInput(Device()))
|
||||
{
|
||||
@ -228,17 +302,23 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct IntersectFunctor
|
||||
class QuadExecWrapper : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
QuadIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
protected:
|
||||
using IdType = vtkm::Vec<vtkm::Id, 5>;
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>>;
|
||||
IdHandle QuadIds;
|
||||
|
||||
public:
|
||||
QuadExecWrapper(IdHandle& quadIds)
|
||||
: QuadIds(quadIds)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRaysImp(Device(), rays, returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT QuadLeafIntersector<Device> PrepareForExecution(Device) const
|
||||
{
|
||||
return QuadLeafIntersector<Device>(QuadIds);
|
||||
}
|
||||
};
|
||||
|
||||
@ -343,24 +423,22 @@ QuadIntersector::~QuadIntersector()
|
||||
|
||||
void QuadIntersector::IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
IntersectRaysImp(rays, returnCellIndex);
|
||||
}
|
||||
|
||||
void QuadIntersector::IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
IntersectRaysImp(rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void QuadIntersector::IntersectRaysImp(Device,
|
||||
Ray<Precision>& rays,
|
||||
bool vtkmNotUsed(returnCellIndex))
|
||||
template <typename Precision>
|
||||
void QuadIntersector::IntersectRaysImp(Ray<Precision>& rays, bool vtkmNotUsed(returnCellIndex))
|
||||
{
|
||||
|
||||
detail::QuadLeafIntersector<Device> leafIntersector(this->QuadIds);
|
||||
detail::QuadExecWrapper leafIntersector(this->QuadIds);
|
||||
|
||||
BVHTraverser<detail::QuadLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
BVHTraverser traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle);
|
||||
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
@ -401,6 +479,27 @@ void QuadIntersector::IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
|
||||
void QuadIntersector::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);
|
||||
|
||||
this->SetAABBs(AABB);
|
||||
}
|
||||
|
||||
vtkm::Id QuadIntersector::GetNumberOfShapes() const
|
||||
{
|
||||
return QuadIds.GetNumberOfValues();
|
||||
|
@ -31,80 +31,6 @@ 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
|
||||
{
|
||||
@ -117,42 +43,15 @@ public:
|
||||
|
||||
|
||||
void SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> quadIds)
|
||||
{
|
||||
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 IntersectRaysImp(Ray<Precision>& rays, bool returnCellIndex);
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
|
@ -113,11 +113,11 @@ public:
|
||||
class RayOperations
|
||||
{
|
||||
public:
|
||||
template <typename Device, typename T>
|
||||
static void ResetStatus(Ray<T>& rays, vtkm::UInt8 status, Device)
|
||||
template <typename T>
|
||||
static void ResetStatus(Ray<T>& rays, vtkm::UInt8 status)
|
||||
{
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> statusHandle(status, rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(Device(), statusHandle, rays.Status);
|
||||
vtkm::cont::Algorithm::Copy(statusHandle, rays.Status);
|
||||
}
|
||||
|
||||
//
|
||||
@ -146,8 +146,8 @@ public:
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::rendering::CanvasRayTracer& canvas);
|
||||
|
||||
template <typename Device, typename T>
|
||||
static vtkm::Id RaysInMesh(Ray<T>& rays, Device)
|
||||
template <typename T>
|
||||
static vtkm::Id RaysInMesh(Ray<T>& rays)
|
||||
{
|
||||
vtkm::Vec<UInt8, 2> maskValues;
|
||||
maskValues[0] = RAY_ACTIVE;
|
||||
@ -157,17 +157,16 @@ public:
|
||||
|
||||
vtkm::worklet::DispatcherMapField<ManyMask<vtkm::UInt8, 2>> dispatcher{ (
|
||||
ManyMask<vtkm::UInt8, 2>{ maskValues }) };
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.Status, masks);
|
||||
vtkm::cont::ArrayHandleCast<vtkm::Id, vtkm::cont::ArrayHandle<vtkm::UInt8>> castedMasks(masks);
|
||||
const vtkm::Id initVal = 0;
|
||||
vtkm::Id count = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(castedMasks, initVal);
|
||||
vtkm::Id count = vtkm::cont::Algorithm::Reduce(castedMasks, initVal);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template <typename Device, typename T>
|
||||
static vtkm::Id GetStatusCount(Ray<T>& rays, vtkm::Id status, Device)
|
||||
template <typename T>
|
||||
static vtkm::Id GetStatusCount(Ray<T>& rays, vtkm::Id status)
|
||||
{
|
||||
vtkm::UInt8 statusUInt8;
|
||||
if (status < 0 || status > 255)
|
||||
@ -180,17 +179,16 @@ public:
|
||||
|
||||
vtkm::worklet::DispatcherMapField<Mask<vtkm::UInt8>> dispatcher{ (
|
||||
Mask<vtkm::UInt8>{ statusUInt8 }) };
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.Status, masks);
|
||||
vtkm::cont::ArrayHandleCast<vtkm::Id, vtkm::cont::ArrayHandle<vtkm::UInt8>> castedMasks(masks);
|
||||
const vtkm::Id initVal = 0;
|
||||
vtkm::Id count = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(castedMasks, initVal);
|
||||
vtkm::Id count = vtkm::cont::Algorithm::Reduce(castedMasks, initVal);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template <typename Device, typename T>
|
||||
static vtkm::Id RaysProcessed(Ray<T>& rays, Device)
|
||||
template <typename T>
|
||||
static vtkm::Id RaysProcessed(Ray<T>& rays)
|
||||
{
|
||||
vtkm::Vec<UInt8, 3> maskValues;
|
||||
maskValues[0] = RAY_TERMINATED;
|
||||
@ -201,17 +199,16 @@ public:
|
||||
|
||||
vtkm::worklet::DispatcherMapField<ManyMask<vtkm::UInt8, 3>> dispatcher{ (
|
||||
ManyMask<vtkm::UInt8, 3>{ maskValues }) };
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.Status, masks);
|
||||
vtkm::cont::ArrayHandleCast<vtkm::Id, vtkm::cont::ArrayHandle<vtkm::UInt8>> castedMasks(masks);
|
||||
const vtkm::Id initVal = 0;
|
||||
vtkm::Id count = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(castedMasks, initVal);
|
||||
vtkm::Id count = vtkm::cont::Algorithm::Reduce(castedMasks, initVal);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template <typename Device, typename T>
|
||||
static vtkm::cont::ArrayHandle<vtkm::UInt8> CompactActiveRays(Ray<T>& rays, Device)
|
||||
template <typename T>
|
||||
static vtkm::cont::ArrayHandle<vtkm::UInt8> CompactActiveRays(Ray<T>& rays)
|
||||
{
|
||||
vtkm::Vec<UInt8, 1> maskValues;
|
||||
maskValues[0] = RAY_ACTIVE;
|
||||
@ -220,7 +217,6 @@ public:
|
||||
|
||||
vtkm::worklet::DispatcherMapField<Mask<vtkm::UInt8>> dispatcher{ (
|
||||
Mask<vtkm::UInt8>{ statusUInt8 }) };
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.Status, masks);
|
||||
|
||||
vtkm::cont::ArrayHandle<T> emptyHandle;
|
||||
@ -261,7 +257,7 @@ public:
|
||||
break;
|
||||
}
|
||||
vtkm::cont::ArrayHandle<T> compacted;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(*floatArrayPointers[i], masks, compacted);
|
||||
vtkm::cont::Algorithm::CopyIf(*floatArrayPointers[i], masks, compacted);
|
||||
*floatArrayPointers[i] = compacted;
|
||||
}
|
||||
|
||||
@ -275,15 +271,15 @@ public:
|
||||
rays.Dir = vtkm::cont::make_ArrayHandleCompositeVector(rays.DirX, rays.DirY, rays.DirZ);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> compactedHits;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(rays.HitIdx, masks, compactedHits);
|
||||
vtkm::cont::Algorithm::CopyIf(rays.HitIdx, masks, compactedHits);
|
||||
rays.HitIdx = compactedHits;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> compactedPixels;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(rays.PixelIdx, masks, compactedPixels);
|
||||
vtkm::cont::Algorithm::CopyIf(rays.PixelIdx, masks, compactedPixels);
|
||||
rays.PixelIdx = compactedPixels;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> compactedStatus;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(rays.Status, masks, compactedStatus);
|
||||
vtkm::cont::Algorithm::CopyIf(rays.Status, masks, compactedStatus);
|
||||
rays.Status = compactedStatus;
|
||||
|
||||
rays.NumRays = rays.Status.GetPortalConstControl().GetNumberOfValues();
|
||||
@ -291,7 +287,7 @@ public:
|
||||
const size_t bufferCount = static_cast<size_t>(rays.Buffers.size());
|
||||
for (size_t i = 0; i < bufferCount; ++i)
|
||||
{
|
||||
ChannelBufferOperations::Compact(rays.Buffers[i], masks, rays.NumRays, Device());
|
||||
ChannelBufferOperations::Compact(rays.Buffers[i], masks, rays.NumRays);
|
||||
}
|
||||
return masks;
|
||||
}
|
||||
@ -340,12 +336,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Device, typename T>
|
||||
static void CopyDistancesToMin(Ray<T> rays, Device, const T offset = 0.f)
|
||||
template <typename T>
|
||||
static void CopyDistancesToMin(Ray<T> rays, const T offset = 0.f)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<CopyAndOffsetMask<T>> dispatcher{ (
|
||||
CopyAndOffsetMask<T>{ offset, RAY_EXITED_MESH }) };
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.Distance, rays.MinDistance, rays.Status);
|
||||
}
|
||||
};
|
||||
|
@ -141,6 +141,8 @@ public:
|
||||
IdArrayPortal PointIds;
|
||||
FloatPortal Radii;
|
||||
|
||||
SphereLeafIntersector() {}
|
||||
|
||||
SphereLeafIntersector(const IdHandle& pointIds, const FloatHandle& radii)
|
||||
: PointIds(pointIds.PrepareForInput(Device()))
|
||||
, Radii(radii.PrepareForInput(Device()))
|
||||
@ -193,17 +195,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct IntersectFunctor
|
||||
class SphereLeafWrapper : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
SphereIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
protected:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using FloatHandle = vtkm::cont::ArrayHandle<vtkm::Float32>;
|
||||
IdHandle PointIds;
|
||||
FloatHandle Radii;
|
||||
|
||||
public:
|
||||
SphereLeafWrapper(IdHandle& pointIds, FloatHandle radii)
|
||||
: PointIds(pointIds)
|
||||
, Radii(radii)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRaysImp(Device(), rays, returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT SphereLeafIntersector<Device> PrepareForExecution(Device) const
|
||||
{
|
||||
return SphereLeafIntersector<Device>(PointIds, Radii);
|
||||
}
|
||||
};
|
||||
|
||||
@ -321,24 +331,22 @@ void SphereIntersector::SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
|
||||
void SphereIntersector::IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
IntersectRaysImp(rays, returnCellIndex);
|
||||
}
|
||||
|
||||
void SphereIntersector::IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex)
|
||||
{
|
||||
vtkm::cont::TryExecute(detail::IntersectFunctor(), this, rays, returnCellIndex);
|
||||
IntersectRaysImp(rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void SphereIntersector::IntersectRaysImp(Device,
|
||||
Ray<Precision>& rays,
|
||||
bool vtkmNotUsed(returnCellIndex))
|
||||
template <typename Precision>
|
||||
void SphereIntersector::IntersectRaysImp(Ray<Precision>& rays, bool vtkmNotUsed(returnCellIndex))
|
||||
{
|
||||
|
||||
detail::SphereLeafIntersector<Device> leafIntersector(this->PointIds, Radii);
|
||||
detail::SphereLeafWrapper leafIntersector(this->PointIds, Radii);
|
||||
|
||||
BVHTraverser<detail::SphereLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
BVHTraverser traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle);
|
||||
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
|
@ -48,8 +48,8 @@ public:
|
||||
|
||||
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 IntersectRaysImp(Ray<Precision>& rays, bool returnCellIndex);
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
|
@ -19,16 +19,11 @@
|
||||
//============================================================================
|
||||
#ifndef vtk_m_rendering_raytracing_TriagnleIntersector_h
|
||||
#define vtk_m_rendering_raytracing_TriagnleIntersector_h
|
||||
#include <cstring>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||
#include <vtkm/rendering/internal/RunTriangulator.h>
|
||||
#include <vtkm/rendering/raytracing/BVHTraverser.h>
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/ShapeIntersector.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -37,896 +32,44 @@ namespace rendering
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class Moller
|
||||
{
|
||||
public:
|
||||
template <typename Precision>
|
||||
VTKM_EXEC void IntersectTri(const vtkm::Vec<Precision, 3>& a,
|
||||
const vtkm::Vec<Precision, 3>& b,
|
||||
const vtkm::Vec<Precision, 3>& c,
|
||||
const vtkm::Vec<Precision, 3>& dir,
|
||||
Precision& distance,
|
||||
Precision& u,
|
||||
Precision& v,
|
||||
const vtkm::Vec<Precision, 3>& origin) const
|
||||
{
|
||||
const vtkm::Float32 EPSILON2 = 0.0001f;
|
||||
|
||||
vtkm::Vec<Precision, 3> e1 = b - a;
|
||||
vtkm::Vec<Precision, 3> e2 = c - a;
|
||||
|
||||
vtkm::Vec<Precision, 3> p;
|
||||
p[0] = dir[1] * e2[2] - dir[2] * e2[1];
|
||||
p[1] = dir[2] * e2[0] - dir[0] * e2[2];
|
||||
p[2] = dir[0] * e2[1] - dir[1] * e2[0];
|
||||
Precision dot = e1[0] * p[0] + e1[1] * p[1] + e1[2] * p[2];
|
||||
if (dot != 0.f)
|
||||
{
|
||||
dot = 1.f / dot;
|
||||
vtkm::Vec<Precision, 3> t;
|
||||
t = origin - a;
|
||||
|
||||
u = (t[0] * p[0] + t[1] * p[1] + t[2] * p[2]) * dot;
|
||||
if (u >= (0.f - EPSILON2) && u <= (1.f + EPSILON2))
|
||||
{
|
||||
|
||||
vtkm::Vec<Precision, 3> q; // = t % e1;
|
||||
q[0] = t[1] * e1[2] - t[2] * e1[1];
|
||||
q[1] = t[2] * e1[0] - t[0] * e1[2];
|
||||
q[2] = t[0] * e1[1] - t[1] * e1[0];
|
||||
v = (dir[0] * q[0] + dir[1] * q[1] + dir[2] * q[2]) * dot;
|
||||
if (v >= (0.f - EPSILON2) && v <= (1.f + EPSILON2) && !(u + v > 1.f))
|
||||
{
|
||||
distance = (e2[0] * q[0] + e2[1] * q[1] + e2[2] * q[2]) * dot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; //Moller
|
||||
|
||||
|
||||
|
||||
// TODO: optimization for sorting ray dims before this call.
|
||||
// This is called multiple times and kz,kx, and ky are
|
||||
// constant for the ray
|
||||
|
||||
|
||||
class WaterTight
|
||||
{
|
||||
public:
|
||||
template <typename Precision>
|
||||
VTKM_EXEC inline void FindDir(const vtkm::Vec<Precision, 3>& dir,
|
||||
vtkm::Vec<Precision, 3>& s,
|
||||
vtkm::Vec<Int32, 3>& k) const
|
||||
{
|
||||
//Find max ray direction
|
||||
k[2] = 0;
|
||||
if (vtkm::Abs(dir[0]) > vtkm::Abs(dir[1]))
|
||||
{
|
||||
if (vtkm::Abs(dir[0]) > vtkm::Abs(dir[2]))
|
||||
k[2] = 0;
|
||||
else
|
||||
k[2] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vtkm::Abs(dir[1]) > vtkm::Abs(dir[2]))
|
||||
k[2] = 1;
|
||||
else
|
||||
k[2] = 2;
|
||||
}
|
||||
|
||||
k[0] = k[2] + 1;
|
||||
if (k[0] == 3)
|
||||
k[0] = 0;
|
||||
k[1] = k[0] + 1;
|
||||
if (k[1] == 3)
|
||||
k[1] = 0;
|
||||
|
||||
if (dir[k[2]] < 0.f)
|
||||
{
|
||||
vtkm::Int32 temp = k[1];
|
||||
k[1] = k[0];
|
||||
k[0] = temp;
|
||||
}
|
||||
|
||||
s[0] = dir[k[0]] / dir[k[2]];
|
||||
s[1] = dir[k[1]] / dir[k[2]];
|
||||
s[2] = 1.f / dir[k[2]];
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
VTKM_EXEC_CONT inline void IntersectTri(const vtkm::Vec<Precision, 3>& a,
|
||||
const vtkm::Vec<Precision, 3>& b,
|
||||
const vtkm::Vec<Precision, 3>& c,
|
||||
const vtkm::Vec<Precision, 3>& dir,
|
||||
Precision& distance,
|
||||
Precision& u,
|
||||
Precision& v,
|
||||
const vtkm::Vec<Precision, 3>& origin) const
|
||||
{
|
||||
vtkm::Vec<Int32, 3> k;
|
||||
vtkm::Vec<Precision, 3> s;
|
||||
//Find max ray direction
|
||||
k[2] = 0;
|
||||
if (vtkm::Abs(dir[0]) > vtkm::Abs(dir[1]))
|
||||
{
|
||||
if (vtkm::Abs(dir[0]) > vtkm::Abs(dir[2]))
|
||||
k[2] = 0;
|
||||
else
|
||||
k[2] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vtkm::Abs(dir[1]) > vtkm::Abs(dir[2]))
|
||||
k[2] = 1;
|
||||
else
|
||||
k[2] = 2;
|
||||
}
|
||||
|
||||
k[0] = k[2] + 1;
|
||||
if (k[0] == 3)
|
||||
k[0] = 0;
|
||||
k[1] = k[0] + 1;
|
||||
if (k[1] == 3)
|
||||
k[1] = 0;
|
||||
|
||||
if (dir[k[2]] < 0.f)
|
||||
{
|
||||
vtkm::Int32 temp = k[1];
|
||||
k[1] = k[0];
|
||||
k[0] = temp;
|
||||
}
|
||||
|
||||
s[0] = dir[k[0]] / dir[k[2]];
|
||||
s[1] = dir[k[1]] / dir[k[2]];
|
||||
s[2] = 1.f / dir[k[2]];
|
||||
|
||||
vtkm::Vec<Precision, 3> A, B, C;
|
||||
A = a - origin;
|
||||
B = b - origin;
|
||||
C = c - origin;
|
||||
|
||||
const Precision Ax = A[k[0]] - s[0] * A[k[2]];
|
||||
const Precision Ay = A[k[1]] - s[1] * A[k[2]];
|
||||
const Precision Bx = B[k[0]] - s[0] * B[k[2]];
|
||||
const Precision By = B[k[1]] - s[1] * B[k[2]];
|
||||
const Precision Cx = C[k[0]] - s[0] * C[k[2]];
|
||||
const Precision Cy = C[k[1]] - s[1] * C[k[2]];
|
||||
|
||||
//scaled barycentric coords
|
||||
u = Cx * By - Cy * Bx;
|
||||
v = Ax * Cy - Ay * Cx;
|
||||
Precision w = Bx * Ay - By * Ax;
|
||||
if (u == 0.f || v == 0.f || w == 0.f)
|
||||
{
|
||||
vtkm::Float64 CxBy = vtkm::Float64(Cx) * vtkm::Float64(By);
|
||||
vtkm::Float64 CyBx = vtkm::Float64(Cy) * vtkm::Float64(Bx);
|
||||
u = vtkm::Float32(CxBy - CyBx);
|
||||
|
||||
vtkm::Float64 AxCy = vtkm::Float64(Ax) * vtkm::Float64(Cy);
|
||||
vtkm::Float64 AyCx = vtkm::Float64(Ay) * vtkm::Float64(Cx);
|
||||
v = vtkm::Float32(AxCy - AyCx);
|
||||
|
||||
vtkm::Float64 BxAy = vtkm::Float64(Bx) * vtkm::Float64(Ay);
|
||||
vtkm::Float64 ByAx = vtkm::Float64(By) * vtkm::Float64(Ax);
|
||||
w = vtkm::Float32(BxAy - ByAx);
|
||||
}
|
||||
Precision low = vtkm::Min(u, vtkm::Min(v, w));
|
||||
Precision high = vtkm::Max(u, vtkm::Max(v, w));
|
||||
|
||||
bool invalid = (low < 0.) && (high > 0.);
|
||||
|
||||
Precision det = u + v + w;
|
||||
|
||||
if (det == 0.)
|
||||
invalid = true;
|
||||
|
||||
const Precision Az = s[2] * A[k[2]];
|
||||
const Precision Bz = s[2] * B[k[2]];
|
||||
const Precision Cz = s[2] * C[k[2]];
|
||||
|
||||
det = 1.f / det;
|
||||
|
||||
u = u * det;
|
||||
v = v * det;
|
||||
|
||||
distance = (u * Az + v * Bz + w * det * Cz);
|
||||
u = v;
|
||||
v = w * det;
|
||||
if (invalid)
|
||||
distance = -1.;
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
VTKM_EXEC inline void IntersectTriSn(const vtkm::Vec<Precision, 3>& a,
|
||||
const vtkm::Vec<Precision, 3>& b,
|
||||
const vtkm::Vec<Precision, 3>& c,
|
||||
const vtkm::Vec<Precision, 3>& s,
|
||||
const vtkm::Vec<Int32, 3>& k,
|
||||
Precision& distance,
|
||||
Precision& u,
|
||||
Precision& v,
|
||||
const vtkm::Vec<Precision, 3>& origin) const
|
||||
{
|
||||
vtkm::Vec<Precision, 3> A, B, C;
|
||||
A = a - origin;
|
||||
B = b - origin;
|
||||
C = c - origin;
|
||||
|
||||
const Precision Ax = A[k[0]] - s[0] * A[k[2]];
|
||||
const Precision Ay = A[k[1]] - s[1] * A[k[2]];
|
||||
const Precision Bx = B[k[0]] - s[0] * B[k[2]];
|
||||
const Precision By = B[k[1]] - s[1] * B[k[2]];
|
||||
const Precision Cx = C[k[0]] - s[0] * C[k[2]];
|
||||
const Precision Cy = C[k[1]] - s[1] * C[k[2]];
|
||||
|
||||
//scaled barycentric coords
|
||||
u = Cx * By - Cy * Bx;
|
||||
v = Ax * Cy - Ay * Cx;
|
||||
Precision w = Bx * Ay - By * Ax;
|
||||
if (u == 0.f || v == 0.f || w == 0.f)
|
||||
{
|
||||
vtkm::Float64 CxBy = vtkm::Float64(Cx) * vtkm::Float64(By);
|
||||
vtkm::Float64 CyBx = vtkm::Float64(Cy) * vtkm::Float64(Bx);
|
||||
u = vtkm::Float32(CxBy - CyBx);
|
||||
|
||||
vtkm::Float64 AxCy = vtkm::Float64(Ax) * vtkm::Float64(Cy);
|
||||
vtkm::Float64 AyCx = vtkm::Float64(Ay) * vtkm::Float64(Cx);
|
||||
v = vtkm::Float32(AxCy - AyCx);
|
||||
|
||||
vtkm::Float64 BxAy = vtkm::Float64(Bx) * vtkm::Float64(Ay);
|
||||
vtkm::Float64 ByAx = vtkm::Float64(By) * vtkm::Float64(Ax);
|
||||
w = vtkm::Float32(BxAy - ByAx);
|
||||
}
|
||||
|
||||
Precision low = vtkm::Min(u, vtkm::Min(v, w));
|
||||
Precision high = vtkm::Max(u, vtkm::Max(v, w));
|
||||
|
||||
bool invalid = (low < 0.) && (high > 0.);
|
||||
|
||||
Precision det = u + v + w;
|
||||
|
||||
if (det == 0.)
|
||||
invalid = true;
|
||||
|
||||
const Precision Az = s[2] * A[k[2]];
|
||||
const Precision Bz = s[2] * B[k[2]];
|
||||
const Precision Cz = s[2] * C[k[2]];
|
||||
|
||||
det = 1.f / det;
|
||||
|
||||
u = u * det;
|
||||
v = v * det;
|
||||
|
||||
distance = (u * Az + v * Bz + w * det * Cz);
|
||||
u = v;
|
||||
v = w * det;
|
||||
if (invalid)
|
||||
distance = -1.;
|
||||
}
|
||||
}; //WaterTight
|
||||
|
||||
template <>
|
||||
VTKM_EXEC inline void WaterTight::IntersectTri<vtkm::Float64>(
|
||||
const vtkm::Vec<vtkm::Float64, 3>& a,
|
||||
const vtkm::Vec<vtkm::Float64, 3>& b,
|
||||
const vtkm::Vec<vtkm::Float64, 3>& c,
|
||||
const vtkm::Vec<vtkm::Float64, 3>& dir,
|
||||
vtkm::Float64& distance,
|
||||
vtkm::Float64& u,
|
||||
vtkm::Float64& v,
|
||||
const vtkm::Vec<vtkm::Float64, 3>& origin) const
|
||||
{
|
||||
//Find max ray direction
|
||||
int kz = 0;
|
||||
if (vtkm::Abs(dir[0]) > vtkm::Abs(dir[1]))
|
||||
{
|
||||
if (vtkm::Abs(dir[0]) > vtkm::Abs(dir[2]))
|
||||
kz = 0;
|
||||
else
|
||||
kz = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vtkm::Abs(dir[1]) > vtkm::Abs(dir[2]))
|
||||
kz = 1;
|
||||
else
|
||||
kz = 2;
|
||||
}
|
||||
|
||||
vtkm::Int32 kx = kz + 1;
|
||||
if (kx == 3)
|
||||
kx = 0;
|
||||
vtkm::Int32 ky = kx + 1;
|
||||
if (ky == 3)
|
||||
ky = 0;
|
||||
|
||||
if (dir[kz] < 0.f)
|
||||
{
|
||||
vtkm::Int32 temp = ky;
|
||||
ky = kx;
|
||||
kx = temp;
|
||||
}
|
||||
|
||||
vtkm::Float64 Sx = dir[kx] / dir[kz];
|
||||
vtkm::Float64 Sy = dir[ky] / dir[kz];
|
||||
vtkm::Float64 Sz = 1. / dir[kz];
|
||||
|
||||
|
||||
|
||||
vtkm::Vec<vtkm::Float64, 3> A, B, C;
|
||||
A = a - origin;
|
||||
B = b - origin;
|
||||
C = c - origin;
|
||||
|
||||
const vtkm::Float64 Ax = A[kx] - Sx * A[kz];
|
||||
const vtkm::Float64 Ay = A[ky] - Sy * A[kz];
|
||||
const vtkm::Float64 Bx = B[kx] - Sx * B[kz];
|
||||
const vtkm::Float64 By = B[ky] - Sy * B[kz];
|
||||
const vtkm::Float64 Cx = C[kx] - Sx * C[kz];
|
||||
const vtkm::Float64 Cy = C[ky] - Sy * C[kz];
|
||||
|
||||
//scaled barycentric coords
|
||||
u = Cx * By - Cy * Bx;
|
||||
v = Ax * Cy - Ay * Cx;
|
||||
|
||||
vtkm::Float64 w = Bx * Ay - By * Ax;
|
||||
|
||||
vtkm::Float64 low = vtkm::Min(u, vtkm::Min(v, w));
|
||||
vtkm::Float64 high = vtkm::Max(u, vtkm::Max(v, w));
|
||||
bool invalid = (low < 0.) && (high > 0.);
|
||||
|
||||
vtkm::Float64 det = u + v + w;
|
||||
|
||||
if (det == 0.)
|
||||
invalid = true;
|
||||
|
||||
const vtkm::Float64 Az = Sz * A[kz];
|
||||
const vtkm::Float64 Bz = Sz * B[kz];
|
||||
const vtkm::Float64 Cz = Sz * C[kz];
|
||||
|
||||
det = 1. / det;
|
||||
|
||||
u = u * det;
|
||||
v = v * det;
|
||||
|
||||
distance = (u * Az + v * Bz + w * det * Cz);
|
||||
u = v;
|
||||
v = w * det;
|
||||
if (invalid)
|
||||
distance = -1.;
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
//class WaterTightTriLeafIntersector : public vtkm::exec::ExecutionObjectBase
|
||||
class WaterTightTriLeafIntersector
|
||||
{
|
||||
public:
|
||||
using Id4Handle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using Id4ArrayPortal = typename Id4Handle::ExecutionTypes<Device>::PortalConst;
|
||||
Id4ArrayPortal Triangles;
|
||||
|
||||
public:
|
||||
WaterTightTriLeafIntersector(const Id4Handle& triangles)
|
||||
: Triangles(triangles.PrepareForInput(Device()))
|
||||
{
|
||||
}
|
||||
|
||||
WaterTightTriLeafIntersector(const WaterTightTriLeafIntersector<Device>& other)
|
||||
: Triangles(other.Triangles)
|
||||
{
|
||||
}
|
||||
|
||||
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,
|
||||
Precision& minU,
|
||||
Precision& minV,
|
||||
LeafPortalType leafs,
|
||||
const Precision& minDistance) const
|
||||
{
|
||||
const vtkm::Id triangleCount = leafs.Get(currentNode);
|
||||
WaterTight intersector;
|
||||
for (vtkm::Id i = 1; i <= triangleCount; ++i)
|
||||
{
|
||||
const vtkm::Id triIndex = leafs.Get(currentNode + i);
|
||||
vtkm::Vec<Id, 4> triangle = Triangles.Get(triIndex);
|
||||
vtkm::Vec<Precision, 3> a = vtkm::Vec<Precision, 3>(points.Get(triangle[1]));
|
||||
vtkm::Vec<Precision, 3> b = vtkm::Vec<Precision, 3>(points.Get(triangle[2]));
|
||||
vtkm::Vec<Precision, 3> c = vtkm::Vec<Precision, 3>(points.Get(triangle[3]));
|
||||
Precision distance = -1.;
|
||||
Precision u, v;
|
||||
|
||||
intersector.IntersectTri(a, b, c, dir, distance, u, v, origin);
|
||||
if (distance != -1. && distance < closestDistance && distance > minDistance)
|
||||
{
|
||||
closestDistance = distance;
|
||||
minU = u;
|
||||
minV = v;
|
||||
hitIndex = triIndex;
|
||||
}
|
||||
} // for
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Device>
|
||||
//class MollerTriLeafIntersector : public vtkm::exec::ExecutionObjectBase
|
||||
class MollerTriLeafIntersector
|
||||
{
|
||||
//protected:
|
||||
public:
|
||||
using Id4Handle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using Id4ArrayPortal = typename Id4Handle::ExecutionTypes<Device>::PortalConst;
|
||||
Id4ArrayPortal Triangles;
|
||||
|
||||
public:
|
||||
MollerTriLeafIntersector(const Id4Handle& triangles)
|
||||
: Triangles(triangles.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,
|
||||
Precision& minU,
|
||||
Precision& minV,
|
||||
LeafPortalType leafs,
|
||||
const Precision& minDistance) const
|
||||
{
|
||||
const vtkm::Id triangleCount = leafs.Get(currentNode);
|
||||
Moller intersector;
|
||||
for (vtkm::Id i = 1; i <= triangleCount; ++i)
|
||||
{
|
||||
const vtkm::Id triIndex = leafs.Get(currentNode + i);
|
||||
vtkm::Vec<Id, 4> triangle = Triangles.Get(triIndex);
|
||||
vtkm::Vec<Precision, 3> a = vtkm::Vec<Precision, 3>(points.Get(triangle[1]));
|
||||
vtkm::Vec<Precision, 3> b = vtkm::Vec<Precision, 3>(points.Get(triangle[2]));
|
||||
vtkm::Vec<Precision, 3> c = vtkm::Vec<Precision, 3>(points.Get(triangle[3]));
|
||||
Precision distance = -1.;
|
||||
Precision u, v;
|
||||
|
||||
intersector.IntersectTri(a, b, c, dir, distance, u, v, origin);
|
||||
|
||||
if (distance != -1. && distance < closestDistance && distance > minDistance)
|
||||
{
|
||||
closestDistance = distance;
|
||||
minU = u;
|
||||
minV = v;
|
||||
hitIndex = triIndex;
|
||||
}
|
||||
} // for
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
VTKM_EXEC inline void swap(T& a, T& b)
|
||||
{
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float32 up(const vtkm::Float32& a)
|
||||
{
|
||||
return (a > 0.f) ? a * (1.f + vtkm::Float32(2e-23)) : a * (1.f - vtkm::Float32(2e-23));
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float32 down(const vtkm::Float32& a)
|
||||
{
|
||||
return (a > 0.f) ? a * (1.f - vtkm::Float32(2e-23)) : a * (1.f + vtkm::Float32(2e-23));
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float32 upFast(const vtkm::Float32& a)
|
||||
{
|
||||
return a * (1.f + vtkm::Float32(2e-23));
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Float32 downFast(const vtkm::Float32& a)
|
||||
{
|
||||
return a * (1.f - vtkm::Float32(2e-23));
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class TriangleIntersectionData
|
||||
{
|
||||
public:
|
||||
// Worklet to calutate the normals of a triagle if
|
||||
// none are stored in the data set
|
||||
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<Id, 4> indices = indicesPortal.Get(hitIndex);
|
||||
vtkm::Vec<Precision, 3> a = points.Get(indices[1]);
|
||||
vtkm::Vec<Precision, 3> b = points.Get(indices[2]);
|
||||
vtkm::Vec<Precision, 3> c = points.Get(indices[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 LerpScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
LerpScalar(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 = 0.f;
|
||||
}
|
||||
typedef void ControlSignature(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldInOut<>,
|
||||
WholeArrayIn<ScalarRenderingTypes>,
|
||||
WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6);
|
||||
template <typename ScalarPortalType, typename IndicesPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
||||
const Precision& u,
|
||||
const Precision& v,
|
||||
Precision& lerpedScalar,
|
||||
const ScalarPortalType& scalars,
|
||||
const IndicesPortalType& indicesPortal) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Vec<Id, 4> indices = indicesPortal.Get(hitIndex);
|
||||
|
||||
Precision n = 1.f - u - v;
|
||||
Precision aScalar = Precision(scalars.Get(indices[1]));
|
||||
Precision bScalar = Precision(scalars.Get(indices[2]));
|
||||
Precision cScalar = Precision(scalars.Get(indices[3]));
|
||||
lerpedScalar = aScalar * n + bScalar * u + cScalar * v;
|
||||
//normalize
|
||||
lerpedScalar = (lerpedScalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class LerpScalar
|
||||
|
||||
template <typename Precision>
|
||||
class NodalScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
NodalScalar(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<>,
|
||||
FieldOut<>,
|
||||
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::Vec<Id, 4> indices = indicesPortal.Get(hitIndex);
|
||||
|
||||
//Todo: one normalization
|
||||
scalar = Precision(scalars.Get(indices[0]));
|
||||
|
||||
//normalize
|
||||
scalar = (scalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class LerpScalar
|
||||
|
||||
template <typename Precision>
|
||||
VTKM_CONT void Run(Ray<Precision>& rays,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
|
||||
vtkm::cont::CoordinateSystem coordsHandle,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
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 cell set or points");
|
||||
bool isAssocPoints = scalarField->GetAssociation() == vtkm::cont::Field::Association::POINTS;
|
||||
|
||||
// Find the triangle normal
|
||||
vtkm::worklet::DispatcherMapField<CalculateNormals>(CalculateNormals())
|
||||
.Invoke(
|
||||
rays.HitIdx, rays.Dir, rays.NormalX, rays.NormalY, rays.NormalZ, coordsHandle, triangles);
|
||||
|
||||
// Calculate scalar value at intersection point
|
||||
if (isAssocPoints)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<LerpScalar<Precision>>(
|
||||
LerpScalar<Precision>(vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)))
|
||||
.Invoke(rays.HitIdx, rays.U, rays.V, rays.Scalar, *scalarField, triangles);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<NodalScalar<Precision>>(
|
||||
NodalScalar<Precision>(vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)))
|
||||
.Invoke(rays.HitIdx, rays.Scalar, *scalarField, triangles);
|
||||
}
|
||||
} // Run
|
||||
|
||||
}; // Class IntersectionData
|
||||
|
||||
#define AABB_EPSILON 0.00001f
|
||||
class FindTriangleAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
FindTriangleAABBs() {}
|
||||
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, 4> indices,
|
||||
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;
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(indices[1]));
|
||||
xmin = point[0];
|
||||
ymin = point[1];
|
||||
zmin = point[2];
|
||||
xmax = xmin;
|
||||
ymax = ymin;
|
||||
zmax = zmin;
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(indices[2]));
|
||||
xmin = vtkm::Min(xmin, point[0]);
|
||||
ymin = vtkm::Min(ymin, point[1]);
|
||||
zmin = vtkm::Min(zmin, point[2]);
|
||||
xmax = vtkm::Max(xmax, point[0]);
|
||||
ymax = vtkm::Max(ymax, point[1]);
|
||||
zmax = vtkm::Max(zmax, point[2]);
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(indices[3]));
|
||||
xmin = vtkm::Min(xmin, point[0]);
|
||||
ymin = vtkm::Min(ymin, point[1]);
|
||||
zmin = vtkm::Min(zmin, point[2]);
|
||||
xmax = vtkm::Max(xmax, point[0]);
|
||||
ymax = vtkm::Max(ymax, point[1]);
|
||||
zmax = vtkm::Max(zmax, point[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
|
||||
#undef AABB_EPSILON
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class TriangleIntersector : public ShapeIntersector
|
||||
class VTKM_RENDERING_EXPORT TriangleIntersector : public ShapeIntersector
|
||||
{
|
||||
protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Triangles;
|
||||
bool UseWaterTight;
|
||||
|
||||
public:
|
||||
TriangleIntersector()
|
||||
: UseWaterTight(false)
|
||||
{
|
||||
}
|
||||
TriangleIntersector();
|
||||
|
||||
void SetUseWaterTight(bool useIt) { UseWaterTight = useIt; }
|
||||
void SetUseWaterTight(bool useIt);
|
||||
|
||||
void SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles);
|
||||
|
||||
CoordsHandle = coords;
|
||||
Triangles = triangles;
|
||||
|
||||
vtkm::rendering::raytracing::AABBs AABB;
|
||||
vtkm::worklet::DispatcherMapField<detail::FindTriangleAABBs>(detail::FindTriangleAABBs())
|
||||
.Invoke(Triangles,
|
||||
AABB.xmins,
|
||||
AABB.ymins,
|
||||
AABB.zmins,
|
||||
AABB.xmaxs,
|
||||
AABB.ymaxs,
|
||||
AABB.zmaxs,
|
||||
CoordsHandle);
|
||||
|
||||
this->SetAABBs(AABB);
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles() { return Triangles; }
|
||||
|
||||
class CellIndexFilter : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CellIndexFilter() {}
|
||||
typedef void ControlSignature(FieldInOut<>, WholeArrayIn<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
template <typename TrianglePortalType>
|
||||
VTKM_EXEC void operator()(vtkm::Id& hitIndex, TrianglePortalType& triangles) const
|
||||
{
|
||||
vtkm::Id cellIndex = -1;
|
||||
if (hitIndex != -1)
|
||||
{
|
||||
cellIndex = triangles.Get(hitIndex)[0];
|
||||
}
|
||||
|
||||
hitIndex = cellIndex;
|
||||
}
|
||||
}; //class CellIndexFilter
|
||||
|
||||
struct IntersectFunctor
|
||||
{
|
||||
template <typename Device, typename Precision>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
TriangleIntersector* self,
|
||||
Ray<Precision>& rays,
|
||||
bool returnCellIndex)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->IntersectRays(rays, Device(), returnCellIndex);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles();
|
||||
vtkm::Id GetNumberOfShapes() const override;
|
||||
|
||||
|
||||
VTKM_CONT void IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex = false) override
|
||||
{
|
||||
vtkm::cont::TryExecute(IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
VTKM_CONT void IntersectRays(Ray<vtkm::Float32>& rays, bool returnCellIndex = false) override;
|
||||
VTKM_CONT void IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex = false) override;
|
||||
|
||||
|
||||
VTKM_CONT void IntersectRays(Ray<vtkm::Float64>& rays, bool returnCellIndex = false) override
|
||||
{
|
||||
vtkm::cont::TryExecute(IntersectFunctor(), this, rays, returnCellIndex);
|
||||
}
|
||||
|
||||
template <typename Precision, typename Device>
|
||||
VTKM_CONT void IntersectRays(Ray<Precision>& rays,
|
||||
Device vtkmNotUsed(Device),
|
||||
bool returnCellIndex)
|
||||
{
|
||||
|
||||
if (UseWaterTight)
|
||||
{
|
||||
WaterTightTriLeafIntersector<Device> leafIntersector(this->Triangles);
|
||||
|
||||
BVHTraverser<WaterTightTriLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
}
|
||||
else
|
||||
{
|
||||
MollerTriLeafIntersector<Device> leafIntersector(this->Triangles);
|
||||
|
||||
BVHTraverser<MollerTriLeafIntersector> traverser;
|
||||
traverser.IntersectRays(rays, this->BVH, leafIntersector, this->CoordsHandle, Device());
|
||||
}
|
||||
// Normally we return the index of the triangle hit,
|
||||
// but in some cases we are only interested in the cell
|
||||
if (returnCellIndex)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<CellIndexFilter> cellIndexFilterDispatcher;
|
||||
cellIndexFilterDispatcher.Invoke(rays.HitIdx, Triangles);
|
||||
}
|
||||
// Update ray status
|
||||
RayOperations::UpdateRayStatus(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT void IntersectionData(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) override
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
VTKM_CONT void IntersectionData(Ray<vtkm::Float64>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange) override
|
||||
{
|
||||
IntersectionDataImp(rays, scalarField, scalarRange);
|
||||
}
|
||||
const vtkm::Range& scalarRange) override;
|
||||
|
||||
template <typename Precision>
|
||||
VTKM_CONT void IntersectRaysImp(Ray<Precision>& rays, bool returnCellIndex);
|
||||
|
||||
template <typename Precision>
|
||||
VTKM_CONT void IntersectionDataImp(Ray<Precision>& rays,
|
||||
const vtkm::cont::Field* scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
ShapeIntersector::IntersectionPoint(rays);
|
||||
detail::TriangleIntersectionData intData;
|
||||
intData.Run(rays, this->Triangles, this->CoordsHandle, scalarField, scalarRange);
|
||||
}
|
||||
const vtkm::Range& scalarRange);
|
||||
|
||||
vtkm::Id GetNumberOfShapes() const override { return Triangles.GetNumberOfValues(); }
|
||||
}; // class intersector
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user