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