//------------------------------------------------------------------------------
// generate display IDs for Vtr verts
static void
createVertNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer) {

    int maxlevel = refiner.GetMaxLevel(),
        firstvert = 0;

    if (refiner.IsUniform()) {
        for (int i=0; i<maxlevel; ++i) {
            firstvert += refiner.GetNumVertices(i);
        }
    }

    static char buf[16];
    if (refiner.IsUniform()) {
        for (int i=firstvert; i<(int)vertexBuffer.size(); ++i) {
            snprintf(buf, 16, "%d", i);
            g_font->Print3D(vertexBuffer[i].GetPos(), buf, 1);
        }
    } else {

        for (int level=0, vert=0; level<=refiner.GetMaxLevel(); ++level) {
            for (int i=0; i<refiner.GetNumVertices(level); ++i, ++vert) {
                snprintf(buf, 16, "%d", i);
                g_font->Print3D(vertexBuffer[vert].GetPos(), buf, 1);
            }
        }
    }
}
//------------------------------------------------------------------------------
// generate display IDs for Vtr faces
static void
createFaceNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer) {

    static char buf[16];

    if (refiner.IsUniform()) {
        int maxlevel = refiner.GetMaxLevel(),
            firstvert = 0;

        for (int i=0; i<maxlevel; ++i) {
            firstvert += refiner.GetNumVertices(i);
        }

        for (int face=0; face<refiner.GetNumFaces(maxlevel); ++face) {

            Vertex center(0.0f, 0.0f, 0.0f);

            OpenSubdiv::Far::IndexArray const verts =
                refiner.GetFaceVertices(maxlevel, face);

            float weight = 1.0f / (float)verts.size();

            for (int vert=0; vert<verts.size(); ++vert) {
                center.AddWithWeight(vertexBuffer[firstvert+verts[vert]], weight);
            }

            snprintf(buf, 16, "%d", face);
            g_font->Print3D(center.GetPos(), buf, 2);
        }
    } else {
        int maxlevel = refiner.GetMaxLevel(),
//            patch = refiner.GetNumFaces(0),
            firstvert = refiner.GetNumVertices(0);

        for (int level=1; level<=maxlevel; ++level) {

            int nfaces = refiner.GetNumFaces(level);

            for (int face=0; face<nfaces; ++face /*, ++patch */) {

                Vertex center(0.0f, 0.0f, 0.0f);

                OpenSubdiv::Far::IndexArray const verts =
                    refiner.GetFaceVertices(level, face);

                float weight = 1.0f / (float)verts.size();

                for (int vert=0; vert<verts.size(); ++vert) {
                    center.AddWithWeight(vertexBuffer[firstvert+verts[vert]], weight);
                }
                snprintf(buf, 16, "%d", face);
                g_font->Print3D(center.GetPos(), buf, 2);
            }
            firstvert+=refiner.GetNumVertices(level);
        }
    }
}
//------------------------------------------------------------------------------
// generate display IDs for Vtr edges
static void
createEdgeNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer, bool ids=false, bool sharpness=false) {

    if (ids or sharpness) {

        int maxlevel = refiner.GetMaxLevel(),
            firstvert = 0;

        for (int i=0; i<maxlevel; ++i) {
            firstvert += refiner.GetNumVertices(i);
        }

        static char buf[16];
        for (int i=0; i<refiner.GetNumEdges(maxlevel); ++i) {

            Vertex center(0.0f, 0.0f, 0.0f);

            OpenSubdiv::Far::IndexArray const verts =
                refiner.GetEdgeVertices(maxlevel, i);
            assert(verts.size()==2);

            center.AddWithWeight(vertexBuffer[firstvert+verts[0]], 0.5f);
            center.AddWithWeight(vertexBuffer[firstvert+verts[1]], 0.5f);

            if (ids) {
                snprintf(buf, 16, "%d", i);
                g_font->Print3D(center.GetPos(), buf, 3);
            }

            if (sharpness) {
                float sharpness = refiner.GetEdgeSharpness(maxlevel, i);
                if (sharpness>0.0f) {
                    snprintf(buf, 16, "%g", sharpness);
                    g_font->Print3D(center.GetPos(), buf, std::min(8,(int)sharpness+4));
                }
            }
        }
    }
}
示例#4
0
static void
createMesh(ShapeDesc const & shapeDesc, int level) {

    typedef Far::ConstIndexArray IndexArray;
    typedef Far::LimitStencilTablesFactory::LocationArray LocationArray;

    Shape const * shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme);

    // create Vtr mesh (topology)
    OpenSubdiv::Sdc::SchemeType sdctype = GetSdcType(*shape);
    OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape);

    OpenSubdiv::Far::TopologyRefiner * refiner =
        OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(*shape,
            OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions));

    // save coarse topology (used for coarse mesh drawing)
    int nedges = refiner->GetNumEdges(0),
        nverts = refiner->GetNumVertices(0);

    g_coarseEdges.resize(nedges*2);
    g_coarseEdgeSharpness.resize(nedges);
    g_coarseVertexSharpness.resize(nverts);

    for(int i=0; i<nedges; ++i) {
        IndexArray verts = refiner->GetEdgeVertices(0, i);
        g_coarseEdges[i*2  ]=verts[0];
        g_coarseEdges[i*2+1]=verts[1];
        g_coarseEdgeSharpness[i]=refiner->GetEdgeSharpness(0, i);
    }

    for(int i=0; i<nverts; ++i) {
        g_coarseVertexSharpness[i]=refiner->GetVertexSharpness(0, i);
    }

    g_orgPositions=shape->verts;

    if (g_bilinear) {
        Far::TopologyRefiner::UniformOptions options(level);
        options.fullTopologyInLastLevel = true;
        refiner->RefineUniform(options);
    } else {
        Far::TopologyRefiner::AdaptiveOptions options(level);
        options.fullTopologyInLastLevel = false;
        options.useSingleCreasePatch = false;
        refiner->RefineAdaptive(options);
    }

    int nfaces = refiner->GetNumPtexFaces();

    float * u = new float[g_nsamples*nfaces], * uPtr = u,
          * v = new float[g_nsamples*nfaces], * vPtr = v;

    std::vector<LocationArray> locs(nfaces);

    srand( static_cast<int>(2147483647) ); // use a large Pell prime number
    for (int face=0; face<nfaces; ++face) {

        LocationArray & larray = locs[face];
        larray.ptexIdx = face;
        larray.numLocations = g_nsamples;
        larray.s = uPtr;
        larray.t = vPtr;

        for (int j=0; j<g_nsamples; ++j, ++uPtr, ++vPtr) {
            *uPtr = (float)rand()/(float)RAND_MAX;
            *vPtr = (float)rand()/(float)RAND_MAX;
        }
    }

    delete g_controlStencils;
    g_controlStencils = Far::LimitStencilTablesFactory::Create(*refiner, locs);

    delete [] u;
    delete [] v;

    g_nsamplesDrawn = g_controlStencils->GetNumStencils();

    // Create control vertex buffer (layout: [ P(xyz) ] )
    delete g_controlValues;
    g_controlValues = Osd::CpuVertexBuffer::Create(3, nverts);

    // Create eval context & data buffers
    delete g_evalCtx;
    g_evalCtx = Osd::CpuEvalStencilsContext::Create(g_controlStencils);

    delete g_stencilValues;
    g_stencilValues = Osd::CpuGLVertexBuffer::Create(3, g_controlStencils->GetNumStencils() * 6 );

    delete shape;
    delete refiner;

    updateGeom();

    // Bind g_stencilValues as GL_LINES VAO
    glBindVertexArray(g_stencilsVAO);

    glBindBuffer(GL_ARRAY_BUFFER, g_stencilValues->BindVBO());

    glBindVertexArray(0);

}