mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-20 11:05:44 +00:00
Merge topic 'line_rendering'
8e0a0308 Handles the case when the passed canvas has rendered data. b727377f Refactoring 44357d51 Apply external faces filter on cellset before wireframing 7e95269c Refactoring wireframing code 5738e895 Wireframe rendering 657b0b94 Applies `clang-format` and minor refactoring af2acc57 Implements a simple line renderer using Xialin Wu's algorithm Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Matt Larsen <mlarsen@cs.uoregon.edu> Merge-request: !895
This commit is contained in:
commit
93aa64109f
@ -41,6 +41,7 @@ set(headers
|
|||||||
MapperRayTracer.h
|
MapperRayTracer.h
|
||||||
MapperVolume.h
|
MapperVolume.h
|
||||||
MapperConnectivity.h
|
MapperConnectivity.h
|
||||||
|
MapperWireframer.h
|
||||||
TextAnnotation.h
|
TextAnnotation.h
|
||||||
TextAnnotationBillboard.h
|
TextAnnotationBillboard.h
|
||||||
TextAnnotationScreen.h
|
TextAnnotationScreen.h
|
||||||
@ -73,6 +74,7 @@ set(sources
|
|||||||
MapperRayTracer.cxx
|
MapperRayTracer.cxx
|
||||||
MapperVolume.cxx
|
MapperVolume.cxx
|
||||||
MapperConnectivity.cxx
|
MapperConnectivity.cxx
|
||||||
|
MapperWireframer.cxx
|
||||||
Scene.cxx
|
Scene.cxx
|
||||||
TextAnnotation.cxx
|
TextAnnotation.cxx
|
||||||
TextAnnotationBillboard.cxx
|
TextAnnotationBillboard.cxx
|
||||||
@ -126,6 +128,8 @@ set(osmesa_sources
|
|||||||
# This list of sources has code that uses devices and so might need to be
|
# This list of sources has code that uses devices and so might need to be
|
||||||
# compiled with a device-specific compiler (like CUDA).
|
# compiled with a device-specific compiler (like CUDA).
|
||||||
set(device_sources
|
set(device_sources
|
||||||
|
Mapper.cxx
|
||||||
|
MapperWireframer.cxx
|
||||||
CanvasRayTracer.cxx
|
CanvasRayTracer.cxx
|
||||||
ConnectivityProxy.cxx
|
ConnectivityProxy.cxx
|
||||||
raytracing/BoundingVolumeHierarchy.cxx
|
raytracing/BoundingVolumeHierarchy.cxx
|
||||||
|
269
vtkm/rendering/MapperWireframer.cxx
Normal file
269
vtkm/rendering/MapperWireframer.cxx
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Copyright 2016 Sandia Corporation.
|
||||||
|
// Copyright 2016 UT-Battelle, LLC.
|
||||||
|
// Copyright 2016 Los Alamos National Security.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// the U.S. Government retains certain rights in this software.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||||
|
// this software.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/Assert.h>
|
||||||
|
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||||
|
#include <vtkm/cont/TryExecute.h>
|
||||||
|
#include <vtkm/exec/CellEdge.h>
|
||||||
|
#include <vtkm/filter/ExternalFaces.h>
|
||||||
|
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||||
|
#include <vtkm/rendering/MapperRayTracer.h>
|
||||||
|
#include <vtkm/rendering/MapperWireframer.h>
|
||||||
|
#include <vtkm/rendering/Wireframer.h>
|
||||||
|
#include <vtkm/worklet/DispatcherMapField.h>
|
||||||
|
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||||
|
#include <vtkm/worklet/ScatterCounting.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace rendering
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct EdgesCounter : public vtkm::worklet::WorkletMapPointToCell
|
||||||
|
{
|
||||||
|
typedef void ControlSignature(CellSetIn cellSet, FieldOutCell<> numEdges);
|
||||||
|
typedef _2 ExecutionSignature(CellShape shape, PointCount numPoints);
|
||||||
|
using InputDomain = _1;
|
||||||
|
|
||||||
|
template <typename CellShapeTag>
|
||||||
|
VTKM_EXEC vtkm::IdComponent operator()(CellShapeTag shape, vtkm::IdComponent numPoints) const
|
||||||
|
{
|
||||||
|
if (shape.Id == vtkm::CELL_SHAPE_LINE)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, *this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; // struct EdgesCounter
|
||||||
|
|
||||||
|
struct EdgesExtracter : public vtkm::worklet::WorkletMapPointToCell
|
||||||
|
{
|
||||||
|
typedef void ControlSignature(CellSetIn cellSet, FieldOutCell<> edgeIndices);
|
||||||
|
typedef void ExecutionSignature(CellShape, PointIndices, VisitIndex, _2);
|
||||||
|
using InputDomain = _1;
|
||||||
|
using ScatterType = vtkm::worklet::ScatterCounting;
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
template <typename CountArrayType, typename DeviceTag>
|
||||||
|
EdgesExtracter(const CountArrayType& counts, DeviceTag device)
|
||||||
|
: Scatter(counts, device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT ScatterType GetScatter() const { return this->Scatter; }
|
||||||
|
|
||||||
|
template <typename CellShapeTag, typename PointIndexVecType, typename EdgeIndexVecType>
|
||||||
|
VTKM_EXEC void operator()(CellShapeTag shape,
|
||||||
|
const PointIndexVecType& pointIndices,
|
||||||
|
vtkm::IdComponent visitIndex,
|
||||||
|
EdgeIndexVecType& edgeIndices) const
|
||||||
|
{
|
||||||
|
vtkm::Id p1, p2;
|
||||||
|
if (shape.Id == vtkm::CELL_SHAPE_LINE)
|
||||||
|
{
|
||||||
|
p1 = pointIndices[0];
|
||||||
|
p2 = pointIndices[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtkm::Vec<vtkm::IdComponent, 2> localEdgeIndices = vtkm::exec::CellEdgeLocalIndices(
|
||||||
|
pointIndices.GetNumberOfComponents(), visitIndex, shape, *this);
|
||||||
|
p1 = pointIndices[localEdgeIndices[0]];
|
||||||
|
p2 = pointIndices[localEdgeIndices[1]];
|
||||||
|
}
|
||||||
|
// These indices need to be arranged in a definite order, as they will later be sorted to
|
||||||
|
// detect duplicates
|
||||||
|
edgeIndices[0] = p1 < p2 ? p1 : p2;
|
||||||
|
edgeIndices[1] = p1 < p2 ? p2 : p1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ScatterType Scatter;
|
||||||
|
}; // struct EdgesExtracter
|
||||||
|
|
||||||
|
struct ExtractUniqueEdges
|
||||||
|
{
|
||||||
|
vtkm::cont::DynamicCellSet CellSet;
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 2>> EdgeIndices;
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
ExtractUniqueEdges(const vtkm::cont::DynamicCellSet& cellSet)
|
||||||
|
: CellSet(cellSet)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DeviceTag>
|
||||||
|
VTKM_CONT bool operator()(DeviceTag)
|
||||||
|
{
|
||||||
|
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceTag);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> counts;
|
||||||
|
vtkm::worklet::DispatcherMapTopology<EdgesCounter, DeviceTag>().Invoke(CellSet, counts);
|
||||||
|
EdgesExtracter extractWorklet(counts, DeviceTag());
|
||||||
|
vtkm::worklet::DispatcherMapTopology<EdgesExtracter, DeviceTag> extractDispatcher(
|
||||||
|
extractWorklet);
|
||||||
|
extractDispatcher.Invoke(CellSet, EdgeIndices);
|
||||||
|
vtkm::cont::DeviceAdapterAlgorithm<DeviceTag>::template Sort<vtkm::Id2>(EdgeIndices);
|
||||||
|
vtkm::cont::DeviceAdapterAlgorithm<DeviceTag>::template Unique<vtkm::Id2>(EdgeIndices);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}; // struct ExtractUniqueEdges
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
struct MapperWireframer::InternalsType
|
||||||
|
{
|
||||||
|
InternalsType()
|
||||||
|
: InternalsType(nullptr, false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalsType(vtkm::rendering::Canvas* canvas, bool showInternalZones, bool isOverlay)
|
||||||
|
: Canvas(canvas)
|
||||||
|
, ShowInternalZones(showInternalZones)
|
||||||
|
, IsOverlay(isOverlay)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::rendering::Canvas* Canvas;
|
||||||
|
bool ShowInternalZones;
|
||||||
|
bool IsOverlay;
|
||||||
|
}; // struct MapperWireframer::InternalsType
|
||||||
|
|
||||||
|
MapperWireframer::MapperWireframer()
|
||||||
|
: Internals(new InternalsType(nullptr, false, false))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MapperWireframer::~MapperWireframer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::rendering::Canvas* MapperWireframer::GetCanvas() const
|
||||||
|
{
|
||||||
|
return this->Internals->Canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperWireframer::SetCanvas(vtkm::rendering::Canvas* canvas)
|
||||||
|
{
|
||||||
|
this->Internals->Canvas = canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapperWireframer::GetShowInternalZones() const
|
||||||
|
{
|
||||||
|
return this->Internals->ShowInternalZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperWireframer::SetShowInternalZones(bool showInternalZones)
|
||||||
|
{
|
||||||
|
this->Internals->ShowInternalZones = showInternalZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapperWireframer::GetIsOverlay() const
|
||||||
|
{
|
||||||
|
return this->Internals->IsOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperWireframer::SetIsOverlay(bool isOverlay)
|
||||||
|
{
|
||||||
|
this->Internals->IsOverlay = isOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperWireframer::StartScene()
|
||||||
|
{
|
||||||
|
// Nothing needs to be done.
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperWireframer::EndScene()
|
||||||
|
{
|
||||||
|
// Nothing needs to be done.
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperWireframer::RenderCells(const vtkm::cont::DynamicCellSet& inCellSet,
|
||||||
|
const vtkm::cont::CoordinateSystem& coords,
|
||||||
|
const vtkm::cont::Field& inScalarField,
|
||||||
|
const vtkm::rendering::ColorTable& colorTable,
|
||||||
|
const vtkm::rendering::Camera& camera,
|
||||||
|
const vtkm::Range& scalarRange)
|
||||||
|
{
|
||||||
|
vtkm::cont::DynamicCellSet cellSet = inCellSet;
|
||||||
|
vtkm::cont::Field field = inScalarField;
|
||||||
|
if (!(this->Internals->ShowInternalZones))
|
||||||
|
{
|
||||||
|
// If internal zones are to be hidden, the number of edges processed can be reduced by
|
||||||
|
// running the external faces filter on the input cell set.
|
||||||
|
vtkm::cont::DataSet dataSet;
|
||||||
|
dataSet.AddCoordinateSystem(coords);
|
||||||
|
dataSet.AddCellSet(inCellSet);
|
||||||
|
vtkm::filter::ExternalFaces externalFaces;
|
||||||
|
externalFaces.SetCompactPoints(false);
|
||||||
|
externalFaces.SetPassPolyData(true);
|
||||||
|
vtkm::filter::Result result = externalFaces.Execute(dataSet);
|
||||||
|
externalFaces.MapFieldOntoOutput(result, inScalarField);
|
||||||
|
cellSet = result.GetDataSet().GetCellSet();
|
||||||
|
field = result.GetDataSet().GetField(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract unique edges from the cell set.
|
||||||
|
ExtractUniqueEdges extracter(cellSet);
|
||||||
|
vtkm::cont::TryExecute(extracter);
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 2>> edgeIndices = extracter.EdgeIndices;
|
||||||
|
|
||||||
|
Wireframer renderer(
|
||||||
|
this->Internals->Canvas, this->Internals->ShowInternalZones, this->Internals->IsOverlay);
|
||||||
|
// Render the cell set using a raytracer, on a separate canvas, and use the generated depth
|
||||||
|
// buffer, which represents the solid mesh, to avoid drawing on the internal zones
|
||||||
|
if (!(this->Internals->ShowInternalZones) && !(this->Internals->IsOverlay))
|
||||||
|
{
|
||||||
|
CanvasRayTracer canvas(this->Internals->Canvas->GetWidth(),
|
||||||
|
this->Internals->Canvas->GetHeight());
|
||||||
|
canvas.SetBackgroundColor(vtkm::rendering::Color::white);
|
||||||
|
canvas.Initialize();
|
||||||
|
canvas.Activate();
|
||||||
|
canvas.Clear();
|
||||||
|
MapperRayTracer raytracer;
|
||||||
|
raytracer.SetCanvas(&canvas);
|
||||||
|
raytracer.SetActiveColorTable(colorTable);
|
||||||
|
raytracer.RenderCells(cellSet, coords, field, colorTable, camera, scalarRange);
|
||||||
|
renderer.SetSolidDepthBuffer(canvas.GetDepthBuffer());
|
||||||
|
}
|
||||||
|
else if (this->Internals->IsOverlay)
|
||||||
|
{
|
||||||
|
renderer.SetSolidDepthBuffer(this->Internals->Canvas->GetDepthBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.SetCamera(camera);
|
||||||
|
renderer.SetColorMap(this->ColorMap);
|
||||||
|
renderer.SetData(coords, edgeIndices, field, scalarRange);
|
||||||
|
renderer.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::rendering::Mapper* MapperWireframer::NewCopy() const
|
||||||
|
{
|
||||||
|
return new vtkm::rendering::MapperWireframer(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace vtkm::rendering
|
72
vtkm/rendering/MapperWireframer.h
Normal file
72
vtkm/rendering/MapperWireframer.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Copyright 2015 Sandia Corporation.
|
||||||
|
// Copyright 2015 UT-Battelle, LLC.
|
||||||
|
// Copyright 2015 Los Alamos National Security.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// the U.S. Government retains certain rights in this software.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||||
|
// this software.
|
||||||
|
//============================================================================
|
||||||
|
#ifndef vtk_m_rendering_MapperWireframer_h
|
||||||
|
#define vtk_m_rendering_MapperWireframer_h
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <vtkm/cont/CoordinateSystem.h>
|
||||||
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
|
#include <vtkm/cont/Field.h>
|
||||||
|
#include <vtkm/rendering/Camera.h>
|
||||||
|
#include <vtkm/rendering/Canvas.h>
|
||||||
|
#include <vtkm/rendering/ColorTable.h>
|
||||||
|
#include <vtkm/rendering/Mapper.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace rendering
|
||||||
|
{
|
||||||
|
|
||||||
|
class VTKM_RENDERING_EXPORT MapperWireframer : public Mapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VTKM_CONT
|
||||||
|
MapperWireframer();
|
||||||
|
virtual ~MapperWireframer();
|
||||||
|
|
||||||
|
virtual vtkm::rendering::Canvas* GetCanvas() const VTKM_OVERRIDE;
|
||||||
|
virtual void SetCanvas(vtkm::rendering::Canvas* canvas) VTKM_OVERRIDE;
|
||||||
|
|
||||||
|
bool GetShowInternalZones() const;
|
||||||
|
void SetShowInternalZones(bool showInternalZones);
|
||||||
|
|
||||||
|
bool GetIsOverlay() const;
|
||||||
|
void SetIsOverlay(bool isOverlay);
|
||||||
|
|
||||||
|
virtual void StartScene() VTKM_OVERRIDE;
|
||||||
|
virtual void EndScene() VTKM_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||||
|
const vtkm::cont::CoordinateSystem& coords,
|
||||||
|
const vtkm::cont::Field& scalarField,
|
||||||
|
const vtkm::rendering::ColorTable& colorTable,
|
||||||
|
const vtkm::rendering::Camera& camera,
|
||||||
|
const vtkm::Range& scalarRange) VTKM_OVERRIDE;
|
||||||
|
|
||||||
|
virtual vtkm::rendering::Mapper* NewCopy() const VTKM_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct InternalsType;
|
||||||
|
std::shared_ptr<InternalsType> Internals;
|
||||||
|
}; // class MapperWireframer
|
||||||
|
}
|
||||||
|
} // namespace vtkm::rendering
|
||||||
|
#endif // vtk_m_rendering_MapperWireframer_h
|
533
vtkm/rendering/Wireframer.h
Normal file
533
vtkm/rendering/Wireframer.h
Normal file
@ -0,0 +1,533 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Copyright 2016 Sandia Corporation.
|
||||||
|
// Copyright 2016 UT-Battelle, LLC.
|
||||||
|
// Copyright 2016 Los Alamos National Security.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// the U.S. Government retains certain rights in this software.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||||
|
// this software.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef vtk_m_rendering_Wireframer_h
|
||||||
|
#define vtk_m_rendering_Wireframer_h
|
||||||
|
|
||||||
|
#include <vtkm/Assert.h>
|
||||||
|
#include <vtkm/Math.h>
|
||||||
|
#include <vtkm/Types.h>
|
||||||
|
#include <vtkm/VectorAnalysis.h>
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/DynamicArrayHandle.h>
|
||||||
|
#include <vtkm/exec/AtomicArray.h>
|
||||||
|
#include <vtkm/rendering/MatrixHelpers.h>
|
||||||
|
#include <vtkm/rendering/Triangulator.h>
|
||||||
|
#include <vtkm/worklet/DispatcherMapField.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace rendering
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
using ColorMapHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||||
|
using IndicesHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 2>>;
|
||||||
|
using PackedFrameBufferHandle = vtkm::cont::ArrayHandle<vtkm::Int64>;
|
||||||
|
|
||||||
|
// Depth value of 1.0f
|
||||||
|
const vtkm::Int64 ClearDepth = 0x3F800000;
|
||||||
|
// Packed frame buffer value with color set as white and depth as 1.0f
|
||||||
|
const vtkm::Int64 ClearValue = 0x3F800000FFFFFFFF;
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
vtkm::Float32 IntegerPart(vtkm::Float32 x)
|
||||||
|
{
|
||||||
|
return vtkm::Floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
vtkm::Float32 FractionalPart(vtkm::Float32 x)
|
||||||
|
{
|
||||||
|
return x - vtkm::Floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
vtkm::Float32 ReverseFractionalPart(vtkm::Float32 x)
|
||||||
|
{
|
||||||
|
return 1.0f - FractionalPart(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
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::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::Float32 a);
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
vtkm::UInt32 PackColor(const vtkm::Vec<vtkm::Float32, 4>& 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Vec<vtkm::Float32, 4>& 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
struct CopyIntoFrameBuffer : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
typedef void ControlSignature(FieldIn<>, FieldIn<>, FieldOut<>);
|
||||||
|
typedef void ExecutionSignature(_1, _2, _3);
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
CopyIntoFrameBuffer() {}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
void operator()(const vtkm::Vec<vtkm::Float32, 4>& color,
|
||||||
|
const vtkm::Float32& depth,
|
||||||
|
vtkm::Int64& outValue) const
|
||||||
|
{
|
||||||
|
PackedValue packed;
|
||||||
|
packed.Ints.Color = PackColor(color);
|
||||||
|
packed.Floats.Depth = depth;
|
||||||
|
outValue = packed.Raw;
|
||||||
|
}
|
||||||
|
}; //struct CopyIntoFrameBuffer
|
||||||
|
|
||||||
|
template <typename DeviceTag>
|
||||||
|
class EdgePlotter : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using AtomicPackedFrameBufferHandle = vtkm::exec::AtomicArray<vtkm::Int64, DeviceTag>;
|
||||||
|
|
||||||
|
typedef void ControlSignature(FieldIn<>, WholeArrayIn<>, WholeArrayIn<Scalar>);
|
||||||
|
typedef void ExecutionSignature(_1, _2, _3);
|
||||||
|
using InputDomain = _1;
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
EdgePlotter(const vtkm::Matrix<vtkm::Float32, 4, 4>& worldToProjection,
|
||||||
|
vtkm::Id width,
|
||||||
|
vtkm::Id height,
|
||||||
|
const vtkm::Range& fieldRange,
|
||||||
|
const ColorMapHandle& colorMap,
|
||||||
|
const AtomicPackedFrameBufferHandle& frameBuffer,
|
||||||
|
const vtkm::Range& clippingRange)
|
||||||
|
: WorldToProjection(worldToProjection)
|
||||||
|
, Width(width)
|
||||||
|
, Height(height)
|
||||||
|
, ColorMap(colorMap.PrepareForInput(DeviceTag()))
|
||||||
|
, ColorMapSize(vtkm::Float32(colorMap.GetNumberOfValues() - 1))
|
||||||
|
, FrameBuffer(frameBuffer)
|
||||||
|
, FieldMin(vtkm::Float32(fieldRange.Min))
|
||||||
|
{
|
||||||
|
InverseFieldDelta = 1.0f / vtkm::Float32(fieldRange.Length());
|
||||||
|
Offset = vtkm::Max(0.03f / vtkm::Float32(clippingRange.Length()), 0.000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CoordinatesPortalType, typename ScalarFieldPortalType>
|
||||||
|
VTKM_EXEC void operator()(const vtkm::Vec<vtkm::Id, 2>& edgeIndices,
|
||||||
|
const CoordinatesPortalType& coordsPortal,
|
||||||
|
const ScalarFieldPortalType& fieldPortal) const
|
||||||
|
{
|
||||||
|
vtkm::Id point1Idx = edgeIndices[0];
|
||||||
|
vtkm::Id point2Idx = edgeIndices[1];
|
||||||
|
|
||||||
|
vtkm::Vec<vtkm::Float32, 3> point1 = coordsPortal.Get(edgeIndices[0]);
|
||||||
|
vtkm::Vec<vtkm::Float32, 3> point2 = coordsPortal.Get(edgeIndices[1]);
|
||||||
|
TransformWorldToViewport(point1);
|
||||||
|
TransformWorldToViewport(point2);
|
||||||
|
|
||||||
|
vtkm::Float32 x1 = point1[0];
|
||||||
|
vtkm::Float32 y1 = point1[1];
|
||||||
|
vtkm::Float32 z1 = point1[2];
|
||||||
|
vtkm::Float32 x2 = point2[0];
|
||||||
|
vtkm::Float32 y2 = point2[1];
|
||||||
|
vtkm::Float32 z2 = point2[2];
|
||||||
|
// If the line is steep, i.e., the height is greater than the width, then
|
||||||
|
// transpose the co-ordinates to prevent "holes" in the line. This ensures
|
||||||
|
// that we pick the co-ordinate which grows at a lesser rate than the other.
|
||||||
|
bool transposed = vtkm::Abs(y2 - y1) > vtkm::Abs(x2 - x1);
|
||||||
|
if (transposed)
|
||||||
|
{
|
||||||
|
std::swap(x1, y1);
|
||||||
|
std::swap(x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we are always going from left to right
|
||||||
|
if (x1 > x2)
|
||||||
|
{
|
||||||
|
std::swap(x1, x2);
|
||||||
|
std::swap(y1, y2);
|
||||||
|
std::swap(z1, z2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Float32 dx = x2 - x1;
|
||||||
|
vtkm::Float32 dy = y2 - y1;
|
||||||
|
vtkm::Float32 gradient = (dx == 0.0) ? 1.0f : (dy / dx);
|
||||||
|
|
||||||
|
vtkm::Float32 xEnd = vtkm::Round(x1);
|
||||||
|
vtkm::Float32 yEnd = y1 + gradient * (xEnd - x1);
|
||||||
|
vtkm::Float32 xGap = ReverseFractionalPart(x1 + 0.5f);
|
||||||
|
vtkm::Float32 xPxl1 = xEnd, yPxl1 = IntegerPart(yEnd);
|
||||||
|
vtkm::Float64 point1Field = fieldPortal.Get(point1Idx);
|
||||||
|
vtkm::Float64 point2Field = fieldPortal.Get(point2Idx);
|
||||||
|
|
||||||
|
// Plot first endpoint
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> color = GetColor(point1Field);
|
||||||
|
if (transposed)
|
||||||
|
{
|
||||||
|
Plot(yPxl1, xPxl1, z1, color, ReverseFractionalPart(yEnd) * xGap);
|
||||||
|
Plot(yPxl1 + 1, xPxl1, z1, color, FractionalPart(yEnd) * xGap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Plot(xPxl1, yPxl1, z1, color, ReverseFractionalPart(yEnd) * xGap);
|
||||||
|
Plot(xPxl1, yPxl1 + 1, z1, color, FractionalPart(yEnd) * xGap);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Float32 interY = yEnd + gradient;
|
||||||
|
xEnd = vtkm::Round(x2);
|
||||||
|
yEnd = y2 + gradient * (xEnd - x2);
|
||||||
|
xGap = FractionalPart(x2 + 0.5f);
|
||||||
|
vtkm::Float32 xPxl2 = xEnd, yPxl2 = IntegerPart(yEnd);
|
||||||
|
|
||||||
|
// Plot second endpoint
|
||||||
|
color = GetColor(point2Field);
|
||||||
|
if (transposed)
|
||||||
|
{
|
||||||
|
Plot(yPxl2, xPxl2, z2, color, ReverseFractionalPart(yEnd) * xGap);
|
||||||
|
Plot(yPxl2 + 1, xPxl2, z2, color, FractionalPart(yEnd) * xGap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Plot(xPxl2, yPxl2, z2, color, ReverseFractionalPart(yEnd) * xGap);
|
||||||
|
Plot(xPxl2, yPxl2 + 1, z2, color, FractionalPart(yEnd) * xGap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plot rest of the line
|
||||||
|
if (transposed)
|
||||||
|
{
|
||||||
|
for (vtkm::Float32 x = xPxl1 + 1; x <= xPxl2 - 1; ++x)
|
||||||
|
{
|
||||||
|
vtkm::Float32 t = IntegerPart(interY);
|
||||||
|
vtkm::Float32 factor = (x - x1) / dx;
|
||||||
|
vtkm::Float32 depth = vtkm::Lerp(z1, z2, factor);
|
||||||
|
vtkm::Float64 fieldValue = vtkm::Lerp(point1Field, point2Field, factor);
|
||||||
|
color = GetColor(fieldValue);
|
||||||
|
Plot(t, x, depth, color, ReverseFractionalPart(interY));
|
||||||
|
Plot(t + 1, x, depth, color, FractionalPart(interY));
|
||||||
|
interY += gradient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (vtkm::Float32 x = xPxl1 + 1; x <= xPxl2 - 1; ++x)
|
||||||
|
{
|
||||||
|
vtkm::Float32 t = IntegerPart(interY);
|
||||||
|
vtkm::Float32 factor = (x - x1) / dx;
|
||||||
|
vtkm::Float32 depth = vtkm::Lerp(z1, z2, factor);
|
||||||
|
vtkm::Float64 fieldValue = vtkm::Lerp(point1Field, point2Field, factor);
|
||||||
|
color = GetColor(fieldValue);
|
||||||
|
Plot(x, t, depth, color, ReverseFractionalPart(interY));
|
||||||
|
Plot(x, t + 1, depth, color, FractionalPart(interY));
|
||||||
|
interY += gradient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
using ColorMapPortalConst = typename ColorMapHandle::ExecutionTypes<DeviceTag>::PortalConst;
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
void TransformWorldToViewport(vtkm::Vec<vtkm::Float32, 3>& point) const
|
||||||
|
{
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> temp(point[0], point[1], point[2], 1.0f);
|
||||||
|
temp = vtkm::MatrixMultiply(WorldToProjection, temp);
|
||||||
|
for (vtkm::IdComponent i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
point[i] = temp[i] / temp[3];
|
||||||
|
}
|
||||||
|
// Scale to canvas width and height
|
||||||
|
point[0] = (point[0] * 0.5f + 0.5f) * vtkm::Float32(Width);
|
||||||
|
point[1] = (point[1] * 0.5f + 0.5f) * vtkm::Float32(Height);
|
||||||
|
// Convert from -1/+1 to 0/+1 range
|
||||||
|
point[2] = point[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.
|
||||||
|
point[2] -= Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC vtkm::Vec<vtkm::Float32, 4> GetColor(vtkm::Float64 fieldValue) const
|
||||||
|
{
|
||||||
|
vtkm::Int32 colorIdx =
|
||||||
|
vtkm::Int32((vtkm::Float32(fieldValue) - FieldMin) * ColorMapSize * InverseFieldDelta);
|
||||||
|
return ColorMap.Get(colorIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
void Plot(vtkm::Float32 x,
|
||||||
|
vtkm::Float32 y,
|
||||||
|
vtkm::Float32 depth,
|
||||||
|
const vtkm::Vec<vtkm::Float32, 4>& color,
|
||||||
|
vtkm::Float32 intensity) const
|
||||||
|
{
|
||||||
|
vtkm::Id xi = static_cast<vtkm::Id>(x), yi = static_cast<vtkm::Id>(y);
|
||||||
|
if (xi < 0 || xi >= Width || yi < 0 || yi >= Height)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vtkm::Id index = yi * Width + xi;
|
||||||
|
PackedValue current, next;
|
||||||
|
current.Raw = ClearValue;
|
||||||
|
next.Floats.Depth = depth;
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> blendedColor;
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> srcColor;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UnpackColor(current.Ints.Color, srcColor);
|
||||||
|
vtkm::Float32 inverseIntensity = (1.0f - intensity);
|
||||||
|
vtkm::Float32 alpha = srcColor[3] * inverseIntensity;
|
||||||
|
blendedColor[0] = color[0] * intensity + srcColor[0] * alpha;
|
||||||
|
blendedColor[1] = color[1] * intensity + srcColor[1] * alpha;
|
||||||
|
blendedColor[2] = color[2] * intensity + srcColor[2] * alpha;
|
||||||
|
blendedColor[3] = alpha + intensity;
|
||||||
|
next.Ints.Color = PackColor(blendedColor);
|
||||||
|
current.Raw = FrameBuffer.CompareAndSwap(index, next.Raw, current.Raw);
|
||||||
|
} while (current.Floats.Depth > next.Floats.Depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Matrix<vtkm::Float32, 4, 4> WorldToProjection;
|
||||||
|
vtkm::Id Width;
|
||||||
|
vtkm::Id Height;
|
||||||
|
ColorMapPortalConst ColorMap;
|
||||||
|
vtkm::Float32 ColorMapSize;
|
||||||
|
AtomicPackedFrameBufferHandle FrameBuffer;
|
||||||
|
vtkm::Float32 FieldMin;
|
||||||
|
vtkm::Float32 InverseFieldDelta;
|
||||||
|
vtkm::Float32 Offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BufferConverter : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VTKM_CONT
|
||||||
|
BufferConverter(vtkm::Vec<vtkm::Float32, 4> backgroundColor)
|
||||||
|
: BackgroundColor(backgroundColor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void ControlSignature(FieldIn<>, ExecObject, ExecObject);
|
||||||
|
typedef void ExecutionSignature(_1, _2, _3, WorkIndex);
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
void operator()(const vtkm::Int64& packedValue,
|
||||||
|
vtkm::exec::ExecutionWholeArray<vtkm::Float32>& depthBuffer,
|
||||||
|
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>& colorBuffer,
|
||||||
|
const vtkm::Id& index) const
|
||||||
|
{
|
||||||
|
PackedValue packed;
|
||||||
|
packed.Raw = packedValue;
|
||||||
|
float depth = packed.Floats.Depth;
|
||||||
|
if (depth <= depthBuffer.Get(index))
|
||||||
|
{
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> color;
|
||||||
|
UnpackColor(packed.Ints.Color, color);
|
||||||
|
colorBuffer.Set(index, color);
|
||||||
|
depthBuffer.Set(index, depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> BackgroundColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class Wireframer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VTKM_CONT
|
||||||
|
Wireframer(vtkm::rendering::Canvas* canvas, bool showInternalZones, bool isOverlay)
|
||||||
|
: Canvas(canvas)
|
||||||
|
, ShowInternalZones(showInternalZones)
|
||||||
|
, IsOverlay(isOverlay)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void SetCamera(const vtkm::rendering::Camera& camera) { this->Camera = camera; }
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void SetColorMap(const ColorMapHandle& colorMap) { this->ColorMap = colorMap; }
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void SetSolidDepthBuffer(const vtkm::cont::ArrayHandle<vtkm::Float32> depthBuffer)
|
||||||
|
{
|
||||||
|
this->SolidDepthBuffer = depthBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void SetData(const vtkm::cont::CoordinateSystem& coords,
|
||||||
|
const IndicesHandle& endPointIndices,
|
||||||
|
const vtkm::cont::Field& field,
|
||||||
|
const vtkm::Range& fieldRange)
|
||||||
|
{
|
||||||
|
this->Bounds = coords.GetBounds();
|
||||||
|
this->Coordinates = coords.GetData();
|
||||||
|
this->PointIndices = endPointIndices;
|
||||||
|
this->ScalarField = field;
|
||||||
|
this->ScalarFieldRange = fieldRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void Render()
|
||||||
|
{
|
||||||
|
RenderWithDeviceFunctor functor(this);
|
||||||
|
vtkm::cont::TryExecute(functor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename DeviceTag>
|
||||||
|
VTKM_CONT void RenderWithDevice(DeviceTag)
|
||||||
|
{
|
||||||
|
if (ScalarField.GetAssociation() != vtkm::cont::Field::ASSOC_POINTS)
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorBadValue("Field is not associated with points");
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Matrix<vtkm::Float32, 4, 4> WorldToProjection =
|
||||||
|
vtkm::MatrixMultiply(Camera.CreateProjectionMatrix(Canvas->GetWidth(), Canvas->GetHeight()),
|
||||||
|
Camera.CreateViewMatrix());
|
||||||
|
vtkm::Id width = static_cast<vtkm::Id>(Canvas->GetWidth());
|
||||||
|
vtkm::Id height = static_cast<vtkm::Id>(Canvas->GetHeight());
|
||||||
|
vtkm::Id pixelCount = width * height;
|
||||||
|
FrameBuffer.PrepareForOutput(pixelCount, DeviceTag());
|
||||||
|
|
||||||
|
vtkm::Vec<vtkm::Float32, 4> clearColor = Canvas->GetBackgroundColor().Components;
|
||||||
|
vtkm::UInt32 packedClearColor = PackColor(clearColor);
|
||||||
|
if (ShowInternalZones && !IsOverlay)
|
||||||
|
{
|
||||||
|
using MemSet =
|
||||||
|
typename vtkm::rendering::Triangulator<DeviceTag>::template MemSet<vtkm::Int64>;
|
||||||
|
vtkm::Int64 clearValue = (ClearDepth << 32) | packedClearColor;
|
||||||
|
MemSet memSet(clearValue);
|
||||||
|
vtkm::worklet::DispatcherMapField<MemSet>(memSet).Invoke(FrameBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VTKM_ASSERT(SolidDepthBuffer.GetNumberOfValues() == pixelCount);
|
||||||
|
CopyIntoFrameBuffer bufferCopy;
|
||||||
|
vtkm::worklet::DispatcherMapField<CopyIntoFrameBuffer>(bufferCopy)
|
||||||
|
.Invoke(Canvas->GetColorBuffer(), SolidDepthBuffer, FrameBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgePlotter<DeviceTag> plotter(WorldToProjection,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
ScalarFieldRange,
|
||||||
|
ColorMap,
|
||||||
|
FrameBuffer,
|
||||||
|
Camera.GetClippingRange());
|
||||||
|
vtkm::worklet::DispatcherMapField<EdgePlotter<DeviceTag>, DeviceTag>(plotter).Invoke(
|
||||||
|
PointIndices, Coordinates, ScalarField.GetData());
|
||||||
|
|
||||||
|
BufferConverter converter(clearColor);
|
||||||
|
vtkm::worklet::DispatcherMapField<BufferConverter, DeviceTag>(converter).Invoke(
|
||||||
|
FrameBuffer,
|
||||||
|
vtkm::exec::ExecutionWholeArray<vtkm::Float32>(Canvas->GetDepthBuffer()),
|
||||||
|
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>(Canvas->GetColorBuffer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
struct RenderWithDeviceFunctor
|
||||||
|
{
|
||||||
|
Wireframer* Renderer;
|
||||||
|
|
||||||
|
RenderWithDeviceFunctor(Wireframer* renderer)
|
||||||
|
: Renderer(renderer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DeviceTag>
|
||||||
|
VTKM_CONT bool operator()(DeviceTag)
|
||||||
|
{
|
||||||
|
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceTag);
|
||||||
|
Renderer->RenderWithDevice(DeviceTag());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vtkm::Bounds Bounds;
|
||||||
|
vtkm::rendering::Camera Camera;
|
||||||
|
vtkm::rendering::Canvas* Canvas;
|
||||||
|
bool ShowInternalZones;
|
||||||
|
bool IsOverlay;
|
||||||
|
ColorMapHandle ColorMap;
|
||||||
|
vtkm::cont::DynamicArrayHandleCoordinateSystem Coordinates;
|
||||||
|
IndicesHandle PointIndices;
|
||||||
|
vtkm::cont::Field ScalarField;
|
||||||
|
vtkm::Range ScalarFieldRange;
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> SolidDepthBuffer;
|
||||||
|
PackedFrameBufferHandle FrameBuffer;
|
||||||
|
}; // class Wireframer
|
||||||
|
}
|
||||||
|
} //namespace vtkm::rendering
|
||||||
|
|
||||||
|
#endif //vtk_m_rendering_Wireframer_h
|
@ -29,6 +29,7 @@ set(unit_tests
|
|||||||
UnitTestMultiMapper.cxx
|
UnitTestMultiMapper.cxx
|
||||||
UnitTestMapperRayTracer.cxx
|
UnitTestMapperRayTracer.cxx
|
||||||
UnitTestMapperVolume.cxx
|
UnitTestMapperVolume.cxx
|
||||||
|
UnitTestMapperWireframer.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
VTKm_unit_tests(SOURCES ${unit_tests})
|
VTKm_unit_tests(SOURCES ${unit_tests})
|
||||||
|
52
vtkm/rendering/testing/UnitTestMapperWireframer.cxx
Normal file
52
vtkm/rendering/testing/UnitTestMapperWireframer.cxx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Copyright 2015 Sandia Corporation.
|
||||||
|
// Copyright 2015 UT-Battelle, LLC.
|
||||||
|
// Copyright 2015 Los Alamos National Security.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// the U.S. Government retains certain rights in this software.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||||
|
// this software.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/DeviceAdapter.h>
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||||
|
#include <vtkm/rendering/MapperWireframer.h>
|
||||||
|
#include <vtkm/rendering/testing/RenderTest.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void RenderTests()
|
||||||
|
{
|
||||||
|
typedef vtkm::rendering::MapperWireframer M;
|
||||||
|
typedef vtkm::rendering::CanvasRayTracer C;
|
||||||
|
typedef vtkm::rendering::View3D V3;
|
||||||
|
|
||||||
|
vtkm::cont::testing::MakeTestDataSet maker;
|
||||||
|
vtkm::rendering::ColorTable colorTable("thermal");
|
||||||
|
|
||||||
|
vtkm::rendering::testing::Render<M, C, V3>(
|
||||||
|
maker.Make3DRegularDataSet0(), "pointvar", colorTable, "reg3D.pnm");
|
||||||
|
vtkm::rendering::testing::Render<M, C, V3>(
|
||||||
|
maker.Make3DRectilinearDataSet0(), "pointvar", colorTable, "rect3D.pnm");
|
||||||
|
vtkm::rendering::testing::Render<M, C, V3>(
|
||||||
|
maker.Make3DExplicitDataSet4(), "pointvar", colorTable, "expl3D.pnm");
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
int UnitTestMapperWireframer(int, char* [])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(RenderTests);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user