Exemple #1
0
void PackedPatchTable::pack(Far::PatchTable* patch_table, int offset)
{
	num_arrays = 0;
	num_patches = 0;
	num_indices = 0;
	num_nodes = 0;

#ifdef WITH_OPENSUBDIV
	num_arrays = patch_table->GetNumPatchArrays();

	for(int i = 0; i < num_arrays; i++) {
		int patches = patch_table->GetNumPatches(i);
		int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();

		num_patches += patches;
		num_indices += patches * num_control;
	}

	table.resize(total_size());
	uint* data = table.data();

	uint* array = data;
	uint* index = array + num_arrays * PATCH_ARRAY_SIZE;
	uint* param = index + num_indices;
	uint* handle = param + num_patches * PATCH_PARAM_SIZE;

	uint current_param = 0;

	for(int i = 0; i < num_arrays; i++) {
		*(array++) = patch_table->GetPatchArrayDescriptor(i).GetType();
		*(array++) = patch_table->GetNumPatches(i);
		*(array++) = (index - data) + offset;
		*(array++) = (param - data) + offset;

		Far::ConstIndexArray indices = patch_table->GetPatchArrayVertices(i);

		for(int j = 0; j < indices.size(); j++) {
			*(index++) = indices[j];
		}

		const Far::PatchParamTable& param_table = patch_table->GetPatchParamTable();

		int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
		int patches = patch_table->GetNumPatches(i);

		for(int j = 0; j < patches; j++, current_param++) {
			*(param++) = param_table[current_param].field0;
			*(param++) = param_table[current_param].field1;

			*(handle++) = (array - data) - PATCH_ARRAY_SIZE + offset;
			*(handle++) = (param - data) - PATCH_PARAM_SIZE + offset;
			*(handle++) = j * num_control;
		}
	}

	build_patch_map(*this, patch_table, offset);
#else
	(void)patch_table;
	(void)offset;
#endif
}
CpuPatchTable::CpuPatchTable(const Far::PatchTable *farPatchTable) {
    int nPatchArrays = farPatchTable->GetNumPatchArrays();

    // count
    int numPatches = 0;
    int numIndices = 0;
    for (int j = 0; j < nPatchArrays; ++j) {
        int nPatch = farPatchTable->GetNumPatches(j);
        int nCV = farPatchTable->GetPatchArrayDescriptor(j).GetNumControlVertices();
        numPatches += nPatch;
        numIndices += nPatch * nCV;
    }
    _patchArrays.reserve(nPatchArrays);
    _indexBuffer.reserve(numIndices);
    _patchParamBuffer.reserve(numPatches);

    // for each patchArray
    for (int j = 0; j < nPatchArrays; ++j) {
        PatchArray patchArray(farPatchTable->GetPatchArrayDescriptor(j),
                              farPatchTable->GetNumPatches(j),
                              (int)_indexBuffer.size(),
                              (int)_patchParamBuffer.size());
        _patchArrays.push_back(patchArray);

        // indices
        Far::ConstIndexArray indices = farPatchTable->GetPatchArrayVertices(j);
        for (int k = 0; k < indices.size(); ++k) {
            _indexBuffer.push_back(indices[k]);
        }

        // patchParams bundling
        // XXX: this process won't be needed if Far::PatchParam includes
        // sharpness.
#if 0
        // XXX: we need sharpness interface for patcharray or put sharpness
        //      into patchParam.
        Far::ConstPatchParamArray patchParams =
            farPatchTable->GetPatchParams(j);
        for (int k = 0; k < patchParams.size(); ++k) {
            float sharpness = 0.0;
            _patchParamBuffer.push_back(patchParams[k].field0);
            _patchParamBuffer.push_back(patchParams[k].field1);
            _patchParamBuffer.push_back(*((unsigned int *)&sharpness));
        }
#else
        // XXX: workaround. GetPatchParamTable() will be deprecated though.
        Far::PatchParamTable const & patchParamTable =
            farPatchTable->GetPatchParamTable();
        std::vector<Far::Index> const &sharpnessIndexTable =
            farPatchTable->GetSharpnessIndexTable();
        int numPatches = farPatchTable->GetNumPatches(j);
        for (int k = 0; k < numPatches; ++k) {
            float sharpness = 0.0;
            int patchIndex = (int)_patchParamBuffer.size();
            if (patchIndex < (int)sharpnessIndexTable.size()) {
                int sharpnessIndex = sharpnessIndexTable[patchIndex];
                if (sharpnessIndex >= 0)
                    sharpness = farPatchTable->GetSharpnessValues()[sharpnessIndex];
            }
            PatchParam param;
            //param.patchParam = patchParamTable[patchIndex];
            param.field0 = patchParamTable[patchIndex].field0;
            param.field1 = patchParamTable[patchIndex].field1;
            param.sharpness = sharpness;
            _patchParamBuffer.push_back(param);
        }
#endif
    }
}
Exemple #3
0
//------------------------------------------------------------------------------
int main(int, char **) {

    // Generate some FarTopologyRefiner (see far_tutorial_0 for details).
    Far::TopologyRefiner * refiner = createTopologyRefiner();

    // Uniformly refine the topolgy up to 'maxlevel'.
    int maxlevel = 4;
    refiner->RefineUniform(Far::TopologyRefiner::UniformOptions(maxlevel));

    // Use the FarStencilTable factory to create cascading stencil table
    // note: we want stencils for the each refinement level
    //       "cascade" mode is achieved by setting "factorizeIntermediateLevels"
    //       to false
    Far::StencilTableFactory::Options options;
    options.generateIntermediateLevels=true;
    options.factorizeIntermediateLevels=false;
    options.generateOffsets=true;

    Far::StencilTable const * stencilTable =
        Far::StencilTableFactory::Create(*refiner, options);

    std::vector<Vertex> vertexBuffer(refiner->GetNumVerticesTotal()-g_nverts);

    Vertex * destVerts = &vertexBuffer[0];

    int start = 0, end = 0; // stencils batches for each level of subdivision
    for (int level=0; level<maxlevel; ++level) {

        int nverts = refiner->GetLevel(level+1).GetNumVertices();

        Vertex const * srcVerts = reinterpret_cast<Vertex *>(g_verts);
        if (level>0) {
             srcVerts = &vertexBuffer[start];
        }

        start = end;
        end += nverts;

        stencilTable->UpdateValues(srcVerts, destVerts, start, end);
        
        // apply 2 hierarchical edits on level 1 vertices
        if (level==1) {
            float * pos = destVerts[start+5].GetPosition();
            pos[1] += 0.5f;            

            pos = destVerts[start+20].GetPosition();
            pos[0] += 0.25f;
        }
    }


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

        Vertex * verts = &vertexBuffer[0];

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

            Far::TopologyLevel const & refLevel = refiner->GetLevel(level);

            printf("g level_%d\n", level);

            int nverts = refLevel.GetNumVertices();
            for (int vert=0; vert<nverts; ++vert) {
                float const * pos = verts[vert].GetPosition();
                printf("v %f %f %f\n", pos[0], pos[1], pos[2]);
            }
            verts += nverts;
 
            // Print faces
            for (int face=0; face<refLevel.GetNumFaces(); ++face) {

                Far::ConstIndexArray fverts = refLevel.GetFaceVertices(face);

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

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

    delete refiner;
    delete stencilTable;
}
//------------------------------------------------------------------------------
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");
        }
    }
}