1.. 2 Copyright 2013 Pixar 3 4 Licensed under the Apache License, Version 2.0 (the "Apache License") 5 with the following modification; you may not use this file except in 6 compliance with the Apache License and the following modification to it: 7 Section 6. Trademarks. is deleted and replaced with: 8 9 6. Trademarks. This License does not grant permission to use the trade 10 names, trademarks, service marks, or product names of the Licensor 11 and its affiliates, except as required to comply with Section 4(c) of 12 the License and to reproduce the content of the NOTICE file. 13 14 You may obtain a copy of the Apache License at 15 16 http://www.apache.org/licenses/LICENSE-2.0 17 18 Unless required by applicable law or agreed to in writing, software 19 distributed under the Apache License with the above modification is 20 distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 KIND, either express or implied. See the Apache License for the specific 22 language governing permissions and limitations under the Apache License. 23 24 25API Overview 26------------ 27 28.. contents:: 29 :local: 30 :backlinks: none 31 32.. image:: images/osd_splash.png 33 :align: center 34 :target: images/osd_splash.png 35 36 37API Layers 38========== 39 40OpenSubdiv is structured as a set of layered libraries. This structure facilitates 41operation on a variety of computing resources, and allows developers to only opt-in 42to the layers and feature sets that they require. 43From a top-down point of view, OpenSubdiv is comprised of several layers, 44some public, and some private. 45 46Layers list: 47 48+-----------------------------------------+--------------------------------------------------------------------------------+ 49| | **Sdc** |The lowest level layer, implements the core subdivision details | 50| | Subdivision Core |to facilitate the generation of consistent results. Most cases will only | 51| | `Sdc Overview <sdc_overview.html>`__ |require the use of simple public types and constants from Sdc. | 52+-----------------------------------------+--------------------------------------------------------------------------------+ 53| | **Vtr** | A suite of classes to provide an intermediate | 54| | Vectorized Topological Representation | representation of topology that supports efficient refinement. | 55| | `Vtr Overview <vtr_overview.html>`__ | *Vtr* is intended for internal use only. | 56+-----------------------------------------+--------------------------------------------------------------------------------+ 57| | **Far** | | 58| | Feature Adaptive Representation | The central interface that processes client-supplied | 59| | `Far Overview <far_overview.html>`__ | geometry and turns it into a serialized data | 60| | representation ready for parallel processing in *Osd*. | 61| | *Far* also provides a fully-featured single-threaded | 62| | implementation of subdivision interpolation algorithms. | 63+-----------------------------------------+--------------------------------------------------------------------------------+ 64| | **Osd** | | 65| | OpenSubdiv cross platform | A suite of classes to provide parallel subdivision | 66| | `Osd Overview <osd_overview.html>`__ | kernels and drawing utilities on a variety of platforms | 67| | such as TBB, CUDA, OpenCL, GLSL and DirectX. | 68+-----------------------------------------+--------------------------------------------------------------------------------+ 69 70Client mesh data enters the API through the Far layer. Typically, results will 71be collected from the Osd layer. However, it is possible to use 72functionality from Far without introducing any dependency on Osd. 73 74Although there are several entry-points to provide topology and primitive variable 75data to OpenSubdiv, eventually everything must pass through the private Vtr and Sdc 76representations for topological analysis. 77 78.. image:: images/api_layers_3_0.png 79 :align: center 80 81Using the Right Tools 82===================== 83 84OpenSubdiv's tiered interface offers a lot flexibility to make your application 85both fast and robust. Because navigating through the large collection of classes and 86features can be challenging, here are use cases that should help sketch 87the broad lines of going about using subdivisions in your application. 88 89General client application requirements: 90 91+----------------------+-------------------------------------------------------+ 92| Surface Limit | For some applications, a polygonal approximation of | 93| | the smooth surface is enough. Others require | 94| | C :sup:`2` continuous differentiable bi-cubic patches | 95| | (ex: deformable displacement mapping, smooth normals | 96| | and semi-sharp creases...) | 97+----------------------+-------------------------------------------------------+ 98| Deforming Surface | Applications such as off-line image renderers often | 99| | process a single frame at a time. Others, such as | 100| | interactive games need to evaluate deforming | 101| | character surface every frame. Because we can amortize| 102| | many computations if the topology of the mesh does not| 103| | change, OpenSubdiv provides 'stencil tables' in order | 104| | to leverage subdivision refinement into a | 105| | pre-computation step. | 106+----------------------+-------------------------------------------------------+ 107| Multi-threading | OpenSubdiv also provides dedicated interfaces to | 108| | leverage parallelism on a wide variety of platforms | 109| | and API standards, including both CPUs and GPUs. | 110+----------------------+-------------------------------------------------------+ 111| GPU Draw | If the application requires interactive drawing on | 112| | screen, OpenSubdiv provides several back-end | 113| | implementations, including D3D11 and OpenGL. These | 114| | back-ends provide full support for programmable | 115| | shading. | 116+----------------------+-------------------------------------------------------+ 117 118 119 120Use case 1: Simple refinement 121============================= 122 123The following example shows the most simple case to get your mesh refined uniformly. 124 125.. image:: images/usecase1_image.png 126 127.. image:: images/usecase1.png 128 :align: center 129 1301. Define a class for the primvar you want to refine. 131 It's required to have Clear() and AddWithWeight() functions. 132 133.. code:: c++ 134 135 struct Vertex { 136 void Clear() { x = y = z = 0; } 137 void AddWithWeight(Vertex const &src, float weight) { 138 x += weight * src.x; 139 y += weight * src.y; 140 z += weight * src.z; 141 } 142 float x, y, z; 143 }; 144 1452. Instantiate a `Far::TopologyRefiner <far_overview.html#far-topologyrefiner>`_ 146from the `Far::TopologyDescriptor <far_overview.html#far-topologyrefinerfactory>`_. 147 148 149.. code:: c++ 150 151 Far::TopologyDescriptor desc; 152 desc.numVertices = <the number of vertices> 153 desc.numFaces = <the number of faces> 154 desc.numVertsPerFace = <array of the number of verts per face> 155 desc.vertIndicesPerFace = <array of vert indices> 156 157 Far::TopologyRefiner * refiner = Far::TopologyRefinerFactory<Descriptor>::Create(desc); 158 1593. Call RefineUniform() to refine the topology up to 'maxlevel'. 160 161.. code:: c++ 162 163 refiner->RefineUniform(Far::TopologyRefiner::UniformOptions(maxlevel)); 164 1654. Interpolate vertex primvar data at 'level' using 166`Far::PrimvarRefiner <far_overview.html#far-primvarrefiner>`_ 167 168.. code:: c++ 169 170 Far::PrimvarRefiner primvarRefiner(*refiner); 171 172 Vertex const *src = <coarse vertices> 173 Vertex *dst = <refined vertices> 174 175 primvarRefiner.Interpolate(level, src, dst); 176 1775. The topology at the refined level can be obtained from Far::TopologyLevel 178 179.. code:: c++ 180 181 Far::TopologyLevel const & refLastLevel = refiner->GetLevel(maxlevel); 182 183 int nverts = refLastLevel.GetNumVertices(); 184 int nfaces = refLastLevel.GetNumFaces(); 185 186 for (int face = 0; face < nfaces; ++face) { 187 Far::ConstIndexArray fverts = refLastLevel.GetFaceVertices(face); 188 189 // do something with dst and fverts 190 } 191 1926. Done! See `Far tutorial 1.1 <far_tutorial_1_1.html>`__ for the complete code example. 193 194Use case 2: GL adaptive tessellation drawing of animating mesh 195============================================================== 196 197The next example is showing how to draw adaptive tessellated patches in GL using OpenSubdiv. 198The osd layer helps you to interact with GL and other device specific APIs. Also for an 199efficient refinement of animating mesh on a static topology, we create a stencil table to 200refine the positions changing over time. 201 202The following example code uses an Osd::GLMesh utility class which composites a stencil 203table, patch table, vertex buffer and evaluator in osd layer. You can also use those classes 204independently. 205 206.. image:: images/usecase2.png 207 :align: center 208 2091. Instantiate a `Far::TopologyRefiner <far_overview.html#far-topologyrefiner>`_ from the 210`Far::TopologyDescriptor <far_overview.html#far-topologyrefinerfactory>`_, same as usecase 1. 211 2122. Setup Osd::Mesh. In this example we use b-spline endcap. 213 214.. code:: c++ 215 216 int numVertexElements = 3; // x, y, z 217 218 Osd::MeshBitset bits; 219 bits.set(Osd::MeshAdaptive, true); // set adaptive 220 bits.set(Osd::MeshEndCapBSplineBasis, true); // use b-spline basis patch for endcap. 221 222 Osd::GLMeshInterface *mesh = new Osd::Mesh<Osd::CpuGLVertexBuffer, Far::StencilTable, 223 Osd::CpuEvaluator, Osd::GLPatchTable> 224 (refiner, numVertexElements, 0, level, bits); 225 2263. Update coarse vertices and refine (Osd::Mesh::Refine() calls 227`Osd::CpuEvaluator::EvalStencils() <osd_overview.html#refinement>`_) 228 229.. code:: c++ 230 231 mesh->UpdateVertexBuffer(&vertex[0], 0, nverts); 232 mesh->Refine(); 233 2344. Bind index buffer, PatchParamBuffer and vertex buffer 235 236.. code:: c++ 237 238 // index buffer 239 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetPatchTable()->GetPatchIndexBuffer()); 240 241 // vertex buffer 242 glBindBuffer(GL_ARRAY_BUFFER, mesh->BindVertexBuffer()); 243 glEnableVertexAttribArray(0); 244 glVertexAttribPointer(0, numVertexElements, GL_FLOAT, GL_FALSE, 245 numVertexElements*sizeof(float), 0); 246 247 // patch param buffer 248 glActiveTexture(GL_TEXTURE0); 249 glBindTexture(GL_TEXTURE_BUFFER, mesh->GetPatchTable()->GetPatchParamTextureBuffer()); 250 2515. Draw. Since we use b-spline endcaps in this example, there is only one PatchArray in the patch table. You may need to iterate patch arrays as you use other type of endcap. To configure GLSL program for each patch type, see `osd shader interface <osd_shader_interface.html>`__ for more details. 252 253.. code:: c++ 254 255 Osd::PatchArray const & patch = mesh->GetPatchTable()->GetPatchArrays()[0]; 256 Far::PatchDescriptor desc = patch.GetDescriptor(); 257 258 int numVertsPerPatch = desc.GetNumControlVertices(); // 16 for B-spline patches 259 glUseProgram(BSplinePatchProgram); 260 glPatchParameteri(GL_PATCH_VERTICES, numVertsPerPatch); 261 glDrawElements(GL_PATCHES, patch.GetNumPatches() * numVertsPerPatch, 262 GL_UNSIGNED_INT, 0); 263 2646. As the mesh animates, repeat from step 3 to update positions, refine, and draw. 265 See `glViewer <glviewer.html>`__ and other examples for more complete usage. 266 267Tutorials and Examples 268====================== 269 270For more use cases, please see `Tutorials <tutorials.html>`_ and `Examples <code_examples.html>`_ 271 272 273