diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7dbc296..c0b1b8b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,18 @@ else()
message(FATAL_ERROR, "Cannot locate opensubdiv/version.h in CMAKE_SOURCE_DIR")
endif()
+# Evaluate 'soname' from OSD version
+
+ # replace '_' with '.'
+ string(REGEX REPLACE "(_)" "." OSD_SONAME ${OpenSubdiv_VERSION})
+
+ # remove starting 'v' character
+ string(REGEX REPLACE "^v" "" OSD_SONAME ${OSD_SONAME})
+
+ add_definitions(
+ -DOPENSUBDIV_VERSION_STRING="${OSD_SONAME}"
+ )
+
#-------------------------------------------------------------------------------
message(STATUS "Compiling ${CMAKE_PROJECT_NAME} version ${OpenSubdiv_VERSION}")
@@ -121,16 +133,16 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(OSD_COMPILER_FLAGS)
-# Disable spurious warnings in gcc builds and clang
+# Disable spurrious warnings in gcc builds and clang
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANGCC OR CMAKE_COMPILER_IS_ICC )
# Turn on all warnings
if(CMAKE_COMPILER_IS_ICC)
- list(APPEND OSD_COMPILER_FLAGS -w3 -wd1418 -wd981 -wd383 -wd193)
+ list(APPEND OSD_COMPILER_FLAGS -w2 -wd1572 -wd1418 -wd981 -wd383 -wd193 -wd444)
else()
list(APPEND OSD_COMPILER_FLAGS -Wall -Wextra)
endif()
-
+
# HBR uses the offsetof macro on a templated struct, which appears
# to spurriously set off this warning in both gccc and Clang
list(APPEND OSD_COMPILER_FLAGS -Wno-invalid-offsetof)
@@ -218,6 +230,9 @@ elseif(MSVC)
/W3 # Use warning level recommended for production purposes.
/WX # Treat all compiler warnings as errors.
+ # warning C4005: macro redefinition
+ /wd4005
+
# these warnings are being triggered from inside VC's header files
# warning C4350: behavior change: 'member1' called instead of 'member2'
/wd4350
@@ -275,8 +290,8 @@ option(MAYA_LOCATION "Path to Maya" "")
option(NO_LIB "Disable the opensubdiv libs build (caveat emptor)" OFF)
option(NO_EXAMPLES "Disable examples build" OFF)
+option(NO_TUTORIALS "Disable tutorials build" OFF)
option(NO_REGRESSION "Disable regression tests build" OFF)
-option(NO_PYTHON "Disable Python SWIG build" OFF)
option(NO_MAYA "Disable Maya plugin build" OFF)
option(NO_PTEX "Disable PTex support" OFF)
option(NO_DOC "Disable documentation build" OFF)
@@ -285,8 +300,7 @@ option(NO_TBB "Disable TBB backend" OFF)
option(NO_CUDA "Disable CUDA backend" OFF)
option(NO_OPENCL "Disable OpenCL backend" OFF)
option(NO_CLEW "Disable CLEW wrapper library" OFF)
-option(NO_GCD "Disable GrandCentralDispatch backend" OFF)
-option(NO_NEON "Disable NEON backend" OFF)
+option(NO_OPENGL "Disable OpenGL support")
# Check for dependencies
if(NOT NO_OMP)
@@ -295,13 +309,15 @@ endif()
if(NOT NO_TBB)
find_package(TBB 4.0)
endif()
-find_package(OpenGL)
+if (NOT NO_OPENGL)
+ find_package(OpenGL)
+endif()
find_package(OpenGLES)
if(NOT NO_OPENCL)
if(NOT NO_CLEW)
find_package(CLEW)
endif()
- if(NOT CLEW_FOUND)
+ if (NOT CLEW_FOUND)
find_package(OpenCL 1.1)
else()
set(OPENCL_FOUND TRUE)
@@ -311,15 +327,11 @@ if(NOT NO_CUDA)
find_package(CUDA 4.0)
endif()
if(NOT ANDROID AND NOT IOS)
- find_package(GLFW 2.7.0)
+ find_package(GLFW 3.0.0)
endif()
if(NOT NO_PTEX)
find_package(PTex 2.0)
endif()
-find_package(PythonInterp 2.6)
-find_package(SWIG 1.3.40)
-find_package(Doxygen 1.8.4)
-find_package(Docutils 0.6)
if (OPENGL_FOUND AND NOT IOS)
if (APPLE)
find_package(GLEW)
@@ -332,30 +344,21 @@ if (WIN32)
find_package(DXSDK)
endif()
-if (NOT NO_GCD AND APPLE)
- set(GCD_FOUND 1)
-endif()
-
-if (NOT NO_NEON AND ANDROID)
- set(NEON_FOUND 1)
-endif()
-
if (NOT NO_MAYA)
find_package(Maya 201200)
endif()
+if (NOT NO_DOC)
+ find_package(Doxygen 1.8.4)
+ find_package(Docutils 0.6)
+else()
+ set(DOXYGEN_EXECUTABLE )
+endif()
+
# Warn about missing dependencies that will cause parts of OpenSubdiv to be
# disabled. Also, add preprocessor defines that can be used in the source
# code to determine if a specific dependency is present or not.
-if(GCD_FOUND)
- add_definitions( -DOPENSUBDIV_HAS_GCD )
-endif()
-
-if(NEON_FOUND)
- add_definitions(-DLOCAL_ARM_MODE=arm -DLOCAL_ARM_NEON=true -mfpu=neon)
-endif()
-
if(OPENMP_FOUND)
add_definitions(
-DOPENSUBDIV_HAS_OPENMP
@@ -403,11 +406,13 @@ if(GLEW_FOUND AND OPENGL_4_2_FOUND)
-DOPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
)
else()
- message(WARNING
- "OpenGL 4.2 was not found : support for GLSL transform feedback kernels "
- "will be disabled in Osd. If you have an OpenGL SDK installed "
- "(version 4.2 or above), please refer to the FindOpenGL.cmake "
- "shared module in your cmake installation.")
+ if (NOT NO_OPENGL)
+ message(WARNING
+ "OpenGL 4.2 was not found : support for GLSL transform feedback kernels "
+ "will be disabled in Osd. If you have an OpenGL SDK installed "
+ "(version 4.2 or above), please refer to the FindOpenGL.cmake "
+ "shared module in your cmake installation.")
+ endif()
endif()
# note : (GLSL compute shader kernels require GL 4.3)
@@ -416,11 +421,13 @@ if(GLEW_FOUND AND OPENGL_4_3_FOUND)
-DOPENSUBDIV_HAS_GLSL_COMPUTE
)
else()
- message(WARNING
- "OpenGL 4.3 was not found : support for GLSL compute shader kernels "
- "will be disabled in Osd. If you have an OpenGL SDK installed "
- "(version 4.3 or above), please refer to the FindOpenGL.cmake "
- "shared module in your cmake installation.")
+ if (NOT NO_OPENGL)
+ message(WARNING
+ "OpenGL 4.3 was not found : support for GLSL compute shader kernels "
+ "will be disabled in Osd. If you have an OpenGL SDK installed "
+ "(version 4.3 or above), please refer to the FindOpenGL.cmake "
+ "shared module in your cmake installation.")
+ endif()
endif()
if(OPENGLES_FOUND)
@@ -443,8 +450,8 @@ if(OPENCL_FOUND)
if (NOT NO_CLEW)
message(WARNING
"OpenCL was found, but CLEW was not. "
- "Building with OpenCL support enabled, but the build "
- "wouldn't be portable on systems without OpenCL installed.")
+ "Building with OpenCL support enabled, but the built binary "
+ "will not be portable to systems without OpenCL installed.")
endif()
endif()
else()
@@ -584,23 +591,20 @@ function(_stringify src_files varname)
foreach(src_file ${src_files})
- string(REGEX REPLACE ".*[.](.*)" "\\1" extension "${src_file}")
+ string(REGEX REPLACE ".*[.](.*)" "\\1" extension "${src_file}")
- if(NOT ${extension} STREQUAL "cu")
+ string(REGEX REPLACE "(.*)[.].*" "\\1.gen.h" inc_file "${src_file}")
+ list(APPEND inc_files "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}")
- string(REGEX REPLACE "(.*)[.].*" "\\1.gen.h" inc_file "${src_file}")
- list(APPEND inc_files "${inc_file}")
+ add_custom_command(
+ OUTPUT
+ "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
+ COMMAND
+ stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
+ DEPENDS
+ stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}"
+ )
- add_custom_command(
- OUTPUT
- "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
- COMMAND
- stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
- DEPENDS
- stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}"
- )
-
- endif()
endforeach()
set(${varname} ${inc_files} PARENT_SCOPE)
endfunction()
@@ -670,7 +674,7 @@ endmacro()
add_subdirectory(opensubdiv)
-if (NOT NO_REGRESSION AND NOT ANDROID AND NOT IOS) # XXXdyu
+if (NOT ANDROID AND NOT IOS) # XXXdyu
add_subdirectory(regression)
endif()
@@ -678,8 +682,8 @@ if (NOT NO_EXAMPLES)
add_subdirectory(examples)
endif()
-if (NOT NO_PYTHON)
- add_subdirectory(python)
+if (NOT NO_TUTORIALS)
+ add_subdirectory(tutorials)
endif()
if (NOT NO_DOC)
diff --git a/NOTICE.txt b/NOTICE.txt
index 2acf5afa..baec75f3 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -2,8 +2,9 @@
Copyright 2013 Pixar
All rights reserved.
- This product includes software developed at
- Pixar (http://www.pixar.com/).
- Autodesk, Inc. (http://www.autodesk.com/).
- Google, Inc. (http://www.google.com/).
- DigitalFish (http://digitalfish.com/).
+ This product includes software developed at:
+ Pixar (http://www.pixar.com/).
+ Dreamworks Animation (http://www.dreamworksanimation.com/)
+ Autodesk, Inc. (http://www.autodesk.com/).
+ Google, Inc. (http://www.google.com/).
+ DigitalFish (http://digitalfish.com/).
diff --git a/README.md b/README.md
index fb2178e3..761b3523 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,11 @@ Feel free to use it and let us know what you think.
For more details about OpenSubdiv, see [Pixar Graphics Technologies](http://graphics.pixar.com).
+# 3.0 ALPHA Release
+
+The OpenSubdiv 3.0 release is still early in its development cycle. As such, all APIs, code examples and documentation are subject to change at any time, without notice or backward compatibility with existing code. Please consult the [release notes](http://graphics.pixar.com/opensubdiv/docs_3x_alpha/intro.html) for more details about the features and improvements contained in this new release.
+
+The 3.0 Beta release is tentatively scheduled for late Q4 2014.
## Git Flow
@@ -31,6 +36,7 @@ Required:
Optional:
* [GLEW](http://sourceforge.net/projects/glew/) (Windows/Linux only)
* [CUDA](http://developer.nvidia.com/category/zone/cuda-zone)
+* [TBB] (https://www.threadingbuildingblocks.org/)
* [OpenCL](http://www.khronos.org/opencl/)
* [GLFW](http://www.glfw.org/)
* [Ptex](https://github.com/wdas/ptex)
@@ -56,16 +62,17 @@ Optional:
-DNO_LIB=1 // disable the opensubdiv libs build (caveat emptor)
-DNO_EXAMPLES=1 // disable examples build
+-DNO_TUTORIALS=1 // disable tutorials build
-DNO_REGRESSION=1 // disable regression tests build
--DNO_PYTHON=1 // disable Python SWIG build
-DNO_MAYA=1 // disable Maya plugin build
-DNO_PTEX=1 // disable PTex support
-DNO_DOC=1 // disable documentation build
-DNO_OMP=1 // disable OpenMP
+-DNO_TBB=1 // disable TBB
-DNO_CUDA=1 // disable CUDA
-DNO_OPENCL=1 // disable OpenCL
+-DNO_OPENGL=1 // disable OpenGL
-DNO_CLEW=1 // disable CLEW wrapper library
--DNO_GCD=1 // disable GrandCentralDispatch on OSX
````
The paths to Maya, Ptex, GLFW, and GLEW can also be specified through the
diff --git a/cmake/FindGLEW.cmake b/cmake/FindGLEW.cmake
index ab138542..222379e8 100644
--- a/cmake/FindGLEW.cmake
+++ b/cmake/FindGLEW.cmake
@@ -33,7 +33,8 @@
include(FindPackageHandleStandardArgs)
if (WIN32)
- find_path( GLEW_INCLUDE_DIR
+
+ find_path(GLEW_INCLUDE_DIR
NAMES
GL/glew.h
PATHS
@@ -41,9 +42,15 @@ if (WIN32)
"$ENV{GLEW_LOCATION}/include"
"$ENV{PROGRAMFILES}/GLEW/include"
"${PROJECT_SOURCE_DIR}/extern/glew/include"
- DOC "The directory where GL/glew.h resides" )
+ DOC "The directory where GL/glew.h resides" )
- find_library( GLEW_LIBRARY
+ if ("${CMAKE_GENERATOR}" MATCHES "[Ww]in64")
+ set(ARCH x64)
+ else()
+ set(ARCH x86)
+ endif()
+
+ find_library(GLEW_LIBRARY
NAMES
glew GLEW glew32s glew32
PATHS
@@ -52,7 +59,9 @@ if (WIN32)
"$ENV{PROGRAMFILES}/GLEW/lib"
"${PROJECT_SOURCE_DIR}/extern/glew/bin"
"${PROJECT_SOURCE_DIR}/extern/glew/lib"
- DOC "The GLEW library")
+ PATH_SUFFIXES
+ Release/${ARCH}
+ DOC "The GLEW library")
endif ()
if (${CMAKE_HOST_UNIX})
diff --git a/cmake/FindMaya.cmake b/cmake/FindMaya.cmake
index 203e05e0..d4027c72 100644
--- a/cmake/FindMaya.cmake
+++ b/cmake/FindMaya.cmake
@@ -56,6 +56,7 @@ if(APPLE)
HINTS
"${MAYA_LOCATION}"
"$ENV{MAYA_LOCATION}"
+ "/Applications/Autodesk/maya2015/Maya.app/Contents"
"/Applications/Autodesk/maya2014/Maya.app/Contents"
"/Applications/Autodesk/maya2013.5/Maya.app/Contents"
"/Applications/Autodesk/maya2013/Maya.app/Contents"
@@ -82,6 +83,8 @@ if(UNIX)
HINTS
"${MAYA_LOCATION}"
"$ENV{MAYA_LOCATION}"
+ "/usr/autodesk/maya2015-x64"
+ "/usr/autodesk/maya2014-x64"
"/usr/autodesk/maya2013-x64"
"/usr/autodesk/maya2012.17-x64"
"/usr/autodesk/maya2012-x64"
@@ -107,6 +110,10 @@ if(WIN32)
HINTS
"${MAYA_LOCATION}"
"$ENV{MAYA_LOCATION}"
+ "C:/Program Files/Autodesk/Maya2015.5-x64"
+ "C:/Program Files/Autodesk/Maya2015.5"
+ "C:/Program Files/Autodesk/Maya2014.5-x64"
+ "C:/Program Files/Autodesk/Maya2014.5"
"C:/Program Files/Autodesk/Maya2013.5-x64"
"C:/Program Files/Autodesk/Maya2013.5"
"C:/Program Files (x86)/Autodesk/Maya2013.5"
diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt
index 77de4808..8afd97b7 100644
--- a/documentation/CMakeLists.txt
+++ b/documentation/CMakeLists.txt
@@ -30,20 +30,20 @@ if (DOXYGEN_FOUND)
add_custom_target(doc_doxy
${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/OpenSubdiv.doxy"
- WORKING_DIRECTORY
+ WORKING_DIRECTORY
"${CMAKE_BINARY_DIR}/public_headers/"
DEPENDS
public_headers
- COMMENT
+ COMMENT
"Generating API documentation with Doxygen" VERBATIM
)
list(APPEND DOC_TARGETS doc_doxy)
- install(
+ install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/doxy_html"
- DESTINATION
+ DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
@@ -54,6 +54,7 @@ else()
endif()
+find_package(PythonInterp 2.6)
# ReST - HTML documentation
if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
@@ -62,33 +63,54 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
search.html
)
- set(RST_FILES
+ set(RST_FILES
additional_resources.rst
api_overview.rst
cmake_build.rst
code_examples.rst
dxviewer.rst
+ dxptexviewer.rst
far_overview.rst
getting_started.rst
- glviewer.rst
+ glevallimit.rst
+ glfvarviewer.rst
+ glpainttest.rst
+ glptexviewer.rst
+ glsharetopology.rst
glstencilviewer.rst
- glbatchviewer.rst
+ glviewer.rst
hbr_overview.rst
- intro.rst
- limiteval.rst
+ intro.rst
maya_osdpolysmooth.rst
osd_overview.rst
- painttest.rst
- ptexviewer.rst
- release_notes.rst
- subdivision_surfaces.rst
+ release_notes.rst
+ release_notes_2x.rst
+ sdc_overview.rst
+ subdivision_surfaces.rst
+ tutorials.rst
using_osd.rst
using_osd_compile.rst
using_osd_hbr.rst
using_osd_textures.rst
- uvviewer.rst
+ vtr_overview.rst
)
+
+ # Configure release number in RST template file
+
+ # Replace '_' with '.'
+ string(REGEX REPLACE "(_)" "." RELEASE_STRING ${OpenSubdiv_VERSION})
+
+ # Remove starting 'v' character
+ string(REGEX REPLACE "^v" "" RELEASE_STRING ${RELEASE_STRING})
+
+ # Format API version string
+ set(RELEASE_STRING "Release ${RELEASE_STRING}")
+
+ # Replace string in navigation bar
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rst_template.txt"
+ "${CMAKE_CURRENT_BINARY_DIR}/rst_template.txt" )
+
# process rst markup files
foreach(src ${RST_FILES})
get_filename_component(BASENAME ${src} NAME_WE)
@@ -97,17 +119,17 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${BASENAME}.html")
add_custom_command(
- OUTPUT
+ OUTPUT
"${outfile}"
- COMMAND
+ COMMAND
"${RST2HTML_EXECUTABLE}"
- ARGS
+ ARGS
--date
--time
- --no-xml-declaration
+ --no-xml-declaration
--initial-header-level=3
--strip-comments
- --template="${CMAKE_CURRENT_SOURCE_DIR}/rst_template.txt"
+ --template="${CMAKE_CURRENT_BINARY_DIR}/rst_template.txt"
--stylesheet=css/rst.css
--link-stylesheet
"${infile}" "${outfile}"
@@ -119,13 +141,13 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
list(APPEND RST_TARGETS ${src})
- install(
+ install(
FILES
"${outfile}"
- DESTINATION
+ DESTINATION
"${CMAKE_DOCDIR_BASE}"
- PERMISSIONS
- OWNER_READ GROUP_READ WORLD_READ
+ PERMISSIONS
+ OWNER_READ GROUP_READ WORLD_READ
)
endforeach()
@@ -148,15 +170,15 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
list(APPEND HTML_TARGETS ${src})
- install(
+ install(
FILES
"${outfile}"
- DESTINATION
+ DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
endforeach()
- # copy the site resources to the build area so that the
+ # copy the site resources to the build area so that the
# documentation can be read without an install
add_custom_target(doc_html_images
COMMAND
@@ -180,41 +202,41 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
"${CMAKE_CURRENT_SOURCE_DIR}/processHtml.py"
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/nav_template.txt"
- DEPENDS
+ DEPENDS
${HTML_TARGETS}
${RST_TARGETS}
doc_tipuesearch
)
- add_custom_target(doc_html
- DEPENDS
- search_index
+ add_custom_target(doc_html
+ DEPENDS
+ search_index
${HTML_TARGETS}
${RST_TARGETS}
- doc_html_images
- doc_html_css
+ doc_html_images
+ doc_html_css
doc_tipuesearch
)
- install(
+ install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/tipuesearch"
- DESTINATION
+ DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
- install(
+ install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/images"
- DESTINATION
+ DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
- install(
+ install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/css"
- DESTINATION
+ DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
diff --git a/documentation/additional_resources.rst b/documentation/additional_resources.rst
index 8b657004..fa668a46 100644
--- a/documentation/additional_resources.rst
+++ b/documentation/additional_resources.rst
@@ -31,9 +31,6 @@ Additional Resources
----
-Tutorials
-=========
-
Links
=====
@@ -46,8 +43,8 @@ Links
Videos
======
-**Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces (2012)**
-*******************************************************************************
+Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces (2012)
+***************************************************************************
.. raw:: html
@@ -55,8 +52,8 @@ Videos
-**Open Subdivision Technology Review (2012)**
-*********************************************
+Open Subdivision Technology Review (2012)
+*****************************************
.. raw:: html
@@ -66,8 +63,8 @@ Videos
First public demonstration of OpenSubdiv at Siggraph 2012.
-**Autodesk User Group At Anaheim (2013)**
-*****************************************
+Autodesk User Group At Anaheim (2013)
+*************************************
.. raw:: html
@@ -77,8 +74,8 @@ First public demonstration of OpenSubdiv at Siggraph 2012.
Bill Polson, Director of Industry Strategy at Pixar Animation Studios
-**Why Model with Subdivisions (2013)**
-**************************************
+Why Model with Subdivisions (2013)
+**********************************
.. raw:: html
@@ -88,8 +85,8 @@ Bill Polson, Director of Industry Strategy at Pixar Animation Studios
Ivo Kos, Modelling Technical Director at Pixar Animation Studios
-**Meet the Experts: The OpenSubdiv Project (2013)**
-***************************************************
+Meet the Experts: The OpenSubdiv Project (2013)
+***********************************************
.. raw:: html
diff --git a/documentation/api_overview.rst b/documentation/api_overview.rst
index f4c72aea..3aace0a4 100644
--- a/documentation/api_overview.rst
+++ b/documentation/api_overview.rst
@@ -33,7 +33,7 @@ API Overview
Architecture Overview
=====================
-Because the OpenSubdiv software is intended to run on a variete of computing
+Because the OpenSubdiv software is intended to run on a variety of computing
resources, the API architecture has to accomodate a fairly complex matrix of
interoperations. In order to achieve the requisite flexibility, the code structure
is both layered and modular.
@@ -53,57 +53,64 @@ processing costs of any given feature that is not used.
----
-Layers
-======
+API Layers
+==========
-From a top-down point of view, OpenSubdiv is comprised of 3 layers : **Hbr**,
-**Far** and **Osd**.
+From a top-down point of view, OpenSubdiv is comprised of several layers, some
+public, and some private.
-.. image:: images/api_layers.png
+Layers list in descending order:
-The color groupings indicate inter-layer functional dependencies:
+ * **Osd** (OpenSubdiv)
+ * **Far** (Feature Adaptive Representation)
+ * **Vtr** (Vectorized Topological Representation)
+ * **Sdc** (Subdivision Core)
- * Osd depends on Far, but not on Hbr
- * Far depends on Hbr
- * Hbr has no dependencies
+Client mesh data enters the API through the Far layer. Typically, results will
+be collected from the Osd layer. However, it is therefore possible to use
+functionality from Far without introducing any dependency on Osd.
-It is therefore possible to use functionality from Hbr without introducing any
-dependency on either Far or Osd.
+Although there are several entry-points to provide topology and primitive variable
+data to OpenSubdiv, eventually everything must pass through the private Vtr and Sdc
+representations for topological analysis.
-----
+See `Using the Right Tools`_ for more in-depth coverage.
-Representation vs. Implementation Layers
-****************************************
-
-One of the core performance goals of our subdivision algorithms is to leverage
-interactive performance out of massively parallel code execution wherever
-possible. In order to support a large diversity of discrete compute devices through
-multiple dedicated SDKs, it is critical to distill the computations into the
-smallest and simplest kernels possible. These can in turn be safely ported and
-optimized for each of the hardware platforms.
-
-.. image:: images/api_representations.png
-
-This separation of general purpose against hardware-specific code is translated into
-two types of layers : the **implementation** layer against the **representation**
-layers.
-
-----
-
-Data Flows
-**********
-
-Data flows are mostly 1-directional, from top to bottom as a number of algorithms
-are preparing the coarse mesh data to be refined and passing their results to
-the next element in the processing chain.
-
-.. image:: images/api_data_flow.png
+.. image:: images/api_layers_3_0.png
:align: center
----
+Representation vs. Implementation Layers
+========================================
+
+One of the core performance goals of our subdivision algorithms is to leverage
+interactive performance out of massively parallel code execution wherever
+possible. In order to support a large diversity of compute architectures
+it is critical to stream the geometric data to the compute kernels in the
+most optimal way.
+
+Data structures that are efficient for topology analysis during the pre-computation
+stage are not very good candidates for parallel processing. Our layered structure
+reflects this requirement: topology analysis and other pre-computation tasks are
+delegated to "representation" layers, while the actual execution of computations
+has been moved to an "implementation" layer.
+
+.. image:: images/api_representations.png
+
+**Representation** layers are for general purpose algorithms and differenciated by
+the requirements placed on data represenation. See `Multiple Representations`_ for
+more details.
+
+The **Implementation** layer contains hardware and API-specific implementations.
+In order to minimize code redundancy and bugs, we strive to reduce device-specific
+computation logic to the most simplistic expression possible (in many cases as
+simple as series of multiply-ads).
+
+----
+
Multiple Representations
-************************
+========================
The coarse mesh of a subdivision surface is represented by a collection of
components that maintain relationships to each other.
@@ -126,14 +133,14 @@ the very description of these connections (dependencies) between vertices.
:align: center
This is why OpenSubdiv provides specific representations for mesh data:
- - Hbr is a half-edge relational representation
- - Far is a serialized representation
+ - Vtr is a vectorized topology-only representation
+ - Far is a feature adaptive serialized representation
A typical workflow would be to manipulate the topology in authoring applications,
-maybe using Hbr meshes for common editing operations. Once the topology of the mesh
-has stabilized, it is processed into a serialized form that can then be evaluated
-at interactive framerates. The serialized form is embodied by Far, which can then
-be migrated by the device-specific functions in Osd.
+maybe using Hbr or a similar relational representation for common editing operations.
+Once the topology of the mesh has stabilized, it is processed into a serialized form
+that can then be evaluated at interactive framerates. The serialized form is
+embodied by Far, which can then be migrated by device-specific functions in Osd.
.. image:: images/api_workflows.png
:align: center
@@ -153,10 +160,56 @@ architecture:
.. image:: images/osd_layers.png
-Hbr serves both as an advanced topological description and the custodian of the
-Catmull-Clark (and Loop) subdivision rules. Far is then used to leverage these
-rules in order to produce serialized topological tables.
+Vtr serves both as a private, efficient, intermediate topological description and
+as the custodian of the Catmull-Clark (and Loop) subdivision rules. Far is used to
+leverage these rules in order to produce serialized topological tables.
The remaining computations have been reduced to extremely simple forms of
interpolation, which can be dispatched to a variety of discrete computation
platforms.
+
+----
+
+Using the Right Tools
+=====================
+
+OpenSubdiv's tiered interface offers a lot flexibility to make your application
+both fast and robust. Because navigating through the large collection of classes and
+features can be challenging, here is a flow-chart that should help sketch
+the broad lines of going about using subdivisions in your application.
+
+General client application requirements:
+
++----------------------+-------------------------------------------------------+
+| Surface Limit | For some applications, a polygonal approximation of |
+| | the smooth surface is enough. Others require |
+| | C :sup:`2` continuous differentiable bi-cubic patches |
+| | (ex: deformable displacement mapping, smooth normals |
+| | and semi-sharp creases...) |
++----------------------+-------------------------------------------------------+
+| Deforming Surface | Applications such as off-line image renderers often |
+| | process a single frame at a time. Others, such as |
+| | interactive games need to evaluate deforming |
+| | character surface every frame. Because we can amortize|
+| | many computations if the topology of the mesh does not|
+| | change, OpenSubdiv provides 'stencil tables' in order |
+| | to leverage subdivision refinement into a |
+| | pre-computation step. |
++----------------------+-------------------------------------------------------+
+| Multi-threading | OpenSubdiv also provides dedicated interfaces to |
+| | leverage parallelism on a wide variety of platforms |
+| | and API standards, including both CPUs and GPUs. |
++----------------------+-------------------------------------------------------+
+| GPU Draw | If the application requires interactive drawing on |
+| | screen, OpenSubdiv provides several back-end |
+| | implementations, including D3D11 and OpenGL. These |
+| | back-ends provide full support for programmable |
+| | shading. |
++----------------------+-------------------------------------------------------+
+
+Flow-chart:
+
+.. image:: images/osd_flow.png
+ :align: center
+ :target: images/osd_flow.png
+
diff --git a/documentation/cmake_build.rst b/documentation/cmake_build.rst
index 619a4194..dc511708 100644
--- a/documentation/cmake_build.rst
+++ b/documentation/cmake_build.rst
@@ -1,26 +1,26 @@
-..
+..
Copyright 2013 Pixar
-
+
Licensed under the Apache License, Version 2.0 (the "Apache License")
with the following modification; you may not use this file except in
compliance with the Apache License and the following modification to it:
Section 6. Trademarks. is deleted and replaced with:
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor
and its affiliates, except as required to comply with Section 4(c) of
the License and to reproduce the content of the NOTICE file.
-
+
You may obtain a copy of the Apache License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the Apache License with the above modification is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Apache License for the specific
language governing permissions and limitations under the Apache License.
-
+
Building with Cmake
-------------------
@@ -37,28 +37,29 @@ Information on how to build OpenSubdiv
Overview
========
-Assuming that you have `cloned `__ the source repository
+Assuming that you have `cloned `__ the source repository
and selected an appropriate release branch, the following instructions will
walk you through the Cmake and configuration and build process.
Cmake is a cross-platform, open-source build system. Cmake controls the compilation
-process using platform independent configuration files in order to generate
+process using platform independent configuration files in order to generate
makefiles and workspaces that are native to the platform of choice.
The process involves the following steps:
- 1. Locate & build the requisite dependencies
- 2. Configure & run CMake to generate Makefiles / MSVC solution / XCode project
- 3. Run the build from make / MSVC / XCode
+
+ #. Locate & build the requisite dependencies
+ #. Configure & run CMake to generate Makefiles / MSVC solution / XCode project
+ #. Run the build from make / MSVC / XCode
----
Step 1: Dependencies
====================
-Cmake will adapt the build based on which dependencies have been successfully
+Cmake will adapt the build based on which dependencies have been successfully
discovered and will disable certain features and code examples accordingly.
-Please refer to the documentation of each of the dependency packages for specific
+Please refer to the documentation of each of the dependency packages for specific
build and installation instructions.
Required
@@ -105,7 +106,7 @@ The following configuration arguments can be passed to the cmake command line.
-DCMAKE_INSTALL_PREFIX=[base path to install OpenSubdiv (default: Current directory)]
-DCMAKE_LIBDIR_BASE=[library directory basename (default: lib)]
-
+
-DCUDA_TOOLKIT_ROOT_DIR=[path to CUDA]
-DPTEX_LOCATION=[path to Ptex]
-DGLEW_LOCATION=[path to GLEW]
@@ -113,11 +114,11 @@ The following configuration arguments can be passed to the cmake command line.
-DMAYA_LOCATION=[path to Maya]
-DTBB_LOCATION=[path to Intel's TBB]
-DICC_LOCATION=[path to Intel's C++ Studio XE]
-
+
-DNO_LIB=1 // disable the opensubdiv libs build (caveat emptor)
-DNO_EXAMPLES=1 // disable examples build
+ -DNO_TUTORIALS=1 // disable tutorials build
-DNO_REGRESSION=1 // disable regression tests build
- -DNO_PYTHON=1 // disable Python SWIG build
-DNO_MAYA=1 // disable Maya plugin build
-DNO_PTEX=1 // disable PTex support
-DNO_DOC=1 // disable documentation build
@@ -125,22 +126,19 @@ The following configuration arguments can be passed to the cmake command line.
-DNO_TBB=1 // disable TBB
-DNO_CUDA=1 // disable CUDA
-DNO_OPENCL=1 // disable OpenCL
+ -DNO_OPENGL=1 // disable OpenGL
-DNO_CLEW=1 // disable CLEW wrapper library
- -DNO_GCD=1 // disable GrandCentralDispatch on OSX
Environment Variables
_____________________
-The paths to Maya, Ptex, GLFW, and GLEW can also be specified through the
-following environment variables:
+The paths to Maya, Ptex, GLFW, GLEW and other dependencies can also be specified
+through the following environment variables:
.. code:: c++
- MAYA_LOCATION
- PTEX_LOCATION
- GLFW_LOCATION
- GLEW_LOCATION
-
+ MAYA_LOCATION, PTEX_LOCATION, GLFW_LOCATION, GLEW_LOCATION
+
Automated Script
________________
@@ -159,7 +157,7 @@ time. Here is a typical workflow:
Where *cmake_setup* is a configuration script.
-Here is an example CMake configuration script for a full typical windows-based
+Here is an example CMake configuration script for a full typical windows-based
build that can be run in GitShell :
.. code:: c++
@@ -184,12 +182,12 @@ build that can be run in GitShell :
\cp -f c:/Users/opensubdiv/demo/src/zlib-1.2.7/contrib/vstudio/vc10/x64/ZlibDllRelease/zlibwapi.dll bin/Release/
\cp -f c:/Users/opensubdiv/demo/src/ptex/x64/lib/Ptex.dll bin/Debug/
\cp -f c:/Users/opensubdiv/demo/src/ptex/x64/lib/Ptex.dll bin/Release/
-
+
.. container:: impnotip
* **Important**
- Notice that the following scripts start by **recursively removing** the *../build/* and
+ Notice that the following scripts start by **recursively removing** the *../build/* and
*../inst/* directories. Make sure you modify them to suit your build workflow.
Here is a similar script for \*Nix-based platforms:
@@ -224,7 +222,7 @@ Here is a similar script for OSX:
Using Intel's C++ Studio XE
___________________________
-OpenSubdiv can be also be built with `Intel's C++ compiler `__
+OpenSubdiv can be also be built with `Intel's C++ compiler `__
(icc). The default compiler can be overriden in CMake with the following configuration options:
.. code:: c++
@@ -263,14 +261,14 @@ CMake provides a cross-platform command-line build:
Alternatively, you can native toolkits to launch the build. The steps differ for each OS:
- * *Windows* :
+ * *Windows* :
launch VC++ with the solution generated by cmake in your build directory.
- * *OSX* :
+ * *OSX* :
run *make* in the build directory
- * *\*Nix* :
- | run *make* in your build directory
+ * *\*Nix* :
+ | run *make* in your build directory
| - use the *clean* target to remove previous build results
| - use *VERBOSE=1* for verbose build output
@@ -279,10 +277,10 @@ Alternatively, you can native toolkits to launch the build. The steps differ for
**Note**
We recommend against using CMake's Xcode project generator (-G "Xcode") on OSX, as it seems to
generate some dependencies incorrectly. We recommend instead reverting to Makefiles on OSX, and
- launching *make*, instead of *xcodebuild* to execute the build (make sure to install the command
+ launching *make*, instead of *xcodebuild* to execute the build (make sure to install the command
line tools in Xcode)
-
+
----
Build Targets
@@ -290,7 +288,7 @@ _____________
Makefile-based builds allow the use of named target. Here are some of the more
useful target names:
-
+
*osd_\_\*
| The core components of the OpenSubdiv libraries
|
@@ -298,7 +296,7 @@ useful target names:
*\*
| Builds specific code examples by name (glViewer, ptexViewer...)
|
-
+
*doc*
| Builds ReST and doxygen documentation
|
diff --git a/documentation/code_examples.rst b/documentation/code_examples.rst
index fb1f39cb..19004105 100644
--- a/documentation/code_examples.rst
+++ b/documentation/code_examples.rst
@@ -38,39 +38,26 @@ of the software.
:widths: 50 50
* - | `glViewer `_
- | `glBatchViewer `_
- | `glStencilViewer `_
- - | `limitEval `_
- | `paintTest `_
- | `ptexViewer `_
- | `uvViewer `_
+ | `glPtexViewer `_
+ | `glEvalLimit `_
+ - | `glStencilViewer `_
+ | `glPaintTest `_
+ | `glShareTopology `_
+ | `glFVarViewer `_
.. list-table:: **DirectX examples**
:class: quickref
:widths: 50 50
* - | `dxViewer `_
- - |
+ - | `dxPtexViewer `_
.. list-table:: **Plugin examples**
:class: quickref
- :widths: 50 50
+ :widths: 50
* - | `osdPolySmooth `_
- | `mayaViewer `_
- - | `mayaPtexViewer `_
-|
-
-.. container:: notebox
-
- **Note:**
- the mayaViewer and mayaPtexViewer plugins are currently unsupported and they
- may fail to compile or work with current versions of OpenSubdiv. These were
- originally written for the sole purpose of live demonstrations and the code
- is provided only as an implementation example.
-
-|
----
diff --git a/documentation/css/flavor.css b/documentation/css/flavor.css
index bfe41f86..fa7b220b 100644
--- a/documentation/css/flavor.css
+++ b/documentation/css/flavor.css
@@ -1,149 +1,155 @@
-/*
+/*
Copyright 2013 Pixar
-
+
Licensed under the Apache License, Version 2.0 (the "Apache License")
with the following modification; you may not use this file except in
compliance with the Apache License and the following modification to it:
Section 6. Trademarks. is deleted and replaced with:
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor
and its affiliates, except as required to comply with Section 4(c) of
the License and to reproduce the content of the NOTICE file.
-
+
You may obtain a copy of the Apache License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the Apache License with the above modification is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Apache License for the specific
language governing permissions and limitations under the Apache License.
-*/
+*/
/* Basic Styles
________________________*/
body {
- background: #000 url("../images/studio-tools.png") no-repeat;
+ background: #000 url("../images/studio-tools.png") no-repeat;
}
a {
- color: #FFCC03;
+ color: #FFCC03;
}
a:visited {
}
a:hover {
- color: #fff;
+ color: #fff;
}
a:active {
- color: #FFCC03;
+ color: #FFCC03;
}
.center {
- width: 944px;
- margin:0 auto;
- display:block!important;
+ width: 944px;
+ margin:0 auto;
+ display:block!important;
}
.noBullets {
- list-style-type:none;
+ list-style-type:none;
}
.center ul li {
- list-style-type: none;
- padding-left: 15px;
+ list-style-type: none;
+ padding-left: 15px;
}
ol {
- margin: 0 0 0 28px;
- padding: 0;
- background:none;
+ margin: 0 0 0 28px;
+ padding: 0;
+ background:none;
}
ol li {
- list-style-type: decimal-leading-zero;
- font-weight: bold;
- font-size: 14px!important;
- color: #CCC!important;
+ list-style-type: decimal;
+ font-weight: bold;
+ font-size: 14px!important;
+ color: #CCC!important;
}
ol li h3 {
- font-size:20px!important;
- color: #ccc!important;
+ font-size:20px!important;
+ color: #ccc!important;
}
ol li p {
- font-size: 13px!important;
- font-weight:normal!important;
- color: #999!important;
+ font-size: 13px!important;
+ font-weight:normal!important;
+ color: #999!important;
}
p.fine-print {
- font-size: 9px!important;
+ font-size: 9px!important;
}
.noBullets {
- list-style-type:none;
+ list-style-type:none;
}
#mainContentContainer {
- width: 944px;
- padding-bottom: 20px;
- margin: 10px 0 0px;
- border: 1px solid #666;
- border-radius : 7px;
- -moz-border-radius : 7px;
- -webkit-border-radius: 7px;
- color: #CCCCCC;
- background-color: #2C2C2C;
- float:left;
- position:relative;
+ width: 944px;
+ padding-bottom: 20px;
+ margin: 10px 0 0px;
+ border: 1px solid #666;
+ border-radius : 7px;
+ -moz-border-radius : 7px;
+ -webkit-border-radius: 7px;
+ color: #CCCCCC;
+ background-color: #2C2C2C;
+ float:left;
+ position:relative;
}
.marginL0 {
- margin-left:0!important;
+ margin-left:0!important;
}
.paddingL0 {
- padding-left:0!important
+ padding-left:0!important
}
#mainFooterContainer {
- width: 944px;
- margin: 0 auto 0;
- color: #CCCCCC;
+ width: 944px;
+ margin: 0 auto 0;
+ color: #CCCCCC;
}
h2.title {
- margin-bottom: 10px;
- color: #CCC;
- line-height: 26px;
- margin-top: 20px;
+ margin-bottom: 10px;
+ color: #CCC;
+ line-height: 26px;
+ margin-top: 20px;
}
h1.title {
- float: left;
- padding-left: 25px;
- padding-right: 25px;
+ float: left;
+ padding-left: 25px;
+ padding-right: 25px;
}
.floatLeft {
- float:left!important;
+ float:left!important;
}
h1.title, h1 {
- margin: 20px 0 10px;
+ margin: 20px 0 10px;
}
#mainContentContainer h1, #mainContentContainer h2, #mainContentContainer h3, #mainContentContainer h4, #mainContentContainer h5, #mainFooterContainer h1, #mainFooterContainer h2, #mainFooterContainer h3, #mainFooterContainer h4, #mainFooterContainer h5 {
- font-weight:lighter;
+ font-weight:lighter;
}
#mainContentContainer h1, #mainFooterContainer h1 {
- font-size: 38px;
- line-height: 35px;
- margin-bottom:10px;
+ font-size: 38px;
+ line-height: 35px;
+ margin-bottom:10px;
}
#mainContentContainer h2, #mainFooterContainer h2 {
- font-size: 26px;
- margin-bottom:5px;
+ font-size: 26px;
+ margin-bottom:5px;
}
#mainContentContainer h3, #mainFooterContainer h3 {
- font-size:20px;
- clear: left;
- line-height: 23px;
- margin-bottom:0;
+ font-size:20px;
+ font-weight:bold;
+ clear: left;
+ line-height: 23px;
+ margin-bottom:0;
}
-#mainFooterContainer h4 {
- margin: 10px 0 5px;
+#mainContentContainer h4, #mainFooterContainer h4 {
+ font-size:18px;
+ margin: 10px 15px 5px;
+}
+#mainContentContainer h5, #mainFooterContainer h5 {
+ font-size:16px;
+ margin: 10px 15px 5px;
}
ul.creatorFooterNav li {
- background: none;
- display: inline-block;
- float: left;
- padding: 0;
- font-size: 16px;
+ background: none;
+ display: inline-block;
+ float: left;
+ padding: 0;
+ font-size: 16px;
}
/* Table Styles
@@ -151,352 +157,352 @@ ________________________*/
table {
}
table a {
- color:#00ccff
+ color:#00ccff
}
td {
}
#mainContentContainer p {
- color: #999999;
- font-size: 13px;
- line-height: 18px;
- margin-top: 5px;
- margin-right: 0;
- margin-bottom: 15px;
- margin-left: 15px;
+ color: #999999;
+ font-size: 13px;
+ line-height: 18px;
+ margin-top: 5px;
+ margin-right: 0;
+ margin-bottom: 15px;
+ margin-left: 15px;
}
#mainContentContainer li {
- color: #999;
- font-size: 12px;
- line-height:14px;
- margin: 5px 0;
+ color: #999;
+ font-size: 12px;
+ line-height:14px;
+ margin: 5px 0;
}
#mainFooterContainer p {
- color: #999;
- font-size: 12px;
- line-height: 16px;
- margin: 0 0 5px 0;
+ color: #999;
+ font-size: 12px;
+ line-height: 16px;
+ margin: 0 0 5px 0;
}
#mainFooterContainer a.readMore {
- font-size:12px;
+ font-size:12px;
}
ul.creatorFooterNav {
- float: left;
- margin: 0;
- border:none;
+ float: left;
+ margin: 0;
+ border:none;
}
ul.creatorFooterNav li a {
- color: #666666;
- text-decoration: none;
- margin-left:10px;
- float:left;
- padding: 20px 10px!important;
+ color: #666666;
+ text-decoration: none;
+ margin-left:10px;
+ float:left;
+ padding: 20px 10px!important;
}
ul.creatorFooterNav li a:hover, a h4:hover {
- color:#fff;
+ color:#fff;
}
ul.creatorFooterNav li.creatorMainNavActive a, ul.creatorFooterNav li a:active, a h4:active {
- color:#FFCC03;
+ color:#FFCC03;
}
.headerColor {
- background: none;
- border-bottom: medium none;
- color:#606060;
+ background: none;
+ border-bottom: medium none;
+ color:#606060;
}
a.logo {
- float: left;
- margin:-35px 0px 0px 20px;
- padding: 0px 0px 0px 0px;
+ float: left;
+ margin:-35px 0px 0px 20px;
+ padding: 0px 0px 0px 0px;
}
.featuredSynopsis h3 {
- color:#ccc;
- margin: 5px 0!important;
+ color:#ccc;
+ margin: 5px 0!important;
}
.featuredSynopsis a.targetUrl h3 {
- color:#ccc;
- margin: 5px 0!important;
+ color:#ccc;
+ margin: 5px 0!important;
}
.featuredSynopsis a.targetUrl h3:hover {
- color:#fff;
+ color:#fff;
}
.featuredSynopsis a.targetUrl h3:active {
- color:#FFCC03;
+ color:#FFCC03;
}
/*Pixar Align Styles
________________________*/
.paddingL0 {
- padding-left:0;
+ padding-left:0;
}
.paddingR0 {
- padding-right:0;
+ padding-right:0;
}
.padding20 {
- padding:20px;
+ padding:20px;
}
.padding15 {
- padding:15px;
+ padding:15px;
}
.paddingL25 {
- padding-left:25px!important;
+ padding-left:25px!important;
}
.paddingR25 {
- padding-right:25px!important;
+ padding-right:25px!important;
}
.paddingLR25 {
- padding-left:25px!important;
- padding-right:25px!important;
+ padding-left:25px!important;
+ padding-right:25px!important;
}
.paddingLR10 {
- padding-left:10px!important;
- padding-right:10px!important;
+ padding-left:10px!important;
+ padding-right:10px!important;
}
.paddingNone ul {
- padding-right:0!important;
- padding-left:0!important;
+ padding-right:0!important;
+ padding-left:0!important;
}
.paddingB50 {
- padding-bottom:50px;
+ padding-bottom:50px;
}
.width300 {
- width:300px!important;
+ width:300px!important;
}
.marginTB10 {
- margin-top:10px!important;
- margin-bottom:10px!important;
+ margin-top:10px!important;
+ margin-bottom:10px!important;
}
.marginTB0 {
- margin-top:0px!important;
- margin-bottom:0px!important;
+ margin-top:0px!important;
+ margin-bottom:0px!important;
}
.marginT10 {
- margin-top:10px;
+ margin-top:10px;
}
.marginT20 {
- margin-top:20px;
+ margin-top:20px;
}
.marginT15 {
- margin-top:15px;
+ margin-top:15px;
}
.marginT10 {
- margin-top:10px;
+ margin-top:10px;
}
.marginT5 {
- margin-top:5px;
+ margin-top:5px;
}
.marginL20 {
- margin-left:20px!important;
+ margin-left:20px!important;
}
.marginL100 {
- margin-top:100px;
+ margin-top:100px;
}
.setWidth {
- width:944px;
+ width:944px;
}
.setTextHeight {
- height:150px;
+ height:150px;
}
.setTextHeightCustom {
- height:328px;
+ height:328px;
}
.marginR10 {
- margin-right:10px;
+ margin-right:10px;
}
.marginR15 {
- margin-right:15px;
+ margin-right:15px;
}
.marginR20 {
- margin-right:20px;
+ margin-right:20px;
}
marginLR25 {
- margin-left:25px;
- margin-right:25px;
+ margin-left:25px;
+ margin-right:25px;
}
.marginL50 {
- margin-left:50px;
+ margin-left:50px;
}
.marginL125 {
- margin-left: 125px;
+ margin-left: 125px;
}
.marginT5 {
- margin-top: 5px;
+ margin-top: 5px;
}
.marginT75 {
- margin-top: 75px;
+ margin-top: 75px;
}
.marginT50 {
- margin-top: 50px;
+ margin-top: 50px;
}
.marginT52 {
- margin-top: 52px;
+ margin-top: 52px;
}
.marginT62 {
- margin-top: 62px;
+ margin-top: 62px;
}
.marginT60 {
- margin-top: 60px;
+ margin-top: 60px;
}
.marginT30 {
- margin-top: 30px;
+ margin-top: 30px;
}
.marginT40 {
- margin-top: 40px;
+ margin-top: 40px;
}
.marginB20 {
- margin-bottom: 20px!important;
+ margin-bottom: 20px!important;
}
.marginB40 {
- margin-bottom:40px;
+ margin-bottom:40px;
}
.padding10 {
- padding:10px;
+ padding:10px;
}
.marginT25 {
- margin-top:25px;
+ margin-top:25px;
}
.marginB0 {
- margin-bottom:0!important;
+ margin-bottom:0!important;
}
.paddingB0 {
- padding-bottom:0!important;
+ padding-bottom:0!important;
}
.buttonPaddingRegister {
- padding:20px 15px;
+ padding:20px 15px;
}
.height350 {
- height:350px;
+ height:350px;
}
.dateStamp {
- color: #00CCFF;
- font-size: 13px;
- font-style: normal;
- font-weight: normal;
- padding: 0;
+ color: #00CCFF;
+ font-size: 13px;
+ font-style: normal;
+ font-weight: normal;
+ padding: 0;
}
.featuredSynopsis .dateStamp {
- margin-top: 30px;
+ margin-top: 30px;
}
.copyrightText {
- position:absolute;
- right:10px;
- bottom:5px;
- color:#fff;
- font-size:10px;
- opacity:.5;
- text-align: right;
+ position:absolute;
+ right:10px;
+ bottom:5px;
+ color:#fff;
+ font-size:10px;
+ opacity:.5;
+ text-align: right;
}
/*Pixar Main Nav Styles
________________________*/
#mainSiteNavigation {
- float: left;
- padding: 7px 0 0;
- width: 944px;
- background: none;
- color: #CCCCCC;
- border-bottom: 1px solid #666666;
+ float: left;
+ padding: 7px 0 0;
+ width: 944px;
+ background: none;
+ color: #CCCCCC;
+ border-bottom: 1px solid #666666;
}
#mainSiteNavigation .creatorMainNav {
- margin: 4px 10px 10px 10px;
- padding: 0px;
+ margin: 4px 10px 10px 10px;
+ padding: 0px;
}
#mainSiteNavigation .creatorMainNav li {
- padding: 0px;
- margin: 8px 15px;
- background:none;
- font-size: 14px;
+ padding: 0px;
+ margin: 8px 15px;
+ background:none;
+ font-size: 14px;
}
#mainSiteNavigation .creatorMainNav li a {
- color: #9a9a9a;
- letter-spacing: 1px;
- text-decoration: none;
- font-size: 14px;
+ color: #9a9a9a;
+ letter-spacing: 1px;
+ text-decoration: none;
+ font-size: 14px;
}
#mainSiteNavigation .creatorMainNav li a:hover {
- color: #ffffff;
+ color: #ffffff;
}
#mainSiteNavigation .creatorMainNav li a:active {
- color: #FFCC03;
+ color: #FFCC03;
}
#mainSiteNavigation .creatorMainNav li.creatorMainNavActive a {
- color: #FFCC03;
+ color: #FFCC03;
}
a.readMore {
- font-size:14px;
- color:#666;
+ font-size:14px;
+ color:#666;
}
a.readMore:hover {
- color:#fff!important;
+ color:#fff!important;
}
a.readMore:active {
- color:#ffcc03!important
+ color:#ffcc03!important
}
/*Pixar Logo Styles
________________________*/
div.homeRenderManLink {
- float: left;
- height: 45px;
- margin: 0 0px 0 5px;
- width: 300px;
- color: #999;
- font-size: 32px;
- font-family: Futura, Arial, Helvetica, sans-serif;
- text-indent: 10px;
+ float: left;
+ height: 45px;
+ margin: 0 0px 0 5px;
+ width: 300px;
+ color: #999;
+ font-size: 32px;
+ font-family: Futura, Arial, Helvetica, sans-serif;
+ text-indent: 10px;
}
div.homeRenderManLinkWide {
- float: left;
- height: 45px;
- margin: 0 0px 0 5px;
- width: 900px;
- color: #999;
- font-size: 32px;
- font-family: Futura, Arial, Helvetica, sans-serif;
- text-indent: 10px;
+ float: left;
+ height: 45px;
+ margin: 0 0px 0 5px;
+ width: 900px;
+ color: #999;
+ font-size: 32px;
+ font-family: Futura, Arial, Helvetica, sans-serif;
+ text-indent: 10px;
}
div.homeRenderManLink a {
- color: #999;
+ color: #999;
}
div.homeRenderManLink a:hover {
- /*background-position:-178px 0;*/
+ /*background-position:-178px 0;*/
}
.blueButton {
- -moz-border-radius: 15px;
- -webkit-border-radius: 15px;
- border: 1px solid black;
- background: #F8C600;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+ border: 1px solid black;
+ background: #F8C600;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#204D79', endColorstr='#003260');
- background: -webkit-gradient(linear, left top, left bottom, from(#204D79), to(#003260));
- background: -moz-linear-gradient(bottom, #003260, #204D79);
- box-shadow: 0 1px 0px #3471aa inset;
- -webkit-box-shadow: 0 1px 0px #3471aa inset;
- -moz-box-shadow: 0 1px 0 #3471aa inset;
- color: #ccc!important;
- float: right;
- font-size: 11px;
- font-weight: bold;
- text-shadow: 0 1px 0 black;
- text-transform: uppercase;
- padding: 7px 0;
- width: 115px;
- text-align: center;
+ background: -webkit-gradient(linear, left top, left bottom, from(#204D79), to(#003260));
+ background: -moz-linear-gradient(bottom, #003260, #204D79);
+ box-shadow: 0 1px 0px #3471aa inset;
+ -webkit-box-shadow: 0 1px 0px #3471aa inset;
+ -moz-box-shadow: 0 1px 0 #3471aa inset;
+ color: #ccc!important;
+ float: right;
+ font-size: 11px;
+ font-weight: bold;
+ text-shadow: 0 1px 0 black;
+ text-transform: uppercase;
+ padding: 7px 0;
+ width: 115px;
+ text-align: center;
}
.blueButton:hover {
- color: #ccc!important;
- background: #f8c600;
+ color: #ccc!important;
+ background: #f8c600;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#275d8e', endColorstr='#003d72');
- background: -webkit-gradient(linear, left top, left bottom, from(#275d8e), to(#003d72));
- background: -moz-linear-gradient(bottom, #003d72, #275d8e);
- cursor:pointer;
+ background: -webkit-gradient(linear, left top, left bottom, from(#275d8e), to(#003d72));
+ background: -moz-linear-gradient(bottom, #003d72, #275d8e);
+ cursor:pointer;
}
.blueButton:active {
- color:#fff!important;
- background: #000;
+ color:#fff!important;
+ background: #000;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#002345', endColorstr='#204D79');
- background: -webkit-gradient(linear, left top, left bottom, from(#002345), to(#204D79));
- background: -moz-linear-gradient(bottom, #204D79, #002345);
- box-shadow: 0px 1px 0px #444;
- -webkit-box-shadow: 0px 1px 0px #444;
- -moz-box-shadow: 0px 1px 0px #444;
+ background: -webkit-gradient(linear, left top, left bottom, from(#002345), to(#204D79));
+ background: -moz-linear-gradient(bottom, #204D79, #002345);
+ box-shadow: 0px 1px 0px #444;
+ -webkit-box-shadow: 0px 1px 0px #444;
+ -moz-box-shadow: 0px 1px 0px #444;
}
@@ -504,264 +510,264 @@ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#002345', endC
________________________*/
#homeSlider {
- clear: left;
- float: left;
- height: 420px;
- margin-bottom: -21px;
+ clear: left;
+ float: left;
+ height: 420px;
+ margin-bottom: -21px;
}
#lofslidecontent-home .lof-slidecontent, #lofslidecontent-home .lof-slidecontent a {
- color:#FFF;
+ color:#FFF;
}
#lofslidecontent-home .lof-slidecontent {
- position:absolute;
- overflow:hidden;
+ position:absolute;
+ overflow:hidden;
}
#lofslidecontent-home .lof-main-outer {
- position:relative;
- height:100%;
- width:980px;
- z-index:3px;
- overflow:hidden;
+ position:relative;
+ height:100%;
+ width:980px;
+ z-index:3px;
+ overflow:hidden;
}
#lofslidecontent-home .lof-main-outer-small {
- position:relative;
- height:100%;
- width:980px;
- z-index:3px;
- overflow:hidden;
+ position:relative;
+ height:100%;
+ width:980px;
+ z-index:3px;
+ overflow:hidden;
}
#lofslidecontent-home ul.lof-main-wapper li {
- overflow:hidden;
- padding:0px;
- margin:1px;
- float:left;
- position:relative;
- height: 420px;
+ overflow:hidden;
+ padding:0px;
+ margin:1px;
+ float:left;
+ position:relative;
+ height: 420px;
}
#lofslidecontent-home ul.lof-main-wapper li img {
- padding:0;
+ padding:0;
}
#lofslidecontent-home .options {
- width: 300px;
- background: rgba(23, 23, 23, 0.75);
- border: 1px solid rgba(0, 0, 0, 0.25);
- padding: 10px;
- position: absolute;
- top: 20%;
- left: 20px;
- z-index: 9;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- -ms-border-radius: 10px;
- border-radius: 10px;
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
- -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
- -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
- -ms-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ width: 300px;
+ background: rgba(23, 23, 23, 0.75);
+ border: 1px solid rgba(0, 0, 0, 0.25);
+ padding: 10px;
+ position: absolute;
+ top: 20%;
+ left: 20px;
+ z-index: 9;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ -ms-border-radius: 10px;
+ border-radius: 10px;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ -ms-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
}
#lofslidecontent-home .options-banner {
- top: 0px;
- left: 0px;
- margin-top: 325px;
- height: 90px;
- width: 942px;
- background: #000;
- box-shadow: 0;
- -webkit-box-shadow: 0;
- border: 1px solid rgba(0, 0, 0, 0.25);
- padding: 10px;
- position: absolute;
- z-index: 9;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- -ms-border-radius: 10px;
- border-radius: 10px;
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
- -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
- -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
- -ms-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ top: 0px;
+ left: 0px;
+ margin-top: 325px;
+ height: 90px;
+ width: 942px;
+ background: #000;
+ box-shadow: 0;
+ -webkit-box-shadow: 0;
+ border: 1px solid rgba(0, 0, 0, 0.25);
+ padding: 10px;
+ position: absolute;
+ z-index: 9;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ -ms-border-radius: 10px;
+ border-radius: 10px;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
+ -ms-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.75);
}
.options-banner h2 {
- margin-left: 10px;
+ margin-left: 10px;
}
.options-banner p {
- margin-top: 10px!important;
- margin-left: 10px!important;
+ margin-top: 10px!important;
+ margin-left: 10px!important;
}
#lofslidecontent-home .copyright {
- font-size: 11px;
- font-weight:bold;
- color:#fff;
- bottom:5px;
- left:30px;
- z-index: 70;
- position: absolute;
+ font-size: 11px;
+ font-weight:bold;
+ color:#fff;
+ bottom:5px;
+ left:30px;
+ z-index: 70;
+ position: absolute;
}
#lofslidecontent-home ul.lof-main-wapper {
- overflow:hidden;
- padding:0px;
- margin:0;
- position:absolute;
- overflow:hidden;
+ overflow:hidden;
+ padding:0px;
+ margin:0;
+ position:absolute;
+ overflow:hidden;
}
#mainContent, .mainContent {
- float:left;
- width: 550px;
- padding-bottom: 20px;
+ float:left;
+ width: 550px;
+ padding-bottom: 20px;
}
#mainContent h3, .mainContent h3 {
- margin-top: 0;
+ margin-top: 0;
}
/*Pixar Press Section Styles
________________________*/
.copyrightFooter {
- color: #666;
- float: right;
- font-size: 11px;
- margin-right: 10px;
- margin-top: 25px;
+ color: #666;
+ float: right;
+ font-size: 11px;
+ margin-right: 10px;
+ margin-top: 25px;
}
div.articleSynopsis p {
- padding: 0px 25px;
- margin: 0 0 10px;
+ padding: 0px 25px;
+ margin: 0 0 10px;
}
h4.synopsis-head {
- font-size: 16px;
- font-weight: bold;
- line-height: 1.3em;
- margin: 10px 0 5px 3px;
+ font-size: 16px;
+ font-weight: bold;
+ line-height: 1.3em;
+ margin: 10px 0 5px 3px;
}
h1.articleContentTitle {
- font-size: 38px;
- float: left;
- font-weight: lighter;
- margin-top: 35px;
- padding: 0px 25px;
- width: 95%;
- line-height: 40px!important;
+ font-size: 38px;
+ float: left;
+ font-weight: lighter;
+ margin-top: 35px;
+ padding: 0px 25px;
+ width: 95%;
+ line-height: 40px!important;
}
h1.articleContentTitle a {
- float:left;
- margin-right: 5px;
- font-size:38px;
+ float:left;
+ margin-right: 5px;
+ font-size:38px;
}
h1.articleContentTitle span {
- float:left;
- font-size:38px;
+ float:left;
+ font-size:38px;
}
h2.articleContentTitle {
- font-size: 24px;
- float: left;
- font-weight: lighter;
- margin-top: 20px;
- padding: 0px 10px;
- width: 95%;
- line-height: 1.6em!important;
+ font-size: 24px;
+ float: left;
+ font-weight: lighter;
+ margin-top: 20px;
+ padding: 0px 10px;
+ width: 95%;
+ line-height: 1.6em!important;
}
h2.articleContentTitle a {
- float:left;
- margin-right: 5px;
- font-size:24px;
+ float:left;
+ margin-right: 5px;
+ font-size:24px;
}
h2.articleContentTitle span {
- float:left;
- font-size:24px;
+ float:left;
+ font-size:24px;
}
/*Pixar Footer Styles
________________________*/
#footerLeftEntriesForSection, #footerCenterEntriesForSection, #footerRightEntriesForSection {
- float: left;
- margin: 20px 0 25px 23px;
- width: 285px;
+ float: left;
+ margin: 20px 0 25px 23px;
+ width: 285px;
}
#footerLeftEntriesForSection h4, #footerCenterEntriesForSection h4, #footerRightEntriesForSection h4 {
- text-transform:uppercase;
+ text-transform:uppercase;
}
#footerLeftEntriesForSection ul, #footerCenterEntriesForSection ul, #footerRightEntriesForSection ul {
- float:left;
- display:inline-block;
- list-style-type:none;
- margin: 0;
- padding: 0;
+ float:left;
+ display:inline-block;
+ list-style-type:none;
+ margin: 0;
+ padding: 0;
}
#footerLeftEntriesForSection ul li, #footerCenterEntriesForSection ul li, #footerRightEntriesForSection ul li {
- float:left;
- margin: 0;
- padding: 0 0 10px 0;
- display:inline-block;
- list-style-type:none;
- background: none;
- width: 285px;
+ float:left;
+ margin: 0;
+ padding: 0 0 10px 0;
+ display:inline-block;
+ list-style-type:none;
+ background: none;
+ width: 285px;
}
.featuredSynopsis h3.title, h3.simpleLinkContainer {
- margin: 5px 0;
- padding:0;
+ margin: 5px 0;
+ padding:0;
}
.featuredSynopsis-schedule h3.title {
- margin-top: 20px;
- color: #e0e0e0;
+ margin-top: 20px;
+ color: #e0e0e0;
}
h3.title {
- color: 00CCFF;
+ color: 00CCFF;
}
/*Pixar Video Page Styles
________________________*/
.featuredSynopsis {
- float: left;
- margin: 0 0 0px;
+ float: left;
+ margin: 0 0 0px;
}
.featuredSynopsis-schedule {
- margin: 0 0 0px;
+ margin: 0 0 0px;
}
.borderTop {
- border-top:1px solid #666;
- margin-top: 20px;
- padding-top: 20px;
- margin-bottom: 0;
+ border-top:1px solid #666;
+ margin-top: 20px;
+ padding-top: 20px;
+ margin-bottom: 0;
}
.featuredSynopsisWide {
- float: left;
- width: 896px;
- margin: 0 0 20px;
- border-top: 1px solid #666666;
+ float: left;
+ width: 896px;
+ margin: 0 0 20px;
+ border-top: 1px solid #666666;
}
.featuredSynopsisWide .ogImage {
- float: right;
- margin-top: 30px;
- margin-left: 30px;
+ float: right;
+ margin-top: 30px;
+ margin-left: 30px;
}
th {
- text-align:left;
+ text-align:left;
}
/*Pixar Color Styles
________________________*/
.footerColor a {
- color: #cccccc;
+ color: #cccccc;
}
.footerColor {
background-color: #2C2C2C;
- margin: 20px 0 0 0;
- border: 1px solid #666;
- -moz-border-radius : 7px;
- -webkit-border-radius: 7px;
- height: 265px;
+ margin: 20px 0 0 0;
+ border: 1px solid #666;
+ -moz-border-radius : 7px;
+ -webkit-border-radius: 7px;
+ height: 265px;
}
hr {
- background-color: #666666;
- border: 0 none;
- clear: both;
- color: #666666;
- float: left;
- height: 1px;
- margin: 15px 25px 15px 25px;
- width: 894px;
+ background-color: #666666;
+ border: 0 none;
+ clear: both;
+ color: #666666;
+ float: left;
+ height: 1px;
+ margin: 15px 25px 15px 25px;
+ width: 894px;
}
@@ -770,175 +776,175 @@ ________________________*/
pre, code {
- border: 1px dashed #555555;
- background:#222;
- padding: 5px 10px;
- line-height: 21px;
- word-wrap:break-word;
- text-align: left;
- width: 96%;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
+ border: 1px dashed #555555;
+ background:#222;
+ padding: 5px 10px;
+ line-height: 21px;
+ word-wrap:break-word;
+ text-align: left;
+ width: 96%;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
}
.code-keyword {
- color:#036eff;
+ color:#036eff;
}
.code-quote {
- color:#13db03;
+ color:#13db03;
}
.code-object {
- color:#e403ff;
+ color:#e403ff;
}
.entranceList ul {
- padding:0 25px;
+ padding:0 25px;
}
.entranceList li {
- background: #222222;
- border: 1px solid #000000;
- -moz-box-shadow: 0 1px 0 #555555 inset;
- -webkit-box-shadow: 0 1px 0 #555555 inset;
- float: left;
- margin: 0px 15px 30px!important;
- position:relative;
- padding: 1px;
- width: 45%;
+ background: #222222;
+ border: 1px solid #000000;
+ -moz-box-shadow: 0 1px 0 #555555 inset;
+ -webkit-box-shadow: 0 1px 0 #555555 inset;
+ float: left;
+ margin: 0px 15px 30px!important;
+ position:relative;
+ padding: 1px;
+ width: 45%;
}
.entranceList li:hover {
- background:#333;
+ background:#333;
}
.entranceList li:hover h3 {
- color:#fff!important;
+ color:#fff!important;
}
.entranceList li h3 {
- clear:none!important;
+ clear:none!important;
}
.entranceList li:active h3 {
- color: #FFCC03!important;
+ color: #FFCC03!important;
}
.entranceList li img {
- height:100px;
- width:100px;
- border-right: 1px solid #000000;
- float:left;
+ height:100px;
+ width:100px;
+ border-right: 1px solid #000000;
+ float:left;
}
.entranceList li h3 {
- float: left;
- margin: 10px 0px 0 15px!important;
- width: 70%;
+ float: left;
+ margin: 10px 0px 0 15px!important;
+ width: 70%;
}
.entranceList li div.synopsis div.news-author p {
- float: left;
- line-height: 16px !important;
- margin: 5px 0 0 15px !important;
- width: 70%;
+ float: left;
+ line-height: 16px !important;
+ margin: 5px 0 0 15px !important;
+ width: 70%;
}
.entranceList li div.synopsis p {
- float: left!important;
+ float: left!important;
}
div.news-author {
- font-style:italic;
+ font-style:italic;
}
div.news-author:before {
- content: "-";
+ content: "-";
}
.entranceList li a.clickableDiv {
- height: 105px;
- left: 0;
- position: absolute;
- top: 0;
- width: 412px;
+ height: 105px;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 412px;
}
.entranceList ul li {
- background:#222!important;
- padding: 0;
+ background:#222!important;
+ padding: 0;
}
.hidden, .displayNone {
- display:none;
+ display:none;
}
.button {
- border: 1px solid black;
- background: #111;
+ border: 1px solid black;
+ background: #111;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#000000');
- background: -webkit-gradient(linear, left top, left bottom, from(#333333), to(#000));
- background: -moz-linear-gradient(bottom, #000, #333333);
- box-shadow: 0 1px 0px #666 inset;
- -webkit-box-shadow: 0 1px 0px #666 inset;
- -moz-box-shadow: 0 1px 0 #666 inset;
- color: #ccc;
- float:left;
- min-width:90px;
- font-size: 11px;
- font-weight: bold;
- text-shadow: 0 1px 0 black;
- text-transform: uppercase;
- padding: 10px;
- text-align: center;
+ background: -webkit-gradient(linear, left top, left bottom, from(#333333), to(#000));
+ background: -moz-linear-gradient(bottom, #000, #333333);
+ box-shadow: 0 1px 0px #666 inset;
+ -webkit-box-shadow: 0 1px 0px #666 inset;
+ -moz-box-shadow: 0 1px 0 #666 inset;
+ color: #ccc;
+ float:left;
+ min-width:90px;
+ font-size: 11px;
+ font-weight: bold;
+ text-shadow: 0 1px 0 black;
+ text-transform: uppercase;
+ padding: 10px;
+ text-align: center;
}
.blueButton {
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border: 1px solid black;
- background: #F8C600;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border: 1px solid black;
+ background: #F8C600;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#204D79', endColorstr='#003260');
- background: -webkit-gradient(linear, left top, left bottom, from(#204D79), to(#003260));
- background: -moz-linear-gradient(bottom, #003260, #204D79);
- box-shadow: 0 1px 0px #3471aa inset;
- -webkit-box-shadow: 0 1px 0px #3471aa inset;
- -moz-box-shadow: 0 1px 0 #3471aa inset;
- color: #ccc;
- float: right;
- font-size: 11px;
- font-weight: bold;
- text-shadow: 0 1px 0 black;
- text-transform: uppercase;
- padding: 7px 0;
- width: 115px;
- text-align: center;
+ background: -webkit-gradient(linear, left top, left bottom, from(#204D79), to(#003260));
+ background: -moz-linear-gradient(bottom, #003260, #204D79);
+ box-shadow: 0 1px 0px #3471aa inset;
+ -webkit-box-shadow: 0 1px 0px #3471aa inset;
+ -moz-box-shadow: 0 1px 0 #3471aa inset;
+ color: #ccc;
+ float: right;
+ font-size: 11px;
+ font-weight: bold;
+ text-shadow: 0 1px 0 black;
+ text-transform: uppercase;
+ padding: 7px 0;
+ width: 115px;
+ text-align: center;
}
.blueButton:hover {
- background: #f8c600; /* for non-css3 browsers */
+ background: #f8c600; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#275d8e', endColorstr='#003d72'); /* for IE */
- background: -webkit-gradient(linear, left top, left bottom, from(#275d8e), to(#003d72)); /* for webkit browsers */
- background: -moz-linear-gradient(bottom, #003d72, #275d8e); /* for firefox 3.6+ */
- cursor:pointer;
+ background: -webkit-gradient(linear, left top, left bottom, from(#275d8e), to(#003d72)); /* for webkit browsers */
+ background: -moz-linear-gradient(bottom, #003d72, #275d8e); /* for firefox 3.6+ */
+ cursor:pointer;
}
.blueButton:active {
- color:#fff;
- background: #000; /* for non-css3 browsers */
+ color:#fff;
+ background: #000; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#002345', endColorstr='#204D79'); /* for IE */
- background: -webkit-gradient(linear, left top, left bottom, from(#002345), to(#204D79)); /* for webkit browsers */
- background: -moz-linear-gradient(bottom, #204D79, #002345); /* for firefox 3.6+ */
- box-shadow: 0px 1px 0px #444;
- -webkit-box-shadow: 0px 1px 0px #444;
- -moz-box-shadow: 0px 1px 0px #444;
+ background: -webkit-gradient(linear, left top, left bottom, from(#002345), to(#204D79)); /* for webkit browsers */
+ background: -moz-linear-gradient(bottom, #204D79, #002345); /* for firefox 3.6+ */
+ box-shadow: 0px 1px 0px #444;
+ -webkit-box-shadow: 0px 1px 0px #444;
+ -moz-box-shadow: 0px 1px 0px #444;
}
.margin0 {
- margin:0;
+ margin:0;
}
.padding0 {
- padding:0;
+ padding:0;
}
.width944 {
- width:944px;
+ width:944px;
}
.width450 {
- width:450px;
+ width:450px;
}
.width475 {
- width:475px;
+ width:475px;
}
.width500 {
- width:500px;
+ width:500px;
}
.paddingLR20 {
- padding-left:20px;
- padding-right:20px;
+ padding-left:20px;
+ padding-right:20px;
}
.mediaTile td {
- border-bottom: 1px solid #222;
- border-top: 1px solid #333;
- margin: 0;
- padding: 15px 0 0;
+ border-bottom: 1px solid #222;
+ border-top: 1px solid #333;
+ margin: 0;
+ padding: 15px 0 0;
}
.clickableBox {
diff --git a/documentation/css/renderman-university.css b/documentation/css/renderman-university.css
index 7a87f95e..05b9ecf8 100644
--- a/documentation/css/renderman-university.css
+++ b/documentation/css/renderman-university.css
@@ -52,7 +52,7 @@
}
.coursewareBackground ul li {
padding-left: 6px!important;
- list-style-type:square!important;
+ list-style-type:disc!important;
}
.coursewareBackground h1, .coursewareBackground h2, .coursewareBackground h1 a, .coursewareBackground h2 a {
padding-bottom:10px;
diff --git a/documentation/css/rst.css b/documentation/css/rst.css
index fb978ed5..64e54f19 100644
--- a/documentation/css/rst.css
+++ b/documentation/css/rst.css
@@ -466,6 +466,10 @@ code {
font-weight: bold;
}
+div.quickLinks {
+ margin-left: 15px;
+}
+
div.navigation {
position:fixed;
width:245px;
@@ -482,6 +486,8 @@ div.navigation {
div.navigation ul {
list-style-image: url('../images/toggler0.gif');
+ margin-left: 0px;
+ padding-left: 20px;
}
div.navigation a:link,
diff --git a/documentation/diagrams.odg b/documentation/diagrams.odg
index 9f220735..6c305fc7 100644
Binary files a/documentation/diagrams.odg and b/documentation/diagrams.odg differ
diff --git a/documentation/dxptexviewer.rst b/documentation/dxptexviewer.rst
new file mode 100644
index 00000000..aebb644b
--- /dev/null
+++ b/documentation/dxptexviewer.rst
@@ -0,0 +1,117 @@
+..
+ Copyright 2013 Pixar
+
+ Licensed under the Apache License, Version 2.0 (the "Apache License")
+ with the following modification; you may not use this file except in
+ compliance with the Apache License and the following modification to it:
+ Section 6. Trademarks. is deleted and replaced with:
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor
+ and its affiliates, except as required to comply with Section 4(c) of
+ the License and to reproduce the content of the NOTICE file.
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the Apache License with the above modification is
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the Apache License for the specific
+ language governing permissions and limitations under the Apache License.
+
+
+dxPtexViewer
+------------
+
+.. contents::
+ :local:
+ :backlinks: none
+
+SYNOPSIS
+========
+
+.. parsed-literal::
+ :class: codefhead
+
+ **dxPtexViewer**
+ [**-e** *environment map*]
+ [**-d** *HDR diffuse map*]
+ [**-s** *HDR specular map*]
+ [**-y**]
+ [**--disp** *displacement scale*]
+ [**-l** *isolation level*]
+ *ptex color file*
+ *ptex displacement file*
+ *ptex occlusion file*
+ *ptex specular file*
+ *objfile(s)*
+
+DESCRIPTION
+===========
+
+``dxPtexViewer`` is a stand-alone application that showcases advanced HDR shading
+with color, displacement, occlusion and specular ptex maps. Multiple controls
+are available to experiment with the algorithms.
+
+.. include:: under_development.rst
+
+
+OPTIONS
+=======
+
+**-e** *environment map*
+ A low dynamic range spherical environment map used as a background. Ideally,
+ a color-normalized version of the HDR light probe.
+
+**-d** *HDR diffuse map*
+ An HDR file containing a diffuse environment map (typically they are low
+ resolution blurry hemispherical convolutions of the environment light probe).
+
+**-s** *environment map*
+ An HDR file containing a specular environment map.
+
+**--disp** *displacement scale*
+ A scalar multiplier for the shader displacement values.
+
+**-y**
+ Swap Z-up geometry to Y-UP.
+
+**-l** *isolation level*
+ Select the desired isolation level of adaptive feature isolation. This can be
+ useful when trying to load large pieces of geometry.
+
+*ptex color file*
+ A ptex file containing RGB channels read as material albedo color.
+
+*ptex displacement file*
+ A single-channel ptex file (preferrably float precision) containing the
+ displacement values.
+
+*ptex occlusion file*
+ A single-channel ptex file (preferrably 8 bits precision) containing a
+ pre-computed ambient occlusion signal.
+
+*ptex specular file*
+ A single-channel ptex file (preferrably 8 bits precision) applied to modulate
+ the specular reflectance of the material
+
+*objfile(s)*
+ A sequence of obj files used as an animation loop (the topology has to match
+ the data contained in all the ptex files !)
+
+
+Keyboard Controls
+=================
+
+ .. code:: c++
+
+ q : quit
+ esc : hide GUI
+ f : fit frame
+ +/- : increase / decrese tessellation rate
+
+
+
+.. include:: examples_see_also.rst
diff --git a/documentation/dxviewer.rst b/documentation/dxviewer.rst
index be06ae73..7542f5ea 100644
--- a/documentation/dxviewer.rst
+++ b/documentation/dxviewer.rst
@@ -44,12 +44,16 @@ DESCRIPTION
uniform and feature adaptive subdivision schemes to a collection of geometric
shapes. Multiple controls are available to experiment with the algorithms.
+.. image:: images/dxviewer.png
+ :width: 400px
+ :align: center
+ :target: images/dxviewer.png
.. container:: impnotip
* **Note:**
- dxViewer requires Microsoft's DirectX 11 SDK
+ dxViewer requires Microsoft's DirectX D3D11 SDK
OPTIONS
=======
@@ -62,16 +66,5 @@ OPTIONS
Number of repetitions of the animtion loop (default=0 is infinite)
-SEE ALSO
-========
-
-`Code Examples `__, \
-`glViewer `__, \
-`glBatchViewer `__, \
-`glStencilViewer `__, \
-`ptexViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
-`uvViewer `__, \
+.. include:: examples_see_also.rst
diff --git a/documentation/examples_see_also.rst b/documentation/examples_see_also.rst
new file mode 100644
index 00000000..d53a3624
--- /dev/null
+++ b/documentation/examples_see_also.rst
@@ -0,0 +1,14 @@
+SEE ALSO
+========
+
+Other `examples `__ \ :
+`glViewer `__, \
+`glShareTopology `__, \
+`glStencilViewer `__, \
+`glPtexViewer `__, \
+`glEvalLimit `__, \
+`glFVarViewer `__, \
+`dxViewer `__, \
+`dxPtexViewer `__, \
+`mayaPolySmooth `__, \
+
diff --git a/documentation/far_overview.rst b/documentation/far_overview.rst
index 867ceb88..df33b9fc 100644
--- a/documentation/far_overview.rst
+++ b/documentation/far_overview.rst
@@ -1,20 +1,20 @@
..
Copyright 2013 Pixar
-
+
Licensed under the Apache License, Version 2.0 (the "Apache License")
with the following modification; you may not use this file except in
compliance with the Apache License and the following modification to it:
Section 6. Trademarks. is deleted and replaced with:
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor
and its affiliates, except as required to comply with Section 4(c) of
the License and to reproduce the content of the NOTICE file.
-
+
You may obtain a copy of the Apache License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the Apache License with the above modification is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -29,39 +29,227 @@ FAR Overview
:local:
:backlinks: none
+.. image:: images/api_layers_3_0.png
+ :width: 100px
+ :target: images/api_layers_3_0.png
+
Feature Adaptive Representation (Far)
=====================================
-Far is a serialized topoloigcal data representation.Far uses hbr to create and
-cache fast run time data structures for table driven subdivision of vertices and
-cubic patches for limit surface evaluation. `Feature-adaptive `__
-refinement logic is used to adaptively refine coarse topology near features like
-extraordinary vertices and creases in order to make the topology amenable to
-cubic patch evaluation. Far is also a generic, templated algorithmic base API
-that clients in higher levels instantiate and use by providing an implementation
-of a vertex class. It supports these subdivision schemes:
+The *Far* API layer is the central interface that processes client-supplied
+geometry and turns it into a `serialized data representation
+`__ ready for parallel processing.
-Factories & Tables
+First, *Far* provides the tools to refine subidivision topology
+(`Far::TopologyRefiner <#far-topologyrefiner>`__). Topology refinement can be
+either uniform or sparse, where extraordinary features are automatically
+isolated (see `feature adaptive subdivision `__).
+
+As a geometry representation, *Far* also provides a set of *"Tables"* classes.
+These tables are designed to be static containers for the refined topology
+data, after it has been serialized and factorized. This represnetation is
+embodied in the `Far::PatchTables <#far-patchtables>`__ and the
+`Far::StencilTables <#far-patchtables>`__ classes.
+
+*Far* is also a fully featured API. Typically *Far* tabular data is targetted at
+*Osd*, where it can be processed by an implementation optimized for a specific
+hardware. However, for client-code that does not require a dedicated
+implementation, *Far* itself provides a fully-featured single-threaded
+implementation of subdivision interpolation algorithms, both discrete and at
+the limit.
+
+Refining Topology
+=================
+
+The *Far* topology classes present a public interface for the refinement
+functionality provided in *Vtr*, either directly within Far or indirectly
+eventually though *Osd*. The two main topology refinement classes are as
+follows:
+
++-------------------------------+---------------------------------------------------+
+| TopologyRefiner | A class encapsulating the topology of a refined |
+| | mesh. |
++-------------------------------+---------------------------------------------------+
+| TopologyRefinerFactory | A factory class template specialized by users (in |
+| | terms of their mesh class) to construct |
+| | TopologyRefiner as quickly as possible. |
++-------------------------------+---------------------------------------------------+
+
+These classes are the least well defined of the API, but given they provide the
+public interface to all of the improvements proposed, they potentially warrant
+the most attention. Far::TopologyRefiner is purely topological and it is the
+backbone used to construct or be associated with the other table classes in Far.
+
+.. container:: notebox
+
+ **Alpha Issues**
+
+ Interface issues needing attention:
+
+ * TopologyRefiner::Refine() needs more options (bundled in struct)
+ * TopologyRefiner::Interpolate() methods need revisiting
+ * considering simplifying TopologyRefiner interface overall -- may expose
+ TopologyLevel for public inspection
+ * specialization of TopologyRefinerFactory needs more work
+
+Far::TopologyRefiner
+********************
+
+TopologyRefiner is the building block for many other useful classes in
+OpenSubdiv, but its purpose is more specific. It is intended to store the
+topology of an arbitrarily refined subdivision hierarchy to support the
+construction of `stencil tables <#patch-tables>`__, `patch tables
+<#patch-tables>`__, etc.
+
+Aside from public access to topology, *TopologyRefiner::Refine(...)* is
+internally where simple specifications of refinement (currently uniform or
+feature-adaptive with a level argument) will be translated into refinement
+operations within Vtr. Feature-adaptive refinement is a special case of
+*"sparse"* or *"selective"* refinement, and so the feature-adaptive logic
+exists internal to TopologyRefiner and translates the feature-analysis into a
+simpler topological specification of refinement to Vtr.
+
+.. image:: images/topology_refiner.png
+ :align: center
+
+The longer term intent is that the public Refine(...) operation eventually be
+overloaded to allow clients more selective control of refinement. While
+TopologyRefiner is a purely topological class, and so free of any definitions
+of vertex data, the public inteface has been extended to include templated
+functors that allow clients to interpolate primitive variable data.
+
+Far::TopologyRefinerFactory
+***************************
+
+Consistent with other classes in Far instances of TopologyRefiner are created
+by a factory class -- in this case Far::TopologyRefinerFactory. This class
+is an important entry point for clients its task is to map/convert data in a
+client's mesh into the internal `Vtr `__ representation as
+quickly as possible.
+
+The TopologyRefinerFactory class is a class template parameterized by and
+specialized for the client's mesh class, i.e. TopologyRefinerFactory.
+Since a client' mesh representation knows best how to identify the topological
+neighborhoods required, no generic implementation would provide the most
+direct means of conversion possible, and so we rely on specialization. For
+situations where mesh data is not defined in a boundary representation, a
+simple container for raw mesh data is provided along with a Factory
+specialized to construct TopologyRefiners from it.
+
+So there are two ways to create TopologyRefiners:
+
+ * use the existing TopologyRefinerFactory with a
+ populated instance of TopologyDescriptor
+ * specialize TopologyRefinerFactory for more efficient
+ conversion
+
+XXXX
+
+Specialization of TopologyRefinerFactory should be done with care
+as the goal here is to maximize the performance of the conversion and so
+minimize overhead due to runtime validation. The template provides the
+high-level construction of the required topology vectors of the underlying
+Vtr, with the requirement that two methods will be specialized with the
+following purpose:
+
+ * specify the sizes of topological data so that vectors can be pre-allocated
+ * assign the topological data to the newly allocated vectors
+
+As noted above, the assumption here is that the client's boundary-rep knows best
+how to retrieve the data that we require most efficiently. After the factory class
+gathers sizing information and allocates appropriate memory, the factory provides
+the client with locations of the appropriate tables to be populated (using the
+same `Array `__ classes and interface used to access
+the tables). The client is expected to load a complete topological description
+along with additional optional data, i.e.:
+
+ * the six topological relations required by Vtr, oriented when manifold
+ * sharpness values for edges and/or vertices (optional)
+ * additional tags related to the components, e.g. holes (optional)
+ * values-per-face for face-varying channels (optional)
+
+While there is plenty of opportunity for user error here, that is no different
+from any other conversion process. Given that Far controls the construction
+process through the Factory class, we do have ample opportunity to insert
+runtime validation, and to vary that level of validation at any time on an
+instance of the Factory.
+
+A common base class has been created for the factory class, i.e.:
+
+.. code:: c++
+
+ template
+ class TopologyRefinerFactory : public TopologyRefinerFactoryBase
+
+both to provide common code independent of and also potentially to
+protect core code from unwanted specialization.
+
+Far::PatchTables
+================
+
+.. include:: under_development.rst
+
+
+Far::StencilTables
==================
-Subdivision Tables
-==================
+.. include:: under_development.rst
-Patch Tables
-============
+The base container for stencil data is the StencilTables class. As with most
+other Far entities, it has an associated StencilTablesFactory that requires
+a TopologyRefiner:
+.. image:: images/far_stencil5.png
+ :align: center
-Stencil Tables
-==============
+Principles
+**********
+Iterative subdivision algorithms such as the one used in `SubdivisionTables
+<#subdivision-tables>`__ converge towards the limit surface by sucessively
+refining the vertices of the coarse control cage.
-Stencils are the most direct method of evaluation of specific locations on the
-limit of a subdivision surface starting from the coarse vertices of the control
-cage.
+.. image:: images/far_stencil4.png
+ :align: center
+
+Each step is dependent upon the previous subidivion step being completed, and a
+substantial number of steps may be required in order approximate the limit. Since
+each subdivision step incurs an O(4 :superscript:`n`) growing amount of
+computations, the accrued number of interpolations can be quite large.
+
+However, every intermediate subdivided vertex can be expressed as a linear
+interpolation of vertice from the previous step. So, eventually, every point at
+on the limit surface can be expressed as a weighted average of the set of coarse
+control vertices from the one-ring surrounding the face that the point is in:
+
+.. image:: images/far_stencil3.png
+ :align: center
+
+Where:
+
+.. image:: images/far_stencil2.png
+ :align: center
+
+Stencils are created by combining the list of control vertices of the 1-ring
+to a set of interpolation weights obtained by successive accumulation of
+subdivision interpolation weights.
+
+The weight accumulation process is made efficient by adaptively subdividing the
+control cage only around extraordinary locations, and otherwise reverting to fast
+bi-cubic bspline patch evaluation. The use of bi-cubic patches also allows the
+accumulation of analytical derivatives.
+
+Limit Stencils
+**************
+
+Limit stencils are the most direct method of evaluation of specific locations on
+the limit of a subdivision surface starting from the coarse vertices of the
+control cage.
.. image:: images/far_stencil0.png
:align: center
+
Sample Location
***************
@@ -76,89 +264,11 @@ unique ptex face indices for instance.
.. image:: images/far_stencil6.png
:align: center
+Code example
+************
-Principles
-**********
-
-Iterative subdivision algorithms such as the one used in `FarSubdivisionTables <#subdivision-tables>`__
-converge towards the limit surface by sucessively refining the vertices of the
-coarse control cage.
-
-.. image:: images/far_stencil4.png
- :align: center
-
-Each step is dependent upon the previous subidivion step being completed, and a
-substantial number of steps may be required in order approximate the limit. Since
-each subdivision step incurs an O(4 :superscript:`n`) growing amount of
-computations, the accrued number of interpolations can be quite large.
-
-However, every intermediate subdivided vertex can be expressed as a linear
-interpolation of vertice from the previous step. So, eventually, every point at
-on the limit surface can be expressed as a weighted average of the set of coarse
-control vertices from the one-ring surrounding the face that the point is in:
-
-.. image:: images/far_stencil3.png
- :align: center
-
-Where:
-
-.. image:: images/far_stencil2.png
- :align: center
-
-Stencils are created by combining the list of control vertices of the 1-ring
-to a set of interpolation weights obtained by successive accumulation of
-subdivision interpolation weights.
-
-The weight accumulation process is made efficient by adaptively subdividing the
-control cage only around extraordinary locations, and otherwise reverting to fast
-bi-cubic bspline patch evaluation. The use of bi-cubic patches also allows the
-accumulation of analytical derivatives.
-
-API Architecture
-****************
-
-The base container for stencil data is the FarStencilTables class. As with most
-other Far entities, it has an associated FarStencilTablesFactory that requires
-an HbrMesh:
-
-.. image:: images/far_stencil5.png
- :align: center
-
-Assuming a properly qualified HbrMesh:
-
-.. code:: c++
-
- HMesh * mesh;
-
- FarStencilTables controlStencils;
-
- OpenSubdiv::FarStencilTablesFactory<> factory(mesh);
-
- for (int i=0; iGetFace(i);
-
- int nv = f->GetNumVertices();
-
- if (nv!=4) {
-
- // if the face is not a quad, we have to iterate over sub-quad(rants)
- for (int j=0; jGetNumVertices(); ++j) {
-
- factory.SetCurrentFace(i,j);
-
- factory.AppendStencils( &controlStencils, nsamples/nv, u, v, reflevel );
- }
- } else {
-
- factory.SetCurrentFace(i);
-
- factory.AppendStencils( &controlStencils, g_nsamples, u, v, reflevel );
- }
- }
-
-When the control vertices (controlPoints) move in space, the limit locations can
-be very efficiently recomputed simply by applying the blending weights to the
+When the control vertices (controlPoints) move in space, the limit locations can
+be very efficiently recomputed simply by applying the blending weights to the
series of coarse control vertices:
.. code:: c++
@@ -183,7 +293,7 @@ series of coarse control vertices:
points,
utan,
vtan;
-
+
// Uppdate points by applying stencils
controlStencils.UpdateValues( reinterpret_cast(
&controlPoints[0]), &points[0] );
diff --git a/documentation/getting_started.rst b/documentation/getting_started.rst
index f48d45c1..49434b11 100644
--- a/documentation/getting_started.rst
+++ b/documentation/getting_started.rst
@@ -1,26 +1,26 @@
-..
+..
Copyright 2013 Pixar
-
+
Licensed under the Apache License, Version 2.0 (the "Apache License")
with the following modification; you may not use this file except in
compliance with the Apache License and the following modification to it:
Section 6. Trademarks. is deleted and replaced with:
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor
and its affiliates, except as required to comply with Section 4(c) of
the License and to reproduce the content of the NOTICE file.
-
+
You may obtain a copy of the Apache License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the Apache License with the above modification is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Apache License for the specific
language governing permissions and limitations under the Apache License.
-
+
Getting Started
---------------
@@ -30,13 +30,13 @@ Getting Started
:backlinks: none
-Getting started with Git and accessing the source code.
+Getting started with Git and accessing the source code.
Downloading the code
====================
-The code is hosted on a Github public repository. Download and setup information
+The code is hosted on a Github public repository. Download and setup information
for Git tools can be found `here `__.
You can access the OpenSubdiv Git repository at https://github.com/PixarAnimationStudios/OpenSubdiv
@@ -44,28 +44,28 @@ You can access the OpenSubdiv Git repository at https://github.com/PixarAnimatio
From there, there are several ways of downloading the OpenSubdiv source code.
- Zip archive : downloaded from `here `__
-
+
- Using a GUI client : you can find a list `here `__
Please refer to the documentation of your preferred application.
- - From the GitShell, Cygwin or the CLI : assuming that you have the Git tools
- installed, you can clone the OpenSubdiv repository directly with the
+ - From the GitShell, Cygwin or the CLI : assuming that you have the Git tools
+ installed, you can clone the OpenSubdiv repository directly with the
following command:
-
- .. code:: c++
-
- git clone https://github.com/PixarAnimationStudios/OpenSubdiv.git
-
-
-These methods only pull static archives, which is are not under the version
+ .. code:: c++
+
+ git clone https://github.com/PixarAnimationStudios/OpenSubdiv.git
+
+
+
+These methods only pull static archives, which is are not under the version
control system and therefore cannot pull updates or push changes back. If you
intend on contributing features or fixes to the main trunk of the code, you will
need to create a free Github account and clone a fork of the OpenSubdiv repository.
Submissions to the main code trunk can be sent using Git's pull-request mechanisms.
Please note that we are using the git flow tools so all changes should be made to
-our *dev* branch. Before we can accept submissions however, we will need a signed
+our *dev* branch. Before we can accept submissions however, we will need a signed
`Contributor's License Agreement `__.
----
@@ -73,17 +73,22 @@ our *dev* branch. Before we can accept submissions however, we will need a signe
Branches & Git Flow
===================
-Since version 1.1.0, OpenSubdiv has adopted the `Git Flow
+Since version 1.1.0, OpenSubdiv has adopted the `Git Flow
`__ branching model .
Our active development branch is named *dev* : all new features and buf fixes should
be submitted to this branch. The changes submitted to the dev branch are periodically
patched to the 'master' branch as new versions are released.
+.. image:: images/gitflow.jpg
+ :align: center
+ :target: images/gitflow.jpg
+
+
Checking out branches
_____________________
-The Git Flow `tools `__ are not a requisite for
+The Git Flow `tools `__ are not a requisite for
working with the OpenSubdiv code base, but new work should always be performed in
the *dev* branch, or dedicated feature-branches. By default, a cloned repository
will be pointing to the 'master' branch. You can switch to the *dev* branch using
@@ -130,10 +135,10 @@ Checking out version 1.2.0:
Making Changes
______________
-Direct push access to the OpenSubdiv master repository is currently limited to a
+Direct push access to the OpenSubdiv master repository is currently limited to a
small internal development team. External code should be submitted by sending Git
-`pull-requests `__ from
-forks of our *dev* branch.
+`pull-requests `__ from
+forks of our *dev* branch.
----
@@ -142,32 +147,25 @@ Code Overview
The OpenSubdiv code base contains the following main areas:
-**./opensubdiv/**
-
- The main subdivision APIs : Hbr, Far and Osd.
-
-
-**./regression/**
-
- Standalone regression tests and baseline data to help maintain the integrity of
- our APIs. If GPU SDKs are detected, some tests will attempt to run computations
- on those GPUs.
-
-**./examples/**
-
- A small collection of standalone applications that illustrate how to deploy the
- various features and optimizations of the OpenSubdiv APIs. The GL-based examples
- rely on the cross-platform GLFW API for interactive window management, while the
- DirectX ones are OS-native.
-
-**./python/**
-
- Python-SWIG bindings for a minimal uniform refinement wrapper
-
-**./documentation/**
-
- The reStructuredText source files along with python scripts that generate the HTML
- documentation site.
++----------------------+---------------------------------------------------------------------------------------+
+| Directory | Contents |
++======================+=======================================================================================+
+| **./opensubdiv/** | The main subdivision APIs : Sdc, Vtr, Far and Osd. |
++----------------------+---------------------------------------------------------------------------------------+
+| **./examples/** | A small collection of standalone applications that illustrate how to deploy the +
+| | various features and optimizations of the OpenSubdiv APIs. The GL-based examples |
+| | rely on the cross-platform GLFW API for interactive window management, while the |
+| | DirectX ones are OS-native. |
++----------------------+---------------------------------------------------------------------------------------+
+| **./tutorials/** | Tutorials showing how to manipulate the APIs of OpenSubdiv. |
++----------------------+---------------------------------------------------------------------------------------+
+| **./documentation/** | The reStructuredText source files along with python scripts that generate the HTML |
+| | documentation site. |
++----------------------+---------------------------------------------------------------------------------------+
+| **./regression/** | Standalone regression tests and baseline data to help maintain the integrity of |
+| | our APIs. If GPU SDKs are detected, some tests will attempt to run computations |
+| | on those GPUs. |
++----------------------+---------------------------------------------------------------------------------------+
----
diff --git a/documentation/limiteval.rst b/documentation/glevallimit.rst
similarity index 82%
rename from documentation/limiteval.rst
rename to documentation/glevallimit.rst
index 350371eb..69652612 100644
--- a/documentation/limiteval.rst
+++ b/documentation/glevallimit.rst
@@ -22,8 +22,8 @@
language governing permissions and limitations under the Apache License.
-limitEval
----------
+glEvalLimit
+-----------
.. contents::
:local:
@@ -40,7 +40,7 @@ SYNOPSIS
DESCRIPTION
===========
-``limitEval`` is a stand-alone application that showcases the limit surface
+``glEvalLimit`` is a stand-alone application that showcases the limit surface
Eval module. On the given shape, random samples are generated in local u,v space.
Vertex, varying and face-varying data is then computed on the surface limit and
displayed as colors. Multiple controls are available to experiment with the algorithms.
@@ -57,14 +57,4 @@ OPTIONS
Launches the application in full-screen mode (if is supported by GLFW on the
OS)
-SEE ALSO
-========
-
-`Code Examples `__, \
-`glViewer `__, \
-`glBatchViewer `__, \
-`ptexViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
-
+.. include:: examples_see_also.rst
diff --git a/documentation/uvviewer.rst b/documentation/glfvarviewer.rst
similarity index 81%
rename from documentation/uvviewer.rst
rename to documentation/glfvarviewer.rst
index 6d1202d8..e3d13134 100644
--- a/documentation/uvviewer.rst
+++ b/documentation/glfvarviewer.rst
@@ -22,8 +22,8 @@
language governing permissions and limitations under the Apache License.
-uvViewer
---------
+glFVarViewer
+------------
.. contents::
:local:
@@ -32,12 +32,12 @@ uvViewer
SYNOPSIS
========
- **uvViewer** [**-d** *isolation level*] [**-c** *animation loops*] [**-f**] *objfile(s)*
+ **glFVarViewer** [**-d** *isolation level*] [**-c** *animation loops*] [**-f**] *objfile(s)*
DESCRIPTION
===========
-``uvViewer`` is a stand-alone application that allows the inspection of
+``glFVarViewer`` is a stand-alone application that allows the inspection of
face-varying data interpolation. The window displays 2 views:
* left side: regular 3D view of the model, with a procedural (u,v) texture
@@ -65,14 +65,5 @@ OPTIONS
Launches the application in full-screen mode (if is supported by GLFW on the
OS)
-SEE ALSO
-========
-
-`Code Examples `__, \
-`glBatchViewer `__, \
-`glStencilViewer `__, \
-`ptexViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
+.. include:: examples_see_also.rst
diff --git a/documentation/painttest.rst b/documentation/glpainttest.rst
similarity index 76%
rename from documentation/painttest.rst
rename to documentation/glpainttest.rst
index bddc6f9d..d88ee8a1 100644
--- a/documentation/painttest.rst
+++ b/documentation/glpainttest.rst
@@ -22,8 +22,8 @@
language governing permissions and limitations under the Apache License.
-paintTest
----------
+glPaintTest
+-----------
.. contents::
:local:
@@ -35,16 +35,15 @@ SYNOPSIS
.. parsed-literal::
:class: codefhead
- **paintTest**
+ **glPaintTest**
[**-f**]
*objfile(s)*
DESCRIPTION
===========
-``ptexViewer`` is a stand-alone application that showcases advanced HDR shading
-with color, displacement, occlusion and specular ptex maps. Multiple controls
-are available to experiment with the algorithms.
+``glPaintTest`` is a small stand-alone application showing the potential of
+using GPU limit tessellation for painting and sculpting applications.
.. image:: images/painttest.jpg
:width: 400px
@@ -72,15 +71,4 @@ Keyboard Controls
d : use texture as displacement
-SEE ALSO
-========
-
-`Code Examples `__, \
-`glViewer `__, \
-`glBatchViewer `__, \
-`glStencilViewer `__, \
-`ptexViewer `__, \
-`limitEval `__, \
-`dxViewer `__, \
-
-
+.. include:: examples_see_also.rst
diff --git a/documentation/ptexviewer.rst b/documentation/glptexviewer.rst
similarity index 88%
rename from documentation/ptexviewer.rst
rename to documentation/glptexviewer.rst
index 613ef1cd..3aaddf67 100644
--- a/documentation/ptexviewer.rst
+++ b/documentation/glptexviewer.rst
@@ -22,8 +22,8 @@
language governing permissions and limitations under the Apache License.
-ptexViewer
-----------
+glPtexViewer
+------------
.. contents::
:local:
@@ -35,7 +35,7 @@ SYNOPSIS
.. parsed-literal::
:class: codefhead
- **ptexViewer**
+ **glPtexViewer**
[**-e** *environment map*]
[**-d** *HDR diffuse map*]
[**-s** *HDR specular map*]
@@ -54,7 +54,7 @@ SYNOPSIS
DESCRIPTION
===========
-``ptexViewer`` is a stand-alone application that showcases advanced HDR shading
+``glPtexViewer`` is a stand-alone application that showcases advanced HDR shading
with color, displacement, occlusion and specular ptex maps. Multiple controls
are available to experiment with the algorithms.
@@ -122,20 +122,14 @@ Keyboard Controls
.. code:: c++
- e : draw normals
- g : toggle ptex texel guttering
+ q : quit
+ esc : hide GUI
+ x : save screenshot
+ f : fit frame
+ +/- : increase / decrese tessellation rate
r : reload and re-compile the shader files
+ e : draw normals
-SEE ALSO
-========
-
-`Code Examples `__, \
-`glViewer `__, \
-`glBatchViewer `__, \
-`glStencilViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
-`uvViewer `__, \
+.. include:: examples_see_also.rst
diff --git a/documentation/glsharetopology.rst b/documentation/glsharetopology.rst
new file mode 100644
index 00000000..12a87aae
--- /dev/null
+++ b/documentation/glsharetopology.rst
@@ -0,0 +1,58 @@
+..
+ Copyright 2013 Pixar
+
+ Licensed under the Apache License, Version 2.0 (the "Apache License")
+ with the following modification; you may not use this file except in
+ compliance with the Apache License and the following modification to it:
+ Section 6. Trademarks. is deleted and replaced with:
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor
+ and its affiliates, except as required to comply with Section 4(c) of
+ the License and to reproduce the content of the NOTICE file.
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the Apache License with the above modification is
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the Apache License for the specific
+ language governing permissions and limitations under the Apache License.
+
+
+glShareTopology
+---------------
+
+.. contents::
+ :local:
+ :backlinks: none
+
+SYNOPSIS
+========
+
+.. parsed-literal::
+ :class: codefhead
+
+ **glShareTopology** [**-d** *isolation level*] *objfile(s)*
+
+DESCRIPTION
+===========
+
+``glShareTopology`` is a stand-alone application that showcases the implementation of topology
+instancing across Compute contexts. Multiple controls are available to experiment with the algorithms.
+
+.. image:: images/glsharetopology.png
+ :width: 400px
+ :align: center
+ :target: images/glsharetopology.png
+
+OPTIONS
+=======
+
+**-d** *isolation level*
+ Select the desired isolation level of adaptive feature isolation. This can be
+ useful when trying to load large pieces of geometry.
+
+.. include:: examples_see_also.rst
diff --git a/documentation/glstencilviewer.rst b/documentation/glstencilviewer.rst
index 19a478c5..c502c171 100644
--- a/documentation/glstencilviewer.rst
+++ b/documentation/glstencilviewer.rst
@@ -1,26 +1,26 @@
-..
+..
Copyright 2013 Pixar
-
+
Licensed under the Apache License, Version 2.0 (the "Apache License")
with the following modification; you may not use this file except in
compliance with the Apache License and the following modification to it:
Section 6. Trademarks. is deleted and replaced with:
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor
and its affiliates, except as required to comply with Section 4(c) of
the License and to reproduce the content of the NOTICE file.
-
+
You may obtain a copy of the Apache License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the Apache License with the above modification is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Apache License for the specific
language governing permissions and limitations under the Apache License.
-
+
glStencilViewer
---------------
@@ -32,7 +32,7 @@ glStencilViewer
SYNOPSIS
========
-.. parsed-literal::
+.. parsed-literal::
:class: codefhead
**glStencilViewer** [**-d** *isolation level*] [**-f**] *objfile(s)*
@@ -40,35 +40,24 @@ SYNOPSIS
DESCRIPTION
===========
-``glStencilViewer`` is a stand-alone application that showcases the application of
-pre-computed stencil tables to a collection of geometric test shapes. Multiple
+``glStencilViewer`` is a stand-alone application that showcases the application of
+pre-computed stencil tables to a collection of geometric test shapes. Multiple
controls are available to experiment with the algorithms.
-.. image:: images/glstencilviewer.png
+.. image:: images/glstencilviewer.png
:width: 400px
:align: center
- :target: images/glstencilviewer.png
+ :target: images/glstencilviewer.png
OPTIONS
=======
**-d** *isolation level*
- Select the desired isolation level of adaptive feature isolation. This can be
+ Select the desired isolation level of adaptive feature isolation. This can be
useful when trying to load large pieces of geometry.
**-f**
Launches the application in full-screen mode (if is supported by GLFW on the
OS)
-SEE ALSO
-========
-
-`Code Examples `__, \
-`glViewer `__, \
-`glBatchViewer `__, \
-`ptexViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
-`uvViewer `__, \
-
+.. include:: examples_see_also.rst
diff --git a/documentation/glviewer.rst b/documentation/glviewer.rst
index afee261e..7877b840 100644
--- a/documentation/glviewer.rst
+++ b/documentation/glviewer.rst
@@ -35,7 +35,12 @@ SYNOPSIS
.. parsed-literal::
:class: codefhead
- **glViewer** [**-d** *isolation level*] [**-c** *animation loops*] [**-f**] *objfile(s)*
+ **glViewer**
+ [**-d** *isolation level*]
+ [**-c** *animation loops*]
+ [**-f**]
+ [**-axis**]
+ *objfile(s)*
DESCRIPTION
===========
@@ -63,15 +68,11 @@ OPTIONS
Launches the application in full-screen mode (if is supported by GLFW on the
OS)
-SEE ALSO
-========
+**-axis**
+ Swap Y-up / Z-up axis when loading obj files
-`Code Examples `__, \
-`glBatchViewer `__, \
-`glStencilViewer `__, \
-`ptexViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
-`uvViewer `__, \
+*objfile(s)*
+ A sequence of obj files used as an animation loop (the topology has to match
+ the data contained in all the ptex files !)
+.. include:: examples_see_also.rst
diff --git a/documentation/hbr_overview.rst b/documentation/hbr_overview.rst
index 080b9ed7..eaf93daa 100644
--- a/documentation/hbr_overview.rst
+++ b/documentation/hbr_overview.rst
@@ -1,26 +1,26 @@
-..
+..
Copyright 2013 Pixar
-
+
Licensed under the Apache License, Version 2.0 (the "Apache License")
with the following modification; you may not use this file except in
compliance with the Apache License and the following modification to it:
Section 6. Trademarks. is deleted and replaced with:
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor
and its affiliates, except as required to comply with Section 4(c) of
the License and to reproduce the content of the NOTICE file.
-
+
You may obtain a copy of the Apache License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the Apache License with the above modification is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Apache License for the specific
language governing permissions and limitations under the Apache License.
-
+
HBR Overview
------------
@@ -36,11 +36,24 @@ Hierarchical Boundary Representation (Hbr)
Hbr is an interconnected topological data representation. The high level of vertex
connectivity information makes this representation well suited for creation and
editing purposes. It is however inefficient for interactive refinement operations:
-Separate objects are allocated for each vertex and edge with pointers to neighboring
+Separate objects are allocated for each vertex and edge with pointers to neighboring
vertices and edges.
Hbr is also the lowest-level subdivision library in Pixar's `Photorealistic RenderMan`.
+.. container:: notebox
+
+ **Note**
+
+ As of OpenSubdiv 3.0, all **Hbr** dependencies have been removed from the
+ core APIs (**Sdc**, **Vtr**, **Far**, **Osd**). The legacy source code of
+ **Hbr** is provided purely for regression and legacy purposes. If your code
+ is currently depending on Hbr functionaliy, we recommend migrating to the
+ newer APIs as we cannot guarantee that this code will be maintained in
+ future releases.
+ For more information see the `3.0 release notes `_
+
+
----
Half-edge Data Structure
@@ -56,12 +69,12 @@ The current implementation is based on a half-edge data structure.
Half-edge cycles and Manifold Topology
======================================
-Because half-edges only carry a reference to their opposite half-edge, a given
-edge can only access a single neighboring edge cycle.
+Because half-edges only carry a reference to their opposite half-edge, a given
+edge can only access a single neighboring edge cycle.
.. image:: images/half_edge_cycle.png
:align: center
-
+
This is a fundamental limitation of the half-edge data structure, in that it
cannot represent non-manifold geometry, in particular fan-type topologies. A
different approach to topology will probably be necessary in order to accomodate
@@ -72,10 +85,10 @@ non-manifold geometry.
Templated Vertex Class
======================
-The vertex class has been abstracted into a set of templated function accesses.
-Providing Hbr with a template vertex class that does not implement these functions
-allows client-code to use Hbr as a pure topological analysis tool without having
-to pay any costs for data interpolation. It also allows client-code to remain in
+The vertex class has been abstracted into a set of templated function accesses.
+Providing Hbr with a template vertex class that does not implement these functions
+allows client-code to use Hbr as a pure topological analysis tool without having
+to pay any costs for data interpolation. It also allows client-code to remain in
complete control of the layout of the vertex data : interleaved or non-interleaved.
----
@@ -97,13 +110,13 @@ Boundary Interpolation Rules
| k_InterpolateBoundaryAlwaysSharp |
+------------------------------------+
-This enum is shared for both `vertex and face-varying interpolation
+This enum is shared for both `vertex and face-varying interpolation
`__, with the following
distinctions:
- vertex boundaries:
- the *BoundaryNone* rule skips all boundary vertices (results are ''undefined'')
- the *AlwaysSharp* rule does not apply
-
+
- face-varying boundaries:
- the *BoundaryNone* rule selects bilinear face-varying interpolation
diff --git a/documentation/images/api_data_flow.png b/documentation/images/api_data_flow.png
index 95682575..69a10874 100644
Binary files a/documentation/images/api_data_flow.png and b/documentation/images/api_data_flow.png differ
diff --git a/documentation/images/api_layers.png b/documentation/images/api_layers.png
index 14c0cfd2..1dd7fb22 100644
Binary files a/documentation/images/api_layers.png and b/documentation/images/api_layers.png differ
diff --git a/documentation/images/api_layers_3_0.png b/documentation/images/api_layers_3_0.png
new file mode 100644
index 00000000..08315937
Binary files /dev/null and b/documentation/images/api_layers_3_0.png differ
diff --git a/documentation/images/api_representations.png b/documentation/images/api_representations.png
index 6d31d691..9ffc1c51 100644
Binary files a/documentation/images/api_representations.png and b/documentation/images/api_representations.png differ
diff --git a/documentation/images/api_workflows.png b/documentation/images/api_workflows.png
index c439e1fa..80d0fd9a 100644
Binary files a/documentation/images/api_workflows.png and b/documentation/images/api_workflows.png differ
diff --git a/documentation/images/construction.png b/documentation/images/construction.png
new file mode 100644
index 00000000..aea605fb
Binary files /dev/null and b/documentation/images/construction.png differ
diff --git a/documentation/images/dxviewer.png b/documentation/images/dxviewer.png
new file mode 100644
index 00000000..b29af583
Binary files /dev/null and b/documentation/images/dxviewer.png differ
diff --git a/documentation/images/far_tutorial_0.0.png b/documentation/images/far_tutorial_0.0.png
new file mode 100644
index 00000000..e18edfd6
Binary files /dev/null and b/documentation/images/far_tutorial_0.0.png differ
diff --git a/documentation/images/far_tutorial_1.0.png b/documentation/images/far_tutorial_1.0.png
new file mode 100644
index 00000000..0bc548d8
Binary files /dev/null and b/documentation/images/far_tutorial_1.0.png differ
diff --git a/documentation/images/far_tutorial_3.0.png b/documentation/images/far_tutorial_3.0.png
new file mode 100644
index 00000000..c07dd826
Binary files /dev/null and b/documentation/images/far_tutorial_3.0.png differ
diff --git a/documentation/images/gitflow.jpg b/documentation/images/gitflow.jpg
new file mode 100644
index 00000000..425e13c3
Binary files /dev/null and b/documentation/images/gitflow.jpg differ
diff --git a/documentation/images/glsharetopology.png b/documentation/images/glsharetopology.png
new file mode 100644
index 00000000..6aaddff8
Binary files /dev/null and b/documentation/images/glsharetopology.png differ
diff --git a/documentation/images/hbr_tutorial_2.0.png b/documentation/images/hbr_tutorial_2.0.png
new file mode 100644
index 00000000..becab919
Binary files /dev/null and b/documentation/images/hbr_tutorial_2.0.png differ
diff --git a/documentation/images/osd_flow.png b/documentation/images/osd_flow.png
new file mode 100644
index 00000000..da504d64
Binary files /dev/null and b/documentation/images/osd_flow.png differ
diff --git a/documentation/images/osd_layers.png b/documentation/images/osd_layers.png
index 62b0a543..16c02d3c 100644
Binary files a/documentation/images/osd_layers.png and b/documentation/images/osd_layers.png differ
diff --git a/documentation/images/osd_splash.png b/documentation/images/osd_splash.png
new file mode 100644
index 00000000..270469dd
Binary files /dev/null and b/documentation/images/osd_splash.png differ
diff --git a/documentation/images/topology_refiner.png b/documentation/images/topology_refiner.png
new file mode 100644
index 00000000..a2c99797
Binary files /dev/null and b/documentation/images/topology_refiner.png differ
diff --git a/documentation/images/vtr_refinement.1.png b/documentation/images/vtr_refinement.1.png
new file mode 100644
index 00000000..2ca00486
Binary files /dev/null and b/documentation/images/vtr_refinement.1.png differ
diff --git a/documentation/intro.rst b/documentation/intro.rst
index e6e49272..6592b003 100644
--- a/documentation/intro.rst
+++ b/documentation/intro.rst
@@ -69,10 +69,9 @@ a character of 30,000 polygons to the second level of subdivision (500,000 polyg
Being able to perform the same operation in less than 3ms allows the user to interact
with the smooth, accurate limit surface at all times.
-.. image:: images/efficient_subdivision.png
- :height: 400px
+.. image:: images/osd_splash.png
:align: center
- :target: images/efficient_subdivision.png
+ :target: images/osd_splash.png
diff --git a/documentation/maya_osdpolysmooth.rst b/documentation/maya_osdpolysmooth.rst
index dc7c6320..d263729e 100644
--- a/documentation/maya_osdpolysmooth.rst
+++ b/documentation/maya_osdpolysmooth.rst
@@ -100,14 +100,5 @@ fvarBoundaryMethod, fvarPropagateCorners, smoothTriangles, creaseMethod,
| - Chaikin: Improves the appearance of multiedge creases with varying weight | | | |
+-----------------------------------------------------------------------------------------+------+----------+------------------------------------+
-SEE ALSO
-========
-`Code Examples `__, \
-`glBatchViewer `__, \
-`glStencilViewer `__, \
-`ptexViewer `__, \
-`paintTest `__, \
-`limitEval `__, \
-`dxViewer `__, \
-`uvViewer `__, \
+.. include:: examples_see_also.rst
diff --git a/documentation/nav_template.txt b/documentation/nav_template.txt
index 3e68a6ed..323355dc 100644
--- a/documentation/nav_template.txt
+++ b/documentation/nav_template.txt
@@ -1,20 +1,20 @@
+
User Docs
diff --git a/documentation/sdc_overview.rst b/documentation/sdc_overview.rst
new file mode 100644
index 00000000..a6e1287b
--- /dev/null
+++ b/documentation/sdc_overview.rst
@@ -0,0 +1,357 @@
+..
+ Copyright 2013 Pixar
+
+ Licensed under the Apache License, Version 2.0 (the "Apache License")
+ with the following modification; you may not use this file except in
+ compliance with the Apache License and the following modification to it:
+ Section 6. Trademarks. is deleted and replaced with:
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor
+ and its affiliates, except as required to comply with Section 4(c) of
+ the License and to reproduce the content of the NOTICE file.
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the Apache License with the above modification is
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the Apache License for the specific
+ language governing permissions and limitations under the Apache License.
+
+
+Sdc Overview
+------------
+
+.. contents::
+ :local:
+ :backlinks: none
+
+.. image:: images/api_layers_3_0.png
+ :width: 100px
+ :target: images/api_layers_3_0.png
+
+Subdivision Core (Sdc)
+======================
+
+Sdc is the lowest level layer in OpenSubdiv. Its intent is to separate
+the core subdivision details from any particular representation of a mesh
+(it was previously bound to Hbr) to facilate other classes both internal
+and external to OpenSubdiv generating consistent results.
+
+The functionality can be divided roughly into three sections:
+
+ * types, traits and options for the supported subdivision schemes
+ * computations required to support semi-sharp creasing
+ * computing mask weights for subdivided vertices for all schemes
+
+Overall the approach taken was to extract the functionality at as low a
+level as possible. In some cases they are not far from being simple global
+functions. The intent was to start at a low level and build any higher
+level functionality as needed. What exists now is functional for ongoing
+development and anticipated needs within OpenSubdiv for the near future.
+
+Its also worth noting that the intent of Sdc is to provide the building
+blocks for OpenSubdiv and its clients to efficiently process the specific
+set of subdivision schemes that are supported. It is not intended to be
+a general framework for defining customized subdivision schemes.
+
+
+.. container:: notebox
+
+ **Alpha Issues**
+
+ Warnings of change:
+
+ * note change in creasing method from *"Normal"* to *"Uniform"* and
+ related use of *"Uniform"*
+ * all boundary interpolation choices in *Sdc::Options* are subject to change
+
+ Other changes under consideration:
+
+ * ** face-weights to support face-centers and/or original vertices
+ * merging *Sdc::TypeTraits* into *Sdc::Scheme* as static methods
+ * static initialization of creasing constants (for smooth and
+ infinitely sharp)
+ * how to document template paremeter interfaces, e.g. **,
+ **, etc.?
+
+
+Types, Traits and Options
+=========================
+
+The most basic type is the enum *Sdc::Type* that identifies the fixed set of
+subdivision schemes supported by OpenSubdiv: *Bilinear*, *Catmark* and *Loop*.
+With this alone, we intend to avoid all dynamic casting issues related to the
+scheme by simply adding members to the associated subclasses for inspection.
+In addition to the type enum itself, a class defining a set of
+*TypeTraits* for each scheme is provided along with the required
+specializations for each scheme.
+
+The second contribution is the collection of all variations in one place that can
+be applied to the subdivision schemes, i.e. the boundary interpolation rules,
+creasing method, edge subdivision choices, etc. The fact that these are all
+declared in one place alone should help clients see the full set of variations
+that are possible.
+
+A simple Options struct (a set of bitfields) aggregates all of these variations
+into a single object (the equivalent of an integer in this case) that are passed
+around to other Sdc classes and/or methods and are expected to be used at a higher
+level both within OpenSubdiv and externally. By aggregating the options and
+passing them around as a group, it allows us to extend the set easily in future
+without the need to rewire a lot of interfaces to accomodate the new choice.
+Clients can enables new choices at the highest level and be assured that they will
+propagate to the lowest level where they are relevant.
+
+
+Creasing support
+================
+
+Since the computations involved in the support of semi-sharp creasing are
+independent of the subdivision scheme, the goal in Sdc was to encapsulate all
+related creasing functionality in a similarly independent manner. Computations
+involving sharpness values are also much less dependent on topology -- there
+are vertices and edges with sharpness values, but knowledge of faces or boundary
+edges is not required -- so the complexity of topological neighborhoods required
+for more scheme-specific functionality is arguably not necessary here.
+
+Creasing computations have been provided as methods defined on a Crease class
+that is constructed with a set of Options. Its methods typically take sharpness
+values as inputs and compute one or a corresponding set of new sharpness values
+as a result. For the "Uniform" creasing method (previously known as *"Normal"*),
+the computations may be so trivial as to question whether such an interface is
+worth it, but for "Chaikin" or other schemes in future that are non-trivial, the
+benefits should be clear. Functionality is divided between both uniform and
+non-uniform, so clients have some control over avoiding unnecessary overhead,
+e.g. non-uniform computations typically require neighboring sharpness values
+around a vertex, while uniform does not.
+
+Also included as part of the Crease class is the Rule enum -- this indicates if
+a vertex is Smooth, Crease, Dart or Corner (referred to as the "mask" in Hbr)
+and is a function of the sharpness values at and around a vertex. Knowing the
+Rule for a vertex can accelerate mask queries, and the Rule can often be
+inferred based on the origin of a vertex (e.g. it originated from the middle of
+a face, was the child of a Smooth vertex, etc.).
+
+Methods are defined for the Crease class to:
+
+ * subdivide edge and vertex sharpness values
+ * determine the Rule for a vertex based on incident sharpness values
+ * determine the transitional weight between two sets of sharpness values
+
+Being all low-level and working directly on sharpness values, it is a client's
+responsibility to coordinate the application of any hierarchical crease edits
+with their computations.
+
+Similarly, in keeping with this as a low-level interface, values are passed as
+primitive arrays. This follows the trend in OpenSubdiv of dealing with data of
+various kinds (e.g. weights, component indices, now sharpness values, etc.) in
+small contiguous sets of values. In most internal cases we can refer to a set
+of values or gather what will typically be a small number of values on the stack
+for temporary use.
+
+
+Scheme-specific support
+=======================
+
+While the TypeTraits class provides traits for each subdivision scheme supported
+by OpenSubdiv (i.e. *Bilinear*, *Catmark* and *Loop*), the Scheme class
+provides methods for computing the various sets of weights used to compute new
+vertices resulting from subdivision. The collection of weights used to compute
+a single vertex at a new subdivision level is typically referred to as a
+*"mask"*. The primary purpose of the Scheme class is to provide such masks in a
+manner both general and efficient.
+
+Each subdivision scheme has its own values for its masks, and each are provided
+as specializations of the template class *Scheme*. The intent is to
+minimize the amount of code specific to each scheme.
+
+The computation of mask weights for subdivided vertices is the most significant
+contribution of Sdc. The use of semi-sharp creasing with each
+non-linear subdivision scheme complicates what are otherwise simple
+masks detemined solely by the topology, and packaging that functionality to
+achieve both the generality and efficiency desired has been a challenge.
+
+Mask queries are defined in the *Scheme* class template, which has
+specializations for each of the supported subdivision schemes. Mask queries
+are defined in terms of interfaces for two template parameters: the first
+defining the topological neighborhood of a vertex, and a second defining a
+container in which to gather the individual weights:
+
+.. code:: c++
+
+ template
+ void ComputeFaceVertexMask(FACE const& faceNeighborhood, MASK& faceVertexMask, ...) const;
+
+Each mask query is expected to call methods defined for the **FACE**, **EDGE** or
+**VERTEX** classes to obtain the information they require ; typically these
+methods are simple queries about the topology and associated sharpness values.
+Clients are free to use their own mesh representations to gather the requested
+information as quickly as possible, or to cache some subset as member variables
+for immediate inline retrieval.
+
+In general, the set of weights for a subdivided vertex is dependent on the following:
+
+ * the topology around the parent component from which the vertex originates
+ * the type of subdivision *Rule* applicable to the parent component
+ * the type of subdivision *Rule* applicable to the new child vertex
+ * a transitional weight blending the effect between differing parent and child rules
+
+This seems fairly straight-forward, until we look at some of the dependencies involved:
+
+ * the parent *Rule* requires the sharpness values at and around the parent component
+ * the child *Rule* requires the subdivided sharpness values at and around the new
+ child vertex (though it can sometimes be trivially inferred from the parent)
+ * the transitional weight between differing rules requires all parent and child
+ sharpness values
+
+Clearly the sharpness values are inspected multiple times and so it pays to have
+them available for retrieval. Computing them on an as-needed basis may be simple
+for uniform creasing, but a non-uniform creasing method requires traversing
+topological neighborhoods, and that in addition to the computation itself can be
+costly.
+
+The point here is that it is potentially unreasonable to expect to evaluate the
+mask weights completely independent of any other consideration. Expecting and
+encouraging the client to have subdivided sharpness values first, for use in more
+than one place, is therefore recommended.
+
+The complexity of the general case above is also unnecessary for most vertices.
+Any client using Sdc typically has more information about the nature of the vertex
+being subdivided and much of this can be avoided -- particularly for the smooth
+interior case that often dominates. More on that in the details of the Scheme classes.
+
+Given that most of the complexity has been moved into the template parameters for
+the mask queries, the Scheme class remains fairly simple. Like the Crease class,
+it is instantiated with a set of Options to avoid them cluttering the interface.
+It is currently little more than three methods for the mask queries for each vertex
+type. The set of masks may need to be extended in future to include limit masks
+and (potentially) masks for face-varying data sets (whose neighborhoods may vary in
+their definition).
+
+The mask queries have been written in a way that greatly simplifies the
+specializations required for each scheme. The generic implementation for both
+the edge-vertex and vertex-vertex masks take care of all of the creasing logic,
+requiring only a small set of specific masks to be assigned for each Scheme:
+smooth and crease masks for an edge-vertex, and smooth, crease and corner masks
+for a vertex-vertex. Other than the *Bilinear* case, which will specialize the
+mask queries to trivialize them for linear interpolation, the specializations
+for each *Scheme* should only require defining this set of masks -- and with
+two of them common (edge-vertex crease and vertex-vertex corner) the Catmark
+scheme only needs to define three.
+
+
+The , and interfaces
+******************************************
+
+Mask queries require an interface to a topological neighborhood, currently
+labeled **FACE**, **EDGE** and **VERTEX**. This naming potentially implies more
+generality than intended as such classes are only expected to provide the
+methods required of the mask queries to compute its associated weights. While
+all methods must be defined, some may rarely be invoked, and the client has
+considerable flexibility in the implementation of these: they can defer some
+evaluations lazily until required, or be pro-active and cache information in
+member variables for immediate access.
+
+An approach discussed in the past has alluded to iterator classes that clients
+would write to traverse their meshes. The mask queries would then be parameterized
+in terms of a more general and generic mesh component that would make use of more
+general traversal iterators. The advantage here is the iterators are written once,
+then traversal is left to the query and only what is necessary is gathered. The
+disadvantages are that clients are forced to write these to do anything, getting
+them correct and efficient may not be trivial (or possible in some cases), and that
+the same data (e.g. subdivided sharpness) may be gathered or computed multiple
+times for different purposes.
+
+The other extreme was to gather everything possible required at once, but that is
+objectionable. The approach taken here provides a reasonable compromise between
+the two. The mask queries ask for exactly what they want, and the provided classes
+are expected to deliver it as efficiently as possible. In some cases the client
+may already be storing it in a more accessible form and general topological
+iteration can be avoided.
+
+The information requested of these classes in the three mask queries is as follows:
+
+ For **FACE**:
+ * the number of incident vertices
+
+ For **EDGE**:
+ * the number of incident faces
+ * the sharpness value of the parent edge
+ * the sharpness values of the two child edges
+ * the number of vertices per incident face
+
+ For **VERTEX**:
+ * the number of incident faces
+ * the number of incident edges
+ * the sharpness value of the parent vertex
+ * the sharpness values for each incident parent edge
+ * the sharpness value of the child vertex
+ * the sharpness values for each incident child edge
+
+The latter should not be surprising given the dependencies noted above. There
+are also a few more to consider for future use, e.g. whether the **EDGE** or
+**VERTEX** is manifold or not. In most cases additional information can be
+provided to the mask queries (i.e. pre-determined Rules) and most of the child
+sharpness values are not necessary. The most demanding situation is a
+fractional crease that decays to zero -- in which case all parent and child
+sharpness values in the neighborhood are required to determine the proper
+transitional weight.
+
+
+The interface
+********************
+
+Methods dealing with the collections of weights defining a mask are typically
+parameterized by a *MASK* template parameter that contains the weights. The set of
+mask weights is currently divided into vertex-weights, edge-weights and
+face-weights -- consistent with previous usage in OpenSubdiv and providing some
+useful correllation between the full set of weights and topology. The
+vertex-weights refer to parent vertices incident the parent component from which a
+vertex originated, the edge-weights the vertices opposite incident edges of the
+parent, and the face-weights the center of indicent parent faces. Note the latter
+is **NOT** in terms of vertices of the parent but potentially vertices in the child
+originating from faces of the parent. This has been done historically in
+OpenSubdiv but is finding less use -- particularly when it comes to providing
+greater support for the Loop scheme -- and is a point needing attention.
+
+So the mask queries require the following capabilities:
+
+ * assign the number of vertex, edge and/or face weights
+ * retrieve the number of vertex, edge and/or face weights
+ * assign individual vertex, edge and/or face weights by index
+ * retrieve individual vertex, edge and/or face weights by index
+
+through a set of methods required of all *MASK* classes. Since the maximum
+number of weights is typically known based on the topology, usage within Vtr,
+*Far* or *Hbr* is expected to simply define buffers on the stack or in
+pre-allocated tables to be partitioned into the three sets of weights on
+construction of a *MASK* and then populated by the mask queries.
+
+A potentially useful side-effect of this is that the client can define their
+weights to be stored in either single or double-precision. With that
+possibility in mind, care was taken within the mask queries to make use of a
+declared type in the *MASK* interface (*MASK::Weight*) for intermediate
+calculations. Having support for double-precision masks in *Sdc* does enable it
+at higher levels in OpenSubdiv if later desired, and that support is made
+almost trivial with *MASK* being generic.
+
+It is important to remember here that these masks are being defined consistent
+with existing usage within OpenSubdiv: both *Hbr* and the subdivision tables
+generated by *Far*. As noted above, the "face weights" correspond to the
+centers of incident faces, i.e. vertices on the same level as the vertex for
+which the mask is being computed, and not relative to vertices in the parent
+level as with the other sets of weights. It is true that the weights can be
+translated into a set in terms solely of parent vertices, but in the general
+case (i.e. *Catmark* subdivision with non-quads in the base mesh) this requires
+additional topological association. In general we would need N-3 weights for
+the N-3 vertices between the two incident edges, where N is the number of
+vertices of each face (typically 4 even at level 0). Perhaps such a
+translation method could be provided on the mask class, with an optional
+indication of the incident face topology for the irregular cases. The *Loop*
+scheme does not have *"face weights"*, for a vertex-vertex mask, but for an
+edge-vertex mask it does require weights associated with the faces incident the
+edge -- either the vertex opposite the edge for each triangle, or its center
+(which has no other use for Loop).
diff --git a/documentation/subdivision_surfaces.rst b/documentation/subdivision_surfaces.rst
index 7ebd5e36..fb8e4829 100644
--- a/documentation/subdivision_surfaces.rst
+++ b/documentation/subdivision_surfaces.rst
@@ -41,10 +41,11 @@ bicubic patches such as BSplines or NURBS.
:align: center
:height: 200
-However, while they do provide a reliable smooth limit surface definition, bicubic
-patch surfaces are limited to 2-dimensional topologies, which only describes a
-very small fraction of real-world shapes. This fundamental parametric limitation
-requires authoring tools to implementat at least the following functionalities:
+However, while they do provide a reliable smooth limit surface definition,
+bi-cubic patch surfaces are limited to 2-dimensional topologies, which only
+describes a very small fraction of real-world shapes. This fundamental
+parametric limitation requires authoring tools to implement at least the
+following functionalities:
- smooth trimming
- seams stitching
@@ -61,15 +62,16 @@ therefore are not constrained by these difficulties.
Arbitrary Topology
==================
-A subdivision surface, like a parametric surface, is described by its control mesh
-of points. The surface itself can approximate or interpolate this control mesh
-while being piecewise smooth. But where polygonal surfaces require large numbers
-of data points to approximate being smooth, a subdivision surface is smooth -
-meaning that polygonal artifacts are never present, no matter how the surface
-animates or how closely it is viewed.
+A subdivision surface, like a parametric surface, is described by its control
+mesh of points. The surface itself can approximate or interpolate this control
+mesh while being piecewise smooth. But where polygonal surfaces require large
+numbers of data points to approximate being smooth, a subdivision surface is
+smooth - meaning that polygonal artifacts are never present, no matter how the
+surface animates or how closely it is viewed.
-Ordinary cubic B-spline surfaces are rectangular grids of tensor-product patches.
-Subdivision surfaces generalize these to control grids with arbitrary connectivity.
+Ordinary cubic B-spline surfaces are rectangular grids of tensor-product
+patches. Subdivision surfaces generalize these to control grids with arbitrary
+connectivity.
.. raw:: html
@@ -120,16 +122,17 @@ A vertex is disconnected from any edge and face.
:align: center
:target: images/nonmanifold_vert.png
-This case is fairly trivial: there is no possible way to exact a limit surface here,
-so the vertex simply has to be flagged as non-contributing, or discarded gracefully.
+This case is fairly trivial: there is no possible way to exact a limit surface
+here, so the vertex simply has to be flagged as non-contributing, or discarded
+gracefully.
----
Boundary Interpolation Rules
============================
-Boundary interpolation rules control how boundary face edges and facevarying data
-are interpolated.
+Boundary interpolation rules control how boundary face edges and face-varying
+data are interpolated.
Vertex Data
***********
@@ -158,25 +161,25 @@ On a quad example:
:target: images/vertex_boundary.png
-Facevarying Data
-****************
+Face-varying Data
+*****************
-The following rule sets can be applied to facevarying data interpolation:
+The following rule sets can be applied to face-varying data interpolation:
+--------+----------------------------------------------------------+
| Mode | Behavior |
+========+==========================================================+
-| 0 | Bilinear interpolation (no smoothing) |
+| 0 | Bi-linear interpolation (no smoothing) |
+--------+----------------------------------------------------------+
| 1 | Smooth UV |
| | |
| | |
+--------+----------------------------------------------------------+
| 2 | Same as (1) but does not infer the presence of corners |
-| | where two facevarying edges meet at a single faceA |
+| | where two face-varying edges meet at a single faceA |
| | |
+--------+----------------------------------------------------------+
-| 3 | Smooths facevarying values only near vertices that are |
+| 3 | Smooth face-varying values only near vertices that are |
| | not at a discontinuous boundary; all vertices on a |
| | discontinuous boundary are subdivided with a sharp rule |
| | (interpolated through). |
@@ -193,32 +196,32 @@ Unwrapped cube example:
Propagate Corners
+++++++++++++++++
-Facevarying interpolation mode 2 (*EdgeAndCorner*) can further be modified by the
-application of the *Propagate Corner* flag.
+Face-varying interpolation mode 2 (*EdgeAndCorner*) can further be modified by
+the application of the *Propagate Corner* flag.
----
Semi-Sharp Creases
==================
-It is possible to modify the subdivision rules to create piecewise smooth surfaces
-containing infinitely sharp features such as creases and corners. As a special
-case, surfaces can be made to interpolate their boundaries by tagging their boundary
-edges as sharp.
+It is possible to modify the subdivision rules to create piecewise smooth
+surfaces containing infinitely sharp features such as creases and corners. As a
+special case, surfaces can be made to interpolate their boundaries by tagging
+their boundary edges as sharp.
However, we've recognized that real world surfaces never really have infinitely
-sharp edges, especially when viewed sufficiently close. To this end, we've added
-the notion of semi-sharp creases, i.e. rounded creases of controllable sharpness.
-These allow you to create features that are more akin to fillets and blends. As
-you tag edges and edge chains as creases, you also supply a sharpness value that
-ranges from 0-10, with sharpness values >=10 treated as infinitely sharp.
-
-It should be noted that infinitely sharp creases are really tangent discontinuities
-in the surface, implying that the geometric normals are also discontinuous there.
-Therefore, displacing along the normal will likely tear apart the surface along
-the crease. If you really want to displace a surface at a crease, it may be better
-to make the crease semi-sharp.
+sharp edges, especially when viewed sufficiently close. To this end, we've
+added the notion of semi-sharp creases, i.e. rounded creases of controllable
+sharpness. These allow you to create features that are more akin to fillets and
+blends. As you tag edges and edge chains as creases, you also supply a
+sharpness value that ranges from 0-10, with sharpness values >=10 treated as
+infinitely sharp.
+It should be noted that infinitely sharp creases are really tangent
+discontinuities in the surface, implying that the geometric normals are also
+discontinuous there. Therefore, displacing along the normal will likely tear
+apart the surface along the crease. If you really want to displace a surface at
+a crease, it may be better to make the crease semi-sharp.
.. image:: images/gtruck.jpg
:align: center
@@ -231,7 +234,7 @@ Chaikin Rule
============
Chaikin's curve subdivision algorithm improves the appearance of multi-edge
-semi-sharp creases with vayring weights. The Chaikin rule interpolates the
+semi-sharp creases with varying weights. The Chaikin rule interpolates the
sharpness of incident edges.
.. image:: images/chaikin.png
@@ -243,19 +246,21 @@ sharpness of incident edges.
Hierarchical Edits
==================
-To understand the hierarchical aspect of subdivision, we realize that subdivision
-itself leads to a natural hierarchy: after the first level of subdivision, each
-face in a subdivision mesh subdivides to four quads (in the Catmull-Clark scheme),
-or four triangles (in the Loop scheme). This creates a parent and child relationship
-between the original face and the resulting four subdivided faces, which in turn
-leads to a hierarchy of subdivision as each child in turn subdivides. A hierarchical
-edit is an edit made to any one of the faces, edges, or vertices that arise anywhere
-during subdivision. Normally these subdivision components inherit values from their
-parents based on a set of subdivision rules that depend on the subdivision scheme.
+To understand the hierarchical aspect of subdivision, we realize that
+subdivision itself leads to a natural hierarchy: after the first level of
+subdivision, each face in a subdivision mesh subdivides to four quads (in the
+Catmull-Clark scheme), or four triangles (in the Loop scheme). This creates a
+parent and child relationship between the original face and the resulting four
+subdivided faces, which in turn leads to a hierarchy of subdivision as each
+child in turn subdivides. A hierarchical edit is an edit made to any one of the
+faces, edges, or vertices that arise anywhere during subdivision. Normally
+these subdivision components inherit values from their parents based on a set
+of subdivision rules that depend on the subdivision scheme.
-A hierarchical edit overrides these values. This allows for a compact specification
-of localized detail on a subdivision surface, without having to express information
-about the rest of the subdivision surface at the same level of detail.
+A hierarchical edit overrides these values. This allows for a compact
+specification of localized detail on a subdivision surface, without having to
+express information about the rest of the subdivision surface at the same level
+of detail.
.. image:: images/hedit_example1.png
:align: center
@@ -267,15 +272,15 @@ about the rest of the subdivision surface at the same level of detail.
Hierarchical Edits Paths
************************
-In order to perform a hierarchical edit, we need to be able to name the subdivision
-component we are interested in, no matter where it may occur in the subdivision
-hierarchy. This leads us to a hierarchical path specification for faces, since
-once we have a face we can navigate to an incident edge or vertex by association.
-We note that in a subdivision mesh, a face always has incident vertices, which are
-labelled (in relation to the face) with an integer index starting at zero and in
-consecutive order according to the usual winding rules for subdivision surfaces.
-Faces also have incident edges, and these are labelled according to the origin
-vertex of the edge.
+In order to perform a hierarchical edit, we need to be able to name the
+subdivision component we are interested in, no matter where it may occur in the
+subdivision hierarchy. This leads us to a hierarchical path specification for
+faces, since once we have a face we can navigate to an incident edge or vertex
+by association. We note that in a subdivision mesh, a face always has incident
+vertices, which are labelled (in relation to the face) with an integer index
+starting at zero and in consecutive order according to the usual winding rules
+for subdivision surfaces. Faces also have incident edges, and these are
+labelled according to the origin vertex of the edge.
.. image:: images/face_winding.png
:align: center
@@ -285,53 +290,55 @@ vertex of the edge.
.. role:: green
.. role:: blue
-In this diagram, the indices of the vertices of the base face are marked in :red:`red`;
-so on the left we have an extraordinary Catmull-Clark face with five vertices
-(labeled :red:`0-4`) and on the right we have a regular Catmull-Clark face with four
-vertices (labelled :red:`0-3`). The indices of the child faces are :blue:`blue`; note that in
-both the extraordinary and regular cases, the child faces are indexed the same
-way, i.e. the subface labeled :blue:`n` has one incident vertex that is the result of the
-subdivision of the parent vertex also labeled :red:`n` in the parent face. Specifically,
-we note that the subface :blue:`1` in both the regular and extraordinary face is nearest
-to the vertex labelled :red:`1` in the parent.
+In this diagram, the indices of the vertices of the base face are marked in
+:red:`red`; so on the left we have an extraordinary Catmull-Clark face with
+five vertices (labeled :red:`0-4`) and on the right we have a regular
+Catmull-Clark face with four vertices (labelled :red:`0-3`). The indices of the
+child faces are :blue:`blue`; note that in both the extraordinary and regular
+cases, the child faces are indexed the same way, i.e. the sub-face labeled
+:blue:`n` has one incident vertex that is the result of the subdivision of the
+parent vertex also labeled :red:`n` in the parent face. Specifically, we note
+that the sub-face :blue:`1` in both the regular and extraordinary face is
+nearest to the vertex labelled :red:`1` in the parent.
The indices of the vertices of the child faces are labeled :green:`green`, and
this is where the difference lies between the extraordinary and regular case;
-in the extraordinary case, vertex to vertex subdivision always results in a vertex
-labeled :green:`0`, while in the regular case, vertex to vertex subdivision
-assigns the same index to the child vertex. Again, specifically, we note that the
-parent vertex indexed :red:`1` in the extraordinary case has a child vertex :green:`0`,
-while in the regular case the parent vertex indexed :red:`1` actually has a child
-vertex that is indexed :green:`1`. Note that this indexing scheme was chosen to
-maintain the property that the vertex labeled 0 always has the lowest u/v
-parametric value on the face.
+in the extraordinary case, vertex to vertex subdivision always results in a
+vertex labeled :green:`0`, while in the regular case, vertex to vertex
+subdivision assigns the same index to the child vertex. Again, specifically, we
+note that the parent vertex indexed :red:`1` in the extraordinary case has a
+child vertex :green:`0`, while in the regular case the parent vertex indexed
+:red:`1` actually has a child vertex that is indexed :green:`1`. Note that this
+indexing scheme was chosen to maintain the property that the vertex labeled 0
+always has the lowest u/v parametric value on the face.
.. image:: images/hedit_path.gif
:align: center
:target: images/hedit_path.gif
By appending a vertex index to a face index, we can create a vertex path
-specification. For example, (:blue:`655` :green:`2` :red:`3` 0) specifies the 1st.
-vertex of the :red:`3` rd. child face of the :green:`2` nd. child face of the of
-the :blue:`655` th. face of the subdivision mesh.
+specification. For example, (:blue:`655` :green:`2` :red:`3` 0) specifies the
+1st. vertex of the :red:`3` rd. child face of the :green:`2` nd. child face of
+the of the :blue:`655` th. face of the subdivision mesh.
----
Vertex Edits
************
-Vertex hierarchical edits can modify the value or the sharpness of primitive variables for vertices
-and sub-vertices anywhere in the subdivision hierarchy.
+Vertex hierarchical edits can modify the value or the sharpness of primitive
+variables for vertices and sub-vertices anywhere in the subdivision hierarchy.
.. image:: images/hedit_example1.png
:align: center
:height: 300
:target: images/hedit_example1.png
-The edits are performed using either an "add" or a "set" operator. "set" indicates the primitive
-variable value or sharpness is to be set directly to the values specified. "add" adds a value to the
-normal result computed via standard subdivision rules. In other words, this operation allows value
-offsets to be applied to the mesh at any level of the hierarchy.
+The edits are performed using either an "add" or a "set" operator. "set"
+indicates the primitive variable value or sharpness is to be set directly to
+the values specified. "add" adds a value to the normal result computed via
+standard subdivision rules. In other words, this operation allows value offsets
+to be applied to the mesh at any level of the hierarchy.
.. image:: images/hedit_example2.png
:align: center
@@ -344,7 +351,7 @@ Edge Edits
**********
Edge hierarchical edits can only modify the sharpness of primitive variables for edges
-and sub-edges anywhere in the subdivision hierarchy.
+and sub-edges anywhere in the subdivision hierarchy.
.. image:: images/hedit_example4.png
:align: center
@@ -356,15 +363,17 @@ and sub-edges anywhere in the subdivision hierarchy.
Face Edits
**********
-Face hierarchical edits can modify several properties of faces and sub-faces anywhere in the
-subdivision hierarchy.
+Face hierarchical edits can modify several properties of faces and sub-faces
+anywhere in the subdivision hierarchy.
Modifiable properties include:
- * The "set" or "add" operators modify the value of primitive variables associated with faces.
- * The "hole" operation introduces holes (missing faces) into the subdivision mesh at any
- level in the subdivision hierarchy. The faces will be deleted, and none of their children
- will appear (you cannot "unhole" a face if any ancestor is a "hole"). This operation takes
- no float or string arguments.
+
+ * The "set" or "add" operators modify the value of primitive variables
+ associated with faces.
+ * The "hole" operation introduces holes (missing faces) into the subdivision
+ mesh at any level in the subdivision hierarchy. The faces will be deleted,
+ and none of their children will appear (you cannot "unhole" a face if any
+ ancestor is a "hole"). This operation takes no float or string arguments.
.. image:: images/hedit_example5.png
:align: center
@@ -377,7 +386,8 @@ Modifiable properties include:
Limitations
***********
-XXXX
+.. include:: under_development.rst
+
----
@@ -417,7 +427,7 @@ Main features comparison:
| Uniform | Feature Adaptive |
+=======================================================+========================================================+
| | |
-| * Bilinear approximation | * Bicubic limit patches |
+| * Bi-linear approximation | * Bi-cubic limit patches |
| * No tangents / no normals | * Analytical tangents / normals |
| * No smooth shading around creases | |
| * No animated displacements | |
diff --git a/documentation/tutorials.rst b/documentation/tutorials.rst
new file mode 100644
index 00000000..aeb7aa6e
--- /dev/null
+++ b/documentation/tutorials.rst
@@ -0,0 +1,138 @@
+..
+ Copyright 2013 Pixar
+
+ Licensed under the Apache License, Version 2.0 (the "Apache License")
+ with the following modification; you may not use this file except in
+ compliance with the Apache License and the following modification to it:
+ Section 6. Trademarks. is deleted and replaced with:
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor
+ and its affiliates, except as required to comply with Section 4(c) of
+ the License and to reproduce the content of the NOTICE file.
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the Apache License with the above modification is
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the Apache License for the specific
+ language governing permissions and limitations under the Apache License.
+
+
+Tutorials
+---------
+
+.. contents::
+ :local:
+ :backlinks: none
+
+----
+
+The tutorial source code can be found in the `github.com repository
+`__
+or in your local ``/turorials``.
+
+----
+
+.. raw:: html
+
+
+
+----
+
+.. |far_tut_0| image:: images/far_tutorial_0.0.png
+ :width: 100px
+ :target: images/far_tutorial_0.0.png
+
+.. |far_tut_1| image:: images/far_tutorial_1.0.png
+ :width: 100px
+ :target: images/far_tutorial_1.0.png
+
+.. |far_tut_3| image:: images/far_tutorial_3.0.png
+ :width: 100px
+ :target: images/far_tutorial_3.0.png
+
+.. list-table:: **Far Tutorials**
+ :class: quickref
+ :widths: 50 50
+
+ * - | **Tutorial 0**
+ | This tutorial presents in a very succint way the requisite steps to
+ instantiate a Far mesh from simple topological data.
+ | |far_tut_0|
+ |
+ | **Tutorial 1**
+ | This tutorial shows how to interface a high-level topology representation
+ with Far for better efficiency. In tutorial 0, we showed how to instantiate
+ topology from a simple face-vertex list. Here we will show how to take
+ advantage of more complex data structures.
+ |
+ | **Tutorial 2**
+ | Building on tutorial 0, this example shows how to instantiate a simple mesh,
+ refine it uniformly and then interpolate both 'vertex' and 'varying' primvar
+ data.
+ | |far_tut_1|
+ |
+ - | **Tutorial 3**
+ | Building on tutorial 0, this example shows how to instantiate a simple mesh,
+ refine it uniformly and then interpolate both 'vertex' and 'face-varying'
+ primvar data.
+ The resulting interpolated data is output as an 'obj' file, with the
+ 'face-varying' data recorded in the uv texture layout.
+ | |far_tut_3|
+ |
+ | **Tutorial 4**
+ | This tutorial shows how to create and manipulate FarStencilTables. We use the
+ factorized stencils to interpolate vertex primvar data buffers.
+ |
+ | **Tutorial 5**
+ | This tutorial shows how to create and manipulate both 'vertex' and 'varying'
+ FarStencilTables to interpolate 2 primvar data buffers: vertex positions and
+ vertex colors.
+ |
+
+----
+
+.. list-table:: **Osd Tutorials**
+ :class: quickref
+ :widths: 50 50
+
+ * - | **Tutorial 0**
+ | This tutorial demonstrates the manipulation of Osd 'Compute' 'Contexts' and
+ 'Controllers'.
+ |
+ - |
+
+.. |hbr_tut_2| image:: images/hbr_tutorial_2.0.png
+ :width: 100px
+ :target: images/hbr_tutorial_2.0.png
+
+.. list-table:: **Hbr Tutorials**
+ :class: quickref
+ :widths: 50 50
+
+ * - | **Tutorial 0**
+ | This tutorial presents, in a very succint way, the requisite steps to
+ instantiate an Hbr mesh from simple topological data.
+ |
+ | **Tutorial 1**
+ | This tutorial shows how to safely create Hbr meshes from arbitrary topology.
+ Because Hbr is a half-edge data structure, it cannot represeent non-manifold
+ topology. Ensuring that the geometry used is manifold is a requirement to use
+ Hbr safely. This tutorial presents some simple tests to detect inappropriate
+ topology.
+ |
+ - | **Tutorial 2**
+ | This tutorial shows how to subdivide uniformly a simple Hbr mesh. We are
+ building upon previous turtorials and assuming a fully instantiated mesh:
+ we start with an HbrMesh pointer initialized from the same pyramid shape
+ used in hbr_tutorial_0. We then apply the Refine() function sequentially
+ to all the faces in the mesh to generate several levels of uniform
+ subdivision. The resulting data is then dumped to the terminal in Wavefront
+ OBJ format for inspection.
+ | |hbr_tut_2|
+ |
+
diff --git a/documentation/under_development.rst b/documentation/under_development.rst
new file mode 100644
index 00000000..568b49c0
--- /dev/null
+++ b/documentation/under_development.rst
@@ -0,0 +1,10 @@
+
+.. container:: notebox
+
+ Content under development....
+
+ .. image:: images/construction.png
+ :align: center
+ :height: 100
+
+
diff --git a/documentation/using_osd.rst b/documentation/using_osd.rst
index dc634826..4d12ccde 100644
--- a/documentation/using_osd.rst
+++ b/documentation/using_osd.rst
@@ -29,22 +29,35 @@ Using OpenSubdiv
:local:
:backlinks: none
-.. image:: images/barb_1.jpg
- :width: 400px
+.. image:: images/osd_splash.png
:align: center
+ :target: images/osd_splash.png
-Using OpenSubdiv
-================
+OpenSubdiv APIs
+===============
-.. list-table:: **OpenGL examples**
+.. list-table:: **APIs Overview**
+ :class: quickref
+ :widths: 50 50
+
+ * - | `Overview `_
+ - | `Osd API `_
+ | `Far API `_
+ | `Vtr API `_
+ | `Sdc API `_
+ |
+
+
+
+Coding With OpenSubdiv
+======================
+
+.. list-table:: **General Topics**
:class: quickref
:widths: 50 50
* - | `Compiling & Linking `_
- | `Textures `_
- - | `Manipulating Topology `_
-
-|
-
-
+ | `Tutorials `_
+ - | Writing Shaders
+ | `Textures (UV & Ptex) `_
diff --git a/documentation/using_osd_hbr.rst b/documentation/using_osd_hbr.rst
index d0042a49..5b617fe2 100644
--- a/documentation/using_osd_hbr.rst
+++ b/documentation/using_osd_hbr.rst
@@ -32,6 +32,19 @@ Using Hbr
----
+.. container:: notebox
+
+ **Note**
+
+ As of OpenSubdiv 3.0, all **Hbr** dependencies have been removed from the
+ core APIs (**Sdc**, **Vtr**, **Far**, **Osd**). The legacy source code of
+ **Hbr** is provided purely for regression and legacy purposes. If your code
+ is currently depending on Hbr functionaliy, we recommend migrating to the
+ newer APIs as we cannot guarantee that this code will be maintained in
+ future releases.
+ For more information see the `3.0 release notes `_
+
+
Vertex Template API
===================
@@ -100,29 +113,25 @@ does not support arbitrary variables or varying interpolation.
In some cases, if only topological analysis is required, the class can be left un-implemented.
Far and Osd for instance store vertex data in serialized interleaved vectors. Here
-is the OsdVertex class for reference:
+is the Osd::Vertex class for reference:
.. code:: c++
- class OsdVertex {
+ class Vertex {
public:
- OsdVertex() {}
+ Vertex() {}
- OsdVertex(int index) {}
+ Vertex(int /* index */) {}
- OsdVertex(OsdVertex const & src) {}
+ Vertex(Vertex const & /* src */) {}
- void AddWithWeight(OsdVertex const & i, float weight, void * = 0) {}
+ void AddWithWeight(Vertex const & /* i */, float /* weight */, void * = 0) {}
- void AddVaryingWithWeight(const OsdVertex & i, float weight, void * = 0) {}
+ void AddVaryingWithWeight(const Vertex & /* i */, float /* weight */, void * = 0) {}
void Clear(void * = 0) {}
- void ApplyVertexEdit(HbrVertexEdit const &) { }
-
void ApplyVertexEdit(FarVertexEdit const &) { }
-
- void ApplyMovingVertexEdit(HbrMovingVertexEdit const &) { }
};
diff --git a/documentation/using_osd_textures.rst b/documentation/using_osd_textures.rst
index 7d969235..22a8f511 100644
--- a/documentation/using_osd_textures.rst
+++ b/documentation/using_osd_textures.rst
@@ -37,7 +37,6 @@ Ptex Face Indices
:align: center
:target: images/ptex_coarse.png
-
Non-quad topology
_________________
@@ -48,3 +47,6 @@ _________________
Filtering
_________
+
+.. include:: under_development.rst
+
diff --git a/documentation/vtr_overview.rst b/documentation/vtr_overview.rst
new file mode 100644
index 00000000..de28515e
--- /dev/null
+++ b/documentation/vtr_overview.rst
@@ -0,0 +1,238 @@
+..
+ Copyright 2013 Pixar
+
+ Licensed under the Apache License, Version 2.0 (the "Apache License")
+ with the following modification; you may not use this file except in
+ compliance with the Apache License and the following modification to it:
+ Section 6. Trademarks. is deleted and replaced with:
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor
+ and its affiliates, except as required to comply with Section 4(c) of
+ the License and to reproduce the content of the NOTICE file.
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the Apache License with the above modification is
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the Apache License for the specific
+ language governing permissions and limitations under the Apache License.
+
+
+Vtr Overview
+------------
+
+.. contents::
+ :local:
+ :backlinks: none
+
+.. image:: images/api_layers_3_0.png
+ :width: 100px
+ :target: images/api_layers_3_0.png
+
+Vectorized Topology Representation (Vtr)
+========================================
+
+*Vtr* consists of a suite of classes that collectively provide an intermediate
+representation of topology that supports efficient refinement. *Vtr* is
+intended for internal use only and is currently accessed through the *Far*
+layer by the `Far::TopologyRefiner `__, which assembles
+these *Vtr* classes to meet the topological and refinement needs of the *Far*
+layer.
+
+*Vtr* is vectorized in that its topological data is stored more as a collection of
+vectors of primitive elements rather than as the faces, vertices and edges that
+make up many other topological representations. It is essentially a
+structure-of-arrays (SOA) approach to topology in contrast to the more common
+array-of-structures pattern found in many other topological representations.
+Vtr's use of vectors allows it to be fairly efficient in its use of memory and
+similarly efficient to refine, but the topology is fixed once defined.
+
+*Vtr* classes are purely topological. They are even more independent of the
+representation of vertices, faces, etc. than Hbr in that they are not even
+parameterized by an interface to such components. So the same set of Vtr
+objects can eventually be used to serve more than one representation of these
+components. The primary requirement is that a mesh be expressable as an
+indexable set (i.e. a vector or array) of vertices, edges and faces. The index
+of a component uniquely identifies it and properties are retrieved by referring
+to it by index.
+
+The two primary classes in *Vtr* consist of:
+
+ * `Vtr::Level <#vtrlevel>`__ - a class representing complete vertex topology
+ for a level
+ * `Vtr::Refinement <#vtrrefinement>`__ - a class mapping a parent *Vtr::Level*
+ to a child level
+
+Others exist to represent the following:
+
+ * selection and appropriate tagging of components for sparse refinement
+ * divergence of face-varying topology from the vertex topology
+ * mapping between face-varying topology at successive levels
+ * common low-level utilities, e.g. simple array classes
+
+Contents along with current issues being addressed. More details may be
+provided in the headers themselves.
+
+
+.. container:: notebox
+
+ **Alpha Issues**
+
+ Being intended for internal use, any changes to *Vtr* should not impact public
+ interfaces. Regardless, its worth noting some of the work planned:
+
+ * support for tri-split refinement required by Loop subdivision
+ * addition of more per-component tags to propogate with refinement
+ (e.g. holes, etc.)
+ * encapsulation of any scheme-specific code into classes specific to the
+ schemes
+ * potential nesting of FVar classes within *Level* and *Refinement*
+ * potential specializations for regular *Levels* and *Refinements*
+
+ Priority will be given to satisfying functional needs.
+
+
+Vtr::Level
+==========
+
+*Vtr::Level* is a complete topological description of a subdivision level, with the
+topological relations, sharpness values and component tags all stored in
+vectors (literally std::vectors, but easily changed via typedefs). There are no
+classes or objects for the mesh component types (i.e. faces, edges and
+vertices) but simply an integer index to identify each. It can be viewed as a
+structure-of-arrays representation of the topology: any property related to a
+particular component is stored in an array and accessible using the index
+identifying that component. So with no classes the for the components, its
+difficult to say what constitutes a "vertex" or a "face": they are each the sum
+of all the fields scattered amongst the many vectors included.
+
+*Level* represents a single level of a potential hierarchy and is capable of
+representing the complete base mesh. There are no members that relate data in
+one level to any other, either below or above. As such, any *Level* can be
+used as the base level for a new subdivision hierarchy (potentially more than
+one). All relationships between separate levels are maintained in the
+`Vtr::Refinement <#vtrrefinement>`__ class.
+
+Topological Relationships
+*************************
+
+*Level* requires the definition of and associations between a fixed set of
+indexable components for all three component types, i.e. an explicit edge list
+in addition to the expected set of vertices and faces. There are no explicit
+component objects in the representation, only an integer index (*Vtr::Index*)
+identifying each component within the set and data associated with that
+component in the various vectors.
+
+The topology is stored as six sets of incident relations between the components:
+two each for the two other component types incident each component type, i.e.:
+
+ * for each face, its incident vertices and incident edges
+ * for each edge, its incident vertices and incident faces
+ * for each vertex, its incident edges and incident faces
+
+The collection of incidence relations is a vectorized variation of AIF (the
+"Adjacency and Incidence Framework"). The set of these six incidence relations
+is not minimal (only four are required, but that set excludes the most desired
+face-vertex relation) but all six are kept and maintained to facilitate faster
+refinement. While the sizes of several vectors are directly proportional to the
+number of vertices, edges or faces to which the data is associated, the sizes
+of some of the vectors for these relations is more cumulative and so additional
+vectors of offsets is required (typical of the face-vertex list commonly used
+as the minimal definition of mesh topology).
+
+Vectors for the sharpness values associated with crease edges and corner
+vertices are included (and so sized according to the number of edges and
+vertices), along with additional tags for the components that may be helpful to
+refinement (i.e. the type of subdivision Rule associated with each vertex).
+
+A *Level* is really just a container for data in a subdivision level, and so
+its public methods are primarily to access that data. Modification of the data
+is protected and only made available to classes that are intended to construct
+*Levels*: currently the *Far* factory class that is responsible for building the
+base level, and the `Vtr::Refinement <#vtrrefinement>`__ class that constructs
+subsequent levels during refinement.
+
+Memory Efficiency
+*****************
+
+One of the advantages in storing data in what is essentially a
+structure-of-arrays, rather than the array-of-structures more typical of
+topological representations, is that we can be more selective about memory
+usage in some cases. Particularly in the case of uniform refinement, when the
+data in subsequent levels is typically 4x its predecessor, we can minimize what
+we either generate or keep around at each level. For instance, if only a
+face-list is required at the finest level, we only need to generate one of the
+six topological relations: the vertices incident each face. When we do keep
+*Levels* around in memory (as is the case with the `Far::TopologyRefiner
+`__) we do have do have the opportunity to prune what is not
+strictly necessary after the refinement. Just as with construction, whatever
+classes are privileged to construct a *Level* are likely those that will be
+privileged to prune its contents when needed.
+
+
+Vtr::Refinement
+===============
+
+While `Vtr::Level <#vtrlevel>`__ contains the topology for a subdivision level,
+*Vtr::Refinement* is responsible for creating a new level via refinement of an
+existing one, and for maintaining the relationships between the components in
+the parent and child levels. So a simplified view of a subdivision hierarchy
+with *Vtr* is a set of *Levels* with a *Refinement* between each
+successive pair.
+
+.. image:: images/vtr_refinement.1.png
+ :align: center
+ :target: images/vtr_refinement.1.png
+
+
+*Refinement* is a friend of *Level* and will populate a child level from
+a parent given a set of refinement parameters. Aside from parameters related
+to data or depth, there are two kinds of refinement supported: uniform and
+sparse. The latter sparse refinement requires selection of an arbitrary set of
+components -- any dependent or *"neighboring"* components that are required for
+the limit will be automatically included. So feature-adaptive refinement is
+just one form of this selective sparse refinement, the criteria being the
+topological features of interest (creases and extra-ordinary vertices). The
+intent is to eventually provide more flexibility to facilitate the refinement
+of particular regions of interest or more dynamic/adaptive needs.
+
+Parent-child and child-parent relationships
+*******************************************
+
+While *Refinement* populates a new child *Level* as part of its refinement
+operation, it also accumulates the relationships between the parent and child
+level (and as with *Level*, this data is stored in vectors indexable by the
+components).
+
+The associations between components in the two levels was initially only
+uni-directional: child components were associated with incident components
+of a parent component based on the parent components topology, so we had a
+parent-to-child mapping (one to many). Storing the reverse child-to-parent
+mapping was avoided to reduce memory (particularly in the case of uniform
+refinement) as it often was not necessary, but a growing need for it,
+particularly in the case of sparse feature-adaptive refinement, lead to it
+being included.
+
+Data flexibility
+****************
+
+One of the advantages of the structure-of-arrays representation in both
+*Level* and *Refinement* is that we can make more dynamic choices about what
+type of data we choose to allocate and use based on needs. For instance, we can
+choose between maintaining the parent-child or child-parent mapping in
+*Refinement*, or both if needed, and we can remove one if no longer
+necessary. An active example of this is uniform refinement: if we only require
+the face-vertex list at the finest subdivision level, there is no need to
+generate a complete topological description of that level (as would be required
+of more traditional representations), and given that level is 4x the magnitude
+of its parent, the savings are considerable.
+
+Currently there is nothing specific to a subdivision scheme in the refinement
+other than the type of topological splitting to apply. The refinement does
+subdivide sharpness values for creasing, but that too is independent of scheme.
+Tags were added to the base level that are propagated through the refinement
+and these too are dependent on the scheme, but are applied externally.
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 69837dc0..08f848ce 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -23,80 +23,77 @@
#
+add_subdirectory(common)
-if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
+if (NOT NO_OPENGL)
+ if (OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
- # optional dependency - enables screenshots in some examples
- find_package(PNG)
- if (PNG_FOUND)
- include_directories("${PNG_INCLUDE_DIRS}")
- list(APPEND PLATFORM_LIBRARIES "${PNG_LIBRARIES}")
- add_definitions(-DOPENSUBDIV_HAS_PNG)
+ # optional dependency - enables screenshots in some examples
+ find_package(PNG)
+ if (PNG_FOUND)
+ include_directories("${PNG_INCLUDE_DIRS}")
+ list(APPEND PLATFORM_LIBRARIES "${PNG_LIBRARIES}")
+ add_definitions(-DOPENSUBDIV_HAS_PNG)
+ endif()
+
+
+ add_subdirectory(glViewer)
+ add_subdirectory(glEvalLimit)
+ add_subdirectory(glShareTopology)
+ add_subdirectory(glFVarViewer)
+ #add_subdirectory(glStencilViewer)
+
+ if (CMAKE_COMPILER_IS_CLANGCC)
+ # This code is intended for debugging only
+ # and currently only compiles with Clang.
+ add_subdirectory(vtrViewer)
+ endif()
+
+ if (OPENGL_4_3_FOUND AND (NOT APPLE))
+ add_subdirectory(glPaintTest)
+ endif()
+
+ if (PTEX_FOUND)
+ add_subdirectory(glPtexViewer)
+ endif()
+
+ else()
+
+ set(MISSING "")
+
+ if (NOT OPENGL_FOUND)
+ list(APPEND MISSING OpenGL)
+ endif()
+
+ if (NOT GLEW_FOUND)
+ list(APPEND MISSING glew)
+ endif()
+
+ if (NOT GLFW_FOUND)
+ list(APPEND MISSING glfw)
+ endif()
+
+ message(WARNING
+ "The following libraries could not be found : ${MISSING}. "
+ "The glViewer and ptexViewer examples will not be available. "
+ "If you have these libraries installed, please specify their "
+ "path to cmake (through the GLEW_LOCATION and GLFW_LOCATION "
+ "command line arguments or environment variables)."
+ )
endif()
-
- add_subdirectory(common)
-
- add_subdirectory(glViewer)
- add_subdirectory(glBatchViewer)
- add_subdirectory(glStencilViewer)
- add_subdirectory(simpleCpu)
- add_subdirectory(limitEval)
- add_subdirectory(tessellateObjFile)
- add_subdirectory(uvViewer)
- add_subdirectory(facePartition)
- add_subdirectory(topologySharing)
-
- if(OPENGL_4_3_FOUND AND (NOT APPLE))
- add_subdirectory(paintTest)
- endif()
-
- if(PTEX_FOUND)
- add_subdirectory(ptexViewer)
- endif()
-
-else()
-
- set(MISSING "")
-
- if (NOT OPENGL_FOUND)
- list(APPEND MISSING OpenGL)
- endif()
-
- if (NOT GLEW_FOUND)
- list(APPEND MISSING glew)
- endif()
-
- if (NOT GLFW_FOUND)
- list(APPEND MISSING glfw)
- endif()
-
- message(WARNING
- "The following libraries could not be found : ${MISSING}. "
- "The glViewer and ptexViewer examples will not be available. "
- "If you have these libraries installed, please specify their "
- "path to cmake (through the GLEW_LOCATION and GLFW_LOCATION "
- "command line arguments or environment variables)."
- )
endif()
-if(DXSDK_FOUND)
+if (DXSDK_FOUND)
add_subdirectory(dxViewer)
- if(PTEX_FOUND)
+ if (PTEX_FOUND)
add_subdirectory(dxPtexViewer)
endif()
endif()
-if(MAYA_FOUND AND (NOT NO_MAYA))
- add_subdirectory(osdPolySmooth)
-
- # manuelk: the following plugins are disabled until further notice
-
- #add_subdirectory(mayaViewer)
- #if(PTEX_FOUND)
- #add_subdirectory(mayaPtexViewer)
- #endif()
+if (MAYA_FOUND AND (NOT NO_MAYA))
+ add_subdirectory(mayaPolySmooth)
endif()
diff --git a/examples/common/CMakeLists.txt b/examples/common/CMakeLists.txt
index 47146e09..00a72c3f 100644
--- a/examples/common/CMakeLists.txt
+++ b/examples/common/CMakeLists.txt
@@ -31,6 +31,7 @@ set(EXAMPLES_COMMON_SOURCE_FILES
font_image.cpp
hdr_reader.cpp
hud.cpp
+ objAnim.cpp
patchColors.cpp
)
@@ -40,6 +41,7 @@ set(EXAMPLES_COMMON_HEADER_FILES
font_image.h
hdr_reader.h
hud.h
+ objAnim.h
patchColors.h
simple_math.h
stopwatch.h
diff --git a/examples/common/clInit.h b/examples/common/clInit.h
index dd9f53b8..21a490e9 100644
--- a/examples/common/clInit.h
+++ b/examples/common/clInit.h
@@ -105,6 +105,8 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
#endif
delete[] clPlatformIDs;
+ int clDeviceUsed = 0;
+
#if defined(__APPLE__)
*clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, &ciErrNum);
if (ciErrNum != CL_SUCCESS) {
@@ -122,16 +124,64 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
cl_device_id *clDevices = new cl_device_id[numDevices];
clGetGLContextInfoAPPLE(*clContext, kCGLContext, CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, numDevices * sizeof(cl_device_id), clDevices, NULL);
#else
+
+ // get the number of GPU devices available to the platform
cl_uint numDevices = 0;
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
if (numDevices == 0) {
- printf("No sharable devices.\n");
+ printf("No CL GPU device found.\n");
return false;
}
+
+ // create the device list
cl_device_id *clDevices = new cl_device_id[numDevices];
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL);
- *clContext = clCreateContext(props, numDevices, clDevices, NULL, NULL, &ciErrNum);
+#define GL_SHARING_EXTENSION "cl_khr_gl_sharing"
+
+ // find a device that supports sharing with GL (SLI / X-fire configurations)
+ bool sharingSupported=false;
+ for (int i=0; i<(int)numDevices; ++i) {
+
+ size_t extensionSize;
+ ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
+ if (ciErrNum != CL_SUCCESS) {
+ printf("Error %d in clGetDeviceInfo\n", ciErrNum);
+ return false;
+ }
+
+ if (extensionSize>0) {
+ char* extensions = (char*)malloc(extensionSize);
+ ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize);
+ if (ciErrNum != CL_SUCCESS) {
+ printf("Error %d in clGetDeviceInfo\n", ciErrNum);
+ return false;
+ }
+ std::string stdDevString(extensions);
+ free(extensions);
+ size_t szOldPos = 0, szSpacePos = stdDevString.find(' ', szOldPos); // extensions string is space delimited
+ while (szSpacePos != stdDevString.npos) {
+ if (strcmp(GL_SHARING_EXTENSION,
+ stdDevString.substr(szOldPos, szSpacePos - szOldPos).c_str())==0) {
+ clDeviceUsed = i;
+ sharingSupported = true;
+ break;
+ }
+ do {
+ szOldPos = szSpacePos + 1;
+ szSpacePos = stdDevString.find(' ', szOldPos);
+ } while (szSpacePos == szOldPos);
+ }
+ }
+ }
+
+ if (not sharingSupported) {
+ printf("No device found that supports CL/GL context sharing\n");
+ delete[] clDevices;
+ return false;
+ }
+
+ *clContext = clCreateContext(props, 1, &clDevices[clDeviceUsed], NULL, NULL, &ciErrNum);
if (ciErrNum != CL_SUCCESS) {
printf("Error %d in clCreateContext\n", ciErrNum);
delete[] clDevices;
@@ -139,7 +189,7 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
}
#endif
- *clQueue = clCreateCommandQueue(*clContext, clDevices[0], 0, &ciErrNum);
+ *clQueue = clCreateCommandQueue(*clContext, clDevices[clDeviceUsed], 0, &ciErrNum);
delete[] clDevices;
if (ciErrNum != CL_SUCCESS) {
printf("Error %d in clCreateCommandQueue\n", ciErrNum);
diff --git a/examples/common/d3d11_hud.cpp b/examples/common/d3d11_hud.cpp
index fdecd2af..984e0e87 100755
--- a/examples/common/d3d11_hud.cpp
+++ b/examples/common/d3d11_hud.cpp
@@ -48,7 +48,7 @@ static const char *s_VS =
" return vout;\n"
"}";
-static const char *s_PS =
+static const char *s_PS =
"struct pixelIn { float4 pos : SV_POSITION; float4 color : COLOR0; float2 uv : TEXCOORD0; };\n"
"Texture2D tx : register(t0); \n"
"SamplerState sm : register(s0); \n"
@@ -86,9 +86,9 @@ D3D11hud::~D3D11hud()
}
void
-D3D11hud::Init(int width, int height)
+D3D11hud::Init(int width, int height, int frameBufferWidth, int frameBufferHeight)
{
- Hud::Init(width, height, width, height);
+ Hud::Init(width, height, frameBufferWidth, frameBufferHeight);
ID3D11Device *device = NULL;
_deviceContext->GetDevice(&device);
@@ -111,11 +111,11 @@ D3D11hud::Init(int width, int height)
subData.pSysMem = font_image;
subData.SysMemPitch = FONT_TEXTURE_WIDTH*4;
subData.SysMemSlicePitch = FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*4;
-
+
HRESULT hr = device->CreateTexture2D(&texDesc, &subData, &_fontTexture);
assert(_fontTexture);
- // shader resource view
+ // shader resource view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = texDesc.Format;
@@ -177,7 +177,7 @@ D3D11hud::Init(int width, int height)
device->CreateRasterizerState(&rasDesc, &_rasterizerState);
assert(_rasterizerState);
- // constant buffer
+ // constant buffer
D3D11_BUFFER_DESC cbDesc;
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
@@ -190,9 +190,9 @@ D3D11hud::Init(int width, int height)
}
void
-D3D11hud::Rebuild(int width, int height)
+D3D11hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
{
- Hud::Rebuild(width, height, width, height);
+ Hud::Rebuild(width, height, framebufferWidth, framebufferHeight);
SAFE_RELEASE(_staticVbo);
@@ -222,7 +222,7 @@ D3D11hud::Rebuild(int width, int height)
bool
D3D11hud::Flush()
{
- if (!Hud::Flush())
+ if (!Hud::Flush())
return false;
// update dynamic text
diff --git a/examples/common/d3d11_hud.h b/examples/common/d3d11_hud.h
index db1fd26f..59f4adce 100644
--- a/examples/common/d3d11_hud.h
+++ b/examples/common/d3d11_hud.h
@@ -34,9 +34,18 @@ public:
D3D11hud(ID3D11DeviceContext *deviceContext);
~D3D11hud();
- virtual void Init(int width, int height);
+ void Init(int width, int height) {
+ Init(width, height, width, height);
+ }
- virtual void Rebuild(int width, int height);
+ void Rebuild(int width, int height) {
+ Rebuild(width, height, width, height);
+ }
+
+ virtual void Init(int width, int height, int framebufferWidth, int framebufferHeight);
+
+ virtual void Rebuild(int width, int height,
+ int framebufferWidth, int framebufferHeight);
virtual bool Flush();
diff --git a/examples/common/gl_framebuffer.cpp b/examples/common/gl_framebuffer.cpp
index 150ff60f..0cad266e 100644
--- a/examples/common/gl_framebuffer.cpp
+++ b/examples/common/gl_framebuffer.cpp
@@ -188,7 +188,7 @@ GLFrameBuffer::compileProgram(char const * src, char const * defines) {
if (colorMap != -1)
glUniform1i(colorMap, 0); // GL_TEXTURE0
- GLint normalMap = glGetUniformLocation(program, "normalMap");
+ GLint colorMap = glGetUniformLocation(program, "normalMap");
if (normalMap != -1)
glUniform1i(normalMap, 1); // GL_TEXTURE1
diff --git a/examples/common/gl_framebuffer.h b/examples/common/gl_framebuffer.h
index 7defe2d9..71a231ae 100644
--- a/examples/common/gl_framebuffer.h
+++ b/examples/common/gl_framebuffer.h
@@ -33,7 +33,6 @@ class GLhud;
class GLFrameBuffer {
public:
-
GLFrameBuffer();
int GetWidth() const {
diff --git a/examples/common/gl_hud.cpp b/examples/common/gl_hud.cpp
index 68673128..d24fd0e2 100644
--- a/examples/common/gl_hud.cpp
+++ b/examples/common/gl_hud.cpp
@@ -198,7 +198,7 @@ void
GLhud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
{
Hud::Rebuild(width, height, framebufferWidth, framebufferHeight);
-
+
if (not _staticVbo)
return;
@@ -250,4 +250,3 @@ GLhud::Flush()
return true;
}
-
diff --git a/examples/common/gl_hud.h b/examples/common/gl_hud.h
index 560635c0..c55a7e79 100644
--- a/examples/common/gl_hud.h
+++ b/examples/common/gl_hud.h
@@ -51,7 +51,7 @@ public:
int framebufferWidth, int framebufferHeight);
virtual bool Flush();
-
+
void SetFrameBuffer(GLFrameBuffer * frameBuffer) {
if (not _frameBuffer) {
_frameBuffer = frameBuffer;
@@ -64,6 +64,10 @@ public:
return _frameBuffer;
}
+ GLuint GetFontTexture() const {
+ return _fontTexture;
+ }
+
private:
diff --git a/examples/common/hdr_reader.cpp b/examples/common/hdr_reader.cpp
index cd829bbf..ba3071e3 100644
--- a/examples/common/hdr_reader.cpp
+++ b/examples/common/hdr_reader.cpp
@@ -98,11 +98,11 @@ unsigned char *loadHdr(const char *filename, HdrInfo *info, bool convertToFloat)
for (int i = 1; i < n; ++i) {
if (buffer[i] == 'X') {
if (not (info->flag & HDR_Y_MAJOR)) info->flag |= HDR_X_MAJOR;
- info->flag |= (buffer[i-1] == '-') ? HDR_X_DEC : 0;
+ info->flag |= (char)((buffer[i-1] == '-') ? HDR_X_DEC : 0);
info->width = atoi(&buffer[i+1]);
} else if (buffer[i] == 'Y') {
if (not (info->flag & HDR_X_MAJOR)) info->flag |= HDR_Y_MAJOR;
- info->flag |= (buffer[i-1] == '-') ? HDR_Y_DEC : 0;
+ info->flag |= (char)((buffer[i-1] == '-') ? HDR_Y_DEC : 0);
info->height = atoi(&buffer[i+1]);
}
}
diff --git a/examples/common/hud.cpp b/examples/common/hud.cpp
index a3832f64..9a89ef9a 100644
--- a/examples/common/hud.cpp
+++ b/examples/common/hud.cpp
@@ -1,597 +1,597 @@
-//
-// Copyright 2013 Pixar
-//
-// Licensed under the Apache License, Version 2.0 (the "Apache License")
-// with the following modification; you may not use this file except in
-// compliance with the Apache License and the following modification to it:
-// Section 6. Trademarks. is deleted and replaced with:
-//
-// 6. Trademarks. This License does not grant permission to use the trade
-// names, trademarks, service marks, or product names of the Licensor
-// and its affiliates, except as required to comply with Section 4(c) of
-// the License and to reproduce the content of the NOTICE file.
-//
-// You may obtain a copy of the Apache License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the Apache License with the above modification is
-// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the Apache License for the specific
-// language governing permissions and limitations under the Apache License.
-//
-
-#include
-#include
-#include
-#include
-#include
-#include "hud.h"
-#include "font_image.h"
-
-#if _MSC_VER
-#define snprintf _snprintf
-#endif
-
-Hud::Hud() : _visible(true), _windowWidth(0), _windowHeight(0),
- _framebufferWidth(0), _framebufferHeight(0),
- _requiresRebuildStatic(true)
-{
- _capturedSlider = -1;
-}
-
-Hud::~Hud()
-{
-}
-
-void
-Hud::Init(int width, int height, int framebufferWidth, int framebufferHeight)
-{
- _windowWidth = width;
- _windowHeight = height;
- _framebufferWidth = framebufferWidth;
- _framebufferHeight = framebufferHeight;
-}
-
-int
-Hud::GetWidth() const
-{
- return _windowWidth;
-}
-
-int
-Hud::GetHeight() const
-{
- return _windowHeight;
-}
-
-void
-Hud::Clear()
-{
- _radioButtons.clear();
- _checkBoxes.clear();
- _sliders.clear();
- _vboSource.clear();
- _requiresRebuildStatic = true;
-}
-
-bool
-Hud::KeyDown(int key)
-{
- for (std::vector::iterator it = _radioButtons.begin();
- it != _radioButtons.end(); ++it) {
- if (key == it->shortcut) {
- int nextLocalIndex = it->localIndex;
- if (it->sharedShortcut) {
- // find checked radio button in this group
- int maxLocalIndex = 0;
- for (std::vector::iterator it2 = _radioButtons.begin();
- it2 != _radioButtons.end(); ++it2) {
-
- if (it2->group == it->group) {
- maxLocalIndex = std::max(maxLocalIndex, it2->localIndex);
- if (it2->checked) {
- nextLocalIndex = it2->localIndex+1;
- }
- }
- }
- if (nextLocalIndex > maxLocalIndex) nextLocalIndex = 0;
- }
- for (std::vector::iterator it2 = _radioButtons.begin();
- it2 != _radioButtons.end(); ++it2) {
- if (it2->group == it->group) {
- if (it2->localIndex == nextLocalIndex) {
- it2->checked = true;
- it2->callback(it2->callbackData);
- } else {
- it2->checked = false;
- }
- }
- }
- _requiresRebuildStatic = true;
- return true;
- }
- }
- for (std::vector::iterator it = _checkBoxes.begin();
- it != _checkBoxes.end(); ++it) {
-
- if (key == it->shortcut) {
- it->checked = !it->checked;
- it->callback(it->checked, it->callbackData);
- _requiresRebuildStatic = true;
- return true;
- }
- }
- for (std::vector::iterator it = _pulldowns.begin();
- it != _pulldowns.end(); ++it) {
- if (key==it->shortcut) {
- // cycle through selections
- ++it->selected;
- if (it->selected>=(int)it->labels.size()) {
- it->selected=0;
- }
- it->callback(it->values[it->selected]);
- _requiresRebuildStatic = true;
- return true;
- }
- }
-
- return false;
-}
-
-bool
-Hud::MouseClick(int x, int y)
-{
- if (!IsVisible()) {
- return false;
- }
-
- for (std::vector::iterator it = _radioButtons.begin();
- it != _radioButtons.end(); ++it) {
- if (hitTest(*it, x, y)) {
- for (std::vector::iterator it2 = _radioButtons.begin();
- it2 != _radioButtons.end(); ++it2) {
-
- if (it2->group == it->group && it != it2) it2->checked = false;
- }
- it->checked = true;
- it->callback(it->callbackData);
- _requiresRebuildStatic = true;
- return true;
- }
- }
- for (std::vector::iterator it = _checkBoxes.begin();
- it != _checkBoxes.end(); ++it) {
- if (hitTest(*it, x, y)) {
- it->checked = !it->checked;
- it->callback(it->checked, it->callbackData);
- _requiresRebuildStatic = true;
- return true;
- }
- }
- for (std::vector::iterator it = _sliders.begin();
- it != _sliders.end(); ++it) {
- if (hitTest(*it, x, y)) {
- int bx = 0, by = 0;
- getWindowPos(*it, &bx, &by);
- it->SetValue(((x-bx-FONT_CHAR_WIDTH/2)/float(it->w))*(it->max - it->min) + it->min);
- it->callback(it->value, it->callbackData);
- _capturedSlider = (int)(it - _sliders.begin());
- _requiresRebuildStatic = true;
- return true;
- }
- }
- for (std::vector::iterator it = _pulldowns.begin();
- it != _pulldowns.end(); ++it) {
- if (hitTest(*it, x, y)) {
- if (not it->open) {
- it->h = FONT_CHAR_HEIGHT;
- it->h *= (int)it->labels.size();
- it->open=true;
- } else {
- int label_width = (3+(int)it->label.size()) * FONT_CHAR_WIDTH;
- int bx = 0, by = 0;
- getWindowPos(*it, &bx, &by);
- if (x > (bx+label_width)) {
- int sel = it->selected;
- it->SetSelected((y-by)/FONT_CHAR_HEIGHT);
- if (it->selected!=sel) {
- it->callback(it->values[it->selected]);
- }
- } else {
- it->open=not it->open;
- }
- }
- _requiresRebuildStatic = true;
- return true;
- }
- }
- return false;
-}
-
-void
-Hud::MouseMotion(int x, int /* y */)
-{
- if (_capturedSlider != -1) {
- std::vector::iterator it = _sliders.begin() + _capturedSlider;
-
- int bx = it->x > 0 ? it->x : _windowWidth + it->x;
- it->SetValue(((x-bx-FONT_CHAR_WIDTH/2)/float(it->w))*(it->max - it->min) + it->min);
- it->callback(it->value, it->callbackData);
- _requiresRebuildStatic = true;
- }
-}
-
-bool
-Hud::MouseCapture() const
-{
- return _capturedSlider != -1;
-}
-
-void
-Hud::MouseRelease()
-{
- _capturedSlider = -1;
-}
-
-void
-Hud::AddLabel(const char *label, int x, int y)
-{
- Item l;
- l.label = label;
- l.x = x;
- l.y = y;
-
- _labels.push_back(l);
- _requiresRebuildStatic = true;
-}
-
-void
-Hud::AddCheckBox(const char *label, bool checked, int x, int y,
- CheckBoxCallback callback, int data, int shortcut)
-{
- CheckBox cb;
- cb.label = label;
- cb.checked = checked;
- cb.x = x;
- cb.y = y;
- cb.w = (int)(strlen(label)+1) * FONT_CHAR_WIDTH;
- cb.h = FONT_CHAR_HEIGHT;
- cb.callback = callback;
- cb.callbackData = data;
- cb.shortcut = shortcut;
-
- _checkBoxes.push_back(cb);
- _requiresRebuildStatic = true;
-}
-
-void
-Hud::AddRadioButton(int group, const char *label, bool checked, int x, int y,
- RadioButtonCallback callback, int data, int shortcut)
-{
- RadioButton rb;
- rb.group = group;
- rb.label = label;
- rb.checked = checked;
- rb.x = x;
- rb.y = y;
- rb.w = (int)(strlen(label)+1) * FONT_CHAR_WIDTH;
- rb.h = FONT_CHAR_HEIGHT;
- rb.callback = callback;
- rb.callbackData = data;
- rb.shortcut = shortcut;
- rb.sharedShortcut = false;
- rb.localIndex = 0;
-
- for (std::vector::iterator it = _radioButtons.begin();
- it != _radioButtons.end(); ++it) {
- if (it->group == group) {
- rb.localIndex = it->localIndex+1;
- if (it->shortcut == shortcut) {
- it->sharedShortcut = true;
- rb.sharedShortcut = true;
- }
- }
- }
-
- _radioButtons.push_back(rb);
- _requiresRebuildStatic = true;
-}
-
-void
-Hud::AddSlider(const char *label, float min, float max, float value,
- int x, int y, int width, bool intStep, SliderCallback callback, int data)
-{
- Slider slider;
- slider.label = label;
- slider.x = x;
- slider.y = y;
- slider.w = width * FONT_CHAR_WIDTH;
- slider.h = FONT_CHAR_HEIGHT * 2;
- slider.min = min;
- slider.max = max;
- slider.value = value;
- slider.callback = callback;
- slider.callbackData = data;
- slider.intStep = intStep;
-
- _sliders.push_back(slider);
- _requiresRebuildStatic = true;
-}
-
-int
-Hud::AddPullDown(const char *label, int x, int y, int width,
- PullDownCallback callback, int shortcut)
-{
-
- PullDown pd;
- pd.label = label;
- pd.x = x;
- pd.y = y;
- pd.w = width;
- pd.h = FONT_CHAR_HEIGHT;
- pd.open = false;
- pd.selected = 0;
- pd.callback = callback;
- pd.shortcut = shortcut;
-
- _pulldowns.push_back(pd);
- _requiresRebuildStatic = true;
-
- return (int)_pulldowns.size()-1;
-}
-
-void
-Hud::AddPullDownButton(int handle, const char *label, int value, bool checked)
-{
- if (handle < (int)_pulldowns.size()) {
-
- PullDown & pulldown = _pulldowns[handle];
-
- pulldown.labels.push_back(label);
- pulldown.values.push_back(value);
- if (checked) {
- pulldown.selected = (int)pulldown.labels.size()-1;
- }
- }
-}
-
-
-
-int
-Hud::drawChar(std::vector &vboSource,
- int x, int y, float r, float g, float b, char ch)
-{
- const float w = 1.0f/FONT_TEXTURE_COLUMNS;
- const float h = 1.0f/FONT_TEXTURE_ROWS;
-
- float u = (ch%FONT_TEXTURE_COLUMNS)/(float)FONT_TEXTURE_COLUMNS;
- float v = (ch/FONT_TEXTURE_COLUMNS)/(float)FONT_TEXTURE_ROWS;
-
- vboSource.push_back(float(x));
- vboSource.push_back(float(y));
- vboSource.push_back(r);
- vboSource.push_back(g);
- vboSource.push_back(b);
- vboSource.push_back(u);
- vboSource.push_back(v);
-
- vboSource.push_back(float(x));
- vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
- vboSource.push_back(r);
- vboSource.push_back(g);
- vboSource.push_back(b);
- vboSource.push_back(u);
- vboSource.push_back(v+h);
-
- vboSource.push_back(float(x+FONT_CHAR_WIDTH));
- vboSource.push_back(float(y));
- vboSource.push_back(r);
- vboSource.push_back(g);
- vboSource.push_back(b);
- vboSource.push_back(u+w);
- vboSource.push_back(v);
-
- vboSource.push_back(float(x+FONT_CHAR_WIDTH));
- vboSource.push_back(float(y));
- vboSource.push_back(r);
- vboSource.push_back(g);
- vboSource.push_back(b);
- vboSource.push_back(u+w);
- vboSource.push_back(v);
-
- vboSource.push_back(float(x));
- vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
- vboSource.push_back(r);
- vboSource.push_back(g);
- vboSource.push_back(b);
- vboSource.push_back(u);
- vboSource.push_back(v+h);
-
- vboSource.push_back(float(x+FONT_CHAR_WIDTH));
- vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
- vboSource.push_back(r);
- vboSource.push_back(g);
- vboSource.push_back(b);
- vboSource.push_back(u+w);
- vboSource.push_back(v+h);
-
- return x + FONT_CHAR_WIDTH;
-}
-
-int
-Hud::drawString(std::vector &vboSource,
- int x, int y, float r, float g, float b, const char *c)
-{
- while (*c) {
- char ch = (*c) & 0x7f;
- x = drawChar(vboSource, x, y, r, g, b, ch);
- c++;
- }
- return x;
-}
-
-void
-Hud::DrawString(int x, int y, const char *fmt, ...)
-{
- char buf[1024];
- va_list args;
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
-
- x = x > 0 ? x : _windowWidth + x;
- y = y > 0 ? y : _windowHeight + y;
-
- drawString(_vboSource, x, y, 1, 1, 1, buf);
-}
-
-void
-Hud::DrawString(int x, int y, float r, float g, float b, const char *fmt, ...)
-{
- char buf[1024];
- va_list args;
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
-
- x = x > 0 ? x : _windowWidth + x;
- y = y > 0 ? y : _windowHeight + y;
-
- drawString(_vboSource, x, y, r, g, b, buf);
-}
-
-void
-Hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
-{
- _requiresRebuildStatic = false;
- _windowWidth = width;
- _windowHeight = height;
- _framebufferWidth = framebufferWidth;
- _framebufferHeight = framebufferHeight;
-
- _staticVboSource.clear();
-
- int x, y;
- // add UI elements
- for (std::vector::const_iterator it = _labels.begin();
- it != _labels.end(); ++it) {
- getWindowPos(*it, &x, &y);
- drawString(_staticVboSource, x, y, 1, 1, 1, it->label.c_str());
- }
- // draw radio buttons
- for (std::vector::const_iterator it = _radioButtons.begin();
- it != _radioButtons.end(); ++it) {
- getWindowPos(*it, &x, &y);
- if (it->checked) {
- x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_RADIO_BUTTON_ON);
- drawString(_staticVboSource, x, y, 1, 1, 0, it->label.c_str());
- } else {
- x = drawChar(_staticVboSource, x, y, 1, 1, 1, ' ');
- drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
- }
- }
- // draw checkboxes
- for (std::vector::const_iterator it = _checkBoxes.begin();
- it != _checkBoxes.end(); ++it) {
- getWindowPos(*it, &x, &y);
- if (it->checked) {
- x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_CHECK_BOX_ON);
- drawString(_staticVboSource, x, y, 1, 1, 0, it->label.c_str());
- } else {
- x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_CHECK_BOX_OFF);
- drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
- }
- }
- // draw sliders
- for (std::vector::const_iterator it = _sliders.begin();
- it != _sliders.end(); ++it) {
- getWindowPos(*it, &x, &y);
- int sx = x;
- x = drawString(_staticVboSource, x, y, 1, 1, 1, it->label.c_str());
- char value[16];
- snprintf(value, 16, " : %.2f", it->value);
- drawString(_staticVboSource, x, y, 1, 1, 1, value);
-
- // new line
- y += FONT_CHAR_HEIGHT;
- x = sx;
-
- x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_LEFT);
- int nw = it->w / FONT_CHAR_WIDTH;
- for (int i = 1; i < nw; ++i) {
- x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_MIDDLE);
- }
- drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_RIGHT);
- int pos = (int)((it->value/float(it->max-it->min))*it->w);
- drawChar(_staticVboSource, sx+pos, y, 1, 1, 0, FONT_SLIDER_CURSOR);
- }
- // draw pulldowns
- for (std::vector::const_iterator it = _pulldowns.begin();
- it != _pulldowns.end(); ++it) {
- getWindowPos(*it, &x, &y);
-
- x = drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
- x += FONT_CHAR_WIDTH;
-
- if (it->open) {
- x = drawChar(_staticVboSource, x, y, 1, 1, 0, FONT_ARROW_DOWN);
- x += FONT_CHAR_WIDTH;
- for (int i=0; i<(int)it->labels.size(); ++i, y+=FONT_CHAR_HEIGHT) {
- if (i==it->selected) {
- drawString(_staticVboSource, x, y, 1, 1, 0, it->labels[i]);
- } else {
- drawString(_staticVboSource, x, y, 0.5f, 0.5f, 0.5f, it->labels[i]);
- }
- }
- } else {
- x = drawChar(_staticVboSource, x, y, .5f, .5f, .5f, FONT_ARROW_RIGHT);
- x += FONT_CHAR_WIDTH;
- drawString(_staticVboSource, x, y, 1, 1, 0, it->labels[it->selected]);
- }
- }
-
- drawString(_staticVboSource, _windowWidth-80, _windowHeight-48, .5, .5, .5,
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f");
- drawString(_staticVboSource, _windowWidth-80, _windowHeight-32, .5, .5, .5,
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f");
-}
-
-bool
-Hud::Flush()
-{
- if (!_visible) {
- _vboSource.clear();
- return false;
- }
-
- if (_requiresRebuildStatic)
- Rebuild(_windowWidth, _windowHeight, _framebufferWidth, _framebufferHeight);
-
- return true;
-}
-
-bool
-Hud::IsVisible() const
-{
- return _visible;
-}
-
-void
-Hud::SetVisible(bool visible)
-{
- _visible = visible;
-}
-
-std::vector &
-Hud::getVboSource()
-{
- return _vboSource;
-}
-
-std::vector &
-Hud::getStaticVboSource()
-{
- return _staticVboSource;
-}
+//
+// Copyright 2013 Pixar
+//
+// Licensed under the Apache License, Version 2.0 (the "Apache License")
+// with the following modification; you may not use this file except in
+// compliance with the Apache License and the following modification to it:
+// Section 6. Trademarks. is deleted and replaced with:
+//
+// 6. Trademarks. This License does not grant permission to use the trade
+// names, trademarks, service marks, or product names of the Licensor
+// and its affiliates, except as required to comply with Section 4(c) of
+// the License and to reproduce the content of the NOTICE file.
+//
+// You may obtain a copy of the Apache License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the Apache License with the above modification is
+// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the Apache License for the specific
+// language governing permissions and limitations under the Apache License.
+//
+
+#include
+#include
+#include
+#include
+#include
+#include "hud.h"
+#include "font_image.h"
+
+#if _MSC_VER
+#define snprintf _snprintf
+#endif
+
+Hud::Hud() : _visible(true), _windowWidth(0), _windowHeight(0),
+ _framebufferWidth(0), _framebufferHeight(0),
+ _requiresRebuildStatic(true)
+{
+ _capturedSlider = -1;
+}
+
+Hud::~Hud()
+{
+}
+
+void
+Hud::Init(int width, int height, int framebufferWidth, int framebufferHeight)
+{
+ _windowWidth = width;
+ _windowHeight = height;
+ _framebufferWidth = framebufferWidth;
+ _framebufferHeight = framebufferHeight;
+}
+
+int
+Hud::GetWidth() const
+{
+ return _windowWidth;
+}
+
+int
+Hud::GetHeight() const
+{
+ return _windowHeight;
+}
+
+void
+Hud::Clear()
+{
+ _radioButtons.clear();
+ _checkBoxes.clear();
+ _sliders.clear();
+ _vboSource.clear();
+ _requiresRebuildStatic = true;
+}
+
+bool
+Hud::KeyDown(int key)
+{
+ for (std::vector::iterator it = _radioButtons.begin();
+ it != _radioButtons.end(); ++it) {
+ if (key == it->shortcut) {
+ int nextLocalIndex = it->localIndex;
+ if (it->sharedShortcut) {
+ // find checked radio button in this group
+ int maxLocalIndex = 0;
+ for (std::vector::iterator it2 = _radioButtons.begin();
+ it2 != _radioButtons.end(); ++it2) {
+
+ if (it2->group == it->group) {
+ maxLocalIndex = std::max(maxLocalIndex, it2->localIndex);
+ if (it2->checked) {
+ nextLocalIndex = it2->localIndex+1;
+ }
+ }
+ }
+ if (nextLocalIndex > maxLocalIndex) nextLocalIndex = 0;
+ }
+ for (std::vector::iterator it2 = _radioButtons.begin();
+ it2 != _radioButtons.end(); ++it2) {
+ if (it2->group == it->group) {
+ if (it2->localIndex == nextLocalIndex) {
+ it2->checked = true;
+ it2->callback(it2->callbackData);
+ } else {
+ it2->checked = false;
+ }
+ }
+ }
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+ for (std::vector::iterator it = _checkBoxes.begin();
+ it != _checkBoxes.end(); ++it) {
+
+ if (key == it->shortcut) {
+ it->checked = !it->checked;
+ it->callback(it->checked, it->callbackData);
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+ for (std::vector::iterator it = _pulldowns.begin();
+ it != _pulldowns.end(); ++it) {
+ if (key==it->shortcut) {
+ // cycle through selections
+ ++it->selected;
+ if (it->selected>=(int)it->labels.size()) {
+ it->selected=0;
+ }
+ it->callback(it->values[it->selected]);
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+Hud::MouseClick(int x, int y)
+{
+ if (!IsVisible()) {
+ return false;
+ }
+
+ for (std::vector::iterator it = _radioButtons.begin();
+ it != _radioButtons.end(); ++it) {
+ if (hitTest(*it, x, y)) {
+ for (std::vector::iterator it2 = _radioButtons.begin();
+ it2 != _radioButtons.end(); ++it2) {
+
+ if (it2->group == it->group && it != it2) it2->checked = false;
+ }
+ it->checked = true;
+ it->callback(it->callbackData);
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+ for (std::vector::iterator it = _checkBoxes.begin();
+ it != _checkBoxes.end(); ++it) {
+ if (hitTest(*it, x, y)) {
+ it->checked = !it->checked;
+ it->callback(it->checked, it->callbackData);
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+ for (std::vector::iterator it = _sliders.begin();
+ it != _sliders.end(); ++it) {
+ if (hitTest(*it, x, y)) {
+ int bx = 0, by = 0;
+ getWindowPos(*it, &bx, &by);
+ it->SetValue(((x-bx-FONT_CHAR_WIDTH/2)/float(it->w))*(it->max - it->min) + it->min);
+ it->callback(it->value, it->callbackData);
+ _capturedSlider = (int)(it - _sliders.begin());
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+ for (std::vector::iterator it = _pulldowns.begin();
+ it != _pulldowns.end(); ++it) {
+ if (hitTest(*it, x, y)) {
+ if (not it->open) {
+ it->h = FONT_CHAR_HEIGHT;
+ it->h *= (int)it->labels.size();
+ it->open=true;
+ } else {
+ int label_width = (3+(int)it->label.size()) * FONT_CHAR_WIDTH;
+ int bx = 0, by = 0;
+ getWindowPos(*it, &bx, &by);
+ if (x > (bx+label_width)) {
+ int sel = it->selected;
+ it->SetSelected((y-by)/FONT_CHAR_HEIGHT);
+ if (it->selected!=sel) {
+ it->callback(it->values[it->selected]);
+ }
+ } else {
+ it->open=not it->open;
+ }
+ }
+ _requiresRebuildStatic = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+Hud::MouseMotion(int x, int /* y */)
+{
+ if (_capturedSlider != -1) {
+ std::vector::iterator it = _sliders.begin() + _capturedSlider;
+
+ int bx = it->x > 0 ? it->x : _windowWidth + it->x;
+ it->SetValue(((x-bx-FONT_CHAR_WIDTH/2)/float(it->w))*(it->max - it->min) + it->min);
+ it->callback(it->value, it->callbackData);
+ _requiresRebuildStatic = true;
+ }
+}
+
+bool
+Hud::MouseCapture() const
+{
+ return _capturedSlider != -1;
+}
+
+void
+Hud::MouseRelease()
+{
+ _capturedSlider = -1;
+}
+
+void
+Hud::AddLabel(const char *label, int x, int y)
+{
+ Item l;
+ l.label = label;
+ l.x = x;
+ l.y = y;
+
+ _labels.push_back(l);
+ _requiresRebuildStatic = true;
+}
+
+void
+Hud::AddCheckBox(const char *label, bool checked, int x, int y,
+ CheckBoxCallback callback, int data, int shortcut)
+{
+ CheckBox cb;
+ cb.label = label;
+ cb.checked = checked;
+ cb.x = x;
+ cb.y = y;
+ cb.w = (int)(strlen(label)+1) * FONT_CHAR_WIDTH;
+ cb.h = FONT_CHAR_HEIGHT;
+ cb.callback = callback;
+ cb.callbackData = data;
+ cb.shortcut = shortcut;
+
+ _checkBoxes.push_back(cb);
+ _requiresRebuildStatic = true;
+}
+
+void
+Hud::AddRadioButton(int group, const char *label, bool checked, int x, int y,
+ RadioButtonCallback callback, int data, int shortcut)
+{
+ RadioButton rb;
+ rb.group = group;
+ rb.label = label;
+ rb.checked = checked;
+ rb.x = x;
+ rb.y = y;
+ rb.w = (int)(strlen(label)+1) * FONT_CHAR_WIDTH;
+ rb.h = FONT_CHAR_HEIGHT;
+ rb.callback = callback;
+ rb.callbackData = data;
+ rb.shortcut = shortcut;
+ rb.sharedShortcut = false;
+ rb.localIndex = 0;
+
+ for (std::vector::iterator it = _radioButtons.begin();
+ it != _radioButtons.end(); ++it) {
+ if (it->group == group) {
+ rb.localIndex = it->localIndex+1;
+ if (it->shortcut == shortcut) {
+ it->sharedShortcut = true;
+ rb.sharedShortcut = true;
+ }
+ }
+ }
+
+ _radioButtons.push_back(rb);
+ _requiresRebuildStatic = true;
+}
+
+void
+Hud::AddSlider(const char *label, float min, float max, float value,
+ int x, int y, int width, bool intStep, SliderCallback callback, int data)
+{
+ Slider slider;
+ slider.label = label;
+ slider.x = x;
+ slider.y = y;
+ slider.w = width * FONT_CHAR_WIDTH;
+ slider.h = FONT_CHAR_HEIGHT * 2;
+ slider.min = min;
+ slider.max = max;
+ slider.value = value;
+ slider.callback = callback;
+ slider.callbackData = data;
+ slider.intStep = intStep;
+
+ _sliders.push_back(slider);
+ _requiresRebuildStatic = true;
+}
+
+int
+Hud::AddPullDown(const char *label, int x, int y, int width,
+ PullDownCallback callback, int shortcut)
+{
+
+ PullDown pd;
+ pd.label = label;
+ pd.x = x;
+ pd.y = y;
+ pd.w = width;
+ pd.h = FONT_CHAR_HEIGHT;
+ pd.open = false;
+ pd.selected = 0;
+ pd.callback = callback;
+ pd.shortcut = shortcut;
+
+ _pulldowns.push_back(pd);
+ _requiresRebuildStatic = true;
+
+ return (int)_pulldowns.size()-1;
+}
+
+void
+Hud::AddPullDownButton(int handle, const char *label, int value, bool checked)
+{
+ if (handle < (int)_pulldowns.size()) {
+
+ PullDown & pulldown = _pulldowns[handle];
+
+ pulldown.labels.push_back(label);
+ pulldown.values.push_back(value);
+ if (checked) {
+ pulldown.selected = (int)pulldown.labels.size()-1;
+ }
+ }
+}
+
+
+
+int
+Hud::drawChar(std::vector &vboSource,
+ int x, int y, float r, float g, float b, char ch)
+{
+ const float w = 1.0f/FONT_TEXTURE_COLUMNS;
+ const float h = 1.0f/FONT_TEXTURE_ROWS;
+
+ float u = (ch%FONT_TEXTURE_COLUMNS)/(float)FONT_TEXTURE_COLUMNS;
+ float v = (ch/FONT_TEXTURE_COLUMNS)/(float)FONT_TEXTURE_ROWS;
+
+ vboSource.push_back(float(x));
+ vboSource.push_back(float(y));
+ vboSource.push_back(r);
+ vboSource.push_back(g);
+ vboSource.push_back(b);
+ vboSource.push_back(u);
+ vboSource.push_back(v);
+
+ vboSource.push_back(float(x));
+ vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
+ vboSource.push_back(r);
+ vboSource.push_back(g);
+ vboSource.push_back(b);
+ vboSource.push_back(u);
+ vboSource.push_back(v+h);
+
+ vboSource.push_back(float(x+FONT_CHAR_WIDTH));
+ vboSource.push_back(float(y));
+ vboSource.push_back(r);
+ vboSource.push_back(g);
+ vboSource.push_back(b);
+ vboSource.push_back(u+w);
+ vboSource.push_back(v);
+
+ vboSource.push_back(float(x+FONT_CHAR_WIDTH));
+ vboSource.push_back(float(y));
+ vboSource.push_back(r);
+ vboSource.push_back(g);
+ vboSource.push_back(b);
+ vboSource.push_back(u+w);
+ vboSource.push_back(v);
+
+ vboSource.push_back(float(x));
+ vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
+ vboSource.push_back(r);
+ vboSource.push_back(g);
+ vboSource.push_back(b);
+ vboSource.push_back(u);
+ vboSource.push_back(v+h);
+
+ vboSource.push_back(float(x+FONT_CHAR_WIDTH));
+ vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
+ vboSource.push_back(r);
+ vboSource.push_back(g);
+ vboSource.push_back(b);
+ vboSource.push_back(u+w);
+ vboSource.push_back(v+h);
+
+ return x + FONT_CHAR_WIDTH;
+}
+
+int
+Hud::drawString(std::vector &vboSource,
+ int x, int y, float r, float g, float b, const char *c)
+{
+ while (*c) {
+ char ch = (char)((*c) & 0x7f);
+ x = drawChar(vboSource, x, y, r, g, b, ch);
+ c++;
+ }
+ return x;
+}
+
+void
+Hud::DrawString(int x, int y, const char *fmt, ...)
+{
+ char buf[1024];
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ x = x > 0 ? x : _windowWidth + x;
+ y = y > 0 ? y : _windowHeight + y;
+
+ drawString(_vboSource, x, y, 1, 1, 1, buf);
+}
+
+void
+Hud::DrawString(int x, int y, float r, float g, float b, const char *fmt, ...)
+{
+ char buf[1024];
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ x = x > 0 ? x : _windowWidth + x;
+ y = y > 0 ? y : _windowHeight + y;
+
+ drawString(_vboSource, x, y, r, g, b, buf);
+}
+
+void
+Hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
+{
+ _requiresRebuildStatic = false;
+ _windowWidth = width;
+ _windowHeight = height;
+ _framebufferWidth = framebufferWidth;
+ _framebufferHeight = framebufferHeight;
+
+ _staticVboSource.clear();
+
+ int x, y;
+ // add UI elements
+ for (std::vector::const_iterator it = _labels.begin();
+ it != _labels.end(); ++it) {
+ getWindowPos(*it, &x, &y);
+ drawString(_staticVboSource, x, y, 1, 1, 1, it->label.c_str());
+ }
+ // draw radio buttons
+ for (std::vector::const_iterator it = _radioButtons.begin();
+ it != _radioButtons.end(); ++it) {
+ getWindowPos(*it, &x, &y);
+ if (it->checked) {
+ x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_RADIO_BUTTON_ON);
+ drawString(_staticVboSource, x, y, 1, 1, 0, it->label.c_str());
+ } else {
+ x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_RADIO_BUTTON_OFF);
+ drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
+ }
+ }
+ // draw checkboxes
+ for (std::vector::const_iterator it = _checkBoxes.begin();
+ it != _checkBoxes.end(); ++it) {
+ getWindowPos(*it, &x, &y);
+ if (it->checked) {
+ x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_CHECK_BOX_ON);
+ drawString(_staticVboSource, x, y, 1, 1, 0, it->label.c_str());
+ } else {
+ x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_CHECK_BOX_OFF);
+ drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
+ }
+ }
+ // draw sliders
+ for (std::vector::const_iterator it = _sliders.begin();
+ it != _sliders.end(); ++it) {
+ getWindowPos(*it, &x, &y);
+ int sx = x;
+ x = drawString(_staticVboSource, x, y, 1, 1, 1, it->label.c_str());
+ char value[16];
+ snprintf(value, 16, " : %.2f", it->value);
+ drawString(_staticVboSource, x, y, 1, 1, 1, value);
+
+ // new line
+ y += FONT_CHAR_HEIGHT;
+ x = sx;
+
+ x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_LEFT);
+ int nw = it->w / FONT_CHAR_WIDTH;
+ for (int i = 1; i < nw; ++i) {
+ x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_MIDDLE);
+ }
+ drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_RIGHT);
+ int pos = (int)((it->value/float(it->max-it->min))*it->w);
+ drawChar(_staticVboSource, sx+pos, y, 1, 1, 0, FONT_SLIDER_CURSOR);
+ }
+ // draw pulldowns
+ for (std::vector::const_iterator it = _pulldowns.begin();
+ it != _pulldowns.end(); ++it) {
+ getWindowPos(*it, &x, &y);
+
+ x = drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
+ x += FONT_CHAR_WIDTH;
+
+ if (it->open) {
+ x = drawChar(_staticVboSource, x, y, 1, 1, 0, FONT_ARROW_DOWN);
+ x += FONT_CHAR_WIDTH;
+ for (int i=0; i<(int)it->labels.size(); ++i, y+=FONT_CHAR_HEIGHT) {
+ if (i==it->selected) {
+ drawString(_staticVboSource, x, y, 1, 1, 0, it->labels[i]);
+ } else {
+ drawString(_staticVboSource, x, y, 0.5f, 0.5f, 0.5f, it->labels[i]);
+ }
+ }
+ } else {
+ x = drawChar(_staticVboSource, x, y, .5f, .5f, .5f, FONT_ARROW_RIGHT);
+ x += FONT_CHAR_WIDTH;
+ drawString(_staticVboSource, x, y, 1, 1, 0, it->labels[it->selected]);
+ }
+ }
+
+ drawString(_staticVboSource, _windowWidth-80, _windowHeight-48, .5, .5, .5,
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f");
+ drawString(_staticVboSource, _windowWidth-80, _windowHeight-32, .5, .5, .5,
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f");
+}
+
+bool
+Hud::Flush()
+{
+ if (!_visible) {
+ _vboSource.clear();
+ return false;
+ }
+
+ if (_requiresRebuildStatic)
+ this->Rebuild(_windowWidth, _windowHeight, _framebufferWidth, _framebufferHeight);
+
+ return true;
+}
+
+bool
+Hud::IsVisible() const
+{
+ return _visible;
+}
+
+void
+Hud::SetVisible(bool visible)
+{
+ _visible = visible;
+}
+
+std::vector &
+Hud::getVboSource()
+{
+ return _vboSource;
+}
+
+std::vector &
+Hud::getStaticVboSource()
+{
+ return _staticVboSource;
+}
diff --git a/examples/common/hud.h b/examples/common/hud.h
index 1d10fb35..29c6282b 100644
--- a/examples/common/hud.h
+++ b/examples/common/hud.h
@@ -74,9 +74,9 @@ public:
int AddPullDown(const char *label, int x, int y, int width,
PullDownCallback callback=0, int shortcut=0);
-
+
void AddPullDownButton(int handle, const char *label, int value, bool checked=false);
-
+
bool KeyDown(int key);
bool MouseClick(int x, int y);
@@ -129,16 +129,16 @@ protected:
value = std::max(std::min(v, max), min);
}
};
-
+
struct PullDown : public Item {
- bool open;
+ bool open;
int selected;
std::vector labels;
std::vector values;
int shortcut;
PullDownCallback callback;
-
+
void SetSelected(int idx) {
if (idx>=0 and idx<(int)labels.size()) {
selected=idx;
diff --git a/examples/common/objAnim.cpp b/examples/common/objAnim.cpp
new file mode 100644
index 00000000..53e67585
--- /dev/null
+++ b/examples/common/objAnim.cpp
@@ -0,0 +1,149 @@
+//
+// Copyright 2013 Pixar
+//
+// Licensed under the Apache License, Version 2.0 (the "Apache License")
+// with the following modification; you may not use this file except in
+// compliance with the Apache License and the following modification to it:
+// Section 6. Trademarks. is deleted and replaced with:
+//
+// 6. Trademarks. This License does not grant permission to use the trade
+// names, trademarks, service marks, or product names of the Licensor
+// and its affiliates, except as required to comply with Section 4(c) of
+// the License and to reproduce the content of the NOTICE file.
+//
+// You may obtain a copy of the Apache License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the Apache License with the above modification is
+// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the Apache License for the specific
+// language governing permissions and limitations under the Apache License.
+//
+
+#include "objAnim.h"
+
+#include <../regression/common/shape_utils.h>
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+ObjAnim::ObjAnim() : _shape(0) {
+}
+
+ObjAnim::~ObjAnim() {
+
+ delete _shape;
+}
+
+void
+ObjAnim::InterpolatePositions(float time, float * positions, int stride) const {
+
+ assert(positions);
+
+ if ( _positions.empty() or (not _shape)) {
+ //printf("Error: InterpolatePositions on unfit ObjAnim instance\n");
+ return;
+ }
+
+ int nkeys = GetNumKeyframes(),
+ nverts = GetShape()->GetNumVertices();
+
+ const float fps = 24.0f;
+
+ float p = fmodf(time * fps, (float)nkeys);
+
+ int key = (int)p;
+
+ float b = p - key;
+
+ for (int i = 0; i objFiles, bool axis) {
+
+ ObjAnim * anim=0;
+
+ Shape const * shape = 0;
+
+ if (not objFiles.empty()) {
+
+ anim = new ObjAnim;
+
+ anim->_positions.reserve(objFiles.size());
+
+ for (int i = 0; i < (int)objFiles.size(); ++i) {
+
+ if (not objFiles[i]) {
+ continue;
+ }
+
+ std::ifstream ifs(objFiles[i]);
+
+ if (ifs) {
+
+ std::stringstream ss;
+ ss << ifs.rdbuf();
+ ifs.close();
+
+ printf("Reading %s\r", objFiles[i]);
+ fflush(stdout);
+ std::string str = ss.str();
+
+ shape = Shape::parseObj(str.c_str(), kCatmark, axis);
+
+ if (i==0) {
+
+ anim->_shape = shape;
+ anim->_positions.push_back(shape->verts);
+ } else {
+
+ if (shape->verts.size() != anim->_shape->verts.size()) {
+ printf("Error: vertex count doesn't match (%s)\n", objFiles[i]);
+ goto error;
+ }
+
+ if (shape->nvertsPerFace.size() != anim->_shape->nvertsPerFace.size()) {
+ printf("Error: face vertex count array doesn't match (%s)\n", objFiles[i]);
+ goto error;
+ }
+
+ if (shape->faceverts.size() != anim->_shape->faceverts.size()) {
+ printf("Error: face vertices array doesn't match (%s)\n", objFiles[i]);
+ goto error;
+ }
+
+ anim->_positions.push_back(shape->verts);
+ delete shape;
+ }
+
+ } else {
+ printf("Error in reading %s\n", objFiles[i]);
+ goto error;
+ }
+ }
+ printf("\n");
+ }
+
+ return anim;
+
+error:
+ delete shape;
+ delete anim;
+ return 0;
+}
diff --git a/python/osd/buffer.h b/examples/common/objAnim.h
similarity index 60%
rename from python/osd/buffer.h
rename to examples/common/objAnim.h
index 291d4929..3d635df7 100644
--- a/python/osd/buffer.h
+++ b/examples/common/objAnim.h
@@ -22,44 +22,45 @@
// language governing permissions and limitations under the Apache License.
//
-#pragma once
+#ifndef OBJ_ANIM_H
+#define OBJ_ANIM_H
+
#include
-namespace shim {
+struct Shape;
- typedef std::vector Buffer;
+class ObjAnim {
- enum DataType {
- invalid,
- int8,
- uint8,
- int16,
- uint16,
- int32,
- uint32,
- int64,
- uint64,
- int128,
- uint128,
- int256,
- uint256,
- float16,
- float32,
- float64,
- float80,
- float96,
- float128,
- };
+public:
- struct HomogeneousBuffer {
- shim::Buffer Buffer;
- shim::DataType Type;
- };
+ // Factory function
+ static ObjAnim const * Create(std::vector objFiles, bool axis=true);
- typedef std::vector Layout;
+ // Destructor
+ ~ObjAnim();
- struct HeterogeneousBuffer {
- shim::Buffer Buffer;
- shim::Layout Layout;
- };
-}
+ // Populates 'positions' with the interpolated vertex data for a given
+ // time.
+ void InterpolatePositions(float time, float * positions, int stride) const;
+
+ // Number of key-frames in the animation
+ int GetNumKeyframes() const {
+ return (int)_positions.size();
+ }
+
+ // Returns the full 'Shape'
+ Shape const * GetShape() const {
+ return _shape;
+ }
+
+
+private:
+
+ ObjAnim();
+
+ Shape const * _shape;
+
+ std::vector > _positions;
+};
+
+#endif // OBJ_ANIM_H
diff --git a/examples/common/patchColors.cpp b/examples/common/patchColors.cpp
index a2658b71..2aeb2ee7 100644
--- a/examples/common/patchColors.cpp
+++ b/examples/common/patchColors.cpp
@@ -24,38 +24,50 @@
#include "patchColors.h"
-float const * getAdaptivePatchColor(OpenSubdiv::OsdDrawContext::PatchDescriptor const & desc) {
+static float _colors[4][5][4] = {{{1.0f, 1.0f, 1.0f, 1.0f}, // regular
+ {0.8f, 0.0f, 0.0f, 1.0f}, // boundary
+ {0.0f, 1.0f, 0.0f, 1.0f}, // corner
+ {1.0f, 1.0f, 0.0f, 1.0f}, // gregory
+ {1.0f, 0.5f, 0.0f, 1.0f}}, // gregory boundary
- static float _colors[4][5][4] = {{{1.0f, 1.0f, 1.0f, 1.0f}, // regular
- {0.8f, 0.0f, 0.0f, 1.0f}, // boundary
- {0.0f, 1.0f, 0.0f, 1.0f}, // corner
- {1.0f, 1.0f, 0.0f, 1.0f}, // gregory
- {1.0f, 0.5f, 0.0f, 1.0f}}, // gregory boundary
+ {{0.0f, 1.0f, 1.0f, 1.0f}, // regular pattern 0
+ {0.0f, 0.5f, 1.0f, 1.0f}, // regular pattern 1
+ {0.0f, 0.5f, 0.5f, 1.0f}, // regular pattern 2
+ {0.5f, 0.0f, 1.0f, 1.0f}, // regular pattern 3
+ {1.0f, 0.5f, 1.0f, 1.0f}}, // regular pattern 4
- {{0.0f, 1.0f, 1.0f, 1.0f}, // regular pattern 0
- {0.0f, 0.5f, 1.0f, 1.0f}, // regular pattern 1
- {0.0f, 0.5f, 0.5f, 1.0f}, // regular pattern 2
- {0.5f, 0.0f, 1.0f, 1.0f}, // regular pattern 3
- {1.0f, 0.5f, 1.0f, 1.0f}}, // regular pattern 4
-
- {{0.0f, 0.0f, 0.75f, 1.0f}, // boundary pattern 0
- {0.0f, 0.2f, 0.75f, 1.0f}, // boundary pattern 1
- {0.0f, 0.4f, 0.75f, 1.0f}, // boundary pattern 2
- {0.0f, 0.6f, 0.75f, 1.0f}, // boundary pattern 3
- {0.0f, 0.8f, 0.75f, 1.0f}}, // boundary pattern 4
-
- {{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 0
- {0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 1
- {0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 2
- {0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 3
- {0.25f, 0.25f, 0.25f, 1.0f}}}; // corner pattern 4
+ {{0.0f, 0.0f, 0.75f, 1.0f}, // boundary pattern 0
+ {0.0f, 0.2f, 0.75f, 1.0f}, // boundary pattern 1
+ {0.0f, 0.4f, 0.75f, 1.0f}, // boundary pattern 2
+ {0.0f, 0.6f, 0.75f, 1.0f}, // boundary pattern 3
+ {0.0f, 0.8f, 0.75f, 1.0f}}, // boundary pattern 4
- typedef OpenSubdiv::FarPatchTables FPT;
+ {{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 0
+ {0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 1
+ {0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 2
+ {0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 3
+ {0.25f, 0.25f, 0.25f, 1.0f}}}; // corner pattern 4
- if (desc.GetPattern()==FPT::NON_TRANSITION) {
- return _colors[0][(int)(desc.GetType()-FPT::REGULAR)];
+typedef OpenSubdiv::Far::PatchTables FarPatchTables;
+
+
+float const *
+getAdaptivePatchColor(FarPatchTables::Descriptor const & desc) {
+
+ if (desc.GetPattern()==FarPatchTables::NON_TRANSITION) {
+ return _colors[0][(int)(desc.GetType()-FarPatchTables::REGULAR)];
} else {
- return _colors[(int)(desc.GetType()-FPT::REGULAR)+1][(int)desc.GetPattern()-1];
+ return _colors[(int)(desc.GetType()-FarPatchTables::REGULAR)+1][(int)desc.GetPattern()-1];
+ }
+}
+
+float const *
+getAdaptivePatchColor(OpenSubdiv::Osd::DrawContext::PatchDescriptor const & desc) {
+
+ if (desc.GetPattern()==FarPatchTables::NON_TRANSITION) {
+ return _colors[0][(int)(desc.GetType()-FarPatchTables::REGULAR)];
+ } else {
+ return _colors[(int)(desc.GetType()-FarPatchTables::REGULAR)+1][(int)desc.GetPattern()-1];
}
}
diff --git a/examples/common/patchColors.h b/examples/common/patchColors.h
index bfbeca74..b4fc6986 100644
--- a/examples/common/patchColors.h
+++ b/examples/common/patchColors.h
@@ -27,8 +27,12 @@
#include
+#include
+
// returns a unique color for each type of feature-adaptive patches
-float const * getAdaptivePatchColor(OpenSubdiv::OsdDrawContext::PatchDescriptor const & desc);
+float const * getAdaptivePatchColor(OpenSubdiv::Osd::DrawContext::PatchDescriptor const & desc);
+
+float const * getAdaptivePatchColor(OpenSubdiv::Far::PatchTables::Descriptor const & desc);
#endif /* COMMON_PATCH_COLORS_H */
diff --git a/examples/common/simple_math.h b/examples/common/simple_math.h
index 21f52077..700d3d41 100644
--- a/examples/common/simple_math.h
+++ b/examples/common/simple_math.h
@@ -143,7 +143,7 @@ inverseMatrix(float *d, const float *m) {
float det = m[0] * d[0] + m[1] * d[4] + m[2] * d[8] + m[3] * d[12];
- if (det == 0) return;
+ if (det == 0.0f) return;
det = 1.0f / det;
for (int i = 0; i < 16; i++)
@@ -154,7 +154,7 @@ inline void
perspective(float *m, float fovy, float aspect, float znear, float zfar)
{
float r = 2 * (float)M_PI * fovy / 360.0F;
- float t = 1.0f / tan(r*0.5f);
+ float t = 1.0f / tanf(r*0.5f);
m[0] = t/aspect;
m[1] = m[2] = m[3] = 0.0;
m[4] = 0.0;
@@ -205,8 +205,8 @@ inline void
rotate(float *m, float angle, float x, float y, float z)
{
float r = 2 * (float) M_PI * angle/360.0f;
- float c = cos(r);
- float s = sin(r);
+ float c = cosf(r);
+ float s = sinf(r);
float t[16];
t[0] = x*x*(1-c)+c;
t[1] = y*x*(1-c)+z*s;
diff --git a/examples/common/stopwatch.h b/examples/common/stopwatch.h
index 1a58fec3..32d0b153 100644
--- a/examples/common/stopwatch.h
+++ b/examples/common/stopwatch.h
@@ -38,6 +38,8 @@ class Stopwatch {
public:
#ifndef _WINDOWS
+ Stopwatch() : _totalElapsed(0) { }
+
void Start() {
struct timeval l_rtime;
gettimeofday(&l_rtime,0);
@@ -60,7 +62,7 @@ public:
return _totalElapsed;
}
#else
- Stopwatch() {
+ Stopwatch() : _totalElapsed(0) {
QueryPerformanceFrequency(&_frequency);
}
diff --git a/examples/dxPtexViewer/CMakeLists.txt b/examples/dxPtexViewer/CMakeLists.txt
index 646c7d65..d856a91e 100644
--- a/examples/dxPtexViewer/CMakeLists.txt
+++ b/examples/dxPtexViewer/CMakeLists.txt
@@ -53,6 +53,7 @@ _add_possibly_cuda_executable(dxPtexViewer WIN32
"${SOURCE_FILES}"
"${SHADER_FILES}"
"${INC_FILES}"
+ $
$
)
diff --git a/examples/dxPtexViewer/dxPtexViewer.cpp b/examples/dxPtexViewer/dxPtexViewer.cpp
index c797e610..eeb135bd 100644
--- a/examples/dxPtexViewer/dxPtexViewer.cpp
+++ b/examples/dxPtexViewer/dxPtexViewer.cpp
@@ -34,11 +34,11 @@
#include
#include
#include
-OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
+OpenSubdiv::Osd::CpuComputeController * g_cpuComputeController = NULL;
#ifdef OPENSUBDIV_HAS_OPENMP
#include
- OpenSubdiv::OsdOmpComputeController * g_ompComputeController = NULL;
+ OpenSubdiv::Osd::OmpComputeController * g_ompComputeController = NULL;
#endif
#undef OPENSUBDIV_HAS_OPENCL // XXX: dyu OpenCL D3D11 interop needs work...
@@ -51,7 +51,7 @@ OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
cl_context g_clContext;
cl_command_queue g_clQueue;
- OpenSubdiv::OsdCLComputeController * g_clComputeController = NULL;
+ OpenSubdiv::Osd::CLComputeController * g_clComputeController = NULL;
#endif
#ifdef OPENSUBDIV_HAS_CUDA
@@ -63,24 +63,24 @@ OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
#include
bool g_cudaInitialized = false;
- OpenSubdiv::OsdCudaComputeController * g_cudaComputeController = NULL;
+ OpenSubdiv::Osd::CudaComputeController * g_cudaComputeController = NULL;
#endif
#include
#include
#include
-OpenSubdiv::OsdD3D11ComputeController * g_d3d11ComputeController = NULL;
+OpenSubdiv::Osd::D3D11ComputeController * g_d3d11ComputeController = NULL;
#include
-OpenSubdiv::OsdD3D11MeshInterface *g_mesh;
+OpenSubdiv::Osd::D3D11MeshInterface *g_mesh;
#include "Ptexture.h"
#include "PtexUtils.h"
+#include
#include "../common/stopwatch.h"
#include "../common/simple_math.h"
#include "../common/d3d11_hud.h"
-#include "../../regression/common/shape_utils.h"
static const char *g_shaderSource =
#include "shader.gen.h"
@@ -90,16 +90,13 @@ static const char *g_shaderSource =
#include
#include
#include
+#include
+#include
#include
#include
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
-typedef OpenSubdiv::HbrMesh OsdHbrMesh;
-typedef OpenSubdiv::HbrVertex OsdHbrVertex;
-typedef OpenSubdiv::HbrFace OsdHbrFace;
-typedef OpenSubdiv::HbrHalfedge OsdHbrHalfedge;
-
enum KernelType { kCPU = 0,
kOPENMP = 1,
kCUDA = 2,
@@ -220,10 +217,10 @@ float g_animTime = 0;
std::vector g_positions,
g_normals;
-OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexImage = 0;
-OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexDisplacement = 0;
-OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexOcclusion = 0;
-OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexSpecular = 0;
+OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexImage = 0;
+OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexDisplacement = 0;
+OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexOcclusion = 0;
+OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexSpecular = 0;
const char * g_ptexColorFilename;
ID3D11Device * g_pd3dDevice = NULL;
@@ -245,24 +242,28 @@ bool g_bDone = false;
//------------------------------------------------------------------------------
static void
-calcNormals(OsdHbrMesh * mesh, std::vector const & pos, std::vector & result ) {
+calcNormals(OpenSubdiv::Far::TopologyRefiner * refiner,
+ std::vector const & pos, std::vector & result ) {
+
+ typedef OpenSubdiv::Far::IndexArray IndexArray;
// calc normal vectors
- int nverts = (int)pos.size()/3;
+ int nverts = refiner->GetNumVertices(0),
+ nfaces = refiner->GetNumFaces(0);
- int nfaces = mesh->GetNumCoarseFaces();
- for (int i = 0; i < nfaces; ++i) {
- OsdHbrFace * f = mesh->GetFace(i);
+ for (int face = 0; face < nfaces; ++face) {
- float const * p0 = &pos[f->GetVertex(0)->GetID()*3],
- * p1 = &pos[f->GetVertex(1)->GetID()*3],
- * p2 = &pos[f->GetVertex(2)->GetID()*3];
+ IndexArray fverts = refiner->GetFaceVertices(0, face);
+
+ float const * p0 = &pos[fverts[0]*3],
+ * p1 = &pos[fverts[1]*3],
+ * p2 = &pos[fverts[2]*3];
float n[3];
cross(n, p0, p1, p2);
- for (int j = 0; j < f->GetNumVertices(); j++) {
- int idx = f->GetVertex(j)->GetID() * 3;
+ for (int vert = 0; vert < fverts.size(); ++vert) {
+ int idx = fverts[vert] * 3;
result[idx ] += n[0];
result[idx+1] += n[1];
result[idx+2] += n[2];
@@ -318,45 +319,56 @@ updateGeom() {
//-------------------------------------------------------------------------------
static void
-fitFrame()
-{
+fitFrame() {
g_pan[0] = g_pan[1] = 0;
g_dolly = g_size;
}
//-------------------------------------------------------------------------------
-template
-OpenSubdiv::HbrMesh