219 lines
5.5 KiB
C++
219 lines
5.5 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt for details.
|
|
//
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
//============================================================================
|
|
#include <vtkm/rendering/raytracing/ScalarRenderer.h>
|
|
|
|
#include <iostream>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
|
#include <vtkm/cont/ColorTable.h>
|
|
#include <vtkm/cont/Timer.h>
|
|
|
|
#include <vtkm/rendering/raytracing/Logger.h>
|
|
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
|
#include <vtkm/worklet/DispatcherMapField.h>
|
|
#include <vtkm/worklet/WorkletMapField.h>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace rendering
|
|
{
|
|
namespace raytracing
|
|
{
|
|
|
|
namespace detail
|
|
{
|
|
template <typename Precision>
|
|
class FilterDepth : public vtkm::worklet::WorkletMapField
|
|
{
|
|
private:
|
|
Precision MissScalar;
|
|
|
|
public:
|
|
VTKM_CONT
|
|
FilterDepth(const Precision missScalar)
|
|
: MissScalar(missScalar)
|
|
{
|
|
}
|
|
|
|
typedef void ControlSignature(FieldIn, FieldInOut);
|
|
|
|
typedef void ExecutionSignature(_1, _2);
|
|
VTKM_EXEC void operator()(const vtkm::Id& hitIndex, Precision& scalar) const
|
|
{
|
|
Precision value = scalar;
|
|
if (hitIndex < 0)
|
|
{
|
|
value = MissScalar;
|
|
}
|
|
|
|
scalar = value;
|
|
}
|
|
}; //class WriteBuffer
|
|
|
|
template <typename Precision>
|
|
class WriteBuffer : public vtkm::worklet::WorkletMapField
|
|
{
|
|
private:
|
|
Precision MissScalar;
|
|
|
|
public:
|
|
VTKM_CONT
|
|
WriteBuffer(const Precision missScalar)
|
|
: MissScalar(missScalar)
|
|
{
|
|
}
|
|
|
|
typedef void ControlSignature(FieldIn, FieldIn, FieldOut);
|
|
|
|
typedef void ExecutionSignature(_1, _2, _3);
|
|
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
|
const Precision& scalar,
|
|
Precision& output) const
|
|
{
|
|
Precision value = scalar;
|
|
if (hitIndex < 0)
|
|
{
|
|
value = MissScalar;
|
|
}
|
|
|
|
output = value;
|
|
}
|
|
}; //class WriteBuffer
|
|
|
|
template <typename Precision>
|
|
class WriteDepthBuffer : public vtkm::worklet::WorkletMapField
|
|
{
|
|
public:
|
|
VTKM_CONT
|
|
WriteDepthBuffer() {}
|
|
|
|
typedef void ControlSignature(FieldIn, FieldOut);
|
|
|
|
typedef void ExecutionSignature(_1, _2);
|
|
VTKM_EXEC void operator()(const Precision& depth, Precision& output) const { output = depth; }
|
|
}; //class WriteDepthBuffer
|
|
} // namespace detail
|
|
|
|
ScalarRenderer::ScalarRenderer()
|
|
: IntersectorValid(false)
|
|
{
|
|
}
|
|
|
|
ScalarRenderer::~ScalarRenderer()
|
|
{
|
|
}
|
|
|
|
void ScalarRenderer::SetShapeIntersector(std::shared_ptr<ShapeIntersector> intersector)
|
|
{
|
|
Intersector = intersector;
|
|
IntersectorValid = true;
|
|
}
|
|
|
|
void ScalarRenderer::AddField(const vtkm::cont::Field& scalarField)
|
|
{
|
|
vtkm::cont::ArrayHandle<vtkm::Range> ranges = scalarField.GetRange();
|
|
if (ranges.GetNumberOfValues() != 1)
|
|
{
|
|
throw vtkm::cont::ErrorBadValue("ScalarRenderer(AddField): field must be a scalar");
|
|
}
|
|
Ranges.push_back(ranges.ReadPortal().Get(0));
|
|
Fields.push_back(scalarField);
|
|
}
|
|
|
|
void ScalarRenderer::Render(Ray<vtkm::Float32>& rays, vtkm::Float32 missScalar)
|
|
{
|
|
RenderOnDevice(rays, missScalar);
|
|
}
|
|
|
|
void ScalarRenderer::Render(Ray<vtkm::Float64>& rays, vtkm::Float64 missScalar)
|
|
{
|
|
RenderOnDevice(rays, missScalar);
|
|
}
|
|
|
|
template <typename Precision>
|
|
void ScalarRenderer::RenderOnDevice(Ray<Precision>& rays, Precision missScalar)
|
|
{
|
|
using Timer = vtkm::cont::Timer;
|
|
|
|
Logger* logger = Logger::GetInstance();
|
|
Timer renderTimer;
|
|
renderTimer.Start();
|
|
vtkm::Float64 time = 0.;
|
|
logger->OpenLogEntry("scalar_renderer");
|
|
logger->AddLogData("device", GetDeviceString());
|
|
|
|
logger->AddLogData("num_rays", rays.NumRays);
|
|
const size_t numFields = Fields.size();
|
|
|
|
if (numFields == 0)
|
|
{
|
|
throw vtkm::cont::ErrorBadValue("ScalarRenderer: no fields added");
|
|
}
|
|
if (!IntersectorValid)
|
|
{
|
|
throw vtkm::cont::ErrorBadValue("ScalarRenderer: intersector never set");
|
|
}
|
|
|
|
Timer timer;
|
|
timer.Start();
|
|
|
|
Intersector->IntersectRays(rays);
|
|
time = timer.GetElapsedTime();
|
|
logger->AddLogData("intersect", time);
|
|
|
|
for (size_t f = 0; f < numFields; ++f)
|
|
{
|
|
timer.Start();
|
|
Intersector->IntersectionData(rays, Fields[f], Ranges[f]);
|
|
time = timer.GetElapsedTime();
|
|
logger->AddLogData("intersection_data", time);
|
|
AddBuffer(rays, missScalar, Fields[f].GetName());
|
|
}
|
|
|
|
vtkm::worklet::DispatcherMapField<detail::FilterDepth<Precision>>(
|
|
detail::FilterDepth<Precision>(missScalar))
|
|
.Invoke(rays.HitIdx, rays.Distance);
|
|
|
|
time = renderTimer.GetElapsedTime();
|
|
logger->CloseLogEntry(time);
|
|
} // RenderOnDevice
|
|
|
|
template <typename Precision>
|
|
void ScalarRenderer::AddBuffer(Ray<Precision>& rays, Precision missScalar, const std::string name)
|
|
{
|
|
const vtkm::Int32 numChannels = 1;
|
|
ChannelBuffer<Precision> buffer(numChannels, rays.NumRays);
|
|
|
|
vtkm::worklet::DispatcherMapField<detail::WriteBuffer<Precision>>(
|
|
detail::WriteBuffer<Precision>(missScalar))
|
|
.Invoke(rays.HitIdx, rays.Scalar, buffer.Buffer);
|
|
|
|
buffer.SetName(name);
|
|
rays.Buffers.push_back(buffer);
|
|
}
|
|
|
|
template <typename Precision>
|
|
void ScalarRenderer::AddDepthBuffer(Ray<Precision>& rays)
|
|
{
|
|
const vtkm::Int32 numChannels = 1;
|
|
ChannelBuffer<Precision> buffer(numChannels, rays.NumRays);
|
|
|
|
vtkm::worklet::DispatcherMapField<detail::WriteDepthBuffer<Precision>>(
|
|
detail::WriteDepthBuffer<Precision>())
|
|
.Invoke(rays.Depth, buffer.Buffer);
|
|
|
|
buffer.SetName("depth");
|
|
rays.Buffers.push_back(buffer);
|
|
}
|
|
}
|
|
}
|
|
} // namespace vtkm::rendering::raytracing
|