Exemple #1
0
//------------------------------------------------------------------------------
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
        //
        // Mote: 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);

            // Mote : 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");
        }
    }

}
Exemple #2
0
//------------------------------------------------------------------------------
// 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 or 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 and 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."
                       " 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;
}
//------------------------------------------------------------------------------
static void
createHbrMesh(Shape * shape, int maxlevel) {

    Stopwatch s;
    s.Start();

    // create Hbr mesh using functions from hbr_utils
    Hmesh * hmesh = createMesh<Vertex>(shape->scheme, /*fvarwidth*/ 0);

    createVerticesWithPositions<Vertex>(shape, hmesh);

    createTopology<Vertex>(shape, hmesh, shape->scheme);
    s.Stop();

    std::vector<Hface const *>   coarseFaces,  // list of Hbr coarse faces
                                 refinedFaces; // list of Hbr faces refined at maxlevel

    int nfaces = hmesh->GetNumFaces();

    { // create control cage GL mesh
        coarseFaces.resize(nfaces);
        for (int i=0; i<nfaces; ++i) {
            coarseFaces[i] = hmesh->GetFace(i);
        }

        GLMesh::Options coarseOptions;
        coarseOptions.vertColorMode=GLMesh::VERTCOLOR_BY_SHARPNESS;
        coarseOptions.edgeColorMode=GLMesh::EDGECOLOR_BY_SHARPNESS;
        coarseOptions.faceColorMode=GLMesh::FACECOLOR_SOLID;

        g_base_glmesh.Initialize(coarseOptions, coarseFaces);
        g_base_glmesh.InitializeDeviceBuffers();
    }

    { // create maxlevel refined GL mesh
        s.Start();

        OpenSubdiv::Far::PatchTables const * patchTables = 0;

        if (g_Adaptive) {
            int maxvalence = RefineAdaptive(*hmesh, maxlevel, refinedFaces);

            patchTables = CreatePatchTables(*hmesh, maxvalence);

            patchTables->GetNumPatches();

            delete patchTables;
        } else {
            RefineUniform(*hmesh, maxlevel, refinedFaces);
        }

        s.Stop();
        //printf("Hbr time: %f ms\n", float(s.GetElapsed())*1000.0f);

        if (g_HbrDrawVertIDs) {
            createVertNumbers(refinedFaces);
        }

        // Hbr is a half-edge rep, so edges do not have unique IDs that
        // can be displayed

        if (g_HbrDrawEdgeSharpness) {
            createEdgeNumbers(refinedFaces);
        }

        if (g_HbrDrawFaceIDs) {
            createFaceNumbers(refinedFaces, /*ptex*/ false);
        }

        if (g_HbrDrawPtexIDs) {
            createFaceNumbers(refinedFaces, /*ptex*/ true);
        }

        GLMesh::Options refinedOptions;
        refinedOptions.vertColorMode=GLMesh::VERTCOLOR_BY_SHARPNESS;
        refinedOptions.edgeColorMode=GLMesh::EDGECOLOR_BY_SHARPNESS;
        refinedOptions.faceColorMode=GLMesh::FACECOLOR_SOLID;

        g_hbr_glmesh.Initialize(refinedOptions, refinedFaces);
        g_hbr_glmesh.SetDiffuseColor(1.0f,0.75f,0.9f, 1.0f);
    }

    g_hbr_glmesh.InitializeDeviceBuffers();

    delete hmesh;
}