var tipuesearch = { "pages": [ {"title":"Downloads", "text":"Downloads Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Downloads 3.6.0 User Docs API Docs Release Notes Forum Github Downloads Coupe Car Coupe Car Note  we can use javascripts buttons to trigger download see button-download or we can just paste regular ReST hyperlinks to the files here. Direct links probably more reliable though. Coupe car maya Download Coupe car obj Download EULA OpenSubdiv is covered by a modified Apache 2.0 license included below, and is free to use for commercial or non-commercial use. All Pixar patents in the area of subdivision surface algorithms have also been released for public use. We welcome any involvement in the development or extension of this code in fact, we would love it. Please contact us if you are interested. Copyright 2013 Pixar Licensed under the Apache License, Version 2.0 the Apache License with the following modification you may not use this file except in compliance with the Apache License and the following modification to it Section 6. Trademarks. is deleted and replaced with 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor and its affiliates, except as required to comply with Section 4c of the License and to reproduce the content of the NOTICE file. You may obtain a copy of the Apache License at httpwww.apache.orglicensesLICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the Apache License with the above modification is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for the specific language governing permissions and limitations under the Apache License. Accept Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"downloads.html"}, 
{"title":"License", "text":"License Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen License 3.6.0 User Docs API Docs Release Notes Forum Github License Open Source License OpenSubdiv is covered by a modified Apache 2.0 license included below, and is free to use for commercial or non-commercial use. All Pixar patents in the area of subdivision surface algorithms have also been released for public use. We welcome any involvement in the development or extension of this code in fact, we would love it. Please contact us if you are interested. For information on Apache licenses, see httpwww.apache.orglicenses The following license text describes the open source policy adopted by Pixar and is included in every source file. Copyright 2013 Pixar Licensed under the Apache License, Version 2.0 the Apache License with the following modification you may not use this file except in compliance with the Apache License and the following modification to it Section 6. Trademarks. is deleted and replaced with 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor and its affiliates, except as required to comply with Section 4c of the License and to reproduce the content of the NOTICE file. You may obtain a copy of the Apache License at httpwww.apache.orglicensesLICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the Apache License with the above modification is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for the specific language governing permissions and limitations under the Apache License. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"license.html"}, 
{"title":"glShareTopology", "text":"glShareTopology Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glShareTopology 3.6.0 User Docs API Docs Release Notes Forum Github glShareTopology SYNOPSIS DESCRIPTION OPTIONS SEE ALSO SYNOPSIS 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. OPTIONS See the description of the common comand line options for the subset of common options supported here. SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glsharetopology.html"}, 
{"title":"Contributing to OpenSubdiv", "text":"Contributing to OpenSubdiv Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Contributing to OpenSubdiv 3.6.0 User Docs API Docs Release Notes Forum Github Contributing to OpenSubdiv Contributor License Agreement Understand Git Recommended Git Workflow Sending a Pull Request Contributor License Agreement In order for us to accept code submissions merge git pull-requests, contributors need to sign the Contributor License Agreement CLA. There are two CLAs, one for individuals and one for corporations. As for the end-user license, both are based on Apache. They are found in the code repository  individual form , corporate form . Please email the signed CLA to opensubdiv-clapixar.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 whats going on under the hood. There are many free resources on the internet, one which weve found useful is the following e-book httpsgithub.compluralsightgit-internals-pdfreleases 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 httpsgithub.comyourusernameOpenSubdiv.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 httpsgithub.comPixarAnimationStudiosOpenSubdiv.git Verify your remotes are setup correctly git remote -v Which should look something like origin httpsgithub.comyourusernameOpenSubdiv.git fetch origin httpsgithub.comyourusernameOpenSubdiv.git push upstream httpsgithub.comPixarAnimationStudiosOpenSubdiv.git fetch upstream httpsgithub.comPixarAnimationStudiosOpenSubdiv.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 upstreamdev 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 upstreamdev 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 youve 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. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"contributing.html"}, 
{"title":"glEvalLimit", "text":"glEvalLimit Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glEvalLimit 3.6.0 User Docs API Docs Release Notes Forum Github glEvalLimit SYNOPSIS DESCRIPTION OPTIONS SEE ALSO SYNOPSIS glEvalLimit  -f   -yup   -u   -a   -l refinement level  objfiles  -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 FarTopologyRefiner. 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. OPTIONS See the description of the common comand line options for the subset of common options supported here. SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glevallimit.html"}, 
{"title":"glFVarViewer", "text":"glFVarViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glFVarViewer 3.6.0 User Docs API Docs Release Notes Forum Github glFVarViewer SYNOPSIS DESCRIPTION OPTIONS SEE ALSO SYNOPSIS glFVarViewer  -f   -u   -a   -l refinement level   -c animation loops  objfiles  -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. OPTIONS See the description of the common comand line options for the subset of common options supported here. SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glfvarviewer.html"}, 
{"title":"glStencilViewer", "text":"glStencilViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glStencilViewer 3.6.0 User Docs API Docs Release Notes Forum Github glStencilViewer SYNOPSIS DESCRIPTION OPTIONS SEE ALSO SYNOPSIS glStencilViewer  -f   -yup   -u   -a   -l refinement level  objfiles  -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. OPTIONS See the description of the common comand line options for the subset of common options supported here. SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glstencilviewer.html"}, 
{"title":"HBR Overview", "text":"HBR Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen HBR Overview 3.6.0 User Docs API Docs Release Notes Forum Github HBR Overview Hierarchical Boundary Representation Hbr Half-edge Data Structure Half-edge cycles and Manifold Topology Templated Vertex Class Boundary Interpolation Rules 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 Pixars Photorealistic RenderMan . 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 Half-edge Data Structure The current implementation is based on a half-edge data structure. Half-edge cycles and Manifold Topology Because half-edges only carry a reference to their opposite half-edge, a given edge can only access a single neighboring edge cycle. 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 Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"hbr_overview.html"}, 
{"title":"Additional Resources", "text":"Additional Resources Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Additional Resources 3.6.0 User Docs API Docs Release Notes Forum Github Additional Resources Links Videos Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces 2012 Open Subdivision Technology Review 2012 Autodesk User Group At Anaheim 2013 Why Model with Subdivisions 2013 Meet the Experts The OpenSubdiv Project 2013 Links OpenSubdiv Github Repository OpenSubdiv with Mudbox and Maya Videos Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces 2012 Open Subdivision Technology Review 2012 Autodesk User Group At Anaheim 2013 Why Model with Subdivisions 2013 Meet the Experts The OpenSubdiv Project 2013 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. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"additional_resources.html"}, 
{"title":"glViewer", "text":"glViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glViewer 3.6.0 User Docs API Docs Release Notes Forum Github glViewer SYNOPSIS DESCRIPTION OPTIONS SEE ALSO SYNOPSIS glViewer  -f   -yup   -u   -a   -l refinement level   -c animation loops  objfiles  -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. OPTIONS See the description of the common comand line options for the subset of common options supported here. SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glviewer.html"}, 
{"title":"Code Examples", "text":"Code Examples Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Code Examples 3.6.0 User Docs API Docs Release Notes Forum Github Code Examples Standalone Viewers OpenSubdiv builds a number of standalone viewers that demonstrate various aspects of the software. OpenGL examples glViewer glFVarViewer glEvalLimit glStencilViewer glPtexViewer glPaintTest glShareTopology DirectX examples dxViewer dxPtexViewer Metal examples mtlViewer mtlPtexViewer 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 objfiles  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  nextprev 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 Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"code_examples.html"}, 
{"title":"dxViewer", "text":"dxViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen dxViewer 3.6.0 User Docs API Docs Release Notes Forum Github dxViewer SYNOPSIS DESCRIPTION OPTIONS SEE ALSO SYNOPSIS dxViewer  -f   -yup   -u   -a   -l refinement level   -c animation loops  objfiles  -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. OPTIONS See the description of the common comand line options for the subset of common options supported here. SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"dxviewer.html"}, 
{"title":"Introduction", "text":"Introduction Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Introduction 3.6.0 User Docs API Docs Release Notes Forum Github Introduction Introduction Why Fast Subdivision  Research Heritage Licensing Contributing External Resources Introduction OpenSubdiv is a set of open source libraries that implement high performance subdivision surface subdiv evaluation on massively parallel CPU and GPU architectures. This code path is optimized for drawing deforming surfaces with static topology at interactive framerates. OpenSubdiv is an API ready to be integrated into 3rd party digital content creation tools. It is not an application, nor a tool that can be used directly to create digital assets. Why Fast Subdivision  Subdivision surfaces are commonly used for final rendering of character shapes for a smooth and controllable limit surfaces. However, subdivision surfaces in interactive apps are typically drawn as their polygonal control hulls because of performance. The polygonal control hull is an approximation that is offset from the true limit surface. Looking at an approximation in the interactive app makes it difficult to see exact contact, like fingers touching a potion bottle or hands touching a cheek. It also makes it difficult to see poke-throughs in cloth simulation if the skin and cloth are both approximations. This problem is particularly bad when one character is much larger than another and unequal subdiv face sizes cause approximation errors to be magnified. Maya and Pixars proprietary Presto animation system can take 100ms to subdivide a character of 30,000 polygons to the second level of subdivision 500,000 polygons. Being able to perform the same operation in less than 3ms allows the user to interact with the smooth, accurate limit surface at all times. Research The new GPU technology behind OpenSubdiv is the result of a joint research effort between Pixar and Microsoft. Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces Matthias Niessner, Charles Loop, Mark Meyer, and Tony DeRose ACM Transactions on Graphics, Vol. 31 No. 1 Article 6 January 2012 httpgraphics.pixar.comlibraryGPUSubdivRenderingApaper.pdf Efficient Evaluation of Semi-Smooth Creases in Catmull-Clark Subdivision Surfaces Matthias Niessner, Charles Loop, and Guenter Greiner. Eurographics Proceedings, Cagliari, 2012 httpsniessnerlab.orgpapers20121semismoothniessner2012efficient.pdf Analytic Displacement Mapping using Hardware Tessellation Matthias Niessner, Charles Loop ACM Transactions on Graphics, Vol. 32 No. 3 Article 26 June 2013 httpsniessnerlab.orgpapers20133analyticniessner2013analytic.pdf Heritage This is the fifth-generation subdiv library in use by Pixars proprietary animation system in a lineage that started with code written by Tony DeRose and Tien Truong for Geris Game in 1996. Each generation has been a from-scratch rewrite that has built upon our experience using subdivision surfaces to make animated films. This code is live, so Pixars changes to OpenSubdiv for current and future films will be released as open source at the same time they are rolled out to Pixar animation production. Subdivision for Modeling and Animation Denis Zorin, Peter Schroder Course Notes of SIGGRAPH 1999 httpwww.multires.caltech.edupubssig99notes.pdf Subdivision Surfaces in Character Animation Tony DeRose, Michael Kass, Tien Truong Proceedings of SIGGRAPH 1998 httpgraphics.pixar.comlibraryGeripaper.pdf Recursively generated B-spline surfaces on arbitrary topological meshes Catmull, E. Clark, J. Computer-Aided Design 10 6 1978 Licensing OpenSubdiv is covered by the Apache License, and is free to use for commercial or non-commercial use. This is the same code that Pixar uses internally for animated film production. Our intent is to encourage a geometry standard for subdivision surfaces, by providing consistent i.e. yielding the same limit surface, high performance implementations on a variety of platforms. Why Apache We were looking for a commercial-friendly license that would convey our patents to the end users. This quickly narrowed the field to Microsoft Public License or Apache. Initially we chose MSPL because it handled trademarks better. But at the request of several companies we gave Apache another look, and decided to go with Apache with a very slight modification that simply says you cannot use any contributors trademarks. In other words, you can use OpenSubdiv to make a product, but you cannot use a Luxo Lamp or other character, etc. when marketing your product. License Header Contributing For details on how to contribute to OpenSubdiv, see the page on Contributing External Resources Pixar Research Pixar RD Portal Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"intro.html"}, 
{"title":"Hierarchical Edits", "text":"Hierarchical Edits Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Hierarchical Edits 3.6.0 User Docs API Docs Release Notes Forum Github Hierarchical Edits Hierarchical Edits Hierarchical Edits Paths Vertex Edits Edge Edits Face Edits 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. 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. In this diagram, the indices of the vertices of the base face are marked in red  so on the left we have an extraordinary Catmull-Clark face with five vertices labeled 0-4  and on the right we have a regular Catmull-Clark face with four vertices labelled 0-3 . The indices of the child faces are blue  note that in both the extraordinary and regular cases, the child faces are indexed the same way, i.e. the sub-face labeled n has one incident vertex that is the result of the subdivision of the parent vertex also labeled n in the parent face. Specifically, we note that the sub-face 1 in both the regular and extraordinary face is nearest to the vertex labelled 1 in the parent. The indices of the vertices of the child faces are labeled 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 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 1 in the extraordinary case has a child vertex 0 , while in the regular case the parent vertex indexed 1 actually has a child vertex that is indexed 1 . Note that this indexing scheme was chosen to maintain the property that the vertex labeled 0 always has the lowest uv parametric value on the face. By appending a vertex index to a face index, we can create a vertex path specification. For example,  655 2 3 0 specifies the 1st. vertex of the 3 rd. child face of the 2 nd. child face of the of the 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. 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. Edge Edits Edge hierarchical edits can only modify the sharpness of primitive variables for edges and sub-edges anywhere in the subdivision hierarchy. Face Edits Face hierarchical edits can modify several properties of faces and sub-faces anywhere in the subdivision hierarchy. 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. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"hedits.html"}, 
{"title":"Modeling Tips", "text":"Modeling Tips Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Modeling Tips 3.6.0 User Docs API Docs Release Notes Forum Github Modeling Tips Topology Use Fewer Spans Avoid High Valence vertices Edge-Loop Transitions Practical Topology Primer Triangles and N-Gons Semi-Sharp Creases Use crease sets Additional Resources The following sections describe common techniques specific to modeling with subdivision surfaces. Note The following information contains techniques specific to the Catmull-Clark subdivision scheme. Some elements need to be adjusted for Loop surfaces. Topology Well-constructed subdivision meshes have several important properties They consist primarily of regular faces quads for Catmull-Clark, tris for Loop They contain few extraordinary vertices They efficiently describe the intended shape They are topologically manifold Use Fewer Spans While polygon models need to use a large number of spans to approximate smooth curved surfaces, subdivision models require significantly fewer control points. In most situations, 6 spans are enough to create accurate circular shapes, and 4 is often enough to approximate background objects. Avoid High Valence vertices A high valence vertex is a vertex connected to more than 4 adjacent edges. High valence vertices cause several problems when subdivided The Catmull-Clark scheme can produce wavy surfaces when a revolution vertex is surrounded by triangles see here  High valence vertices incur fairly large performance hits Currently, OpenSubdiv has a hard constraint imposed by GPU shaders on the maximum valence of a vertex 27 on current hardware Instead, here are some topological strategies to cap revolution shapes Note that all these cylinders use only quad faces, and all the vertices in the caps have a valence of 4 except the bottom left example Edge-Loop Transitions It is often necessary to vary the density of control vertices over the surface mesh areas around the fingers of a hand require more CVs than the comparatively simpler region around the palm. It is important to handle the topology around these transitions efficiently. One strategy is to use extraordinary vertices, such as this example, using a valence 5 vertex to expand 3 edge loops into 5. Practical Topology Primer Some real-world examples showing how to produce detailed shapes with sparse topology, few extraordinary vertices, and no high-valence revolution poles. Triangles and N-Gons Used sparsely, non-quads can be very useful to gather 3 or more diverging edge-loops. These are often encountered in highly deforming areas with curvature saddle-points ex arm-torso connection. The strategic placement of a pentagon in one of these critical spots ensures that the surface remains smooth, while allowing for complex topology to flow around. Semi-Sharp Creases Semi-sharp creases can be a very powerful tool for hard-surface modeling. Both edges and vertices can be tagged with a sharpness value. Crease sharpness values range from 0 smooth to 10 infinitely sharp It is generally cheaper to use creases whenever possible, instead of adding extra edgesedge-loops. However... Creases introduce extra computation costs that are proportional to the sharpness value. So... Sharpness values above 5 should rarely be needed. The following sections introduce some techniques to best leverage them. Use crease sets Complex hard-surface models giant robots, vehicles, buildings... are likely to tag large number of edges  it is extremely useful to organize these edgesedge loops into logical sets with descriptive names. Edges or vertices in a crease set group all share the same sharpness value. If you are modeling with Maya, the CreaseSetEditor implements this type of workflow. Additionally, for debugging purposes, it is often very helpful if the name of a set contains the sharpness value ex topDeck_2. Besides authoring convenience, one of the benefits of having many edge-loops share identical sharpness values is that it enables very powerful performance optimizations within the feature adaptive algorithm faster renders  less memory. Additional Resources An excellent short tutorial from the Guerrilla CG Project that illustrates many of the common pitfalls of subdivision modeling, and the strategies to overcome them Ivo Kos, Modelling Technical Director at Pixar Animation Studios, shows some of the modeling techniques he uses when modeling props and architecture sets for feature films. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"mod_notes.html"}, 
{"title":"glPaintTest", "text":"glPaintTest Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glPaintTest 3.6.0 User Docs API Docs Release Notes Forum Github glPaintTest SYNOPSIS DESCRIPTION OPTIONS KEYBOARD CONTROLS SEE ALSO SYNOPSIS glPaintTest  -f   -yup   -l adaptive refinement level  objfiles  -catmark   -loop  DESCRIPTION glPaintTest is a small stand-alone application showing the potential of using GPU limit tessellation for painting and sculpting applications. OPTIONS See the description of the common comand line options for the subset of common options supported here. KEYBOARD CONTROLS c  use texture as color d  use texture as displacement SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glpainttest.html"}, 
{"title":"dxPtexViewer", "text":"dxPtexViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen dxPtexViewer 3.6.0 User Docs API Docs Release Notes Forum Github dxPtexViewer SYNOPSIS DESCRIPTION OPTIONS KEYBOARD CONTROLS SEE ALSO SYNOPSIS 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 objfiles 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. OPTIONS See the description of the common comand 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 objfiles 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 q  quit esc  hide GUI f  fit frame -  increase  decrese tessellation rate SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"dxptexviewer.html"}, 
{"title":"mtlViewer", "text":"mtlViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen mtlViewer 3.6.0 User Docs API Docs Release Notes Forum Github mtlViewer SYNOPSIS DESCRIPTION KEYBOARD CONTROLS SEE ALSO SYNOPSIS open mtlViewer.app --args  -yup   -u   -a   -l refinement level  objfiles  -catmark   -loop   -bilinear  DESCRIPTION mtlViewer 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. mtlViewer running on macOS mtlViewer running on iOS KEYBOARD CONTROLS q  quit f  fit frame -  increase  decrease tessellation rate SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"mtlviewer.html"}, 
{"title":"glPtexViewer", "text":"glPtexViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen glPtexViewer 3.6.0 User Docs API Docs Release Notes Forum Github glPtexViewer SYNOPSIS DESCRIPTION OPTIONS KEYBOARD CONTROLS SEE ALSO SYNOPSIS 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 objfiles 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. OPTIONS See the description of the common comand 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 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 SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"glptexviewer.html"}, 
{"title":"mtlPtexViewer", "text":"mtlPtexViewer Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen mtlPtexViewer 3.6.0 User Docs API Docs Release Notes Forum Github mtlPtexViewer SYNOPSIS DESCRIPTION KEYBOARD CONTROLS SEE ALSO SYNOPSIS open mtlPtexViewer.app --args  -yup   -u   -a   -l isolation level  ptex color file ptex displacement file DESCRIPTION mtlPtexViewer is a stand-alone application demonstrating shading with color and displacement ptex maps. Multiple controls are available to experiment with the algorithms. KEYBOARD CONTROLS q  quit f  fit frame -  increase  decrease tessellation rate SEE ALSO Other examples  glViewer , glFVarViewer , glEvalLimit , glStencilViewer , glPtexViewer , glPaintTest , glShareTopology , dxViewer , dxPtexViewer , Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"mtlptexviewer.html"}, 
{"title":"Getting Started", "text":"Getting Started Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Getting Started 3.6.0 User Docs API Docs Release Notes Forum Github Getting Started Downloading the code Branches  Git Flow Checking out branches API Versions Making Changes Code Overview Downloading the code The code is hosted on a Github public repository. Download and setup information for Git tools can be found here . You can access the OpenSubdiv Git repository at httpsgithub.comPixarAnimationStudiosOpenSubdiv From there, there are several ways of downloading the OpenSubdiv source code. Zip archive  downloaded from here Using a GUI client  you can find a list here Please refer to the documentation of your preferred application. From the GitShell, Cygwin or the CLI  assuming that you have the Git tools installed, you can clone the OpenSubdiv repository directly with the following command git clone https  github.comPixarAnimationStudiosOpenSubdiv.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 Gits 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 Contributors License Agreement . Branches  Git Flow Since version 1.1.0, OpenSubdiv has adopted the Git Flow branching model . Our active development branch is named dev  all new features and 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. Checking out branches The Git Flow tools are not a requisite for working with the OpenSubdiv code base, but new work should always be performed in the dev branch, or dedicated feature-branches. By default, a cloned repository will be pointing to the release branch. You can switch to the dev branch using the following command git checkout dev You can check that the branch has now been switched simply with git branch Which should return  dev release API Versions OpenSubdiv maintains an internal API versioning system. The version number can be read from the file .opensubdivversion.h . Following the Git-Flow pattern, our releases are indexed using Gits tagging system. List of the existing tags git tag -- list Checking out version 1.2.0 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 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. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"getting_started.html"}, 
{"title":"Subdivision Compatibility", "text":"Subdivision Compatibility Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Subdivision Compatibility 3.6.0 User Docs API Docs Release Notes Forum Github Subdivision Compatibility Subdivision Compatibility Compatibility with OpenSubdiv 2.x Compatibility with RenderMan Incompatibilities Other Differences 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 HbrMeshSetFVarInterpolateBoundarMethodInterpolateBoundaryMethod const void HbrMeshSetFVarPropagateCornersbool 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 . 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 Hbrs 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 SdcOptionsFVarLinearInterpolation enum and its equivalents for HbrMeshs 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 NA ignored FVAR_LINEAR_CORNERS_ONLY NA NA FVAR_LINEAR_CORNERS_PLUS1 k_InterpolateBoundaryEdgeAndCorner false FVAR_LINEAR_CORNERS_PLUS2 k_InterpolateBoundaryEdgeAndCorner true FVAR_LINEAR_BOUNDARIES k_InterpolateBoundaryAlwaysSharp NA ignored FVAR_LINEAR_ALL k_InterpolateBoundaryNone NA 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 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 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 SdcOptionsCreasingMethod 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 SdcOptionsTriangleSubdivision 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 methods 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 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.0s 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 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. 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 Hbrs 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 Hbrs 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. Hbrs 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. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"compatibility.html"}, 
{"title":"OSD Overview", "text":"OSD Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen OSD Overview 3.6.0 User Docs API Docs Release Notes Forum Github OSD Overview OpenSubdiv Osd Refinement Limit Stencil Evaluation Limit Evaluation with PatchTable OpenGLDX11Metal Drawing with Hardware Tessellation InterleavedBatched Buffer Configuration Cross-Platform Implementation OpenSubdiv Osd Osd contains device dependent code that makes Far structures available on various backends such as TBB, CUDA, OpenCL, GLSL, etc. The main roles of Osd are Refinement Compute stencil-based uniformadaptive subdivision on CPUGPU backends Limit Stencil Evaluation Compute limit surfaces by limit stencils on CPUGPU backends Limit Evaluation with PatchTable Compute limit surfaces by patch evaluation on CPUGPU backends OpenGLDX11Metal Drawing with hardware tessellation Provide GLSLHLSLMetal tessellation functions for patch table InterleavedBatched buffer configuration Provide consistent buffer descriptor to deal with arbitrary buffer layout. Cross-Platform Implementation Provide convenient classes to interop between compute and draw APIs These are independently used by clients. For example, a client can use only the limit stencil evaluation, or a client can refine subdivision surfaces and draw them with the PatchTable and Osd tessellation shaders. All device specific evaluation kernels are implemented in the Evaluator classes. Since Evaluators dont own vertex buffers, clients should provide their own buffers as a source and destination. There are some interop classes defined in Osd for convenience. OpenSubdiv utilizes a series of regression tests to compare and enforce identical results across different computational devices. Refinement Osd supports both uniform and feature adaptive subdivision. Once clients create a FarStencilTable for the topology, they can convert it into device-specific stencil tables if necessary. The following table shows which evaluator classes and stencil table interfaces can be used together. Note that while Osd provides these stencil table classes which can be easily constructed from FarStencilTable, clients arent required to use these table classes. Clients may have their own entities as a stencil tables as long as EvaluatorEvalStencils can access the necessary interfaces. Backend Evaluator class compatible stencil table CPU CPU single-threaded CpuEvaluator FarStencilTable TBB CPU multi-threaded TbbEvaluator FarStencilTable OpenMP CPU multi-threaded OmpEvaluator FarStencilTable CUDA GPU CudaEvaluator CudaStencilTable OpenCL CPUGPU CLEvaluator CLStencilTable GL ComputeShader GPU GLComputeEvaluator GLStencilTableSSBO GL Transform Feedback GPU GLXFBEvaluator GLStencilTableTBO DX11 ComputeShader GPU D3D11ComputeEvaluator D3D11StencilTable Metal GPU MTLComputeEvaluator MTLStencilTable Limit Stencil Evaluation Limit stencil evaluation is quite similar to refinement in Osd . At first clients create FarLimitStencilTable for the locations to evaluate the limit surfaces, then convert it into an evaluator compatible stencil table and call EvaluatorEvalStencils. Limit Evaluation with PatchTable Another way to evaluate the limit surfaces is to use the PatchTable. Once all control vertices and local points are resolved by the stencil evaluation, Osd can evaluate the limit surfaces through the PatchTable. Backend Evaluator class compatible patch table CPU CPU single-threaded CpuEvaluator CpuPatchTable TBB CPU multi-threaded TbbEvaluator CpuPatchTable OpenMP CPU multi-threaded OmpEvaluator CpuPatchTable CUDA GPU CudaEvaluator CudaPatchTable OpenCL CPUGPU CLEvaluator CLPatchTable GL ComputeShader GPU GLComputeEvaluator GLPatchTable GL Transform Feedback GPU GLXFBEvaluator GLPatchTable DX11 ComputeShader GPU D3D11ComputeEvaluator not yet supported D3D11PatchTable Metal ComputeShader GPU MTLComputeEvaluator MTLPatchTable Release Notes 3.x Osd evaluation backends EvaluatorEvalPatches do not support evaluation of single-crease or Legacy Gregory patch types. OpenGLDX11Metal Drawing with Hardware Tessellation One of the most interesting use cases of the Osd layer is realtime drawing of subdivision surfaces using hardware tessellation. This is somewhat similar to limit evaluation with PatchTable described above. Drawing differs from limit evaluation in that Osd provides shader snippets for patch evaluation and clients will inject them into their own shader source. See shader interface for a more detailed discussion of the shader interface. InterleavedBatched Buffer Configuration All Osd layer APIs assume that each primitive variables to be computed points, colors, uvs ... are contiguous arrays of 32bit floating point values. The Osd API refers to such an array as a buffer. A buffer can exist on CPU memory or GPU memory. Osd Evaluators typically take one source buffer and one destination buffer, or three destination buffers if derivatives are being computed. Osd Evaluators also take BufferDescriptors, that are used to specify the layout of the source and destination buffers. A BufferDescriptor is a struct of 3 integers which specify an offset, length and stride. For example Vertex 0 Vertex 1 ... X Y Z X Y Z ... The layout of this buffer can be described as Osd  BufferDescriptor desc  offset   0 , length   3 , stride   3  BufferDescriptor can be used for an interleaved buffer too. Vertex 0 Vertex 1 ... X Y Z R G B A X Y Z R G B A ... Osd  BufferDescriptor xyzDesc  0 , 3 , 7  Osd  BufferDescriptor rgbaDesc  3 , 4 , 7  Although the source and destination buffers dont need to be the same buffer for EvalStencils, adaptive patch tables are constructed to first index the coarse vertices and the refined vertices immediately afterward. In this case, the BufferDescriptor for the destination should include the offset as the number of coarse vertices to be skipped. Coarse vertices n  Src Refined vertices  Dst Vertex 0 Vertex 1 ... Vertex n Vertex n1 X Y Z X Y Z ... X Y Z X Y Z ... Osd  BufferDescriptor srcDesc  0 , 3 , 3  Osd  BufferDescriptor dstDesc  n  3 , 3 , 3  Also note that the source descriptor doesnt have to start with offset  0. This is useful when a client has a big buffer with multiple objects batched together. Cross-Platform Implementation One of the key goals of OpenSubdiv is to achieve as much cross-platform flexibility as possible and leverage all optimized hardware paths where available. This can be very challenging as there is a very large variety of plaftorms and APIs available, with very distinct capabilities. In Osd , Evaluators dont care about interops between those APIs. All Evaluators have two kinds of APIs for both EvalStencils and EvalPatches. Explicit signatures which directly take device-specific buffer representation e.g., pointer for CpuEvaluator, GLuint buffer for GLComputeEvaluator, etc. Generic signatures which take arbitrary buffer classes. The buffer class is required to have a certain method to return the device-specific buffer representation. The later interface is useful if the client supports multiple backends at the same time. The methods that need to be implemented for the Evaluators are Evaluator class object method CpuEvaluator TbbEvaluator OmpEvaluator pointer to cpu memory BindCpuBuffer CudaEvaluator pointer to cuda memory BindCudaBuffer CLEvaluator cl_mem BindCLBuffer GLComputeEvaluator GLXFBEvaluator GL buffer object BindVBO D3D11ComputeEvaluator D3D11 UAV BindD3D11UAV MTLComputeEvaluator MTLBuffer BindMTLBuffer The buffers can use these methods as a trigger of interop. Osd provides a default implementation of interop buffer for most of the backend combinations. For example, if the client wants to use CUDA as a computation backend and use OpenGL as the drawing API, OsdCudaGLVertexBuffer fits the case since it implements BindCudaBuffer and BindVBO. Again, clients can implement their own buffer class and pass it to the Evaluators. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"osd_overview.html"}, 
{"title":"API Overview", "text":"API Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen API Overview 3.6.0 User Docs API Docs Release Notes Forum Github API Overview API Layers Using the Right Tools Use case 1 Simple refinement Use case 2 GL adaptive tessellation drawing of animating mesh Tutorials and Examples 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 Subdivision Core Sdc Overview The lowest level layer, implements the core subdivision details to facilitate the generation of consistent results. Most cases will only require the use of simple public types and constants from Sdc. Vtr Vectorized Topological Representation Vtr Overview A suite of classes to provide an intermediate representation of topology that supports efficient refinement. Vtr is intended for internal use only. Far Feature Adaptive Representation Far Overview The central interface that processes client-supplied 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 Bace Face Representation Bfr Overview A suite of classes to provide parameterization, evaluation and tessellation on the CPU. Bfr is more flexible and more scalable than Osd but potentially less efficient. Osd OpenSubdiv cross platform Osd Overview A suite of classes to provide parallel subdivision 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. Using the Right Tools OpenSubdivs 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 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. Define a class for the primvar you want to refine. Its required to have Clear and AddWithWeight functions. 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 FarTopologyRefiner from the FarTopologyDescriptor . 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  Call RefineUniform to refine the topology up to maxlevel. refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel  4. Interpolate vertex primvar data at level using FarPrimvarRefiner Far  PrimvarRefiner primvarRefiner   refiner  Vertex const  src   coarse vertices  Vertex  dst   refined vertices  primvarRefiner . Interpolate  level , src , dst  The topology at the refined level can be obtained from FarTopologyLevel 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  Done See Far tutorial 1.1 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 OsdGLMesh utility class which composites a stencil table, patch table, vertex buffer and evaluator in osd layer. You can also use those classes independently. 1. Instantiate a FarTopologyRefiner from the FarTopologyDescriptor , same as usecase 1. Setup OsdMesh. In this example we use b-spline endcap. 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 OsdMeshRefine calls OsdCpuEvaluatorEvalStencils  mesh - UpdateVertexBuffer   vertex  0 , 0 , nverts  mesh - Refine  Bind index buffer, PatchParamBuffer and vertex buffer  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  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 for more details. 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  As the mesh animates, repeat from step 3 to update positions, refine, and draw. See glViewer and other examples for more complete usage. Tutorials and Examples For more use cases, please see Tutorials and Examples Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"api_overview.html"}, 
{"title":"FAR Overview", "text":"FAR Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen FAR Overview 3.6.0 User Docs API Docs Release Notes Forum Github FAR Overview Feature Adaptive Representation Far Topology Refinement Primvar Refinement FarTopologyRefiner FarTopologyRefinerFactory FarPrimvarRefiner FarPatchTable Patch Arrays Patch Types Patch Parameterization Single-Crease Patches Local Points Legacy Gregory Patches FarStencilTable Advantages Principles Cascading Stencils Limit Stencils Sample Location On Extraordinary Faces Code example 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 . 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 . The Far topology classes present a public interface for the refinement functionality provided in 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. TopologyRefinerFactoryMESH A factory class template specialized in terms of the applications 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. FarTopologyRefiner 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 , or a 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. FarTopologyRefinerFactory Consistent with other classes in Far, instances of TopologyRefiner are created by a factory class -- in this case FarTopologyRefinerFactory. Here we outline several approaches for converting mesh topology into the required FarTopologyRefiner. Additional documentation is provided with the FarTopologyRefinerFactoryMESH 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 TopologyRefinerFactoryTopologyDescriptor with a populated instance of TopologyDescriptor specialize TopologyRefinerFactoryclass MESH for more efficient conversion, using only face-vertex information fully specialize TopologyRefinerFactorclass MESH for most control over conversion Use the FarTopologyDescriptor FarTopologyDescriptor 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 andor vertex, hole tags to faces, or to define multiple sets channels of face-varying data. Almost all of the Far tutorials i.e. tutorialsfartutorial_ illustrate use of the TopologyDescriptor and its factory for creating TopologyRefiners, i.e. TopologyRefinerFactoryTopologyDescriptor. 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 TopologyDescriptors 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 TopologyRefinerFactoryclass 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 TopologyRefinerFactoryTopologyDescriptor provides a clear and complete example of constructing a TopologyRefiner with minimal topology information, i.e. the face-vertex list. The class template TopologyRefinerFactoryMESH 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 specificationspecialization 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 clients boundary-rep knows best how to retrieve the data that we require most efficiently. After the factory class gathers sizing information and allocates appropriate memory, the factory provides the client with locations of the appropriate tables to be populated using the same Array classes and interface used to access the tables. The client is expected to load a complete topological description along with additional optional data, i.e. the six topological relations required by Vtr, oriented when manifold sharpness values for edges andor 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 TopologyRefiners 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. 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. FarPrimvarRefiner 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. Limitdst Interpolate to the limit surface using vertex weights Limitdst, 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 , or PatchTable , to refine primvar data. FarPatchTable PatchTable is the collection of patches derived from the refined faces of a particular mesh topology. This collection is created using FarPatchTableFactory from an instance of FarTopologyRefiner 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. Patch Types The following are the different patch types that can be represented in the PatchTable Patch Type CVs Description NON_PATCH na 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 FarPatchParam 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. 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 FarPatchMap. These offset indices can be identified from the coarse face using the FarPtexIndices class when needed. 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 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. 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. 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. FarStencilTable 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 classes leverage these properties by exploiting CPU and GPU parallelism. 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 O4 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. 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. See implementation details, see the Far cascading stencil tutorial 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. 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 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. 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 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   Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_overview.html"}, 
{"title":"Building with CMake", "text":"Building with CMake Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Building with CMake 3.6.0 User Docs API Docs Release Notes Forum Github Building with CMake Overview Step 1 Dependencies Required Optional Step 2 Configuring CMake Useful Build Options Environment Variables Automated Script Using Intels C Studio XE Using Clang Step 3 Building Build Targets Compiling  Linking an OpenSubdiv Application Overview Assuming that you have cloned the source repository and selected an appropriate release branch, the following instructions will walk you through the CMake and configuration and build process. CMake is a cross-platform, open-source build system. CMake controls the compilation process using platform independent configuration files in order to generate 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 version 3.12 Optional Ptex support features for ptex textures and the ptexViewer example Zlib required for Ptex under Windows CUDA TBB OpenCL DX11 SDK GLFW required for standalone examples and some regression tests Docutils required for reST-based documentation Python Pygments required for Docutils reST styling Doxygen Step 2 Configuring CMake One way to configure CMake is to use the CMake GUI . 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 OpenSubdivcmake folder. Useful Build Options The following configuration arguments can be passed to the CMake command line. - 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_PREFIX_PATH   semicolon - separated list of directories specifying installation prefixes to be searched by the find_package  command  default  empty list  - DCUDA_TOOLKIT_ROOT_DIR   path to CUDA  - DOSD_CUDA_NVCC_FLAGS   CUDA options , e . g . -- gpu - architecture  - DPTEX_LOCATION   path to Ptex  - DGLFW_LOCATION   path to GLFW  - 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 support - DNO_DOC  1  disable documentation build - DNO_OMP  1  disable OpenMP - DNO_TBB  1  disable TBB - DNO_CUDA  1  disable CUDA - DNO_OPENCL  1  disable OpenCL - DNO_OPENGL  1  disable OpenGL - DNO_CLEW  1  disable CLEW wrapper library Environment Variables The paths to Ptex, GLFW, other dependencies can also be specified through the following environment variables PTEX_LOCATION , GLFW_LOCATION 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 git clone https  github.comPixarAnimationStudiosOpenSubdiv.git folder cd  folder  mkdir build cd build source ..  ..  cmake_setup Where cmake_setup is a configuration script. Here is an example CMake configuration script for a full typical windows-based build that can be run in GitShell  bintcsh  Replace the .. with a full path to the root of the OpenSubdiv source tree if necessary cProgram Files x86CMake 2.8bincmake.exe  - G Visual Studio 15 2017 Win64  - D GLFW_LOCATIONstringcProgram Filesglfw-2.7.7.bin.WIN64  - D OPENCL_INCLUDE_DIRSstringcProgramDataNVIDIA CorporationNVIDIA GPU Computing SDK 4.2OpenCLcommoninc  - D _OPENCL_CPP_INCLUDE_DIRSstringcProgramDataNVIDIA CorporationNVIDIA GPU Computing SDK 4.2OpenCLcommoninc  - D OPENCL_LIBRARIESstringcProgramDataNVIDIA CorporationNVIDIA GPU Computing SDK 4.2OpenCLcommonlibx64OpenCL.lib  - D PTEX_LOCATIONstringcUsersopensubdivdemosrcptexx64  ..  copy Ptex dependencies Windows only mkdir - p bin   Debug , Release   cp - f c  Users  opensubdiv  demo  src  zlib -1.2.7  contrib  vstudio  vc10  x64  ZlibDllRelease  zlibwapi . dll bin  Debug   cp - f c  Users  opensubdiv  demo  src  zlib -1.2.7  contrib  vstudio  vc10  x64  ZlibDllRelease  zlibwapi . dll bin  Release   cp - f c  Users  opensubdiv  demo  src  ptex  x64  lib  Ptex . dll bin  Debug   cp - f c  Users  opensubdiv  demo  src  ptex  x64  lib  Ptex . dll bin  Release  Important Notice that the following scripts start by recursively removing the ..build and ..inst directories. Make sure you modify them to suit your build workflow. Here is a similar script for Nix-based platforms echo  Removing build cd .. rm - rf build  inst   mkdir build  cd build  echo  Running cmake cmake - DPTEX_LOCATION  home  opensubdiv  dev  opensource  ptex  install  - DGLFW_LOCATION  home  opensubdiv  dev  opensource  glfw  build  - DDOXYGEN_EXECUTABLE  home  opensubdiv  dev  opensource  doxygen  inst  bin  doxygen  - DCMAKE_INSTALL_PREFIX  ..  inst  - DCMAKE_BUILD_TYPE  Debug  .. Here is a similar script for macOS echo  Removing build cd .. rm - rf build  inst   mkdir build  cd build  echo  Running cmake cmake - DOPENGL_INCLUDE_DIR  Applications  Xcode . app  Contents  Developer  Platforms  MacOSX . platform  Developer  SDKs  MacOSX10 .9 . sdk  System  Library  Frameworks  OpenGL . framework  Headers  - DGLFW_LOCATION  Users  opensubdiv  dev  opensource  glfw  inst  - DNO_OMP  1 - DNO_REGRESSION  0  - DCMAKE_INSTALL_PREFIX  ..  inst  - DCMAKE_BUILD_TYPE  Debug  ..  Using Intels C Studio XE OpenSubdiv can be also be built with Intels C compiler icc. The default compiler can be overriden in CMake with the following configuration options - 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 - DICC_LOCATION   path to Intel  s C  Studio XE  Using Clang CMake can also be overriden to use the clang compilers by configuring the following options - DCMAKE_CXX_COMPILER  clang   - DCMAKE_C_COMPILER  clang  Step 3 Building CMake provides a cross-platform command-line build cmake -- build . -- target install -- config Release Alternatively, you can use native toolkits to launch the build. The steps differ for each OS Windows  launch VC 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 VERBOSE1 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_staticdynamic_CPUGPU 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 -IOPENSUBDIVinclude -c myapp.cpp g myapp.o -LOPENSUBDIVlib -losdGPU -losdCPU -o myapp macOS g -IOPENSUBDIVinclude -c myapp.cpp g myapp.o -LOPENSUBDIVlib -losdGPU -losdCPU -o myapp install_name_tool -add_rpath OPENSUBDIVlib myapp On 64-bit OS-X add -m64 after each g . Windows cl nologo MT TP DWIN32 IOPENSUBDIVinclude -c myapp.cpp link nologo outmyapp.exe LIBPATHOPENSUBDIVlib libosdGPU.lib libosdCPU.lib myapp.obj 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. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"cmake_build.html"}, 
{"title":"BFR Overview", "text":"BFR Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen BFR Overview 3.6.0 User Docs API Docs Release Notes Forum Github BFR Overview Base Face Representation Bfr Evaluation BfrSurfaceFactory BfrSurface Parameterization BfrParameterization Discontinuous Parameterizations Tessellation BfrTessellation Tessellation Rates Differences from Hardware Tessellation More on BfrSurfaceFactory BfrSurfaceFactoryCache Defining a Thread-Safe SurfaceFactory Internal versus External SurfaceFactoryCache Customizing a BfrSurfaceFactory The BfrSurfaceFactoryMeshAdapter Interface Customizing the Subclass Interface Base Face Representation Bfr Bfr is an alternate API layer that treats a subdivision mesh provided by a client as a piecewise parameteric surface primitive . The name Bfr derives from the fact that the concepts and classes of this interface all relate to the base faces of a mesh. Concepts such as parameterization , evaluation and tessellation all refer to and are embodied by classes that deal with a specific face of the original unrefined mesh. The Bfr interfaces allow the limit surface for a single face to be identified and evaluated independently of all other faces without any global pre-processing. While concepts and utilities from the Far interface are used internally, the details of their usage is hidden. There is no need to coordinate adaptive refinement with tables of patches, stencils, Ptex indices, patch maps, etc. The resulting evaluation interface is much simpler, more flexible and more scalable than those assembled with the Far classes -- providing a preferable alternative for many CPU-based use cases. The main classes in Bfr include SurfaceFactory A light-weight interface to a mesh that constructs pieces of limit surface for specified faces of a mesh in the form of Surfaces. Surface A class encapsulating the limit surface of a face with methods for complete parametric evaluation. Parameterization A simple class defining the available parameterizations of faces and for identifying that of a particular face. Tessellation A simple class providing information about a specified tessellation pattern for a given Parameterization. Bfr is well suited to cases where evaluation of the mesh may be sparse, dynamically determined or iterative Newton, gradient descent, etc. It is not intended to replace the cases for which Far has been designed i.e. repeated evaluation of a fixed set of points but is intended to complement them. While simplicity, flexibility and reasonable performance were the main goals of Bfr , its current implementation often outperforms the table-based solutions of Far for many common use cases -- both in terms of execution time and memory use. An area that Bfr does not address, and where Far remains more suited, is capturing a specific representation of the limit surface for external use. Bfr intentionally keeps internal implementation details private to allow future improvements or extensions. Those representation details may be publicly exposed in future releases, but until then, use of Far is required for such purposes. Evaluation Since subdivision surfaces are piecewise parametric surfaces, the main operation of interest is evaluation. Bfr deals with the limit surface of a mesh as a whole by associating pieces of surface with each face of the mesh. These pieces of surface are referred to in the context of Bfr simply as surfaces and represented by BfrSurface. Each face of the mesh has an implicit local 2D parameterization and individual coordinates of that parameterization are used to evaluate its corresponding Surface. In general, 3- and 4-sided faces use the same parameterizations for quad and triangular patches used elsewhere in OpenSubdiv Parameterizations are defined for other faces more details to follow, so Surfaces for all faces can be evaluated given any 2D parametric coordinate of its face. Given an instance of a mesh, usage first requires the creation of a BfrSurfaceFactory corresponding to that mesh -- from which Surfaces can then be created for evaluation. Construction of the SurfaceFactory involves no pre-processing and Surfaces can be created and discarded as needed. The processes of constructing and evaluating Surfaces are described in more detail below. BfrSurfaceFactory Construction of BfrSurfaces requires an instance of BfrSurfaceFactory. An instance of SurfaceFactory is a light-weight interface to an instance of a mesh that requires little to no construction cost or memory. The SurfaceFactory does no work until a Surface is requested for a particular face -- at which point the factory inspects the mesh topology around that face to assemble the Surface. SurfaceFactory is actually a base class that is inherited to provide a consistent construction interface for Surfaces. Subclasses are derived to support a particular class of connected mesh -- to implement the topology inspection around each face required to construct the Surface. Use of these subclasses is very simple given the public interface of SurfaceFactory, but defining such a subclass is not. That more complex use case of SurfaceFactory will be described in detail later with other more advanced topics. In many cases, it is not necessary to explicitly define a subclass of SurfaceFactory, as the tutorials for Bfr illustrate. If already using OpenSubdiv for other reasons, a FarTopologyRefiner will have been constructed to represent the initial base mesh before refinement. Bfr provides a subclass of SurfaceFactory using FarTopologyRefiner as the base mesh ignoring any levels of refinement for immediate use in such cases. For those cases when no connected mesh representation is available at all i.e. only raw, unconnected mesh data exists construction of a FarTopologyRefiner provides a reasonably efficient connected mesh representation see the Far tutorials for construction details, whose provided subclass for SurfaceFactory is then readily available. Given the different interpolation types for mesh data i.e. vertex, varying and face-varying, the common interface for SurfaceFactory provides methods to construct Surfaces explicitly for all data types. So for positions, the methods for vertex data must be used to obtain the desired Surface, while for texture coordinates the methods for face-varying are usually required, e.g. Surface  CreateVertexSurface  Index faceIndex  const  Surface  CreateVaryingSurface  Index faceIndex  const  Surface  CreateFaceVaryingSurface  Index faceIndex  const  The Surfaces created by these construction methods may all be distinct as the underlying representations of the Surfaces and the indices of the data that define them will often differ. For example, the position data may require a bicubic patch while the face-varying texture data may be linear or a different type of bicubic patch given the different interpolation rules for face-varying and the possibility of seams. While the internal representations of the Surfaces constructed for different data interpolation types may differ, since they are all constructed as Surfaces, the functionality used to evaluate them is identical. BfrSurface The Surface class encapsulates the piece of limit surface associated with a particular face of the mesh. The term surface is used rather than patch to emphasize that the Surface may itself be a piecewise parametric surface composed of more than one patch potentially even a complex set of patches. Surface is also a class template selected by floating point precision, and so typically declared as BfrSurfacefloat. Just as a simpler type name is likely to be declared when used, the simple name Surface will be used to refer to it here. And where code fragments may be warranted, float will be substituted for the template parameter for clarity. Once created, there are two steps required to evaluate a Surface preparation of associated data points from the mesh the actual calls to evaluation methods using these data points The latter is straight-forward, but the former warrants a little more explanation. The shape of a Surface for a base face is influenced by the set of data points associated with both the vertices of the face and a subset of those in its immediate neighborhood. These control points are identified when the Surface is initialized and are publicly available for inspection if desired. The control points are sufficient to define the Surface if the face and its neighborhood are regular, but any irregularity an extra-ordinary vertex, crease, etc. usually requires additional, intermediate points to be computed from those control points in order to evaluate the Surface efficiently. Having previously avoided use of the term patch in favor of surface, the term patch points is now used to refer to these intermediate points. Patch points always include the control points as a subset and may be followed by points needed for any additional patches required to represent a more complex Surface. While the patch points are assembled in a local array for direct use by the Surface, the control points can either be gathered and accessed locally or indexed from buffers associated with the mesh for other purposes e.g. computing a bounding box of the Surface Once the patch points for a Surface are prepared, they can be passed to the main evaluation methods with the desired parametric coordinates. As previously noted, since the Surface class is a template for floating point precision, evaluation is supported in single or double precision by constructing a Surface for the desired precision. Evaluation methods are overloaded to obtain simply position or including all first or second derivatives. So preparation and evaluation can be achieved with the following  Preparing patch points void PreparePatchPoints  float const  meshPoints , PointDescriptor meshPointDescriptor , float  patchPoints , PointDescriptor patchPointDescriptor  const   Evaluating position and 1st derivatives void Evaluate  float const uv  2 , float const  patchPoints , PointDescriptor patchPointDescriptor , float  P , float  dPdu , float  dPdv  const  The PointDescriptor class here is a simple struct defining the size and stride of the associated array of points. Any use of mesh points, control points or patch points generally requires an accompanying descriptor. Depending on the complexity of the limit surface, this preparation of patch points can be costly -- especially if only evaluating the Surface once or twice. In such cases, it is worth considering evaluating limit stencils, i.e. sets of coefficients that combine the original control vertices of the mesh without requiring the computation of intermediate values. The cost of evaluating stencils is considerably higher than direct evaluation, but that added overhead is often offset by avoiding the use of patch points. Surfaces should be considered a class for transient use as retaining them for longer term usage can reduce their benefits. The relatively high cost of initialization of irregular Surfaces can be a deterrent and often motivates their retention despite increased memory costs. Retaining all Surfaces of a mesh for random sampling is a situation that should be undertaken with caution and will be discussed in more detail later with other advanced topics. Parameterization Each face of a mesh has an implicit local 2D parameterization whose 2D coordinates are used to evaluate the Surface for that face. Bfr adopts the parameterizations defined elsewhere in OpenSubdiv for quadrilateral and triangular patches, for use quadrilateral and triangular faces But the parameterization of a face is also dependent on the subdivision scheme applied to it. Subdivision schemes that divide faces into quads are ultimately represented by quadrilateral patches. So a face that is a quad can be parameterized as a single quad, but other non-quad faces are parameterized as a set of quad sub-faces, i.e. faces resulting from subdivision A triangle subdivided with a quad-based scheme e.g. Catmull-Clark will therefore not have the parameterization of the triangular patch indicated previously, but another defined by its quad sub-faces illustrated above to be described in more detail below. Subdivision schemes that divide faces into triangles are currently restricted to triangles only, so all faces are parameterized as single triangles. If Loop subdivision is extended to non-triangles in future, a parameterization involving triangular sub-faces will be necessary. Note that triangles are often parameterized elsewhere in terms of barycentric coordinates u,v,w where w  1 - u - v . As is the case elsewhere in OpenSubdiv, Bfr considers parametric coordinates as 2D u,v pairs for all purposes. All faces have an implicit 2D local parameterization and all interfaces requiring parametric coordinates consider only the u,v pair. If interaction with some other tool set requiring barycentric coordinates for triangles is necessary, it is left to users to compute the implicit w accordingly. BfrParameterization BfrParameterization is a simple class that fully defines the parameterization for a particular face. An instance of Parameterization is fully defined on construction given the size of a face and the subdivision scheme applied to it where the face size is its number of verticesedges. Since any parameterization of N -sided faces requires N in some form, the face size is stored as a member and made publicly available. Each Surface has the Parameterization of its face assigned internally as part of its construction, and that is used internally by the Surface in many of its methods. The need to deal directly with the explicit details of the Parameterization class is not generally necessary. Often it is sufficient to retrieve the Parameterization from a Surface for use in some other context e.g. passed to BfrTessellation. The enumerated type ParameterizationType currently defines three kinds of parameterizations -- one of which is assigned to each instance on construction according to the properties of the face QUAD Applied to quadrilateral faces with a quad-based subdivision scheme e.g. Catmark or Bilinear. TRI Applied to triangular faces with a triangle-based subdivision scheme e.g. Loop. QUAD_SUBFACES Applied to non-quad faces with a quad-based subdivision scheme -- dividing the face into quadrilateral sub-faces. Parameterizations that involve subdivision into sub-faces, e.g. QUAD_SUBFACES, may warrant some care as they are not continuous. Depending on how they are defined, the sub-faces may be disjoint e.g. Bfr  or overlap in parametric space e.g. Ptex. To help these situations, methods to detect the presence of sub-faces and deal with their local parameterizations are made available. Discontinuous Parameterizations When a face does not have a regular parameterization, the division of the parameterization into sub-faces can create complications -- as noted and addressed elsewhere in OpenSubdiv. BfrParameterization defines a quadrangulated sub-face parameterization differently from the Far and Osd interfaces. For an N -sided face, Far uses a parameterization adopted by Ptex. In this case, all quad sub-faces are parameterized over the unit square and require an additional index of the sub-face to identify them. So Ptex coordinates require three values the index and u,v of the sub-face. To embed sub-face coordinates in a single u,v pair, Bfr tiles the sub-faces in disjoint regions in parameter space. This tiling is similar to the Udim convention for textures, where a UDim on the order of sqrtN is used to preserve accuracy for increasing N  Note also that the edges of each sub-face are of parametric length 0.5, which results in a total parametric length of 1.0 for all base edges. This differs again from Ptex, which parameterizes sub-faces with edge lengths of 1.0, and so can lead to inconsistencies in parametric scale typically with derivatives across edges of the mesh if not careful. As previously mentioned, care may be necessary when dealing with the discontinuities that exist in parameterizations with sub-faces. This is particularly true if evaluating data at sampled locations of the face and needing to evaluate at other locations interpolated from these. Interpolation between parametric locations, e.g. A, B and C, should be avoided when discontinuous. In many cases, dealing directly with coordinates of the sub-faces is unavoidable, e.g. interpolating Ptex coordinates for sampling of textures assigned explicitly to the sub-faces. Methods are provided to convert from Bfr s tiled parameterization to and from other representations that use a local parameterization for each sub-face. Tessellation Once a Surface can be evaluated it can be tessellated. Given a 2D parameterization, a tessellation consists of two parts a set of parametric coordinates sampling the Parameterization a set of faces connecting these coordinates that covers the entire Parameterization Once evaluated, the resulting set of sample points and the faces connecting them effectively define a mesh for that parameterization. For the sake of brevity both here and in the programming interface, the parametric coordinates or sample points are referred to simply as coords or Coords -- avoiding the term points, which is already a heavily overloaded term. Similarly the faces connecting the coords are referred to as facets or Facets -- avoiding the term face to avoid confusion with the base face of the mesh being tessellated. Bfr provides a simple class to support a variety of tessellation patterns for the different Parameterization types and methods for retrieving its associated coords and facets. In many cases the patterns they define are similar to those of GPU hardware tessellation -- which may be more familiar to many -- but they do differ in several ways, as noted below. BfrTessellation In Bfr a Tessellation is a simple class defined by a Parameterization and a given set of tessellation rates and a few additional options. These two elements define a specific tessellation pattern for all faces sharing that Parameterization. An instance of Tessellation can then be inspected to identify all or subsets of its coords or facets. The process of tessellation in other contexts usually generates triangular facets, but that is not the case with Bfr . While producing triangular facets is the default, options are available to have Tessellation include quads in patterns for parameterizations associated with quad-based subdivision schemes. For simple uniform patterns, these produce patterns that are similar in topology to those resulting from subdivision Tessellation of 4- and 5-sided faces of a quad-based scheme using quadrilateral facets left and triangular right The name Tessellation was chosen rather than Tessellator as it is a passive class that simply holds information define its pattern. It doesnt do much other than providing information about the pattern when requested. A few general properties about the pattern are determined and retained on construction, after which an instance is immutable. So it does not maintain any additional state between queries. In order to provide flexibility when dealing with tessellations of adjacent faces, the coords arising from an instance of Tessellation are ordered and are retrievable in ways to help identify points along edges that may be shared between two or more faces. The coords of a Tessellation are generated in concentric rings, beginning with the outer ring and starting with the first vertex Ordering of coords around boundary for quad and tri parameterizations. Methods of the Tessellation class allow the coords associated with specific vertices or edges to be identified, as well as providing the coords for the entire ring around the boundary separately from those of the interior if desired. While the ordering of coords in the interior is not defined and so not to be relied upon, the ordering of the boundary coords is specifically fixed to support the correlation of potentially shared coords between faces. The Tessellation class is completely independent of the Surface class. Tessellation simply takes a Parameterization and tessellation rates and provides the coords and facets that define its pattern. So Tessellation can be used in any other evaluation context where the Parameterizations are appropriate. Tessellation Rates For a particular Parameterization, the various tessellation patterns are determined by one or more tessellation rates. The simplest set of patterns uses a single tessellation rate and is said to be uniform, i.e. all edges and the interior of the face are split to a similar degree Uniform tessellation of a quadrilateral and triangle with rates of 5 and 8. More complex non-uniform patterns allow the edges of the face to be split independently from the interior of the face. Given rates for each edge, a suitable uniform rate for the interior can be either inferred or specified explicitly. These are typically referred to as the outer rates and the inner rate. The single rate specified for a simple uniform tessellation is essentially the specification of a single inner rate while the outer rates for all edges are inferred as the same. Non-uniform tessellation of a quadrilateral, triangle and 5-sided face with various outer and inner rates. In the case of Parameterizations for quads, it is common elsewhere to associate two inner rates with the opposing edges. So two separate inner rates are available for quad parameterizations -- to be specified or otherwise inferred Quad tessellations with differing inner rates with matching left and varying outer rates right. Differences from Hardware Tessellation Since the specifications for hardware tessellation often leave some details of the patterns as implementation dependent, no two hardware implementations are necessarily the same. Typically there may be subtle differences in the non-uniform tessellation patterns along boundaries, and that is to be executed here. Bfr does provide some obvious additional functionality not present in hardware tessellation and vice versa, e.g. Bfr provides the following not supported by hardware tessellation patterns for parameterizations other than quads and tris e.g. N-sided preservation of quad facets of quad-based parameterizations while hardware tessellation provides the following not supported by Bfr  patterns for so-called fractional tessellation non-integer rates The lack of fractional tessellation in Bfr is something that may be addressed in a future release. Where the functionality of Bfr and hardware tessellation overlap, a few other differences are worth noting indexing of edges and their associated outer tessellation rates uniform tessellation patterns for triangles differ significantly For the indexing of edges and rates, when specifying an outer rate associated with an edge, the array index for rate i is expected to correspond to edge i . Bfr follows the convention established elsewhere in OpenSubdiv of labelingindexing edges 0, 1, etc. between vertex pairs 0,1, 1,2, etc. So outer rate 0 corresponds to the edge between vertices 0,1. In contrast, hardware tessellation associates the rate for the edge between vertices 0,1 as outer rate 1 -- its outer rate 0 is between vertices N-1,0. So an offset of 1 is warranted when comparing the two. Outer edge tessellation rates of 1,3,5,7 applied to a quad with Bfr left and GPU tessellation right. For the uniform tessellation of triangles, its well known that the needs of hardware implementation led designers to factor the patterns for triangles to make use of the same hardware necessary for quads. As a result, many edges are introduced into a simple tessellation of a triangle that are not parallel to one of its three edges. Bfr uses patterns more consistent with those resulting from the subdivision of triangles. Only edges parallel to the edges of the triangle are introduced, which creates more uniform facets both edge lengths and area and reduces their number by one third. This can reduce artifacts that sometimes arise with use of the hardware patterns at lower tessellation rates Uniform tessellation of a triangle with Bfr left and GPU tessellation right. These triangular patterns have been referred to as integer spacing for triangular patches in early work on hardware tessellation. But use of these patterns was generally discarded in favor of techniques that split the triangle into three quads -- allowing the hardware solution for quad tessellation to be reused. More on BfrSurfaceFactory The primary function of BfrSurfaceFactory is to identify and construct a representation of the limit surface for a given face of a mesh. It achieves this by inspecting the topology around the given face and constructing a suitable representation encapsulated in a Surface. The regions around a face can be divided into two categories based on their topology those that are regular and those that are not, i.e. those that are irregular. Recalling the illustration from Irregular versus Irregular Features  Patches of regular Surfaces Potential patches of irregular Surfaces The representation of the limit surface for regular regions is trivial -- it is a single parametric patch whose basis is determined by the subdivision scheme e.g. uniform bicubic B-spline for Catmull-Clark. In contrast, the representation of the limit surface for an irregular region cannot be accurately represented so simply. It can be far more complex depending on the features present extra-ordinary vertices, creasing of edges, etc.. It may be as simple as a different kind of parametric patch whose points are derived from those of the mesh, or it may often be a set of patches in a hierarchy resulting from local subdivision.  Bfr intentionally hides the details of these representations to allow future improvement. The cost of determining and assembling the representations of irregular Surfaces is therefore often significant. Some of the performance benefits of the SurfaceFactory are achieved by having it cache the complexities of the irregular surfaces that it encounters. In many common use cases, awareness and management of this caching is not necessary as illustrated by the tutorials. But the thread-safe construction of Surfaces is one area where some awareness is required. Other use cases that share the cache between meshes are also worth exploring as they can further reduce potentially significant costs. BfrSurfaceFactoryCache The SurfaceFactoryCache is the class used by SurfaceFactory to cache the topological information that it can reuse for other similarly irregular faces of the mesh. Though it is a publicly accessible class, the SurfaceFactoryCache has little to no public interface other than construction made available to support more advanced cases covered later and in most cases it can be completely ignored. Typically an instance of SurfaceFactory has an internal SurfaceFactoryCache member which is used by that factory for its lifetime. Since that cache member is mutable -- potentially updated when an irregular Surface is created -- it does need to be thread-safe if the SurfaceFactory is to be used in a threaded context. To accommodate this need, SurfaceFactoryCache is defined as a base class with an accompanying class template to allow the trivial declaration of thread-safe subclasses template  typename MUTEX_TYPE , typename READ_LOCK_GUARD_TYPE , typename WRITE_LOCK_GUARD_TYPE  class SurfaceFactoryCacheThreaded  public SurfaceFactoryCache  ...  For example, a local type for a thread-safe cache using stdshared_mutex from C17 could be simply declared as follows include shared_mutex typedef Bfr  SurfaceFactoryCacheThreaded  std  shared_mutex , std  shared_lock  std  shared_mutex  , std  unique_lock  std  shared_mutex   ThreadSafeCache  Such thread-safe cache types are essential when distributing the work of a single SurfaceFactory across multiple threads. They can be encapsulated in the definitions of subclasses of SurfaceFactory or used to define external cache instances for use with any subclass of SurfaceFactory. Defining a Thread-Safe SurfaceFactory The thread-safety of a SurfaceFactory is purely dependent on the thread-safety of the SurfaceFactoryCache that it uses. With caching disabled, any SurfaceFactory is thread-safe but will be far less efficient in dealing with irregular Surfaces. When a subclass of SurfaceFactory is defined discussed in more detail later, one of its responsibilities is to identify and manage an instance of SurfaceFactoryCache for its internal use. Defining such a subclass is a simple matter of declaring a thread-safe SurfaceFactoryCache type as noted above along with a local member of that type to be used by each instance. Given the widespread use of the FarTopologyRefiner in OpenSubdiv, and the lack of a connected mesh representation in many contexts, a subclass of SurfaceFactory is made available to use a TopologyRefiner as a mesh, i.e. the BfrRefinerSurfaceFactory subclass. Since many OpenSubdiv users may make use of the RefinerSurfaceFactory subclass, and they may have different preferences of threading model, the RefinerSurfaceFactory subclass is similarly defined as a class template to enable threading flexibility. In this case, the template is parameterized by the desired type of SurfaceFactoryCache, which embodies the threading specifications as noted above, i.e. template  class CACHE_TYPE  SurfaceFactoryCache  class RefinerSurfaceFactory  public ...  ...  The default template is the base SurfaceFactoryCache which is not thread-safe, but a simple declaration of a thread-safe cache type is sufficient to declare a similarly thread-safe RefinerSurfaceFactory type include opensubdivbfrsurfaceFactoryCache.h  Declare thread-safe cache type see stdshared_mutex example above typedef Bfr  SurfaceFactoryCacheThreaded  ...  ThreadSafeCache   Declare thread-safe factory type typedef Bfr  RefinerSurfaceFactory  ThreadSafeCache  ThreadSafeFactory  The resulting factory type safely allows the construction of Surfaces and their subsequent evaluation and tessellation to be distributed over multiple threads. Internal versus External SurfaceFactoryCache Typical usage of the SurfaceFactoryCache by the SurfaceFactory is to have the factory create an internal cache member to be used for the lifetime of the factory associated with a mesh. But the data stored in the cache is not in any way dependent on the factory or mesh used to create it. So a cache can potentially be shared by multiple factories. While such sharing is possible -- and the Bfr interfaces intentionally permit it -- any exploration should proceed with caution. Greater public knowledge and control of the cache is ultimately necessary to manage its potentially unbounded memory increase, and support in the public interface is currently limited. A cache stored as a member varialbe and managed exclusively by the factory is said to be internal while one managed exclusively by its client is said to be external. In both cases, the factory deals with retrieving data from or adding data to the cache -- only management of the caches ownership differs, and that ownership is never transferred. A subset of the methods of SurfaceFactoryOptions provide the means of specifying the use of an internal or external cache, or no caching at all  Assign an external cache to override the internal Options  SetExternalCache  SurfaceFactoryCache  cache   Enable or disable caching default is true Options  EnableCaching  bool on  As noted here, specifying an external cache will override use of a factorys internal cache. Disabling caching takes precedence over both, but is generally not practical and exists mainly to aide debugging. The common use of the internal cache is to create a SurfaceFactory and distribute processing of the Surfaces of its faces over multiple threads, or to construct Surfaces for the mesh for any other purpose while the mesh remains in scope. There is no need to deal explicitly with the SurfaceFactoryCache in these cases. Use cases for an external cache are more varied and explicit, including creating a single external cache to process a sequence of meshes on a single thread cache thread-safety not required creating a separate external cache on each thread to process a set of meshes distributed over multiple threads cache thread-safety not required creating a single external cache for multiple meshes distributed over multiple threads cache thread-safety required, and beware of unbounded memory growth here Future extensions to the public interface of SurfaceFactoryCache may be made to support common use cases as their common needs are made clearer. Customizing a BfrSurfaceFactory One of the goals of Bfr is to provide a lightweight interface for the evaluation of Surfaces from any connected mesh representation. In order to do so, the factory needs to gather topological information from that mesh representation. That information is provide to the factory through inheritance a subclass of SurfaceFactory is defined that fulfills all requirements of the factory. It must be made clear that a subclass can only be created from a connected mesh representation, i.e. a representation that includes connectivity or adjacency relationships between its components vertices, faces and edges. Classes for simple containers of mesh topology used for external formats e.g. USD, Alembic, etc. are generally not connected . Many applications construct a connected mesh representation for internal use when loading such mesh data -- using a variety of techniques including half-edges, winged-edges or table-based relationships. There are many choices here that offer a variety of trade-offs depending on usage e.g. fixed vs dynamic topology and so no best solution. Once constructed and available within an application, Bfr strives to take advantage of that representation. As a minimum requirement for supporting a subclass of SurfaceFactory, a connected mesh representation must be able to efficiently identify the incident faces of any given vertex. As noted earlier, when no such representation is available, users can construct a FarTopologyRefiner for their connected mesh and use BfrRefinerSurfaceFactory. There are three requirements of a subclass of SurfaceFactory fulfill the interface required to adapt the connected mesh to the factory provide an internal cache for the factory of the preferred type extend the existing SurfaceFactory interface for the connected mesh type The first of these is the most significant and is the focus here. The second was mentioned previously with the SurfaceFactoryCache and is trivial. The last should also be trivial and is generally optional at minimum the subclass will need a constructor to create an instance of the factory from a given mesh, but anything more is not strictly essential. It is important to note that anyone attempting to write such a subclass must have an intimate understanding of the topological capabilities and limitations of the mesh representation involved. The SurfaceFactory is topologically robust in that it will support meshes with a wide range of degenerate or non-manifold features, but in order to process topology efficiently, a subclass needs to indicate when and where those degeneracies may occur. A simplified implementation of the BfrRefinerSurfaceFactory is provided in the tutorials for illustration purposes. The BfrSurfaceFactoryMeshAdapter Interface The SurfaceFactoryMeshAdapter class defines the interface used to satisfy the topological requirements of the SurfaceFactory. An implementation for a particular mesh class provides the base factory with everything needed to identify the limit surface of a given face from its surrounding topology. The SurfaceFactory actually inherits the SurfaceFactoryMeshAdapter interface but does not implement it -- deferring that to its subclasses -- since separate subclasses of SurfaceFactoryMeshAdapter serve no other purpose. The limit surface for a face is fully defined by the complete set of incident vertices, faces and edges surrounding the face. But it is difficult to accurately and efficiently assemble and represent all of that required information in a single class or query for all possible cases. So the mesh adapter interface provides a suite of methods to allow the factory to gather only what it needs for the Surface required -- which may differ considerably according to whether the Surface is for vertex or face-varying data, linear or non-linear, etc. The virtual methods required can be organized into small groups devoted to particular aspects of construction. A description of the methods and purposes for each group follows, with more details and exact signatures available in the accompanying Doxygen for the SurfaceFactoryMeshAdapter class. Basic Properties of a Face A small set of simple methods indicate whether the SurfaceFactory needs to create a Surface for a face, and if so, how virtual bool isFaceHole  Index faceIndex  const  0  virtual int getFaceSize  Index faceIndex  const  0  These are trivial and self-explanatory. Identifying Indices for an Entire Face If the Surface requested turns out to be linearly interpolated e.g. for varying or linear face-varying data indices for the control point data are all assigned to the face and can be trivially identified virtual int getFaceVertexIndices  Index faceIndex , Index vertexIndices  const  0  virtual int getFaceFVarValueIndices  Index faceIndex , FVarID faceVaryingID , Index faceVaryingIndices  const  0  Since multiple sets of face-varying data with different topology may be assigned to the mesh, an identifier needs to be specified both in the public interface when requesting a Surface and here when the factory assembles it. How a face-varying identifier is interpreted is completely determined by the subclass through the implementation of the methods that require it. Specifying the Neighborhood Around a Vertex When the Surface requested is not linear, the entire neighborhood around the face must be determined. This is achieved by specifying the neighborhoods around each of the vertices of the face, which the factory then assembles. For the neighborhood of each face-vertex, the factory obtains a complete specification in a simple VertexDescriptor class. An instance of VertexDescriptor is provided and populated with the following method virtual int populateFaceVertexDescriptor  Index faceIndex , int faceVertex , VertexDescriptor  vertexDescriptor  const  0  Within this method, the given VertexDescriptor instance is initialized using a small suite of VertexDescriptor methods that specify the following information about the vertex and its neighborhood whether the neighborhood is manifold ordered counter-clockwise whether the vertex is on a boundary the sizes of all or each incident face the sharpness of the vertex the sharpness of edges of incident faces These methods are specified between Initialize and Finalize methods, so an interior vertex of valence 4 with three incident quads and one incident triangle might be specified as follows int vertexValence  4  vertexDescriptor . Initialize  vertexValence  vertexDescriptor . SetManifold  true  vertexDescriptor . SetBoundary  false  vertexDescriptor . SetIncidentFaceSize  0 , 4  vertexDescriptor . SetIncidentFaceSize  1 , 4  vertexDescriptor . SetIncidentFaceSize  2 , 3  vertexDescriptor . SetIncidentFaceSize  3 , 4  vertexDescriptor . Finalize  Specifying the vertex neighborhood as manifold is critical to allowing the factory to inspect the neighborhood efficiently. A manifold vertex has its incident faces and edges ordered in a counter-clockwise orientation and is free of degeneracies. If it is not clear that a vertex is manifold, it should not be set as such or the factorys inspection of associated data will not be correct. Identifying Indices Around a Vertex When the Surface requested is not linear, the indices of control point data for the entire neighborhood of the face are ultimately required, and that entire set is similarly determined by identifying the indices for each of the neighborhoods of the face-vertices virtual int getFaceVertexIncidentFaceVertexIndices  Index faceIndex , int faceVertex , Index vertexIndices  const  0  virtual int getFaceVertexIncidentFaceFVarValueIndices  Index faceIndex , int faceVertex , FVarID faceVaryingID , Index faceVaryingIndices  const  0  As was the case with the methods retrieving indices for the entire face, one exists for identifying indices vertex data while another exists to identify indices for a specified set of face-varying data. Customizing the Subclass Interface Once the topological requirements of a subclass have been satisfied for its mesh representation, minor customizations of the inherited interface of SurfaceFactory may be useful. Consider a class called Mesh and its associated subclass of SurfaceFactory called MeshSurfaceFactory. At minimum, a constructor of MeshSurfaceFactory is necessary to construct an instance for a particular instance of mesh. This is typically achieved as follows MeshSurfaceFactory  Mesh const  mesh , Options const  options  In addition to the Mesh instance, such a constructor passes a set of Options i.e. SurfaceFactoryOptions to the base SurfaceFactory. Any additional arguments are possible here, e.g. perhaps only a single face-varying UV set is supported, and that might be specified by identifying it on construction. Given that mesh representations often have their own associated classes that internally contain the actual data, it may be useful to provide a few other conveniences to simplify working with a Mesh. For example, if mesh data is stored in a class called MeshPrimvar, a method to construct a Surface from a given MeshPrimvar may be useful, e.g. bool InitPrimvarSurface  int faceIndex , MeshPrimvar const  meshPrimvar , Surface  float   surface  which would then determine the nature of the MeshPrimvar data interpolated as vertex, varying or face-varying and act accordingly. It may also be worth simplifying the template complexity here if only one precision is ever required. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_overview.html"}, 
{"title":"Porting Guide 2.x to 3.0", "text":"Porting Guide 2.x to 3.0 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Porting Guide 2.x to 3.0 3.6.0 User Docs API Docs Release Notes Forum Github Porting Guide 2.x to 3.0 Porting Guide 2.x to 3.0 Source Code Organization Hbr Layer Translation Subdivision Schemes and Options in Sdc Specifying Face Varying Topology and Options Far Layer Translation Ordering of Refined Vertices Osd Layer Translation Controller Objects ComputeContext, DrawContext EvalLimitContext OsdMesh OsdKernelBatch OsdVertex Feature Adaptive Shader Changes End Cap Strategies Changes to Subdivision Build Support for Combining 2.x and 3.0 Porting Guide 2.x to 3.0 This document is a high-level description of how to port exiting OpenSubdiv 2.x code to use OpenSubdiv 3.0. NOTE If your questions are not answered here, please contact us on the OpenSubdiv forum and we will be happy to help Source Code Organization Given the scale of functional changes that were being made to the public interface, we took the opportunity in 3.0 to update the coding style and organization -- most notably making use of namespaces for each library. Subdirectory Namespace Relevance hbr NA Historical, no longer used sdc Sdc New, low-level, public options, constants, etc. vtr Vtr New, internal use, topology representation far Far Revised, similar functionality with new API osd Osd Revised, similar functionality with new API Hbr Layer Translation Client mesh topology is now translated into an instance of FarTopologyRefiner instead of HbrMesh. OpenSubdiv 2.x OpenSubdiv 3.0 HbrMeshVTX_TYPE FarTopologyRefiner The FarTopologyRefiner is now the core representation of topology from which all other major classes in Far and Osd are constructed. It was designed to support efficient refinement uniform or sparse of a base mesh of arbitrary topology no manifold restrictions. Once constructed it can be directly refined to meet some need, or passed to other contexts that will refine it to meet their needs. In contrast to directly assembling an HbrMesh, the TopologyRefiner, like other classes in Far, requires a Factory class for its construction. One of the early goals of these factories was to allow a client to convert their existing boundary representation -- with its full topological traversal abilities -- directly into the TopologyRefiners representation. While this is now possible, this also represents the most complex construction process and is only recommended for usage where this conversion process is critical. Details on how to construct a TopologyRefiner can be found in the Far overview documentation. Additionally, documentation for FarTopologyRefinerFactoryMESH outlines the requirements, and Far tutorial 3.1 tutorialsfartutorial_3_1 provides an example of a factory for directly converting HbrMeshes to TopologyRefiners. Its worth a reminder here that FarTopologyRefiner contains only topological information which does include sharpness, since that is considered relating to subdivision topology and not the positions or other data associated with a mesh. While HbrMeshT required some definition of a vertex type T and dimensions of face-varying data, TopologyRefiner is more clearly separated from the data. So the construction of the TopologyRefiner does not involve data specification at all. Subdivision Schemes and Options in Sdc The creation of a new TopologyRefiner requires specification of a subdivision scheme and a set of options that are applicable to all schemes. With HbrMesh, the scheme was specified by declaring a static instance of a specific subclass of a subdivision object, and the options were specified with a number of methods on the different classes. Such general information about the schemes has now been encapsulated in the Sdc layer for use throughout OpenSubdiv. The subdivision scheme is now a simple enumerated type SdcSchemeType and the entire set of options that can be applied to a scheme is encapsulated in a single simple struct of flags and enumerated types SdcOptions. OpenSubdiv 2.x OpenSubdiv 3.0 HbrMeshTSetInterpolateBoundaryMethod SdcOptionsSetVtxBoundaryInterpolation HbrMeshTSetFVarInterpolateBoundaryMethod SdcOptionsSetFVarLinearInterpolation HbrSubdivisionTSetCreaseSubdivisionMethod SdcOptionsSetCreasingMethod Specifying Face Varying Topology and Options Both the way in which face varying data is associated with a mesh and the options used to control its interpolation have changed. The documentation on Compatibility with OpenSubdiv 2.x details the equivalence of interpolation options between Hbr and the new SdcOptionsFVarLinearInterpolation enum, while the section on Face Varying Interpolation illustrates their effects. Face varying data is now specified by index rather than by value, or as often stated, it is specified topologically. Just as vertices for faces are specified by indices into a potential buffer of positions, face varying values are specified by indices into a potential buffer of values. Both vertices and face varying values frequently referred to as FVarValues in the API are assigned and associated with the corners of all faces. In many cases this will simplify representation as many common geometry container formats such as Obj or Alembic specify texture coordinates the same way. For other cases, where a value per face-corner is provided with no indication of which values incident each vertex should be considered shared, it will be necessary to determine shared indices for values at each vertex if any non-linear interpolation is desired. Far Layer Translation While TopologyRefiner was introduced into Far as the new intermediate topology representation, several other changes were made to classes in Far to provide more modular building blocks for use by the Osd layer or directly. OpenSubdiv 2.x OpenSubdiv 3.0 FarMeshU NA, no longer needed FarSubdivisionTables FarStencilTable FarPatchTables FarPatchTable Ordering of Refined Vertices The FarMesh was previously responsible for refining an HbrMesh -- generating new vertices and faces in successive levels of refinement in the FarSubdivisionTables. Vertices were grouped and reordered from the native ordering of HbrMesh so that vertices requiring similar processing were consecutive. Such grouping alleviated most of the idiosyncrasies of HbrMeshs native ordering but not all. FarToplogyRefiner is inherently a collection of refinement levels, and within each refined level so excluding the base level, all components are still grouped for the same reasons. There are two issues here though the ordering of these groups has changed though an option exists to preserve it the ordering of components within these groups is not guaranteed to have been preserved Vertices in a refined level are grouped according to the type of component in the parent level from which they originated, i.e. some vertices originate from the center of a face face-vertices, some from an edge edge-vertices and some from a vertex vertex-vertices. Note that there is a conflict in terminology here -- face-vertices and edge-vertices most often refer to vertices incident a face or edge -- but for the sake of this discussion, we use them to refer to the component from which a child vertex originates. The following table shows the ordering of these groups in 2.x and the two choices available in 3.0. The option is the orderVerticesFromFacesFirst flag that can be set in the Option structs passed to the uniform and adaptive refinement methods of TopologyRefiner Version and option Vertex group ordering 2.x face-vertices, edge-vertices, vertex-vertices 3.0 default vertex-vertices, face-vertices, edge-vertices 3.0 orderVerticesFromFacesFirst  true face-vertices, edge-vertices, vertex-vertices The decision to change the default ordering was based on common feedback the rationale was to allow a trivial mapping from vertices in the cage to their descendants at all refinement levels. While the grouping is fundamental to the refinement process, the ordering of the groups is internally flexible, and the full set of possible orderings can be made publicly available in future if there is demand for such flexibility. The ordering of vertices within these groups was never clearly defined given the way that HbrMesh applied its refinement. For example, for the face-vertices in a level, it was never clear which face-vertices would be first as it depended on the order in which HbrMesh traversed the parent faces and generated them. Given one face, HbrMesh would often visit neighboring faces first before moving to the next intended face. The ordering with FarTopologyRefiner is much clearer and predictable. Using the face-vertices as an example, the order of the face-vertices in level N1 is identical to the order of the parent faces in level N from which they originated. So if we have face-vertices Vi , Vj and Vk at some level, originating from faces Fi , Fj and Fk in the previous level, they will be ordered in increasing order of i , j and k . For uniform refinement the ordering of face vertices Vi will therefore exactly match the ordering of the parent faces Fi . For adaptive or otherwise sparse refinement, the subset of Vi will be ordered similarly, just with components missing from those not refined. The same is true of all vertices, i.e. edge-vertices and vertex-vertices, and also for other components in refined levels, i.e. the child faces and edges. For child faces and edges, more than one will originate from the same parent face or edge. In addition to the overall ordering based on the parent faces or edges, another ordering is imposed on multiple children originating from the same face or edge. They will be ordered based on the corner or end-vertex with which they are associated. In the case of refined faces, another way to view the ordering is to consider the way that faces are originally defined -- by specifying the set of vertices for the corners of each face, often aggregated into a single large array. The ordering of the set of refined faces for each level will correspond directly to such an array of vertices per face in the previous level. Osd Layer Translation Two big changes in the 3.0 API have allowed the Osd layer to be significantly simpler, the first is the move to stencil tables from subdivision tables and the second is shader simplification. With this refactoring, the focus has been to use more meaningful names and to make the data contained within an object more apparent. Controller Objects The API-specific ComputeController has been replaced with the Evaluator . It reflects the fact that stencil compute batches are significantly simpler than subdivision table compute batches. The name Evaluator was chosen with the hope that is more meaningful than the generic ComputeController moniker the Evaluator evaluates stencil and patch tables. In the 2.x code base, subdiv level buffers were always required to be allocated contiguously, however in 3.0 with the shift to stencil tables, this strict allocation scheme is no longer required. As a result, the EvalStencils and EvalPatches methods now accept both a source and a destination descriptor. OpenSubdiv 2.x OpenSubdiv 3.0 ComputeControllerRefine Osd...EvaluatorEvalStencils ComputeControllerSynchronize Osd...EvaluatorSynchronize EvalStencilsControllerUpdateValues Osd...EvaluatorEvalStencils EvalStencilsControllerUpdateDerivs Osd...EvaluatorEvalStencils EvalLimitControllerEvalLimitSample Osd...EvaluatorEvalPatches Also note that OsdVertexDescriptor has been renamed, however its data members and semantic purpose remains the same OpenSubdiv 2.x OpenSubdiv 3.0 OsdVertexBufferDescriptor OsdBufferDescriptor ComputeContext, DrawContext ComputeContext and DrawContext have been replaced with API-specific StencilTable and PatchTable objects, for example OsdGLStencilTableSSBO. OpenSubdiv 2.x OpenSubdiv 3.0 ComputeContext Osd...StencilTable e.g. GLStencilTableTBO EvalStencilsContext Osd...StencilTable DrawContext Osd...PatchTable e.g. GLPatchTable EvalLimitContext The data stored in EvalLimitContext has been merged into the Evaluator class as well. EvalCoords have been moved into their own type, OsdPatchCoords. The primary change here is that the PTex face ID is no longer part of the data structure, rather the client can use a FarPatchMap to convert from PTex face ID to a FarPatchTablePatchHandle. OpenSubdiv 2.x OpenSubdiv 3.0 EvalLimitContext PatchTable EvalLimitContextEvalCoords OsdPatchCoords types.h OsdMesh While not strictly required, OsdMesh is still supported in 3.0 as convenience API for allocating buffers. OsdMesh serves as a simple way to allocate all required data, in the location required by the API for example, GPU buffers for OpenGL. OsdKernelBatch No translation, it is no longer part of the API. OsdVertex No translation, it is no longer part of the API. Feature Adaptive Shader Changes In 3.0, the feature adaptive screen-space tessellation shaders have been dramatically simplified, and the client-facing API has changed dramatically as well. The primary shift is to reduce the total number of shader combinations, and as a result, some of the complexity management mechanisms are no longer necessary. In the discussion below, some key changes are highlighted, but deep integrations may require additional discussion please feel free to send follow up questions to the OpenSubdiv google group. The number of feature adaptive shaders has been reduced from N to exactly 1 or 2, depending on how end-caps are handled. Osd layer no longer compiles shaders, rather it returns shader source for the client to compile. This source is obtained via OsdGLSLHLSLPatchShaderSource. The API exposed in shaders to access patch-based data has been consolidated and formalized, see osdglslPatchCommon.glsl and osdhlslPatchCommon.hlsl for details. Patches are no longer rotated and transition patches have been eliminated, simplifying PatchDescriptor to a 4 bits. Additionally, FarPatchTablesDescriptor has been moved into its own class in the Far namespace. The following table outlines the API translation between 2.x and 3.0 OpenSubdiv 2.x OpenSubdiv 3.0 OsdDrawContextPatchDescriptor NA, no longer needed. OsdDrawContextPatchArray OSdPatchArray types.h FarPatchTablesPatchDescriptor FarPatchDescriptor patchDescriptor.h FarPatchTablesPatchArray made private. End Cap Strategies By default, OpenSubdiv uses Gregory patches to approximate the patches around extraordinary vertices at the maximum isolation level, this process is referred to as end-capping. If ENDCAP_BSPLINE_BASIS is specified to PatchTableFactoryOptions, BSpline patches are used, which gives less accuracy, but it makes possible to render an entire mesh in a single draw call. Both patches require additional control points that are not part of the mesh, we refer to these as local points. In 3.0, the local points of those patches are computed by applying a stencil table to refined vertices to construct a new stencil table for the local points. Since this new stencil table is topologically compatible with the primary stencil table for refinement, it is convenient and efficient to splice those stencil tables together. This splicing can be done in the following way FarStencilTable const refineStencils  FarStencilTableFactoryCreatetopologyRefiner FarPatchTable cosnt patchTable  FarPatchTableFactoryCreatetopologyRefiner FarStencilTable const localPointStencils  patchTable-GetLocalPointStencilTable FarStencilTable const splicedStencils  FarStencilTableFactoryAppendLocalPointStencilTablestopologyRefiner, refineStencils, localPointStencils NOTE Once the spliced stencil table is created, the refined stencils can be released, but the local point stencils are owned by patchTable, it should not be released. OpenSubdiv 3.0 also supports 2.x style Gregory patches, if ENDCAP_LEGACY_GREGORY is specified to PatchTableFactoryOptions. In this case, such an extra stencil splicing isnt needed, however clients must still bind additional buffers VertexValence buffer and QuadOffsets buffer. See OsdGLLegacyGregoryPatchTable for additional details. Changes to Subdivision 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 -- none of which was taken lightly. More details are provided in Subdivision Compatibility , while the following offers a quick overview All face-varying interpolation options have been combined into a single enum. Vertex interpolation options have been renamed or removed The naming of the standard creasing method has changed from Normal to Uniform . Unused legacy modes of the smoothtriangle option have been removed. The averaging of Chaikin creasing with infinitely sharp edges has changed. Support for Hierarchical Edits has been removed. Build Support for Combining 2.x and 3.0 Running OpenSubdiv 2.0 and 3.0 in a single process is supported, however some special care must be taken to avoid namespace collisions, both in terms of run-time symbols avoid using OpenSubdivOsd, for example and in terms of build-time search paths. To support both OpenSubdiv 2.0 and 3.0 in your build environment, you can prefix the header install directory of OpenSubdiv 3.0. Do this using the build flag CMAKE_INCDIR_BASE when configuring cmake i.e. -DCMAKE_INCDIR_BASEincludeopensubdiv3 and then including files from opensubdiv3... in client code. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"porting.html"}, 
{"title":"Overview of Release 3.0", "text":"Overview of Release 3.0 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.0 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.0 Release 3.0 Subdivision Core Sdc Topology and Refinement Limit Properties and Patches Faster Evaluation and Display Updated Source-Code Style Documentation and Tutorials Additional Resources Porting Guide Subdivision Compatibility Release 3.0 OpenSubdiv 3.0 represents a landmark release, with profound changes to the core algorithms, simplified APIs, and streamlined GPU execution. Providing faster, more efficient, and more flexible subdivision code remains our principal goal. To achieve this, OpenSubdiv 3.0 introduces many improvements that constitute a fairly radical departure from previous versions. This document highlights some of the major changes that have gone in to the 3.0 release. Subdivision Core Sdc In consideration of past, present and future topological representations, all low-level details fundamental to subdivision and the specific subdivision schemes have been factored into a new low-level layer called Sdc SubDivision Core. This layer encapsulates the full set of applicable options, the formulae required to support semi-sharp creasing, the formulae for the refinement masks of each subdivision scheme, etc. As initially conceived, its goal was often expressed as separating the math from the mesh. Sdc provides the low-level nuts and bolts to provide a subdivision implementation consistent with OpenSubdiv. It is used by OpenSubdivs libraries and may also be useful in providing an existing clients implementation with the details necessary to make that implementation consistent with OpenSubdiv. Topology and Refinement OpenSubdiv 3.0 introduces a new intermediate internal topological representation named Vtr Vectorized Topology Representation. Compared to the Hbr library used in previous versions, Vtr is much more efficient for the kinds of topological analysis required by Far and is more flexible. While Hbr is no longer used by OpenSubdiv, it will remain in the source distribution for legacy and regression purposes. Faster Subdivision A major focus of the 3.0 release is performance, and the improvement to the initial refinement of a mesh required for topological analysis is close to an order magnitude often much more for uniform, but less for adaptive. Supporting for Non-manifold Topology With topology conversion no longer constrained by Hbr, OpenSubdiv is no longer restricted to meshes of manifold topology. With one exception non-triangles with Loop subdivision, any set of faces and vertices that can be represented in common container formats such as Obj or Alembic can be represented and subdivided. With future efforts to bring the functionality for the Loop scheme up to par with Catmark, that last remaining topological restriction will be removed. Simpler Conversion of Topology Several entry-points are now available for client topology, rather than the single incremental assembly of an HbrMesh that previously existed. The new topological relationships can be populated using either a high-level interface where simplicity has been emphasized, or a more complex lower-level interface for enhanced efficiency. Face Varying Topology Previously, face-varying data was assigned by value to the vertex for each face, and whether or not the set of values around a vertex was continuous was determined by comparing these values later. In some cases this could result in two values that were not meant to be shared being welded together. Face-varying data is now specified topologically just as the vertex topology is defined from a set of vertices and integer references indices to these vertices for the corner of each face, face-varying topology is defined from a set of values and integer references indices to these values for the corner of each face. So if values are to be considered distinct around a vertex, they are given distinct indices and no comparison of any data is ever performed. Note that the number of vertices and values will typically differ, but since indices are assigned to the corners of all faces for both, the total number of indices assigned to all faces will be the same. This ensures that OpenSubdivs face-varying topology matches what is often specified in common geometry container formats like Obj, Alembic and USD. Multiple channels of face-varying data can be defined and each is topologically independent of the others. Limit Properties and Patches A fundamental goal of OpenSubdiv is to provide an accurate and reliable representation of the limit surface. Improvements have been made both to the properties positions and tangents at discrete points in the subdivision hierarchy, as well as to the representations of patches used for the continuous limit surface between them. Removed Fixed Valence Tables Limit properties of extra-ordinary vertices are computed for arbitrary valence and new patch types no longer rely on small table sizes. All tables that restricted the valence of a vertex to some relatively small table size have now been removed. The only restriction on valence that exists is within the new topology representation, which restricts it to the size of an unsigned 16-bit integer 65,535. This limit could also be removed, by recompiling with a certain size changed from 16- to 32-bits, but doing so would increase the memory cost for all common cases. We feel the 16-bit limit is a reasonable compromise. Single Crease Patch OpenSubdiv 3.0 newly implements efficient evaluation of semi-smooth creases using single crease patches. With this optimization, high-order edge sharpness tags can be handled very efficiently for both computation time and memory consumption.  Niessner et al., Efficient Evaluation of Semi-Smooth Creases in Catmull-Clark Subdivision Surfaces. Eurographics Short Papers. 2012. httpresearch.microsoft.comen-usumpeoplecloopEG2012.pdf New Irregular Patch Approximations While legacy Gregory patch support is still available, we have introduced several new options for representing irregular patches Legacy Gregory, fast Gregory Basis stencils, and BSpline patches. Gregory basis stencils provide the same high quality approximation of Legacy Gregory patches, but execute considerably faster with a simpler GPU representation. While BSpline patches are not as close an approximation as Gregory patches, they enable an entire adaptively refined mesh to be drawn with screen space tessellation via a single global shader configuration Gregory Basis patches require one additional global shader configuration. The new implementations of the GregoryBasis and BSpline approximations relax the previous max valence limit. Legacy Gregory patch still has a limitation of max valence typically 24, depending on the hardware capability of GL_MAX_VARYING_VECTORS. Users are still encouraged to use models with vertices of low valence for both improved model quality and performance. Faster Evaluation and Display OpenSubdiv 3.0 also introduces new data structures and algorithms that greatly enhance performance for the common case of repeated evaluation both on the CPU and GPU. Introducing Stencil Tables OpenSubdiv 3.0 replaces the serialized subdivision tables with factorized stencil tables. The SubdivisionTables class of earlier releases contained a large number of data inter-dependencies, which incurred penalties from fences or force additional kernel launches. Most of these dependencies have now been factorized away in the pre-computation stage, yielding stencil tables FarStencilTable instead. Stencils remove all data dependencies and simplify all the computations into a single trivial kernel. This simplification results in a faster pre-computation stage, faster execution on GPU, with less driver overhead. The new stencil tables Compute back-end is supported on all the same platforms as previous releases except GCD. Faster, Simpler GPU Kernels On the GPU side, the replacement of subdivision tables with stencils greatly reduces bottlenecks in compute, yielding as much as a 4x interpolation speed-up. At the same time, stencils reduce the complexity of interpolation to a single kernel launch per primitive, a critical improvement for mobile platforms. As a result of these changes, compute batching is now trivial, which in turn enabled API simplifications in the Osd layer. Unified Adaptive Shaders Adaptive tessellation shader configurations have been greatly simplified. The number of shader configurations has been reduced from a combinatorial per-patch explosion down to a constant two global configurations. This massive improvement over the 2.x code base results in significantly faster load times and a reduced per-frame cost for adaptive drawing. Similar to compute kernel simplification, this shader simplification has resulted in additional simplifications in the Osd layer. Updated Source-Code Style OpenSubdiv 3.0 replaces naming prefixes with C namespaces for all API layers, bringing the source style more in line with contemporary specifications mostly inspired from the Google C Style Guide . The large-scale changes introduced in this release generally break compatibility with existing client-code. However, this gives us the opportunity to effect some much needed updates to our code-style guidelines and general conventions, throughout the entire OpenSubdiv code-base. We are hoping to drastically improve the quality, consistency and readability of the source code. Documentation and Tutorials The documentation has been reorganized and fleshed out. This release introduces a number of new tutorials . The tutorials provide an easier entry point for learning the API than do the programs provided in examples. The examples provide more fleshed out solutions and are a good next step after the tutorials are mastered. Additional Resources Porting Guide Please see the Porting Guide for help on how to port existing code written for OpenSubdiv 2.x to the new 3.0 release. Subdivision Compatibility The 3.0 release has made some minor changes to the subdivision specification and rules. See Subdivision Compatibility for a complete list. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_30.html"}, 
{"title":"References", "text":"References Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen References 3.6.0 User Docs API Docs Release Notes Forum Github References References References Analytic Displacement Mapping using Hardware Tessellation Matthias Niessner, Charles Loop ACM Transactions on Graphics, Vol. 32 No. 3 Article 26 June 2013 httpresearch.microsoft.comen-usumpeoplecloopTOG2013.pdf httpdoi.org10.11452487228.2487234 Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces Matthias Niessner, Charles Loop, Mark Meyer, and Tony DeRose ACM Transactions on Graphics, Vol. 31 No. 1 Article 6 January 2012 httpresearch.microsoft.comen-usumpeopleclooptog2012.pdf httpdoi.org10.11452077341.2077347 Efficient Evaluation of Semi-Smooth Creases in Catmull-Clark Subdivision Surfaces Matthias Niessner, Charles Loop, and Guenter Greiner. Eurographics Proceedings, Cagliari, 2012 httpresearch.microsoft.comen-usumpeoplecloopEG2012.pdf httpdoi.org10.2312confEG2012short041-044 Approximating Subdivision Surfaces with Gregory Patches for Hardware Tessellation Charles Loop, Scott Schaefer, Tianyun Ni, Ignacio Castano SIGGRAPH Asia Conference Proceedings 2009 httpwww.dgp.toronto.edupeoplestamrealityResearchpdfsig98.pdf httpdoi.org10.11451661412.1618497 GPU Smoothing of Quad Meshes T. L. Ni, Y. Yeo, A. Myles, V. Goel and J. Peters Proc. IEEE SMI 2008 httpwww.cise.ufl.eduresearchSurfLabpaperssmi08.pdf httpdoi.org10.1109SMI.2008.4547938 Fast Parallel Construction of Smooth Surfaces from Meshes with TriQuadPent Facets A. Myles and T. Ni and J. Peters Eurographics Symposium on Geometry Processing 2008 httpswww.cise.ufl.eduresearchSurfLabpapers08poly.pdf httpdoi.org10.1111j.1467-8659.2008.01276.x Approximating Catmull-Clark Subdivision Surfaces with Bicubic Patches Charles Loop, Scott Schaefer ACM Transactions on Graphics, Vol. 27 No. 1 Article 8 March 2008 httpresearch.microsoft.comen-usumpeoplecloopacctog.pdf httpdoi.org10.11451330511.1330519 Rapid Evaluation of Catmull-Clark Subdivision Surfaces Jeffrey Bolz and Peter Schroder Web3D Proceedings 2002 httpwww.multires.caltech.edupubsfastsubd.pdf httpdoi.org10.1145504502.504505 Piecewise Smooth Subdivision Surfaces with Normal Control Henning Biermann, Adi Levin and Denis Zorin SIGGRAPH 2000 Conference Proceedings httpmrl.nyu.edudzorinpapersbiermann2000pss.pdf httpdoi.org10.1145344779.344841 Subdivision for Modeling and Animation Denis Zorin, Peter Schroder Course Notes of SIGGRAPH 1999 httpwww.multires.caltech.edupubssig99notes.pdf Exact Evaluation of Catmull-Clark Subdivision Surfaces at Arbitrary Parameter Values Jos Stam SIGGRAPH 98 Conference Proceedings, Annual Conference Series, July 1998 httpwww.dgp.toronto.edupeoplestamrealityResearchpdfsig98.pdf httpdoi.org10.1145280814.280945 Subdivision Surfaces in Character Animation Tony DeRose, Michael Kass, Tien Truong Proceedings of SIGGRAPH 1998 httpgraphics.pixar.comlibraryGeripaper.pdf httpdoi.org10.1145280814.280826 Efficient, Fair Interpolation Using Catmull-Clark Surfaces Mark Halstead, Michael Kass, Tony DeRose SIGGRAPH 93 Conference Proceedings httpgraphics.pixar.comlibraryFairSubdivisionpaper.pdf httpdoi.org10.1145166117.166121 Recursively generated B-spline surfaces on arbitrary topological meshes Catmull, E. Clark, J. Computer-Aided Design 10 6 1978 httpdoi.org10.10160010-448528782990110-0 Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"references.html"}, 
{"title":"OSD Tessellation shader Interface", "text":"OSD Tessellation shader Interface Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen OSD Tessellation shader Interface 3.6.0 User Docs API Docs Release Notes Forum Github OSD Tessellation shader Interface Basic Tessellation Control Shader Example for B-Spline patches Tessellation Evaluation Shader Example for B-Spline patches Basis Conversion B-spline Patch Gregory Basis Patch Box-spline Triangle Patch Gregory Triangle Patch Legacy Gregory Patch 2.x compatibility Tessellation levels Tessellation levels at each tessellated vertex Tessellation levels computed at each patch Uniform Screenspace Basic Starting with 3.0, Osd tessellation shaders can be used as a set of functions from client shader code. In order to tessellate Osd patches, client shader code should perform the following steps regular B-spline patch case In a tessellation control shader fetch a PatchParam for the current patch call OsdComputePerPatchVertexBSpline to compute OsdPerPatchVertexBezier. compute tessellation level. To prevent cracks on transition patches, two vec4 parameters tessOuterHi, tessOuterLo will be needed in addition to built-in gl_TessLevelInnerOuters. In a tessellation evaluation shader call OsdGetTessParameterization to remap gl_TessCoord to a patch parameter at which to evaluate. call OsdEvalPatchBezierOsdEvalPatchGregory to evaluate the current patch. The following is a minimal example of GLSL code explaining how client shader code uses OpenSubdiv shader functions to tessellate patches of a patch table. Tessellation Control Shader Example for B-Spline patches layout  vertices  16  out  in vec3 position  patch out vec4 tessOuterLo , tessOuterHi  out OsdPerPatchVertexBezier v  void main    Get a patch param from texture buffer. ivec3 patchParam  OsdGetPatchParam  gl_PrimitiveID   Compute per-patch vertices. OsdComputePerPatchVertexBSpline  patchParam , gl_InvocationID , position , v   Compute tessellation factors. if  gl_InvocationID  0   vec4 tessLevelOuter  vec4  0  vec2 tessLevelInner  vec2  0  OsdGetTessLevelsUniform  patchParam , tessLevelOuter , tessLevelInner , tessOuterLo , tessOuterHi  gl_TessLevelOuter  0   tessLevelOuter  0  gl_TessLevelOuter  1   tessLevelOuter  1  gl_TessLevelOuter  2   tessLevelOuter  2  gl_TessLevelOuter  3   tessLevelOuter  3  gl_TessLevelInner  0   tessLevelInner  0  gl_TessLevelInner  1   tessLevelInner  1    Tessellation Evaluation Shader Example for B-Spline patches layout  quads  in  patch in vec4 tessOuterLo , tessOuterHi  in OsdPerPatchVertexBezier v  uniform mat4 mvpMatrix  void main    Compute tesscoord. vec2 UV  OsdGetTessParameterization  gl_TessCoord . xy , tessOuterLo , tessOuterHi  vec3 P  vec3  0 , dPu  vec3  0 , dPv  vec3  0  vec3 N  vec3  0 , dNu  vec3  0 , dNv  vec3  0  ivec3 patchParam  inpt  0 . v . patchParam   Evaluate patch at the tess coord UV OsdEvalPatchBezier  patchParam , UV , v , P , dPu , dPv , N , dNu , dNv   Apply model-view-projection matrix. gl_Position  mvpMatrix  vec4  P , 1   Basis Conversion B-spline Patch The following diagram shows how the Osd shaders process b-spline patches. While regular patches are expressed as b-spline patches in FarPatchTable, the Osd shader converts them into Bezier basis patches for simplicity and efficiency. This conversion is performed in the tessellation control stage. The boundary edge evaluation and single crease matrix evaluation are also resolved during this conversion. OsdComputePerPatchVertexBSpline can be used for this process. The resulting Bezier control vertices are stored in OsdPerPatchVertexBezier struct. void OsdComputePerPatchVertexBSpline  ivec3 patchParam , int ID , vec3 cv  16 , out OsdPerPatchVertexBezier result  The tessellation evaluation shader takes an array of OsdPerPatchVertexBezier struct, and then evaluates the patch using the OsdEvalPatchBezier function. void OsdEvalPatchBezier  ivec3 patchParam , vec2 UV , OsdPerPatchVertexBezier cv  16 , out vec3 P , out vec3 dPu , out vec3 dPv , out vec3 N , out vec3 dNu , out vec3 dNv  Gregory Basis Patch In a similar way, Gregory basis patches are processed as follows OsdComputePerPatchVertexGregoryBasis can be used for the Gregory patches although no basis conversion involved for the Gregory patches and the resulting vertices are stored in a OsdPerPatchVertexGreogryBasis struct. void OsdComputePerPatchVertexGregoryBasis  ivec3 patchParam , int ID , vec3 cv , out OsdPerPatchVertexGregoryBasis result  The tessellation evaluation shader takes an array of OsdPerPatchVertexGregoryBasis struct, and then evaluates the patch using the OsdEvalPatchGregory function. void OsdEvalPatchGregory  ivec3 patchParam , vec2 UV , vec3 cv  20 , out vec3 P , out vec3 dPu , out vec3 dPv , out vec3 N , out vec3 dNu , out vec3 dNv  Box-spline Triangle Patch While regular triangle patches are expressed as triangular box-spline patches in FarPatchTable, the Osd shader converts them into triangular Bezier patches for consistency. This conversion is performed in the tessellation control stage. The boundary edge evaluation is resolved during this conversion. OsdComputePerPatchVertexBoxSplineTriangle can be used for this process. The resulting Bezier control vertices are stored in OsdPerPatchVertexBezier struct. void OsdComputePerPatchVertexBoxSplineTriangle  ivec3 patchParam , int ID , vec3 cv  12 , out OsdPerPatchVertexBezier result  The tessellation evaluation shader takes an array of OsdPerPatchVertexBezier struct, and then evaluates the patch using the OsdEvalPatchBezierTriangle function. void OsdEvalPatchBezierTriangle  ivec3 patchParam , vec2 UV , OsdPerPatchVertexBezier cv  15 , out vec3 P , out vec3 dPu , out vec3 dPv , out vec3 N , out vec3 dNu , out vec3 dNv  Gregory Triangle Patch OsdComputePerPatchVertexGregoryBasis can be used for the quartic triangular Gregory patches although no basis conversion involved for the Gregory triangle patches and the resulting vertices are stored in a OsdPerPatchVertexGreogryBasis struct. void OsdComputePerPatchVertexGregoryBasis  ivec3 patchParam , int ID , vec3 cv , out OsdPerPatchVertexGregoryBasis result  The tessellation evaluation shader takes an array of OsdPerPatchVertexGregoryBasis struct, and then evaluates the patch using the OsdEvalPatchGregoryTriangle function. void OsdEvalPatchGregoryTriangle  ivec3 patchParam , vec2 UV , vec3 cv  18 , out vec3 P , out vec3 dPu , out vec3 dPv , out vec3 N , out vec3 dNu , out vec3 dNv  Legacy Gregory Patch 2.x compatibility OpenSubdiv 3.0 also supports 2.x style Gregory patch evaluation see far_overview. In order to evaluate a legacy Gregory patch, client needs to bind extra buffers and to perform extra steps in the vertex shader as shown in the following diagram Tessellation levels Osd provides both uniform and screen-space adaptive tessellation level computation. Because of the nature of feature adaptive subdivision , we need to pay extra attention for a patchs outer tessellation level for the screen-space adaptive case so that cracks dont appear. An edge of the patch marked as a transition edge is split into two segments Hi and Lo. The Osd shaders uses these two segments to ensure the same tessellation along the edge between different levels of subdivision. In the following example, suppose the left hand side patch has determined the tessellation level of its right edge to be 5. gl_TessLevelOuter is set to 5 for the edge, and at the same time we also pass 2 and 3 to the tessellation evaluation shader as separate levels for the two segments of the edge split at the middle. Tessellation levels at each tessellated vertex The tessellation evaluation shader takes gl_TessCoord and those two values, and remaps gl_TessCoord using OsdGetTessParameterization or OsdGetTessLevelParameterizationTriangle to ensure the parameters are consistent across adjacent patches. vec2 OsdGetTessParameterization  vec2 uv , vec4 tessOuterLo , vec4 tessOuterHi  vec2 OsdGetTessParameterizationTriangle  vec3 uvw , vec4 tessOuterLo , vec4 tessOuterHi  Tessellation levels computed at each patch These tessellation levels can be computed the corresponding method in the tesselation control shader. Note that these functions potentially requires all bezier control points, you need to call barrier to ensure the conversion is done for all invocations. See osdglslPatchBSpline.glsl for more details. Uniform void OsdGetTessLevelsUniform  ivec3 patchParam , out vec4 tessLevelOuter , out vec2 tessLevelInner , out vec4 tessOuterLo , out vec4 tessOuterHi  void OsdGetTessLevelsUniformTriangle  ivec3 patchParam , out vec4 tessLevelOuter , out vec2 tessLevelInner , out vec4 tessOuterLo , out vec4 tessOuterHi  Screenspace void OsdEvalPatchBezierTessLevels  OsdPerPatchVertexBezier cpBezier  16 , ivec3 patchParam , out vec4 tessLevelOuter , out vec2 tessLevelInner , out vec4 tessOuterLo , out vec4 tessOuterHi  void OsdEvalPatchBezierTriangleTessLevels  vec3 cv  15 , ivec3 patchParam , out vec4 tessLevelOuter , out vec2 tessLevelInner , out vec4 tessOuterLo , out vec4 tessOuterHi  Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"osd_shader_interface.html"}, 
{"title":"Overview of Release 3.1", "text":"Overview of Release 3.1 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.1 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.1 New Features Bicubic Face-Varying Patches Varying and Face-Varying Evaluation Second Order Derivative Evaluation Separate Levels of Feature Isolation Sharp Patches for Infinitely Sharp Features API Additions OsdCpuEvaluator, GLComputeEvaluator, etc OsdCpuPatchTable, GLPatchTable, etc OsdMeshBits OsdPatchParam OsdGLSLPatchShaderSource, HLSLPatchShaderSource FarLimitStencil FarLimitStencilTable FarLimitStencilTableFactoryOptions FarPatchParam FarPatchTable FarPatchTableFactoryOptions FarTopologyLevel FarTopologyRefinerAdaptiveOptions Other Changes Improvements Bug Fixes New Features Bicubic Face-Varying Patches The motivation for this feature is to improve drawing and evaluation of face-varying primvar values for all face-varying interpolation options . A common use of non-linear face-varying data is to capture a UV projection on the surface. The following example shows a simple shape with the face-varying interpolation option assigned to a non-linear choice to achieve the desired projection in this case FVAR_LINEAR_NONE Linear Face-Varying Patches Bicubic Face-Varying Patches The result on the left shows the old linearly interpolated patches, which ignores any non-linear settings. The result on the right shows the new use of bicubic face-varying patches to accurately interpolate the desired projection. Generation of a full face-varying patch representation can be enabled using a new option in FarPatchTableFactoryOptions. Additionally, topological refinement can be improved to consider fvar channel topology using a new option in FarTopologyRefinerAdaptiveOptions. See the API additions below and their associated Doxygen text for more details. Evaluation of patch basis weights for all patch types as been added to the GPU shader source provided by OsdGLSLPatchShaderSource, and OsdHLSLPatchShaderSource. Use of non-linear face-varying patches increases the storage size of the patch table and may also require additional data access and computation while drawing. Varying and Face-Varying Evaluation This feature extends existing evaluation methods to support evaluation of varying and face-varying primvar data at arbitrary limit surface locations. Varying Primvar Evaluation Face-Varying Primvar Evaluation The image on the left shows evaluation of varying primvar values and the image on the right shows evaluation of face-varying primvar values. The EvaluateBasis API of FarPatchTable has been extended as well as the OSD Evaluator API. Second Order Derivative Evaluation This feature extends the FarLimitStencilTable and FarPatchTable interfaces to support evaluation of 2nd order partial derivatives. The generation of derivative values for FarLimitStencilTable is controlled by new options that can be specified when creating the stencil table. Additionally, the implementation exposes a more accurate method to compute derivatives for Gregory basis patches. This can be enabled using the CMake configuration and compile time definition OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES. Separate Levels of Feature Isolation The primary motivation for this feature is to reduce the number of patches generated by adaptive refinement when they can be adequately represented at a lower level. A single level of isolation must be as high as the greatest semi-sharp feature to properly resolve the shape of that feature. That high isolation level generates many unnecessary patches for smooth extra-ordinary vertices. In the following example, a single semi-sharp vertex is refined to level 5 Single Isolation Level 5 Primary Level 5, Secondary Level 2 Single isolation to level 5 on the left results in 312 patches. The right shows the semi-sharp feature isolated to 5, but with the new secondary level set to 2, the number of patches is reduced to 123. The second specified level of adaptive refinement is used to halt isolation for features that typically do not require the specified maximum. These include interior and boundary extra-ordinary vertices and those infinitely sharp patches that correspond to boundary extra-ordinary patches. The secondary level is available as a new option in FarTopologyRefinerAdaptiveOptions. Sharp Patches for Infinitely Sharp Features The motivation for sharp patches is to accurately represent the limit surface of infinitely sharp features, which otherwise can only be approximated by very high levels of adaptive refinement, resulting in many unnecessary patches. The true limit surface for regular faces along an infinitely sharp crease is a regular B-Spline patch -- the same as regular faces along a boundary. Similarly, the limit surface for faces around an extra-ordinary vertex on an infinitely sharp crease is the same as that of faces around an extra-ordinary vertex on a boundary. So these patches are identified and isolated to the same degree -- the regular patches as soon as possible, and the irregular patches to the depth specified. Consider the following regressionshapecatmark_cube_creases2 Level 5 without Sharp Patches Level 5 with Sharp Patches Level 2 with Sharp Patches Without use of sharp patches on the left, isolating to level 5 generates 1764 patches and does still not capture the sharp edges. With sharp patches in the center, isolating to the same degree level 5 reduces the number of patches to 96 and captures the sharp edges. The sharp features can be captured at a lower degree with comparable accuracy as illustrated on the right where isolation to level 2 further reduces the number of patches to 42. The use of infinitely sharp patches can be enabled both at a high level as an new option to OsdMesh, or more directly when adaptively refining or construction the patch tables in FarTopologyRefinerAdaptiveOptions and FarPatchTableFactoryOptions. Given the improved accuracy and reduced patches by the use of simple regular patches, we would prefer that this be the default behavior, but it was made an explicit option in order to avoid disrupting existing usage. In a future major release this feature will hopefully be the norm. API Additions See associated Doxygen for full details. OsdCpuEvaluator, GLComputeEvaluator, etc EvalPatchesVarying EvalPatchesFaceVarying OsdCpuPatchTable, GLPatchTable, etc GetFVarPatchArrayBuffer GetFVarPatchIndexBuffer GetFVarPatchIndexSize GetFVarPatchParamBuffer GetFVarPatchParamSize GetNumFVarChannels GetVaryingPatchArrayBuffer GetVaryingPatchIndexBuffer GetVaryingPatchIndexSize OsdMeshBits member MeshFVarAdaptive member MeshUseInfSharpPatch OsdPatchParam IsRegular Unnormalize extensions to Set OsdGLSLPatchShaderSource, HLSLPatchShaderSource GetPatchBasisShaderSource FarLimitStencil GetDuuWeights GetDuvWeights GetDvvWeights extensions to LimitStencil FarLimitStencilTable GetDuuWeights GetDuvWeights GetDvvWeights Update2ndDerivs extensions to LimitStencilTable FarLimitStencilTableFactoryOptions member generate1stDerivatives member generate1stDerivatives extensions to LimitTableStencilFactoryCreate FarPatchParam IsRegular Unnormalize extensions to Set FarPatchTable ComputeLocalPointValuesFaceVarying ComputeLocalPointValuesVarying GetFVarPatchDescriptor GetFVarPatchParam GetNumLocalPointsFaceVarying GetNumLocalPointsVarying GetPatchArrayVaryingVertices GetPatchArrayFVarPatchParam GetPatchArrayFVarValues GetPatchFVarPatchParam GetPatchVaryingVertices GetVaryingPatchDescriptor GetVaryingVertices EvaluateBasisFaceVarying EvaluateBasisVarying extensions to EvaluateBasis FarPatchTableFactoryOptions member useInfSharpPatch member genenerateFVarLegacyLinearPatches FarTopologyLevel DoesEdgeFVarTopologyMatch DoesFaceFVarTopologyMatch DoesVertexFVarTopologyMatch IsEdgeBoundary IsEdgeNonManifold IsVertexBoundary IsVertexNonManifold FarTopologyRefinerAdaptiveOptions member secondaryLevel member useInfSharpPatch member considerFVarChannels Other Changes Improvements Enabled the use of CMakes folder feature Removed the use of iso646 alternative keywords and, or, not, etc. to improve portability Added numerical valued preprocessor directives OPENSUBDIV_VERSION_MAJOR, etc. to opensubdivversion.h Improved documentation for FarPatchParam and added Unnormalize to complement Normalize Added additional topology queries to FarTopologyLevel Updated glFVarViewer and glEvalLimit viewer to make use of bicubic face-varying patches Updated glViewer and dxViewer to add a toggle for InfSharpPatch Updated dxPtexViewer for improved feature parity with glPtexViewer Improved far_regression to exercise shapes independent of Hbr compatibility Added support for Appveyor continuous integration testing Removed cmakeFindIlmBase Removed mayaPolySmooth example Bug Fixes Fixed Ptex version parsing and compatibility issues Fixed compatibility issues with VS2015 Fixed bug interpolating face-varying data with Bilinear scheme Fixed bug with refinement using Chaikin creasing Fixed bugs with HUD sliders in the example viewers Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_31.html"}, 
{"title":"Overview of Release 3.2", "text":"Overview of Release 3.2 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.2 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.2 New Features Face-Varying Stencil Evaluation 1st and 2nd Derivative Evaluation Smooth Corner Patch API Additions OsdCpuEvaluator, GLComputeEvaluator, etc OsdMesh OsdMeshBits FarPatchTableFactoryOptions FarStencilTableFactory FarStencilTableFactoryOptions Other Changes Improvements Bug Fixes New Features Face-Varying Stencil Evaluation Face-Varying primvar values may now be refined using stencil tables. The stencil table for a face-varying channel is created by specifying the desired fvarChannel and setting the FarStencilTableFactoryOption interpolationMode to INTERPOLATE_FACE_VARYING when creating the stencil table. 1st and 2nd Derivative Evaluation The Osd Evaluator API has been extended to support 1st derivative and 2nd partial derivative evaluation for stencils and patches. 1st Derivative Surface Normal 2nd Derivative Surface Curvature On the left is an example of computing a surface normal at each point using the evaluated 1st derivatives, while on the right is an example of computing surface curvature at each point using the evaluated 2nd partial derivatives. Smooth Corner Patch An option has been added to disable the legacy behavior of generating a sharp-corner patch at a smooth corner. Corners which are actually sharp will continue to generate sharp-corner patches. The differences between the two methods is most apparent at low-levels of feature isolation. This feature is controlled by the generateLegacySharpCornerPatches option added to FarPatchTableFactoryOptions. Sharp Corner Patch legacy behavior Smooth Corner Patch On the left is the legacy behavior of generating sharp corner patches at smooth corners. The image on the right shows the correct smooth corner patches generated when this legacy behavior is disabled. API Additions See associated Doxygen for full details. OsdCpuEvaluator, GLComputeEvaluator, etc Create EvalStencils EvalPatches EvalPatchesVarying EvalPatchesFaceVarying OsdMesh Create OsdMeshBits member MeshUseSmoothCornerPatch FarPatchTableFactoryOptions member generateLegacySharpCornerPatches FarStencilTableFactory enumeration ModeINTERPOLATE_FACE_VARYING AppendLocalPointStencilTableFaceVarying FarStencilTableFactoryOptions member fvarChannel Other Changes Improvements Corrected numerous spelling errors in doxygen comments Updated glFVarViewer with improved error detection and command line parsing Added option to build using MSVC with static CRT Bug Fixes Fixed a double delete of GL program in OsdGLComputeEvaluator Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_32.html"}, 
{"title":"Overview of Release 3.3", "text":"Overview of Release 3.3 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.3 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.3 New Features Metal Compute and Tessellation API Additions OsdMTLContext OsdMTLComputeEvaluator OsdMTLStencilTable OsdMTLMeshInterface OsdMTLPatchTable OsdMTLLegacyGregoryPatchTable OsdPatchShaderSource OsdCPUMTLVertexBuffer Other Changes Improvements New Features Metal Compute and Tessellation Added support for drawing and evaluation using Apples Metal API for high performance and low-overhead GPU access. This includes the full set of Osd interfaces needed to draw using Metal graphics rendering including tessellation shaders and evaluate stencils and patch tables using Metal compute processing. Also includes an example mtlViewer that can be built to run on either macOS or iOS. Metal Graphics Rendering with Tessellation Metal Patch Evaluation using Compute Processing API Additions See associated Doxygen for full details. OsdMTLContext device and commandQueue member data OsdMTLComputeEvaluator Create EvalStencils EvalPatches EvalPatchesVarying EvalPatchesFaceVarying Compile Synchronize OsdMTLStencilTable Create GetSizesBuffer GetIndicesBuffer GetDuWeightsBuffer GetDvWeightsBuffer GetDuuWeightsBuffer GetDuvWeightsBuffer GetDvvWeightsBuffer GetNumStencils OsdMTLMeshInterface GetNumVertices GetMaxValence UpdateVertexBuffer UpdateVaryingBuffer Refine Synchronize GetPatchTable GetFarPatchTable BindVertexBuffer BindVaryingBuffer OsdMTLPatchTable Create GetPatchArrays GetPatchIndexBuffer GetPatchParamBuffer GetVaryingPatchArrays GetVaryingPatchIndexBuffer GetNumFVarChannels GetFVarPatchArrays GetFVarPatchIndexBuffer GetFVarPatchParamBuffer OsdMTLLegacyGregoryPatchTable UpdateVertexBuffer GetVertexBuffer GetVertexValenceBuffer GetQuadOffsetsBuffer OsdPatchShaderSource GetCommonShaderSource GetPatchBasisShaderSource GetVertexShaderSource GetHullShaderSource GetDomainShaderSource OsdCPUMTLVertexBuffer Create UpdateData GetNumElements GetNumVertices BindCpuBuffer BindMTLBuffer BindVBO Other Changes Improvements Fixed several instances of local variable shadowing that could cause build warnings Updated continuous-integration build scripts and added testing on macOS Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_33.html"}, 
{"title":"Overview of Release 3.5", "text":"Overview of Release 3.5 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.5 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.5 New Features Simplified Surface Evaluation Tessellation Patterns API Additions New classes in namespace Bfr Additions to FarTopologyLevel Additions to nested Options classes in Far Other Changes Deprecation Announcements Improvements Bug Fixes New Features Simplified Surface Evaluation The new Bfr interface provides an alternative to Far and Osd for evaluating the limit surface -- treating a subdivision mesh as a piecewise parameteric surface primitive . The Bfr interface is named for Base Face Representation as all concepts and classes relate to the individual faces of the original unrefined mesh, i.e. its base faces. Each base face has a piece of limit surface associated with it  BfrSurface  that is parameterized  BfrParameterization  and so can be evaluated and tessellated The limit surface for each face can be identified and evaluated independently of any other faces without any global pre-processing of a connected mesh. The resulting evaluation interface is much simpler, more flexible and more scalable than those assembled with the table-based class in Far -- providing a preferable alternative for many CPU-based use cases though not all. See the Bfr Overview documentation for more details. Tessellation Patterns In addition to evaluation, the Bfr interface includes a Tessellation class that provides tessellation patterns for all faces of a base mesh. A Tessellation does not encapsulate the entire tessellation process but simply provides topological patterns to assemble such a process. All faces of a mesh have a Parameterization which can be used to define a Tessellation with the specification of one or more tessellation rates. A single tessellation rate defines simple uniform tessellations while tessellation rates for each edge provide more complex non-uniform patterns A small set of options is also available to define the resulting patterns e.g. the preservation of quad faces with quad-based subdivision schemes  above left and center  and to generate its output in a more favorable form. Tessellation patterns do not support the full flexibility of typical hardware tessellation e.g. no fractional tessellation but do provide some useful alternatives to hardware tessellation e.g. the quad preservation previously noted, and more uniform triangles for triangular patches  above right . The Tessellation class is also completely independent of evaluation in Bfr , and so can be used with any other evaluation interface. See the Tessellation subsection of the Bfr Overview for more details. API Additions See associated Doxygen for full details. New classes in namespace Bfr class Parameterization class Surface class SurfaceFactory class SurfaceFactoryCache class SurfaceFactoryMeshAdapter class RefinerSurfaceFactory class Tessellation Additions to FarTopologyLevel TopologyLevelIsVertexCorner TopologyLevelIsVertexRegular TopologyLevelIsVertexInfSharp TopologyLevelIsVertexSemiSharp TopologyLevelIsEdgeInfSharp TopologyLevelIsEdgeSemiSharp Additions to nested Options classes in Far PatchTableFactoryOptionsSetMaxIsolationLevel TopologyRefinerUniformOptionsSetRefinementLevel TopologyRefinerAdaptiveOptionsSetMaxIsolationLevel TopologyRefinerAdaptiveOptionsSetMaxSecondaryLevel Other Changes Deprecation Announcements Hbr is deprecated and will be removed from subsequent releases Improvements Suppression of GCC compiler warnings GitHub 1253, 1254, 1270 Additional methods for FarTopologyLevel GitHub 1227, 1255 Improved mixed partial derivative at Gregory patch corners GitHub 1252 Minor improvements to Far tutorials GitHub 1226, 1241 Added CMake config GitHub 1242 Updated CMake minimum version to 3.12 GitHub 1237, 1261 Updated documentation build scripts for Python 3 1265, 1266 Updated stringify build tool for improved cross compilation support GitHub 1267 Added NO_MACOS_FRAMEWORKS build option GitHub 1238 Updated Azure pipelines agents for Unbuntu and macOS GitHub 1247, 1256 Removed obsolete AppVeyor and Travis CI scripts GitHub 1259 Bug Fixes Cache active program for OsdGLComputeEvaluator GitHub 1244 Fixed member initialization warnings in OsdD3D11ComputeEvaluator GitHub 1239 Fixed GLSL shader source to remove storage qualifiers from struct members GitHub 1271 Fixed use of CMake variables for Apple builds GitHub 1235 Fixed build errors when using OpenGL without GLFW GitHub 1257 Fixed links to embedded videos GitHub 1231 Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_35.html"}, 
{"title":"Overview of Release 3.4", "text":"Overview of Release 3.4 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.4 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.4 New Features Triangular Patches for Loop Subdivision Major Improvements to Introductory Documentation Sparse Patch Tables Support for Double Precision in Far API Additions Far extensions for triangular patches Construction and refinement of topology Construction and interface of FarPatchTable Construction and use of Far stencil tables Far class templates for double precision Far member functions converted to templates for double precision OsdMeshBits OsdPatchArray Osd extensions for patch evaluation common to all shaders Osd extensions for patch tessellation common to all shaders Other Changes Improvements Bug Fixes New Features Triangular Patches for Loop Subdivision Support for the drawing and evaluation of Loop subdivision meshes with triangular patches was added. This includes the full set of Far and Osd interfaces for both evaluation and drawing. The feature set supported for Loop subdivision now matches that of Catmark, including creases, face-varying patches, non-manifold topology, etc. The long standing requirement that Loop meshes be purely triangular remains, as Loop subdivision is not defined for non-triangular faces. And as is the case with the use of the Catmark scheme, application of Loop subdivision to dense, poorly modeled meshes may lead to unexpectedly poor performance andor surface quality. The patch representation used for Loop subdivision is intended to exactly match the underlying limit surface where regular, and so uses quartic triangular Box-splines. This is in contrast to approaches that use simpler patches to approximate the Loop limit surface everywhere. As with Catmark, Gregory patches are used to approximate irregular areas. Though other choices are available that compromise surface quality in favor of improved performance, they may be less effective with Loop than they are with Catmark. Major Improvements to Introductory Documentation A significant rewrite of the Subdivision Surfaces page is included in this release. The new documentation emphasizes the piecewise parametric surface nature of subdivision surfaces and the implications of supporting arbitary topology . As a true surface primitive, the distinction between the control points and the limit surface and the corresponding operations of subdivision and tessellation that are applied to them is made clear. Sparse Patch Tables Interfaces in Far for the construction of PatchTables and the required adaptive refinement have been extended to apply to an arbitrary subset of faces. This allows patches for either large meshes or meshes that may otherwise benefit from some kind of partioning e.g. areas of static and dynamic topology to be managed in an arbitrary number of groups. In the extreme, a PatchTable forming the tree of patches for a single base face can be constructed. Client data buffers for the base mesh do not need to be partitioned and base mesh topology can be shared by multiple instances of FarTopologyRefiner used to create corresponding instances of FarPatchTables. See the new Far tutorial 5.2 for a simple example. Support for Double Precision in Far Classes and interfaces in Far have been adapted to allow support for double precision via templates parameterized for float or double. Class templates for major classes such as FarStencilTable have been introduced and the original classes preserved for compatibility. Other classes such as FarPatchTable have had methods overloaded or replaced with template functions to support both single and double precision. Internally, all use of floating point constants and math library functions has been adapted to maximize accuracy appropriate to the precision of the template instance. Interfaces in Osd have not been extended. The extensions in Far provide the basis for extensions in Osd, but demand is limited. For those benefiting from such Osd extensions, contributions are welcomed. See the revised Far tutorial 5.1 that constructs a FarPatchTable for a simple example. API Additions See associated Doxygen for full details. Far extensions for triangular patches enum PatchDescriptorTypeGREGORY_TRIANGLE PatchParamNormalizeTriangle PatchParamUnnormalizeTriangle PatchParamIsTriangleRotated Construction and refinement of topology overloaded TopologyRefinerFactoryCreate extensions to TopologyRefinerRefineAdaptive Construction and interface of FarPatchTable overloaded PatchTableFactoryCreate PatchTableFactoryGetRefineAdaptiveOptions member PatchTableFactoryOptionsincludeBaseLevelIndices member PatchTableFactoryOptionsincludeFVarBaseLevelIndices member PatchTableFactoryOptionsgenerateVaryingTables member PatchTableFactoryOptionsgenerateVaryingLocalPoints member PatchTableFactoryOptionssetPatchPrecisionDouble member PatchTableFactoryOptionssetFVarPatchPrecisionDouble PatchTableGetFVarPatchDescriptorRegular PatchTableGetFVarPatchDescriptorIrregular PatchTableGetFVarValueStride Construction and use of Far stencil tables overloaded StencilTableUpdateValues enum LimitStencilTableFactoryMode member LimitStencilTableFactoryOptionsinterpolationMode member LimitStencilTableFactoryOptionsfvarChannel Far class templates for double precision class StencilReal class StencilTableReal class StencilTableFactoryReal class LimitStencilReal class LimitStencilTableReal class LimitStencilTableFactoryReal class PrimvarRefinerReal Far member functions converted to templates for double precision PatchParamNormalize PatchParamUnnormalize PatchTableEvaluateBasis PatchTableEvaluateBasisVarying PatchTableEvaluateBasisFaceVarying PatchTableGetLocalPointStencilTable PatchTableGetLocalPointVaryingStencilTable PatchTableGetLocalPointFaceVaryingStencilTable PatchMapFindPatch OsdMeshBits enumeration MeshEndCapBilinearBasis OsdPatchArray GetDescriptorRegular GetDescriptorIrregular GetPatchTyperRegular GetPatchTyperIrregular GetStride Osd extensions for patch evaluation common to all shaders struct OsdPatchArray and OsdPatchArrayInit struct OsdPatchCoord and OsdPatchCoordInit struct OsdPatchParam and OsdPatchParamInit OsdPatchParamGetFaceId OsdPatchParamGetU OsdPatchParamGetV OsdPatchParamGetTransition OsdPatchParamGetBoundary OsdPatchParamGetNonQuadRoot OsdPatchParamGetDepth OsdPatchParamGetParamFraction OsdPatchParamIsRegular OsdPatchParamIsTriangleRotated OsdPatchParamNormalize OsdPatchParamUnnormalize OsdPatchParamNormalizeTriangle OsdPatchParamUnnormalizeTriangle OsdEvaluatePatchBasisNormalized OsdEvaluatePatchBasis Osd extensions for patch tessellation common to all shaders OsdInterpolatePatchCoordTriangle OsdComputePerPatchVertexBoxSplineTriangle OsdEvalPatchBezierTriangle OsdEvalPatchGregoryTriangle OsdGetTessLevelsUniformTriangle OsdEvalPatchBezierTessLevels OsdEvalPatchBezierTriangleTessLevels OsdGetTessParameterizationTriangle Other Changes Improvements Added new build script GitHub 1068 Added support for newer DirectX SDKs GitHub 1066 Patch arrays extended to support combined regular and irregular types GitHub 995 FarPatchTables and adaptive refinement supported for Bilinear scheme GitHub 1035 New FarPatchTableFactory method to determine adaptive refinement options GitHub 1047 New FarPatchTableFactory options to align primvar buffers of uniform tables GitHub 986 FarStencilTableUpdateValues overloaded to support separate base buffer GitHub 1011 FarLimitStencilTableFactory updated to create face-varying tables GitHub 1012 Regular patches on boundaries no longer require additional isolation GitHub 1025 Inclusion of OpenSubdiv header files in source code now consistent GitHub 767 Re-organization of and additions to Far tutorials GitHub 1083 Examples now use common command-line conventions and parsing GitHub 1056 Bug Fixes Fixed FarPrimvarRefiner internal limitFVar prototype GitHub 979 Fixed FarStencilTable append when base StencilTable empty GitHub 982 Patches around non-manifold vertices now free of cracks GitHub 1013 Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_34.html"}, 
{"title":"Overview of Release 3.6", "text":"Overview of Release 3.6 Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Overview of Release 3.6 3.6.0 User Docs API Docs Release Notes Forum Github Overview of Release 3.6 New Features Modern Graphics APIs and Parallel Computation Updated Third-party APIs and Tools API Additions Additions to OsdPatchShaderSource Osd extensions for patch evaluation from client shaders and compute kernels Other Changes Deprecation Announcements Improvements Bug Fixes New Features The purpose of this release is to address concerns which improve support for current typical use cases and provide support for significant new use cases. Modern Graphics APIs and Parallel Computation OpenSubdiv is organized as a set of components for working with subdivision surface representations, i.e. Bfr, Far, Vtr, Sdc along with a collection of back-end components in Osd supporting the use of specific low-level subsystems to work with subdivision surface data. These back-end components in Osd have taken many forms including in some cases specific complete GPU shaders along with controller classes to manage compilation and execution of these shaders. In practice it has been more effective for Osd to simply supply the functions needed to operate on subdivision surface data, allowing the client application or client library to take care of using these functions from client provided shaders and computation kernels using client provided execution controllers. This has been the direction for the Osd library for some time and the changes implemented in this release make this even more straightforward. The existing methods OsdGLSLPatchShaderSourceGetPatchBasisShaderSource OsdHLSLPatchShaderSourceGetPatchBasisShaderSource OsdMTLPatchShaderSourceGetPatchBasisShaderSource continue to return shader source strings at runtime which contain definitions and functions allowing client shader code to evaluate values and first and second derivatives on the piecewise parametric patches resulting from subdivison refinement. The identical code is now available at compile time as opensubdivosdpatchBasis.h and is essentially a shader interface that can be used from client kernels including those implemented using TBB, CUDA, C, etc. Similarly, the new methods OsdGLSLPatchShaderSourceGetPatchDrawingShaderSource OsdHLSLPatchShaderSourceGetPatchDrawingShaderSource OsdMTLPatchShaderSourceGetPatchDrawingShaderSource return shader source strings at runtime which contain definitions and functions allowing clients to draw the piecewise parametric patches resulting from subdivision, e.g. using GPU tessellation shaders or GPU mesh shaders. The returned shader source has been stripped of resource binding and other potentially problematic defintions since these are usually best handled by client shader code. These methods have been tested successfully with new client code using Vulkan and DirectX 12 in addition to existing client code using OpenGL, Metal, DirectX 11, etc. Updated Third-party APIs and Tools While the methods described above will be the most effective way to use OpenSubdiv, some of the existing back-end components have been updated to accommodate evolving third-party APIs and tools. Specifically, the TBB implementation has been updated to allow use with the oneTBB API while continuing to maintain compatibility with earlier releases of TBB. Also, there have been minor fixes to the CMake build to accommodate using the Ninja build system and also systems with OpenCL 3.0. API Additions See associated Doxygen for full details. Additions to OsdPatchShaderSource GLSLPatchShaderSourceGetPatchDrawingShaderSource HLSLPatchShaderSourceGetPatchDrawingShaderSource MTLPatchShaderSourceGetPatchDrawingShaderSource Osd extensions for patch evaluation from client shaders and compute kernels struct OsdPatchArray and OsdPatchArrayInit struct OsdPatchCoord and OsdPatchCoordInit struct OsdPatchParam and OsdPatchParamInit OsdPatchParamGetFaceId OsdPatchParamGetU OsdPatchParamGetV OsdPatchParamGetTransition OsdPatchParamGetBoundary OsdPatchParamGetNonQuadRoot OsdPatchParamGetDepth OsdPatchParamGetParamFraction OsdPatchParamIsRegular OsdPatchParamIsTriangleRotated OsdPatchParamNormalize OsdPatchParamUnnormalize OsdPatchParamNormalizeTriangle OsdPatchParamUnnormalizeTriangle OsdEvaluatePatchBasisNormalized OsdEvaluatePatchBasis Other Changes Deprecation Announcements The methods OsdTbbEvaluatorSetNumThreads and OsdOmpEvaluatorSetNumThreads have been marked deprecated. Improvements Updated Osd patch drawing shader source to exclude legacy shader constructs to improve compatibility with Vulkan, DX12, etc. GitHub 1320 Installed Osd patch evaluation headers to allow use from client shaders and compute kernels GitHub 1321 Updated CMake build to locate TBB using TBBs CMake config in order to support oneTBB GitHub 1319 Updated CMake FindOpenCL module to support parsing version information from recent OpenCL headers GitHub 1322 Removed obsolete .travis.yml GitHub 1324 Bug Fixes Fixed inconsistent warning levels for MSVC builds when using Ninja GitHub 1318 Fixed documentation build errors when using Ninja GitHub 1323 Fixed build errors resulting from oneTBB API changes GitHub 1317 Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_36.html"}, 
{"title":"Sdc Overview", "text":"Sdc Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Sdc Overview 3.6.0 User Docs API Docs Release Notes Forum Github Sdc Overview Subdivision Core Sdc Types, Traits and Options Creasing support Scheme-specific support The FACE, EDGE and VERTEX interfaces The MASK interface Subdivision Core Sdc Sdc is the lowest level layer in OpenSubdiv. Its intent is to separate the core subdivision details from any particular representation of a mesh it was previously bound to Hbr to facilitate the generation of consistent results with other mesh representations, both internal and external to OpenSubdiv. The functionality can be divided roughly into three sections types, traits and options for the supported subdivision schemes computations required to support semi-sharp creasing computations for mask weights of subdivided vertices for all schemes For most common usage, familiarity with only the first of these is necessary -- primarily the use of public types and constants for the choice of subdivision scheme and its associated options. The latter two provide the basis for a more comprehensive implementation of subdivision, which requires considerably more understanding and effort. Overall, the approach was to extract the functionality at the lowest level possible. In some cases, the implementation is not far from being simple global functions. The intent was to start at a low level and build any higher level functionality as needed. What exists now is functional for ongoing development and anticipated needs within OpenSubdiv for the near future. The intent of Sdc is to provide the building blocks for OpenSubdiv and its clients to efficiently process the specific set of supported subdivision schemes. It is not intended to be a general framework for defining customized subdivision schemes. Types, Traits and Options The most basic type is the enum SdcSchemeType that identifies the fixed set of subdivision schemes supported by OpenSubdiv Bilinear , Catmark and Loop . With this alone, we intend to avoid all dynamic casting issues related to the scheme by simply adding members to the associated subclasses for inspection. In addition to the type enum itself, a class defining a fixed set of traits associated with each scheme is provided. While these traits are available as static methods in the interface of a class supporting more functionality for each scheme to be described shortly, the SchemeTypeTraits provide queries of the traits for a variable of type SdcSchemeType -- enabling parameterization of code by the value of a trait without templates or virtual inheritance a simple internal table of traits is constructed and trivially indexed. The second contribution is the collection of all variations in one place that can be applied to the subdivision schemes, i.e. the boundary interpolation rules, creasing method, edge subdivision choices, etc. The fact that these are all declared in one place alone should help clients see the full set of variations that are possible. A simple Options struct a set of bitfields aggregates all of these variations into a single object the equivalent of an integer in this case that are passed around to other Sdc classes andor methods and are expected to be used at a higher level both within OpenSubdiv and externally. By aggregating the options and passing them around as a group, it allows us to extend the set easily in future without the need to rewire a lot of interfaces to accommodate the new choice. Clients can enable new choices at the highest level and be assured that they will propagate to the lowest level where they are relevant. Unlike other options structs used elsewhere to specify variations of a particular method, SdcOptions defines all options that affect the shape of the underlying limit surface of a subdivision mesh. Other operations at higher levels in the library may have options that approximate the shape and so create a slightly different appearance, but SdcOptions is a fundamental part of the definition of the true limit surface. Creasing support Since the computations involved in the support of semi-sharp creasing are independent of the subdivision scheme, the goal in Sdc was to encapsulate all related creasing functionality in a similarly independent manner. Computations involving sharpness values are also much less dependent on topology -- there are vertices and edges with sharpness values, but knowledge of faces or boundary edges is not required, -- so the complexity of topological neighborhoods required for more scheme-specific functionality is arguably not necessary here. Creasing computations have been provided as methods defined on a Crease class that is constructed with a set of Options. Its methods typically take sharpness values as inputs and compute a corresponding set of sharpness values as a result. For the Uniform creasing method previously known as Normal , the computations may be so trivial as to question whether such an interface is worth it, but for Chaikin or other schemes in the future that are non-trivial, the benefits should be clear. Functionality is divided between both uniform and non-uniform, so clients have some control over avoiding unnecessary overhead, e.g. non-uniform computations typically require neighboring sharpness values around a vertex, while uniform does not. Also included as part of the Crease class is the Rule enum -- this indicates if a vertex is Smooth, Crease, Dart or Corner referred to as the mask in Hbr and is a function of the sharpness values at and around a vertex. Knowing the Rule for a vertex can accelerate mask queries, and the Rule can often be inferred based on the origin of a vertex e.g. it originated from the middle of a face, was the child of a Smooth vertex, etc.. Methods are defined for the Crease class to subdivide edge and vertex sharpness values determine the Rule for a vertex based on incident sharpness values determine the transitional weight between two sets of sharpness values Being all low-level and working directly on sharpness values, it is a clients responsibility to coordinate the application of any hierarchical crease edits with their computations. Similarly, in keeping with this as a low-level interface, values are passed as primitive arrays. This follows the trend in OpenSubdiv of dealing with data of various kinds e.g. weights, component indices, now sharpness values, etc. in small contiguous sets of values. In most internal cases we can refer to a set of values or gather what will typically be a small number of values on the stack for temporary use. Scheme-specific support While the SchemeTypeTraits class provides traits for each subdivision scheme supported by OpenSubdiv i.e. Bilinear , Catmark and Loop , the Scheme class provides these more directly, Additionally, the Scheme class provides methods for computing the various sets of weights used to compute new vertices resulting from subdivision. The collection of weights used to compute a single vertex at a new subdivision level is typically referred to as a mask . The primary purpose of the Scheme class is to provide such masks in a manner both general and efficient. Each subdivision scheme has its own values for its masks, and each are provided as specializations of the template class SchemeSchemeType TYPE . The intent is to minimize the amount of code specific to each scheme. The computation of mask weights for subdivided vertices is the most significant contribution of Sdc. The use of semi-sharp creasing with each non-linear subdivision scheme complicates what are otherwise simple masks determined solely by the topology, and packaging that functionality to achieve both the generality and efficiency desired has been a challenge. Mask queries are defined in the Scheme class template, which has specializations for each of the supported subdivision schemes. Mask queries are defined in terms of interfaces for two template parameters the first defining the topological neighborhood of a vertex, and a second defining a container in which to gather the individual weights template  typename FACE , typename MASK  void ComputeFaceVertexMask  FACE const  faceNeighborhood , MASK  faceVertexMask , ... const  Each mask query is expected to call methods defined for the FACE , EDGE or VERTEX classes to obtain the information they require  typically these methods are simple queries about the topology and associated sharpness values. Clients are free to use their own mesh representations to gather the requested information as quickly as possible, or to cache some subset as member variables for immediate inline retrieval. In general, the set of weights for a subdivided vertex is dependent on the following the topology around the parent component from which the vertex originates the type of subdivision Rule applicable to the parent component the type of subdivision Rule applicable to the new child vertex a transitional weight blending the effect between differing parent and child rules This seems fairly straight-forward, until we look at some of the dependencies involved the parent Rule requires the sharpness values at and around the parent component the child Rule requires the subdivided sharpness values at and around the new child vertex though it can sometimes be trivially inferred from the parent the transitional weight between differing rules requires all parent and child sharpness values Clearly the sharpness values are inspected multiple times and so it pays to have them available for retrieval. Computing them on an as-needed basis may be simple for uniform creasing, but a non-uniform creasing method requires traversing topological neighborhoods, and that in addition to the computation itself can be costly. The point here is that it is potentially unreasonable to expect to evaluate the mask weights completely independent of any other consideration. Expecting and encouraging the client to have subdivided sharpness values first, for use in more than one place, is therefore recommended. The complexity of the general case above is also unnecessary for most vertices. Any client using Sdc typically has more information about the nature of the vertex being subdivided and much of this can be avoided -- particularly for the smooth interior case that often dominates. More on that in the details of the Scheme classes. Given that most of the complexity has been moved into the template parameters for the mask queries, the Scheme class remains fairly simple. Like the Crease class, it is instantiated with a set of Options to avoid them cluttering the interface. It is currently little more than a few methods for the limit and refinement masks for each vertex type, plus the few fixed traits of the scheme as static methods. The mask queries have been written in a way that greatly simplifies the specializations required for each scheme. The generic implementation for both the edge-vertex and vertex-vertex masks take care of all of the creasing logic, requiring only a small set of specific masks to be assigned for each Scheme smooth and crease masks for an edge-vertex, and smooth, crease and corner masks for a vertex-vertex. Other than the Bilinear case, which will specialize the mask queries to trivialize them for linear interpolation, the specializations for each Scheme should only require defining this set of masks -- and with two of them common edge-vertex crease and vertex-vertex corner the Catmark scheme only needs to define three. The FACE, EDGE and VERTEX interfaces Mask queries require an interface to a topological neighborhood, currently labeled FACE , EDGE and VERTEX . This naming potentially implies more generality than intended, as such classes are only expected to provide the methods required of the mask queries to compute its associated weights. While all methods must be defined, some may rarely be invoked, and the client has considerable flexibility in the implementation of these they can defer some evaluations lazily until required, or be pro-active and cache information in member variables for immediate access. An approach discussed in the past has alluded to iterator classes that clients would write to traverse their meshes. The mask queries would then be parameterized in terms of a more general and generic mesh component that would make use of more general traversal iterators. The advantage here is the iterators are written once, then traversal is left to the query and only what is necessary is gathered. The disadvantages are that clients are forced to write these to do anything, getting them correct and efficient may not be trivial or possible in some cases, and that the same data e.g. subdivided sharpness may be gathered or computed multiple times for different purposes. The other extreme was to gather everything possible required at once, but that is objectionable. The approach taken here provides a reasonable compromise between the two. The mask queries ask for exactly what they want, and the provided classes are expected to deliver it as efficiently as possible. In some cases the client may already be storing it in a more accessible form and general topological iteration can be avoided. The information requested of these classes in the three mask queries is as follows For FACE  the number of incident vertices For EDGE  the number of incident faces the sharpness value of the parent edge the sharpness values of the two child edges the number of vertices per incident face For VERTEX  the number of incident faces the number of incident edges the sharpness value of the parent vertex the sharpness values for each incident parent edge the sharpness value of the child vertex the sharpness values for each incident child edge The latter should not be surprising given the dependencies noted above. There are also a few more to consider for future use, e.g. whether the EDGE or VERTEX is manifold or not. In most cases, additional information can be provided to the mask queries i.e. pre-determined Rules, and most of the child sharpness values are not necessary. The most demanding situation is a fractional crease that decays to zero -- in which case all parent and child sharpness values in the neighborhood are required to determine the proper transitional weight. The MASK interface Methods dealing with the collections of weights defining a mask are typically parameterized by a MASK template parameter that contains the weights. The set of mask weights is currently divided into vertex-weights, edge-weights and face-weights -- consistent with previous usage in OpenSubdiv and providing some useful correlation between the full set of weights and topology. The vertex-weights refer to parent vertices incident the parent component from which a vertex originated, the edge-weights the vertices opposite incident edges of the parent, and the face-weights the center of incident parent faces. Note the latter is NOT in terms of vertices of the parent but potentially vertices in the child originating from faces of the parent. This has been done historically in OpenSubdiv but is finding less use -- particularly when it comes to providing greater support for the Loop scheme -- and is a point needing attention. So the mask queries require the following capabilities assign the number of vertex, edge andor face weights retrieve the number of vertex, edge andor face weights assign individual vertex, edge andor face weights by index retrieve individual vertex, edge andor face weights by index through a set of methods required of all MASK classes. Since the maximum number of weights is typically known based on the topology, usage within Vtr, Far or Hbr is expected to simply define buffers on the stack. Another option is to utilize pre-allocated tables, partitioned into the three sets of weights on construction of a MASK , and populated by the mask queries. A potentially useful side-effect of this is that the client can define their weights to be stored in either single or double-precision. With that possibility in mind, care was taken within the mask queries to make use of a declared type in the MASK interface  MASKWeight  for intermediate calculations. Having support for double-precision masks in Sdc does enable it at higher levels in OpenSubdiv if later desired, and that support is made almost trivial with MASK being generic. It is important to remember here that these masks are being defined consistent with existing usage within OpenSubdiv both Hbr and the subdivision tables generated by Far . As noted above, the face weights correspond to the centers of incident faces, i.e. vertices on the same level as the vertex for which the mask is being computed, and not relative to vertices in the parent level as with the other sets of weights. It is true that the weights can be translated into a set in terms solely of parent vertices, but in the general case i.e. Catmark subdivision with non-quads in the base mesh this requires additional topological association. In general we would need N-3 weights for the N-3 vertices between the two incident edges, where N is the number of vertices of each face typically 4 even at level 0. Perhaps such a translation method could be provided on the mask class, with an optional indication of the incident face topology for the irregular cases. The Loop scheme does not have face weights , for a vertex-vertex mask, but for an edge-vertex mask it does require weights associated with the faces incident the edge -- either the vertex opposite the edge for each triangle, or its center which has no other use for Loop. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"sdc_overview.html"}, 
{"title":"Tutorials", "text":"Tutorials Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Tutorials 3.6.0 User Docs API Docs Release Notes Forum Github Tutorials Bfr Tutorials 1. Basic Evaluation and Tessellation Tutorial 1.1 Tutorial 1.2 Tutorial 1.3 Tutorial 1.4 Tutorial 1.5 2. More on Tessellation Tutorial 2.1 Tutorial 2.2 3. Additional Topics Tutorial 3.1 Tutorial 3.2 Far Tutorials 1. Basic Construction and Interpolation Tutorial 1.1 Tutorial 1.2 2. Uniform Refinement and Primvar Data Types Tutorial 2.1 Tutorial 2.2 Tutorial 2.3 3. Creating a Custom FarTopologyRefinerFactory Tutorial 3.1 4. Construction and Usage of FarStencilTables Tutorial 4.1 Tutorial 4.2 Tutorial 4.3 5. Construction and Usage of FarPatchTables Tutorial 5.1 Tutorial 5.2 Tutorial 5.3 Osd Tutorials Tutorial 0 Hbr Tutorials Tutorial 0 Tutorial 1 Tutorial 2 The tutorial source code can be found in the github.com repository or in your local repository roottutorials . Bfr Tutorials All tutorials for the Bfr interface follow a similar pattern without any command line arguments, a default mesh usually a cube is used and the results printed to standard output in Obj format. Command line arguments can be used to specify an alternate mesh for input, as well as directing the output to a specified Obj file. Some tutorials may offer additional command line options to trigger internal options relevant to the topic, e.g. those illustrating tessellation may support a -quads option to use the option to tessellate quad-bases subdivision meshes with quads. 1. Basic Evaluation and Tessellation Tutorial 1.1 This tutorial illustrates the use of BfrSurfaceFactory and BfrSurface to evaluate points on the limit of each face. The limit positions at all corners of the face are evaluated and connected to the limit position in the center of the face -- creating a simple triangular tessellation. code Tutorial 1.2 This tutorial shows the added use of BfrTessellation to identify the set of points and connectivity for a uniform tessellation. Both a Surface and Tessellation is identified for each face, with the Tessellation indicating which points are to be evaluated by the Surface. code Tessellation patterns for quad-based subdivision schemes can optionally preserve quads left or be fully triangulated center, while triangular schemes always yield triangles right Tutorial 1.3 This tutorial extends the previous tutorial on uniform Tessellation by adding face-varying Surfaces to compute corresponding UVs for each evaluated position. code Tutorial 1.4 This tutorial extends the previous tutorial on uniform tessellation of position and UV by illustrating how additional mesh data interleaved with the position and UV data is easily handled. code Tutorial 1.5 This tutorial is similar to the first tutorial showing uniform tessellation of position but makes use of limit stencils for its evaluation of points of the tessellation pattern. code 2. More on Tessellation Tutorial 2.1 This tutorial extends the use of Tessellation to illustrate the use of non-uniform tessellation rates per edge. A simple edge-length metric is used to determine the tessellation rate for each edge of a face. code The following contrasts uniform tessellation left with the resulting length-based tessellations -- preserving quads center and fully triangulated right Tutorial 2.2 This tutorial is a more complex extension of the use of Tessellation that illustrates how the separation and association of tessellation data with the boundary and interior of the face can be used. Limit points evaluated on the vertices and edges of a face the boundary of the Tessellation are computed once and shared with adjacent faces -- creating a topologically watertight tessellation of the mesh. code 3. Additional Topics Tutorial 3.1 This tutorial shows a basic example of the more advanced topic of creating a subclass of SurfaceFactory adapted to a connected mesh representation -- requiring an implementation of the SurfaceFactoryMeshAdapter interface for that mesh. A simplified version of the implementation of FarTopologyRefiner is provided. Note that the code imported here is that of the main program, not the separate header and source files of the custom subclass illustrated -- which current documentation scripts cannot import. Tutorial 3.2 This tutorial shows how to initialize and retain Surfaces for later use. The simple uniform tessellation tutorial is modified to first create and populate a simple caching structure that initializes and stores the Surfaces for all faces of the mesh. The loop for each face of the mesh then retrieves its Surface and associated patch points from the cache. code Far Tutorials 1. Basic Construction and Interpolation Tutorial 1.1 This tutorial presents the requisite steps to instantiate a mesh as a FarTopologyRefiner from simple topological data and to interpolate vertex data associated with the mesh. code Tutorial 1.2 This tutorial makes use of a different vertex data definition for use when vertex data is of arbitrary width. Uniform refinement is applied to data buffers of three types two of fixed but different sizes and the third a union of the two that is dynamically sized and constructed. code 2. Uniform Refinement and Primvar Data Types Tutorial 2.1 Building on the basic tutorial, this example shows how to instantiate a simple mesh, refine it uniformly and then interpolate both vertex and varying primvar data. code Tutorial 2.2 Building on the previous tutorial, this example shows how to instantiate a simple mesh, refine it uniformly and then interpolate both vertex and face-varying primvar data. The resulting interpolated data is output in Obj format, with the face-varying data recorded in the UV texture layout. code Tutorial 2.3 Building on previous tutorials, this example shows how to instantiate a simple mesh, refine it uniformly, interpolate both vertex and face-varying primvar data, and finally calculate approximated smooth normals. The resulting interpolated data is output in Obj format. code 3. Creating a Custom FarTopologyRefinerFactory Tutorial 3.1 Previous tutorials have instantiated topology from a simple face-vertex list via the FarTopologyDescriptor and its TopologyRefinerFactory. This tutorial shows how to more efficiently convert an existing high-level topology representation to a FarTopologyDescriptor with a custom factory class. code 4. Construction and Usage of FarStencilTables Tutorial 4.1 This tutorial shows how to create and manipulate a StencilTable. Factorized stencils are used to efficiently interpolate vertex primvar data buffers. code Tutorial 4.2 This tutorial shows how to create and manipulate StencilTables for both vertex and varying primvar data buffers vertex positions and varying colors. code Tutorial 4.3 This tutorial shows how to create and manipulate tables of cascading stencils to apply hierarchical vertex edits. code 5. Construction and Usage of FarPatchTables Tutorial 5.1 This tutorial shows how to compute points on the limit surface at arbitrary parametric locations using a FarPatchTable constructed from adaptive refinement. code Tutorial 5.2 Building on the previous tutorial, this example shows how to manage the limit surface of a potentially large mesh by creating and evaluating separate PatchTables for selected groups of faces of the mesh. code Tutorial 5.3 Building on the previous tutorials for both PatchTables and StencilTables, this example shows how to construct a LimitStencilTable to repeatedly evaluate an arbitrary collection of points on the limit surface. code Osd Tutorials Tutorial 0 This tutorial demonstrates the manipulation of Osd Evaluator and BufferDescriptor. code Hbr Tutorials Use of Hbr is no longer recommended -- these tutorials are included solely for historical reference. Tutorial 0 This tutorial presents, in a very succinct way, the requisite steps to instantiate an Hbr mesh from simple topological data. code Tutorial 1 This tutorial shows how to safely create Hbr meshes from arbitrary topology. Because Hbr is a half-edge data structure, it cannot represent non-manifold topology. Ensuring that the geometry used is manifold is a requirement to use Hbr safely. This tutorial presents some simple tests to detect inappropriate topology. code Tutorial 2 This tutorial shows how to subdivide uniformly a simple Hbr mesh. We are building upon previous tutorials and assuming a fully instantiated mesh we start with an HbrMesh pointer initialized from the same pyramid shape used in hbr_tutorial_0. We then apply the Refine function sequentially to all the faces in the mesh to generate several levels of uniform subdivision. The resulting data is then dumped to the terminal in Wavefront OBJ format for inspection. code Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"tutorials.html"}, 
{"title":"3.0 - 3.6 Release Notes", "text":"3.0 - 3.6 Release Notes Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen 3.0 - 3.6 Release Notes 3.6.0 User Docs API Docs Release Notes Forum Github 3.0 - 3.6 Release Notes Release 3.6 Release 3.6.0 - Sep 2023 Release 3.5 Release 3.5.1 - July 2023 Release 3.5.0 - Sep 2022 Release 3.4 Release 3.4.4 - Feb 2021 Release 3.4.3 - Apr 2020 Release 3.4.0 - Jun 2019 Release 3.3 Release 3.3.3 - Jul 2018 Release 3.3.2 - Jun 2018 Release 3.3.1 - Feb 1018 Release 3.3.0 - Aug 2017 Release 3.2 Release 3.2.0 - Feb 2017 Release 3.1 Release 3.1.1 - Jan 2017 Release 3.1.0 - Oct 2016 Release 3.0 Release 3.0.5 - Mar 2016 Release 3.0.4 - Feb 2016 Release 3.0.3 - Oct 2015 Release 3.0.2 - Aug 2015 Release 3.0.1 - Aug 2015 Release 3.0.0 - Jun 2015 Release 3.0.0 RC2 Release 3.0.0 RC1 Previous 2.x Release Notes Release 3.6 Release 3.6.0 - Sep 2023 Release 3.6.0 is a significant release with new features, several configuration improvements, and bug fixes. For more information on the following, see Release 3.6 Changes Updated Osd patch drawing shader source to exclude legacy shader constructs to improve compatibility with Vulkan, DX12, etc. GitHub 1320 Installed Osd patch evaluation headers to allow use from client shaders and compute kernels GitHub 1321 Updated CMake build to locate TBB using TBBs CMake config in order to support oneTBB GitHub 1319 Updated CMake FindOpenCL module to support parsing version information from recent OpenCL headers GitHub 1322 Removed obsolete .travis.yml GitHub 1324 Bug Fixes Fixed inconsistent warning levels for MSVC builds when using Ninja GitHub 1318 Fixed documentation build errors when using Ninja GitHub 1323 Fixed build errors resulting from oneTBB API changes GitHub 1317 Release 3.5 Release 3.5.1 - July 2023 Release 3.5.1 is a minor release including bug fixes and configuration improvements. Changes Updated CMake to set fallback CMAKE_CXX_STANDARD to C14 GitHub 1276 Updated CMake with OpenGL import targets to avoid link errors GitHub 1277 Updated CMake to set gpu architecture fallback only for older CUDA versions GitHub 965 1299 Updated CMake to use append for CMAKE_MODULE_PATH GitHub 1296 Fixed interface includes for CMake config GitHub 1278 Fixed warnings with newer and stricter use of Clang GitHub 1275 1289 1290 Fixed potential float constant cast errors for OpenCL GitHub 1285 Fixed generation of Apple Frameworks with no OSD_GPU targets enabled GitHub 1224 1236 Bug Fixes Fixed BfrSurface construction bug for rare topological case GitHub 1301 Fixed CUDA example dependencies with GLX on Linux GitHub 1294 Release 3.5.0 - Sep 2022 Release 3.5.0 is a significant release with new features, several configuration improvements, and a few other improvements and bug fixes. For more information on the following, see Release 3.5 Deprecation Announcements Hbr is deprecated and will be removed from subsequent releases New Features Simplified Surface Evaluation Bfr Tessellation Patterns Bfr Changes Suppression of GCC compiler warnings GitHub 1253, 1254, 1270 Additional methods for FarTopologyLevel GitHub 1227, 1255 Improved mixed partial derivative at Gregory patch corners GitHub 1252 Minor improvements to Far tutorials GitHub 1226, 1241 Added CMake config GitHub 1242 Updated CMake minimum version to 3.12 GitHub 1237, 1261 Updated documentation build scripts for Python 3 1265, 1266 Updated stringify build tool for improved cross compilation support GitHub 1267 Added NO_MACOS_FRAMEWORKS build option GitHub 1238 Updated Azure pipelines agents for Unbuntu and macOS GitHub 1247, 1256 Removed obsolete AppVeyor and Travis CI scripts GitHub 1259 Bug Fixes Cache active program for OsdGLComputeEvaluator GitHub 1244 Fixed member initialization warnings in OsdD3D11ComputeEvaluator GitHub 1239 Fixed GLSL shader source to remove storage qualifiers from struct members GitHub 1271 Fixed use of CMake variables for Apple builds GitHub 1235 Fixed build errors when using OpenGL without GLFW GitHub 1257 Fixed links to embedded videos GitHub 1231 Release 3.4 Release 3.4.4 - Feb 2021 Release 3.4.4 is a minor release including bug fixes and configuration improvements Changes The master branch on GitHub has been renamed release GitHub 1218 1219 The CMake configuration has been updated to allow use as a sub-project GitHub 1206 Removed obsolete references to hbr from examplesfarViewer GitHub 1217 Bug Fixes Fixed bug with sparse PatchTables and irregular face-varying seams GitHub 1203 Fixed loss of precision when using double precision stencil tables GitHub 1207 Fixed reset of FarTopologyRefinerGetMaxLevel after call to Unrefine GitHub 1208 Fixed linking with -ldl on unix systems GitHub 1196 Fixed naming and installation of macOS frameworks GitHub 1194 1201 Fixed GL version and extension processing and dynamic loading on macOS GitHub 1216 Fixed FindDocutils.cmake to be more robust GitHub 1213 1220 Fixed errors using build_scriptsbuild_osd.py with Python3 GitHub 1206 Release 3.4.3 - Apr 2020 Release 3.4.3 is a minor release including bug fixes and configuration improvements Changes GLEW is no longer required by default GitHub 1183 1184 Removed false Ptex link dependency from libosdCPU GitHub 1174 Removed false GLFW link dependency from DX11 and Metal examples GitHub 1178 Removed link dependency on unused TBB libraries GitHub 1064 Added option to disable building of dynamic shared libraries GitHub 1169 Added new tutorial for FarLimitStencilTable GitHub 1176 Updated use of EXT_direct_state_access to ARB_direct_state_access GitHub 1184 Fixed C strict aliasing warnings GitHub 1182 Fixed MSVC warnings in example code GitHub 1158 1172 Fixed compatibility with Visual Studio 2019 GitHub 1173 1189 Fixed CMake CMP0054 warnings GitHub 1180 Added prefix to OpenSubdiv CMake macros GitHub 1157 Moved utilities in examplescommon to regressioncommon GitHub 1167 Minor fixes to Far tutorials GitHub 1175 1177 Switched to Azure Pipelines for continuous integration testing instead of Travis-CI and AppVeyor GitHub 1168 1190 Bug Fixes Fixed selective boundary interpolation for case SdcOptionsVTX_BOUNDARY_NONE GitHub 1170 1171 Fixed static library linking to address missing symbols GitHub 1192 Additional fixes for dynamic and static linking GitHub 1193 Release 3.4.0 - Jun 2019 Release 3.4.0 is a significant release with several new features, bug fixes, and general code and configuration improvements. For more information on the following, please see Release 3.4 New Features Triangular Patches for Loop subdivision Improvements to Introductory Documentation Sparse Patch Tables and Adaptive Refinement Full Support for Double Precision in Far Changes Added new build script GitHub 1068 Added support for newer DirectX SDKs GitHub 1066 Patch arrays extended to support combined regular and irregular types GitHub 995 FarPatchTables and adaptive refinement supported for Bilinear scheme GitHub 1035 New FarPatchTableFactory method to determine adaptive refinement options GitHub 1047 New FarPatchTableFactory options to align primvar buffers of uniform tables GitHub 986 FarStencilTableUpdateValues overloaded to support separate base buffer GitHub 1011 FarLimitStencilTableFactory updated to create face-varying tables GitHub 1012 Regular patches on boundaries no longer require additional isolation GitHub 1025 Inclusion of OpenSubdiv header files in source code now consistent GitHub 767 Re-organization of and additions to Far tutorials GitHub 1083 examples now use common command-line conventions and parsing GitHub 1056 Bug Fixes Fixed FarPrimvarRefiner internal limitFVar prototype GitHub 979 Fixed FarStencilTable append when base StencilTable empty GitHub 982 Patches around non-manifold vertices now free of cracks GitHub 1013 Release 3.3 Release 3.3.3 - Jul 2018 Release 3.3.3 is bug-fix release addressing regressions from release 3.3.2 Bug Fixes Fixed a regression in PatchTable construction with varying patches GitHub 976 Fixed a regression in PatchTable construction for face-varying patches GitHub 972 Fixed a bug in the initialization of FarSourcePatch GitHub 971 Release 3.3.2 - Jun 2018 Release 3.3.2 is a minor release with potentially significant performance improvements to the patch pre-processing stages Changes Improved performance of PatchTable construction GitHub 966 The resulting improved accuracy will produce slight numerical differences in computations involving patches, e.g. StencilTable and PatchTable evaluation Bug Fixes FarPatchTableFactory now supports PatchTable construction with ENDCAP_BILINEAR_BASIS specified Release 3.3.1 - Feb 1018 Release 3.3.1 is a minor bug-fix release Bug Fixes Fixed GLSLHLSLMetal patch shader code to resolve degenerate normals GitHub 947 Fixed problems with face-varying patches in uniform PatchTables GitHub 946 Fixed integer overflow bugs for large meshes in PatchTable factories GitHub 957 Fixed computation of PatchParam for triangle refinement GitHub 962 Changes Added build options NO_GLFW and NO_GLFW_X11 Added additional shapes with infinitely sharp creases to the Metal and DX11 example viewers Disabled GL tests during CI runs on Linux Improved stability of examplesglImaging in CI runs by testing GL version Release 3.3.0 - Aug 2017 Release 3.3.0 is significant release adding an Osd implementation for Apples Metal API New Features Added an Osd implementation for Apples Metal API Added the mtlViewer example Changes Fixed several instances of local variable shadowing that could cause build warnings Updated continuous-integration build scripts and added testing on macOS Release 3.2 Release 3.2.0 - Feb 2017 Release 3.2.0 is a minor release containing API additions and bug fixes New Features Extended FarStencilTableFactory to support face-varying Extended Osd Evaluator classes to support evaluation of 1st and 2nd derivatives Added an option to disable generation of legacy sharp corner patches Changes Corrected numerous spelling errors in doxygen comments Updated glFVarViewer with improved error detection and command line parsing Added option to build using MSVC with static CRT Bug Fixes Fixed a double delete of GL program in OsdGLComputeEvaluator Release 3.1 Release 3.1.1 - Jan 2017 Release 3.1.1 is a minor bug-fix release. Bug Fixes Fixed a bug with non-manifold face-varying topology causing a crash during patch table creation Fixed GLEW compilation and linking with dynamic GLEW libraries on Windows Fixed GLFW linking with GLFW 3.2 on X11 platforms Release 3.1.0 - Oct 2016 Release 3.1.0 is a significant release with several new features, bug fixes, and general code and configuration improvements. For more information on the following, please see Release 3.1 New Features Bicubic Face-Varying Patches Varying and Face-Varying Evaluation Second Order Derivative Evaluation Separate Levels of Feature Isolation Sharp Patches for Infinitely Sharp Features Changes Enabled the use of CMakes folder feature Removed the use of iso646 alternative keywords and, or, not, etc. to improve portability Added numerical valued preprocessor directives OPENSUBDIV_VERSION_MAJOR, etc. to opensubdivversion.h Improved documentation for FarPatchParam and added Unnormalize to complement Normalize Added additional topology queries to FarTopologyLevel Updated glFVarViewer and glEvalLimit viewer to make use of bicubic face-varying patches Updated glViewer and dxViewer to add a toggle for InfSharpPatch Updated dxPtexViewer for improved feature parity with glPtexViewer Improved far_regression to exercise shapes independent of Hbr compatibility Added support for Appveyor continuous integration testing Removed cmakeFindIlmBase Removed mayaPolySmooth example Bug Fixes Fixed Ptex version parsing and compatibility issues Fixed compatibility issues with VS2015 Fixed bug interpolating face-varying data with Bilinear scheme Fixed bug with refinement using Chaikin creasing Fixed bugs with HUD sliders in the example viewers Release 3.0 Release 3.0.5 - Mar 2016 Release 3.0.5 is a minor stability release with performance and correctness bug fixes. Bug Fixes The previous release reduced transient memory use during PatchTable construction, but increased the amount of memory consumed by the resulting PatchTable itself, this regression has been fixed. The example Ptex texture sampling code has been fixed to prevent sampling beyond the texels for a face when multisample rasterization is enabled. Release 3.0.4 - Feb 2016 Release 3.0.4 is a minor stability release which includes important performance and bug fixes. New Features Added accessor methods to FarLimitStencilTable to retrieve limit stencil data including derivative weights Added support for OpenCL event control to OsdCLVertexBuffer and OsdCLEvaluator Changes Major reduction in memory use during FarPatchTable construction for topologies with large numbers of extraordinary features Improved performance for GL and D3D11 tessellation control  hull shader execution when drawing BSpline patches with the single crease patch optimization enabled Bug Fixes Restored support for drawing with fractional tessellation Fixed far_tutorial_6 to refine primvar data only up to the number of levels produced by topological refinement Fixed build warnings and errors reported by Visual Studio 2015 Release 3.0.3 - Oct 2015 Release 3.0.3 is a minor stability release which includes important performance and bug fixes. New Features Smooth normal generation tutorial, far_tutorial_8 Changes Major performance improvement in PatchTable construction Improved patch approximations for non-manifold features Bug Fixes Fixed double delete in GLSL Compute controller Fixed buffer layout for GLSL Compute kernel Fixed GL buffer leak in OsdGLPatchTable Fixed out-of-bounds data access for TBB and OMP stencil evaluation Fixed WIN32_LEAN_AND_MEAN typo Fixed Loop-related shader issues glFVarViewer Release 3.0.2 - Aug 2015 Release 3.0.2 is a minor release for a specific fix. Bug Fixes Fixed drawing of single crease patches Release 3.0.1 - Aug 2015 Release 3.0.1 is a minor release focused on stability and correctness. Changes Added a references section to the documentation, please see References Removed references to AddVaryingWithWeight from examples and tutorials Added more regression test shapes Addressed general compiler warnings e.g. signed vs unsigned comparisons Addressed compiler warnings in the core libraries reported by GCCs -Wshadow Eased GCC version restriction, earlier requirement for version 4.8 or newer is no longer needed Replaced topology initialization assertions with errors Improved compatibility with ICC Improved descriptive content and formatting of Far error messages Improved build when configured to include no GPU specific code Bug Fixes Fixed handling of unconnected vertices to avoid out of bounds data access Fixed non-zero starting offsets for TbbEvalStencils and OmpEvalStencils Fixed FarStencilTableFactoryOptionsfactorizeIntermediateLevels Fixed FarPatchTablesFactoryOptionsgenerateAllLevels Fixed the behavior of VTX_BOUNDARY_NONE for meshes with bilinear scheme Fixed some template method specializations which produced duplicate definitions Disabled depth buffering when drawing the UI in the example viewers Disabled the fractional tessellation spacing option in example viewers since this mode is currently not supported Release 3.0.0 - Jun 2015 Release 3.0.0 is a major release with many significant improvements and changes. For more information on the following, please see Release 3.0 New Features Faster subdivision using less memory Support for non-manifold topology Face-Varying data specified topologically Elimination of fixed valence tables Single-crease patch for semi-sharp edges Additional irregular patch approximations Introduction of Stencil Tables Faster, simpler GPU kernels Unified adaptive shaders Updated coding style with namespaces More documentation and tutorials Bug Fixes Smooth Face-Varying interpolation around creases Release 3.0.0 RC2 New Features Documentation updates far_tutorial_3 updates for the multiple face-varying channels maya example plugin interpolates a UV channel and a vertex color channel Bug Fixes Fixed a LimitStencilTableFactory bug, which returns an invalid table PatchParam encoding changed to support refinement levels up to 10 Added Xinerama link dependency Fixed MSVC 32bit build problem Fixed minor cmake issues Fixed glViewerfarViewer stability bugs Release 3.0.0 RC1 Changes FarTopologyRefiner was split into several classes to clarify and focus the API. Interpolation of Vertex and Varying primvars in a single pass is no longer supported. The Osd layer was largely refactored. Previous 2.x Release Notes Previous releases Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_notes.html"}, 
{"title":"Release Notes", "text":"Release Notes Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Release Notes 3.6.0 User Docs API Docs Release Notes Forum Github Release Notes Release 2.6.0 Release 2.5.1 Release 2.5.0 Release 2.4.1 Release 2.4.0 Release 2.3.5 Release 2.3.4 Release 2.3.3 Release 2.3.2 Release 2.3.1 Release 2.3.0 Release 2.2.0 Release 2.1.0 Release 2.0.1 Release 2.0.0 Release 1.2.4 Release 1.2.3 Release 1.2.2 Release 1.2.1 Release 1.2.0 Release 1.1.0 Release 1.0.0 Release 2.6.0 New Features Add subdivision kernels for ARM NEON Add OsdUtilVertexSplit which creates a vertex-varying data table by duplicating vertices in a FarMesh Add basic functions to work with FV data via evaluator API Changes Added Catmark restricted vertex compute kernels that optimize for vertices with no semi-sharp creases Fix accessor omissions in osdmesh.h Add support for different subdivision schemes for OsdUtilMesh Bug Fixes Fix crashes when using rather low-end cards like Intel ones Fix a bug in the creation of an edge-vertex kernel batch Fix mismatch in declaration and usage of OsdCudaComputeRestrictedVertexA Fix a bug in the vertex order for restricted Catmark vertex-vertex kernel batches Fix a bug in FarCatmarkSubdivisionTablesFactory that prevented the CATMARK_QUAD_FACE_VERTEX kernel from being selected for subdivision level 2 or greater. Fix a bug in OsdUtilVertexSplit that occurs when getting the address of the end of a stdvector Fix error in createCLBuffer that occurs when the buffer size is zero Fix a bug in the CUDA computeRestrictedEdge kernel Fix duplicate variables with identical name Fix osdutil build errors Fix cmake diagnostic messsage Release 2.5.1 New Features Add CATMARK_QUAD_FACE_VERTEX and CATMARK_TRI_QUAD_FACE_VERTEX compute kernels optimization that takes advantage of all-quads or all-triange-and-quads meshes Bug Fixes Fix a compiler error in the GLSL Transform Feedback kernels on OS X Fix boundary interpolation in osdutil Fix bilinear stencil tangent computions Release 2.5.0 New Features Add ability to generate triangle patches for a uniformly subdivided mesh Add new example topologySharing Add interleaved buffer mode in glViewer Add GLSL compute kernel to glBatchViewer Add TBB compute kernel to glBatchViewer Add a PullDown widget to our HUD in examplescommon GUI updates  cosmetic changes to GL example code Adding a programmable image shader to gl_hud Code cleanup for GLFrameBuffer in examplescommon Implement C-API accessor to evaluator topology osdutil Add command line option to CMakes options Add a CMake option to disable OpenCL Add a FindCLEW.cmake module in anticipation of using CLEW as a dependency Integrate CLEW into osd library and examples Changes Change interleaved buffer support in OsdCompute Removed OsdVertexDescriptor and replaced with OsdVertexBufferDescriptor Reorganize ComputeContext and ComputeController. Reorganize EvalStencilContext and EvalStencilController Moved transient states current vertex buffer etc to controller Reorganize EvalLimitContext and EvalLimitController Moved transient states current vertex buffer etc to controller Fix adaptive isolation of sharp corner vertices Fix incorrect FarMeshFactory logic for isolating multiple corner vertices in corner patches Change EvalLimit Gregory patch kernels to the large weights table to accomodate higher valences Fix calculation of screen space LOD tess factors for transition corner patches. Add a public constructor to OsdMesh Decrease compiler warning thresholds and fix outstanding warnings Make PTex support optional Add a NO_MAYA flag to CMakeLists to disable all Autodesk Maya dependencies in the build Document NO_MAYA command line option Bug Fixes Fix mistakenly deleted memory barrier in glsl OsdCompute kernel. Fix shape_utils genRIB function to use streams correctly. Temporary workaround for the synchronization bug of glsl compute kernel Fix Hud display for higher DPI MBP retina Fix Hud d3d11 Fix examples to use GL timer query to measure the GPU draw timing more precisely Fix glViewer stop updating during freeze. Fix file permissions on farPatchTablesFactory.h Fix some meory leaks in adaptive evaluator osdutil Fix OsdUtilAdaptiveEvaluator concurrency issue Fix OsdUtilRefiner incorrect Invalid size of patch array error reporting. Fix OsdUtilPatchPartitioner failure for triangle patches Fixes a bug that causes OsdUtilPatchPartitioner to fail to rebuild the face-varying data table correctly for triangle patches. Add missing third parameter to templated OsdDrawContext usage osdutilbatch.h Return success status from openSubdiv_finishEvaluatorDescr osdutil Remove debugging stdcout calls osdutil Build errors  warnings Fix OSX Core Profile build GLFrameBuffer Fix ptexViewer build error on OSX Fix framebuffer shader compiling for OSX Reordering includes to address a compile error on OSXglew environment Fix compilation errors with CLEW enabled Fix icc build problems Fix compiler warnings in OsdClVertexBuffer Fix compilation error on windowsmsvc2013 Fix build warningserrors with VS2010 Pro Fix Windows build warning in FarPatchTablesFactory Fix doxygen generation errors Release 2.4.1 Changes Add correct OpenSubdiv namespace beginend blocks. Bug Fixes Compile osdutil with -fPIC for correct linking. Fix a bug of OsdUtilMeshBatch, the varying buffer isnt computed with CL kernels Fix FindGLFW.cmake to use the GLFW_LOCATION environment variable in Windows Fix Draw contexts do not fully initialize patch arrays Release 2.4.0 New Features Adding functionality to store uniform face-varying data across multiple levels of subdivision Add OsdUtilPatchPartitioner. It splits patcharray into subsets so that clients can draw partial surfaces for both adaptive and uniform. Changes Remove FarMesh dependency from OsdContext. Use DSA APIs for GL buffer update if available. Refactor Far API replace void- of all kernel applications with CONTEXT template parameter. It eliminates many static_casts from void- for both far and osd classes. move the big switch-cases of far default kernel launches out of Refine so that osd controllers can arbitrary mix default kernels and custom kernels. change FarKernelBatchkernelType from enum to int, clients can add custom kernel types. remove a back-pointer to farmesh from subdivision table. untemplate all subdivision table classes and template their compute methods instead. Those methods take a typed vertex storage. remove an unused argument FarMesh from the constructor of subdivision table factories. Refactor FarSubdivisionTables. Delete scheme specialized subdivision tables. The base class FarSubdivisionTables already has all tables, so we just need scheme enum to identify which scheme the subdivision tables belong to. This brings a lot of code cleanups around far factory classes. Move FarMultiMeshFactory to OsdUtil. Move table splicing functions of FarMultiMeshFactory into factories Change PxOsdUtil prefix to final OsdUtil prefix. Improve error reporting in osdutil refinement classes, and fix a build issue Bug Fixes Fix another multi mesh splicing bug of face varying data. Make CMake path variables more robust Fixing a crash on Marvericks wglew Update dxViewer example documentation Fix wrong logic in openSubdiv_setEvaluatorCoarsePositions Remove debug print from adaptive evaluators initialization Release 2.3.5 New Features Add the ability to read obj files to the dxViewer example Add screen-capture function to ptexViewer Update documention for Xcode builds Add documentation boundary interpolation rules and face-varying boundary interpolation rules Changes Refactoring FarPatchTables and FarPatchTablesFactory Move GL vertex buffer VBO buffer allocation out of allocate and into BindVBO Enable uvViewer on OS X now that Mavericks is released. Replacing un-necessary dynamic_cast with reinterpret_cast within FarDispatcher Minor code cleanup of FarMeshFactory Remove address space qualifiers from OpenCL kernel functions Fix OpenCL initialization to be slightly more robust Add OpenCL header include paths where necessary Add static specifiers for non-kernel CL funcs at program scope Add stddef.h to pythonosdosdshim.i Modify ptexViewer and uvViewer shaders to address some portability issues Bug Fixes Fix Gregory Boundary patch buffer overrun Fix black texels when the resolution of a ptex face is less than 4 Fix a splicing bug in FarMultiMeshFactory Fix a build error when using older versions of GLFW Fix build warnings optimized Fix FindTBB.cmake Fix FindMaya.cmake Fix glViewer support for GLSL compute Fix ptexViewer enable specular pass in both IBL and point lighting Fix Zlib include in ptexViewer Fix ptexViewer shader errors. Fix osdPolySmooth Maya plugin Fix UV merging in osdPolySmooth code example Add cleanup function to osdPolySmooth Maya plugin Fix Maya OsdPolySmooth node component output Fix GLSL array instantiation syntax for glStencilViewer Fix examples to run correctly on high DPI displays with GLFW 3 Release 2.3.4 New Features Adding CPUOMPTBB Context  Controller pairs for CPU evaluation of smooth normals Added adaptiveEvaluator class inspired by Sergeys work in blender OsdUtil Changes Changed the HUD to ignore mouse clicks when not visible. Updates for blender development OsdUtil Add C compatible API to access the adaptiveEvaluator class from non-C OsdUtil Update license headers to apache OsdUtil CMake build improvement  make osd a cmake object library  remove compiling redundancies Improve stringification of shaders  kernels in CMake build Bug Fixes Fixed iOS build Fixed VS2010 warningserrors. Fix OsdCpuEvalLimitKernel Fix maxvalence calculation in FarMeshFactory Fix FarStencilFactory control stencil caching Removing assert for high-valence vertices running off limit tangent pre-computed table. Fix degenerate stencil limit tangent code path. Fix unused variable build warnings gcc 4.8.2 - Fedora 19 Fix build warning from osdutiladaptiveEvaluator.cpp Release 2.3.3 Changes Modify Far remapping of singular vertices to point to their source vertex. Refactoring Ptex Mipmap and Analytic Displacement code Adding some documentation for Chaikin crease rule Misc. improvements to PxOsdUtilsMesh Adding recommended isolation output to OsdPolySmooth node Bug Fixes Adding an error check on version parsing of main CMakeLists Fix regex in FindMaya.cmake that breaks with recent versions of Maya Fix crashes induced by typeid Fixed VS2010 build warning Fix build break in hbr_regression Fix incorrect capitalization in GL ptexViewer shader.glsl Fix OSX build add stdlib.h include Release 2.3.2 New Features Adding control cage drawing to ptexViewer Adding Maya osdPolySmooth plugin into OpenSubdiv examples. Changes Removing some glGetError checks that are causing problems for Autodesk D3D11DrawRegistry returns the common shader config for all non-tess patcharrays. Updates to simple cpu osdutil classes Bug Fixes Fix Hbr Chaikin crease rule Fix Chaikin tag parsing Fix return value of allocate function for OsdCPUGLVertxBuffer Fixed GLSL shader portability. Fix FindGLFW.cmake for GLFW 3.03 on OSX Fixed compiler warnings. Fixed VS2010 build errors Fixed WIN32 build error when no DXSDK installed. Fix OSX build stdlib.h needs to be included in glPtexMipmapTexture.h Fix for crash in new meshrefiner code in OsdUtil Release 2.3.1 New Features Add DX11 version of ptex mipmap loader Add DX11 ptex viewer work in progress Add DX11 fractional partitioning, normal derivatives computation Add memory usage controls to Ptex loader Add face-varying boundary interpolation parsing to shape_utils Add simple HbrMesh and FarMesh wrapper classes to osdutil Changes Amend language of attribution file NOTICE.txt Optimize a bit of ptex mipmap lookup. Show ptex memory usage in GL and DX11 ptexViewers Improve ptex guttering Addding some video links to our collection of external resources Bug Fixes Fix edge-only face-varying interpolation Fix Far to handle disconnected vertices in an Hbr mesh Fixed ptex cache resource release sequence Fix build symbol conflict in Far Fix patch parambuffer generation in OsdD3D11DrawContext Fix a minor osdutil build warning seen with gcc 4.8.1 Fix VS2010 build errors Release 2.3.0 New Features Added Analytical displacement mapping Analytic Displacement Mapping using Hardware Tessellation Niessner and Loop TOG 2013 Added a new ptex mipmap loader Added face varying macros for loop subdivision Added the uvViewer example to see how face varying interpolation rule works Added a slider component and cleanup hud code. Changes Adding license  attribution files, improved language of the code headers Install documentation into the Filesystem Hierarchy Standard location Set GLFW_OPENGL_FORWARD_COMPAT on Mac OS to make samples work on that platform Added surface normal mode  mipmap to ptxViewer Bug Fixes Fix a bug of bad fvar splicing for loop surface. Fix incorrect bilinear limit tangents in FarStencilTablesFactory Fix boundary interpolation rules doc Added an error check on updating cuda buffer Fix face varying rendering on loop surface Fixed glBatchViewer build for GLFW 2.x Expand search paths for FindGLFW.cmake for Debian and other Linux architectures Fix CMake executable builds for ICC Fix bhr baseline regression, so reference files are real OBJs Fixed clKernelBundle.cpp to build on Android. Fix misc build warings Release 2.2.0 New Features Added subdivision stencil functionality Far  OsdEval Bug Fixes Fix D3D11DrawContext to check for NULL pointers Fix cpuEvalLimitController crash bug Fixed search path suffixes for ICC libs Fixed invalid initialization of glslTransformFeedback kernel. Release 2.1.0 New Features Added TBB Compute back-end on Linux contribution from Sheng Fu Added support for ICC compiler still Beta Changes Added constructor to OsdMesh with a FarMesh  as input Modify CMake to name and sym-link DSOs based on Linux ABI versioning spec Added command line input to DX11 viewer FarMultiMesh can splice uniform and adaptive meshes together. Bug Fixes Fix FarMultiMesh splicing Removed unnecessary cudaThreadSynchronize calls. Fix glViewer overlapping HUD menus Fix facevarying rendering in glBatchViewer Fix build of GLSL transform feedback kernels Fix Getting Started documentation Release 2.0.1 New Features New CLA files to reflect Apache 2.0 licensing Changes Move all public headers to includeopensubdiv... Adding Osd documentation based on Siggraph slides Bug Fixes Fix incorrect transition pattern 3 in GLSL  HLSL shaders Fix CMake build to not link GPU-based libraries into libosdCPU Fix support for GLEW on OSX Fix GLFW Xrandr  xf86vmode dependency paths for X11 based systems Fix HUD display overlaps in code examples Fix FindGLEW.cmake to be aware of multiarch on linux systems Fix some hard-coded include paths in CMake build Release 2.0.0 New Features New CMake build flags NO_LIB, NO_CUDA, NO_PYTHON Changes OpenSubdiv is now under Apache 2.0 license HbrHalfedge and HbrFVarData copy constructors are now private Documentation style matched to graphics.pixar.com  new content Add an animation freeze button to ptexViewer Variable name changes for better readability across all example shader code Bug Fixes Fix incorrect patch generation for patches with 2 non-consecutive boundary edges Fix undefined gl_PrimitiveID shader build errors Fix for shader macro OSD_DISPLACEMENT_CALLBACK Fix out-of-bounds stdvector access in FarPatchTablesFactory Release 1.2.4 New Features Adding support for fractional tessellation of patches Adding a much needed API documention system based on Docutils RST markup Adding support for face-varying interpolation in GLSL APIs Adding varying data buffers to OsdMesh Adding accessors to the vertex buffers in OsdGlMesh Adding face-varying data to regression shapes Changes Cleanup of common bicubic patch shader code GLSL  HLSL for portability ATI  OSX drivers Bug Fixes Fix FarVertexEditTablesFactory to insert properly vertex edit batches fixes incorrect hierarchical hole in regression shape Fix FarPatchMap quadtree to not drop top-level non-quad faces Fix Gregory patches bug with incorrect max-valence Fix FarPatchTablesGetNumFaces and FarPatchTablesGetFaceVertices functions to return the correct values Fix face indexing GLSL code ptex works on non-quads again Fix face-varying data splicing in FarMultiMeshFactory Fix ptex face indexing in FarMultiMeshFactory Fix glew include to not break builds Fix Clang  ICC build failures with FarPatchTables Fix build and example code to work with GFLW 3.0 Fix cmake to have ptex dynamically linked in OSX Release 1.2.3 New Features Adding Varying and Face-Varying data interpolation to EvalLimit Changes EvalLimit API refactor  the EvalContext now has dedicated structs to track all the vertex, varying and face-varying data streams. Also renamed some buffers into tables to maintain code consistency EvalLimit optimization  switch serial indexing to a quad-tree based search Bug Fixes Face-varying data bug fixes  making sure the data is carried around appropriately Fixes for OpenCL use with the new batching APIs GLSL general shader code cleanup  fixes for better portability GLSL Tranform Feedback initialization fix Critical fix for FarMultiMesh batching indexing was incorrect Fix osdutil CL implementation protect includes on systems with no OpenCL SDK installed Fix face-varying interpolation on adaptive patches FarPatchTables  fix IsFeatureAdaptive to return the correct answer Fix Far factories to handle the absence of face-varying data correctly. Many GLSL shader code style fixes which should help with ATI  OSX shader compiling Release 1.2.2 New Features Introducing the EvalLimit API  the Eval module aims at providing support for computational tasks that are not related to drawing the surfaces. The EvalLimit sub-module provides an API that enables client code to evaluate primitive variables on the limit surface. OsdxxxComputeController  minor optimization. Added early exit to Refine method to avoid unnecessary interop. Changes OsdGLDawContext  minor API change. Protecting some member variables and adding const accessors OsdError  minor API refactor, added Warning functions. Bug Fixes Fix Ptex bug  prevent corner texel guttering code to from going into infinite loops Adding the ability for a FarMeshFactory to construct patchTables starting from firstLevel in uniform subdivision mode Consolidating the color coding of bicubic patch types through all our our code examples this is used mostly as a debugging tool Fixing some MSVC build warnings Update to the outdated README.md Release 1.2.1 New Features Added CUDA runtime error checking Release 1.2.0 Changes Major Far refactor around patchTables to introduce the draw batching API Renaming osd_util to osdutil Bug Fixes Fix GLSL transform feedback initialization bug in ptexViewer Minor bug  typo fixes Release 1.1.0 New Features release initiated because of the switch to Git Flow Release 1.0.0 Oringal release Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"release_notes_2x.html"}, 
{"title":"Subdivision Surfaces", "text":"Subdivision Surfaces Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Subdivision Surfaces 3.6.0 User Docs API Docs Release Notes Forum Github Subdivision Surfaces Overview Piecewise Parametric Surfaces Parametric Patches Piecewise Surfaces Arbitrary Topology Regular versus Irregular Features Non-manifold Topology Subdivision versus Tessellation Subdivision Tessellation Which to Use Mesh Data and Topology Separating Data from Topology Vertex and Varying Data Face-Varying Data and Topology Schemes and Options Subdivision Schemes Boundary Interpolation Rules Face-varying Interpolation Rules Semi-Sharp Creases Other Options Chaikin Rule Triangle Subdivision Rule Overview Subdivision surfaces are a common modeling primitive that has gained popularity in animation and visual effects over the past decades. As the name suggests, subdivision surfaces are fundamentally surfaces . More specifically, subdivision surfaces are piecewise parametric surfaces defined over meshes of arbitrary topology -- both concepts that will be described in the sections that follow. Subdivision is both an operation that can be applied to a polygonal mesh to refine it, and a mathematical tool that defines the underlying smooth surface to which repeated subdivision of the mesh converges. Explicit subdivision is simple to apply some number of times to provide a smoother mesh, and that simplicity has historically lead to many tools representing the shape this way. In contrast, deriving the smooth surface that ultimately defines the shape -- its limit surface -- is considerably more complex but provides greater accuracy and flexibility. These differences have led to confusion in how some tools expose subdivision surfaces. The ultimate goal is to have all tools use subdivision surfaces as true surface primitives. The focus here is therefore less on subdivision and more on the nature of the surface that results from it. In addition to providing a consistent implementation of subdivision -- one that includes a number of widely used feature extensions -- a significant value of OpenSubdiv is that it makes the limit surface more accessible. Since its introduction, OpenSubdiv has received interest from users and developers with a wide variety of skills, interests and backgrounds. This document is intended to present subdivision surfaces from a perspective helpful in making use of OpenSubdiv. One purpose it serves is to provide a high level overview for those with less experience with the algorithms or mathematics of subdivision. The other is to provide an overview of the feature set available with OpenSubdiv, and to introduce those capabilities with the terminology used by OpenSubdiv as much of it is overloaded. Piecewise Parametric Surfaces Piecewise parametric surfaces are arguably the most widely used geometric representation in industrial design, entertainment and many other areas. Many of the objects we deal with everyday -- cars, mobile phones, laptops -- were all designed and visualized first as piecewise parametric surfaces before those designs were approved and pursued. Piecewise parametric surfaces are ultimately just collections of simpler modeling primitives referred to as patches. Patches constitute the pieces of the larger surface in much the same way as a face or polygon constitutes a piece of a polygonal mesh. Parametric Patches Patches are the building blocks of piecewise smooth surfaces, and many different kinds of patches have evolved to meet the needs of geometric modeling. Two of the more effective and common patches are illustrated below Single bicubic B-Spline patch Single bicubic Bezier patch Patches consist of a set of points or vertices that affect a rectangular piece of smooth surface triangular patches also exist. That rectangle is parameterized in its two directions, transforming a simple 2D rectangle into the 3D surface u,v 2D domain of a patch Mapping from u,v to x,y,z The points that control the shape of the surface are usually referred to as control points or control vertices, and the collection of the entire set defining a patch as the control mesh, the control hull, the control cage or simply the hull, the cage, etc. For the sake of brevity we will frequently use the term cage, which serves us more generally later. So a patch essentially consist of two entities its control points and the surface affected by them. The way the control points affect the surface is what makes the different types of patches unique. Even patches defined by the same number of points can have different behavior. Note that all 16 points of the B-Spline patch above are relatively far from the surface they define compared to the similar Bezier patch. The two patches in that example actually represent exactly the same piece of surface -- each with a set of control points having different effects on it. In mathematical terms, each control point has a basis function associated with it that affects the surface in a particular way when only that point is moved Bicubic B-Spline basis function Bicubic Bezier basis funciton It is these basis functions that often give rise to the names of the different patches. There are pros and cons to these different properties of the control points of patches, which become more apparent as we assemble patches into piecewise surfaces. Piecewise Surfaces Piecewise parametric surfaces are collections of patches. For rectangular patches, one of the simplest ways to construct a collection is to define a set of patches using a rectangular grid of control points Piecewise B-Spline surface Piecewise Bezier surface Note that we can overlap the points of adjacent B-spline patches. This overlapping means that moving one control point affects multiple patches -- but it also ensures that those patches always meet smoothly this was a design intention and not true for other patch types. Adjacent Bezier patches only share points at their boundaries and coordinating the points across those boundaries to keep the surface smooth is possible, but awkward. This makes B-splines a more favorable surface representation for interactive modeling, but Bezier patches serve many other useful purposes. A more complicated B-spline surface Part of a more complicated B-Spline surface Just as a patch consisted of a cage and a surface, the same is now true of the collection. The control cage is manipulated by a designer and the surface of each of the patches involved is displayed so they can assess its effect. Arbitrary Topology Piecewise surfaces discussed thus far have been restricted to collections of patches over regular grids of control points. There is a certain simplicity with rectangular parametric surfaces that is appealing, but a surface representation that supports arbitrary topology has many other advantages. Rectangular parametric surfaces gained widespread adoption despite their topological limitations, and their popularity continues today in some areas. Complex objects often need many such surfaces to represent them and a variety of techniques have evolved to assemble them effectively, including stitching multiple surfaces together or cutting holes into them trimming. These are complicated techniques, and while effective in some contexts e.g. industrial design they become cumbersome in others e.g. animation and visual effects. A single polygonal mesh can represent shapes with far more complexity than a single rectangular piecewise surface, but its faceted nature eventually becomes a problem. Subdivision surfaces combine the topological flexibility of polygonal meshes with the underlying smoothness of piecewise parametric surfaces. Just as rectangular piecewise parametric surfaces have a collection of control points its cage stored as a grid and an underlying surface, subdivision surfaces also have a collection of control points its cage stored as a mesh and an underlying surface often referred as its limit surface. Regular versus Irregular Features A mesh contains the vertices and faces that form the cage for the underlying surface, and the topology of that mesh can be arbitrarily complex. In areas where the faces and vertices of the mesh are connected to form rectangular grids, the limit surface becomes one of the rectangular piecewise parametric surfaces previously mentioned. These regions of the mesh are said to be regular they provide behavior familiar from the use of similar rectangular surfaces and their limit surface is relatively simple to deal with. All other areas are considered irregular they provide the desired topological flexibility and so are less familiar and less predictable in some cases and their limit surface can be much more complicated. Irregular features come in a number of forms. The most widely referred to is an extra-ordinary vertex, i.e. a vertex which, in the case of a quad subdivision scheme like Catmull-Clark, does not have four incident faces. Irregular vertex and incident faces Regular and irregular regions of the surface The presence of these irregular features makes the limit surface around them similarly irregular, i.e. it cannot be represented as simply as it can for regular regions. Its worth noting that irregular regions shrink in size and become more isolated as subdivision is applied. A face with a lot of extra-ordinary vertices around it makes for a very complicated surface, and isolating these features is a way to help deal with that complexity Two valence-5 vertices nearby Isolation subdivided once Isolation subdivided twice Its generally necessary to perform some kind of local subdivision in these areas to break these pieces of surface into smaller, more manageable pieces, and the term feature adaptive subdivision has become popular in recent years to describe this process. Whether this is done explicitly or implicitly, globally or locally, what matters most is that there is an underlying piece of limit surface for each face -- albeit a potentially complicated one at an irregular feature -- that can be evaluated in much the same way as rectangular piecewise surfaces. Patches of the regular regions Patches of the irregular region While supporting a smooth surface in these irregular areas is the main advantage of subdivision surfaces, both the complexity of the resulting surfaces and their quality are reasons to use them with care. When the topology is largely irregular, there is a higher cost associated with its surface, so minimizing irregularities is advantageous. And in some cases the surface quality, i.e. the perceived smoothness, of the irregular surfaces can lead to undesirable artefacts. An arbitrary polygonal mesh will often not make a good subdivision cage, regardless of how good that polygonal mesh appears. As with rectangular piecewise parametric surfaces, the cage should be shaped to affect the underlying surface it is intended to represent. See Modeling Tips for related recommendations. Non-manifold Topology Since the cage of a subdivision surface is stored in a mesh, and often manipulated in the same context as polygonal meshes, the topic of manifold versus non-manifold topology warrants some attention. There are many definitions or descriptions of what distinguishes a manifold mesh from one that is not. These range from concise but abstract mathematical definitions to sets of examples showing manifold and non-manifold meshes -- all have their value and an appropriate audience. The following is not a strict definition but serves well to illustrate most local topological configurations that cause a mesh to be non-manifold. Consider standing on the faces of a mesh and walking around each vertex in turn. Assuming a right-hand winding order of faces, stand on the side of the face in the positive normal direction. And when walking, step across each incident edge in a counter-clockwise direction to the next incident face. For an interior vertex start at the corner of any incident face walk around the vertex across each incident edge to the next unvisited face repeat if you arrive back where you started and any incident faces or edges were not visited, the mesh is non-manifold Similarly, for a boundary vertex start at the corner of the face containing the leading boundary edge walk around the vertex across each incident edge to the next unvisited face repeat if you arrive at another boundary edge and any incident faces or edges were not visited, the mesh is non-manifold If you can walk around all vertices this way and dont encounter any non-manifold features, the mesh is likely manifold. Obviously if a vertex has no faces, there is nothing to walk around and this test cant succeed, so it is again non-manifold. All of the faces around a vertex should also be in the same orientation, otherwise two adjacent faces have normals in opposite directions and the mesh will be considered non-manifold, so we should really include that constraint when stepping to the next face to be more strict. Consider walking around the indicated vertices of the following non-manifold meshes Edges with  2 incident faces Faces sharing a vertex but no edges As mentioned earlier, many tools do not support non-manifold meshes, and in some contexts, e.g. 3D printing, they should be strictly avoided. Sometimes a manifold mesh may be desired and enforced as an end result, but the mesh may temporarily become non-manifold due to a particular sequence of modeling operations. Rather than supporting or advocating the use of non-manifold meshes, OpenSubdiv strives to be robust in the presence of non-manifold features to simplify the usage of its clients -- sparing them the need for topological analysis to determine when OpenSubdiv can or cannot be used. Although subdivision rules are not as well standardized in areas where the mesh is not manifold, OpenSubdiv provides simple rules and a reasonable limit surface in most cases. Surface around edges with  2 incident faces Surface for faces sharing a vertex but no edges As with the case of regular versus irregular features, since every face has a corresponding piece of surface associated with it -- whether locally manifold or not -- the term arbitrary topology can be said to include non-manifold topology. Subdivision versus Tessellation The preceding sections illustrate subdivision surfaces as piecewise parametric surfaces of arbitrary topology. As piecewise parametric surfaces, they consist of a cage and the underlying surface defined by that cage. Two techniques used to display subdivision surfaces are subdivision and tessellation. Both have their legitimate uses, but there is an important distinction between them subdivision operates on a cage and produces a refined cage tessellation operates on a surface and produces a discretization of that surface The existence and relative simplicity of the subdivision algorithm makes it easy to apply repeatedly to approximate the shape of the surface, but with the result being a refined cage, that approximation is not always very accurate. When compared to a cage refined to a different level, or a tessellation that uses points evaluated directly on the limit surface, the discrepancies can be confusing. Subdivision Subdivision is the process that gives subdivision surfaces their name, but it is not unique to them. Being piecewise parametric surfaces, lets first look at subdivision in the context of the simpler parametric patches that comprise them. Subdivision is a special case of refinement , which is key to the success of some of the most widely used types of parametric patches and their aggregate surfaces. A surface can be refined when an algorithm exists such that more control points can be introduced while keeping the shape of the surface exactly the same . For interactive and design purposes, this allows a designer to introduce more resolution for finer control without introducing undesired side effects in the shape. For more analytical purposes, it allows the surface to be broken into pieces, often adaptively, while being faithful to the original shape. One reason why both B-spline and Bezier patches are so widely used is that both of them can be refined. Uniform subdivision -- the process of splitting each of the patches in one or both of its directions -- is a special case of refinement that both of these patch types support B-Spline surface and its cage Cage subdivided 1x Cage subdivided 2x In the cases illustrated above for B-Splines, the uniformly refined cages produce the same limit surface as the original granted in more pieces. So it is fair to say that both uniform B-splines and Bezier surfaces are subdivision surfaces. The limit surface remains the same with the many more control points roughly 4x with each iteration of subdivision, and those points are closer to but not on the surface. It may be tempting to use these new control points to represent the surface, but using the same number of points evaluated at corresponding uniformly spaced parametric locations on the surface is usually simpler and more effective. Note also that points of the cage typically do not have any normal vectors associated with them, though we can evaluate normals explicitly for arbitrary locations on the surface just as we do for position. So if displaying a cage as a shaded surface, normal vectors at each of the control points must be contrived. Both the positions and normals of the points on the finer cage are therefore both approximations. For more general subdivision surfaces, the same is true. Subdivision will refine a mesh of arbitrary topology, but the resulting points will not lie on the limit surface and any normal vectors contrived from and associated with these points will only be approximations to those of the limit surface. Tessellation There is little need to use subdivision to approximate a parametric surface when it can be computed directly, i.e. it can be tessellated. We can evaluate at arbitrary locations on the surface and connect the resulting points to form a tessellation -- a discretization of the limit surface -- that is far more flexible than the results achieved from uniform subdivision Uniform 3x3 tessellation of B-spline surface Curvature-adaptive tessellation of B-spline surface For a simple parametric surface, the direct evaluation of the limit surface is also simple, but for more complicated subdivision surfaces of arbitrary topology, this is less the case. The lack of a clear understanding of the relationship between the limit surface and the cage has historically lead to many applications avoiding tessellation. Its worth mentioning that subdivision can be used to generate a tessellation even when the limit surface is not available for direct evaluation. The recursive nature of subdivision does give rise to formulae that allow a point on the limit surface to be computed that corresponds to each point of the cage. This process is often referred to as snapping or pushing the points of the cage onto the limit surface. Subdivided 1x and snapped to limit surface Subdivided 2x and snapped to limit surface Since the end result is a connected set of points on the limit surface, this forms a tessellation of the limit surface, and we consider it a separate process to subdivision though it does make use of it. The fact that such a tessellation might have been achieved using subdivision is indistinguishable from the final result -- the same tessellation might just as easily have been generated by evaluating limit patches of the cage uniformly 2x, 4x, 8x, etc. along each edge. Which to Use Subdivision is undeniably useful in creating finer cages to manipulate the surface, but tessellation is preferred for displaying the surface when the patches are available for direct evaluation. There was a time when global refinement was pursued in limited circles as a way of rapidly evaluating parametric surfaces along isoparametric lines, but patch evaluation, i.e. tessellation, generally prevails. Considerable confusion has arisen due the way the two techniques have been employed and presented when displaying the shape in end-user applications. One can argue that if an application displays a representation of the surface that is satisfactory for its purposes, then it is not necessary to burden the user with additional terminology and choices. But when two representations of the same surface differ considerably between two applications, the lack of any explanation or control leads to confusion. As long as applications make different choices on how to display the surface, we seek a balance between simplicity and control. Since subdivided points do not lie on the limit surface, it is important to make it clear to users when subdivision is being used instead of tessellation. This is particularly true in applications where the cage and the surface are displayed in the same style as there is no visual cue for users to make that distinction. Mesh Data and Topology The ability of subdivision surfaces to support arbitrary topology leads to the use of meshes to store both the topology of the cage and the data values associated with its control points, i.e. its vertices. The shape of a mesh, or the subdivision surface that results from it, is a combination of the topology of the mesh and the position data associated with its vertices. When dealing with meshes there are advantages to separating the topology from the data, and this is even more important when dealing with subdivision surfaces. The shape referred to above is not just the shape of the mesh the cage in this case but could be the shape of a refined cage or the limit surface. By observing the roles that both the data and topology play in operations such as subdivision and evaluation, significant advantages can be gained by managing data, topology and the associated computations accordingly. While the main purpose of subdivision surfaces is to use position data associated with the vertices to define a smooth, continuous limit surface, there are many cases where non-positional data is associated with a mesh. That data may often be interpolated smoothly like position, but often it is preferred to interpolate it linearly or even make it discontinuous along edges of the mesh. Texture coordinates and color are common examples here. Other than position, which is assigned to and associated with vertices, there are no constraints on how arbitrary data can or should be associated or interpolated. Texture coordinates, for example, can be assigned to create a completely smooth limit surface like the position, linearly interpolated across faces, or even made discontinuous between them. There are, however, consequences to consider -- both in terms of data management and performance -- which are described below as the terminology and techniques used to achieve each are defined. Separating Data from Topology While the topology of meshes used to store subdivision surfaces is arbitrarily complex and variable, the topology of the parametric patches that make up its limit surface are simple and fixed. Bicubic B-Spline and Bezier patches are both defined by a simple 4x4 grid of control points and a set of basis functions for each point that collectively form the resulting surface. For such a patch, the position at a given parametric location is the result of the combination of position data associated with its control points and the weights of the corresponding basis functions  weights being the values of basis functions evaluated at a parametric location. The topology and the basis functions remain the same, so we can make use of the weights independent of the data. If the positions of the control points change, we can simply recombine the new position data with the weights that we just used and apply the same combination. The fixed topology of a parametric patch and two shapes resulting from two sets of positions. Similarly, for a piecewise surface, the position at a given parametric location is the result of the single patch containing that parametric location evaluated at the given position. The control points involved are the subset of control points associated with that particular patch. If the topology of the surface is fixed, so too is the topology of the collection of patches that comprise that surface. If the positions of those control points change, we can recombine the new position data with the same weights for the subset of points associated with the patch. More complex but fixed topology of a surface and two shapes resulting from two sets of positions. This holds for a piecewise surface of arbitrary topology. Regardless of how complex the topology, as long as it remains fixed i.e. relationships between vertices, edges and faces does not change or anything other settings affecting subdivision rules, the same techniques apply. This is just one example of the value of separating computations involving topology from those involving the data. Both subdivision and evaluation can be factored into steps involving topology computing the weights and combining the data separately. Three shapes resulting from three sets of positions for a mesh of fixed topology. When the topology is fixed, enormous savings are possible by pre-computing information associated with the topology and organizing the data associated with the control points in a way that can be efficiently combined with it. This is key to understanding some of the techniques used to process subdivision surfaces. For a mesh of arbitrary topology, the control points of the underlying surface are the vertices, and position data associated with them is most familiar. But there is nothing that requires that the control points of a patch have to represent position -- the same techniques apply regardless of the type of data involved. Vertex and Varying Data The most typical and fundamental operation is to evaluate a position on the surface, i.e. evaluate the underlying patches of the limit surface using the x,y,z positions at the vertices of the mesh. Given a parametric u,v location on one such patch, the data-independent evaluation method first computes the weights and then combines the x,y,z vertex positions resulting in an x,y,z position at that location. But the weights and their combination can be applied to any data at the vertices, e.g. color, texture coordinates or anything else. Data associated with the vertices that is interpolated this way, including position, is said to be vertex data or to have vertex interpolation. Specifying other data as vertex data will result in it being smoothly interpolated in exactly the same way using exactly the same weights as the position. So to capture a simple 2D projection of the surface for texture coordinates, 2D values matching the x,y of the positions would be used. If linear interpolation of data associated with vertices is desired instead, the data is said to be varying data or to have varying interpolation. Here the non-linear evaluation of the patches defining the smooth limit surface is ignored and weights for simple linear interpolation are used. This is a common choice for texture coordinates as evaluation of texture without the need of bicubic patches is computationally cheaper. The linear interpolation will not capture the smoothness required of a true projection between the vertices, but both vertex and varying interpolation have their uses. Projected texture smoothly interpolated from vertex data Projected texture linearly interpolated from varying data Since both vertex and varying data is associated with vertices a unique value assigned to each, the resulting surface will be continuous -- piecewise smooth in the case of vertex data and piecewise linear in the case of varying. Face-Varying Data and Topology In order to support discontinuities in data on the surface, unlike vertex and varying data, there must be multiple values associated with vertices, edges andor faces, in order for a discontinuity to exist. Discontinuities are made possible by assigning values to the corners of faces, similar to the way in which vertices are assigned to the corners of faces when defining the topology of the mesh. Recalling the assignment of vertices to faces Vertex indices are assigned to all corners of each face as part of mesh construction and are often referred to as the face-vertices of an individual face or the mesh. All face-vertices that share the same vertex index will be connected by that vertex and share the same vertex data associated with it. By assigning a different set of indices to the face-vertices -- indices not referring to the vertices but some set of data to be associated with the corners of each face -- corners that share the same vertex no longer need to share the same data value and the data can be made discontinuous between faces This method of associating data values with the face-vertices of the mesh is said to be assigning face-varying data for face-varying interpolation. An interpolated value will vary continuously within a face i.e. the patch of the limit surface associated with the face but not necessarily across the edges or vertices shared with adjacent faces. Disjoint face-varying UV regions applied to the limit surface The combination of associating data values not with the vertices the control points but the face corners, and the resulting data-dependent discontinuities that result, make this a considerably more complicated approach than vertex or varying. The added complexity of the data alone is reason to only use it when necessary, i.e. when discontinuities are desired and present. Part of the complexity of dealing with face-varying data and interpolation is the way in which the interpolation behavior can be defined. Where the data is continuous, the interpolation can be specified to be as smooth as the underlying limit surface of vertex data or simply linear as achieved with varying data. Where the data is discontinuous -- across interior edges and around vertices -- the discontinuities create boundaries for the data, and partition the underlying surface into disjoint regions. The interpolation along these boundaries can also be specified as smooth or linear in a number of ways many of which have a historical basis. A more complete description of the different linear interpolation options with face-varying data and interpolation is given later. These options make it possible to treat the data as either vertex or varying, but with the added presence of discontinuities. An essential point to remember with face-varying interpolation is that each set of data is free to have its own discontinuities -- this leads to each data set having both unique topology and size. The topology specified for a collection of face-varying data is referred to as a channel and is unique to face-varying interpolation. Unlike vertex and varying interpolation, which both associate a data value with a vertex, the number of values in a face-varying channel is not fixed by the number of vertices or faces. The number of indices assigned to the face-corners will be the same for all channels, but the number of unique values referred to by these indices may not. We can take advantage of the common mesh topology in areas where the data is continuous, but we lose some of those advantages around the discontinuities. This results in the higher complexity and cost of a face-varying channel compared to vertex or varying data. If the topology for a channel is fixed, though, similar techniques can be applied to factor computation related to the topology so that changes to the data can be processed efficiently. Schemes and Options While previous sections have described subdivision surfaces in more general terms, this section describes a number of common variations often referred to as extensions to the subdivision algorithms and the ways that they are represented in OpenSubdiv. The number and nature of the extensions here significantly complicate what are otherwise fairly simple subdivision algorithms. Historically applications have supported either a subset or have had varying implementations of the same feature. OpenSubdiv strives to provide a consistent and efficient implementation of this feature set. Given the varying presentations of some of these features elsewhere, the naming chosen by OpenSubdiv is emphasized here. Subdivision Schemes OpenSubdiv provides two well known subdivision surface types -- Catmull-Clark often referred to more tersely as Catmark and Loop subdivision. Catmull-Clark is more widely used and suited to quad-dominant meshes, while Loop is preferred for and requires purely triangulated meshes. The many examples from previous sections have illustrated the more popular Catmull-Clark scheme. For an example of Loop Boundary Interpolation Rules Boundary interpolation rules control how subdivision and the limit surface behave for faces adjacent to boundary edges and vertices. The following choices are available via the enumeration SdcOptionsVtxBoundaryInterpolation  Mode Behavior VTX_BOUNDARY_NONE No boundary edge interpolation is applied by default boundary faces are tagged as holes so that the boundary vertices continue to support the adjacent interior faces, but no surface corresponding to the boundary faces is generated boundary faces can be selectively interpolated by sharpening all boundary edges incident the vertices of the face VTX_BOUNDARY_EDGE_ONLY A sequence of boundary vertices defines a smooth curve to which the limit surface along boundary faces extends VTX_BOUNDARY_EDGE_AND_CORNER Similar to edge-only but the smooth curve resulting on the boundary is made to interpolate corner vertices vertices with exactly one incident face On a grid example In practice, it is rare to use no boundary interpolation at all -- this feature has its uses in allowing separate meshes to be seamlessly joined together by replicating the vertices along boundaries, but these uses are limited. Given the global nature of the setting, it is usually preferable to explicitly make the boundary faces holes in the areas where surfaces from separate meshes are joined, rather than sharpening edges to interpolate the desired boundaries everywhere else. The remaining edge only and edge and corner choices are then solely distinguished by whether or not the surface at corner vertices is smooth or sharp. Face-varying Interpolation Rules Face-varying interpolation rules control how face-varying data is interpolated both in the interior of face-varying regions smooth or linear and at the boundaries where it is discontinuous constrained to be linear or pinned in a number of ways. Where the topology is continuous and the interpolation chosen to be smooth, the behavior of face-varying interpolation will match that of the vertex interpolation. Choices for face-varying interpolation are most commonly available in the context of UVs for texture coordinates and a number of names for such choices have evolved in different applications over the years. The choices offered by OpenSubdiv cover a wide range of popular applications. The feature is named face-varying linear interpolation -- rather than boundary interpolation commonly used -- to emphasize that it can be applied to the entire surface not just boundaries and that the effects are to make the surface behave more linearly in various ways. The following choices are available for the SdcOptionsFVarLinearInterpolation enum -- the ordering here applying progressively more linear constraints Mode Behavior FVAR_LINEAR_NONE smooth everywhere the mesh is smooth FVAR_LINEAR_CORNERS_ONLY linearly interpolate sharpen or pin corners only FVAR_LINEAR_CORNERS_PLUS1 CORNERS_ONLY  sharpening of junctions of 3 or more regions FVAR_LINEAR_CORNERS_PLUS2 CORNERS_PLUS1  sharpening of darts and concave corners FVAR_LINEAR_BOUNDARIES linear interpolation along all boundary edges and corners FVAR_LINEAR_ALL linear interpolation everywhere boundaries and interior These rules cannot make the interpolation of the face-varying data smoother than that of the vertices. The presence of sharp features of the mesh created by sharpness values, boundary interpolation rules, or the subdivision scheme itself e.g. Bilinear take precedence. All face-varying interpolation modes illustrated in UV space using a simple 4x4 grid of quads segmented into three UV regions their control point locations implied by interpolation in the FVAR_LINEAR_ALL case For those familiar, this shape and its assigned UV sets are available for inspection in the catmark_fvar_bound1 shape of OpenSubdivs example and regression shapes. Semi-Sharp Creases Just as some types of parametric surfaces support additional shaping controls to affect creasing along the boundaries between surface elements, OpenSubdiv provides additional sharpness values or weights associated with edges and vertices to achieve similar results over arbitrary topology. Setting sharpness values to a maximum value 10 in this case -- a number chosen for historical reasons effectively modifies the subdivision rules so that the boundaries between the piecewise smooth surfaces are infinitely sharp or discontinuous. But since real world surfaces never really have infinitely sharp edges, especially when viewed sufficiently close, it is often preferable to set the sharpness lower than this value, making the crease semi-sharp. A constant weight value assigned to a sequence of edges connected edges therefore enables the creation of features akin to fillets and blends without adding extra rows of vertices though that technique still has its merits Sharpness values range from 0-10, with a value of 0 or less having no effect on the surface and a value of 10 or more making the feature completely sharp. It should be noted that infinitely sharp creases are really tangent discontinuities in the surface, implying that the geometric normals are also discontinuous there. Therefore, displacing along the normal will likely tear apart the surface along the crease. If you really want to displace a surface at a crease, it may be better to make the crease semi-sharp. Other Options While the preceding options represent features available in a wide-variety of tools and modeling formats, a few others exist whose recognition and adoption is more limited. In some cases, they offer improvements to undesirable behavior of the subdivision algorithms, but their effects are less than ideal. Given both their limited effectiveness and lack of recognition, these options should be used with caution. Chaikin Rule The Chaikin Rule is a variation of the semi-sharp creasing method that attempts to improve the appearance of creases along a sequence of connected edges when the sharpness values differ. This choice modifies the subdivision of sharpness values using Chaikins curve subdivision algorithm to consider all sharpness values of edges around a common vertex when determining the sharpness of child edges. The creasing method can be set using the values defined in the enumeration SdcOptionsCreasingMethod  Mode Behavior CREASE_UNIFORM Apply regular semi-sharp crease rules CREASE_CHAIKIN Apply Chaikin semi-sharp crease rules Example of contiguous semi-sharp creases interpolation Triangle Subdivision Rule The triangle subdivision rule is a rule added to the Catmull-Clark scheme that modifies the behavior at triangular faces to improve the undesirable surface artefacts that often result in such areas. Mode Behavior TRI_SUB_CATMARK Default Catmark scheme weights TRI_SUB_SMOOTH Smooth triangle weights Cylinder example  This rule was empirically determined to make triangles subdivide more smoothly. However, this rule breaks the nice property that two separate meshes can be joined seamlessly by overlapping their boundaries i.e. when there are triangles at either boundary, it is impossible to join the meshes seamlessly Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"subdivision_surfaces.html"}, 
{"title":"Vtr Overview", "text":"Vtr Overview Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Vtr Overview 3.6.0 User Docs API Docs Release Notes Forum Github Vtr Overview Vectorized Topology Representation Vtr VtrLevel Topological Relationships Memory Efficiency VtrRefinement Parent-child and child-parent relationships Data flexibility Vectorized Topology Representation Vtr Vtr consists of a suite of classes that collectively provide an intermediate representation of topology that supports efficient refinement. Vtr is intended for internal use only and is currently accessed through the Far layer by the FarTopologyRefiner , which assembles these Vtr classes to meet the topological and refinement needs of the Far layer. What follows is therefore more intended to provide insite into the underlying architecture than to describe particular usage. For documentation more relevant to direct usage, proceed to the Far section previously noted. Vtr is vectorized in that its topological data is stored more as a collection of vectors of primitive elements rather than as the faces, vertices and edges that make up many other topological representations. It is essentially a structure-of-arrays SOA approach to topology in contrast to the more common array-of-structures pattern found in many other topological representations. Vtrs use of vectors allows it to be fairly efficient in its use of memory and similarly efficient to refine, but the topology is fixed once defined. Vtr classes are purely topological. They are even more independent of the representation of vertices, faces, etc. than Hbr in that they are not even parameterized by an interface to such components. So the same set of Vtr objects can eventually be used to serve more than one representation of these components. The primary requirement is that a mesh be expressable as an indexable set i.e. a vector or array of vertices, edges and faces. The index of a component uniquely identifies it and properties are retrieved by referring to it by index. Its worth qualifying the term topological here and elsewhere -- we generally refer to topology as subdivision topology rather than mesh topology. A subdivision hierarchy is impacted by the presence of semi-sharp creasing, as the subdivision rules change in response to that creasing. So subdivision topology includes the sharpness values assigned to edges and vertices that affect the semi-sharp creasing. The two primary classes in Vtr consist of VtrLevel - a class representing complete vertex topology for a level VtrRefinement - a class mapping a parent VtrLevel to a child level Others exist to represent the following selection and appropriate tagging of components for sparse refinement divergence of face-varying topology from the vertex topology mapping between face-varying topology at successive levels common low-level utilities, e.g. simple array classes VtrLevel VtrLevel is a complete topological description of a subdivision level, with the topological relations, sharpness values and component tags all stored in vectors literally stdvectors, but easily changed via typedefs. There are no classes or objects for the mesh component types i.e. faces, edges and vertices but simply an integer index to identify each. It can be viewed as a structure-of-arrays representation of the topology any property related to a particular component is stored in an array and accessible using the index identifying that component. So with no classes the for the components, its difficult to say what constitutes a vertex or a face they are each the sum of all the fields scattered amongst the many vectors included. Level represents a single level of a potential hierarchy and is capable of representing the complete base mesh. There are no members that relate data in one level to any other, either below or above. As such, any Level can be used as the base level for a new subdivision hierarchy potentially more than one. All relationships between separate levels are maintained in the VtrRefinement class. Topological Relationships Level requires the definition of and associations between a fixed set of indexable components for all three component types, i.e. an explicit edge list in addition to the expected set of vertices and faces. There are no explicit component objects in the representation, only an integer index  VtrIndex  identifying each component within the set and data associated with that component in the various vectors. The topology is stored as six sets of incident relations between the components two each for the two other component types incident each component type, i.e. for each face, its incident vertices and incident edges for each edge, its incident vertices and incident faces for each vertex, its incident edges and incident faces The collection of incidence relations is a vectorized variation of AIF the Adjacency and Incidence Framework. The set of these six incidence relations is not minimal only four are required, but that set excludes the most desired face-vertex relation but all six are kept and maintained to facilitate faster refinement. While the sizes of several vectors are directly proportional to the number of vertices, edges or faces to which the data is associated, the sizes of some of the vectors for these relations is more cumulative and so additional vectors of offsets is required typical of the face-vertex list commonly used as the minimal definition of mesh topology. Vectors for the sharpness values associated with crease edges and corner vertices are included and so sized according to the number of edges and vertices, along with additional tags for the components that may be helpful to refinement i.e. the type of subdivision Rule associated with each vertex. A Level is really just a container for data in a subdivision level, and so its public methods are primarily to access that data. Modification of the data is protected and only made available to classes that are intended to construct Levels  currently the Far factory class that is responsible for building the base level, and the VtrRefinement class that constructs subsequent levels during refinement. Memory Efficiency One of the advantages in storing data in what is essentially a structure-of-arrays, rather than the array-of-structures more typical of topological representations, is that we can be more selective about memory usage in some cases. Particularly in the case of uniform refinement, when the data in subsequent levels is typically 4x its predecessor, we can minimize what we either generate or keep around at each level. For instance, if only a face-list is required at the finest level, we only need to generate one of the six topological relations the vertices incident each face. When we do keep Levels around in memory as is the case with the FarTopologyRefiner  we do have do have the opportunity to prune what is not strictly necessary after the refinement. Just as with construction, whatever classes are privileged to construct a Level are likely those that will be privileged to prune its contents when needed. The current implementation of Level is far from optimal though -- there are opportunities for improvement. After one level of subdivision, the faces in a Level will be either all quads or tris. Having specializations for these cases and using the more general case in support of N-sided faces for the base level only is one possibility. Levels also allocate dozens of vectors in which to store all data. Since these vectors are of fixed size once created, they could be aggregated by partitioning one or a smaller number of larger block of memory into the desired pieces. The desire to make some of these improvements is part of why Vtr is not directly exposed for public use and instead exposed via Far. VtrRefinement While VtrLevel contains the topology for each subdivision level, VtrRefinement is responsible for creating a new level via refinement of an existing one, and for maintaining the relationships between the components in the parent and child levels. So a simplified view of a subdivision hierarchy with Vtr is a set of Levels with a Refinement between each successive pair. Refinement is a friend of Level and will populate a child level from a parent given a set of refinement parameters. Aside from parameters related to data or depth, there are two kinds of refinement supported uniform and sparse. The latter sparse refinement requires selection of an arbitrary set of components -- any dependent or neighboring components that are required for the limit will be automatically included. So feature-adaptive refinement is just one form of this selective sparse refinement, the criteria being the topological features of interest creases and extra-ordinary vertices. The intent is to eventually provide more flexibility to facilitate the refinement of particular regions of interest or more dynamicadaptive needs. Refinement has also been subclassed according to the type of topological split being performed, i.e. splitting all faces into quads or tris via the QuadRefinement and TriRefinement subclasses. As noted with VtrLevel , there is further room for improvement in memory andor performance here by combining more optimal specializations for both Refinement and Level -- with consideration of separating the uniform and sparse cases. Parent-child and child-parent relationships While Refinement populates a new child Level as part of its refinement operation, it also accumulates the relationships between the parent and child level and as with Level , this data is stored in vectors indexable by the components. The associations between components in the two levels was initially only uni-directional child components were associated with incident components of a parent component based on the parent components topology, so we had a parent-to-child mapping one to many. Storing the reverse child-to-parent mapping was avoided to reduce memory particularly in the case of uniform refinement as it often was not necessary, but a growing need for it, particularly in the case of sparse feature-adaptive refinement, lead to it being included. Data flexibility One of the advantages of the structure-of-arrays representation in both Level and Refinement is that we can make more dynamic choices about what type of data we choose to allocate and use based on needs. For instance, we can choose between maintaining the parent-child or child-parent mapping in Refinement , or both if needed, and we can remove one if no longer necessary. An active example of this is uniform refinement if we only require the face-vertex list at the finest subdivision level, there is no need to generate a complete topological description of that level as would be required of more traditional representations, and given that level is 4x the magnitude of its parent, the savings are considerable. Currently there is nothing specific to a subdivision scheme in the refinement other than the type of topological splitting to apply. The refinement does subdivide sharpness values for creasing, but that too is independent of scheme. Tags were added to the base level that are propagated through the refinement and these too are dependent on the scheme, but are applied externally. Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"vtr_overview.html"}, 
{"title":"Using Hbr", "text":"Using Hbr Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen Using Hbr 3.6.0 User Docs API Docs Release Notes Forum Github Using Hbr Vertex Template API Creating a Mesh Instantiating an HbrMesh Creating Vertices Creating Faces Wrapping Things Up Boundary Interpolation Rules Adding Creases Vertex Creases Edge Creases Holes Hierarchical Edits Face-varying Data Instantiating the HbrMesh Setting the Face-Varying Data Retrieving the Face-Varying Data Valence Operators Managing Singular Vertices 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 Vertex Template API The Hbr API abstracts the vertex class through templating. Client-code is expected to provide a vertex class that implements the requisite interpolation functionality. Here is an example of a simple vertex class that accounts for 3D position, but does not support arbitrary variables or varying interpolation. struct Vertex  Vertex    Vertex  int i    Vertex  const Vertex  src   _pos  0   src . _pos  0  _pos  1   src . _pos  1  _pos  2   src . _pos  2    Vertex     void AddWithWeight  const Vertex  src , float weight , void   0   _pos  0   weight  src . _pos  0  _pos  1   weight  src . _pos  1  _pos  2   weight  src . _pos  2   void AddVaryingWithWeight  const Vertex  , float , void   0    void Clear  void   0   _pos  0   _pos  1   _pos  2   0.0f   void SetPosition  float x , float y , float z   _pos  0   x  _pos  1   y  _pos  2   z   void ApplyVertexEdit  const OpenSubdiv  HbrVertexEdit  Vertex   edit   const float  src  edit . GetEdit  switch  edit . GetOperation   case OpenSubdiv  HbrHierarchicalEdit  Vertex  Set  _pos  0   src  0  _pos  1   src  1  _pos  2   src  2  break  case OpenSubdiv  HbrHierarchicalEdit  Vertex  Add  _pos  0   src  0  _pos  1   src  1  _pos  2   src  2  break  case OpenSubdiv  HbrHierarchicalEdit  Vertex  Subtract  _pos  0  - src  0  _pos  1  - src  1  _pos  2  - src  2  break    void ApplyMovingVertexEdit  const OpenSubdiv  HbrMovingVertexEdit  Vertex       custom functions  data not required by Hbr ------------------------- Vertex  float x , float y , float z   _pos  0   x  _pos  1   y  _pos  2   z   const float  GetPos  const  return _pos   float _pos  3   In some cases, if only topological analysis is required, the class can be left un-implemented. Far and Osd for instance store vertex data in serialized interleaved vectors. Here is the OsdVertex class for reference class Vertex  public  Vertex   Vertex  int  index    Vertex  Vertex const   src    void AddWithWeight  Vertex const   i  , float  weight  , void   0   void AddVaryingWithWeight  const Vertex   i  , float  weight  , void   0   void Clear  void   0   void ApplyVertexEdit  FarVertexEdit const      Creating a Mesh The following tutorial walks through the steps of instantiating a simple Hbr mesh. The code found in regressioncommonshape_utils.h can also be used as an example. While this implementation covers many of Hbr s features, it does not provide coverage for the complete Renderman specification though. Instantiating an HbrMesh First we need to instantiate a mesh object. Hbr supports 3 subdivision schemes Catmull-Clark catmark Loop Bilinear The scheme is selected by passing an specialized instance of HbrSubdivisionT , HbrCatmarkSubdivisionT in this case. The scheme can be shared across multiple mesh objects, so we only need a single instance. static OpenSubdiv  HbrCatmarkSubdivision  Vertex  _scheme  OpenSubdiv  HbrMesh  Vertex   mesh  new OpenSubdiv  HbrMesh  Vertex   _scheme  Creating Vertices Adding vertices to the mesh is accomplished using the HbrMeshNewVertex method. Because Hbr uses a dedicated vertex allocator to help alleviate the performance impact of intensive fragmented memory allocations. This optimization results in the following design pattern Vertex vtx  for  int i  0  i  numVerts  i    Vertex  v  mesh - NewVertex  i , vtx   v-SetPosition  We instantiate a single default vertex object named vtx on the stack. We then recover the pointer to the actual vertex created in the mesh from the NewVertex method. Once we have recovered that pointer, we can set the data for our vertex by using any of the custom accessors. Creating Faces Once all the vertices have been registered in the mesh, we can start adding the faces with HbrMeshNewFace . Assuming we had an obj style reader, we need to know the number of vertices in the face and the indices of these vertices. for  int f  0  f  numFaces   f   int nverts  obj - GetNumVertices  f  const int  faceverts  obj - GetFaceVerts  f  mesh - NewFace  nv , fv , 0   However, Hbr is not able to handle non-manifold geometry. In order to avoid tripping asserts or causing memory violations, lets rewrite the previous loop with some some prototype code to check the validity of the topology. for  int f  0  f  numFaces   f   int nv  obj - GetNumVertices  f  const int  fv  obj - GetFaceVerts  f   triangles only for Loop subdivision  if  scheme  kLoop  and  nv  3   printf  Trying to create a Loop subd with non-triangle face n   continue    now check the half-edges connectivity for  int j  0  j  nv  j    OpenSubdiv  HbrVertex  T   origin  mesh - GetVertex  fv  j   OpenSubdiv  HbrVertex  T   destination  mesh - GetVertex  fv  j  1   nv   OpenSubdiv  HbrHalfedge  T   opposite  destination - GetEdge  origin  if  origin  NULL  destination  NULL   printf   An edge was specified that connected a nonexistent vertex n   continue   if  origin  destination   printf   An edge was specified that connected a vertex to itself n   continue   if  opposite  opposite - GetOpposite    printf   A non-manifold edge incident to more than 2 faces was found n   continue   if  origin - GetEdge  destination   printf   An edge connecting two vertices was specified more than once.  Its likely that an incident face was flipped n   continue    mesh - NewFace  nv , fv , 0   Wrapping Things Up Once we have vertices and faces set in our mesh, we still need to wrap things up by calling HbrMeshFinish  mesh - Finish  Finish iterates over the mesh to apply the boundary interpolation rules and checks for singular vertices. At this point, there is one final topology check remaining to validate the mesh mesh - Finish  if  mesh - GetNumDisconnectedVertices   printf  The specified subdivmesh contains disconnected surface components. n    abort or iterate over the mesh to remove the offending vertices  Boundary Interpolation Rules The rule-set can be selected using the following accessors Vertex and varying data mesh - SetInterpolateBoundaryMethod  OpenSubdiv  HbrMesh  Vertex  k_InterpolateBoundaryEdgeOnly  Face-varying data mesh - SetFVarInterpolateBoundaryMethod  OpenSubdiv  HbrMesh  Vertex  k_InterpolateBoundaryEdgeOnly  Additional information on boundary interpolation rules can be found here Warning The boundary interpolation rules must be set before the call to HbrMeshFinish , which sets the sharpness values to boundary edges and vertices based on these rules. Adding Creases Hbr supports a sharpness attribute on both edges and vertices. Sharpness is set using the SetSharpnessfloat accessors. Vertex Creases Given an index, vertices are very easy to access in the mesh. int idx   vertex index float sharp   the edge sharpness OpenSubdiv  HbrVertex  Vertex   v  mesh - GetVertex  idx  if  v   v - SetSharpness  std  max  0.0f , sharp    else printf  cannot find vertex for corner tag d n  , idx  Edge Creases Usually, edge creases are described with a vertex indices pair. Here is some sample code to locate the matching half-edge and set a crease sharpness. int v0 , v1   vertex indices float sharp   the edge sharpness OpenSubdiv  HbrVertex  Vertex   v  mesh - GetVertex  v0 ,  w  mesh - GetVertex  v1  OpenSubdiv  HbrHalfedge  Vertex   e  0  if  v  w   if  e  v - GetEdge  w   0  e  w - GetEdge  v  if  e   e - SetSharpness  std  max  0.0f , sharp    else printf  cannot find edge for crease tag d,d n  , v0 , v1   Holes Hbr faces support a hole tag. int idx   the face index OpenSubdiv  HbrFace  Vertex   f  mesh - GetFace  idx  if  f   f - SetHole   else printf  cannot find face for hole tag d n  , idx  Note The hole tag is hierarchical  sub-faces can also be marked as holes. See Hierarchical Edits Hierarchical Edits Hbr supports the following types of hierarchical edits Type Function Corner edits Modify vertex sharpness Crease edits Modify edge sharpness FaceEdit Modify custom face data FVarEdit Modify face-varying data VertexEdit Modify vertex and varying data HoleEdit Set hole tag Modifications are one of the following 3 operations Operation Set Add Subtract Here is a simple example that creates a hierarchical vertex edit.  path  655, 2, 3, 0 int faceid  655 , nsubfaces  2 , subfaces  2    2 , 3 , vertexid  0  int offset  0 ,  offset to the vertex or varying data numElems  3   number of elements to apply the modifier to x,y,z  3 bool isP  false   shortcut to identify modifications to the vertex position P OpenSubdiv  HbrHierarchicalEdit  Vertex  Operation op  OpenSubdiv  HbrHierarchicalEdit  T  Set  float values  3    1.0f , 0.5f , 0.0f   edit values OpenSubdiv  HbrVertexEdit  T   edit  new OpenSubdiv  HbrVertexEdit  T   faceid , nsubfaces , subfaces , vertexid , offset , floatwidth , isP , op , values  Face-varying Data Here is a walk-through of how to store face-varying data for a u,v pair. Unlike vertex and varying data which is accessed through the templated vertex API, face-varying data is directly aggregated as vectors of float data. Instantiating the HbrMesh The HbrMesh needs to retain some knowledge about the face-varying data that it carries in order to refine it correctly. int fvarwidth  2   total width of the fvar data static int indices  1    0 ,  1 offset set to 0 widths  1    2   2 floats in a u,v pair int const fvarcount  fvarwidth  0  1  0 ,  fvarindices  fvarwidth  0  indices  NULL ,  fvarwidths  fvarwidth  0  widths  NULL  mesh  new OpenSubdiv  HbrMesh  T    _scheme , fvarcount , fvarindices , fvarwidths , fvarwidth  Setting the Face-Varying Data After the topology has been created, Hbr is ready to accept face-varying data. Here is some sample code for  int i  0 , idx  0  i  numFaces   i   OpenSubdiv  HbrFace  Vertex   f  mesh - GetFace  i  int nv  f - GetNumVertices   note this is not the fastest way OpenSubdiv  HbrHalfedge  Vertex   e  f - GetFirstEdge  for  int j  0  j  nv   j , e  e - GetNext   OpenSubdiv  HbrFVarData  Vertex   fvt  e - GetOrgVertex  - GetFVarData  f  float const  fvdata  GetFaceVaryingData  i , j  if  not fvt . IsInitialized    if no fvar daa exists yet on the vertex fvt . SetAllData  2 , fvdata   else if  not fvt . CompareAll  2 , fvdata    if there already is fvar data and there is a boundary add the new data OpenSubdiv  HbrFVarData  T   nfvt  e - GetOrgVertex  - NewFVarData  f  nfvt . SetAllData  2 , fvdata     Retrieving the Face-Varying Data The HbrFVarData structures are expanded during the refinement process, with every sub-face being assigned a set of interpolated face-varying data. This data can be accessed in 2 ways  From a face, passing a vertex index  OpenSubdivHbrFaceVertex  f OpenSubdiv  HbrFVarData const  fv  f . GetFVarData  vindex  const float  data  fv . GetData  From a vertex, passing a pointer to an incident face  OpenSubdivHbrFaceVertex  f OpenSubdiv  HbrFVarData const  fv  myVertex . GetFVarData  f  const float  data  fv . GetData  Valence Operators When manipulating meshes, it is often necessary to iterate over neighboring faces or vertices. Rather than gather lists of pointers and return them, Hbr exposes an operator pattern that guarantees consistent mesh traversals. The following example shows how to use an operator to count the number of neighboring vertices use HbrVertexGetValence for proper valence counts OpenSubdivHbrVertexVertex  v class MyOperator  public OpenSubdiv  HbrVertexOperator  Vertex   public  int count  MyOperator   count  0    virtual void operator   OpenSubdiv  HbrVertex  Vertex   v    count    MyOperator op  v - ApplyOperatorSurroundingVertices  op  Managing Singular Vertices Certain topological configurations would force vertices to share multiple half-edge cycles. Because Hbr is a half-edge representation, these singular vertices have to be duplicated as part of the HbrMeshFinish phase of the instantiation. These duplicated vertices can cause problems for client-code that tries to populate buffers of vertex or varying data. The following sample code shows how to match the vertex data to singular vertex splits  Populating an OsdCpuVertexBuffer with vertex data positions,... float const  vtxData  inMeshFn . getRawPoints   returnStatus  OpenSubdiv  OsdCpuVertexBuffer  vertexBuffer  OpenSubdiv  OsdCpuVertexBuffer  Create  numVertexElements , numFarVerts  vertexBuffer - UpdateData  vtxData , 0 , numVertices   Duplicate the vertex data into the split singular vertices std  vector  std  pair  int , int   const splits  hbrMesh - GetSplitVertices  for  int i  0  i   int  splits . size   i   vertexBuffer - UpdateData  vtxData  splits  i . second  numVertexElements , splits  i . first , 1   Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"using_osd_hbr.html"}, 
{"title":"hbr_tutorial_0.cpp", "text":"hbr_tutorial_0.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen hbr_tutorial_0.cpp 3.6.0 User Docs API Docs Release Notes Forum Github hbr_tutorial_0.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialshbrtutorial_0hbr_tutorial_0.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial presents in a very succinct way the requisite steps to  instantiate an Hbr mesh from simple topological data.  include opensubdivhbrmesh.h include opensubdivhbrcatmark.h include cstdio ------------------------------------------------------------------------------  Vertex container implementation.   The HbrMeshT class is a templated interface that expects a vertex class to  perform interpolation on arbitrary vertex data.   For the template specialization of the HbrMesh interface to be met, our  Vertex object to implement a minimal set of constructors and member  functions.   Since we are not going to subdivide the mesh, the struct presented here has  been left minimalistic. The only customization added to our container was to  provide storage and accessors for the position of a 3D vertex.  struct Vertex   Hbr minimal required interface ---------------------- Vertex    Vertex  int i    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0    void AddWithWeight  Vertex const  , float    void AddVaryingWithWeight  Vertex const  , float     Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   const float  GetPosition  const  return _position   private  float _position  3   typedef OpenSubdiv  HbrMesh  Vertex  Hmesh  typedef OpenSubdiv  HbrFace  Vertex  Hface  typedef OpenSubdiv  HbrVertex  Vertex  Hvertex  typedef OpenSubdiv  HbrHalfedge  Vertex  Hhalfedge  ------------------------------------------------------------------------------  Pyramid geometry from catmark_pyramid.h static float verts  5  3    0.0f , 0.0f , 2.0f ,  0.0f , -2.0f , 0.0f ,  2.0f , 0.0f , 0.0f ,  0.0f , 2.0f , 0.0f ,  -2.0f , 0.0f , 0.0f  static int nverts  5 , nfaces  5  static int facenverts  5    3 , 3 , 3 , 3 , 4  static int faceverts  16    0 , 1 , 2 , 0 , 2 , 3 , 0 , 3 , 4 , 0 , 4 , 1 , 4 , 3 , 2 , 1  ------------------------------------------------------------------------------ int main  int , char     Create a subdivision scheme Catmull-Clark here OpenSubdiv  HbrCatmarkSubdivision  Vertex   catmark  new OpenSubdiv  HbrCatmarkSubdivision  Vertex    Create an empty Hbr mesh Hmesh  hmesh  new Hmesh  catmark   Populate the vertices Vertex v  for  int i  0  i  nverts   i    Primitive variable data must be set here in our case we set  the 3D position of the vertex. v . SetPosition  verts  i  0 , verts  i  1 , verts  i  2   Add the vertex to the mesh. hmesh - NewVertex  i , v    Create the topology int  fv  faceverts  for  int i  0  i  nfaces   i   int nv  facenverts  i  hmesh - NewFace  nv , fv , 0  fv  nv    Set subdivision options   By default vertex interpolation is set to none on boundaries, which  can produce un-expected results, so we change it to edge-only.  hmesh - SetInterpolateBoundaryMethod  Hmesh  k_InterpolateBoundaryEdgeOnly   Call Finish to finalize the data structures before using the mesh. hmesh - Finish  printf  Created a pyramid with d faces and d vertices. n  , hmesh - GetNumFaces , hmesh - GetNumVertices  delete hmesh  delete catmark   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"hbr_tutorial_0.html"}, 
{"title":"hbr_tutorial_1.cpp", "text":"hbr_tutorial_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen hbr_tutorial_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github hbr_tutorial_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialshbrtutorial_1hbr_tutorial_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to safely create Hbr meshes from arbitrary topology.  Because Hbr is a half-edge data structure, it cannot represent non-manifold  topology. Ensuring that the geometry used is manifold is a requirement to use  Hbr safely. This tutorial presents some simple tests to detect inappropriate  topology.  include opensubdivhbrmesh.h include opensubdivhbrcatmark.h include cstdio ------------------------------------------------------------------------------ struct Vertex   Hbr minimal required interface ---------------------- Vertex    Vertex  int i    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0    void AddWithWeight  Vertex const  , float    void AddVaryingWithWeight  Vertex const  , float     Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   const float  GetPosition  const  return _position   private  float _position  3   typedef OpenSubdiv  HbrMesh  Vertex  Hmesh  typedef OpenSubdiv  HbrFace  Vertex  Hface  typedef OpenSubdiv  HbrVertex  Vertex  Hvertex  typedef OpenSubdiv  HbrHalfedge  Vertex  Hhalfedge  ------------------------------------------------------------------------------  Non-manifold geometry from catmark_fan.h   o             o    f2      o------------o------------o             f0   f1       o------------ o------------o   The shared edge of a fan is adjacent to 3 faces, and therefore non-manifold.  static float verts  8  3    -1.0 , 0.0 , -1.0 ,  -1.0 , 0.0 , 0.0 ,  0.0 , 0.0 , 0.0 ,  0.0 , 0.0 , -1.0 ,  1.0 , 0.0 , 0.0 ,  1.0 , 0.0 , -1.0 ,  0.0 , 1.0 , 0.0 ,  0.0 , 1.0 , -1.0  static int nverts  8 , nfaces  3  static int facenverts  3    4 , 4 , 4  static int faceverts  12    0 , 1 , 2 , 3 , 3 , 2 , 4 , 5 , 3 , 2 , 6 , 7  ------------------------------------------------------------------------------ int main  int , char    OpenSubdiv  HbrCatmarkSubdivision  Vertex   catmark  new OpenSubdiv  HbrCatmarkSubdivision  Vertex   Hmesh  hmesh  new Hmesh  catmark  Vertex v  for  int i  0  i  nverts   i   v . SetPosition  verts  i  0 , verts  i  1 , verts  i  2  hmesh - NewVertex  i , v    Create the topology int  fv  faceverts  for  int i  0  i  nfaces   i   int nv  facenverts  i  bool valid  true  for  int j  0  j  nv  j    Hvertex const  origin  hmesh - GetVertex  fv  j ,  destination  hmesh - GetVertex  fv  j  1   nv  Hhalfedge const  opposite  destination - GetEdge  origin   Make sure that the vertices exist in the mesh if  origin  NULL  destination  NULL   printf   An edge was specified that connected a nonexistent vertex n   valid  false  break    Check for a degenerate edge if  origin  destination   printf   An edge was specified that connected a vertex to itself n   valid  false  break    Check that no more than 2 faces are adjacent to the edge if  opposite  opposite - GetOpposite    printf   A non-manifold edge incident to more than 2 faces was found n   valid  false  break    Check that the edge is unique and oriented properly if  origin - GetEdge  destination   printf   An edge connecting two vertices was specified more than once.  Its likely that an incident face was flipped n   valid  false  break    if  valid   hmesh - NewFace  nv , fv , 0   else  printf   Skipped face d n  , i   fv  nv   hmesh - SetInterpolateBoundaryMethod  Hmesh  k_InterpolateBoundaryEdgeOnly  hmesh - Finish  printf  Created a fan with d faces and d vertices. n  , hmesh - GetNumFaces , hmesh - GetNumVertices  delete hmesh  delete catmark   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"hbr_tutorial_1.html"}, 
{"title":"far_tutorial_1_1.cpp", "text":"far_tutorial_1_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_1_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_1_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_1_1far_tutorial_1_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial presents in a very succinct way the requisite steps to  instantiate and refine a mesh with Far from simple topological data.  include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include cstdio ------------------------------------------------------------------------------  Vertex container implementation.  struct Vertex   Minimal required interface ---------------------- Vertex    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0   _position  0   _position  1   _position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _position  0   weight  src . _position  0  _position  1   weight  src . _position  1  _position  2   weight  src . _position  2    Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   const float  GetPosition  const  return _position   private  float _position  3   ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h static float g_verts  8  3    -0.5f , -0.5f , 0.5f ,  0.5f , -0.5f , 0.5f ,  -0.5f , 0.5f , 0.5f ,  0.5f , 0.5f , 0.5f ,  -0.5f , 0.5f , -0.5f ,  0.5f , 0.5f , -0.5f ,  -0.5f , -0.5f , -0.5f ,  0.5f , -0.5f , -0.5f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4  using namespace OpenSubdiv  ------------------------------------------------------------------------------ int main  int , char     Populate a topology descriptor with our raw data typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  int maxlevel  2   Uniformly refine the topology up to maxlevel refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel   Allocate a buffer for vertex primvar data. The buffer length is set to  be the sum of all children vertices up to the highest level of refinement. std  vector  Vertex  vbuffer  refiner - GetNumVerticesTotal  Vertex  verts   vbuffer  0   Initialize coarse mesh positions int nCoarseVerts  g_nverts  for  int i  0  i  nCoarseVerts   i   verts  i . SetPosition  g_verts  i  0 , g_verts  i  1 , g_verts  i  2    Interpolate vertex primvar data Far  PrimvarRefiner primvarRefiner   refiner  Vertex  src  verts  for  int level  1  level  maxlevel   level   Vertex  dst  src  refiner - GetLevel  level -1 . GetNumVertices  primvarRefiner . Interpolate  level , src , dst  src  dst     Output OBJ of the highest level refined ----------- Far  TopologyLevel const  refLastLevel  refiner - GetLevel  maxlevel  int nverts  refLastLevel . GetNumVertices  int nfaces  refLastLevel . GetNumFaces   Print vertex positions int firstOfLastVerts  refiner - GetNumVerticesTotal  - nverts  for  int vert  0  vert  nverts   vert   float const  pos  verts  firstOfLastVerts  vert . GetPosition  printf  v f f f n  , pos  0 , pos  1 , pos  2    Print faces for  int face  0  face  nfaces   face   Far  ConstIndexArray fverts  refLastLevel . GetFaceVertices  face   all refined Catmark faces should be quads assert  fverts . size   4  printf  f   for  int vert  0  vert  fverts . size   vert   printf  d  , fverts  vert   1   OBJ uses 1-based arrays...  printf   n     delete refiner  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_1_1.html"}, 
{"title":"hbr_tutorial_2.cpp", "text":"hbr_tutorial_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen hbr_tutorial_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github hbr_tutorial_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialshbrtutorial_2hbr_tutorial_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to subdivide uniformly a simple Hbr mesh. We are  building upon previous tutorials and assuming a fully instantiated mesh  we start with an HbrMesh pointer initialized from the same pyramid shape  used in hbr_tutorial_0.   We then apply the Refine function sequentially to all the faces in the  mesh to generate several levels of uniform subdivision. The resulting data  is then dumped to the terminal in Wavefront OBJ format for inspection.  include opensubdivhbrmesh.h include opensubdivhbrcatmark.h include cassert include cstdio ------------------------------------------------------------------------------   For this tutorial, we have to flesh out the Vertex class further. Note that now  the copy constructor, Clear and AddwithWeight methods have been  implemented to interpolate our float3 position data.   This vertex specialization pattern leaves client-code free to implement  arbitrary vertex primvar data schemes or none at all to conserve efficiency  struct Vertex   Hbr minimal required interface ---------------------- Vertex    Vertex  int i    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0   _position  0   _position  1   _position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _position  0   weight  src . _position  0  _position  1   weight  src . _position  1  _position  2   weight  src . _position  2   void AddVaryingWithWeight  Vertex const  , float     Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   const float  GetPosition  const  return _position   private  float _position  3   typedef OpenSubdiv  HbrMesh  Vertex  Hmesh  typedef OpenSubdiv  HbrFace  Vertex  Hface  typedef OpenSubdiv  HbrVertex  Vertex  Hvertex  typedef OpenSubdiv  HbrHalfedge  Vertex  Hhalfedge  Hmesh  createMesh  ------------------------------------------------------------------------------ int main  int , char    Hmesh  hmesh  createMesh  int maxlevel  2 ,  2 levels of subdivision firstface  0 ,  marker to the first face index of level 2 firstvertex  0   marker to the first vertex index of level 2  Refine the mesh to maxlevel for  int level  0  level  maxlevel   level    Total number of faces in the mesh, across all levels   Note this function iterates over the list of faces and can be slow int nfaces  hmesh - GetNumFaces  if  level   maxlevel -1    Save our vertex marker firstvertex  hmesh - GetNumVertices    Iterate over the faces of the current level of subdivision for  int face  firstface  face  nfaces   face   Hface  f  hmesh - GetFace  face   Note hole tags would have to be dealt with here. f - Refine    Save our face index marker for the next level firstface  nfaces     Output OBJ of the highest level refined -----------  Print vertex positions int nverts  hmesh - GetNumVertices  for  int vert  firstvertex  vert  nverts   vert   float const  pos  hmesh - GetVertex  vert  - GetData . GetPosition  printf  v f f f n  , pos  0 , pos  1 , pos  2    Print faces for  int face  firstface  face  hmesh - GetNumFaces   face   Hface  f  hmesh - GetFace  face  assert  f - GetNumVertices   4  printf  f   for  int vert  0  vert  4   vert    OBJ uses 1-based arrays printf  d  , f - GetVertex  vert  - GetID  - firstvertex  1   printf   n      ------------------------------------------------------------------------------  Creates an Hbr mesh   see hbr_tutorial_0 and hbr_tutorial_1 for more details  Hmesh  createMesh    Pyramid geometry from catmark_pyramid.h static float verts  5  3    0.0f , 0.0f , 2.0f ,  0.0f , -2.0f , 0.0f ,  2.0f , 0.0f , 0.0f ,  0.0f , 2.0f , 0.0f ,  -2.0f , 0.0f , 0.0f  static int nverts  5 , nfaces  5  static int facenverts  5    3 , 3 , 3 , 3 , 4  static int faceverts  16    0 , 1 , 2 , 0 , 2 , 3 , 0 , 3 , 4 , 0 , 4 , 1 , 4 , 3 , 2 , 1  OpenSubdiv  HbrCatmarkSubdivision  Vertex   catmark  new OpenSubdiv  HbrCatmarkSubdivision  Vertex   Hmesh  hmesh  new Hmesh  catmark   Populate the vertices Vertex v  for  int i  0  i  nverts   i   v . SetPosition  verts  i  0 , verts  i  1 , verts  i  2  hmesh - NewVertex  i , v    Create the topology int  fv  faceverts  for  int i  0  i  nfaces   i   int nv  facenverts  i  bool valid  true  for  int j  0  j  nv  j    Hvertex const  origin  hmesh - GetVertex  fv  j ,  destination  hmesh - GetVertex  fv  j  1   nv  Hhalfedge const  opposite  destination - GetEdge  origin   Make sure that the vertices exist in the mesh if  origin  NULL  destination  NULL   printf   An edge was specified that connected a nonexistent vertex n   valid  false  break    Check for a degenerate edge if  origin  destination   printf   An edge was specified that connected a vertex to itself n   valid  false  break    Check that no more than 2 faces are adjacent to the edge if  opposite  opposite - GetOpposite    printf   A non-manifold edge incident to more than 2 faces was found n   valid  false  break    Check that the edge is unique and oriented properly if  origin - GetEdge  destination   printf   An edge connecting two vertices was specified more than once.  Its likely that an incident face was flipped n   valid  false  break    if  valid   hmesh - NewFace  nv , fv , 0   else  printf   Skipped face d n  , i   fv  nv   hmesh - SetInterpolateBoundaryMethod  Hmesh  k_InterpolateBoundaryEdgeOnly  hmesh - Finish  return hmesh   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"hbr_tutorial_2.html"}, 
{"title":"far_tutorial_2_1.cpp", "text":"far_tutorial_2_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_2_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_2_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_2_1far_tutorial_2_1.cpp ------------------------------------------------------------------------------  Tutorial description   Building on tutorial 0, this example shows how to instantiate a simple mesh,  refine it uniformly and then interpolate additional sets of primvar data.  include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include cstdio ------------------------------------------------------------------------------  Vertex container implementation.   We are adding a per-vertex color attribute to our primvar data. While they  are separate properties and exist in separate buffers as when read from an  Alembic file they are both of the form float3 and so we can use the same  underlying type.   While color and position may be the same, well make the color a varying  primvar, e.g. it is constrained to being linearly interpolated between  vertices, rather than smoothly like position and other vertex data.  struct Point3   Minimal required interface ---------------------- Point3    void Clear  void   0   _point  0   _point  1   _point  2   0.0f   void AddWithWeight  Point3 const  src , float weight   _point  0   weight  src . _point  0  _point  1   weight  src . _point  1  _point  2   weight  src . _point  2    Public interface ------------------------------------ void SetPoint  float x , float y , float z   _point  0   x  _point  1   y  _point  2   z   const float  GetPoint  const  return _point   private  float _point  3   typedef Point3 VertexPosition  typedef Point3 VertexColor  ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h static float g_verts  8  3    -0.5f , -0.5f , 0.5f ,  0.5f , -0.5f , 0.5f ,  -0.5f , 0.5f , 0.5f ,  0.5f , 0.5f , 0.5f ,  -0.5f , 0.5f , -0.5f ,  0.5f , 0.5f , -0.5f ,  -0.5f , -0.5f , -0.5f ,  0.5f , -0.5f , -0.5f   Per-vertex RGB color data static float g_colors  8  3    1.0f , 0.0f , 0.5f ,  0.0f , 1.0f , 0.0f ,  0.0f , 0.0f , 1.0f ,  1.0f , 1.0f , 1.0f ,  1.0f , 1.0f , 0.0f ,  0.0f , 1.0f , 1.0f ,  1.0f , 0.0f , 1.0f ,  0.0f , 0.0f , 0.0f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4  using namespace OpenSubdiv  static Far  TopologyRefiner  createFarTopologyRefiner  ------------------------------------------------------------------------------ int main  int , char    int maxlevel  5  Far  TopologyRefiner  refiner  createFarTopologyRefiner   Uniformly refine the topology up to maxlevel refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel   Allocate buffers for vertex primvar data.   We assume we received the coarse data for the mesh in separate buffers  from some other source, e.g. an Alembic file. Meanwhile, we want buffers  for the lastfinest subdivision level to persist. We have no interest  in the intermediate levels.   Determine the sizes for our needs int nCoarseVerts  g_nverts  int nFineVerts  refiner - GetLevel  maxlevel . GetNumVertices  int nTotalVerts  refiner - GetNumVerticesTotal  int nTempVerts  nTotalVerts - nCoarseVerts - nFineVerts   Allocate and initialize the primvar data for the original coarse vertices std  vector  VertexPosition  coarsePosBuffer  nCoarseVerts  std  vector  VertexColor  coarseClrBuffer  nCoarseVerts  for  int i  0  i  nCoarseVerts   i   coarsePosBuffer  i . SetPoint  g_verts  i  0 , g_verts  i  1 , g_verts  i  2  coarseClrBuffer  i . SetPoint  g_colors  i  0 , g_colors  i  1 , g_colors  i  2    Allocate intermediate and final storage to be populated std  vector  VertexPosition  tempPosBuffer  nTempVerts  std  vector  VertexPosition  finePosBuffer  nFineVerts  std  vector  VertexColor  tempClrBuffer  nTempVerts  std  vector  VertexColor  fineClrBuffer  nFineVerts   Interpolate all primvar data -- separate buffers can be populated on  separate threads if desired VertexPosition  srcPos   coarsePosBuffer  0  VertexPosition  dstPos   tempPosBuffer  0  VertexColor  srcClr   coarseClrBuffer  0  VertexColor  dstClr   tempClrBuffer  0  Far  PrimvarRefiner primvarRefiner   refiner  for  int level  1  level  maxlevel   level   primvarRefiner . Interpolate  level , srcPos , dstPos  primvarRefiner . InterpolateVarying  level , srcClr , dstClr  srcPos  dstPos , dstPos  refiner - GetLevel  level . GetNumVertices  srcClr  dstClr , dstClr  refiner - GetLevel  level . GetNumVertices    Interpolate the last level into the separate buffers for our final data primvarRefiner . Interpolate  maxlevel , srcPos , finePosBuffer  primvarRefiner . InterpolateVarying  maxlevel , srcClr , fineClrBuffer    Visualization with Maya  print a MEL script that generates colored  particles at the location of the refined vertices dont forget to  turn shading on in the viewport to see the colors int nverts  nFineVerts   Output particle positions printf  particle   for  int vert  0  vert  nverts   vert   float const  pos  finePosBuffer  vert . GetPoint  printf  -p f f f n  , pos  0 , pos  1 , pos  2   printf   n    Set particle point size 20 -- very large printf  addAttr -is true -ln  pointSize  -at long -dv 20 particleShape1 n    Add per-particle color attribute rgbPP printf  addAttr -ln  rgbPP  -dt vectorArray particleShape1 n    Set per-particle color values from our primvar data printf  setAttr  particleShape1.rgbPP  -type  vectorArray  d  , nverts  for  int vert  0  vert  nverts   vert   float const  color  fineClrBuffer  vert . GetPoint  printf  f f f n  , color  0 , color  1 , color  2   printf   n    delete refiner  return EXIT_SUCCESS   ------------------------------------------------------------------------------  Creates FarTopologyRefiner from raw geometry   see tutorial_1_1 for more details  static Far  TopologyRefiner  createFarTopologyRefiner    Populate a topology descriptor with our raw data typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  return refiner   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_2_1.html"}, 
{"title":"far_tutorial_1_2.cpp", "text":"far_tutorial_1_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_1_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_1_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_1_2far_tutorial_1_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial illustrates two different styles of defining classes for  interpolating primvar data with the template methods in Far. The most  common usage involves data of a fixed size, so the focus here is on an  alternative supporting variable length data.  include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include cstdio using namespace OpenSubdiv    Vertex data containers for interpolation  - Coord3 is fixed to support 3 floats  - Coord2 is fixed to support 2 floats  - CoordBuffer can support a specified number of floats  struct Coord3  Coord3    Coord3  float x , float y , float z   _xyz  0   x , _xyz  1   y , _xyz  2   z   void Clear   _xyz  0   _xyz  1   _xyz  2   0.0f   void AddWithWeight  Coord3 const  src , float weight   _xyz  0   weight  src . _xyz  0  _xyz  1   weight  src . _xyz  1  _xyz  2   weight  src . _xyz  2   float const  Coords  const  return  _xyz  0   private  float _xyz  3   struct Coord2  Coord2    Coord2  float u , float v   _uv  0   u , _uv  1   v   void Clear   _uv  0   _uv  1   0.0f   void AddWithWeight  Coord2 const  src , float weight   _uv  0   weight  src . _uv  0  _uv  1   weight  src . _uv  1   float const  Coords  const  return  _uv  0   private  float _uv  2   struct CoordBuffer    The head of an external buffer and stride is specified on construction  CoordBuffer  float  data , int size   _data  data , _size  size    CoordBuffer   _data  0 , _size  0    void Clear   for  int i  0  i  _size   i   _data  i   0.0f    void AddWithWeight  CoordBuffer const  src , float weight   assert  src . _size  _size  for  int i  0  i  _size   i   _data  i   weight  src . _data  i    float const  Coords  const  return _data     Defining  to return a location elsewhere in the buffer is the key  requirement to supporting interpolatible data of varying size  CoordBuffer operator  int index  const  return CoordBuffer  _data  index  _size , _size   private  float  _data  int _size     Global cube geometry from catmark_cube.h   Topology static int g_nverts  8  static int g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4   Primvar data static float g_verts  8  3    0.0f , 0.0f , 1.0f ,  1.0f , 0.0f , 1.0f ,  0.0f , 1.0f , 1.0f ,  1.0f , 1.0f , 1.0f ,  0.0f , 1.0f , 0.0f ,  1.0f , 1.0f , 0.0f ,  0.0f , 0.0f , 0.0f ,  1.0f , 0.0f , 0.0f    Creates FarTopologyRefiner from raw geometry above see tutorial_1_1 for  more details  static Far  TopologyRefiner  createFarTopologyRefiner   typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  return refiner     Overview of main  - create a FarTopologyRefiner and uniformly refine it  - allocate separate and combined data buffers for vertex positions and UVs  - populate all refined data buffers and compare results  - write the result in Obj format   Disable warnings for exact floating point comparisons ifdef __INTEL_COMPILER pragma warning disable 1572 endif int main  int , char     Instantiate a FarTopologyRefiner from the global geometry Far  TopologyRefiner  refiner  createFarTopologyRefiner   Uniformly refine the topology up to maxlevel int maxlevel  2  refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel   Allocate and populate data buffers for vertex primvar data -- positions and  UVs. We assign UV coordiantes by simply projectingassigning XY values.  The position and UV buffers use their associated data types, while the  combined buffer uses 5 floats per vertex.  int numBaseVertices  g_nverts  int numTotalVertices  refiner - GetNumVerticesTotal  std  vector  Coord3  posData  numTotalVertices  std  vector  Coord2  uvData  numTotalVertices  int combinedStride  3  2  std  vector  float  combinedData  numTotalVertices  combinedStride  for  int i  0  i  numBaseVertices   i   posData  i   Coord3  g_verts  i  0 , g_verts  i  1 , g_verts  i  2  uvData  i   Coord2  g_verts  i  0 , g_verts  i  1  float  coordCombined   combinedData  i  combinedStride  coordCombined  0   g_verts  i  0  coordCombined  1   g_verts  i  1  coordCombined  2   g_verts  i  2  coordCombined  3   g_verts  i  0  coordCombined  4   g_verts  i  1    Interpolate vertex primvar data Far  PrimvarRefiner primvarRefiner   refiner  Coord3  posSrc   posData  0  Coord2  uvSrc   uvData  0  CoordBuffer combinedSrc   combinedData  0 , combinedStride  for  int level  1  level  maxlevel   level   int numLevelVerts  refiner - GetLevel  level -1 . GetNumVertices  Coord3  posDst  posSrc  numLevelVerts  Coord2  uvDst  uvSrc  numLevelVerts  CoordBuffer combinedDst  combinedSrc  numLevelVerts  primvarRefiner . Interpolate  level , posSrc , posDst  primvarRefiner . Interpolate  level , uvSrc , uvDst  primvarRefiner . Interpolate  level , combinedSrc , combinedDst  posSrc  posDst  uvSrc  uvDst  combinedSrc  combinedDst    Verify that the combined coords match the separate results for  int i  numBaseVertices  i  numTotalVertices   i   float const  posCoords  posData  i . Coords  float const  uvCoords  uvData  i . Coords  float const  combCoords   combinedData  combinedStride  i  assert  combCoords  0   posCoords  0  assert  combCoords  1   posCoords  1  assert  combCoords  2   posCoords  2  assert  combCoords  3   uvCoords  0  assert  combCoords  4   uvCoords  1     Output OBJ of the highest level refined  Far  TopologyLevel const  refLastLevel  refiner - GetLevel  maxlevel  int firstOfLastVerts  numTotalVertices - refLastLevel . GetNumVertices   Print vertex positions printf   Vertices n   for  int vert  firstOfLastVerts  vert  numTotalVertices   vert   float const  pos   combinedData  vert  combinedStride  printf  v f f f n  , pos  0 , pos  1 , pos  2   printf   UV coordinates n   for  int vert  firstOfLastVerts  vert  numTotalVertices   vert   float const  uv   combinedData  vert  combinedStride   3  printf  vt f f n  , uv  0 , uv  1    Print faces int numFaces  refLastLevel . GetNumFaces  printf   Faces n   for  int face  0  face  numFaces   face   Far  ConstIndexArray fverts  refLastLevel . GetFaceVertices  face  printf  f   for  int fvert  0  fvert  fverts . size   fvert   int objIndex  1  fverts  fvert   OBJ uses 1-based arrays... printf  dd  , objIndex , objIndex   printf   n    delete refiner  return EXIT_SUCCESS   Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_1_2.html"}, 
{"title":"far_tutorial_4_1.cpp", "text":"far_tutorial_4_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_4_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_4_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_4_1far_tutorial_4_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to create and manipulate FarStencilTable. We use  the factorized stencils to interpolate vertex primvar data buffers.  include opensubdivfartopologyDescriptor.h include opensubdivfarstencilTable.h include opensubdivfarstencilTableFactory.h include cstdio include cstring ------------------------------------------------------------------------------  Vertex container implementation.  struct Vertex   Minimal required interface ---------------------- Vertex    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0   _position  0   _position  1   _position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _position  0   weight  src . _position  0  _position  1   weight  src . _position  1  _position  2   weight  src . _position  2    Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   float const  GetPosition  const  return _position   private  float _position  3   ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h static float g_verts  24    -0.5f , -0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , 0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , -0.5f , -0.5f , -0.5f , -0.5f , 0.5f , -0.5f , -0.5f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4  using namespace OpenSubdiv  static Far  TopologyRefiner  createTopologyRefiner  ------------------------------------------------------------------------------ int main  int , char     Generate a FarTopologyRefiner see tutorial_1_1 for details. Far  TopologyRefiner  refiner  createTopologyRefiner   Uniformly refine the topology up to maxlevel. int maxlevel  3  refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel   Use the FarStencilTable factory to create discrete stencil table  note we only want stencils for the highest refinement level. Far  StencilTableFactory  Options options  options . generateIntermediateLevels  false  options . generateOffsets  true  Far  StencilTable const  stencilTable  Far  StencilTableFactory  Create   refiner , options   Allocate vertex primvar buffer 1 stencil for each vertex int nstencils  stencilTable - GetNumStencils  std  vector  Vertex  vertexBuffer  nstencils   Quick  dirty re-cast of the primvar data from our cube  this is where you would drive shape deformations every frame Vertex  controlValues  reinterpret_cast  Vertex   g_verts    This section would be applied every frame after control vertices have  been moved.  Apply stencils on the control vertex data to update the primvar data  of the refined vertices. stencilTable - UpdateValues  controlValues ,  vertexBuffer  0     Visualization with Maya  print a MEL script that generates particles  at the location of the refined vertices printf  particle   for  int i  0  i   int  vertexBuffer . size   i   float const  pos  vertexBuffer  i . GetPosition  printf  -p f f f n  , pos  0 , pos  1 , pos  2   printf  -c 1 n    delete refiner  delete stencilTable  return EXIT_SUCCESS   ------------------------------------------------------------------------------ static Far  TopologyRefiner  createTopologyRefiner    Populate a topology descriptor with our raw data. typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor. return Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_4_1.html"}, 
{"title":"far_tutorial_2_2.cpp", "text":"far_tutorial_2_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_2_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_2_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_2_2far_tutorial_2_2.cpp ------------------------------------------------------------------------------  Tutorial description   Building on tutorial 0, this example shows how to instantiate a simple mesh,  refine it uniformly and then interpolate both vertex and face-varying  primvar data.  The resulting interpolated data is output as an obj file, with the  face-varying data recorded in the uv texture layout.  include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include cstdio ------------------------------------------------------------------------------  Face-varying implementation.   struct Vertex   Minimal required interface ---------------------- Vertex    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0   _position  0   _position  1   _position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _position  0   weight  src . _position  0  _position  1   weight  src . _position  1  _position  2   weight  src . _position  2    Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   const float  GetPosition  const  return _position   private  float _position  3   ------------------------------------------------------------------------------  Face-varying container implementation.   We are using a uv texture layout as a face-varying primitive variable  attribute. Because face-varying data is specified per-face-per-vertex,  we cannot use the same container that we use for vertex or varying  data. We specify a new container, which only carries u,v coordinates.  Similarly to our Vertex container, we add a minimalistic interpolation  interface with a Clear and AddWithWeight methods.  struct FVarVertexUV   Minimal required interface ---------------------- void Clear   u  v  0.0f   void AddWithWeight  FVarVertexUV const  src , float weight   u  weight  src . u  v  weight  src . v    Basic uv layout channel float u , v   struct FVarVertexColor   Minimal required interface ---------------------- void Clear   r  g  b  a  0.0f   void AddWithWeight  FVarVertexColor const  src , float weight   r  weight  src . r  g  weight  src . g  b  weight  src . b  a  weight  src . a    Basic color layout channel float r , g , b , a   ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h  vertex primitive variable data  topology static float g_verts  8  3    -0.5f , -0.5f , 0.5f ,  0.5f , -0.5f , 0.5f ,  -0.5f , 0.5f , 0.5f ,  0.5f , 0.5f , 0.5f ,  -0.5f , 0.5f , -0.5f ,  0.5f , 0.5f , -0.5f ,  -0.5f , -0.5f , -0.5f ,  0.5f , -0.5f , -0.5f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4   face-varying primitive variable data  topology for UVs static float g_uvs  14  2    0.375 , 0.00 ,  0.625 , 0.00 ,  0.375 , 0.25 ,  0.625 , 0.25 ,  0.375 , 0.50 ,  0.625 , 0.50 ,  0.375 , 0.75 ,  0.625 , 0.75 ,  0.375 , 1.00 ,  0.625 , 1.00 ,  0.875 , 0.00 ,  0.875 , 0.25 ,  0.125 , 0.00 ,  0.125 , 0.25  static int g_nuvs  14  static int g_uvIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 9 , 8 , 1 , 10 , 11 , 3 , 12 , 0 , 2 , 13   face-varying primitive variable data  topology for color static float g_colors  24  4    1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 0.0 , 0.0 , 1.0 ,  1.0 , 0.0 , 0.0 , 1.0 ,  1.0 , 0.0 , 0.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0  static int g_ncolors  24  static int g_colorIndices  24    0 , 3 , 9 , 6 , 7 , 10 , 15 , 12 , 13 , 16 , 21 , 18 , 19 , 22 , 4 , 1 , 5 , 23 , 17 , 11 , 20 , 2 , 8 , 14  using namespace OpenSubdiv  ------------------------------------------------------------------------------ int main  int , char    int maxlevel  3  typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  options . SetFVarLinearInterpolation  Sdc  Options  FVAR_LINEAR_NONE   Populate a topology descriptor with our raw data Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices  int channelUV  0  int channelColor  1   Create a face-varying channel descriptor Descriptor  FVarChannel channels  2  channels  channelUV . numValues  g_nuvs  channels  channelUV . valueIndices  g_uvIndices  channels  channelColor . numValues  g_ncolors  channels  channelColor . valueIndices  g_colorIndices   Add the channel topology to the main descriptor desc . numFVarChannels  2  desc . fvarChannels  channels   Instantiate a FarTopologyRefiner from the descriptor Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options   Uniformly refine the topology up to maxlevel  note fullTopologyInLastLevel must be true to work with face-varying data  Far  TopologyRefiner  UniformOptions refineOptions  maxlevel  refineOptions . fullTopologyInLastLevel  true  refiner - RefineUniform  refineOptions    Allocate and initialize the vertex primvar data see tutorial 2 for  more details. std  vector  Vertex  vbuffer  refiner - GetNumVerticesTotal  Vertex  verts   vbuffer  0  for  int i  0  i  g_nverts   i   verts  i . SetPosition  g_verts  i  0 , g_verts  i  1 , g_verts  i  2    Allocate and initialize the first channel of face-varying primvar data UVs std  vector  FVarVertexUV  fvBufferUV  refiner - GetNumFVarValuesTotal  channelUV  FVarVertexUV  fvVertsUV   fvBufferUV  0  for  int i  0  i  g_nuvs   i   fvVertsUV  i . u  g_uvs  i  0  fvVertsUV  i . v  g_uvs  i  1    Allocate  interpolate the face-varying primvar data colors std  vector  FVarVertexColor  fvBufferColor  refiner - GetNumFVarValuesTotal  channelColor  FVarVertexColor  fvVertsColor   fvBufferColor  0  for  int i  0  i  g_ncolors   i   fvVertsColor  i . r  g_colors  i  0  fvVertsColor  i . g  g_colors  i  1  fvVertsColor  i . b  g_colors  i  2  fvVertsColor  i . a  g_colors  i  3    Interpolate both vertex and face-varying primvar data Far  PrimvarRefiner primvarRefiner   refiner  Vertex  srcVert  verts  FVarVertexUV  srcFVarUV  fvVertsUV  FVarVertexColor  srcFVarColor  fvVertsColor  for  int level  1  level  maxlevel   level   Vertex  dstVert  srcVert  refiner - GetLevel  level -1 . GetNumVertices  FVarVertexUV  dstFVarUV  srcFVarUV  refiner - GetLevel  level -1 . GetNumFVarValues  channelUV  FVarVertexColor  dstFVarColor  srcFVarColor  refiner - GetLevel  level -1 . GetNumFVarValues  channelColor  primvarRefiner . Interpolate  level , srcVert , dstVert  primvarRefiner . InterpolateFaceVarying  level , srcFVarUV , dstFVarUV , channelUV  primvarRefiner . InterpolateFaceVarying  level , srcFVarColor , dstFVarColor , channelColor  srcVert  dstVert  srcFVarUV  dstFVarUV  srcFVarColor  dstFVarColor     Output OBJ of the highest level refined ----------- Far  TopologyLevel const  refLastLevel  refiner - GetLevel  maxlevel  int nverts  refLastLevel . GetNumVertices  int nuvs  refLastLevel . GetNumFVarValues  channelUV  int ncolors  refLastLevel . GetNumFVarValues  channelColor  int nfaces  refLastLevel . GetNumFaces   Print vertex positions int firstOfLastVerts  refiner - GetNumVerticesTotal  - nverts  for  int vert  0  vert  nverts   vert   float const  pos  verts  firstOfLastVerts  vert . GetPosition  printf  v f f f n  , pos  0 , pos  1 , pos  2    Print uvs int firstOfLastUvs  refiner - GetNumFVarValuesTotal  channelUV  - nuvs  for  int fvvert  0  fvvert  nuvs   fvvert   FVarVertexUV const  uv  fvVertsUV  firstOfLastUvs  fvvert  printf  vt f f n  , uv . u , uv . v    Print colors int firstOfLastColors  refiner - GetNumFVarValuesTotal  channelColor  - ncolors  for  int fvvert  0  fvvert  ncolors   fvvert   FVarVertexColor const  c  fvVertsColor  firstOfLastColors  fvvert  printf  c f f f f n  , c . r , c . g , c . b , c . a    Print faces for  int face  0  face  nfaces   face   Far  ConstIndexArray fverts  refLastLevel . GetFaceVertices  face  Far  ConstIndexArray fuvs  refLastLevel . GetFaceFVarValues  face , channelUV   all refined Catmark faces should be quads assert  fverts . size   4  fuvs . size   4  printf  f   for  int vert  0  vert  fverts . size   vert    OBJ uses 1-based arrays... printf  dd  , fverts  vert   1 , fuvs  vert   1   printf   n     delete refiner  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_2_2.html"}, 
{"title":"far_tutorial_4_2.cpp", "text":"far_tutorial_4_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_4_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_4_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_4_2far_tutorial_4_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to create and manipulate both vertex and varying  FarStencilTable to interpolate 2 primvar data buffers vertex positions and  vertex colors.  include opensubdivfartopologyDescriptor.h include opensubdivfarstencilTable.h include opensubdivfarstencilTableFactory.h include cstdio include cstring ------------------------------------------------------------------------------  Vertex container implementation.  struct Vertex   Minimal required interface ---------------------- Vertex    Vertex  Vertex const  src   _data  0   src . _data  0  _data  1   src . _data  1  _data  2   src . _data  2   void Clear  void   0   _data  0   _data  1   _data  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _data  0   weight  src . _data  0  _data  1   weight  src . _data  1  _data  2   weight  src . _data  2    Public interface ------------------------------------ float const  GetData  const  return _data   private  float _data  3   ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h static float g_verts  24    -0.5f , -0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , 0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , -0.5f , -0.5f , -0.5f , -0.5f , 0.5f , -0.5f , -0.5f   Per-vertex RGB color data static float g_colors  24    1.0f , 0.0f , 0.5f , 0.0f , 1.0f , 0.0f , 0.0f , 0.0f , 1.0f , 1.0f , 1.0f , 1.0f , 1.0f , 1.0f , 0.0f , 0.0f , 1.0f , 1.0f , 1.0f , 0.0f , 1.0f , 0.0f , 0.0f , 0.0f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4  using namespace OpenSubdiv  static Far  TopologyRefiner  createTopologyRefiner  ------------------------------------------------------------------------------ int main  int , char     Generate a FarTopologyRefiner see tutorial_1_1 for details. Far  TopologyRefiner  refiner  createTopologyRefiner   Uniformly refine the topology up to maxlevel. int maxlevel  4  refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel  int nverts  refiner - GetLevel  maxlevel . GetNumVertices   Use the FarStencilTable factory to create discrete stencil table Far  StencilTableFactory  Options options  options . generateIntermediateLevels  false   only the highest refinement level. options . generateOffsets  true    Vertex primvar data   Create stencils table for vertex interpolation options . interpolationMode  Far  StencilTableFactory  INTERPOLATE_VERTEX  Far  StencilTable const  vertexStencils  Far  StencilTableFactory  Create   refiner , options  assert  nverts  vertexStencils - GetNumStencils   Allocate vertex primvar buffer 1 stencil for each vertex std  vector  Vertex  vertexBuffer  vertexStencils - GetNumStencils   Use the cube vertex positions as vertex primvar data Vertex  vertexCVs  reinterpret_cast  Vertex   g_verts    Varying primvar data   Create stencils table for varying interpolation options . interpolationMode  Far  StencilTableFactory  INTERPOLATE_VARYING  Far  StencilTable const  varyingStencils  Far  StencilTableFactory  Create   refiner , options  assert  nverts  varyingStencils - GetNumStencils   Allocate varying primvar buffer 1 stencil for each vertex std  vector  Vertex  varyingBuffer  varyingStencils - GetNumStencils   Use per-vertex array of RGB colors as varying primvar data Vertex  varyingCVs  reinterpret_cast  Vertex   g_colors  delete refiner    Apply stencils in frame loop    This section would be applied every frame after control vertices have  been moved.  Apply stencils on the control vertex data to update the primvar data  of the refined vertices. vertexStencils - UpdateValues  vertexCVs ,  vertexBuffer  0  varyingStencils - UpdateValues  varyingCVs ,  varyingBuffer  0     Visualization with Maya  print a MEL script that generates particles  at the location of the refined vertices printf  particle   for  int vert  0  vert   int  nverts   vert   float const  pos  vertexBuffer  vert . GetData  printf  -p f f f n  , pos  0 , pos  1 , pos  2   printf  -c 1 n    Set particle point size 20 -- very large printf  addAttr -is true -ln  pointSize  -at long -dv 20 particleShape1 n    Add per-particle color attribute rgbPP printf  addAttr -ln  rgbPP  -dt vectorArray particleShape1 n    Set per-particle color values from our varying primvar data printf  setAttr  particleShape1.rgbPP  -type  vectorArray  d  , nverts  for  int vert  0  vert  nverts   vert   float const  color  varyingBuffer  vert . GetData  printf  f f f n  , color  0 , color  1 , color  2   printf   n    delete vertexStencils  delete varyingStencils  return EXIT_SUCCESS   ------------------------------------------------------------------------------ static Far  TopologyRefiner  createTopologyRefiner    Populate a topology descriptor with our raw data. typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor. Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  return refiner   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_4_2.html"}, 
{"title":"far_tutorial_3_1.cpp", "text":"far_tutorial_3_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_3_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_3_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_3_1far_tutorial_3_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to interface a high-level topology representation  with Far for better efficiency. In tutorial 0, we showed how to instantiate  topology from a simple face-vertex list. Here we will show how to take  advantage of more complex data structures.   Many client applications that manipulate geometry use advanced data structures  such as half-edge, quad-edge or winged-edge in order to represent complex  topological relationships beyond the usual face-vertex lists. We can take  advantage of this information.   Far provides an advanced interface that allows such a client application to  communicate advanced component relationships directly and avoid having Far  rebuilding them redundantly.  include opensubdivfartopologyRefinerFactory.h include opensubdivfarprimvarRefiner.h include cstdio ------------------------------------------------------------------------------ using namespace OpenSubdiv  ------------------------------------------------------------------------------   For this tutorial, we provide the complete topological representation of a  simple pyramid. In our case, we store it as a simple sequence of integers,  with the understanding that client-code would provide a fully implemented  data-structure such as quad-edges or winged-edges.   Pyramid geometry from catmark_pyramid.h - extended for this tutorial  static int g_nverts  5 , g_nedges  8 , g_nfaces  5   vertex positions static float g_verts  5  3    0.0f , 0.0f , 2.0f ,  0.0f , -2.0f , 0.0f ,  2.0f , 0.0f , 0.0f ,  0.0f , 2.0f , 0.0f ,  -2.0f , 0.0f , 0.0f   number of vertices in each face static int g_facenverts  5    3 , 3 , 3 , 3 , 4   index of face vertices static int g_faceverts  16    0 , 1 , 2 , 0 , 2 , 3 , 0 , 3 , 4 , 0 , 4 , 1 , 4 , 3 , 2 , 1   index of edge vertices 2 per edge static int g_edgeverts  16    0 , 1 , 1 , 2 , 2 , 0 , 2 , 3 , 3 , 0 , 3 , 4 , 4 , 0 , 4 , 1   index of face edges static int g_faceedges  16    0 , 1 , 2 , 2 , 3 , 4 , 4 , 5 , 6 , 6 , 7 , 0 , 5 , 3 , 1 , 7   number of faces adjacent to each edge static int g_edgenfaces  8    2 , 2 , 2 , 2 , 2 , 2 , 2 , 2   index of faces incident to a given edge static int g_edgefaces  16    0 , 3 , 0 , 4 , 0 , 1 , 1 , 4 , 1 , 2 , 2 , 4 , 2 , 3 , 3 , 4   number of faces incident to each vertex static int g_vertexnfaces  5    4 , 3 , 3 , 3 , 3   index of faces incident to each vertex static int g_vertexfaces  25    0 , 1 , 2 , 3 , 0 , 3 , 4 , 0 , 4 , 1 , 1 , 4 , 2 , 2 , 4 , 3   number of edges incident to each vertex static int g_vertexnedges  5    4 , 3 , 3 , 3 , 3   index of edges incident to each vertex static int g_vertexedges  25    0 , 2 , 4 , 6 , 1 , 0 , 7 , 2 , 1 , 3 , 4 , 3 , 5 , 6 , 5 , 7   Edge crease sharpness static float g_edgeCreases  8    0.0f , 2.5f , 0.0f , 2.5f , 0.0f , 2.5f , 0.0f , 2.5f  ------------------------------------------------------------------------------   Because existing client-code may not provide an exact match for the  topological queries required by Fars interface, we can provide a converter  class. This can be particularly useful for instance if the client  data-structure requires additional relationships to be mapped. For instance,  half-edge representations do not store unique edge indices and it can be  difficult to traverse edges or faces adjacent to a given vertex.   Using an intermediate wrapper class allows us to leverage existing  relationships information from a mesh, and generate the missing components  temporarily.   For a practical example, you can look at the file hbr_to_vtr.h in the same  tutorial directory. This example implements a OsdHbrConverter class as a  way of interfacing PRmans half-edge representation to Far.  struct Converter  public  Sdc  SchemeType GetType  const  return Sdc  SCHEME_CATMARK   Sdc  Options GetOptions  const  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  return options   int GetNumFaces  const  return g_nfaces   int GetNumEdges  const  return g_nedges   int GetNumVertices  const  return g_nverts     Face relationships  int GetNumFaceVerts  int face  const  return g_facenverts  face   int const  GetFaceVerts  int face  const  return g_faceverts  getCompOffset  g_facenverts , face   int const  GetFaceEdges  int face  const  return g_faceedges  getCompOffset  g_facenverts , face     Edge relationships  int const  GetEdgeVertices  int edge  const  return g_edgeverts  edge  2   int GetNumEdgeFaces  int edge  const  return g_edgenfaces  edge   int const  GetEdgeFaces  int edge  const  return g_edgefaces  getCompOffset  g_edgenfaces , edge     Vertex relationships  int GetNumVertexEdges  int vert  const  return g_vertexnedges  vert   int const  GetVertexEdges  int vert  const  return g_vertexedges  getCompOffset  g_vertexnedges , vert   int GetNumVertexFaces  int vert  const  return g_vertexnfaces  vert   int const  GetVertexFaces  int vert  const  return g_vertexfaces  getCompOffset  g_vertexnfaces , vert   private  int getCompOffset  int const  comps , int comp  const  int ofs  0  for  int i  0  i  comp   i   ofs  comps  i   return ofs    ------------------------------------------------------------------------------ namespace OpenSubdiv  namespace OPENSUBDIV_VERSION  namespace Far  template  bool TopologyRefinerFactory  Converter  resizeComponentTopology  TopologyRefiner  refiner , Converter const  conv    Faces and face-verts int nfaces  conv . GetNumFaces  setNumBaseFaces  refiner , nfaces  for  int face  0  face  nfaces   face   int nv  conv . GetNumFaceVerts  face  setNumBaseFaceVertices  refiner , face , nv    Edges and edge-faces int nedges  conv . GetNumEdges  setNumBaseEdges  refiner , nedges  for  int edge  0  edge  nedges   edge   int nf  conv . GetNumEdgeFaces  edge  setNumBaseEdgeFaces  refiner , edge , nf    Vertices and vert-faces and vert-edges int nverts  conv . GetNumVertices  setNumBaseVertices  refiner , nverts  for  int vert  0  vert  nverts   vert   int ne  conv . GetNumVertexEdges  vert , nf  conv . GetNumVertexFaces  vert  setNumBaseVertexEdges  refiner , vert , ne  setNumBaseVertexFaces  refiner , vert , nf   return true   template  bool TopologyRefinerFactory  Converter  assignComponentTopology  TopologyRefiner  refiner , Converter const  conv   using Far  IndexArray    Face relations int nfaces  conv . GetNumFaces  for  int face  0  face  nfaces   face   IndexArray dstFaceVerts  getBaseFaceVertices  refiner , face  IndexArray dstFaceEdges  getBaseFaceEdges  refiner , face  int const  faceverts  conv . GetFaceVerts  face  int const  faceedges  conv . GetFaceEdges  face  for  int vert  0  vert  conv . GetNumFaceVerts  face   vert   dstFaceVerts  vert   faceverts  vert  dstFaceEdges  vert   faceedges  vert       Edge relations   Note if your representation is unable to provide edge relationships  ex half-edges, you can comment out this section and Far will  automatically generate the missing information.  int nedges  conv . GetNumEdges  for  int edge  0  edge  nedges   edge    Edge-vertices IndexArray dstEdgeVerts  getBaseEdgeVertices  refiner , edge  dstEdgeVerts  0   conv . GetEdgeVertices  edge  0  dstEdgeVerts  1   conv . GetEdgeVertices  edge  1   Edge-faces IndexArray dstEdgeFaces  getBaseEdgeFaces  refiner , edge  for  int face  0  face  conv . GetNumEdgeFaces  face   face   dstEdgeFaces  face   conv . GetEdgeFaces  edge  face       Vertex relations int nverts  conv . GetNumVertices  for  int vert  0  vert  nverts   vert    Vert-Faces IndexArray vertFaces  getBaseVertexFaces  refiner , vert  LocalIndexArray vertInFaceIndices  getBaseVertexFaceLocalIndicesrefiner, vert for  int face  0  face  conv . GetNumVertexFaces  vert   face   vertFaces  face   conv . GetVertexFaces  vert  face    Vert-Edges IndexArray vertEdges  getBaseVertexEdges  refiner , vert  LocalIndexArray vertInEdgeIndices  getBaseVertexEdgeLocalIndicesrefiner, vert for  int edge  0  edge  conv . GetNumVertexEdges  vert   edge   vertEdges  edge   conv . GetVertexEdges  vert  edge     populateBaseLocalIndices  refiner  return true   template  bool TopologyRefinerFactory  Converter  assignComponentTags  TopologyRefiner  refiner , Converter const  conv    arbitrarily sharpen the 4 bottom edges of the pyramid to 2.5f for  int edge  0  edge  conv . GetNumEdges   edge   setBaseEdgeSharpness  refiner , edge , g_edgeCreases  edge   return true   ifdef _MSC_VER template  void TopologyRefinerFactory  Converter  reportInvalidTopology  TopologyError  errCode  , char const  msg , Converter const   mesh      Optional topology validation error reporting  This method is called whenever the factory encounters topology validation  errors. By default, nothing is reported  Warning  msg   template  bool TopologyRefinerFactory  Converter  assignFaceVaryingTopology  TopologyRefiner   refiner  , Converter const   conv     Because of the way MSVC specializes templated functions, we had to  remove the default stubs in FarTopologyRefinerFactory. In this  example, no face-varying data is being added, but we still need to  implement a template specialization or MSVC linker fails. return true   endif   namespace Far   namespace OPENSUBDIV_VERSION   namespace OpenSubdiv ------------------------------------------------------------------------------   Vertex container implementation.  struct Vertex   Minimal required interface ---------------------- Vertex    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0   _position  0   _position  1   _position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _position  0   weight  src . _position  0  _position  1   weight  src . _position  1  _position  2   weight  src . _position  2    Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   const float  GetPosition  const  return _position   private  float _position  3   ------------------------------------------------------------------------------ int main  int , char    Converter conv  Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Converter  Create  conv , Far  TopologyRefinerFactory  Converter  Options  conv . GetType , conv . GetOptions  int maxlevel  5   Uniformly refine the topology up to maxlevel refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel   Allocate a buffer for vertex primvar data. The buffer length is set to  be the sum of all children vertices up to the highest level of refinement. std  vector  Vertex  vbuffer  refiner - GetNumVerticesTotal  Vertex  verts   vbuffer  0   Initialize coarse mesh positions int nCoarseVerts  g_nverts  for  int i  0  i  nCoarseVerts   i   verts  i . SetPosition  g_verts  i  0 , g_verts  i  1 , g_verts  i  2    Interpolate vertex primvar data Far  PrimvarRefiner primvarRefiner   refiner  Vertex  src  verts  for  int level  1  level  maxlevel   level   Vertex  dst  src  refiner - GetLevel  level -1 . GetNumVertices  primvarRefiner . Interpolate  level , src , dst  src  dst     Output OBJ of the highest level refined ----------- Far  TopologyLevel const  refLastLevel  refiner - GetLevel  maxlevel  int nverts  refLastLevel . GetNumVertices  int nfaces  refLastLevel . GetNumFaces   Print vertex positions int firstOfLastVerts  refiner - GetNumVerticesTotal  - nverts  for  int vert  0  vert  nverts   vert   float const  pos  verts  firstOfLastVerts  vert . GetPosition  printf  v f f f n  , pos  0 , pos  1 , pos  2    Print faces for  int face  0  face  nfaces   face   Far  ConstIndexArray fverts  refLastLevel . GetFaceVertices  face   all refined Catmark faces should be quads assert  fverts . size   4  printf  f   for  int vert  0  vert  fverts . size   vert   printf  d  , fverts  vert   1   OBJ uses 1-based arrays...  printf   n     delete refiner  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_3_1.html"}, 
{"title":"far_tutorial_4_3.cpp", "text":"far_tutorial_4_3.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_4_3.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_4_3.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_4_3far_tutorial_4_3.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to create and manipulate table of cascading stencils.   We initialize a FarTopologyRefiner with a cube and apply uniform  refinement. We then use a FarStencilTableFactory to generate a stencil  table. We set the factory Options to not factorize intermediate levels,  thus giving a table of cascading stencils.   We then apply the stencils to the vertex position primvar data, and insert  a hierarchical edit at level 1. This edit is smoothed by the application  of the subsequent stencil cascades.   The results are dumped into an OBJ file that shows the intermediate levels  of refinement of the original cube.  include opensubdivfartopologyDescriptor.h include opensubdivfarstencilTable.h include opensubdivfarstencilTableFactory.h include cstdio include cstring ------------------------------------------------------------------------------  Vertex container implementation.  struct Vertex   Minimal required interface ---------------------- Vertex    Vertex  Vertex const  src   _position  0   src . _position  0  _position  1   src . _position  1  _position  2   src . _position  2   void Clear  void   0   _position  0   _position  1   _position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   _position  0   weight  src . _position  0  _position  1   weight  src . _position  1  _position  2   weight  src . _position  2    Public interface ------------------------------------ void SetPosition  float x , float y , float z   _position  0   x  _position  1   y  _position  2   z   float const  GetPosition  const  return _position   float  GetPosition   return _position   private  float _position  3   ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h static float g_verts  24    -0.5f , -0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , 0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , -0.5f , -0.5f , -0.5f , -0.5f , 0.5f , -0.5f , -0.5f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4  using namespace OpenSubdiv  static Far  TopologyRefiner  createTopologyRefiner  ------------------------------------------------------------------------------ int main  int , char     Generate a FarTopologyRefiner see tutorial_1_1 for details. Far  TopologyRefiner  refiner  createTopologyRefiner   Uniformly refine the topology up to maxlevel. int maxlevel  4  refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel   Use the FarStencilTable factory to create cascading stencil table  note we want stencils for each refinement level  cascade mode is achieved by setting factorizeIntermediateLevels  to false Far  StencilTableFactory  Options options  options . generateIntermediateLevels  true  options . factorizeIntermediateLevels  false  options . generateOffsets  true  Far  StencilTable const  stencilTable  Far  StencilTableFactory  Create   refiner , options  std  vector  Vertex  vertexBuffer  refiner - GetNumVerticesTotal  - g_nverts  Vertex  destVerts   vertexBuffer  0  int start  0 , end  0   stencil batches for each level of subdivision for  int level  0  level  maxlevel   level   int nverts  refiner - GetLevel  level  1 . GetNumVertices  Vertex const  srcVerts  reinterpret_cast  Vertex   g_verts  if  level  0   srcVerts   vertexBuffer  start   start  end  end  nverts  stencilTable - UpdateValues  srcVerts , destVerts , start , end   apply 2 hierarchical edits on level 1 vertices if  level  1   float  pos  destVerts  start  5 . GetPosition  pos  1   0.5f  pos  destVerts  start  20 . GetPosition  pos  0   0.25f      Output OBJ of the highest level refined ----------- Vertex  verts   vertexBuffer  0   Print vertex positions for  int level  1 , firstvert  0  level  maxlevel   level   Far  TopologyLevel const  refLevel  refiner - GetLevel  level  printf  g level_d n  , level  int nverts  refLevel . GetNumVertices  for  int vert  0  vert  nverts   vert   float const  pos  verts  vert . GetPosition  printf  v f f f n  , pos  0 , pos  1 , pos  2   verts  nverts   Print faces for  int face  0  face  refLevel . GetNumFaces   face   Far  ConstIndexArray fverts  refLevel . GetFaceVertices  face   all refined Catmark faces should be quads assert  fverts . size   4  printf  f   for  int vert  0  vert  fverts . size   vert   printf  d  , fverts  vert   firstvert  1   OBJ uses 1-based arrays...  printf   n    firstvert  nverts    delete refiner  delete stencilTable  return EXIT_SUCCESS   ------------------------------------------------------------------------------ static Far  TopologyRefiner  createTopologyRefiner    Populate a topology descriptor with our raw data. typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor. return Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_4_3.html"}, 
{"title":"far_tutorial_2_3.cpp", "text":"far_tutorial_2_3.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_2_3.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_2_3.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_2_3far_tutorial_2_3.cpp ------------------------------------------------------------------------------  Tutorial description   NOTE The following approaches are approximations to compute smooth normals,  for highest fidelity patches should be used for positions and normals,  which form the true limit surface.   Building on tutorial 3, this example shows how to instantiate a simple mesh,  refine it uniformly, interpolate both vertex and face-varying  primvar data, and finally calculate approximated smooth normals.  The resulting interpolated data is output in obj format.   Currently, this tutorial supports 3 methods to approximate smooth normals   CrossTriangle  Calculates smooth normals accumulating per vertex using  3 verts to generate 2 vectors. This approximation has  trouble when working with quads which can be non-planar  since it only takes into account half of each face.   CrossQuad  Calculates smooth normals accumulating per vertex  but this time, instead of taking into account only 3 verts  it creates 2 vectors crossing the quad.  This approximation builds upon CrossTriangle but takes  into account the 4 verts of the face.   Limit  Calculates the normals at the limit for each vert  at the last level of subdivision.  These are the true limit normals, however, in this example  they are used with verts that are not at the limit.  This can lead to new visual artifacts since the normals  and the positions dont match. Additionally, this approach  requires extra computation to calculate the limit normals.  For this reason, we strongly suggest using  limit positions with limit normals.  include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include cstdio ------------------------------------------------------------------------------  Math helpers.    Returns the normalized version of the input vector inline void normalize  float  n   float rn  1.0f  sqrtf  n  0   n  0   n  1   n  1   n  2   n  2  n  0   rn  n  1   rn  n  2   rn    Returns the cross product of p v1 and p v2. void cross  float const  v1 , float const  v2 , float  vOut   vOut  0   v1  1   v2  2  - v1  2   v2  1  vOut  1   v1  2   v2  0  - v1  0   v2  2  vOut  2   v1  0   v2  1  - v1  1   v2  0   ------------------------------------------------------------------------------  Face-varying implementation.   struct Vertex   Minimal required interface ---------------------- Vertex   Clear   Vertex  Vertex const  src   position  0   src . position  0  position  1   src . position  1  position  2   src . position  2   void Clear   position  0   position  1   position  2   0.0f   void AddWithWeight  Vertex const  src , float weight   position  0   weight  src . position  0  position  1   weight  src . position  1  position  2   weight  src . position  2    Public interface ------------------------------------ void SetPosition  float x , float y , float z   position  0   x  position  1   y  position  2   z   const float  GetPosition  const  return position   float position  3   ------------------------------------------------------------------------------  Face-varying container implementation.   We are using a uv texture layout as a face-varying primtiive variable  attribute. Because face-varying data is specified per-face-per-vertex,  we cannot use the same container that we use for vertex or varying  data. We specify a new container, which only carries u,v coordinates.  Similarly to our Vertex container, we add a minimaliztic interpolation  interface with a Clear and AddWithWeight methods.  struct FVarVertexUV   Minimal required interface ---------------------- void Clear   u  v  0.0f   void AddWithWeight  FVarVertexUV const  src , float weight   u  weight  src . u  v  weight  src . v    Basic uv layout channel float u , v   struct FVarVertexColor   Minimal required interface ---------------------- void Clear   r  g  b  a  0.0f   void AddWithWeight  FVarVertexColor const  src , float weight   r  weight  src . r  g  weight  src . g  b  weight  src . b  a  weight  src . a    Basic color layout channel float r , g , b , a   ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h  vertex primitive variable data  topology static float g_verts  8  3    -0.5f , -0.5f , 0.5f ,  0.5f , -0.5f , 0.5f ,  -0.5f , 0.5f , 0.5f ,  0.5f , 0.5f , 0.5f ,  -0.5f , 0.5f , -0.5f ,  0.5f , 0.5f , -0.5f ,  -0.5f , -0.5f , -0.5f ,  0.5f , -0.5f , -0.5f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4   face-varying primitive variable data  topology for UVs static float g_uvs  14  2    0.375 , 0.00 ,  0.625 , 0.00 ,  0.375 , 0.25 ,  0.625 , 0.25 ,  0.375 , 0.50 ,  0.625 , 0.50 ,  0.375 , 0.75 ,  0.625 , 0.75 ,  0.375 , 1.00 ,  0.625 , 1.00 ,  0.875 , 0.00 ,  0.875 , 0.25 ,  0.125 , 0.00 ,  0.125 , 0.25  static int g_nuvs  14  static int g_uvIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 9 , 8 , 1 , 10 , 11 , 3 , 12 , 0 , 2 , 13   face-varying primitive variable data  topology for color static float g_colors  24  4    1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 0.0 , 0.0 , 1.0 ,  1.0 , 0.0 , 0.0 , 1.0 ,  1.0 , 0.0 , 0.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0 ,  1.0 , 1.0 , 1.0 , 1.0  static int g_ncolors  24  static int g_colorIndices  24    0 , 3 , 9 , 6 , 7 , 10 , 15 , 12 , 13 , 16 , 21 , 18 , 19 , 22 , 4 , 1 , 5 , 23 , 17 , 11 , 20 , 2 , 8 , 14  using namespace OpenSubdiv   Approximation methods for smooth normal computations enum NormalApproximation  CrossTriangle , CrossQuad , Limit  ------------------------------------------------------------------------------ int main  int argc , char  argv   const int maxlevel  2  enum NormalApproximation normalApproximation  CrossTriangle   Parsing command line parameters to see if the user wants to use a  specific method to calculate normals for  int i  1  i  argc   i   if  strstr  argv  i , -limit   normalApproximation  Limit   else if   strcmp  argv  i , -crossquad   normalApproximation  CrossQuad   else if   strcmp  argv  i , -crosstriangle   normalApproximation  CrossTriangle   else  printf  Parameters  n   printf   -crosstriangle  use the cross product of vectors n   printf   generated from 3 verts default. n   printf   -crossquad  use the cross product of vectors n   printf   generated from 4 verts. n   printf   -limit  use normals calculated from the limit. n   return 0    typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  options . SetFVarLinearInterpolation  Sdc  Options  FVAR_LINEAR_NONE   Populate a topology descriptor with our raw data Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Create a face-varying channel descriptor const int numChannels  2  const int channelUV  0  const int channelColor  1  Descriptor  FVarChannel channels  numChannels  channels  channelUV . numValues  g_nuvs  channels  channelUV . valueIndices  g_uvIndices  channels  channelColor . numValues  g_ncolors  channels  channelColor . valueIndices  g_colorIndices   Add the channel topology to the main descriptor desc . numFVarChannels  numChannels  desc . fvarChannels  channels   Instantiate a FarTopologyRefiner from the descriptor Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options   Uniformly refine the topolgy up to maxlevel  note fullTopologyInLastLevel must be true to work with face-varying data  Far  TopologyRefiner  UniformOptions refineOptions  maxlevel  refineOptions . fullTopologyInLastLevel  true  refiner - RefineUniform  refineOptions    Allocate and initialize the vertex primvar data see tutorial 2 for  more details. std  vector  Vertex  vbuffer  refiner - GetNumVerticesTotal  Vertex  verts   vbuffer  0  for  int i  0  i  g_nverts   i   verts  i . SetPosition  g_verts  i  0 , g_verts  i  1 , g_verts  i  2    Allocate  initialize the first channel of face-varying primvars UVs std  vector  FVarVertexUV  fvBufferUV  refiner - GetNumFVarValuesTotal  channelUV  FVarVertexUV  fvVertsUV   fvBufferUV  0  for  int i  0  i  g_nuvs   i   fvVertsUV  i . u  g_uvs  i  0  fvVertsUV  i . v  g_uvs  i  1    Allocate  interpolate the face-varying primvar data colors std  vector  FVarVertexColor  fvBufferColor  refiner - GetNumFVarValuesTotal  channelColor  FVarVertexColor  fvVertsColor   fvBufferColor  0  for  int i  0  i  g_ncolors   i   fvVertsColor  i . r  g_colors  i  0  fvVertsColor  i . g  g_colors  i  1  fvVertsColor  i . b  g_colors  i  2  fvVertsColor  i . a  g_colors  i  3    Interpolate both vertex and face-varying primvar data Far  PrimvarRefiner primvarRefiner   refiner  Vertex  srcVert  verts  FVarVertexUV  srcFVarUV  fvVertsUV  FVarVertexColor  srcFVarColor  fvVertsColor  for  int level  1  level  maxlevel   level   Vertex  dstVert  srcVert  refiner - GetLevel  level -1 . GetNumVertices  FVarVertexUV  dstFVarUV  srcFVarUV  refiner - GetLevel  level -1 . GetNumFVarValues  channelUV  FVarVertexColor  dstFVarColor  srcFVarColor  refiner - GetLevel  level -1 . GetNumFVarValues  channelColor  primvarRefiner . Interpolate  level , srcVert , dstVert  primvarRefiner . InterpolateFaceVarying  level , srcFVarUV , dstFVarUV , channelUV  primvarRefiner . InterpolateFaceVarying  level , srcFVarColor , dstFVarColor , channelColor  srcVert  dstVert  srcFVarUV  dstFVarUV  srcFVarColor  dstFVarColor    Approximate normals Far  TopologyLevel const  refLastLevel  refiner - GetLevel  maxlevel  int nverts  refLastLevel . GetNumVertices  int nfaces  refLastLevel . GetNumFaces  int firstOfLastVerts  refiner - GetNumVerticesTotal  - nverts  std  vector  Vertex  normals  nverts   Different ways to approximate smooth normals   For details check the description at the beginning of the file if  normalApproximation  Limit    Approximation using the normal at the limit with verts that are  not at the limit   For details check the description at the beginning of the file std  vector  Vertex  fineLimitPos  nverts  std  vector  Vertex  fineDu  nverts  std  vector  Vertex  fineDv  nverts  primvarRefiner . Limit   verts  firstOfLastVerts , fineLimitPos , fineDu , fineDv  for  int vert  0  vert  nverts   vert   float const  du  fineDu  vert . GetPosition  float const  dv  fineDv  vert . GetPosition  float norm  3  cross  du , dv , norm  normals  vert . SetPosition  norm  0 , norm  1 , norm  2    else if  normalApproximation  CrossQuad    Approximate smooth normals by accumulating normal vectors computed as  the cross product of two vectors generated by the 4 verts that  form each quad   For details check the description at the beginning of the file for  int f  0  f  nfaces  f    Far  ConstIndexArray faceVertices  refLastLevel . GetFaceVertices  f   We will use the first three verts to calculate a normal const float  v0  verts  firstOfLastVerts  faceVertices  0  . GetPosition  const float  v1  verts  firstOfLastVerts  faceVertices  1  . GetPosition  const float  v2  verts  firstOfLastVerts  faceVertices  2  . GetPosition  const float  v3  verts  firstOfLastVerts  faceVertices  3  . GetPosition   Calculate the cross product between the vectors formed by v1-v0 and  v2-v0, and then normalize the result float normalCalculated    0.0 , 0.0 , 0.0  float a  3    v2  0  - v0  0 , v2  1  - v0  1 , v2  2  - v0  2   float b  3    v3  0  - v1  0 , v3  1  - v1  1 , v3  2  - v1  2   cross  a , b , normalCalculated  normalize  normalCalculated   Accumulate that normal on all verts that are part of that face for  int vInFace  0  vInFace  faceVertices . size   vInFace    int vertexIndex  faceVertices  vInFace  normals  vertexIndex . position  0   normalCalculated  0  normals  vertexIndex . position  1   normalCalculated  1  normals  vertexIndex . position  2   normalCalculated  2     else if  normalApproximation  CrossTriangle    Approximate smooth normals by accumulating normal vectors computed as  the cross product of two vectors generated by 3 verts of the quad   For details check the description at the beginning of the file for  int f  0  f  nfaces  f    Far  ConstIndexArray faceVertices  refLastLevel . GetFaceVertices  f   We will use the first three verts to calculate a normal const float  v0  verts  firstOfLastVerts  faceVertices  0  . GetPosition  const float  v1  verts  firstOfLastVerts  faceVertices  1  . GetPosition  const float  v2  verts  firstOfLastVerts  faceVertices  2  . GetPosition   Calculate the cross product between the vectors formed by v1-v0 and  v2-v0, and then normalize the result float normalCalculated    0.0 , 0.0 , 0.0  float a  3    v1  0  - v0  0 , v1  1  - v0  1 , v1  2  - v0  2   float b  3    v2  0  - v0  0 , v2  1  - v0  1 , v2  2  - v0  2   cross  a , b , normalCalculated  normalize  normalCalculated   Accumulate that normal on all verts that are part of that face for  int vInFace  0  vInFace  faceVertices . size   vInFace    int vertexIndex  faceVertices  vInFace  normals  vertexIndex . position  0   normalCalculated  0  normals  vertexIndex . position  1   normalCalculated  1  normals  vertexIndex . position  2   normalCalculated  2      Finally we just need to normalize the accumulated normals for  int vert  0  vert  nverts   vert   normalize   normals  vert . position  0     Output OBJ of the highest level refined -----------  Print vertex positions for  int vert  0  vert  nverts   vert   float const  pos  verts  firstOfLastVerts  vert . GetPosition  printf  v f f f n  , pos  0 , pos  1 , pos  2    Print vertex normals for  int vert  0  vert  nverts   vert   float const  pos  normals  vert . GetPosition  printf  vn f f f n  , pos  0 , pos  1 , pos  2    Print uvs int nuvs  refLastLevel . GetNumFVarValues  channelUV  int firstOfLastUvs  refiner - GetNumFVarValuesTotal  channelUV  - nuvs  for  int fvvert  0  fvvert  nuvs   fvvert   FVarVertexUV const  uv  fvVertsUV  firstOfLastUvs  fvvert  printf  vt f f n  , uv . u , uv . v    Print faces for  int face  0  face  nfaces   face   Far  ConstIndexArray fverts  refLastLevel . GetFaceVertices  face  Far  ConstIndexArray fuvs  refLastLevel . GetFaceFVarValues  face , channelUV   all refined Catmark faces should be quads assert  fverts . size   4  fuvs . size   4  printf  f   for  int vert  0  vert  fverts . size   vert    OBJ uses 1-based arrays... printf  ddd  , fverts  vert   1 , fuvs  vert   1 , fverts  vert   1   printf   n     delete refiner  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_2_3.html"}, 
{"title":"far_tutorial_5_1.cpp", "text":"far_tutorial_5_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_5_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_5_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_5_1far_tutorial_5_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to interpolate surface limits at arbitrary  parametric locations using feature adaptive FarPatchTables.   The evaluation of the limit surface at arbitrary locations requires the  adaptive isolation of topological features. This process converts the  input polygonal control cage into a collection of bi-cubic patches.   We can then evaluate the patches at random parametric locations and  obtain analytical positions and tangents on the limit surface.   The results are dumped into a MEL script that draws streak particle  systems that show the tangent and bi-tangent at the random samples locations.  include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include opensubdivfarpatchTableFactory.h include opensubdivfarpatchMap.h include opensubdivfarptexIndices.h include cassert include cstdio include cstring include cfloat using namespace OpenSubdiv  typedef double Real   pyramid geometry from catmark_pyramid_crease0.h static int const g_nverts  5  static Real const g_verts  24    0.0f , 0.0f , 2.0f , 0.0f , -2.0f , 0.0f , 2.0f , 0.0f , 0.0f , 0.0f , 2.0f , 0.0f , -2.0f , 0.0f , 0.0f ,  static int const g_vertsperface  5    3 , 3 , 3 , 3 , 4  static int const g_nfaces  5  static int const g_faceverts  16    0 , 1 , 2 , 0 , 2 , 3 , 0 , 3 , 4 , 0 , 4 , 1 , 4 , 3 , 2 , 1  static int const g_ncreases  4  static int const g_creaseverts  8    4 , 3 , 3 , 2 , 2 , 1 , 1 , 4  static float const g_creaseweights  4    3.0f , 3.0f , 3.0f , 3.0f   Creates a FarTopologyRefiner from the pyramid shape above static Far  TopologyRefiner  createTopologyRefiner  ------------------------------------------------------------------------------  Vertex container implementation.  struct Vertex   Minimal required interface ---------------------- Vertex    void Clear  void   0   point  0   point  1   point  2   0.0f   void AddWithWeight  Vertex const  src , Real weight   point  0   weight  src . point  0  point  1   weight  src . point  1  point  2   weight  src . point  2   Real point  3   ------------------------------------------------------------------------------  Limit frame container implementation -- this interface is not strictly  required but follows a similar pattern to Vertex.  struct LimitFrame  void Clear  void   0   point  0   point  1   point  2   0.0f  deriv1  0   deriv1  1   deriv1  2   0.0f  deriv2  0   deriv2  1   deriv2  2   0.0f   void AddWithWeight  Vertex const  src , Real weight , Real d1Weight , Real d2Weight   point  0   weight  src . point  0  point  1   weight  src . point  1  point  2   weight  src . point  2  deriv1  0   d1Weight  src . point  0  deriv1  1   d1Weight  src . point  1  deriv1  2   d1Weight  src . point  2  deriv2  0   d2Weight  src . point  0  deriv2  1   d2Weight  src . point  1  deriv2  2   d2Weight  src . point  2   Real point  3 , deriv1  3 , deriv2  3   ------------------------------------------------------------------------------ int main  int , char     Generate a FarTopologyRefiner see tutorial_1_1 for details. Far  TopologyRefiner  refiner  createTopologyRefiner   Patches are constructed from adaptively refined faces, but the processes  of constructing the PatchTable and of applying adaptive refinement have  historically been separate. Adaptive refinement is applied purely to  satisfy the needs of the desired PatchTable, so options associated with  adaptive refinement should be derived from those specified for the  PatchTable. This is not a strict requirement, but it will avoid  problems arising from specifyingcoordinating the two independently  especially when dealing with face-varying patches.  Initialize options for the PatchTable   Choose patches adaptively refined to level 3 since the sharpest crease  in the shape is 3.0f in g_creaseweights, and include the inf-sharp  crease option just to illustrate the need to syncronize options.  int maxPatchLevel  3  Far  PatchTableFactory  Options patchOptions  maxPatchLevel  patchOptions . SetPatchPrecision  Real   patchOptions . useInfSharpPatch  true  patchOptions . generateVaryingTables  false  patchOptions . endCapType  Far  PatchTableFactory  Options  ENDCAP_GREGORY_BASIS   Initialize corresonding options for adaptive refinement Far  TopologyRefiner  AdaptiveOptions adaptiveOptions  maxPatchLevel  bool assignAdaptiveOptionsExplicitly  false  if  assignAdaptiveOptionsExplicitly   adaptiveOptions . useInfSharpPatch  true   else   Be sure patch options were intialized with the desired max level adaptiveOptions  patchOptions . GetRefineAdaptiveOptions   assert  adaptiveOptions . useInfSharpPatch  patchOptions . useInfSharpPatch   Apply adaptive refinement and construct the associated PatchTable to  evaluate the limit surface refiner - RefineAdaptive  adaptiveOptions  Far  PatchTable const  patchTable  Far  PatchTableFactory  Create   refiner , patchOptions   Compute the total number of points we need to evaluate the PatchTable.  Approximations at irregular or extraordinary features require the use  of additional points associated with the patches that are referred to  as local points i.e. local to the PatchTable. int nRefinerVertices  refiner - GetNumVerticesTotal  int nLocalPoints  patchTable - GetNumLocalPoints   Create a buffer to hold the position of the refined verts and  local points, then copy the coarse positions at the beginning. std  vector  Vertex  verts  nRefinerVertices  nLocalPoints  std  memcpy   verts  0 , g_verts , g_nverts  3  sizeof  Real   Adaptive refinement may result in fewer levels than the max specified. int nRefinedLevels  refiner - GetNumLevels   Interpolate vertex primvar data  they are the control vertices  of the limit patches see tutorial_1_1 for details Far  PrimvarRefinerReal  Real  primvarRefiner   refiner  Vertex  src   verts  0  for  int level  1  level  nRefinedLevels   level   Vertex  dst  src  refiner - GetLevel  level -1 . GetNumVertices  primvarRefiner . Interpolate  level , src , dst  src  dst    Evaluate local points from interpolated vertex primvars. if  nLocalPoints   patchTable - GetLocalPointStencilTable  Real   - UpdateValues   verts  0 ,  verts  nRefinerVertices    Create a FarPatchMap to help locating patches in the table Far  PatchMap patchmap   patchTable   Create a FarPtexIndices to help find indices of ptex faces. Far  PtexIndices ptexIndices   refiner   Generate random samples on each ptex face int nsamplesPerFace  200 , nfaces  ptexIndices . GetNumFaces  std  vector  LimitFrame  samples  nsamplesPerFace  nfaces  srand  static_cast  int   2147483647   Real pWeights  20 , dsWeights  20 , dtWeights  20  for  int face  0 , count  0  face  nfaces   face   for  int sample  0  sample  nsamplesPerFace   sample ,  count   Real s   Real  rand    Real  RAND_MAX , t   Real  rand    Real  RAND_MAX   Locate the patch corresponding to the face ptex idx and s,t Far  PatchTable  PatchHandle const  handle  patchmap . FindPatch  face , s , t  assert  handle   Evaluate the patch weights, identify the CVs and compute the limit frame patchTable - EvaluateBasis   handle , s , t , pWeights , dsWeights , dtWeights  Far  ConstIndexArray cvs  patchTable - GetPatchVertices   handle  LimitFrame  dst  samples  count  dst . Clear  for  int cv  0  cv  cvs . size   cv   dst . AddWithWeight  verts  cvs  cv , pWeights  cv , dsWeights  cv , dtWeights  cv       Visualization with Maya  print a MEL script that generates particles  at the location of the limit vertices int nsamples   int  samples . size  printf  file -f -new n    Output particle positions for the tangent printf  particle -n deriv1   for  int sample  0  sample  nsamples   sample   Real const  pos  samples  sample . point  printf  -p f f f n  , pos  0 , pos  1 , pos  2   printf   n    Set per-particle direction using the limit tangent display as Streak printf  setAttr  deriv1.particleRenderType  6 n   printf  setAttr  deriv1.velocity  -type  vectorArray  d  , nsamples  for  int sample  0  sample  nsamples   sample   Real const  tan1  samples  sample . deriv1  printf  f f f n  , tan1  0 , tan1  1 , tan1  2   printf   n    Output particle positions for the bi-tangent printf  particle -n deriv2   for  int sample  0  sample  nsamples   sample   Real const  pos  samples  sample . point  printf  -p f f f n  , pos  0 , pos  1 , pos  2   printf   n   printf  setAttr  deriv2.particleRenderType  6 n   printf  setAttr  deriv2.velocity  -type  vectorArray  d  , nsamples  for  int sample  0  sample  nsamples   sample   Real const  tan2  samples  sample . deriv2  printf  f f f n  , tan2  0 , tan2  1 , tan2  2   printf   n    Exercise to the reader  cross tangent  bi-tangent for limit  surface normal...  Force Maya DAG update to see the result in the viewport printf  currentTime -edit currentTime -q n   printf  select deriv1Shape deriv2Shape n    delete refiner  delete patchTable  return EXIT_SUCCESS   ------------------------------------------------------------------------------ static Far  TopologyRefiner  createTopologyRefiner   typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_faceverts  desc . numCreases  g_ncreases  desc . creaseVertexIndexPairs  g_creaseverts  desc . creaseWeights  g_creaseweights   Instantiate a FarTopologyRefiner from the descriptor. Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  return refiner   Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_5_1.html"}, 
{"title":"bfr_tutorial_1_1.cpp", "text":"bfr_tutorial_1_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_1_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_1_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_1_1bfr_tutorial_1_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial illustrates the use of the SurfaceFactory, Surface  and Parameterization classes for creating and evaluating the limit  surface associated with each base face of a mesh.   Following the creation of a connected mesh for a shape using a  FarTopologyRefiner, as illustrated in Far tutorials, an instance  of a SurfaceFactory is declared to process its faces. Each face of  the mesh is evaluated and tessellated independently with a simple  triangle fan, with results written out in Obj format for inspection.   These classes make it simple to evaluate and tessellate all faces  quads, tris or others while supporting the full set of subdivision  options. While a triangle fan may be a trivial tessellation and so  not very useful later examples using the Tessellation class provide  more useful results with the same simplicity.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include vector include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing though  none are used in this simple case  SurfaceFactory  Options surfaceOptions  SurfaceFactory meshSurfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface faceSurface  std  vector  float  facePatchPoints  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  int  outTriangles    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  meshSurfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surface for this face -- if valid skipping  holes and boundary faces in some rare cases  if   meshSurfaceFactory . InitVertexSurface  faceIndex ,  faceSurface   continue     Get the Parameterization of the Surface and use it to identify  coordinates for evaluation -- in this case, at the vertices  and center of the face to create a fan of triangles  Bfr  Parameterization faceParam  faceSurface . GetParameterization  int faceSize  faceParam . GetFaceSize  int numOutCoords  faceSize  1  outCoords . resize  numOutCoords  2  for  int i  0  i  faceSize   i   faceParam . GetVertexCoord  i ,  outCoords  i  2   faceParam . GetCenterCoord   outCoords  faceSize  2    Prepare the patch points for the Surface, then use them to  evaluate output points for all identified coordinates   Resize patch point and output arrays int pointSize  3  facePatchPoints . resize  faceSurface . GetNumPatchPoints   pointSize  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize   Populate patch point and output arrays faceSurface . PreparePatchPoints  meshVertexPositions . data , pointSize , facePatchPoints . data , pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   faceSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outPos  j ,  outDu  j ,  outDv  j     Identify the faces of the tessellation, i.e. the triangle fan  connecting points at the vertices to the center last point   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face.  int objVertexIndexOffset  objWriter . GetNumVertices  outTriangles . resize  faceSize  3  int  outTriangle  outTriangles . data  for  int i  0  i  faceSize   i , outTriangle  3   outTriangle  0   objVertexIndexOffset  i  outTriangle  1   objVertexIndexOffset   i  1   faceSize  outTriangle  2   objVertexIndexOffset  faceSize     Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  objWriter . WriteFaces  outTriangles , 3 , true , false      Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_1_1.html"}, 
{"title":"bfr_tutorial_1_2.cpp", "text":"bfr_tutorial_1_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_1_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_1_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_1_2bfr_tutorial_1_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial builds on the previous tutorial that makes use of the  SurfaceFactory and Surface for evaluating the limit surface of faces  by using the Tessellation class to determine the points to evaluate  and the faces that connect them.   The Tessellation class replaces the explicit determination of points  and faces for the triangle fan of the previous example. Given a  uniform tessellation rate via a command line option, Tessellation  returns the set of coordinates to evaluate, and separately returns  the faces that connect them.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing though  none are used in this simple case  SurfaceFactory  Options surfaceOptions  SurfaceFactory meshSurfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface faceSurface  std  vector  float  facePatchPoints  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  meshSurfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surface for this face -- if valid skipping  holes and boundary faces in some rare cases  if   meshSurfaceFactory . InitVertexSurface  faceIndex ,  faceSurface   continue     Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  faceSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Prepare the patch points for the Surface, then use them to  evaluate output points for all identified coordinates   Resize patch point and output arrays int pointSize  3  facePatchPoints . resize  faceSurface . GetNumPatchPoints   pointSize  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize   Populate patch point and output arrays faceSurface . PreparePatchPoints  meshVertexPositions . data , pointSize , facePatchPoints . data , pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   faceSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outPos  j ,  outDu  j ,  outDv  j     Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  objWriter . WriteFaces  outFacets , tessFacetSize , true , false      Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_1_2.html"}, 
{"title":"far_tutorial_5_3.cpp", "text":"far_tutorial_5_3.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_5_3.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_5_3.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_5_3far_tutorial_5_3.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to use a FarLimitStenciTable to repeatedly  and efficiently evaluate a set of points and optionally derivatives  on the limit surface.   A LimitStencilTable derives from StencilTable but is specialized to  factor the evaluation of limit positions and derivatives into stencils.  This allows a set of limit properties to be efficiently recomputed in  response to changes to the vertices of the base mesh. Constructing  the different kinds of StencilTables can have a high cost, so whether  that cost is worth it will depend on your usage e.g. if points are  only computed once, using stencil tables is typically not worth the  added cost.   Any points on the limit surface can be identified for evaluation. In  this example we create a crude tessellation similar to tutorial_5_2.  The midpoint of each face and points near the corners of the face are  evaluated and a triangle fan connects them.  include ......regressioncommonarg_utils.h include ......regressioncommonfar_utils.h include opensubdivfartopologyDescriptor.h include opensubdivfarpatchTableFactory.h include opensubdivfarstencilTableFactory.h include opensubdivfarptexIndices.h include cassert include cstdio include cstring include fstream include sstream using namespace OpenSubdiv  using Far  Index    Global utilities in this namespace are not relevant to the tutorial.  They simply serve to construct some default geometry to be processed  in the form of a TopologyRefiner and vector of vertex positions.  namespace    Simple structs for x,y,z position and a 3-tuple for the set  of vertices of a triangle  struct Pos  Pos    Pos  float x , float y , float z   p  0   x , p  1   y , p  2   z   Pos operator   Pos const  op  const  return Pos  p  0   op . p  0 , p  1   op . p  1 , p  2   op . p  2    Clear and AddWithWeight required for interpolation void Clear  void   0   p  0   p  1   p  2   0.0f   void AddWithWeight  Pos const  src , float weight   p  0   weight  src . p  0  p  1   weight  src . p  1  p  2   weight  src . p  2   float p  3   typedef std  vector  Pos  PosVector  struct Tri  Tri    Tri  int a , int b , int c   v  0   a , v  1   b , v  2   c   int v  3   typedef std  vector  Tri  TriVector    Functions to populate the topology and geometry arrays a simple  shape whose positions may be transformed  void createCube  std  vector  int   vertsPerFace , std  vector  Index   faceVertsPerFace , std  vector  Pos   positionsPerVert    Local topology and position of a cube centered at origin static float const cubePositions  8  3     -0.5f , -0.5f , -0.5f ,  -0.5f , 0.5f , -0.5f ,  -0.5f , 0.5f , 0.5f ,  -0.5f , -0.5f , 0.5f ,  0.5f , -0.5f , -0.5f ,  0.5f , 0.5f , -0.5f ,  0.5f , 0.5f , 0.5f ,  0.5f , -0.5f , 0.5f   static int const cubeFaceVerts  6  4     0 , 3 , 2 , 1 ,  4 , 5 , 6 , 7 ,  0 , 4 , 7 , 3 ,  1 , 2 , 6 , 5 ,  0 , 1 , 5 , 4 ,  3 , 7 , 6 , 2    Initialize verts-per-face and face-vertices for each face vertsPerFace . resize  6  faceVertsPerFace . resize  24  for  int i  0  i  6   i   vertsPerFace  i   4  for  int j  0  j  4   j   faceVertsPerFace  i  4  j   cubeFaceVerts  i  j     Initialize vertex positions positionsPerVert . resize  8  for  int i  0  i  8   i   float const  p  cubePositions  i  positionsPerVert  i   Pos  p  0 , p  1 , p  2      Create a TopologyRefiner from default geometry created above  Far  TopologyRefiner  createTopologyRefinerDefault  PosVector  posVector   std  vector  int  topVertsPerFace  std  vector  Index  topFaceVerts  createCube  topVertsPerFace , topFaceVerts , posVector  typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_AND_CORNER  Descriptor desc  desc . numVertices   int  posVector . size  desc . numFaces   int  topVertsPerFace . size  desc . numVertsPerFace   topVertsPerFace  0  desc . vertIndicesPerFace   topFaceVerts  0   Instantiate a FarTopologyRefiner from the descriptor. Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  assert  refiner  return refiner     Create a TopologyRefiner from a specified Obj file  geometry created internally  Far  TopologyRefiner  createTopologyRefinerFromObj  std  string const  objFileName , Sdc  SchemeType schemeType , PosVector  posVector   const char  filename  objFileName . c_str  const Shape  shape  0  std  ifstream ifs  filename  if  ifs   std  stringstream ss  ss  ifs . rdbuf  ifs . close  std  string shapeString  ss . str  shape  Shape  parseObj  shapeString . c_str , ConvertSdcTypeToShapeScheme  schemeType , false  if  shape  0   fprintf  stderr , Error Cannot create Shape from .obj file s n  , filename  return 0    else  fprintf  stderr , Error Cannot open .obj file s n  , filename  return 0   Sdc  SchemeType sdcType  GetSdcType   shape  Sdc  Options sdcOptions  GetSdcOptions   shape  Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Shape  Create   shape , Far  TopologyRefinerFactory  Shape  Options  sdcType , sdcOptions  if  refiner  0   fprintf  stderr , Error Unable to construct TopologyRefiner  from .obj file s n  , filename  return 0   int numVertices  refiner - GetNumVerticesTotal  posVector . resize  numVertices  std  memcpy   posVector  0 . p  0 ,  shape - verts  0 , numVertices  3  sizeof  float  delete shape  return refiner     Simple function to export an Obj file for the limit points -- which  provides a simple tessllation similar to tutorial_5_2.  int writeToObj  Far  TopologyLevel const  baseLevel , std  vector  Pos  const  vertexPositions , int nextObjVertexIndex   for  size_t i  0  i  vertexPositions . size   i   float const  p  vertexPositions  i . p  printf  v f f f n  , p  0 , p  1 , p  2     Connect the sequences of limit points center followed by corners  into triangle fans for each base face  for  int i  0  i  baseLevel . GetNumFaces   i   int faceSize  baseLevel . GetFaceVertices  i . size  int vCenter  nextObjVertexIndex  1  int vCorner  vCenter  1  for  int k  0  k  faceSize   k   printf  f d d d n  , vCenter , vCorner  k , vCorner   k  1   faceSize   nextObjVertexIndex  faceSize  1   return nextObjVertexIndex     end namespace   Command line arguments parsed to provide run-time options  class Args  public  std  string inputObjFile  Sdc  SchemeType schemeType  int maxPatchDepth  int numPoses  Pos poseOffset  bool deriv1Flag  bool noPatchesFlag  bool noOutputFlag  public  Args  int argc , char  argv   inputObjFile , schemeType  Sdc  SCHEME_CATMARK , maxPatchDepth  3 , numPoses  0 , poseOffset  1.0f , 0.0f , 0.0f , deriv1Flag  false , noPatchesFlag  false , noOutputFlag  false    Parse and assign standard arguments and Obj files ArgOptions args  args . Parse  argc , argv  maxPatchDepth  args . GetLevel  schemeType  ConvertShapeSchemeToSdcType  args . GetDefaultScheme  const std  vector  const char  objFiles  args . GetObjFiles  if   objFiles . empty   for  size_t i  1  i  objFiles . size   i   fprintf  stderr , Warning .obj file s ignored n  , objFiles  i   inputObjFile  std  string  objFiles  0    Parse remaining arguments specific to this example const std  vector  const char   rargs  args . GetRemainingArgs  for  size_t i  0  i  rargs . size   i   if   strcmp  rargs  i , -d1   deriv1Flag  true   else if   strcmp  rargs  i , -nopatches   noPatchesFlag  true   else if   strcmp  rargs  i , -poses   if   i  rargs . size  numPoses  atoi  rargs  i   else if   strcmp  rargs  i , -offset   if   i  rargs . size  poseOffset . p  0    float  atof  rargs  i  if   i  rargs . size  poseOffset . p  1    float  atof  rargs  i  if   i  rargs . size  poseOffset . p  2    float  atof  rargs  i   else if   strcmp  rargs  i , -nooutput   noOutputFlag  true   else  fprintf  stderr , Warning Argument s ignored n  , rargs  i     private  Args       Assemble the set of locations for the limit points. The resulting  vector of LocationArrays can contain arbitrary locations on the limit  surface -- with multiple locations for the same patch grouped into a  single array.   In this case, for each base face, coordinates for the center and its  corners are specified -- from which we will construct a triangle fan  providing a crude tessellation similar to tutorial_5_2.  typedef Far  LimitStencilTableFactory  LocationArray LocationArray  int assembleLimitPointLocations  Far  TopologyRefiner const  refiner , std  vector  LocationArray   locations     Coordinates for the center of the face and its corners slightly  inset. Unlike most of the public interface for patches, the  LocationArray refers to parameteric coordinates as s,t, so that  convention will be followed here.   Note that the s,t coordinates in a LocationArray are referred to  by reference. The memory holding these s,t values must persist  while the LimitStencilTable is constructed -- the arrays here are  declared as static for that purpose.  static float const quadSCoords  5    0.5f , 0.05f , 0.95f , 0.95f , 0.05f  static float const quadTCoords  5    0.5f , 0.05f , 0.05f , 0.95f , 0.95f  static float const triSCoords  4    0.33f , 0.05f , 0.95f , 0.05f  static float const triTCoords  4    0.33f , 0.05f , 0.00f , 0.95f  static float const irregSCoords  2    1.0f , 0.05f  static float const irregTCoords  2    1.0f , 0.05f    Since these are references to patches to be evaluated, we require  use of the Ptex indices to identify the top-most parameterized  patch, which is essential to dealing with non-quad faces in the  case of Catmark.  Far  TopologyLevel const  baseLevel  refiner . GetLevel  0  Far  PtexIndices basePtexIndices  refiner  int regFaceSize  Sdc  SchemeTypeTraits  GetRegularFaceSize  refiner . GetSchemeType    For each base face, simply refer to the s,t arrays for regular quad  and triangular patches with a single LocationArray. Otherwise, for  irregular faces, the corners of the face come from different patches  and so must be referenced in separate LocationArrays.  locations . clear  int numLimitPoints  0  for  int i  0  i  baseLevel . GetNumFaces   i   int baseFaceSize  baseLevel . GetFaceVertices  i . size  int basePtexId  basePtexIndices . GetFaceId  i  bool faceIsRegular   baseFaceSize  regFaceSize  if  faceIsRegular    All coordinates are on the same top-level patch LocationArray loc  loc . ptexIdx  basePtexId  loc . numLocations  baseFaceSize  1  if  baseFaceSize  4   loc . s  quadSCoords  loc . t  quadTCoords   else  loc . s  triSCoords  loc . t  triTCoords   locations . push_back  loc   else   Center coordinate is on the first sub-patch while those on  near the corners are on each successive sub-patch LocationArray loc  loc . numLocations  1  for  int j  0  j  baseFaceSize   j   bool isPerimeter   j  0  loc . ptexIdx  basePtexId   isPerimeter   j -1   0  loc . s   irregSCoords  isPerimeter  loc . t   irregTCoords  isPerimeter  locations . push_back  loc    numLimitPoints  baseFaceSize  1   return numLimitPoints     Load command line arguments and geometry, build the LimitStencilTable  for a set of points on the limit surface and compute those points for  several orientations of the mesh  int main  int argc , char  argv   Args args  argc , argv    Create or load the base geometry command line arguments allow a  .obj file to be specified, providing a TopologyRefiner and a set  of base vertex positions to work with  std  vector  Pos  basePositions  Far  TopologyRefiner  refinerPtr  args . inputObjFile . empty   createTopologyRefinerDefault  basePositions   createTopologyRefinerFromObj  args . inputObjFile , args . schemeType , basePositions  assert  refinerPtr  Far  TopologyRefiner  refiner   refinerPtr  Far  TopologyLevel const  baseLevel  refiner . GetLevel  0    Use of LimitStencilTable requires either explicit or implicit use  of a PatchTable. A PatchTable is not required to construct a  LimitStencilTable -- one will be constructed internally for use  and discarded -- but explicit construction is recommended to control  the many legacy options for PatchTable, rather than relying on  internal defaults. Adaptive refinement is required in both cases  to indicate the accuracy of the patches.   Note that if a TopologyRefiner and PatchTable are not used for  any other purpose than computing the limit points, that specifying  the subset of faces containing those limit points in the adaptive  refinement and PatchTable construction can avoid unnecessary  overhead.  Far  PatchTable  patchTablePtr  0  if  args . noPatchesFlag   refiner . RefineAdaptive  Far  TopologyRefiner  AdaptiveOptions  args . maxPatchDepth   else  Far  PatchTableFactory  Options patchOptions  args . maxPatchDepth  patchOptions . useInfSharpPatch  true  patchOptions . generateLegacySharpCornerPatches  false  patchOptions . generateVaryingTables  false  patchOptions . generateFVarTables  false  patchOptions . endCapType  Far  PatchTableFactory  Options  ENDCAP_GREGORY_BASIS  refiner . RefineAdaptive  patchOptions . GetRefineAdaptiveOptions  patchTablePtr  Far  PatchTableFactory  Create  refiner , patchOptions  assert  patchTablePtr     Assemble the set of locations for the limit points. For each base  face, coordinates for the center and its corners are specified --  from which we will construct a triangle fan providing a crude  tessellation similar to tutorial_5_2.  std  vector  LocationArray  locations  int numLimitPoints  assembleLimitPointLocations  refiner , locations    Construct a LimitStencilTable from the refiner, patch table optional  and the collection of limit point locations. Stencils can optionally  be created for computing dervatives -- the default is to compute 1st  derivative stencils, so be sure to disable that if not necessary  Far  LimitStencilTableFactory  Options limitOptions  limitOptions . generate1stDerivatives  args . deriv1Flag  Far  LimitStencilTable const  limitStencilTablePtr  Far  LimitStencilTableFactory  Create  refiner , locations , 0 ,  optional StencilTable for the refined points patchTablePtr ,  optional PatchTable limitOptions  assert  limitStencilTablePtr  Far  LimitStencilTable const  limitStencilTable   limitStencilTablePtr    Apply the constructed LimitStencilTable to compute limit positions  from the base level vertex positions. This is trivial if computing  all positions in one invokation. The UpdateValues method and those  for derivatives are overloaded to optionally accept a subrange of  indices to distribute the computation  std  vector  Pos  limitPositions  numLimitPoints  limitStencilTable . UpdateValues  basePositions , limitPositions   Call with the optional subrange limitStencilTable . UpdateValues  basePositions , limitPositions , 0 , numLimitPoints  2  limitStencilTable . UpdateValues  basePositions , limitPositions ,  numLimitPoints  2   1 , numLimitPoints   Write vertices and faces in Obj format for the original limit points int objVertCount  0  if   args . noOutputFlag   printf  g base_mesh n   objVertCount  writeToObj  baseLevel , limitPositions , objVertCount     Recompute the limit points and output faces for different poses of  the original mesh -- in this case simply translated. Also optionally  compute 1st derivatives though they are not used here  std  vector  Pos  posePositions  basePositions  std  vector  Pos  limitDu  args . deriv1Flag  numLimitPoints  0  std  vector  Pos  limitDv  args . deriv1Flag  numLimitPoints  0  for  int i  0  i  args . numPoses   i    Trivially transform the base vertex positions and re-compute for  size_t j  0  j  basePositions . size   j   posePositions  j   posePositions  j   args . poseOffset   limitStencilTable . UpdateValues  posePositions , limitPositions  if  args . deriv1Flag   limitStencilTable . UpdateDerivs  posePositions , limitDu , limitDv   if   args . noOutputFlag   printf   n g pose_d n  , i  objVertCount  writeToObj  baseLevel , limitPositions , objVertCount    delete refinerPtr  delete patchTablePtr  delete limitStencilTablePtr  return EXIT_SUCCESS   Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_5_3.html"}, 
{"title":"bfr_tutorial_1_3.cpp", "text":"bfr_tutorial_1_3.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_1_3.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_1_3.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_1_3bfr_tutorial_1_3.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial builds on the previous tutorial that makes use of the  SurfaceFactory, Surface and Tessellation classes for evaluating and  tessellating the limit surface of faces of a mesh by adding support  for the evaluation of face-varying UVs.   If UVs exist in the given mesh, they will be evaluated and included  with the vertex positions and normals previously illustrated as  part of the tessellation written to the Obj file.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  bool uv2xyzFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false , uv2xyzFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else if   strcmp  argv  i , -uv2xyz   uv2xyzFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , std  vector  float  const  meshFaceVaryingUVs , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing   When dealing with face-varying data, an identifier is necessary  when constructing Surfaces in order to distinguish the different  face-varying data channels. To avoid repeatedly specifying that  identifier when only one is present or of interest, it can be  specified via the Options.  bool meshHasUVs   meshTopology . GetNumFVarChannels   0  SurfaceFactory  Options surfaceOptions  if  meshHasUVs   surfaceOptions . SetDefaultFVarID  0   SurfaceFactory surfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface posSurface  Surface uvSurface  std  vector  float  facePatchPoints  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  float  outUV  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  surfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surfaces for position and UVs of this face.  There are two ways to do this -- both illustrated here   Creating Surfaces for the different data interpolation types  independently is clear and convenient, but considerable work  may be duplicated in the construction process in the case of  non-linear face-varying Surfaces. So unless it is known that  face-varying interpolation is linear, use of InitSurfaces  is generally preferred.   Remember also that the face-varying identifier is omitted from  the initialization methods here as it was previously assigned  to the SurfaceFactoryOptions. In the absence of an assignment  of the default FVarID to the Options, a failure to specify the  FVarID here will result in failure.   The cases below are expanded for illustration purposes, and  validity of the resulting Surface is tested here, rather than  the return value of initialization methods.  bool createSurfacesTogether  true  if   meshHasUVs   surfaceFactory . InitVertexSurface  faceIndex ,  posSurface   else if  createSurfacesTogether   surfaceFactory . InitSurfaces  faceIndex ,  posSurface ,  uvSurface   else  if  surfaceFactory . InitVertexSurface  faceIndex ,  posSurface   surfaceFactory . InitFaceVaryingSurface  faceIndex ,  uvSurface    if   posSurface . IsValid  continue    Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  posSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Prepare the patch points for the Surface, then use them to  evaluate output points for all identified coordinates   Evaluate vertex positions   Resize patch point and output arrays int pointSize  3  facePatchPoints . resize  posSurface . GetNumPatchPoints   pointSize  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize   Populate patch point and output arrays posSurface . PreparePatchPoints  meshVertexPositions . data , pointSize , facePatchPoints . data , pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   posSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outPos  j ,  outDu  j ,  outDv  j     Evaluate face-varying UVs when present if  meshHasUVs    Resize patch point and output arrays  - note reuse of the same patch point array as position int pointSize  2  facePatchPoints . resize  uvSurface . GetNumPatchPoints   pointSize  outUV . resize  numOutCoords  pointSize   Populate patch point and output arrays uvSurface . PreparePatchPoints  meshFaceVaryingUVs . data , pointSize , facePatchPoints . data , pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   uvSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outUV  j      Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  if  meshHasUVs  options . uv2xyzFlag   objWriter . WriteVertexPositions  outUV , 2  objWriter . WriteFaces  outFacets , tessFacetSize , false , false   else  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  if  meshHasUVs   objWriter . WriteVertexUVs  outUV   objWriter . WriteFaces  outFacets , tessFacetSize , true , meshHasUVs       Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , meshFVarUVs , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_1_3.html"}, 
{"title":"far_tutorial_5_2.cpp", "text":"far_tutorial_5_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen far_tutorial_5_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github far_tutorial_5_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsfartutorial_5_2far_tutorial_5_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial shows how to manage the limit surface of a potentially  large mesh by creating groups of patches for selected faces of the  mesh. Familiarity with construction and evaluation of a PatchTable  is assumed see tutorial_5_1.   When the patches for a mesh do not need to be retained for further  use, e.g. when simply computing points for a tessellation, the time  and space required to construct a single large PatchTable can be  considerable. By constructing, evaluating and discarding smaller  PatchTables for subsets of the mesh, the high transient memory cost  can be avoided when computed serially. When computed in parallel,  there may be little memory savings, but the construction time can  then be distributed.   This tutorial creates simple geometry currently a lattice of cubes  that can be expanded in complexity with a simple multiplier. The  collection of faces are then divided into a specified number of groups  from which patches will be constructed and evaluated. A simple  tessellation a triangle fan around the midpoint of each face is then  written in Obj format to the standard output.  include ......regressioncommonarg_utils.h include ......regressioncommonfar_utils.h include opensubdivfartopologyDescriptor.h include opensubdivfarprimvarRefiner.h include opensubdivfarpatchTableFactory.h include opensubdivfarpatchMap.h include opensubdivfarptexIndices.h include cassert include cstdio include cstring include fstream include sstream using namespace OpenSubdiv  using Far  Index    Global utilities in this namespace are not relevant to the tutorial.  They simply serve to construct some default geometry to be processed  in the form of a TopologyRefiner and vector of vertex positions.  namespace    Simple structs for x,y,z position and a 3-tuple for the set  of vertices of a triangle  struct Pos  Pos    Pos  float x , float y , float z   p  0   x , p  1   y , p  2   z   Pos operator   Pos const  op  const  return Pos  p  0   op . p  0 , p  1   op . p  1 , p  2   op . p  2    Clear and AddWithWeight required for interpolation void Clear  void   0   p  0   p  1   p  2   0.0f   void AddWithWeight  Pos const  src , float weight   p  0   weight  src . p  0  p  1   weight  src . p  1  p  2   weight  src . p  2   float p  3   typedef std  vector  Pos  PosVector  struct Tri  Tri    Tri  int a , int b , int c   v  0   a , v  1   b , v  2   c   int v  3   typedef std  vector  Tri  TriVector    Functions to populate the topology and geometry arrays with simple  shapes that we can multiply to increase complexity  void appendDefaultPrimitive  Pos const  origin , std  vector  int   vertsPerFace , std  vector  Index   faceVerts , std  vector  Pos   positionsPerVert    Local topology and position of a cube centered at origin static float const cubePositions  8  3     -0.5f , -0.5f , -0.5f ,  -0.5f , 0.5f , -0.5f ,  -0.5f , 0.5f , 0.5f ,  -0.5f , -0.5f , 0.5f ,  0.5f , -0.5f , -0.5f ,  0.5f , 0.5f , -0.5f ,  0.5f , 0.5f , 0.5f ,  0.5f , -0.5f , 0.5f   static int const cubeFaceVerts  6  4     0 , 3 , 2 , 1 ,  4 , 5 , 6 , 7 ,  0 , 4 , 7 , 3 ,  1 , 2 , 6 , 5 ,  0 , 1 , 5 , 4 ,  3 , 7 , 6 , 2    Identify the next vertex before appending vertex positions int baseVertex   int  positionsPerVert . size  for  int i  0  i  8   i   float const  p  cubePositions  i  positionsPerVert . push_back  origin  Pos  p  0 , p  1 , p  2    Append number of verts-per-face and face-vertices for each face for  int i  0  i  6   i   vertsPerFace . push_back  4  for  int j  0  j  4   j   faceVerts . push_back  baseVertex  cubeFaceVerts  i  j     void createDefaultGeometry  int multiplier , std  vector  int   vertsPerFace , std  vector  Index   faceVerts , std  vector  Pos   positionsPerVert    Default primitive is currently a cube int const vertsPerPrimitive  8  int const facesPerPrimitive  6  int const faceVertsPerPrimitive  24  int nPrimitives  multiplier  multiplier  multiplier  positionsPerVert . reserve  nPrimitives  vertsPerPrimitive  vertsPerFace . reserve  nPrimitives  facesPerPrimitive  faceVerts . reserve  nPrimitives  faceVertsPerPrimitive  for  int x  0  x  multiplier   x   for  int y  0  y  multiplier   y   for  int z  0  z  multiplier   z   appendDefaultPrimitive  Pos  float  x  2.0f ,  float  y  2.0f ,  float  z  2.0f , vertsPerFace , faceVerts , positionsPerVert        Create a TopologyRefiner from default geometry created above  Far  TopologyRefiner  createTopologyRefinerDefault  int multiplier , PosVector  posVector   std  vector  int  topVertsPerFace  std  vector  Index  topFaceVerts  createDefaultGeometry  multiplier , topVertsPerFace , topFaceVerts , posVector  typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_AND_CORNER  Descriptor desc  desc . numVertices   int  posVector . size  desc . numFaces   int  topVertsPerFace . size  desc . numVertsPerFace   topVertsPerFace  0  desc . vertIndicesPerFace   topFaceVerts  0   Instantiate a FarTopologyRefiner from the descriptor. Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options  if  refiner  0   exit  EXIT_FAILURE   bool dumpDefaultGeometryToObj  false  if  dumpDefaultGeometryToObj   int nVerts   int  posVector . size  for  int i  0  i  nVerts   i   float const  p  posVector  i . p  printf  v f f f n  , p  0 , p  1 , p  2   int const  fVerts   topFaceVerts  0  int nFaces   int  topVertsPerFace . size  for  int i  0  i  nFaces   i   printf  f  for  int j  0  j  topVertsPerFace  i   j   printf   d , 1   fVerts    printf   n    exit  EXIT_SUCCESS   return refiner     Create a TopologyRefiner from a specified Obj file  geometry created internally  Far  TopologyRefiner  createTopologyRefinerFromObj  std  string const  objFileName , Sdc  SchemeType schemeType , PosVector  posVector   const char  filename  objFileName . c_str  const Shape  shape  0  std  ifstream ifs  filename  if  ifs   std  stringstream ss  ss  ifs . rdbuf  ifs . close  std  string shapeString  ss . str  shape  Shape  parseObj  shapeString . c_str , ConvertSdcTypeToShapeScheme  schemeType , false  if  shape  0   fprintf  stderr , Error Cannot create Shape  from .obj file s n  , filename  return 0    else  fprintf  stderr , Error Cannot open .obj file s n  , filename  return 0   Sdc  SchemeType sdcType  GetSdcType   shape  Sdc  Options sdcOptions  GetSdcOptions   shape  Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Shape  Create   shape , Far  TopologyRefinerFactory  Shape  Options  sdcType , sdcOptions  if  refiner  0   fprintf  stderr , Error Unable to construct TopologyRefiner  from .obj file s n  , filename  return 0   int numVertices  refiner - GetNumVerticesTotal  posVector . resize  numVertices  std  memcpy   posVector  0 . p  0 ,  shape - verts  0 , numVertices  3  sizeof  float  delete shape  return refiner     end namespace   The PatchGroup bundles objects used to create and evaluate a sparse set  of patches. Its construction creates a PatchTable and all other objects  necessary to evaluate patches associated with the specified subset of  faces provided. A simple method to tessellate a specified face is  provided.   Note that, since the data buffers for the base level and refined levels  are separate we want to avoid copying primvar data for the base level  of a potentially large mesh, that patch evaluation needs to account  for the separation when combining control points.  struct PatchGroup  PatchGroup  Far  PatchTableFactory  Options patchOptions , Far  TopologyRefiner const  baseRefinerArg , Far  PtexIndices const  basePtexIndicesArg , std  vector  Pos  const  basePositionsArg , std  vector  Index  const  baseFacesArg   PatchGroup  void TessellateBaseFace  int face , PosVector  tessPoints , TriVector  tessTris  const   Const reference members Far  TopologyRefiner const  baseRefiner  Far  PtexIndices const  basePtexIndices  std  vector  Pos  const  basePositions  std  vector  Index  const  baseFaces   Members constructed to evaluate patches Far  PatchTable  patchTable  Far  PatchMap  patchMap  int patchFaceSize  std  vector  Pos  localPositions   PatchGroup  PatchGroup  Far  PatchTableFactory  Options patchOptions , Far  TopologyRefiner const  baseRefinerArg , Far  PtexIndices const  basePtexIndicesArg , std  vector  Pos  const  basePositionsArg , std  vector  Index  const  baseFacesArg   baseRefiner  baseRefinerArg , basePtexIndices  basePtexIndicesArg , basePositions  basePositionsArg , baseFaces  baseFacesArg    Create a local refiner sharing the base level, apply adaptive  refinement to the given subset of base faces, and construct a patch  table and its associated map for the same set of faces  Far  ConstIndexArray groupFaces   baseFaces  0 ,  int  baseFaces . size  Far  TopologyRefiner  localRefiner  Far  TopologyRefinerFactory  Far  TopologyDescriptor  Create  baseRefiner  localRefiner - RefineAdaptive  patchOptions . GetRefineAdaptiveOptions , groupFaces  patchTable  Far  PatchTableFactory  Create   localRefiner , patchOptions , groupFaces  patchMap  new Far  PatchMap   patchTable  patchFaceSize  Sdc  SchemeTypeTraits  GetRegularFaceSize  baseRefiner . GetSchemeType   Compute the number of refined and local points needed to evaluate the  patches, allocate and interpolate. This varies from tutorial_5_1 in  that the primvar buffer for the base vertices is separate from the  refined vertices and local patch points which must also be accounted  for when evaluating the patches.  int nBaseVertices  localRefiner - GetLevel  0 . GetNumVertices  int nRefinedVertices  localRefiner - GetNumVerticesTotal  - nBaseVertices  int nLocalPoints  patchTable - GetNumLocalPoints  localPositions . resize  nRefinedVertices  nLocalPoints  if  nRefinedVertices   Far  PrimvarRefiner primvarRefiner   localRefiner  Pos const  src   basePositions  0  Pos  dst   localPositions  0  for  int level  1  level  localRefiner - GetNumLevels   level   primvarRefiner . Interpolate  level , src , dst  src  dst  dst  localRefiner - GetLevel  level . GetNumVertices    if  nLocalPoints   patchTable - GetLocalPointStencilTable  - UpdateValues   basePositions  0 , nBaseVertices ,  localPositions  0 ,  localPositions  nRefinedVertices   delete localRefiner   PatchGroup  PatchGroup   delete patchTable  delete patchMap   void PatchGroup  TessellateBaseFace  int face , PosVector  tessPoints , TriVector  tessTris  const   Tesselate the face with points at the midpoint of the face and at  each corner, and triangles connecting the midpoint to each edge.  Irregular faces require an aribrary number of corners points, but  all are at the origin of the child face of the irregular base face  float const quadPoints  5  2     0.5f , 0.5f ,  0.0f , 0.0f ,  1.0f , 0.0f ,  1.0f , 1.0f ,  0.0f , 1.0f   float const triPoints  4  2     0.5f , 0.5f ,  0.0f , 0.0f ,  1.0f , 0.0f ,  0.0f , 1.0f   float const irregPoints  4  2     1.0f , 1.0f ,  0.0f , 0.0f    Determine the topology of the given base face and the resulting  tessellation points and faces to generate  int baseFace  baseFaces  face  int faceSize  baseRefiner . GetLevel  0 . GetFaceVertices  baseFace . size  bool faceIsIrregular   faceSize  patchFaceSize  int nTessPoints  faceSize  1  int nTessFaces  faceSize  tessPoints . resize  nTessPoints  tessTris . resize  nTessFaces   Compute the mid and corner points -- remember that for an irregular  face, we must reference the individual ptex faces for each corner  int ptexFace  basePtexIndices . GetFaceId  baseFace  int numBaseVerts   int  basePositions . size  for  int i  0  i  nTessPoints   i    Choose the s,t coordinate from the fixed tessellation float const  st  faceIsIrregular  irregPoints  i  0    faceSize  4   quadPoints  i   triPoints  i   Locate the patch corresponding to the face ptex idx and s,t  and evaluate int patchFace  ptexFace  if  faceIsIrregular   i  0   patchFace  i - 1   Far  PatchTable  PatchHandle const  handle  patchMap - FindPatch  patchFace , st  0 , st  1  assert  handle  float pWeights  20  patchTable - EvaluateBasis   handle , st  0 , st  1 , pWeights   Identify the patch cvs and combine with the evaluated weights --  remember to distinguish cvs in the base level Far  ConstIndexArray cvIndices  patchTable - GetPatchVertices   handle  Pos  pos  tessPoints  i  pos . Clear  for  int cv  0  cv  cvIndices . size   cv   int cvIndex  cvIndices  cv  if  cvIndex  numBaseVerts   pos . AddWithWeight  basePositions  cvIndex , pWeights  cv   else  pos . AddWithWeight  localPositions  cvIndex - numBaseVerts , pWeights  cv      Assign triangles connecting the midpoint of the base face to the  points computed at the ends of each of its edges  for  int i  0  i  nTessFaces   i   tessTris  i   Tri  0 , 1  i , 1   i  1   faceSize      Command line arguments parsed to provide run-time options  class Args  public  std  string inputObjFile  Sdc  SchemeType schemeType  int geoMultiplier  int maxPatchDepth  int numPatchGroups  bool noTessFlag  bool noOutputFlag  public  Args  int argc , char  argv   inputObjFile , schemeType  Sdc  SCHEME_CATMARK , geoMultiplier  10 , maxPatchDepth  3 , numPatchGroups  10 , noTessFlag  false , noOutputFlag  false    Parse and assign standard arguments and Obj files ArgOptions args  args . Parse  argc , argv  maxPatchDepth  args . GetLevel  schemeType  ConvertShapeSchemeToSdcType  args . GetDefaultScheme  const std  vector  const char  objFiles  args . GetObjFiles  if   objFiles . empty   for  size_t i  1  i  objFiles . size   i   fprintf  stderr , Warning .obj file s ignored n  , objFiles  i   inputObjFile  std  string  objFiles  0    Parse remaining arguments specific to this example const std  vector  const char   rargs  args . GetRemainingArgs  for  size_t i  0  i  rargs . size   i   if   strcmp  rargs  i , -groups   if   i  rargs . size  numPatchGroups  atoi  rargs  i   else if   strcmp  rargs  i , -mult   if   i  rargs . size  geoMultiplier  atoi  rargs  i   else if   strcmp  rargs  i , -notess   noTessFlag  true   else if   strcmp  rargs  i , -nooutput   noOutputFlag  true   else  fprintf  stderr , Warning Argument s ignored n  , rargs  i     private  Args       Load command line arguments and geometry, then divide the mesh into groups  of faces from which to create and tessellate patches  int main  int argc , char  argv   Args args  argc , argv    Create or load the base geometry command line arguments allow a  .obj file to be specified. In addition to the TopologyRefiner  and set of positions for the base vertices, a set of PtexIndices is  also required to evaluate patches, so build it here once for use  elsewhere  std  vector  Pos  basePositions  Far  TopologyRefiner  baseRefinerPtr  args . inputObjFile . empty   createTopologyRefinerDefault  args . geoMultiplier , basePositions   createTopologyRefinerFromObj  args . inputObjFile , args . schemeType , basePositions  assert  baseRefinerPtr  Far  TopologyRefiner  baseRefiner   baseRefinerPtr  Far  PtexIndices basePtexIndices  baseRefiner    Determine the sizes of the patch groups specified -- there will be  two sizes that differ by one to account for unequal division  int numBaseFaces  baseRefiner . GetNumFacesTotal  int numPatchGroups  args . numPatchGroups  if  numPatchGroups  numBaseFaces   numPatchGroups  numBaseFaces   else if  numPatchGroups  1   numPatchGroups  1   int lesserGroupSize  numBaseFaces  numPatchGroups  int numLargerGroups  numBaseFaces -  numPatchGroups  lesserGroupSize    Define the options used to construct the patches for each group.  Unless suppressed, a tessellation in Obj format will also be printed  to standard output, so keep track of the vertex indices.  Far  PatchTableFactory  Options patchOptions  args . maxPatchDepth  patchOptions . generateVaryingTables  false  patchOptions . shareEndCapPatchPoints  false  patchOptions . endCapType  Far  PatchTableFactory  Options  ENDCAP_GREGORY_BASIS  int objVertCount  0  PosVector tessPoints  TriVector tessFaces  for  int i  0  i  numPatchGroups   i     Initialize a vector with a group of base faces from which to  create and evaluate patches  Index minFace  i  lesserGroupSize  std  min  i , numLargerGroups  Index maxFace  minFace  lesserGroupSize   i  numLargerGroups  std  vector  Far  Index  baseFaces  maxFace - minFace  for  int face  minFace  face  maxFace   face   baseFaces  face - minFace   face     Declare a PatchGroup and tessellate its base faces -- generating  vertices and faces in Obj format to standard output  PatchGroup patchGroup  patchOptions , baseRefiner , basePtexIndices , basePositions , baseFaces  if  args . noTessFlag  continue  if   args . noOutputFlag   printf  g patchGroup_d n  , i   for  int j  0  j   int  baseFaces . size   j   patchGroup . TessellateBaseFace  j , tessPoints , tessFaces  if   args . noOutputFlag   int nVerts   int  tessPoints . size  for  int k  0  k  nVerts   k   float const  p  tessPoints  k . p  printf  v f f f n  , p  0 , p  1 , p  2   int nTris   int  tessFaces . size  int vBase  1  objVertCount  for  int k  0  k  nTris   k   int const  v  tessFaces  k . v  printf  f d d d n  , vBase  v  0 , vBase  v  1 , vBase  v  2   objVertCount  nVerts     delete baseRefinerPtr  return EXIT_SUCCESS   Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"far_tutorial_5_2.html"}, 
{"title":"bfr_tutorial_1_5.cpp", "text":"bfr_tutorial_1_5.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_1_5.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_1_5.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_1_5bfr_tutorial_1_5.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial is an alternative to an earlier tutorial that showed  uniform tessellation. This version differs by evaluating the points  of the tessellation using limit stencils instead of the standard  Surface evaluation methods.   Limit stencils factor the evaluation into a set of coefficients for  each control point affecting the Surface.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing though  none are used in this simple case  SurfaceFactory  Options surfaceOptions  SurfaceFactory meshSurfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface faceSurface  std  vector  float  faceControlPoints  std  vector  float  limitStencils  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  meshSurfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surface for this face -- if valid skipping  holes and boundary faces in some rare cases  if   meshSurfaceFactory . InitVertexSurface  faceIndex ,  faceSurface   continue     Resize stencils and control point arrays based on the number  of control points for the Surface  int numControlPoints  faceSurface . GetNumControlPoints  limitStencils . resize  3  numControlPoints  float  pStencil  limitStencils . data  float  duStencil  limitStencils . data   numControlPoints  float  dvStencil  limitStencils . data   numControlPoints  2    Limit stencils can be applied using the control points in a  local array or directy from the mesh. Both are shown here, so  if using the local array, resize and populate it  bool gatherControlPoints  true  if  gatherControlPoints   faceControlPoints . resize  numControlPoints  3  faceSurface . GatherControlPoints  meshVertexPositions . data , 3 , faceControlPoints . data , 3     Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  faceSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Evaluate and apply stencils to compute points of the tessellation  outPos . resize  numOutCoords  3  outDu . resize  numOutCoords  3  outDv . resize  numOutCoords  3  for  int i  0  i  numOutCoords   i   float const  uv  outCoords . data   i  2  faceSurface . EvaluateStencil  uv , pStencil , duStencil , dvStencil  float  p  outPos . data   i  3  float  du  outDu . data   i  3  float  dv  outDv . data   i  3  if  gatherControlPoints   float const  controlPoints  faceControlPoints . data  faceSurface . ApplyStencil  pStencil , controlPoints , 3 , p  faceSurface . ApplyStencil  duStencil , controlPoints , 3 , du  faceSurface . ApplyStencil  dvStencil , controlPoints , 3 , dv   else  float const  meshPoints  meshVertexPositions . data  faceSurface . ApplyStencilFromMesh  pStencil , meshPoints , 3 , p  faceSurface . ApplyStencilFromMesh  duStencil , meshPoints , 3 , du  faceSurface . ApplyStencilFromMesh  dvStencil , meshPoints , 3 , dv      Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  objWriter . WriteFaces  outFacets , tessFacetSize , true , false      Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_1_5.html"}, 
{"title":"bfr_tutorial_1_4.cpp", "text":"bfr_tutorial_1_4.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_1_4.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_1_4.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_1_4bfr_tutorial_1_4.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial builds on the previous tutorial that makes use of the  SurfaceFactory, Surface and Tessellation classes for evaluating and  tessellating the limit surface of faces of a mesh by illustrating  how the presence of additional data in the mesh arrays is handled.   As in the previous tutorial, vertex positions and face-varying UVs  are provided with the mesh to be evaluated. But here an additional  color is interleaved with the position in the vertex data of the  mesh and a third component is added to face-varying UV data making  it u,v,w.   To evaluate the position and 2D UVs while avoiding the color and  unused third UV coordinate, the SurfacePointDescriptor class is  used to describe the size and stride of the desired data to be  evaluated in the arrays of mesh data.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  bool uv2xyzFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false , uv2xyzFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else if   strcmp  argv  i , -uv2xyz   uv2xyzFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVtxData , int vtxDataSize , std  vector  float  const  meshFVarData , int fvarDataSize , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface  typedef Surface  PointDescriptor SurfacePoint    Identify the source positions and UVs within more general data  arrays for the mesh. If position andor UV are not at the start  of the vtx andor fvar data, simply offset the head of the array  here accordingly  bool meshHasUVs   meshTopology . GetNumFVarChannels   0  float const  meshPosData  meshVtxData . data  SurfacePoint meshPosPoint  3 , vtxDataSize  float const  meshUVData  meshHasUVs  meshFVarData . data   0  SurfacePoint meshUVPoint  2 , fvarDataSize    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing   When dealing with face-varying data, an identifier is necessary  when constructing Surfaces in order to distinguish the different  face-varying data channels. To avoid repeatedly specifying that  identifier when only one is present or of interest, it can be  specified via the Options.  SurfaceFactory  Options surfaceOptions  if  meshHasUVs   surfaceOptions . SetDefaultFVarID  0   SurfaceFactory surfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface posSurface  Surface uvSurface  std  vector  float  facePatchPoints  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  float  outUV  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  surfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surfaces for position and UVs of this face.  There are two ways to do this -- both illustrated here   Creating Surfaces for the different data interpolation types  independently is clear and convenient, but considerable work  may be duplicated in the construction process in the case of  non-linear face-varying Surfaces. So unless it is known that  face-varying interpolation is linear, use of InitSurfaces  is generally preferred.   Remember also that the face-varying identifier is omitted from  the initialization methods here as it was previously assigned  to the SurfaceFactoryOptions. In the absence of an assignment  of the default FVarID to the Options, a failure to specify the  FVarID here will result in failure.   The cases below are expanded for illustration purposes, and  validity of the resulting Surface is tested here, rather than  the return value of initialization methods.  bool createSurfacesTogether  true  if   meshHasUVs   surfaceFactory . InitVertexSurface  faceIndex ,  posSurface   else if  createSurfacesTogether   surfaceFactory . InitSurfaces  faceIndex ,  posSurface ,  uvSurface   else  if  surfaceFactory . InitVertexSurface  faceIndex ,  posSurface   surfaceFactory . InitFaceVaryingSurface  faceIndex ,  uvSurface    if   posSurface . IsValid  continue    Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  posSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Prepare the patch points for the Surface, then use them to  evaluate output points for all identified coordinates   Evaluate vertex positions   Resize patch point and output arrays int pointSize  meshPosPoint . size  facePatchPoints . resize  posSurface . GetNumPatchPoints   pointSize  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize   Populate patch point and output arrays float  patchPosData  facePatchPoints . data  SurfacePoint patchPosPoint  pointSize  posSurface . PreparePatchPoints  meshPosData , meshPosPoint , patchPosData , patchPosPoint  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   posSurface . Evaluate   outCoords  i  2 , patchPosData , patchPosPoint ,  outPos  j ,  outDu  j ,  outDv  j     Evaluate face-varying UVs when present if  meshHasUVs    Resize patch point and output arrays  - note reuse of the same patch point array as position int pointSize  meshUVPoint . size  facePatchPoints . resize  uvSurface . GetNumPatchPoints   pointSize  outUV . resize  numOutCoords  pointSize   Populate patch point and output arrays float  patchUVData  facePatchPoints . data  SurfacePoint patchUVPoint  pointSize  uvSurface . PreparePatchPoints  meshUVData , meshUVPoint , patchUVData , patchUVPoint  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   uvSurface . Evaluate   outCoords  i  2 , patchUVData , patchUVPoint ,  outUV  j      Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  if  meshHasUVs  options . uv2xyzFlag   objWriter . WriteVertexPositions  outUV , 2  objWriter . WriteFaces  outFacets , tessFacetSize , false , false   else  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  if  meshHasUVs   objWriter . WriteVertexUVs  outUV   objWriter . WriteFaces  outFacets , tessFacetSize , true , meshHasUVs       Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE     Expand the loaded position and UV arrays to include additional  data initialized with -1 for distinction, e.g. add a 4-tuple  for RGBA color to the vertex data and add a third field w  to the face-varying data  int numPos   int  meshVtxPositions . size   3  int vtxSize  7  std  vector  float  vtxData  numPos  vtxSize , -1.0f  for  int i  0  i  numPos   i   vtxData  i  vtxSize   meshVtxPositions  i  3  vtxData  i  vtxSize  1   meshVtxPositions  i  3  1  vtxData  i  vtxSize  2   meshVtxPositions  i  3  2   int numUVs   int  meshFVarUVs . size   2  int fvarSize  3  std  vector  float  fvarData  numUVs  fvarSize , -1.0f  for  int i  0  i  numUVs   i   fvarData  i  fvarSize   meshFVarUVs  i  2  fvarData  i  fvarSize  1   meshFVarUVs  i  2  1     Pass the expanded data arrays along with their respective strides  tessellateToObj   meshTopology , vtxData , vtxSize , fvarData , fvarSize , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_1_4.html"}, 
{"title":"osd_tutorial_0.cpp", "text":"osd_tutorial_0.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen osd_tutorial_0.cpp 3.6.0 User Docs API Docs Release Notes Forum Github osd_tutorial_0.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsosdtutorial_0osd_tutorial_0.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial demonstrates the manipulation of Osd Evaluator and  BufferDescriptor.  include opensubdivfartopologyDescriptor.h include opensubdivfarstencilTableFactory.h include opensubdivosdcpuEvaluator.h include opensubdivosdcpuVertexBuffer.h include cstdio include cstring ------------------------------------------------------------------------------  Cube geometry from catmark_cube.h static float g_verts  24    -0.5f , -0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , 0.5f , 0.5f , 0.5f , -0.5f , 0.5f , -0.5f , 0.5f , 0.5f , -0.5f , -0.5f , -0.5f , -0.5f , 0.5f , -0.5f , -0.5f  static int g_nverts  8 , g_nfaces  6  static int g_vertsperface  6    4 , 4 , 4 , 4 , 4 , 4  static int g_vertIndices  24    0 , 1 , 3 , 2 , 2 , 3 , 5 , 4 , 4 , 5 , 7 , 6 , 6 , 7 , 1 , 0 , 1 , 7 , 5 , 3 , 6 , 0 , 2 , 4  using namespace OpenSubdiv  static Far  TopologyRefiner const  createTopologyRefiner  int maxlevel  ------------------------------------------------------------------------------ int main  int , char    int maxlevel  2 , nCoarseVerts  0 , nRefinedVerts  0    Setup phase  Far  StencilTable const  stencilTable  NULL    Setup FarStencilTable Far  TopologyRefiner const  refiner  createTopologyRefiner  maxlevel   Setup a factory to create FarStencilTable for more details see  Far tutorials Far  StencilTableFactory  Options options  options . generateOffsets  true  options . generateIntermediateLevels  false  stencilTable  Far  StencilTableFactory  Create   refiner , options  nCoarseVerts  refiner - GetLevel  0 . GetNumVertices  nRefinedVerts  stencilTable - GetNumStencils   We are done with Far cleanup table delete refiner    Setup a buffer for vertex primvar data Osd  CpuVertexBuffer  vbuffer  Osd  CpuVertexBuffer  Create  3 , nCoarseVerts  nRefinedVerts    Execution phase every frame    Pack the control vertex data at the start of the vertex buffer  and update every time control data changes vbuffer - UpdateData  g_verts , 0 , nCoarseVerts  Osd  BufferDescriptor srcDesc  0 , 3 , 3  Osd  BufferDescriptor dstDesc  nCoarseVerts  3 , 3 , 3   Launch the computation Osd  CpuEvaluator  EvalStencils  vbuffer , srcDesc , vbuffer , dstDesc , stencilTable     Visualization with Maya  print a MEL script that generates particles  at the location of the refined vertices printf  particle   float const  refinedVerts  vbuffer - BindCpuBuffer   3  nCoarseVerts  for  int i  0  i  nRefinedVerts   i   float const  vert  refinedVerts  3  i  printf  -p f f f n  , vert  0 , vert  1 , vert  2   printf  -c 1 n    delete stencilTable  delete vbuffer   ------------------------------------------------------------------------------ static Far  TopologyRefiner const  createTopologyRefiner  int maxlevel    Populate a topology descriptor with our raw data typedef Far  TopologyDescriptor Descriptor  Sdc  SchemeType type  OpenSubdiv  Sdc  SCHEME_CATMARK  Sdc  Options options  options . SetVtxBoundaryInterpolation  Sdc  Options  VTX_BOUNDARY_EDGE_ONLY  Descriptor desc  desc . numVertices  g_nverts  desc . numFaces  g_nfaces  desc . numVertsPerFace  g_vertsperface  desc . vertIndicesPerFace  g_vertIndices   Instantiate a FarTopologyRefiner from the descriptor Far  TopologyRefiner  refiner  Far  TopologyRefinerFactory  Descriptor  Create  desc , Far  TopologyRefinerFactory  Descriptor  Options  type , options   Uniformly refine the topology up to maxlevel refiner - RefineUniform  Far  TopologyRefiner  UniformOptions  maxlevel  return refiner   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"osd_tutorial_0.html"}, 
{"title":"bfr_tutorial_2_1.cpp", "text":"bfr_tutorial_2_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_2_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_2_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_2_1bfr_tutorial_2_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial builds on the previous tutorial that makes use of the  SurfaceFactory, Surface and Tessellation classes by illustrating the  use of non-uniform tessellation parameters with Tessellation.   Tessellation rates for the edges of a face are determined by a  length associated with each edge. That length may be computed using  either the control hull or the limit surface. The length of a  tessellation interval is required and will be inferred if not  explicitly specified as a command line option.   The tessellation rate for an edge is computed as its length divided  by the length of the tessellation interval. A maximum tessellation  rate is imposed to prevent accidental unbounded tessellation, but  can easily be raised as needed.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio include cmath include algorithm  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  float tessInterval  int tessRateMax  bool useHullFlag  bool tessQuadsFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessInterval  0.0f , tessRateMax  10 , useHullFlag  false , tessQuadsFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -length   if   i  argc  tessInterval   float  atof  argv  i   else if   strcmp  argv  i , -max   if   i  argc  tessRateMax  atoi  argv  i   else if   strcmp  argv  i , -hull   useHullFlag  true   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       Local trivial functions for simple edge length calculations and the  determination of associated tessellation rates  inline float EdgeLength  float const  v0 , float const  v1   float dv  3  dv  0   std  abs  v0  0  - v1  0  dv  1   std  abs  v0  1  - v1  1  dv  2   std  abs  v0  2  - v1  2  return std  sqrt  dv  0   dv  0   dv  1   dv  1   dv  2   dv  2   float FindLongestEdge  Far  TopologyRefiner const  mesh , std  vector  float  const  vertPos , int pointSize   float maxLength  0.0f  int numEdges  mesh . GetLevel  0 . GetNumEdges  for  int i  0  i  numEdges   i   Far  ConstIndexArray edgeVerts  mesh . GetLevel  0 . GetEdgeVertices  i  float edgeLength  EdgeLength   vertPos  edgeVerts  0   pointSize ,  vertPos  edgeVerts  1   pointSize  maxLength  std  max  maxLength , edgeLength   return maxLength   void GetEdgeTessRates  std  vector  float  const  vertPos , int pointSize , Args const  options , int  edgeRates   int numEdges   int  vertPos . size   pointSize  for  int i  0  i  numEdges   i   int j   i  1   numEdges  float edgeLength  EdgeLength   vertPos  i  pointSize ,  vertPos  j  pointSize  edgeRates  i   1   int  edgeLength  options . tessInterval  edgeRates  i   std  min  edgeRates  i , options . tessRateMax      The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing though  none are used in this simple case  SurfaceFactory  Options surfaceOptions  SurfaceFactory meshSurfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface faceSurface  std  vector  float  facePatchPoints  std  vector  int  faceTessRates  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  meshSurfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surface for this face -- if valid skipping  holes and boundary faces in some rare cases  if   meshSurfaceFactory . InitVertexSurface  faceIndex ,  faceSurface   continue     Prepare the Surface patch points first as it may be evaluated  to determine suitable edge-rates for Tessellation  int pointSize  3  facePatchPoints . resize  faceSurface . GetNumPatchPoints   pointSize  faceSurface . PreparePatchPoints  meshVertexPositions . data , pointSize , facePatchPoints . data , pointSize    For each of the N edges of the face, a tessellation rate is  determined to initialize a non-uniform Tessellation pattern.   Many metrics are possible -- some based on the geometry itself  size, curvature, others dependent on viewpoint screen space  size, center of view, etc. and many more. Simple techniques  are chosen here for illustration and can easily be replaced.   Here two methods are shown using lengths between the corners of  the face -- the first using the vertex positions of the face and  the second using points evaluated at the corners of its limit  surface. Use of the control hull is more efficient avoiding the  evaluation but may prove less effective in some cases though  both estimates have their limitations.  int N  faceSurface . GetFaceSize   Use the output array temporarily to hold the N positions outPos . resize  N  pointSize  if  options . useHullFlag   Far  ConstIndexArray verts  meshTopology . GetLevel  0 . GetFaceVertices  faceIndex  for  int i  0 , j  0  i  N   i , j  pointSize   float const  vPos   meshVertexPositions  verts  i   pointSize  outPos  j   vPos  0  outPos  j  1   vPos  1  outPos  j  2   vPos  2    else  Bfr  Parameterization faceParam  faceSurface . GetParameterization  for  int i  0 , j  0  i  N   i , j  pointSize   float uv  2  faceParam . GetVertexCoord  i , uv  faceSurface . Evaluate  uv , facePatchPoints . data , pointSize ,  outPos  j    faceTessRates . resize  N  GetEdgeTessRates  outPos , pointSize , options , faceTessRates . data    Declare a non-uniform Tessellation using the rates for each  edge and identify coordinates of the points to evaluate   Additional interior rates can be optionally provided 2 for  quads, 1 for others but will be inferred in their absence.  Bfr  Tessellation tessPattern  faceSurface . GetParameterization , N , faceTessRates . data , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Resize the output arrays and evaluate  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   faceSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outPos  j ,  outDu  j ,  outDv  j     Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  objWriter . WriteFaces  outFacets , tessFacetSize , true , false      Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE     If no interval length was specified, set one by finding the longest  edge of the mesh and dividing it by the maximum tessellation rate  if  args . tessInterval  0.0f   args . tessInterval  FindLongestEdge   meshTopology , meshVtxPositions , 3    float  args . tessRateMax   tessellateToObj   meshTopology , meshVtxPositions , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_2_1.html"}, 
{"title":"bfr_tutorial_3_1.cpp", "text":"bfr_tutorial_3_1.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_3_1.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_3_1.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_3_1bfr_tutorial_3_1.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial illustrates the definition of a custom subclass of  BfrSurfaceFactory -- providing a class with the SurfaceFactory  interface adapted to a connected mesh representation.   The bulk of this code is therefore identical to a previous tutorial  1.3 which illustrates simple use of a BfrSurface factory. The  only difference here lies in the explicit local definition of the  subclass of BfrSurfaceFactory for FarTopologyRefiner -- named  CustomSurfaceFactory in this case.  include .customSurfaceFactory.h include opensubdivfartopologyRefiner.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  bool uv2xyzFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false , uv2xyzFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else if   strcmp  argv  i , -uv2xyz   uv2xyzFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , std  vector  float  const  meshFaceVaryingUVs , Args const  options     Use simpler local type names for the Surface and its factory  typedef CustomSurfaceFactory SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing   When dealing with face-varying data, an identifier is necessary  when constructing Surfaces in order to distinguish the different  face-varying data channels. To avoid repeatedly specifying that  identifier when only one is present or of interest, it can be  specified via the Options.  bool meshHasUVs   meshTopology . GetNumFVarChannels   0  SurfaceFactory  Options surfaceOptions  if  meshHasUVs   surfaceOptions . SetDefaultFVarID  0   SurfaceFactory surfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface posSurface  Surface uvSurface  std  vector  float  facePatchPoints  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  float  outUV  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  surfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surfaces for position and UVs of this face.  There are two ways to do this -- both illustrated here   Creating Surfaces for the different data interpolation types  independently is clear and convenient, but considerable work  may be duplicated in the construction process in the case of  non-linear face-varying Surfaces. So unless it is known that  face-varying interpolation is linear, use of InitSurfaces  is generally preferred.   Remember also that the face-varying identifier is omitted from  the initialization methods here as it was previously assigned  to the SurfaceFactoryOptions. In the absence of an assignment  of the default FVarID to the Options, a failure to specify the  FVarID here will result in failure.   The cases below are expanded for illustration purposes, and  validity of the resulting Surface is tested here, rather than  the return value of initialization methods.  bool createSurfacesTogether  true  if   meshHasUVs   surfaceFactory . InitVertexSurface  faceIndex ,  posSurface   else if  createSurfacesTogether   surfaceFactory . InitSurfaces  faceIndex ,  posSurface ,  uvSurface   else  if  surfaceFactory . InitVertexSurface  faceIndex ,  posSurface   surfaceFactory . InitFaceVaryingSurface  faceIndex ,  uvSurface    if   posSurface . IsValid  continue    Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  posSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Prepare the patch points for the Surface, then use them to  evaluate output points for all identified coordinates   Evaluate vertex positions   Resize patch point and output arrays int pointSize  3  facePatchPoints . resize  posSurface . GetNumPatchPoints   pointSize  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize   Populate patch point and output arrays posSurface . PreparePatchPoints  meshVertexPositions . data , pointSize , facePatchPoints . data , pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   posSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outPos  j ,  outDu  j ,  outDv  j     Evaluate face-varying UVs when present if  meshHasUVs    Resize patch point and output arrays  - note reuse of the same patch point array as position int pointSize  2  facePatchPoints . resize  uvSurface . GetNumPatchPoints   pointSize  outUV . resize  numOutCoords  pointSize   Populate patch point and output arrays uvSurface . PreparePatchPoints  meshFaceVaryingUVs . data , pointSize , facePatchPoints . data , pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   uvSurface . Evaluate   outCoords  i  2 , facePatchPoints . data , pointSize ,  outUV  j      Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  if  meshHasUVs  options . uv2xyzFlag   objWriter . WriteVertexPositions  outUV , 2  objWriter . WriteFaces  outFacets , tessFacetSize , false , false   else  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  if  meshHasUVs   objWriter . WriteVertexUVs  outUV   objWriter . WriteFaces  outFacets , tessFacetSize , true , meshHasUVs       Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , meshFVarUVs , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_3_1.html"}, 
{"title":"bfr_tutorial_2_2.cpp", "text":"bfr_tutorial_2_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_2_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_2_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_2_2bfr_tutorial_2_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial builds on others using the SurfaceFactory, Surface  and Tessellation classes by using more of the functionality of the  Tessellation class to construct a tessellation of the mesh that is  topologically watertight, i.e. resulting points evaluated along  shared edges or vertices are shared and not duplicated.   Since Tessellation provides points around its boundary first, the  evaluated points for shared vertices and edges are identified when  constructed and reused when shared later. The boundary of the  tessellation of a face is therefore a collection of shared points  and methods of Tessellation help to remap the faces generated to  the shared set of points.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include string include cstring include cstdio include cassert  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv  using Far  Index  using Far  IndexArray  using Far  ConstIndexArray    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       Simple local structs supporting shared points for vertices and edges  namespace  struct SharedVertex  SharedVertex   pointIndex  -1    bool IsSet  const  return pointIndex  0   void Set  int index   pointIndex  index   int pointIndex   struct SharedEdge  SharedEdge   pointIndex  -1 , numPoints  0    bool IsSet  const  return pointIndex  0   void Set  int index , int n   pointIndex  index , numPoints  n   int pointIndex  int numPoints     end namespace   The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.   This tessellation function differs from earlier tutorials in that it  computes and reuses shared points at vertices and edges of the mesh.  There are several ways to compute these shared points, and which is  best depends on context.   Dealing with shared data poses complications for threading in general,  so computing all points for the vertices and edges up front may be  preferred -- despite the fact that faces will be visited more than once  first when generating potentially shared vertex or edge points, and  later when generating any interior points. The loops for vertices and  edges can be threaded and the indexing of the shared points is simpler.   For the single-threaded case here, the faces are each processed in  order and any shared points will be computed and used as needed. So  each face is visited once and so each Surface initialized once but  the bookkeeping to deal with indices of shared points becomes more  complicated.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing though  none are used in this simple case  SurfaceFactory  Options surfaceOptions  SurfaceFactory meshSurfaceFactory  meshTopology , surfaceOptions    The Surface to be constructed and evaluated for each face -- as  well as the intermediate and output data associated with it -- can  be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  Surface faceSurface  std  vector  float  facePatchPoints  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Declare vectors to identify shared tessellation points at vertices  and edges and their indices around the boundary of a face  Far  TopologyLevel const  baseLevel  meshTopology . GetLevel  0  std  vector  SharedVertex  sharedVerts  baseLevel . GetNumVertices  std  vector  SharedEdge  sharedEdges  baseLevel . GetNumEdges  std  vector  int  tessBoundaryIndices    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numMeshPointsEvaluated  0  int numFaces  meshSurfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Initialize the Surface for this face -- if valid skipping  holes and boundary faces in some rare cases  if   meshSurfaceFactory . InitVertexSurface  faceIndex ,  faceSurface   continue     Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  faceSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Prepare the patch points for the Surface, then use them to  evaluate output points for all identified coordinates   Resize patch point and output arrays int pointSize  3  facePatchPoints . resize  faceSurface . GetNumPatchPoints   pointSize  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize   Populate the patch point array faceSurface . PreparePatchPoints  meshVertexPositions . data , pointSize , facePatchPoints . data , pointSize    Evaluate the sample points of the Tessellation   First traverse the boundary of the face to determine whether  to evaluate or share points on vertices and edges of the face.  Both pre-existing and new boundary points are identified by  index in an array for later use. The interior points are all  trivially computed after the boundary is dealt with.   Identify the boundary and interior coords and initialize the  index array for the potentially shared boundary points  int numBoundaryCoords  tessPattern . GetNumBoundaryCoords  int numInteriorCoords  numOutCoords - numBoundaryCoords  float const  tessBoundaryCoords   outCoords  0  float const  tessInteriorCoords   outCoords  numBoundaryCoords  2  ConstIndexArray fVerts  baseLevel . GetFaceVertices  faceIndex  ConstIndexArray fEdges  baseLevel . GetFaceEdges  faceIndex  tessBoundaryIndices . resize  numBoundaryCoords    Walk around the face, inspecting each vertex and outgoing edge,  and populating the index array of boundary points  float  patchPointData  facePatchPoints . data  int boundaryIndex  0  int numFacePointsEvaluated  0  for  int i  0  i  fVerts . size   i   Index vertIndex  fVerts  i  Index edgeIndex  fEdges  i  int edgeRate  options . tessUniformRate    Evaluateassign or retrieve the shared point for the vertex  SharedVertex  sharedVertex  sharedVerts  vertIndex  if   sharedVertex . IsSet    Identify indices of the new shared point in both the  mesh and face and increment their inventory int indexInMesh  numMeshPointsEvaluated   int indexInFace  numFacePointsEvaluated   sharedVertex . Set  indexInMesh   Evaluate new shared point and assign index to boundary float const  uv   tessBoundaryCoords  boundaryIndex  2  int pIndex  indexInFace  pointSize  faceSurface . Evaluate  uv , patchPointData , pointSize ,  outPos  pIndex ,  outDu  pIndex ,  outDv  pIndex  tessBoundaryIndices  boundaryIndex    indexInMesh   else   Assign shared vertex point index to boundary tessBoundaryIndices  boundaryIndex    sharedVertex . pointIndex     Evaluateassign or retrieve all shared points for the edge   To keep this simple, assume the edge is manifold. So the  second face sharing the edge has that edge in the opposite  direction in its boundary relative to the first face --  making it necessary to reverse the order of shared points  for the boundary of the second face.   To support a non-manifold edge, all subsequent faces that  share the assigned shared edge must determine if their  orientation of that edge is reversed relative to the first  face for which the shared edge points were evaluated. So a  little more book-keeping andor inspection is required.  if  edgeRate  1   int pointsPerEdge  edgeRate - 1  SharedEdge  sharedEdge  sharedEdges  edgeIndex  if   sharedEdge . IsSet    Identify indices of the new shared points in both the  mesh and face and increment their inventory int nextInMesh  numMeshPointsEvaluated  int nextInFace  numFacePointsEvaluated  numFacePointsEvaluated  pointsPerEdge  numMeshPointsEvaluated  pointsPerEdge  sharedEdge . Set  nextInMesh , pointsPerEdge   Evaluate shared points and assign indices to boundary float const  uv   tessBoundaryCoords  boundaryIndex  2  for  int j  0  j  pointsPerEdge   j , uv  2   int pIndex   nextInFace    pointSize  faceSurface . Evaluate  uv , patchPointData , pointSize ,  outPos  pIndex ,  outDu  pIndex ,  outDv  pIndex  tessBoundaryIndices  boundaryIndex    nextInMesh     else   See note above on simplification for manifold edges assert   baseLevel . IsEdgeNonManifold  edgeIndex   Assign shared points to boundary in reverse order int nextInMesh  sharedEdge . pointIndex  pointsPerEdge - 1  for  int j  0  j  pointsPerEdge   j   tessBoundaryIndices  boundaryIndex    nextInMesh --        Evaluate any interior points unique to this face -- appending  them to those shared points computed above for the boundary  if  numInteriorCoords   float const  uv  tessInteriorCoords  int iLast  numFacePointsEvaluated  numInteriorCoords  for  int i  numFacePointsEvaluated  i  iLast   i , uv  2   int pIndex  i  pointSize  faceSurface . Evaluate  uv , patchPointData , pointSize ,  outPos  pIndex ,  outDu  pIndex ,  outDv  pIndex   numFacePointsEvaluated  numInteriorCoords  numMeshPointsEvaluated  numInteriorCoords     Remember to trimresize the arrays storing evaluation results  for new points to reflect the size actually populated.  outPos . resize  numFacePointsEvaluated  pointSize  outDu . resize  numFacePointsEvaluated  pointSize  outDv . resize  numFacePointsEvaluated  pointSize    Identify the faces of the Tessellation   Note that the coordinate indices used by the facets are local  to the face i.e. they range from 0..N-1, where N is the  number of coordinates in the pattern and so need to be offset  when writing to Obj format.   For more advanced use, the coordinates associated with the  boundary and interior of the pattern are distinguishable so  that those on the boundary can be easily remapped to refer to  shared edge or corner points, while those in the interior can  be separately offset or similarly remapped.   So transform the indices of the facets here as needed using  the indices of shared boundary points assembled above and a  suitable offset for the new interior points added  int tessInteriorOffset  numMeshPointsEvaluated - numOutCoords  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , tessBoundaryIndices . data , tessInteriorOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  objWriter . WriteFaces  outFacets , tessFacetSize , true , false      Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_2_2.html"}, 
{"title":"bfr_tutorial_3_2.cpp", "text":"bfr_tutorial_3_2.cpp Introduction License Getting Started Contributing Building OpenSubdiv Code Examples References Subdivision Surfaces Piecewise Parametric Surfaces Arbitrary Topology Subdivision versus Tessellation Mesh Data and Topology Schemes and Options Modeling Tips OpenSubdiv User Guide API Overview Sdc Vtr Far Topology Refiner Topology Refiner Factory Primvar Refiner Patch Table Stencil Table Bfr Evaluation Parameterization Tessellation More on Surface Factory Custom Surface Factory Osd Shader Interface Tutorials Historical But Relevant Hbr Using Hbr Hierarchical Edits Additional Resources Forum Links Videos Releases Release 3.6 Release 3.5 Release 3.4 Release 3.3 Release 3.2 Release 3.1 Release 3.0 Overview Porting Guide 2.0 to 3.0 Subdivision Compatibility Release Notes Doxygen bfr_tutorial_3_2.cpp 3.6.0 User Docs API Docs Release Notes Forum Github bfr_tutorial_3_2.cpp httpsgithub.comPixarAnimationStudiosOpenSubdivblobreleasetutorialsbfrtutorial_3_2bfr_tutorial_3_2.cpp ------------------------------------------------------------------------------  Tutorial description   This tutorial is a variation of tutorials showing simple uniform  tessellation. Rather than constructing and evaluating a Surface at  a time, this tutorial shows how Surfaces can be created and saved  for repeated use.   A simple SurfaceCache class is created that creates and stores the  Surface for each face, along with the patch points associated with  it. The main tessellation function remains essentially the same,  but here it access the Surfaces from the SurfaceCache rather than  computing them locally.   Note that while this example illustrated the retention of all  Surfaces for a mesh, this behavior is not recommended. It does not  scale well for large meshes and undermines the memory savings that  transient use of Surfaces is designed to achieve. Rather than  storing Surfaces for all faces, maintaining a priority queue for a  fixed number may be a reasonable compromise.  include opensubdivfartopologyRefiner.h include opensubdivbfrrefinerSurfaceFactory.h include opensubdivbfrsurface.h include opensubdivbfrtessellation.h include vector include memory include string include cstring include cstdio  Local headers with support for this tutorial in namespace tutorial include .meshLoader.h include .objWriter.h using namespace OpenSubdiv    Simple command line arguments to provide input and run-time options  class Args  public  std  string inputObjFile  std  string outputObjFile  Sdc  SchemeType schemeType  int tessUniformRate  bool tessQuadsFlag  public  Args  int argc , char  argv   inputObjFile , outputObjFile , schemeType  Sdc  SCHEME_CATMARK , tessUniformRate  5 , tessQuadsFlag  false   for  int i  1  i  argc   i   if  strstr  argv  i , .obj   if  inputObjFile . empty   inputObjFile  std  string  argv  i   else  fprintf  stderr , Warning Extra Obj file s ignored n  , argv  i    else if   strcmp  argv  i , -o   if   i  argc  outputObjFile  std  string  argv  i   else if   strcmp  argv  i , -bilinear   schemeType  Sdc  SCHEME_BILINEAR   else if   strcmp  argv  i , -catmark   schemeType  Sdc  SCHEME_CATMARK   else if   strcmp  argv  i , -loop   schemeType  Sdc  SCHEME_LOOP   else if   strcmp  argv  i , -res   if   i  argc  tessUniformRate  atoi  argv  i   else if   strcmp  argv  i , -quads   tessQuadsFlag  true   else  fprintf  stderr , Warning Unrecognized argument s ignored n  , argv  i     private  Args       This simple class creates and dispenses Surfaces for all faces of  a mesh. It consists primarily of an array of simple structs entries  for each face and a single array of patch points for all Surfaces  created.   There are many ways to create such a cache depending on requirements.  This is a simple example, but the interface presents some options that  are worth considering. A SurfaceCache is constructed here given the  following   - a reference to the SurfaceFactory  - the cache could just as easily take a reference to the mesh  and construct the SurfaceFactory internally   - the position data for the mesh  - this is needed to compute patch points for the Surfaces  - if caching UVs or any other primvar, other data needs to be  provided -- along with the interpolation type for that data  vertex, face-varying, etc.   - option to cache patch points  - the cache could store the Surfaces only or also include  their patch points  - storing patch points takes more memory but will eliminate  any preparation time for evaluation of the Surface   - option to cache all surfaces  - the benefits to caching simple linear or regular surfaces  are minimal -- and may even be detrimental  - so only caching non-linear irregular surfaces is an option  worth considering   The SurfaceCache implementation here provides the options noted above.  But for simplicity, the actual usage of the SurfaceCache does not deal  with the permutations of additional work that is necessary when the  Surfaces or their patch points are not cached.  class SurfaceCache  public  typedef Bfr  Surface  float  Surface  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  public  SurfaceCache  SurfaceFactory const  surfaceFactory , std  vector  float  const  meshPoints , bool cachePatchPoints  true , bool cacheAllSurfaces  true  SurfaceCache   delete   SurfaceCache   default    Public methods to retrieved cached Surfaces and their pre-computed  patch points  bool FaceHasLimitSurface  int face   return _entries  face . hasLimit   Surface const  GetSurface  int face   return _entries  face . surface . get  float const  GetPatchPoints  int face   return getPatchPoints  face   private   Simple struct to keep track of Surface and more for each face struct FaceEntry  FaceEntry   surface , hasLimit  false , pointOffset  -1    std  unique_ptr  Surface const  surface  bool hasLimit  int pointOffset    Non-const version to be used internally to aide assignment float  getPatchPoints  int face   return  _entries  face . surface   _points . empty    _points . data   _entries  face . pointOffset  3   0   private  std  vector  FaceEntry  _entries  std  vector  float  _points   SurfaceCache  SurfaceCache  SurfaceFactory const  surfaceFactory , std  vector  float  const  meshPoints , bool cachePatchPoints , bool cacheAllSurfaces   int numFaces  surfaceFactory . GetNumFaces  _entries . resize  numFaces  int numPointsInCache  0  for  int face  0  face  numFaces   face   Surface  s  surfaceFactory . CreateVertexSurface  float   face  if  s   FaceEntry  entry  _entries  face  entry . hasLimit  true  if  cacheAllSurfaces    s - IsRegular    s - IsLinear   entry . surface . reset  s  entry . pointOffset  numPointsInCache  numPointsInCache  s - GetNumPatchPoints   else  delete s     if  cachePatchPoints   _points . resize  numPointsInCache  3  for  int face  0  face  numFaces   face   float  patchPoints  getPatchPoints  face  if  patchPoints   GetSurface  face  - PreparePatchPoints  meshPoints . data , 3 , patchPoints , 3        The main tessellation function given a mesh and vertex positions,  tessellate each face -- writing results in Obj format.  void tessellateToObj  Far  TopologyRefiner const  meshTopology , std  vector  float  const  meshVertexPositions , Args const  options     Use simpler local type names for the Surface and its factory  typedef Bfr  RefinerSurfaceFactory  SurfaceFactory  typedef Bfr  Surface  float  Surface    Initialize the SurfaceFactory for the given base mesh very low  cost in terms of both time and space and tessellate each face  independently i.e. no shared vertices   Note that the SurfaceFactory is not thread-safe by default due to  use of an internal cache. Creating a separate instance of the  SurfaceFactory for each thread is one way to safely parallelize  this loop. Another preferred is to assign a thread-safe cache  to the single instance.   First declare any evaluation options when initializing though  none are used in this simple case  SurfaceFactory  Options surfaceOptions  SurfaceFactory meshSurfaceFactory  meshTopology , surfaceOptions    Initialize a SurfaceCache to construct Surfaces for all faces.  From this point forward the SurfaceFactory is no longer used to  access Surfaces. Note also that usage below is specific to the  options used to initialize the SurfaceCache  bool cachePatchPoints  true  bool cacheAllSurfaces  true  SurfaceCache surfaceCache  meshSurfaceFactory , meshVertexPositions , cachePatchPoints , cacheAllSurfaces    As with previous tutorials, output data associated with the face  can be declared in the scope local to each face. But since dynamic  memory is involved with these variables, it is preferred to declare  them outside that loop to preserve and reuse that dynamic memory.  std  vector  float  outCoords  std  vector  float  outPos , outDu , outDv  std  vector  int  outFacets    Assign Tessellation Options applied for all faces. Tessellations  allow the creating of either 3- or 4-sided faces -- both of which  are supported here via a command line option  int const tessFacetSize  3  options . tessQuadsFlag  Bfr  Tessellation  Options tessOptions  tessOptions . SetFacetSize  tessFacetSize  tessOptions . PreserveQuads  options . tessQuadsFlag    Process each face, writing the output of each in Obj format  tutorial  ObjWriter objWriter  options . outputObjFile  int numFaces  meshSurfaceFactory . GetNumFaces  for  int faceIndex  0  faceIndex  numFaces   faceIndex     Retrieve the Surface for this face when present  if   surfaceCache . FaceHasLimitSurface  faceIndex  continue  Surface const  faceSurface   surfaceCache . GetSurface  faceIndex    Declare a simple uniform Tessellation for the Parameterization  of this face and identify coordinates of the points to evaluate  Bfr  Tessellation tessPattern  faceSurface . GetParameterization , options . tessUniformRate , tessOptions  int numOutCoords  tessPattern . GetNumCoords  outCoords . resize  numOutCoords  2  tessPattern . GetCoords  outCoords . data    Retrieve the patch points for the Surface, then use them to  evaluate output points for all identified coordinates  float const  facePatchPoints  surfaceCache . GetPatchPoints  faceIndex  int pointSize  3  outPos . resize  numOutCoords  pointSize  outDu . resize  numOutCoords  pointSize  outDv . resize  numOutCoords  pointSize  for  int i  0 , j  0  i  numOutCoords   i , j  pointSize   faceSurface . Evaluate   outCoords  i  2 , facePatchPoints , pointSize ,  outPos  j ,  outDu  j ,  outDv  j     Identify the faces of the Tessellation   Note the need to offset vertex indices for the output faces --  using the number of vertices generated prior to this face. One  of several Tessellation methods to transform the facet indices  simply translates all indices by the desired offset.  int objVertexIndexOffset  objWriter . GetNumVertices  int numFacets  tessPattern . GetNumFacets  outFacets . resize  numFacets  tessFacetSize  tessPattern . GetFacets  outFacets . data  tessPattern . TransformFacetCoordIndices  outFacets . data , objVertexIndexOffset    Write the evaluated points and faces connecting them as Obj  objWriter . WriteGroupName  baseFace_ , faceIndex  objWriter . WriteVertexPositions  outPos  objWriter . WriteVertexNormals  outDu , outDv  objWriter . WriteFaces  outFacets , tessFacetSize , true , false      Load command line arguments, specified or default geometry and process  int main  int argc , char  argv   Args args  argc , argv  Far  TopologyRefiner  meshTopology  0  std  vector  float  meshVtxPositions  std  vector  float  meshFVarUVs  meshTopology  tutorial  createTopologyRefiner  args . inputObjFile , args . schemeType , meshVtxPositions , meshFVarUVs  if  meshTopology  0   return EXIT_FAILURE   tessellateToObj   meshTopology , meshVtxPositions , args  delete meshTopology  return EXIT_SUCCESS   ------------------------------------------------------------------------------ Generated on 2024-03-07 1156 UTC. User Docs API Docs Release Notes Forum TM   1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use", "tags": "", "loc":"bfr_tutorial_3_2.html"}, 
]};