# hbr_tutorial_0.cpp

https://github.com/PixarAnimationStudios/OpenSubdiv/blob/release/tutorials/hbr/tutorial_0/hbr_tutorial_0.cpp

System Message: WARNING/2 (`/build/opensubdiv/src/OpenSubdiv-3_6_1/build/documentation/hbr_tutorial_0.rst`, line 9)

Cannot analyze code. Pygments package not found.

    .. code:: c++

        //------------------------------------------------------------------------------
        // Tutorial description:
        //
        // This tutorial presents in a very succinct way the requisite steps to
        // instantiate an Hbr mesh from simple topological data.
        //

        #include <opensubdiv/hbr/mesh.h>
        #include <opensubdiv/hbr/catmark.h>

        #include <cstdio>

        //------------------------------------------------------------------------------
        // Vertex container implementation.
        //
        // The HbrMesh<T> 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;
        }

        //------------------------------------------------------------------------------

- User Docs
- API Docs
- Release Notes
- Forum

TM & © 1986 - 2017 PIXAR. ALL RIGHTS RESERVED. Terms of Use