far_tutorial_4_3.cpp
System Message: WARNING/2 (/construction/graphics/opensubdiv/.build/documentation/far_tutorial_4_3.rst, line 9)
Cannot analyze code. Pygments package not found.
.. code:: c //------------------------------------------------------------------------------ // Tutorial description: // // This tutorial shows how to create and manipulate table of cascading stencils. // // We initialize a Far::TopologyRefiner with a cube and apply uniform // refinement. We then use a Far::StencilTableFactory to generate a stencil // table. We set the factory Options to not factorize intermediate levels, // thus giving a table of "cascading" stencils. // // We then apply the stencils to the vertex position primvar data, and insert // a hierarchical edit at level 1. This edit is smoothed by the application // of the subsequent stencil cascades. // // The results are dumped into an OBJ file that shows the intermediate levels // of refinement of the original cube. // #include <opensubdiv/far/topologyDescriptor.h> #include <opensubdiv/far/stencilTable.h> #include <opensubdiv/far/stencilTableFactory.h> #include <cstdio> #include <cstring> //------------------------------------------------------------------------------ // Vertex container implementation. // struct Vertex { // Minimal required interface ---------------------- Vertex() { } 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]; } // Public interface ------------------------------------ void SetPosition(float x, float y, float z) { _position[0]=x; _position[1]=y; _position[2]=z; } float const * GetPosition() const { return _position; } float * GetPosition() { return _position; } private: float _position[3]; }; //------------------------------------------------------------------------------ // Cube geometry from catmark_cube.h static float g_verts[24] = {-0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f }; static int g_nverts = 8, g_nfaces = 6; static int g_vertsperface[6] = { 4, 4, 4, 4, 4, 4 }; static int g_vertIndices[24] = { 0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4 }; using namespace OpenSubdiv; static Far::TopologyRefiner * createTopologyRefiner(); //------------------------------------------------------------------------------ int main(int, char **) { // Generate a Far::TopologyRefiner (see tutorial_1_1 for details). Far::TopologyRefiner * refiner = createTopologyRefiner(); // Uniformly refine the topology up to 'maxlevel'. int maxlevel = 4; refiner->RefineUniform(Far::TopologyRefiner::UniformOptions(maxlevel)); // Use the Far::StencilTable factory to create cascading stencil table // note: we want stencils for 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; // stencil 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; } //------------------------------------------------------------------------------ static Far::TopologyRefiner * createTopologyRefiner() { // Populate a topology descriptor with our raw data. typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; Sdc::Options options; options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY); Descriptor desc; desc.numVertices = g_nverts; desc.numFaces = g_nfaces; desc.numVertsPerFace = g_vertsperface; desc.vertIndicesPerFace = g_vertIndices; // Instantiate a Far::TopologyRefiner from the descriptor. return Far::TopologyRefinerFactory<Descriptor>::Create(desc, Far::TopologyRefinerFactory<Descriptor>::Options(type, options)); } //------------------------------------------------------------------------------
Generated on: 2021-04-14 09:48 UTC.