diff --git a/examples/projectTest/main.cpp b/examples/projectTest/main.cpp index c4b2270e..964ab435 100644 --- a/examples/projectTest/main.cpp +++ b/examples/projectTest/main.cpp @@ -84,13 +84,19 @@ createOsdMesh(char *inputFile, char *outputFile, std::string *errorMessage) PxOsdUtilSubdivTopology topology; std::vector pointPositions; - if (not topology.ReadFromObjFile(inputFile, &pointPositions, errorMessage)) + if (not topology.ReadFromObjFile(inputFile, &pointPositions, errorMessage)) { return false; + } + topology.refinementLevel = 3; + + std::cout << "Did read topology\n"; + PxOsdUtilUniformEvaluator uniformEvaluator; // Create uniformEvaluator if (not uniformEvaluator.Initialize(topology, errorMessage)) { + std::cout << "Initialize failed with " << *errorMessage << "\n"; return false; } @@ -98,36 +104,40 @@ createOsdMesh(char *inputFile, char *outputFile, std::string *errorMessage) uniformEvaluator.SetCoarsePositions(pointPositions, errorMessage); // Refine with eight threads - if (not uniformEvaluator.Refine(8, errorMessage)) + if (not uniformEvaluator.Refine(8, errorMessage)) { + std::cout << "Refine failed with " << *errorMessage << "\n"; return false; + } std::vector refinedQuads; if (not uniformEvaluator.GetRefinedQuads(&refinedQuads, errorMessage)) { - std::cout << "GetRefinedQuads failed with " << *errorMessage << std::endl; + std::cout << "GetRefinedQuads failed with " << *errorMessage << std::endl; + return false; } float *refinedPositions = NULL; int numFloats = 0; if (not uniformEvaluator.GetRefinedPositions(&refinedPositions, &numFloats, errorMessage)) { - std::cout << "GetRefinedPositions failed with " << *errorMessage << std::endl; + std::cout << "GetRefinedPositions failed with " << *errorMessage << std::endl; + return false; } std::cout << "Quads = " << refinedQuads.size()/4 << std::endl; - for (int i=0; i<(int)refinedQuads.size(); i+=4) { - std::cout << "(" << refinedQuads[i] << - ", " << refinedQuads[i+1] << - ", " << refinedQuads[i+2] << - ", " << refinedQuads[i+3] << - ")\n"; - } +// for (int i=0; i<(int)refinedQuads.size(); i+=4) { +// std::cout << "(" << refinedQuads[i] << +// ", " << refinedQuads[i+1] << +// ", " << refinedQuads[i+2] << +// ", " << refinedQuads[i+3] << +// ")\n"; +// } std::cout << "Hot damn, it worked.\n"; std::cout << "Positions = " << numFloats/3 << std::endl; - for (int i=0; i::Initialize(const PxOsdUtilSubdivTopology &topology, int fvarWidth = _hmesh->GetTotalFVarWidth(); if (_t.fvData.size() < _t.nverts.size() * fvarWidth || fvarWidth != (int)_t.fvNames.size()) { -/*XXX if (errorMessage) - *errorMessage = TfStringPrintf( - "Incorrectly sized face data: name count = %d, " - "data width = %d, face count = %d, total data size = %d.", - (int) _t.fvNames.size(), - fvarWidth, - (int) _t.nverts.size(), - (int) _t.fvData.size()); -*/ - return false; + if (errorMessage) { + stringstream ss; + ss << "Incorrectly sized face data: name count = " << + _t.fvNames.size() << + ", data width = " << fvarWidth << + ", face count = " << _t.nverts.size() << + ", total data size = %d." << _t.fvData.size(); + *errorMessage = ss.str(); + } + return false; } // ptex index is not necessarily the same as the face index @@ -243,8 +243,10 @@ PxOsdUtilMesh::Initialize(const PxOsdUtilSubdivTopology &topology, // names.size() * NumRefinedFaces * 4 template void PxOsdUtilMesh::GetRefinedFVData( - int level, const vector& names, vector* outdata) + const vector& names, vector* outdata) { + int level = _t.refinementLevel; + // First some sanity checking. if (!outdata) { return; diff --git a/opensubdiv/osdutil/mesh.h b/opensubdiv/osdutil/mesh.h index 0abff97b..b2abf0fe 100644 --- a/opensubdiv/osdutil/mesh.h +++ b/opensubdiv/osdutil/mesh.h @@ -74,8 +74,7 @@ class PxOsdUtilMesh { // by a refiner. // XXX: this assumes uniform subdivision, should be moved // into uniformRefiner? - void GetRefinedFVData(int subdivisionLevel, - const std::vector& names, + void GetRefinedFVData(const std::vector& names, std::vector* fvdata); OpenSubdiv::OPENSUBDIV_VERSION::HbrMesh *GetHbrMesh() { return _hmesh;} diff --git a/opensubdiv/osdutil/refiner.cpp b/opensubdiv/osdutil/refiner.cpp index ac888105..24ac2738 100644 --- a/opensubdiv/osdutil/refiner.cpp +++ b/opensubdiv/osdutil/refiner.cpp @@ -29,7 +29,8 @@ #include -#include + +#include using namespace OpenSubdiv; using namespace std; @@ -49,7 +50,6 @@ PxOsdUtilRefiner::PxOsdUtilRefiner(): _numRefinedVerts(0), _numUniformQuads(0), _numPatches(0), - _level(1), _isRefined(false) { } @@ -84,35 +84,19 @@ PxOsdUtilRefiner::Initialize( const PxOsdUtilSubdivTopology &t = _mesh->GetTopology(); if (adaptive) { - std::cout << "\tAdaptive mesh for refiner\n"; FarMeshFactory adaptiveMeshFactory( - _mesh->GetHbrMesh(), t.maxLevels, true); + _mesh->GetHbrMesh(), t.refinementLevel, true); _farMesh = adaptiveMeshFactory.Create(); } else { - std::cout << "\tUniform mesh for refiner, maxLevels = " << t.maxLevels << "\n"; - - HbrMesh *hmesh = _mesh->GetHbrMesh(); - - t.Print(); - - std::cout << "\tHbr mesh has faces " << hmesh->GetNumFaces() << " " << hmesh->GetNumCoarseFaces() << " and vertices " << - hmesh->GetNumVertices() << ", disconnected = " << - hmesh->GetNumDisconnectedVertices() << "\n"; - - hmesh->PrintStats(std::cout); - - - // create the quad tables to include all levels by specifying - // firstLevel as 1 + // XXX:gelder + // Had problems with patchArrayVector in patchTables not working + // unless firstLevel is passed as 1 here. Bug in refiner? FarMeshFactory uniformMeshFactory( - _mesh->GetHbrMesh(), t.maxLevels, false); + _mesh->GetHbrMesh(), t.refinementLevel, false, /*firstLevel*/1); _farMesh = uniformMeshFactory.Create(); - - std::cout << "\tUniform farmesh created with " << t.maxLevels << "\n"; - } // @@ -126,32 +110,33 @@ PxOsdUtilRefiner::Initialize( const FarSubdivisionTables* ftable = _farMesh->GetSubdivisionTables(); - // Find quads array at _level + // Find quads array at given level const FarPatchTables * ptables = _farMesh->GetPatchTables(); const FarPatchTables::PatchArrayVector & parrays = ptables->GetPatchArrayVector(); - if (_level > (int)parrays.size()) { -/*XXX - *errorMessage = TfStringPrintf( - "Invalid size of patch array %d %d\n", - _level, (int)parrays.size());; -*/ + if (t.refinementLevel > (int)parrays.size()) { + if (errorMessage) { + stringstream ss; + ss << "Invalid size of patch array " << t.refinementLevel << " " << + (int)parrays.size(); + *errorMessage = ss.str(); + } return false; } // parrays doesn't contain base mesh, so it starts with level==1 - const FarPatchTables::PatchArray & parray = parrays[_level-1]; + const FarPatchTables::PatchArray & parray = parrays[t.refinementLevel-1]; _patchParamTable = &(ptables->GetPatchParamTable()); // Global index of the first point in this array - _firstVertexOffset = ftable->GetFirstVertexOffset(_level); + _firstVertexOffset = ftable->GetFirstVertexOffset(t.refinementLevel); // Global index of the first face (patch) in this array _firstPatchOffset = parray.GetPatchIndex(); - _numRefinedVerts = (int) ftable->GetNumVertices(_level); + _numRefinedVerts = (int) ftable->GetNumVertices(t.refinementLevel); std::cout << "refiner has " << _numRefinedVerts << " refined verts\n"; if (adaptive) { @@ -191,7 +176,8 @@ PxOsdUtilRefiner::GetRefinedQuads( quads->resize(_numUniformQuads * 4); const FarPatchTables * ptables = _farMesh->GetPatchTables(); - const unsigned int *quadIndices = ptables->GetFaceVertices(_level); + const unsigned int *quadIndices = + ptables->GetFaceVertices(_mesh->GetTopology().refinementLevel); for (int i=0; i<_numUniformQuads*4; ++i) { (*quads)[i] = quadIndices[i] - _firstVertexOffset; @@ -252,11 +238,13 @@ PxOsdUtilRefiner::GetRefinedPtexUvs(vector* subfaceUvs, const FarPatchTables * ptables = _farMesh->GetPatchTables(); const FarPatchTables::PatchArrayVector & parrays = ptables->GetPatchArrayVector(); - if (_level > (int)parrays.size()) { + int refinementLevel = _mesh->GetTopology().refinementLevel; + + if (refinementLevel > (int)parrays.size()) { if (errorMessage) *errorMessage = "Invalid size of patch array"; } - const FarPatchTables::PatchArray & parray = parrays[_level-1]; + const FarPatchTables::PatchArray & parray = parrays[refinementLevel-1]; const FarPatchTables::PatchParamTable& paramTable = ptables->GetPatchParamTable(); diff --git a/opensubdiv/osdutil/refiner.h b/opensubdiv/osdutil/refiner.h index 61dde92f..7107619c 100644 --- a/opensubdiv/osdutil/refiner.h +++ b/opensubdiv/osdutil/refiner.h @@ -83,10 +83,9 @@ class PxOsdUtilRefiner { // Fetch the face varying attribute values on refined quads // Calls through to the lower level mesh class to extract // face varying data from hbr. - void GetRefinedFVData(int subdivisionLevel, - const std::vector& names, + void GetRefinedFVData(const std::vector& names, std::vector* fvdata) { - _mesh->GetRefinedFVData(subdivisionLevel, names, fvdata); + _mesh->GetRefinedFVData(names, fvdata); } // Const access to far mesh @@ -112,7 +111,7 @@ class PxOsdUtilRefiner { // If true, feature adaptive refinement is used and _farMesh // is populated with bspline and gregory patches. // if false, uniform refinement is used by subdividing the entire - // mesh _level times. + // mesh N times. bool _adaptive; // The next block of member variables are the OpenSubdiv meshe @@ -145,8 +144,6 @@ class PxOsdUtilRefiner { int _numUniformQuads; // zero if adaptive = true int _numPatches; // zero if adaptive = false - int _level; - bool _isRefined; }; diff --git a/opensubdiv/osdutil/topology.cpp b/opensubdiv/osdutil/topology.cpp index 80ec8ed0..ec354c8d 100644 --- a/opensubdiv/osdutil/topology.cpp +++ b/opensubdiv/osdutil/topology.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include using namespace std; @@ -33,7 +34,7 @@ using namespace std; PxOsdUtilSubdivTopology::PxOsdUtilSubdivTopology(): name("noname"), numVertices(0), - maxLevels(2) // arbitrary, start with a reasonable subdivision level + refinementLevel(2) // arbitrary, start with a reasonable subdivision level { std::cout << "Creating subdiv topology object\n"; } @@ -53,7 +54,7 @@ PxOsdUtilSubdivTopology::Initialize( { numVertices = numVerticesParam; - maxLevels = levels; + refinementLevel = levels; nverts.resize(numFaces); for (int i=0; isize()/3; + numVertices = pointPositions->size()/3; return true; } diff --git a/opensubdiv/osdutil/topology.h b/opensubdiv/osdutil/topology.h index f0c5b33b..35947daf 100644 --- a/opensubdiv/osdutil/topology.h +++ b/opensubdiv/osdutil/topology.h @@ -56,7 +56,7 @@ class PxOsdUtilSubdivTopology { // XXX Would be great for these members to be private with accessors std::string name; int numVertices; - int maxLevels; + int refinementLevel; std::vector indices; std::vector nverts; std::vector vvNames; diff --git a/opensubdiv/osdutil/uniformEvaluator.cpp b/opensubdiv/osdutil/uniformEvaluator.cpp index 261d0407..82eb844a 100644 --- a/opensubdiv/osdutil/uniformEvaluator.cpp +++ b/opensubdiv/osdutil/uniformEvaluator.cpp @@ -122,7 +122,7 @@ PxOsdUtilUniformEvaluator::Initialize( } // No need to create a far mesh if no subdivision is required. - if (_refiner->GetTopology().maxLevels == 0) { + if (_refiner->GetTopology().refinementLevel == 0) { // Three elements per unrefined point _vertexBuffer = OsdCpuVertexBuffer::Create( diff --git a/opensubdiv/osdutil/uniformEvaluator.h b/opensubdiv/osdutil/uniformEvaluator.h index 6803e2cd..aabd62ae 100644 --- a/opensubdiv/osdutil/uniformEvaluator.h +++ b/opensubdiv/osdutil/uniformEvaluator.h @@ -111,10 +111,10 @@ class PxOsdUtilUniformEvaluator { // Fetch the face varying attribute values on refined quads, call // through to the refiner but keep in evaluator API for // one-stop-service for user API - void GetRefinedFVData(int subdivisionLevel, + void GetRefinedFVData( const std::vector& names, std::vector* fvdata) { - _refiner->GetRefinedFVData(subdivisionLevel, names, fvdata); + _refiner->GetRefinedFVData(names, fvdata); }