mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
refactoring ray tracing
This commit is contained in:
parent
bc9772021c
commit
1c2f78ca92
@ -28,9 +28,10 @@
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
|
||||
#include <vtkm/rendering/Camera.h>
|
||||
#include <vtkm/rendering/internal/RunTriangulator.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleExtractor.h>
|
||||
|
||||
#include <vtkm/exec/FunctorBase.h>
|
||||
|
||||
@ -66,18 +67,24 @@ struct BenchRayTracing
|
||||
camera.ResetToBounds(bounds);
|
||||
|
||||
vtkm::cont::DynamicCellSet cellset = Data.GetCellSet();
|
||||
vtkm::rendering::internal::RunTriangulator(cellset, Indices, NumberOfTriangles);
|
||||
|
||||
vtkm::rendering::raytracing::TriangleExtractor triExtractor;
|
||||
triExtractor.ExtractCells(cellset);
|
||||
vtkm::rendering::raytracing::TriangleIntersector* triIntersector =
|
||||
new vtkm::rendering::raytracing::TriangleIntersector();
|
||||
triIntersector->SetData(Coords, triExtractor.GetTriangles());
|
||||
Tracer.AddShapeIntersector(triIntersector);
|
||||
|
||||
vtkm::rendering::CanvasRayTracer canvas(1920, 1080);
|
||||
RayCamera.SetParameters(camera, canvas);
|
||||
RayCamera.CreateRays(Rays, Coords);
|
||||
RayCamera.CreateRays(Rays, Coords.GetBounds());
|
||||
|
||||
Rays.Buffers.at(0).InitConst(0.f);
|
||||
|
||||
vtkm::cont::Field field = Data.GetField("pointvar");
|
||||
vtkm::Range range = field.GetRange().GetPortalConstControl().Get(0);
|
||||
|
||||
Tracer.SetData(Coords.GetData(), Indices, field, NumberOfTriangles, range, bounds);
|
||||
Tracer.SetField(field, range);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> temp;
|
||||
vtkm::cont::ColorTable table("cool to warm");
|
||||
@ -107,7 +114,7 @@ struct BenchRayTracing
|
||||
{
|
||||
vtkm::cont::Timer<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> timer;
|
||||
|
||||
RayCamera.CreateRays(Rays, Coords);
|
||||
RayCamera.CreateRays(Rays, Coords.GetBounds());
|
||||
Tracer.Render(Rays);
|
||||
|
||||
return timer.GetElapsedTime();
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
vtkm::cont::DataSet Make3DExplicitDataSet4();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSet5();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSet6();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSet7();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSet8();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSetZoo();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSetPolygonal();
|
||||
vtkm::cont::DataSet Make3DExplicitDataSetCowNose();
|
||||
};
|
||||
@ -924,6 +927,400 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DExplicitDataSet6()
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
inline vtkm::cont::DataSet MakeTestDataSet::Make3DExplicitDataSetZoo()
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
vtkm::cont::DataSetBuilderExplicit dsb;
|
||||
vtkm::cont::DataSetFieldAdd dsf;
|
||||
|
||||
// Coordinates
|
||||
const int nVerts = 30;
|
||||
const int nCells = 27;
|
||||
using CoordType = vtkm::Vec<vtkm::Float32, 3>;
|
||||
|
||||
std::vector<CoordType> coords =
|
||||
|
||||
{ { 0.00f, 0.00f, 0.00f }, { 1.00f, 0.00f, 0.00f }, { 2.00f, 0.00f, 0.00f },
|
||||
{ 0.00f, 0.00f, 1.00f }, { 1.00f, 0.00f, 1.00f }, { 2.00f, 0.00f, 1.00f },
|
||||
{ 0.00f, 1.00f, 0.00f }, { 1.00f, 1.00f, 0.00f }, { 2.00f, 1.00f, 0.00f },
|
||||
{ 0.00f, 1.00f, 1.00f }, { 1.00f, 1.00f, 1.00f }, { 2.00f, 1.00f, 1.00f },
|
||||
{ 0.00f, 2.00f, 0.00f }, { 1.00f, 2.00f, 0.00f }, { 2.00f, 2.00f, 0.00f },
|
||||
{ 0.00f, 2.00f, 1.00f }, { 1.00f, 2.00f, 1.00f }, { 2.00f, 2.00f, 1.00f },
|
||||
{ 1.00f, 3.00f, 1.00f }, { 2.75f, 0.00f, 1.00f }, { 3.00f, 0.00f, 0.75f },
|
||||
{ 3.00f, 0.25f, 1.00f }, { 3.00f, 1.00f, 1.00f }, { 3.00f, 1.00f, 0.00f },
|
||||
{ 2.57f, 2.00f, 1.00f }, { 3.00f, 1.75f, 1.00f }, { 3.00f, 1.75f, 0.75f },
|
||||
{ 3.00f, 0.00f, 0.00f }, { 2.57f, 0.42f, 0.57f }, { 2.59f, 1.43f, 0.71f } };
|
||||
|
||||
// Connectivity
|
||||
std::vector<vtkm::UInt8> shapes;
|
||||
std::vector<vtkm::IdComponent> numindices;
|
||||
std::vector<vtkm::Id> conn;
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_HEXAHEDRON);
|
||||
numindices.push_back(8);
|
||||
conn.push_back(0);
|
||||
conn.push_back(3);
|
||||
conn.push_back(4);
|
||||
conn.push_back(1);
|
||||
conn.push_back(6);
|
||||
conn.push_back(9);
|
||||
conn.push_back(10);
|
||||
conn.push_back(7);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_HEXAHEDRON);
|
||||
numindices.push_back(8);
|
||||
conn.push_back(1);
|
||||
conn.push_back(4);
|
||||
conn.push_back(5);
|
||||
conn.push_back(2);
|
||||
conn.push_back(7);
|
||||
conn.push_back(10);
|
||||
conn.push_back(11);
|
||||
conn.push_back(8);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(23);
|
||||
conn.push_back(26);
|
||||
conn.push_back(24);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(24);
|
||||
conn.push_back(26);
|
||||
conn.push_back(25);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(8);
|
||||
conn.push_back(17);
|
||||
conn.push_back(11);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(17);
|
||||
conn.push_back(24);
|
||||
conn.push_back(25);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(24);
|
||||
conn.push_back(17);
|
||||
conn.push_back(8);
|
||||
conn.push_back(23);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(23);
|
||||
conn.push_back(8);
|
||||
conn.push_back(11);
|
||||
conn.push_back(22);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(25);
|
||||
conn.push_back(22);
|
||||
conn.push_back(11);
|
||||
conn.push_back(17);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(26);
|
||||
conn.push_back(23);
|
||||
conn.push_back(22);
|
||||
conn.push_back(25);
|
||||
conn.push_back(29);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(23);
|
||||
conn.push_back(8);
|
||||
conn.push_back(2);
|
||||
conn.push_back(27);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(22);
|
||||
conn.push_back(11);
|
||||
conn.push_back(8);
|
||||
conn.push_back(23);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(11);
|
||||
conn.push_back(5);
|
||||
conn.push_back(2);
|
||||
conn.push_back(8);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(21);
|
||||
conn.push_back(19);
|
||||
conn.push_back(5);
|
||||
conn.push_back(11);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(11);
|
||||
conn.push_back(22);
|
||||
conn.push_back(21);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(5);
|
||||
conn.push_back(19);
|
||||
conn.push_back(20);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(23);
|
||||
conn.push_back(27);
|
||||
conn.push_back(20);
|
||||
conn.push_back(21);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(20);
|
||||
conn.push_back(27);
|
||||
conn.push_back(2);
|
||||
conn.push_back(5);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(19);
|
||||
conn.push_back(21);
|
||||
conn.push_back(20);
|
||||
conn.push_back(28);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(7);
|
||||
conn.push_back(6);
|
||||
conn.push_back(12);
|
||||
conn.push_back(13);
|
||||
conn.push_back(16);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(6);
|
||||
conn.push_back(9);
|
||||
conn.push_back(15);
|
||||
conn.push_back(12);
|
||||
conn.push_back(16);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_PYRAMID);
|
||||
numindices.push_back(5);
|
||||
conn.push_back(6);
|
||||
conn.push_back(7);
|
||||
conn.push_back(10);
|
||||
conn.push_back(9);
|
||||
conn.push_back(16);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TETRA);
|
||||
numindices.push_back(4);
|
||||
conn.push_back(12);
|
||||
conn.push_back(15);
|
||||
conn.push_back(16);
|
||||
conn.push_back(18);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_WEDGE);
|
||||
numindices.push_back(6);
|
||||
conn.push_back(8);
|
||||
conn.push_back(14);
|
||||
conn.push_back(17);
|
||||
conn.push_back(7);
|
||||
conn.push_back(13);
|
||||
conn.push_back(16);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_WEDGE);
|
||||
numindices.push_back(6);
|
||||
conn.push_back(11);
|
||||
conn.push_back(8);
|
||||
conn.push_back(17);
|
||||
conn.push_back(10);
|
||||
conn.push_back(7);
|
||||
conn.push_back(16);
|
||||
|
||||
dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates", "cells");
|
||||
|
||||
// Field data
|
||||
vtkm::Float32 pointvar[nVerts] =
|
||||
|
||||
{ 4.0, 5.0f, 9.5f, 5.5f, 6.0f, 9.5f, 5.0f, 5.5f, 5.7f, 6.5f, 6.4f, 6.9f, 6.6f, 6.1f, 7.1f,
|
||||
7.2f, 7.3f, 7.4f, 9.1f, 9.2f, 9.3f, 5.4f, 9.5f, 9.6f, 6.7f, 9.8f, 6.0f, 4.3f, 4.9f, 4.1f };
|
||||
|
||||
vtkm::Float32 cellvar[nCells] =
|
||||
|
||||
{ 4.0f, 5.0f, 9.5f, 5.5f, 6.0f, 9.5f, 5.0f, 5.5f, 5.7f, 6.5f, 6.4f, 6.9f, 6.6f, 6.1f,
|
||||
7.1f, 7.2f, 7.3f, 7.4f, 9.1f, 9.2f, 9.3f, 5.4f, 9.5f, 9.6f, 6.7f, 9.8f, 6.0f };
|
||||
|
||||
dsf.AddPointField(dataSet, "pointvar", pointvar, nVerts);
|
||||
dsf.AddCellField(dataSet, "cellvar", cellvar, nCells, "cells");
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
inline vtkm::cont::DataSet MakeTestDataSet::Make3DExplicitDataSet7()
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
vtkm::cont::DataSetBuilderExplicit dsb;
|
||||
vtkm::cont::DataSetFieldAdd dsf;
|
||||
|
||||
// Coordinates
|
||||
const int nVerts = 8;
|
||||
const int nCells = 8;
|
||||
|
||||
using CoordType = vtkm::Vec<vtkm::Float32, 3>;
|
||||
std::vector<CoordType> coords = { { -0.707f, -0.354f, -0.354f }, { 0.000f, -0.854f, 0.146f },
|
||||
{ 0.000f, -0.146f, 0.854f }, { -0.707f, 0.354f, 0.354f },
|
||||
{ 10.0f, 10.0f, 10.0f }, { 5.0f, 5.0f, 5.0f },
|
||||
{ 0.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, -2.0f } };
|
||||
|
||||
// Connectivity
|
||||
std::vector<vtkm::UInt8> shapes;
|
||||
std::vector<vtkm::IdComponent> numindices;
|
||||
std::vector<vtkm::Id> conn;
|
||||
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(0);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(1);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(2);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(3);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(4);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(5);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(6);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_VERTEX);
|
||||
numindices.push_back(1);
|
||||
conn.push_back(7);
|
||||
|
||||
|
||||
dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates", "cells");
|
||||
|
||||
// Field data
|
||||
vtkm::Float32 pointvar[nVerts] = { 100.0f, 78.0f, 49.0f, 17.0f, 10.f, 20.f, 33.f, 52.f };
|
||||
vtkm::Float32 cellvar[nCells] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f };
|
||||
|
||||
dsf.AddPointField(dataSet, "pointvar", pointvar, nVerts);
|
||||
dsf.AddCellField(dataSet, "cellvar", cellvar, nCells, "cells");
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
inline vtkm::cont::DataSet MakeTestDataSet::Make3DExplicitDataSet8()
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
vtkm::cont::DataSetBuilderExplicit dsb;
|
||||
vtkm::cont::DataSetFieldAdd dsf;
|
||||
|
||||
// Coordinates
|
||||
const int nVerts = 8;
|
||||
const int nCells = 10;
|
||||
using CoordType = vtkm::Vec<vtkm::Float32, 3>;
|
||||
std::vector<CoordType> coords = { { -0.707f, -0.354f, -0.354f }, { 0.000f, -0.854f, 0.146f },
|
||||
{ 0.000f, -0.146f, 0.854f }, { -0.707f, 0.354f, 0.354f },
|
||||
{ 10.0f, 10.0f, 10.0f }, { 5.0f, 5.0f, 5.0f },
|
||||
{ 0.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, -2.0f } };
|
||||
|
||||
// Connectivity
|
||||
std::vector<vtkm::UInt8> shapes;
|
||||
std::vector<vtkm::IdComponent> numindices;
|
||||
std::vector<vtkm::Id> conn;
|
||||
|
||||
//I need two triangles because the leaf needs four nodes otherwise segfault?
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(0);
|
||||
conn.push_back(1);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(1);
|
||||
conn.push_back(2);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(2);
|
||||
conn.push_back(3);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(3);
|
||||
conn.push_back(4);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(4);
|
||||
conn.push_back(5);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(5);
|
||||
conn.push_back(6);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_LINE);
|
||||
numindices.push_back(2);
|
||||
conn.push_back(6);
|
||||
conn.push_back(7);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE);
|
||||
numindices.push_back(3);
|
||||
conn.push_back(2);
|
||||
conn.push_back(5);
|
||||
conn.push_back(4);
|
||||
|
||||
shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE);
|
||||
numindices.push_back(3);
|
||||
conn.push_back(4);
|
||||
conn.push_back(5);
|
||||
conn.push_back(6);
|
||||
|
||||
dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates", "cells");
|
||||
|
||||
// Field data
|
||||
vtkm::Float32 pointvar[nVerts] = { 100.0f, 78.0f, 49.0f, 17.0f, 94.0f, 71.0f, 47.0f, 57.0f };
|
||||
vtkm::Float32 cellvar[nCells] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f };
|
||||
|
||||
dsf.AddPointField(dataSet, "pointvar", pointvar, nVerts);
|
||||
dsf.AddCellField(dataSet, "cellvar", cellvar, nCells, "cells");
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
inline vtkm::cont::DataSet MakeTestDataSet::Make3DExplicitDataSetPolygonal()
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
@ -59,15 +59,20 @@ set(headers
|
||||
ColorBarAnnotation.h
|
||||
ColorLegendAnnotation.h
|
||||
ConnectivityProxy.h
|
||||
Cylinderizer.h
|
||||
DecodePNG.h
|
||||
LineRenderer.h
|
||||
MatrixHelpers.h
|
||||
Scene.h
|
||||
Mapper.h
|
||||
MapperCylinder.h
|
||||
MapperPoint.h
|
||||
MapperQuad.h
|
||||
MapperRayTracer.h
|
||||
MapperVolume.h
|
||||
MapperConnectivity.h
|
||||
MapperWireframer.h
|
||||
Quadralizer.h
|
||||
TextAnnotation.h
|
||||
TextAnnotationBillboard.h
|
||||
TextAnnotationScreen.h
|
||||
@ -96,8 +101,12 @@ set(sources
|
||||
DecodePNG.cxx
|
||||
LineRenderer.cxx
|
||||
MapperConnectivity.cxx
|
||||
MapperCylinder.cxx
|
||||
MapperPoint.cxx
|
||||
MapperQuad.cxx
|
||||
MapperRayTracer.cxx
|
||||
MapperVolume.cxx
|
||||
#MapperWireframer.cxx
|
||||
Scene.cxx
|
||||
TextAnnotation.cxx
|
||||
TextAnnotationBillboard.cxx
|
||||
@ -107,10 +116,6 @@ set(sources
|
||||
View2D.cxx
|
||||
View3D.cxx
|
||||
WorldAnnotator.cxx
|
||||
|
||||
raytracing/ConnectivityBase.cxx
|
||||
raytracing/ConnectivityTracerBase.cxx
|
||||
raytracing/ConnectivityTracerFactory.cxx
|
||||
raytracing/Logger.cxx
|
||||
)
|
||||
|
||||
@ -161,8 +166,18 @@ set(device_sources
|
||||
raytracing/Camera.cxx
|
||||
raytracing/ChannelBuffer.cxx
|
||||
raytracing/ConnectivityTracer.cxx
|
||||
raytracing/RayOperations.cxx
|
||||
raytracing/CylinderExtractor.cxx
|
||||
raytracing/CylinderIntersector.cxx
|
||||
raytracing/MeshConnectivityBuilder.cxx
|
||||
raytracing/MeshConnectivityContainers.cxx
|
||||
raytracing/QuadExtractor.cxx
|
||||
raytracing/QuadIntersector.cxx
|
||||
raytracing/RayTracer.cxx
|
||||
raytracing/RayOperations.cxx
|
||||
raytracing/ShapeIntersector.cxx
|
||||
raytracing/SphereExtractor.cxx
|
||||
raytracing/SphereIntersector.cxx
|
||||
raytracing/TriangleExtractor.cxx
|
||||
raytracing/VolumeRendererStructured.cxx
|
||||
)
|
||||
|
||||
|
@ -313,8 +313,11 @@ void Canvas::Activate()
|
||||
|
||||
void Canvas::Clear()
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<internal::ClearBuffers>().Invoke(this->GetColorBuffer(),
|
||||
this->GetDepthBuffer());
|
||||
// TODO: Should the rendering library support policies or some other way to
|
||||
// configure with custom devices?
|
||||
internal::ClearBuffers worklet;
|
||||
vtkm::worklet::DispatcherMapField<internal::ClearBuffers> dispatcher(worklet);
|
||||
dispatcher.Invoke(this->GetColorBuffer(), this->GetDepthBuffer());
|
||||
}
|
||||
|
||||
void Canvas::Finish()
|
||||
@ -323,9 +326,9 @@ void Canvas::Finish()
|
||||
|
||||
void Canvas::BlendBackground()
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<internal::BlendBackground>(
|
||||
this->GetBackgroundColor().Components)
|
||||
.Invoke(this->GetColorBuffer());
|
||||
internal::BlendBackground worklet(GetBackgroundColor().Components);
|
||||
vtkm::worklet::DispatcherMapField<internal::BlendBackground> dispatcher(worklet);
|
||||
dispatcher.Invoke(this->GetColorBuffer());
|
||||
}
|
||||
|
||||
void Canvas::ResizeBuffers(vtkm::Id width, vtkm::Id height)
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/ConnectivityProxy.h>
|
||||
#include <vtkm/rendering/Mapper.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracerFactory.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracer.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
|
||||
@ -34,9 +34,9 @@ struct ConnectivityProxy::InternalsType
|
||||
{
|
||||
protected:
|
||||
using ColorMapType = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||
using BaseType = vtkm::rendering::raytracing::ConnectivityBase;
|
||||
using TracerType = vtkm::rendering::raytracing::ConnectivityTracer;
|
||||
|
||||
BaseType* Tracer;
|
||||
TracerType Tracer;
|
||||
vtkm::cont::Field ScalarField;
|
||||
vtkm::cont::Field EmissionField;
|
||||
vtkm::cont::DynamicCellSet Cells;
|
||||
@ -48,29 +48,6 @@ protected:
|
||||
vtkm::Range ScalarRange;
|
||||
bool CompositeBackground;
|
||||
|
||||
struct BoundsFunctor
|
||||
{
|
||||
vtkm::rendering::ConnectivityProxy::InternalsType* Internals;
|
||||
const vtkm::cont::CoordinateSystem& Coordinates;
|
||||
|
||||
VTKM_CONT
|
||||
BoundsFunctor(vtkm::rendering::ConnectivityProxy::InternalsType* self,
|
||||
const vtkm::cont::CoordinateSystem& coordinates)
|
||||
: Internals(self)
|
||||
, Coordinates(coordinates)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
|
||||
Internals->SpatialBounds = Internals->Coords.GetBounds();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
InternalsType(vtkm::cont::DataSet& dataSet)
|
||||
{
|
||||
@ -87,11 +64,9 @@ public:
|
||||
{
|
||||
this->SetScalarField(Dataset.GetField(0).GetName());
|
||||
}
|
||||
|
||||
Tracer = raytracing::ConnectivityTracerFactory::CreateTracer(Cells, Coords);
|
||||
}
|
||||
|
||||
~InternalsType() { delete Tracer; }
|
||||
~InternalsType() {}
|
||||
|
||||
void SetSampleDistance(const vtkm::Float32& distance)
|
||||
{
|
||||
@ -100,7 +75,7 @@ public:
|
||||
std::cout << "Volume Tracer Error: must set volume mode before setting sample dist\n";
|
||||
return;
|
||||
}
|
||||
Tracer->SetSampleDistance(distance);
|
||||
Tracer.SetSampleDistance(distance);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -120,14 +95,14 @@ public:
|
||||
VTKM_CONT
|
||||
void SetColorMap(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colormap)
|
||||
{
|
||||
Tracer->SetColorMap(colormap);
|
||||
Tracer.SetColorMap(colormap);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void SetCompositeBackground(bool on) { CompositeBackground = on; }
|
||||
|
||||
VTKM_CONT
|
||||
void SetDebugPrints(bool on) { Tracer->SetDebugOn(on); }
|
||||
void SetDebugPrints(bool vtkmNotUsed(on)) { /*Tracer->SetDebugOn(on);*/}
|
||||
|
||||
VTKM_CONT
|
||||
void SetEmissionField(const std::string& fieldName)
|
||||
@ -155,15 +130,18 @@ public:
|
||||
|
||||
if (Mode == VOLUME_MODE)
|
||||
{
|
||||
Tracer->SetVolumeData(this->ScalarField, this->ScalarRange);
|
||||
Tracer.SetVolumeData(this->ScalarField, this->ScalarRange, this->Cells, this->Coords);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracer->SetEnergyData(
|
||||
this->ScalarField, rays.Buffers.at(0).GetNumChannels(), this->EmissionField);
|
||||
Tracer.SetEnergyData(this->ScalarField,
|
||||
rays.Buffers.at(0).GetNumChannels(),
|
||||
this->Cells,
|
||||
this->Coords,
|
||||
this->EmissionField);
|
||||
}
|
||||
|
||||
Tracer->Trace(rays);
|
||||
Tracer.Trace(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -171,14 +149,18 @@ public:
|
||||
{
|
||||
if (Mode == VOLUME_MODE)
|
||||
{
|
||||
Tracer->SetVolumeData(this->ScalarField, this->ScalarRange);
|
||||
Tracer.SetVolumeData(this->ScalarField, this->ScalarRange, this->Cells, this->Coords);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracer->SetEnergyData(
|
||||
this->ScalarField, rays.Buffers.at(0).GetNumChannels(), this->EmissionField);
|
||||
Tracer.SetEnergyData(this->ScalarField,
|
||||
rays.Buffers.at(0).GetNumChannels(),
|
||||
this->Cells,
|
||||
this->Coords,
|
||||
this->EmissionField);
|
||||
}
|
||||
Tracer->Trace(rays);
|
||||
|
||||
Tracer.Trace(rays);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -193,20 +175,20 @@ public:
|
||||
vtkm::rendering::raytracing::Camera rayCamera;
|
||||
rayCamera.SetParameters(camera, *canvas);
|
||||
vtkm::rendering::raytracing::Ray<vtkm::Float32> rays;
|
||||
rayCamera.CreateRays(rays, this->Coords);
|
||||
rayCamera.CreateRays(rays, this->Coords.GetBounds());
|
||||
rays.Buffers.at(0).InitConst(0.f);
|
||||
raytracing::RayOperations::MapCanvasToRays(rays, camera, *canvas);
|
||||
|
||||
if (Mode == VOLUME_MODE)
|
||||
{
|
||||
Tracer->SetVolumeData(this->ScalarField, this->ScalarRange);
|
||||
Tracer.SetVolumeData(this->ScalarField, this->ScalarRange, this->Cells, this->Coords);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("ENERGY MODE Not implemented for this use case\n");
|
||||
}
|
||||
|
||||
Tracer->Trace(rays);
|
||||
Tracer.Trace(rays);
|
||||
|
||||
canvas->WriteToCanvas(rays, rays.Buffers.at(0).Buffer, camera);
|
||||
if (CompositeBackground)
|
||||
|
@ -24,10 +24,8 @@
|
||||
#include <vtkm/rendering/MapperConnectivity.h>
|
||||
#include <vtkm/rendering/View.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracerFactory.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/SphereExtractor.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleExtractor.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -91,25 +94,38 @@ void MapperRayTracer::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
logger->OpenLogEntry("mapper_ray_tracer");
|
||||
vtkm::cont::Timer<> tot_timer;
|
||||
vtkm::cont::Timer<> timer;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> indices;
|
||||
vtkm::Id numberOfTriangles;
|
||||
|
||||
vtkm::rendering::internal::RunTriangulator(cellset, indices, numberOfTriangles);
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("triangulator", time);
|
||||
// make sure we start fresh
|
||||
this->Internals->Tracer.Clear();
|
||||
//
|
||||
// Add supported shapes
|
||||
//
|
||||
vtkm::Bounds shapeBounds;
|
||||
raytracing::TriangleExtractor triExtractor;
|
||||
triExtractor.ExtractCells(cellset);
|
||||
if (triExtractor.GetNumberOfTriangles() > 0)
|
||||
{
|
||||
raytracing::TriangleIntersector* triIntersector = new raytracing::TriangleIntersector();
|
||||
triIntersector->SetData(coords, triExtractor.GetTriangles());
|
||||
this->Internals->Tracer.AddShapeIntersector(triIntersector);
|
||||
shapeBounds.Include(triIntersector->GetShapeBounds());
|
||||
}
|
||||
|
||||
//
|
||||
// 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);
|
||||
|
||||
this->Internals->RayCamera.CreateRays(this->Internals->Rays, coords);
|
||||
this->Internals->RayCamera.CreateRays(this->Internals->Rays, shapeBounds);
|
||||
this->Internals->Rays.Buffers.at(0).InitConst(0.f);
|
||||
raytracing::RayOperations::MapCanvasToRays(
|
||||
this->Internals->Rays, camera, *this->Internals->Canvas);
|
||||
|
||||
vtkm::Bounds dataBounds = coords.GetBounds();
|
||||
vtkm::cont::Field& field = const_cast<vtkm::cont::Field&>(scalarField);
|
||||
this->Internals->Tracer.SetData(
|
||||
coords.GetData(), indices, field, numberOfTriangles, scalarRange, dataBounds);
|
||||
|
||||
|
||||
this->Internals->Tracer.SetField(scalarField, scalarRange);
|
||||
|
||||
this->Internals->Tracer.SetColorMap(this->ColorMap);
|
||||
this->Internals->Tracer.Render(this->Internals->Rays);
|
||||
@ -123,7 +139,7 @@ void MapperRayTracer::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
this->Internals->Canvas->BlendBackground();
|
||||
}
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("write_to_canvas", time);
|
||||
time = tot_timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
|
@ -114,7 +114,7 @@ void MapperVolume::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
|
||||
|
||||
rayCamera.SetParameters(camera, *this->Internals->Canvas);
|
||||
|
||||
rayCamera.CreateRays(rays, coords);
|
||||
rayCamera.CreateRays(rays, coords.GetBounds());
|
||||
rays.Buffers.at(0).InitConst(0.f);
|
||||
raytracing::RayOperations::MapCanvasToRays(rays, camera, *this->Internals->Canvas);
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifndef vtk_m_rendering_Texture2D_h
|
||||
#define vtk_m_rendering_Texture2D_h
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
@ -77,7 +77,7 @@ public:
|
||||
// We do not know the lifetime of the underlying data source of input `data`. Since it might
|
||||
// be from a shallow copy of the data source, we make a deep copy of the input data and keep
|
||||
// it's portal. The copy operation is very fast.
|
||||
vtkm::cont::ArrayCopy(data, Data);
|
||||
vtkm::cont::Algorithm::Copy(data, Data);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
|
@ -20,11 +20,12 @@
|
||||
#ifndef vtk_m_rendering_Triangulator_h
|
||||
#define vtk_m_rendering_Triangulator_h
|
||||
|
||||
#include <typeinfo>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/CellSetPermutation.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
@ -36,35 +37,11 @@ namespace rendering
|
||||
///
|
||||
/// This class creates a array of triangle indices from both 3D and 2D
|
||||
/// explicit cell sets. This list can serve as input to opengl and the
|
||||
/// ray tracer scene renderers. TODO: Add regular grid support
|
||||
/// ray tracer scene renderers.
|
||||
///
|
||||
template <typename Device>
|
||||
class Triangulator
|
||||
{
|
||||
private:
|
||||
using IdArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using Vec4ArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using Vec4ArrayPortalType = typename Vec4ArrayHandle::ExecutionTypes<Device>::Portal;
|
||||
using IdPortalConstType = typename IdArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
public:
|
||||
template <class T>
|
||||
class MemSet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
T Value;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MemSet(T value)
|
||||
: Value(value)
|
||||
{
|
||||
}
|
||||
using ControlSignature = void(FieldOut<>);
|
||||
using ExecutionSignature = void(_1);
|
||||
VTKM_EXEC
|
||||
void operator()(T& outValue) const { outValue = Value; }
|
||||
}; //class MemSet
|
||||
|
||||
class CountTriangles : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
public:
|
||||
@ -108,27 +85,21 @@ public:
|
||||
template <int DIM>
|
||||
class TrianglulateStructured : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
private:
|
||||
Vec4ArrayPortalType OutputIndices;
|
||||
|
||||
public:
|
||||
using ControlSignature = void(CellSetIn cellset, FieldInTo<>);
|
||||
using ExecutionSignature = void(FromIndices, _2);
|
||||
//using InputDomain = _1;
|
||||
using ControlSignature = void(CellSetIn cellset, FieldInTo<>, WholeArrayOut<>);
|
||||
using ExecutionSignature = void(FromIndices, _2, _3);
|
||||
VTKM_CONT
|
||||
TrianglulateStructured(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& outputIndices)
|
||||
{
|
||||
this->OutputIndices =
|
||||
outputIndices.PrepareForOutput(outputIndices.GetNumberOfValues(), Device());
|
||||
}
|
||||
TrianglulateStructured() {}
|
||||
|
||||
#if defined(VTKM_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127) //conditional expression is constant
|
||||
#endif
|
||||
//TODO: Remove the if/then with templates.
|
||||
template <typename CellNodeVecType>
|
||||
VTKM_EXEC void operator()(const CellNodeVecType& cellIndices, const vtkm::Id& cellIndex) const
|
||||
template <typename CellNodeVecType, typename OutIndicesPortal>
|
||||
VTKM_EXEC void operator()(const CellNodeVecType& cellIndices,
|
||||
const vtkm::Id& cellIndex,
|
||||
OutIndicesPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 4> triangle;
|
||||
if (DIM == 2)
|
||||
@ -139,10 +110,10 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[2];
|
||||
triangle[0] = cellIndex;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
// 0-3-2
|
||||
triangle[2] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
}
|
||||
else if (DIM == 3)
|
||||
{
|
||||
@ -152,62 +123,62 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[5];
|
||||
triangle[0] = cellIndex;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 2, triangle);
|
||||
outputIndices.Set(triangleOffset + 2, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[5];
|
||||
OutputIndices.Set(triangleOffset + 3, triangle);
|
||||
outputIndices.Set(triangleOffset + 3, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[7];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 4, triangle);
|
||||
outputIndices.Set(triangleOffset + 4, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 5, triangle);
|
||||
outputIndices.Set(triangleOffset + 5, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[7];
|
||||
OutputIndices.Set(triangleOffset + 6, triangle);
|
||||
outputIndices.Set(triangleOffset + 6, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[7];
|
||||
triangle[3] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 7, triangle);
|
||||
outputIndices.Set(triangleOffset + 7, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[3];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 8, triangle);
|
||||
outputIndices.Set(triangleOffset + 8, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[1];
|
||||
OutputIndices.Set(triangleOffset + 9, triangle);
|
||||
outputIndices.Set(triangleOffset + 9, triangle);
|
||||
|
||||
triangle[1] = cellIndices[4];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 10, triangle);
|
||||
outputIndices.Set(triangleOffset + 10, triangle);
|
||||
|
||||
triangle[1] = cellIndices[4];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[7];
|
||||
OutputIndices.Set(triangleOffset + 11, triangle);
|
||||
outputIndices.Set(triangleOffset + 11, triangle);
|
||||
}
|
||||
}
|
||||
#if defined(VTKM_MSVC)
|
||||
@ -303,24 +274,19 @@ public:
|
||||
|
||||
class Trianglulate : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
private:
|
||||
Vec4ArrayPortalType OutputIndices;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
Trianglulate(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& outputIndices,
|
||||
const vtkm::Id& size)
|
||||
{
|
||||
this->OutputIndices = outputIndices.PrepareForOutput(size, Device());
|
||||
}
|
||||
using ControlSignature = void(CellSetIn cellset, FieldInCell<>);
|
||||
using ExecutionSignature = void(_2, CellShape, PointIndices, WorkIndex);
|
||||
Trianglulate() {}
|
||||
using ControlSignature = void(CellSetIn cellset, FieldInCell<>, WholeArrayOut<>);
|
||||
using ExecutionSignature = void(_2, CellShape, PointIndices, WorkIndex, _3);
|
||||
|
||||
template <typename VecType>
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& triangleOffset,
|
||||
vtkm::CellShapeTagQuad vtkmNotUsed(shapeType),
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId) const
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 4> triangle;
|
||||
|
||||
@ -329,17 +295,18 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[2];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[2] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
}
|
||||
|
||||
template <typename VecType>
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& triangleOffset,
|
||||
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId) const
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 4> triangle;
|
||||
|
||||
@ -347,69 +314,70 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[5];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 2, triangle);
|
||||
outputIndices.Set(triangleOffset + 2, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[5];
|
||||
OutputIndices.Set(triangleOffset + 3, triangle);
|
||||
outputIndices.Set(triangleOffset + 3, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[7];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 4, triangle);
|
||||
outputIndices.Set(triangleOffset + 4, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 5, triangle);
|
||||
outputIndices.Set(triangleOffset + 5, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[7];
|
||||
OutputIndices.Set(triangleOffset + 6, triangle);
|
||||
outputIndices.Set(triangleOffset + 6, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[7];
|
||||
triangle[3] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 7, triangle);
|
||||
outputIndices.Set(triangleOffset + 7, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[3];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 8, triangle);
|
||||
outputIndices.Set(triangleOffset + 8, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[1];
|
||||
OutputIndices.Set(triangleOffset + 9, triangle);
|
||||
outputIndices.Set(triangleOffset + 9, triangle);
|
||||
|
||||
triangle[1] = cellIndices[4];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 10, triangle);
|
||||
outputIndices.Set(triangleOffset + 10, triangle);
|
||||
|
||||
triangle[1] = cellIndices[4];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[7];
|
||||
OutputIndices.Set(triangleOffset + 11, triangle);
|
||||
outputIndices.Set(triangleOffset + 11, triangle);
|
||||
}
|
||||
|
||||
template <typename VecType>
|
||||
template <typename VecType, typename OutputPortal>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& triangleOffset,
|
||||
vtkm::CellShapeTagGeneric shapeType,
|
||||
const VecType& cellIndices,
|
||||
const vtkm::Id& cellId) const
|
||||
const vtkm::Id& cellId,
|
||||
OutputPortal& outputIndices) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 4> triangle;
|
||||
|
||||
@ -420,7 +388,7 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[2];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
|
||||
{
|
||||
@ -429,10 +397,10 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[2];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[2] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_TETRA)
|
||||
{
|
||||
@ -440,22 +408,22 @@ public:
|
||||
triangle[2] = cellIndices[3];
|
||||
triangle[3] = cellIndices[1];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 2, triangle);
|
||||
outputIndices.Set(triangleOffset + 2, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[1];
|
||||
OutputIndices.Set(triangleOffset + 3, triangle);
|
||||
outputIndices.Set(triangleOffset + 3, triangle);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_HEXAHEDRON)
|
||||
{
|
||||
@ -463,62 +431,62 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[5];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 2, triangle);
|
||||
outputIndices.Set(triangleOffset + 2, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[5];
|
||||
OutputIndices.Set(triangleOffset + 3, triangle);
|
||||
outputIndices.Set(triangleOffset + 3, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[7];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 4, triangle);
|
||||
outputIndices.Set(triangleOffset + 4, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 5, triangle);
|
||||
outputIndices.Set(triangleOffset + 5, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[7];
|
||||
OutputIndices.Set(triangleOffset + 6, triangle);
|
||||
outputIndices.Set(triangleOffset + 6, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[7];
|
||||
triangle[3] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 7, triangle);
|
||||
outputIndices.Set(triangleOffset + 7, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[3];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 8, triangle);
|
||||
outputIndices.Set(triangleOffset + 8, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[1];
|
||||
OutputIndices.Set(triangleOffset + 9, triangle);
|
||||
outputIndices.Set(triangleOffset + 9, triangle);
|
||||
|
||||
triangle[1] = cellIndices[4];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[6];
|
||||
OutputIndices.Set(triangleOffset + 10, triangle);
|
||||
outputIndices.Set(triangleOffset + 10, triangle);
|
||||
|
||||
triangle[1] = cellIndices[4];
|
||||
triangle[2] = cellIndices[6];
|
||||
triangle[3] = cellIndices[7];
|
||||
OutputIndices.Set(triangleOffset + 11, triangle);
|
||||
outputIndices.Set(triangleOffset + 11, triangle);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_WEDGE)
|
||||
{
|
||||
@ -526,42 +494,42 @@ public:
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[2];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[0];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 2, triangle);
|
||||
outputIndices.Set(triangleOffset + 2, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[5];
|
||||
OutputIndices.Set(triangleOffset + 3, triangle);
|
||||
outputIndices.Set(triangleOffset + 3, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[5];
|
||||
OutputIndices.Set(triangleOffset + 4, triangle);
|
||||
outputIndices.Set(triangleOffset + 4, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[5];
|
||||
triangle[3] = cellIndices[2];
|
||||
OutputIndices.Set(triangleOffset + 5, triangle);
|
||||
outputIndices.Set(triangleOffset + 5, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[3];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 6, triangle);
|
||||
outputIndices.Set(triangleOffset + 6, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[1];
|
||||
OutputIndices.Set(triangleOffset + 7, triangle);
|
||||
outputIndices.Set(triangleOffset + 7, triangle);
|
||||
}
|
||||
if (shapeType.Id == vtkm::CELL_SHAPE_PYRAMID)
|
||||
{
|
||||
@ -569,32 +537,32 @@ public:
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[1];
|
||||
triangle[0] = cellId;
|
||||
OutputIndices.Set(triangleOffset, triangle);
|
||||
outputIndices.Set(triangleOffset, triangle);
|
||||
|
||||
triangle[1] = cellIndices[1];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 1, triangle);
|
||||
outputIndices.Set(triangleOffset + 1, triangle);
|
||||
|
||||
triangle[1] = cellIndices[2];
|
||||
triangle[2] = cellIndices[3];
|
||||
triangle[3] = cellIndices[4];
|
||||
OutputIndices.Set(triangleOffset + 2, triangle);
|
||||
outputIndices.Set(triangleOffset + 2, triangle);
|
||||
|
||||
triangle[1] = cellIndices[0];
|
||||
triangle[2] = cellIndices[4];
|
||||
triangle[3] = cellIndices[3];
|
||||
OutputIndices.Set(triangleOffset + 3, triangle);
|
||||
outputIndices.Set(triangleOffset + 3, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[2];
|
||||
triangle[3] = cellIndices[1];
|
||||
OutputIndices.Set(triangleOffset + 4, triangle);
|
||||
outputIndices.Set(triangleOffset + 4, triangle);
|
||||
|
||||
triangle[1] = cellIndices[3];
|
||||
triangle[2] = cellIndices[1];
|
||||
triangle[3] = cellIndices[0];
|
||||
OutputIndices.Set(triangleOffset + 5, triangle);
|
||||
outputIndices.Set(triangleOffset + 5, triangle);
|
||||
}
|
||||
}
|
||||
}; //class Trianglulate
|
||||
@ -608,16 +576,20 @@ public:
|
||||
vtkm::Id& outputTriangles)
|
||||
{
|
||||
//Eliminate unseen triangles
|
||||
vtkm::worklet::DispatcherMapField<IndicesSort>().Invoke(outputIndices);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Sort(outputIndices, IndicesLessThan());
|
||||
vtkm::worklet::DispatcherMapField<IndicesSort> sortInvoker;
|
||||
sortInvoker.Invoke(outputIndices);
|
||||
|
||||
vtkm::cont::Algorithm::Sort(outputIndices, IndicesLessThan());
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> flags;
|
||||
flags.Allocate(outputTriangles);
|
||||
vtkm::worklet::DispatcherMapField<MemSet<vtkm::UInt8>>(MemSet<vtkm::UInt8>(1)).Invoke(flags);
|
||||
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> one(1, outputTriangles);
|
||||
vtkm::cont::Algorithm::Copy(one, flags);
|
||||
//Unique triangles will have a flag = 1
|
||||
vtkm::worklet::DispatcherMapField<UniqueTriangles>().Invoke(outputIndices, flags);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> subset;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(outputIndices, flags, subset);
|
||||
vtkm::cont::Algorithm::CopyIf(outputIndices, flags, subset);
|
||||
outputIndices = subset;
|
||||
outputTriangles = subset.GetNumberOfValues();
|
||||
}
|
||||
@ -630,13 +602,23 @@ public:
|
||||
bool fastPath = false;
|
||||
if (cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
||||
{
|
||||
//vtkm::cont::CellSetStructured<3> cellSetStructured3D =
|
||||
// cellset.Cast<vtkm::cont::CellSetStructured<3>>();
|
||||
|
||||
//raytracing::MeshConnectivityBuilder<Device> builder;
|
||||
//outputIndices = builder.ExternalTrianglesStructured(cellSetStructured3D);
|
||||
//outputTriangles = outputIndices.GetNumberOfValues();
|
||||
//fastPath = true;
|
||||
vtkm::cont::CellSetStructured<3> cellSetStructured3D =
|
||||
cellset.Cast<vtkm::cont::CellSetStructured<3>>();
|
||||
const vtkm::Id numCells = cellSetStructured3D.GetNumberOfCells();
|
||||
|
||||
raytracing::MeshConnectivityBuilder<Device> builder;
|
||||
outputIndices = builder.ExternalTrianglesStructured(cellSetStructured3D);
|
||||
outputTriangles = outputIndices.GetNumberOfValues();
|
||||
fastPath = true;
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, numCells);
|
||||
outputIndices.Allocate(numCells * 12);
|
||||
vtkm::worklet::DispatcherMapTopology<TrianglulateStructured<3>>(TrianglulateStructured<3>())
|
||||
.Invoke(cellSetStructured3D, cellIdxs, outputIndices);
|
||||
|
||||
outputTriangles = numCells * 12;
|
||||
}
|
||||
else if (cellset.IsSameType(vtkm::cont::CellSetStructured<2>()))
|
||||
{
|
||||
@ -646,11 +628,12 @@ public:
|
||||
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> cellIdxs(0, 1, numCells);
|
||||
outputIndices.Allocate(numCells * 2);
|
||||
vtkm::worklet::DispatcherMapTopology<TrianglulateStructured<2>>(
|
||||
TrianglulateStructured<2>(outputIndices))
|
||||
.Invoke(cellSetStructured2D, cellIdxs);
|
||||
vtkm::worklet::DispatcherMapTopology<TrianglulateStructured<2>>(TrianglulateStructured<2>())
|
||||
.Invoke(cellSetStructured2D, cellIdxs, outputIndices);
|
||||
|
||||
outputTriangles = numCells * 2;
|
||||
// no need to do external faces on 2D cell set
|
||||
fastPath = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -659,16 +642,14 @@ public:
|
||||
.Invoke(cellset, trianglesPerCell);
|
||||
|
||||
vtkm::Id totalTriangles = 0;
|
||||
totalTriangles =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(trianglesPerCell, vtkm::Id(0));
|
||||
totalTriangles = vtkm::cont::Algorithm::Reduce(trianglesPerCell, vtkm::Id(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(trianglesPerCell, cellOffsets);
|
||||
vtkm::cont::Algorithm::ScanExclusive(trianglesPerCell, cellOffsets);
|
||||
outputIndices.Allocate(totalTriangles);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<Trianglulate>(
|
||||
Trianglulate(outputIndices, totalTriangles))
|
||||
.Invoke(cellset, cellOffsets);
|
||||
vtkm::worklet::DispatcherMapTopology<Trianglulate>(Trianglulate())
|
||||
.Invoke(cellset, cellOffsets, outputIndices);
|
||||
|
||||
outputTriangles = totalTriangles;
|
||||
}
|
||||
|
@ -496,10 +496,8 @@ private:
|
||||
|
||||
if (ShowInternalZones && !IsOverlay)
|
||||
{
|
||||
using MemSet =
|
||||
typename vtkm::rendering::Triangulator<DeviceTag>::template MemSet<vtkm::Int64>;
|
||||
MemSet memSet(ClearValue);
|
||||
vtkm::worklet::DispatcherMapField<MemSet>(memSet).Invoke(FrameBuffer);
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Int64> clear(ClearValue, pixelCount);
|
||||
vtkm::cont::Algorithm::Copy(clear, FrameBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -30,47 +30,12 @@ namespace rendering
|
||||
namespace internal
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct TriangulatorFunctor
|
||||
{
|
||||
vtkm::cont::DynamicCellSet CellSet;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Indices;
|
||||
vtkm::Id NumberOfTriangles;
|
||||
|
||||
VTKM_CONT
|
||||
TriangulatorFunctor(vtkm::cont::DynamicCellSet cellSet)
|
||||
: CellSet(cellSet)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device)
|
||||
{
|
||||
vtkm::rendering::Triangulator<Device> triangulator;
|
||||
triangulator.Run(this->CellSet, this->Indices, this->NumberOfTriangles);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void RunTriangulator(const vtkm::cont::DynamicCellSet& cellSet,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& indices,
|
||||
vtkm::Id& numberOfTriangles,
|
||||
vtkm::cont::RuntimeDeviceTracker tracker)
|
||||
vtkm::Id& numberOfTriangles)
|
||||
{
|
||||
// TODO: Should the rendering library support policies or some other way to
|
||||
// configure with custom devices?
|
||||
TriangulatorFunctor triangulatorFunctor(cellSet);
|
||||
if (!vtkm::cont::TryExecute(triangulatorFunctor, tracker))
|
||||
{
|
||||
throw vtkm::cont::ErrorExecution("Failed to execute triangulator.");
|
||||
}
|
||||
|
||||
indices = triangulatorFunctor.Indices;
|
||||
numberOfTriangles = triangulatorFunctor.NumberOfTriangles;
|
||||
vtkm::rendering::Triangulator triangulator;
|
||||
triangulator.Run(cellSet, indices, numberOfTriangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,11 +39,9 @@ namespace internal
|
||||
/// filters, and filters should be compiled in a library (for the same reason).
|
||||
///
|
||||
VTKM_RENDERING_EXPORT
|
||||
void RunTriangulator(
|
||||
const vtkm::cont::DynamicCellSet& cellSet,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& indices,
|
||||
vtkm::Id& numberOfTriangles,
|
||||
vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
|
||||
void RunTriangulator(const vtkm::cont::DynamicCellSet& cellSet,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& indices,
|
||||
vtkm::Id& numberOfTriangles);
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::rendering::internal
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||
@ -49,11 +50,11 @@ namespace raytracing
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class LinearBVHBuilder
|
||||
{
|
||||
public:
|
||||
class CountingIterator;
|
||||
class FindAABBs;
|
||||
|
||||
template <typename Device>
|
||||
class GatherFloat32;
|
||||
@ -61,6 +62,8 @@ public:
|
||||
template <typename Device>
|
||||
class GatherVecCast;
|
||||
|
||||
class CreateLeafs;
|
||||
|
||||
class BVHData;
|
||||
|
||||
template <typename Device>
|
||||
@ -73,11 +76,10 @@ public:
|
||||
LinearBVHBuilder() {}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void SortAABBS(
|
||||
BVHData& bvh,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& triangleIndices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>& outputTriangleIndices,
|
||||
Device vtkmNotUsed(device));
|
||||
VTKM_CONT void SortAABBS(BVHData& bvh, Device vtkmNotUsed(device));
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void BuildHierarchy(BVHData& bvh);
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void RunOnDevice(LinearBVH& linearBVH, Device device);
|
||||
@ -94,70 +96,6 @@ public:
|
||||
void operator()(const vtkm::Id& index, vtkm::Id& outId) const { outId = index; }
|
||||
}; //class countingIterator
|
||||
|
||||
class LinearBVHBuilder::FindAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
FindAABBs() {}
|
||||
using ControlSignature = void(FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7, _8);
|
||||
template <typename PointPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Vec<vtkm::Id, 4> indices,
|
||||
vtkm::Float32& xmin,
|
||||
vtkm::Float32& ymin,
|
||||
vtkm::Float32& zmin,
|
||||
vtkm::Float32& xmax,
|
||||
vtkm::Float32& ymax,
|
||||
vtkm::Float32& zmax,
|
||||
const PointPortalType& points) const
|
||||
{
|
||||
// cast to Float32
|
||||
vtkm::Vec<vtkm::Float32, 3> point;
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(indices[1]));
|
||||
xmin = point[0];
|
||||
ymin = point[1];
|
||||
zmin = point[2];
|
||||
xmax = xmin;
|
||||
ymax = ymin;
|
||||
zmax = zmin;
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(indices[2]));
|
||||
xmin = vtkm::Min(xmin, point[0]);
|
||||
ymin = vtkm::Min(ymin, point[1]);
|
||||
zmin = vtkm::Min(zmin, point[2]);
|
||||
xmax = vtkm::Max(xmax, point[0]);
|
||||
ymax = vtkm::Max(ymax, point[1]);
|
||||
zmax = vtkm::Max(zmax, point[2]);
|
||||
point = static_cast<vtkm::Vec<vtkm::Float32, 3>>(points.Get(indices[3]));
|
||||
xmin = vtkm::Min(xmin, point[0]);
|
||||
ymin = vtkm::Min(ymin, point[1]);
|
||||
zmin = vtkm::Min(zmin, point[2]);
|
||||
xmax = vtkm::Max(xmax, point[0]);
|
||||
ymax = vtkm::Max(ymax, point[1]);
|
||||
zmax = vtkm::Max(zmax, point[2]);
|
||||
|
||||
|
||||
vtkm::Float32 xEpsilon, yEpsilon, zEpsilon;
|
||||
const vtkm::Float32 minEpsilon = 1e-6f;
|
||||
xEpsilon = vtkm::Max(minEpsilon, AABB_EPSILON * (xmax - xmin));
|
||||
yEpsilon = vtkm::Max(minEpsilon, AABB_EPSILON * (ymax - ymin));
|
||||
zEpsilon = vtkm::Max(minEpsilon, AABB_EPSILON * (zmax - zmin));
|
||||
|
||||
xmin -= xEpsilon;
|
||||
ymin -= yEpsilon;
|
||||
zmin -= zEpsilon;
|
||||
xmax += xEpsilon;
|
||||
ymax += yEpsilon;
|
||||
zmax += zEpsilon;
|
||||
}
|
||||
}; //class FindAABBs
|
||||
|
||||
template <typename Device>
|
||||
class LinearBVHBuilder::GatherFloat32 : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
@ -186,6 +124,27 @@ public:
|
||||
}
|
||||
}; //class GatherFloat
|
||||
|
||||
class LinearBVHBuilder::CreateLeafs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
CreateLeafs() {}
|
||||
|
||||
typedef void ControlSignature(FieldIn<>, WholeArrayOut<>);
|
||||
typedef void ExecutionSignature(_1, _2, WorkIndex);
|
||||
|
||||
template <typename LeafPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& dataIndex,
|
||||
LeafPortalType& leafs,
|
||||
const vtkm::Id& index) const
|
||||
{
|
||||
const vtkm::Id offset = index * 2;
|
||||
leafs.Set(offset, 1); // number of primitives
|
||||
leafs.Set(offset + 1, dataIndex); // number of primitives
|
||||
}
|
||||
}; //class createLeafs
|
||||
|
||||
template <typename Device>
|
||||
class LinearBVHBuilder::GatherVecCast : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
@ -221,48 +180,34 @@ class LinearBVHBuilder::BVHData
|
||||
{
|
||||
public:
|
||||
//TODO: make private
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* xmins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* ymins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* zmins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* xmaxs;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* ymaxs;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* zmaxs;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt32> mortonCodes;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> parent;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> leftChild;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> rightChild;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> leafs;
|
||||
vtkm::cont::ArrayHandle<vtkm::Bounds> innerBounds;
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> leafOffsets;
|
||||
AABBs& AABB;
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT BVHData(vtkm::Id numPrimitives, Device vtkmNotUsed(device))
|
||||
: NumPrimitives(numPrimitives)
|
||||
VTKM_CONT BVHData(vtkm::Id numPrimitives, AABBs& aabbs, Device vtkmNotUsed(device))
|
||||
: leafOffsets(0, 2, numPrimitives)
|
||||
, AABB(aabbs)
|
||||
, NumPrimitives(numPrimitives)
|
||||
{
|
||||
InnerNodeCount = NumPrimitives - 1;
|
||||
vtkm::Id size = NumPrimitives + InnerNodeCount;
|
||||
xmins = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
ymins = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
zmins = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
xmaxs = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
ymaxs = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
zmaxs = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
|
||||
parent.PrepareForOutput(size, Device());
|
||||
leftChild.PrepareForOutput(InnerNodeCount, Device());
|
||||
rightChild.PrepareForOutput(InnerNodeCount, Device());
|
||||
innerBounds.PrepareForOutput(InnerNodeCount, Device());
|
||||
mortonCodes.PrepareForOutput(NumPrimitives, Device());
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
~BVHData()
|
||||
{
|
||||
//
|
||||
delete xmins;
|
||||
delete ymins;
|
||||
delete zmins;
|
||||
delete xmaxs;
|
||||
delete ymaxs;
|
||||
delete zmaxs;
|
||||
}
|
||||
~BVHData() {}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfPrimitives() const { return NumPrimitives; }
|
||||
VTKM_CONT
|
||||
@ -295,8 +240,6 @@ private:
|
||||
IdConstPortal LeftChildren;
|
||||
IdConstPortal RightChildren;
|
||||
vtkm::Int32 LeafCount;
|
||||
//Int8Handle Counters;
|
||||
//Int8ArrayPortal CountersPortal;
|
||||
vtkm::exec::AtomicArrayExecutionObject<vtkm::Int32, Device> Counters;
|
||||
|
||||
public:
|
||||
@ -321,17 +264,19 @@ public:
|
||||
WholeArrayIn<Scalar>,
|
||||
WholeArrayIn<Scalar>,
|
||||
WholeArrayIn<Scalar>,
|
||||
WholeArrayIn<Scalar>);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2, _3, _4, _5, _6);
|
||||
WholeArrayIn<Scalar>,
|
||||
WholeArrayIn<>);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2, _3, _4, _5, _6, _7);
|
||||
|
||||
template <typename InputPortalType>
|
||||
template <typename InputPortalType, typename OffsetPortalType>
|
||||
VTKM_EXEC_CONT void operator()(const vtkm::Id workIndex,
|
||||
const InputPortalType& xmin,
|
||||
const InputPortalType& ymin,
|
||||
const InputPortalType& zmin,
|
||||
const InputPortalType& xmax,
|
||||
const InputPortalType& ymax,
|
||||
const InputPortalType& zmax) const
|
||||
const InputPortalType& zmax,
|
||||
const OffsetPortalType& leafOffsets) const
|
||||
{
|
||||
//move up into the inner nodes
|
||||
vtkm::Id currentNode = LeafCount - 1 + workIndex;
|
||||
@ -348,6 +293,8 @@ public:
|
||||
childVector[1] = RightChildren.Get(currentNode);
|
||||
if (childVector[0] > (LeafCount - 2))
|
||||
{
|
||||
//our left child is a leaf, so just grab the AABB
|
||||
//and set it in the current node
|
||||
childVector[0] = childVector[0] - LeafCount + 1;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4>
|
||||
@ -363,11 +310,15 @@ public:
|
||||
second4Vec[0] = ymax.Get(childVector[0]);
|
||||
second4Vec[1] = zmax.Get(childVector[0]);
|
||||
FlatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
|
||||
childVector[0] = -(childVector[0] + 1);
|
||||
// set index to leaf
|
||||
vtkm::Id leafIndex = leafOffsets.Get(childVector[0]);
|
||||
childVector[0] = -(leafIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//our left child is an inner node, so gather
|
||||
//both AABBs in the child and join them for
|
||||
//the current node left AABB.
|
||||
vtkm::Id child = childVector[0] * 4;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> cFirst4Vec = FlatBVH.Get(child);
|
||||
@ -389,6 +340,8 @@ public:
|
||||
|
||||
if (childVector[1] > (LeafCount - 2))
|
||||
{
|
||||
//our right child is a leaf, so just grab the AABB
|
||||
//and set it in the current node
|
||||
childVector[1] = childVector[1] - LeafCount + 1;
|
||||
|
||||
|
||||
@ -404,11 +357,16 @@ public:
|
||||
third4Vec[2] = ymax.Get(childVector[1]);
|
||||
third4Vec[3] = zmax.Get(childVector[1]);
|
||||
FlatBVH.Set(currentNodeOffset + 2, third4Vec);
|
||||
childVector[1] = -(childVector[1] + 1);
|
||||
|
||||
// set index to leaf
|
||||
vtkm::Id leafIndex = leafOffsets.Get(childVector[1]);
|
||||
childVector[1] = -(leafIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//our left child is an inner node, so gather
|
||||
//both AABBs in the child and join them for
|
||||
//the current node left AABB.
|
||||
vtkm::Id child = childVector[1] * 4;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> cFirst4Vec = FlatBVH.Get(child);
|
||||
@ -426,7 +384,7 @@ public:
|
||||
cThird4Vec[3] = vtkm::Max(cSecond4Vec[1], cThird4Vec[3]);
|
||||
FlatBVH.Set(currentNodeOffset + 2, cThird4Vec);
|
||||
}
|
||||
vtkm::Vec<vtkm::Float32, 4> fourth4Vec(0.f, 0.f, 0.f, 0.f);
|
||||
vtkm::Vec<vtkm::Float32, 4> fourth4Vec;
|
||||
vtkm::Int32 leftChild =
|
||||
static_cast<vtkm::Int32>((childVector[0] >= 0) ? childVector[0] * 4 : childVector[0]);
|
||||
memcpy(&fourth4Vec[0], &leftChild, 4);
|
||||
@ -438,7 +396,6 @@ public:
|
||||
}
|
||||
}; //class PropagateAABBs
|
||||
|
||||
|
||||
template <typename Device>
|
||||
class LinearBVHBuilder::TreeBuilder : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
@ -453,7 +410,7 @@ private:
|
||||
IdPortalType ParentPortal;
|
||||
vtkm::Id LeafCount;
|
||||
vtkm::Id InnerCount;
|
||||
//TODO: get intrinsic support
|
||||
//TODO: get instrinsic support
|
||||
VTKM_EXEC
|
||||
inline vtkm::Int32 CountLeadingZeros(vtkm::UInt32& x) const
|
||||
{
|
||||
@ -555,7 +512,7 @@ public:
|
||||
vtkm::Int32 deltaNode = delta(idx, j);
|
||||
vtkm::Int32 s = 0;
|
||||
vtkm::Float32 divFactor = 2.f;
|
||||
//find the split position using a binary search
|
||||
//find the split postition using a binary search
|
||||
for (vtkm::Int32 t = (vtkm::Int32)ceil(vtkm::Float32(l) / divFactor);;
|
||||
divFactor *= 2, t = (vtkm::Int32)ceil(vtkm::Float32(l) / divFactor))
|
||||
{
|
||||
@ -599,11 +556,7 @@ public:
|
||||
}; // class TreeBuilder
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void LinearBVHBuilder::SortAABBS(
|
||||
BVHData& bvh,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& triangleIndices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>& outputTriangleIndices,
|
||||
Device vtkmNotUsed(device))
|
||||
VTKM_CONT void LinearBVHBuilder::SortAABBS(BVHData& bvh, Device vtkmNotUsed(device))
|
||||
{
|
||||
//create array of indexes to be sorted with morton codes
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> iterator;
|
||||
@ -612,92 +565,91 @@ VTKM_CONT void LinearBVHBuilder::SortAABBS(
|
||||
iteratorDispatcher.SetDevice(Device());
|
||||
iteratorDispatcher.Invoke(iterator);
|
||||
|
||||
//std::cout<<"\n\n\n";
|
||||
//sort the morton codes
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(bvh.mortonCodes, iterator);
|
||||
|
||||
vtkm::Id arraySize = bvh.GetNumberOfPrimitives();
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* tempStorage;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32>* tempPtr;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> temp1;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> temp2;
|
||||
|
||||
|
||||
tempStorage = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
//tempStorage = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
//xmins
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32<Device>> dispatcher(
|
||||
GatherFloat32<Device>(*bvh.xmins, *tempStorage, arraySize));
|
||||
GatherFloat32<Device>(bvh.AABB.xmins, temp1, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
|
||||
tempPtr = bvh.xmins;
|
||||
bvh.xmins = tempStorage;
|
||||
tempStorage = tempPtr;
|
||||
temp2 = bvh.AABB.xmins;
|
||||
bvh.AABB.xmins = temp1;
|
||||
temp1 = temp2;
|
||||
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32<Device>> dispatcher(
|
||||
GatherFloat32<Device>(*bvh.ymins, *tempStorage, arraySize));
|
||||
GatherFloat32<Device>(bvh.AABB.ymins, temp1, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
|
||||
tempPtr = bvh.ymins;
|
||||
bvh.ymins = tempStorage;
|
||||
tempStorage = tempPtr;
|
||||
temp2 = bvh.AABB.ymins;
|
||||
bvh.AABB.ymins = temp1;
|
||||
temp1 = temp2;
|
||||
//zmins
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32<Device>> dispatcher(
|
||||
GatherFloat32<Device>(*bvh.zmins, *tempStorage, arraySize));
|
||||
GatherFloat32<Device>(bvh.AABB.zmins, temp1, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
tempPtr = bvh.zmins;
|
||||
bvh.zmins = tempStorage;
|
||||
tempStorage = tempPtr;
|
||||
|
||||
temp2 = bvh.AABB.zmins;
|
||||
bvh.AABB.zmins = temp1;
|
||||
temp1 = temp2;
|
||||
//xmaxs
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32<Device>> dispatcher(
|
||||
GatherFloat32<Device>(*bvh.xmaxs, *tempStorage, arraySize));
|
||||
GatherFloat32<Device>(bvh.AABB.xmaxs, temp1, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
|
||||
tempPtr = bvh.xmaxs;
|
||||
bvh.xmaxs = tempStorage;
|
||||
tempStorage = tempPtr;
|
||||
temp2 = bvh.AABB.xmaxs;
|
||||
bvh.AABB.xmaxs = temp1;
|
||||
temp1 = temp2;
|
||||
//ymaxs
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32<Device>> dispatcher(
|
||||
GatherFloat32<Device>(*bvh.ymaxs, *tempStorage, arraySize));
|
||||
GatherFloat32<Device>(bvh.AABB.ymaxs, temp1, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
|
||||
tempPtr = bvh.ymaxs;
|
||||
bvh.ymaxs = tempStorage;
|
||||
tempStorage = tempPtr;
|
||||
temp2 = bvh.AABB.ymaxs;
|
||||
bvh.AABB.ymaxs = temp1;
|
||||
temp1 = temp2;
|
||||
//zmaxs
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32<Device>> dispatcher(
|
||||
GatherFloat32<Device>(*bvh.zmaxs, *tempStorage, arraySize));
|
||||
GatherFloat32<Device>(bvh.AABB.zmaxs, temp1, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
|
||||
tempPtr = bvh.zmaxs;
|
||||
bvh.zmaxs = tempStorage;
|
||||
tempStorage = tempPtr;
|
||||
temp2 = bvh.AABB.zmaxs;
|
||||
bvh.AABB.zmaxs = temp1;
|
||||
temp1 = temp2;
|
||||
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<GatherVecCast<Device>> dispatcher(
|
||||
GatherVecCast<Device>(triangleIndices, outputTriangleIndices, arraySize));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(iterator);
|
||||
}
|
||||
delete tempStorage;
|
||||
// Create the leaf references
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> iter(0, 1, arraySize);
|
||||
bvh.leafs.PrepareForOutput(arraySize * 2, Device());
|
||||
|
||||
} // method SortAABBs
|
||||
vtkm::worklet::DispatcherMapField<CreateLeafs> createDis;
|
||||
createDis.SetDevice(Device());
|
||||
createDis.Invoke(iterator, bvh.leafs);
|
||||
|
||||
} // method SortAABB
|
||||
|
||||
// Adding this as a template parameter to allow restricted types and
|
||||
// storage for dynamic coordinate system to limit crazy code bloat and
|
||||
@ -708,52 +660,42 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("bvh_constuct");
|
||||
logger->AddLogData("device", GetDeviceString(Device()));
|
||||
|
||||
vtkm::cont::Timer<Device> constructTimer;
|
||||
|
||||
auto coordsHandle = linearBVH.GetCoordsHandle();
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangleIndices = linearBVH.GetTriangles();
|
||||
vtkm::Id numberOfTriangles = linearBVH.GetNumberOfTriangles();
|
||||
vtkm::Id numberOfAABBs = linearBVH.GetNumberOfAABBs();
|
||||
|
||||
logger->AddLogData("bvh_num_triangles ", numberOfTriangles);
|
||||
logger->AddLogData("bvh_num_aabbs", numberOfAABBs);
|
||||
|
||||
const vtkm::Id numBBoxes = numberOfTriangles;
|
||||
BVHData bvh(numBBoxes, device);
|
||||
const vtkm::Id numBBoxes = numberOfAABBs;
|
||||
BVHData bvh(numBBoxes, linearBVH.GetAABBs(), device);
|
||||
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
vtkm::worklet::DispatcherMapField<FindAABBs> findAABBDispatcher{ (FindAABBs{}) };
|
||||
findAABBDispatcher.SetDevice(Device());
|
||||
findAABBDispatcher.Invoke(triangleIndices,
|
||||
*bvh.xmins,
|
||||
*bvh.ymins,
|
||||
*bvh.zmins,
|
||||
*bvh.xmaxs,
|
||||
*bvh.ymaxs,
|
||||
*bvh.zmaxs,
|
||||
coordsHandle);
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("find_aabb", time);
|
||||
timer.Reset();
|
||||
|
||||
// Find the extent of all bounding boxes to generate normalization for morton codes
|
||||
vtkm::Vec<vtkm::Float32, 3> minExtent(vtkm::Infinity32(), vtkm::Infinity32(), vtkm::Infinity32());
|
||||
vtkm::Vec<vtkm::Float32, 3> maxExtent(
|
||||
vtkm::NegativeInfinity32(), vtkm::NegativeInfinity32(), vtkm::NegativeInfinity32());
|
||||
maxExtent[0] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(*bvh.xmaxs, maxExtent[0], MaxValue());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.xmaxs, maxExtent[0], MaxValue());
|
||||
maxExtent[1] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(*bvh.ymaxs, maxExtent[1], MaxValue());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.ymaxs, maxExtent[1], MaxValue());
|
||||
maxExtent[2] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(*bvh.zmaxs, maxExtent[2], MaxValue());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.zmaxs, maxExtent[2], MaxValue());
|
||||
minExtent[0] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(*bvh.xmins, minExtent[0], MinValue());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.xmins, minExtent[0], MinValue());
|
||||
minExtent[1] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(*bvh.ymins, minExtent[1], MinValue());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.ymins, minExtent[1], MinValue());
|
||||
minExtent[2] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(*bvh.zmins, minExtent[2], MinValue());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.zmins, minExtent[2], MinValue());
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
linearBVH.TotalBounds.X.Min = minExtent[0];
|
||||
linearBVH.TotalBounds.X.Max = maxExtent[0];
|
||||
linearBVH.TotalBounds.Y.Min = minExtent[1];
|
||||
linearBVH.TotalBounds.Y.Max = maxExtent[1];
|
||||
linearBVH.TotalBounds.Z.Min = minExtent[2];
|
||||
linearBVH.TotalBounds.Z.Max = maxExtent[2];
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("calc_extents", time);
|
||||
timer.Reset();
|
||||
|
||||
@ -765,11 +707,16 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
}
|
||||
|
||||
//Generate the morton codes
|
||||
vtkm::worklet::DispatcherMapField<MortonCodeAABB> mortonCodeAABBDispatcher(
|
||||
vtkm::worklet::DispatcherMapField<MortonCodeAABB> mortonDis(
|
||||
MortonCodeAABB(inverseExtent, minExtent));
|
||||
mortonCodeAABBDispatcher.SetDevice(Device());
|
||||
mortonCodeAABBDispatcher.Invoke(
|
||||
*bvh.xmins, *bvh.ymins, *bvh.zmins, *bvh.xmaxs, *bvh.ymaxs, *bvh.zmaxs, bvh.mortonCodes);
|
||||
mortonDis.SetDevice(Device());
|
||||
mortonDis.Invoke(bvh.AABB.xmins,
|
||||
bvh.AABB.ymins,
|
||||
bvh.AABB.zmins,
|
||||
bvh.AABB.xmaxs,
|
||||
bvh.AABB.ymaxs,
|
||||
bvh.AABB.zmaxs,
|
||||
bvh.mortonCodes);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("morton_codes", time);
|
||||
@ -777,16 +724,16 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
|
||||
linearBVH.Allocate(bvh.GetNumberOfPrimitives(), Device());
|
||||
|
||||
SortAABBS(bvh, triangleIndices, linearBVH.LeafNodes, Device());
|
||||
SortAABBS(bvh, Device());
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("sort_aabbs", time);
|
||||
timer.Reset();
|
||||
|
||||
vtkm::worklet::DispatcherMapField<TreeBuilder<Device>> treeBuilderDispatcher(
|
||||
vtkm::worklet::DispatcherMapField<TreeBuilder<Device>> treeDis(
|
||||
TreeBuilder<Device>(bvh.mortonCodes, bvh.parent, bvh.GetNumberOfPrimitives()));
|
||||
treeBuilderDispatcher.SetDevice(Device());
|
||||
treeBuilderDispatcher.Invoke(bvh.leftChild, bvh.rightChild);
|
||||
treeDis.SetDevice(Device());
|
||||
treeDis.Invoke(bvh.leftChild, bvh.rightChild);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("build_tree", time);
|
||||
@ -796,25 +743,25 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> counters;
|
||||
counters.PrepareForOutput(bvh.GetNumberOfPrimitives() - 1, Device());
|
||||
vtkm::Int32 zero = 0;
|
||||
vtkm::worklet::DispatcherMapField<MemSet<vtkm::Int32>> resetCountersDispatcher(
|
||||
(MemSet<vtkm::Int32>(zero)));
|
||||
resetCountersDispatcher.SetDevice(Device());
|
||||
resetCountersDispatcher.Invoke(counters);
|
||||
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Int32> zero(0, bvh.GetNumberOfPrimitives() - 1);
|
||||
vtkm::cont::Algorithm::Copy(Device(), zero, counters);
|
||||
|
||||
vtkm::cont::AtomicArray<vtkm::Int32> atomicCounters(counters);
|
||||
|
||||
|
||||
vtkm::worklet::DispatcherMapField<PropagateAABBs<Device>> propagateAABBDispatcher(
|
||||
PropagateAABBs<Device>(bvh.parent,
|
||||
bvh.leftChild,
|
||||
bvh.rightChild,
|
||||
primitiveCount,
|
||||
linearBVH.FlatBVH,
|
||||
atomicCounters));
|
||||
propagateAABBDispatcher.SetDevice(Device());
|
||||
propagateAABBDispatcher.Invoke(
|
||||
*bvh.xmins, *bvh.ymins, *bvh.zmins, *bvh.xmaxs, *bvh.ymaxs, *bvh.zmaxs);
|
||||
vtkm::worklet::DispatcherMapField<PropagateAABBs<Device>> propDis(PropagateAABBs<Device>(
|
||||
bvh.parent, bvh.leftChild, bvh.rightChild, primitiveCount, linearBVH.FlatBVH, atomicCounters));
|
||||
propDis.SetDevice(Device());
|
||||
propDis.Invoke(bvh.AABB.xmins,
|
||||
bvh.AABB.ymins,
|
||||
bvh.AABB.zmins,
|
||||
bvh.AABB.xmaxs,
|
||||
bvh.AABB.ymaxs,
|
||||
bvh.AABB.zmaxs,
|
||||
bvh.leafOffsets);
|
||||
|
||||
linearBVH.Leafs = bvh.leafs;
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("propagate_aabbs", time);
|
||||
|
||||
@ -844,12 +791,8 @@ LinearBVH::LinearBVH()
|
||||
, CanConstruct(false){};
|
||||
|
||||
VTKM_CONT
|
||||
LinearBVH::LinearBVH(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
|
||||
vtkm::Bounds coordBounds)
|
||||
: CoordBounds(coordBounds)
|
||||
, CoordsHandle(coordsHandle)
|
||||
, Triangles(triangles)
|
||||
LinearBVH::LinearBVH(AABBs& aabbs)
|
||||
: AABB(aabbs)
|
||||
, IsConstructed(false)
|
||||
, CanConstruct(true)
|
||||
{
|
||||
@ -857,12 +800,10 @@ LinearBVH::LinearBVH(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
|
||||
|
||||
VTKM_CONT
|
||||
LinearBVH::LinearBVH(const LinearBVH& other)
|
||||
: FlatBVH(other.FlatBVH)
|
||||
, LeafNodes(other.LeafNodes)
|
||||
: AABB(other.AABB)
|
||||
, FlatBVH(other.FlatBVH)
|
||||
, Leafs(other.Leafs)
|
||||
, LeafCount(other.LeafCount)
|
||||
, CoordBounds(other.CoordBounds)
|
||||
, CoordsHandle(other.CoordsHandle)
|
||||
, Triangles(other.Triangles)
|
||||
, IsConstructed(other.IsConstructed)
|
||||
, CanConstruct(other.CanConstruct)
|
||||
{
|
||||
@ -871,7 +812,6 @@ template <typename Device>
|
||||
VTKM_CONT void LinearBVH::Allocate(const vtkm::Id& leafCount, Device deviceAdapter)
|
||||
{
|
||||
LeafCount = leafCount;
|
||||
LeafNodes.PrepareForOutput(leafCount, deviceAdapter);
|
||||
FlatBVH.PrepareForOutput((leafCount - 1) * 4, deviceAdapter);
|
||||
}
|
||||
|
||||
@ -889,13 +829,9 @@ void LinearBVH::Construct()
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void LinearBVH::SetData(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
|
||||
vtkm::Bounds coordBounds)
|
||||
void LinearBVH::SetData(AABBs& aabbs)
|
||||
{
|
||||
CoordBounds = coordBounds;
|
||||
CoordsHandle = coordsHandle;
|
||||
Triangles = triangles;
|
||||
AABB = aabbs;
|
||||
IsConstructed = false;
|
||||
CanConstruct = true;
|
||||
}
|
||||
@ -912,15 +848,33 @@ void LinearBVH::ConstructOnDevice(Device device)
|
||||
if (!IsConstructed)
|
||||
{
|
||||
//
|
||||
// This algorithm needs at least 2 triangles
|
||||
// This algorithm needs at least 2 AABBs
|
||||
//
|
||||
vtkm::Id numTriangles = this->GetNumberOfTriangles();
|
||||
if (numTriangles == 1)
|
||||
vtkm::Id numAABBs = this->GetNumberOfAABBs();
|
||||
if (numAABBs == 1)
|
||||
{
|
||||
vtkm::Vec<vtkm::Id, 4> triangle = Triangles.GetPortalControl().Get(0);
|
||||
Triangles.Allocate(2);
|
||||
Triangles.GetPortalControl().Set(0, triangle);
|
||||
Triangles.GetPortalControl().Set(1, triangle);
|
||||
vtkm::Float32 xmin = AABB.xmins.GetPortalControl().Get(0);
|
||||
vtkm::Float32 ymin = AABB.ymins.GetPortalControl().Get(0);
|
||||
vtkm::Float32 zmin = AABB.zmins.GetPortalControl().Get(0);
|
||||
vtkm::Float32 xmax = AABB.xmaxs.GetPortalControl().Get(0);
|
||||
vtkm::Float32 ymax = AABB.ymaxs.GetPortalControl().Get(0);
|
||||
vtkm::Float32 zmax = AABB.zmaxs.GetPortalControl().Get(0);
|
||||
|
||||
AABB.xmins.Allocate(2);
|
||||
AABB.ymins.Allocate(2);
|
||||
AABB.zmins.Allocate(2);
|
||||
AABB.xmaxs.Allocate(2);
|
||||
AABB.ymaxs.Allocate(2);
|
||||
AABB.zmaxs.Allocate(2);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
AABB.xmins.GetPortalControl().Set(i, xmin);
|
||||
AABB.ymins.GetPortalControl().Set(i, ymin);
|
||||
AABB.zmins.GetPortalControl().Set(i, zmin);
|
||||
AABB.xmaxs.GetPortalControl().Set(i, xmax);
|
||||
AABB.ymaxs.GetPortalControl().Set(i, ymax);
|
||||
AABB.zmaxs.GetPortalControl().Set(i, zmax);
|
||||
}
|
||||
}
|
||||
detail::LinearBVHBuilder builder;
|
||||
builder.RunOnDevice(*this, device);
|
||||
@ -952,21 +906,15 @@ bool LinearBVH::GetIsConstructed() const
|
||||
{
|
||||
return IsConstructed;
|
||||
}
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates LinearBVH::GetCoordsHandle() const
|
||||
|
||||
vtkm::Id LinearBVH::GetNumberOfAABBs() const
|
||||
{
|
||||
return CoordsHandle;
|
||||
return AABB.xmins.GetPortalConstControl().GetNumberOfValues();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> LinearBVH::GetTriangles() const
|
||||
AABBs& LinearBVH::GetAABBs()
|
||||
{
|
||||
return Triangles;
|
||||
}
|
||||
|
||||
vtkm::Id LinearBVH::GetNumberOfTriangles() const
|
||||
{
|
||||
return Triangles.GetPortalConstControl().GetNumberOfValues();
|
||||
return AABB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,16 @@ namespace rendering
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
struct AABBs
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> xmins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> ymins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> zmins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> xmaxs;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> ymaxs;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> zmaxs;
|
||||
};
|
||||
|
||||
//
|
||||
// This is the data structure that is passed to the ray tracer.
|
||||
//
|
||||
@ -38,16 +48,15 @@ class VTKM_RENDERING_EXPORT LinearBVH
|
||||
{
|
||||
public:
|
||||
using InnerNodesHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||
using LeafNodesHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>;
|
||||
using LeafNodesHandle = vtkm::cont::ArrayHandle<Id>;
|
||||
AABBs AABB;
|
||||
InnerNodesHandle FlatBVH;
|
||||
LeafNodesHandle LeafNodes;
|
||||
LeafNodesHandle Leafs;
|
||||
vtkm::Bounds TotalBounds;
|
||||
struct ConstructFunctor;
|
||||
vtkm::Id LeafCount;
|
||||
vtkm::Bounds CoordBounds;
|
||||
|
||||
protected:
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates CoordsHandle;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Triangles;
|
||||
bool IsConstructed;
|
||||
bool CanConstruct;
|
||||
|
||||
@ -55,9 +64,7 @@ public:
|
||||
LinearBVH();
|
||||
|
||||
VTKM_CONT
|
||||
LinearBVH(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
|
||||
vtkm::Bounds coordBounds);
|
||||
LinearBVH(AABBs& aabbs);
|
||||
|
||||
VTKM_CONT
|
||||
LinearBVH(const LinearBVH& other);
|
||||
@ -69,9 +76,10 @@ public:
|
||||
void Construct();
|
||||
|
||||
VTKM_CONT
|
||||
void SetData(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
|
||||
vtkm::Bounds coordBounds);
|
||||
void SetData(AABBs& aabbs);
|
||||
|
||||
VTKM_CONT
|
||||
AABBs& GetAABBs();
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void ConstructOnDevice(Device device);
|
||||
@ -79,13 +87,7 @@ public:
|
||||
VTKM_CONT
|
||||
bool GetIsConstructed() const;
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordsHandle() const;
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles() const;
|
||||
|
||||
vtkm::Id GetNumberOfTriangles() const;
|
||||
vtkm::Id GetNumberOfAABBs() const;
|
||||
}; // class LinearBVH
|
||||
}
|
||||
}
|
||||
|
@ -20,24 +20,32 @@
|
||||
|
||||
set(headers
|
||||
BoundingVolumeHierarchy.h
|
||||
BVHTraverser.h
|
||||
Camera.h
|
||||
CellIntersector.h
|
||||
CellSampler.h
|
||||
CellTables.h
|
||||
ChannelBuffer.h
|
||||
ChannelBufferOperations.h
|
||||
ConnectivityBase.h
|
||||
ConnectivityTracer.h
|
||||
ConnectivityTracerBase.h
|
||||
ConnectivityTracerFactory.h
|
||||
CylinderExtractor.h
|
||||
CylinderIntersector.h
|
||||
Logger.h
|
||||
MeshConnectivityBuilder.h
|
||||
MeshConnectivityStructures.h
|
||||
MeshConnectivityContainers.h
|
||||
MeshConnectivityBase.h
|
||||
MortonCodes.h
|
||||
QuadExtractor.h
|
||||
QuadIntersector.h
|
||||
Ray.h
|
||||
RayOperations.h
|
||||
RayTracer.h
|
||||
RayTracingTypeDefs.h
|
||||
Sampler.h
|
||||
ShapeIntersector.h
|
||||
SphereExtractor.h
|
||||
SphereIntersector.h
|
||||
TriangleExtractor.h
|
||||
TriangleIntersector.h
|
||||
VolumeRendererStructured.h
|
||||
Worklets.h
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
#include <vtkm/rendering/raytracing/Sampler.h>
|
||||
#include <vtkm/rendering/raytracing/Worklets.h>
|
||||
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
@ -162,6 +163,82 @@ public:
|
||||
|
||||
}; // class pixelData
|
||||
|
||||
class PerspectiveRayGenJitter : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
vtkm::Int32 w;
|
||||
vtkm::Int32 h;
|
||||
vtkm::Vec<vtkm::Float32, 3> nlook; // normalized look
|
||||
vtkm::Vec<vtkm::Float32, 3> delta_x;
|
||||
vtkm::Vec<vtkm::Float32, 3> delta_y;
|
||||
vtkm::Int32 CurrentSample;
|
||||
VTKM_CONT_EXPORT
|
||||
PerspectiveRayGenJitter(vtkm::Int32 width,
|
||||
vtkm::Int32 height,
|
||||
vtkm::Float32 fovX,
|
||||
vtkm::Float32 fovY,
|
||||
vtkm::Vec<vtkm::Float32, 3> look,
|
||||
vtkm::Vec<vtkm::Float32, 3> up,
|
||||
vtkm::Float32 _zoom,
|
||||
vtkm::Int32 currentSample)
|
||||
: w(width)
|
||||
, h(height)
|
||||
{
|
||||
vtkm::Float32 thx = tanf((fovX * 3.1415926f / 180.f) * .5f);
|
||||
vtkm::Float32 thy = tanf((fovY * 3.1415926f / 180.f) * .5f);
|
||||
vtkm::Vec<vtkm::Float32, 3> ru = vtkm::Cross(up, look);
|
||||
vtkm::Normalize(ru);
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 3> rv = vtkm::Cross(ru, look);
|
||||
vtkm::Normalize(rv);
|
||||
|
||||
delta_x = ru * (2 * thx / (float)w);
|
||||
delta_y = rv * (2 * thy / (float)h);
|
||||
|
||||
if (_zoom > 0)
|
||||
{
|
||||
delta_x[0] = delta_x[0] / _zoom;
|
||||
delta_x[1] = delta_x[1] / _zoom;
|
||||
delta_x[2] = delta_x[2] / _zoom;
|
||||
delta_y[0] = delta_y[0] / _zoom;
|
||||
delta_y[1] = delta_y[1] / _zoom;
|
||||
delta_y[2] = delta_y[2] / _zoom;
|
||||
}
|
||||
nlook = look;
|
||||
vtkm::Normalize(nlook);
|
||||
CurrentSample = currentSample;
|
||||
}
|
||||
|
||||
typedef void ControlSignature(FieldOut<>, FieldOut<>, FieldOut<>, FieldIn<>);
|
||||
|
||||
typedef void ExecutionSignature(WorkIndex, _1, _2, _3, _4);
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::Id idx,
|
||||
vtkm::Float32& rayDirX,
|
||||
vtkm::Float32& rayDirY,
|
||||
vtkm::Float32& rayDirZ,
|
||||
const vtkm::Int32& seed) const
|
||||
{
|
||||
vtkm::Vec<vtkm::Float32, 2> xy;
|
||||
Halton2D<3>(CurrentSample + seed, xy);
|
||||
xy[0] -= .5f;
|
||||
xy[1] -= .5f;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 3> ray_dir(rayDirX, rayDirY, rayDirZ);
|
||||
vtkm::Float32 i = static_cast<vtkm::Float32>(vtkm::Int32(idx) % w);
|
||||
vtkm::Float32 j = static_cast<vtkm::Float32>(vtkm::Int32(idx) / w);
|
||||
i += xy[0];
|
||||
j += xy[1];
|
||||
ray_dir = nlook + delta_x * ((2.f * i - vtkm::Float32(w)) / 2.0f) +
|
||||
delta_y * ((2.f * j - vtkm::Float32(h)) / 2.0f);
|
||||
vtkm::Normalize(ray_dir);
|
||||
rayDirX = ray_dir[0];
|
||||
rayDirY = ray_dir[1];
|
||||
rayDirZ = ray_dir[2];
|
||||
}
|
||||
|
||||
}; // class perspective ray gen jitter
|
||||
|
||||
class Camera::Ortho2DRayGen : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
@ -631,35 +708,6 @@ bool Camera::GetIsViewDirty() const
|
||||
return this->IsViewDirty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename Precision>
|
||||
struct Camera::CreateRaysFunctor
|
||||
{
|
||||
vtkm::rendering::raytracing::Camera* Self;
|
||||
const vtkm::cont::CoordinateSystem& Coords;
|
||||
vtkm::rendering::raytracing::Ray<Precision>& Rays;
|
||||
VTKM_CONT
|
||||
CreateRaysFunctor(vtkm::rendering::raytracing::Camera* self,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::rendering::raytracing::Ray<Precision>& rays)
|
||||
: Self(self)
|
||||
, Coords(coords)
|
||||
, Rays(rays)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
|
||||
vtkm::Bounds boundingBox = Coords.GetBounds();
|
||||
Self->CreateRaysOnDevice(this->Rays, Device(), boundingBox);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void Camera::GetPixelData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::Int32& activePixels,
|
||||
vtkm::Float32& aveRayDistance)
|
||||
@ -695,53 +743,42 @@ void Camera::GetPixelData(const vtkm::cont::CoordinateSystem& coords,
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Camera::CreateRays(Ray<vtkm::Float32>& rays, const vtkm::cont::CoordinateSystem& coords)
|
||||
void Camera::CreateRays(Ray<vtkm::Float32>& rays, vtkm::Bounds bounds)
|
||||
{
|
||||
CreateRaysFunctor<Float32> functor(this, coords, rays);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
CreateRaysImpl(rays, bounds);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Camera::CreateRays(Ray<vtkm::Float64>& rays, const vtkm::cont::CoordinateSystem& coords)
|
||||
void Camera::CreateRays(Ray<vtkm::Float64>& rays, vtkm::Bounds bounds)
|
||||
{
|
||||
CreateRaysFunctor<Float64> functor(this, coords, rays);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
CreateRaysImpl(rays, bounds);
|
||||
}
|
||||
|
||||
template <typename Precision, typename Device>
|
||||
VTKM_CONT void Camera::CreateRaysOnDevice(Ray<Precision>& rays,
|
||||
Device,
|
||||
const vtkm::Bounds boundingBox)
|
||||
template <typename Precision>
|
||||
VTKM_CONT void Camera::CreateRaysImpl(Ray<Precision>& rays, const vtkm::Bounds boundingBox)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
vtkm::cont::Timer<Device> createTimer;
|
||||
vtkm::cont::Timer<vtkm::cont::DeviceAdapterTagSerial> createTimer;
|
||||
logger->OpenLogEntry("ray_camera");
|
||||
logger->AddLogData("device", GetDeviceString(Device()));
|
||||
|
||||
bool ortho = this->CameraView.GetMode() == vtkm::rendering::Camera::MODE_2D;
|
||||
this->UpdateDimensions(rays, Device(), boundingBox, ortho);
|
||||
|
||||
this->UpdateDimensions(rays, boundingBox, ortho);
|
||||
this->WriteSettingsToLog();
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
vtkm::cont::Timer<vtkm::cont::DeviceAdapterTagSerial> timer;
|
||||
//Set the origin of the ray back to the camera position
|
||||
|
||||
Precision infinity;
|
||||
GetInfinity(infinity);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MemSet<Precision>> memSetInfDispatcher(
|
||||
(MemSet<Precision>(infinity)));
|
||||
memSetInfDispatcher.SetDevice(Device());
|
||||
memSetInfDispatcher.Invoke(rays.MaxDistance);
|
||||
vtkm::cont::ArrayHandleConstant<Precision> inf(infinity, rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(inf, rays.MaxDistance);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MemSet<Precision>> memSet0Dispatcher((MemSet<Precision>(0.f)));
|
||||
memSet0Dispatcher.SetDevice(Device());
|
||||
memSet0Dispatcher.Invoke(rays.MinDistance);
|
||||
memSet0Dispatcher.Invoke(rays.Distance);
|
||||
vtkm::cont::ArrayHandleConstant<Precision> zero(0, rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(zero, rays.MinDistance);
|
||||
vtkm::cont::Algorithm::Copy(zero, rays.Distance);
|
||||
|
||||
//Reset the Rays Hit Index to -2
|
||||
vtkm::worklet::DispatcherMapField<MemSet<vtkm::Id>> memSetM2Dispatcher((MemSet<vtkm::Id>(-2)));
|
||||
memSetM2Dispatcher.SetDevice(Device());
|
||||
memSetM2Dispatcher.Invoke(rays.HitIdx);
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> initHit(-2, rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(initHit, rays.HitIdx);
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("camera_memset", time);
|
||||
@ -760,7 +797,6 @@ VTKM_CONT void Camera::CreateRaysOnDevice(Ray<Precision>& rays,
|
||||
this->SubsetMinX,
|
||||
this->SubsetMinY,
|
||||
this->CameraView));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.DirX,
|
||||
rays.DirY,
|
||||
rays.DirZ,
|
||||
@ -783,23 +819,19 @@ VTKM_CONT void Camera::CreateRaysOnDevice(Ray<Precision>& rays,
|
||||
this->SubsetWidth,
|
||||
this->SubsetMinX,
|
||||
this->SubsetMinY));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.DirX, rays.DirY, rays.DirZ, rays.PixelIdx); //X Y Z
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MemSet<Precision>> memSetPos0Dispatcher(
|
||||
MemSet<Precision>(this->Position[0]));
|
||||
memSetPos0Dispatcher.SetDevice(Device());
|
||||
memSetPos0Dispatcher.Invoke(rays.OriginX);
|
||||
std::cout << "c7\n";
|
||||
vtkm::cont::ArrayHandleConstant<Precision> posX(this->Position[0], rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(posX, rays.OriginX);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MemSet<Precision>> memSetPos1Dispatcher(
|
||||
MemSet<Precision>(this->Position[1]));
|
||||
memSetPos1Dispatcher.SetDevice(Device());
|
||||
memSetPos1Dispatcher.Invoke(rays.OriginY);
|
||||
vtkm::cont::ArrayHandleConstant<Precision> posY(this->Position[1], rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(posY, rays.OriginY);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MemSet<Precision>> memSetPos2Dispatcher(
|
||||
MemSet<Precision>(this->Position[2]));
|
||||
memSetPos2Dispatcher.SetDevice(Device());
|
||||
memSetPos2Dispatcher.Invoke(rays.OriginZ);
|
||||
vtkm::cont::ArrayHandleConstant<Precision> posZ(this->Position[2], rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(posZ, rays.OriginZ);
|
||||
|
||||
std::cout << "c10\n";
|
||||
}
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
@ -909,9 +941,8 @@ void Camera::FindSubset(const vtkm::Bounds& bounds)
|
||||
logger->AddLogData("subset_height", dy);
|
||||
}
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
template <typename Precision>
|
||||
VTKM_CONT void Camera::UpdateDimensions(Ray<Precision>& rays,
|
||||
Device,
|
||||
const vtkm::Bounds& boundingBox,
|
||||
bool ortho2D)
|
||||
{
|
||||
@ -971,7 +1002,8 @@ VTKM_CONT void Camera::UpdateDimensions(Ray<Precision>& rays,
|
||||
// resize rays and buffers
|
||||
if (rays.NumRays != SubsetWidth * SubsetHeight)
|
||||
{
|
||||
RayOperations::Resize(rays, this->SubsetHeight * this->SubsetWidth, Device());
|
||||
RayOperations::Resize(
|
||||
rays, this->SubsetHeight * this->SubsetWidth, VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,6 @@ class VTKM_RENDERING_EXPORT Camera
|
||||
|
||||
private:
|
||||
struct PixelDataFunctor;
|
||||
template <typename Precision>
|
||||
struct CreateRaysFunctor;
|
||||
vtkm::rendering::CanvasRayTracer Canvas;
|
||||
vtkm::Int32 Height;
|
||||
vtkm::Int32 Width;
|
||||
@ -134,19 +132,18 @@ public:
|
||||
bool GetIsViewDirty() const;
|
||||
|
||||
VTKM_CONT
|
||||
void CreateRays(Ray<vtkm::Float32>& rays, const vtkm::cont::CoordinateSystem& coords);
|
||||
void CreateRays(Ray<vtkm::Float32>& rays, vtkm::Bounds bounds);
|
||||
|
||||
VTKM_CONT
|
||||
void CreateRays(Ray<vtkm::Float64>& rays, const vtkm::cont::CoordinateSystem& coords);
|
||||
void CreateRays(Ray<vtkm::Float64>& rays, vtkm::Bounds bounds);
|
||||
|
||||
VTKM_CONT
|
||||
void GetPixelData(const vtkm::cont::CoordinateSystem& coords,
|
||||
vtkm::Int32& activePixels,
|
||||
vtkm::Float32& aveRayDistance);
|
||||
|
||||
template <typename Precision, typename DeviceAdapter>
|
||||
VTKM_CONT void CreateRaysOnDevice(Ray<Precision>& rays,
|
||||
DeviceAdapter,
|
||||
const vtkm::Bounds boundingBox);
|
||||
template <typename Precision>
|
||||
VTKM_CONT void CreateRaysImpl(Ray<Precision>& rays, const vtkm::Bounds boundingBox);
|
||||
|
||||
void CreateDebugRay(vtkm::Vec<vtkm::Int32, 2> pixel, Ray<vtkm::Float32>& rays);
|
||||
|
||||
@ -160,9 +157,8 @@ private:
|
||||
VTKM_CONT
|
||||
void FindSubset(const vtkm::Bounds& bounds);
|
||||
|
||||
template <typename DeviceAdapter, typename Precision>
|
||||
template <typename Precision>
|
||||
VTKM_CONT void UpdateDimensions(Ray<Precision>& rays,
|
||||
DeviceAdapter,
|
||||
const vtkm::Bounds& boundingBox,
|
||||
bool ortho2D);
|
||||
|
||||
|
@ -43,11 +43,10 @@ VTKM_EXEC_CONT inline void IntersectZoo(T xpoints[8],
|
||||
const vtkm::Int32& shapeType)
|
||||
{
|
||||
// Some precalc for water tight intersections
|
||||
T sx, sy, sz;
|
||||
vtkm::Int32 kx, ky, kz;
|
||||
WaterTight<T> intersector;
|
||||
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
|
||||
|
||||
vtkm::Vec<T, 3> s;
|
||||
vtkm::Vec<vtkm::Int32, 3> k;
|
||||
WaterTight intersector;
|
||||
intersector.FindDir(dir, s, k);
|
||||
CellTables tables;
|
||||
const vtkm::Int32 tableOffset = tables.ZooLookUp(tables.CellTypeLookUp(shapeType), 0);
|
||||
const vtkm::Int32 numTriangles = tables.ZooLookUp(tables.CellTypeLookUp(shapeType), 1);
|
||||
@ -71,21 +70,7 @@ VTKM_EXEC_CONT inline void IntersectZoo(T xpoints[8],
|
||||
T distance = -1.f;
|
||||
|
||||
T uNotUsed, vNotUsed;
|
||||
intersector.IntersectTriSn(a,
|
||||
b,
|
||||
c,
|
||||
sx,
|
||||
sy,
|
||||
sz,
|
||||
kx,
|
||||
ky,
|
||||
kz,
|
||||
distance,
|
||||
uNotUsed,
|
||||
vNotUsed,
|
||||
origin[0],
|
||||
origin[1],
|
||||
origin[2]);
|
||||
intersector.IntersectTriSn(a, b, c, s, k, distance, uNotUsed, vNotUsed, origin);
|
||||
|
||||
if (distance != -1.f)
|
||||
{
|
||||
@ -105,10 +90,10 @@ VTKM_EXEC_CONT inline void IntersectHex(T xpoints[8],
|
||||
T distances[6])
|
||||
{
|
||||
// Some precalc for water tight intersections
|
||||
T sx, sy, sz;
|
||||
vtkm::Int32 kx, ky, kz;
|
||||
WaterTight<T> intersector;
|
||||
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
|
||||
vtkm::Vec<T, 3> s;
|
||||
vtkm::Vec<vtkm::Int32, 3> k;
|
||||
WaterTight intersector;
|
||||
intersector.FindDir(dir, s, k);
|
||||
|
||||
CellTables tables;
|
||||
// Decompose each face into two triangles
|
||||
@ -131,42 +116,14 @@ VTKM_EXEC_CONT inline void IntersectHex(T xpoints[8],
|
||||
distances[i] = distance; //init to -1
|
||||
|
||||
T uNotUsed, vNotUsed;
|
||||
intersector.IntersectTriSn(a,
|
||||
b,
|
||||
c,
|
||||
sx,
|
||||
sy,
|
||||
sz,
|
||||
kx,
|
||||
ky,
|
||||
kz,
|
||||
distance,
|
||||
uNotUsed,
|
||||
vNotUsed,
|
||||
origin[0],
|
||||
origin[1],
|
||||
origin[2]);
|
||||
intersector.IntersectTriSn(a, b, c, s, k, distance, uNotUsed, vNotUsed, origin);
|
||||
|
||||
if (distance != -1.f)
|
||||
distances[i] = distance;
|
||||
|
||||
distance = -1.f;
|
||||
|
||||
intersector.IntersectTriSn(a,
|
||||
c,
|
||||
d,
|
||||
sx,
|
||||
sy,
|
||||
sz,
|
||||
kx,
|
||||
ky,
|
||||
kz,
|
||||
distance,
|
||||
uNotUsed,
|
||||
vNotUsed,
|
||||
origin[0],
|
||||
origin[1],
|
||||
origin[2]);
|
||||
intersector.IntersectTriSn(a, c, d, s, k, distance, uNotUsed, vNotUsed, origin);
|
||||
|
||||
|
||||
|
||||
@ -188,10 +145,10 @@ VTKM_EXEC_CONT inline void IntersectTet(T xpoints[8],
|
||||
T distances[6])
|
||||
{
|
||||
// Some precalc for water tight intersections
|
||||
T sx, sy, sz;
|
||||
vtkm::Int32 kx, ky, kz;
|
||||
WaterTight<T> intersector;
|
||||
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
|
||||
vtkm::Vec<T, 3> s;
|
||||
vtkm::Vec<vtkm::Int32, 3> k;
|
||||
WaterTight intersector;
|
||||
intersector.FindDir(dir, s, k);
|
||||
|
||||
CellTables tables;
|
||||
const vtkm::Int32 tableOffset = tables.FaceLookUp(tables.CellTypeLookUp(CELL_SHAPE_TETRA), 0);
|
||||
@ -212,21 +169,7 @@ VTKM_EXEC_CONT inline void IntersectTet(T xpoints[8],
|
||||
|
||||
T uNotUsed, vNotUsed;
|
||||
|
||||
intersector.IntersectTriSn(a,
|
||||
b,
|
||||
c,
|
||||
sx,
|
||||
sy,
|
||||
sz,
|
||||
kx,
|
||||
ky,
|
||||
kz,
|
||||
distance,
|
||||
uNotUsed,
|
||||
vNotUsed,
|
||||
origin[0],
|
||||
origin[1],
|
||||
origin[2]);
|
||||
intersector.IntersectTriSn(a, b, c, s, k, distance, uNotUsed, vNotUsed, origin);
|
||||
|
||||
if (distance != -1.f)
|
||||
distances[i] = distance;
|
||||
@ -245,10 +188,10 @@ VTKM_EXEC_CONT inline void IntersectWedge(T xpoints[8],
|
||||
T distances[6])
|
||||
{
|
||||
// Some precalc for water tight intersections
|
||||
T sx, sy, sz;
|
||||
vtkm::Int32 kx, ky, kz;
|
||||
WaterTight<T> intersector;
|
||||
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
|
||||
vtkm::Vec<T, 3> s;
|
||||
vtkm::Vec<vtkm::Int32, 3> k;
|
||||
WaterTight intersector;
|
||||
intersector.FindDir(dir, s, k);
|
||||
// TODO: try two sepate loops to see performance impact
|
||||
CellTables tables;
|
||||
const vtkm::Int32 tableOffset = tables.FaceLookUp(tables.CellTypeLookUp(CELL_SHAPE_WEDGE), 0);
|
||||
@ -273,21 +216,7 @@ VTKM_EXEC_CONT inline void IntersectWedge(T xpoints[8],
|
||||
|
||||
T uNotUsed, vNotUsed;
|
||||
|
||||
intersector.IntersectTriSn(a,
|
||||
b,
|
||||
c,
|
||||
sx,
|
||||
sy,
|
||||
sz,
|
||||
kx,
|
||||
ky,
|
||||
kz,
|
||||
distance,
|
||||
uNotUsed,
|
||||
vNotUsed,
|
||||
origin[0],
|
||||
origin[1],
|
||||
origin[2]);
|
||||
intersector.IntersectTriSn(a, b, c, s, k, distance, uNotUsed, vNotUsed, origin);
|
||||
|
||||
if (distance != -1.f)
|
||||
distances[i] = distance;
|
||||
@ -298,21 +227,7 @@ VTKM_EXEC_CONT inline void IntersectWedge(T xpoints[8],
|
||||
continue;
|
||||
distance = -1.f;
|
||||
|
||||
intersector.IntersectTriSn(a,
|
||||
c,
|
||||
d,
|
||||
sx,
|
||||
sy,
|
||||
sz,
|
||||
kx,
|
||||
ky,
|
||||
kz,
|
||||
distance,
|
||||
uNotUsed,
|
||||
vNotUsed,
|
||||
origin[0],
|
||||
origin[1],
|
||||
origin[2]);
|
||||
intersector.IntersectTriSn(a, c, d, s, k, distance, uNotUsed, vNotUsed, origin);
|
||||
|
||||
if (distance != -1.f)
|
||||
{
|
||||
|
@ -440,9 +440,15 @@ template <typename Precision>
|
||||
void ChannelBuffer<Precision>::Normalize(bool invert)
|
||||
{
|
||||
|
||||
NormalizeFunctor<Precision> functor(this->Buffer, invert);
|
||||
|
||||
vtkm::cont::TryExecute(functor);
|
||||
vtkm::cont::Field asField(
|
||||
"name meaningless", vtkm::cont::Field::Association::POINTS, this->Buffer);
|
||||
vtkm::Range range;
|
||||
asField.GetRange(&range);
|
||||
Precision minScalar = static_cast<Precision>(range.Min);
|
||||
Precision maxScalar = static_cast<Precision>(range.Max);
|
||||
vtkm::worklet::DispatcherMapField<NormalizeBuffer<Precision>> dispatcher(
|
||||
NormalizeBuffer<Precision>(minScalar, maxScalar, invert));
|
||||
dispatcher.Invoke(this->Buffer);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
@ -465,30 +471,11 @@ struct ResizeChannelFunctor
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Precision>
|
||||
struct InitConstFunctor
|
||||
{
|
||||
ChannelBuffer<Precision>* Self;
|
||||
Precision Value;
|
||||
InitConstFunctor(ChannelBuffer<Precision>* self, Precision value)
|
||||
: Self(self)
|
||||
, Value(value)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
bool operator()(Device device)
|
||||
{
|
||||
ChannelBufferOperations::InitConst(*Self, Value, device);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Precision>
|
||||
void ChannelBuffer<Precision>::InitConst(const Precision value)
|
||||
{
|
||||
InitConstFunctor<Precision> functor(this, value);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
vtkm::cont::ArrayHandleConstant<Precision> valueHandle(value, this->GetBufferLength());
|
||||
vtkm::cont::Algorithm::Copy(valueHandle, this->Buffer);
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/ChannelBuffer.h>
|
||||
@ -143,10 +144,8 @@ public:
|
||||
template <typename Device, typename Precision>
|
||||
static void InitConst(ChannelBuffer<Precision>& buffer, const Precision value, Device)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<MemSet<Precision>> memSetDispatcher(
|
||||
(MemSet<Precision>(value)));
|
||||
memSetDispatcher.SetDevice(Device());
|
||||
memSetDispatcher.Invoke(buffer.Buffer);
|
||||
vtkm::cont::ArrayHandleConstant<Precision> valueHandle(value, buffer.GetBufferLength());
|
||||
vtkm::cont::Algorithm::Copy(Device(), valueHandle, buffer.Buffer);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2018 UT-Battelle, LLC.
|
||||
// Copyright 2018 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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/rendering/raytracing/ConnectivityBase.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
ConnectivityBase::ConnectivityBase()
|
||||
{
|
||||
}
|
||||
|
||||
ConnectivityBase::~ConnectivityBase()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_Connectivity_Base_h
|
||||
#define vtk_m_rendering_raytracing_Connectivity_Base_h
|
||||
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT ConnectivityBase
|
||||
{
|
||||
public:
|
||||
enum IntegrationMode
|
||||
{
|
||||
Volume,
|
||||
Energy
|
||||
};
|
||||
|
||||
ConnectivityBase();
|
||||
virtual ~ConnectivityBase();
|
||||
|
||||
virtual void Trace(Ray<vtkm::Float64>& rays) = 0;
|
||||
|
||||
virtual void Trace(Ray<vtkm::Float32>& rays) = 0;
|
||||
|
||||
virtual void SetVolumeData(const vtkm::cont::Field& scalarField,
|
||||
const vtkm::Range& scalarBounds) = 0;
|
||||
|
||||
virtual void SetEnergyData(const vtkm::cont::Field& absorption,
|
||||
const vtkm::Int32 numBins,
|
||||
const vtkm::cont::Field& emission = vtkm::cont::Field()) = 0;
|
||||
|
||||
virtual void SetBackgroundColor(const vtkm::Vec<vtkm::Float32, 4>& backgroundColor) = 0;
|
||||
|
||||
virtual void SetSampleDistance(const vtkm::Float32& distance) = 0;
|
||||
|
||||
virtual void SetColorMap(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap) = 0;
|
||||
|
||||
virtual void SetDebugOn(bool on) = 0;
|
||||
}; // class ConnectivityBase
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::rendering::raytracing
|
||||
#endif
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracer.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracer.hxx>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -43,34 +44,185 @@ struct RenderFunctor
|
||||
} //namespace detail
|
||||
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::Trace(Ray<vtkm::Float32>& rays)
|
||||
void ConnectivityTracer::Trace(Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
detail::RenderFunctor functor;
|
||||
vtkm::cont::TryExecute(functor, *this, rays);
|
||||
}
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::Trace(Ray<vtkm::Float64>& rays)
|
||||
void ConnectivityTracer::Trace(Ray<vtkm::Float64>& rays)
|
||||
{
|
||||
detail::RenderFunctor functor;
|
||||
vtkm::cont::TryExecute(functor, *this, rays);
|
||||
}
|
||||
|
||||
//explicit construct all valid forms ofConnectivityTracer
|
||||
void ConnectivityTracer::Init()
|
||||
{
|
||||
//
|
||||
// Check to see if a sample distance was set
|
||||
//
|
||||
if (SampleDistance <= 0)
|
||||
{
|
||||
vtkm::Bounds coordsBounds = Coords.GetBounds();
|
||||
BoundingBox[0] = vtkm::Float32(coordsBounds.X.Min);
|
||||
BoundingBox[1] = vtkm::Float32(coordsBounds.X.Max);
|
||||
BoundingBox[2] = vtkm::Float32(coordsBounds.Y.Min);
|
||||
BoundingBox[3] = vtkm::Float32(coordsBounds.Y.Max);
|
||||
BoundingBox[4] = vtkm::Float32(coordsBounds.Z.Min);
|
||||
BoundingBox[5] = vtkm::Float32(coordsBounds.Z.Max);
|
||||
|
||||
BackgroundColor[0] = 1.f;
|
||||
BackgroundColor[1] = 1.f;
|
||||
BackgroundColor[2] = 1.f;
|
||||
BackgroundColor[3] = 1.f;
|
||||
const vtkm::Float32 defaultSampleRate = 200.f;
|
||||
// We need to set some default sample distance
|
||||
vtkm::Vec<vtkm::Float32, 3> extent;
|
||||
extent[0] = BoundingBox[1] - BoundingBox[0];
|
||||
extent[1] = BoundingBox[3] - BoundingBox[2];
|
||||
extent[2] = BoundingBox[5] - BoundingBox[4];
|
||||
SampleDistance = vtkm::Magnitude(extent) / defaultSampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::Id ConnectivityTracer::GetNumberOfMeshCells() const
|
||||
{
|
||||
return CellSet.GetNumberOfCells();
|
||||
}
|
||||
|
||||
void ConnectivityTracer::SetColorMap(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap)
|
||||
{
|
||||
ColorMap = colorMap;
|
||||
}
|
||||
|
||||
void ConnectivityTracer::SetVolumeData(const vtkm::cont::Field& scalarField,
|
||||
const vtkm::Range& scalarBounds,
|
||||
const vtkm::cont::DynamicCellSet& cellSet,
|
||||
const vtkm::cont::CoordinateSystem& coords)
|
||||
{
|
||||
//TODO: Need a way to tell if we have been updated
|
||||
ScalarField = scalarField;
|
||||
ScalarBounds = scalarBounds;
|
||||
CellSet = cellSet;
|
||||
Coords = coords;
|
||||
MeshConnIsConstructed = false;
|
||||
|
||||
|
||||
bool isSupportedField =
|
||||
(ScalarField.GetAssociation() == vtkm::cont::Field::Association::POINTS ||
|
||||
ScalarField.GetAssociation() == vtkm::cont::Field::Association::CELL_SET);
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Field not accociated with cell set or points");
|
||||
FieldAssocPoints = ScalarField.GetAssociation() == vtkm::cont::Field::Association::POINTS;
|
||||
|
||||
this->Integrator = Volume;
|
||||
|
||||
if (MeshContainer == nullptr)
|
||||
{
|
||||
delete MeshContainer;
|
||||
}
|
||||
MeshConnectivityBuilder builder;
|
||||
MeshContainer = builder.BuildConnectivity(cellSet, coords);
|
||||
}
|
||||
|
||||
void ConnectivityTracer::SetEnergyData(const vtkm::cont::Field& absorption,
|
||||
const vtkm::Int32 numBins,
|
||||
const vtkm::cont::DynamicCellSet& cellSet,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& emission)
|
||||
{
|
||||
bool isSupportedField = absorption.GetAssociation() == vtkm::cont::Field::Association::CELL_SET;
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Absorption Field '" + absorption.GetName() +
|
||||
"' not accociated with cells");
|
||||
ScalarField = absorption;
|
||||
CellSet = cellSet;
|
||||
Coords = coords;
|
||||
MeshConnIsConstructed = false;
|
||||
// Check for emission
|
||||
HasEmission = false;
|
||||
|
||||
if (emission.GetAssociation() != vtkm::cont::Field::Association::ANY)
|
||||
{
|
||||
if (emission.GetAssociation() != vtkm::cont::Field::Association::CELL_SET)
|
||||
throw vtkm::cont::ErrorBadValue("Emission Field '" + emission.GetName() +
|
||||
"' not accociated with cells");
|
||||
HasEmission = true;
|
||||
EmissionField = emission;
|
||||
}
|
||||
// Do some basic range checking
|
||||
if (numBins < 1)
|
||||
throw vtkm::cont::ErrorBadValue("Number of energy bins is less than 1");
|
||||
vtkm::Id binCount = ScalarField.GetData().GetNumberOfValues();
|
||||
vtkm::Id cellCount = this->GetNumberOfMeshCells();
|
||||
if (cellCount != (binCount / vtkm::Id(numBins)))
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Invalid number of absorption bins\n";
|
||||
message << "Number of cells: " << cellCount << "\n";
|
||||
message << "Number of field values: " << binCount << "\n";
|
||||
message << "Number of bins: " << numBins << "\n";
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
if (HasEmission)
|
||||
{
|
||||
binCount = EmissionField.GetData().GetNumberOfValues();
|
||||
if (cellCount != (binCount / vtkm::Id(numBins)))
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Invalid number of emission bins\n";
|
||||
message << "Number of cells: " << cellCount << "\n";
|
||||
message << "Number of field values: " << binCount << "\n";
|
||||
message << "Number of bins: " << numBins << "\n";
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
}
|
||||
//TODO: Need a way to tell if we have been updated
|
||||
this->Integrator = Energy;
|
||||
|
||||
if (MeshContainer == nullptr)
|
||||
{
|
||||
delete MeshContainer;
|
||||
}
|
||||
MeshConnectivityBuilder builder;
|
||||
MeshContainer = builder.BuildConnectivity(cellSet, coords);
|
||||
}
|
||||
|
||||
void ConnectivityTracer::SetBackgroundColor(const vtkm::Vec<vtkm::Float32, 4>& backgroundColor)
|
||||
{
|
||||
BackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
void ConnectivityTracer::SetSampleDistance(const vtkm::Float32& distance)
|
||||
{
|
||||
if (distance <= 0.f)
|
||||
throw vtkm::cont::ErrorBadValue("Sample distance must be positive.");
|
||||
SampleDistance = distance;
|
||||
}
|
||||
|
||||
void ConnectivityTracer::ResetTimers()
|
||||
{
|
||||
IntersectTime = 0.;
|
||||
IntegrateTime = 0.;
|
||||
SampleTime = 0.;
|
||||
LostRayTime = 0.;
|
||||
MeshEntryTime = 0.;
|
||||
}
|
||||
|
||||
void ConnectivityTracer::LogTimers()
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->AddLogData("intersect ", IntersectTime);
|
||||
logger->AddLogData("integrate ", IntegrateTime);
|
||||
logger->AddLogData("sample_cells ", SampleTime);
|
||||
logger->AddLogData("lost_rays ", LostRayTime);
|
||||
logger->AddLogData("mesh_entry", LostRayTime);
|
||||
}
|
||||
|
||||
|
||||
template class detail::RayTracking<float>;
|
||||
template class detail::RayTracking<double>;
|
||||
|
||||
template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_ZOO, UnstructuredMeshConn>;
|
||||
template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_HEXAHEDRON, UnstructuredMeshConnSingleType>;
|
||||
template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_WEDGE, UnstructuredMeshConnSingleType>;
|
||||
template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_TETRA, UnstructuredMeshConnSingleType>;
|
||||
template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_STRUCTURED, StructuredMeshConn>;
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::rendering::raytracing
|
||||
|
@ -22,9 +22,10 @@
|
||||
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracerBase.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityStructures.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityContainers.h>
|
||||
|
||||
#ifndef CELL_SHAPE_ZOO
|
||||
#define CELL_SHAPE_ZOO 255
|
||||
@ -81,53 +82,94 @@ public:
|
||||
} //namespace detail
|
||||
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
class ConnectivityTracer : public ConnectivityTracerBase
|
||||
class ConnectivityTracer
|
||||
{
|
||||
public:
|
||||
ConnectivityTracer(ConnectivityType& meshConn)
|
||||
: ConnectivityTracerBase()
|
||||
, MeshConn(meshConn)
|
||||
ConnectivityTracer()
|
||||
: MeshContainer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void SetBoundingBox(Device)
|
||||
~ConnectivityTracer()
|
||||
{
|
||||
vtkm::Bounds coordsBounds = MeshConn.GetCoordinateBounds(Device());
|
||||
BoundingBox[0] = vtkm::Float32(coordsBounds.X.Min);
|
||||
BoundingBox[1] = vtkm::Float32(coordsBounds.X.Max);
|
||||
BoundingBox[2] = vtkm::Float32(coordsBounds.Y.Min);
|
||||
BoundingBox[3] = vtkm::Float32(coordsBounds.Y.Max);
|
||||
BoundingBox[4] = vtkm::Float32(coordsBounds.Z.Min);
|
||||
BoundingBox[5] = vtkm::Float32(coordsBounds.Z.Max);
|
||||
BackgroundColor[0] = 1.f;
|
||||
BackgroundColor[1] = 1.f;
|
||||
BackgroundColor[2] = 1.f;
|
||||
BackgroundColor[3] = 1.f;
|
||||
if (MeshContainer != nullptr)
|
||||
{
|
||||
delete MeshContainer;
|
||||
}
|
||||
}
|
||||
|
||||
void Trace(Ray<vtkm::Float32>& rays) override;
|
||||
enum IntegrationMode
|
||||
{
|
||||
Volume,
|
||||
Energy
|
||||
};
|
||||
|
||||
void Trace(Ray<vtkm::Float64>& rays) override;
|
||||
void SetVolumeData(const vtkm::cont::Field& scalarField,
|
||||
const vtkm::Range& scalarBounds,
|
||||
const vtkm::cont::DynamicCellSet& cellSet,
|
||||
const vtkm::cont::CoordinateSystem& coords);
|
||||
|
||||
ConnectivityType GetMeshConn() { return MeshConn; }
|
||||
void SetEnergyData(const vtkm::cont::Field& absorption,
|
||||
const vtkm::Int32 numBins,
|
||||
const vtkm::cont::DynamicCellSet& cellSet,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::Field& emission);
|
||||
|
||||
vtkm::Id GetNumberOfMeshCells() override { return MeshConn.GetNumberOfCells(); }
|
||||
void SetBackgroundColor(const vtkm::Vec<vtkm::Float32, 4>& backgroundColor);
|
||||
void SetSampleDistance(const vtkm::Float32& distance);
|
||||
void SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap);
|
||||
// template <typename Device>
|
||||
// VTKM_CONT void SetBoundingBox(Device)
|
||||
// {
|
||||
// vtkm::Bounds coordsBounds = MeshConn->GetCoordinateBounds(Device());
|
||||
// BoundingBox[0] = vtkm::Float32(coordsBounds.X.Min);
|
||||
// BoundingBox[1] = vtkm::Float32(coordsBounds.X.Max);
|
||||
// BoundingBox[2] = vtkm::Float32(coordsBounds.Y.Min);
|
||||
// BoundingBox[3] = vtkm::Float32(coordsBounds.Y.Max);
|
||||
// BoundingBox[4] = vtkm::Float32(coordsBounds.Z.Min);
|
||||
// BoundingBox[5] = vtkm::Float32(coordsBounds.Z.Max);
|
||||
// BackgroundColor[0] = 1.f;
|
||||
// BackgroundColor[1] = 1.f;
|
||||
// BackgroundColor[2] = 1.f;
|
||||
// BackgroundColor[3] = 1.f;
|
||||
// }
|
||||
|
||||
void Trace(Ray<vtkm::Float32>& rays);
|
||||
|
||||
void Trace(Ray<vtkm::Float64>& rays);
|
||||
|
||||
MeshConnContainer* GetMeshContainer() { return MeshContainer; }
|
||||
|
||||
void Init();
|
||||
|
||||
vtkm::Id GetNumberOfMeshCells() const;
|
||||
|
||||
void ResetTimers();
|
||||
void LogTimers();
|
||||
|
||||
//vtkm::Id GetNumberOfMeshCells() override { return MeshConn.GetNumberOfCells(); }
|
||||
private:
|
||||
friend struct detail::RenderFunctor;
|
||||
template <typename FloatType, typename Device>
|
||||
void IntersectCell(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
void IntersectCell(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void AccumulatePathLengths(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void FindLostRays(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
void FindLostRays(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void SampleCells(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
void SampleCells(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void IntegrateCells(Ray<FloatType>& rays, detail::RayTracking<FloatType>& tracker, Device);
|
||||
@ -135,24 +177,60 @@ private:
|
||||
template <typename FloatType, typename Device>
|
||||
void OffsetMinDistances(Ray<FloatType>& rays, Device);
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void PrintRayStatus(Ray<FloatType>& rays, Device);
|
||||
|
||||
protected:
|
||||
template <typename Device, typename FloatType>
|
||||
void RenderOnDevice(Ray<FloatType>& rays, Device);
|
||||
|
||||
ConnectivityType MeshConn;
|
||||
// Data set info
|
||||
vtkm::cont::Field ScalarField;
|
||||
vtkm::cont::Field EmissionField;
|
||||
vtkm::cont::DynamicCellSet CellSet;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
vtkm::Range ScalarBounds;
|
||||
vtkm::Float32 BoundingBox[6];
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>> ColorMap;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> PreviousCellIds;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> BackgroundColor;
|
||||
vtkm::Float32 SampleDistance;
|
||||
vtkm::Id RaysLost;
|
||||
IntegrationMode Integrator;
|
||||
//
|
||||
// flags
|
||||
bool CountRayStatus;
|
||||
bool MeshConnIsConstructed;
|
||||
bool DebugFiltersOn;
|
||||
bool ReEnterMesh; // Do not try to re-enter the mesh
|
||||
bool CreatePartialComposites;
|
||||
bool FieldAssocPoints;
|
||||
bool HasEmission; // Mode for integrating through energy bins
|
||||
|
||||
// timers
|
||||
vtkm::Float64 IntersectTime;
|
||||
vtkm::Float64 IntegrateTime;
|
||||
vtkm::Float64 SampleTime;
|
||||
vtkm::Float64 LostRayTime;
|
||||
vtkm::Float64 MeshEntryTime;
|
||||
|
||||
MeshConnContainer* MeshContainer;
|
||||
}; // class ConnectivityTracer<CellType,ConnectivityType>
|
||||
|
||||
#ifndef vtk_m_rendering_raytracing_ConnectivityTracer_cxx
|
||||
//extern explicit instantiations of ConnectivityTracer
|
||||
extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_ZOO, UnstructuredMeshConn>;
|
||||
extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_HEXAHEDRON, UnstructuredMeshConnSingleType>;
|
||||
extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_WEDGE, UnstructuredMeshConnSingleType>;
|
||||
extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_TETRA, UnstructuredMeshConnSingleType>;
|
||||
extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
ConnectivityTracer<CELL_SHAPE_STRUCTURED, StructuredMeshConn>;
|
||||
//extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
// ConnectivityTracer<CELL_SHAPE_ZOO>;
|
||||
//extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
// ConnectivityTracer<CELL_SHAPE_HEXAHEDRON>;
|
||||
//extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
// ConnectivityTracer<CELL_SHAPE_WEDGE>;
|
||||
//extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
// ConnectivityTracer<CELL_SHAPE_TETRA>;
|
||||
//extern template class VTKM_RENDERING_TEMPLATE_EXPORT
|
||||
// ConnectivityTracer<CELL_SHAPE_STRUCTURED>;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,13 @@
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterListHelpers.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/CellIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/CellSampler.h>
|
||||
#include <vtkm/rendering/raytracing/CellTables.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityBase.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityStructures.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBase.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
@ -110,15 +110,11 @@ void RayTracking<FloatType>::Init(const vtkm::Id size,
|
||||
// Init the exit faces. This value is used to load the next cell
|
||||
// base on the cell and face it left
|
||||
//
|
||||
vtkm::worklet::DispatcherMapField<MemSet<vtkm::Int32>> initExitFaceDispatcher(
|
||||
MemSet<vtkm::Int32>(-1));
|
||||
initExitFaceDispatcher.SetDevice(Device());
|
||||
initExitFaceDispatcher.Invoke(ExitFace);
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Int32> negOne(-1, size);
|
||||
vtkm::cont::Algorithm::Copy(Device(), negOne, ExitFace);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MemSet<FloatType>> initExitDistanceDispatcher(
|
||||
MemSet<FloatType>(-1));
|
||||
initExitDistanceDispatcher.SetDevice(Device());
|
||||
initExitDistanceDispatcher.Invoke(*ExitDist);
|
||||
vtkm::cont::ArrayHandleConstant<FloatType> negOnef(-1.f, size);
|
||||
vtkm::cont::Algorithm::Copy(Device(), negOnef, *ExitDist);
|
||||
}
|
||||
|
||||
template <typename FloatType>
|
||||
@ -131,6 +127,20 @@ void RayTracking<FloatType>::Swap()
|
||||
}
|
||||
} //namespace detail
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer::PrintRayStatus(Ray<FloatType>& rays, Device)
|
||||
{
|
||||
vtkm::Id raysExited = RayOperations::GetStatusCount(rays, RAY_EXITED_MESH, Device());
|
||||
vtkm::Id raysActive = RayOperations::GetStatusCount(rays, RAY_ACTIVE, Device());
|
||||
vtkm::Id raysAbandoned = RayOperations::GetStatusCount(rays, RAY_ABANDONED, Device());
|
||||
vtkm::Id raysExitedDom = RayOperations::GetStatusCount(rays, RAY_EXITED_DOMAIN, Device());
|
||||
std::cout << "\r Ray Status " << std::setw(10) << std::left << " Lost " << std::setw(10)
|
||||
<< std::left << RaysLost << std::setw(10) << std::left << " Exited " << std::setw(10)
|
||||
<< std::left << raysExited << std::setw(10) << std::left << " Active " << std::setw(10)
|
||||
<< raysActive << std::setw(10) << std::left << " Abandoned " << std::setw(10)
|
||||
<< raysAbandoned << " Exited Domain " << std::setw(10) << std::left << raysExitedDom
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
//
|
||||
// Advance Ray
|
||||
@ -160,16 +170,15 @@ public:
|
||||
}
|
||||
}; //class AdvanceRay
|
||||
|
||||
template <vtkm::Int32 CellType, typename FloatType, typename MeshType>
|
||||
template <typename FloatType>
|
||||
class LocateCell : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
MeshType MeshConn;
|
||||
CellIntersector<CellType> Intersector;
|
||||
const MeshConnectivityBase* MeshConn;
|
||||
CellIntersector<255> Intersector;
|
||||
|
||||
public:
|
||||
template <typename ConnectivityType>
|
||||
LocateCell(ConnectivityType& meshConn)
|
||||
LocateCell(const MeshConnectivityBase* meshConn)
|
||||
: MeshConn(meshConn)
|
||||
{
|
||||
}
|
||||
@ -196,7 +205,7 @@ public:
|
||||
{
|
||||
if (enterFace != -1 && rayStatus == RAY_ACTIVE)
|
||||
{
|
||||
currentCell = MeshConn.GetConnectingCell(currentCell, enterFace);
|
||||
currentCell = MeshConn->GetConnectingCell(currentCell, enterFace);
|
||||
if (currentCell == -1)
|
||||
rayStatus = RAY_EXITED_MESH;
|
||||
enterFace = -1;
|
||||
@ -212,7 +221,7 @@ public:
|
||||
vtkm::Id cellConn[8];
|
||||
FloatType distances[6];
|
||||
|
||||
const vtkm::Int32 numIndices = MeshConn.GetCellIndices(cellConn, currentCell);
|
||||
const vtkm::Int32 numIndices = MeshConn->GetCellIndices(cellConn, currentCell);
|
||||
//load local cell data
|
||||
for (int i = 0; i < numIndices; ++i)
|
||||
{
|
||||
@ -222,7 +231,7 @@ public:
|
||||
ypoints[i] = point[1];
|
||||
zpoints[i] = point[2];
|
||||
}
|
||||
const vtkm::UInt8 cellShape = MeshConn.GetCellShape(currentCell);
|
||||
const vtkm::UInt8 cellShape = MeshConn->GetCellShape(currentCell);
|
||||
Intersector.IntersectCell(xpoints, ypoints, zpoints, dir, origin, distances, cellShape);
|
||||
|
||||
CellTables tables;
|
||||
@ -267,7 +276,7 @@ public:
|
||||
} //operator
|
||||
}; //class LocateCell
|
||||
|
||||
template <vtkm::Int32 CellType, typename FloatType, typename Device, typename MeshType>
|
||||
template <typename FloatType, typename Device>
|
||||
class RayBumper : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
@ -276,15 +285,14 @@ private:
|
||||
FloatTypePortal DirectionsX;
|
||||
FloatTypePortal DirectionsY;
|
||||
FloatTypePortal DirectionsZ;
|
||||
MeshType MeshConn;
|
||||
CellIntersector<CellType> Intersector;
|
||||
const MeshConnectivityBase* MeshConn;
|
||||
CellIntersector<255> Intersector;
|
||||
const vtkm::UInt8 FailureStatus; // the status to assign ray if we fail to find the intersection
|
||||
public:
|
||||
template <typename ConnectivityType>
|
||||
RayBumper(FloatTypeHandle dirsx,
|
||||
FloatTypeHandle dirsy,
|
||||
FloatTypeHandle dirsz,
|
||||
ConnectivityType meshConn,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
vtkm::UInt8 failureStatus = RAY_ABANDONED)
|
||||
: DirectionsX(dirsx.PrepareForInPlace(Device()))
|
||||
, DirectionsY(dirsy.PrepareForInPlace(Device()))
|
||||
@ -327,7 +335,7 @@ public:
|
||||
FloatType distances[6];
|
||||
|
||||
vtkm::Vec<FloatType, 3> centroid(0., 0., 0.);
|
||||
const vtkm::Int32 numIndices = MeshConn.GetCellIndices(cellConn, currentCell);
|
||||
const vtkm::Int32 numIndices = MeshConn->GetCellIndices(cellConn, currentCell);
|
||||
//load local cell data
|
||||
for (int i = 0; i < numIndices; ++i)
|
||||
{
|
||||
@ -358,7 +366,7 @@ public:
|
||||
DirectionsY.Set(pixelIndex, dir[1]);
|
||||
DirectionsZ.Set(pixelIndex, dir[2]);
|
||||
|
||||
const vtkm::UInt8 cellShape = MeshConn.GetCellShape(currentCell);
|
||||
const vtkm::UInt8 cellShape = MeshConn->GetCellShape(currentCell);
|
||||
Intersector.IntersectCell(xpoints, ypoints, zpoints, dir, origin, distances, cellShape);
|
||||
|
||||
CellTables tables;
|
||||
@ -674,7 +682,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <vtkm::Int32 CellType, typename FloatType, typename Device, typename MeshType>
|
||||
template <typename FloatType, typename Device>
|
||||
class SampleCellAssocCells : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
@ -683,23 +691,22 @@ private:
|
||||
using ColorConstPortal = typename ColorHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using ColorPortal = typename ColorBuffer::template ExecutionTypes<Device>::Portal;
|
||||
|
||||
CellSampler<CellType> Sampler;
|
||||
CellSampler<255> Sampler;
|
||||
FloatType SampleDistance;
|
||||
FloatType MinScalar;
|
||||
FloatType InvDeltaScalar;
|
||||
ColorPortal FrameBuffer;
|
||||
ColorConstPortal ColorMap;
|
||||
MeshType MeshConn;
|
||||
const MeshConnectivityBase* MeshConn;
|
||||
vtkm::Int32 ColorMapSize;
|
||||
|
||||
public:
|
||||
template <typename ConnectivityType>
|
||||
SampleCellAssocCells(const FloatType& sampleDistance,
|
||||
const FloatType& minScalar,
|
||||
const FloatType& maxScalar,
|
||||
ColorHandle& colorMap,
|
||||
ColorBuffer& frameBuffer,
|
||||
ConnectivityType& meshConn)
|
||||
const MeshConnectivityBase* meshConn)
|
||||
: SampleDistance(sampleDistance)
|
||||
, MinScalar(minScalar)
|
||||
, ColorMap(colorMap.PrepareForInput(Device()))
|
||||
@ -792,7 +799,7 @@ public:
|
||||
}
|
||||
}; //class Sample cell
|
||||
|
||||
template <vtkm::Int32 CellType, typename FloatType, typename Device, typename MeshType>
|
||||
template <typename FloatType, typename Device>
|
||||
class SampleCellAssocPoints : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
@ -801,9 +808,9 @@ private:
|
||||
using ColorConstPortal = typename ColorHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using ColorPortal = typename ColorBuffer::template ExecutionTypes<Device>::Portal;
|
||||
|
||||
CellSampler<CellType> Sampler;
|
||||
CellSampler<255> Sampler;
|
||||
FloatType SampleDistance;
|
||||
MeshType MeshConn;
|
||||
const MeshConnectivityBase* MeshConn;
|
||||
FloatType MinScalar;
|
||||
FloatType InvDeltaScalar;
|
||||
ColorPortal FrameBuffer;
|
||||
@ -811,13 +818,12 @@ private:
|
||||
vtkm::Id ColorMapSize;
|
||||
|
||||
public:
|
||||
template <typename ConnectivityType>
|
||||
SampleCellAssocPoints(const FloatType& sampleDistance,
|
||||
const FloatType& minScalar,
|
||||
const FloatType& maxScalar,
|
||||
ColorHandle& colorMap,
|
||||
ColorBuffer& frameBuffer,
|
||||
ConnectivityType& meshConn)
|
||||
const MeshConnectivityBase* meshConn)
|
||||
: SampleDistance(sampleDistance)
|
||||
, MeshConn(meshConn)
|
||||
, MinScalar(minScalar)
|
||||
@ -881,7 +887,7 @@ public:
|
||||
}
|
||||
//load local scalar cell data
|
||||
vtkm::Id cellConn[8];
|
||||
const vtkm::Int32 numIndices = MeshConn.GetCellIndices(cellConn, currentCell);
|
||||
const vtkm::Int32 numIndices = MeshConn->GetCellIndices(cellConn, currentCell);
|
||||
for (int i = 0; i < numIndices; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(scalarPortal, cellConn[i]);
|
||||
@ -900,7 +906,7 @@ public:
|
||||
currentDistance = enterDistance;
|
||||
}
|
||||
|
||||
const vtkm::Int32 cellShape = MeshConn.GetCellShape(currentCell);
|
||||
const vtkm::Int32 cellShape = MeshConn->GetCellShape(currentCell);
|
||||
while (enterDistance <= currentDistance && currentDistance <= exitDistance)
|
||||
{
|
||||
vtkm::Vec<FloatType, 3> sampleLoc = origin + currentDistance * dir;
|
||||
@ -952,37 +958,34 @@ public:
|
||||
}
|
||||
}; //class Sample cell
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::IntersectCell(
|
||||
Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
void ConnectivityTracer::IntersectCell(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device)
|
||||
{
|
||||
using LocateC = LocateCell<CellType, FloatType, MeshConnExec<ConnectivityType, Device>>;
|
||||
using LocateC = LocateCell<FloatType>;
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
vtkm::worklet::DispatcherMapField<LocateC> dispatcher((LocateC(MeshConn)));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.HitIdx,
|
||||
this->MeshConn.GetCoordinates(),
|
||||
rays.Dir,
|
||||
*(tracker.EnterDist),
|
||||
*(tracker.ExitDist),
|
||||
tracker.ExitFace,
|
||||
rays.Status,
|
||||
rays.Origin);
|
||||
vtkm::worklet::DispatcherMapField<LocateC> locateDispatch(meshConn);
|
||||
locateDispatch.SetDevice(Device());
|
||||
locateDispatch.Invoke(rays.HitIdx,
|
||||
this->Coords,
|
||||
rays.Dir,
|
||||
*(tracker.EnterDist),
|
||||
*(tracker.ExitDist),
|
||||
tracker.ExitFace,
|
||||
rays.Status,
|
||||
rays.Origin);
|
||||
|
||||
if (this->CountRayStatus)
|
||||
RaysLost = RayOperations::GetStatusCount(rays, RAY_LOST, Device());
|
||||
this->IntersectTime += timer.GetElapsedTime();
|
||||
}
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::AccumulatePathLengths(
|
||||
Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
void ConnectivityTracer::AccumulatePathLengths(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<AddPathLengths<FloatType>> dispatcher(
|
||||
(AddPathLengths<FloatType>()));
|
||||
@ -991,41 +994,37 @@ void ConnectivityTracer<CellType, ConnectivityType>::AccumulatePathLengths(
|
||||
rays.Status, *(tracker.EnterDist), *(tracker.ExitDist), rays.GetBuffer("path_lengths").Buffer);
|
||||
}
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::FindLostRays(
|
||||
Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
void ConnectivityTracer::FindLostRays(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device)
|
||||
{
|
||||
using RayB = RayBumper<CellType, FloatType, Device, MeshConnExec<ConnectivityType, Device>>;
|
||||
using RayB = RayBumper<FloatType, Device>;
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<RayB> dispatcher(
|
||||
RayB(rays.DirX, rays.DirY, rays.DirZ, this->MeshConn));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.HitIdx,
|
||||
this->MeshConn.GetCoordinates(),
|
||||
*(tracker.EnterDist),
|
||||
*(tracker.ExitDist),
|
||||
tracker.ExitFace,
|
||||
rays.Status,
|
||||
rays.Origin);
|
||||
vtkm::worklet::DispatcherMapField<RayB> bumpDispatch(
|
||||
RayB(rays.DirX, rays.DirY, rays.DirZ, meshConn));
|
||||
bumpDispatch.SetDevice(Device());
|
||||
bumpDispatch.Invoke(rays.HitIdx,
|
||||
this->Coords,
|
||||
*(tracker.EnterDist),
|
||||
*(tracker.ExitDist),
|
||||
tracker.ExitFace,
|
||||
rays.Status,
|
||||
rays.Origin);
|
||||
|
||||
this->LostRayTime += timer.GetElapsedTime();
|
||||
}
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::SampleCells(
|
||||
Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
void ConnectivityTracer::SampleCells(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
const MeshConnectivityBase* meshConn,
|
||||
Device)
|
||||
{
|
||||
using SampleP =
|
||||
SampleCellAssocPoints<CellType, FloatType, Device, MeshConnExec<ConnectivityType, Device>>;
|
||||
using SampleC =
|
||||
SampleCellAssocCells<CellType, FloatType, Device, MeshConnExec<ConnectivityType, Device>>;
|
||||
using SampleP = SampleCellAssocPoints<FloatType, Device>;
|
||||
using SampleC = SampleCellAssocCells<FloatType, Device>;
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
|
||||
VTKM_ASSERT(rays.Buffers.at(0).GetNumChannels() == 4);
|
||||
@ -1038,10 +1037,10 @@ void ConnectivityTracer<CellType, ConnectivityType>::SampleCells(
|
||||
vtkm::Float32(this->ScalarBounds.Max),
|
||||
this->ColorMap,
|
||||
rays.Buffers.at(0).Buffer,
|
||||
this->MeshConn));
|
||||
meshConn));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.HitIdx,
|
||||
this->MeshConn.GetCoordinates(),
|
||||
this->Coords,
|
||||
this->ScalarField.GetData(),
|
||||
*(tracker.EnterDist),
|
||||
*(tracker.ExitDist),
|
||||
@ -1058,7 +1057,7 @@ void ConnectivityTracer<CellType, ConnectivityType>::SampleCells(
|
||||
vtkm::Float32(this->ScalarBounds.Max),
|
||||
this->ColorMap,
|
||||
rays.Buffers.at(0).Buffer,
|
||||
this->MeshConn));
|
||||
meshConn));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.HitIdx,
|
||||
this->ScalarField.GetData(),
|
||||
@ -1071,12 +1070,10 @@ void ConnectivityTracer<CellType, ConnectivityType>::SampleCells(
|
||||
this->SampleTime += timer.GetElapsedTime();
|
||||
}
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::IntegrateCells(
|
||||
Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
void ConnectivityTracer::IntegrateCells(Ray<FloatType>& rays,
|
||||
detail::RayTracking<FloatType>& tracker,
|
||||
Device)
|
||||
{
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
if (HasEmission)
|
||||
@ -1114,9 +1111,9 @@ void ConnectivityTracer<CellType, ConnectivityType>::IntegrateCells(
|
||||
IntegrateTime += timer.GetElapsedTime();
|
||||
}
|
||||
|
||||
// template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
// template <vtkm::Int32 CellType>
|
||||
// template <typename FloatType>
|
||||
// void ConnectivityTracer<CellType,ConnectivityType>::PrintDebugRay(Ray<FloatType>& rays, vtkm::Id rayId)
|
||||
// void ConnectivityTracer<CellType>::PrintDebugRay(Ray<FloatType>& rays, vtkm::Id rayId)
|
||||
// {
|
||||
// vtkm::Id index = -1;
|
||||
// for (vtkm::Id i = 0; i < rays.NumRays; ++i)
|
||||
@ -1142,10 +1139,8 @@ void ConnectivityTracer<CellType, ConnectivityType>::IntegrateCells(
|
||||
// std::cout << "+++++++++++++++++++++++++\n";
|
||||
// }
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename FloatType, typename Device>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::OffsetMinDistances(Ray<FloatType>& rays,
|
||||
Device)
|
||||
void ConnectivityTracer::OffsetMinDistances(Ray<FloatType>& rays, Device)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<AdvanceRay<FloatType>> dispatcher(
|
||||
AdvanceRay<FloatType>(FloatType(0.001)));
|
||||
@ -1153,22 +1148,26 @@ void ConnectivityTracer<CellType, ConnectivityType>::OffsetMinDistances(Ray<Floa
|
||||
dispatcher.Invoke(rays.Status, rays.MinDistance);
|
||||
}
|
||||
|
||||
template <vtkm::Int32 CellType, typename ConnectivityType>
|
||||
template <typename Device, typename FloatType>
|
||||
void ConnectivityTracer<CellType, ConnectivityType>::RenderOnDevice(Ray<FloatType>& rays, Device)
|
||||
void ConnectivityTracer::RenderOnDevice(Ray<FloatType>& rays, Device)
|
||||
{
|
||||
this->RaysLost = 0;
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("conn_tracer");
|
||||
logger->AddLogData("device", GetDeviceString(Device()));
|
||||
this->ResetTimers();
|
||||
vtkm::cont::Timer<Device> renderTimer;
|
||||
|
||||
this->SetBoundingBox(Device());
|
||||
vtkm::cont::DeviceAdapterId devId = Device();
|
||||
|
||||
const MeshConnectivityBase* meshConn = MeshContainer->Construct(devId);
|
||||
|
||||
//this->SetBoundingBox(Device());
|
||||
|
||||
bool hasPathLengths = rays.HasBuffer("path_lengths");
|
||||
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
this->Init();
|
||||
this->Init(); // sets sample distance
|
||||
//
|
||||
// All Rays begin as exited to force intersection
|
||||
//
|
||||
@ -1180,9 +1179,7 @@ void ConnectivityTracer<CellType, ConnectivityType>::RenderOnDevice(Ray<FloatTyp
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("init", time);
|
||||
|
||||
MeshConn.Construct(Device());
|
||||
|
||||
|
||||
//CountRayStatus = true;
|
||||
bool cullMissedRays = true;
|
||||
bool workRemaining = true;
|
||||
if (this->CountRayStatus)
|
||||
@ -1197,7 +1194,7 @@ void ConnectivityTracer<CellType, ConnectivityType>::RenderOnDevice(Ray<FloatTyp
|
||||
//
|
||||
// if ray misses the external face it will be marked RAY_EXITED_MESH
|
||||
//
|
||||
MeshConn.FindEntry(rays, Device());
|
||||
MeshContainer->FindEntry(rays, devId);
|
||||
MeshEntryTime += entryTimer.GetElapsedTime();
|
||||
}
|
||||
|
||||
@ -1225,17 +1222,17 @@ void ConnectivityTracer<CellType, ConnectivityType>::RenderOnDevice(Ray<FloatTyp
|
||||
{
|
||||
//
|
||||
// Rays the leave the mesh will be marked as RAYEXITED_MESH
|
||||
this->IntersectCell(rays, rayTracker, Device());
|
||||
this->IntersectCell(rays, rayTracker, meshConn, Device());
|
||||
//
|
||||
// If the ray was lost due to precision issues, we find it.
|
||||
// If it is marked RAY_ABANDONED, then something went wrong.
|
||||
//
|
||||
this->FindLostRays(rays, rayTracker, Device());
|
||||
this->FindLostRays(rays, rayTracker, meshConn, Device());
|
||||
//
|
||||
// integrate along the ray
|
||||
//
|
||||
if (this->Integrator == Volume)
|
||||
this->SampleCells(rays, rayTracker, Device());
|
||||
this->SampleCells(rays, rayTracker, meshConn, Device());
|
||||
else
|
||||
this->IntegrateCells(rays, rayTracker, Device());
|
||||
|
||||
|
@ -1,170 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2018 UT-Battelle, LLC.
|
||||
// Copyright 2018 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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/rendering/raytracing/ConnectivityTracerBase.h>
|
||||
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
ConnectivityTracerBase::ConnectivityTracerBase()
|
||||
: ConnectivityBase()
|
||||
, CountRayStatus(false)
|
||||
{
|
||||
}
|
||||
|
||||
ConnectivityTracerBase::~ConnectivityTracerBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::SetDebugOn(bool on)
|
||||
{
|
||||
CountRayStatus = on;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::Init()
|
||||
{
|
||||
//
|
||||
// Check to see if a sample distance was set
|
||||
//
|
||||
if (SampleDistance <= 0)
|
||||
{
|
||||
const vtkm::Float32 defaultSampleRate = 200.f;
|
||||
// We need to set some default sample distance
|
||||
vtkm::Vec<vtkm::Float32, 3> extent;
|
||||
extent[0] = BoundingBox[1] - BoundingBox[0];
|
||||
extent[1] = BoundingBox[3] - BoundingBox[2];
|
||||
extent[2] = BoundingBox[5] - BoundingBox[4];
|
||||
SampleDistance = vtkm::Magnitude(extent) / defaultSampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::SetColorMap(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap)
|
||||
{
|
||||
ColorMap = colorMap;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::SetVolumeData(const vtkm::cont::Field& scalarField,
|
||||
const vtkm::Range& scalarBounds)
|
||||
{
|
||||
//TODO: Need a way to tell if we have been updated
|
||||
ScalarField = scalarField;
|
||||
ScalarBounds = scalarBounds;
|
||||
|
||||
bool isSupportedField =
|
||||
(ScalarField.GetAssociation() == vtkm::cont::Field::Association::POINTS ||
|
||||
ScalarField.GetAssociation() == vtkm::cont::Field::Association::CELL_SET);
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Field not accociated with cell set or points");
|
||||
FieldAssocPoints = ScalarField.GetAssociation() == vtkm::cont::Field::Association::POINTS;
|
||||
|
||||
this->Integrator = Volume;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::SetEnergyData(const vtkm::cont::Field& absorption,
|
||||
const vtkm::Int32 numBins,
|
||||
const vtkm::cont::Field& emission)
|
||||
{
|
||||
bool isSupportedField = absorption.GetAssociation() == vtkm::cont::Field::Association::CELL_SET;
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Absorption Field '" + absorption.GetName() +
|
||||
"' not accociated with cells");
|
||||
ScalarField = absorption;
|
||||
// Check for emission
|
||||
HasEmission = false;
|
||||
|
||||
if (emission.GetAssociation() != vtkm::cont::Field::Association::ANY)
|
||||
{
|
||||
if (emission.GetAssociation() != vtkm::cont::Field::Association::CELL_SET)
|
||||
throw vtkm::cont::ErrorBadValue("Emission Field '" + emission.GetName() +
|
||||
"' not accociated with cells");
|
||||
HasEmission = true;
|
||||
EmissionField = emission;
|
||||
}
|
||||
// Do some basic range checking
|
||||
if (numBins < 1)
|
||||
throw vtkm::cont::ErrorBadValue("Number of energy bins is less than 1");
|
||||
vtkm::Id binCount = ScalarField.GetData().GetNumberOfValues();
|
||||
vtkm::Id cellCount = this->GetNumberOfMeshCells();
|
||||
if (cellCount != (binCount / vtkm::Id(numBins)))
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Invalid number of absorption bins\n";
|
||||
message << "Number of cells: " << cellCount << "\n";
|
||||
message << "Number of field values: " << binCount << "\n";
|
||||
message << "Number of bins: " << numBins << "\n";
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
if (HasEmission)
|
||||
{
|
||||
binCount = EmissionField.GetData().GetNumberOfValues();
|
||||
if (cellCount != (binCount / vtkm::Id(numBins)))
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Invalid number of emission bins\n";
|
||||
message << "Number of cells: " << cellCount << "\n";
|
||||
message << "Number of field values: " << binCount << "\n";
|
||||
message << "Number of bins: " << numBins << "\n";
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
}
|
||||
//TODO: Need a way to tell if we have been updated
|
||||
this->Integrator = Energy;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::SetBackgroundColor(const vtkm::Vec<vtkm::Float32, 4>& backgroundColor)
|
||||
{
|
||||
BackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::SetSampleDistance(const vtkm::Float32& distance)
|
||||
{
|
||||
if (distance <= 0.f)
|
||||
throw vtkm::cont::ErrorBadValue("Sample distance must be positive.");
|
||||
SampleDistance = distance;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::ResetTimers()
|
||||
{
|
||||
IntersectTime = 0.;
|
||||
IntegrateTime = 0.;
|
||||
SampleTime = 0.;
|
||||
LostRayTime = 0.;
|
||||
MeshEntryTime = 0.;
|
||||
}
|
||||
|
||||
void ConnectivityTracerBase::LogTimers()
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->AddLogData("intersect ", IntersectTime);
|
||||
logger->AddLogData("integrate ", IntegrateTime);
|
||||
logger->AddLogData("sample_cells ", SampleTime);
|
||||
logger->AddLogData("lost_rays ", LostRayTime);
|
||||
logger->AddLogData("mesh_entry", LostRayTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_ConnectivityTracerBase_h
|
||||
#define vtk_m_rendering_raytracing_ConnectivityTracerBase_h
|
||||
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/ConnectivityBase.h>
|
||||
#include <vtkm/rendering/raytracing/RayOperations.h>
|
||||
|
||||
#include <vtkm/Bounds.h>
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT ConnectivityTracerBase : public ConnectivityBase
|
||||
{
|
||||
public:
|
||||
ConnectivityTracerBase();
|
||||
|
||||
virtual ~ConnectivityTracerBase();
|
||||
|
||||
void Init();
|
||||
|
||||
virtual vtkm::Id GetNumberOfMeshCells() = 0;
|
||||
|
||||
void SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap) override;
|
||||
|
||||
void SetVolumeData(const vtkm::cont::Field& scalarField,
|
||||
const vtkm::Range& scalarBounds) override;
|
||||
|
||||
void SetEnergyData(const vtkm::cont::Field& absorption,
|
||||
const vtkm::Int32 numBins,
|
||||
const vtkm::cont::Field& emission) override;
|
||||
|
||||
|
||||
void SetBackgroundColor(const vtkm::Vec<vtkm::Float32, 4>& backgroundColor) override;
|
||||
|
||||
void SetSampleDistance(const vtkm::Float32& distance) override;
|
||||
|
||||
void SetDebugOn(bool on) override;
|
||||
|
||||
protected:
|
||||
vtkm::cont::Field ScalarField;
|
||||
vtkm::cont::Field EmissionField;
|
||||
vtkm::Range ScalarBounds;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>> ColorMap;
|
||||
vtkm::Float32 BoundingBox[6];
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> PreviousCellIds;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> BackgroundColor;
|
||||
vtkm::Float32 SampleDistance;
|
||||
bool CountRayStatus;
|
||||
vtkm::Id RaysLost;
|
||||
IntegrationMode Integrator;
|
||||
bool DebugFiltersOn;
|
||||
bool ReEnterMesh; // Do not try to re-enter the mesh
|
||||
bool CreatePartialComposites;
|
||||
bool FieldAssocPoints;
|
||||
bool HasEmission; // Mode for integrating through energy bins
|
||||
|
||||
// timers
|
||||
vtkm::Float64 IntersectTime;
|
||||
vtkm::Float64 IntegrateTime;
|
||||
vtkm::Float64 SampleTime;
|
||||
vtkm::Float64 LostRayTime;
|
||||
vtkm::Float64 MeshEntryTime;
|
||||
|
||||
template <typename FloatType, typename Device>
|
||||
void PrintRayStatus(Ray<FloatType>& rays, Device)
|
||||
{
|
||||
vtkm::Id raysExited = RayOperations::GetStatusCount(rays, RAY_EXITED_MESH, Device());
|
||||
vtkm::Id raysActive = RayOperations::GetStatusCount(rays, RAY_ACTIVE, Device());
|
||||
vtkm::Id raysAbandoned = RayOperations::GetStatusCount(rays, RAY_ABANDONED, Device());
|
||||
vtkm::Id raysExitedDom = RayOperations::GetStatusCount(rays, RAY_EXITED_DOMAIN, Device());
|
||||
std::cout << "\r Ray Status " << std::setw(10) << std::left << " Lost " << std::setw(10)
|
||||
<< std::left << RaysLost << std::setw(10) << std::left << " Exited " << std::setw(10)
|
||||
<< std::left << raysExited << std::setw(10) << std::left << " Active "
|
||||
<< std::setw(10) << raysActive << std::setw(10) << std::left << " Abandoned "
|
||||
<< std::setw(10) << raysAbandoned << " Exited Domain " << std::setw(10) << std::left
|
||||
<< raysExitedDom << "\n";
|
||||
}
|
||||
|
||||
void ResetTimers();
|
||||
|
||||
void LogTimers();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,112 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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/rendering/raytracing/ConnectivityTracer.h>
|
||||
#include <vtkm/rendering/raytracing/ConnectivityTracerFactory.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
|
||||
#ifndef CELL_SHAPE_ZOO
|
||||
#define CELL_SHAPE_ZOO 255
|
||||
#endif
|
||||
|
||||
#ifndef CELL_SHAPE_STRUCTURED
|
||||
#define CELL_SHAPE_STRUCTURED 254
|
||||
#endif
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ConnectivityTracerFactory::TracerType ConnectivityTracerFactory::DetectCellSetType(
|
||||
const vtkm::cont::DynamicCellSet& cellset)
|
||||
{
|
||||
ConnectivityTracerFactory::TracerType type = Unsupported;
|
||||
if (cellset.IsSameType(vtkm::cont::CellSetExplicit<>()))
|
||||
{
|
||||
type = Unstructured;
|
||||
}
|
||||
else if (cellset.IsSameType(vtkm::cont::CellSetSingleType<>()))
|
||||
{
|
||||
vtkm::cont::CellSetSingleType<> singleType = cellset.Cast<vtkm::cont::CellSetSingleType<>>();
|
||||
//
|
||||
// Now we need to determine what type of cells this holds
|
||||
//
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
|
||||
singleType.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
vtkm::UInt8 shapeType = shapes.GetPortalConstControl().Get(0);
|
||||
if (shapeType == CELL_SHAPE_HEXAHEDRON)
|
||||
type = UnstructuredHex;
|
||||
if (shapeType == CELL_SHAPE_TETRA)
|
||||
type = UnstructuredTet;
|
||||
if (shapeType == CELL_SHAPE_WEDGE)
|
||||
type = UnstructuredWedge;
|
||||
if (shapeType == CELL_SHAPE_PYRAMID)
|
||||
type = UnstructuredPyramid;
|
||||
}
|
||||
else if (cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
||||
{
|
||||
type = Structured;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ConnectivityBase* ConnectivityTracerFactory::CreateTracer(
|
||||
const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords)
|
||||
{
|
||||
ConnectivityTracerFactory::TracerType type = DetectCellSetType(cellset);
|
||||
if (type == Unstructured)
|
||||
{
|
||||
UnstructuredMeshConn meshConn(cellset, coords);
|
||||
return new ConnectivityTracer<CELL_SHAPE_ZOO, UnstructuredMeshConn>(meshConn);
|
||||
}
|
||||
else if (type == UnstructuredHex)
|
||||
{
|
||||
UnstructuredMeshConnSingleType meshConn(cellset, coords);
|
||||
return new ConnectivityTracer<CELL_SHAPE_HEXAHEDRON, UnstructuredMeshConnSingleType>(meshConn);
|
||||
}
|
||||
else if (type == UnstructuredWedge)
|
||||
{
|
||||
UnstructuredMeshConnSingleType meshConn(cellset, coords);
|
||||
return new ConnectivityTracer<CELL_SHAPE_WEDGE, UnstructuredMeshConnSingleType>(meshConn);
|
||||
}
|
||||
else if (type == UnstructuredTet)
|
||||
{
|
||||
UnstructuredMeshConnSingleType meshConn(cellset, coords);
|
||||
|
||||
return new ConnectivityTracer<CELL_SHAPE_TETRA, UnstructuredMeshConnSingleType>(meshConn);
|
||||
}
|
||||
else if (type == Structured)
|
||||
{
|
||||
StructuredMeshConn meshConn(cellset, coords);
|
||||
return new ConnectivityTracer<CELL_SHAPE_STRUCTURED, StructuredMeshConn>(meshConn);
|
||||
}
|
||||
|
||||
throw vtkm::cont::ErrorBadValue("Connectivity tracer: cell set type unsupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::rendering::raytracing
|
@ -1,64 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2018 UT-Battelle, LLC.
|
||||
// Copyright 2018 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_ConnectivityTracerFactory_h
|
||||
#define vtk_m_rendering_raytracing_ConnectivityTracerFactory_h
|
||||
|
||||
#include <vtkm/rendering/raytracing/ConnectivityBase.h>
|
||||
#include <vtkm/rendering/vtkm_rendering_export.h>
|
||||
|
||||
#include <vtkm/cont/DynamicCellSet.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{ //forward declares
|
||||
class CoordinateSystem;
|
||||
}
|
||||
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
class VTKM_RENDERING_EXPORT ConnectivityTracerFactory
|
||||
{
|
||||
public:
|
||||
enum TracerType
|
||||
{
|
||||
Unsupported = 0,
|
||||
Structured = 1,
|
||||
Unstructured = 2,
|
||||
UnstructuredHex = 3,
|
||||
UnstructuredTet = 4,
|
||||
UnstructuredWedge = 5,
|
||||
UnstructuredPyramid = 6
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static TracerType DetectCellSetType(const vtkm::cont::DynamicCellSet& cellset);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static ConnectivityBase* CreateTracer(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords);
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::rendering::raytracing
|
||||
#endif
|
@ -20,23 +20,8 @@
|
||||
#ifndef vtk_m_rendering_raytracing_MeshConnectivityBuilder_h
|
||||
#define vtk_m_rendering_raytracing_MeshConnectivityBuilder_h
|
||||
|
||||
#include <vtkm/cont/CellSetExplicit.h>
|
||||
#include <vtkm/cont/CellSetSingleType.h>
|
||||
#include <vtkm/cont/CellSetStructured.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/CellTables.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/MortonCodes.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
#include <vtkm/rendering/raytracing/Worklets.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityContainers.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -45,790 +30,36 @@ namespace rendering
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
struct IsExternal
|
||||
{
|
||||
VTKM_EXEC_CONT
|
||||
inline bool operator()(const vtkm::Id& x) const { return (x < 0); }
|
||||
}; //struct IsExternal
|
||||
|
||||
class CountFaces : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountFaces() {}
|
||||
using ControlSignature = void(WholeArrayIn<>, FieldOut<>);
|
||||
using ExecutionSignature = void(_1, _2, WorkIndex);
|
||||
template <typename ShapePortalType>
|
||||
VTKM_EXEC inline void operator()(const ShapePortalType& shapes,
|
||||
vtkm::Id& faces,
|
||||
const vtkm::Id& index) const
|
||||
{
|
||||
BOUNDS_CHECK(shapes, index);
|
||||
vtkm::UInt8 shapeType = shapes.Get(index);
|
||||
if (shapeType == vtkm::CELL_SHAPE_TETRA)
|
||||
{
|
||||
faces = 4;
|
||||
}
|
||||
else if (shapeType == vtkm::CELL_SHAPE_HEXAHEDRON)
|
||||
{
|
||||
faces = 6;
|
||||
}
|
||||
else if (shapeType == vtkm::CELL_SHAPE_WEDGE)
|
||||
{
|
||||
faces = 5;
|
||||
}
|
||||
else if (shapeType == vtkm::CELL_SHAPE_PYRAMID)
|
||||
{
|
||||
faces = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
faces = 0;
|
||||
}
|
||||
}
|
||||
}; //class CountFaces
|
||||
|
||||
class MortonNeighbor : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
MortonNeighbor() {}
|
||||
using ControlSignature = void(WholeArrayIn<>,
|
||||
WholeArrayInOut<Id3Type>,
|
||||
WholeArrayIn<>,
|
||||
WholeArrayIn<>,
|
||||
WholeArrayIn<>,
|
||||
WholeArrayOut<>);
|
||||
using ExecutionSignature = void(_1, _2, WorkIndex, _3, _4, _5, _6);
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Int32 GetShapeOffset(const vtkm::UInt8& shapeType) const
|
||||
{
|
||||
|
||||
CellTables tables;
|
||||
//TODO: This might be better as if if if
|
||||
vtkm::Int32 tableOffset = 0;
|
||||
if (shapeType == vtkm::CELL_SHAPE_TETRA)
|
||||
{
|
||||
tableOffset = tables.FaceLookUp(1, 0);
|
||||
}
|
||||
else if (shapeType == vtkm::CELL_SHAPE_HEXAHEDRON)
|
||||
{
|
||||
tableOffset = tables.FaceLookUp(0, 0);
|
||||
}
|
||||
else if (shapeType == vtkm::CELL_SHAPE_WEDGE)
|
||||
{
|
||||
tableOffset = tables.FaceLookUp(2, 0);
|
||||
}
|
||||
else if (shapeType == vtkm::CELL_SHAPE_PYRAMID)
|
||||
{
|
||||
tableOffset = tables.FaceLookUp(3, 0);
|
||||
}
|
||||
else
|
||||
printf("Error shape not recognized %d\n", (int)shapeType);
|
||||
|
||||
return tableOffset;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
inline bool IsIn(const vtkm::Id& needle,
|
||||
const vtkm::Vec<vtkm::Id, 4>& heystack,
|
||||
const vtkm::Int32& numIndices) const
|
||||
{
|
||||
bool isIn = false;
|
||||
for (vtkm::Int32 i = 0; i < numIndices; ++i)
|
||||
{
|
||||
if (needle == heystack[i])
|
||||
isIn = true;
|
||||
}
|
||||
return isIn;
|
||||
}
|
||||
|
||||
|
||||
template <typename MortonPortalType,
|
||||
typename FaceIdPairsPortalType,
|
||||
typename ConnPortalType,
|
||||
typename ShapePortalType,
|
||||
typename OffsetPortalType,
|
||||
typename ExternalFaceFlagType>
|
||||
VTKM_EXEC inline void operator()(const MortonPortalType& mortonCodes,
|
||||
FaceIdPairsPortalType& faceIdPairs,
|
||||
const vtkm::Id& index,
|
||||
const ConnPortalType& connectivity,
|
||||
const ShapePortalType& shapes,
|
||||
const OffsetPortalType& offsets,
|
||||
ExternalFaceFlagType& flags) const
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vtkm::Id currentIndex = index - 1;
|
||||
BOUNDS_CHECK(mortonCodes, index);
|
||||
vtkm::UInt32 myCode = mortonCodes.Get(index);
|
||||
BOUNDS_CHECK(mortonCodes, currentIndex);
|
||||
vtkm::UInt32 myNeighbor = mortonCodes.Get(currentIndex);
|
||||
bool isInternal = false;
|
||||
vtkm::Id connectedCell = -1;
|
||||
|
||||
CellTables tables;
|
||||
while (currentIndex > -1 && myCode == myNeighbor)
|
||||
{
|
||||
myNeighbor = mortonCodes.Get(currentIndex);
|
||||
// just because the codes are equal does not mean that
|
||||
// they are the same face. We need to double check.
|
||||
if (myCode == myNeighbor)
|
||||
{
|
||||
//get the index of the shape face in the table.
|
||||
BOUNDS_CHECK(faceIdPairs, index);
|
||||
vtkm::Id cellId1 = faceIdPairs.Get(index)[0];
|
||||
BOUNDS_CHECK(faceIdPairs, currentIndex);
|
||||
vtkm::Id cellId2 = faceIdPairs.Get(currentIndex)[0];
|
||||
BOUNDS_CHECK(shapes, cellId1);
|
||||
BOUNDS_CHECK(shapes, cellId2);
|
||||
vtkm::Int32 shape1Offset =
|
||||
GetShapeOffset(shapes.Get(cellId1)) + static_cast<vtkm::Int32>(faceIdPairs.Get(index)[1]);
|
||||
vtkm::Int32 shape2Offset = GetShapeOffset(shapes.Get(cellId2)) +
|
||||
static_cast<vtkm::Int32>(faceIdPairs.Get(currentIndex)[1]);
|
||||
|
||||
const vtkm::Int32 icount1 = tables.ShapesFaceList(shape1Offset, 0);
|
||||
const vtkm::Int32 icount2 = tables.ShapesFaceList(shape2Offset, 0);
|
||||
//Check to see if we have the same number of idices
|
||||
if (icount1 != icount2)
|
||||
continue;
|
||||
|
||||
|
||||
//TODO: we can do better than this
|
||||
vtkm::Vec<vtkm::Id, 4> indices1;
|
||||
vtkm::Vec<vtkm::Id, 4> indices2;
|
||||
|
||||
const auto faceLength = tables.ShapesFaceList(shape1Offset, 0);
|
||||
for (vtkm::Int32 i = 1; i <= faceLength; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(offsets, cellId1);
|
||||
BOUNDS_CHECK(offsets, cellId2);
|
||||
BOUNDS_CHECK(connectivity,
|
||||
(offsets.Get(cellId1) + tables.ShapesFaceList(shape1Offset, i)));
|
||||
BOUNDS_CHECK(connectivity,
|
||||
(offsets.Get(cellId2) + tables.ShapesFaceList(shape2Offset, i)));
|
||||
indices1[i - 1] =
|
||||
connectivity.Get(offsets.Get(cellId1) + tables.ShapesFaceList(shape1Offset, i));
|
||||
indices2[i - 1] =
|
||||
connectivity.Get(offsets.Get(cellId2) + tables.ShapesFaceList(shape2Offset, i));
|
||||
}
|
||||
|
||||
bool isEqual = true;
|
||||
for (vtkm::Int32 i = 0; i < faceLength; ++i)
|
||||
{
|
||||
if (!IsIn(indices1[i], indices2, faceLength))
|
||||
isEqual = false;
|
||||
}
|
||||
|
||||
if (isEqual)
|
||||
{
|
||||
isInternal = true;
|
||||
|
||||
connectedCell = cellId2;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentIndex--;
|
||||
}
|
||||
|
||||
//this means that this cell is responsible for both itself and the other cell
|
||||
//set the connection for the other cell
|
||||
if (isInternal)
|
||||
{
|
||||
BOUNDS_CHECK(faceIdPairs, index);
|
||||
vtkm::Vec<vtkm::Id, 3> facePair = faceIdPairs.Get(index);
|
||||
vtkm::Id myCell = facePair[0];
|
||||
facePair[2] = connectedCell;
|
||||
BOUNDS_CHECK(faceIdPairs, index);
|
||||
faceIdPairs.Set(index, facePair);
|
||||
|
||||
BOUNDS_CHECK(faceIdPairs, currentIndex);
|
||||
facePair = faceIdPairs.Get(currentIndex);
|
||||
facePair[2] = myCell;
|
||||
BOUNDS_CHECK(faceIdPairs, currentIndex);
|
||||
faceIdPairs.Set(currentIndex, facePair);
|
||||
BOUNDS_CHECK(flags, currentIndex);
|
||||
flags.Set(currentIndex, myCell);
|
||||
BOUNDS_CHECK(flags, index);
|
||||
flags.Set(index, connectedCell);
|
||||
}
|
||||
}
|
||||
}; //class Neighbor
|
||||
|
||||
class ExternalTriangles : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
ExternalTriangles() {}
|
||||
using ControlSignature =
|
||||
void(FieldIn<>, WholeArrayIn<>, WholeArrayIn<>, WholeArrayIn<>, WholeArrayOut<>, FieldIn<>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6);
|
||||
template <typename ShapePortalType,
|
||||
typename InIndicesPortalType,
|
||||
typename OutIndicesPortalType,
|
||||
typename ShapeOffsetsPortal>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Vec<vtkm::Id, 3>& faceIdPair,
|
||||
const ShapePortalType& shapes,
|
||||
const ShapeOffsetsPortal& shapeOffsets,
|
||||
const InIndicesPortalType& indices,
|
||||
const OutIndicesPortalType& outputIndices,
|
||||
const vtkm::Id& outputOffset) const
|
||||
{
|
||||
CellTables tables;
|
||||
|
||||
vtkm::Id cellId = faceIdPair[0];
|
||||
BOUNDS_CHECK(shapeOffsets, cellId);
|
||||
vtkm::Id offset = shapeOffsets.Get(cellId);
|
||||
BOUNDS_CHECK(shapes, cellId);
|
||||
vtkm::Int32 shapeId = static_cast<vtkm::Int32>(shapes.Get(cellId));
|
||||
vtkm::Int32 shapesFaceOffset = tables.FaceLookUp(tables.CellTypeLookUp(shapeId), 0);
|
||||
if (shapesFaceOffset == -1)
|
||||
{
|
||||
printf("Unsupported Shape Type %d\n", shapeId);
|
||||
return;
|
||||
}
|
||||
|
||||
vtkm::Vec<vtkm::Id, 4> faceIndices(-1, -1, -1, -1);
|
||||
vtkm::Int32 tableIndex = static_cast<vtkm::Int32>(shapesFaceOffset + faceIdPair[1]);
|
||||
const vtkm::Int32 numIndices = tables.ShapesFaceList(tableIndex, 0);
|
||||
|
||||
for (vtkm::Int32 i = 1; i <= numIndices; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(indices, offset + tables.ShapesFaceList(tableIndex, i));
|
||||
faceIndices[i - 1] = indices.Get(offset + tables.ShapesFaceList(tableIndex, i));
|
||||
}
|
||||
vtkm::Vec<vtkm::Id, 4> triangle;
|
||||
triangle[0] = cellId;
|
||||
triangle[1] = faceIndices[0];
|
||||
triangle[2] = faceIndices[1];
|
||||
triangle[3] = faceIndices[2];
|
||||
BOUNDS_CHECK(outputIndices, outputOffset);
|
||||
outputIndices.Set(outputOffset, triangle);
|
||||
if (numIndices == 4)
|
||||
{
|
||||
triangle[1] = faceIndices[0];
|
||||
triangle[2] = faceIndices[2];
|
||||
triangle[3] = faceIndices[3];
|
||||
|
||||
BOUNDS_CHECK(outputIndices, outputOffset + 1);
|
||||
outputIndices.Set(outputOffset + 1, triangle);
|
||||
}
|
||||
}
|
||||
}; //class External Triangles
|
||||
|
||||
// Face conn was originally used for filtering out internal
|
||||
// faces and was sorted with faces. To make it usable,
|
||||
// we need to scatter back the connectivity into the original
|
||||
// cell order, i.e., conn for cell 0 at 0,1,2,3,4,5
|
||||
class WriteFaceConn : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn<>, WholeArrayIn<>, WholeArrayOut<IdType>);
|
||||
using ExecutionSignature = void(_1, _2, _3);
|
||||
|
||||
VTKM_CONT
|
||||
WriteFaceConn() {}
|
||||
|
||||
template <typename FaceOffsetsPortalType, typename FaceConnectivityPortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Vec<vtkm::Id, 3>& faceIdPair,
|
||||
const FaceOffsetsPortalType& faceOffsets,
|
||||
FaceConnectivityPortalType& faceConn) const
|
||||
{
|
||||
vtkm::Id cellId = faceIdPair[0];
|
||||
BOUNDS_CHECK(faceOffsets, cellId);
|
||||
vtkm::Id faceOffset = faceOffsets.Get(cellId) + faceIdPair[1]; // cellOffset ++ faceId
|
||||
BOUNDS_CHECK(faceConn, faceOffset);
|
||||
faceConn.Set(faceOffset, faceIdPair[2]);
|
||||
}
|
||||
}; //class WriteFaceConn
|
||||
|
||||
class StructuredExternalTriangles : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
protected:
|
||||
using ConnType = vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell,
|
||||
3>;
|
||||
ConnType Connectivity;
|
||||
vtkm::Id Segments[7];
|
||||
vtkm::Id3 CellDims;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
StructuredExternalTriangles(const ConnType& connectivity)
|
||||
: Connectivity(connectivity)
|
||||
{
|
||||
vtkm::Id3 cellDims = Connectivity.GetPointDimensions();
|
||||
cellDims[0] -= 1;
|
||||
cellDims[1] -= 1;
|
||||
cellDims[2] -= 1;
|
||||
CellDims = cellDims;
|
||||
|
||||
//We have 6 segments for each of the six faces.
|
||||
Segments[0] = 0;
|
||||
// 0-1 = the two faces parallel to the x-z plane
|
||||
Segments[1] = cellDims[0] * cellDims[2];
|
||||
Segments[2] = Segments[1] + Segments[1];
|
||||
// 2-3 parallel to the y-z plane
|
||||
Segments[3] = Segments[2] + cellDims[1] * cellDims[2];
|
||||
Segments[4] = Segments[3] + cellDims[1] * cellDims[2];
|
||||
// 4-5 parallel to the x-y plane
|
||||
Segments[5] = Segments[4] + cellDims[1] * cellDims[0];
|
||||
Segments[6] = Segments[5] + cellDims[1] * cellDims[0];
|
||||
}
|
||||
using ControlSignature = void(FieldIn<>, WholeArrayOut<>);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
template <typename TrianglePortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& index, TrianglePortalType& triangles) const
|
||||
{
|
||||
// Each one of size segments will process
|
||||
// one face of the hex and domain
|
||||
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 SegmentToFace[6] = { 0, 2, 1, 3, 4, 5 };
|
||||
|
||||
// Each face/segment has 2 varying dimensions
|
||||
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 SegmentDirections[6][2] = {
|
||||
{ 0, 2 }, //face 0 and 2 have the same directions
|
||||
{ 0, 2 }, { 1, 2 }, //1 and 3
|
||||
{ 1, 2 }, { 0, 1 }, // 4 and 5
|
||||
{ 0, 1 }
|
||||
};
|
||||
|
||||
//
|
||||
// We get one index per extenal face
|
||||
//
|
||||
|
||||
//
|
||||
// Cell face to extract which is also the domain
|
||||
// face in this segment
|
||||
//
|
||||
|
||||
vtkm::Int32 segment;
|
||||
|
||||
for (segment = 0; index >= Segments[segment + 1]; ++segment)
|
||||
;
|
||||
|
||||
if (segment >= 6)
|
||||
{
|
||||
printf("OUT OF BOUDNS %d", (int)index);
|
||||
}
|
||||
vtkm::Int32 cellFace = SegmentToFace[segment];
|
||||
|
||||
// Face relative directions of the
|
||||
// 2 varying coordinates.
|
||||
vtkm::Int32 dir1, dir2;
|
||||
dir1 = SegmentDirections[segment][0];
|
||||
dir2 = SegmentDirections[segment][1];
|
||||
|
||||
// For each face, we will have a relative offset to
|
||||
// the "bottom corner" of the face. Three are at the
|
||||
// origin and we have to adjust for the other faces.
|
||||
vtkm::Id3 cellIndex(0, 0, 0);
|
||||
if (cellFace == 1)
|
||||
cellIndex[0] = CellDims[0] - 1;
|
||||
if (cellFace == 2)
|
||||
cellIndex[1] = CellDims[1] - 1;
|
||||
if (cellFace == 5)
|
||||
cellIndex[2] = CellDims[2] - 1;
|
||||
|
||||
|
||||
// index is the global index of all external faces
|
||||
// the offset is the relative index of the cell
|
||||
// on the current 2d face
|
||||
|
||||
vtkm::Id offset = index - Segments[segment];
|
||||
vtkm::Id dir1Offset = offset % CellDims[dir1];
|
||||
vtkm::Id dir2Offset = offset / CellDims[dir1];
|
||||
|
||||
cellIndex[dir1] = cellIndex[dir1] + dir1Offset;
|
||||
cellIndex[dir2] = cellIndex[dir2] + dir2Offset;
|
||||
vtkm::Id cellId = Connectivity.LogicalToFlatToIndex(cellIndex);
|
||||
vtkm::VecVariable<vtkm::Id, 8> cellIndices = Connectivity.GetIndices(cellId);
|
||||
|
||||
// Look up the offset into the face list for each cell type
|
||||
// This should always be zero, but in case this table changes I don't
|
||||
// want to break anything.
|
||||
CellTables tables;
|
||||
vtkm::Int32 shapesFaceOffset =
|
||||
tables.FaceLookUp(tables.CellTypeLookUp(CELL_SHAPE_HEXAHEDRON), 0);
|
||||
|
||||
vtkm::Vec<vtkm::Id, 4> faceIndices;
|
||||
vtkm::Int32 tableIndex = shapesFaceOffset + cellFace;
|
||||
|
||||
// Load the face
|
||||
for (vtkm::Int32 i = 1; i <= 4; ++i)
|
||||
{
|
||||
faceIndices[i - 1] = cellIndices[tables.ShapesFaceList(tableIndex, i)];
|
||||
}
|
||||
const vtkm::Id outputOffset = index * 2;
|
||||
vtkm::Vec<vtkm::Id, 4> triangle;
|
||||
triangle[0] = cellId;
|
||||
triangle[1] = faceIndices[0];
|
||||
triangle[2] = faceIndices[1];
|
||||
triangle[3] = faceIndices[2];
|
||||
BOUNDS_CHECK(triangles, outputOffset);
|
||||
triangles.Set(outputOffset, triangle);
|
||||
triangle[1] = faceIndices[0];
|
||||
triangle[2] = faceIndices[2];
|
||||
triangle[3] = faceIndices[3];
|
||||
BOUNDS_CHECK(triangles, outputOffset);
|
||||
triangles.Set(outputOffset + 1, triangle);
|
||||
}
|
||||
}; //class StructuredExternalTriangles
|
||||
|
||||
//If with output faces or triangles, we still have to calculate the size of the output
|
||||
//array. TODO: switch to faces only
|
||||
class CountExternalTriangles : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CountExternalTriangles() {}
|
||||
using ControlSignature = void(FieldIn<>, WholeArrayIn<>, FieldOut<>);
|
||||
using ExecutionSignature = void(_1, _2, _3);
|
||||
template <typename ShapePortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Vec<vtkm::Id, 3>& faceIdPair,
|
||||
const ShapePortalType& shapes,
|
||||
vtkm::Id& triangleCount) const
|
||||
{
|
||||
CellTables tables;
|
||||
vtkm::Id cellId = faceIdPair[0];
|
||||
vtkm::Id cellFace = faceIdPair[1];
|
||||
vtkm::Int32 shapeType = static_cast<vtkm::Int32>(shapes.Get(cellId));
|
||||
vtkm::Int32 faceStartIndex = tables.FaceLookUp(tables.CellTypeLookUp(shapeType), 0);
|
||||
if (faceStartIndex == -1)
|
||||
{
|
||||
//Unsupported Shape Type this should never happen
|
||||
triangleCount = 0;
|
||||
return;
|
||||
}
|
||||
vtkm::Int32 faceType =
|
||||
tables.ShapesFaceList(faceStartIndex + static_cast<vtkm::Int32>(cellFace), 0);
|
||||
// The face will either have 4 or 3 indices, so quad or tri
|
||||
triangleCount = (faceType == 4) ? 2 : 1;
|
||||
|
||||
//faceConn.Set(faceOffset, faceIdPair[2]);
|
||||
}
|
||||
}; //class WriteFaceConn
|
||||
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class MeshConnectivityBuilder
|
||||
{
|
||||
public:
|
||||
MeshConnectivityBuilder() {}
|
||||
~MeshConnectivityBuilder() {}
|
||||
MeshConnectivityBuilder();
|
||||
~MeshConnectivityBuilder();
|
||||
|
||||
VTKM_CONT
|
||||
MeshConnContainer* BuildConnectivity(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coordinates);
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> ExternalTrianglesStructured(
|
||||
vtkm::cont::CellSetStructured<3>& cellSetStructured);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetFaceConnectivity();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetFaceOffsets();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetExternalTriangles();
|
||||
|
||||
protected:
|
||||
VTKM_CONT
|
||||
void BuildConnectivity(vtkm::cont::CellSetSingleType<>& cellSetUnstructured,
|
||||
const vtkm::cont::ArrayHandleVirtualCoordinates& coordinates,
|
||||
vtkm::Bounds coordsBounds)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("mesh_conn");
|
||||
logger->AddLogData("device", GetDeviceString(DeviceAdapter()));
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
|
||||
vtkm::Float32 BoundingBox[6];
|
||||
BoundingBox[0] = vtkm::Float32(coordsBounds.X.Min);
|
||||
BoundingBox[1] = vtkm::Float32(coordsBounds.X.Max);
|
||||
BoundingBox[2] = vtkm::Float32(coordsBounds.Y.Min);
|
||||
BoundingBox[3] = vtkm::Float32(coordsBounds.Y.Max);
|
||||
BoundingBox[4] = vtkm::Float32(coordsBounds.Z.Min);
|
||||
BoundingBox[5] = vtkm::Float32(coordsBounds.Z.Max);
|
||||
|
||||
const vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes = cellSetUnstructured.GetShapesArray(
|
||||
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id> conn = cellSetUnstructured.GetConnectivityArray(
|
||||
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
const vtkm::cont::ArrayHandleCounting<vtkm::Id> shapeOffsets =
|
||||
cellSetUnstructured.GetIndexOffsetArray(vtkm::TopologyElementTagPoint(),
|
||||
vtkm::TopologyElementTagCell());
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> faceConnectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>> cellFaceId;
|
||||
|
||||
this->GenerateFaceConnnectivity(cellSetUnstructured,
|
||||
shapes,
|
||||
conn,
|
||||
shapeOffsets,
|
||||
coordinates,
|
||||
faceConnectivity,
|
||||
cellFaceId,
|
||||
BoundingBox);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> externalTriangles;
|
||||
//Extenal Faces
|
||||
|
||||
externalTriangles =
|
||||
this->ExtractExternalFaces(cellFaceId, faceConnectivity, shapes, conn, shapeOffsets);
|
||||
|
||||
|
||||
// scatter the coonectivity into the original order
|
||||
vtkm::worklet::DispatcherMapField<WriteFaceConn> dispatcherWriteFaceConn;
|
||||
dispatcherWriteFaceConn.SetDevice(DeviceAdapter());
|
||||
dispatcherWriteFaceConn.Invoke(cellFaceId, this->FaceOffsets, faceConnectivity);
|
||||
|
||||
|
||||
FaceConnectivity = faceConnectivity;
|
||||
OutsideTriangles = externalTriangles;
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
vtkm::Bounds coordsBounds);
|
||||
|
||||
VTKM_CONT
|
||||
void BuildConnectivity(vtkm::cont::CellSetExplicit<>& cellSetUnstructured,
|
||||
const vtkm::cont::ArrayHandleVirtualCoordinates& coordinates,
|
||||
vtkm::Bounds coordsBounds)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("meah_conn");
|
||||
logger->AddLogData("device", GetDeviceString(DeviceAdapter()));
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
|
||||
vtkm::Float32 BoundingBox[6];
|
||||
BoundingBox[0] = vtkm::Float32(coordsBounds.X.Min);
|
||||
BoundingBox[1] = vtkm::Float32(coordsBounds.X.Max);
|
||||
BoundingBox[2] = vtkm::Float32(coordsBounds.Y.Min);
|
||||
BoundingBox[3] = vtkm::Float32(coordsBounds.Y.Max);
|
||||
BoundingBox[4] = vtkm::Float32(coordsBounds.Z.Min);
|
||||
BoundingBox[5] = vtkm::Float32(coordsBounds.Z.Max);
|
||||
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8> shapes = cellSetUnstructured.GetShapesArray(
|
||||
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id> conn = cellSetUnstructured.GetConnectivityArray(
|
||||
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id> shapeOffsets = cellSetUnstructured.GetIndexOffsetArray(
|
||||
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> faceConnectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>> cellFaceId;
|
||||
|
||||
this->GenerateFaceConnnectivity(cellSetUnstructured,
|
||||
shapes,
|
||||
conn,
|
||||
shapeOffsets,
|
||||
coordinates,
|
||||
faceConnectivity,
|
||||
cellFaceId,
|
||||
BoundingBox);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> externalTriangles;
|
||||
//
|
||||
//Extenal Faces
|
||||
externalTriangles =
|
||||
this->ExtractExternalFaces(cellFaceId, faceConnectivity, shapes, conn, shapeOffsets);
|
||||
|
||||
// scatter the coonectivity into the original order
|
||||
vtkm::worklet::DispatcherMapField<WriteFaceConn> dispatcher{ (WriteFaceConn{}) };
|
||||
dispatcher.SetDevice(DeviceAdapter());
|
||||
dispatcher.Invoke(cellFaceId, this->FaceOffsets, faceConnectivity);
|
||||
|
||||
FaceConnectivity = faceConnectivity;
|
||||
OutsideTriangles = externalTriangles;
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
|
||||
// Should we just make this name BuildConnectivity?
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> ExternalTrianglesStructured(
|
||||
vtkm::cont::CellSetStructured<3>& cellSetStructured)
|
||||
{
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
|
||||
vtkm::Id3 cellDims = cellSetStructured.GetCellDimensions();
|
||||
vtkm::Id numFaces =
|
||||
cellDims[0] * cellDims[1] * 2 + cellDims[1] * cellDims[2] * 2 + cellDims[2] * cellDims[0] * 2;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles;
|
||||
triangles.PrepareForOutput(numFaces * 2, DeviceAdapter());
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> counting(0, 1, numFaces);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<StructuredExternalTriangles> dispatcher(
|
||||
StructuredExternalTriangles(cellSetStructured.PrepareForInput(
|
||||
DeviceAdapter(), vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell())));
|
||||
dispatcher.SetDevice(DeviceAdapter());
|
||||
dispatcher.Invoke(counting, triangles);
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
Logger::GetInstance()->AddLogData("structured_external_faces", time);
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetFaceConnectivity() { return FaceConnectivity; }
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetFaceOffsets() { return FaceOffsets; }
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetExternalTriangles()
|
||||
{
|
||||
return OutsideTriangles;
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename CellSetType,
|
||||
typename ShapeHandleType,
|
||||
typename ConnHandleType,
|
||||
typename OffsetsHandleType>
|
||||
VTKM_CONT void GenerateFaceConnnectivity(
|
||||
const CellSetType cellSet,
|
||||
const ShapeHandleType shapes,
|
||||
const ConnHandleType conn,
|
||||
const OffsetsHandleType shapeOffsets,
|
||||
const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& faceConnectivity,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>>& cellFaceId,
|
||||
vtkm::Float32 BoundingBox[6])
|
||||
{
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
|
||||
vtkm::Id numCells = shapes.GetNumberOfValues();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> coordinates;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Copy(coords, coordinates);
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
// Count the number of total faces in the cell set
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> facesPerCell;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<CountFaces> countFacesDispatcher{ (CountFaces{}) };
|
||||
countFacesDispatcher.SetDevice(DeviceAdapter());
|
||||
countFacesDispatcher.Invoke(shapes, facesPerCell);
|
||||
|
||||
vtkm::Id totalFaces = 0;
|
||||
totalFaces =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Reduce(facesPerCell, vtkm::Id(0));
|
||||
|
||||
// Calculate the offsets so each cell knows where to insert the morton code
|
||||
// for each face
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellOffsets;
|
||||
cellOffsets.PrepareForOutput(numCells, DeviceAdapter());
|
||||
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::ScanExclusive(facesPerCell, cellOffsets);
|
||||
// cell offsets also serve as the offsets into the array that tracks connectivity.
|
||||
// For example, we have a hex with 6 faces and each face connects to another cell.
|
||||
// The connecting cells (from each face) are stored beginning at index cellOffsets[cellId]
|
||||
this->FaceOffsets = cellOffsets;
|
||||
|
||||
// We are creating a spatial hash based on morton codes calculated
|
||||
// from the centriod (point average) of each face. Each centroid is
|
||||
// calculated in way (consistent order of floating point calcs) that
|
||||
// ensures that each face maps to the same morton code. It is possbilbe
|
||||
// that two non-connecting faces map to the same morton code, but if
|
||||
// if a face has a matching face from another cell, it will be mapped
|
||||
// to the same morton code. We check for this.
|
||||
|
||||
// set up everything we need to gen morton codes
|
||||
vtkm::Vec<vtkm::Float32, 3> inverseExtent;
|
||||
inverseExtent[0] = 1.f / (BoundingBox[1] - BoundingBox[0]);
|
||||
inverseExtent[1] = 1.f / (BoundingBox[3] - BoundingBox[2]);
|
||||
inverseExtent[2] = 1.f / (BoundingBox[5] - BoundingBox[4]);
|
||||
vtkm::Vec<vtkm::Float32, 3> minPoint;
|
||||
minPoint[0] = BoundingBox[0];
|
||||
minPoint[1] = BoundingBox[2];
|
||||
minPoint[2] = BoundingBox[4];
|
||||
|
||||
// Morton Codes are created for the centroid of each face.
|
||||
// cellFaceId:
|
||||
// 0) Cell that the face belongs to
|
||||
// 1) Face of the the cell (e.g., hex will have 6 faces and this is 1 of the 6)
|
||||
// 2) cell id of the cell that connects to the corresponding face (1)
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt32> faceMortonCodes;
|
||||
cellFaceId.PrepareForOutput(totalFaces, DeviceAdapter());
|
||||
faceMortonCodes.PrepareForOutput(totalFaces, DeviceAdapter());
|
||||
vtkm::worklet::DispatcherMapTopology<MortonCodeFace> mortonCodeFaceDispatcher(
|
||||
MortonCodeFace(inverseExtent, minPoint));
|
||||
mortonCodeFaceDispatcher.SetDevice(DeviceAdapter());
|
||||
mortonCodeFaceDispatcher.Invoke(cellSet, coordinates, cellOffsets, faceMortonCodes, cellFaceId);
|
||||
|
||||
// Sort the "faces" (i.e., morton codes)
|
||||
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::SortByKey(faceMortonCodes, cellFaceId);
|
||||
|
||||
// Allocate space for the final face-to-face conectivity
|
||||
faceConnectivity.PrepareForOutput(totalFaces, DeviceAdapter());
|
||||
|
||||
// Initialize All connecting faces to -1 (connects to nothing)
|
||||
vtkm::worklet::DispatcherMapField<MemSet<vtkm::Id>> memSetDispatcher(MemSet<vtkm::Id>(-1));
|
||||
memSetDispatcher.SetDevice(DeviceAdapter());
|
||||
memSetDispatcher.Invoke(faceConnectivity);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MortonNeighbor> mortonNeighborDispatcher{ (
|
||||
MortonNeighbor{}) };
|
||||
mortonNeighborDispatcher.SetDevice(DeviceAdapter());
|
||||
mortonNeighborDispatcher.Invoke(
|
||||
faceMortonCodes, cellFaceId, conn, shapes, shapeOffsets, faceConnectivity);
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
Logger::GetInstance()->AddLogData("gen_face_conn", time);
|
||||
}
|
||||
|
||||
template <typename ShapeHandleType, typename OffsetsHandleType, typename ConnHandleType>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Vec<Id, 4>> ExtractExternalFaces(
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>>
|
||||
cellFaceId, // Map of cell, face, and connecting cell
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>
|
||||
faceConnectivity, // -1 if the face does not connect to any other face
|
||||
const ShapeHandleType& shapes,
|
||||
const ConnHandleType& conn,
|
||||
const OffsetsHandleType& shapeOffsets)
|
||||
{
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 3>> externalFacePairs;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::CopyIf(
|
||||
cellFaceId, faceConnectivity, externalFacePairs, IsExternal());
|
||||
|
||||
// We need to count the number of triangle per external face
|
||||
// If it is a single cell type and it is a tet or hex, this is a special case
|
||||
// i.e., we do not need to calculate it. TODO
|
||||
// Otherwise, we need to check to see if the face is a quad or triangle
|
||||
|
||||
vtkm::Id numExternalFaces = externalFacePairs.GetNumberOfValues();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> trianglesPerExternalFace;
|
||||
trianglesPerExternalFace.PrepareForOutput(numExternalFaces, DeviceAdapter());
|
||||
|
||||
|
||||
vtkm::worklet::DispatcherMapField<CountExternalTriangles> countExternalDispatcher{ (
|
||||
CountExternalTriangles{}) };
|
||||
countExternalDispatcher.SetDevice(DeviceAdapter());
|
||||
countExternalDispatcher.Invoke(externalFacePairs, shapes, trianglesPerExternalFace);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> externalTriangleOffsets;
|
||||
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::ScanExclusive(trianglesPerExternalFace,
|
||||
externalTriangleOffsets);
|
||||
|
||||
vtkm::Id totalExternalTriangles;
|
||||
totalExternalTriangles = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Reduce(
|
||||
trianglesPerExternalFace, vtkm::Id(0));
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> externalTriangles;
|
||||
externalTriangles.PrepareForOutput(totalExternalTriangles, DeviceAdapter());
|
||||
//count the number triangles in the external faces
|
||||
|
||||
vtkm::worklet::DispatcherMapField<ExternalTriangles> externalTriDispatcher{ (
|
||||
ExternalTriangles{}) };
|
||||
externalTriDispatcher.SetDevice(DeviceAdapter());
|
||||
externalTriDispatcher.Invoke(
|
||||
externalFacePairs, shapes, shapeOffsets, conn, externalTriangles, externalTriangleOffsets);
|
||||
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
Logger::GetInstance()->AddLogData("external_faces", time);
|
||||
return externalTriangles;
|
||||
}
|
||||
|
||||
vtkm::Bounds coordsBounds);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> FaceConnectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> FaceOffsets;
|
||||
|
@ -1,772 +0,0 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_raytracing_MeshConnectivityStructures_h
|
||||
#define vtk_m_rendering_raytracing_MeshConnectivityStructures_h
|
||||
#include <sstream>
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
{
|
||||
namespace raytracing
|
||||
{
|
||||
|
||||
// MeshConnectivityStrucutures:
|
||||
// Policy classes for different types of meshes. Each implemented class
|
||||
// Must implement GetConnetingCell( indexOfCurrentCell, face) that returns
|
||||
// the index of the cell that connects to the "face" of the current cell.
|
||||
// Each policy should have a copy constructor to facilitate clean passing
|
||||
// to worklets (i.e., initialize execution portals if needed).
|
||||
|
||||
//
|
||||
// Primary template for MeshConnExec Object
|
||||
//
|
||||
|
||||
template <typename MeshType, typename Device>
|
||||
class MeshConnExec
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
class UnstructuredMeshConn
|
||||
{
|
||||
public:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using Id4Handle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using UCharHandle = vtkm::cont::ArrayHandle<vtkm::UInt8>;
|
||||
// Control Environment Handles
|
||||
// FaceConn
|
||||
IdHandle FaceConnectivity;
|
||||
IdHandle FaceOffsets;
|
||||
//Cell Set
|
||||
IdHandle CellConn;
|
||||
IdHandle CellOffsets;
|
||||
UCharHandle Shapes;
|
||||
// Mesh Boundary
|
||||
Id4Handle ExternalTriangles;
|
||||
LinearBVH Bvh;
|
||||
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
vtkm::cont::CellSetExplicit<> Cellset;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
|
||||
protected:
|
||||
bool IsConstructed;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
UnstructuredMeshConn(){};
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
UnstructuredMeshConn(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords)
|
||||
: IsConstructed(false)
|
||||
{
|
||||
Coords = coords;
|
||||
|
||||
if (!cellset.IsSameType(vtkm::cont::CellSetExplicit<>()))
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Unstructured Mesh Connecitity Error: not an explicit cell set!");
|
||||
}
|
||||
|
||||
Cellset = cellset.Cast<vtkm::cont::CellSetExplicit<>>();
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Grab the cell arrays
|
||||
//
|
||||
CellConn =
|
||||
Cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
CellOffsets =
|
||||
Cellset.GetIndexOffsetArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
Shapes =
|
||||
Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
VTKM_CONT UnstructuredMeshConn(const T& other)
|
||||
: FaceConnectivity(other.FaceConnectivity)
|
||||
, FaceOffsets(other.FaceOffsets)
|
||||
, CellConn(other.CellConn)
|
||||
, CellOffsets(other.CellOffsets)
|
||||
, Shapes(other.Shapes)
|
||||
, ExternalTriangles(other.ExternalTriangles)
|
||||
, Bvh(other.Bvh)
|
||||
, CoordinateBounds(other.CoordinateBounds)
|
||||
, Cellset(other.Cellset)
|
||||
, Coords(other.Coords)
|
||||
, IsConstructed(other.IsConstructed)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename Device>
|
||||
VTKM_CONT void Construct(Device)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("mesh_conn_construction");
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
if (!IsConstructed)
|
||||
{
|
||||
|
||||
CoordinateBounds = Coords.GetBounds();
|
||||
MeshConnectivityBuilder<Device> connBuilder;
|
||||
|
||||
//
|
||||
// Build the face-to-face connectivity
|
||||
//
|
||||
connBuilder.BuildConnectivity(Cellset, Coords.GetData(), CoordinateBounds);
|
||||
|
||||
//
|
||||
// Initialize all of the array handles
|
||||
//
|
||||
FaceConnectivity = connBuilder.GetFaceConnectivity();
|
||||
FaceOffsets = connBuilder.GetFaceOffsets();
|
||||
ExternalTriangles = connBuilder.GetExternalTriangles();
|
||||
|
||||
//
|
||||
// Build BVH on external triangles
|
||||
//
|
||||
Bvh.SetData(Coords.GetData(), ExternalTriangles, Coords.GetBounds());
|
||||
Bvh.ConstructOnDevice(Device());
|
||||
IsConstructed = true;
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T, typename Device>
|
||||
VTKM_CONT void FindEntry(Ray<T>& rays, Device)
|
||||
{
|
||||
if (!IsConstructed)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Unstructured Mesh Connecitity Error: FindEntry called before Construct");
|
||||
}
|
||||
TriangleIntersector<Device, TriLeafIntersector<WaterTight<T>>> intersector;
|
||||
bool getCellIndex = true;
|
||||
intersector.runHitOnly(rays, Bvh, Coords.GetData(), getCellIndex);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfCells() { return this->Shapes.GetPortalConstControl().GetNumberOfValues(); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Control Environment Methods
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
Id4Handle GetExternalTriangles() { return ExternalTriangles; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordinates() { return Coords.GetData(); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename Device>
|
||||
VTKM_CONT vtkm::Bounds GetCoordinateBounds(Device)
|
||||
{
|
||||
CoordinateBounds = Coords.GetBounds();
|
||||
return CoordinateBounds;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
bool GetIsConstructed() { return IsConstructed; }
|
||||
}; //Unstructure mesh conn
|
||||
|
||||
template <typename Device>
|
||||
class MeshConnExec<UnstructuredMeshConn, Device>
|
||||
{
|
||||
protected:
|
||||
using IdHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using Id4Handle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using UCharHandle = typename vtkm::cont::ArrayHandle<vtkm::UInt8>;
|
||||
using IdConstPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using UCharConstPortal = typename UCharHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
// Constant Portals for the execution Environment
|
||||
//FaceConn
|
||||
IdConstPortal FaceConnPortal;
|
||||
IdConstPortal FaceOffsetsPortal;
|
||||
//Cell Set
|
||||
IdConstPortal CellConnPortal;
|
||||
IdConstPortal CellOffsetsPortal;
|
||||
UCharConstPortal ShapesPortal;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
MeshConnExec(){};
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MeshConnExec(UnstructuredMeshConn& conn)
|
||||
: FaceConnPortal(conn.FaceConnectivity.PrepareForInput(Device()))
|
||||
, FaceOffsetsPortal(conn.FaceOffsets.PrepareForInput(Device()))
|
||||
, CellConnPortal(conn.CellConn.PrepareForInput(Device()))
|
||||
, CellOffsetsPortal(conn.CellOffsets.PrepareForInput(Device()))
|
||||
, ShapesPortal(conn.Shapes.PrepareForInput(Device()))
|
||||
{
|
||||
if (!conn.GetIsConstructed())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Unstructured Mesh Connecitity Error: GetExecObj called before Construct");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
VTKM_CONT MeshConnExec(const T& other)
|
||||
: FaceConnPortal(other.FaceConnPortal)
|
||||
, FaceOffsetsPortal(other.FaceConnPortal)
|
||||
, CellConnPortal(other.CellConnPortal)
|
||||
, CellOffsetsPortal(other.CellOffsetsPortal)
|
||||
, ShapesPortal(other.ShapesPortal)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// Execution Environment Methods
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
inline vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
|
||||
{
|
||||
BOUNDS_CHECK(FaceOffsetsPortal, cellId);
|
||||
vtkm::Id cellStartIndex = FaceOffsetsPortal.Get(cellId);
|
||||
BOUNDS_CHECK(FaceConnPortal, cellStartIndex + face);
|
||||
return FaceConnPortal.Get(cellStartIndex + face);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const
|
||||
{
|
||||
CellTables tables;
|
||||
const vtkm::Int32 shapeId = static_cast<vtkm::Int32>(ShapesPortal.Get(cellId));
|
||||
const vtkm::Int32 numIndices = tables.FaceLookUp(tables.CellTypeLookUp(shapeId), 2);
|
||||
BOUNDS_CHECK(CellOffsetsPortal, cellId);
|
||||
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
|
||||
|
||||
for (vtkm::Int32 i = 0; i < numIndices; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(CellConnPortal, cellOffset + i);
|
||||
cellIndices[i] = CellConnPortal.Get(cellOffset + i);
|
||||
}
|
||||
return numIndices;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
inline vtkm::UInt8 GetCellShape(const vtkm::Id& cellId) const
|
||||
{
|
||||
BOUNDS_CHECK(ShapesPortal, cellId)
|
||||
return ShapesPortal.Get(cellId);
|
||||
}
|
||||
|
||||
}; //Unstructure mesh conn exec
|
||||
|
||||
|
||||
// Specialized version for unstructured meshes consisting of
|
||||
// a single type of cell.
|
||||
class UnstructuredMeshConnSingleType
|
||||
{
|
||||
public:
|
||||
using IdHandle = vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using Id4Handle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using CountingHandle = vtkm::cont::ArrayHandleCounting<vtkm::Id>;
|
||||
using ShapesHandle = vtkm::cont::ArrayHandleConstant<vtkm::UInt8>;
|
||||
using NumIndicesHandle = vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>;
|
||||
// Control Environment Handles
|
||||
IdHandle FaceConnectivity;
|
||||
CountingHandle CellOffsets;
|
||||
IdHandle CellConnectivity;
|
||||
// Mesh Boundary
|
||||
LinearBVH Bvh;
|
||||
Id4Handle ExternalTriangles;
|
||||
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
vtkm::cont::CellSetSingleType<> Cellset;
|
||||
|
||||
vtkm::Int32 ShapeId;
|
||||
vtkm::Int32 NumIndices;
|
||||
vtkm::Int32 NumFaces;
|
||||
|
||||
protected:
|
||||
bool IsConstructed;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
UnstructuredMeshConnSingleType() {}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
UnstructuredMeshConnSingleType(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords)
|
||||
: IsConstructed(false)
|
||||
{
|
||||
|
||||
Coords = coords;
|
||||
|
||||
if (!cellset.IsSameType(vtkm::cont::CellSetSingleType<>()))
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Unstructured Mesh Connecitity Single type Error: not an single type cell set!");
|
||||
}
|
||||
|
||||
Cellset = cellset.Cast<vtkm::cont::CellSetSingleType<>>();
|
||||
|
||||
CellConnectivity =
|
||||
Cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
|
||||
Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
|
||||
|
||||
CellTables tables;
|
||||
ShapeId = shapes.GetPortalConstControl().Get(0);
|
||||
NumIndices = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 2);
|
||||
|
||||
if (NumIndices == 0)
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Unstructured Mesh Connecitity Single type Error: unsupported cell type: ";
|
||||
message << ShapeId;
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
vtkm::Id start = 0;
|
||||
NumFaces = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 1);
|
||||
vtkm::Id numCells = CellConnectivity.GetPortalConstControl().GetNumberOfValues();
|
||||
CellOffsets = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(start, NumIndices, numCells);
|
||||
|
||||
//
|
||||
// Initialize all of the array portals
|
||||
//
|
||||
}
|
||||
template <typename T>
|
||||
VTKM_CONT UnstructuredMeshConnSingleType(const T& other)
|
||||
: FaceConnectivity(other.FaceConnectivity)
|
||||
, CellOffsets(other.CellOffsets)
|
||||
, CellConnectivity(other.CellConnectivity)
|
||||
, Bvh(other.Bvh)
|
||||
, ExternalTriangles(other.ExternalTriangles)
|
||||
, CoordinateBounds(other.CoordinateBounds)
|
||||
, Coords(other.coords)
|
||||
, Cellset(other.Cellset)
|
||||
, ShapeId(other.ShapeId)
|
||||
, NumIndices(other.NumIndices)
|
||||
, NumFaces(other.NumFaces)
|
||||
, IsConstructed(other.IsConstructed)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename Device>
|
||||
VTKM_CONT void Construct(Device)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("mesh_conn_construction");
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
|
||||
if (!IsConstructed)
|
||||
{
|
||||
CoordinateBounds = Coords.GetBounds();
|
||||
|
||||
MeshConnectivityBuilder<Device> connBuilder;
|
||||
|
||||
//
|
||||
// Build the face-to-face connectivity
|
||||
//
|
||||
connBuilder.BuildConnectivity(Cellset, Coords.GetData(), CoordinateBounds);
|
||||
//
|
||||
// Initialize all of the array handles
|
||||
//
|
||||
FaceConnectivity = connBuilder.GetFaceConnectivity();
|
||||
ExternalTriangles = connBuilder.GetExternalTriangles();
|
||||
|
||||
//
|
||||
// Build BVH on external triangles
|
||||
//
|
||||
Bvh.SetData(Coords.GetData(), ExternalTriangles, Coords.GetBounds());
|
||||
Bvh.ConstructOnDevice(Device());
|
||||
|
||||
IsConstructed = true;
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename T, typename Device>
|
||||
VTKM_CONT void FindEntry(Ray<T>& rays, Device)
|
||||
{
|
||||
if (!IsConstructed)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Unstructured Mesh Connecitity Single Error: FindEntry called before Construct");
|
||||
}
|
||||
TriangleIntersector<Device, TriLeafIntersector<WaterTight<T>>> intersector;
|
||||
bool getCellIndex = true;
|
||||
intersector.runHitOnly(rays, Bvh, Coords.GetData(), getCellIndex);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfCells() { return this->Cellset.GetNumberOfCells(); }
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
Id4Handle GetExternalTriangles() { return ExternalTriangles; }
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordinates() { return Coords.GetData(); }
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename Device>
|
||||
VTKM_CONT vtkm::Bounds GetCoordinateBounds(Device)
|
||||
{
|
||||
CoordinateBounds = Coords.GetBounds();
|
||||
return CoordinateBounds;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
bool GetIsConstructed() { return IsConstructed; }
|
||||
}; //UnstructuredMeshConn Single Type
|
||||
|
||||
template <typename Device>
|
||||
class MeshConnExec<UnstructuredMeshConnSingleType, Device>
|
||||
{
|
||||
protected:
|
||||
using IdHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using Id4Handle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using CountingHandle = typename vtkm::cont::ArrayHandleCounting<vtkm::Id>;
|
||||
using ShapesHandle = typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>;
|
||||
|
||||
using IdConstPortal = typename IdHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using CountingPortal = typename CountingHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using NumIndicesHandle = typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>;
|
||||
// Constant Portals for the execution Environment
|
||||
IdConstPortal FaceConnPortal;
|
||||
IdConstPortal CellConnectivityPortal;
|
||||
CountingPortal CellOffsetsPortal;
|
||||
|
||||
vtkm::Int32 ShapeId;
|
||||
vtkm::Int32 NumIndices;
|
||||
vtkm::Int32 NumFaces;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
MeshConnExec() {}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MeshConnExec(UnstructuredMeshConnSingleType& conn)
|
||||
: FaceConnPortal(conn.FaceConnectivity.PrepareForInput(Device()))
|
||||
, CellConnectivityPortal(conn.CellConnectivity.PrepareForInput(Device()))
|
||||
, CellOffsetsPortal(conn.CellOffsets.PrepareForInput(Device()))
|
||||
, ShapeId(conn.ShapeId)
|
||||
, NumIndices(conn.NumIndices)
|
||||
, NumFaces(conn.NumFaces)
|
||||
{
|
||||
if (!conn.GetIsConstructed())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Unstructured Mesh Connecitity Single Error: GetExecObj called before Construct");
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
VTKM_CONT MeshConnExec(const T& other)
|
||||
: FaceConnPortal(other.FaceConnPortal)
|
||||
, CellOffsetsPortal(other.CellOffsetsPortal)
|
||||
, CellConnectivityPortal(other.CellConnectivityPortal)
|
||||
, ShapeId(other.ShapeId)
|
||||
, NumIndices(other.NumIndices)
|
||||
, NumFaces(other.NumFaces)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// Execution Environment Methods
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
inline vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
|
||||
{
|
||||
BOUNDS_CHECK(CellOffsetsPortal, cellId);
|
||||
vtkm::Id cellStartIndex = cellId * NumFaces;
|
||||
BOUNDS_CHECK(FaceConnPortal, cellStartIndex + face);
|
||||
return FaceConnPortal.Get(cellStartIndex + face);
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const
|
||||
{
|
||||
BOUNDS_CHECK(CellOffsetsPortal, cellId);
|
||||
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
|
||||
|
||||
for (vtkm::Int32 i = 0; i < NumIndices; ++i)
|
||||
{
|
||||
BOUNDS_CHECK(CellConnectivityPortal, cellOffset + i);
|
||||
cellIndices[i] = CellConnectivityPortal.Get(cellOffset + i);
|
||||
}
|
||||
|
||||
return NumIndices;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
inline vtkm::UInt8 GetCellShape(const vtkm::Id& vtkmNotUsed(cellId)) const
|
||||
{
|
||||
return vtkm::UInt8(ShapeId);
|
||||
}
|
||||
|
||||
}; //MeshConn Single type specialization
|
||||
|
||||
class StructuredMeshConn
|
||||
{
|
||||
public:
|
||||
using Id4Handle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
vtkm::Id3 CellDims;
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
vtkm::cont::CoordinateSystem Coords;
|
||||
vtkm::cont::CellSetStructured<3> Cellset;
|
||||
// Mesh Boundary
|
||||
LinearBVH Bvh;
|
||||
Id4Handle ExternalTriangles;
|
||||
|
||||
protected:
|
||||
bool IsConstructed;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
StructuredMeshConn() {}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
StructuredMeshConn(const vtkm::cont::DynamicCellSet& cellset,
|
||||
const vtkm::cont::CoordinateSystem& coords)
|
||||
: IsConstructed(false)
|
||||
{
|
||||
Coords = coords;
|
||||
|
||||
if (!cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Structured Mesh Connecitity Error: not a Structured<3> cell set!");
|
||||
}
|
||||
|
||||
Cellset = cellset.Cast<vtkm::cont::CellSetStructured<3>>();
|
||||
PointDims = Cellset.GetPointDimensions();
|
||||
CellDims = Cellset.GetCellDimensions();
|
||||
}
|
||||
template <typename T>
|
||||
VTKM_CONT StructuredMeshConn(const T& other)
|
||||
: CellDims(other.CellDims)
|
||||
, PointDims(other.PointDims)
|
||||
, CoordinateBounds(other.CoordinateBounds)
|
||||
, Coords(other.coords)
|
||||
, Cellset(other.Cellset)
|
||||
, Bvh(other.Bvh)
|
||||
, ExternalTriangles(other.ExternalTriangles)
|
||||
, IsConstructed(other.IsConstructed)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename Device>
|
||||
VTKM_CONT void Construct(Device)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("mesh_conn_construction");
|
||||
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
|
||||
if (!IsConstructed)
|
||||
{
|
||||
CoordinateBounds = Coords.GetBounds();
|
||||
|
||||
MeshConnectivityBuilder<Device> connBuilder;
|
||||
ExternalTriangles = connBuilder.ExternalTrianglesStructured(Cellset);
|
||||
|
||||
//
|
||||
// Build BVH on external triangles
|
||||
//
|
||||
Bvh.SetData(Coords.GetData(), ExternalTriangles, Coords.GetBounds());
|
||||
Bvh.ConstructOnDevice(Device());
|
||||
IsConstructed = true;
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T, typename Device>
|
||||
VTKM_CONT void FindEntry(Ray<T>& rays, Device)
|
||||
{
|
||||
if (!IsConstructed)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Structured Mesh Connecitity Single Error: FindEntry called before Construct");
|
||||
}
|
||||
TriangleIntersector<Device, TriLeafIntersector<WaterTight<T>>> intersector;
|
||||
bool getCellIndex = true;
|
||||
intersector.runHitOnly(rays, Bvh, Coords.GetData(), getCellIndex);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfCells() { return this->CellDims[0] * this->CellDims[1] * this->CellDims[2]; }
|
||||
//----------------------------------------------------------------------------
|
||||
// Control Environment Methods
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
Id4Handle GetExternalTriangles() { return ExternalTriangles; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordinates() { return Coords.GetData(); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename Device>
|
||||
VTKM_CONT vtkm::Bounds GetCoordinateBounds(Device)
|
||||
{
|
||||
CoordinateBounds = Coords.GetBounds();
|
||||
return CoordinateBounds;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
bool GetIsConstructed() { return IsConstructed; }
|
||||
}; //structure mesh conn
|
||||
|
||||
template <typename Device>
|
||||
class MeshConnExec<StructuredMeshConn, Device>
|
||||
{
|
||||
protected:
|
||||
using Id4Handle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
vtkm::Id3 CellDims;
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Bounds CoordinateBounds;
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
MeshConnExec() {}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MeshConnExec(const StructuredMeshConn& other)
|
||||
: CellDims(other.CellDims)
|
||||
, PointDims(other.PointDims)
|
||||
, CoordinateBounds(other.CoordinateBounds)
|
||||
{
|
||||
}
|
||||
template <typename T>
|
||||
VTKM_CONT MeshConnExec(const T& other)
|
||||
: CellDims(other.CellDims)
|
||||
, PointDims(other.PointDims)
|
||||
, CoordinateBounds(other.CoordinateBounds)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// Execution Environment Methods
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
|
||||
{
|
||||
//TODO: there is probably a better way to do this.
|
||||
vtkm::Id3 logicalCellId;
|
||||
logicalCellId[0] = cellId % CellDims[0];
|
||||
logicalCellId[1] = (cellId / CellDims[0]) % CellDims[1];
|
||||
logicalCellId[2] = cellId / (CellDims[0] * CellDims[1]);
|
||||
if (face == 0)
|
||||
logicalCellId[1] -= 1;
|
||||
if (face == 2)
|
||||
logicalCellId[1] += 1;
|
||||
if (face == 1)
|
||||
logicalCellId[0] += 1;
|
||||
if (face == 3)
|
||||
logicalCellId[0] -= 1;
|
||||
if (face == 4)
|
||||
logicalCellId[2] -= 1;
|
||||
if (face == 5)
|
||||
logicalCellId[2] += 1;
|
||||
vtkm::Id nextCell =
|
||||
(logicalCellId[2] * CellDims[1] + logicalCellId[1]) * CellDims[0] + logicalCellId[0];
|
||||
bool validCell = true;
|
||||
if (logicalCellId[0] >= CellDims[0])
|
||||
validCell = false;
|
||||
if (logicalCellId[1] >= CellDims[1])
|
||||
validCell = false;
|
||||
if (logicalCellId[2] >= CellDims[2])
|
||||
validCell = false;
|
||||
vtkm::Id minId = vtkm::Min(logicalCellId[0], vtkm::Min(logicalCellId[1], logicalCellId[2]));
|
||||
if (minId < 0)
|
||||
validCell = false;
|
||||
if (!validCell)
|
||||
nextCell = -1;
|
||||
return nextCell;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellIndex) const
|
||||
{
|
||||
|
||||
vtkm::Id3 cellId;
|
||||
cellId[0] = cellIndex % CellDims[0];
|
||||
cellId[1] = (cellIndex / CellDims[0]) % CellDims[1];
|
||||
cellId[2] = cellIndex / (CellDims[0] * CellDims[1]);
|
||||
cellIndices[0] = (cellId[2] * PointDims[1] + cellId[1]) * PointDims[0] + cellId[0];
|
||||
cellIndices[1] = cellIndices[0] + 1;
|
||||
cellIndices[2] = cellIndices[1] + PointDims[0];
|
||||
cellIndices[3] = cellIndices[2] - 1;
|
||||
cellIndices[4] = cellIndices[0] + PointDims[0] * PointDims[1];
|
||||
cellIndices[5] = cellIndices[4] + 1;
|
||||
cellIndices[6] = cellIndices[5] + PointDims[0];
|
||||
cellIndices[7] = cellIndices[6] - 1;
|
||||
return 8;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8],
|
||||
const vtkm::Vec<vtkm::Id, 3>& cellId) const
|
||||
{
|
||||
|
||||
cellIndices[0] = (cellId[2] * PointDims[1] + cellId[1]) * PointDims[0] + cellId[0];
|
||||
cellIndices[1] = cellIndices[0] + 1;
|
||||
cellIndices[2] = cellIndices[1] + PointDims[0];
|
||||
cellIndices[3] = cellIndices[2] - 1;
|
||||
cellIndices[4] = cellIndices[0] + PointDims[0] * PointDims[1];
|
||||
cellIndices[5] = cellIndices[4] + 1;
|
||||
cellIndices[6] = cellIndices[5] + PointDims[0];
|
||||
cellIndices[7] = cellIndices[6] - 1;
|
||||
return 8;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VTKM_EXEC
|
||||
inline vtkm::UInt8 GetCellShape(const vtkm::Id& vtkmNotUsed(cellId)) const
|
||||
{
|
||||
return vtkm::UInt8(CELL_SHAPE_HEXAHEDRON);
|
||||
}
|
||||
}; //Unstructure mesh conn
|
||||
}
|
||||
}
|
||||
} //namespace vtkm::rendering::raytracing
|
||||
#endif
|
@ -25,6 +25,7 @@
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/CellTables.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
|
@ -129,6 +129,20 @@ public:
|
||||
DebugHeight = -1;
|
||||
}
|
||||
|
||||
|
||||
struct EnableIntersectionDataFunctor
|
||||
{
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device, Ray<Precision>* self)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->EnableIntersectionData(Device());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void EnableIntersectionData() { vtkm::cont::TryExecute(EnableIntersectionDataFunctor(), this); }
|
||||
|
||||
template <typename Device>
|
||||
void EnableIntersectionData(Device)
|
||||
{
|
||||
@ -185,11 +199,18 @@ public:
|
||||
this->Resize(size, Device());
|
||||
}
|
||||
|
||||
|
||||
VTKM_CONT void Resize(const vtkm::Int32 size)
|
||||
struct ResizeFunctor
|
||||
{
|
||||
this->Resize(size, vtkm::cont::DeviceAdapterTagSerial());
|
||||
}
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device, Ray<Precision>* self, const vtkm::Int32 size)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
self->Resize(size, Device());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
VTKM_CONT void Resize(const vtkm::Int32 size) { vtkm::cont::TryExecute(ResizeFunctor(), size); }
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void Resize(const vtkm::Int32 size, Device)
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define vtk_m_rendering_raytracing_Ray_Operations_h
|
||||
|
||||
#include <vtkm/Matrix.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
#include <vtkm/rendering/Camera.h>
|
||||
#include <vtkm/rendering/CanvasRayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/ChannelBufferOperations.h>
|
||||
@ -117,10 +116,8 @@ public:
|
||||
template <typename Device, typename T>
|
||||
static void ResetStatus(Ray<T>& rays, vtkm::UInt8 status, Device)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<MemSet<vtkm::UInt8>> dispatcher(
|
||||
(MemSet<vtkm::UInt8>(status)));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(rays.Status);
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> statusHandle(status, rays.NumRays);
|
||||
vtkm::cont::Algorithm::Copy(Device(), statusHandle, rays.Status);
|
||||
}
|
||||
|
||||
//
|
||||
@ -137,6 +134,14 @@ public:
|
||||
dispatcher.Invoke(rays.HitIdx, rays.Status);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void UpdateRayStatus(Ray<T>& rays)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<detail::RayStatusFilter> dispatcher{ (
|
||||
detail::RayStatusFilter{}) };
|
||||
dispatcher.Invoke(rays.HitIdx, rays.Status);
|
||||
}
|
||||
|
||||
static void MapCanvasToRays(Ray<vtkm::Float32>& rays,
|
||||
const vtkm::rendering::Camera& camera,
|
||||
const vtkm::rendering::CanvasRayTracer& canvas);
|
||||
|
@ -25,13 +25,10 @@
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/ColorTable.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -44,237 +41,12 @@ namespace raytracing
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class IntersectionPoint : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
IntersectionPoint() {}
|
||||
using ControlSignature =
|
||||
void(FieldIn<>, FieldIn<>, FieldIn<>, FieldIn<>, FieldOut<>, FieldOut<>, FieldOut<>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7);
|
||||
template <typename Precision>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& hitIndex,
|
||||
const Precision& distance,
|
||||
const vtkm::Vec<Precision, 3>& rayDir,
|
||||
const vtkm::Vec<Precision, 3>& rayOrigin,
|
||||
Precision& intersectionX,
|
||||
Precision& intersectionY,
|
||||
Precision& intersectionZ) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
intersectionX = rayOrigin[0] + rayDir[0] * distance;
|
||||
intersectionY = rayOrigin[1] + rayDir[1] * distance;
|
||||
intersectionZ = rayOrigin[2] + rayDir[2] * distance;
|
||||
}
|
||||
}; //class IntersectionPoint
|
||||
|
||||
template <typename Device>
|
||||
class IntersectionData
|
||||
{
|
||||
public:
|
||||
// Worklet to calutate the normals of a triagle if
|
||||
// none are stored in the data set
|
||||
class CalculateNormals : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using Vec4IntArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>;
|
||||
using IndicesArrayPortal = typename Vec4IntArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
IndicesArrayPortal IndicesPortal;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
CalculateNormals(const Vec4IntArrayHandle& indices)
|
||||
: IndicesPortal(indices.PrepareForInput(Device()))
|
||||
{
|
||||
}
|
||||
using ControlSignature = void(FieldIn<>,
|
||||
FieldIn<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
WholeArrayIn<Vec3RenderingTypes>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6);
|
||||
template <typename Precision, typename PointPortalType>
|
||||
VTKM_EXEC inline void operator()(const vtkm::Id& hitIndex,
|
||||
const vtkm::Vec<Precision, 3>& rayDir,
|
||||
Precision& normalX,
|
||||
Precision& normalY,
|
||||
Precision& normalZ,
|
||||
const PointPortalType& points) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Vec<Int32, 4> indices = IndicesPortal.Get(hitIndex);
|
||||
vtkm::Vec<Precision, 3> a = points.Get(indices[1]);
|
||||
vtkm::Vec<Precision, 3> b = points.Get(indices[2]);
|
||||
vtkm::Vec<Precision, 3> c = points.Get(indices[3]);
|
||||
|
||||
vtkm::Vec<Precision, 3> normal = vtkm::TriangleNormal(a, b, c);
|
||||
vtkm::Normalize(normal);
|
||||
|
||||
//flip the normal if its pointing the wrong way
|
||||
if (vtkm::Dot(normal, rayDir) > 0.f)
|
||||
normal = -normal;
|
||||
normalX = normal[0];
|
||||
normalY = normal[1];
|
||||
normalZ = normal[2];
|
||||
}
|
||||
}; //class CalculateNormals
|
||||
|
||||
template <typename Precision>
|
||||
class LerpScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using Vec4IntArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>;
|
||||
using IndicesArrayPortal = typename Vec4IntArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
IndicesArrayPortal IndicesPortal;
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
LerpScalar(const Vec4IntArrayHandle& indices,
|
||||
const vtkm::Float32& minScalar,
|
||||
const vtkm::Float32& maxScalar)
|
||||
: IndicesPortal(indices.PrepareForInput(Device()))
|
||||
, MinScalar(minScalar)
|
||||
{
|
||||
//Make sure the we don't divide by zero on
|
||||
//something like an iso-surface
|
||||
if (maxScalar - MinScalar != 0.f)
|
||||
invDeltaScalar = 1.f / (maxScalar - MinScalar);
|
||||
else
|
||||
invDeltaScalar = 1.f / minScalar;
|
||||
}
|
||||
using ControlSignature =
|
||||
void(FieldIn<>, FieldIn<>, FieldIn<>, FieldOut<>, WholeArrayIn<ScalarRenderingTypes>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5);
|
||||
template <typename ScalarPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
||||
const Precision& u,
|
||||
const Precision& v,
|
||||
Precision& lerpedScalar,
|
||||
const ScalarPortalType& scalars) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Vec<Int32, 4> indices = IndicesPortal.Get(hitIndex);
|
||||
|
||||
Precision n = 1.f - u - v;
|
||||
Precision aScalar = Precision(scalars.Get(indices[1]));
|
||||
Precision bScalar = Precision(scalars.Get(indices[2]));
|
||||
Precision cScalar = Precision(scalars.Get(indices[3]));
|
||||
lerpedScalar = aScalar * n + bScalar * u + cScalar * v;
|
||||
//normalize
|
||||
lerpedScalar = (lerpedScalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class LerpScalar
|
||||
|
||||
template <typename Precision>
|
||||
class NodalScalar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using Vec4IntArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>;
|
||||
using IndicesArrayPortal = typename Vec4IntArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
IndicesArrayPortal IndicesPortal;
|
||||
Precision MinScalar;
|
||||
Precision invDeltaScalar;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
NodalScalar(const Vec4IntArrayHandle& indices,
|
||||
const vtkm::Float32& minScalar,
|
||||
const vtkm::Float32& maxScalar)
|
||||
: IndicesPortal(indices.PrepareForInput(Device()))
|
||||
, MinScalar(minScalar)
|
||||
{
|
||||
//Make sure the we don't divide by zero on
|
||||
//something like an iso-surface
|
||||
if (maxScalar - MinScalar != 0.f)
|
||||
invDeltaScalar = 1.f / (maxScalar - MinScalar);
|
||||
else
|
||||
invDeltaScalar = 1.f / minScalar;
|
||||
}
|
||||
|
||||
using ControlSignature = void(FieldIn<>, FieldOut<>, WholeArrayIn<ScalarRenderingTypes>);
|
||||
|
||||
using ExecutionSignature = void(_1, _2, _3);
|
||||
template <typename ScalarPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
|
||||
Precision& scalar,
|
||||
const ScalarPortalType& scalars) const
|
||||
{
|
||||
if (hitIndex < 0)
|
||||
return;
|
||||
|
||||
vtkm::Vec<Int32, 4> indices = IndicesPortal.Get(hitIndex);
|
||||
|
||||
//Todo: one normalization
|
||||
scalar = Precision(scalars.Get(indices[0]));
|
||||
|
||||
//normalize
|
||||
scalar = (scalar - MinScalar) * invDeltaScalar;
|
||||
}
|
||||
}; //class LerpScalar
|
||||
template <typename Precision>
|
||||
VTKM_CONT void run(Ray<Precision>& rays,
|
||||
LinearBVH& bvh,
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates& coordsHandle,
|
||||
const vtkm::cont::Field& scalarField,
|
||||
const vtkm::Range& scalarRange)
|
||||
{
|
||||
bool isSupportedField =
|
||||
(scalarField.GetAssociation() == vtkm::cont::Field::Association::POINTS ||
|
||||
scalarField.GetAssociation() == vtkm::cont::Field::Association::CELL_SET);
|
||||
if (!isSupportedField)
|
||||
throw vtkm::cont::ErrorBadValue("Field not accociated with cell set or points");
|
||||
bool isAssocPoints = scalarField.GetAssociation() == vtkm::cont::Field::Association::POINTS;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<CalculateNormals> calcNormalsDispatcher(
|
||||
CalculateNormals(bvh.LeafNodes));
|
||||
calcNormalsDispatcher.SetDevice(Device());
|
||||
calcNormalsDispatcher.Invoke(
|
||||
rays.HitIdx, rays.Dir, rays.NormalX, rays.NormalY, rays.NormalZ, coordsHandle);
|
||||
|
||||
if (isAssocPoints)
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<LerpScalar<Precision>> lerpScalarDispatcher(
|
||||
LerpScalar<Precision>(
|
||||
bvh.LeafNodes, vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)));
|
||||
lerpScalarDispatcher.SetDevice(Device());
|
||||
lerpScalarDispatcher.Invoke(rays.HitIdx, rays.U, rays.V, rays.Scalar, scalarField);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<NodalScalar<Precision>> nodalScalarDispatcher(
|
||||
NodalScalar<Precision>(
|
||||
bvh.LeafNodes, vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)));
|
||||
nodalScalarDispatcher.SetDevice(Device());
|
||||
nodalScalarDispatcher.Invoke(rays.HitIdx, rays.Scalar, scalarField);
|
||||
}
|
||||
} // Run
|
||||
|
||||
}; // Class IntersectionData
|
||||
|
||||
template <typename Device>
|
||||
class SurfaceColor
|
||||
{
|
||||
public:
|
||||
class MapScalarToColor : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using ColorArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||
using ColorArrayPortal = typename ColorArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
ColorArrayPortal ColorMap;
|
||||
vtkm::Int32 ColorMapSize;
|
||||
vtkm::Vec<vtkm::Float32, 3> LightPosition;
|
||||
vtkm::Vec<vtkm::Float32, 3> LightAbmient;
|
||||
vtkm::Vec<vtkm::Float32, 3> LightDiffuse;
|
||||
@ -285,14 +57,10 @@ public:
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
MapScalarToColor(const ColorArrayHandle& colorMap,
|
||||
const vtkm::Int32& colorMapSize,
|
||||
const vtkm::Vec<vtkm::Float32, 3>& lightPosition,
|
||||
MapScalarToColor(const vtkm::Vec<vtkm::Float32, 3>& lightPosition,
|
||||
const vtkm::Vec<vtkm::Float32, 3>& cameraPosition,
|
||||
const vtkm::Vec<vtkm::Float32, 3>& lookAt)
|
||||
: ColorMap(colorMap.PrepareForInput(Device()))
|
||||
, ColorMapSize(colorMapSize)
|
||||
, LightPosition(lightPosition)
|
||||
: LightPosition(lightPosition)
|
||||
, CameraPosition(cameraPosition)
|
||||
, LookAt(lookAt)
|
||||
{
|
||||
@ -308,14 +76,18 @@ public:
|
||||
LightSpecular[2] = .7f;
|
||||
SpecularExponent = 20.f;
|
||||
}
|
||||
using ControlSignature = void(FieldIn<>, FieldIn<>, FieldIn<>, FieldIn<>, WholeArrayInOut<>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, WorkIndex);
|
||||
template <typename ColorPortalType, typename Precision>
|
||||
|
||||
using ControlSignature =
|
||||
void(FieldIn<>, FieldIn<>, FieldIn<>, FieldIn<>, WholeArrayInOut<>, WholeArrayIn<>);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, WorkIndex);
|
||||
|
||||
template <typename ColorPortalType, typename Precision, typename ColorMapPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hitIdx,
|
||||
const Precision& scalar,
|
||||
const vtkm::Vec<Precision, 3>& normal,
|
||||
const vtkm::Vec<Precision, 3>& intersection,
|
||||
ColorPortalType& colors,
|
||||
ColorMapPortalType colorMap,
|
||||
const vtkm::Id& idx) const
|
||||
{
|
||||
vtkm::Vec<Precision, 4> color;
|
||||
@ -336,23 +108,23 @@ public:
|
||||
vtkm::Normalize(lightDir);
|
||||
vtkm::Normalize(viewDir);
|
||||
//Diffuse lighting
|
||||
Precision cosTheta = vtkm::Dot(normal, lightDir);
|
||||
Precision cosTheta = vtkm::dot(normal, lightDir);
|
||||
//clamp tp [0,1]
|
||||
const Precision zero = 0.f;
|
||||
const Precision one = 1.f;
|
||||
cosTheta = vtkm::Min(vtkm::Max(cosTheta, zero), one);
|
||||
//Specular lighting
|
||||
vtkm::Vec<Precision, 3> reflect = 2.f * vtkm::Dot(lightDir, normal) * normal - lightDir;
|
||||
vtkm::Vec<Precision, 3> reflect = 2.f * vtkm::dot(lightDir, normal) * normal - lightDir;
|
||||
vtkm::Normalize(reflect);
|
||||
Precision cosPhi = vtkm::Dot(reflect, viewDir);
|
||||
Precision specularConstant =
|
||||
Precision(pow(vtkm::Max(cosPhi, zero), (Precision)SpecularExponent));
|
||||
vtkm::Int32 colorIdx = vtkm::Int32(scalar * Precision(ColorMapSize - 1));
|
||||
Precision cosPhi = vtkm::dot(reflect, viewDir);
|
||||
Precision specularConstant = Precision(pow(vtkm::Max(cosPhi, zero), SpecularExponent));
|
||||
vtkm::Int32 colorMapSize = static_cast<vtkm::Int32>(colorMap.GetNumberOfValues());
|
||||
vtkm::Int32 colorIdx = vtkm::Int32(scalar * Precision(colorMapSize - 1));
|
||||
|
||||
//Just in case clamp the value to the valid range
|
||||
colorIdx = (colorIdx < 0) ? 0 : colorIdx;
|
||||
colorIdx = (colorIdx > ColorMapSize - 1) ? ColorMapSize - 1 : colorIdx;
|
||||
color = ColorMap.Get(colorIdx);
|
||||
// clamp color index
|
||||
colorIdx = vtkm::Max(0, colorIdx);
|
||||
colorIdx = vtkm::Min(colorMapSize - 1, colorIdx);
|
||||
color = colorMap.Get(colorIdx);
|
||||
|
||||
color[0] *= vtkm::Min(
|
||||
LightAbmient[0] + LightDiffuse[0] * cosTheta + LightSpecular[0] * specularConstant, one);
|
||||
@ -377,144 +149,116 @@ public:
|
||||
// TODO: support light positions
|
||||
vtkm::Vec<vtkm::Float32, 3> scale(2, 2, 2);
|
||||
vtkm::Vec<vtkm::Float32, 3> lightPosition = camera.GetPosition() + scale * camera.GetUp();
|
||||
const vtkm::Int32 colorMapSize = vtkm::Int32(colorMap.GetNumberOfValues());
|
||||
vtkm::worklet::DispatcherMapField<MapScalarToColor> dispatcher(MapScalarToColor(
|
||||
colorMap, colorMapSize, lightPosition, camera.GetPosition(), camera.GetLookAt()));
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(
|
||||
rays.HitIdx, rays.Scalar, rays.Normal, rays.Intersection, rays.Buffers.at(0).Buffer);
|
||||
vtkm::worklet::DispatcherMapField<MapScalarToColor>(
|
||||
MapScalarToColor(lightPosition, camera.GetPosition(), camera.GetLookAt()))
|
||||
.Invoke(rays.HitIdx,
|
||||
rays.Scalar,
|
||||
rays.Normal,
|
||||
rays.Intersection,
|
||||
rays.Buffers.at(0).Buffer,
|
||||
colorMap);
|
||||
}
|
||||
}; // class SurfaceColor
|
||||
|
||||
} // namespace detail
|
||||
|
||||
RayTracer::RayTracer()
|
||||
: NumberOfShapes(0)
|
||||
{
|
||||
}
|
||||
|
||||
RayTracer::~RayTracer()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
Camera& RayTracer::GetCamera()
|
||||
{
|
||||
return camera;
|
||||
}
|
||||
|
||||
void RayTracer::SetData(const vtkm::cont::ArrayHandleVirtualCoordinates& coordsHandle,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& indices,
|
||||
vtkm::cont::Field& scalarField,
|
||||
const vtkm::Id& numberOfTriangles,
|
||||
const vtkm::Range& scalarRange,
|
||||
const vtkm::Bounds& dataBounds)
|
||||
|
||||
void RayTracer::AddShapeIntersector(ShapeIntersector* intersector)
|
||||
{
|
||||
CoordsHandle = coordsHandle;
|
||||
Indices = indices;
|
||||
ScalarField = scalarField;
|
||||
NumberOfTriangles = numberOfTriangles;
|
||||
ScalarRange = scalarRange;
|
||||
DataBounds = dataBounds;
|
||||
Bvh.SetData(coordsHandle, indices, DataBounds);
|
||||
NumberOfShapes += intersector->GetNumberOfShapes();
|
||||
Intersectors.push_back(intersector);
|
||||
}
|
||||
|
||||
void RayTracer::SetField(const vtkm::cont::Field& scalarField, const vtkm::Range& scalarRange)
|
||||
{
|
||||
ScalarField = &scalarField;
|
||||
ScalarRange = scalarRange;
|
||||
}
|
||||
|
||||
void RayTracer::SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap)
|
||||
{
|
||||
ColorMap = colorMap;
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
struct RayTracer::RenderFunctor
|
||||
{
|
||||
protected:
|
||||
vtkm::rendering::raytracing::RayTracer* Self;
|
||||
vtkm::rendering::raytracing::Ray<Precision>& Rays;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
RenderFunctor(vtkm::rendering::raytracing::RayTracer* self,
|
||||
vtkm::rendering::raytracing::Ray<Precision>& rays)
|
||||
: Self(self)
|
||||
, Rays(rays)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
|
||||
this->Self->RenderOnDevice(this->Rays, Device());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void RayTracer::Render(Ray<vtkm::Float32>& rays)
|
||||
{
|
||||
RenderFunctor<vtkm::Float32> functor(this, rays);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
}
|
||||
void
|
||||
|
||||
RayTracer::Render(Ray<vtkm::Float64> &rays)
|
||||
{
|
||||
RenderFunctor<vtkm::Float64> functor(this, rays);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
RenderOnDevice(rays);
|
||||
}
|
||||
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void RayTracer::RenderOnDevice(Ray<Precision>& rays, Device)
|
||||
void RayTracer::Render(Ray<vtkm::Float64>& rays)
|
||||
{
|
||||
rays.EnableIntersectionData(Device());
|
||||
RenderOnDevice(rays);
|
||||
}
|
||||
|
||||
vtkm::Id RayTracer::GetNumberOfShapes() const
|
||||
{
|
||||
return NumberOfShapes;
|
||||
}
|
||||
|
||||
void RayTracer::Clear()
|
||||
{
|
||||
size_t numShapes = Intersectors.size();
|
||||
for (size_t i = 0; i < numShapes; ++i)
|
||||
{
|
||||
delete Intersectors[i];
|
||||
}
|
||||
|
||||
Intersectors.clear();
|
||||
}
|
||||
|
||||
template <typename Precision>
|
||||
void RayTracer::RenderOnDevice(Ray<Precision>& rays)
|
||||
{
|
||||
using Timer = vtkm::cont::Timer<vtkm::cont::DeviceAdapterTagSerial>;
|
||||
|
||||
Logger* logger = Logger::GetInstance();
|
||||
vtkm::cont::Timer<Device> renderTimer;
|
||||
Timer renderTimer;
|
||||
vtkm::Float64 time = 0.;
|
||||
logger->OpenLogEntry("ray_tracer");
|
||||
logger->AddLogData("device", GetDeviceString(Device()));
|
||||
logger->AddLogData("device", GetDeviceString());
|
||||
|
||||
Bvh.ConstructOnDevice(Device());
|
||||
logger->AddLogData("triangles", NumberOfTriangles);
|
||||
logger->AddLogData("shapes", NumberOfShapes);
|
||||
logger->AddLogData("num_rays", rays.NumRays);
|
||||
|
||||
if (NumberOfTriangles > 0)
|
||||
size_t numShapes = Intersectors.size();
|
||||
if (NumberOfShapes > 0)
|
||||
{
|
||||
vtkm::cont::Timer<Device> timer;
|
||||
// Find distance to intersection
|
||||
TriangleIntersector<Device, TriLeafIntersector<Moller>> intersector;
|
||||
intersector.run(rays, Bvh, CoordsHandle);
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("intersect", time);
|
||||
timer.Reset();
|
||||
Timer timer;
|
||||
|
||||
// Calculate normal and scalar value (TODO: find a better name)
|
||||
detail::IntersectionData<Device> intData;
|
||||
intData.run(rays, Bvh, CoordsHandle, ScalarField, ScalarRange);
|
||||
for (size_t i = 0; i < numShapes; ++i)
|
||||
{
|
||||
Intersectors[i]->IntersectRays(rays);
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("intersect", time);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("intersection_data", time);
|
||||
timer.Reset();
|
||||
timer.Reset();
|
||||
Intersectors[i]->IntersectionData(rays, ScalarField, ScalarRange);
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("intersection_data", time);
|
||||
timer.Reset();
|
||||
|
||||
// Find the intersection point from hit distance
|
||||
vtkm::worklet::DispatcherMapField<detail::IntersectionPoint> intersectionPointDispatcher{ (
|
||||
detail::IntersectionPoint{}) };
|
||||
intersectionPointDispatcher.SetDevice(Device());
|
||||
intersectionPointDispatcher.Invoke(rays.HitIdx,
|
||||
rays.Distance,
|
||||
rays.Dir,
|
||||
rays.Origin,
|
||||
rays.IntersectionX,
|
||||
rays.IntersectionY,
|
||||
rays.IntersectionZ);
|
||||
// Calculate the color at the intersection point
|
||||
detail::SurfaceColor surfaceColor;
|
||||
surfaceColor.run(rays, ColorMap, camera);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("find_point", time);
|
||||
timer.Reset();
|
||||
|
||||
// Calculate the color at the intersection point
|
||||
detail::SurfaceColor<Device> surfaceColor;
|
||||
surfaceColor.run(rays, ColorMap, camera);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("shade", time);
|
||||
timer.Reset();
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("shade", time);
|
||||
timer.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
time = renderTimer.GetElapsedTime();
|
||||
|
@ -20,11 +20,12 @@
|
||||
#ifndef vtk_m_rendering_raytracing_RayTracer_h
|
||||
#define vtk_m_rendering_raytracing_RayTracer_h
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
|
||||
#include <vtkm/rendering/raytracing/Camera.h>
|
||||
|
||||
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
|
||||
namespace vtkm
|
||||
{
|
||||
namespace rendering
|
||||
@ -35,43 +36,47 @@ namespace raytracing
|
||||
class VTKM_RENDERING_EXPORT RayTracer
|
||||
{
|
||||
protected:
|
||||
LinearBVH Bvh;
|
||||
std::vector<ShapeIntersector*> Intersectors;
|
||||
Camera camera;
|
||||
vtkm::cont::ArrayHandleVirtualCoordinates CoordsHandle;
|
||||
vtkm::cont::Field ScalarField;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Indices;
|
||||
const vtkm::cont::Field* ScalarField;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> Scalars;
|
||||
vtkm::Id NumberOfTriangles;
|
||||
vtkm::Id NumberOfShapes;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>> ColorMap;
|
||||
vtkm::Range ScalarRange;
|
||||
vtkm::Bounds DataBounds;
|
||||
template <typename Precision>
|
||||
struct RenderFunctor;
|
||||
|
||||
template <typename Device, typename Precision>
|
||||
void RenderOnDevice(Ray<Precision>& rays, Device);
|
||||
template <typename Precision>
|
||||
void RenderOnDevice(Ray<Precision>& rays);
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
RayTracer();
|
||||
VTKM_CONT
|
||||
~RayTracer();
|
||||
|
||||
VTKM_CONT
|
||||
Camera& GetCamera();
|
||||
|
||||
VTKM_CONT
|
||||
void SetData(const vtkm::cont::ArrayHandleVirtualCoordinates& coordsHandle,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>& indices,
|
||||
vtkm::cont::Field& scalarField,
|
||||
const vtkm::Id& numberOfTriangles,
|
||||
const vtkm::Range& scalarRange,
|
||||
const vtkm::Bounds& dataBounds);
|
||||
void AddShapeIntersector(ShapeIntersector* intersector);
|
||||
|
||||
VTKM_CONT
|
||||
void SetField(const vtkm::cont::Field& scalarField, const vtkm::Range& scalarRange);
|
||||
|
||||
VTKM_CONT
|
||||
void SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>& colorMap);
|
||||
|
||||
VTKM_CONT
|
||||
void Render(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays);
|
||||
|
||||
VTKM_CONT
|
||||
void Render(vtkm::rendering::raytracing::Ray<vtkm::Float64>& rays);
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfShapes() const;
|
||||
|
||||
VTKM_CONT
|
||||
void Clear();
|
||||
|
||||
}; //class RayTracer
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/DeviceAdapterListTag.h>
|
||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -101,6 +102,30 @@ inline std::string GetDeviceString<vtkm::cont::DeviceAdapterTagCuda>(
|
||||
return "cuda";
|
||||
}
|
||||
|
||||
struct DeviceStringFunctor
|
||||
{
|
||||
std::string result;
|
||||
DeviceStringFunctor()
|
||||
: result("")
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT bool operator()(Device)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result = GetDeviceString(Device());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string GetDeviceString()
|
||||
{
|
||||
DeviceStringFunctor functor;
|
||||
vtkm::cont::TryExecute(functor);
|
||||
return functor.result;
|
||||
}
|
||||
|
||||
using ColorBuffer4f = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||
using ColorBuffer4b = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,9 @@ set(unit_tests
|
||||
UnitTestCanvas.cxx
|
||||
UnitTestMapperConnectivity.cxx
|
||||
UnitTestMultiMapper.cxx
|
||||
UnitTestMapperCylinders.cxx
|
||||
UnitTestMapperPoints.cxx
|
||||
UnitTestMapperQuads.cxx
|
||||
UnitTestMapperRayTracer.cxx
|
||||
UnitTestMapperWireframer.cxx
|
||||
UnitTestMapperVolume.cxx
|
||||
|
@ -55,8 +55,11 @@ inline void SetCamera<vtkm::rendering::View3D>(vtkm::rendering::Camera& camera,
|
||||
const vtkm::Bounds& coordBounds,
|
||||
const vtkm::cont::Field&)
|
||||
{
|
||||
vtkm::Bounds b = coordBounds;
|
||||
b.Z.Min = 0;
|
||||
b.Z.Max = 4;
|
||||
camera = vtkm::rendering::Camera();
|
||||
camera.ResetToBounds(coordBounds);
|
||||
camera.ResetToBounds(b);
|
||||
camera.Azimuth(static_cast<vtkm::Float32>(45.0));
|
||||
camera.Elevation(static_cast<vtkm::Float32>(45.0));
|
||||
}
|
||||
@ -124,6 +127,36 @@ void Render(const vtkm::cont::DataSet& ds,
|
||||
Render<MapperType, CanvasType, ViewType>(view, outputFile);
|
||||
}
|
||||
|
||||
// A render test that allows for testing different mapper params
|
||||
template <typename MapperType, typename CanvasType, typename ViewType>
|
||||
void Render(MapperType& mapper,
|
||||
const vtkm::cont::DataSet& ds,
|
||||
const std::string& fieldNm,
|
||||
const vtkm::cont::ColorTable& colorTable,
|
||||
const std::string& outputFile)
|
||||
{
|
||||
CanvasType canvas(512, 512);
|
||||
vtkm::rendering::Scene scene;
|
||||
|
||||
scene.AddActor(vtkm::rendering::Actor(
|
||||
ds.GetCellSet(), ds.GetCoordinateSystem(), ds.GetField(fieldNm), colorTable));
|
||||
vtkm::rendering::Camera camera;
|
||||
SetCamera<ViewType>(camera, ds.GetCoordinateSystem().GetBounds(), ds.GetField(fieldNm));
|
||||
vtkm::rendering::Color background(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
vtkm::rendering::Color foreground(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
ViewType view(scene, mapper, canvas, camera, background, foreground);
|
||||
|
||||
// Print the title
|
||||
vtkm::rendering::TextAnnotationScreen* titleAnnotation =
|
||||
new vtkm::rendering::TextAnnotationScreen("Test Plot",
|
||||
vtkm::rendering::Color(1, 1, 1, 1),
|
||||
.075f,
|
||||
vtkm::Vec<vtkm::Float32, 2>(-.11f, .92f),
|
||||
0.f);
|
||||
view.AddAnnotation(titleAnnotation);
|
||||
Render<MapperType, CanvasType, ViewType>(view, outputFile);
|
||||
}
|
||||
|
||||
template <typename MapperType, typename CanvasType, typename ViewType>
|
||||
void Render(const vtkm::cont::DataSet& ds,
|
||||
const std::vector<std::string>& fields,
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <vtkm/rendering/MapperConnectivity.h>
|
||||
#include <vtkm/rendering/Scene.h>
|
||||
#include <vtkm/rendering/View3D.h>
|
||||
#include <vtkm/rendering/raytracing/Logger.h>
|
||||
#include <vtkm/rendering/testing/RenderTest.h>
|
||||
|
||||
namespace
|
||||
@ -34,19 +35,26 @@ namespace
|
||||
|
||||
void RenderTests()
|
||||
{
|
||||
using M = vtkm::rendering::MapperConnectivity;
|
||||
using C = vtkm::rendering::CanvasRayTracer;
|
||||
using V3 = vtkm::rendering::View3D;
|
||||
try
|
||||
{
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::ColorTable colorTable("inferno");
|
||||
using M = vtkm::rendering::MapperConnectivity;
|
||||
using C = vtkm::rendering::CanvasRayTracer;
|
||||
using V3 = vtkm::rendering::View3D;
|
||||
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::ColorTable colorTable("inferno");
|
||||
|
||||
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.Make3DExplicitDataSet5(), "pointvar", colorTable, "explicit3D.pnm");
|
||||
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.Make3DExplicitDataSetZoo(), "pointvar", colorTable, "explicit3D.pnm");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << vtkm::rendering::raytracing::Logger::GetInstance()->GetStream().str() << "\n";
|
||||
std::cout << e.what() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
@ -49,7 +49,10 @@ void RenderTests()
|
||||
maker.Make3DExplicitDataSet4(), "pointvar", colorTable, "rt_expl3D.pnm");
|
||||
|
||||
vtkm::rendering::testing::Render<M, C, V2>(
|
||||
maker.Make2DUniformDataSet1(), "pointvar", colorTable, "rt_uni2D.pnm");
|
||||
maker.Make2DUniformDataSet1(), "pointvar", colorTable, "uni2D.pnm");
|
||||
|
||||
vtkm::rendering::testing::Render<M, C, V3>(
|
||||
maker.Make3DExplicitDataSet7(), "cellvar", colorTable, "spheres.pnm");
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
Loading…
Reference in New Issue
Block a user