Merge branch 'rendering-library' into 'master'

Rendering library

Pull the majority of the implementation of the rendering
package into a library for better compile performance.

See merge request !527
This commit is contained in:
Kenneth Moreland 2016-09-09 16:28:09 -04:00
commit 8e845d6933
86 changed files with 16993 additions and 13971 deletions

@ -43,11 +43,13 @@ if (NOT VTKm_SOURCE_DIR)
message(SEND_ERROR "VTKm_SOURCE_DIR not defined.")
endif (NOT VTKm_SOURCE_DIR)
function(check_directory directory)
function(check_directory directory parent_CMakeLists_contents)
message("Checking directory ${directory}...")
get_filename_component(directory_name "${directory}" NAME)
if(EXISTS "${directory}/CMakeLists.txt")
file(READ "${directory}/CMakeLists.txt" CMakeListsContents)
file(READ "${directory}/CMakeLists.txt" CMakeLists_contents)
endif()
foreach (glob_expression ${FILES_TO_CHECK})
@ -70,14 +72,23 @@ function(check_directory directory)
# Remove .in suffix. These are generally configured files that generate
# new files that are actually used in the build.
string(REGEX REPLACE ".in$" "" file_check "${file}")
string(FIND "${CMakeListsContents}" "${file_check}" position)
string(FIND "${CMakeLists_contents}" "${file_check}" position)
if(${position} LESS 0)
message(SEND_ERROR
"****************************************************************
# Check the CMakeLists.txt of the parent directory. Some sources of
# internal directories are packaged into libraries in the parent
# directory.
string(FIND "${parent_CMakeLists_contents}"
"${directory_name}/${file_check}"
position
)
if(${position} LESS 0)
message(SEND_ERROR
"****************************************************************
${file_check} is not found in ${directory}/CMakeLists.txt
This indicates that the file is not part of the build system. Thus it might be missing build targets. All such files should be explicitly handled by CMake.")
endif()
endif()
endif() # Not in parent's CMakeLists.txt
endif() # Not in CMakeLists.txt
endif() # Not skipped
endforeach (file)
endforeach(glob_expression)
@ -86,10 +97,10 @@ This indicates that the file is not part of the build system. Thus it might be m
"${directory}/*")
foreach(file ${file_list})
if(IS_DIRECTORY "${file}")
check_directory("${file}")
check_directory("${file}" "${CMakeLists_contents}")
endif()
endforeach(file)
endfunction(check_directory)
check_directory("${VTKm_SOURCE_DIR}/vtkm")
check_directory("${VTKm_SOURCE_DIR}/examples")
check_directory("${VTKm_SOURCE_DIR}/vtkm" "")
check_directory("${VTKm_SOURCE_DIR}/examples" "")

@ -52,9 +52,6 @@ if(VTKm_PACKAGE_IN_BUILD)
set(VTKm_INCLUDE_DIRS ${VTKm_INCLUDE_DIRS} "@VTKm_SOURCE_DIR@")
endif()
# Clear out the libraries. We will add more when loading components.
set(VTKm_LIBRARIES)
set(VTKm_REQUIRED_BOOST_VERSION "@VTKm_REQUIRED_BOOST_VERSION@")
if(NOT VTKm_PACKAGE_IN_BUILD)
@ -63,11 +60,21 @@ else()
set_and_check(VTKm_CMAKE_MODULE_PATH "@VTKm_SOURCE_DIR@/CMake")
endif()
set(VTKm_BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@")
set(VTKm_ENABLE_CUDA "@VTKm_ENABLE_CUDA@")
set(VTKm_ENABLE_TBB "@VTKm_ENABLE_TBB@")
set(VTKm_ENABLE_OPENGL_INTEROP "@VTKm_ENABLE_OPENGL_INTEROP@")
set(VTKm_BUILD_RENDERING "@VTKm_BUILD_RENDERING@")
# Load the library exports, but only if not compiling VTK-m itself
set_and_check(VTKm_CONFIG_DIR "@PACKAGE_VTKm_INSTALL_CONFIG_DIR@")
if(NOT "${CMAKE_BINARY_DIR}" STREQUAL "@VTKm_BINARY_DIR@")
include(${VTKm_CONFIG_DIR}/VTKmTargets.cmake)
endif()
# Clear out the libraries. We will add more when loading components.
set(VTKm_LIBRARIES)
# The VTKm variables used to configure components and packages silently.
set(VTKm_CONFIGURE_QUIET "${VTKm_FIND_QUIETLY}")
set(VTKm_FIND_PACKAGE_QUIETLY "")

@ -41,6 +41,7 @@ set(VTKm_AVAILABLE_COMPONENTS
EGL
GLFW
Interop
Rendering
TBB
CUDA
)
@ -202,6 +203,19 @@ macro(vtkm_configure_component_Interop)
)
endmacro(vtkm_configure_component_Interop)
macro(vtkm_configure_component_Rendering)
if(VTKm_BUILD_RENDERING)
vtkm_configure_component_OpenGL()
vtkm_configure_component_EGL()
vtkm_configure_component_OSMesa()
endif()
vtkm_finish_configure_component(Rendering
DEPENDENT_VARIABLES VTKm_BUILD_RENDERING VTKm_Base_FOUND
ADD_LIBRARIES vtkm_rendering
)
endmacro(vtkm_configure_component_Rendering)
macro(vtkm_configure_component_TBB)
if(VTKm_ENABLE_TBB)
vtkm_configure_component_Base()

@ -19,6 +19,7 @@
##============================================================================
include(CMakeParseArguments)
include(GenerateExportHeader)
# Utility to build a kit name from the current directory.
function(vtkm_get_kit_name kitvar)
@ -552,6 +553,125 @@ function(vtkm_benchmarks device_adapter)
endfunction(vtkm_benchmarks)
# Given a list of *.cxx source files that during configure time are deterimined
# to have CUDA code, wrap the sources in *.cu files so that they get compiled
# with nvcc.
function(vtkm_wrap_sources_for_cuda cuda_source_list_var)
set(original_sources ${ARGN})
set(cuda_sources)
foreach(source_file ${original_sources})
get_filename_component(source_name ${source_file} NAME_WE)
get_filename_component(source_file_path ${source_file} ABSOLUTE)
set(wrapped_file ${CMAKE_CURRENT_BINARY_DIR}/${source_name}.cu)
configure_file(
${VTKm_SOURCE_DIR}/CMake/WrapCUDASource.cu.in
${wrapped_file}
@ONLY)
list(APPEND cuda_sources ${wrapped_file})
endforeach(source_file)
set_source_files_properties(${original_sources}
PROPERTIES HEADER_FILE_ONLY TRUE
)
set(${cuda_source_list_var} ${cuda_sources} PARENT_SCOPE)
endfunction(vtkm_wrap_sources_for_cuda)
set(VTKM_HAS_AT_LEAST_ONE_LIBRARY FALSE CACHE INTERNAL "" FORCE)
# Add a VTK-m library. The name of the library will match the "kit" name
# (e.g. vtkm_rendering) unless the NAME argument is given.
#
# vtkm_library(
# [NAME <name>]
# SOURCES <source_list>
# [CUDA]
# [WRAP_FOR_CUDA <source_list>]
# )
function(vtkm_library)
set(options CUDA)
set(oneValueArgs NAME)
set(multiValueArgs SOURCES WRAP_FOR_CUDA)
cmake_parse_arguments(VTKm_LIB
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
vtkm_get_kit_name(kit dir_prefix)
if(VTKm_LIB_NAME)
set(lib_name ${VTKm_LIB_NAME})
else()
set(lib_name ${kit})
endif()
if(VTKm_LIB_CUDA)
vtkm_setup_nvcc_flags(old_nvcc_flags old_cxx_flags)
vtkm_wrap_sources_for_cuda(cuda_sources ${VTKm_LIB_WRAP_FOR_CUDA})
# Cuda compiles do not respect target_include_directories
cuda_include_directories(${VTKm_INCLUDE_DIRS})
cuda_add_library(${lib_name} ${VTKm_LIB_SOURCES} ${cuda_sources})
set(CUDA_NVCC_FLAGS ${old_nvcc_flags})
set(CMAKE_CXX_FLAGS ${old_cxx_flags})
else()
add_library(${lib_name} ${VTKm_LIB_SOURCES})
endif()
#do it as a property value so we don't pollute the include_directories
#for any other targets
set_property(TARGET ${lib_name} APPEND PROPERTY
INCLUDE_DIRECTORIES ${VTKm_INCLUDE_DIRS} )
target_link_libraries(${lib_name} ${VTKm_LIBRARIES})
set(cxx_args ${VTKm_COMPILE_OPTIONS})
separate_arguments(cxx_args)
target_compile_options(${lib_name} PRIVATE ${cxx_args})
# Make sure libraries go to lib directory and dll go to bin directory.
# Mostly important on Windows.
set_target_properties(${lib_name} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
)
if(MSVC)
vtkm_setup_msvc_properties(${lib_name})
endif()
if(VTKm_EXTRA_COMPILER_WARNINGS)
set(cxx_args ${CMAKE_CXX_FLAGS_WARN_EXTRA})
separate_arguments(cxx_args)
target_compile_options(${lib_name}
PRIVATE ${cxx_args}
)
endif(VTKm_EXTRA_COMPILER_WARNINGS)
generate_export_header(${lib_name})
#generate_export_header creates the header in CMAKE_CURRENT_BINARY_DIR.
#The build expects it in the install directory.
file(COPY
${CMAKE_CURRENT_BINARY_DIR}/${lib_name}_export.h
DESTINATION
${CMAKE_BINARY_DIR}/${VTKm_INSTALL_INCLUDE_DIR}/${dir_prefix}
)
install(TARGETS ${lib_name}
EXPORT ${VTKm_EXPORT_NAME}
ARCHIVE DESTINATION ${VTKm_INSTALL_LIB_DIR}
LIBRARY DESTINATION ${VTKm_INSTALL_LIB_DIR}
RUNTIME DESTINATION ${VTKm_INSTALL_BIN_DIR}
)
vtkm_install_headers("${dir_prefix}"
${CMAKE_BINARY_DIR}/${VTKm_INSTALL_INCLUDE_DIR}/${dir_prefix}/${lib_name}_export.h
)
set(VTKM_HAS_AT_LEAST_ONE_LIBRARY TRUE CACHE INTERNAL "" FORCE)
endfunction(vtkm_library)
# The Thrust project is not as careful as the VTKm project in avoiding warnings
# on shadow variables and unused arguments. With a real GCC compiler, you
# can disable these warnings inline, but with something like nvcc, those

@ -0,0 +1 @@
#include "@source_file_path@"

@ -46,9 +46,13 @@ set(VTKm_PATCH_VERSION 0)
set(VTKm_VERSION "${VTKm_MAJOR_VERSION}.${VTKm_MINOR_VERSION}.${VTKm_PATCH_VERSION}")
set(VTKm_INSTALL_INCLUDE_DIR "include")
set(VTKm_INSTALL_CONFIG_DIR "include")
set(VTKm_INSTALL_CONFIG_DIR "lib")
set(VTKm_INSTALL_LIB_DIR "lib")
set(VTKm_INSTALL_BIN_DIR "bin")
set(VTKm_INSTALL_CMAKE_MODULE_DIR "share/vtkm/cmake")
set(VTKm_EXPORT_NAME "VTKmTargets")
set(VTKm_REQUIRED_BOOST_VERSION "1.48")
set(VTKm_CMAKE_MODULE_PATH ${VTKm_SOURCE_DIR}/CMake)
@ -112,6 +116,9 @@ option(VTKm_USE_DOUBLE_PRECISION
)
option(VTKm_USE_64BIT_IDS "Use 64-bit indices." ON)
option(BUILD_SHARED_LIBS "Build VTK-m with shared libraries" ON)
set(VTKm_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
if (VTKm_ENABLE_TESTING)
enable_testing()
include(CTest)
@ -149,7 +156,7 @@ set( EXECUTABLE_OUTPUT_PATH
## Set the directory where the libraries will be stored
set( LIBRARY_OUTPUT_PATH
${PROJECT_BINARY_DIR}/libs
${PROJECT_BINARY_DIR}/lib
CACHE PATH
"Directory where all the libraries will be stored"
)
@ -278,7 +285,12 @@ configure_package_config_file(
${VTKm_SOURCE_DIR}/CMake/VTKmConfig.cmake.in
${VTKm_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR}/VTKmConfig.cmake
INSTALL_DESTINATION ${VTKm_INSTALL_CONFIG_DIR}
PATH_VARS VTKm_INSTALL_INCLUDE_DIR VTKm_INSTALL_CMAKE_MODULE_DIR
PATH_VARS
VTKm_INSTALL_INCLUDE_DIR
VTKm_INSTALL_CONFIG_DIR
VTKm_INSTALL_LIB_DIR
VTKm_INSTALL_BIN_DIR
VTKm_INSTALL_CMAKE_MODULE_DIR
)
write_basic_package_version_file(
@ -322,7 +334,23 @@ install(
DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR}
)
# Create and install exports for external projects
if(${VTKM_HAS_AT_LEAST_ONE_LIBRARY})
export(EXPORT ${VTKm_EXPORT_NAME}
FILE ${CMAKE_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR}/VTKmTargets.cmake
)
install(EXPORT ${VTKm_EXPORT_NAME}
DESTINATION ${VTKm_INSTALL_LIB_DIR}
FILE VTKmTargets.cmake
)
else() # No libraries built
file(WRITE ${CMAKE_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR}/VTKmTargets.cmake
"# This build of VTK-m has no libraries to export targets for"
)
install(FILES ${CMAKE_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR}/VTKmTargets.cmake
DESTINATION ${VTKm_INSTALL_LIB_DIR}
)
endif()
# Enable CPack packaging
set(CPACK_PACKAGE_DESCRIPTION_FILE ${VTKm_SOURCE_DIR}/README.md)

@ -23,11 +23,11 @@
#Find the VTK-m package
find_package(VTKm QUIET REQUIRED
COMPONENTS Base
OPTIONAL_COMPONENTS Serial Cuda TBB OSMesa
OPTIONAL_COMPONENTS Serial Cuda TBB OSMesa Rendering
)
if(VTKm_OSMesa_FOUND)
if(VTKm_OSMesa_FOUND AND VTKm_Rendering_FOUND)
if(VTKm_CUDA_FOUND)
# Cuda compiles do not respect target_include_directories
cuda_include_directories(${VTKm_INCLUDE_DIRS})

@ -23,7 +23,7 @@
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>

@ -23,12 +23,12 @@
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET
COMPONENTS Base
OPTIONAL_COMPONENTS Serial OpenGL
OPTIONAL_COMPONENTS Serial OpenGL Rendering
)
find_package(GLUT)
if(VTKm_OpenGL_FOUND AND GLUT_FOUND)
if(VTKm_OpenGL_FOUND AND VTKm_Rendering_FOUND AND GLUT_FOUND)
add_executable(Rendering_SERIAL Rendering.cxx)
target_include_directories(Rendering_SERIAL PRIVATE ${GLUT_INCLUDE_DIR} ${VTKm_INCLUDE_DIRS})
target_link_libraries(Rendering_SERIAL ${GLUT_LIBRARIES} ${VTKm_LIBRARIES})

@ -42,7 +42,7 @@
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/rendering/ColorTable.h>
vtkm::rendering::View3D *view = nullptr;
@ -138,7 +138,7 @@ main(int argc, char* argv[])
vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f);
vtkm::rendering::CanvasGL canvas;
vtkm::rendering::MapperGL<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> mapper;
vtkm::rendering::MapperGL mapper;
vtkm::rendering::Scene scene;
scene.AddActor(vtkm::rendering::Actor(ds.GetCellSet(),

@ -53,11 +53,34 @@ vtkm::Vec<T,3> Transform3DPoint(const vtkm::Matrix<T,4,4> &matrix,
vtkm::dot(vtkm::MatrixGetRow(matrix,2), homogeneousPoint));
}
/// \brief Transform a 3D point by a transformation matrix.
/// \brief Transform a 3D point by a transformation matrix with perspective.
///
/// Given a 4x4 transformation matrix and a 3D point, returns the point
/// transformed by the given matrix in homogeneous coordinates.
///
/// Unlike Transform3DPoint, this method honors the fourth component of the
/// transformed homogeneous coordiante. This makes it applicable for perspective
/// transformations, but requires some more computations.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T,3> Transform3DPointPerspective(const vtkm::Matrix<T,4,4> &matrix,
const vtkm::Vec<T,3> &point)
{
vtkm::Vec<T,4> homogeneousPoint(point[0], point[1], point[2], T(1));
T inverseW = 1/vtkm::dot(vtkm::MatrixGetRow(matrix,3), homogeneousPoint);
return vtkm::Vec<T,3>(
vtkm::dot(vtkm::MatrixGetRow(matrix,0), homogeneousPoint)*inverseW,
vtkm::dot(vtkm::MatrixGetRow(matrix,1), homogeneousPoint)*inverseW,
vtkm::dot(vtkm::MatrixGetRow(matrix,2), homogeneousPoint)*inverseW);
}
/// \brief Transform a 3D vector by a transformation matrix.
///
/// Given a 4x4 transformation matrix and a 3D vector, returns the vector
/// transformed by the given matrix in homogeneous coordinates. Unlike points,
/// vectors do not get translated.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T,3> Transform3DVector(const vtkm::Matrix<T,4,4> &matrix,

@ -284,7 +284,6 @@ public:
/// with CUDA), then the automatically generated destructor could be
/// created for all devices, and it would not be valid for all devices.
///
VTKM_CONT_EXPORT
virtual ~ArrayHandle() { }
/// \brief Copies an ArrayHandle

@ -52,6 +52,7 @@
#define VTKM_CONSTEXPR constexpr
#endif
#define VTKM_OVERRIDE override
/// Simple macro to identify a parameter as unused. This allows you to name a
/// parameter that is not used. There are several instances where you might

136
vtkm/rendering/Actor.cxx Normal file

@ -0,0 +1,136 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/Actor.h>
#include <vtkm/Assert.h>
#include <vtkm/cont/TryExecute.h>
namespace vtkm {
namespace rendering {
struct Actor::InternalsType
{
vtkm::cont::DynamicCellSet Cells;
vtkm::cont::CoordinateSystem Coordinates;
vtkm::cont::Field ScalarField;
vtkm::rendering::ColorTable ColorTable;
vtkm::Range ScalarRange;
vtkm::Bounds SpatialBounds;
VTKM_CONT_EXPORT
InternalsType(const vtkm::cont::DynamicCellSet &cells,
const vtkm::cont::CoordinateSystem &coordinates,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &colorTable)
: Cells(cells),
Coordinates(coordinates),
ScalarField(scalarField),
ColorTable(colorTable)
{ }
};
struct Actor::RangeFunctor
{
vtkm::rendering::Actor::InternalsType *Internals;
const vtkm::cont::CoordinateSystem &Coordinates;
const vtkm::cont::Field &ScalarField;
VTKM_CONT_EXPORT
RangeFunctor(vtkm::rendering::Actor *self,
const vtkm::cont::CoordinateSystem &coordinates,
const vtkm::cont::Field &scalarField)
: Internals(self->Internals.get()),
Coordinates(coordinates),
ScalarField(scalarField)
{ }
template<typename Device>
VTKM_CONT_EXPORT
bool operator()(Device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
this->ScalarField.GetRange(&this->Internals->ScalarRange, Device());
this->Internals->SpatialBounds = this->Coordinates.GetBounds(Device());
return true;
}
};
Actor::Actor(const vtkm::cont::DynamicCellSet &cells,
const vtkm::cont::CoordinateSystem &coordinates,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &colorTable)
: Internals(new InternalsType(cells, coordinates, scalarField, colorTable))
{
VTKM_ASSERT(scalarField.GetData().GetNumberOfComponents() == 1);
RangeFunctor functor(this, coordinates, scalarField);
vtkm::cont::TryExecute(functor);
}
void Actor::Render(vtkm::rendering::Mapper &mapper,
vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera) const
{
mapper.SetCanvas(&canvas);
mapper.SetActiveColorTable(this->Internals->ColorTable);
mapper.RenderCells(this->Internals->Cells,
this->Internals->Coordinates,
this->Internals->ScalarField,
this->Internals->ColorTable,
camera,
this->Internals->ScalarRange);
}
const vtkm::cont::DynamicCellSet &Actor::GetCells() const
{
return this->Internals->Cells;
}
const vtkm::cont::CoordinateSystem &Actor::GetCoordiantes() const
{
return this->Internals->Coordinates;
}
const vtkm::cont::Field &Actor::GetScalarField() const
{
return this->Internals->ScalarField;
}
const vtkm::rendering::ColorTable &Actor::GetColorTable() const
{
return this->Internals->ColorTable;
}
const vtkm::Range &Actor::GetScalarRange() const
{
return this->Internals->ScalarRange;
}
const vtkm::Bounds &Actor::GetSpatialBounds() const
{
return this->Internals->SpatialBounds;
}
}
} // namespace vtkm::rendering

@ -20,10 +20,15 @@
#ifndef vtk_m_rendering_Actor_h
#define vtk_m_rendering_Actor_h
#include <vtkm/Assert.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Mapper.h>
#include <vector>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/shared_ptr.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
namespace vtkm {
namespace rendering {
@ -31,49 +36,41 @@ namespace rendering {
class Actor
{
public:
//Actor(points, cells, field, colortable) {}
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
Actor(const vtkm::cont::DynamicCellSet &cells,
const vtkm::cont::CoordinateSystem &coordinates,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &colorTable =
vtkm::rendering::ColorTable("default"))
: Cells(cells),
Coordinates(coordinates),
ScalarField(scalarField),
ColorTable(colorTable)
{
VTKM_ASSERT(scalarField.GetData().GetNumberOfComponents() == 1);
vtkm::rendering::ColorTable("default"));
scalarField.GetRange(&this->ScalarRange,
VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
this->SpatialBounds =
coordinates.GetBounds(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
}
VTKM_RENDERING_EXPORT
void Render(vtkm::rendering::Mapper &mapper,
vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera) const;
template<typename MapperType, typename CanvasType>
VTKM_CONT_EXPORT
void Render(MapperType &mapper,
CanvasType &canvas,
const vtkm::rendering::Camera &camera) const
{
mapper.SetCanvas(&canvas);
mapper.SetActiveColorTable(this->ColorTable);
mapper.RenderCells(this->Cells,
this->Coordinates,
this->ScalarField,
this->ColorTable,
camera,
this->ScalarRange);
}
VTKM_RENDERING_EXPORT
const vtkm::cont::DynamicCellSet &GetCells() const;
vtkm::cont::DynamicCellSet Cells;
vtkm::cont::CoordinateSystem Coordinates;
vtkm::cont::Field ScalarField;
vtkm::rendering::ColorTable ColorTable;
VTKM_RENDERING_EXPORT
const vtkm::cont::CoordinateSystem &GetCoordiantes() const;
vtkm::Range ScalarRange;
vtkm::Bounds SpatialBounds;
VTKM_RENDERING_EXPORT
const vtkm::cont::Field &GetScalarField() const;
VTKM_RENDERING_EXPORT
const vtkm::rendering::ColorTable &GetColorTable() const;
VTKM_RENDERING_EXPORT
const vtkm::Range &GetScalarRange() const;
VTKM_RENDERING_EXPORT
const vtkm::Bounds &GetSpatialBounds() const;
private:
struct InternalsType;
boost::shared_ptr<InternalsType> Internals;
struct RangeFunctor;
};
}} //namespace vtkm::rendering

@ -0,0 +1,156 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/AxisAnnotation.h>
#include <vtkm/cont/ErrorControlBadType.h>
namespace vtkm {
namespace rendering {
namespace {
inline vtkm::Float64 ffix(vtkm::Float64 value)
{
int ivalue = (int)(value);
vtkm::Float64 v = (value - ivalue);
if (v > 0.9999)
{
ivalue++;
}
return static_cast<vtkm::Float64>(ivalue);
}
} // anonymous namespace
void AxisAnnotation::CalculateTicks(const vtkm::Range &range,
bool minor,
std::vector<vtkm::Float64> &positions,
std::vector<vtkm::Float64> &proportions,
int modifyTickQuantity) const
{
positions.clear();
proportions.clear();
if (!range.IsNonEmpty()) { return; }
vtkm::Float64 length = range.Length();
// Find the integral points.
vtkm::Float64 pow10 = log10(length);
// Build in numerical tolerance
vtkm::Float64 eps = 10.0e-10;
pow10 += eps;
// ffix moves you in the wrong direction if pow10 is negative.
if (pow10 < 0.)
{
pow10 = pow10 - 1.;
}
vtkm::Float64 fxt = pow(10., ffix(pow10));
// Find the number of integral points in the interval.
int numTicks = int(ffix(length/fxt) + 1);
// We should get about major 10 ticks on a length that's near
// the power of 10. (e.g. length=1000). If the length is small
// enough we have less than 5 ticks (e.g. length=400), then
// divide the step by 2, or if it's about 2 ticks (e.g. length=150)
// or less, then divide the step by 5. That gets us back to
// about 10 major ticks.
//
// But we might want more or less. To adjust this up by
// approximately a factor of 2, instead of the default
// 1/2/5 dividers, use 2/5/10, and to adjust it down by
// about a factor of two, use .5/1/2 as the dividers.
// (We constrain to 1s, 2s, and 5s, for the obvious reason
// that only those values are factors of 10.....)
vtkm::Float64 divs[5] = { 0.5, 1, 2, 5, 10 };
int divindex = (numTicks >= 5) ? 1 : (numTicks >= 3 ? 2 : 3);
divindex += modifyTickQuantity;
vtkm::Float64 div = divs[divindex];
// If there aren't enough major tick points in this decade, use the next
// decade.
vtkm::Float64 majorStep = fxt / div;
vtkm::Float64 minorStep = (fxt/div) / 10.;
// When we get too close, we lose the tickmarks. Run some special case code.
if (numTicks <= 1)
{
if (minor)
{
// no minor ticks
return;
}
else
{
positions.resize(3);
proportions.resize(3);
positions[0] = range.Min;
positions[1] = range.Center();
positions[2] = range.Max;
proportions[0] = 0.0;
proportions[1] = 0.5;
proportions[2] = 1.0;
return;
}
}
// Figure out the first major and minor tick locations, relative to the
// start of the axis.
vtkm::Float64 majorStart, minorStart;
if (range.Min < 0.)
{
majorStart = majorStep*(ffix(range.Min*(1./majorStep)));
minorStart = minorStep*(ffix(range.Min*(1./minorStep)));
}
else
{
majorStart = majorStep*(ffix(range.Min*(1./majorStep) + .999));
minorStart = minorStep*(ffix(range.Min*(1./minorStep) + .999));
}
// Create all of the minor ticks
const int max_count_cutoff = 1000;
numTicks = 0;
vtkm::Float64 location = minor ? minorStart : majorStart;
vtkm::Float64 step = minor ? minorStep : majorStep;
while (location <= range.Max && numTicks < max_count_cutoff)
{
positions.push_back(location);
proportions.push_back((location - range.Min) / length);
numTicks++;
location += step;
}
}
AxisAnnotation::AxisAnnotation()
{ }
AxisAnnotation::~AxisAnnotation()
{ }
}
} // namespace vtkm::rendering

@ -20,6 +20,8 @@
#ifndef vtk_m_rendering_AxisAnnotation_h
#define vtk_m_rendering_AxisAnnotation_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/Scene.h>
@ -30,134 +32,24 @@ namespace rendering {
class AxisAnnotation
{
private:
protected:
inline vtkm::Float64 ffix(vtkm::Float64 value)
{
int ivalue = (int)(value);
vtkm::Float64 v = (value - ivalue);
if (v > 0.9999)
{
ivalue++;
}
return static_cast<vtkm::Float64>(ivalue);
}
void CalculateTicks(vtkm::Float64 lower, vtkm::Float64 upper, bool minor,
void CalculateTicks(const vtkm::Range &range,
bool minor,
std::vector<vtkm::Float64> &positions,
std::vector<vtkm::Float64> &proportions,
int modifyTickQuantity)
{
positions.clear();
proportions.clear();
int modifyTickQuantity) const;
vtkm::Float64 sortedRange[2];
sortedRange[0] = lower < upper ? lower : upper;
sortedRange[1] = lower > upper ? lower : upper;
public:
VTKM_RENDERING_EXPORT
AxisAnnotation();
vtkm::Float64 range = sortedRange[1] - sortedRange[0];
VTKM_RENDERING_EXPORT
~AxisAnnotation();
// Find the integral points.
vtkm::Float64 pow10 = log10(range);
// Build in numerical tolerance
vtkm::Float64 eps = 10.0e-10;
pow10 += eps;
// ffix moves you in the wrong direction if pow10 is negative.
if (pow10 < 0.)
{
pow10 = pow10 - 1.;
}
vtkm::Float64 fxt = pow(10., ffix(pow10));
// Find the number of integral points in the interval.
int numTicks = int(ffix(range/fxt) + 1);
// We should get about major 10 ticks on a range that's near
// the power of 10. (e.g. range=1000). If the range is small
// enough we have less than 5 ticks (e.g. range=400), then
// divide the step by 2, or if it's about 2 ticks (e.g. range=150)
// or less, then divide the step by 5. That gets us back to
// about 10 major ticks.
//
// But we might want more or less. To adjust this up by
// approximately a factor of 2, instead of the default
// 1/2/5 dividers, use 2/5/10, and to adjust it down by
// about a factor of two, use .5/1/2 as the dividers.
// (We constrain to 1s, 2s, and 5s, for the obvious reason
// that only those values are factors of 10.....)
vtkm::Float64 divs[5] = { 0.5, 1, 2, 5, 10 };
int divindex = (numTicks >= 5) ? 1 : (numTicks >= 3 ? 2 : 3);
divindex += modifyTickQuantity;
vtkm::Float64 div = divs[divindex];
// If there aren't enough major tick points in this decade, use the next
// decade.
vtkm::Float64 majorStep = fxt / div;
vtkm::Float64 minorStep = (fxt/div) / 10.;
// When we get too close, we lose the tickmarks. Run some special case code.
if (numTicks <= 1)
{
if (minor)
{
// no minor ticks
return;
}
else
{
positions.resize(3);
proportions.resize(3);
positions[0] = lower;
positions[1] = (lower+upper) / 2.;
positions[2] = upper;
proportions[0] = 0.0;
proportions[1] = 0.5;
proportions[2] = 1.0;
return;
}
}
// Figure out the first major and minor tick locations, relative to the
// start of the axis.
vtkm::Float64 majorStart, minorStart;
if (sortedRange[0] < 0.)
{
majorStart = majorStep*(ffix(sortedRange[0]*(1./majorStep)));
minorStart = minorStep*(ffix(sortedRange[0]*(1./minorStep)));
}
else
{
majorStart = majorStep*(ffix(sortedRange[0]*(1./majorStep) + .999));
minorStart = minorStep*(ffix(sortedRange[0]*(1./minorStep) + .999));
}
// Create all of the minor ticks
const int max_count_cutoff = 1000;
numTicks = 0;
vtkm::Float64 location = minor ? minorStart : majorStart;
vtkm::Float64 step = minor ? minorStep : majorStep;
while (location <= sortedRange[1] && numTicks < max_count_cutoff)
{
positions.push_back(location);
proportions.push_back((location - sortedRange[0]) / range);
numTicks++;
location += step;
}
if (sortedRange[0] != lower)
{
// We must reverse all of the proportions.
for (unsigned int j = 0 ; j < proportions.size(); j++)
{
proportions[j] = 1. - proportions[j];
}
}
}
VTKM_RENDERING_EXPORT
virtual void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas) = 0;
};

@ -0,0 +1,181 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/AxisAnnotation2D.h>
#include <vtkm/rendering/TextAnnotationScreen.h>
#include <sstream>
namespace vtkm {
namespace rendering {
AxisAnnotation2D::AxisAnnotation2D()
: AxisAnnotation()
{
this->AlignH = TextAnnotation::HCenter;
this->AlignV = TextAnnotation::VCenter;
this->FontScale = 0.05f;
this->LineWidth = 1.0;
this->Color = vtkm::rendering::Color(1,1,1);
this->Logarithmic = false;
this->MoreOrLessTickAdjustment = 0;
}
AxisAnnotation2D::~AxisAnnotation2D()
{
}
void AxisAnnotation2D::SetRangeForAutoTicks(const Range &range)
{
this->TickRange = range;
#if 0
if (this->Logarithmic)
{
CalculateTicksLogarithmic(this->TickRange.Min,
this->TickRange.Max,
false,
this->PositionsMajor,
this->ProportionsMajor,
this->MoreOrLessTickAdjustment);
CalculateTicksLogarithmic(this->TickRange.Min,
this->TickRange.Max,
true,
this->PositionsMinor,
this->ProportionsMinor,
this->MoreOrLessTickAdjustment);
}
else
#endif
{
CalculateTicks(this->TickRange,
false,
this->PositionsMajor,
this->ProportionsMajor,
this->MoreOrLessTickAdjustment);
CalculateTicks(this->TickRange,
true,
this->PositionsMinor,
this->ProportionsMinor,
this->MoreOrLessTickAdjustment);
}
}
void AxisAnnotation2D::SetMajorTicks(const std::vector<vtkm::Float64> &pos,
const std::vector<vtkm::Float64> &prop)
{
this->PositionsMajor.clear();
this->PositionsMajor.insert(this->PositionsMajor.begin(),
pos.begin(),
pos.end());
this->ProportionsMajor.clear();
this->ProportionsMajor.insert(this->ProportionsMajor.begin(),
prop.begin(),
prop.end());
}
void AxisAnnotation2D::SetMinorTicks(const std::vector<vtkm::Float64> &pos,
const std::vector<vtkm::Float64> &prop)
{
this->PositionsMinor.clear();
this->PositionsMinor.insert(this->PositionsMinor.begin(), pos.begin(), pos.end());
this->ProportionsMinor.clear();
this->ProportionsMinor.insert(this->ProportionsMinor.begin(), prop.begin(), prop.end());
}
void AxisAnnotation2D::Render(
const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas)
{
canvas.AddLine(this->PosX0,this->PosY0, this->PosX1,this->PosY1, this->LineWidth, this->Color);
// major ticks
unsigned int nmajor = (unsigned int)this->ProportionsMajor.size();
while (this->Labels.size() < nmajor)
{
this->Labels.push_back(new vtkm::rendering::TextAnnotationScreen(
"test",
this->Color,
this->FontScale,
vtkm::Vec<vtkm::Float32,2>(0,0),
0));
}
std::stringstream numberToString;
for (unsigned int i=0; i<nmajor; ++i)
{
vtkm::Float64 xc = this->PosX0 + (this->PosX1-this->PosX0) * this->ProportionsMajor[i];
vtkm::Float64 yc = this->PosY0 + (this->PosY1-this->PosY0) * this->ProportionsMajor[i];
vtkm::Float64 xs = xc - this->MajorTickSizeX*this->MajorTickOffset;
vtkm::Float64 xe = xc + this->MajorTickSizeX*(1. - this->MajorTickOffset);
vtkm::Float64 ys = yc - this->MajorTickSizeY*this->MajorTickOffset;
vtkm::Float64 ye = yc + this->MajorTickSizeY*(1. - this->MajorTickOffset);
canvas.AddLine(xs,ys, xe,ye, 1.0, this->Color);
if (this->MajorTickSizeY == 0)
{
// slight shift to space between label and tick
xs -= (this->MajorTickSizeX<0?-1.:+1.) * this->FontScale * .1;
}
numberToString.str("");
numberToString << this->PositionsMajor[i];
this->Labels[i]->SetText(numberToString.str());
//if (fabs(this->PositionsMajor[i]) < 1e-10)
// this->Labels[i]->SetText("0");
((TextAnnotationScreen*)(this->Labels[i]))->SetPosition(vtkm::Float32(xs),
vtkm::Float32(ys));
this->Labels[i]->SetAlignment(this->AlignH,this->AlignV);
}
// minor ticks
if (this->MinorTickSizeX != 0 || this->MinorTickSizeY != 0)
{
unsigned int nminor = (unsigned int)this->ProportionsMinor.size();
for (unsigned int i=0; i<nminor; ++i)
{
vtkm::Float64 xc = this->PosX0 + (this->PosX1-this->PosX0) * this->ProportionsMinor[i];
vtkm::Float64 yc = this->PosY0 + (this->PosY1-this->PosY0) * this->ProportionsMinor[i];
vtkm::Float64 xs = xc - this->MinorTickSizeX*this->MinorTickOffset;
vtkm::Float64 xe = xc + this->MinorTickSizeX*(1. - this->MinorTickOffset);
vtkm::Float64 ys = yc - this->MinorTickSizeY*this->MinorTickOffset;
vtkm::Float64 ye = yc + this->MinorTickSizeY*(1. - this->MinorTickOffset);
canvas.AddLine(xs,ys, xe,ye, 1.0, this->Color);
}
}
for (unsigned int i=0; i<nmajor; ++i)
{
this->Labels[i]->Render(camera, worldAnnotator, canvas);
}
}
}
} // namespace vtkm::rendering

@ -20,215 +20,144 @@
#ifndef vtk_m_rendering_AxisAnnotation2D_h
#define vtk_m_rendering_AxisAnnotation2D_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/Range.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/AxisAnnotation.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/WorldAnnotator.h>
#include <vtkm/rendering/AxisAnnotation.h>
#include <vtkm/rendering/TextAnnotation.h>
#include <sstream>
namespace vtkm {
namespace rendering {
class AxisAnnotation2D : public AxisAnnotation
{
protected:
vtkm::Float64 maj_tx, maj_ty, maj_toff;
vtkm::Float64 min_tx, min_ty, min_toff;
vtkm::Float64 x0, y0, x1, y1;
vtkm::Float64 lower, upper;
vtkm::Float32 fontscale;
vtkm::Float32 linewidth;
vtkm::rendering::Color color;
bool logarithmic;
vtkm::Float64 MajorTickSizeX, MajorTickSizeY, MajorTickOffset;
vtkm::Float64 MinorTickSizeX, MinorTickSizeY, MinorTickOffset;
vtkm::Float64 PosX0, PosY0, PosX1, PosY1;
vtkm::Range TickRange;
vtkm::Float32 FontScale;
vtkm::Float32 LineWidth;
vtkm::rendering::Color Color;
bool Logarithmic;
TextAnnotation::HorizontalAlignment halign;
TextAnnotation::VerticalAlignment valign;
std::vector<TextAnnotation*> labels;
TextAnnotation::HorizontalAlignment AlignH;
TextAnnotation::VerticalAlignment AlignV;
std::vector<TextAnnotation*> Labels;
std::vector<vtkm::Float64> maj_positions;
std::vector<vtkm::Float64> maj_proportions;
std::vector<vtkm::Float64> PositionsMajor;
std::vector<vtkm::Float64> ProportionsMajor;
std::vector<vtkm::Float64> min_positions;
std::vector<vtkm::Float64> min_proportions;
std::vector<vtkm::Float64> PositionsMinor;
std::vector<vtkm::Float64> ProportionsMinor;
int moreOrLessTickAdjustment;
int MoreOrLessTickAdjustment;
public:
AxisAnnotation2D() : AxisAnnotation()
{
halign = TextAnnotation::HCenter;
valign = TextAnnotation::VCenter;
fontscale = 0.05f;
linewidth = 1.0;
color = Color(1,1,1);
logarithmic = false;
moreOrLessTickAdjustment = 0;
}
virtual ~AxisAnnotation2D()
{
}
VTKM_RENDERING_EXPORT
AxisAnnotation2D();
VTKM_RENDERING_EXPORT
~AxisAnnotation2D();
#if 0
VTKM_RENDERING_EXPORT
void SetLogarithmic(bool l)
{
logarithmic = l;
this->Logarithmic = l;
}
#endif
VTKM_RENDERING_EXPORT
void SetMoreOrLessTickAdjustment(int offset)
{
moreOrLessTickAdjustment = offset;
this->MoreOrLessTickAdjustment = offset;
}
VTKM_RENDERING_EXPORT
void SetColor(vtkm::rendering::Color c)
{
color = c;
this->Color = c;
}
VTKM_RENDERING_EXPORT
void SetLineWidth(vtkm::Float32 lw)
{
linewidth = lw;
this->LineWidth = lw;
}
VTKM_RENDERING_EXPORT
void SetMajorTickSize(vtkm::Float64 xlen, vtkm::Float64 ylen, vtkm::Float64 offset)
{
/// offset of 0 means the tick is inside the frame
/// offset of 1 means the tick is outside the frame
/// offset of 0.5 means the tick is centered on the frame
maj_tx=xlen;
maj_ty=ylen;
maj_toff = offset;
this->MajorTickSizeX=xlen;
this->MajorTickSizeY=ylen;
this->MajorTickOffset = offset;
}
VTKM_RENDERING_EXPORT
void SetMinorTickSize(vtkm::Float64 xlen, vtkm::Float64 ylen, vtkm::Float64 offset)
{
min_tx=xlen;
min_ty=ylen;
min_toff = offset;
this->MinorTickSizeX=xlen;
this->MinorTickSizeY=ylen;
this->MinorTickOffset = offset;
}
///\todo: rename, since it might be screen OR world position?
void SetScreenPosition(vtkm::Float64 x0_, vtkm::Float64 y0_,
vtkm::Float64 x1_, vtkm::Float64 y1_)
{
x0 = x0_;
y0 = y0_;
x1 = x1_;
y1 = y1_;
///\todo: rename, since it might be screen OR world position?
VTKM_RENDERING_EXPORT
void SetScreenPosition(vtkm::Float64 x0, vtkm::Float64 y0,
vtkm::Float64 x1, vtkm::Float64 y1)
{
this->PosX0 = x0;
this->PosY0 = y0;
this->PosX1 = x1;
this->PosY1 = y1;
}
VTKM_RENDERING_EXPORT
void SetLabelAlignment(TextAnnotation::HorizontalAlignment h,
TextAnnotation::VerticalAlignment v)
{
halign = h;
valign = v;
this->AlignH = h;
this->AlignV = v;
}
VTKM_RENDERING_EXPORT
void SetLabelFontScale(vtkm::Float32 s)
{
fontscale = s;
for (unsigned int i=0; i<labels.size(); i++)
labels[i]->SetScale(s);
this->FontScale = s;
for (unsigned int i=0; i<this->Labels.size(); i++)
this->Labels[i]->SetScale(s);
}
void SetRangeForAutoTicks(vtkm::Float64 l, vtkm::Float64 u)
VTKM_RENDERING_EXPORT
void SetRangeForAutoTicks(const vtkm::Range &range);
VTKM_RENDERING_EXPORT
void SetRangeForAutoTicks(vtkm::Float64 lower, vtkm::Float64 upper)
{
lower = l;
upper = u;
#if 0
if (logarithmic)
{
CalculateTicksLogarithmic(lower, upper, false, maj_positions, maj_proportions, moreOrLessTickAdjustment);
CalculateTicksLogarithmic(lower, upper, true, min_positions, min_proportions, moreOrLessTickAdjustment);
}
else
#endif
{
CalculateTicks(lower, upper, false, maj_positions, maj_proportions, moreOrLessTickAdjustment);
CalculateTicks(lower, upper, true, min_positions, min_proportions, moreOrLessTickAdjustment);
}
this->SetRangeForAutoTicks(vtkm::Range(lower, upper));
}
void SetMajorTicks(const std::vector<vtkm::Float64> &pos, const std::vector<vtkm::Float64> &prop)
{
maj_positions.clear();
maj_positions.insert(maj_positions.begin(), pos.begin(), pos.end());
maj_proportions.clear();
maj_proportions.insert(maj_proportions.begin(), prop.begin(), prop.end());
}
void SetMinorTicks(const std::vector<vtkm::Float64> &pos, const std::vector<vtkm::Float64> &prop)
{
min_positions.clear();
min_positions.insert(min_positions.begin(), pos.begin(), pos.end());
VTKM_RENDERING_EXPORT
void SetMajorTicks(const std::vector<vtkm::Float64> &positions,
const std::vector<vtkm::Float64> &proportions);
min_proportions.clear();
min_proportions.insert(min_proportions.begin(), prop.begin(), prop.end());
}
virtual void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas)
{
canvas.AddLine(x0,y0, x1,y1, linewidth, color);
VTKM_RENDERING_EXPORT
void SetMinorTicks(const std::vector<vtkm::Float64> &positions,
const std::vector<vtkm::Float64> &proportions);
// major ticks
unsigned int nmajor = (unsigned int)maj_proportions.size();
while (labels.size() < nmajor)
{
labels.push_back(new ScreenTextAnnotation("test",
color,
fontscale,
0,0, 0));
}
std::stringstream numberToString;
for (unsigned int i=0; i<nmajor; ++i)
{
vtkm::Float64 xc = x0 + (x1-x0) * maj_proportions[i];
vtkm::Float64 yc = y0 + (y1-y0) * maj_proportions[i];
vtkm::Float64 xs = xc - maj_tx*maj_toff;
vtkm::Float64 xe = xc + maj_tx*(1. - maj_toff);
vtkm::Float64 ys = yc - maj_ty*maj_toff;
vtkm::Float64 ye = yc + maj_ty*(1. - maj_toff);
canvas.AddLine(xs,ys, xe,ye, 1.0, color);
if (maj_ty == 0)
{
// slight shift to space between label and tick
xs -= (maj_tx<0?-1.:+1.) * fontscale * .1;
}
numberToString.str("");
numberToString << maj_positions[i];
labels[i]->SetText(numberToString.str());
//if (fabs(maj_positions[i]) < 1e-10)
// labels[i]->SetText("0");
((ScreenTextAnnotation*)(labels[i]))->SetPosition(vtkm::Float32(xs),
vtkm::Float32(ys));
labels[i]->SetAlignment(halign,valign);
}
// minor ticks
if (min_tx != 0 || min_ty != 0)
{
unsigned int nminor = (unsigned int)min_proportions.size();
for (unsigned int i=0; i<nminor; ++i)
{
vtkm::Float64 xc = x0 + (x1-x0) * min_proportions[i];
vtkm::Float64 yc = y0 + (y1-y0) * min_proportions[i];
vtkm::Float64 xs = xc - min_tx*min_toff;
vtkm::Float64 xe = xc + min_tx*(1. - min_toff);
vtkm::Float64 ys = yc - min_ty*min_toff;
vtkm::Float64 ye = yc + min_ty*(1. - min_toff);
canvas.AddLine(xs,ys, xe,ye, 1.0, color);
}
}
for (unsigned int i=0; i<nmajor; ++i)
{
labels[i]->Render(camera, worldAnnotator, canvas);
}
}
VTKM_RENDERING_EXPORT
void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas) VTKM_OVERRIDE;
};
}} //namespace vtkm::rendering

@ -0,0 +1,191 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/AxisAnnotation3D.h>
namespace vtkm {
namespace rendering {
AxisAnnotation3D::AxisAnnotation3D()
: AxisAnnotation(),
TickMajorSize(1.0),
TickMajorOffset(1.0),
TickMinorSize(0.1),
TickMinorOffset(1.0),
Axis(0),
Invert(1, 1, 1),
Point0(0, 0, 0),
Point1(1, 0, 0),
Range(0, 1),
FontScale(0.05f), // screen space font size
FontOffset(0.1f), // world space offset from axis
LineWidth(1.0),
Color(1,1,1),
MoreOrLessTickAdjustment(0)
{ }
AxisAnnotation3D::~AxisAnnotation3D()
{ }
void AxisAnnotation3D::SetTickInvert(bool x, bool y, bool z)
{
this->Invert[0] = x ? +1.0f : -1.0f;
this->Invert[1] = y ? +1.0f : -1.0f;
this->Invert[2] = z ? +1.0f : -1.0f;
}
void AxisAnnotation3D::SetLabelFontScale(Float64 s)
{
this->FontScale = s;
for (unsigned int i=0; i<this->Labels.size(); i++)
{
this->Labels[i]->SetScale(vtkm::Float32(s));
}
}
void AxisAnnotation3D::Render(const Camera &camera,
const WorldAnnotator &worldAnnotator,
Canvas &canvas)
{
bool infront = true;
worldAnnotator.AddLine(this->Point0,this->Point1,this->LineWidth,this->Color,infront);
std::vector<vtkm::Float64> positions;
std::vector<vtkm::Float64> proportions;
// major ticks
CalculateTicks(this->Range, false, positions, proportions, this->MoreOrLessTickAdjustment);
unsigned int nmajor = (unsigned int)proportions.size();
while (this->Labels.size() < nmajor)
{
this->Labels.push_back(new TextAnnotationBillboard(
"test",
this->Color,
vtkm::Float32(this->FontScale),
vtkm::Vec<vtkm::Float32,3>(0,0,0),
0));
}
std::stringstream numberToString;
for (unsigned int i=0; i<nmajor; ++i)
{
vtkm::Vec<vtkm::Float64,3> tickPos =
proportions[i]*(this->Point1-this->Point0) + this->Point0;
for (int pass=0; pass<=1; pass++)
{
vtkm::Vec<vtkm::Float64,3> tickSize(0);
if (pass == 0)
{
switch (this->Axis)
{
case 0: tickSize[1] = this->TickMajorSize; break;
case 1: tickSize[0] = this->TickMajorSize; break;
case 2: tickSize[0] = this->TickMajorSize; break;
}
}
else // pass == 1
{
switch (this->Axis)
{
case 0: tickSize[2] = this->TickMajorSize; break;
case 1: tickSize[2] = this->TickMajorSize; break;
case 2: tickSize[1] = this->TickMajorSize; break;
}
}
tickSize = tickSize * this->Invert;
vtkm::Vec<vtkm::Float64,3> start =
tickPos - tickSize*this->TickMajorOffset;
vtkm::Vec<vtkm::Float64,3> end =
tickPos - tickSize*(1.0 - this->TickMajorOffset);
worldAnnotator.AddLine(start,
end,
this->LineWidth,
this->Color,
infront);
}
vtkm::Vec<vtkm::Float32,3> tickSize(0);
vtkm::Float32 s = 0.4f * this->FontOffset;
switch (this->Axis)
{
case 0: tickSize[1]=s; tickSize[2]=s; break;
case 1: tickSize[0]=s; tickSize[2]=s; break;
case 2: tickSize[0]=s; tickSize[1]=s; break;
}
tickSize = tickSize * this->Invert;
numberToString.str("");
numberToString << positions[i];
this->Labels[i]->SetText(numberToString.str());
//if (fabs(positions[i]) < 1e-10)
// this->Labels[i]->SetText("0");
this->Labels[i]->SetPosition(vtkm::Float32(tickPos[0] - tickSize[0]),
vtkm::Float32(tickPos[1] - tickSize[1]),
vtkm::Float32(tickPos[2] - tickSize[2]));
this->Labels[i]->SetAlignment(TextAnnotation::HCenter,
TextAnnotation::VCenter);
}
// minor ticks
CalculateTicks(this->Range, true, positions, proportions, this->MoreOrLessTickAdjustment);
unsigned int nminor = (unsigned int)proportions.size();
for (unsigned int i=0; i<nminor; ++i)
{
vtkm::Vec<vtkm::Float64,3> tickPos =
proportions[i]*(this->Point1-this->Point0) + this->Point0;
for (int pass=0; pass<=1; pass++)
{
vtkm::Vec<vtkm::Float64,3> tickSize(0);
if (pass == 0)
{
switch (this->Axis)
{
case 0: tickSize[1] = this->TickMajorSize; break;
case 1: tickSize[0] = this->TickMajorSize; break;
case 2: tickSize[0] = this->TickMajorSize; break;
}
}
else // pass == 1
{
switch (this->Axis)
{
case 0: tickSize[2] = this->TickMajorSize; break;
case 1: tickSize[2] = this->TickMajorSize; break;
case 2: tickSize[1] = this->TickMajorSize; break;
}
}
tickSize = tickSize * this->Invert;
vtkm::Vec<vtkm::Float64,3> start =
tickPos - tickSize*this->TickMinorOffset;
vtkm::Vec<vtkm::Float64,3> end =
tickPos - tickSize*(1.0 - this->TickMinorOffset);
worldAnnotator.AddLine(start, end, this->LineWidth, this->Color, infront);
}
}
for (unsigned int i=0; i<nmajor; ++i)
{
this->Labels[i]->Render(camera, worldAnnotator, canvas);
}
}
}
} // namespace vtkm::rendering

@ -20,13 +20,16 @@
#ifndef vtk_m_rendering_AxisAnnotation3D_h
#define vtk_m_rendering_AxisAnnotation3D_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/Range.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/WorldAnnotator.h>
#include <vtkm/rendering/AxisAnnotation.h>
#include <vtkm/rendering/TextAnnotation.h>
#include <vtkm/rendering/TextAnnotationBillboard.h>
#include <sstream>
@ -37,204 +40,102 @@ class AxisAnnotation3D : public AxisAnnotation
{
private:
protected:
vtkm::Float64 maj_size, maj_toff;
vtkm::Float64 min_size, min_toff;
int axis;
vtkm::Float32 invertx, inverty, invertz;
vtkm::Float64 x0, y0, z0, x1, y1, z1;
vtkm::Float64 lower, upper;
vtkm::Float64 fontscale;
vtkm::Float32 fontoffset;
vtkm::Float32 linewidth;
vtkm::rendering::Color color;
std::vector<BillboardTextAnnotation*> labels;
int moreOrLessTickAdjustment;
vtkm::Float64 TickMajorSize, TickMajorOffset;
vtkm::Float64 TickMinorSize, TickMinorOffset;
int Axis;
vtkm::Vec<vtkm::Float32,3> Invert;
vtkm::Vec<vtkm::Float64,3> Point0, Point1;
vtkm::Range Range;
vtkm::Float64 FontScale;
vtkm::Float32 FontOffset;
vtkm::Float32 LineWidth;
vtkm::rendering::Color Color;
std::vector<TextAnnotationBillboard*> Labels;
int MoreOrLessTickAdjustment;
public:
AxisAnnotation3D() : AxisAnnotation()
{
axis = 0;
color = Color(1,1,1);
fontoffset = 0.1f; // world space offset from axis
fontscale = 0.05; // screen space font size
linewidth = 1.0;
color = Color(1,1,1);
moreOrLessTickAdjustment = 0;
}
virtual ~AxisAnnotation3D()
{
}
VTKM_RENDERING_EXPORT
AxisAnnotation3D();
VTKM_RENDERING_EXPORT
~AxisAnnotation3D();
VTKM_CONT_EXPORT
void SetMoreOrLessTickAdjustment(int offset)
{
moreOrLessTickAdjustment = offset;
this->MoreOrLessTickAdjustment = offset;
}
VTKM_CONT_EXPORT
void SetColor(vtkm::rendering::Color c)
{
color = c;
this->Color = c;
}
VTKM_CONT_EXPORT
void SetAxis(int a)
{
axis = a;
}
void SetTickInvert(bool x, bool y, bool z)
{
invertx = x ? +1.0f : -1.0f;
inverty = y ? +1.0f : -1.0f;
invertz = z ? +1.0f : -1.0f;
this->Axis = a;
}
VTKM_RENDERING_EXPORT
void SetTickInvert(bool x, bool y, bool z);
/// offset of 0 means the tick is inside the frame
/// offset of 1 means the tick is outside the frame
/// offset of 0.5 means the tick is centered on the frame
VTKM_CONT_EXPORT
void SetMajorTickSize(vtkm::Float64 size, vtkm::Float64 offset)
{
/// offset of 0 means the tick is inside the frame
/// offset of 1 means the tick is outside the frame
/// offset of 0.5 means the tick is centered on the frame
maj_size = size;
maj_toff = offset;
this->TickMajorSize = size;
this->TickMajorOffset = offset;
}
VTKM_CONT_EXPORT
void SetMinorTickSize(vtkm::Float64 size, vtkm::Float64 offset)
{
min_size = size;
min_toff = offset;
this->TickMinorSize = size;
this->TickMinorOffset = offset;
}
void SetWorldPosition(vtkm::Float64 x0_, vtkm::Float64 y0_, vtkm::Float64 z0_,
vtkm::Float64 x1_, vtkm::Float64 y1_, vtkm::Float64 z1_)
{
x0 = x0_;
y0 = y0_;
z0 = z0_;
x1 = x1_;
y1 = y1_;
z1 = z1_;
}
void SetLabelFontScale(vtkm::Float64 s)
VTKM_CONT_EXPORT
void SetWorldPosition(const vtkm::Vec<vtkm::Float64,3> &point0,
const vtkm::Vec<vtkm::Float64,3> &point1)
{
fontscale = s;
for (unsigned int i=0; i<labels.size(); i++)
labels[i]->SetScale(vtkm::Float32(s));
this->Point0 = point0;
this->Point1 = point1;
}
VTKM_CONT_EXPORT
void SetWorldPosition(vtkm::Float64 x0, vtkm::Float64 y0, vtkm::Float64 z0,
vtkm::Float64 x1, vtkm::Float64 y1, vtkm::Float64 z1)
{
this->SetWorldPosition(vtkm::make_Vec(x0,y0,z0), vtkm::make_Vec(x1,y1,z1));
}
VTKM_RENDERING_EXPORT
void SetLabelFontScale(vtkm::Float64 s);
VTKM_RENDERING_EXPORT
void SetLabelFontOffset(vtkm::Float32 off)
{
fontoffset = off;
this->FontOffset = off;
}
void SetRange(vtkm::Float64 l, vtkm::Float64 u)
VTKM_RENDERING_EXPORT
void SetRange(const vtkm::Range &range)
{
lower = l;
upper = u;
this->Range = range;
}
VTKM_RENDERING_EXPORT
void SetRange(vtkm::Float64 lower, vtkm::Float64 upper)
{
this->SetRange(vtkm::Range(lower, upper));
}
virtual void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas)
{
bool infront = true;
worldAnnotator.AddLine(x0,y0,z0,
x1,y1,z1,
linewidth, color, infront);
std::vector<vtkm::Float64> positions;
std::vector<vtkm::Float64> proportions;
// major ticks
CalculateTicks(lower, upper, false, positions, proportions, moreOrLessTickAdjustment);
unsigned int nmajor = (unsigned int)proportions.size();
while (labels.size() < nmajor)
{
labels.push_back(new BillboardTextAnnotation("test",
color,
vtkm::Float32(fontscale),
0,0,0,
0));
}
std::stringstream numberToString;
for (unsigned int i=0; i<nmajor; ++i)
{
vtkm::Float64 xc = x0 + (x1-x0) * proportions[i];
vtkm::Float64 yc = y0 + (y1-y0) * proportions[i];
vtkm::Float64 zc = z0 + (z1-z0) * proportions[i];
for (int pass=0; pass<=1; pass++)
{
vtkm::Float64 tx=0, ty=0, tz=0;
switch (axis)
{
case 0: if (pass==0) ty=maj_size; else tz=maj_size; break;
case 1: if (pass==0) tx=maj_size; else tz=maj_size; break;
case 2: if (pass==0) tx=maj_size; else ty=maj_size; break;
}
tx *= invertx;
ty *= inverty;
tz *= invertz;
vtkm::Float64 xs = xc - tx*maj_toff;
vtkm::Float64 xe = xc + tx*(1. - maj_toff);
vtkm::Float64 ys = yc - ty*maj_toff;
vtkm::Float64 ye = yc + ty*(1. - maj_toff);
vtkm::Float64 zs = zc - tz*maj_toff;
vtkm::Float64 ze = zc + tz*(1. - maj_toff);
worldAnnotator.AddLine(xs,ys,zs,
xe,ye,ze,
linewidth, color, infront);
}
vtkm::Float32 tx=0, ty=0, tz=0;
const vtkm::Float32 s = 0.4f;
switch (axis)
{
case 0: ty=s*fontoffset; tz=s*fontoffset; break;
case 1: tx=s*fontoffset; tz=s*fontoffset; break;
case 2: tx=s*fontoffset; ty=s*fontoffset; break;
}
tx *= invertx;
ty *= inverty;
tz *= invertz;
numberToString.str("");
numberToString << positions[i];
labels[i]->SetText(numberToString.str());
//if (fabs(positions[i]) < 1e-10)
// labels[i]->SetText("0");
labels[i]->SetPosition(vtkm::Float32(xc - tx),
vtkm::Float32(yc - ty),
vtkm::Float32(zc - tz));
labels[i]->SetAlignment(TextAnnotation::HCenter,
TextAnnotation::VCenter);
}
// minor ticks
CalculateTicks(lower, upper, true, positions, proportions, moreOrLessTickAdjustment);
unsigned int nminor = (unsigned int)proportions.size();
for (unsigned int i=0; i<nminor; ++i)
{
vtkm::Float64 xc = x0 + (x1-x0) * proportions[i];
vtkm::Float64 yc = y0 + (y1-y0) * proportions[i];
vtkm::Float64 zc = z0 + (z1-z0) * proportions[i];
for (int pass=0; pass<=1; pass++)
{
vtkm::Float64 tx=0, ty=0, tz=0;
switch (axis)
{
case 0: if (pass==0) ty=min_size; else tz=min_size; break;
case 1: if (pass==0) tx=min_size; else tz=min_size; break;
case 2: if (pass==0) tx=min_size; else ty=min_size; break;
}
tx *= invertx;
ty *= inverty;
tz *= invertz;
vtkm::Float64 xs = xc - tx*min_toff;
vtkm::Float64 xe = xc + tx*(1. - min_toff);
vtkm::Float64 ys = yc - ty*min_toff;
vtkm::Float64 ye = yc + ty*(1. - min_toff);
vtkm::Float64 zs = zc - tz*min_toff;
vtkm::Float64 ze = zc + tz*(1. - min_toff);
worldAnnotator.AddLine(xs,ys,zs,
xe,ye,ze,
linewidth, color, infront);
}
}
for (unsigned int i=0; i<nmajor; ++i)
{
labels[i]->Render(camera, worldAnnotator, canvas);
}
}
vtkm::rendering::Canvas &canvas) VTKM_OVERRIDE;
};

@ -0,0 +1,95 @@
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//
//=============================================================================
#include <vtkm/rendering/BitmapFont.h>
namespace vtkm {
namespace rendering {
BitmapFont::BitmapFont()
{
for (int i=0; i<256; ++i)
ShortMap[i] = 0;
this->PadL=0;
this->PadR=0;
this->PadT=0;
this->PadB=0;
}
const vtkm::rendering::BitmapFont::Character &
BitmapFont::GetChar(char c) const
{
std::size_t mappedCharIndex =
static_cast<std::size_t>(this->ShortMap[(unsigned char)c]);
return this->Chars[mappedCharIndex];
}
vtkm::Float32
BitmapFont::GetTextWidth(const std::string &text) const
{
vtkm::Float32 width = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
Character c = this->GetChar(text[i]);
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
const bool kerning = true;
if (kerning && nextchar>0)
width += vtkm::Float32(c.kern[int(nextchar)]) / vtkm::Float32(this->Height);
width += vtkm::Float32(c.adv) / vtkm::Float32(this->Height);
}
return width;
}
void BitmapFont::GetCharPolygon(char character,
vtkm::Float32 &x, vtkm::Float32 &y,
vtkm::Float32 &vl, vtkm::Float32 &vr,
vtkm::Float32 &vt, vtkm::Float32 &vb,
vtkm::Float32 &tl, vtkm::Float32 &tr,
vtkm::Float32 &tt, vtkm::Float32 &tb,
char nextchar) const
{
Character c = this->GetChar(character);
// By default, the origin for the font is at the
// baseline. That's nice, but we'd rather it
// be at the actual bottom, so create an offset.
vtkm::Float32 yoff = -vtkm::Float32(this->Descender) / vtkm::Float32(this->Height);
tl = vtkm::Float32(c.x + this->PadL) / vtkm::Float32(this->ImgW);
tr = vtkm::Float32(c.x + c.w - this->PadR) / vtkm::Float32(this->ImgW);
tt = 1.f - vtkm::Float32(c.y + this->PadT) / vtkm::Float32(this->ImgH);
tb = 1.f - vtkm::Float32(c.y + c.h - this->PadB) / vtkm::Float32(this->ImgH);
vl = x + vtkm::Float32(c.offx + this->PadL) / vtkm::Float32(this->Height);
vr = x + vtkm::Float32(c.offx + c.w - this->PadR) / vtkm::Float32(this->Height);
vt = yoff + y + vtkm::Float32(c.offy - this->PadT) / vtkm::Float32(this->Height);
vb = yoff + y + vtkm::Float32(c.offy - c.h + this->PadB) / vtkm::Float32(this->Height);
const bool kerning = true;
if (kerning && nextchar>0)
x += vtkm::Float32(c.kern[int(nextchar)]) / vtkm::Float32(this->Height);
x += vtkm::Float32(c.adv) / vtkm::Float32(this->Height);
}
}
} // namespace vtkm::rendering

@ -22,6 +22,8 @@
#ifndef vtk_m_BitmapFont_h
#define vtk_m_BitmapFont_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/Types.h>
#include <string>
@ -62,7 +64,9 @@ public:
void ResetKerning()
{
for (int i=0; i<256; i++)
{
kern[i]=0;
}
}
};
@ -79,617 +83,27 @@ public:
std::vector<unsigned char> RawImageFileData;
public:
BitmapFont()
{
for (int i=0; i<256; ++i)
ShortMap[i] = 0;
this->PadL=0;
this->PadR=0;
this->PadT=0;
this->PadB=0;
}
Character GetChar(char c) const
{
std::size_t mappedCharIndex =
static_cast<std::size_t>(this->ShortMap[(unsigned char)c]);
return this->Chars[mappedCharIndex];
}
VTKM_RENDERING_EXPORT
BitmapFont();
VTKM_RENDERING_EXPORT
const Character &GetChar(char c) const;
VTKM_CONT_EXPORT
const std::vector<unsigned char> &GetRawImageData() const
{
return this->RawImageFileData;
}
vtkm::Float32 GetTextWidth(const std::string &text) const
{
vtkm::Float32 width = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
Character c = this->GetChar(text[i]);
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
const bool kerning = true;
if (kerning && nextchar>0)
width += vtkm::Float32(c.kern[int(nextchar)]) / vtkm::Float32(this->Height);
width += vtkm::Float32(c.adv) / vtkm::Float32(this->Height);
}
return width;
}
VTKM_RENDERING_EXPORT
vtkm::Float32 GetTextWidth(const std::string &text) const;
void GetCharPolygon(char character, vtkm::Float32 &x, vtkm::Float32 &y,
vtkm::Float32 &vl, vtkm::Float32 &vr, vtkm::Float32 &vt, vtkm::Float32 &vb,
vtkm::Float32 &tl, vtkm::Float32 &tr, vtkm::Float32 &tt, vtkm::Float32 &tb,
char nextchar = 0) const
{
Character c = this->GetChar(character);
// By default, the origin for the font is at the
// baseline. That's nice, but we'd rather it
// be at the actual bottom, so create an offset.
vtkm::Float32 yoff = -vtkm::Float32(this->Descender) / vtkm::Float32(this->Height);
tl = vtkm::Float32(c.x + this->PadL) / vtkm::Float32(this->ImgW);
tr = vtkm::Float32(c.x + c.w - this->PadR) / vtkm::Float32(this->ImgW);
tt = 1.f - vtkm::Float32(c.y + this->PadT) / vtkm::Float32(this->ImgH);
tb = 1.f - vtkm::Float32(c.y + c.h - this->PadB) / vtkm::Float32(this->ImgH);
vl = x + vtkm::Float32(c.offx + this->PadL) / vtkm::Float32(this->Height);
vr = x + vtkm::Float32(c.offx + c.w - this->PadR) / vtkm::Float32(this->Height);
vt = yoff + y + vtkm::Float32(c.offy - this->PadT) / vtkm::Float32(this->Height);
vb = yoff + y + vtkm::Float32(c.offy - c.h + this->PadB) / vtkm::Float32(this->Height);
const bool kerning = true;
if (kerning && nextchar>0)
x += vtkm::Float32(c.kern[int(nextchar)]) / vtkm::Float32(this->Height);
x += vtkm::Float32(c.adv) / vtkm::Float32(this->Height);
}
char nextchar = 0) const;
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Below is the PicoPNG source file obtained 2013-01-07 from
// http://lodev.org/lodepng/picopng.cpp. It has the following
// modifications relative to the original:
// 1. decodePNG() was made static.
// 2. std:: qualify size_t
// 3. main() and helper code at the bottom of the file was removed.
// 4. remove unused known_type variable.
// 5. added explicit casts to remove compiler warnings
// 6. renamed a function argument to avoid a shadowing warning
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#include <vector>
/*
decodePNG: The picoPNG function, decodes a PNG file buffer in memory, into a raw pixel buffer.
out_image: output parameter, this will contain the raw pixels after decoding.
By default the output is 32-bit RGBA color.
The std::vector is automatically resized to the correct size.
image_width: output_parameter, this will contain the width of the image in pixels.
image_height: output_parameter, this will contain the height of the image in pixels.
in_png: pointer to the buffer of the PNG file in memory. To get it from a file on
disk, load it and store it in a memory buffer yourself first.
in_size: size of the input PNG file in bytes.
convert_to_rgba32: optional parameter, true by default.
Set to true to get the output in RGBA 32-bit (8 bit per channel) color format
no matter what color type the original PNG image had. This gives predictable,
useable data from any random input PNG.
Set to false to do no color conversion at all. The result then has the same data
type as the PNG image, which can range from 1 bit to 64 bits per pixel.
Information about the color type or palette colors are not provided. You need
to know this information yourself to be able to use the data so this only
works for trusted PNG files. Use LodePNG instead of picoPNG if you need this information.
return: 0 if success, not 0 if some error occured.
*/
VTKM_CONT_EXPORT
int decodePNG(std::vector<unsigned char>& out_image, unsigned long& image_width, unsigned long& image_height, const unsigned char* in_png, std::size_t in_size, bool convert_to_rgba32=true)
{
// picoPNG version 20101224
// Copyright (c) 2005-2010 Lode Vandevenne
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
// picoPNG is a PNG decoder in one C++ function of around 500 lines. Use picoPNG for
// programs that need only 1 .cpp file. Since it's a single function, it's very limited,
// it can convert a PNG to raw pixel data either converted to 32-bit RGBA color or
// with no color conversion at all. For anything more complex, another tiny library
// is available: LodePNG (lodepng.c(pp)), which is a single source and header file.
// Apologies for the compact code style, it's to make this tiny.
static const unsigned long LENBASE[29] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
static const unsigned long LENEXTRA[29] = {0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
static const unsigned long DISTBASE[30] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
static const unsigned long DISTEXTRA[30] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
static const unsigned long CLCL[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; //code length code lengths
struct Zlib //nested functions for zlib decompression
{
static unsigned long readBitFromStream(std::size_t& bitp, const unsigned char* bits) { unsigned long result = (bits[bitp >> 3] >> (bitp & 0x7)) & 1; bitp++; return result;}
static unsigned long readBitsFromStream(std::size_t& bitp, const unsigned char* bits, std::size_t nbits)
{
unsigned long result = 0;
for(std::size_t i = 0; i < nbits; i++) result += (readBitFromStream(bitp, bits)) << i;
return result;
}
struct HuffmanTree
{
int makeFromLengths(const std::vector<unsigned long>& bitlen, unsigned long maxbitlen)
{ //make tree given the lengths
unsigned long numcodes = (unsigned long)(bitlen.size()), treepos = 0, nodefilled = 0;
std::vector<unsigned long> tree1d(numcodes), blcount(maxbitlen + 1, 0), nextcode(maxbitlen + 1, 0);
for(unsigned long bits = 0; bits < numcodes; bits++) blcount[bitlen[bits]]++; //count number of instances of each code length
for(unsigned long bits = 1; bits <= maxbitlen; bits++) nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1;
for(unsigned long n = 0; n < numcodes; n++) if(bitlen[n] != 0) tree1d[n] = nextcode[bitlen[n]]++; //generate all the codes
tree2d.clear(); tree2d.resize(numcodes * 2, 32767); //32767 here means the tree2d isn't filled there yet
for(unsigned long n = 0; n < numcodes; n++) //the codes
for(unsigned long i = 0; i < bitlen[n]; i++) //the bits for this code
{
unsigned long bit = (tree1d[n] >> (bitlen[n] - i - 1)) & 1;
if(treepos > numcodes - 2) return 55;
if(tree2d[2 * treepos + bit] == 32767) //not yet filled in
{
if(i + 1 == bitlen[n]) { tree2d[2 * treepos + bit] = n; treepos = 0; } //last bit
else { tree2d[2 * treepos + bit] = ++nodefilled + numcodes; treepos = nodefilled; } //addresses are encoded as values > numcodes
}
else treepos = tree2d[2 * treepos + bit] - numcodes; //subtract numcodes from address to get address value
}
return 0;
}
int decode(bool& decoded, unsigned long& result, std::size_t& treepos, unsigned long bit) const
{ //Decodes a symbol from the tree
unsigned long numcodes = (unsigned long)tree2d.size() / 2;
if(treepos >= numcodes) return 11; //error: you appeared outside the codetree
result = tree2d[2 * treepos + bit];
decoded = (result < numcodes);
treepos = decoded ? 0 : result - numcodes;
return 0;
}
std::vector<unsigned long> tree2d; //2D representation of a huffman tree: The one dimension is "0" or "1", the other contains all nodes and leaves of the tree.
};
struct Inflator
{
int error;
void inflate(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, std::size_t inpos = 0)
{
std::size_t bp = 0, pos = 0; //bit pointer and byte pointer
error = 0;
unsigned long BFINAL = 0;
while(!BFINAL && !error)
{
if(bp >> 3 >= in.size()) { error = 52; return; } //error, bit pointer will jump past memory
BFINAL = readBitFromStream(bp, &in[inpos]);
unsigned long BTYPE = readBitFromStream(bp, &in[inpos]); BTYPE += 2 * readBitFromStream(bp, &in[inpos]);
if(BTYPE == 3) { error = 20; return; } //error: invalid BTYPE
else if(BTYPE == 0) inflateNoCompression(out, &in[inpos], bp, pos, in.size());
else inflateHuffmanBlock(out, &in[inpos], bp, pos, in.size(), BTYPE);
}
if(!error) out.resize(pos); //Only now we know the true size of out, resize it to that
}
void generateFixedTrees(HuffmanTree& tree, HuffmanTree& treeD) //get the tree of a deflated block with fixed tree
{
std::vector<unsigned long> bitlen(288, 8), bitlenD(32, 5);;
for(std::size_t i = 144; i <= 255; i++) bitlen[i] = 9;
for(std::size_t i = 256; i <= 279; i++) bitlen[i] = 7;
tree.makeFromLengths(bitlen, 15);
treeD.makeFromLengths(bitlenD, 15);
}
HuffmanTree codetree, codetreeD, codelengthcodetree; //the code tree for Huffman codes, dist codes, and code length codes
unsigned long huffmanDecodeSymbol(const unsigned char* in, std::size_t& bp, const HuffmanTree& lcodetree, std::size_t inlength)
{ //decode a single symbol from given list of bits with given code tree. return value is the symbol
bool decoded; unsigned long ct;
for(std::size_t treepos = 0;;)
{
if((bp & 0x07) == 0 && (bp >> 3) > inlength) { error = 10; return 0; } //error: end reached without endcode
error = lcodetree.decode(decoded, ct, treepos, readBitFromStream(bp, in)); if(error) return 0; //stop, an error happened
if(decoded) return ct;
}
}
void getTreeInflateDynamic(HuffmanTree& tree, HuffmanTree& treeD, const unsigned char* in, std::size_t& bp, std::size_t inlength)
{ //get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree
std::vector<unsigned long> bitlen(288, 0), bitlenD(32, 0);
if(bp >> 3 >= inlength - 2) { error = 49; return; } //the bit pointer is or will go past the memory
std::size_t HLIT = readBitsFromStream(bp, in, 5) + 257; //number of literal/length codes + 257
std::size_t HDIST = readBitsFromStream(bp, in, 5) + 1; //number of dist codes + 1
std::size_t HCLEN = readBitsFromStream(bp, in, 4) + 4; //number of code length codes + 4
std::vector<unsigned long> codelengthcode(19); //lengths of tree to decode the lengths of the dynamic tree
for(std::size_t i = 0; i < 19; i++) codelengthcode[CLCL[i]] = (i < HCLEN) ? readBitsFromStream(bp, in, 3) : 0;
error = codelengthcodetree.makeFromLengths(codelengthcode, 7); if(error) return;
std::size_t i = 0, replength;
while(i < HLIT + HDIST)
{
unsigned long code = huffmanDecodeSymbol(in, bp, codelengthcodetree, inlength); if(error) return;
if(code <= 15) { if(i < HLIT) bitlen[i++] = code; else bitlenD[i++ - HLIT] = code; } //a length code
else if(code == 16) //repeat previous
{
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
replength = 3 + readBitsFromStream(bp, in, 2);
unsigned long value; //set value to the previous code
if((i - 1) < HLIT) value = bitlen[i - 1];
else value = bitlenD[i - HLIT - 1];
for(std::size_t n = 0; n < replength; n++) //repeat this value in the next lengths
{
if(i >= HLIT + HDIST) { error = 13; return; } //error: i is larger than the amount of codes
if(i < HLIT) bitlen[i++] = value; else bitlenD[i++ - HLIT] = value;
}
}
else if(code == 17) //repeat "0" 3-10 times
{
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
replength = 3 + readBitsFromStream(bp, in, 3);
for(std::size_t n = 0; n < replength; n++) //repeat this value in the next lengths
{
if(i >= HLIT + HDIST) { error = 14; return; } //error: i is larger than the amount of codes
if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
}
}
else if(code == 18) //repeat "0" 11-138 times
{
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
replength = 11 + readBitsFromStream(bp, in, 7);
for(std::size_t n = 0; n < replength; n++) //repeat this value in the next lengths
{
if(i >= HLIT + HDIST) { error = 15; return; } //error: i is larger than the amount of codes
if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
}
}
else { error = 16; return; } //error: somehow an unexisting code appeared. This can never happen.
}
if(bitlen[256] == 0) { error = 64; return; } //the length of the end code 256 must be larger than 0
error = tree.makeFromLengths(bitlen, 15); if(error) return; //now we've finally got HLIT and HDIST, so generate the code trees, and the function is done
error = treeD.makeFromLengths(bitlenD, 15); if(error) return;
}
void inflateHuffmanBlock(std::vector<unsigned char>& out, const unsigned char* in, std::size_t& bp, std::size_t& pos, std::size_t inlength, unsigned long btype)
{
if(btype == 1) { generateFixedTrees(codetree, codetreeD); }
else if(btype == 2) { getTreeInflateDynamic(codetree, codetreeD, in, bp, inlength); if(error) return; }
for(;;)
{
unsigned long code = huffmanDecodeSymbol(in, bp, codetree, inlength); if(error) return;
if(code == 256) return; //end code
else if(code <= 255) //literal symbol
{
if(pos >= out.size()) out.resize((pos + 1) * 2); //reserve more room
out[pos++] = (unsigned char)(code);
}
else if(code >= 257 && code <= 285) //length code
{
std::size_t length = LENBASE[code - 257], numextrabits = LENEXTRA[code - 257];
if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
length += readBitsFromStream(bp, in, numextrabits);
unsigned long codeD = huffmanDecodeSymbol(in, bp, codetreeD, inlength); if(error) return;
if(codeD > 29) { error = 18; return; } //error: invalid dist code (30-31 are never used)
unsigned long dist = DISTBASE[codeD], numextrabitsD = DISTEXTRA[codeD];
if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
dist += readBitsFromStream(bp, in, numextrabitsD);
std::size_t start = pos, back = start - dist; //backwards
if(pos + length >= out.size()) out.resize((pos + length) * 2); //reserve more room
for(std::size_t i = 0; i < length; i++) { out[pos++] = out[back++]; if(back >= start) back = start - dist; }
}
}
}
void inflateNoCompression(std::vector<unsigned char>& out, const unsigned char* in, std::size_t& bp, std::size_t& pos, std::size_t inlength)
{
while((bp & 0x7) != 0) bp++; //go to first boundary of byte
std::size_t p = bp / 8;
if(p >= inlength - 4) { error = 52; return; } //error, bit pointer will jump past memory
unsigned long LEN = in[p] + 256 * in[p + 1], NLEN = in[p + 2] + 256 * in[p + 3]; p += 4;
if(LEN + NLEN != 65535) { error = 21; return; } //error: NLEN is not one's complement of LEN
if(pos + LEN >= out.size()) out.resize(pos + LEN);
if(p + LEN > inlength) { error = 23; return; } //error: reading outside of in buffer
for(unsigned long n = 0; n < LEN; n++) out[pos++] = in[p++]; //read LEN bytes of literal data
bp = p * 8;
}
};
int decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in) //returns error value
{
Inflator inflator;
if(in.size() < 2) { return 53; } //error, size of zlib data too small
if((in[0] * 256 + in[1]) % 31 != 0) { return 24; } //error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way
unsigned long CM = in[0] & 15, CINFO = (in[0] >> 4) & 15, FDICT = (in[1] >> 5) & 1;
if(CM != 8 || CINFO > 7) { return 25; } //error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec
if(FDICT != 0) { return 26; } //error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."
inflator.inflate(out, in, 2);
return inflator.error; //note: adler32 checksum was skipped and ignored
}
};
struct PNG //nested functions for PNG decoding
{
struct Info
{
unsigned long width, height, colorType, bitDepth, compressionMethod, filterMethod, interlaceMethod, key_r, key_g, key_b;
bool key_defined; //is a transparent color key given?
std::vector<unsigned char> palette;
} info;
int error;
void decode(std::vector<unsigned char>& out, const unsigned char* in, std::size_t size, bool convert_to_rgba32_flag)
{
error = 0;
if(size == 0 || in == 0) { error = 48; return; } //the given data is empty
readPngHeader(&in[0], size); if(error) return;
std::size_t pos = 33; //first byte of the first chunk after the header
std::vector<unsigned char> idat; //the data from idat chunks
bool IEND = false;
info.key_defined = false;
while(!IEND) //loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer
{
if(pos + 8 >= size) { error = 30; return; } //error: size of the in buffer too small to contain next chunk
std::size_t chunkLength = read32bitInt(&in[pos]); pos += 4;
if(chunkLength > 2147483647) { error = 63; return; }
if(pos + chunkLength >= size) { error = 35; return; } //error: size of the in buffer too small to contain next chunk
if(in[pos + 0] == 'I' && in[pos + 1] == 'D' && in[pos + 2] == 'A' && in[pos + 3] == 'T') //IDAT chunk, containing compressed image data
{
idat.insert(idat.end(), &in[pos + 4], &in[pos + 4 + chunkLength]);
pos += (4 + chunkLength);
}
else if(in[pos + 0] == 'I' && in[pos + 1] == 'E' && in[pos + 2] == 'N' && in[pos + 3] == 'D') { pos += 4; IEND = true; }
else if(in[pos + 0] == 'P' && in[pos + 1] == 'L' && in[pos + 2] == 'T' && in[pos + 3] == 'E') //palette chunk (PLTE)
{
pos += 4; //go after the 4 letters
info.palette.resize(4 * (chunkLength / 3));
if(info.palette.size() > (4 * 256)) { error = 38; return; } //error: palette too big
for(std::size_t i = 0; i < info.palette.size(); i += 4)
{
for(std::size_t j = 0; j < 3; j++) info.palette[i + j] = in[pos++]; //RGB
info.palette[i + 3] = 255; //alpha
}
}
else if(in[pos + 0] == 't' && in[pos + 1] == 'R' && in[pos + 2] == 'N' && in[pos + 3] == 'S') //palette transparency chunk (tRNS)
{
pos += 4; //go after the 4 letters
if(info.colorType == 3)
{
if(4 * chunkLength > info.palette.size()) { error = 39; return; } //error: more alpha values given than there are palette entries
for(std::size_t i = 0; i < chunkLength; i++) info.palette[4 * i + 3] = in[pos++];
}
else if(info.colorType == 0)
{
if(chunkLength != 2) { error = 40; return; } //error: this chunk must be 2 bytes for greyscale image
info.key_defined = 1; info.key_r = info.key_g = info.key_b = 256 * in[pos] + in[pos + 1]; pos += 2;
}
else if(info.colorType == 2)
{
if(chunkLength != 6) { error = 41; return; } //error: this chunk must be 6 bytes for RGB image
info.key_defined = 1;
info.key_r = 256 * in[pos] + in[pos + 1]; pos += 2;
info.key_g = 256 * in[pos] + in[pos + 1]; pos += 2;
info.key_b = 256 * in[pos] + in[pos + 1]; pos += 2;
}
else { error = 42; return; } //error: tRNS chunk not allowed for other color models
}
else //it's not an implemented chunk type, so ignore it: skip over the data
{
if(!(in[pos + 0] & 32)) { error = 69; return; } //error: unknown critical chunk (5th bit of first byte of chunk type is 0)
pos += (chunkLength + 4); //skip 4 letters and uninterpreted data of unimplemented chunk
}
pos += 4; //step over CRC (which is ignored)
}
unsigned long bpp = getBpp(info);
std::vector<unsigned char> scanlines(((info.width * (info.height * bpp + 7)) / 8) + info.height); //now the out buffer will be filled
Zlib zlib; //decompress with the Zlib decompressor
error = zlib.decompress(scanlines, idat); if(error) return; //stop if the zlib decompressor returned an error
std::size_t bytewidth = (bpp + 7) / 8, outlength = (info.height * info.width * bpp + 7) / 8;
out.resize(outlength); //time to fill the out buffer
unsigned char* out_ = outlength ? &out[0] : 0; //use a regular pointer to the std::vector for faster code if compiled without optimization
if(info.interlaceMethod == 0) //no interlace, just filter
{
std::size_t linestart = 0, linelength = (info.width * bpp + 7) / 8; //length in bytes of a scanline, excluding the filtertype byte
if(bpp >= 8) //byte per byte
for(unsigned long y = 0; y < info.height; y++)
{
unsigned long filterType = scanlines[linestart];
const unsigned char* prevline = (y == 0) ? 0 : &out_[(y - 1) * info.width * bytewidth];
unFilterScanline(&out_[linestart - y], &scanlines[linestart + 1], prevline, bytewidth, filterType, linelength); if(error) return;
linestart += (1 + linelength); //go to start of next scanline
}
else //less than 8 bits per pixel, so fill it up bit per bit
{
std::vector<unsigned char> templine((info.width * bpp + 7) >> 3); //only used if bpp < 8
for(std::size_t y = 0, obp = 0; y < info.height; y++)
{
unsigned long filterType = scanlines[linestart];
const unsigned char* prevline = (y == 0) ? 0 : &out_[(y - 1) * info.width * bytewidth];
unFilterScanline(&templine[0], &scanlines[linestart + 1], prevline, bytewidth, filterType, linelength); if(error) return;
for(std::size_t bp = 0; bp < info.width * bpp;) setBitOfReversedStream(obp, out_, readBitFromReversedStream(bp, &templine[0]));
linestart += (1 + linelength); //go to start of next scanline
}
}
}
else //interlaceMethod is 1 (Adam7)
{
std::size_t passw[7] = { (info.width + 7) / 8, (info.width + 3) / 8, (info.width + 3) / 4, (info.width + 1) / 4, (info.width + 1) / 2, (info.width + 0) / 2, (info.width + 0) / 1 };
std::size_t passh[7] = { (info.height + 7) / 8, (info.height + 7) / 8, (info.height + 3) / 8, (info.height + 3) / 4, (info.height + 1) / 4, (info.height + 1) / 2, (info.height + 0) / 2 };
std::size_t passstart[7] = {0};
std::size_t pattern[28] = {0,4,0,2,0,1,0,0,0,4,0,2,0,1,8,8,4,4,2,2,1,8,8,8,4,4,2,2}; //values for the adam7 passes
for(int i = 0; i < 6; i++) passstart[i + 1] = passstart[i] + passh[i] * ((passw[i] ? 1 : 0) + (passw[i] * bpp + 7) / 8);
std::vector<unsigned char> scanlineo((info.width * bpp + 7) / 8), scanlinen((info.width * bpp + 7) / 8); //"old" and "new" scanline
for(int i = 0; i < 7; i++)
adam7Pass(&out_[0], &scanlinen[0], &scanlineo[0], &scanlines[passstart[i]], info.width, pattern[i], pattern[i + 7], pattern[i + 14], pattern[i + 21], passw[i], passh[i], bpp);
}
if(convert_to_rgba32_flag && (info.colorType != 6 || info.bitDepth != 8)) //conversion needed
{
std::vector<unsigned char> data = out;
error = convert(out, &data[0], info, info.width, info.height);
}
}
void readPngHeader(const unsigned char* in, std::size_t inlength) //read the information from the header and store it in the Info
{
if(inlength < 29) { error = 27; return; } //error: the data length is smaller than the length of the header
if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { error = 28; return; } //no PNG signature
if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') { error = 29; return; } //error: it doesn't start with a IHDR chunk!
info.width = read32bitInt(&in[16]); info.height = read32bitInt(&in[20]);
info.bitDepth = in[24]; info.colorType = in[25];
info.compressionMethod = in[26]; if(in[26] != 0) { error = 32; return; } //error: only compression method 0 is allowed in the specification
info.filterMethod = in[27]; if(in[27] != 0) { error = 33; return; } //error: only filter method 0 is allowed in the specification
info.interlaceMethod = in[28]; if(in[28] > 1) { error = 34; return; } //error: only interlace methods 0 and 1 exist in the specification
error = checkColorValidity(info.colorType, info.bitDepth);
}
void unFilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, std::size_t bytewidth, unsigned long filterType, std::size_t length)
{
switch(filterType)
{
case 0: for(std::size_t i = 0; i < length; i++) recon[i] = scanline[i]; break;
case 1:
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i]);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + recon[i - bytewidth]);
break;
case 2:
if(precon) for(std::size_t i = 0; i < length; i++) recon[i] = (unsigned char)(scanline[i] + precon[i]);
else for(std::size_t i = 0; i < length; i++) recon[i] = (unsigned char)(scanline[i]);
break;
case 3:
if(precon)
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i] + precon[i] / 2);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2));
}
else
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i]);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + recon[i - bytewidth] / 2);
}
break;
case 4:
if(precon)
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(0, precon[i], 0));
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
}
else
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i]);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], 0, 0));
}
break;
default: error = 36; return; //error: unexisting filter type given
}
}
void adam7Pass(unsigned char* out, unsigned char* linen, unsigned char* lineo, const unsigned char* in, unsigned long w, std::size_t passleft, std::size_t passtop, std::size_t spacex, std::size_t spacey, std::size_t passw, std::size_t passh, unsigned long bpp)
{ //filter and reposition the pixels into the output when the image is Adam7 interlaced. This function can only do it after the full image is already decoded. The out buffer must have the correct allocated memory size already.
if(passw == 0) return;
std::size_t bytewidth = (bpp + 7) / 8, linelength = 1 + ((bpp * passw + 7) / 8);
for(unsigned long y = 0; y < passh; y++)
{
unsigned char filterType = in[y * linelength], *prevline = (y == 0) ? 0 : lineo;
unFilterScanline(linen, &in[y * linelength + 1], prevline, bytewidth, filterType, (w * bpp + 7) / 8); if(error) return;
if(bpp >= 8) for(std::size_t i = 0; i < passw; i++) for(std::size_t b = 0; b < bytewidth; b++) //b = current byte of this pixel
out[bytewidth * w * (passtop + spacey * y) + bytewidth * (passleft + spacex * i) + b] = linen[bytewidth * i + b];
else for(std::size_t i = 0; i < passw; i++)
{
std::size_t obp = bpp * w * (passtop + spacey * y) + bpp * (passleft + spacex * i), bp = i * bpp;
for(std::size_t b = 0; b < bpp; b++) setBitOfReversedStream(obp, out, readBitFromReversedStream(bp, &linen[0]));
}
unsigned char* temp = linen; linen = lineo; lineo = temp; //swap the two buffer pointers "line old" and "line new"
}
}
static unsigned long readBitFromReversedStream(std::size_t& bitp, const unsigned char* bits) { unsigned long result = (bits[bitp >> 3] >> (7 - (bitp & 0x7))) & 1; bitp++; return result;}
static unsigned long readBitsFromReversedStream(std::size_t& bitp, const unsigned char* bits, unsigned long nbits)
{
unsigned long result = 0;
for(std::size_t i = nbits - 1; i < nbits; i--) result += ((readBitFromReversedStream(bitp, bits)) << i);
return result;
}
void setBitOfReversedStream(std::size_t& bitp, unsigned char* bits, unsigned long bit) { bits[bitp >> 3] |= (unsigned char)( (bit << (7 - (bitp & 0x7))) ); bitp++; }
unsigned long read32bitInt(const unsigned char* buffer) { return ((unsigned long)buffer[0] << 24) | ((unsigned long)buffer[1] << 16) | ((unsigned long)buffer[2] << 8) | (unsigned long)buffer[3]; }
int checkColorValidity(unsigned long colorType, unsigned long bd) //return type is a LodePNG error code
{
if((colorType == 2 || colorType == 4 || colorType == 6)) { if(!(bd == 8 || bd == 16)) return 37; else return 0; }
else if(colorType == 0) { if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; else return 0; }
else if(colorType == 3) { if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; else return 0; }
else return 31; //unexisting color type
}
unsigned long getBpp(const Info& linfo)
{
if(linfo.colorType == 2) return (3 * linfo.bitDepth);
else if(linfo.colorType >= 4) return (linfo.colorType - 2) * linfo.bitDepth;
else return linfo.bitDepth;
}
int convert(std::vector<unsigned char>& out, const unsigned char* in, Info& infoIn, unsigned long w, unsigned long h)
{ //converts from any color type to 32-bit. return value = LodePNG error code
std::size_t numpixels = w * h, bp = 0;
out.resize(numpixels * 4);
unsigned char* out_ = out.empty() ? 0 : &out[0]; //faster if compiled without optimization
if(infoIn.bitDepth == 8 && infoIn.colorType == 0) //greyscale
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[i];
out_[4 * i + 3] = (infoIn.key_defined && in[i] == infoIn.key_r) ? 0 : 255;
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 2) //RGB color
for(std::size_t i = 0; i < numpixels; i++)
{
for(std::size_t c = 0; c < 3; c++) out_[4 * i + c] = in[3 * i + c];
out_[4 * i + 3] = (infoIn.key_defined == 1 && in[3 * i + 0] == infoIn.key_r && in[3 * i + 1] == infoIn.key_g && in[3 * i + 2] == infoIn.key_b) ? 0 : 255;
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 3) //indexed color (palette)
for(std::size_t i = 0; i < numpixels; i++)
{
if(4U * in[i] >= infoIn.palette.size()) return 46;
for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = infoIn.palette[4 * in[i] + c]; //get rgb colors from the palette
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 4) //greyscale with alpha
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[2 * i + 0];
out_[4 * i + 3] = in[2 * i + 1];
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 6) for(std::size_t i = 0; i < numpixels; i++) for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = in[4 * i + c]; //RGB with alpha
else if(infoIn.bitDepth == 16 && infoIn.colorType == 0) //greyscale
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[2 * i];
out_[4 * i + 3] = (infoIn.key_defined && 256U * in[i] + in[i + 1] == infoIn.key_r) ? 0 : 255;
}
else if(infoIn.bitDepth == 16 && infoIn.colorType == 2) //RGB color
for(std::size_t i = 0; i < numpixels; i++)
{
for(std::size_t c = 0; c < 3; c++) out_[4 * i + c] = in[6 * i + 2 * c];
out_[4 * i + 3] = (infoIn.key_defined && 256U*in[6*i+0]+in[6*i+1] == infoIn.key_r && 256U*in[6*i+2]+in[6*i+3] == infoIn.key_g && 256U*in[6*i+4]+in[6*i+5] == infoIn.key_b) ? 0 : 255;
}
else if(infoIn.bitDepth == 16 && infoIn.colorType == 4) //greyscale with alpha
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[4 * i]; //most significant byte
out_[4 * i + 3] = in[4 * i + 2];
}
else if(infoIn.bitDepth == 16 && infoIn.colorType == 6) for(std::size_t i = 0; i < numpixels; i++) for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = in[8 * i + 2 * c]; //RGB with alpha
else if(infoIn.bitDepth < 8 && infoIn.colorType == 0) //greyscale
for(std::size_t i = 0; i < numpixels; i++)
{
unsigned long value = (readBitsFromReversedStream(bp, in, infoIn.bitDepth) * 255) / ((1 << infoIn.bitDepth) - 1); //scale value from 0 to 255
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = (unsigned char)(value);
out_[4 * i + 3] = (infoIn.key_defined && value && ((1U << infoIn.bitDepth) - 1U) == infoIn.key_r && ((1U << infoIn.bitDepth) - 1U)) ? 0 : 255;
}
else if(infoIn.bitDepth < 8 && infoIn.colorType == 3) //palette
for(std::size_t i = 0; i < numpixels; i++)
{
unsigned long value = readBitsFromReversedStream(bp, in, infoIn.bitDepth);
if(4 * value >= infoIn.palette.size()) return 47;
for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = infoIn.palette[4 * value + c]; //get rgb colors from the palette
}
return 0;
}
unsigned char paethPredictor(short a, short b, short c) //Paeth predicter, used by PNG filter type 4
{
short p = short(a + b - c), pa = short(p > a ? (p - a) : (a - p)), pb = short(p > b ? (p - b) : (b - p)), pc = short(p > c ? (p - c) : (c - p));
return (unsigned char)((pa <= pb && pa <= pc) ? a : pb <= pc ? b : c);
}
};
PNG decoder; decoder.decode(out_image, in_png, in_size, convert_to_rgba32);
image_width = decoder.info.width; image_height = decoder.info.height;
return decoder.error;
}
}} //namespace vtkm::rendering
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,83 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/BoundingBoxAnnotation.h>
namespace vtkm {
namespace rendering {
BoundingBoxAnnotation::BoundingBoxAnnotation()
: Color(0.5, 0.5, 0.5), Extents(-1, 1, -1, 1, -1, 1)
{
}
BoundingBoxAnnotation::~BoundingBoxAnnotation()
{
}
void BoundingBoxAnnotation::Render(const vtkm::rendering::Camera &,
const WorldAnnotator &annotator)
{
//win->SetupForWorldSpace();
vtkm::Float32 linewidth = 1.0;
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Min,
this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Max,
this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Max,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Max,
this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Max,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
}
}
} // namespace vtkm::rendering

@ -20,10 +20,9 @@
#ifndef vtk_m_rendering_BoundingBoxAnnotation_h
#define vtk_m_rendering_BoundingBoxAnnotation_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/Bounds.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/WorldAnnotator.h>
namespace vtkm {
@ -36,75 +35,39 @@ private:
vtkm::Bounds Extents;
public:
BoundingBoxAnnotation()
: Color(0.5, 0.5, 0.5), Extents(-1, 1, -1, 1, -1, 1)
{
}
virtual ~BoundingBoxAnnotation()
{
}
vtkm::Bounds GetExtents() const
VTKM_RENDERING_EXPORT
BoundingBoxAnnotation();
VTKM_RENDERING_EXPORT
virtual ~BoundingBoxAnnotation();
VTKM_CONT_EXPORT
const vtkm::Bounds &GetExtents() const
{
return this->Extents;
}
VTKM_CONT_EXPORT
void SetExtents(const vtkm::Bounds &extents)
{
this->Extents = extents;
}
VTKM_CONT_EXPORT
const vtkm::rendering::Color &GetColor() const
{
return this->Color;
}
VTKM_CONT_EXPORT
void SetColor(vtkm::rendering::Color c)
{
this->Color = c;
}
VTKM_RENDERING_EXPORT
virtual void Render(const vtkm::rendering::Camera &,
const WorldAnnotator &annotator)
{
//win->SetupForWorldSpace();
vtkm::Float32 linewidth = 1.0;
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Min,
this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Max,
this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Max,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Min,this->Extents.Z.Max,
this->Extents.X.Max,this->Extents.Y.Min,this->Extents.Z.Max,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Min,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Min,
linewidth, this->Color);
annotator.AddLine(this->Extents.X.Min,this->Extents.Y.Max,this->Extents.Z.Max,
this->Extents.X.Max,this->Extents.Y.Max,this->Extents.Z.Max,
linewidth, this->Color);
}
const WorldAnnotator &annotator);
};

@ -32,54 +32,128 @@ set(headers
Color.h
ColorBarAnnotation.h
ColorTable.h
DecodePNG.h
MatrixHelpers.h
Scene.h
Mapper.h
MapperRayTracer.h
MapperVolume.h
TextAnnotation.h
TextAnnotationBillboard.h
TextAnnotationScreen.h
Triangulator.h
View.h
View2D.h
View3D.h
WorldAnnotator.h
)
set(sources
Actor.cxx
AxisAnnotation.cxx
AxisAnnotation2D.cxx
AxisAnnotation3D.cxx
BitmapFont.cxx
BitmapFontFactory.cxx
BoundingBoxAnnotation.cxx
Camera.cxx
Canvas.cxx
CanvasRayTracer.cxx
ColorBarAnnotation.cxx
ColorTable.cxx
DecodePNG.cxx
Mapper.cxx
MapperRayTracer.cxx
MapperVolume.cxx
Scene.cxx
TextAnnotation.cxx
TextAnnotationBillboard.cxx
TextAnnotationScreen.cxx
View.cxx
View2D.cxx
View3D.cxx
WorldAnnotator.cxx
internal/RunTriangulator.cxx
)
set(opengl_headers
CanvasGL.h
MapperGL.h
TextureGL.h
WorldAnnotatorGL.h
)
set(opengl_sources
CanvasGL.cxx
MapperGL.cxx
TextureGL.cxx
WorldAnnotatorGL.cxx
)
set(egl_headers
CanvasEGL.h
)
set(egl_sources
CanvasEGL.cxx
)
set(osmesa_headers
CanvasOSMesa.h
)
set(osmesa_sources
CanvasOSMesa.cxx
)
# This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA).
set(device_sources
CanvasRayTracer.cxx
)
#-----------------------------------------------------------------------------
vtkm_configure_component_OpenGL()
if(VTKm_OpenGL_FOUND)
set(headers ${headers} ${opengl_headers})
list(APPEND headers ${opengl_headers})
list(APPEND sources ${opengl_sources})
vtkm_configure_component_OSMesa()
if(VTKm_OSMesa_FOUND)
set(headers ${headers} ${osmesa_headers})
list(APPEND headers ${osmesa_headers})
list(APPEND sources ${osmesa_sources})
endif()
vtkm_configure_component_EGL()
if(VTKm_EGL_FOUND)
set(headers ${headers} ${egl_headers})
list(APPEND headers ${egl_headers})
list(APPEND sources ${egl_headers})
endif()
vtkm_configure_component_GLFW()
if(VTKm_GLFW_FOUND)
set(headers ${headers} ${glfw_headers})
list(APPEND headers ${glfw_headers})
endif()
endif()
vtkm_declare_headers(${headers})
if (VTKm_ENABLE_CUDA)
vtkm_library(
SOURCES ${sources}
CUDA
WRAP_FOR_CUDA ${device_sources}
)
else()
vtkm_library(
SOURCES ${sources}
)
endif()
# Subclasses need rendering library
vtkm_configure_component_Rendering()
add_subdirectory(internal)
add_subdirectory(raytracing)

349
vtkm/rendering/Camera.cxx Normal file

@ -0,0 +1,349 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/Camera.h>
namespace vtkm {
namespace rendering {
vtkm::Matrix<vtkm::Float32,4,4>
Camera::Camera3DStruct::CreateViewMatrix() const
{
return MatrixHelpers::ViewMatrix(this->Position, this->LookAt, this->ViewUp);
}
vtkm::Matrix<vtkm::Float32,4,4>
Camera::Camera3DStruct::CreateProjectionMatrix(vtkm::Id width,
vtkm::Id height,
vtkm::Float32 nearPlane,
vtkm::Float32 farPlane) const
{
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
vtkm::Float32 AspectRatio = vtkm::Float32(width) / vtkm::Float32(height);
vtkm::Float32 fovRad = (this->FieldOfView * 3.1415926f)/180.f;
fovRad = vtkm::Tan( fovRad * 0.5f);
vtkm::Float32 size = nearPlane * fovRad;
vtkm::Float32 left = -size * AspectRatio;
vtkm::Float32 right = size * AspectRatio;
vtkm::Float32 bottom = -size;
vtkm::Float32 top = size;
matrix(0,0) = 2.f * nearPlane / (right - left);
matrix(1,1) = 2.f * nearPlane / (top - bottom);
matrix(0,2) = (right + left) / (right - left);
matrix(1,2) = (top + bottom) / (top - bottom);
matrix(2,2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
matrix(3,2) = -1.f;
matrix(2,3) = -(2.f * farPlane * nearPlane) / (farPlane - nearPlane);
matrix(3,3) = 0.f;
vtkm::Matrix<vtkm::Float32,4,4> T, Z;
T = vtkm::Transform3DTranslate(this->XPan, this->YPan, 0.f);
Z = vtkm::Transform3DScale(this->Zoom, this->Zoom, 1.f);
matrix = vtkm::MatrixMultiply(Z, vtkm::MatrixMultiply(T, matrix));
return matrix;
}
//---------------------------------------------------------------------------
vtkm::Matrix<vtkm::Float32,4,4>
Camera::Camera2DStruct::CreateViewMatrix() const
{
vtkm::Vec<vtkm::Float32,3> lookAt((this->Left + this->Right)/2.f,
(this->Top + this->Bottom)/2.f,
0.f);
vtkm::Vec<vtkm::Float32,3> position = lookAt;
position[2] = 1.f;
vtkm::Vec<vtkm::Float32,3> up(0,1,0);
return MatrixHelpers::ViewMatrix(position, lookAt, up);
}
vtkm::Matrix<vtkm::Float32,4,4>
Camera::Camera2DStruct::CreateProjectionMatrix(vtkm::Float32 size,
vtkm::Float32 znear,
vtkm::Float32 zfar,
vtkm::Float32 aspect) const
{
vtkm::Matrix<vtkm::Float32,4,4> matrix(0.f);
vtkm::Float32 left = -size/2.f * aspect;
vtkm::Float32 right = size/2.f * aspect;
vtkm::Float32 bottom = -size/2.f;
vtkm::Float32 top = size/2.f;
matrix(0,0) = 2.f/(right-left);
matrix(1,1) = 2.f/(top-bottom);
matrix(2,2) = -2.f/(zfar-znear);
matrix(0,3) = -(right+left)/(right-left);
matrix(1,3) = -(top+bottom)/(top-bottom);
matrix(2,3) = -(zfar+znear)/(zfar-znear);
matrix(3,3) = 1.f;
vtkm::Matrix<vtkm::Float32,4,4> T, Z;
T = vtkm::Transform3DTranslate(this->XPan, this->YPan, 0.f);
Z = vtkm::Transform3DScale(this->Zoom, this->Zoom, 1.f);
matrix = vtkm::MatrixMultiply(Z, vtkm::MatrixMultiply(T, matrix));
return matrix;
}
//---------------------------------------------------------------------------
vtkm::Matrix<vtkm::Float32,4,4>
Camera::CreateViewMatrix() const
{
if (this->Mode == Camera::MODE_3D)
{
return this->Camera3D.CreateViewMatrix();
}
else
{
return this->Camera2D.CreateViewMatrix();
}
}
vtkm::Matrix<vtkm::Float32,4,4>
Camera::CreateProjectionMatrix(vtkm::Id screenWidth,
vtkm::Id screenHeight) const
{
if (this->Mode == Camera::MODE_3D)
{
return this->Camera3D.CreateProjectionMatrix(
screenWidth, screenHeight, this->NearPlane, this->FarPlane);
}
else
{
vtkm::Float32 size = vtkm::Abs(this->Camera2D.Top - this->Camera2D.Bottom);
vtkm::Float32 left,right,bottom,top;
this->GetRealViewport(screenWidth,screenHeight,left,right,bottom,top);
vtkm::Float32 aspect =
(static_cast<vtkm::Float32>(screenWidth)*(right-left)) /
(static_cast<vtkm::Float32>(screenHeight)*(top-bottom));
return this->Camera2D.CreateProjectionMatrix(
size, this->NearPlane, this->FarPlane, aspect);
}
}
void Camera::GetRealViewport(vtkm::Id screenWidth,
vtkm::Id screenHeight,
vtkm::Float32 &left,
vtkm::Float32 &right,
vtkm::Float32 &bottom,
vtkm::Float32 &top) const
{
if (this->Mode == Camera::MODE_3D)
{
left = this->ViewportLeft;
right = this->ViewportRight;
bottom = this->ViewportBottom;
top = this->ViewportTop;
}
else
{
vtkm::Float32 maxvw = (this->ViewportRight-this->ViewportLeft) * static_cast<vtkm::Float32>(screenWidth);
vtkm::Float32 maxvh = (this->ViewportTop-this->ViewportBottom) * static_cast<vtkm::Float32>(screenHeight);
vtkm::Float32 waspect = maxvw / maxvh;
vtkm::Float32 daspect = (this->Camera2D.Right - this->Camera2D.Left) / (this->Camera2D.Top - this->Camera2D.Bottom);
daspect *= this->Camera2D.XScale;
//cerr << "waspect="<<waspect << " \tdaspect="<<daspect<<endl;
const bool center = true; // if false, anchor to bottom-left
if (waspect > daspect)
{
vtkm::Float32 new_w = (this->ViewportRight-this->ViewportLeft) * daspect / waspect;
if (center)
{
left = (this->ViewportLeft+this->ViewportRight)/2.f - new_w/2.f;
right = (this->ViewportLeft+this->ViewportRight)/2.f + new_w/2.f;
}
else
{
left = this->ViewportLeft;
right = this->ViewportLeft + new_w;
}
bottom = this->ViewportBottom;
top = this->ViewportTop;
}
else
{
vtkm::Float32 new_h = (this->ViewportTop-this->ViewportBottom) * waspect / daspect;
if (center)
{
bottom = (this->ViewportBottom+this->ViewportTop)/2.f - new_h/2.f;
top = (this->ViewportBottom+this->ViewportTop)/2.f + new_h/2.f;
}
else
{
bottom = this->ViewportBottom;
top = this->ViewportBottom + new_h;
}
left = this->ViewportLeft;
right = this->ViewportRight;
}
}
}
void Camera::Pan(vtkm::Float32 dx, vtkm::Float32 dy)
{
this->Camera3D.XPan += dx;
this->Camera3D.YPan += dy;
this->Camera2D.XPan += dx;
this->Camera2D.YPan += dy;
}
void Camera::Zoom(vtkm::Float32 zoom)
{
vtkm::Float32 factor = vtkm::Pow(4.0f, zoom);
this->Camera3D.Zoom *= factor;
this->Camera3D.XPan *= factor;
this->Camera3D.YPan *= factor;
this->Camera2D.Zoom *= factor;
this->Camera2D.XPan *= factor;
this->Camera2D.YPan *= factor;
}
void Camera::TrackballRotate(vtkm::Float32 startX,
vtkm::Float32 startY,
vtkm::Float32 endX,
vtkm::Float32 endY)
{
vtkm::Matrix<vtkm::Float32,4,4> rotate =
MatrixHelpers::TrackballMatrix(startX,startY, endX,endY);
//Translate matrix
vtkm::Matrix<vtkm::Float32,4,4> translate =
vtkm::Transform3DTranslate(-this->Camera3D.LookAt);
//Translate matrix
vtkm::Matrix<vtkm::Float32,4,4> inverseTranslate =
vtkm::Transform3DTranslate(this->Camera3D.LookAt);
vtkm::Matrix<vtkm::Float32,4,4> view = this->CreateViewMatrix();
view(0,3) = 0;
view(1,3) = 0;
view(2,3) = 0;
vtkm::Matrix<vtkm::Float32,4,4> inverseView = vtkm::MatrixTranspose(view);
//fullTransform = inverseTranslate * inverseView * rotate * view * translate
vtkm::Matrix<vtkm::Float32,4,4> fullTransform;
fullTransform = vtkm::MatrixMultiply(
inverseTranslate, vtkm::MatrixMultiply(
inverseView, vtkm::MatrixMultiply(
rotate, vtkm::MatrixMultiply(
view,translate))));
this->Camera3D.Position =
vtkm::Transform3DPoint(fullTransform, this->Camera3D.Position);
this->Camera3D.LookAt =
vtkm::Transform3DPoint(fullTransform, this->Camera3D.LookAt);
this->Camera3D.ViewUp =
vtkm::Transform3DVector(fullTransform, this->Camera3D.ViewUp);
}
void Camera::ResetToBounds(const vtkm::Bounds &dataBounds)
{
// Save camera mode
ModeEnum saveMode = this->GetMode();
// Reset for 3D camera
vtkm::Vec<vtkm::Float32,3> directionOfProjection =
this->GetPosition() - this->GetLookAt();
vtkm::Normalize(directionOfProjection);
vtkm::Vec<vtkm::Float32,3> center = dataBounds.Center();
this->SetLookAt(center);
vtkm::Vec<vtkm::Float32,3> totalExtent;
totalExtent[0] = vtkm::Float32(dataBounds.X.Length());
totalExtent[1] = vtkm::Float32(dataBounds.Y.Length());
totalExtent[2] = vtkm::Float32(dataBounds.Z.Length());
vtkm::Float32 diagonalLength = vtkm::Magnitude(totalExtent);
this->SetPosition(center + directionOfProjection * diagonalLength * 1.0f);
this->SetFieldOfView(60.0f);
this->SetClippingRange(0.1f * diagonalLength, diagonalLength*10.0f);
// Reset for 2D camera
this->SetViewRange2D(dataBounds);
// Reset pan and zoom
this->Camera3D.XPan = 0;
this->Camera3D.YPan = 0;
this->Camera3D.Zoom = 1;
this->Camera2D.XPan = 0;
this->Camera2D.YPan = 0;
this->Camera2D.Zoom = 1;
// Restore camera mode
this->SetMode(saveMode);
}
void Camera::Roll(vtkm::Float32 angleDegrees)
{
vtkm::Vec<vtkm::Float32,3> directionOfProjection =
this->GetLookAt() - this->GetPosition();
vtkm::Matrix<vtkm::Float32,4,4> rotateTransform =
vtkm::Transform3DRotate(angleDegrees, directionOfProjection);
this->SetViewUp(vtkm::Transform3DVector(rotateTransform,this->GetViewUp()));
}
void Camera::Azimuth(vtkm::Float32 angleDegrees)
{
// Translate to the focal point (LookAt), rotate about view up, and
// translate back again.
vtkm::Matrix<vtkm::Float32,4,4> transform =
vtkm::Transform3DTranslate(this->GetLookAt());
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DRotate(angleDegrees, this->GetViewUp()));
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DTranslate(-this->GetLookAt()));
this->SetPosition(vtkm::Transform3DPoint(transform, this->GetPosition()));
}
void Camera::Elevation(vtkm::Float32 angleDegrees)
{
vtkm::Vec<vtkm::Float32,3> axisOfRotation =
vtkm::Cross(this->GetPosition() - this->GetLookAt(), this->GetViewUp());
// Translate to the focal point (LookAt), rotate about the defined axis,
// and translate back again.
vtkm::Matrix<vtkm::Float32,4,4> transform =
vtkm::Transform3DTranslate(this->GetLookAt());
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DRotate(angleDegrees, axisOfRotation));
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DTranslate(-this->GetLookAt()));
this->SetPosition(vtkm::Transform3DPoint(transform, this->GetPosition()));
}
void Camera::Dolly(vtkm::Float32 value)
{
if (value <= vtkm::Epsilon32()) { return; }
vtkm::Vec<vtkm::Float32,3> lookAtToPos =
this->GetPosition() - this->GetLookAt();
this->SetPosition(this->GetLookAt() + (1.0f/value)*lookAtToPos);
}
}
} // namespace vtkm::rendering

@ -19,6 +19,9 @@
//============================================================================
#ifndef vtk_m_rendering_Camera_h
#define vtk_m_rendering_Camera_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/Bounds.h>
#include <vtkm/Math.h>
#include <vtkm/Matrix.h>
@ -46,45 +49,16 @@ class Camera
Zoom(1.0f)
{}
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateViewMatrix() const
{
return MatrixHelpers::ViewMatrix(this->Position, this->LookAt, this->ViewUp);
}
VTKM_RENDERING_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateViewMatrix() const;
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateProjectionMatrix(vtkm::Id width,
vtkm::Id height,
vtkm::Float32 nearPlane,
vtkm::Float32 farPlane) const
{
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
vtkm::Float32 AspectRatio = vtkm::Float32(width) / vtkm::Float32(height);
vtkm::Float32 fovRad = (this->FieldOfView * 3.1415926f)/180.f;
fovRad = vtkm::Tan( fovRad * 0.5f);
vtkm::Float32 size = nearPlane * fovRad;
vtkm::Float32 left = -size * AspectRatio;
vtkm::Float32 right = size * AspectRatio;
vtkm::Float32 bottom = -size;
vtkm::Float32 top = size;
matrix(0,0) = 2.f * nearPlane / (right - left);
matrix(1,1) = 2.f * nearPlane / (top - bottom);
matrix(0,2) = (right + left) / (right - left);
matrix(1,2) = (top + bottom) / (top - bottom);
matrix(2,2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
matrix(3,2) = -1.f;
matrix(2,3) = -(2.f * farPlane * nearPlane) / (farPlane - nearPlane);
matrix(3,3) = 0.f;
vtkm::Matrix<vtkm::Float32,4,4> T, Z;
T = vtkm::Transform3DTranslate(this->XPan, this->YPan, 0.f);
Z = vtkm::Transform3DScale(this->Zoom, this->Zoom, 1.f);
matrix = vtkm::MatrixMultiply(Z, vtkm::MatrixMultiply(T, matrix));
return matrix;
}
VTKM_RENDERING_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateProjectionMatrix(vtkm::Id width,
vtkm::Id height,
vtkm::Float32 nearPlane,
vtkm::Float32 farPlane) const;
vtkm::Vec<vtkm::Float32,3> LookAt;
@ -111,44 +85,16 @@ class Camera
Zoom(1.0f)
{}
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateViewMatrix() const
{
vtkm::Vec<vtkm::Float32,3> lookAt((this->Left + this->Right)/2.f,
(this->Top + this->Bottom)/2.f,
0.f);
vtkm::Vec<vtkm::Float32,3> position = lookAt;
position[2] = 1.f;
vtkm::Vec<vtkm::Float32,3> up(0,1,0);
return MatrixHelpers::ViewMatrix(position, lookAt, up);
}
VTKM_RENDERING_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateViewMatrix() const;
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateProjectionMatrix(vtkm::Float32 size,
vtkm::Float32 znear,
vtkm::Float32 zfar,
vtkm::Float32 aspect) const
{
vtkm::Matrix<vtkm::Float32,4,4> matrix(0.f);
vtkm::Float32 left = -size/2.f * aspect;
vtkm::Float32 right = size/2.f * aspect;
vtkm::Float32 bottom = -size/2.f;
vtkm::Float32 top = size/2.f;
matrix(0,0) = 2.f/(right-left);
matrix(1,1) = 2.f/(top-bottom);
matrix(2,2) = -2.f/(zfar-znear);
matrix(0,3) = -(right+left)/(right-left);
matrix(1,3) = -(top+bottom)/(top-bottom);
matrix(2,3) = -(zfar+znear)/(zfar-znear);
matrix(3,3) = 1.f;
vtkm::Matrix<vtkm::Float32,4,4> T, Z;
T = vtkm::Transform3DTranslate(this->XPan, this->YPan, 0.f);
Z = vtkm::Transform3DScale(this->Zoom, this->Zoom, 1.f);
matrix = vtkm::MatrixMultiply(Z, vtkm::MatrixMultiply(T, matrix));
return matrix;
}
VTKM_RENDERING_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateProjectionMatrix(vtkm::Float32 size,
vtkm::Float32 znear,
vtkm::Float32 zfar,
vtkm::Float32 aspect) const;
vtkm::Float32 Left;
vtkm::Float32 Right;
@ -173,97 +119,18 @@ public:
ViewportTop(1.0f)
{}
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateViewMatrix() const
{
if (this->Mode == Camera::MODE_3D)
{
return this->Camera3D.CreateViewMatrix();
}
else
{
return this->Camera2D.CreateViewMatrix();
}
}
VTKM_RENDERING_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateViewMatrix() const;
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateProjectionMatrix(
vtkm::Id screenWidth, vtkm::Id screenHeight) const
{
if (this->Mode == Camera::MODE_3D)
{
return this->Camera3D.CreateProjectionMatrix(
screenWidth, screenHeight, this->NearPlane, this->FarPlane);
}
else
{
vtkm::Float32 size = vtkm::Abs(this->Camera2D.Top - this->Camera2D.Bottom);
vtkm::Float32 left,right,bottom,top;
this->GetRealViewport(screenWidth,screenHeight,left,right,bottom,top);
vtkm::Float32 aspect =
(static_cast<vtkm::Float32>(screenWidth)*(right-left)) /
(static_cast<vtkm::Float32>(screenHeight)*(top-bottom));
VTKM_RENDERING_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateProjectionMatrix(vtkm::Id screenWidth, vtkm::Id screenHeight) const;
return this->Camera2D.CreateProjectionMatrix(
size, this->NearPlane, this->FarPlane, aspect);
}
}
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
void GetRealViewport(vtkm::Id screenWidth, vtkm::Id screenHeight,
vtkm::Float32 &left, vtkm::Float32 &right,
vtkm::Float32 &bottom, vtkm::Float32 &top) const
{
if (this->Mode == Camera::MODE_3D)
{
left = this->ViewportLeft;
right = this->ViewportRight;
bottom = this->ViewportBottom;
top = this->ViewportTop;
}
else
{
vtkm::Float32 maxvw = (this->ViewportRight-this->ViewportLeft) * static_cast<vtkm::Float32>(screenWidth);
vtkm::Float32 maxvh = (this->ViewportTop-this->ViewportBottom) * static_cast<vtkm::Float32>(screenHeight);
vtkm::Float32 waspect = maxvw / maxvh;
vtkm::Float32 daspect = (this->Camera2D.Right - this->Camera2D.Left) / (this->Camera2D.Top - this->Camera2D.Bottom);
daspect *= this->Camera2D.XScale;
//cerr << "waspect="<<waspect << " \tdaspect="<<daspect<<endl;
const bool center = true; // if false, anchor to bottom-left
if (waspect > daspect)
{
vtkm::Float32 new_w = (this->ViewportRight-this->ViewportLeft) * daspect / waspect;
if (center)
{
left = (this->ViewportLeft+this->ViewportRight)/2.f - new_w/2.f;
right = (this->ViewportLeft+this->ViewportRight)/2.f + new_w/2.f;
}
else
{
left = this->ViewportLeft;
right = this->ViewportLeft + new_w;
}
bottom = this->ViewportBottom;
top = this->ViewportTop;
}
else
{
vtkm::Float32 new_h = (this->ViewportTop-this->ViewportBottom) * waspect / daspect;
if (center)
{
bottom = (this->ViewportBottom+this->ViewportTop)/2.f - new_h/2.f;
top = (this->ViewportBottom+this->ViewportTop)/2.f + new_h/2.f;
}
else
{
bottom = this->ViewportBottom;
top = this->ViewportBottom + new_h;
}
left = this->ViewportLeft;
right = this->ViewportRight;
}
}
}
vtkm::Float32 &bottom, vtkm::Float32 &top) const;
/// \brief The mode of the camera (2D or 3D).
///
@ -493,14 +360,11 @@ public:
/// \brief Pans the camera
///
VTKM_CONT_EXPORT
void Pan(vtkm::Float32 dx, vtkm::Float32 dy)
{
this->Camera3D.XPan += dx;
this->Camera3D.YPan += dy;
this->Camera2D.XPan += dx;
this->Camera2D.YPan += dy;
}
VTKM_RENDERING_EXPORT
void Pan(vtkm::Float32 dx, vtkm::Float32 dy);
/// \brief Pans the camera
///
VTKM_CONT_EXPORT
void Pan(vtkm::Float64 dx, vtkm::Float64 dy)
{
@ -523,17 +387,9 @@ public:
/// zoom makes the geometry look bigger or closer. Negative zoom has the
/// opposite effect. A zoom of 0 has no effect.
///
VTKM_CONT_EXPORT
void Zoom(vtkm::Float32 zoom)
{
vtkm::Float32 factor = vtkm::Pow(4.0f, zoom);
this->Camera3D.Zoom *= factor;
this->Camera3D.XPan *= factor;
this->Camera3D.YPan *= factor;
this->Camera2D.Zoom *= factor;
this->Camera2D.XPan *= factor;
this->Camera2D.YPan *= factor;
}
VTKM_RENDERING_EXPORT
void Zoom(vtkm::Float32 zoom);
VTKM_CONT_EXPORT
void Zoom(vtkm::Float64 zoom)
{
@ -550,44 +406,12 @@ public:
///
/// \c TrackballRotate changes the mode to 3D.
///
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
void TrackballRotate(vtkm::Float32 startX,
vtkm::Float32 startY,
vtkm::Float32 endX,
vtkm::Float32 endY)
{
vtkm::Matrix<vtkm::Float32,4,4> rotate =
MatrixHelpers::TrackballMatrix(startX,startY, endX,endY);
vtkm::Float32 endY);
//Translate matrix
vtkm::Matrix<vtkm::Float32,4,4> translate =
vtkm::Transform3DTranslate(-this->Camera3D.LookAt);
//Translate matrix
vtkm::Matrix<vtkm::Float32,4,4> inverseTranslate =
vtkm::Transform3DTranslate(this->Camera3D.LookAt);
vtkm::Matrix<vtkm::Float32,4,4> view = this->CreateViewMatrix();
view(0,3) = 0;
view(1,3) = 0;
view(2,3) = 0;
vtkm::Matrix<vtkm::Float32,4,4> inverseView = vtkm::MatrixTranspose(view);
//fullTransform = inverseTranslate * inverseView * rotate * view * translate
vtkm::Matrix<vtkm::Float32,4,4> fullTransform;
fullTransform = vtkm::MatrixMultiply(
inverseTranslate, vtkm::MatrixMultiply(
inverseView, vtkm::MatrixMultiply(
rotate, vtkm::MatrixMultiply(
view,translate))));
this->Camera3D.Position =
vtkm::Transform3DPoint(fullTransform, this->Camera3D.Position);
this->Camera3D.LookAt =
vtkm::Transform3DPoint(fullTransform, this->Camera3D.LookAt);
this->Camera3D.ViewUp =
vtkm::Transform3DVector(fullTransform, this->Camera3D.ViewUp);
}
VTKM_CONT_EXPORT
void TrackballRotate(vtkm::Float64 startX,
vtkm::Float64 startY,
@ -607,43 +431,8 @@ public:
/// the camera so that it is looking at this region in space. The view
/// direction is preserved.
///
VTKM_CONT_EXPORT
void ResetToBounds(const vtkm::Bounds &dataBounds)
{
// Save camera mode
ModeEnum saveMode = this->GetMode();
// Reset for 3D camera
vtkm::Vec<vtkm::Float32,3> directionOfProjection =
this->GetPosition() - this->GetLookAt();
vtkm::Normalize(directionOfProjection);
vtkm::Vec<vtkm::Float32,3> center = dataBounds.Center();
this->SetLookAt(center);
vtkm::Vec<vtkm::Float32,3> totalExtent;
totalExtent[0] = vtkm::Float32(dataBounds.X.Length());
totalExtent[1] = vtkm::Float32(dataBounds.Y.Length());
totalExtent[2] = vtkm::Float32(dataBounds.Z.Length());
vtkm::Float32 diagonalLength = vtkm::Magnitude(totalExtent);
this->SetPosition(center + directionOfProjection * diagonalLength * 1.0f);
this->SetFieldOfView(60.0f);
this->SetClippingRange(0.1f * diagonalLength, diagonalLength*10.0f);
// Reset for 2D camera
this->SetViewRange2D(dataBounds);
// Reset pan and zoom
this->Camera3D.XPan = 0;
this->Camera3D.YPan = 0;
this->Camera3D.Zoom = 1;
this->Camera2D.XPan = 0;
this->Camera2D.YPan = 0;
this->Camera2D.Zoom = 1;
// Restore camera mode
this->SetMode(saveMode);
}
VTKM_RENDERING_EXPORT
void ResetToBounds(const vtkm::Bounds &dataBounds);
/// \brief Roll the camera
///
@ -652,16 +441,9 @@ public:
///
/// Roll is currently only supported for 3D cameras.
///
VTKM_CONT_EXPORT
void Roll(vtkm::Float32 angleDegrees)
{
vtkm::Vec<vtkm::Float32,3> directionOfProjection =
this->GetLookAt() - this->GetPosition();
vtkm::Matrix<vtkm::Float32,4,4> rotateTransform =
vtkm::Transform3DRotate(angleDegrees, directionOfProjection);
VTKM_RENDERING_EXPORT
void Roll(vtkm::Float32 angleDegrees);
this->SetViewUp(vtkm::Transform3DVector(rotateTransform,this->GetViewUp()));
}
VTKM_CONT_EXPORT
void Roll(vtkm::Float64 angleDegrees)
{
@ -677,20 +459,9 @@ public:
/// Azimuth only makes sense for 3D cameras, so the camera mode will be set
/// to 3D when this method is called.
///
VTKM_CONT_EXPORT
void Azimuth(vtkm::Float32 angleDegrees)
{
// Translate to the focal point (LookAt), rotate about view up, and
// translate back again.
vtkm::Matrix<vtkm::Float32,4,4> transform =
vtkm::Transform3DTranslate(this->GetLookAt());
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DRotate(angleDegrees, this->GetViewUp()));
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DTranslate(-this->GetLookAt()));
VTKM_RENDERING_EXPORT
void Azimuth(vtkm::Float32 angleDegrees);
this->SetPosition(vtkm::Transform3DPoint(transform, this->GetPosition()));
}
VTKM_CONT_EXPORT
void Azimuth(vtkm::Float64 angleDegrees)
{
@ -707,23 +478,9 @@ public:
/// Elevation only makes sense for 3D cameras, so the camera mode will be set
/// to 3D when this method is called.
///
VTKM_CONT_EXPORT
void Elevation(vtkm::Float32 angleDegrees)
{
vtkm::Vec<vtkm::Float32,3> axisOfRotation =
vtkm::Cross(this->GetPosition() - this->GetLookAt(), this->GetViewUp());
VTKM_RENDERING_EXPORT
void Elevation(vtkm::Float32 angleDegrees);
// Translate to the focal point (LookAt), rotate about the defined axis,
// and translate back again.
vtkm::Matrix<vtkm::Float32,4,4> transform =
vtkm::Transform3DTranslate(this->GetLookAt());
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DRotate(angleDegrees, axisOfRotation));
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DTranslate(-this->GetLookAt()));
this->SetPosition(vtkm::Transform3DPoint(transform, this->GetPosition()));
}
VTKM_CONT_EXPORT
void Elevation(vtkm::Float64 angleDegrees)
{
@ -740,16 +497,9 @@ public:
/// Dolly only makes sense for 3D cameras, so the camera mode will be set to
/// 3D when this method is called.
///
VTKM_CONT_EXPORT
void Dolly(vtkm::Float32 value)
{
if (value <= vtkm::Epsilon32()) { return; }
VTKM_RENDERING_EXPORT
void Dolly(vtkm::Float32 value);
vtkm::Vec<vtkm::Float32,3> lookAtToPos =
this->GetPosition() - this->GetLookAt();
this->SetPosition(this->GetLookAt() + (1.0f/value)*lookAtToPos);
}
VTKM_CONT_EXPORT
void Dolly(vtkm::Float64 value)
{

66
vtkm/rendering/Canvas.cxx Normal file

@ -0,0 +1,66 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/Canvas.h>
#include <iostream>
#include <fstream>
namespace vtkm {
namespace rendering {
Canvas::Canvas(vtkm::Id width, vtkm::Id height)
: Width(0), Height(0)
{
this->ResizeBuffers(width, height);
}
Canvas::~Canvas()
{ }
void Canvas::SaveAs(const std::string &fileName) const
{
this->RefreshColorBuffer();
std::ofstream of(fileName.c_str());
of<<"P6"<<std::endl<<this->Width<<" "<<this->Height<<std::endl<<255<<std::endl;
ColorBufferType::PortalConstControl colorPortal =
this->ColorBuffer.GetPortalConstControl();
for (vtkm::Id yIndex=this->Height-1; yIndex>=0; yIndex--)
{
for (vtkm::Id xIndex=0; xIndex < this->Width; xIndex++)
{
vtkm::Vec<vtkm::Float32,4> tuple =
colorPortal.Get(yIndex*this->Width + xIndex);
of<<(unsigned char)(tuple[0]*255);
of<<(unsigned char)(tuple[1]*255);
of<<(unsigned char)(tuple[2]*255);
}
}
of.close();
}
vtkm::rendering::WorldAnnotator *
Canvas::CreateWorldAnnotator() const
{
return new vtkm::rendering::WorldAnnotator;
}
}
} // vtkm::rendering

@ -20,36 +20,42 @@
#ifndef vtk_m_rendering_Canvas_h
#define vtk_m_rendering_Canvas_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/Types.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/WorldAnnotator.h>
#include <iostream>
#include <fstream>
namespace vtkm {
namespace rendering {
class Canvas
{
public:
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
Canvas(vtkm::Id width=1024,
vtkm::Id height=1024)
: Width(0), Height(0)
{
this->ResizeBuffers(width, height);
}
vtkm::Id height=1024);
virtual ~Canvas() { }
VTKM_RENDERING_EXPORT
virtual ~Canvas();
VTKM_RENDERING_EXPORT
virtual void Initialize() = 0;
VTKM_RENDERING_EXPORT
virtual void Activate() = 0;
VTKM_RENDERING_EXPORT
virtual void Clear() = 0;
VTKM_RENDERING_EXPORT
virtual void Finish() = 0;
VTKM_RENDERING_EXPORT
virtual vtkm::rendering::Canvas *NewCopy() const = 0;
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,4> > ColorBufferType;
typedef vtkm::cont::ArrayHandle<vtkm::Float32> DepthBufferType;
@ -105,55 +111,83 @@ public:
// If a subclass uses a system that renderers to different buffers, then
// these should be overridden to copy the data to the buffers.
VTKM_CONT_EXPORT
virtual void RefreshColorBuffer() { }
VTKM_CONT_EXPORT
virtual void RefreshDepthBuffer() { }
VTKM_RENDERING_EXPORT
virtual void RefreshColorBuffer() const { }
VTKM_RENDERING_EXPORT
virtual void RefreshDepthBuffer() const { }
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
virtual void SetViewToWorldSpace(const vtkm::rendering::Camera &, bool) {}
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
virtual void SetViewToScreenSpace(const vtkm::rendering::Camera &, bool) {}
VTKM_CONT_EXPORT
void SetViewportClipping(const vtkm::rendering::Camera &, bool) {}
VTKM_RENDERING_EXPORT
virtual void SetViewportClipping(const vtkm::rendering::Camera &, bool) {}
VTKM_RENDERING_EXPORT
virtual void SaveAs(const std::string &fileName) const;
VTKM_RENDERING_EXPORT
virtual void AddLine(const vtkm::Vec<vtkm::Float64,2> &point0,
const vtkm::Vec<vtkm::Float64,2> &point1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &color) const = 0;
VTKM_CONT_EXPORT
virtual void SaveAs(const std::string &fileName)
void AddLine(vtkm::Float64 x0, vtkm::Float64 y0,
vtkm::Float64 x1, vtkm::Float64 y1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &color) const
{
this->RefreshColorBuffer();
std::ofstream of(fileName.c_str());
of<<"P6"<<std::endl<<this->Width<<" "<<this->Height<<std::endl<<255<<std::endl;
ColorBufferType::PortalConstControl colorPortal =
this->ColorBuffer.GetPortalConstControl();
for (vtkm::Id yIndex=this->Height-1; yIndex>=0; yIndex--)
{
for (vtkm::Id xIndex=0; xIndex < this->Width; xIndex++)
{
vtkm::Vec<vtkm::Float32,4> tuple =
colorPortal.Get(yIndex*this->Width + xIndex);
of<<(unsigned char)(tuple[0]*255);
of<<(unsigned char)(tuple[1]*255);
of<<(unsigned char)(tuple[2]*255);
}
}
of.close();
this->AddLine(vtkm::make_Vec(x0, y0),
vtkm::make_Vec(x1, y1),
linewidth,
color);
}
virtual void AddLine(vtkm::Float64, vtkm::Float64,
vtkm::Float64, vtkm::Float64,
vtkm::Float32,
const vtkm::rendering::Color &) const {}
virtual void AddColorBar(vtkm::Float32, vtkm::Float32,
vtkm::Float32, vtkm::Float32,
const vtkm::rendering::ColorTable &,
bool) const {}
virtual void AddText(vtkm::Float32, vtkm::Float32,
vtkm::Float32,
vtkm::Float32,
vtkm::Float32,
vtkm::Float32, vtkm::Float32,
Color,
std::string) const {}
VTKM_RENDERING_EXPORT
virtual void AddColorBar(const vtkm::Bounds &bounds,
const vtkm::rendering::ColorTable &colorTable,
bool horizontal) const = 0;
VTKM_CONT_EXPORT
void AddColorBar(vtkm::Float32 x, vtkm::Float32 y,
vtkm::Float32 width, vtkm::Float32 height,
const vtkm::rendering::ColorTable &colorTable,
bool horizontal) const
{
this->AddColorBar(vtkm::Bounds(vtkm::Range(x, x+width),
vtkm::Range(y,y+height),
vtkm::Range(0,0)),
colorTable,
horizontal);
}
VTKM_RENDERING_EXPORT
virtual void AddText(const vtkm::Vec<vtkm::Float32,2> &position,
vtkm::Float32 scale,
vtkm::Float32 angle,
vtkm::Float32 windowAspect,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color & color,
const std::string &text) const = 0;
VTKM_CONT_EXPORT
void AddText(vtkm::Float32 x, vtkm::Float32 y,
vtkm::Float32 scale,
vtkm::Float32 angle,
vtkm::Float32 windowAspect,
vtkm::Float32 anchorX, vtkm::Float32 anchorY,
const vtkm::rendering::Color & color,
const std::string &text) const
{
this->AddText(vtkm::make_Vec(x, y),
scale,
angle,
windowAspect,
vtkm::make_Vec(anchorX, anchorY),
color,
text);
}
/// Creates a WorldAnnotator of a type that is paired with this Canvas. Other
/// types of world annotators might work, but this provides a default.
@ -162,11 +196,8 @@ public:
/// deleted with delete later). A pointer to the created WorldAnnotator is
/// returned.
///
VTKM_CONT_EXPORT
virtual vtkm::rendering::WorldAnnotator *CreateWorldAnnotator() const
{
return new vtkm::rendering::WorldAnnotator;
}
VTKM_RENDERING_EXPORT
virtual vtkm::rendering::WorldAnnotator *CreateWorldAnnotator() const;
private:
vtkm::Id Width;

@ -0,0 +1,130 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/CanvasEGL.h>
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <EGL/egl.h>
//#include <GL/gl.h>
namespace vtkm {
namespace rendering {
namespace detail {
struct CanvasEGLInternals
{
EGLContext Context;
EGLDisplay Display;
EGLSurface Surface;
};
} // namespace detail
CanvasEGL::CanvasEGL(vtkm::Id width, vtkm::Id height)
: CanvasGL(width, height),
Internals(new detail::CanvasEGLInternals)
{
this->Internals->Context = nullptr;
this->ResizeBuffers(width, height);
}
CanvasEGL::~CanvasEGL()
{
}
void CanvasEGL::Initialize()
{
this->Internals->Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (!(this->Internals->Display))
{
throw vtkm::cont::ErrorControlBadValue("Failed to get EGL display");
}
EGLint major, minor;
if (!(eglInitialize(this->Internals->Display, &major, &minor)))
{
throw vtkm::cont::ErrorControlBadValue("Failed to initialize EGL display");
}
const EGLint cfgAttrs[] =
{
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
EGLint nCfgs;
EGLConfig cfg;
if (!(eglChooseConfig(this->Internals->Display, cfgAttrs, &cfg, 1, &nCfgs)) ||
(nCfgs == 0))
{
throw vtkm::cont::ErrorControlBadValue("Failed to get EGL config");
}
const EGLint pbAttrs[] =
{
EGL_WIDTH, static_cast<EGLint>(this->GetWidth()),
EGL_HEIGHT, static_cast<EGLint>(this->GetHeight()),
EGL_NONE,
};
this->Internals->Surface =
eglCreatePbufferSurface(this->Internals->Display, cfg, pbAttrs);
if (!this->Internals->Surface)
{
throw vtkm::cont::ErrorControlBadValue("Failed to create EGL PBuffer surface");
}
eglBindAPI(EGL_OPENGL_API);
this->Internals->Context =
eglCreateContext(this->Internals->Display, cfg, EGL_NO_CONTEXT, NULL);
if (!this->Internals->Context)
{
throw vtkm::cont::ErrorControlBadValue("Failed to create EGL context");
}
if (!(eglMakeCurrent(this->Internals->Display,
this->Internals->Surface,
this->Internals->Surface,
this->Internals->Context)))
{
throw vtkm::cont::ErrorControlBadValue("Failed to create EGL context current");
}
}
void CanvasEGL::Activate()
{
glEnable(GL_DEPTH_TEST);
}
vtkm::rendering::Canvas *CanvasEGL::NewCopy() const
{
return new vtkm::rendering::CanvasEGL(*this);
}
}
} // namespace vtkm::rendering

@ -6,9 +6,9 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
@ -20,93 +20,44 @@
#ifndef vtk_m_rendering_CanvasEGL_h
#define vtk_m_rendering_CanvasEGL_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <EGL/egl.h>
//#include <GL/gl.h>
#include <iostream>
#include <fstream>
#include <vtkm/rendering/CanvasGL.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/shared_ptr.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
namespace vtkm {
namespace rendering {
namespace detail {
struct CanvasEGLInternals;
}
class CanvasEGL : public CanvasGL
{
public:
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
CanvasEGL(vtkm::Id width=1024,
vtkm::Id height=1024)
: CanvasGL(width,height)
{
ctx = nullptr;
this->ResizeBuffers(width, height);
}
vtkm::Id height=1024);
VTKM_CONT_EXPORT
virtual void Initialize()
{
if (!(dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)))
throw vtkm::cont::ErrorControlBadValue("Failed to get EGL display");
EGLint major, minor;
if (!(eglInitialize(dpy, &major, &minor)))
throw vtkm::cont::ErrorControlBadValue("Failed to initialize EGL display");
VTKM_RENDERING_EXPORT
~CanvasEGL();
const EGLint cfgAttrs[] =
{
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
VTKM_RENDERING_EXPORT
virtual void Initialize() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
virtual void Activate() VTKM_OVERRIDE;
EGLint nCfgs;
EGLConfig cfg;
if (!(eglChooseConfig(dpy, cfgAttrs, &cfg, 1, &nCfgs)) || nCfgs == 0)
throw vtkm::cont::ErrorControlBadValue("Failed to get EGL config");
const EGLint pbAttrs[] =
{
EGL_WIDTH, static_cast<EGLint>(this->GetWidth()),
EGL_HEIGHT, static_cast<EGLint>(this->GetHeight()),
EGL_NONE,
};
if (!(surf = eglCreatePbufferSurface(dpy, cfg, pbAttrs)))
throw vtkm::cont::ErrorControlBadValue("Failed to create EGL PBuffer surface");
eglBindAPI(EGL_OPENGL_API);
if (!(ctx = eglCreateContext(dpy, cfg, EGL_NO_CONTEXT, NULL)))
throw vtkm::cont::ErrorControlBadValue("Failed to create EGL context");
if (!(eglMakeCurrent(dpy, surf, surf, ctx)))
throw vtkm::cont::ErrorControlBadValue("Failed to create EGL context current");
}
VTKM_CONT_EXPORT
virtual void Activate()
{
glEnable(GL_DEPTH_TEST);
}
VTKM_CONT_EXPORT
virtual void Clear()
{
vtkm::rendering::Color backgroundColor = this->GetBackgroundColor();
glClearColor(backgroundColor.Components[0],
backgroundColor.Components[1],
backgroundColor.Components[2],
1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
VTKM_RENDERING_EXPORT
vtkm::rendering::Canvas *NewCopy() const VTKM_OVERRIDE;
private:
EGLContext ctx;
EGLDisplay dpy;
EGLSurface surf;
boost::shared_ptr<detail::CanvasEGLInternals> Internals;
};
}} //namespace vtkm::rendering

339
vtkm/rendering/CanvasGL.cxx Normal file

@ -0,0 +1,339 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/DecodePNG.h>
#include <vtkm/rendering/MatrixHelpers.h>
#include <vtkm/rendering/WorldAnnotatorGL.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
namespace vtkm {
namespace rendering {
CanvasGL::CanvasGL(vtkm::Id width, vtkm::Id height)
: Canvas(width,height)
{
}
CanvasGL::~CanvasGL()
{
}
void CanvasGL::Initialize()
{
// Nothing to initialize
}
void CanvasGL::Activate()
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
this->ResizeBuffers(viewport[2], viewport[3]);
glEnable(GL_DEPTH_TEST);
}
void CanvasGL::Clear()
{
vtkm::rendering::Color backgroundColor = this->GetBackgroundColor();
glClearColor(backgroundColor.Components[0],
backgroundColor.Components[1],
backgroundColor.Components[2],
1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void CanvasGL::Finish()
{
glFinish();
}
vtkm::rendering::Canvas *CanvasGL::NewCopy() const
{
return new vtkm::rendering::CanvasGL(*this);
}
void CanvasGL::SetViewToWorldSpace(const vtkm::rendering::Camera &camera,
bool clip)
{
vtkm::Float32 oglP[16], oglM[16];
MatrixHelpers::CreateOGLMatrix(
camera.CreateProjectionMatrix(this->GetWidth(),
this->GetHeight()),
oglP);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(oglP);
MatrixHelpers::CreateOGLMatrix(camera.CreateViewMatrix(), oglM);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(oglM);
this->SetViewportClipping(camera, clip);
}
void CanvasGL::SetViewToScreenSpace(const vtkm::rendering::Camera &camera,
bool clip)
{
vtkm::Float32 oglP[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
vtkm::Float32 oglM[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
oglP[0*4+0] = 1.;
oglP[1*4+1] = 1.;
oglP[2*4+2] = -1.;
oglP[3*4+3] = 1.;
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(oglP);
oglM[0*4+0] = 1.;
oglM[1*4+1] = 1.;
oglM[2*4+2] = 1.;
oglM[3*4+3] = 1.;
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(oglM);
this->SetViewportClipping(camera, clip);
}
void CanvasGL::SetViewportClipping(const vtkm::rendering::Camera &camera,
bool clip)
{
if (clip)
{
vtkm::Float32 vl, vr, vb, vt;
camera.GetRealViewport(this->GetWidth(), this->GetHeight(),
vl,vr,vb,vt);
vtkm::Float32 _x = static_cast<vtkm::Float32>(this->GetWidth())*(1.f+vl)/2.f;
vtkm::Float32 _y = static_cast<vtkm::Float32>(this->GetHeight())*(1.f+vb)/2.f;
vtkm::Float32 _w = static_cast<vtkm::Float32>(this->GetWidth())*(vr-vl)/2.f;
vtkm::Float32 _h = static_cast<vtkm::Float32>(this->GetHeight())*(vt-vb)/2.f;
glViewport(static_cast<GLint>(_x), static_cast<GLint>(_y),
static_cast<GLsizei>(_w), static_cast<GLsizei>(_h));
}
else
{
glViewport(0,
0,
static_cast<GLsizei>(this->GetWidth()),
static_cast<GLsizei>(this->GetHeight()));
}
}
void CanvasGL::RefreshColorBuffer() const
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
VTKM_ASSERT(viewport[2] == this->GetWidth());
VTKM_ASSERT(viewport[3] == this->GetHeight());
glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
GL_RGBA, GL_FLOAT,
const_cast<vtkm::Vec<float,4> *>(
this->GetColorBuffer().GetStorage().GetArray()));
}
void CanvasGL::RefreshDepthBuffer() const
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
VTKM_ASSERT(viewport[2] == this->GetWidth());
VTKM_ASSERT(viewport[3] == this->GetHeight());
glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
GL_DEPTH_COMPONENT, GL_FLOAT,
const_cast<vtkm::Float32 *>(
this->GetDepthBuffer().GetStorage().GetArray()));
}
void CanvasGL::AddLine(const vtkm::Vec<vtkm::Float64,2> &point0,
const vtkm::Vec<vtkm::Float64,2> &point1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &color) const
{
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glLineWidth(linewidth);
glBegin(GL_LINES);
glVertex2f(float(point0[0]),float(point0[1]));
glVertex2f(float(point1[0]),float(point1[1]));
glEnd();
}
void CanvasGL::AddColorBar(const vtkm::Bounds &bounds,
const vtkm::rendering::ColorTable &colorTable,
bool horizontal) const
{
const int n = 256;
vtkm::Float32 startX = static_cast<vtkm::Float32>(bounds.X.Min);
vtkm::Float32 startY = static_cast<vtkm::Float32>(bounds.Y.Min);
vtkm::Float32 width = static_cast<vtkm::Float32>(bounds.X.Length());
vtkm::Float32 height = static_cast<vtkm::Float32>(bounds.Y.Length());
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glBegin(GL_QUADS);
for (int i=0; i<n; i++)
{
vtkm::Float32 v0 = static_cast<vtkm::Float32>(i)/static_cast<vtkm::Float32>(n);
vtkm::Float32 v1 = static_cast<vtkm::Float32>(i+1)/static_cast<vtkm::Float32>(n);
vtkm::rendering::Color c0 = colorTable.MapRGB(v0);
vtkm::rendering::Color c1 = colorTable.MapRGB(v1);
if (horizontal)
{
vtkm::Float32 x0 = startX + width*v0;
vtkm::Float32 x1 = startX + width*v1;
vtkm::Float32 y0 = startY;
vtkm::Float32 y1 = startY + height;
glColor3f(c0.Components[0], c0.Components[1], c0.Components[2]);
glVertex2f(x0,y0);
glVertex2f(x0,y1);
glColor3f(c1.Components[0], c1.Components[1], c1.Components[2]);
glVertex2f(x1,y1);
glVertex2f(x1,y0);
}
else // vertical
{
vtkm::Float32 x0 = startX;
vtkm::Float32 x1 = startX + width;
vtkm::Float32 y0 = startY + height*v0;
vtkm::Float32 y1 = startY + height*v1;
glColor3f(c0.Components[0], c0.Components[1], c0.Components[2]);
glVertex2f(x0,y1);
glVertex2f(x1,y1);
glColor3f(c1.Components[0], c1.Components[1], c1.Components[2]);
glVertex2f(x1,y0);
glVertex2f(x0,y0);
}
}
glEnd();
}
void CanvasGL::AddText(const vtkm::Vec<vtkm::Float32,2> &position,
vtkm::Float32 scale,
vtkm::Float32 angle,
vtkm::Float32 windowAspect,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color & color,
const std::string &text) const
{
glPushMatrix();
glTranslatef(position[0],position[1],0);
glScalef(1.f/windowAspect, 1, 1);
glRotatef(angle, 0,0,1);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
this->RenderText(scale, anchor, text);
glPopMatrix();
}
vtkm::rendering::WorldAnnotator *
CanvasGL::CreateWorldAnnotator() const
{
return new vtkm::rendering::WorldAnnotatorGL;
}
void CanvasGL::RenderText(vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const std::string &text) const
{
if (!this->FontTexture.Valid())
{
// When we load a font, we save a reference to it for the next time we
// use it. Although technically we are changing the state, the logical
// state does not change, so we go ahead and do it in this const
// function.
vtkm::rendering::CanvasGL *self =
const_cast<vtkm::rendering::CanvasGL *>(this);
self->Font = BitmapFontFactory::CreateLiberation2Sans();
const std::vector<unsigned char> &rawpngdata =
this->Font.GetRawImageData();
std::vector<unsigned char> rgba;
unsigned long width, height;
int error = vtkm::rendering::DecodePNG(rgba, width, height,
&rawpngdata[0], rawpngdata.size());
if (error != 0)
{
return;
}
self->FontTexture.CreateAlphaFromRGBA(int(width),int(height),rgba);
}
this->FontTexture.Enable();
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHTING);
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -.5);
glBegin(GL_QUADS);
vtkm::Float32 textwidth = this->Font.GetTextWidth(text);
vtkm::Float32 fx = -(.5f + .5f*anchor[0]) * textwidth;
vtkm::Float32 fy = -(.5f + .5f*anchor[1]);
vtkm::Float32 fz = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
char c = text[i];
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
vtkm::Float32 vl,vr,vt,vb;
vtkm::Float32 tl,tr,tt,tb;
this->Font.GetCharPolygon(c, fx, fy,
vl, vr, vt, vb,
tl, tr, tt, tb, nextchar);
glTexCoord2f(tl, 1.f-tt);
glVertex3f(scale*vl, scale*vt, fz);
glTexCoord2f(tl, 1.f-tb);
glVertex3f(scale*vl, scale*vb, fz);
glTexCoord2f(tr, 1.f-tb);
glVertex3f(scale*vr, scale*vb, fz);
glTexCoord2f(tr, 1.f-tt);
glVertex3f(scale*vr, scale*vt, fz);
}
glEnd();
this->FontTexture.Disable();
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
}
}
} // namespace vtkm::rendering

@ -20,19 +20,11 @@
#ifndef vtk_m_rendering_CanvasGL_h
#define vtk_m_rendering_CanvasGL_h
#include <vtkm/Types.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/BitmapFont.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/TextureGL.h>
#include <vtkm/rendering/MatrixHelpers.h>
#include <vtkm/rendering/WorldAnnotatorGL.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <iostream>
#include <fstream>
#include <vtkm/rendering/BitmapFont.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/TextureGL.h>
namespace vtkm {
namespace rendering {
@ -40,314 +32,78 @@ namespace rendering {
class CanvasGL : public Canvas
{
public:
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
CanvasGL(vtkm::Id width=1024,
vtkm::Id height=1024)
: Canvas(width,height)
{
}
vtkm::Id height=1024);
VTKM_CONT_EXPORT
virtual void Initialize()
{
// Nothing to initialize
}
VTKM_RENDERING_EXPORT
~CanvasGL();
VTKM_CONT_EXPORT
virtual void Activate()
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
this->ResizeBuffers(viewport[2], viewport[3]);
VTKM_RENDERING_EXPORT
void Initialize() VTKM_OVERRIDE;
glEnable(GL_DEPTH_TEST);
}
VTKM_RENDERING_EXPORT
void Activate() VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void Clear()
{
vtkm::rendering::Color backgroundColor = this->GetBackgroundColor();
glClearColor(backgroundColor.Components[0],
backgroundColor.Components[1],
backgroundColor.Components[2],
1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
VTKM_RENDERING_EXPORT
void Clear() VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void Finish()
{
glFinish();
}
VTKM_RENDERING_EXPORT
void Finish() VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void SetViewToWorldSpace(const vtkm::rendering::Camera &camera,
bool clip)
{
vtkm::Float32 oglP[16], oglM[16];
VTKM_RENDERING_EXPORT
vtkm::rendering::Canvas *NewCopy() const VTKM_OVERRIDE;
MatrixHelpers::CreateOGLMatrix(
camera.CreateProjectionMatrix(this->GetWidth(),
this->GetHeight()),
oglP);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(oglP);
MatrixHelpers::CreateOGLMatrix(camera.CreateViewMatrix(), oglM);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(oglM);
VTKM_RENDERING_EXPORT
void SetViewToWorldSpace(const vtkm::rendering::Camera &camera,
bool clip) VTKM_OVERRIDE;
SetViewportClipping(camera, clip);
}
VTKM_RENDERING_EXPORT
void SetViewToScreenSpace(const vtkm::rendering::Camera &camera,
bool clip) VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void SetViewToScreenSpace(const vtkm::rendering::Camera &camera,
bool clip)
{
vtkm::Float32 oglP[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
vtkm::Float32 oglM[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
VTKM_RENDERING_EXPORT
void SetViewportClipping(const vtkm::rendering::Camera &camera,
bool clip) VTKM_OVERRIDE;
oglP[0*4+0] = 1.;
oglP[1*4+1] = 1.;
oglP[2*4+2] = -1.;
oglP[3*4+3] = 1.;
VTKM_RENDERING_EXPORT
void RefreshColorBuffer() const VTKM_OVERRIDE;
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(oglP);
VTKM_RENDERING_EXPORT
virtual void RefreshDepthBuffer() const VTKM_OVERRIDE;
oglM[0*4+0] = 1.;
oglM[1*4+1] = 1.;
oglM[2*4+2] = 1.;
oglM[3*4+3] = 1.;
VTKM_RENDERING_EXPORT
void AddLine(const vtkm::Vec<vtkm::Float64,2> &point0,
const vtkm::Vec<vtkm::Float64,2> &point1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &color) const VTKM_OVERRIDE;
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(oglM);
SetViewportClipping(camera, clip);
}
VTKM_CONT_EXPORT
virtual void SetViewportClipping(
const vtkm::rendering::Camera &camera, bool clip)
{
if (clip)
{
vtkm::Float32 vl, vr, vb, vt;
camera.GetRealViewport(this->GetWidth(), this->GetHeight(),
vl,vr,vb,vt);
vtkm::Float32 _x = static_cast<vtkm::Float32>(this->GetWidth())*(1.f+vl)/2.f;
vtkm::Float32 _y = static_cast<vtkm::Float32>(this->GetHeight())*(1.f+vb)/2.f;
vtkm::Float32 _w = static_cast<vtkm::Float32>(this->GetWidth())*(vr-vl)/2.f;
vtkm::Float32 _h = static_cast<vtkm::Float32>(this->GetHeight())*(vt-vb)/2.f;
glViewport(static_cast<GLint>(_x), static_cast<GLint>(_y),
static_cast<GLsizei>(_w), static_cast<GLsizei>(_h));
}
else
{
glViewport(0,
0,
static_cast<GLsizei>(this->GetWidth()),
static_cast<GLsizei>(this->GetHeight()));
}
}
VTKM_CONT_EXPORT
virtual void RefreshColorBuffer()
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
VTKM_ASSERT(viewport[2] == this->GetWidth());
VTKM_ASSERT(viewport[3] == this->GetHeight());
glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
GL_RGBA, GL_FLOAT,
&(*vtkm::cont::ArrayPortalToIteratorBegin(
this->GetColorBuffer().GetPortalControl())));
}
VTKM_CONT_EXPORT
virtual void RefreshDepthBuffer()
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
VTKM_ASSERT(viewport[2] == this->GetWidth());
VTKM_ASSERT(viewport[3] == this->GetHeight());
glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
GL_DEPTH_COMPONENT, GL_FLOAT,
&(*vtkm::cont::ArrayPortalToIteratorBegin(
this->GetDepthBuffer().GetPortalControl())));
}
VTKM_CONT_EXPORT
virtual void AddLine(vtkm::Float64 x0, vtkm::Float64 y0,
vtkm::Float64 x1, vtkm::Float64 y1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &c) const
{
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glColor3f(c.Components[0], c.Components[1], c.Components[2]);
glLineWidth(linewidth);
glBegin(GL_LINES);
glVertex2f(float(x0),float(y0));
glVertex2f(float(x1),float(y1));
glEnd();
}
VTKM_CONT_EXPORT
virtual void AddColorBar(vtkm::Float32 x, vtkm::Float32 y,
vtkm::Float32 w, vtkm::Float32 h,
const vtkm::rendering::ColorTable &ct,
bool horizontal) const
{
const int n = 256;
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glBegin(GL_QUADS);
for (int i=0; i<n; i++)
{
vtkm::Float32 v0 = static_cast<vtkm::Float32>(i)/static_cast<vtkm::Float32>(n);
vtkm::Float32 v1 = static_cast<vtkm::Float32>(i+1)/static_cast<vtkm::Float32>(n);
Color c0 = ct.MapRGB(v0);
Color c1 = ct.MapRGB(v1);
if (horizontal)
{
vtkm::Float32 x0 = x + w*v0;
vtkm::Float32 x1 = x + w*v1;
vtkm::Float32 y0 = y;
vtkm::Float32 y1 = y + h;
glColor3f(c0.Components[0], c0.Components[1], c0.Components[2]);
glVertex2f(x0,y0);
glVertex2f(x0,y1);
glColor3f(c1.Components[0], c1.Components[1], c1.Components[2]);
glVertex2f(x1,y1);
glVertex2f(x1,y0);
}
else // vertical
{
vtkm::Float32 x0 = x;
vtkm::Float32 x1 = x + w;
vtkm::Float32 y0 = y + h*v0;
vtkm::Float32 y1 = y + h*v1;
glColor3f(c0.Components[0], c0.Components[1], c0.Components[2]);
glVertex2f(x0,y1);
glVertex2f(x1,y1);
glColor3f(c1.Components[0], c1.Components[1], c1.Components[2]);
glVertex2f(x1,y0);
glVertex2f(x0,y0);
}
}
glEnd();
}
VTKM_RENDERING_EXPORT
void AddColorBar(const vtkm::Bounds &bounds,
const vtkm::rendering::ColorTable &colorTable,
bool horizontal) const VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void AddText(vtkm::Float32 x, vtkm::Float32 y,
vtkm::Float32 scale,
vtkm::Float32 angle,
vtkm::Float32 windowaspect,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
Color color,
std::string text) const
{
glPushMatrix();
glTranslatef(x,y,0);
glScalef(1.f/windowaspect, 1, 1);
glRotatef(angle, 0,0,1);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
this->RenderText(scale, anchorx, anchory, text);
glPopMatrix();
}
VTKM_RENDERING_EXPORT
void AddText(const vtkm::Vec<vtkm::Float32,2> &position,
vtkm::Float32 scale,
vtkm::Float32 angle,
vtkm::Float32 windowAspect,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color & color,
const std::string &text) const VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual vtkm::rendering::WorldAnnotator *CreateWorldAnnotator() const
{
return new vtkm::rendering::WorldAnnotatorGL;
}
VTKM_RENDERING_EXPORT
vtkm::rendering::WorldAnnotator *CreateWorldAnnotator() const VTKM_OVERRIDE;
private:
BitmapFont Font;
TextureGL FontTexture;
vtkm::rendering::BitmapFont Font;
vtkm::rendering::TextureGL FontTexture;
VTKM_RENDERING_EXPORT
void RenderText(vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
std::string text) const
{
if (this->FontTexture.ID == 0)
{
// When we load a font, we save a reference to it for the next time we
// use it. Although technically we are changing the state, the logical
// state does not change, so we go ahead and do it in this const
// function.
vtkm::rendering::CanvasGL *self =
const_cast<vtkm::rendering::CanvasGL *>(this);
self->Font = BitmapFontFactory::CreateLiberation2Sans();
const std::vector<unsigned char> &rawpngdata =
this->Font.GetRawImageData();
std::vector<unsigned char> rgba;
unsigned long width, height;
int error = decodePNG(rgba, width, height,
&rawpngdata[0], rawpngdata.size());
if (error != 0)
{
return;
}
self->FontTexture.CreateAlphaFromRGBA(int(width),int(height),rgba);
}
this->FontTexture.Enable();
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHTING);
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -.5);
glBegin(GL_QUADS);
vtkm::Float32 textwidth = this->Font.GetTextWidth(text);
vtkm::Float32 fx = -(.5f + .5f*anchorx) * textwidth;
vtkm::Float32 fy = -(.5f + .5f*anchory);
vtkm::Float32 fz = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
char c = text[i];
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
vtkm::Float32 vl,vr,vt,vb;
vtkm::Float32 tl,tr,tt,tb;
this->Font.GetCharPolygon(c, fx, fy,
vl, vr, vt, vb,
tl, tr, tt, tb, nextchar);
glTexCoord2f(tl, 1.f-tt);
glVertex3f(scale*vl, scale*vt, fz);
glTexCoord2f(tl, 1.f-tb);
glVertex3f(scale*vl, scale*vb, fz);
glTexCoord2f(tr, 1.f-tb);
glVertex3f(scale*vr, scale*vb, fz);
glTexCoord2f(tr, 1.f-tt);
glVertex3f(scale*vr, scale*vt, fz);
}
glEnd();
this->FontTexture.Disable();
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
}
const vtkm::Vec<vtkm::Float32,2> &anchor,
const std::string &text) const;
};
}} //namespace vtkm::rendering

@ -0,0 +1,119 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/CanvasOSMesa.h>
#include <vtkm/Types.h>
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <GL/osmesa.h>
namespace vtkm {
namespace rendering {
namespace detail {
struct CanvasOSMesaInternals
{
OSMesaContext Context;
};
} // namespace detail
CanvasOSMesa::CanvasOSMesa(vtkm::Id width, vtkm::Id height)
: CanvasGL(width,height),
Internals(new detail::CanvasOSMesaInternals)
{
this->Internals->Context = nullptr;
this->ResizeBuffers(width, height);
}
CanvasOSMesa::~CanvasOSMesa()
{
}
void CanvasOSMesa::Initialize()
{
this->Internals->Context =
OSMesaCreateContextExt(OSMESA_RGBA, 32, 0, 0, NULL);
if (!this->Internals->Context)
{
throw vtkm::cont::ErrorControlBadValue("OSMesa context creation failed.");
}
vtkm::Vec<vtkm::Float32,4> *colorBuffer =
this->GetColorBuffer().GetStorage().GetArray();
if (!OSMesaMakeCurrent(this->Internals->Context,
reinterpret_cast<vtkm::Float32*>(colorBuffer),
GL_FLOAT,
static_cast<GLsizei>(this->GetWidth()),
static_cast<GLsizei>(this->GetHeight())))
{
throw vtkm::cont::ErrorControlBadValue("OSMesa context activation failed.");
}
}
void CanvasOSMesa::RefreshColorBuffer() const
{
// Override superclass because our OSMesa implementation renders right
// to the color buffer.
}
void CanvasOSMesa::Activate()
{
glEnable(GL_DEPTH_TEST);
}
void CanvasOSMesa::Finish()
{
this->CanvasGL::Finish();
// This is disabled because it is handled in RefreshDepthBuffer
#if 0
//Copy zbuff into floating point array.
unsigned int *raw_zbuff;
int zbytes, w, h;
GLboolean ret;
ret = OSMesaGetDepthBuffer(this->Internals->Context, &w, &h, &zbytes, (void**)&raw_zbuff);
if (!ret ||
static_cast<vtkm::Id>(w)!=this->GetWidth() ||
static_cast<vtkm::Id>(h)!=this->GetHeight())
{
throw vtkm::cont::ErrorControlBadValue("Wrong width/height in ZBuffer");
}
vtkm::cont::ArrayHandle<vtkm::Float32>::PortalControl depthPortal =
this->GetDepthBuffer().GetPortalControl();
vtkm::Id npixels = this->GetWidth()*this->GetHeight();
for (vtkm::Id i=0; i<npixels; i++)
for (std::size_t i=0; i<npixels; i++)
{
depthPortal.Set(i, float(raw_zbuff[i]) / float(UINT_MAX));
}
#endif
}
vtkm::rendering::Canvas *CanvasOSMesa::NewCopy() const
{
return new vtkm::rendering::CanvasOSMesa(*this);
}
}
} // namespace vtkm::rendering

@ -20,106 +20,50 @@
#ifndef vtk_m_rendering_CanvasOSMesa_h
#define vtk_m_rendering_CanvasOSMesa_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <GL/osmesa.h>
#include <GL/gl.h>
#include <iostream>
#include <fstream>
#include <vtkm/rendering/CanvasGL.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/shared_ptr.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
namespace vtkm {
namespace rendering {
namespace detail {
struct CanvasOSMesaInternals;
} // namespace detail
class CanvasOSMesa : public CanvasGL
{
public:
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
CanvasOSMesa(vtkm::Id width=1024,
vtkm::Id height=1024)
: CanvasGL(width,height)
{
ctx = nullptr;
this->ResizeBuffers(width, height);
}
vtkm::Id height=1024);
VTKM_CONT_EXPORT
virtual void Initialize()
{
ctx = OSMesaCreateContextExt(OSMESA_RGBA, 32, 0, 0, NULL);
if (!ctx)
{
throw vtkm::cont::ErrorControlBadValue("OSMesa context creation failed.");
}
vtkm::Vec<vtkm::Float32,4> *colorBuffer =
vtkm::cont::ArrayPortalToIteratorBegin(
this->GetColorBuffer().GetPortalControl());
if (!OSMesaMakeCurrent(ctx,
reinterpret_cast<vtkm::Float32*>(colorBuffer),
GL_FLOAT,
static_cast<GLsizei>(this->GetWidth()),
static_cast<GLsizei>(this->GetHeight())))
{
throw vtkm::cont::ErrorControlBadValue("OSMesa context activation failed.");
}
}
VTKM_RENDERING_EXPORT
~CanvasOSMesa();
VTKM_CONT_EXPORT
virtual void RefreshColorBuffer()
{
// Override superclass because our OSMesa implementation renders right
// to the color buffer.
}
VTKM_RENDERING_EXPORT
virtual void Initialize() VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void Activate()
{
glEnable(GL_DEPTH_TEST);
}
VTKM_RENDERING_EXPORT
virtual void RefreshColorBuffer() const VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void Clear()
{
vtkm::rendering::Color backgroundColor = this->GetBackgroundColor();
glClearColor(backgroundColor.Components[0],
backgroundColor.Components[1],
backgroundColor.Components[2],
1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
VTKM_CONT_EXPORT
virtual void Finish()
{
CanvasGL::Finish();
VTKM_RENDERING_EXPORT
virtual void Activate() VTKM_OVERRIDE;
// This is disabled because it is handled in RefreshDepthBuffer
#if 0
//Copy zbuff into floating point array.
unsigned int *raw_zbuff;
int zbytes, w, h;
GLboolean ret;
ret = OSMesaGetDepthBuffer(ctx, &w, &h, &zbytes, (void**)&raw_zbuff);
if (!ret ||
static_cast<vtkm::Id>(w)!=this->GetWidth() ||
static_cast<vtkm::Id>(h)!=this->GetHeight())
{
throw vtkm::cont::ErrorControlBadValue("Wrong width/height in ZBuffer");
}
vtkm::cont::ArrayHandle<vtkm::Float32>::PortalControl depthPortal =
this->GetDepthBuffer().GetPortalControl();
vtkm::Id npixels = this->GetWidth()*this->GetHeight();
for (vtkm::Id i=0; i<npixels; i++)
for (std::size_t i=0; i<npixels; i++)
{
depthPortal.Set(i, float(raw_zbuff[i]) / float(UINT_MAX));
}
#endif
}
VTKM_RENDERING_EXPORT
virtual void Finish() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
vtkm::rendering::Canvas *NewCopy() const VTKM_OVERRIDE;
private:
OSMesaContext ctx;
boost::shared_ptr<detail::CanvasOSMesaInternals> Internals;
};
}} //namespace vtkm::rendering

@ -0,0 +1,151 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/DispatcherMapField.h>
namespace vtkm {
namespace rendering {
namespace internal {
class ClearBuffers : public vtkm::worklet::WorkletMapField
{
vtkm::rendering::Color ClearColor;
public:
VTKM_CONT_EXPORT
ClearBuffers(const vtkm::rendering::Color &clearColor)
: ClearColor(clearColor)
{}
typedef void ControlSignature(FieldOut<>, FieldOut<>);
typedef void ExecutionSignature(_1, _2);
VTKM_EXEC_EXPORT
void operator()(vtkm::Vec<vtkm::Float32,4> &color,
vtkm::Float32 &depth) const
{
color = this->ClearColor.Components;
depth = 1.001f;
}
}; //class ClearBuffers
struct ClearBuffersInvokeFunctor
{
typedef vtkm::rendering::Canvas::ColorBufferType ColorBufferType;
typedef vtkm::rendering::Canvas::DepthBufferType DepthBufferType;
ClearBuffers Worklet;
ColorBufferType ColorBuffer;
DepthBufferType DepthBuffer;
VTKM_CONT_EXPORT
ClearBuffersInvokeFunctor(const vtkm::rendering::Color &backgroundColor,
const ColorBufferType &colorBuffer,
const DepthBufferType &depthBuffer)
: Worklet(backgroundColor),
ColorBuffer(colorBuffer),
DepthBuffer(depthBuffer)
{ }
template<typename Device>
VTKM_CONT_EXPORT
bool operator()(Device) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::worklet::DispatcherMapField<ClearBuffers, Device>
dispatcher(this->Worklet);
dispatcher.Invoke( this->ColorBuffer, this->DepthBuffer);
return true;
}
};
} // namespace internal
CanvasRayTracer::CanvasRayTracer(vtkm::Id width, vtkm::Id height)
: Canvas(width, height)
{ }
CanvasRayTracer::~CanvasRayTracer()
{ }
void CanvasRayTracer::Initialize()
{
// Nothing to initialize
}
void CanvasRayTracer::Activate()
{
// Nothing to activate
}
void CanvasRayTracer::Finish()
{
// Nothing to finish
}
void CanvasRayTracer::Clear()
{
// TODO: Should the rendering library support policies or some other way to
// configure with custom devices?
vtkm::cont::TryExecute(
internal::ClearBuffersInvokeFunctor(this->GetBackgroundColor(),
this->GetColorBuffer(),
this->GetDepthBuffer()));
}
vtkm::rendering::Canvas *CanvasRayTracer::NewCopy() const
{
return new vtkm::rendering::CanvasRayTracer(*this);
}
void CanvasRayTracer::AddLine(const vtkm::Vec<vtkm::Float64,2> &,
const vtkm::Vec<vtkm::Float64,2> &,
vtkm::Float32,
const vtkm::rendering::Color &) const
{
// Not implemented
}
void CanvasRayTracer::AddColorBar(const vtkm::Bounds &,
const vtkm::rendering::ColorTable &,
bool ) const
{
// Not implemented
}
void CanvasRayTracer::AddText(const vtkm::Vec<vtkm::Float32,2> &,
vtkm::Float32,
vtkm::Float32,
vtkm::Float32,
const vtkm::Vec<vtkm::Float32,2> &,
const vtkm::rendering::Color &,
const std::string &) const
{
// Not implemented
}
}
}

@ -20,14 +20,9 @@
#ifndef vtk_m_rendering_CanvasRayTracer_h
#define vtk_m_rendering_CanvasRayTracer_h
#include <vtkm/Types.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <iostream>
#include <fstream>
namespace vtkm {
namespace rendering {
@ -35,43 +30,48 @@ namespace rendering {
class CanvasRayTracer : public Canvas
{
public:
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
CanvasRayTracer(vtkm::Id width=1024,
vtkm::Id height=1024)
: Canvas(width,height)
{
}
vtkm::Id height=1024);
class ClearBuffers : public vtkm::worklet::WorkletMapField
{
vtkm::rendering::Color ClearColor;
public:
VTKM_CONT_EXPORT
ClearBuffers(const vtkm::rendering::Color &clearColor)
: ClearColor(clearColor)
{}
typedef void ControlSignature(FieldOut<>, FieldOut<>);
typedef void ExecutionSignature(_1, _2);
VTKM_EXEC_EXPORT
void operator()(vtkm::Vec<vtkm::Float32,4> &color,
vtkm::Float32 &depth) const
{
color = this->ClearColor.Components;
depth = 1.001f;
}
}; //class ClearBuffers
VTKM_RENDERING_EXPORT
~CanvasRayTracer();
virtual void Initialize() { }
virtual void Activate() { }
virtual void Finish() { }
VTKM_RENDERING_EXPORT
void Initialize() VTKM_OVERRIDE;
VTKM_CONT_EXPORT
virtual void Clear()
{
vtkm::worklet::DispatcherMapField< ClearBuffers >(
ClearBuffers( this->GetBackgroundColor() ) )
.Invoke( this->GetColorBuffer(), this->GetDepthBuffer());
}
VTKM_RENDERING_EXPORT
void Activate() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void Finish() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void Clear() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
vtkm::rendering::Canvas *NewCopy() const VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void AddLine(const vtkm::Vec<vtkm::Float64,2> &point0,
const vtkm::Vec<vtkm::Float64,2> &point1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &color) const VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void AddColorBar(const vtkm::Bounds &bounds,
const vtkm::rendering::ColorTable &colorTable,
bool horizontal) const VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void AddText(const vtkm::Vec<vtkm::Float32,2> &position,
vtkm::Float32 scale,
vtkm::Float32 angle,
vtkm::Float32 windowAspect,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color & color,
const std::string &text) const VTKM_OVERRIDE;
};
}} //namespace vtkm::rendering

@ -24,6 +24,7 @@
#include <vtkm/cont/DataSet.h>
namespace vtkm {
namespace rendering {
/// \brief It's a color!
///
/// This class provides the basic representation of a color. This class was
@ -34,24 +35,27 @@ class Color
{
public:
vtkm::Vec<vtkm::Float32,4> Components;
VTKM_EXEC_CONT_EXPORT
Color()
{
Components[0] = 0;
Components[1] = 0;
Components[2] = 0;
Components[3] = 1;
}
: Components(0, 0, 0, 1)
{ }
VTKM_EXEC_CONT_EXPORT
Color(vtkm::Float32 r_,
vtkm::Float32 g_,
vtkm::Float32 b_,
vtkm::Float32 a_ = 1.f)
{
Components[0] = r_;
Components[1] = g_;
Components[2] = b_;
Components[3] = a_;
}
inline void SetComponentFromByte(vtkm::Int32 i, vtkm::UInt8 v)
: Components(r_, g_, b_, a_)
{ }
VTKM_EXEC_CONT_EXPORT
Color(const vtkm::Vec<vtkm::Float32,4> &components)
: Components(components)
{ }
VTKM_EXEC_CONT_EXPORT
void SetComponentFromByte(vtkm::Int32 i, vtkm::UInt8 v)
{
// Note that though GetComponentAsByte below
// multiplies by 256, we're dividing by 255. here.
@ -77,7 +81,9 @@ class Color
if (Components[i]<0) Components[i] = 0;
if (Components[i]>1) Components[i] = 1;
}
inline vtkm::UInt8 GetComponentAsByte(int i)
VTKM_EXEC_CONT_EXPORT
vtkm::UInt8 GetComponentAsByte(int i)
{
// We need this to match what OpenGL/Mesa do.
// Why? Well, we need to set glClearColor
@ -104,6 +110,8 @@ class Color
// but we have to clamp anyway.
return vtkm::UInt8((tv < 0) ? 0 : (tv > 255) ? 255 : tv);
}
VTKM_EXEC_CONT_EXPORT
void GetRGBA(vtkm::UInt8 &r, vtkm::UInt8 &g,
vtkm::UInt8 &b, vtkm::UInt8 &a)
{
@ -112,10 +120,14 @@ class Color
b = GetComponentAsByte(2);
a = GetComponentAsByte(3);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 RawBrightness()
{
return (Components[0]+Components[1]+Components[2])/3.;
}
VTKM_CONT_EXPORT
friend std::ostream &operator<<(std::ostream &out, const Color &c)
{
out << "["<<c.Components[0]<<","<<c.Components[1]<<","<<c.Components[2]<<","<<c.Components[3]<<"]";

@ -0,0 +1,72 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/ColorBarAnnotation.h>
namespace vtkm {
namespace rendering {
ColorBarAnnotation::ColorBarAnnotation()
{ }
ColorBarAnnotation::~ColorBarAnnotation()
{ }
void ColorBarAnnotation::SetRange(const vtkm::Range &range,
vtkm::IdComponent numTicks)
{
std::vector<vtkm::Float64> positions, proportions;
this->Axis.SetMinorTicks(positions, proportions); // clear any minor ticks
for (vtkm::IdComponent i=0; i<numTicks; ++i)
{
vtkm::Float64 prop =
static_cast<vtkm::Float64>(i) / static_cast<vtkm::Float64>(numTicks-1);
vtkm::Float64 pos = range.Min + prop*range.Length();
positions.push_back(pos);
proportions.push_back(prop);
}
this->Axis.SetMajorTicks(positions, proportions);
}
void ColorBarAnnotation::Render(
const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas)
{
vtkm::Bounds bounds(vtkm::Range(-0.88, +0.88),
vtkm::Range(+0.87, +0.92),
vtkm::Range(0, 0));
canvas.AddColorBar(bounds, this->ColorTable, true);
this->Axis.SetColor(vtkm::rendering::Color(1,1,1));
this->Axis.SetLineWidth(1);
this->Axis.SetScreenPosition(bounds.X.Min, bounds.Y.Min,
bounds.X.Max, bounds.Y.Min);
this->Axis.SetMajorTickSize(0, .02, 1.0);
this->Axis.SetMinorTickSize(0,0,0); // no minor ticks
this->Axis.SetLabelAlignment(TextAnnotation::HCenter,
TextAnnotation::Top);
this->Axis.Render(camera, worldAnnotator, canvas);
}
}
} // namespace vtkm::rendering

@ -20,6 +20,8 @@
#ifndef vtk_m_rendering_ColorBarAnnotation_h
#define vtk_m_rendering_ColorBarAnnotation_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/AxisAnnotation2D.h>
#include <vtkm/rendering/Camera.h>
@ -33,54 +35,35 @@ namespace rendering {
class ColorBarAnnotation
{
protected:
vtkm::rendering::ColorTable colortable;
vtkm::rendering::AxisAnnotation2D axis;
vtkm::rendering::ColorTable ColorTable;
vtkm::rendering::AxisAnnotation2D Axis;
public:
ColorBarAnnotation()
{
}
void SetColorTable(const vtkm::rendering::ColorTable &ct)
{
colortable = ct;
}
void SetRange(vtkm::Float64 l, vtkm::Float64 h, int nticks)
{
std::vector<vtkm::Float64> pos, prop;
axis.SetMinorTicks(pos, prop); // clear any minor ticks
VTKM_RENDERING_EXPORT
ColorBarAnnotation();
for (int i=0; i<nticks; ++i)
{
vtkm::Float64 p = static_cast<vtkm::Float64>(i) / static_cast<vtkm::Float64>(nticks-1);
vtkm::Float64 v = l + p*(h-l);
pos.push_back(v);
prop.push_back(p);
}
axis.SetMajorTicks(pos, prop);
}
void SetRange(const vtkm::Range &range, int nticks)
VTKM_RENDERING_EXPORT
virtual ~ColorBarAnnotation();
VTKM_CONT_EXPORT
void SetColorTable(const vtkm::rendering::ColorTable &colorTable)
{
this->SetRange(range.Min, range.Max, nticks);
this->ColorTable = colorTable;
}
VTKM_RENDERING_EXPORT
void SetRange(const vtkm::Range &range, vtkm::IdComponent numTicks);
VTKM_CONT_EXPORT
void SetRange(vtkm::Float64 l, vtkm::Float64 h, vtkm::IdComponent numTicks)
{
this->SetRange(vtkm::Range(l,h), numTicks);
}
VTKM_RENDERING_EXPORT
virtual void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas)
{
vtkm::Float32 l = -0.88f, r = +0.88f;
vtkm::Float32 b = +0.87f, t = +0.92f;
canvas.AddColorBar(l, t, r-l, b-t,
colortable, true);
axis.SetColor(Color(1,1,1));
axis.SetLineWidth(1);
axis.SetScreenPosition(l,b, r,b);
axis.SetMajorTickSize(0, .02, 1.0);
axis.SetMinorTickSize(0,0,0); // no minor ticks
axis.SetLabelAlignment(TextAnnotation::HCenter,
TextAnnotation::Top);
axis.Render(camera, worldAnnotator, canvas);
}
vtkm::rendering::Canvas &canvas);
};
}} //namespace vtkm::rendering

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,578 @@
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//
//=============================================================================
#include <vtkm/rendering/DecodePNG.h>
namespace vtkm {
namespace rendering {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Below is the PicoPNG source file obtained 2013-01-07 from
// http://lodev.org/lodepng/picopng.cpp. It has the following
// modifications relative to the original:
// 1. decodePNG() was renamed to DecodePNG()
// 2. std:: qualify size_t
// 3. remove #include <vector> (included elsewhere)
// 4. main() and helper code at the bottom of the file was removed
// 5. remove unused known_type variable
// 6. added explicit casts to remove compiler warnings
// 7. renamed a function argument to avoid a shadowing warning
// 8. default argument removed (moved to header prototype declaration)
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#include <vector>
/*
decodePNG: The picoPNG function, decodes a PNG file buffer in memory, into a raw pixel buffer.
out_image: output parameter, this will contain the raw pixels after decoding.
By default the output is 32-bit RGBA color.
The std::vector is automatically resized to the correct size.
image_width: output_parameter, this will contain the width of the image in pixels.
image_height: output_parameter, this will contain the height of the image in pixels.
in_png: pointer to the buffer of the PNG file in memory. To get it from a file on
disk, load it and store it in a memory buffer yourself first.
in_size: size of the input PNG file in bytes.
convert_to_rgba32: optional parameter, true by default.
Set to true to get the output in RGBA 32-bit (8 bit per channel) color format
no matter what color type the original PNG image had. This gives predictable,
useable data from any random input PNG.
Set to false to do no color conversion at all. The result then has the same data
type as the PNG image, which can range from 1 bit to 64 bits per pixel.
Information about the color type or palette colors are not provided. You need
to know this information yourself to be able to use the data so this only
works for trusted PNG files. Use LodePNG instead of picoPNG if you need this information.
return: 0 if success, not 0 if some error occured.
*/
int DecodePNG(std::vector<unsigned char>& out_image, unsigned long& image_width, unsigned long& image_height, const unsigned char* in_png, std::size_t in_size, bool convert_to_rgba32)
{
// picoPNG version 20101224
// Copyright (c) 2005-2010 Lode Vandevenne
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
// picoPNG is a PNG decoder in one C++ function of around 500 lines. Use picoPNG for
// programs that need only 1 .cpp file. Since it's a single function, it's very limited,
// it can convert a PNG to raw pixel data either converted to 32-bit RGBA color or
// with no color conversion at all. For anything more complex, another tiny library
// is available: LodePNG (lodepng.c(pp)), which is a single source and header file.
// Apologies for the compact code style, it's to make this tiny.
static const unsigned long LENBASE[29] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
static const unsigned long LENEXTRA[29] = {0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
static const unsigned long DISTBASE[30] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
static const unsigned long DISTEXTRA[30] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
static const unsigned long CLCL[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; //code length code lengths
struct Zlib //nested functions for zlib decompression
{
static unsigned long readBitFromStream(std::size_t& bitp, const unsigned char* bits) { unsigned long result = (bits[bitp >> 3] >> (bitp & 0x7)) & 1; bitp++; return result;}
static unsigned long readBitsFromStream(std::size_t& bitp, const unsigned char* bits, std::size_t nbits)
{
unsigned long result = 0;
for(std::size_t i = 0; i < nbits; i++) result += (readBitFromStream(bitp, bits)) << i;
return result;
}
struct HuffmanTree
{
int makeFromLengths(const std::vector<unsigned long>& bitlen, unsigned long maxbitlen)
{ //make tree given the lengths
unsigned long numcodes = (unsigned long)(bitlen.size()), treepos = 0, nodefilled = 0;
std::vector<unsigned long> tree1d(numcodes), blcount(maxbitlen + 1, 0), nextcode(maxbitlen + 1, 0);
for(unsigned long bits = 0; bits < numcodes; bits++) blcount[bitlen[bits]]++; //count number of instances of each code length
for(unsigned long bits = 1; bits <= maxbitlen; bits++) nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1;
for(unsigned long n = 0; n < numcodes; n++) if(bitlen[n] != 0) tree1d[n] = nextcode[bitlen[n]]++; //generate all the codes
tree2d.clear(); tree2d.resize(numcodes * 2, 32767); //32767 here means the tree2d isn't filled there yet
for(unsigned long n = 0; n < numcodes; n++) //the codes
for(unsigned long i = 0; i < bitlen[n]; i++) //the bits for this code
{
unsigned long bit = (tree1d[n] >> (bitlen[n] - i - 1)) & 1;
if(treepos > numcodes - 2) return 55;
if(tree2d[2 * treepos + bit] == 32767) //not yet filled in
{
if(i + 1 == bitlen[n]) { tree2d[2 * treepos + bit] = n; treepos = 0; } //last bit
else { tree2d[2 * treepos + bit] = ++nodefilled + numcodes; treepos = nodefilled; } //addresses are encoded as values > numcodes
}
else treepos = tree2d[2 * treepos + bit] - numcodes; //subtract numcodes from address to get address value
}
return 0;
}
int decode(bool& decoded, unsigned long& result, std::size_t& treepos, unsigned long bit) const
{ //Decodes a symbol from the tree
unsigned long numcodes = (unsigned long)tree2d.size() / 2;
if(treepos >= numcodes) return 11; //error: you appeared outside the codetree
result = tree2d[2 * treepos + bit];
decoded = (result < numcodes);
treepos = decoded ? 0 : result - numcodes;
return 0;
}
std::vector<unsigned long> tree2d; //2D representation of a huffman tree: The one dimension is "0" or "1", the other contains all nodes and leaves of the tree.
};
struct Inflator
{
int error;
void inflate(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, std::size_t inpos = 0)
{
std::size_t bp = 0, pos = 0; //bit pointer and byte pointer
error = 0;
unsigned long BFINAL = 0;
while(!BFINAL && !error)
{
if(bp >> 3 >= in.size()) { error = 52; return; } //error, bit pointer will jump past memory
BFINAL = readBitFromStream(bp, &in[inpos]);
unsigned long BTYPE = readBitFromStream(bp, &in[inpos]); BTYPE += 2 * readBitFromStream(bp, &in[inpos]);
if(BTYPE == 3) { error = 20; return; } //error: invalid BTYPE
else if(BTYPE == 0) inflateNoCompression(out, &in[inpos], bp, pos, in.size());
else inflateHuffmanBlock(out, &in[inpos], bp, pos, in.size(), BTYPE);
}
if(!error) out.resize(pos); //Only now we know the true size of out, resize it to that
}
void generateFixedTrees(HuffmanTree& tree, HuffmanTree& treeD) //get the tree of a deflated block with fixed tree
{
std::vector<unsigned long> bitlen(288, 8), bitlenD(32, 5);;
for(std::size_t i = 144; i <= 255; i++) bitlen[i] = 9;
for(std::size_t i = 256; i <= 279; i++) bitlen[i] = 7;
tree.makeFromLengths(bitlen, 15);
treeD.makeFromLengths(bitlenD, 15);
}
HuffmanTree codetree, codetreeD, codelengthcodetree; //the code tree for Huffman codes, dist codes, and code length codes
unsigned long huffmanDecodeSymbol(const unsigned char* in, std::size_t& bp, const HuffmanTree& lcodetree, std::size_t inlength)
{ //decode a single symbol from given list of bits with given code tree. return value is the symbol
bool decoded; unsigned long ct;
for(std::size_t treepos = 0;;)
{
if((bp & 0x07) == 0 && (bp >> 3) > inlength) { error = 10; return 0; } //error: end reached without endcode
error = lcodetree.decode(decoded, ct, treepos, readBitFromStream(bp, in)); if(error) return 0; //stop, an error happened
if(decoded) return ct;
}
}
void getTreeInflateDynamic(HuffmanTree& tree, HuffmanTree& treeD, const unsigned char* in, std::size_t& bp, std::size_t inlength)
{ //get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree
std::vector<unsigned long> bitlen(288, 0), bitlenD(32, 0);
if(bp >> 3 >= inlength - 2) { error = 49; return; } //the bit pointer is or will go past the memory
std::size_t HLIT = readBitsFromStream(bp, in, 5) + 257; //number of literal/length codes + 257
std::size_t HDIST = readBitsFromStream(bp, in, 5) + 1; //number of dist codes + 1
std::size_t HCLEN = readBitsFromStream(bp, in, 4) + 4; //number of code length codes + 4
std::vector<unsigned long> codelengthcode(19); //lengths of tree to decode the lengths of the dynamic tree
for(std::size_t i = 0; i < 19; i++) codelengthcode[CLCL[i]] = (i < HCLEN) ? readBitsFromStream(bp, in, 3) : 0;
error = codelengthcodetree.makeFromLengths(codelengthcode, 7); if(error) return;
std::size_t i = 0, replength;
while(i < HLIT + HDIST)
{
unsigned long code = huffmanDecodeSymbol(in, bp, codelengthcodetree, inlength); if(error) return;
if(code <= 15) { if(i < HLIT) bitlen[i++] = code; else bitlenD[i++ - HLIT] = code; } //a length code
else if(code == 16) //repeat previous
{
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
replength = 3 + readBitsFromStream(bp, in, 2);
unsigned long value; //set value to the previous code
if((i - 1) < HLIT) value = bitlen[i - 1];
else value = bitlenD[i - HLIT - 1];
for(std::size_t n = 0; n < replength; n++) //repeat this value in the next lengths
{
if(i >= HLIT + HDIST) { error = 13; return; } //error: i is larger than the amount of codes
if(i < HLIT) bitlen[i++] = value; else bitlenD[i++ - HLIT] = value;
}
}
else if(code == 17) //repeat "0" 3-10 times
{
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
replength = 3 + readBitsFromStream(bp, in, 3);
for(std::size_t n = 0; n < replength; n++) //repeat this value in the next lengths
{
if(i >= HLIT + HDIST) { error = 14; return; } //error: i is larger than the amount of codes
if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
}
}
else if(code == 18) //repeat "0" 11-138 times
{
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
replength = 11 + readBitsFromStream(bp, in, 7);
for(std::size_t n = 0; n < replength; n++) //repeat this value in the next lengths
{
if(i >= HLIT + HDIST) { error = 15; return; } //error: i is larger than the amount of codes
if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
}
}
else { error = 16; return; } //error: somehow an unexisting code appeared. This can never happen.
}
if(bitlen[256] == 0) { error = 64; return; } //the length of the end code 256 must be larger than 0
error = tree.makeFromLengths(bitlen, 15); if(error) return; //now we've finally got HLIT and HDIST, so generate the code trees, and the function is done
error = treeD.makeFromLengths(bitlenD, 15); if(error) return;
}
void inflateHuffmanBlock(std::vector<unsigned char>& out, const unsigned char* in, std::size_t& bp, std::size_t& pos, std::size_t inlength, unsigned long btype)
{
if(btype == 1) { generateFixedTrees(codetree, codetreeD); }
else if(btype == 2) { getTreeInflateDynamic(codetree, codetreeD, in, bp, inlength); if(error) return; }
for(;;)
{
unsigned long code = huffmanDecodeSymbol(in, bp, codetree, inlength); if(error) return;
if(code == 256) return; //end code
else if(code <= 255) //literal symbol
{
if(pos >= out.size()) out.resize((pos + 1) * 2); //reserve more room
out[pos++] = (unsigned char)(code);
}
else if(code >= 257 && code <= 285) //length code
{
std::size_t length = LENBASE[code - 257], numextrabits = LENEXTRA[code - 257];
if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
length += readBitsFromStream(bp, in, numextrabits);
unsigned long codeD = huffmanDecodeSymbol(in, bp, codetreeD, inlength); if(error) return;
if(codeD > 29) { error = 18; return; } //error: invalid dist code (30-31 are never used)
unsigned long dist = DISTBASE[codeD], numextrabitsD = DISTEXTRA[codeD];
if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
dist += readBitsFromStream(bp, in, numextrabitsD);
std::size_t start = pos, back = start - dist; //backwards
if(pos + length >= out.size()) out.resize((pos + length) * 2); //reserve more room
for(std::size_t i = 0; i < length; i++) { out[pos++] = out[back++]; if(back >= start) back = start - dist; }
}
}
}
void inflateNoCompression(std::vector<unsigned char>& out, const unsigned char* in, std::size_t& bp, std::size_t& pos, std::size_t inlength)
{
while((bp & 0x7) != 0) bp++; //go to first boundary of byte
std::size_t p = bp / 8;
if(p >= inlength - 4) { error = 52; return; } //error, bit pointer will jump past memory
unsigned long LEN = in[p] + 256 * in[p + 1], NLEN = in[p + 2] + 256 * in[p + 3]; p += 4;
if(LEN + NLEN != 65535) { error = 21; return; } //error: NLEN is not one's complement of LEN
if(pos + LEN >= out.size()) out.resize(pos + LEN);
if(p + LEN > inlength) { error = 23; return; } //error: reading outside of in buffer
for(unsigned long n = 0; n < LEN; n++) out[pos++] = in[p++]; //read LEN bytes of literal data
bp = p * 8;
}
};
int decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in) //returns error value
{
Inflator inflator;
if(in.size() < 2) { return 53; } //error, size of zlib data too small
if((in[0] * 256 + in[1]) % 31 != 0) { return 24; } //error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way
unsigned long CM = in[0] & 15, CINFO = (in[0] >> 4) & 15, FDICT = (in[1] >> 5) & 1;
if(CM != 8 || CINFO > 7) { return 25; } //error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec
if(FDICT != 0) { return 26; } //error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."
inflator.inflate(out, in, 2);
return inflator.error; //note: adler32 checksum was skipped and ignored
}
};
struct PNG //nested functions for PNG decoding
{
struct Info
{
unsigned long width, height, colorType, bitDepth, compressionMethod, filterMethod, interlaceMethod, key_r, key_g, key_b;
bool key_defined; //is a transparent color key given?
std::vector<unsigned char> palette;
} info;
int error;
void decode(std::vector<unsigned char>& out, const unsigned char* in, std::size_t size, bool convert_to_rgba32_flag)
{
error = 0;
if(size == 0 || in == 0) { error = 48; return; } //the given data is empty
readPngHeader(&in[0], size); if(error) return;
std::size_t pos = 33; //first byte of the first chunk after the header
std::vector<unsigned char> idat; //the data from idat chunks
bool IEND = false;
info.key_defined = false;
while(!IEND) //loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer
{
if(pos + 8 >= size) { error = 30; return; } //error: size of the in buffer too small to contain next chunk
std::size_t chunkLength = read32bitInt(&in[pos]); pos += 4;
if(chunkLength > 2147483647) { error = 63; return; }
if(pos + chunkLength >= size) { error = 35; return; } //error: size of the in buffer too small to contain next chunk
if(in[pos + 0] == 'I' && in[pos + 1] == 'D' && in[pos + 2] == 'A' && in[pos + 3] == 'T') //IDAT chunk, containing compressed image data
{
idat.insert(idat.end(), &in[pos + 4], &in[pos + 4 + chunkLength]);
pos += (4 + chunkLength);
}
else if(in[pos + 0] == 'I' && in[pos + 1] == 'E' && in[pos + 2] == 'N' && in[pos + 3] == 'D') { pos += 4; IEND = true; }
else if(in[pos + 0] == 'P' && in[pos + 1] == 'L' && in[pos + 2] == 'T' && in[pos + 3] == 'E') //palette chunk (PLTE)
{
pos += 4; //go after the 4 letters
info.palette.resize(4 * (chunkLength / 3));
if(info.palette.size() > (4 * 256)) { error = 38; return; } //error: palette too big
for(std::size_t i = 0; i < info.palette.size(); i += 4)
{
for(std::size_t j = 0; j < 3; j++) info.palette[i + j] = in[pos++]; //RGB
info.palette[i + 3] = 255; //alpha
}
}
else if(in[pos + 0] == 't' && in[pos + 1] == 'R' && in[pos + 2] == 'N' && in[pos + 3] == 'S') //palette transparency chunk (tRNS)
{
pos += 4; //go after the 4 letters
if(info.colorType == 3)
{
if(4 * chunkLength > info.palette.size()) { error = 39; return; } //error: more alpha values given than there are palette entries
for(std::size_t i = 0; i < chunkLength; i++) info.palette[4 * i + 3] = in[pos++];
}
else if(info.colorType == 0)
{
if(chunkLength != 2) { error = 40; return; } //error: this chunk must be 2 bytes for greyscale image
info.key_defined = 1; info.key_r = info.key_g = info.key_b = 256 * in[pos] + in[pos + 1]; pos += 2;
}
else if(info.colorType == 2)
{
if(chunkLength != 6) { error = 41; return; } //error: this chunk must be 6 bytes for RGB image
info.key_defined = 1;
info.key_r = 256 * in[pos] + in[pos + 1]; pos += 2;
info.key_g = 256 * in[pos] + in[pos + 1]; pos += 2;
info.key_b = 256 * in[pos] + in[pos + 1]; pos += 2;
}
else { error = 42; return; } //error: tRNS chunk not allowed for other color models
}
else //it's not an implemented chunk type, so ignore it: skip over the data
{
if(!(in[pos + 0] & 32)) { error = 69; return; } //error: unknown critical chunk (5th bit of first byte of chunk type is 0)
pos += (chunkLength + 4); //skip 4 letters and uninterpreted data of unimplemented chunk
}
pos += 4; //step over CRC (which is ignored)
}
unsigned long bpp = getBpp(info);
std::vector<unsigned char> scanlines(((info.width * (info.height * bpp + 7)) / 8) + info.height); //now the out buffer will be filled
Zlib zlib; //decompress with the Zlib decompressor
error = zlib.decompress(scanlines, idat); if(error) return; //stop if the zlib decompressor returned an error
std::size_t bytewidth = (bpp + 7) / 8, outlength = (info.height * info.width * bpp + 7) / 8;
out.resize(outlength); //time to fill the out buffer
unsigned char* out_ = outlength ? &out[0] : 0; //use a regular pointer to the std::vector for faster code if compiled without optimization
if(info.interlaceMethod == 0) //no interlace, just filter
{
std::size_t linestart = 0, linelength = (info.width * bpp + 7) / 8; //length in bytes of a scanline, excluding the filtertype byte
if(bpp >= 8) //byte per byte
for(unsigned long y = 0; y < info.height; y++)
{
unsigned long filterType = scanlines[linestart];
const unsigned char* prevline = (y == 0) ? 0 : &out_[(y - 1) * info.width * bytewidth];
unFilterScanline(&out_[linestart - y], &scanlines[linestart + 1], prevline, bytewidth, filterType, linelength); if(error) return;
linestart += (1 + linelength); //go to start of next scanline
}
else //less than 8 bits per pixel, so fill it up bit per bit
{
std::vector<unsigned char> templine((info.width * bpp + 7) >> 3); //only used if bpp < 8
for(std::size_t y = 0, obp = 0; y < info.height; y++)
{
unsigned long filterType = scanlines[linestart];
const unsigned char* prevline = (y == 0) ? 0 : &out_[(y - 1) * info.width * bytewidth];
unFilterScanline(&templine[0], &scanlines[linestart + 1], prevline, bytewidth, filterType, linelength); if(error) return;
for(std::size_t bp = 0; bp < info.width * bpp;) setBitOfReversedStream(obp, out_, readBitFromReversedStream(bp, &templine[0]));
linestart += (1 + linelength); //go to start of next scanline
}
}
}
else //interlaceMethod is 1 (Adam7)
{
std::size_t passw[7] = { (info.width + 7) / 8, (info.width + 3) / 8, (info.width + 3) / 4, (info.width + 1) / 4, (info.width + 1) / 2, (info.width + 0) / 2, (info.width + 0) / 1 };
std::size_t passh[7] = { (info.height + 7) / 8, (info.height + 7) / 8, (info.height + 3) / 8, (info.height + 3) / 4, (info.height + 1) / 4, (info.height + 1) / 2, (info.height + 0) / 2 };
std::size_t passstart[7] = {0};
std::size_t pattern[28] = {0,4,0,2,0,1,0,0,0,4,0,2,0,1,8,8,4,4,2,2,1,8,8,8,4,4,2,2}; //values for the adam7 passes
for(int i = 0; i < 6; i++) passstart[i + 1] = passstart[i] + passh[i] * ((passw[i] ? 1 : 0) + (passw[i] * bpp + 7) / 8);
std::vector<unsigned char> scanlineo((info.width * bpp + 7) / 8), scanlinen((info.width * bpp + 7) / 8); //"old" and "new" scanline
for(int i = 0; i < 7; i++)
adam7Pass(&out_[0], &scanlinen[0], &scanlineo[0], &scanlines[passstart[i]], info.width, pattern[i], pattern[i + 7], pattern[i + 14], pattern[i + 21], passw[i], passh[i], bpp);
}
if(convert_to_rgba32_flag && (info.colorType != 6 || info.bitDepth != 8)) //conversion needed
{
std::vector<unsigned char> data = out;
error = convert(out, &data[0], info, info.width, info.height);
}
}
void readPngHeader(const unsigned char* in, std::size_t inlength) //read the information from the header and store it in the Info
{
if(inlength < 29) { error = 27; return; } //error: the data length is smaller than the length of the header
if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { error = 28; return; } //no PNG signature
if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') { error = 29; return; } //error: it doesn't start with a IHDR chunk!
info.width = read32bitInt(&in[16]); info.height = read32bitInt(&in[20]);
info.bitDepth = in[24]; info.colorType = in[25];
info.compressionMethod = in[26]; if(in[26] != 0) { error = 32; return; } //error: only compression method 0 is allowed in the specification
info.filterMethod = in[27]; if(in[27] != 0) { error = 33; return; } //error: only filter method 0 is allowed in the specification
info.interlaceMethod = in[28]; if(in[28] > 1) { error = 34; return; } //error: only interlace methods 0 and 1 exist in the specification
error = checkColorValidity(info.colorType, info.bitDepth);
}
void unFilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, std::size_t bytewidth, unsigned long filterType, std::size_t length)
{
switch(filterType)
{
case 0: for(std::size_t i = 0; i < length; i++) recon[i] = scanline[i]; break;
case 1:
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i]);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + recon[i - bytewidth]);
break;
case 2:
if(precon) for(std::size_t i = 0; i < length; i++) recon[i] = (unsigned char)(scanline[i] + precon[i]);
else for(std::size_t i = 0; i < length; i++) recon[i] = (unsigned char)(scanline[i]);
break;
case 3:
if(precon)
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i] + precon[i] / 2);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2));
}
else
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i]);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + recon[i - bytewidth] / 2);
}
break;
case 4:
if(precon)
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(0, precon[i], 0));
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
}
else
{
for(std::size_t i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i]);
for(std::size_t i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], 0, 0));
}
break;
default: error = 36; return; //error: unexisting filter type given
}
}
void adam7Pass(unsigned char* out, unsigned char* linen, unsigned char* lineo, const unsigned char* in, unsigned long w, std::size_t passleft, std::size_t passtop, std::size_t spacex, std::size_t spacey, std::size_t passw, std::size_t passh, unsigned long bpp)
{ //filter and reposition the pixels into the output when the image is Adam7 interlaced. This function can only do it after the full image is already decoded. The out buffer must have the correct allocated memory size already.
if(passw == 0) return;
std::size_t bytewidth = (bpp + 7) / 8, linelength = 1 + ((bpp * passw + 7) / 8);
for(unsigned long y = 0; y < passh; y++)
{
unsigned char filterType = in[y * linelength], *prevline = (y == 0) ? 0 : lineo;
unFilterScanline(linen, &in[y * linelength + 1], prevline, bytewidth, filterType, (w * bpp + 7) / 8); if(error) return;
if(bpp >= 8) for(std::size_t i = 0; i < passw; i++) for(std::size_t b = 0; b < bytewidth; b++) //b = current byte of this pixel
out[bytewidth * w * (passtop + spacey * y) + bytewidth * (passleft + spacex * i) + b] = linen[bytewidth * i + b];
else for(std::size_t i = 0; i < passw; i++)
{
std::size_t obp = bpp * w * (passtop + spacey * y) + bpp * (passleft + spacex * i), bp = i * bpp;
for(std::size_t b = 0; b < bpp; b++) setBitOfReversedStream(obp, out, readBitFromReversedStream(bp, &linen[0]));
}
unsigned char* temp = linen; linen = lineo; lineo = temp; //swap the two buffer pointers "line old" and "line new"
}
}
static unsigned long readBitFromReversedStream(std::size_t& bitp, const unsigned char* bits) { unsigned long result = (bits[bitp >> 3] >> (7 - (bitp & 0x7))) & 1; bitp++; return result;}
static unsigned long readBitsFromReversedStream(std::size_t& bitp, const unsigned char* bits, unsigned long nbits)
{
unsigned long result = 0;
for(std::size_t i = nbits - 1; i < nbits; i--) result += ((readBitFromReversedStream(bitp, bits)) << i);
return result;
}
void setBitOfReversedStream(std::size_t& bitp, unsigned char* bits, unsigned long bit) { bits[bitp >> 3] |= (unsigned char)( (bit << (7 - (bitp & 0x7))) ); bitp++; }
unsigned long read32bitInt(const unsigned char* buffer) { return ((unsigned long)buffer[0] << 24) | ((unsigned long)buffer[1] << 16) | ((unsigned long)buffer[2] << 8) | (unsigned long)buffer[3]; }
int checkColorValidity(unsigned long colorType, unsigned long bd) //return type is a LodePNG error code
{
if((colorType == 2 || colorType == 4 || colorType == 6)) { if(!(bd == 8 || bd == 16)) return 37; else return 0; }
else if(colorType == 0) { if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; else return 0; }
else if(colorType == 3) { if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; else return 0; }
else return 31; //unexisting color type
}
unsigned long getBpp(const Info& linfo)
{
if(linfo.colorType == 2) return (3 * linfo.bitDepth);
else if(linfo.colorType >= 4) return (linfo.colorType - 2) * linfo.bitDepth;
else return linfo.bitDepth;
}
int convert(std::vector<unsigned char>& out, const unsigned char* in, Info& infoIn, unsigned long w, unsigned long h)
{ //converts from any color type to 32-bit. return value = LodePNG error code
std::size_t numpixels = w * h, bp = 0;
out.resize(numpixels * 4);
unsigned char* out_ = out.empty() ? 0 : &out[0]; //faster if compiled without optimization
if(infoIn.bitDepth == 8 && infoIn.colorType == 0) //greyscale
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[i];
out_[4 * i + 3] = (infoIn.key_defined && in[i] == infoIn.key_r) ? 0 : 255;
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 2) //RGB color
for(std::size_t i = 0; i < numpixels; i++)
{
for(std::size_t c = 0; c < 3; c++) out_[4 * i + c] = in[3 * i + c];
out_[4 * i + 3] = (infoIn.key_defined == 1 && in[3 * i + 0] == infoIn.key_r && in[3 * i + 1] == infoIn.key_g && in[3 * i + 2] == infoIn.key_b) ? 0 : 255;
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 3) //indexed color (palette)
for(std::size_t i = 0; i < numpixels; i++)
{
if(4U * in[i] >= infoIn.palette.size()) return 46;
for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = infoIn.palette[4 * in[i] + c]; //get rgb colors from the palette
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 4) //greyscale with alpha
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[2 * i + 0];
out_[4 * i + 3] = in[2 * i + 1];
}
else if(infoIn.bitDepth == 8 && infoIn.colorType == 6) for(std::size_t i = 0; i < numpixels; i++) for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = in[4 * i + c]; //RGB with alpha
else if(infoIn.bitDepth == 16 && infoIn.colorType == 0) //greyscale
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[2 * i];
out_[4 * i + 3] = (infoIn.key_defined && 256U * in[i] + in[i + 1] == infoIn.key_r) ? 0 : 255;
}
else if(infoIn.bitDepth == 16 && infoIn.colorType == 2) //RGB color
for(std::size_t i = 0; i < numpixels; i++)
{
for(std::size_t c = 0; c < 3; c++) out_[4 * i + c] = in[6 * i + 2 * c];
out_[4 * i + 3] = (infoIn.key_defined && 256U*in[6*i+0]+in[6*i+1] == infoIn.key_r && 256U*in[6*i+2]+in[6*i+3] == infoIn.key_g && 256U*in[6*i+4]+in[6*i+5] == infoIn.key_b) ? 0 : 255;
}
else if(infoIn.bitDepth == 16 && infoIn.colorType == 4) //greyscale with alpha
for(std::size_t i = 0; i < numpixels; i++)
{
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = in[4 * i]; //most significant byte
out_[4 * i + 3] = in[4 * i + 2];
}
else if(infoIn.bitDepth == 16 && infoIn.colorType == 6) for(std::size_t i = 0; i < numpixels; i++) for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = in[8 * i + 2 * c]; //RGB with alpha
else if(infoIn.bitDepth < 8 && infoIn.colorType == 0) //greyscale
for(std::size_t i = 0; i < numpixels; i++)
{
unsigned long value = (readBitsFromReversedStream(bp, in, infoIn.bitDepth) * 255) / ((1 << infoIn.bitDepth) - 1); //scale value from 0 to 255
out_[4 * i + 0] = out_[4 * i + 1] = out_[4 * i + 2] = (unsigned char)(value);
out_[4 * i + 3] = (infoIn.key_defined && value && ((1U << infoIn.bitDepth) - 1U) == infoIn.key_r && ((1U << infoIn.bitDepth) - 1U)) ? 0 : 255;
}
else if(infoIn.bitDepth < 8 && infoIn.colorType == 3) //palette
for(std::size_t i = 0; i < numpixels; i++)
{
unsigned long value = readBitsFromReversedStream(bp, in, infoIn.bitDepth);
if(4 * value >= infoIn.palette.size()) return 47;
for(std::size_t c = 0; c < 4; c++) out_[4 * i + c] = infoIn.palette[4 * value + c]; //get rgb colors from the palette
}
return 0;
}
unsigned char paethPredictor(short a, short b, short c) //Paeth predicter, used by PNG filter type 4
{
short p = short(a + b - c), pa = short(p > a ? (p - a) : (a - p)), pb = short(p > b ? (p - b) : (b - p)), pc = short(p > c ? (p - c) : (c - p));
return (unsigned char)((pa <= pb && pa <= pc) ? a : pb <= pc ? b : c);
}
};
PNG decoder; decoder.decode(out_image, in_png, in_size, convert_to_rgba32);
image_width = decoder.info.width; image_height = decoder.info.height;
return decoder.error;
}
}
} // namespace vtkm::rendering

@ -0,0 +1,43 @@
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//
//=============================================================================
#ifndef vtk_m_rendering_DecodePNG_h
#define vtk_m_rendering_DecodePNG_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vector>
namespace vtkm {
namespace rendering {
VTKM_RENDERING_EXPORT
int DecodePNG(std::vector<unsigned char>& out_image,
unsigned long& image_width,
unsigned long& image_height,
const unsigned char* in_png,
std::size_t in_size,
bool convert_to_rgba32=true);
}
} // vtkm::rendering
#endif //vtk_m_rendering_DecodePNG_h

34
vtkm/rendering/Mapper.cxx Normal file

@ -0,0 +1,34 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/Mapper.h>
namespace vtkm {
namespace rendering {
Mapper::~Mapper() { }
void Mapper::SetActiveColorTable(const vtkm::rendering::ColorTable &colorTable)
{
colorTable.Sample(1024, this->ColorMap);
}
}
}

@ -20,7 +20,6 @@
#ifndef vtk_m_rendering_Mapper_h
#define vtk_m_rendering_Mapper_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/ColorTable.h>
@ -35,9 +34,10 @@ public:
{
}
VTKM_CONT_EXPORT
virtual ~Mapper()
{}
VTKM_RENDERING_EXPORT
virtual ~Mapper();
VTKM_RENDERING_EXPORT
virtual void RenderCells(const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
@ -46,27 +46,19 @@ public:
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange) = 0;
VTKM_CONT_EXPORT
virtual void SetActiveColorTable(const ColorTable &ct)
{
ct.Sample(1024, ColorMap);
}
VTKM_RENDERING_EXPORT
virtual void SetActiveColorTable(const ColorTable &ct);
VTKM_RENDERING_EXPORT
virtual void StartScene() = 0;
VTKM_RENDERING_EXPORT
virtual void EndScene() = 0;
VTKM_RENDERING_EXPORT
virtual void SetCanvas(vtkm::rendering::Canvas *canvas) = 0;
VTKM_RENDERING_EXPORT
virtual vtkm::rendering::Mapper *NewCopy() const = 0;
VTKM_CONT_EXPORT
virtual void Render() {}
VTKM_CONT_EXPORT
virtual void Finish() {}
VTKM_CONT_EXPORT
virtual void StartScene()
{
}
VTKM_CONT_EXPORT
virtual void EndScene()
{
}
virtual void SetCanvas(Canvas *vtkmNotUsed(canvas))
{
}
protected:
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,4> > ColorMap;
};

155
vtkm/rendering/MapperGL.cxx Normal file

@ -0,0 +1,155 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <vtkm/rendering/internal/RunTriangulator.h>
namespace vtkm {
namespace rendering {
namespace {
template <typename PtType>
VTKM_CONT_EXPORT
void RenderTriangles(vtkm::Id numTri, const PtType &verts,
const vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id, 4> > &indices,
const vtkm::cont::ArrayHandle<vtkm::Float32> &scalar,
const vtkm::rendering::ColorTable &ct,
const vtkm::Range &scalarRange)
{
vtkm::Float32 sMin = vtkm::Float32(scalarRange.Min);
vtkm::Float32 sMax = vtkm::Float32(scalarRange.Max);
vtkm::Float32 sDiff = sMax-sMin;
glBegin(GL_TRIANGLES);
for (int i = 0; i < numTri; i++)
{
vtkm::Vec<vtkm::Id, 4> idx = indices.GetPortalConstControl().Get(i);
vtkm::Id i1 = idx[1];
vtkm::Id i2 = idx[2];
vtkm::Id i3 = idx[3];
vtkm::Vec<vtkm::Float32, 3> p1 = verts.GetPortalConstControl().Get(idx[1]);
vtkm::Vec<vtkm::Float32, 3> p2 = verts.GetPortalConstControl().Get(idx[2]);
vtkm::Vec<vtkm::Float32, 3> p3 = verts.GetPortalConstControl().Get(idx[3]);
vtkm::Float32 s = scalar.GetPortalConstControl().Get(i1);
s = (s-sMin)/sDiff;
Color color = ct.MapRGB(s);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glVertex3f(p1[0],p1[1],p1[2]);
s = scalar.GetPortalConstControl().Get(i2);
s = (s-sMin)/sDiff;
color = ct.MapRGB(s);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glVertex3f(p2[0],p2[1],p2[2]);
s = scalar.GetPortalConstControl().Get(i3);
s = (s-sMin)/sDiff;
color = ct.MapRGB(s);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glVertex3f(p3[0],p3[1],p3[2]);
}
glEnd();
}
} // anonymous namespace
MapperGL::MapperGL()
{ }
MapperGL::~MapperGL()
{ }
void MapperGL::RenderCells(const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &colorTable,
const vtkm::rendering::Camera &,
const vtkm::Range &scalarRange)
{
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id, 4> > indices;
vtkm::Id numTri;
vtkm::rendering::internal::RunTriangulator(cellset, indices, numTri);
vtkm::cont::ArrayHandle<vtkm::Float32> sf;
sf = scalarField.GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32> >();
vtkm::cont::DynamicArrayHandleCoordinateSystem dcoords = coords.GetData();
vtkm::cont::ArrayHandleUniformPointCoordinates uVerts;
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> > eVerts;
if(dcoords.IsSameType(vtkm::cont::ArrayHandleUniformPointCoordinates()))
{
uVerts = dcoords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
RenderTriangles(numTri, uVerts, indices, sf, colorTable, scalarRange);
}
else if(dcoords.IsSameType(vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> >()))
{
eVerts = dcoords.Cast<vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> > > ();
RenderTriangles(numTri, eVerts, indices, sf, colorTable, scalarRange);
}
else if(dcoords.IsSameType(vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> >()))
{
vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> > rVerts;
rVerts = dcoords.Cast<vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> > > ();
RenderTriangles(numTri, rVerts, indices, sf, colorTable, scalarRange);
}
glFinish();
glFlush();
}
void MapperGL::StartScene()
{
// Nothing needs to be done.
}
void MapperGL::EndScene()
{
// Nothing needs to be done.
}
void MapperGL::SetCanvas(vtkm::rendering::Canvas *)
{
// Nothing needs to be done.
}
vtkm::rendering::Mapper *MapperGL::NewCopy() const
{
return new vtkm::rendering::MapperGL(*this);
}
}
} // namespace vtkm::rendering

@ -20,124 +20,42 @@
#ifndef vtk_m_rendering_MapperGL_h
#define vtk_m_rendering_MapperGL_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/Mapper.h>
#include <vtkm/rendering/Triangulator.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
namespace vtkm {
namespace rendering {
template<typename DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
class MapperGL : public Mapper
{
public:
VTKM_CONT_EXPORT
MapperGL() {}
VTKM_RENDERING_EXPORT
MapperGL();
VTKM_CONT_EXPORT
virtual void RenderCells(const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &colorTable,
const vtkm::rendering::Camera &,
const vtkm::Range &scalarRange)
{
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id, 4> > indices;
vtkm::Id numTri;
Triangulator<DeviceAdapter> triangulator;
triangulator.run(cellset, indices, numTri);
VTKM_RENDERING_EXPORT
~MapperGL();
vtkm::cont::ArrayHandle<vtkm::Float32> sf;
sf = scalarField.GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32> >();
VTKM_RENDERING_EXPORT
void RenderCells(const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &colorTable,
const vtkm::rendering::Camera &,
const vtkm::Range &scalarRange) VTKM_OVERRIDE;
vtkm::cont::DynamicArrayHandleCoordinateSystem dcoords = coords.GetData();
vtkm::cont::ArrayHandleUniformPointCoordinates uVerts;
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> > eVerts;
VTKM_RENDERING_EXPORT
void StartScene() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void EndScene() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void SetCanvas(vtkm::rendering::Canvas *canvas) VTKM_OVERRIDE;
if(dcoords.IsSameType(vtkm::cont::ArrayHandleUniformPointCoordinates()))
{
uVerts = dcoords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
RenderTriangles(numTri, uVerts, indices, sf, colorTable, scalarRange);
}
else if(dcoords.IsSameType(vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> >()))
{
eVerts = dcoords.Cast<vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> > > ();
RenderTriangles(numTri, eVerts, indices, sf, colorTable, scalarRange);
}
else if(dcoords.IsSameType(vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> >()))
{
vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> > rVerts;
rVerts = dcoords.Cast<vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> > > ();
RenderTriangles(numTri, rVerts, indices, sf, colorTable, scalarRange);
}
glFinish();
glFlush();
}
template <typename PtType>
VTKM_CONT_EXPORT
void RenderTriangles(vtkm::Id numTri, const PtType &verts,
const vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id, 4> > &indices,
const vtkm::cont::ArrayHandle<vtkm::Float32> &scalar,
const vtkm::rendering::ColorTable &ct,
const vtkm::Range &scalarRange)
{
vtkm::Float32 sMin = vtkm::Float32(scalarRange.Min);
vtkm::Float32 sMax = vtkm::Float32(scalarRange.Max);
vtkm::Float32 sDiff = sMax-sMin;
glBegin(GL_TRIANGLES);
for (int i = 0; i < numTri; i++)
{
vtkm::Vec<vtkm::Id, 4> idx = indices.GetPortalConstControl().Get(i);
vtkm::Id i1 = idx[1];
vtkm::Id i2 = idx[2];
vtkm::Id i3 = idx[3];
vtkm::Vec<vtkm::Float32, 3> p1 = verts.GetPortalConstControl().Get(idx[1]);
vtkm::Vec<vtkm::Float32, 3> p2 = verts.GetPortalConstControl().Get(idx[2]);
vtkm::Vec<vtkm::Float32, 3> p3 = verts.GetPortalConstControl().Get(idx[3]);
vtkm::Float32 s = scalar.GetPortalConstControl().Get(i1);
s = (s-sMin)/sDiff;
Color color = ct.MapRGB(s);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glVertex3f(p1[0],p1[1],p1[2]);
s = scalar.GetPortalConstControl().Get(i2);
s = (s-sMin)/sDiff;
color = ct.MapRGB(s);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glVertex3f(p2[0],p2[1],p2[2]);
s = scalar.GetPortalConstControl().Get(i3);
s = (s-sMin)/sDiff;
color = ct.MapRGB(s);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glVertex3f(p3[0],p3[1],p3[2]);
}
glEnd();
}
VTKM_RENDERING_EXPORT
vtkm::rendering::Mapper *NewCopy() const VTKM_OVERRIDE;
};
}} //namespace vtkm::rendering

@ -0,0 +1,200 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
#include <vtkm/cont/internal/SimplePolymorphicContainer.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/internal/RunTriangulator.h>
#include <vtkm/rendering/raytracing/RayTracer.h>
#include <vtkm/rendering/raytracing/Camera.h>
namespace vtkm {
namespace rendering {
struct MapperRayTracer::InternalsType
{
vtkm::rendering::CanvasRayTracer *Canvas;
vtkm::cont::internal::RuntimeDeviceTracker DeviceTracker;
boost::shared_ptr<vtkm::cont::internal::SimplePolymorphicContainerBase>
RayTracerContainer;
VTKM_CONT_EXPORT
InternalsType()
: Canvas(nullptr)
{ }
template<typename Device>
VTKM_CONT_EXPORT
vtkm::rendering::raytracing::RayTracer<Device> *GetRayTracer(Device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
typedef vtkm::rendering::raytracing::RayTracer<Device> RayTracerType;
typedef vtkm::cont::internal::SimplePolymorphicContainer<RayTracerType>
ContainerType;
RayTracerType *tracer = NULL;
if (this->RayTracerContainer)
{
ContainerType *container =
dynamic_cast<ContainerType *>(this->RayTracerContainer.get());
if (container)
{
tracer = &container->Item;
}
}
if (tracer == NULL)
{
ContainerType *container
= new vtkm::cont::internal::SimplePolymorphicContainer<RayTracerType>;
tracer = &container->Item;
this->RayTracerContainer.reset(container);
}
return tracer;
}
};
MapperRayTracer::MapperRayTracer()
: Internals(new InternalsType)
{ }
MapperRayTracer::~MapperRayTracer()
{ }
void MapperRayTracer::SetCanvas(vtkm::rendering::Canvas *canvas)
{
if(canvas != nullptr)
{
this->Internals->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
if(this->Internals->Canvas == nullptr)
{
throw vtkm::cont::ErrorControlBadValue(
"Ray Tracer: bad canvas type. Must be CanvasRayTracer");
}
}
else
{
this->Internals->Canvas = nullptr;
}
}
struct MapperRayTracer::RenderFunctor
{
vtkm::rendering::MapperRayTracer *Self;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4> > TriangleIndices;
vtkm::Id NumberOfTriangles;
vtkm::cont::CoordinateSystem Coordinates;
vtkm::cont::Field ScalarField;
vtkm::rendering::Camera Camera;
vtkm::Range ScalarRange;
VTKM_CONT_EXPORT
RenderFunctor(vtkm::rendering::MapperRayTracer *self,
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id,4> > &indices,
vtkm::Id numberOfTriangles,
const vtkm::cont::CoordinateSystem &coordinates,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange)
: Self(self),
TriangleIndices(indices),
NumberOfTriangles(numberOfTriangles),
Coordinates(coordinates),
ScalarField(scalarField),
Camera(camera),
ScalarRange(scalarRange)
{ }
template<typename Device>
bool operator()(Device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::rendering::raytracing::RayTracer<Device> *tracer =
this->Self->Internals->GetRayTracer(Device());
tracer->GetCamera().SetParameters(this->Camera,
*this->Self->Internals->Canvas);
vtkm::Bounds dataBounds = this->Coordinates.GetBounds(Device());
tracer->SetData(this->Coordinates.GetData(),
this->TriangleIndices,
this->ScalarField,
this->NumberOfTriangles,
this->ScalarRange,
dataBounds);
tracer->SetColorMap(this->Self->ColorMap);
tracer->SetBackgroundColor(
this->Self->Internals->Canvas->GetBackgroundColor().Components);
tracer->Render(this->Self->Internals->Canvas);
return true;
}
};
void MapperRayTracer::RenderCells(
const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &vtkmNotUsed(colorTable),
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange)
{
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id, 4> > indices;
vtkm::Id numberOfTriangles;
vtkm::rendering::internal::RunTriangulator(
cellset, indices, numberOfTriangles, this->Internals->DeviceTracker);
RenderFunctor functor(this,
indices,
numberOfTriangles,
coords,
scalarField,
camera,
scalarRange);
vtkm::cont::TryExecute(functor,
this->Internals->DeviceTracker,
VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG());
}
void MapperRayTracer::StartScene()
{
// Nothing needs to be done.
}
void MapperRayTracer::EndScene()
{
// Nothing needs to be done.
}
vtkm::rendering::Mapper *MapperRayTracer::NewCopy() const
{
return new vtkm::rendering::MapperRayTracer(*this);
}
}
} // vtkm::rendering

@ -19,82 +19,54 @@
//============================================================================
#ifndef vtk_m_rendering_MapperRayTracer_h
#define vtk_m_rendering_MapperRayTracer_h
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/Mapper.h>
#include <vtkm/rendering/Triangulator.h>
#include <vtkm/rendering/raytracing/RayTracer.h>
#include <vtkm/rendering/raytracing/Camera.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/Camera.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/shared_ptr.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
namespace vtkm {
namespace rendering {
// static bool doOnce = true;
template<typename DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
class MapperRayTracer : public Mapper
{
protected:
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,4> > ColorMap;
vtkm::rendering::raytracing::RayTracer<DeviceAdapter> Tracer;
CanvasRayTracer *Canvas;
public:
VTKM_CONT_EXPORT
MapperRayTracer()
{
this->Canvas = nullptr;
}
VTKM_CONT_EXPORT
void SetCanvas(vtkm::rendering::Canvas *canvas)
{
if(canvas != nullptr)
{
VTKM_RENDERING_EXPORT
MapperRayTracer();
this->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
if(this->Canvas == nullptr)
{
throw vtkm::cont::ErrorControlBadValue(
"Ray Tracer: bad canvas type. Must be CanvasRayTracer");
}
}
}
VTKM_CONT_EXPORT
void SetActiveColorTable(const ColorTable &colorTable)
{
colorTable.Sample(1024, ColorMap);
}
VTKM_RENDERING_EXPORT
~MapperRayTracer();
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
void SetCanvas(vtkm::rendering::Canvas *canvas) VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void RenderCells(const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &vtkmNotUsed(colorTable),
const vtkm::rendering::ColorTable &colorTable,
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange)
{
const vtkm::Range &scalarRange) VTKM_OVERRIDE;
const vtkm::cont::DynamicArrayHandleCoordinateSystem dynamicCoordsHandle = coords.GetData();
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id, 4> > indices;
this->Tracer.GetCamera().SetParameters(camera, *this->Canvas);
vtkm::Id numberOfTriangles;
VTKM_RENDERING_EXPORT
virtual void StartScene() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
virtual void EndScene() VTKM_OVERRIDE;
vtkm::Bounds dataBounds = coords.GetBounds(DeviceAdapter());
VTKM_RENDERING_EXPORT
vtkm::rendering::Mapper *NewCopy() const VTKM_OVERRIDE;
Triangulator<DeviceAdapter> triangulator;
triangulator.run(cellset, indices, numberOfTriangles);//,dynamicCoordsHandle,dataBounds);
private:
struct InternalsType;
boost::shared_ptr<InternalsType> Internals;
this->Tracer.SetData(dynamicCoordsHandle,
indices,
scalarField,
numberOfTriangles,
scalarRange,
dataBounds);
this->Tracer.SetColorMap(this->ColorMap);
this->Tracer.SetBackgroundColor(
this->Canvas->GetBackgroundColor().Components);
this->Tracer.Render(this->Canvas);
}
struct RenderFunctor;
};
}} //namespace vtkm::rendering
}
} //namespace vtkm::rendering
#endif //vtk_m_rendering_MapperRayTracer_h

@ -0,0 +1,204 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/MapperVolume.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
#include <vtkm/cont/internal/SimplePolymorphicContainer.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/internal/RunTriangulator.h>
#include <vtkm/rendering/raytracing/Camera.h>
#include <vtkm/rendering/raytracing/VolumeRendererStructured.h>
#include <typeinfo>
namespace vtkm {
namespace rendering {
struct MapperVolume::InternalsType
{
vtkm::rendering::CanvasRayTracer *Canvas;
vtkm::cont::internal::RuntimeDeviceTracker DeviceTracker;
boost::shared_ptr<vtkm::cont::internal::SimplePolymorphicContainerBase>
RayTracerContainer;
VTKM_CONT_EXPORT
InternalsType()
: Canvas(nullptr)
{ }
template<typename Device>
VTKM_CONT_EXPORT
vtkm::rendering::raytracing::VolumeRendererStructured<Device> *
GetRayTracer(Device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
typedef vtkm::rendering::raytracing::VolumeRendererStructured<Device>
RayTracerType;
typedef vtkm::cont::internal::SimplePolymorphicContainer<RayTracerType>
ContainerType;
RayTracerType *tracer = NULL;
if (this->RayTracerContainer)
{
ContainerType *container =
dynamic_cast<ContainerType *>(this->RayTracerContainer.get());
if (container)
{
tracer = &container->Item;
}
}
if (tracer == NULL)
{
ContainerType *container
= new vtkm::cont::internal::SimplePolymorphicContainer<RayTracerType>;
tracer = &container->Item;
this->RayTracerContainer.reset(container);
}
return tracer;
}
};
MapperVolume::MapperVolume()
: Internals(new InternalsType)
{ }
MapperVolume::~MapperVolume()
{ }
void MapperVolume::SetCanvas(vtkm::rendering::Canvas *canvas)
{
if(canvas != nullptr)
{
this->Internals->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
if(this->Internals->Canvas == nullptr)
{
throw vtkm::cont::ErrorControlBadValue(
"Ray Tracer: bad canvas type. Must be CanvasRayTracer");
}
}
else
{
this->Internals->Canvas = nullptr;
}
}
struct MapperVolume::RenderFunctor
{
vtkm::rendering::MapperVolume *Self;
vtkm::cont::CellSetStructured<3> CellSet;
vtkm::cont::CoordinateSystem Coordinates;
vtkm::cont::Field ScalarField;
vtkm::rendering::Camera Camera;
vtkm::Range ScalarRange;
VTKM_CONT_EXPORT
RenderFunctor(vtkm::rendering::MapperVolume *self,
const vtkm::cont::CellSetStructured<3> cellSet,
const vtkm::cont::CoordinateSystem &coordinates,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange)
: Self(self),
CellSet(cellSet),
Coordinates(coordinates),
ScalarField(scalarField),
Camera(camera),
ScalarRange(scalarRange)
{ }
template<typename Device>
bool operator()(Device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::rendering::raytracing::VolumeRendererStructured<Device> *tracer =
this->Self->Internals->GetRayTracer(Device());
tracer->GetCamera().SetParameters(this->Camera,
*this->Self->Internals->Canvas);
vtkm::Bounds dataBounds = this->Coordinates.GetBounds(Device());
tracer->SetData(this->Coordinates,
this->ScalarField,
dataBounds,
this->CellSet,
this->ScalarRange);
tracer->SetColorMap(this->Self->ColorMap);
tracer->SetBackgroundColor(
this->Self->Internals->Canvas->GetBackgroundColor().Components);
tracer->Render(this->Self->Internals->Canvas);
return true;
}
};
void MapperVolume::RenderCells(
const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &vtkmNotUsed(colorTable),
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange)
{
if(!cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
{
std::cerr<<"ERROR cell set type not currently supported\n";
std::string theType = typeid(cellset).name();
std::cerr<<"Type : "<<theType<<std::endl;
}
else
{
RenderFunctor functor(this,
cellset.Cast<vtkm::cont::CellSetStructured<3> >(),
coords,
scalarField,
camera,
scalarRange);
vtkm::cont::TryExecute(functor,
this->Internals->DeviceTracker,
VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG());
}
}
void MapperVolume::StartScene()
{
// Nothing needs to be done.
}
void MapperVolume::EndScene()
{
// Nothing needs to be done.
}
vtkm::rendering::Mapper *MapperVolume::NewCopy() const
{
return new vtkm::rendering::MapperVolume(*this);
}
}
} // namespace vtkm::rendering

@ -20,87 +20,51 @@
#ifndef vtk_m_rendering_MapperVolume_h
#define vtk_m_rendering_MapperVolume_h
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/Mapper.h>
#include <vtkm/rendering/Triangulator.h>
#include <vtkm/rendering/raytracing/VolumeRendererStructured.h>
#include <vtkm/rendering/raytracing/Camera.h>
#include <typeinfo>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/shared_ptr.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
namespace vtkm {
namespace rendering {
template<typename DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
class MapperVolume : public Mapper
{
protected:
vtkm::rendering::raytracing::VolumeRendererStructured<DeviceAdapter> Tracer;
CanvasRayTracer *Canvas;
public:
VTKM_CONT_EXPORT
MapperVolume()
{
this->Canvas = nullptr;
}
VTKM_RENDERING_EXPORT
MapperVolume();
VTKM_CONT_EXPORT
void SetNumberOfSamples(const vtkm::Int32 &numSamples)
{
Tracer.SetNumberOfSamples(numSamples);
}
VTKM_RENDERING_EXPORT
~MapperVolume();
VTKM_CONT_EXPORT
void SetCanvas(vtkm::rendering::Canvas *canvas)
{
if(canvas != nullptr)
{
VTKM_RENDERING_EXPORT
void SetCanvas(vtkm::rendering::Canvas *canvas) VTKM_OVERRIDE;
this->Canvas = dynamic_cast<CanvasRayTracer*>(canvas);
if(this->Canvas == nullptr)
{
throw vtkm::cont::ErrorControlBadValue(
"Volume Render: bad canvas type. Must be CanvasRayTracer");
}
}
}
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
virtual void RenderCells(const vtkm::cont::DynamicCellSet &cellset,
const vtkm::cont::CoordinateSystem &coords,
const vtkm::cont::Field &scalarField,
const vtkm::rendering::ColorTable &, //colorTable
const vtkm::rendering::Camera &camera,
const vtkm::Range &scalarRange)
{
// vtkm::cont::DynamicArrayHandleCoordinateSystem dynamicCoordsHandle = coords.GetData();
vtkm::Bounds coordsBounds = coords.GetBounds(DeviceAdapter());
const vtkm::Range &scalarRange) VTKM_OVERRIDE;
if(!cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
{
std::cerr<<"ERROR cell set type not currently supported\n";
std::string theType = typeid(cellset).name();
std::cerr<<"Type : "<<theType<<std::endl;
}
else
{
vtkm::cont::CellSetStructured<3> cellSetStructured3D = cellset.Cast<vtkm::cont::CellSetStructured<3> >();
//vtkm::cont::ArrayHandleUniformPointCoordinates vertices;
//vertices = dynamicCoordsHandle.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
this->Tracer.GetCamera().SetParameters(camera, *this->Canvas);
this->Tracer.SetData(coords,
scalarField,
coordsBounds,
cellSetStructured3D,
scalarRange);
this->Tracer.SetColorMap(this->ColorMap);
this->Tracer.SetBackgroundColor(
this->Canvas->GetBackgroundColor().Components);
this->Tracer.Render(this->Canvas);
}
VTKM_RENDERING_EXPORT
virtual void StartScene() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
virtual void EndScene() VTKM_OVERRIDE;
}
VTKM_RENDERING_EXPORT
vtkm::rendering::Mapper *NewCopy() const VTKM_OVERRIDE;
private:
struct InternalsType;
boost::shared_ptr<InternalsType> Internals;
struct RenderFunctor;
};
}} //namespace vtkm::rendering
}
} //namespace vtkm::rendering
#endif //vtk_m_rendering_MapperVolume_h

82
vtkm/rendering/Scene.cxx Normal file

@ -0,0 +1,82 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/Scene.h>
#include <vector>
namespace vtkm {
namespace rendering {
struct Scene::InternalsType
{
std::vector<vtkm::rendering::Actor> Actors;
};
Scene::Scene()
: Internals(new InternalsType)
{ }
void Scene::AddActor(const vtkm::rendering::Actor &actor)
{
this->Internals->Actors.push_back(actor);
}
const vtkm::rendering::Actor &Scene::GetActor(vtkm::IdComponent index) const
{
return this->Internals->Actors[static_cast<std::size_t>(index)];
}
vtkm::IdComponent Scene::GetNumberOfActors() const
{
return static_cast<vtkm::IdComponent>(this->Internals->Actors.size());
}
void Scene::Render(vtkm::rendering::Mapper &mapper,
vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera) const
{
mapper.StartScene();
for (vtkm::IdComponent actorIndex = 0;
actorIndex < this->GetNumberOfActors();
actorIndex++)
{
const vtkm::rendering::Actor &actor = this->GetActor(actorIndex);
actor.Render(mapper, canvas, camera);
}
mapper.EndScene();
}
vtkm::Bounds Scene::GetSpatialBounds() const
{
vtkm::Bounds bounds;
for (vtkm::IdComponent actorIndex = 0;
actorIndex < this->GetNumberOfActors();
actorIndex++)
{
// accumulate all Actors' spatial bounds into the scene spatial bounds
bounds.Include(this->GetActor(actorIndex).GetSpatialBounds());
}
return bounds;
}
}
} // namespace vtkm::rendering

@ -20,9 +20,12 @@
#ifndef vtk_m_rendering_Scene_h
#define vtk_m_rendering_Scene_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/rendering/Actor.h>
#include <vtkm/rendering/Camera.h>
#include <vector>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Mapper.h>
namespace vtkm {
namespace rendering {
@ -30,59 +33,29 @@ namespace rendering {
class Scene
{
public:
VTKM_CONT_EXPORT
void AddActor(const vtkm::rendering::Actor &actor)
{
this->Actors.push_back(actor);
}
VTKM_RENDERING_EXPORT
Scene();
VTKM_CONT_EXPORT
const vtkm::rendering::Actor &GetActor(vtkm::IdComponent index) const
{
return this->Actors[static_cast<std::size_t>(index)];
}
VTKM_RENDERING_EXPORT
void AddActor(const vtkm::rendering::Actor &actor);
VTKM_CONT_EXPORT
vtkm::IdComponent GetNumberOfActors() const
{
return static_cast<vtkm::IdComponent>(this->Actors.size());
}
VTKM_RENDERING_EXPORT
const vtkm::rendering::Actor &GetActor(vtkm::IdComponent index) const;
Scene() {}
VTKM_RENDERING_EXPORT
vtkm::IdComponent GetNumberOfActors() const;
template<typename MapperType, typename CanvasType>
VTKM_CONT_EXPORT
void Render(MapperType &mapper,
CanvasType &canvas,
vtkm::rendering::Camera &camera) const
{
mapper.StartScene();
for (vtkm::IdComponent actorIndex = 0;
actorIndex < this->GetNumberOfActors();
actorIndex++)
{
const vtkm::rendering::Actor &actor = this->GetActor(actorIndex);
actor.Render(mapper, canvas, camera);
}
mapper.EndScene();
}
VTKM_RENDERING_EXPORT
void Render(vtkm::rendering::Mapper &mapper,
vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera) const;
vtkm::Bounds GetSpatialBounds() const
{
vtkm::Bounds bounds;
for (vtkm::IdComponent actorIndex = 0;
actorIndex < this->GetNumberOfActors();
actorIndex++)
{
// accumulate all Actors' spatial bounds into the scene spatial bounds
bounds.Include(this->GetActor(actorIndex).SpatialBounds);
}
return bounds;
}
VTKM_RENDERING_EXPORT
vtkm::Bounds GetSpatialBounds() const;
private:
std::vector<vtkm::rendering::Actor> Actors;
struct InternalsType;
boost::shared_ptr<InternalsType> Internals;
};
}} //namespace vtkm::rendering

@ -0,0 +1,89 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/TextAnnotation.h>
namespace vtkm {
namespace rendering {
TextAnnotation::TextAnnotation(const std::string &text,
const vtkm::rendering::Color &color,
vtkm::Float32 scale)
: Text(text), TextColor(color), Scale(scale), Anchor(-1,-1)
{
}
TextAnnotation::~TextAnnotation()
{
}
void TextAnnotation::SetText(const std::string &text)
{
this->Text = text;
}
const std::string &TextAnnotation::GetText() const
{
return this->Text;
}
void TextAnnotation::SetRawAnchor(const vtkm::Vec<vtkm::Float32,2> &anchor)
{
this->Anchor = anchor;
}
void TextAnnotation::SetRawAnchor(vtkm::Float32 h, vtkm::Float32 v)
{
this->SetRawAnchor(vtkm::make_Vec(h,v));
}
void TextAnnotation::SetAlignment(HorizontalAlignment h, VerticalAlignment v)
{
switch (h)
{
case Left: this->Anchor[0] = -1.0f; break;
case HCenter: this->Anchor[0] = 0.0f; break;
case Right: this->Anchor[0] = +1.0f; break;
}
// For vertical alignment, "center" is generally the center
// of only the above-baseline contents of the font, so we
// use a value slightly off of zero for VCenter.
// (We don't use an offset value instead of -1.0 for the
// bottom value, because generally we want a true minimum
// extent, e.g. to have text sitting at the bottom of a
// window, and in that case, we need to keep all the text,
// including parts that descend below the baseline, above
// the bottom of the window.
switch (v)
{
case Bottom: this->Anchor[1] = -1.0f; break;
case VCenter: this->Anchor[1] = -0.06f; break;
case Top: this->Anchor[1] = +1.0f; break;
}
}
void TextAnnotation::SetScale(vtkm::Float32 scale)
{
this->Scale = scale;
}
}
} // namespace vtkm::rendering

@ -20,11 +20,12 @@
#ifndef vtk_m_rendering_TextAnnotation_h
#define vtk_m_rendering_TextAnnotation_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/WorldAnnotator.h>
namespace vtkm {
namespace rendering {
@ -45,205 +46,50 @@ public:
};
protected:
std::string Text;
Color TextColor;
vtkm::Float32 Scale;
vtkm::Float32 AnchorX, AnchorY;
std::string Text;
Color TextColor;
vtkm::Float32 Scale;
vtkm::Vec<vtkm::Float32,2> Anchor;
public:
TextAnnotation(const std::string &txt, Color c, vtkm::Float32 s)
: Text(txt), TextColor(c), Scale(s)
{
// default anchor: bottom-left
AnchorX = -1;
AnchorY = -1;
}
virtual ~TextAnnotation()
{
}
void SetText(const std::string &txt)
{
Text = txt;
}
void SetRawAnchor(vtkm::Float32 h, vtkm::Float32 v)
{
AnchorX = h;
AnchorY = v;
}
void SetAlignment(HorizontalAlignment h, VerticalAlignment v)
{
switch (h)
{
case Left: AnchorX = -1.0f; break;
case HCenter: AnchorX = 0.0f; break;
case Right: AnchorX = +1.0f; break;
}
VTKM_RENDERING_EXPORT
TextAnnotation(const std::string &text,
const vtkm::rendering::Color &color,
vtkm::Float32 scalar);
// For vertical alignment, "center" is generally the center
// of only the above-baseline contents of the font, so we
// use a value slightly off of zero for VCenter.
// (We don't use an offset value instead of -1.0 for the
// bottom value, because generally we want a true minimum
// extent, e.g. to have text sitting at the bottom of a
// window, and in that case, we need to keep all the text,
// including parts that descend below the baseline, above
// the bottom of the window.
switch (v)
{
case Bottom: AnchorY = -1.0f; break;
case VCenter: AnchorY = -0.06f; break;
case Top: AnchorY = +1.0f; break;
}
}
void SetScale(vtkm::Float32 s)
{
Scale = s;
}
VTKM_RENDERING_EXPORT
virtual ~TextAnnotation();
VTKM_RENDERING_EXPORT
void SetText(const std::string &text);
VTKM_RENDERING_EXPORT
const std::string &GetText() const;
/// Set the anchor point relative to the box containing the text. The anchor
/// is scaled in both directions to the range [-1,1] with -1 at the lower
/// left and 1 at the upper right.
///
VTKM_RENDERING_EXPORT
void SetRawAnchor(const vtkm::Vec<vtkm::Float32,2> &anchor);
VTKM_RENDERING_EXPORT
void SetRawAnchor(vtkm::Float32 h, vtkm::Float32 v);
VTKM_RENDERING_EXPORT
void SetAlignment(HorizontalAlignment h, VerticalAlignment v);
VTKM_RENDERING_EXPORT
void SetScale(vtkm::Float32 scale);
VTKM_RENDERING_EXPORT
virtual void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas) = 0;
};
class ScreenTextAnnotation : public TextAnnotation
{
protected:
vtkm::Float32 XPos,YPos;
vtkm::Float32 Angle;
public:
ScreenTextAnnotation(const std::string &txt, Color c, vtkm::Float32 s,
vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 angleDeg = 0.)
: TextAnnotation(txt,c,s)
{
XPos = ox;
YPos = oy;
Angle = angleDeg;
}
void SetPosition(vtkm::Float32 ox, vtkm::Float32 oy)
{
XPos = ox;
YPos = oy;
}
virtual void Render(const vtkm::rendering::Camera &vtkmNotUsed(camera),
const vtkm::rendering::WorldAnnotator &,
vtkm::rendering::Canvas &canvas)
{
vtkm::Float32 WindowAspect = vtkm::Float32(canvas.GetWidth()) /
vtkm::Float32(canvas.GetHeight());
canvas.AddText(XPos,YPos,
Scale,
Angle,
WindowAspect,
AnchorX, AnchorY,
TextColor, Text);
}
};
class BillboardTextAnnotation : public TextAnnotation
{
protected:
vtkm::Float32 XPos,YPos,ZPos;
vtkm::Float32 Angle;
public:
BillboardTextAnnotation(const std::string &txt, Color c, vtkm::Float32 s,
vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 oz,
vtkm::Float32 angleDeg = 0.)
: TextAnnotation(txt,c,s)
{
XPos = ox;
YPos = oy;
ZPos = oz;
Angle = angleDeg;
}
void SetPosition(vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 oz)
{
XPos = ox;
YPos = oy;
ZPos = oz;
}
virtual void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas)
{
vtkm::Matrix<vtkm::Float32, 4, 4> V, P;
V = camera.CreateViewMatrix();
P = camera.CreateProjectionMatrix(canvas.GetWidth(), canvas.GetHeight());
vtkm::Vec<vtkm::Float32,4> p4w(XPos,YPos,ZPos,1);
vtkm::Vec<vtkm::Float32,4> p4s =
vtkm::MatrixMultiply(vtkm::MatrixMultiply(P,V), p4w);
canvas.SetViewToScreenSpace(camera,true);
vtkm::Float32 psx = p4s[0] / p4s[3];
vtkm::Float32 psy = p4s[1] / p4s[3];
vtkm::Float32 psz = p4s[2] / p4s[3];
vtkm::Matrix<vtkm::Float32, 4, 4> T;
T = vtkm::Transform3DTranslate(psx,psy,-psz);
vtkm::Float32 WindowAspect =
vtkm::Float32(canvas.GetWidth()) / vtkm::Float32(canvas.GetHeight());
vtkm::Matrix<vtkm::Float32, 4, 4> SW;
SW = vtkm::Transform3DScale(1.f/WindowAspect, 1.f, 1.f);
vtkm::Matrix<vtkm::Float32, 4, 4> SV;
vtkm::MatrixIdentity(SV);
//if view type == 2D?
{
vtkm::Float32 vl, vr, vb, vt;
camera.GetRealViewport(canvas.GetWidth(),canvas.GetHeight(),vl,vr,vb,vt);
vtkm::Float32 xs = (vr-vl);
vtkm::Float32 ys = (vt-vb);
SV = vtkm::Transform3DScale(2.f/xs, 2.f/ys, 1.f);
}
vtkm::Matrix<vtkm::Float32, 4, 4> R;
R = vtkm::Transform3DRotateZ(Angle * 3.14159265f / 180.f);
vtkm::Vec<vtkm::Float32,4> origin4(0,0,0,1);
vtkm::Vec<vtkm::Float32,4> right4(1,0,0,0);
vtkm::Vec<vtkm::Float32,4> up4(0,1,0,0);
vtkm::Matrix<vtkm::Float32, 4, 4> M =
vtkm::MatrixMultiply(T,
vtkm::MatrixMultiply(SW,
vtkm::MatrixMultiply(SV,
R)));
vtkm::Vec<vtkm::Float32,4> new_origin4 =
vtkm::MatrixMultiply(M, origin4);
vtkm::Vec<vtkm::Float32,4> new_right4 =
vtkm::MatrixMultiply(M, right4);
vtkm::Vec<vtkm::Float32,4> new_up4 =
vtkm::MatrixMultiply(M, up4);
vtkm::Float32 px = new_origin4[0] / new_origin4[3];
vtkm::Float32 py = new_origin4[1] / new_origin4[3];
vtkm::Float32 pz = new_origin4[2] / new_origin4[3];
vtkm::Float32 rx = new_right4[0];
vtkm::Float32 ry = new_right4[1];
vtkm::Float32 rz = new_right4[2];
vtkm::Float32 ux = new_up4[0];
vtkm::Float32 uy = new_up4[1];
vtkm::Float32 uz = new_up4[2];
worldAnnotator.AddText(px,py,pz,
rx,ry,rz,
ux,uy,uz,
Scale,
AnchorX, AnchorY,
TextColor, Text);
canvas.SetViewToWorldSpace(camera,true);
}
vtkm::rendering::Canvas &canvas) const = 0;
};
}} //namespace vtkm::rendering
}
} //namespace vtkm::rendering
#endif //vtk_m_rendering_TextAnnotation_h

@ -0,0 +1,121 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/TextAnnotationBillboard.h>
#include <vtkm/Matrix.h>
namespace vtkm {
namespace rendering {
TextAnnotationBillboard::TextAnnotationBillboard(
const std::string &text,
const vtkm::rendering::Color &color,
vtkm::Float32 scalar,
const vtkm::Vec<vtkm::Float32,3> &position,
vtkm::Float32 angleDegrees)
: TextAnnotation(text, color, scalar),
Position(position),
Angle(angleDegrees)
{ }
TextAnnotationBillboard::~TextAnnotationBillboard()
{ }
void TextAnnotationBillboard::SetPosition(
const vtkm::Vec<vtkm::Float32,3> &position)
{
this->Position = position;
}
void TextAnnotationBillboard::SetPosition(
vtkm::Float32 xpos, vtkm::Float32 ypos, vtkm::Float32 zpos)
{
this->SetPosition(vtkm::make_Vec(xpos, ypos, zpos));
}
void TextAnnotationBillboard::Render(
const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas) const
{
using MatrixType = vtkm::Matrix<vtkm::Float32,4,4>;
using VectorType = vtkm::Vec<vtkm::Float32,3>;
MatrixType viewMatrix = camera.CreateViewMatrix();
MatrixType projectionMatrix
= camera.CreateProjectionMatrix(canvas.GetWidth(), canvas.GetHeight());
VectorType screenPos =
vtkm::Transform3DPointPerspective(
vtkm::MatrixMultiply(projectionMatrix,viewMatrix),
this->Position);
canvas.SetViewToScreenSpace(camera,true);
MatrixType translateMatrix =
vtkm::Transform3DTranslate(screenPos[0], screenPos[1], -screenPos[2]);
vtkm::Float32 windowAspect =
vtkm::Float32(canvas.GetWidth()) / vtkm::Float32(canvas.GetHeight());
MatrixType scaleMatrix = vtkm::Transform3DScale(1.f/windowAspect, 1.f, 1.f);
MatrixType viewportMatrix;
vtkm::MatrixIdentity(viewportMatrix);
//if view type == 2D?
{
vtkm::Float32 vl, vr, vb, vt;
camera.GetRealViewport(canvas.GetWidth(),canvas.GetHeight(),vl,vr,vb,vt);
vtkm::Float32 xs = (vr-vl);
vtkm::Float32 ys = (vt-vb);
viewportMatrix = vtkm::Transform3DScale(2.f/xs, 2.f/ys, 1.f);
}
MatrixType rotateMatrix =
vtkm::Transform3DRotateZ(this->Angle * 3.14159265f / 180.f);
vtkm::Matrix<vtkm::Float32, 4, 4> fullTransformMatrix =
vtkm::MatrixMultiply(translateMatrix,
vtkm::MatrixMultiply(scaleMatrix,
vtkm::MatrixMultiply(viewportMatrix,
rotateMatrix)));
VectorType origin =
vtkm::Transform3DPointPerspective(fullTransformMatrix, VectorType(0,0,0));
VectorType right =
vtkm::Transform3DVector(fullTransformMatrix, VectorType(1,0,0));
VectorType up =
vtkm::Transform3DVector(fullTransformMatrix, VectorType(0,1,0));
worldAnnotator.AddText(origin,
right,
up,
this->Scale,
this->Anchor,
this->TextColor,
this->Text);
canvas.SetViewToWorldSpace(camera,true);
}
}
} // vtkm::rendering

@ -0,0 +1,60 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtkm_rendering_TextAnnotationBillboard_h
#define vtkm_rendering_TextAnnotationBillboard_h
#include <vtkm/rendering/TextAnnotation.h>
namespace vtkm {
namespace rendering {
class TextAnnotationBillboard : public TextAnnotation
{
protected:
vtkm::Vec<vtkm::Float32,3> Position;
vtkm::Float32 Angle;
public:
VTKM_RENDERING_EXPORT
TextAnnotationBillboard(const std::string &text,
const vtkm::rendering::Color &color,
vtkm::Float32 scalar,
const vtkm::Vec<vtkm::Float32,3> &position,
vtkm::Float32 angleDegrees = 0);
VTKM_RENDERING_EXPORT
~TextAnnotationBillboard();
VTKM_RENDERING_EXPORT
void SetPosition(const vtkm::Vec<vtkm::Float32,3> &position);
VTKM_RENDERING_EXPORT
void SetPosition(vtkm::Float32 posx, vtkm::Float32 posy, vtkm::Float32 posz);
VTKM_RENDERING_EXPORT
void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &worldAnnotator,
vtkm::rendering::Canvas &canvas) const VTKM_OVERRIDE;
};
}
} // namespace vtkm::rendering
#endif //vtkm_rendering_TextAnnotationBillboard_h

@ -0,0 +1,69 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/TextAnnotationScreen.h>
namespace vtkm {
namespace rendering {
TextAnnotationScreen::TextAnnotationScreen(
const std::string &text,
const vtkm::rendering::Color &color,
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32,2> &position,
vtkm::Float32 angleDegrees)
: TextAnnotation(text,color,scale),
Position(position),
Angle(angleDegrees)
{ }
TextAnnotationScreen::~TextAnnotationScreen()
{ }
void TextAnnotationScreen::SetPosition(
const vtkm::Vec<vtkm::Float32,2> &position)
{
this->Position = position;
}
void TextAnnotationScreen::SetPosition(vtkm::Float32 xpos, vtkm::Float32 ypos)
{
this->SetPosition(vtkm::make_Vec(xpos, ypos));
}
void TextAnnotationScreen::Render(
const vtkm::rendering::Camera &vtkmNotUsed(camera),
const vtkm::rendering::WorldAnnotator &vtkmNotUsed(annotator),
vtkm::rendering::Canvas &canvas) const
{
vtkm::Float32 windowAspect = vtkm::Float32(canvas.GetWidth()) /
vtkm::Float32(canvas.GetHeight());
canvas.AddText(this->Position,
this->Scale,
this->Angle,
windowAspect,
this->Anchor,
this->TextColor,
this->Text);
}
}
} // namespace vtkm::rendering

@ -0,0 +1,60 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_rendering_TextAnnotationScreen_h
#define vtk_m_rendering_TextAnnotationScreen_h
#include <vtkm/rendering/TextAnnotation.h>
namespace vtkm {
namespace rendering {
class TextAnnotationScreen : public TextAnnotation
{
protected:
vtkm::Vec<vtkm::Float32,2> Position;
vtkm::Float32 Angle;
public:
VTKM_RENDERING_EXPORT
TextAnnotationScreen(const std::string &text,
const vtkm::rendering::Color &color,
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32,2> &position,
vtkm::Float32 angleDegrees = 0);
VTKM_RENDERING_EXPORT
~TextAnnotationScreen();
VTKM_RENDERING_EXPORT
void SetPosition(const vtkm::Vec<vtkm::Float32,2> &position);
VTKM_RENDERING_EXPORT
void SetPosition(vtkm::Float32 posx, vtkm::Float32 posy);
VTKM_RENDERING_EXPORT
void Render(const vtkm::rendering::Camera &camera,
const vtkm::rendering::WorldAnnotator &annotator,
vtkm::rendering::Canvas &canvas) const VTKM_OVERRIDE;
};
}
} // namespace vtkm::rendering
#endif //vtk_m_rendering_TextAnnotationScreen_h

@ -0,0 +1,178 @@
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//
//=============================================================================
#include <vtkm/rendering/TextureGL.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
namespace vtkm {
namespace rendering {
struct TextureGL::InternalsType
{
GLuint Id;
int Dimension;
bool MIPMap;
bool Linear2D;
bool LinearMIP;
VTKM_CONT_EXPORT
InternalsType()
: Id(0), Dimension(0), MIPMap(false), Linear2D(true), LinearMIP(true)
{ }
VTKM_CONT_EXPORT
~InternalsType()
{
if (this->Id != 0)
{
glDeleteTextures(1, &this->Id);
}
}
};
TextureGL::TextureGL()
: Internals(new InternalsType)
{ }
TextureGL::~TextureGL()
{ }
bool TextureGL::Valid() const
{
return (this->Internals->Id != 0);
}
void TextureGL::Enable() const
{
if (!this->Valid())
{
return;
}
if (this->Internals->Dimension == 1)
{
// no this->Internals->MIPMapping for 1D (at the moment)
glBindTexture(GL_TEXTURE_1D, this->Internals->Id);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
if (this->Internals->Linear2D)
{
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
glEnable(GL_TEXTURE_1D);
}
else if (this->Internals->Dimension == 2)
{
glBindTexture(GL_TEXTURE_2D, this->Internals->Id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
if (this->Internals->Linear2D)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (!this->Internals->MIPMap)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
else if (this->Internals->LinearMIP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (!this->Internals->MIPMap)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
else if (this->Internals->LinearMIP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
glEnable(GL_TEXTURE_2D);
}
else
{
// Fail silently for invalid dimension.
}
}
void TextureGL::Disable() const
{
if (this->Internals->Dimension == 1)
{
glDisable(GL_TEXTURE_1D);
}
else if (this->Internals->Dimension == 2)
{
glDisable(GL_TEXTURE_2D);
}
else
{
// Fail silently for invalid dimension
}
}
void TextureGL::CreateAlphaFromRGBA(vtkm::Id width,
vtkm::Id height,
const std::vector<unsigned char> &rgba)
{
this->Internals->Dimension = 2;
std::vector<unsigned char> alpha(rgba.size()/4);
VTKM_ASSERT(width*height == static_cast<vtkm::Id>(alpha.size()));
for (std::size_t i=0; i<alpha.size(); i++)
{
alpha[i] = rgba[i*4+3];
}
if (this->Internals->Id == 0)
{
glGenTextures(1, &this->Internals->Id);
}
if (this->Internals->Dimension == 1)
{
glBindTexture(GL_TEXTURE_1D, this->Internals->Id);
}
else if (this->Internals->Dimension == 2)
{
glBindTexture(GL_TEXTURE_2D, this->Internals->Id);
//#define HW_MIPMAPS
#ifdef HW_MIPMAPS
mpimap = true;
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
#endif
glTexImage2D(GL_TEXTURE_2D, 0,
GL_ALPHA,
static_cast<GLsizei>(width), static_cast<GLsizei>(height),
0,
GL_ALPHA,
GL_UNSIGNED_BYTE,
(void*)(&(alpha[0])));
}
}
}
} // namespace vtkm::rendering

@ -22,123 +22,45 @@
#ifndef vtk_m_TextureGL_h
#define vtk_m_TextureGL_h
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/rendering/ColorTable.h>
#include <vector>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/shared_ptr.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
namespace vtkm {
namespace rendering {
class TextureGL
{
public:
GLuint ID;
int Dimension;
bool MIPMap;
bool Linear2D;
bool LinearMIP;
public:
TextureGL()
{
this->ID = 0;
this->Dimension = 0;
this->MIPMap = false;
this->Linear2D = true;
this->LinearMIP = true;
}
void Enable() const
{
if (this->ID == 0)
return;
VTKM_RENDERING_EXPORT
TextureGL();
if (this->Dimension == 1)
{
// no this->MIPMapping for 1D (at the moment)
glBindTexture(GL_TEXTURE_1D, this->ID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
if (this->Linear2D)
{
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
glEnable(GL_TEXTURE_1D);
}
else if (this->Dimension == 2)
{
glBindTexture(GL_TEXTURE_2D, this->ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
if (this->Linear2D)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (!this->MIPMap)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
else if (this->LinearMIP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (!this->MIPMap)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
else if (this->LinearMIP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
glEnable(GL_TEXTURE_2D);
}
}
void Disable() const
{
if (this->Dimension == 1)
glDisable(GL_TEXTURE_1D);
else if (this->Dimension == 2)
glDisable(GL_TEXTURE_2D);
}
void CreateAlphaFromRGBA(int w, int h, std::vector<unsigned char> &rgba)
{
this->Dimension = 2;
std::vector<unsigned char> alpha(rgba.size()/4);
for (unsigned int i=0; i<alpha.size(); i++)
{
alpha[i] = rgba[i*4+3];
}
VTKM_RENDERING_EXPORT
~TextureGL();
if (this->ID == 0)
{
glGenTextures(1, &this->ID);
}
VTKM_RENDERING_EXPORT
bool Valid() const;
if (this->Dimension == 1)
{
glBindTexture(GL_TEXTURE_1D, this->ID);
}
else if (this->Dimension == 2)
{
glBindTexture(GL_TEXTURE_2D, this->ID);
//#define HW_MIPMAPS
#ifdef HW_MIPMAPS
mpimap = true;
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
#endif
glTexImage2D(GL_TEXTURE_2D, 0,
GL_ALPHA,
w, h,
0,
GL_ALPHA,
GL_UNSIGNED_BYTE,
(void*)(&(alpha[0])));
}
}
VTKM_RENDERING_EXPORT
void Enable() const;
VTKM_RENDERING_EXPORT
void Disable() const;
VTKM_RENDERING_EXPORT
void CreateAlphaFromRGBA(vtkm::Id width,
vtkm::Id height,
const std::vector<unsigned char> &rgba);
private:
struct InternalsType;
boost::shared_ptr<InternalsType> Internals;
};

@ -457,7 +457,7 @@ public:
}
VTKM_CONT_EXPORT
void run(const vtkm::cont::DynamicCellSet &cellset,
void Run(const vtkm::cont::DynamicCellSet &cellset,
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Id,4> > &outputIndices,
vtkm::Id &outputTriangles)
{

89
vtkm/rendering/View.cxx Normal file

@ -0,0 +1,89 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/View.h>
namespace vtkm {
namespace rendering {
View::View(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Color &backgroundColor)
: Scene(scene),
MapperPointer(mapper.NewCopy()),
CanvasPointer(canvas.NewCopy()),
WorldAnnotatorPointer(canvas.CreateWorldAnnotator())
{
this->CanvasPointer->SetBackgroundColor(backgroundColor);
vtkm::Bounds spatialBounds = this->Scene.GetSpatialBounds();
this->Camera.ResetToBounds(spatialBounds);
if (spatialBounds.Z.Length() > 0.0)
{
this->Camera.SetModeTo3D();
}
else
{
this->Camera.SetModeTo2D();
}
}
View::View(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor)
: Scene(scene),
MapperPointer(mapper.NewCopy()),
CanvasPointer(canvas.NewCopy()),
WorldAnnotatorPointer(canvas.CreateWorldAnnotator()),
Camera(camera)
{
this->CanvasPointer->SetBackgroundColor(backgroundColor);
}
View::~View()
{ }
void View::Initialize()
{
this->GetCanvas().Initialize();
}
void View::SaveAs(const std::string &fileName) const
{
this->GetCanvas().SaveAs(fileName);
}
void View::SetupForWorldSpace(bool viewportClip)
{
//this->Camera.SetupMatrices();
this->GetCanvas().SetViewToWorldSpace(this->Camera ,viewportClip);
}
void View::SetupForScreenSpace(bool viewportClip)
{
//this->Camera.SetupMatrices();
this->GetCanvas().SetViewToScreenSpace(this->Camera,viewportClip);
}
}
} // namespace vtkm::rendering

@ -20,14 +20,12 @@
#ifndef vtk_m_rendering_View_h
#define vtk_m_rendering_View_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/BoundingBoxAnnotation.h>
#include <vtkm/rendering/AxisAnnotation3D.h>
#include <vtkm/rendering/AxisAnnotation2D.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/ColorBarAnnotation.h>
#include <vtkm/rendering/TextAnnotation.h>
#include <vtkm/rendering/Mapper.h>
#include <vtkm/rendering/Scene.h>
namespace vtkm {
@ -36,74 +34,23 @@ namespace rendering {
class View
{
public:
template<typename MapperType,
typename CanvasType>
VTKM_RENDERING_EXPORT
View(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: Scene(scene),
MapperPointer(new MapperType(mapper)),
CanvasPointer(new CanvasType(canvas))
{
this->CanvasPointer->SetBackgroundColor(backgroundColor);
this->WorldAnnotatorPointer = this->CanvasPointer->CreateWorldAnnotator();
vtkm::rendering::Color(0,0,0,1));
vtkm::Bounds spatialBounds = this->Scene.GetSpatialBounds();
this->Camera.ResetToBounds(spatialBounds);
if (spatialBounds.Z.Length() > 0.0)
{
this->Camera.SetModeTo3D();
}
else
{
this->Camera.SetModeTo2D();
}
}
template<typename MapperType,
typename CanvasType>
VTKM_RENDERING_EXPORT
View(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: Scene(scene),
MapperPointer(new MapperType(mapper)),
CanvasPointer(new CanvasType(canvas)),
Camera(camera)
{
this->CanvasPointer->SetBackgroundColor(backgroundColor);
this->WorldAnnotatorPointer = this->CanvasPointer->CreateWorldAnnotator();
}
vtkm::rendering::Color(0,0,0,1));
template<typename MapperType,
typename CanvasType,
typename WorldAnnotatorType>
View(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const WorldAnnotatorType &annotator,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: Scene(scene),
MapperPointer(new MapperType(mapper)),
CanvasPointer(new CanvasType(canvas)),
WorldAnnotatorPointer(new WorldAnnotatorType(annotator)),
Camera(camera)
{
this->CanvasPointer->SetBackgroundColor(backgroundColor);
}
virtual ~View()
{
delete this->MapperPointer;
delete this->CanvasPointer;
delete this->WorldAnnotatorPointer;
}
VTKM_RENDERING_EXPORT
virtual ~View();
VTKM_CONT_EXPORT
const vtkm::rendering::Scene &GetScene() const { return this->Scene; }
@ -168,330 +115,35 @@ public:
this->CanvasPointer->SetBackgroundColor(color);
}
VTKM_CONT_EXPORT
virtual void Initialize() {this->GetCanvas().Initialize();}
VTKM_RENDERING_EXPORT
virtual void Initialize();
VTKM_CONT_EXPORT
VTKM_RENDERING_EXPORT
virtual void Paint() = 0;
VTKM_CONT_EXPORT
virtual void RenderScreenAnnotations() {}
VTKM_CONT_EXPORT
virtual void RenderWorldAnnotations() {}
VTKM_RENDERING_EXPORT
virtual void RenderScreenAnnotations() = 0;
VTKM_RENDERING_EXPORT
virtual void RenderWorldAnnotations() = 0;
VTKM_CONT_EXPORT
void SaveAs(const std::string &fileName)
{
this->GetCanvas().SaveAs(fileName);
}
VTKM_RENDERING_EXPORT
void SaveAs(const std::string &fileName) const;
protected:
VTKM_CONT_EXPORT
void SetupForWorldSpace(bool viewportClip=true)
{
//this->Camera.SetupMatrices();
this->GetCanvas().SetViewToWorldSpace(this->Camera,viewportClip);
}
VTKM_RENDERING_EXPORT
void SetupForWorldSpace(bool viewportClip=true);
VTKM_CONT_EXPORT
void SetupForScreenSpace(bool viewportClip=false)
{
//this->Camera.SetupMatrices();
this->GetCanvas().SetViewToScreenSpace(this->Camera,viewportClip);
}
VTKM_RENDERING_EXPORT
void SetupForScreenSpace(bool viewportClip=false);
private:
vtkm::rendering::Scene Scene;
vtkm::rendering::Mapper *MapperPointer;
vtkm::rendering::Canvas *CanvasPointer;
vtkm::rendering::WorldAnnotator *WorldAnnotatorPointer;
boost::shared_ptr<vtkm::rendering::Mapper> MapperPointer;
boost::shared_ptr<vtkm::rendering::Canvas> CanvasPointer;
boost::shared_ptr<vtkm::rendering::WorldAnnotator> WorldAnnotatorPointer;
vtkm::rendering::Camera Camera;
};
// View2D View3D
class View3D : public vtkm::rendering::View
{
public:
template<typename MapperType,
typename CanvasType>
VTKM_CONT_EXPORT
View3D(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: View(scene, mapper, canvas, backgroundColor)
{
}
template<typename MapperType,
typename CanvasType>
VTKM_CONT_EXPORT
View3D(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: View(scene, mapper, canvas, camera, backgroundColor)
{
}
template<typename MapperType,
typename CanvasType,
typename WorldAnnotatorType>
VTKM_CONT_EXPORT
View3D(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const WorldAnnotatorType &annotator,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: View(scene, mapper, canvas, annotator, camera, backgroundColor)
{
}
VTKM_CONT_EXPORT
virtual void Paint()
{
this->GetCanvas().Activate();
this->GetCanvas().Clear();
this->SetupForWorldSpace();
this->GetScene().Render(
this->GetMapper(), this->GetCanvas(), this->GetCamera());
this->RenderWorldAnnotations();
this->SetupForScreenSpace();
this->RenderScreenAnnotations();
this->GetCanvas().Finish();
}
VTKM_CONT_EXPORT
virtual void RenderScreenAnnotations()
{
if (this->GetScene().GetNumberOfActors() > 0)
{
//this->ColorBarAnnotation.SetAxisColor(vtkm::rendering::Color(1,1,1));
this->ColorBarAnnotation.SetRange(this->GetScene().GetActor(0).ScalarRange, 5);
this->ColorBarAnnotation.SetColorTable(this->GetScene().GetActor(0).ColorTable);
this->ColorBarAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
}
}
VTKM_CONT_EXPORT
virtual void RenderWorldAnnotations()
{
vtkm::Bounds bounds = this->GetScene().GetSpatialBounds();
vtkm::Float64 xmin = bounds.X.Min, xmax = bounds.X.Max;
vtkm::Float64 ymin = bounds.Y.Min, ymax = bounds.Y.Max;
vtkm::Float64 zmin = bounds.Z.Min, zmax = bounds.Z.Max;
vtkm::Float64 dx = xmax-xmin, dy = ymax-ymin, dz = zmax-zmin;
vtkm::Float64 size = vtkm::Sqrt(dx*dx + dy*dy + dz*dz);
this->BoxAnnotation.SetColor(Color(.5f,.5f,.5f));
this->BoxAnnotation.SetExtents(this->GetScene().GetSpatialBounds());
this->BoxAnnotation.Render(this->GetCamera(), this->GetWorldAnnotator());
vtkm::Vec<vtkm::Float32,3> lookAt = this->GetCamera().GetLookAt();
vtkm::Vec<vtkm::Float32,3> position = this->GetCamera().GetPosition();
bool xtest = lookAt[0] > position[0];
bool ytest = lookAt[1] > position[1];
bool ztest = lookAt[2] > position[2];
const bool outsideedges = true; // if false, do closesttriad
if (outsideedges)
{
xtest = !xtest;
//ytest = !ytest;
}
vtkm::Float64 xrel = vtkm::Abs(dx) / size;
vtkm::Float64 yrel = vtkm::Abs(dy) / size;
vtkm::Float64 zrel = vtkm::Abs(dz) / size;
this->XAxisAnnotation.SetAxis(0);
this->XAxisAnnotation.SetColor(Color(1,1,1));
this->XAxisAnnotation.SetTickInvert(xtest,ytest,ztest);
this->XAxisAnnotation.SetWorldPosition(xmin,
ytest ? ymin : ymax,
ztest ? zmin : zmax,
xmax,
ytest ? ymin : ymax,
ztest ? zmin : zmax);
this->XAxisAnnotation.SetRange(xmin, xmax);
this->XAxisAnnotation.SetMajorTickSize(size / 40.f, 0);
this->XAxisAnnotation.SetMinorTickSize(size / 80.f, 0);
this->XAxisAnnotation.SetLabelFontOffset(vtkm::Float32(size / 15.f));
this->XAxisAnnotation.SetMoreOrLessTickAdjustment(xrel < .3 ? -1 : 0);
this->XAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
this->YAxisAnnotation.SetAxis(1);
this->YAxisAnnotation.SetColor(Color(1,1,1));
this->YAxisAnnotation.SetTickInvert(xtest,ytest,ztest);
this->YAxisAnnotation.SetWorldPosition(xtest ? xmin : xmax,
ymin,
ztest ? zmin : zmax,
xtest ? xmin : xmax,
ymax,
ztest ? zmin : zmax);
this->YAxisAnnotation.SetRange(ymin, ymax);
this->YAxisAnnotation.SetMajorTickSize(size / 40.f, 0);
this->YAxisAnnotation.SetMinorTickSize(size / 80.f, 0);
this->YAxisAnnotation.SetLabelFontOffset(vtkm::Float32(size / 15.f));
this->YAxisAnnotation.SetMoreOrLessTickAdjustment(yrel < .3 ? -1 : 0);
this->YAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
this->ZAxisAnnotation.SetAxis(2);
this->ZAxisAnnotation.SetColor(Color(1,1,1));
this->ZAxisAnnotation.SetTickInvert(xtest,ytest,ztest);
this->ZAxisAnnotation.SetWorldPosition(xtest ? xmin : xmax,
ytest ? ymin : ymax,
zmin,
xtest ? xmin : xmax,
ytest ? ymin : ymax,
zmax);
this->ZAxisAnnotation.SetRange(zmin, zmax);
this->ZAxisAnnotation.SetMajorTickSize(size / 40.f, 0);
this->ZAxisAnnotation.SetMinorTickSize(size / 80.f, 0);
this->ZAxisAnnotation.SetLabelFontOffset(vtkm::Float32(size / 15.f));
this->ZAxisAnnotation.SetMoreOrLessTickAdjustment(zrel < .3 ? -1 : 0);
this->ZAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
}
private:
// 3D-specific annotations
vtkm::rendering::BoundingBoxAnnotation BoxAnnotation;
vtkm::rendering::AxisAnnotation3D XAxisAnnotation;
vtkm::rendering::AxisAnnotation3D YAxisAnnotation;
vtkm::rendering::AxisAnnotation3D ZAxisAnnotation;
vtkm::rendering::ColorBarAnnotation ColorBarAnnotation;
};
class View2D : public vtkm::rendering::View
{
public:
template<typename MapperType,
typename CanvasType>
VTKM_CONT_EXPORT
View2D(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: View(scene, mapper, canvas, backgroundColor)
{
}
template<typename MapperType,
typename CanvasType>
VTKM_CONT_EXPORT
View2D(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: View(scene, mapper, canvas, camera, backgroundColor)
{
}
template<typename MapperType,
typename CanvasType,
typename WorldAnnotatorType>
VTKM_CONT_EXPORT
View2D(const vtkm::rendering::Scene &scene,
const MapperType &mapper,
const CanvasType &canvas,
const WorldAnnotatorType annotator,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1))
: View(scene, mapper, canvas, annotator, camera, backgroundColor)
{
}
VTKM_CONT_EXPORT
virtual void Paint()
{
this->GetCanvas().Activate();
this->GetCanvas().Clear();
this->SetupForWorldSpace();
this->GetScene().Render(
this->GetMapper(), this->GetCanvas(), this->GetCamera());
this->RenderWorldAnnotations();
this->SetupForScreenSpace();
this->RenderScreenAnnotations();
this->GetCanvas().Finish();
}
VTKM_CONT_EXPORT
void RenderScreenAnnotations()
{
vtkm::Float32 viewportLeft;
vtkm::Float32 viewportRight;
vtkm::Float32 viewportTop;
vtkm::Float32 viewportBottom;
this->GetCamera().GetRealViewport(
this->GetCanvas().GetWidth(), this->GetCanvas().GetHeight(),
viewportLeft, viewportRight, viewportBottom, viewportTop);
this->HorizontalAxisAnnotation.SetColor(vtkm::rendering::Color(1,1,1));
this->HorizontalAxisAnnotation.SetScreenPosition(
viewportLeft, viewportBottom, viewportRight, viewportBottom);
vtkm::Bounds viewRange = this->GetCamera().GetViewRange2D();
this->HorizontalAxisAnnotation.SetRangeForAutoTicks(viewRange.X.Min,
viewRange.X.Max);
this->HorizontalAxisAnnotation.SetMajorTickSize(0, .05, 1.0);
this->HorizontalAxisAnnotation.SetMinorTickSize(0, .02, 1.0);
this->HorizontalAxisAnnotation.SetLabelAlignment(TextAnnotation::HCenter,
TextAnnotation::Top);
this->HorizontalAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
vtkm::Float32 windowaspect =
vtkm::Float32(this->GetCanvas().GetWidth()) /
vtkm::Float32(this->GetCanvas().GetHeight());
this->VerticalAxisAnnotation.SetColor(Color(1,1,1));
this->VerticalAxisAnnotation.SetScreenPosition(
viewportLeft, viewportBottom, viewportLeft, viewportTop);
this->VerticalAxisAnnotation.SetRangeForAutoTicks(viewRange.Y.Min,
viewRange.Y.Max);
this->VerticalAxisAnnotation.SetMajorTickSize(.05 / windowaspect, 0, 1.0);
this->VerticalAxisAnnotation.SetMinorTickSize(.02 / windowaspect, 0, 1.0);
this->VerticalAxisAnnotation.SetLabelAlignment(TextAnnotation::Right,
TextAnnotation::VCenter);
this->VerticalAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
const vtkm::rendering::Scene &scene = this->GetScene();
if (scene.GetNumberOfActors() > 0)
{
//this->ColorBarAnnotation.SetAxisColor(vtkm::rendering::Color(1,1,1));
this->ColorBarAnnotation.SetRange(scene.GetActor(0).ScalarRange.Min,
scene.GetActor(0).ScalarRange.Max,
5);
this->ColorBarAnnotation.SetColorTable(scene.GetActor(0).ColorTable);
this->ColorBarAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
}
}
private:
// 2D-specific annotations
vtkm::rendering::AxisAnnotation2D HorizontalAxisAnnotation;
vtkm::rendering::AxisAnnotation2D VerticalAxisAnnotation;
vtkm::rendering::ColorBarAnnotation ColorBarAnnotation;
};
}} //namespace vtkm::rendering
}
} //namespace vtkm::rendering
#endif //vtk_m_rendering_View_h

121
vtkm/rendering/View2D.cxx Normal file

@ -0,0 +1,121 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/View2D.h>
namespace vtkm {
namespace rendering {
View2D::View2D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Color &backgroundColor)
: View(scene, mapper, canvas, backgroundColor)
{
}
View2D::View2D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor)
: View(scene, mapper, canvas, camera, backgroundColor)
{
}
View2D::~View2D()
{
}
void View2D::Paint()
{
this->GetCanvas().Activate();
this->GetCanvas().Clear();
this->SetupForWorldSpace();
this->GetScene().Render(
this->GetMapper(), this->GetCanvas(), this->GetCamera());
this->RenderWorldAnnotations();
this->SetupForScreenSpace();
this->RenderScreenAnnotations();
this->GetCanvas().Finish();
}
void View2D::RenderScreenAnnotations()
{
vtkm::Float32 viewportLeft;
vtkm::Float32 viewportRight;
vtkm::Float32 viewportTop;
vtkm::Float32 viewportBottom;
this->GetCamera().GetRealViewport(
this->GetCanvas().GetWidth(), this->GetCanvas().GetHeight(),
viewportLeft, viewportRight, viewportBottom, viewportTop);
this->HorizontalAxisAnnotation.SetColor(vtkm::rendering::Color(1,1,1));
this->HorizontalAxisAnnotation.SetScreenPosition(
viewportLeft, viewportBottom, viewportRight, viewportBottom);
vtkm::Bounds viewRange = this->GetCamera().GetViewRange2D();
this->HorizontalAxisAnnotation.SetRangeForAutoTicks(viewRange.X.Min,
viewRange.X.Max);
this->HorizontalAxisAnnotation.SetMajorTickSize(0, .05, 1.0);
this->HorizontalAxisAnnotation.SetMinorTickSize(0, .02, 1.0);
this->HorizontalAxisAnnotation.SetLabelAlignment(TextAnnotation::HCenter,
TextAnnotation::Top);
this->HorizontalAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
vtkm::Float32 windowaspect =
vtkm::Float32(this->GetCanvas().GetWidth()) /
vtkm::Float32(this->GetCanvas().GetHeight());
this->VerticalAxisAnnotation.SetColor(Color(1,1,1));
this->VerticalAxisAnnotation.SetScreenPosition(
viewportLeft, viewportBottom, viewportLeft, viewportTop);
this->VerticalAxisAnnotation.SetRangeForAutoTicks(viewRange.Y.Min,
viewRange.Y.Max);
this->VerticalAxisAnnotation.SetMajorTickSize(.05 / windowaspect, 0, 1.0);
this->VerticalAxisAnnotation.SetMinorTickSize(.02 / windowaspect, 0, 1.0);
this->VerticalAxisAnnotation.SetLabelAlignment(TextAnnotation::Right,
TextAnnotation::VCenter);
this->VerticalAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
const vtkm::rendering::Scene &scene = this->GetScene();
if (scene.GetNumberOfActors() > 0)
{
//this->ColorBarAnnotation.SetAxisColor(vtkm::rendering::Color(1,1,1));
this->ColorBarAnnotation.SetRange(scene.GetActor(0).GetScalarRange().Min,
scene.GetActor(0).GetScalarRange().Max,
5);
this->ColorBarAnnotation.SetColorTable(scene.GetActor(0).GetColorTable());
this->ColorBarAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
}
}
void View2D::RenderWorldAnnotations()
{
// 2D views don't have world annotations.
}
}
} // namespace vtkm::rendering

71
vtkm/rendering/View2D.h Normal file

@ -0,0 +1,71 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_rendering_View2D_h
#define vtk_m_rendering_View2D_h
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/AxisAnnotation2D.h>
#include <vtkm/rendering/ColorBarAnnotation.h>
namespace vtkm {
namespace rendering {
class View2D : public vtkm::rendering::View
{
public:
VTKM_RENDERING_EXPORT
View2D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1));
VTKM_RENDERING_EXPORT
View2D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1));
VTKM_RENDERING_EXPORT
~View2D();
VTKM_RENDERING_EXPORT
void Paint() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void RenderScreenAnnotations() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void RenderWorldAnnotations() VTKM_OVERRIDE;
private:
// 2D-specific annotations
vtkm::rendering::AxisAnnotation2D HorizontalAxisAnnotation;
vtkm::rendering::AxisAnnotation2D VerticalAxisAnnotation;
vtkm::rendering::ColorBarAnnotation ColorBarAnnotation;
};
}
} // namespace vtkm::rendering
#endif //vtk_m_rendering_View2D_h

159
vtkm/rendering/View3D.cxx Normal file

@ -0,0 +1,159 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/View3D.h>
namespace vtkm {
namespace rendering {
View3D::View3D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Color &backgroundColor)
: View(scene, mapper, canvas, backgroundColor)
{
}
View3D::View3D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor)
: View(scene, mapper, canvas, camera, backgroundColor)
{
}
View3D::~View3D()
{
}
void View3D::Paint()
{
this->GetCanvas().Activate();
this->GetCanvas().Clear();
this->SetupForWorldSpace();
this->GetScene().Render(
this->GetMapper(), this->GetCanvas(), this->GetCamera());
this->RenderWorldAnnotations();
this->SetupForScreenSpace();
this->RenderScreenAnnotations();
this->GetCanvas().Finish();
}
void View3D::RenderScreenAnnotations()
{
if (this->GetScene().GetNumberOfActors() > 0)
{
//this->ColorBarAnnotation.SetAxisColor(vtkm::rendering::Color(1,1,1));
this->ColorBarAnnotation.SetRange(
this->GetScene().GetActor(0).GetScalarRange(), 5);
this->ColorBarAnnotation.SetColorTable(
this->GetScene().GetActor(0).GetColorTable());
this->ColorBarAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
}
}
void View3D::RenderWorldAnnotations()
{
vtkm::Bounds bounds = this->GetScene().GetSpatialBounds();
vtkm::Float64 xmin = bounds.X.Min, xmax = bounds.X.Max;
vtkm::Float64 ymin = bounds.Y.Min, ymax = bounds.Y.Max;
vtkm::Float64 zmin = bounds.Z.Min, zmax = bounds.Z.Max;
vtkm::Float64 dx = xmax-xmin, dy = ymax-ymin, dz = zmax-zmin;
vtkm::Float64 size = vtkm::Sqrt(dx*dx + dy*dy + dz*dz);
this->BoxAnnotation.SetColor(Color(.5f,.5f,.5f));
this->BoxAnnotation.SetExtents(this->GetScene().GetSpatialBounds());
this->BoxAnnotation.Render(this->GetCamera(), this->GetWorldAnnotator());
vtkm::Vec<vtkm::Float32,3> lookAt = this->GetCamera().GetLookAt();
vtkm::Vec<vtkm::Float32,3> position = this->GetCamera().GetPosition();
bool xtest = lookAt[0] > position[0];
bool ytest = lookAt[1] > position[1];
bool ztest = lookAt[2] > position[2];
const bool outsideedges = true; // if false, do closesttriad
if (outsideedges)
{
xtest = !xtest;
//ytest = !ytest;
}
vtkm::Float64 xrel = vtkm::Abs(dx) / size;
vtkm::Float64 yrel = vtkm::Abs(dy) / size;
vtkm::Float64 zrel = vtkm::Abs(dz) / size;
this->XAxisAnnotation.SetAxis(0);
this->XAxisAnnotation.SetColor(Color(1,1,1));
this->XAxisAnnotation.SetTickInvert(xtest,ytest,ztest);
this->XAxisAnnotation.SetWorldPosition(xmin,
ytest ? ymin : ymax,
ztest ? zmin : zmax,
xmax,
ytest ? ymin : ymax,
ztest ? zmin : zmax);
this->XAxisAnnotation.SetRange(xmin, xmax);
this->XAxisAnnotation.SetMajorTickSize(size / 40.f, 0);
this->XAxisAnnotation.SetMinorTickSize(size / 80.f, 0);
this->XAxisAnnotation.SetLabelFontOffset(vtkm::Float32(size / 15.f));
this->XAxisAnnotation.SetMoreOrLessTickAdjustment(xrel < .3 ? -1 : 0);
this->XAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
this->YAxisAnnotation.SetAxis(1);
this->YAxisAnnotation.SetColor(Color(1,1,1));
this->YAxisAnnotation.SetTickInvert(xtest,ytest,ztest);
this->YAxisAnnotation.SetWorldPosition(xtest ? xmin : xmax,
ymin,
ztest ? zmin : zmax,
xtest ? xmin : xmax,
ymax,
ztest ? zmin : zmax);
this->YAxisAnnotation.SetRange(ymin, ymax);
this->YAxisAnnotation.SetMajorTickSize(size / 40.f, 0);
this->YAxisAnnotation.SetMinorTickSize(size / 80.f, 0);
this->YAxisAnnotation.SetLabelFontOffset(vtkm::Float32(size / 15.f));
this->YAxisAnnotation.SetMoreOrLessTickAdjustment(yrel < .3 ? -1 : 0);
this->YAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
this->ZAxisAnnotation.SetAxis(2);
this->ZAxisAnnotation.SetColor(Color(1,1,1));
this->ZAxisAnnotation.SetTickInvert(xtest,ytest,ztest);
this->ZAxisAnnotation.SetWorldPosition(xtest ? xmin : xmax,
ytest ? ymin : ymax,
zmin,
xtest ? xmin : xmax,
ytest ? ymin : ymax,
zmax);
this->ZAxisAnnotation.SetRange(zmin, zmax);
this->ZAxisAnnotation.SetMajorTickSize(size / 40.f, 0);
this->ZAxisAnnotation.SetMinorTickSize(size / 80.f, 0);
this->ZAxisAnnotation.SetLabelFontOffset(vtkm::Float32(size / 15.f));
this->ZAxisAnnotation.SetMoreOrLessTickAdjustment(zrel < .3 ? -1 : 0);
this->ZAxisAnnotation.Render(
this->GetCamera(), this->GetWorldAnnotator(), this->GetCanvas());
}
}
} // namespace vtkm::rendering

74
vtkm/rendering/View3D.h Normal file

@ -0,0 +1,74 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_rendering_View3D_h
#define vtk_m_rendering_View3D_h
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/AxisAnnotation3D.h>
#include <vtkm/rendering/BoundingBoxAnnotation.h>
#include <vtkm/rendering/ColorBarAnnotation.h>
namespace vtkm {
namespace rendering {
class View3D : public vtkm::rendering::View
{
public:
VTKM_RENDERING_EXPORT
View3D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1));
VTKM_RENDERING_EXPORT
View3D(const vtkm::rendering::Scene &scene,
const vtkm::rendering::Mapper &mapper,
const vtkm::rendering::Canvas &canvas,
const vtkm::rendering::Camera &camera,
const vtkm::rendering::Color &backgroundColor =
vtkm::rendering::Color(0,0,0,1));
VTKM_RENDERING_EXPORT
~View3D();
VTKM_RENDERING_EXPORT
void Paint() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void RenderScreenAnnotations() VTKM_OVERRIDE;
VTKM_RENDERING_EXPORT
void RenderWorldAnnotations() VTKM_OVERRIDE;
private:
// 3D-specific annotations
vtkm::rendering::BoundingBoxAnnotation BoxAnnotation;
vtkm::rendering::AxisAnnotation3D XAxisAnnotation;
vtkm::rendering::AxisAnnotation3D YAxisAnnotation;
vtkm::rendering::AxisAnnotation3D ZAxisAnnotation;
vtkm::rendering::ColorBarAnnotation ColorBarAnnotation;
};
}
} // namespace vtkm::rendering
#endif //vtk_m_rendering_View3D_h

@ -0,0 +1,56 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/WorldAnnotator.h>
namespace vtkm {
namespace rendering {
WorldAnnotator::~WorldAnnotator()
{ }
void WorldAnnotator::AddLine(
const vtkm::Vec<vtkm::Float64,3> &vtkmNotUsed(point0),
const vtkm::Vec<vtkm::Float64,3> &vtkmNotUsed(point1),
vtkm::Float32 vtkmNotUsed(lineWidth),
const vtkm::rendering::Color &vtkmNotUsed(color),
bool vtkmNotUsed(inFront)) const
{
// Default implementation does nothing. Should this be pure virtual and force
// all subclasses to implement this? We would have to implement a
// WorldAnnotator for ray tracing first.
}
void WorldAnnotator::AddText(
const vtkm::Vec<vtkm::Float32,3> &vtkmNotUsed(origin),
const vtkm::Vec<vtkm::Float32,3> &vtkmNotUsed(right),
const vtkm::Vec<vtkm::Float32,3> &vtkmNotUsed(up),
vtkm::Float32 vtkmNotUsed(scale),
const vtkm::Vec<vtkm::Float32,2> &vtkmNotUsed(anchor),
const vtkm::rendering::Color &vtkmNotUsed(color),
const std::string &vtkmNotUsed(text)) const
{
// Default implementation does nothing. Should this be pure virtual and force
// all subclasses to implement this? We would have to implement a
// WorldAnnotator for ray tracing first.
}
}
} // namespace vtkm::rendering

@ -20,7 +20,9 @@
#ifndef vtk_m_rendering_WorldAnnotator_h
#define vtk_m_rendering_WorldAnnotator_h
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/Types.h>
#include <vtkm/rendering/Color.h>
namespace vtkm {
@ -29,20 +31,63 @@ namespace rendering {
class WorldAnnotator
{
public:
virtual ~WorldAnnotator() { }
VTKM_RENDERING_EXPORT
virtual ~WorldAnnotator();
virtual void AddLine(vtkm::Float64, vtkm::Float64, vtkm::Float64,
vtkm::Float64, vtkm::Float64, vtkm::Float64,
vtkm::Float32,
const vtkm::rendering::Color &,
bool=false) const {}
virtual void AddText(vtkm::Float32, vtkm::Float32, vtkm::Float32,
vtkm::Float32, vtkm::Float32, vtkm::Float32,
vtkm::Float32, vtkm::Float32, vtkm::Float32,
vtkm::Float32,
vtkm::Float32, vtkm::Float32,
Color,
std::string) const {}
VTKM_RENDERING_EXPORT
virtual void AddLine(const vtkm::Vec<vtkm::Float64,3> &point0,
const vtkm::Vec<vtkm::Float64,3> &point1,
vtkm::Float32 lineWidth,
const vtkm::rendering::Color &color,
bool inFront = false) const;
VTKM_CONT_EXPORT
void AddLine(vtkm::Float64 x0, vtkm::Float64 y0, vtkm::Float64 z0,
vtkm::Float64 x1, vtkm::Float64 y1, vtkm::Float64 z1,
vtkm::Float32 lineWidth,
const vtkm::rendering::Color &color,
bool inFront = false) const
{
this->AddLine(vtkm::make_Vec(x0,y0,z0),
vtkm::make_Vec(x1,y1,z1),
lineWidth,
color,
inFront);
}
VTKM_RENDERING_EXPORT
virtual void AddText(const vtkm::Vec<vtkm::Float32,3> &origin,
const vtkm::Vec<vtkm::Float32,3> &right,
const vtkm::Vec<vtkm::Float32,3> &up,
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color &color,
const std::string &text) const;
VTKM_CONT_EXPORT
void AddText(vtkm::Float32 originX,
vtkm::Float32 originY,
vtkm::Float32 originZ,
vtkm::Float32 rightX,
vtkm::Float32 rightY,
vtkm::Float32 rightZ,
vtkm::Float32 upX,
vtkm::Float32 upY,
vtkm::Float32 upZ,
vtkm::Float32 scale,
vtkm::Float32 anchorX,
vtkm::Float32 anchorY,
const vtkm::rendering::Color &color,
const std::string &text) const
{
this->AddText(vtkm::make_Vec(originX, originY, originZ),
vtkm::make_Vec(rightX, rightY, rightZ),
vtkm::make_Vec(upX, upY, upZ),
scale,
vtkm::make_Vec(anchorX, anchorY),
color,
text);
}
};
}} //namespace vtkm::rendering

@ -0,0 +1,170 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/WorldAnnotatorGL.h>
#include <vtkm/Matrix.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/DecodePNG.h>
#include <vtkm/rendering/MatrixHelpers.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
namespace vtkm {
namespace rendering {
WorldAnnotatorGL::~WorldAnnotatorGL()
{ }
void WorldAnnotatorGL::AddLine(const vtkm::Vec<vtkm::Float64,3> &point0,
const vtkm::Vec<vtkm::Float64,3> &point1,
vtkm::Float32 lineWidth,
const vtkm::rendering::Color &color,
bool inFront) const
{
if (inFront)
{
glDepthRange(-.0001,.9999);
}
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
glLineWidth(lineWidth);
glBegin(GL_LINES);
glVertex3d(point0[0], point0[1], point0[2]);
glVertex3d(point1[0], point1[1], point1[2]);
glEnd();
if (inFront)
{
glDepthRange(0,1);
}
}
void WorldAnnotatorGL::AddText(const vtkm::Vec<vtkm::Float32,3> &origin,
const vtkm::Vec<vtkm::Float32,3> &right,
const vtkm::Vec<vtkm::Float32,3> &up,
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color &color,
const std::string &text) const
{
vtkm::Vec<vtkm::Float32,3> n = vtkm::Cross(right,up);
vtkm::Normalize(n);
vtkm::Matrix<vtkm::Float32,4,4> m;
m = MatrixHelpers::WorldMatrix(origin, right, up, n);
vtkm::Float32 ogl[16];
MatrixHelpers::CreateOGLMatrix(m, ogl);
glPushMatrix();
glMultMatrixf(ogl);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
this->RenderText(scale, anchor[0], anchor[1], text);
glPopMatrix();
}
void WorldAnnotatorGL::RenderText(vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
std::string text) const
{
if (!this->FontTexture.Valid())
{
// When we load a font, we save a reference to it for the next time we
// use it. Although technically we are changing the state, the logical
// state does not change, so we go ahead and do it in this const
// function.
vtkm::rendering::WorldAnnotatorGL *self =
const_cast<vtkm::rendering::WorldAnnotatorGL *>(this);
self->Font = BitmapFontFactory::CreateLiberation2Sans();
const std::vector<unsigned char> &rawpngdata =
this->Font.GetRawImageData();
std::vector<unsigned char> rgba;
unsigned long width, height;
int error = vtkm::rendering::DecodePNG(rgba, width, height,
&rawpngdata[0], rawpngdata.size());
if (error != 0)
{
return;
}
self->FontTexture.CreateAlphaFromRGBA(int(width),int(height),rgba);
}
this->FontTexture.Enable();
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHTING);
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -.5);
glBegin(GL_QUADS);
vtkm::Float32 textwidth = this->Font.GetTextWidth(text);
vtkm::Float32 fx = -(.5f + .5f*anchorx) * textwidth;
vtkm::Float32 fy = -(.5f + .5f*anchory);
vtkm::Float32 fz = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
char c = text[i];
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
vtkm::Float32 vl,vr,vt,vb;
vtkm::Float32 tl,tr,tt,tb;
this->Font.GetCharPolygon(c, fx, fy,
vl, vr, vt, vb,
tl, tr, tt, tb, nextchar);
glTexCoord2f(tl, 1.f-tt);
glVertex3f(scale*vl, scale*vt, fz);
glTexCoord2f(tl, 1.f-tb);
glVertex3f(scale*vl, scale*vb, fz);
glTexCoord2f(tr, 1.f-tb);
glVertex3f(scale*vr, scale*vb, fz);
glTexCoord2f(tr, 1.f-tt);
glVertex3f(scale*vr, scale*vt, fz);
}
glEnd();
this->FontTexture.Disable();
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
}
}
} // namespace vtkm::rendering

@ -20,17 +20,10 @@
#ifndef vtk_m_rendering_WorldAnnotatorGL_h
#define vtk_m_rendering_WorldAnnotatorGL_h
#include <vtkm/Matrix.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/BitmapFont.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/MatrixHelpers.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/TextureGL.h>
#include <vtkm/rendering/WorldAnnotator.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <vtkm/rendering/BitmapFont.h>
#include <vtkm/rendering/TextureGL.h>
namespace vtkm {
namespace rendering {
@ -38,57 +31,24 @@ namespace rendering {
class WorldAnnotatorGL : public WorldAnnotator
{
public:
virtual void AddLine(vtkm::Float64 x0, vtkm::Float64 y0, vtkm::Float64 z0,
vtkm::Float64 x1, vtkm::Float64 y1, vtkm::Float64 z1,
vtkm::Float32 linewidth,
const vtkm::rendering::Color &c,
bool infront) const
{
if (infront)
glDepthRange(-.0001,.9999);
VTKM_RENDERING_EXPORT
~WorldAnnotatorGL();
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
VTKM_RENDERING_EXPORT
void AddLine(const vtkm::Vec<vtkm::Float64,3> &point0,
const vtkm::Vec<vtkm::Float64,3> &point1,
vtkm::Float32 lineWidth,
const vtkm::rendering::Color &color,
bool inFront) const VTKM_OVERRIDE;
glColor3f(c.Components[0], c.Components[1], c.Components[2]);
glLineWidth(linewidth);
glBegin(GL_LINES);
glVertex3d(x0,y0,z0);
glVertex3d(x1,y1,z1);
glEnd();
if (infront)
glDepthRange(0,1);
}
virtual void AddText(vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 oz,
vtkm::Float32 rx, vtkm::Float32 ry, vtkm::Float32 rz,
vtkm::Float32 ux, vtkm::Float32 uy, vtkm::Float32 uz,
VTKM_RENDERING_EXPORT
void AddText(const vtkm::Vec<vtkm::Float32,3> &origin,
const vtkm::Vec<vtkm::Float32,3> &right,
const vtkm::Vec<vtkm::Float32,3> &up,
vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
Color color,
std::string text) const
{
vtkm::Vec<vtkm::Float32,3> o(ox,oy,oz);
vtkm::Vec<vtkm::Float32,3> r(rx,ry,rz);
vtkm::Vec<vtkm::Float32,3> u(ux,uy,uz);
vtkm::Vec<vtkm::Float32,3> n = vtkm::Cross(r,u);
vtkm::Normalize(n);
vtkm::Matrix<vtkm::Float32,4,4> m;
m = MatrixHelpers::WorldMatrix(o, r, u, n);
vtkm::Float32 ogl[16];
MatrixHelpers::CreateOGLMatrix(m, ogl);
glPushMatrix();
glMultMatrixf(ogl);
glColor3f(color.Components[0], color.Components[1], color.Components[2]);
this->RenderText(scale, anchorx, anchory, text);
glPopMatrix();
}
const vtkm::Vec<vtkm::Float32,2> &anchor,
const vtkm::rendering::Color &color,
const std::string &text) const VTKM_OVERRIDE;
private:
BitmapFont Font;
@ -96,81 +56,7 @@ private:
void RenderText(vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
std::string text) const
{
if (this->FontTexture.ID == 0)
{
// When we load a font, we save a reference to it for the next time we
// use it. Although technically we are changing the state, the logical
// state does not change, so we go ahead and do it in this const
// function.
vtkm::rendering::WorldAnnotatorGL *self =
const_cast<vtkm::rendering::WorldAnnotatorGL *>(this);
self->Font = BitmapFontFactory::CreateLiberation2Sans();
const std::vector<unsigned char> &rawpngdata =
this->Font.GetRawImageData();
std::vector<unsigned char> rgba;
unsigned long width, height;
int error = decodePNG(rgba, width, height,
&rawpngdata[0], rawpngdata.size());
if (error != 0)
{
return;
}
self->FontTexture.CreateAlphaFromRGBA(int(width),int(height),rgba);
}
this->FontTexture.Enable();
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHTING);
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -.5);
glBegin(GL_QUADS);
vtkm::Float32 textwidth = this->Font.GetTextWidth(text);
vtkm::Float32 fx = -(.5f + .5f*anchorx) * textwidth;
vtkm::Float32 fy = -(.5f + .5f*anchory);
vtkm::Float32 fz = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
char c = text[i];
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
vtkm::Float32 vl,vr,vt,vb;
vtkm::Float32 tl,tr,tt,tb;
this->Font.GetCharPolygon(c, fx, fy,
vl, vr, vt, vb,
tl, tr, tt, tb, nextchar);
glTexCoord2f(tl, 1.f-tt);
glVertex3f(scale*vl, scale*vt, fz);
glTexCoord2f(tl, 1.f-tb);
glVertex3f(scale*vl, scale*vb, fz);
glTexCoord2f(tr, 1.f-tb);
glVertex3f(scale*vr, scale*vb, fz);
glTexCoord2f(tr, 1.f-tt);
glVertex3f(scale*vr, scale*vt, fz);
}
glEnd();
this->FontTexture.Disable();
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
}
std::string text) const;
};
}} //namespace vtkm::rendering

@ -20,6 +20,7 @@
set(headers
OpenGLHeaders.h
RunTriangulator.h
)
vtkm_declare_headers(${headers})

@ -0,0 +1,85 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/rendering/internal/RunTriangulator.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/Triangulator.h>
namespace vtkm {
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_EXPORT
TriangulatorFunctor(vtkm::cont::DynamicCellSet cellSet)
: CellSet(cellSet)
{ }
template<typename Device>
VTKM_CONT_EXPORT
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::internal::RuntimeDeviceTracker &tracker)
{
// 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,
VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG()))
{
throw vtkm::cont::ErrorExecution("Failed to execute triangulator.");
}
indices = triangulatorFunctor.Indices;
numberOfTriangles = triangulatorFunctor.NumberOfTriangles;
}
void RunTriangulator(const vtkm::cont::DynamicCellSet &cellSet,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id,4> > &indices,
vtkm::Id &numberOfTriangles)
{
vtkm::cont::internal::RuntimeDeviceTracker tracker;
vtkm::rendering::internal::RunTriangulator(
cellSet, indices, numberOfTriangles, tracker);
}
}
}
} // namespace vtkm::rendering::internal

@ -0,0 +1,52 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_rendering_internal_RunTriangulator_h
#define vtk_m_rendering_internal_RunTriangulator_h
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
namespace vtkm {
namespace rendering {
namespace internal {
/// This is a wrapper around the Triangulator worklet so that the
/// implementation of the triangulator only gets compiled once. This function
/// really is a stop-gap. Eventually, the Triangulator should be moved to
/// 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_RENDERING_EXPORT
void RunTriangulator(const vtkm::cont::DynamicCellSet &cellSet,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id,4> > &indices,
vtkm::Id &numberOfTriangles,
vtkm::cont::internal::RuntimeDeviceTracker &tracker);
}
}
} // namespace vtkm::rendering::internal
#endif //vtk_m_rendering_internal_RunTriangulator_h

@ -27,7 +27,8 @@
#include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Mapper.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View2D.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
namespace vtkm {

@ -22,7 +22,7 @@
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
@ -53,7 +53,7 @@ void Render(const vtkm::cont::DataSet &ds,
{
const vtkm::Int32 W = 512, H = 512;
const vtkm::cont::CoordinateSystem coords = ds.GetCoordinateSystem();
vtkm::rendering::MapperRayTracer<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> mapper;
vtkm::rendering::MapperRayTracer mapper;
vtkm::rendering::Camera camera;
Set3DView(camera, coords);

@ -23,7 +23,7 @@
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperVolume.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
@ -54,7 +54,7 @@ void Render(const vtkm::cont::DataSet &ds,
{
const vtkm::Int32 W = 512, H = 512;
const vtkm::cont::CoordinateSystem coords = ds.GetCoordinateSystem();
vtkm::rendering::MapperVolume<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> mapper;
vtkm::rendering::MapperVolume mapper;
vtkm::rendering::Camera camera;
Set3DView(camera, coords);

@ -23,7 +23,8 @@
#include <vtkm/rendering/CanvasEGL.h>
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View2D.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/rendering/testing/RenderTest.h>

@ -24,7 +24,8 @@
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View2D.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/rendering/testing/RenderTest.h>
@ -49,10 +50,10 @@ void RenderTests()
{
std::cout<<"Press any key to cycle through datasets. ESC to quit."<<std::endl;
typedef vtkm::rendering::MapperGL<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> M;
typedef vtkm::rendering::CanvasGL C;
typedef vtkm::rendering::View3D V3;
typedef vtkm::rendering::View2D V2;
typedef vtkm::rendering::MapperGL MapperType;
typedef vtkm::rendering::CanvasGL CanvasType;
typedef vtkm::rendering::View3D View3DType;
typedef vtkm::rendering::View2D View2DType;
vtkm::cont::testing::MakeTestDataSet maker;
vtkm::rendering::ColorTable colorTable("thermal");
@ -67,16 +68,16 @@ void RenderTests()
glfwPollEvents();
if (which == 0)
vtkm::rendering::testing::Render<M,C,V3>(maker.Make3DRegularDataSet0(),
vtkm::rendering::testing::Render<MapperType,CanvasType,View3DType>(maker.Make3DRegularDataSet0(),
"pointvar", colorTable, "reg3D.pnm");
else if (which == 1)
vtkm::rendering::testing::Render<M,C,V3>(maker.Make3DRectilinearDataSet0(),
vtkm::rendering::testing::Render<MapperType,CanvasType,View3DType>(maker.Make3DRectilinearDataSet0(),
"pointvar", colorTable, "rect3D.pnm");
else if (which == 2)
vtkm::rendering::testing::Render<M,C,V3>(maker.Make3DExplicitDataSet4(),
vtkm::rendering::testing::Render<MapperType,CanvasType,View3DType>(maker.Make3DExplicitDataSet4(),
"pointvar", colorTable, "expl3D.pnm");
else if (which == 3)
vtkm::rendering::testing::Render<M,C,V2>(maker.Make2DRectilinearDataSet0(),
vtkm::rendering::testing::Render<MapperType,CanvasType,View2DType>(maker.Make2DRectilinearDataSet0(),
"pointvar", colorTable, "rect2D.pnm");
glfwSwapBuffers(window);

@ -23,7 +23,8 @@
#include <vtkm/rendering/CanvasOSMesa.h>
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/View2D.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/rendering/testing/RenderTest.h>
@ -32,22 +33,22 @@ namespace {
void RenderTests()
{
typedef vtkm::rendering::MapperGL<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> M;
typedef vtkm::rendering::CanvasOSMesa C;
typedef vtkm::rendering::View3D V3;
typedef vtkm::rendering::View2D V2;
typedef vtkm::rendering::MapperGL MapperType;
typedef vtkm::rendering::CanvasOSMesa CanvasType;
typedef vtkm::rendering::View3D View3DType;
typedef vtkm::rendering::View2D View2DType;
vtkm::cont::testing::MakeTestDataSet maker;
vtkm::rendering::ColorTable colorTable("thermal");
vtkm::rendering::testing::Render<M,C,V3>(maker.Make3DRegularDataSet0(),
"pointvar", colorTable, "reg3D.pnm");
vtkm::rendering::testing::Render<M,C,V3>(maker.Make3DRectilinearDataSet0(),
"pointvar", colorTable, "rect3D.pnm");
vtkm::rendering::testing::Render<M,C,V3>(maker.Make3DExplicitDataSet4(),
"pointvar", colorTable, "expl3D.pnm");
vtkm::rendering::testing::Render<M,C,V2>(maker.Make2DRectilinearDataSet0(),
"pointvar", colorTable, "rect2D.pnm");
vtkm::rendering::testing::Render<MapperType,CanvasType,View3DType>(
maker.Make3DRegularDataSet0(), "pointvar", colorTable, "reg3D.pnm");
vtkm::rendering::testing::Render<MapperType,CanvasType,View3DType>(
maker.Make3DRectilinearDataSet0(), "pointvar", colorTable, "rect3D.pnm");
vtkm::rendering::testing::Render<MapperType,CanvasType,View3DType>(
maker.Make3DExplicitDataSet4(), "pointvar", colorTable, "expl3D.pnm");
vtkm::rendering::testing::Render<MapperType,CanvasType,View2DType>(
maker.Make2DRectilinearDataSet0(), "pointvar", colorTable, "rect2D.pnm");
}
} //namespace

@ -181,6 +181,26 @@ struct TransformTests
test_equal(rotated1, Vec(-startPoint[1],startPoint[0],startPoint[2])),
"Bad rotate.");
}
void CheckPerspective()
{
std::cout << "--- Checking Perspective" << std::endl;
Vec startPoint = this->RandomVector();
std::cout << " Starting point: " << startPoint << std::endl;
Transform perspective(0);
perspective(0, 0) = 1;
perspective(1, 1) = 1;
perspective(2, 2) = 1;
perspective(3, 2) = 1;
Vec projected = vtkm::Transform3DPointPerspective(perspective, startPoint);
std::cout << " Projected: " << projected << std::endl;
VTKM_TEST_ASSERT(
test_equal(projected, startPoint/startPoint[2]),
"Bad perspective.");
}
};
struct TryTransformsFunctor