Adding visualization ability for Gregory patch basis to vtrViewer

This commit is contained in:
manuelk 2014-10-31 17:09:20 -07:00
parent 17c682f055
commit 9ee67664ae
3 changed files with 205 additions and 24 deletions

View File

@ -134,24 +134,6 @@ GLMesh::~GLMesh() {
}
}
//------------------------------------------------------------------------------
void
GLMesh::Initialize(Options options, TopologyRefiner const & refiner,
PatchTables const * patchTables, float const * vertexData) {
if (patchTables) {
initializeBuffers(options, refiner, *patchTables, vertexData);
} else {
initializeBuffers(options, refiner, vertexData);
}
_numComps[COMP_FACE] = (int)_eao[COMP_FACE].size();
_numComps[COMP_EDGE] = (int)_eao[COMP_EDGE].size();
_numComps[COMP_VERT] = (int)_eao[COMP_VERT].size();
InitializeDeviceBuffers();
}
//------------------------------------------------------------------------------
void
GLMesh::initializeVertexComponentBuffer(float const * vertData, int nverts) {
@ -172,6 +154,110 @@ GLMesh::initializeVertexComponentBuffer(float const * vertData, int nverts) {
}
}
//------------------------------------------------------------------------------
void
GLMesh::Initialize(Options options,
int nverts, int nfaces, int * vertsperface, int * faceverts,
float const * vertexData) {
{ // vertex color component ----------------------------
initializeVertexComponentBuffer(vertexData, nverts);
std::vector<float> & vbo = _vbo[COMP_VERT];
for (int vert=0, ofs=3; vert<nverts; ++vert) {
setSolidColor(&vbo[ofs+=6]);
}
}
{ // edge color component ------------------------------
int nedges = nfaces;
std::vector<float> & vbo = _vbo[COMP_EDGE];
vbo.resize(nedges * 2 * 6);
std::vector<int> & eao = _eao[COMP_EDGE];
eao.resize(nedges*2);
for (int edge=0; edge<nedges; ++edge) {
// edge mode expects faces with 2 verts (aka edges) as input
assert(vertsperface[edge]==2);
eao[edge*2 ] = edge*2;
eao[edge*2+1] = edge*2+1;
int const * verts = faceverts + edge*2;
float * v0 = &vbo[edge*2*6],
* v1 = v0+6;
// copy position
memcpy(v0, vertexData + verts[0]*3, sizeof(float)*3);
memcpy(v1, vertexData + verts[1]*3, sizeof(float)*3);
// default to solid color
setSolidColor(v0+3);
setSolidColor(v1+3);
}
}
{ // face component ------------------------------------
std::vector<float> & vbo = _vbo[COMP_FACE];
vbo.resize(nverts * 3);
memcpy(&vbo[0], vertexData, nverts*sizeof(float)*3);
int nfaceverts = 0;
for (int i=0; i<nfaces; ++i) {
nfaceverts += vertsperface[i];
}
std::vector<int> & eao = _eao[COMP_FACE];
eao.resize(nfaceverts);
_faceColors.resize(nfaces*4);
int const * fverts = faceverts;
for (int face=0, ofs=0; face<nfaces; ++face) {
int nverts = vertsperface[face];
for (int vert=0; vert<nverts; ++vert) {
eao[ofs++] = fverts[vert];
}
setSolidColor(&_faceColors[face*4]);
fverts += nverts;
}
}
_numComps[COMP_FACE] = (int)_eao[COMP_FACE].size();
_numComps[COMP_EDGE] = (int)_eao[COMP_EDGE].size();
_numComps[COMP_VERT] = (int)_eao[COMP_VERT].size();
InitializeDeviceBuffers();
}
//------------------------------------------------------------------------------
void
GLMesh::Initialize(Options options, TopologyRefiner const & refiner,
PatchTables const * patchTables, float const * vertexData) {
if (patchTables) {
initializeBuffers(options, refiner, *patchTables, vertexData);
} else {
initializeBuffers(options, refiner, vertexData);
}
_numComps[COMP_FACE] = (int)_eao[COMP_FACE].size();
_numComps[COMP_EDGE] = (int)_eao[COMP_EDGE].size();
_numComps[COMP_VERT] = (int)_eao[COMP_VERT].size();
InitializeDeviceBuffers();
}
//------------------------------------------------------------------------------
void
GLMesh::initializeBuffers(Options options,

View File

@ -71,6 +71,13 @@ public:
faceColorMode:3;
};
// -----------------------------------------------------
// Raw topology initialization
void Initialize(Options options,
int nverts, int nfaces, int * vertsperface, int * faceverts,
float const * vertexData);
// -----------------------------------------------------
// Hbr initialization
template <class T>

View File

@ -50,6 +50,7 @@ GLFWmonitor* g_primary=0;
#include <osd/vertex.h>
#include <osd/cpuGLVertexBuffer.h>
#include <far/gregoryBasis.h>
#include <far/patchTablesFactory.h>
#include <far/stencilTables.h>
#include <far/stencilTablesFactory.h>
@ -77,7 +78,7 @@ GLFWmonitor* g_primary=0;
//------------------------------------------------------------------------------
int g_level = 2,
g_currentShape = 0;
g_currentShape = 18;
enum HudCheckBox { kHUD_CB_DISPLAY_CAGE_EDGES,
kHUD_CB_DISPLAY_CAGE_VERTS,
@ -101,7 +102,8 @@ int g_fullscreen = 0,
int g_displayPatchColor = 1,
g_drawCageEdges = 1,
g_drawCageVertices = 0,
g_HbrDrawMode = kDRAW_NONE,
g_drawGregoryBasis = true,
g_HbrDrawMode = kDRAW_WIREFRAME,
g_HbrDrawVertIDs = false,
g_HbrDrawEdgeSharpness = false,
g_HbrDrawFaceIDs = false,
@ -114,7 +116,7 @@ int g_displayPatchColor = 1,
g_VtrDrawEdgeSharpness = false,
g_numPatches = 0,
g_currentPatch = 0,
g_Adaptive = false;
g_Adaptive = true;
OpenSubdiv::Far::PatchTables::Descriptor g_currentPatchDesc;
@ -492,7 +494,7 @@ createFaceNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
}
//------------------------------------------------------------------------------
// generate display IDs for Vtr faces
// generate display vert IDs for the selected Vtr patch
static void
createPatchNumbers(OpenSubdiv::Far::PatchTables const & patchTables,
std::vector<Vertex> const & vertexBuffer) {
@ -537,6 +539,83 @@ createPatchNumbers(OpenSubdiv::Far::PatchTables const & patchTables,
}
}
//------------------------------------------------------------------------------
// generate display IDs for Vtr Gregory basis
static GLMesh gregoryWire;
static void
createGregoryBasis(OpenSubdiv::Far::TopologyRefiner const & refiner,
std::vector<Vertex> const & vertexBuffer) {
int level = refiner.GetMaxLevel(),
nfaces = refiner.GetNumFaces(level);
int vertOffset = 0;
for (int i=0; i<level; ++i) {
vertOffset += refiner.GetNumVertices(i);
}
std::vector<int> vertsperedge, edgeindices;
std::vector<Vertex> edgeverts;
for (int face=0; face<nfaces; ++face) {
bool regular = refiner.FaceIsRegular(level, face);
if (not regular) {
OpenSubdiv::Far::GregoryBasis const * gbasis =
OpenSubdiv::Far::GregoryBasisFactory::Create(refiner, face);
{ // initialize wireframe
static int basisedges[40] = { 0, 1, 0, 2, 1, 3, 2, 4,
5, 6, 5, 7, 6, 8, 7, 9,
10, 11, 10, 12, 11, 13, 12, 14,
15, 16, 15, 17, 16, 18, 17, 19,
1, 7, 6, 12, 11, 17, 16, 2 };
int nedges = (int)vertsperedge.size();
vertsperedge.resize(nedges+20);
edgeindices.resize(nedges*2+40);
int * vpe = &vertsperedge[nedges],
* ev = &edgeindices[nedges*2];
for (int i=0; i<20; ++i) {
vpe[i] = 2;
ev[i*2] = basisedges[i*2] + nedges;
ev[i*2+1] = basisedges[i*2+1] + nedges;
}
}
std::vector<Vertex> gverts(20);
gbasis->Evaluate(&vertexBuffer[vertOffset], &gverts[0]);
static char buf[16];
for (int i=0; i<4; ++i) {
int vid = i * 5;
snprintf(buf, 16, " P%d", i);
g_font->Print3D(gverts[vid].GetPos(), buf, 3);
snprintf(buf, 16, " Ep%d", i);
g_font->Print3D(gverts[vid+1].GetPos(), buf, 3);
snprintf(buf, 16, " Em%d", i);
g_font->Print3D(gverts[vid+2].GetPos(), buf, 3);
snprintf(buf, 16, " Fp%d", i);
g_font->Print3D(gverts[vid+3].GetPos(), buf, 3);
snprintf(buf, 16, " Fm%d", i);
g_font->Print3D(gverts[vid+4].GetPos(), buf, 3);
}
delete gbasis;
edgeverts.insert(edgeverts.end(), gverts.begin(), gverts.end());
}
}
GLMesh::Options options;
gregoryWire.Initialize(options, (int)edgeverts.size(), (int)vertsperedge.size(),
&vertsperedge[0], &edgeindices[0], (float const * )&edgeverts[0]);
}
//------------------------------------------------------------------------------
// generate display IDs for Vtr faces
static void
@ -671,10 +750,14 @@ createVtrMesh(Shape * shape, int maxlevel) {
createPtexNumbers(*patchTables, vertexBuffer);
}
if (g_Adaptive and patchTables) {
if (g_Adaptive and g_drawGregoryBasis) {
createPatchNumbers(*patchTables, vertexBuffer);
}
if (g_Adaptive and g_drawGregoryBasis) {
createGregoryBasis(*refiner, vertexBuffer);
}
createEdgeNumbers(*refiner, vertexBuffer, g_VtrDrawEdgeIDs!=0, g_VtrDrawEdgeSharpness!=0);
GLMesh::Options options;
@ -845,6 +928,11 @@ display() {
g_vtr_glmesh.Draw(comp, g_transformUB, g_lightingUB);
}
if (g_Adaptive and g_drawGregoryBasis) {
gregoryWire.Draw(GLMesh::COMP_VERT, g_transformUB, g_lightingUB);
gregoryWire.Draw(GLMesh::COMP_EDGE, g_transformUB, g_lightingUB);
}
assert(g_font);
g_font->Draw(g_transformUB);
@ -866,7 +954,7 @@ display() {
double fps = 1.0/g_fpsTimer.GetElapsed();
g_fpsTimer.Start();
{ // display selectde patch info
{ // display selected patch info
static char const * patchTypes[12] = { "undefined", "points", "lines",
"quads", "tris", "loop", "regular", "single crease", "boundary", "corner",
"gregory", "gregory-boundary" };