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:
commit
8e845d6933
@ -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
|
||||
|
1
CMake/WrapCUDASource.cu.in
Normal file
1
CMake/WrapCUDASource.cu.in
Normal file
@ -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
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
|
||||
|
156
vtkm/rendering/AxisAnnotation.cxx
Normal file
156
vtkm/rendering/AxisAnnotation.cxx
Normal file
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
181
vtkm/rendering/AxisAnnotation2D.cxx
Normal file
181
vtkm/rendering/AxisAnnotation2D.cxx
Normal file
@ -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
|
||||
|
191
vtkm/rendering/AxisAnnotation3D.cxx
Normal file
191
vtkm/rendering/AxisAnnotation3D.cxx
Normal file
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
95
vtkm/rendering/BitmapFont.cxx
Normal file
95
vtkm/rendering/BitmapFont.cxx
Normal file
@ -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
|
||||
|
9691
vtkm/rendering/BitmapFontFactory.cxx
Normal file
9691
vtkm/rendering/BitmapFontFactory.cxx
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
83
vtkm/rendering/BoundingBoxAnnotation.cxx
Normal file
83
vtkm/rendering/BoundingBoxAnnotation.cxx
Normal file
@ -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
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
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;
|
||||
|
130
vtkm/rendering/CanvasEGL.cxx
Normal file
130
vtkm/rendering/CanvasEGL.cxx
Normal file
@ -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
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
|
||||
|
119
vtkm/rendering/CanvasOSMesa.cxx
Normal file
119
vtkm/rendering/CanvasOSMesa.cxx
Normal file
@ -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
|
||||
|
151
vtkm/rendering/CanvasRayTracer.cxx
Normal file
151
vtkm/rendering/CanvasRayTracer.cxx
Normal file
@ -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]<<"]";
|
||||
|
72
vtkm/rendering/ColorBarAnnotation.cxx
Normal file
72
vtkm/rendering/ColorBarAnnotation.cxx
Normal file
@ -0,0 +1,72 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 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
|
||||
|
1204
vtkm/rendering/ColorTable.cxx
Normal file
1204
vtkm/rendering/ColorTable.cxx
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
578
vtkm/rendering/DecodePNG.cxx
Normal file
578
vtkm/rendering/DecodePNG.cxx
Normal file
@ -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
|
43
vtkm/rendering/DecodePNG.h
Normal file
43
vtkm/rendering/DecodePNG.h
Normal file
@ -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
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
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
|
||||
|
200
vtkm/rendering/MapperRayTracer.cxx
Normal file
200
vtkm/rendering/MapperRayTracer.cxx
Normal file
@ -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
|
||||
|
204
vtkm/rendering/MapperVolume.cxx
Normal file
204
vtkm/rendering/MapperVolume.cxx
Normal file
@ -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
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
|
||||
|
||||
|
89
vtkm/rendering/TextAnnotation.cxx
Normal file
89
vtkm/rendering/TextAnnotation.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/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
|
||||
|
121
vtkm/rendering/TextAnnotationBillboard.cxx
Normal file
121
vtkm/rendering/TextAnnotationBillboard.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/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
|
60
vtkm/rendering/TextAnnotationBillboard.h
Normal file
60
vtkm/rendering/TextAnnotationBillboard.h
Normal file
@ -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
|
69
vtkm/rendering/TextAnnotationScreen.cxx
Normal file
69
vtkm/rendering/TextAnnotationScreen.cxx
Normal file
@ -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
|
60
vtkm/rendering/TextAnnotationScreen.h
Normal file
60
vtkm/rendering/TextAnnotationScreen.h
Normal file
@ -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
|
178
vtkm/rendering/TextureGL.cxx
Normal file
178
vtkm/rendering/TextureGL.cxx
Normal file
@ -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
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
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
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
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
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
|
56
vtkm/rendering/WorldAnnotator.cxx
Normal file
56
vtkm/rendering/WorldAnnotator.cxx
Normal file
@ -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
|
||||
|
170
vtkm/rendering/WorldAnnotatorGL.cxx
Normal file
170
vtkm/rendering/WorldAnnotatorGL.cxx
Normal file
@ -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})
|
||||
|
85
vtkm/rendering/internal/RunTriangulator.cxx
Normal file
85
vtkm/rendering/internal/RunTriangulator.cxx
Normal file
@ -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
|
52
vtkm/rendering/internal/RunTriangulator.h
Normal file
52
vtkm/rendering/internal/RunTriangulator.h
Normal file
@ -0,0 +1,52 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 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
|
||||
|
Loading…
Reference in New Issue
Block a user