2022-04-01 10:33:57 +00:00
|
|
|
//============================================================================
|
|
|
|
// 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/MapperGlyphScalar.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/Timer.h>
|
|
|
|
|
|
|
|
#include <vtkm/rendering/CanvasRayTracer.h>
|
|
|
|
#include <vtkm/rendering/raytracing/Camera.h>
|
|
|
|
#include <vtkm/rendering/raytracing/GlyphExtractor.h>
|
|
|
|
#include <vtkm/rendering/raytracing/GlyphIntersector.h>
|
|
|
|
#include <vtkm/rendering/raytracing/Logger.h>
|
|
|
|
#include <vtkm/rendering/raytracing/RayOperations.h>
|
|
|
|
#include <vtkm/rendering/raytracing/RayTracer.h>
|
|
|
|
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace rendering
|
|
|
|
{
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
// Packed frame buffer value with color set as black and depth as 1.0f
|
|
|
|
constexpr vtkm::Int64 ClearValue = 0x3F800000000000FF;
|
|
|
|
|
|
|
|
union PackedValue {
|
|
|
|
struct PackedFloats
|
|
|
|
{
|
|
|
|
vtkm::Float32 Color;
|
|
|
|
vtkm::Float32 Depth;
|
|
|
|
} Floats;
|
|
|
|
struct PackedInts
|
|
|
|
{
|
|
|
|
vtkm::UInt32 Color;
|
|
|
|
vtkm::UInt32 Depth;
|
|
|
|
} Ints;
|
|
|
|
vtkm::Int64 Raw;
|
|
|
|
}; // union PackedValue
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::UInt32 ScaleColorComponent(vtkm::Float32 c)
|
|
|
|
{
|
|
|
|
vtkm::Int32 t = vtkm::Int32(c * 256.0f);
|
|
|
|
return vtkm::UInt32(t < 0 ? 0 : (t > 255 ? 255 : t));
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::Float32 a);
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::UInt32 PackColor(const vtkm::Vec4f_32& color)
|
|
|
|
{
|
|
|
|
return PackColor(color[0], color[1], color[2], color[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::Float32 a)
|
|
|
|
{
|
|
|
|
vtkm::UInt32 packed = (ScaleColorComponent(r) << 24);
|
|
|
|
packed |= (ScaleColorComponent(g) << 16);
|
|
|
|
packed |= (ScaleColorComponent(b) << 8);
|
|
|
|
packed |= ScaleColorComponent(a);
|
|
|
|
return packed;
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
void UnpackColor(vtkm::UInt32 color,
|
|
|
|
vtkm::Float32& r,
|
|
|
|
vtkm::Float32& g,
|
|
|
|
vtkm::Float32& b,
|
|
|
|
vtkm::Float32& a);
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
void UnpackColor(vtkm::UInt32 packedColor, vtkm::Vec4f_32& color)
|
|
|
|
{
|
|
|
|
UnpackColor(packedColor, color[0], color[1], color[2], color[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
void UnpackColor(vtkm::UInt32 color,
|
|
|
|
vtkm::Float32& r,
|
|
|
|
vtkm::Float32& g,
|
|
|
|
vtkm::Float32& b,
|
|
|
|
vtkm::Float32& a)
|
|
|
|
{
|
|
|
|
r = vtkm::Float32((color & 0xFF000000) >> 24) / 255.0f;
|
|
|
|
g = vtkm::Float32((color & 0x00FF0000) >> 16) / 255.0f;
|
|
|
|
b = vtkm::Float32((color & 0x0000FF00) >> 8) / 255.0f;
|
|
|
|
a = vtkm::Float32((color & 0x000000FF)) / 255.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
class PackIntoFrameBuffer : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ControlSignature = void(FieldIn, FieldIn, FieldOut);
|
|
|
|
using ExecutionSignature = void(_1, _2, _3);
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
PackIntoFrameBuffer() {}
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
void operator()(const vtkm::Vec4f_32& color,
|
|
|
|
const vtkm::Float32& depth,
|
|
|
|
vtkm::Int64& outValue) const
|
|
|
|
{
|
|
|
|
PackedValue packed;
|
|
|
|
packed.Ints.Color = PackColor(color);
|
|
|
|
packed.Floats.Depth = depth;
|
|
|
|
outValue = packed.Raw;
|
|
|
|
}
|
|
|
|
}; //class PackIntoFrameBuffer
|
|
|
|
|
|
|
|
class UnpackFromFrameBuffer : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT
|
|
|
|
UnpackFromFrameBuffer() {}
|
|
|
|
|
|
|
|
using ControlSignature = void(FieldIn, WholeArrayOut, WholeArrayOut);
|
|
|
|
using ExecutionSignature = void(_1, _2, _3, WorkIndex);
|
|
|
|
|
|
|
|
template <typename ColorBufferPortal, typename DepthBufferPortal>
|
|
|
|
VTKM_EXEC void operator()(const vtkm::Int64& packedValue,
|
|
|
|
ColorBufferPortal& colorBuffer,
|
|
|
|
DepthBufferPortal& depthBuffer,
|
|
|
|
const vtkm::Id& index) const
|
|
|
|
{
|
|
|
|
PackedValue packed;
|
|
|
|
packed.Raw = packedValue;
|
|
|
|
float depth = packed.Floats.Depth;
|
|
|
|
if (depth <= depthBuffer.Get(index))
|
|
|
|
{
|
|
|
|
vtkm::Vec4f_32 color;
|
|
|
|
UnpackColor(packed.Ints.Color, color);
|
|
|
|
colorBuffer.Set(index, color);
|
|
|
|
depthBuffer.Set(index, depth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}; // class UnpackFromFrameBuffer
|
|
|
|
|
|
|
|
class GetNormalizedScalars : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ControlSignature = void(FieldIn pointIds, FieldOut normalizedScalars, WholeArrayIn field);
|
|
|
|
using ExecutionSignature = void(_1, _2, _3);
|
|
|
|
|
|
|
|
VTKM_CONT GetNormalizedScalars(vtkm::Float32 minScalar, vtkm::Float32 maxScalar)
|
|
|
|
: MinScalar(minScalar)
|
|
|
|
{
|
|
|
|
if (minScalar >= maxScalar)
|
|
|
|
{
|
|
|
|
this->InverseScalarDelta = 0.0f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->InverseScalarDelta = 1.0f / (maxScalar - minScalar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename FieldPortalType>
|
|
|
|
VTKM_EXEC void operator()(const vtkm::Id& pointId,
|
|
|
|
vtkm::Float32& normalizedScalar,
|
|
|
|
const FieldPortalType& field) const
|
|
|
|
{
|
|
|
|
normalizedScalar = static_cast<vtkm::Float32>(field.Get(pointId));
|
|
|
|
normalizedScalar = (normalizedScalar - this->MinScalar) * this->InverseScalarDelta;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
vtkm::Float32 MinScalar;
|
|
|
|
vtkm::Float32 InverseScalarDelta;
|
|
|
|
}; // class GetNormalizedScalars
|
|
|
|
|
|
|
|
class BillboardGlyphPlotter : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ControlSignature = void(FieldIn pointIds,
|
|
|
|
FieldIn sizes,
|
|
|
|
FieldIn normalizedScalar,
|
|
|
|
WholeArrayIn coords,
|
|
|
|
WholeArrayIn colorMap,
|
|
|
|
AtomicArrayInOut frameBuffer);
|
|
|
|
|
|
|
|
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6);
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
BillboardGlyphPlotter(const vtkm::Matrix<vtkm::Float32, 4, 4>& worldToProjection,
|
|
|
|
vtkm::Id width,
|
|
|
|
vtkm::Id height,
|
|
|
|
vtkm::Float32 projectionOffset)
|
|
|
|
: WorldToProjection(worldToProjection)
|
|
|
|
, Width(width)
|
|
|
|
, Height(height)
|
|
|
|
, ProjectionOffset(projectionOffset)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename CoordinatesPortal, typename ColorMapPortal, typename FrameBuffer>
|
|
|
|
VTKM_EXEC void operator()(const vtkm::Id& pointId,
|
|
|
|
const vtkm::Float32& size,
|
|
|
|
const vtkm::Float32& normalizedScalar,
|
|
|
|
const CoordinatesPortal& coordsPortal,
|
|
|
|
const ColorMapPortal& colorMap,
|
|
|
|
FrameBuffer& frameBuffer) const
|
|
|
|
{
|
|
|
|
vtkm::Vec3f_32 point = static_cast<vtkm::Vec3f_32>(coordsPortal.Get(pointId));
|
|
|
|
point = this->TransformWorldToViewport(point);
|
|
|
|
vtkm::Vec4f_32 color = this->GetColor(normalizedScalar, colorMap);
|
|
|
|
|
|
|
|
vtkm::Float32 halfSize = size / 2.0f;
|
|
|
|
vtkm::Id x1 = static_cast<vtkm::Id>(vtkm::Round(point[0] - halfSize));
|
|
|
|
vtkm::Id x2 = static_cast<vtkm::Id>(vtkm::Round(point[0] + halfSize));
|
|
|
|
vtkm::Id y1 = static_cast<vtkm::Id>(vtkm::Round(point[1] - halfSize));
|
|
|
|
vtkm::Id y2 = static_cast<vtkm::Id>(vtkm::Round(point[1] + halfSize));
|
|
|
|
vtkm::Float32 depth = point[2];
|
|
|
|
|
|
|
|
for (vtkm::Id x = x1; x <= x2; ++x)
|
|
|
|
{
|
|
|
|
for (vtkm::Id y = y1; y <= y2; ++y)
|
|
|
|
{
|
|
|
|
this->SetColor(x, y, depth, color, frameBuffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
VTKM_EXEC
|
|
|
|
vtkm::Vec3f_32 TransformWorldToViewport(const vtkm::Vec3f_32& point) const
|
|
|
|
{
|
|
|
|
vtkm::Vec4f_32 temp(point[0], point[1], point[2], 1.0f);
|
|
|
|
vtkm::Vec3f_32 result;
|
|
|
|
temp = vtkm::MatrixMultiply(this->WorldToProjection, temp);
|
|
|
|
for (vtkm::IdComponent i = 0; i < 3; ++i)
|
|
|
|
{
|
|
|
|
result[i] = temp[i] / temp[3];
|
|
|
|
}
|
|
|
|
result[0] = (result[0] * 0.5f + 0.5f) * vtkm::Float32(this->Width);
|
|
|
|
result[1] = (result[1] * 0.5f + 0.5f) * vtkm::Float32(this->Height);
|
|
|
|
result[2] = result[2] * 0.5f + 0.5f;
|
|
|
|
// Offset the point to a bit towards the camera. This is to ensure that the front faces of
|
|
|
|
// the wireframe wins the z-depth check against the surface render, and is in addition to the
|
|
|
|
// existing camera space offset.
|
|
|
|
result[2] -= this->ProjectionOffset;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ColorMapPortal>
|
|
|
|
VTKM_EXEC vtkm::Vec4f_32 GetColor(vtkm::Float32 normalizedScalar,
|
|
|
|
const ColorMapPortal& colorMap) const
|
|
|
|
{
|
|
|
|
vtkm::Id colorMapSize = colorMap.GetNumberOfValues() - 1;
|
|
|
|
vtkm::Id colorIdx = static_cast<vtkm::Id>(normalizedScalar * colorMapSize);
|
|
|
|
colorIdx = vtkm::Min(colorMapSize, vtkm::Max(vtkm::Id(0), colorIdx));
|
|
|
|
return colorMap.Get(colorIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename FrameBuffer>
|
|
|
|
VTKM_EXEC void SetColor(vtkm::Id x,
|
|
|
|
vtkm::Id y,
|
|
|
|
vtkm::Float32 depth,
|
|
|
|
const vtkm::Vec4f_32& color,
|
|
|
|
FrameBuffer& frameBuffer) const
|
|
|
|
{
|
|
|
|
if (x < 0 || x >= this->Width || y < 0 || y >= this->Height)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::Id index = y * this->Width + x;
|
|
|
|
PackedValue current, next;
|
|
|
|
current.Raw = ClearValue;
|
|
|
|
next.Floats.Depth = depth;
|
|
|
|
|
|
|
|
vtkm::Vec4f_32 currentColor;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
UnpackColor(current.Ints.Color, currentColor);
|
|
|
|
next.Ints.Color = PackColor(color);
|
|
|
|
frameBuffer.CompareExchange(index, ¤t.Raw, next.Raw);
|
|
|
|
} while (current.Floats.Depth > next.Floats.Depth);
|
|
|
|
}
|
|
|
|
|
|
|
|
const vtkm::Matrix<vtkm::Float32, 4, 4> WorldToProjection;
|
|
|
|
const vtkm::Id Width;
|
|
|
|
const vtkm::Id Height;
|
|
|
|
const vtkm::Float32 ProjectionOffset;
|
|
|
|
}; // class BillboardGlyphPlotter
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
MapperGlyphScalar::MapperGlyphScalar()
|
|
|
|
: MapperGlyphBase()
|
|
|
|
, GlyphType(vtkm::rendering::GlyphType::Sphere)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
MapperGlyphScalar::~MapperGlyphScalar() {}
|
|
|
|
|
|
|
|
vtkm::rendering::GlyphType MapperGlyphScalar::GetGlyphType() const
|
|
|
|
{
|
|
|
|
return this->GlyphType;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapperGlyphScalar::SetGlyphType(vtkm::rendering::GlyphType glyphType)
|
|
|
|
{
|
|
|
|
if (!(glyphType == vtkm::rendering::GlyphType::Axes ||
|
|
|
|
glyphType == vtkm::rendering::GlyphType::Cube ||
|
|
|
|
glyphType == vtkm::rendering::GlyphType::Quad ||
|
|
|
|
glyphType == vtkm::rendering::GlyphType::Sphere))
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadValue("MapperGlyphScalar: bad glyph type");
|
|
|
|
}
|
|
|
|
|
|
|
|
this->GlyphType = glyphType;
|
|
|
|
}
|
|
|
|
|
2023-11-08 00:20:05 +00:00
|
|
|
void MapperGlyphScalar::RenderCellsImpl(const vtkm::cont::UnknownCellSet& cellset,
|
|
|
|
const vtkm::cont::CoordinateSystem& coords,
|
|
|
|
const vtkm::cont::Field& scalarField,
|
|
|
|
const vtkm::cont::ColorTable& vtkmNotUsed(colorTable),
|
|
|
|
const vtkm::rendering::Camera& camera,
|
|
|
|
const vtkm::Range& scalarRange,
|
|
|
|
const vtkm::cont::Field& vtkmNotUsed(ghostField))
|
2022-04-01 10:33:57 +00:00
|
|
|
{
|
|
|
|
raytracing::Logger* logger = raytracing::Logger::GetInstance();
|
|
|
|
|
|
|
|
vtkm::rendering::raytracing::RayTracer tracer;
|
|
|
|
tracer.Clear();
|
|
|
|
|
|
|
|
logger->OpenLogEntry("mapper_glyph_scalar");
|
|
|
|
vtkm::cont::Timer tot_timer;
|
|
|
|
tot_timer.Start();
|
|
|
|
vtkm::cont::Timer timer;
|
|
|
|
|
|
|
|
vtkm::Bounds coordBounds = coords.GetBounds();
|
|
|
|
vtkm::Float32 baseSize = this->BaseSize;
|
2023-10-03 18:13:37 +00:00
|
|
|
// The weird formulation of this condition is to handle NaN correctly.
|
|
|
|
if (!(baseSize > 0))
|
2022-04-01 10:33:57 +00:00
|
|
|
{
|
|
|
|
// set a default size
|
|
|
|
vtkm::Float64 lx = coordBounds.X.Length();
|
|
|
|
vtkm::Float64 ly = coordBounds.Y.Length();
|
|
|
|
vtkm::Float64 lz = coordBounds.Z.Length();
|
|
|
|
vtkm::Float64 mag = vtkm::Sqrt(lx * lx + ly * ly + lz * lz);
|
|
|
|
if (this->GlyphType == vtkm::rendering::GlyphType::Quad)
|
|
|
|
{
|
|
|
|
baseSize = 20.0f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// same as used in vtk ospray
|
|
|
|
constexpr vtkm::Float64 heuristic = 500.;
|
|
|
|
baseSize = static_cast<vtkm::Float32>(mag / heuristic);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::rendering::raytracing::GlyphExtractor glyphExtractor;
|
|
|
|
|
|
|
|
vtkm::cont::DataSet processedDataSet = this->FilterPoints(cellset, coords, scalarField);
|
|
|
|
vtkm::cont::UnknownCellSet processedCellSet = processedDataSet.GetCellSet();
|
|
|
|
vtkm::cont::CoordinateSystem processedCoords = processedDataSet.GetCoordinateSystem();
|
2022-10-31 17:22:37 +00:00
|
|
|
vtkm::cont::Field processedField = processedDataSet.GetField(scalarField.GetName());
|
2022-04-01 10:33:57 +00:00
|
|
|
|
|
|
|
if (this->ScaleByValue)
|
|
|
|
{
|
|
|
|
vtkm::Float32 minSize = baseSize - baseSize * this->ScaleDelta;
|
|
|
|
vtkm::Float32 maxSize = baseSize + baseSize * this->ScaleDelta;
|
2023-07-27 20:07:19 +00:00
|
|
|
if (this->Association == vtkm::cont::Field::Association::Points)
|
2022-04-01 10:33:57 +00:00
|
|
|
{
|
|
|
|
glyphExtractor.ExtractCoordinates(processedCoords, processedField, minSize, maxSize);
|
|
|
|
}
|
2023-07-27 20:07:19 +00:00
|
|
|
else // this->Association == vtkm::cont::Field::Association::Cells
|
2022-04-01 10:33:57 +00:00
|
|
|
{
|
|
|
|
glyphExtractor.ExtractCells(processedCellSet, processedField, minSize, maxSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-07-27 20:07:19 +00:00
|
|
|
if (this->Association == vtkm::cont::Field::Association::Points)
|
2022-04-01 10:33:57 +00:00
|
|
|
{
|
|
|
|
glyphExtractor.ExtractCoordinates(processedCoords, baseSize);
|
|
|
|
}
|
2023-07-27 20:07:19 +00:00
|
|
|
else // this->Association == vtkm::cont::Field::Association::Cells
|
2022-04-01 10:33:57 +00:00
|
|
|
{
|
|
|
|
glyphExtractor.ExtractCells(processedCellSet, baseSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->GlyphType == vtkm::rendering::GlyphType::Quad)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> pointIds = glyphExtractor.GetPointIds();
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Float32> sizes = glyphExtractor.GetSizes();
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Float32> normalizedScalars;
|
|
|
|
vtkm::Float32 rangeMin = static_cast<vtkm::Float32>(scalarRange.Min);
|
|
|
|
vtkm::Float32 rangeMax = static_cast<vtkm::Float32>(scalarRange.Max);
|
|
|
|
vtkm::cont::Invoker invoker;
|
|
|
|
invoker(GetNormalizedScalars{ rangeMin, rangeMax },
|
|
|
|
pointIds,
|
|
|
|
normalizedScalars,
|
|
|
|
vtkm::rendering::raytracing::GetScalarFieldArray(scalarField));
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Int64> frameBuffer;
|
|
|
|
invoker(PackIntoFrameBuffer{},
|
|
|
|
this->Canvas->GetColorBuffer(),
|
|
|
|
this->Canvas->GetDepthBuffer(),
|
|
|
|
frameBuffer);
|
|
|
|
|
|
|
|
vtkm::Range clippingRange = camera.GetClippingRange();
|
|
|
|
vtkm::Float64 offset1 = (clippingRange.Max - clippingRange.Min) / 1.0e4;
|
|
|
|
vtkm::Float64 offset2 = clippingRange.Min / 2.0;
|
|
|
|
vtkm::Float32 offset = static_cast<vtkm::Float32>(vtkm::Min(offset1, offset2));
|
|
|
|
vtkm::Matrix<vtkm::Float32, 4, 4> modelMatrix;
|
|
|
|
vtkm::MatrixIdentity(modelMatrix);
|
|
|
|
modelMatrix[2][3] = offset;
|
|
|
|
vtkm::Matrix<vtkm::Float32, 4, 4> worldToCamera =
|
|
|
|
vtkm::MatrixMultiply(modelMatrix, camera.CreateViewMatrix());
|
|
|
|
vtkm::Matrix<vtkm::Float32, 4, 4> worldToProjection = vtkm::MatrixMultiply(
|
|
|
|
camera.CreateProjectionMatrix(this->Canvas->GetWidth(), this->Canvas->GetHeight()),
|
|
|
|
worldToCamera);
|
|
|
|
vtkm::Float32 projectionOffset =
|
|
|
|
vtkm::Max(0.03f / static_cast<vtkm::Float32>(camera.GetClippingRange().Length()), 1e-4f);
|
|
|
|
invoker(
|
|
|
|
BillboardGlyphPlotter{
|
|
|
|
worldToProjection, this->Canvas->GetWidth(), this->Canvas->GetHeight(), projectionOffset },
|
|
|
|
pointIds,
|
|
|
|
sizes,
|
|
|
|
normalizedScalars,
|
|
|
|
coords,
|
|
|
|
this->ColorMap,
|
|
|
|
frameBuffer);
|
|
|
|
|
|
|
|
timer.Start();
|
|
|
|
invoker(UnpackFromFrameBuffer{},
|
|
|
|
frameBuffer,
|
|
|
|
this->Canvas->GetColorBuffer(),
|
|
|
|
this->Canvas->GetDepthBuffer());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vtkm::Bounds shapeBounds;
|
|
|
|
if (glyphExtractor.GetNumberOfGlyphs() > 0)
|
|
|
|
{
|
|
|
|
auto glyphIntersector = std::make_shared<raytracing::GlyphIntersector>(this->GlyphType);
|
|
|
|
glyphIntersector->SetData(
|
|
|
|
processedCoords, glyphExtractor.GetPointIds(), glyphExtractor.GetSizes());
|
|
|
|
tracer.AddShapeIntersector(glyphIntersector);
|
|
|
|
shapeBounds.Include(glyphIntersector->GetShapeBounds());
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Create rays
|
|
|
|
//
|
|
|
|
vtkm::Int32 width = (vtkm::Int32)this->Canvas->GetWidth();
|
|
|
|
vtkm::Int32 height = (vtkm::Int32)this->Canvas->GetHeight();
|
|
|
|
|
|
|
|
vtkm::rendering::raytracing::Camera RayCamera;
|
|
|
|
vtkm::rendering::raytracing::Ray<vtkm::Float32> Rays;
|
|
|
|
|
|
|
|
RayCamera.SetParameters(camera, width, height);
|
|
|
|
|
|
|
|
RayCamera.CreateRays(Rays, shapeBounds);
|
|
|
|
Rays.Buffers.at(0).InitConst(0.f);
|
|
|
|
raytracing::RayOperations::MapCanvasToRays(Rays, camera, *this->Canvas);
|
|
|
|
|
|
|
|
tracer.SetField(processedField, scalarRange);
|
|
|
|
tracer.GetCamera() = RayCamera;
|
|
|
|
tracer.SetColorMap(this->ColorMap);
|
|
|
|
tracer.Render(Rays);
|
|
|
|
|
|
|
|
timer.Start();
|
|
|
|
this->Canvas->WriteToCanvas(Rays, Rays.Buffers.at(0).Buffer, camera);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->CompositeBackground)
|
|
|
|
{
|
|
|
|
this->Canvas->BlendBackground();
|
|
|
|
}
|
|
|
|
vtkm::Float64 time = timer.GetElapsedTime();
|
|
|
|
logger->AddLogData("write_to_canvas", time);
|
|
|
|
time = tot_timer.GetElapsedTime();
|
|
|
|
logger->CloseLogEntry(time);
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::rendering::Mapper* MapperGlyphScalar::NewCopy() const
|
|
|
|
{
|
|
|
|
return new vtkm::rendering::MapperGlyphScalar(*this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // vtkm::rendering
|