//============================================================================ // 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 #include #include #include #include #include #include #include #include #include #include namespace vtkm { namespace rendering { namespace raytracing { namespace detail { template 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 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 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 intersector) { Intersector = intersector; IntersectorValid = true; } void ScalarRenderer::AddField(const vtkm::cont::Field& scalarField) { vtkm::cont::ArrayHandle ranges = scalarField.GetRange(); if (ranges.GetNumberOfValues() != 1) { throw vtkm::cont::ErrorBadValue("ScalarRenderer(AddField): field must be a scalar"); } Fields.push_back(scalarField); } void ScalarRenderer::Render(Ray& rays, vtkm::Float32 missScalar) { RenderOnDevice(rays, missScalar); } void ScalarRenderer::Render(Ray& rays, vtkm::Float64 missScalar) { RenderOnDevice(rays, missScalar); } template void ScalarRenderer::RenderOnDevice(Ray& 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]); time = timer.GetElapsedTime(); logger->AddLogData("intersection_data", time); AddBuffer(rays, missScalar, Fields[f].GetName()); } vtkm::worklet::DispatcherMapField>( detail::FilterDepth(missScalar)) .Invoke(rays.HitIdx, rays.Distance); time = renderTimer.GetElapsedTime(); logger->CloseLogEntry(time); } // RenderOnDevice template void ScalarRenderer::AddBuffer(Ray& rays, Precision missScalar, const std::string name) { const vtkm::Int32 numChannels = 1; ChannelBuffer buffer(numChannels, rays.NumRays); vtkm::worklet::DispatcherMapField>( detail::WriteBuffer(missScalar)) .Invoke(rays.HitIdx, rays.Scalar, buffer.Buffer); buffer.SetName(name); rays.Buffers.push_back(buffer); } template void ScalarRenderer::AddDepthBuffer(Ray& rays) { const vtkm::Int32 numChannels = 1; ChannelBuffer buffer(numChannels, rays.NumRays); vtkm::worklet::DispatcherMapField>( detail::WriteDepthBuffer()) .Invoke(rays.Depth, buffer.Buffer); buffer.SetName("depth"); rays.Buffers.push_back(buffer); } } } } // namespace vtkm::rendering::raytracing