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