Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,337 @@
#
# Copyright 2013 Pixar
#
# Licensed under the terms set forth in the LICENSE.txt file available at
# https://opensubdiv.org/license.
#
# Doxygen documentation
if (DOXYGEN_FOUND)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/OpenSubdiv.doxy" "${CMAKE_CURRENT_BINARY_DIR}/OpenSubdiv.doxy" @ONLY)
add_custom_target(doc_doxy
${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/OpenSubdiv.doxy"
WORKING_DIRECTORY
"${OpenSubdiv_BINARY_DIR}/public_headers/"
DEPENDS
public_headers
COMMENT
"Generating API documentation with Doxygen" VERBATIM
)
list(APPEND DOC_TARGETS doc_doxy)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/doxy_html"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
else()
message(WARNING
"Doxyen was not found : support for Doxygen automated API documentation is disabled.")
endif()
# ReST - HTML documentation
if (DOCUTILS_FOUND AND Python_Interpreter_FOUND)
set(HTML_FILES
search.html
)
set(RST_FILES
additional_resources.rst
api_overview.rst
bfr_overview.rst
cmake_build.rst
code_examples.rst
compatibility.rst
contributing.rst
dxviewer.rst
dxptexviewer.rst
far_overview.rst
getting_started.rst
glevallimit.rst
glfvarviewer.rst
glpainttest.rst
glptexviewer.rst
glsharetopology.rst
glstencilviewer.rst
glviewer.rst
hedits.rst
hbr_overview.rst
intro.rst
license.rst
mod_notes.rst
mtlviewer.rst
mtlptexviewer.rst
osd_overview.rst
osd_shader_interface.rst
porting.rst
references.rst
release_30.rst
release_31.rst
release_32.rst
release_33.rst
release_34.rst
release_35.rst
release_36.rst
release_37.rst
release_notes.rst
release_notes_2x.rst
sdc_overview.rst
subdivision_surfaces.rst
tutorials.rst
using_osd_hbr.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_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)
set(infile "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${BASENAME}.html")
add_custom_command(
OUTPUT
"${outfile}"
COMMAND
"${RST2HTML_EXECUTABLE}"
ARGS
--date
--time
--no-xml-declaration
--initial-header-level=3
--strip-comments
--template="${CMAKE_CURRENT_BINARY_DIR}/rst_template.txt"
--stylesheet=css/rst.css
--link-stylesheet
"${infile}" "${outfile}"
DEPENDS
"${infile}" rst_template.txt nav_template.txt
)
add_custom_target(${src} DEPENDS "${outfile}")
list(APPEND RST_TARGETS ${src})
install(
FILES
"${outfile}"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
PERMISSIONS
OWNER_READ GROUP_READ WORLD_READ
)
endforeach()
# Generate tutorials pages
# XXXX manuelk we should push more of this logic into the python script
set(TUTORIAL_CODE
hbr/tutorial_0/hbr_tutorial_0.cpp
hbr/tutorial_1/hbr_tutorial_1.cpp
hbr/tutorial_2/hbr_tutorial_2.cpp
far/tutorial_1_1/far_tutorial_1_1.cpp
far/tutorial_1_2/far_tutorial_1_2.cpp
far/tutorial_2_1/far_tutorial_2_1.cpp
far/tutorial_2_2/far_tutorial_2_2.cpp
far/tutorial_2_3/far_tutorial_2_3.cpp
far/tutorial_3_1/far_tutorial_3_1.cpp
far/tutorial_4_1/far_tutorial_4_1.cpp
far/tutorial_4_2/far_tutorial_4_2.cpp
far/tutorial_4_3/far_tutorial_4_3.cpp
far/tutorial_5_1/far_tutorial_5_1.cpp
far/tutorial_5_2/far_tutorial_5_2.cpp
far/tutorial_5_3/far_tutorial_5_3.cpp
bfr/tutorial_1_1/bfr_tutorial_1_1.cpp
bfr/tutorial_1_2/bfr_tutorial_1_2.cpp
bfr/tutorial_1_3/bfr_tutorial_1_3.cpp
bfr/tutorial_1_4/bfr_tutorial_1_4.cpp
bfr/tutorial_1_5/bfr_tutorial_1_5.cpp
bfr/tutorial_2_1/bfr_tutorial_2_1.cpp
bfr/tutorial_2_2/bfr_tutorial_2_2.cpp
bfr/tutorial_3_1/bfr_tutorial_3_1.cpp
bfr/tutorial_3_2/bfr_tutorial_3_2.cpp
osd/tutorial_0/osd_tutorial_0.cpp
)
foreach(tutorial ${TUTORIAL_CODE})
get_filename_component(BASENAME ${tutorial} NAME_WE)
string(REGEX REPLACE "(/)" "_" TARGET_NAME ${tutorial})
set(infile "${OpenSubdiv_SOURCE_DIR}/tutorials/${tutorial}")
set(rstfile "${CMAKE_CURRENT_BINARY_DIR}/${BASENAME}.rst")
set(htmlfile "${CMAKE_CURRENT_BINARY_DIR}/${BASENAME}.html")
# Process C++ code to ReST
add_custom_command(
OUTPUT
"${rstfile}"
COMMAND
"${Python_EXECUTABLE}"
ARGS
"${CMAKE_CURRENT_SOURCE_DIR}/processTutorials.py"
"${infile}"
"${rstfile}"
"${tutorial}"
DEPENDS
${infile}
"${CMAKE_CURRENT_SOURCE_DIR}/processTutorials.py"
)
# Convert ReST to HTML
add_custom_command(
OUTPUT
"${htmlfile}"
COMMAND
"${RST2HTML_EXECUTABLE}"
ARGS
--date
--time
--no-xml-declaration
--initial-header-level=3
--strip-comments
--template="${CMAKE_CURRENT_BINARY_DIR}/rst_template.txt"
--stylesheet=css/rst.css
--link-stylesheet
"${rstfile}" "${htmlfile}"
DEPENDS
"${rstfile}" rst_template.txt nav_template.txt
)
list(APPEND RST_TARGETS ${TARGET_NAME})
add_custom_target(${TARGET_NAME} DEPENDS "${htmlfile}")
install(
FILES
"${htmlfile}"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
PERMISSIONS
OWNER_READ GROUP_READ WORLD_READ
)
endforeach()
# Copy html files to the build area
foreach(src ${HTML_FILES})
set(infile "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${src}")
add_custom_command(
OUTPUT
"${outfile}"
COMMAND
"${CMAKE_COMMAND}"
ARGS
-E copy "${infile}" "${outfile}"
)
# Exclude generated search.html
if (NOT ${src} STREQUAL "search.html")
add_custom_target( ${src} DEPENDS "${outfile}")
endif()
list(APPEND HTML_TARGETS ${src})
install(
FILES
"${outfile}"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
endforeach()
# 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
"${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/images" "${CMAKE_CURRENT_BINARY_DIR}/images"
)
add_custom_target(doc_html_css
COMMAND
${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/css" "${CMAKE_CURRENT_BINARY_DIR}/css"
)
add_custom_target(doc_tipuesearch
COMMAND
${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/tipuesearch" "${CMAKE_CURRENT_BINARY_DIR}/tipuesearch"
)
# build search index and insert navigation tab
add_custom_target(search_index
COMMAND
"${Python_EXECUTABLE}"
"${CMAKE_CURRENT_SOURCE_DIR}/processHtml.py"
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/nav_template.txt"
DEPENDS
${HTML_TARGETS}
${RST_TARGETS}
"${CMAKE_CURRENT_SOURCE_DIR}/processHtml.py"
doc_tipuesearch
)
add_custom_target(doc_html
DEPENDS
search_index
${HTML_TARGETS}
${RST_TARGETS}
doc_html_images
doc_html_css
doc_tipuesearch
)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/tipuesearch"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/images"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/css"
DESTINATION
"${CMAKE_DOCDIR_BASE}"
)
list(APPEND DOC_TARGETS doc_html)
endif()
add_custom_target(doc ALL DEPENDS ${DOC_TARGETS})

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
ReST Documentation
==================
Editing the navigation tab
--------------------------
Edit the file 'nav_template.txt'. It is injected by the python script
'processHtml.py' in the HTML generated by rst2html (docutils).
Note: html comments will be stripped (removes the license text)
Inserting content in <head>
---------------------------
Edit the file 'rst_template.txt' and add HTML in the %(head) section (see
the "favicon" link for reference). Other sections can be similarly accessed.
Diagrams
--------
Use diagrams.odg in OpenOfficeDraw to edit the new diagrams. Use the export
function to generate bitmaps in the images/ directory.
Styling
-------
The css sheet is in css/rst.css
Doxygen Documentation
=====================
Styling
-------
The css sheet is in css/doxy.css

View File

@@ -0,0 +1,65 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Additional Resources
--------------------
.. contents::
:local:
:backlinks: none
----
Videos
======
Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces (2012)
***************************************************************************
.. image:: https://graphics.pixar.com/opensubdiv/videothumbnails/feature_adaptive_siggraph2012.png
:align: center
:width: 75%
:target: https://www.youtube.com/embed/uogAzQoVdNU
Open Subdivision Technology Review (2012)
*****************************************
.. image:: https://graphics.pixar.com/opensubdiv/videothumbnails/opensubdiv_intro_autodesk2012.png
:align: center
:width: 75%
:target: https://www.youtube.com/embed/Y-3L9BOTEtw
Autodesk User Group At Anaheim (2013)
*************************************
.. image:: https://graphics.pixar.com/opensubdiv/videothumbnails/opensubdiv_demo_autodesk2013.png
:align: center
:width: 75%
:target: https://www.youtube.com/embed/9lFwFoCxysI
Why Model with Subdivisions (2013)
**********************************
.. image:: https://graphics.pixar.com/opensubdiv/videothumbnails/subdiv_modeling_pixar2013.png
:align: center
:width: 75%
:target: https://player.vimeo.com/video/70600180
Meet the Experts: The OpenSubdiv Project (2013)
***********************************************
.. image:: https://graphics.pixar.com/opensubdiv/videothumbnails/meet_the_experts_autodesk2013.png
:align: center
:width: 75%
:target: https://www.youtube.com/embed/xFZazwvYc5o
Join special guests, Bill Polson, Dirk Van Gelder, Manuel Kraemer,
Takahito Tejima, David G. Yu and Dale Ruffolo, from Pixar Animation
Studios' GPU team, as they show how real time display of subdivision
surfaces helps artists be more productive, and how this code is open
source and engineered for ease of integration.

View File

@@ -0,0 +1,259 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
API Overview
------------
.. contents::
:local:
:backlinks: none
.. image:: images/osd_splash.png
:align: center
:target: images/osd_splash.png
API Layers
==========
OpenSubdiv is structured as a set of layered libraries. This structure facilitates
operation on a variety of computing resources, and allows developers to only opt-in
to the layers and feature sets that they require.
From a top-down point of view, OpenSubdiv is comprised of several layers,
some public, and some private.
Layers list:
+-----------------------------------------+--------------------------------------------------------------------------------+
| | **Sdc** |The lowest level layer, implements the core subdivision details |
| | Subdivision Core |to facilitate the generation of consistent results. Most cases will only |
| | `Sdc Overview <sdc_overview.html>`__ |require the use of simple public types and constants from Sdc. |
+-----------------------------------------+--------------------------------------------------------------------------------+
| | **Vtr** | A suite of classes to provide an intermediate |
| | Vectorized Topological Representation | representation of topology that supports efficient refinement. |
| | `Vtr Overview <vtr_overview.html>`__ | *Vtr* is intended for internal use only. |
+-----------------------------------------+--------------------------------------------------------------------------------+
| | **Far** | |
| | Feature Adaptive Representation | The central interface that processes client-supplied |
| | `Far Overview <far_overview.html>`__ | geometry and turns it into a serialized data |
| | representation ready for parallel processing in *Osd*. |
| | *Far* also provides a fully-featured single-threaded |
| | implementation of subdivision interpolation algorithms. |
+-----------------------------------------+--------------------------------------------------------------------------------+
| | **Bfr** | A suite of classes to provide parameterization, evaluation |
| | Base Face Representation | and tessellation on the CPU. *Bfr* is more flexible and more |
| | `Bfr Overview <bfr_overview.html>`__ | scalable than *Osd* but potentially less efficient. |
+-----------------------------------------+--------------------------------------------------------------------------------+
| | **Osd** | |
| | OpenSubdiv cross platform | A suite of classes to provide parallel subdivision |
| | `Osd Overview <osd_overview.html>`__ | kernels and drawing utilities on a variety of platforms |
| | such as TBB, CUDA, OpenCL, GLSL and DirectX. |
+-----------------------------------------+--------------------------------------------------------------------------------+
Client mesh data enters the API through the Far layer. Typically, results will
be collected from the Osd layer. However, it is possible to use
functionality from Far without introducing any dependency on 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.
.. image:: images/api_layers_3_0.png
:align: center
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 are use cases 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. |
+----------------------+-------------------------------------------------------+
Use case 1: Simple refinement
=============================
The following example shows the most simple case to get your mesh refined uniformly.
.. image:: images/usecase1_image.png
.. image:: images/usecase1.png
:align: center
1. Define a class for the primvar you want to refine.
It's required to have Clear() and AddWithWeight() functions.
.. code:: c++
struct Vertex {
void Clear() { x = y = z = 0; }
void AddWithWeight(Vertex const &src, float weight) {
x += weight * src.x;
y += weight * src.y;
z += weight * src.z;
}
float x, y, z;
};
2. Instantiate a `Far::TopologyRefiner <far_overview.html#far-topologyrefiner>`_
from the `Far::TopologyDescriptor <far_overview.html#far-topologyrefinerfactory>`_.
.. code:: c++
Far::TopologyDescriptor desc;
desc.numVertices = <the number of vertices>
desc.numFaces = <the number of faces>
desc.numVertsPerFace = <array of the number of verts per face>
desc.vertIndicesPerFace = <array of vert indices>
Far::TopologyRefiner * refiner = Far::TopologyRefinerFactory<Descriptor>::Create(desc);
3. Call RefineUniform() to refine the topology up to 'maxlevel'.
.. code:: c++
refiner->RefineUniform(Far::TopologyRefiner::UniformOptions(maxlevel));
4. Interpolate vertex primvar data at 'level' using
`Far::PrimvarRefiner <far_overview.html#far-primvarrefiner>`_
.. code:: c++
Far::PrimvarRefiner primvarRefiner(*refiner);
Vertex const *src = <coarse vertices>
Vertex *dst = <refined vertices>
primvarRefiner.Interpolate(level, src, dst);
5. The topology at the refined level can be obtained from Far::TopologyLevel
.. code:: c++
Far::TopologyLevel const & refLastLevel = refiner->GetLevel(maxlevel);
int nverts = refLastLevel.GetNumVertices();
int nfaces = refLastLevel.GetNumFaces();
for (int face = 0; face < nfaces; ++face) {
Far::ConstIndexArray fverts = refLastLevel.GetFaceVertices(face);
// do something with dst and fverts
}
6. Done! See `Far tutorial 1.1 <far_tutorial_1_1.html>`__ for the complete code example.
Use case 2: GL adaptive tessellation drawing of animating mesh
==============================================================
The next example is showing how to draw adaptive tessellated patches in GL using OpenSubdiv.
The osd layer helps you to interact with GL and other device specific APIs. Also for an
efficient refinement of animating mesh on a static topology, we create a stencil table to
refine the positions changing over time.
The following example code uses an Osd::GLMesh utility class which composites a stencil
table, patch table, vertex buffer and evaluator in osd layer. You can also use those classes
independently.
.. image:: images/usecase2.png
:align: center
1. Instantiate a `Far::TopologyRefiner <far_overview.html#far-topologyrefiner>`_ from the
`Far::TopologyDescriptor <far_overview.html#far-topologyrefinerfactory>`_, same as usecase 1.
2. Setup Osd::Mesh. In this example we use b-spline endcap.
.. code:: c++
int numVertexElements = 3; // x, y, z
Osd::MeshBitset bits;
bits.set(Osd::MeshAdaptive, true); // set adaptive
bits.set(Osd::MeshEndCapBSplineBasis, true); // use b-spline basis patch for endcap.
Osd::GLMeshInterface *mesh = new Osd::Mesh<Osd::CpuGLVertexBuffer, Far::StencilTable,
Osd::CpuEvaluator, Osd::GLPatchTable>
(refiner, numVertexElements, 0, level, bits);
3. Update coarse vertices and refine (Osd::Mesh::Refine() calls
`Osd::CpuEvaluator::EvalStencils() <osd_overview.html#refinement>`_)
.. code:: c++
mesh->UpdateVertexBuffer(&vertex[0], 0, nverts);
mesh->Refine();
4. Bind index buffer, PatchParamBuffer and vertex buffer
.. code:: c++
// index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetPatchTable()->GetPatchIndexBuffer());
// vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, mesh->BindVertexBuffer());
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, numVertexElements, GL_FLOAT, GL_FALSE,
numVertexElements*sizeof(float), 0);
// patch param buffer
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER, mesh->GetPatchTable()->GetPatchParamTextureBuffer());
5. Draw. Since we use b-spline endcaps in this example, there is only one PatchArray in the patch table. You may need to iterate patch arrays as you use other type of endcap. To configure GLSL program for each patch type, see `osd shader interface <osd_shader_interface.html>`__ for more details.
.. code:: c++
Osd::PatchArray const & patch = mesh->GetPatchTable()->GetPatchArrays()[0];
Far::PatchDescriptor desc = patch.GetDescriptor();
int numVertsPerPatch = desc.GetNumControlVertices(); // 16 for B-spline patches
glUseProgram(BSplinePatchProgram);
glPatchParameteri(GL_PATCH_VERTICES, numVertsPerPatch);
glDrawElements(GL_PATCHES, patch.GetNumPatches() * numVertsPerPatch,
GL_UNSIGNED_INT, 0);
6. As the mesh animates, repeat from step 3 to update positions, refine, and draw.
See `glViewer <glviewer.html>`__ and other examples for more complete usage.
Tutorials and Examples
======================
For more use cases, please see `Tutorials <tutorials.html>`_ and `Examples <code_examples.html>`_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,334 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Building with CMake
-------------------
.. contents::
:local:
:backlinks: none
----
Overview
========
Assuming that you have `cloned <getting_started.html>`__ the source repository
and selected an appropriate release branch, the following instructions will
walk you through the CMake 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
Makefiles and workspaces that are native to the platform of choice.
The process involves the following steps:
#. 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
discovered and will disable certain features and code examples accordingly.
Please refer to the documentation of each of the dependency packages for specific
build and installation instructions.
Required
________
- `CMake <https://www.cmake.org/>`__ version 3.14
Optional OpenSubdiv::Osd Dependencies
_____________________________________
- `OpenGL <https://www.opengl.org>`__
- `Metal <https://developer.apple.com/metal>`__
- `CUDA <https://developer.nvidia.com/cuda-toolkit>`__
- `TBB <https://github.com/uxlfoundation/oneTBB>`__
- `OpenCL <https://www.khronos.org/opencl/>`__
- `DX11 SDK <https://www.microsoft.com/en-us/download/details.aspx?id=6812>`__
Optional Interactive Example Dependencies
_________________________________________
- `GLFW <https://www.glfw.org>`__ (for OpenGL example viewers and some regression tests)
- `Ptex <https://ptex.us/>`__ (for Ptex example viewers)
- `Zlib <https://www.zlib.net/>`__ (for Ptex example viewers)
Optional Documentation Dependencies
___________________________________
- `Doxygen <http://www.doxygen.org/>`__ (for C++ API documentation)
- `Docutils <https://pypi.org/project/docutils>`__ (for reStructuredText documentation)
- `Python Pygments <https://pypi.org/project/Pygments>`__ (for reStructuredText documentation styling)
----
Step 2: Configuring CMake
=========================
One way to configure CMake is to use the `CMake GUI <https://cmake.org/cmake/help/latest/manual/cmake-gui.1.html>`__.
In many cases CMake can fall back on default standard paths in order to find the
packages that OpenSubdiv depends on. For non-standard installations however, a
complete set of override variables is available. The following sub-section lists
some of these variables. For more specific details, please consult the source of
the custom CMake modules in the OpenSubdiv/cmake/ folder.
Useful Build Options
____________________
The following configuration arguments can be passed to the CMake command line.
.. code:: c++
-DCMAKE_BUILD_TYPE=[Debug|Release]
-DCMAKE_INSTALL_PREFIX=[base path to install OpenSubdiv (default: Current directory)]
-DCMAKE_LIBDIR_BASE=[library directory basename (default: lib)]
-DCMAKE_SYSTEM_NAME=[target system name for cross-compilation builds, e.g. iOS]
-DCMAKE_PREFIX_PATH=[semicolon-separated list of directories specifying installation prefixes to be searched by the find_package() command (default: empty list)]
-DCUDA_SDK_ROOT_DIR=[path to CUDA]
-DCUDA_TOOLKIT_ROOT_DIR=[path to CUDA]
-DOSD_CUDA_NVCC_FLAGS=[CUDA options, e.g. --gpu-architecture]
-DGLFW_LOCATION=[path to GLFW for OpenGL example viewers]
-DPTEX_LOCATION=[path to Ptex for Ptex example viewers]
-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_PTEX=1 // disable Ptex examples
-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_CLEW=1 // disable OpenCL loader library
-DNO_OPENGL=1 // disable OpenGL
-DNO_METAL=1 // disable Metal
-DOSD_PATCH_SHADER_SOURCE_GLSL=1 // GLSL Patch Shader Source
-DOSD_PATCH_SHADER_SOURCE_HLSL=1 // HLSL Patch Shader Source
-DOSD_PATCH_SHADER_SOURCE_MSL=1 // MSL Patch Shader Source
Environment Variables
_____________________
The paths to GLFW, Ptex, Zlib, and other dependencies can also be specified
through the following environment variables:
.. code:: c++
GLFW_LOCATION, PTEX_LOCATION, ZLIB_ROOT
Automated Script
________________
The GUI solution will probably become a burden for active developpers who tend to
re-run the configuration step fairly often. A scripted solution can save a lot of
time. Here is a typical workflow:
.. code:: c++
git clone https://github.com/PixarAnimationStudios/OpenSubdiv.git <folder>
cd <folder>
source cmake_setup
Where *cmake_setup* is a configuration script.
.. container:: impnotip
**Important**
Notice that the following scripts start by **recursively removing** the *buildDir* and
*instDir* directories. Make sure you modify them to suit your build workflow.
Here is an example CMake configuration script for a full typical windows-based
build that can be run in GitShell :
.. code:: c++
echo "*** Removing build"
rm -rf buildDir instDir
echo "*** Running cmake"
cmake -B buildDir \
-D CMAKE_INSTALL_PREFIX=instDir \
-G "Visual Studio 16 2019" -A x64 \
-D "GLFW_LOCATION=C:\path\to\glwf" \
-S .
Here is a similar script for \*Nix-based platforms:
.. code:: c++
echo "*** Removing build"
rm -rf buildDir instDir
echo "*** Running cmake"
cmake -B buildDir \
-D CMAKE_INSTALL_PREFIX=instDir \
-D "GLFW_LOCATION=/path/to/glfw" \
-S .
Here is a similar script for macOS:
.. code:: c++
echo "*** Removing build"
rm -rf buildDir instDir
echo "*** Running cmake"
cmake -B buildDir \
-D CMAKE_INSTALL_PREFIX=instDir \
-G Xcode \
-D "GLFW_LOCATION=/path/to/glfw" \
-S .
Here is a similar script for iOS:
Use CMAKE_SYSTEM_NAME to have CMake use the appropriate cross-compilation toolchain when building for iOS.
.. code:: c++
echo "*** Removing build"
rm -rf buildDir instDir
echo "*** Running cmake"
SDKROOT=$(xcrun --sdk iphoneos --show-sdk-path)
cmake -B buildDir \
-D CMAKE_INSTALL_PREFIX=instDir \
-G Xcode \
-D CMAKE_SYSTEM_NAME=iOS \
-D NO_PTEX=1 -D NO_DOC=1 \
-D NO_OMP=1 -D NO_TBB=1 -D NO_CUDA=1 -D NO_OPENCL=1 -D NO_CLEW=1 \
-D NO_TUTORIALS=1 -D NO_EXAMPLES=1 -D NO_REGRESSION=1 -D NO_OPENGL=1 \
-S .
Using Intel's C++ Studio XE
___________________________
OpenSubdiv can be also be built with `Intel's C++ compiler <http://software.intel.com/en-us/intel-compilers>`__
(icc). The default compiler can be overriden in CMake with the following configuration options:
.. code:: c++
-DCMAKE_CXX_COMPILER=[path to icc executable]
-DCMAKE_C_COMPILER=[path to icc executable]
The installation location of the C++ Studio XE can be overriden with:
.. code:: c++
-DICC_LOCATION=[path to Intel's C++ Studio XE]
Using Clang
___________
CMake can also be overriden to use the `clang <http://clang.llvm.org/>`__ compilers by configuring the following options:
.. code:: c++
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_COMPILER=clang \
----
Step 3: Building
================
CMake provides a cross-platform command-line build:
.. code:: c++
cmake --build buildDir --target install --config Release
Alternatively, you can use native toolkits to launch the build. The steps differ for each OS:
* *Windows* :
launch VIsual Studio IDE with the solution generated by CMake in your build directory.
* *macOS* :
launch Xcode with the xcodeproj generated by CMake 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
----
Build Targets
_____________
Makefile-based builds allow the use of named target. Here are some of the more
useful target names:
*osd_\<static\|dynamic\>_\<CPU\|GPU\>*
| The core components of the OpenSubdiv libraries
|
*\<example_name\>*
| Builds specific code examples by name (glViewer, ptexViewer...)
|
*doc*
| Builds ReST and doxygen documentation
|
*doc_html*
| Builds ReST documentation
|
*doc_doxy*
| Builds Doxygen documentation
|
----
Compiling & Linking an OpenSubdiv Application
=============================================
Here are example commands for building an OpenSubdiv application on several architectures:
**Linux**
::
g++ -I$OPENSUBDIV/include -c myapp.cpp
g++ myapp.o -L$OPENSUBDIV/lib -losdGPU -losdCPU -o myapp
**macOS**
::
g++ -I$OPENSUBDIV/include -c myapp.cpp
g++ myapp.o -L$OPENSUBDIV/lib -losdGPU -losdCPU -o myapp
install_name_tool -add_rpath $OPENSUBDIV/lib myapp
(On 64-bit OS-X: add ``-m64`` after each ``g++``.)
**Windows**
::
cl /nologo /MT /TP /DWIN32 /I"%OPENSUBDIV%\include" -c myapp.cpp
link /nologo /out:myapp.exe /LIBPATH:"%OPENSUBDIV%\lib" libosdGPU.lib libosdCPU.lib myapp.obj
.. container:: impnotip
**Note:**
HBR uses the offsetof macro on a templated struct, which appears to spurriously set off a
warning in both gcc and Clang. It is recommended to turn the warning off with the
*-Wno-invalid-offsetof* flag.

View File

@@ -0,0 +1,86 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Code Examples
-------------
Standalone Viewers
==================
OpenSubdiv builds a number of standalone viewers that demonstrate various aspects
of the software.
----
.. list-table:: **OpenGL examples**
:class: quickref
:widths: 50 50
* - | `glViewer <glviewer.html>`_
| `glFVarViewer <glfvarviewer.html>`_
| `glEvalLimit <glevallimit.html>`_
| `glStencilViewer <glstencilviewer.html>`_
- | `glPtexViewer <glptexviewer.html>`_
| `glPaintTest <glpainttest.html>`_
| `glShareTopology <glsharetopology.html>`_
.. list-table:: **DirectX examples**
:class: quickref
* - | `dxViewer <dxviewer.html>`_
- | `dxPtexViewer <dxptexviewer.html>`_
.. list-table:: **Metal examples**
:class: quickref
:widths: 50 50
* - | `mtlViewer <mtlviewer.html>`_
- | `mtlPtexViewer <mtlptexviewer.html>`_
----
Common Command Line Options
===========================
While the following command line options are common, not all examples support
all -- in some cases, certain options are not applicable.
::
-f : launches the application in full-screen mode (if supported)
-yup : set initial view with Y-axis up (Z-up is the default)
-u : apply uniform subdivision to all meshes
-a : apply adaptive subdivision to create patches for the limit surface
-l depth : level of uniform or adaptive refinement to apply
-c count : number of repetitions of the animation loop when supported (default
of 0 is infinite)
-anim : interpret a given set of Obj files as an animated sequence rather
than a set of distinct meshes
-catmark : apply the Catmark scheme to all meshes in given Obj files (default)
-loop : apply the Loop scheme to all meshes in given Obj files
-bilinear : apply the Bilinear scheme to all meshes in given Obj files
objfile(s) : a set of one or more meshes in Obj format (requiring a .obj extension)
that may be distinct meshes or animated versions of a single mesh
----
Common Keyboard Controls
========================
::
Left mouse button drag : orbit camera
Middle mouse button drag : pan camera
Right mouse button : dolly camera
n, p : next/prev model
1, 2, 3, ..., 9, 0 : specify adaptive isolation or uniform refinement level
+, - : increase / decrease tessellation
Tab : toggle full-screen
Esc : turn on / off the HUD
w : switch display mode
q : quit

View File

@@ -0,0 +1,430 @@
..
Copyright 2015 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Subdivision Compatibility
-------------------------
.. contents::
:local:
:backlinks: none
Subdivision Compatibility
=========================
This document highlights areas of compatibility with other software that makes
use of subdivision surfaces, including previous versions of OpenSubdiv.
The "compatibility" here refers to the choice of subdivision rules that define
the shape of the resulting surfaces. Different subdivision rules will lead to
different shapes. Choices affecting shape include:
* the types of subdivision schemes supported (e.g. Catmull-Clark, Loop, etc.)
* the basic rules applied for these schemes
* any extended rules to affect sharpness or creasing
* rules applied separately to face-varying data
Ensuring all of these rules are consistent provides the basis for consistent
shapes, but further approximations to the limit surface create the potential
for subtle deviations. Even within OpenSubdiv, multiple approximations are
possible and vary. For now we focus on the compatibility of subdivision rules
and deal with the limit approximations only when noteworthy.
Compatibility with OpenSubdiv 2.x
=================================
The refactoring of OpenSubdiv 3.0 data representations presented a unique
opportunity to revisit some corners of the subdivision specification and
remove or update some legacy features.
**Face-varying Interpolation Options**
Face-varying interpolation options have been consolidated into a single enum
with one additional choice new to 3.0. No functionality from 2.x has been
removed -- just re-expressed in a simpler and more comprehensible form.
Face-varying interpolation was previously defined by a "boundary interpolation"
enum with four modes and an additional boolean "propagate corners" option,
which was little understood, i.e.:
* void HbrMesh::SetFVarInterpolateBoundarMethod(InterpolateBoundaryMethod) const;
* void HbrMesh::SetFVarPropagateCorners(bool) const;
The latter was only used in conjunction with one
of the four modes ("edge and corner"), so it was effectively a unique fifth
choice. Closer inspection of all of these modes also revealed some unexpected
and undesirable behavior in some common cases -- to an extent that could not
simply be changed -- and so an additional mode was added to avoid such behavior.
All choices are now provided through a single "linear interpolation" enum,
described and illustrated in more detail in the overview of
`Face-Varying Interpolation <subdivision_surfaces.html#face-varying-interpolation-rules>`__.
The use of "boundary" in the name of the enum was intentionally removed
as the choice also affects interior interpolation. The new use of "linear"
is now intended to reflect the fact that interpolation is constrained to be
linear where specified by the choice applied.
All five of Hbr's original modes of face-varying interpolation are supported
(with minor modifications where Hbr was found to be incorrect in the presence
of semi-sharp creasing). An additional mode ("corners only") has also been
added to avoid some of the undesired side-effects of some existing modes
(illustrated below).
The new values for the *"Sdc::Options::FVarLinearInterpolation"* enum and its
equivalents for HbrMesh's InterpolateBoundaryMethod and PropagateCorners flag
are as follows (ordered such that the set of linear constraints applied is
always increasing -- from completely smooth to completely linear):
============================ ================================== =========================
Sdc FVarLinearInterpolation Hbr FVarInterpolateBoundaryMethod Hbr FVarPropogateCorners
============================ ================================== =========================
FVAR_LINEAR_NONE k_InterpolateBoundaryEdgeOnly N/A (ignored)
FVAR_LINEAR_CORNERS_ONLY N/A N/A
FVAR_LINEAR_CORNERS_PLUS1 k_InterpolateBoundaryEdgeAndCorner false
FVAR_LINEAR_CORNERS_PLUS2 k_InterpolateBoundaryEdgeAndCorner true
FVAR_LINEAR_BOUNDARIES k_InterpolateBoundaryAlwaysSharp N/A (ignored)
FVAR_LINEAR_ALL k_InterpolateBoundaryNone N/A (ignored)
============================ ================================== =========================
Aside from the two "corners plus" modes that preserve Hbr behavior, all other
modes are designed so that the interpolation of a disjoint face-varying region
is not affected by changes to other regions that may share the same vertex. So
the behavior of a disjoint region should be well understood and predictable
when looking at it in isolation (e.g. with "corners only" one would expect to
see linear constraints applied where there are topological corners or infinitely
sharp creasing applied within the region, and nowhere else).
This is not true of the "plus" modes, and they are named to reflect the fact
that more is taken into account where disjoint regions meet.
The following example illustrates some undesired effects of the "plus" modes,
which in part motivated the addition of the new "corners only" mode. The
example uses the "catmark_fvar_bound0" and "catmark_fvar_bound1" shapes from
the suite of regression shapes. Both shapes are a simple regular 4x4 grid of
quads with face-varying UV data partitioned into multiple disjoint regions.
The "bound0" shape has two disjoint UV regions -- an upper and lower region --
while the "bound1" shape further splits the lower region in two.
This first figure illustrates the effect of the original "plus1" mode (which
is also the same for "plus2"):
.. image:: images/fvar_corners_plus1.png
:align: center
:width: 60%
:target: images/fvar_corners_plus1.png
Note that the effect of splitting the lower UV region in two has the undesired
side effect of sharpening the boundary of the upper region. This is the result
of the "plus1" mode making collective decisions about the sharpness of all
face-varying boundaries at the vertex rather than decisions local to each
region. In both the "plus1" and "plus2" cases, all face-varying boundaries
sharing a vertex will be sharpened if there are more than two regions meeting
at that vertex.
The second figure illustrates the effect of the new "corners only" mode:
.. image:: images/fvar_corners_only.png
:align: center
:width: 60%
:target: images/fvar_corners_only.png
As expected, the splitting of the lower region does not impact the upper
region. In this case the decision to sharpen a face-varying boundary is made
based on the local topology of each region.
**Vertex Interpolation Options**
Since the various options are now presented through a new API (Sdc rather than
Hbr), based on the history of some of these options and input from interested
parties, the following changes have been implemented:
* The naming of the standard creasing method has been changed from *Normal*
to *Uniform*. Values for *"Sdc::Options::CreasingMethod"* are now:
============== ====================================
CREASE_UNIFORM standard integer subtraction per level (default)
CREASE_CHAIKIN Chaikin (non-uniform) averaging around vertices
============== ====================================
* Legacy modes of the *"smoothtriangle"* rule have been removed (as they
were never actually enabled in the code). Values for
*"Sdc::Options::TriangleSubdivision"* are now:
=============== =================
TRI_SUB_CATMARK Catmull-Clark weights (default)
TRI_SUB_SMOOTH "smooth triangle" weights
=============== =================
These should have little impact since one is a simple change in terminology
as part of a new API while the other was removal of an option that was never
used.
**Change to Chaikin creasing method**
In the process of re-implementing the Chaikin creasing method, observations
lead to a conscious choice to change the behavior of Chaikin creasing in the
presence of infinitely sharp edges (most noticeable at boundaries).
Previously, the inclusion of infinite sharpness values in the Chaikin method's
computation of edge sharpness around a vertex would prevent a
semi-sharp edge from decaying to zero. Infinitely sharp edges are now
excluded from the Chaikin (non-uniform) averaging yielding a much more
predictable and desirable result. For example, where the sharpness assignment
is actually uniform at such a vertex, the result will now behave the same as
the Uniform method.
Since this feature has received little use (only recently activated in
RenderMan), now seemed the best time to make the change before more widespread
adoption.
**Hierarchical Edits**
While extremely powerful, Hierarchical Edits come with additional maintenance
and implementation complexity. Support for them in popular interchange formats
and major DCC applications has either been dropped or was never implemented.
As a result, the need for Hierarchical Edits is too limited to justify the cost
and support for them, and they have therefore been removed from the 3.0 release
of OpenSubdiv. Dropping support for Hierarchical Edits allows for significant
simplifications of many areas of the subdivision algorithms.
While the 3.0 release does not offer direct support for Hierarchical Edits,
the architectural changes and direction of 3.0 still facilitate the application
of the most common value edits for those wishing to use them -- though not
always in the same optimized context. Of course, support for Hierarchical
Edits in the future will be considered based on demand and resources.
**Non-Manifold Topology**
OpenSubdiv 2.x and earlier was limited to dealing with meshes whose topology
was manifold -- a limitation imposed by the use of Hbr. With 3.0 no longer
using Hbr, the manifold restriction has also been removed.
OpenSubdiv 3.0, therefore, supports a superset of the meshes supported by 2.x
and earlier versions (with one known exception noted below).
Non-manifold meshes that are acceptable to 3.0 however will likely not work
with 2.x or earlier.
The one known case that 3.0 will not represent the same as 2.x is ironically
a case that is non-manifold, and for which Hbr did make special accommodation.
That case occurs at a non-manifold vertex where two or more faces meet
at a common vertex, but do not share a common edge, *and* when the boundary
interpolation mode is set for smooth corners (i.e. "edge only"), as
illustrated below:
.. image:: images/bowtie_vertex.png
:align: center
:width: 80%
:target: images/bowtie_vertex.png
The cage is on the left and is refined to level 2 on the right. On the immediate
right, boundary interpolation is set to sharp corners and the results appear
the same for 2.x and 3.0. The center and far right illustrate the affects of
setting boundary interpolation to smooth corners with 2.x and 3.0 respectively.
Note that the 2.x result allows the refined mesh (and so the limit surface) to
split into two while the 3.0 result keeps it connected.
When Hbr encounters such vertices, regardless of the boundary mode it "splits"
the vertex -- creating a separate instance of it for each face. So when
building an HbrMesh, after "finalizing" the mesh, it will result in having
more vertices than were originally defined (termed "split vertices").
OpenSubdiv 2.x (and earlier) successfully hid the presence of these extra
vertices from users.
This case behaves in such a way that violates certain properties of the
surface that 3.0 has attempted to emphasize. One of these relates to the
nature of the limit surface (and becomes more significant in the context of
face varying): if the cage is connected then so too is its limit surface,
or similarly, if the cage consists of *N* connected regions then the limit
surface similarly consists of *N* connected regions. Another undesirable
property here is that the vertex *V* at which these faces meet must have
more than one child vertex *V'*. This makes it difficult to "hide" split
vertices -- OpenSubdiv 2.x tables had an extra level of indirection that
made it possible to do this relatively easily, but 3.0 has dispensed with
such indirection where possible to streamline performance.
Compatibility with RenderMan
============================
Since RenderMan and OpenSubdiv versions prior to 3.0 share a common library
(Hbr), most differences between RenderMan and OpenSubdiv 3.0 are covered in the
preceding section of compatibility with OpenSubdiv 2.x.
In addition to some features between RenderMan and OpenSubdiv that are not
compatible, there are also other differences that may be present due to
differences in the implementations of similar features.
For most use cases, OpenSubdiv 3.0 is largely compatible with RenderMan. There
are however some cases where some differences can be expected. These are
highlighted below for completeness.
Incompatibilities
+++++++++++++++++
OpenSubdiv and RenderMan will be incompatible when certain features are used
that are not common to both. They are fully described in the 2.x compatibility
section and are listed briefly here.
**OpenSubdiv 3.0 Features Not Supported by RenderMan**
* Non-manifold meshes
* Choice of the "corners only" face varying interpolation option
**RenderMan Features Not Supported by OpenSubdiv 3.0**
* Hierarchical Edits
Other Differences
+++++++++++++++++
Some differences can occur due to the differing implementations of the
feature sets. Additionally, OpenSubdiv 3.0's implementation fixes some
issues discovered in Hbr.
**Smooth Face-Varying Interpolation with Creasing**
There have been two discrepancies noted in the way that face-varying data is
interpolated smoothly in the presence of creases. Smooth face-varying
interpolation is expected to match vertex interpolation in the interior and
only differ along the boundaries or discontinuities where the face-varying
topology is intentionally made to differ from the vertex topology.
A simple and effective way to identify discrepancies is to use the X and Y
coordinates of vertex positions as the U and V of texture coordinates. If
these U and V coordinates are assigned to a face-varying channel, smooth
interpolation of U and V is expected to exactly match interpolation of X
and Y, regardless of the presence of any sharpness and creasing.
Two discrepancies can be seen with Hbr when superimposing the XY vertex
interpolation with the "projected" UV face-varying interpolation.
The first discrepancy occurs with interpolation around dart vertices:
.. image:: images/fvar_hbr_dart.png
:align: center
:width: 80%
:target: images/fvar_hbr_dart.png
This example shows a simple regular XY grid on the left with an interior sharp
edge creating a dart vertex in the center. With no asymmetry in the vertices,
the sharpness has no asymmetric affect and the XY vertex interpolation on
the immediate right shows the regular grid expected from refinement. On the
far right is the UV interpolation from Hbr, which exhibits distortion around
the center dart vertex.
The second discrepancy occurs with interpolation involving any fractional
sharpness values. Hbr effectively ignores any fractional sharpness value
in its face-varying interpolation. So edges of vertices with sharpness of
say 2.5, will be treated as though their sharpness is 2.0 when face-varying
values are interpolated. Similarly, any non-zero sharpness value less than
1.0 is treated as zero by truncation and so is essentially ignored.
.. image:: images/fvar_hbr_integer.png
:align: center
:width: 80%
:target: images/fvar_hbr_integer.png
This example shows an asymmetric 2x2 grid of quads on the left with the center
vertex progressively sharpened from 0.5 to 1.0. The three cases of the vertex
smooth and sharpened are superimposed on the immediate right to display the
three distinct interpolation results. On the far right the interpolation from
Hbr displays the same three cases, but only two are visibly distinct -- the
sharpness of 0.5 being treated the same as if it were 0.0.
Both of these cases are corrected in OpenSubdiv 3.0. Smooth face-varying
interpolation in the presence of creasing should match the expected behavior
of the vertex interpolation, except where the face-varying topology is
explicitly made to differ.
**The Chaikin Creasing Method**
At least two discrepancies are know to exist between the implementations of
Hbr in RenderMan and OpenSubdiv 3.0:
* Use of Chaikin creasing with boundaries or infinitely sharp edges
* Subtle shape differences due to Hbr's use of "predictive sharpness"
Fortunately, this feature was only recently added to Hbr and RenderMan and is
little used, so it is expected these differences will have little impact.
The first discrepancy is mentioned briefly in the previous section on
compatibility between OpenSubdiv 2.x and 3.0. A conscious decision was
made to change the averaging of sharpness values involving infinitely
sharp edges in order to make results more predictable and favorable.
The effects can be seen comparing the regression shape "catmark_chaikin2".
The second is more subtle and results from an oversight within Hbr's
implementation that is not easily corrected.
When determining what subdivision rule to apply from one level to the
next, the sharpness values at the next level must be known in order to
determine whether or not a transition between differing rules is required.
If the rule at the next level differs from the previous, a combination of
the two is applied. Such a change results from the sharpness values of
one or more edges (or the vertex itself) decaying to zero.
Rather than compute the sharpness values at the next level accurately,
Hbr "predicts" it by simply subtracting 1.0 from it, as is done with the
uniform creasing method, and it bases decisions on that predicted result.
This does not work for Chaikin though. A sharpness value less than 1.0
may not decay to 0 if it is averaged with neighboring sharpness values
greater than 1.0, so this sharpness prediction can result in the wrong
rule being chosen for the next level.
A typical case would have the subdivision rules for Chaikin creasing
transition from Corner to Crease at one level, then from Crease to
Smooth at the next. Hbr's predictive creasing might mistakenly detect
the transition as Corner to Smooth at one level, then after properly
computing the sharpness values for the next level later, from Crease to
Smooth for the next. One of the regression shapes ("catmark_chakin1")
was disabled from the regression suite because of this effect. The
differences in shape that trigger its regression failure were
investigated and determined to be the result of this issue.
From observations thus far these differences are subtle but can be
noticeable.
**Numerical Precision**
Since its inception, OpenSubdiv has sought to produce results that were
numerically consistent to RenderMan. A regression suite to ensure a
certain level of accuracy was provided to detect any substantial deviation.
At some point in the development of OpenSubdiv, the point was made that
numerical accuracy of Hbr could be improved by changing the order of
operations and combining the vertex with the lowest coefficient first in
one of the subdivision rules. This was applied more thoroughly in the
independent implementation of 3.0 (there seemed no reason not to). In
most cases the relative magnitudes of the coefficients of subdivision and
limit masks is clear so no overhead was necessary to detect them.
At a certain point though, this greater accuracy came in conflict with the
regression suite. It turned out that high-valence vertices could not be
computed to within the desired tolerances set within the suite. The
summation of many small coefficients for the adjacent vertices first, before
the addition of the much larger coefficient for the primary vertex, allowed
for the accumulation of precision that was being truncated by adding the
much larger coefficient first in the Hbr implementation. With extremely
high valence vertices, a difference in magnitude between the most and least
significant coefficients of several orders of magnitude is likely, and that
has a significant impact on the single-precision floating point computations.
The improved accuracy of OpenSubdiv 3.0 can reach a magnitude that will
not go undetected. Whether or not this can lead to visual artifacts is
unclear.

View File

@@ -0,0 +1,124 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Contributing to OpenSubdiv
--------------------------
.. contents::
:local:
:backlinks: none
----
Contributor License Agreement
=============================
Before contributing code to OpenSubdiv, we ask that you sign a Contributor License
Agreement (CLA). At the root of the `repository
<https://github.com/PixarAnimationStudios/OpenSubdiv>`_ you can find the two possible CLAs:
#. `OpenSubdivCLA_corporate.pdf
<https://github.com/PixarAnimationStudios/OpenSubdiv/blob/release/OpenSubdivCLA_corporate.pdf>`_
: please sign this one for corporate use
#. `OpenSubdivCLA_individual.pdf
<https://github.com/PixarAnimationStudios/OpenSubdiv/blob/release/OpenSubdivCLA_individual.pdf>`_
: please sign this one if you're an individual contributor
Once your CLA is signed, send it to `opensubdiv-cla@pixar.com
<mailto:opensubdiv-cla@pixar.com>`__.
Understand Git
==============
First, you should familiarize yourself with the Git data model and commands.
For small changes you may not need to understand Git deeply, but for larger
changes or working with the codebase over a long period of time, it becomes
critical to understand more of what's going on under the hood.
There are many free resources on the internet, one which we've found useful is
the following e-book:
`<https://github.com/pluralsight/git-internals-pdf/releases>`_
Recommended Git Workflow
========================
Once you have a local development tree cloned and working, you can start making
changes. You will need to integrate changes from the source tree as you work;
the following outlines the workflow used by core OpenSubdiv engineers at Pixar
and DreamWorks:
#. Fork the repository into your own local copy. This can be done via the
GitHub website using the "fork" button.
#. Clone your fork locally:
| git clone <your_fork_url> OpenSubdiv.<your_name>
|
| e.g.:
| git clone https://github.com/yourusername/OpenSubdiv.git OpenSubdiv.yourusername
#. Setup two remotes, **origin** and **upstream**. Origin will be setup as a
result of cloning your remote repository, but upstream must be setup manually:
| git remote add **upstream** https://github.com/PixarAnimationStudios/OpenSubdiv.git
Verify your remotes are setup correctly:
| git remote -v
Which should look something like:
| origin https://github.com/yourusername/OpenSubdiv.git (fetch)
| origin https://github.com/yourusername/OpenSubdiv.git (push)
| upstream https://github.com/PixarAnimationStudios/OpenSubdiv.git (fetch)
| upstream https://github.com/PixarAnimationStudios/OpenSubdiv.git (push)
Finally, fetch the upstream content (this is required for the next step):
| git fetch upstream
#. Setup a new branch for each change. Working with branches in Git is its
greatest pleasure, we strongly suggest setting up a new branch for each
change which you plan to pull-request.
All work is done in the "dev" branch, so be sure to keep your change in sync
with this upstream branch. To begin, start your new branch from the dev
branch:
| git checkout -b dev-feature upstream/dev
#. As you are working on your feature, new changes will be merged into the
upstream repository, to sync these changes down and preserve your local
edits, you can continually rebase your local work:
| git pull --rebase upstream dev
Notice the "--rebase" option here. It updates the current branch to the
upstream/dev branch and rebases all edits so they are at the head of your
local feature branch.
Alternatively, you can rebase all your work at once when your feature is
complete.
Sending a Pull Request
======================
First, rebase and squash your changes appropriately to produce a clean set of
changes at the head of your tree. We require changes to be grouped locally to
ensure that rolling back changes can be done easily.
If you've followed the steps above, your pending change should already be queued
up as required. If you have not, you may need to rebase and squash changes at
this point.
Once the change is clean, push your changes to "origin" and go to the GitHub
website to submit your pull request.
Be sure to submit your request against the "dev" branch.

View File

@@ -0,0 +1,240 @@
/*
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
*/
/*-------------------------------GENERAL STYLES-------------------------------*/
html, body {
margin:0;
padding:0;
font-family:Arial, Helvetica, Sans-serif;
background:#000;
}
a img {
border:none;
}
a {
text-decoration:none;
color:#999
}
a:hover {
color:#333;
}
a:active {
color:#000;
}
p {
color:#444;
font-family:Helvetica, Arial, sans-serif;
}
#mainNav {
float:right;
}
.twoThird, #twoThird {
width:66%;
float:left;
}
.oneThird, #oneThird {
width:33%;
float:right;
}
.hidden {
display:none;
}
.creatorMainNavActive a {
color:#333
}
.twoColumn {
float: left;
padding: 0 40px 0 0;
text-align: justify;
width: 450px;
}
.threeColumn {
float: left;
padding: 0 15px 0 0;
text-align: justify;
width: 310px;
}
.fourColumn {
float: left;
padding: 0 15px 0 0;
text-align: justify;
width: 230px;
}
.floatNav {
float:right;
width:460px;
overflow: hidden;
white-space: nowrap;
}
.floatLeft {
float:left;
}
.floatRight {
float:right;
}
.clearBoth, .clearFloat {
clear:both;
}
.fullWidth, .fluidWidth {
width:100%;
}
.dateStamp {
font-size: 11px;
padding:0;
font-weight:bold;
color: #AAAAAA;
font-style: italic;
}
.socialLinksInPage {
margin-bottom:10px;
}
#mainSubNavigation ul, ul.creatorFooterNav, #headerSubNav ul, #blogPostPreview ul, #mainSiteNavigation ul, form#userRegistrationForm ul, #blogEntriesForSection ul, #galleryEntriesForSection ul {
list-style-type:none;
margin:0;
padding:0;
}
.breadcrumbs {
font-size: 10px;
padding: 10px 0 0;
text-align: right;
}
.center {
width:980px;
display:none;
margin:0 auto;
}
.logo {
float: left;
padding: 10px;
}
.adSidebar {
float:left;
margin:10px 0;
}
.sidebarLeft {
width:300px;
float:left;
}
.sidebarRight {
width:300px;
float:right;
}
.articleTextLeft {
width:640px;
padding:0 0 20px 20px;
float:left;
border-left: 1px solid #EEEEEE;
}
.articleTextRight {
width:640px;
padding:0 20px 20px 0;
float:left;
border-right:1px solid #ddd;
}
h2.commentHeading {
border-top:1px solid #ddd;
padding-top:20px;
}
/*-------------------------------BLOG STYLES-------------------------------*/
.blogPostSynopsis {
border-bottom: 1px solid #DDDDDD;
float: left;
margin-bottom: 20px;
padding-bottom: 50px;
}
.blogPostSynopsis h2 {
font-size: 21px;
margin: 0;
}
.blog .articleTextLeft {
border-left: 1px solid #EEEEEE;
float: left;
margin-left: 15px;
padding: 0 0 20px 20px;
width: 640px;
}
.blog .articleRightLeft {
border-right: 1px solid #EEEEEE;
float: left;
margin-right: 15px;
padding: 0 0 20px 20px;
width: 640px;
}
/*-------------------------------FOOTER STYLES-------------------------------*/
.footerColor p {
margin:0;
padding:0;
}
.footerColumn, #footerRight {
background:#ddd;
float:left;
}
ul.creatorFooterNav {
border-top:1px solid #686868;
margin-top:20px;
}
ul.creatorFooterNav li a {
float: left;
padding: 10px 25px 10px 0;
}
/*-------------------------------COLOR STYLES-------------------------------*/
.headerColor {
border-bottom: 1px solid #EEEEEE;
float: left;
}
.subHeaderColor {
border-bottom: 1px solid #EEEEEE;
float: left;
}
.footerColor {
float: left;
background:#000;
margin-top: 20px;
}
#flavorLogo {
float:left;
width:300px;
height:100px;
}
/*-------------------------------NAVIGATION STYLES-------------------------------*/
#mainSiteNavigation {
float:right;
}
#mainSiteNavigation li {
float: left;
padding: 10px;
}
#headerSubNav {
float:right;
}
#headerSubNav li {
float: left;
font-size: 13px;
padding: 10px;
}
#headerSubNav li a.active {
color:#222;
}
#mainSubNavigation {
font-family:'Oswald', Arial, Helvetica, sans-serif;
padding:20px;
}
#mainSubNavigation ul li {
line-height: 30px;
}
#mainSubNavigation li.navbarLabel {
font-size: 18px;
font-weight: bold;
margin: 20px 0 5px;
}

View File

@@ -0,0 +1,34 @@
/*
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
*/
#top {
background-image: url('../images/background.jpg');
background-repeat:repeat;
padding-top:5px;
}
#titlearea {
background-image: url('../images/background.jpg');
background-repeat:repeat;
border: 1px solid rgb(204, 204, 204);
border-radius:15px;
-moz-border-radius:15px;
-webkit-border-radius:15px;
text-decoration: none;
margin-bottom:5px;
margin-left:5px;
margin-right:5px;
}
#projectlogo {
padding-bottom:10px;
padding-left:25px;
}
#projectlogo img {
width:150px;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
/*
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
*/
/* Code Highlighting Styles */
.hll { background-color: #404040 }
.error { color: #a61717; background-color: #e3d2d2 } /* Error */
.generic { color: #d0d0d0 } /* Generic */
.literal { color: #000000 } /* Literal */
.name { color: #000000 } /* Name */
.operator { color: #000000 } /* Operator */
.other { color: #d0d0d0 } /* Other */
.punctuation { color: #000000 } /* Punctuation */
.comment { color: #666666; font-style: italic } /* Comment */
.comment.multiline { color: #666666; font-style: italic } /* Comment.Multiline */
.comment.preproc { color: #0000FF; } /* Comment.Preproc */
.comment.single { color: #666666; font-style: italic } /* Comment.Single */
.comment.special { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
.gd { color: #d22323 } /* Generic.Deleted */
.ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
.gr { color: #d22323 } /* Generic.Error */
.gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
.gi { color: #589819 } /* Generic.Inserted */
.go { color: #cccccc } /* Generic.Output */
.gp { color: #aaaaaa } /* Generic.Prompt */
.gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
.gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
.gt { color: #d22323 } /* Generic.Traceback */
.keyword { color: #bb2828; font-weight: bold } /* Keyword */
.keyword.declaration { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
.keyword.namespace { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
.keyword.type { color: #bb2828; font-weight: bold } /* Keyword.Type */
.kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
.kp { color: #6ab825 } /* Keyword.Pseudo */
.kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
.name.attribute { color: #bbbbbb } /* Name.Attribute */
.name.builtin { color: #24909d } /* Name.Builtin */
.name.class { color: #447fcf; font-weight: bold } /* Name.Class */
.name.constant { color: #40ffff } /* Name.Constant */
.name.decorator { color: #ffa500 } /* Name.Decorator */
.name.entity { color: #d0d0d0 } /* Name.Entity */
.name.exception { color: #bbbbbb } /* Name.Exception */
.name-function { color: #447fcf } /* Name.Function */
.name.label { color: #d0d0d0 } /* Name.Label */
.name.namespace { color: #447fcf; } /* Name.Namespace */
.name.other { color: #d0d0d0 } /* Name.Other */
.name.property { color: #d0d0d0 } /* Name.Property */
.name.tag { color: #6ab825; font-weight: bold } /* Name.Tag */
.name-variable { color: #40ffff } /* Name.Variable */
.operator.word { color: #6ab825; font-weight: bold } /* Operator.Word */
.whitespace { color: #666666 } /* Text.Whitespace */
.literal.date { color: #3677a9 } /* Literal.Date */
.literal.number { color: #006400 } /* Literal.Number */
.literal.number.float { color: #006400 } /* Literal.Number.Float */
.literal.number.hex { color: #006400 } /* Literal.Number.Hex */
.literal.number.integer { color: #006400 } /* Literal.Number.Integer */
.literal.number.integer.long { color: #006400 } /* Literal.Number.Integer.Long */
.literal.number.oct { color: #3677a9 } /* Literal.Number.Oct */
.literal.number.backtick { color: #ed9d13 } /* Literal.String.Backtick */
.literal.number.char { color: #006400 } /* Literal.String.Char */
.literal.number.doc { color: #ed9d13 } /* Literal.String.Doc */
.literal.number.double { color: #ed9d13 } /* Literal.String.Double */
.literal.string { color: #006400 } /* Literal.String */
.literal.string.escape { color: #2E8B57 } /* Literal.String.Escape */
.sh { color: #ed9d13 } /* Literal.String.Heredoc */
.si { color: #ed9d13 } /* Literal.String.Interpol */
.sx { color: #ffa500 } /* Literal.String.Other */
.sr { color: #ed9d13 } /* Literal.String.Regex */
.s1 { color: #ed9d13 } /* Literal.String.Single */
.ss { color: #ed9d13 } /* Literal.String.Symbol */
.bp { color: #24909d } /* Name.Builtin.Pseudo */
.name.variable.class { color: #40ffff } /* Name.Variable.Class */
.name.variable.global { color: #40ffff } /* Name.Variable.Global */
.name.variable.instance { color: #40ffff } /* Name.Variable.Instance */

View File

@@ -0,0 +1,88 @@
/*
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
*/
.coursewareBackground {
background: #efefef;
float: left;
margin: 0 25px 25px;
padding: 30px 50px;
width: 796px;
color: #333;
font-size: 13px!important;
}
.coursewareBackground hr {
display:none;
}
.coursewareBackground img {
margin-bottom:20px;
max-width: 776px;
}
.coursewareBackground strong, .coursewareBackground p, .coursewareBackground h1, .coursewareBackground h2, .coursewareBackground h3, .coursewareBackground h4, .coursewareBackground h5, .coursewareBackground h6, .coursewareBackground li, .coursewareBackground li a {
color:#333;
}
.coursewareBackground a {
color:#000;
text-decoration:underline;
}
.coursewareBackground a:hover {
color: #CC9900!important;
}
.coursewareBackground pre, .coursewareBackground code {
background:#ddd;
}
.coursewareBackground ul li {
padding-left: 6px!important;
list-style-type:disc!important;
}
.coursewareBackground h1, .coursewareBackground h2, .coursewareBackground h1 a, .coursewareBackground h2 a {
padding-bottom:10px;
margin-bottom:10px!important;
clear: left;
border-bottom:1px solid #ccc;
text-decoration:none;
}
.coursewareBackground div.note {
margin-left: 15px;
margin-right: 15px;
padding:10px 5px 10px 5px;
clear: left;
border:1px solid #333;
background: #ccc;
}
.imageLeft {
float:left;
padding:0 10px 10px 0;
margin:0 10px 10px 0;
}
#mainContentContainer p {
font-family:Arial, Helvetica, sans-serif!important;
color:#333!important;
}
#mainContentContainer .entranceList p {
color: #aaa!important;
}
#mainContentContainer .entranceList h3 {
color: #FFCC03;
}
#mainContentContainer a:hover {
color: #FFCC03;
}
h1.articleContentTitle {
width:620px!important;
}
#mainContentContainer ul li {
color:#333;
font-weight:normal;
}
#mainContentContainer ol li {
color: #333!important;
font-weight: normal;
font-family: arial, sans-serif;
font-size: 13px!important;
}
ol img {
margin-left:-28px;
}

View File

@@ -0,0 +1,608 @@
/*
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
*/
/*Code Styles
________________________*/
pre, code {
border: 1px dashed #555555;
background:#222;
padding: 5px 10px;
line-height: 21px;
word-wrap:break-word;
text-align: left;
width: 96%;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.code-keyword {
color:#036eff;
}
.code-quote {
color:#13db03;
}
.code-object {
color:#e403ff;
}
/**************************************************
*
* Browser style sheet - loaded by all CSS aware browsers
*
**************************************************/
.red {
color: rgb(128,0,0);
}
.green {
color: rgb(0,128,0);
}
.blue {
color: rgb(0,0,128);
}
.subtitle {
color: #000000;
font-size: 12pt;
}
/* neutralize the "docutils" class imposed by rst */
table.docutils {
border-style: hidden;
border-spacing: 15px;
outline-style: none; }
.widetablecontainer {
overflow: auto;
}
/* container for a table with centered entries */
table.data {
background-color: #f9f9f9;
border: 1px solid #2f6fab;
border-width: 1px;
border-collapse: collapse;
padding-left: 10px;
margin-top: 10px;
margin-left: 30px;
margin-right: 60px;
text-align: center;
}
table.data tt {
max-width: 400px;
display: inline-block;
word-wrap: break-word;
}
table {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
margin-left:60px;
}
table th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #f9f9f9;
}
/* container for a table with left-aligned entries */
table.data-list {
border: 1px solid #2f6fab;
border-width: 1px;
border-collapse: collapse;
padding-left: 10px;
margin-top: 10px;
margin-left: 30px;
margin-right: 60px;
margin-bottom: 20px;
text-align: left;
}
table.data-list caption {
margin: 5px;
}
table.data-list td{
max-width: 600px;
overflow: hidden;
padding: 6px;
}
/* layout hack to override default left margin in a table */
table.fullpage {
margin-top: 4px;
margin-left: -20px;
border-style: hidden;
outline-style: none;
}
/* specialized container for quick reference indices */
table.quickref caption {
padding: 12px 6px 6px 6px;
}
table.quickref .line {
padding: 2px 15px 2px 15px;
}
table.quickref {
width: 600px;
margin-top: 0px;
margin-left: 30px;
border-style: hidden;
border-collapse: collapse;
outline-style: none;
text-align: left;
}
hr.docutils {
background-color: transparent;
border: 1px solid rgb(204, 204, 204);
clear: none;
color: #333;
display: block;
float: none;
height: 0px;
margin-bottom: 6.5px;
margin-left: 0px;
margin-right: 0px;
margin-top: 6.5px;
width: 794px;
}
/**************************************************
* CLASSES
**************************************************/
/* Only for use in the copyright in the footer */
.size {
line-height: 100%;
}
.no_Indent {
margin-left: inherit;
margin-top: 0;
margin-bottom: 0;
}
.indentedMenu {
margin-left: 18;
margin-top: 0;
margin-bottom: 0;
}
.indentedMenu2 {
margin-left: 36;
margin-top: 0;
margin-bottom: 0;
}
.indentedMenu3 {
margin-left: 54;
margin-top: 0;
margin-bottom: 0;
}
.literal-block {
padding: 1em;
background-color: #f9f9f9;
border: 1px dashed #2f6fab;
clear: both;
margin-left: 25px;
margin-right: 60px;
white-space: pre;
overflow: auto;
width: auto;
font-weight: normal;
}
.no_Indent, .no_Indent_Bold, .indentedMenu, .indentedMenu2, .indentedMenu3 {
line-height: normal;
}
.no_Indent a:link, .no_Indent_Bold a:link, .no_Indent a:visited, .no_Indent a:active,
.indentedMenu a:link, .indentedMenu a:visited, .indentedMenu a:active,
.indentedMenu2 a:link, .indentedMenu2 a:visited, .indentedMenu2 a:active,
.indentedMenu3 a:link, .indentedMenu3 a:visited, .indentedMenu3 a:active
{
text-decoration: none;
}
.no_Indent_Bold
{
font-weight : bold;
}
.menu A:link {
text-decoration: none;
color: "#777777";}
.menu A:visited {
text-decoration: none;
color: "#777777";}
.menu A:hover {
background-color: "#CCCCCC";
color: white; }
.menu {
color: "#CCCCCC";
}
h1.title {
display: none;
}
/****************************************************
*
* Special rst "containers"
*
***************************************************/
.notebox {
padding: 0.2em 1em 1em 1em;
background-color: #f9f9f9;
border: 1px solid rgb(120,30,40);
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
clear: both;
margin-left: 60px;
margin-right: 60px;
/*float:right;*/
}
/* assume the first paragraph is a title */
.notebox p:first-child {
font-weight : bold;
color: rgb(120,30,40);
margin-bottom: 20px;
margin-top: 20px;
}
/* code that only requires markup/emphasis */
.codefhead {
font-family: Monaco, Courier, "Courier New", monospace;
font-size: 13px!important;
clear: both;
margin-left: 0px;
background-color: #ddd;
border: none;
overflow: auto;
font-weight: normal;
}
/* code that requires markup/emphasis and a pretty container */
.stylized-rib {
font-family: Monaco, Courier, "Courier New", monospace;
clear: both;
padding: 1em;
background-color: #f9f9f9;
border: 1px dashed #2f6fab;
font-weight: normal;
}
/* for side-by-side code examples */
.shader-rib {
font-family: Monaco, Courier, "Courier New", monospace;
clear: both;
margin-left: 0px;
padding: 1em;
background-color: #f9f9f9;
border: 1px dashed #2f6fab;
}
/* matches spacing of "codefhead", but restores default fonts */
.codefbody {
font-family : "Verdana", Helvetica, sans-serif;
clear: both;
margin-bottom: 13px;
margin-top: 5px;
margin-left: 30px;
margin-right: 60px;
font-weight: normal;
}
/* special container for Important/Note/Tip pullouts */
.impnotip {
margin-top: 23px;
margin-bottom: 23px;
padding: 0.2em 1em 1em 1em;
border: 3px inset;
border-color: #A77;
clear: both;
margin-left: 60px;
margin-right: 60px;
background-color: #CAA;
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
}
.note {
margin-top: 23px;
margin-bottom: 23px;
padding: 0.2em 1em 1em 1em;
border: 3px inset;
border-color: #7AC;
clear: both;
margin-left: 60px;
margin-right: 60px;
background-color: #7AC;
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
}
ul.auto-toc li {
list-style-type: none;
}
ol li {
list-style-type: decimal;
}
.imgboxtop {
border-top: 1px solid #ddd;
border-right: 1px solid #bbb;
border-left: 1px solid #ddd;
margin: 0;
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.imgboxbottom {
border-right: 1px solid #bbb;
border-bottom: 1px solid #bbb;
border-left: 1px solid #ddd;
margin: 0;
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.caption {
font-size: small;
}
.code {
padding: 1em;
background-color: #f9f9f9;
border: 1px dashed #2f6fab;
clear: both;
font-weight: normal;
margin-right: 20px;
}
pre {
border: 1px dashed #2f6fab;
background: #222;
padding: 5px 10px;
line-height: 21px;
word-wrap: normal;
text-align: left;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
white-space: pre;
overflow: auto;
width: auto;
font-weight: normal;
}
code {
font-family: Monaco, Courier, "Courier New", monospace;
overflow: auto;
width: auto;
border: 0px;
background: transparent;
padding: 0px;
}
.copyright {
text-align: center;
line-height: 80%;
}
.highlight {
color: #880000;
font-weight: bold;
}
div.quickLinks {
margin-left: 15px;
}
div.navigation {
position:fixed;
width:245px;
border: 1px solid rgb(204, 204, 204);
border-radius:15px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
text-decoration: none;
color: #9A9A9A;
font-size: 12px;
font-weight: 400;
font-family: futura-pt, sans-serif;
}
div.navigation ul {
list-style-image: url('../images/toggler0.gif');
margin-left: 0px;
padding-left: 20px;
}
div.navigation a:link,
div.navigation a:visited,
div.navigation a:hover {
color: #9A9A9A;
text-decoration: none;
}
div.document {
background: rgb(240,240,240);
/*
margin-left: 255px;
margin-top: 5px;
padding-top: 15px;
padding-left: 15px;
padding-right: 15px;
padding-bottom: 15px;
*/
border-top-left-radius: 15px;
-moz-border-top-left-radius: 15px;
-webkit-border-top-left-radius: 15px;
border-top-right-radius: 15px;
-moz-border-top-right-radius: 15px;
-webkit-border-top-right-radius: 15px;
font-family:Arial, Helvetica, sans-serif!important;
color:#333!important;
}
div.document a,
div.document a:visited {
color: #333;
}
div.document a:hover {
color: #FFCC03;
}
div.footer {
/* background: #FFF;*/
margin-left: 255px;
padding-top: 15px;
padding-left: 5px;
padding-right: 5px;
padding-bottom: 15px;
border-bottom-left-radius: 15px;
-moz-border-bottom-left-radius: 15px;
-webkit-border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
-moz-border-bottom-right-radius: 15px;
-webkit-border-bottom-right-radius: 15px;
}
div.contents.local.topic {
background-color: transparent;
border: 1px solid #DEDBE7;
border-collapse: collapse;
margin-left: 60px;
margin-right: 60px;
margin-bottom: 15px;
border-radius:5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
img.align-center, .align-center img {
display: block;
margin-left: auto;
margin-right: auto
}
/****************************************************
****************************************************/
body {
background-image: url('../images/background.jpg');
background-repeat:repeat;
}
.page{
position:relative;
width: 946px;
margin:0 auto 0px auto;
}
.hidden {
display: none;
}
/****************************************************
****************************************************/
#searchInput{
/*background: #474747;*/
background: #9A9A9A;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-khtml-border-radius: 5px;
border-radius: 5px;
border: 1px solid black;
-moz-box-shadow: 0 1px 0 #444444;
-webkit-box-shadow: 0 1px 0 #444;
color: white;
font-size: 11px;
padding: 5px 5px;
width: 145px;
height: 17px;
margin-left: 10px;
}
#searchButton{
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-khtml-border-radius: 5px;
border-radius: 5px;
background: black;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#111111');
background: -webkit-gradient(linear, left top, left bottom, from(#333), to(#111));
background: -moz-linear-gradient(bottom, #111, #333);
box-shadow: inset 0px 1px 0px #555;
-webkit-box-shadow: inset 0px 1px 0px #555;
-moz-box-shadow: inset 0px 1px 0px #555;
/*color: #DDD;*/
color: #9A9A9A;
text-transform: uppercase;
font-size: 11px;
padding: 6px 10px;
border: 1px solid black;
height: 28px;
}

Binary file not shown.

View File

@@ -0,0 +1,100 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
dxPtexViewer
------------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**dxPtexViewer** [**-f**] [**-yup**] [**-u**] [**-a**] [**-l** *isolation level*] [**-c** *animation loops*]
[**-e** *environment map*] [**-d** *HDR diffuse map*] [**-s** *HDR specular map*]
[**--disp** *displacement scale*]
*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.
.. image:: images/dxptexviewer.png
:width: 400px
:align: center
:target: images/dxptexviewer.png
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
**-y**
Swap Z-up geometry to Y-UP.
**-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.
*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

View File

@@ -0,0 +1,43 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
dxViewer
--------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**dxViewer** [**-f**] [**-yup**] [**-u**] [**-a**] [**-l** *refinement level*] [**-c** *animation loops*]
*objfile(s)* [**-catmark**] [**-loop**] [**-bilinear**]
DESCRIPTION
===========
``dxViewer`` is a stand-alone application that showcases the application of
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
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,20 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
SEE ALSO
========
Other `examples <code_examples.html>`__ \ :
`glViewer <glviewer.html>`__, \
`glFVarViewer <glfvarviewer.html>`__, \
`glEvalLimit <glevallimit.html>`__, \
`glStencilViewer <glstencilviewer.html>`__, \
`glPtexViewer <glptexviewer.html>`__, \
`glPaintTest <glpainttest.html>`__, \
`glShareTopology <glsharetopology.html>`__, \
`dxViewer <dxviewer.html>`__, \
`dxPtexViewer <dxptexviewer.html>`__, \

View File

@@ -0,0 +1,593 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
FAR Overview
------------
.. contents::
:local:
:backlinks: none
Feature Adaptive Representation (Far)
=====================================
*Far* is the primary API layer for processing client-supplied mesh data
into subdivided surfaces.
The *Far* interface may be used directly and also may be used to prepare
mesh data for further processing by `Osd <osd_overview.html#Osd>`__.
The two main aspects of the subdivision process are *Topology Refinement*
and *Primvar Refinement*.
Topology Refinement
*******************
Topology refinement is the process of splitting the mesh topology
according to the specified subdivison rules to generate new topological
vertices, edges, and faces. This process is purely topological and does
not depend on the speciific values of any primvar data (point positions, etc).
Topology refinement can be either uniform or adaptive, where extraordinary
features are automatically isolated (see
`feature adaptive subdivision <subdivision_surfaces.html#feature-adaptive-subdivision>`__).
The *Far* topology classes present a public interface for the refinement
functionality provided in `Vtr <vtr_overview.html#Vtr>`__,
The main classes in *Far* related to topology refinement are:
+-------------------------------+---------------------------------------------+
| TopologyRefiner | A class encapsulating mesh refinement. |
+-------------------------------+---------------------------------------------+
| TopologyLevel | A class representing one level of |
| | refinement within a TopologyRefiner. |
+-------------------------------+---------------------------------------------+
| TopologyRefinerFactory<MESH> | A factory class template specialized in |
| | terms of the application's mesh |
| | representation used to construct |
| | TopologyRefiner instances. |
+-------------------------------+---------------------------------------------+
Primvar Refinement
******************
Primvar refinement is the process of computing values for primvar data (points,
colors, normals, texture coordinates, etc) by applying weights determined by
the specified subdivision rules. There are many advantages gained by
distinguishing between topology refinement and primvar interpolation
including the ability to apply a single static topological refinement to
multiple primvar instances or to different animated primvar time samples.
*Far* supports methods to refine primvar data at the locations of topological
vertices and at arbitrary locations on the subdivision limit surface.
The main classes in *Far* related to primvar refinement are:
+-----------------------+--------------------------------------------------+
| PrimvarRefiner | A class implementing refinement of primvar data |
| | at the locations of topological vertices. |
+-----------------------+--------------------------------------------------+
| PatchTable | A representation of the refined surface topology |
| | that can be used for efficient evaluation of |
| | primvar data at arbitrary locations. |
+-----------------------+--------------------------------------------------+
| StencilTable | A representation of refinement weights suitable |
| | for efficient parallel processing of primvar |
| | refinement. |
+-----------------------+--------------------------------------------------+
| LimitStencilTable | A representation of refinement weights suitable |
| | for efficient parallel processing of primvar |
| | refinement at arbitrary limit surface locations. |
+-----------------------+--------------------------------------------------+
Far::TopologyRefiner
====================
TopologyRefiner is the building block for many other useful classes in
*Far*. It performs refinement of an arbitrary mesh and provides access to
the refined mesh topology. It can be used for primvar refinement directly
using PrimvarRefiner or indirectly by being used to create
a `stencil table <#patch-table>`__, or a `patch table <#patch-table>`__,
etc.
TopologyRefiner provides the public refinement methods
*RefineUniform()* and *RefineAdapative()* which perform refinement
operations using Vtr. TopologyRefiner provides access to the refined
topology via TopologyLevel instances.
.. image:: images/topology_refiner.png
:align: center
Far::TopologyRefinerFactory
===========================
Consistent with other classes in Far, instances of TopologyRefiner are created
by a factory class -- in this case Far::TopologyRefinerFactory.
Here we outline several approaches for converting mesh topology into the
required Far::TopologyRefiner. Additional documentation is provided with
the Far::TopologyRefinerFactory<MESH> class template used by all, and each
has a concrete example provided in one of the tutorials or in the Far code
itself.
There are three ways to create TopologyRefiners
* use the existing TopologyRefinerFactory<TopologyDescriptor> with a
populated instance of TopologyDescriptor
* specialize TopologyRefinerFactory<class MESH> for more efficient
conversion, using only face-vertex information
* fully specialize TopologyRefinerFactor<class MESH> for most control over
conversion
**Use the Far::TopologyDescriptor**
Far::TopologyDescriptor is a simple struct that can be initialized to refer
to raw mesh topology information -- primarily a face-vertex list -- and then
passed to a provided factory class to create a TopologyRefiner from each.
Topologically, the minimal requirement consists of:
* the number of vertices and faces of the mesh
* an array containing the number of vertices per face
* an array containing the vertices assigned to each face
These last two define one of the six topological relations that are needed
internally by Vtr, but this one relation is sufficient to construct the rest.
Additional members are available to assign sharpness values per edge and/or
vertex, hole tags to faces, or to define multiple sets (channels) of
face-varying data.
Almost all of the Far tutorials (i.e. tutorials/far/tutorial_*) illustrate
use of the TopologyDescriptor and its factory for creating TopologyRefiners,
i.e. TopologyRefinerFactory<TopologyDescriptor>.
For situations when users have raw mesh data and have not yet constructed a
boundary representation of their own, it is hoped that this will suffice.
Options have even been provided to indicate that raw topology information
has been defined in a left-hand winding order and the factory will handle
the conversion to right-hand (counter-clockwise) winding on-the-fly to avoid
unnecessary data duplication.
**Custom Factory for Face Vertices**
If the nature of the TopologyDescriptor's data expectations is not helpful,
and so conversion to large temporary arrays would be necessary to properly
make use of it, it may be worth writing a custom factory.
Specialization of TopologyRefinerFactory<class MESH> 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.
There are two ways to write such a factory: provide only the face-vertex
information for topology and let the factory infer all edges and other
relationships, or provide the complete edge list and all other topological
relationships directly. The latter is considerably more involved and
described in a following section.
The definition of TopologyRefinerFactory<TopologyDescriptor> provides a clear
and complete example of constructing a TopologyRefiner with minimal topology
information, i.e. the face-vertex list. The class template
TopologyRefinerFactory<MESH> documents the needs here and the
TopologyDescriptor instantiation and specialization should illustrate that.
**Custom Factory for Direct Conversion**
Fully specializing a factory for direct conversion is needed only for
those requiring ultimate control and is not generally recommended.
It is recommended that one of the previous two methods initially be used to
convert your mesh topology into a TopologyRefiner. If the conversion
performance is critical, or significant enough to warrant improvement, then
it is worth writing a factory for full topological conversion.
Writing a custom factory requires the specification/specialization of two
methods 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 <vtr_overview.html#arry-type>`__ 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)
This approach requires dealing directly with edges, unlike the other two. In
order to convert edges into a TopologyRefiner's representation, the edges need
to be expressed as a collection of known size N -- each of which is referred to
directly by indices [0,N-1]. This can be awkward for representations such as
half-edge or quad-edge that do not treat the instance of an edge uniquely.
Particular care is also necessary when representing non-manifold features. The
previous two approaches will construct non-manifold features as required from
the face-vertex list -- dealing with degenerate edges and other non-manifold
features as encountered. When directly translating full topology it is
necessary to tag non-manifold features, and also to ensure that certain
edge relationships are satisfied in their presence. More details are
available with the assembly methods of the factory class template.
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. The factory does provide run-time validation on the
topology constructed that can be used for debugging purposes.
A common base class has been created for the factory class, i.e.:
.. code:: c++
template <class MESH>
class TopologyRefinerFactory : public TopologyRefinerFactoryBase
both to provide common code independent of <MESH> and also potentially to
protect core code from unwanted specialization.
Far::PrimvarRefiner
===================
PrimvarRefiner supports refinement of arbitrary primvar data at the locations
of topological vertices. A PrimvarRefiner accesses topology data directly
from a TopologyRefiner.
Different methods are provided to support three different classes of primvar
interpolation. These methods may be used to refine primvar data to a specified
refinement level.
+-------------------------------+-------------------------------------------+
| Interpolate(...) | Interpolate using vertex weights |
+-------------------------------+-------------------------------------------+
| InterpolateVarying(...) | Interpolate using linear weights |
+-------------------------------+-------------------------------------------+
| InterpolateFaceVarying(...) | Interpolate using face-varying weights |
+-------------------------------+-------------------------------------------+
Additional methods allow primvar data to be interpolated to the final limit
surface including the calculation of first derivative tangents.
+-------------------------------+-------------------------------------------+
| Limit(dst) | Interpolate to the limit surface using |
| | vertex weights |
+-------------------------------+-------------------------------------------+
| Limit(dst, dstTan1, dstTan2) | Interpolate including first derivatives |
| | to the limit surface using vertex weights |
+-------------------------------+-------------------------------------------+
| LimitFaceVarying(...) | Interpolate to the limit surface using |
| | face-varying weights |
+-------------------------------+-------------------------------------------+
PrimarRefiner provides a straightforward interface for refining primvar data,
but depending on the application use case, it can be more efficient to create
and use a `StencilTable <#patch-table>`__, or `PatchTable <#patch-table>`__,
to refine primvar data.
Far::PatchTable
================
PatchTable is the collection of patches derived from the refined faces of a particular mesh topology.
This collection is created using *Far::PatchTableFactory* from an instance
of *Far::TopologyRefiner* after refinement has been applied.
Patch Arrays
************
The PatchTable is organized into patch arrays. All patches in each array have
the same type except for face-varying patch arrays which may have a mix of regular and irregular patch types.
The *PatchDescriptor* provides the fundamental description of a patch, including the number of control points per patch as well as the basis for patch evaluation.
Each patch in the array is associated with a *PatchParam* which
specifies additional information about the individual patch.
.. image:: images/far_patchtables.png
:align: center
:target: images/far_patchtables.png
Patch Types
***********
The following are the different patch types that can be represented in the
PatchTable:
+---------------------+------+---------------------------------------------+
| Patch Type | #CVs | Description |
+=====================+======+=============================================+
| NON_PATCH | n/a | *"Undefined"* patch type |
+---------------------+------+---------------------------------------------+
| POINTS | 1 | Points : useful for cage drawing |
+---------------------+------+---------------------------------------------+
| LINES | 2 | Lines : useful for cage drawing |
+---------------------+------+---------------------------------------------+
| QUADS | 4 | Bi-linear quadrilaterals |
+---------------------+------+---------------------------------------------+
| TRIANGLES | 3 | Linear triangles |
+---------------------+------+---------------------------------------------+
| LOOP | 12 | Quartic triangular Box-spline patches |
+---------------------+------+---------------------------------------------+
| REGULAR | 16 | Bi-cubic B-spline patches |
+---------------------+------+---------------------------------------------+
| GREGORY | 4 | Legacy Gregory patches |
+---------------------+------+---------------------------------------------+
| GREGORY_BOUNDARY | 4 | Legacy Gregory Boundary patches |
+---------------------+------+---------------------------------------------+
| GREGORY_BASIS | 20 | Bi-cubic quadrilateral Gregory patches |
+---------------------+------+---------------------------------------------+
| GREGORY_TRIANGLE | 18 | Quartic triangular Gregory patches |
+---------------------+------+---------------------------------------------+
The type of a patch dictates the number of control vertices expected in the
table as well as the method used to evaluate values.
Patch Parameterization
**********************
Here we describe the encoding of the patch parameterization for
quadrilateral patches. The encoding for triangular patches is similar,
please see the API documentation of Far::PatchParam for details.
Each patch represents a specific portion of the parametric space of the
coarse topological face identified by the PatchParam FaceId. As topological
refinement progresses through successive levels, each resulting patch
corresponds to a smaller and smaller subdomain of the face.
The PatchParam UV origin describes the mapping from the uv domain of the
patch to the uv subdomain of the topological face. We encode this uv
origin using log2 integer values for compactness and efficiency.
It is important to note that this uv parameterization is the intrinsic
parameterization within a given patch or coarse face and is distinct
from any client specified face-varying channel data.
.. image:: images/far_patchUV.png
:align: center
:target: images/far_patchUV.png
Patches which result from irregular coarse faces (non-quad faces in the
Catmark scheme) are offset by the one additional level needed to
"quadrangulate" the irregular face. It is the indices of these offset
faces that are stored in the PatchParam and used in other classes such
as the Far::PatchMap. These offset indices can be identified from the
coarse face using the Far::PtexIndices class when needed.
+--------------------------------------------+--------------------------------------------+
| .. image:: images/ptex_coarse.png | .. image:: images/ptex_quadrangulated.png |
| :align: center | :align: center |
| :width: 100% | :width: 100% |
| :target: images/ptex_coarse.png | :target: images/ptex_quadrangulated.png |
+--------------------------------------------+--------------------------------------------+
A patch along an interpolated boundary edge is supported by an incomplete
sets of control vertices. For consistency, patches in the PatchTable always
have a full set of control vertex indices and the PatchParam Boundary bitmask
identifies which control vertices are incomplete (the incomplete control
vertex indices are assigned values which duplicate the first valid index).
Each bit in the boundary bitmask corresponds to one edge of the patch
starting from the edge from the first vertex and continuing around the
patch. With feature adaptive refinement, regular B-spline basis patches
along interpolated boundaries will fall into one of the eight cases
(four boundary and four corner) illustrated below:
.. image:: images/far_patchBoundary.png
:align: center
:target: images/far_patchBoundary.png
Transition edges occur during feature adaptive refinement where a patch
at one level of refinement is adjacent to pairs of patches at the next
level of refinement. These T-junctions do not pose a problem when evaluating
primvar data on patches, but they must be taken into consideration when
tessellating patches (e.g. while drawing) in order to avoid cracks.
The PatchParam Transition bitmask identifies the transition edges of
a patch. Each bit in the bitmask corresponds to one edge of the patch
just like the encoding of boundary edges.
After refining an arbitrary mesh, any of the 16 possible transition edge
configurations might occur. The method of handling transition edges is
delegated to patch drawing code.
.. image:: images/far_patchTransition.png
:align: center
:target: images/far_patchTransition.png
Single-Crease Patches
**************************
Using single-crease patches allows a mesh with creases to be represented
with many fewer patches than would be needed otherwise. A single-crease
patch is a variation of a regular BSpline patch with one additional crease
sharpness parameter.
.. container:: notebox
**Release Notes (3.x)**
Evaluation
of single-crease patches is currently only implemented for OSD patch
drawing, but we expect to implement support in all of the evaluation
code paths for future releases.
Local Points
************
The control vertices represented by a PatchTable are primarily refined points,
i.e. points which result from applying the subdivision scheme uniformly or
adaptively to the points of the coarse mesh. However, the final patches
generated from irregular faces, e.g. patches incident on an extraordinary
vertex might have a representation which requires additional local points.
Legacy Gregory Patches
**********************
Using Gregory patches to approximate the surface at the final patches
generated from irregular faces is an alternative representation which does
not require any additional local points to be computed. Instead, when
Legacy Gregory patches are used, the PatchTable must also have an alternative
representation of the mesh topology encoded as a vertex valence table
and a quad offsets table.
Far::StencilTable
==================
The base container for stencil data is the StencilTable class. As with most
other Far entities, it has an associated StencilTableFactory that requires a
TopologyRefiner:
Advantages
**********
Stencils are used to factorize the interpolation calculations that subdivision
schema apply to vertices of smooth surfaces. If the topology being subdivided
remains constant, factorizing the subdivision weights into stencils during a
pre-compute pass yields substantial amortizations at run-time when re-posing
the control cage.
Factorizing the subdivision weights also allows to express each subdivided
vertex as a weighted sum of vertices from the control cage. This step effectively
removes any data inter-dependency between subdivided vertices : the computations
of subdivision interpolation can be applied to each vertex in parallel without
any barriers or constraint. The `Osd <osd_overview.html#Osd>`__ classes leverage
these properties by exploiting CPU and GPU parallelism.
.. image:: images/far_stencil5.png
:align: center
Principles
**********
Iterative subdivision algorithms converge towards the limit surface by
successively refining the vertices of the coarse control cage. Each successive
iteration interpolates the new vertices by applying polynomial weights to a
*basis of supporting vertices*.
The interpolation calculations for any given vertex can be broken down into
sequences of multiply-add operations applied to the supporting vertices.
Stencil table encodes a factorization of these weighted sums : each stencils is
created by combining the list of control vertices from the 1-ring.
With iterative subdivision, each refinement step is dependent upon the previous
subdivision step being completed, and a substantial number of steps may be
required in order approximate the limit : each subdivision step incurs an
O(4\ :superscript:`n`) growing amount of computations.
Instead, once the weights of the contributing coarse control vertices for a
given refined vertex have been factorized, it is possible to apply the stencil
and directly obtain the interpolated vertex data without having to process the
data for the intermediate refinement levels.
.. image:: images/far_stencil7.png
:align: center
Cascading Stencils
******************
Client-code can control the amount of factorization of the stencils : the tables can be
generated with contributions all the way from a basis of coarse vertices, or
reduced only to contributions from vertices from the previous level of
refinement.
The latter mode allows client-code to access and insert modifications to the
vertex data at set refinement levels -- creating what are often referred
to as *hierarchical edits*. Once the edits have been
applied by the client-code, another set of stencils can be used to smooth the
vertex data to a higher level of refinement.
.. image:: images/far_stencil8.png
:align: center
See implementation details, see the Far cascading stencil `tutorial
<tutorials.html>`_
Limit Stencils
**************
Stencil tables can be trivially extended from discrete subdivided vertices to
arbitrary locations on the limit surface. Aside from extraordinary points, every
location on the limit surface can be expressed as a closed-form weighted
average of a set of coarse control vertices from the 1-ring surrounding the
face.
The weight accumulation process is similar : the control cage is adaptively
subdivided around extraordinary locations. A stencil is then generated for each
limit location simply by factorizing the bi-cubic Bspline patch weights over
those of the contributing basis of control-vertices.
The use of bi-cubic patches also allows the accumulation of analytical
derivatives, so limit stencils carry a set of weights for tangent vectors.
.. image:: images/far_stencil0.png
:align: center
Once the stencil table has been generated, limit stencils are the most direct
and efficient method of evaluation of specific locations on the limit of a
subdivision surface, starting from the coarse vertices of the control cage.
Also: just as discrete stencils, limit stencils that are factorized from coarse
control vertices do not have inter-dependencies and can be evaluated in
parallel.
For implementation details, see the `glStencilViewer <glstencilviewer.html>`_
code example.
Sample Location On Extraordinary Faces
**************************************
Each stencil is associated with a singular parametric location on the coarse
mesh. The parametric location is defined as face location and local [0.0 - 1.0]
(u,v) triplet:
In the case of face that are not quads, a parametric sub-face quadrant needs to
be identified. This can be done either explicitly or implicitly by using the
unique ptex face indices for instance.
.. image:: images/far_stencil6.png
:align: center
Code example
************
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++
class StencilType {
public:
void Clear() {
memset( &x, 0, sizeof(StencilType));
}
void AddWithWeight( StencilType const & cv, float weight ) {
x += cv.x * weight;
y += cv.y * weight;
z += cv.z * weight;
}
float x,y,z;
};
std::vector<StencilType> controlPoints,
points,
utan,
vtan;
// Update points by applying stencils
controlStencils.UpdateValues<StencilType>( &controlPoints[0], &points[0] );
// Update tangents by applying derivative stencils
controlStencils.UpdateDerivs<StencilType>( &controlPoints[0], &utan[0], &vtan[0] );

View File

@@ -0,0 +1,148 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Getting Started
---------------
.. contents::
:local:
:backlinks: none
Downloading the code
====================
The code is hosted on a Github public repository. Download and setup information
for Git tools can be found `here <https://help.github.com/articles/set-up-git>`__.
You can access the OpenSubdiv Git repository at https://github.com/PixarAnimationStudios/OpenSubdiv
From there, there are several ways of downloading the OpenSubdiv source code.
- Zip archive : downloaded from `here <https://github.com/PixarAnimationStudios/OpenSubdiv/archive/release.zip>`__
- Using a GUI client : you can find a list `here <http://git-scm.com/downloads/guis>`__
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
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
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
`Contributor's License Agreement <intro.html#contributing>`__.
----
Branches & Git Flow
===================
Since version 1.1.0, OpenSubdiv has adopted the `Git Flow
<http://nvie.com/posts/a-successful-git-branching-model/>`__ branching model .
Our active development branch is named *dev* : all new features and bug fixes should
be submitted to this branch. The changes submitted to the dev branch are periodically
patched to the 'release' branch as new versions are released.
.. image:: images/git_flow.png
:align: center
:target: images/git_flow.png
Checking out branches
_____________________
The Git Flow `tools <https://github.com/nvie/gitflow>`__ 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 'release' branch. You can switch to the *dev* branch using
the following command:
.. code:: c++
git checkout dev
You can check that the branch has now been switched simply with:
.. code:: c++
git branch
Which should return:
.. code:: c++
* dev
release
API Versions
____________
OpenSubdiv maintains an internal API versioning system. The version number can be
read from the file `./opensubdiv/version.h <https://github.com/PixarAnimationStudios/OpenSubdiv/blob/release/opensubdiv/version.h>`__.
Following the Git-Flow pattern, our releases are indexed using Git's tagging
system.
List of the existing tags:
.. code:: c++
git tag --list
Checking out version 1.2.0:
.. code:: c++
git checkout v1_2_0
Making Changes
______________
Direct push access to the OpenSubdiv repository is currently limited to a
small internal development team. External code should be submitted by sending Git
`pull-requests <https://help.github.com/articles/using-pull-requests>`__ from
forks of our *dev* branch.
----
Code Overview
=============
The OpenSubdiv code base contains the following main areas:
+----------------------+---------------------------------------------------------------------------------------+
| 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. |
+----------------------+---------------------------------------------------------------------------------------+

View File

@@ -0,0 +1,66 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glEvalLimit
-----------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glEvalLimit** [**-f**] [**-yup**] [**-u**] [**-a**] [**-l** *refinement level*]
*objfile(s)* [**-catmark**] [**-loop**] [**-bilinear**]
DESCRIPTION
===========
``glEvalLimit`` is a stand-alone application that showcases the limit surface
Eval module. On the given shape, random samples are generated in local s,t space.
Vertex, varying and face-varying data is then computed on the surface limit and
displayed as colors.
In order to emphasize the dynamic nature of the EvalLimit API, where the
locations can be arbitrarily updated before each evaluation, the glEvalLimit
example treats each sample as a 'ST particle'.
ST Particles are a simplified parametric-space particle dynamics simulation: each
particle is assigned a location on the subdivision surface limit that is
composed of a unique ptex face index, with a local (s,t) parametric pair.
The system also generates an array of parametric velocities (ds, dt) for each
particle. An Update() function then applies the velocities to the locations and
moves the points along the parametric space.
Face boundaries are managed using a ptex adjacency table obtained from the
Far::TopologyRefiner. Every time a particle moves outside of the [0.0f, 1.0f]
parametric range, a 'warp' function moves it to the neighboring face, or
bounces it, if the edge happens to be a boundary.
Note: currently the adjacency code does not handle 'diagonal' crossings, nor
crossings between quad and non-quad faces.
Multiple controls are available to experiment with the algorithms.
.. image:: images/glevallimit.jpg
:width: 400px
:align: center
:target: images/glevallimit.jpg
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,49 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glFVarViewer
------------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glFVarViewer** [**-f**] [**-u**] [**-a**] [**-l** *refinement level*] [**-c** *animation loops*]
*objfile(s)* [**-catmark**] [**-loop**] [**-bilinear**]
DESCRIPTION
===========
``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
* right side: a 2D view of the face-varying (u,v) pair
The HUD allows interactive manipulation of the various face-varying boundary
interpolation rules and tags.
.. image:: images/uvviewer.jpg
:width: 400px
:align: center
:target: images/uvviewer.jpg
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,52 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glPaintTest
-----------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glPaintTest** [**-f**] [**-yup**] [**-l** *adaptive refinement level*]
*objfile(s)* [**-catmark**] [**-loop**]
DESCRIPTION
===========
``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
:align: center
:target: images/painttest.jpg
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
KEYBOARD CONTROLS
=================
.. code:: c++
c : use texture as color
d : use texture as displacement
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,95 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glPtexViewer
------------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glPtexViewer** [**-f**] [**-yup**] [**-u**] [**-a**] [**-l** *isolation level*] [**-c** *animation loops*]
[**-e** *environment map*] [**-d** *HDR diffuse map*] [**-s** *HDR specular map*]
[**--disp** *displacement scale*] [**--bump** *bump scale*]
*ptex color file*
*ptex displacement file*
*ptex occlusion file*
*ptex specular file*
*objfile(s)*
DESCRIPTION
===========
``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.
.. image:: images/barb_1.jpg
:width: 400px
:align: center
:target: images/barb_1.jpg
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
**-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.
**--bump** *displacement scale*
A scalar multiplier for the shader bump values.
*ptex color file*
A ptex file containing RGB channels read as material albedo color.
*ptex displacement file*
A single-channel ptex file (preferably float precision) containing the
displacement values.
*ptex occlusion file*
A single-channel ptex file (preferably 8 bits precision) containing a
pre-computed ambient occlusion signal.
*ptex specular file*
A single-channel ptex file (preferably 8 bits precision) applied to modulate
the specular reflectance of the material
KEYBOARD CONTROLS
=================
.. code:: c++
q : quit
esc : hide GUI
x : save screenshot
f : fit frame
+/- : increase / decrease tessellation rate
r : reload and re-compile the shader files
e : draw normals
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,41 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glShareTopology
---------------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glShareTopology** [**-u**] [**-a**] [**-l** *refinement level*]
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
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,43 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glStencilViewer
---------------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glStencilViewer** [**-f**] [**-yup**] [**-u**] [**-a**] [**-l** *refinement level*]
*objfile(s)* [**-catmark**] [**-loop**] [**-bilinear**]
DESCRIPTION
===========
``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
:width: 400px
:align: center
:target: images/glstencilviewer.png
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,43 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
glViewer
--------
.. contents::
:local:
:backlinks: none
SYNOPSIS
========
.. parsed-literal::
:class: codefhead
**glViewer** [**-f**] [**-yup**] [**-u**] [**-a**] [**-l** *refinement level*] [**-c** *animation loops*]
*objfile(s)* [**-anim**] [**-catmark**] [**-loop**] [**-bilinear**]
DESCRIPTION
===========
``glViewer`` is a stand-alone application that showcases the application of
uniform and feature adaptive subdivision schemes to a collection of geometric
shapes. Multiple controls are available to experiment with the algorithms.
.. image:: images/glviewer.png
:width: 400px
:align: center
:target: images/glviewer.png
OPTIONS
=======
See the description of the
`common comand line options <code_examples.html#common-command-line-options>`__
for the subset of common options supported here.
.. include:: examples_see_also.rst

View File

@@ -0,0 +1,104 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
HBR Overview
------------
.. contents::
:local:
:backlinks: none
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
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 functionality, 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 <release_notes.html>`_
----
Half-edge Data Structure
========================
The current implementation is based on a half-edge data structure.
.. image:: images/half_edge.png
:align: center
----
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.
.. 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 accommodate
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
complete control of the layout of the vertex data : interleaved or non-interleaved.
----
Boundary Interpolation Rules
============================
**Hbr** recognizes 4 rule-sets of boundary interpolation:
+------------------------------------+
| Interpolation Rule-Sets |
+====================================+
| k_InterpolateBoundaryNone |
+------------------------------------+
| k_InterpolateBoundaryEdgeOnly |
+------------------------------------+
| k_InterpolateBoundaryEdgeAndCorner |
+------------------------------------+
| k_InterpolateBoundaryAlwaysSharp |
+------------------------------------+
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

View File

@@ -0,0 +1,164 @@
..
Copyright 2013 Pixar
Licensed under the terms set forth in the LICENSE.txt file available at
https://opensubdiv.org/license.
Hierarchical Edits
------------------
.. contents::
:local:
:backlinks: none
----
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.
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
:height: 300
:target: images/hedit_example1.png
----
.. container:: notebox
**Release Notes (3.0.0)**
Hierarchical Edits have been marked as "extended specification" and support for
hierarchical features has been removed from the 3.0 release. This decision
allows for great simplifications of many areas of the subdivision algorithms.
If we can identify legitimate use-cases for hierarchical tags, we will consider
re-implementing them in future releases, as time and resources allow.
----
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.
.. image:: images/face_winding.png
:align: center
:target: images/face_winding.png
.. role:: red
.. 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 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.
.. 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.
----
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.
.. 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.
.. image:: images/hedit_example2.png
:align: center
:height: 300
:target: images/hedit_example2.png
----
Edge Edits
**********
Edge hierarchical edits can only modify the sharpness of primitive variables for edges
and sub-edges anywhere in the subdivision hierarchy.
.. image:: images/hedit_example4.png
:align: center
:height: 300
:target: images/hedit_example4.png
----
Face Edits
**********
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.
.. image:: images/hedit_example5.png
:align: center
:height: 300
:target: images/hedit_example5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Some files were not shown because too many files have changed in this diff Show More