let there be scalar things

This commit is contained in:
Matt Larsen 2020-02-17 19:00:09 -08:00
parent 1fc064dcf8
commit b4b7519584
15 changed files with 378 additions and 23 deletions

@ -63,6 +63,7 @@ set(headers
MapperConnectivity.h
MapperWireframer.h
Quadralizer.h
ScalarRenderer.h
TextAnnotation.h
TextAnnotationBillboard.h
TextAnnotationScreen.h
@ -109,6 +110,7 @@ set(device_sources
MapperRayTracer.cxx
MapperVolume.cxx
MapperWireframer.cxx
ScalarRenderer.cxx
Scene.cxx
TextAnnotation.cxx
TextAnnotationBillboard.cxx

@ -210,7 +210,7 @@ public:
throw vtkm::cont::ErrorBadValue("Conn Proxy: null canvas");
}
vtkm::rendering::raytracing::Camera rayCamera;
rayCamera.SetParameters(camera, *canvas);
rayCamera.SetParameters(camera, canvas->GetWidth(), canvas->GetHeight());
vtkm::rendering::raytracing::Ray<vtkm::Float32> rays;
rayCamera.CreateRays(rays, this->Coords.GetBounds());
rays.Buffers.at(0).InitConst(0.f);

@ -182,9 +182,10 @@ void MapperCylinder::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
//
// Create rays
//
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
cam.SetParameters(camera, *this->Internals->Canvas);
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
vtkm::Int32 width = this->Internals->Canvas->GetWidth();
vtkm::Int32 height = this->Internals->Canvas->GetHeight();
this->Internals->RayCamera.SetParameters(camera, width, height);
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
this->Internals->Rays.Buffers.at(0).InitConst(0.f);

@ -181,9 +181,10 @@ void MapperPoint::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
//
// Create rays
//
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
cam.SetParameters(camera, *this->Internals->Canvas);
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
vtkm::Int32 width = this->Internals->Canvas->GetWidth();
vtkm::Int32 height = this->Internals->Canvas->GetHeight();
this->Internals->RayCamera.SetParameters(camera, width, height);
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
this->Internals->Rays.Buffers.at(0).InitConst(0.f);

@ -103,9 +103,10 @@ void MapperQuad::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
//
// Create rays
//
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
cam.SetParameters(camera, *this->Internals->Canvas);
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
vtkm::Int32 width = this->Internals->Canvas->GetWidth();
vtkm::Int32 height = this->Internals->Canvas->GetHeight();
this->Internals->RayCamera.SetParameters(camera, width, height);
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
this->Internals->Rays.Buffers.at(0).InitConst(0.f);

@ -107,9 +107,10 @@ void MapperRayTracer::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
//
// Create rays
//
vtkm::rendering::raytracing::Camera& cam = this->Internals->Tracer.GetCamera();
cam.SetParameters(camera, *this->Internals->Canvas);
this->Internals->RayCamera.SetParameters(camera, *this->Internals->Canvas);
vtkm::Int32 width = this->Internals->Canvas->GetWidth();
vtkm::Int32 height = this->Internals->Canvas->GetHeight();
this->Internals->RayCamera.SetParameters(camera, width, height);
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
this->Internals->Rays.Buffers.at(0).InitConst(0.f);

@ -47,8 +47,6 @@ public:
private:
struct InternalsType;
std::shared_ptr<InternalsType> Internals;
struct RenderFunctor;
};
}
} //namespace vtkm::rendering

@ -14,7 +14,6 @@
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/raytracing/Camera.h>
#include <vtkm/rendering/raytracing/Logger.h>
#include <vtkm/rendering/raytracing/RayOperations.h>
@ -103,7 +102,10 @@ void MapperVolume::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
vtkm::rendering::raytracing::Camera rayCamera;
vtkm::rendering::raytracing::Ray<vtkm::Float32> rays;
rayCamera.SetParameters(camera, *this->Internals->Canvas);
vtkm::Int32 width = this->Internals->Canvas->GetWidth();
vtkm::Int32 height = this->Internals->Canvas->GetHeight();
rayCamera.SetParameters(camera, width, height);
rayCamera.CreateRays(rays, coords.GetBounds());
rays.Buffers.at(0).InitConst(0.f);

@ -0,0 +1,218 @@
//============================================================================
// 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/ScalarRenderer.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/raytracing/Camera.h>
#include <vtkm/rendering/raytracing/Logger.h>
#include <vtkm/rendering/raytracing/RayOperations.h>
#include <vtkm/rendering/raytracing/ScalarRenderer.h>
#include <vtkm/rendering/raytracing/SphereExtractor.h>
#include <vtkm/rendering/raytracing/SphereIntersector.h>
#include <vtkm/rendering/raytracing/TriangleExtractor.h>
#include <vtkm/io/writer/VTKDataSetWriter.h>
namespace vtkm
{
namespace rendering
{
struct ScalarRenderer::InternalsType
{
bool ValidDataSet;
vtkm::Int32 Width;
vtkm::Int32 Height;
vtkm::Float32 DefaultValue;
vtkm::cont::DataSet DataSet;
vtkm::rendering::raytracing::ScalarRenderer Tracer;
vtkm::Bounds ShapeBounds;
VTKM_CONT
InternalsType()
: ValidDataSet(false)
, Width(1024)
, Height(1024)
, DefaultValue(vtkm::Nan32())
{
}
};
ScalarRenderer::ScalarRenderer()
: Internals(new InternalsType)
{
}
ScalarRenderer::~ScalarRenderer()
{
}
void ScalarRenderer::SetWidth(const vtkm::Int32 width)
{
if (width < 1)
{
throw vtkm::cont::ErrorBadValue("ScalarRenderer: width must be greater than 0");
}
Internals->Width = width;
}
void ScalarRenderer::SetDefaultValue(const vtkm::Float32 value)
{
Internals->DefaultValue = value;
}
void ScalarRenderer::SetHeight(const vtkm::Int32 height)
{
if (height < 1)
{
throw vtkm::cont::ErrorBadValue("ScalarRenderer: height must be greater than 0");
}
Internals->Height = height;
}
void ScalarRenderer::SetInput(vtkm::cont::DataSet& dataSet)
{
this->Internals->DataSet = dataSet;
this->Internals->ValidDataSet = true;
raytracing::TriangleExtractor triExtractor;
vtkm::cont::DynamicCellSet cellSet = this->Internals->DataSet.GetCellSet();
vtkm::cont::CoordinateSystem coords = this->Internals->DataSet.GetCoordinateSystem();
triExtractor.ExtractCells(cellSet);
if (triExtractor.GetNumberOfTriangles() > 0)
{
auto triIntersector = std::make_shared<raytracing::TriangleIntersector>();
triIntersector->SetData(coords, triExtractor.GetTriangles());
this->Internals->Tracer.SetShapeIntersector(triIntersector);
this->Internals->ShapeBounds = triIntersector->GetShapeBounds();
}
}
ScalarRenderer::Result ScalarRenderer::Render(const vtkm::rendering::Camera& camera)
{
if (Internals->ValidDataSet)
{
throw vtkm::cont::ErrorBadValue("ScalarRenderer: input never set");
}
raytracing::Logger* logger = raytracing::Logger::GetInstance();
logger->OpenLogEntry("scalar_render");
vtkm::cont::Timer tot_timer;
tot_timer.Start();
vtkm::cont::Timer timer;
timer.Start();
//
// Create rays
//
vtkm::rendering::raytracing::Camera cam;
cam.SetParameters(camera, this->Internals->Width, this->Internals->Height);
vtkm::rendering::raytracing::Ray<vtkm::Float32> rays;
cam.CreateRays(rays, this->Internals->ShapeBounds);
rays.Buffers.at(0).InitConst(0.f);
// add fields
const vtkm::Id numFields = this->Internals->DataSet.GetNumberOfFields();
std::map<std::string, vtkm::Range> rangeMap;
for (vtkm::Id i = 0; i < numFields; ++i)
{
vtkm::cont::Field field = this->Internals->DataSet.GetField(i);
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
ranges = field.GetRange();
vtkm::Id comps = ranges.GetNumberOfValues();
if (comps == 1)
{
rangeMap[field.GetName()] = ranges.GetPortalControl().Get(0);
this->Internals->Tracer.AddField(field);
}
}
this->Internals->Tracer.Render(rays, Internals->DefaultValue);
using ArrayF32 = vtkm::cont::ArrayHandle<vtkm::Float32>;
std::vector<ArrayF32> res;
std::vector<std::string> names;
const size_t numBuffers = rays.Buffers.size();
vtkm::Id expandSize = Internals->Width * Internals->Height;
for (size_t i = 0; i < numBuffers; ++i)
{
const std::string name = rays.Buffers[i].GetName();
if (name == "default")
continue;
raytracing::ChannelBuffer<vtkm::Float32> buffer = rays.Buffers[i];
raytracing::ChannelBuffer<vtkm::Float32> expanded =
buffer.ExpandBuffer(rays.PixelIdx, expandSize, Internals->DefaultValue);
res.push_back(expanded.Buffer);
names.push_back(name);
}
raytracing::ChannelBuffer<vtkm::Float32> depthChannel(1, rays.NumRays);
depthChannel.Buffer = rays.Distance;
raytracing::ChannelBuffer<vtkm::Float32> depthExpanded =
depthChannel.ExpandBuffer(rays.PixelIdx, expandSize, Internals->DefaultValue);
res.push_back(depthExpanded.Buffer);
names.push_back("depth");
Result result;
result.Width = Internals->Width;
result.Height = Internals->Height;
result.Scalars = res;
result.ScalarNames = names;
result.Ranges = rangeMap;
vtkm::Float64 time = timer.GetElapsedTime();
logger->AddLogData("write_to_canvas", time);
time = tot_timer.GetElapsedTime();
logger->CloseLogEntry(time);
return result;
}
void ScalarRenderer::Result::SaveVTK(const std::string filename)
{
if (Scalars.size() == 0)
{
throw vtkm::cont::ErrorBadValue("ScalarRenderer: result empty");
}
VTKM_ASSERT(Width > 0);
VTKM_ASSERT(Height > 0);
vtkm::cont::DataSet result;
vtkm::Vec<vtkm::Float32, 3> origin(0.f, 0.f, 0.f);
vtkm::Vec<vtkm::Float32, 3> spacing(1.f, 1.f, 1.f);
vtkm::Id3 dims(Width + 1, Height + 1, 1);
result.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coords", dims, origin, spacing));
vtkm::Id2 dims2(dims[0], dims[1]);
vtkm::cont::CellSetStructured<2> resCellSet;
resCellSet.SetPointDimensions(dims2);
result.SetCellSet(resCellSet);
const size_t fieldSize = Scalars.size();
for (size_t i = 0; i < fieldSize; ++i)
{
result.AddField(
vtkm::cont::Field(ScalarNames[i], vtkm::cont::Field::Association::CELL_SET, Scalars[i]));
}
vtkm::io::writer::VTKDataSetWriter writer(filename + ".vtk");
writer.WriteDataSet(result);
}
}
} // vtkm::rendering

@ -0,0 +1,57 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_rendering_ScalarRenderer_h
#define vtk_m_rendering_ScalarRenderer_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/Camera.h>
#include <memory>
namespace vtkm
{
namespace rendering
{
class VTKM_RENDERING_EXPORT ScalarRenderer
{
public:
ScalarRenderer();
~ScalarRenderer();
void SetInput(vtkm::cont::DataSet& dataSet);
void SetWidth(const vtkm::Int32 width);
void SetHeight(const vtkm::Int32 height);
void SetDefaultValue(vtkm::Float32 value);
struct Result
{
vtkm::Int32 Width;
vtkm::Int32 Height;
std::vector<vtkm::cont::ArrayHandle<vtkm::Float32>> Scalars;
std::vector<std::string> ScalarNames;
std::map<std::string, vtkm::Range> Ranges;
void SaveVTK(const std::string filename);
};
ScalarRenderer::Result Render(const vtkm::rendering::Camera& camera);
private:
struct InternalsType;
std::shared_ptr<InternalsType> Internals;
};
}
} //namespace vtkm::rendering
#endif //vtk_m_rendering_ScalarRenderer_h

@ -494,17 +494,17 @@ Camera::~Camera()
VTKM_CONT
void Camera::SetParameters(const vtkm::rendering::Camera& camera,
vtkm::rendering::CanvasRayTracer& canvas)
const vtkm::Int32 width,
const vtkm::Int32 height)
{
this->SetUp(camera.GetViewUp());
this->SetLookAt(camera.GetLookAt());
this->SetPosition(camera.GetPosition());
this->SetZoom(camera.GetZoom());
this->SetFieldOfView(camera.GetFieldOfView());
this->SetHeight(static_cast<vtkm::Int32>(canvas.GetHeight()));
this->SetWidth(static_cast<vtkm::Int32>(canvas.GetWidth()));
this->SetHeight(height);
this->SetWidth(width);
this->CameraView = camera;
Canvas = canvas;
}

@ -27,7 +27,6 @@ class VTKM_RENDERING_EXPORT Camera
private:
struct PixelDataFunctor;
vtkm::rendering::CanvasRayTracer Canvas;
vtkm::Int32 Height;
vtkm::Int32 Width;
vtkm::Int32 SubsetWidth;
@ -61,7 +60,8 @@ public:
VTKM_CONT
void SetParameters(const vtkm::rendering::Camera& camera,
vtkm::rendering::CanvasRayTracer& canvas);
const vtkm::Int32 width,
const vtkm::Int32 height);
VTKM_CONT

@ -30,6 +30,34 @@ 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
{
@ -150,6 +178,10 @@ void ScalarRenderer::RenderOnDevice(Ray<Precision>& rays, Precision missScalar)
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

@ -24,6 +24,7 @@ set(unit_tests
UnitTestMapperRayTracer.cxx
UnitTestMapperWireframer.cxx
UnitTestMapperVolume.cxx
UnitTestScalarRenderer.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} ALL_BACKENDS LIBRARIES vtkm_rendering)

@ -0,0 +1,41 @@
//============================================================================
// 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/ScalarRenderer.h>
#include <vtkm/rendering/testing/RenderTest.h>
#include <vtkm/source/Tangle.h>
namespace
{
void RenderTests()
{
vtkm::cont::testing::MakeTestDataSet maker;
vtkm::cont::DataSet dataset = maker.Make3DRegularDataSet0();
vtkm::Bounds bounds = dataset.GetCoordinateSystem().GetBounds();
vtkm::rendering::Camera camera;
camera.ResetToBounds(bounds);
camera.Azimuth(-40.f);
camera.Elevation(15.f);
vtkm::rendering::ScalarRenderer renderer;
renderer.SetInput(dataset);
vtkm::rendering::ScalarRenderer::Result res = renderer.Render(camera);
res.SaveVTK("scalar");
}
} //namespace
int UnitTestScalarRenderer(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(RenderTests, argc, argv);
}