Пример #1
0
//------------------------------------------------------------------------------
int main(int, char **) {

    int maxlevel = 3;

    typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor;

    Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK;

    Sdc::Options options;
    options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
    options.SetFVarLinearInterpolation(Sdc::Options::FVAR_LINEAR_NONE);

    // Populate a topology descriptor with our raw data
    Descriptor desc;
    desc.numVertices  = g_nverts;
    desc.numFaces     = g_nfaces;
    desc.numVertsPerFace = g_vertsperface;
    desc.vertIndicesPerFace  = g_vertIndices;

    // Create a face-varying channel descriptor
    Descriptor::FVarChannel uvs;
    uvs.numValues = g_nuvs;
    uvs.valueIndices = g_uvIndices;

    // Add the channel topology to the main descriptor
    desc.numFVarChannels = 1;
    desc.fvarChannels = & uvs;

    // Instantiate a FarTopologyRefiner from the descriptor
    Far::TopologyRefiner * refiner =
        Far::TopologyRefinerFactory<Descriptor>::Create(desc,
            Far::TopologyRefinerFactory<Descriptor>::Options(type, options));

    // Uniformly refine the topolgy up to 'maxlevel'
    // note: fullTopologyInLastLevel must be true to work with face-varying data
    {
        Far::TopologyRefiner::UniformOptions options(maxlevel);
        options.fullTopologyInLastLevel = true;
        refiner->RefineUniform(options);
    }

    // Allocate & interpolate the 'vertex' primvar data (see tutorial 2 for
    // more details).
    std::vector<Vertex> vbuffer(refiner->GetNumVerticesTotal());
    Vertex * verts = &vbuffer[0];

    int nCoarseVerts = g_nverts;
    for (int i=0; i<nCoarseVerts; ++i) {
        verts[i].SetPosition(g_verts[i][0], g_verts[i][1], g_verts[i][2]);
    }

    refiner->Interpolate(verts, verts + nCoarseVerts);


    // Allocate & interpolate the 'face-varying' primvar data
    int channel = 0,
        nCoarseFVVerts = refiner->GetNumFVarValues(0, channel);

    std::vector<FVarVertex> fvBuffer(refiner->GetNumFVarValuesTotal(channel));
    FVarVertex * fvVerts = &fvBuffer[0];

    for (int i=0; i<g_nuvs; ++i) {
        fvVerts[i].u = g_uvs[i][0];
        fvVerts[i].v = g_uvs[i][1];
    }

    refiner->InterpolateFaceVarying(fvVerts, fvVerts + nCoarseFVVerts, channel);


    { // Output OBJ of the highest level refined -----------

        // Print vertex positions
        for (int level=0, firstVert=0; level<=maxlevel; ++level) {

            if (level==maxlevel) {
                for (int vert=0; vert<refiner->GetNumVertices(level); ++vert) {
                    float const * pos = verts[firstVert+vert].GetPosition();
                    printf("v %f %f %f\n", pos[0], pos[1], pos[2]);
                }
            } else {
                firstVert += refiner->GetNumVertices(level);
            }
        }

        // Print uvs
        for (int level=0, firstVert=0; level<=maxlevel; ++level) {

            if (level==maxlevel) {
                for (int vert=0; vert<refiner->GetNumFVarValues(level, channel); ++vert) {
                    FVarVertex const & uv = fvVerts[firstVert+vert];
                    printf("vt %f %f\n", uv.u, uv.v);
                }
            } else {
                firstVert += refiner->GetNumFVarValues(level, channel);
            }
        }


        // Print faces
        for (int face=0; face<refiner->GetNumFaces(maxlevel); ++face) {

            Far::ConstIndexArray fverts = refiner->GetFaceVertices(maxlevel, face),
                                 fvverts = refiner->GetFVarFaceValues(maxlevel, face, channel);

            // all refined Catmark faces should be quads
            assert(fverts.size()==4 and fvverts.size()==4);

            printf("f ");
            for (int vert=0; vert<fverts.size(); ++vert) {
                // OBJ uses 1-based arrays...
                printf("%d/%d ", fverts[vert]+1, fvverts[vert]+1);
            }
            printf("\n");
        }
    }
}
//------------------------------------------------------------------------------
int main(int, char **) {

    int maxlevel = 5;

    Far::TopologyRefiner * refiner = createFarTopologyRefiner();

    // Uniformly refine the topolgy up to 'maxlevel'
    refiner->RefineUniform( maxlevel );

    // Allocate a buffer for vertex primvar data. The buffer length is set to
    // be the sum of all children vertices up to the highest level of refinement.
    std::vector<Vertex> vbuffer(refiner->GetNumVerticesTotal());
    Vertex * verts = &vbuffer[0];

    // Initialize coarse mesh primvar data
    int nCoarseVerts = g_nverts;
    for (int i=0; i<nCoarseVerts; ++i) {

        verts[i].SetPosition(g_verts[i][0], g_verts[i][1], g_verts[i][2]);

        verts[i].SetColor(g_colors[i][0], g_colors[i][1], g_colors[i][2]);
    }

    // Interpolate all primvar data - not that this will perform both 'vertex' and
    // 'varying' interpolation at once by calling each specialized method in our
    // Vertex class with the appropriate weights.
    refiner->Interpolate(verts, verts + nCoarseVerts);



    { // Visualization with Maya : print a MEL script that generates colored
      // particles at the location of the refined vertices (don't forget to
      // turn shading on in the viewport to see the colors)

        int nverts = refiner->GetNumVertices(maxlevel);

        // Position the 'verts' pointer to the first vertex of our 'maxlevel' level
        for (int level=0; level<maxlevel; ++level) {
            verts += refiner->GetNumVertices(level);
        }

        // Output particle positions
        printf("particle ");
        for (int vert=0; vert<nverts; ++vert) {
            float const * pos = verts[vert].GetPosition();
            printf("-p %f %f %f\n", pos[0], pos[1], pos[2]);
        }
        printf(";\n");

        // Set particle point size (20 -- very large)
        printf("addAttr -is true -ln \"pointSize\" -at long -dv 20 particleShape1;\n");

        // Add per-particle color attribute ('rgbPP')
        printf("addAttr -ln \"rgbPP\" -dt vectorArray particleShape1;\n");

        // Set per-particle color values from our 'varying' primvar data
        printf("setAttr \"particleShape1.rgbPP\" -type \"vectorArray\" %d ", nverts);
        for (int vert=0; vert<nverts; ++vert) {
            float const * color = verts[vert].GetColor();
            printf("%f %f %f\n", color[0], color[1], color[2]);
        }
        printf(";\n");
    }
}