https://github.com/PixarAnimationStudios/OpenSubdiv/blob/release/tutorials/hbr/tutorial_2/hbr_tutorial_2.cpp
  
struct Vertex {
        Vertex() { }
    Vertex(int ) { }
    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) { }
        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,            firstface=0,           firstvertex=0; 
        for (int level=0; level<maxlevel; ++level) {
                                int nfaces = hmesh->GetNumFaces();
        if (level==(maxlevel-1)) {
                        firstvertex = hmesh->GetNumVertices();
        }
                for (int face=firstface; face<nfaces; ++face) {
            Hface * f = hmesh->GetFace(face);
                        f->Refine();
        }
                firstface = nfaces;
    }
    { 
                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]);
        }
                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) {
                                printf("%d ", f->GetVertex(vert)->GetID() - firstvertex + 1);
            }
            printf("\n");
        }
    }
}
Hmesh *
createMesh() {
        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);
        Vertex v;
    for (int i=0; i<nverts; ++i) {
        v.SetPosition(verts[i][0], verts[i][1], verts[i][2]);
        hmesh->NewVertex(i, v);
    }
        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);
                        if (origin==NULL || destination==NULL) {
                printf(" An edge was specified that connected a nonexistent vertex\n");
                valid=false;
                break;
            }
                        if (origin == destination) {
                printf(" An edge was specified that connected a vertex to itself\n");
                valid=false;
                break;
            }
                        if (opposite && opposite->GetOpposite() ) {
                printf(" A non-manifold edge incident to more than 2 faces was found\n");
                valid=false;
                break;
            }
                        if (origin->GetEdge(destination)) {
                printf(" An edge connecting two vertices was specified more than once."
                       " It's 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;
}