Fixed problem with refinement level being hardwired to 1, fixed error messages,

other improvements.
This commit is contained in:
gelder 2013-11-06 14:00:29 -08:00
parent 9ad6b117c7
commit def6542192
9 changed files with 76 additions and 79 deletions

View File

@ -84,13 +84,19 @@ createOsdMesh(char *inputFile, char *outputFile, std::string *errorMessage)
PxOsdUtilSubdivTopology topology;
std::vector<float> 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<int> 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<numFloats; i+=3) {
std::cout << "(" << refinedPositions[i] <<
", " << refinedPositions[i+1] <<
"," << refinedPositions[i+2] << ")\n";
}
// for (int i=0; i<numFloats; i+=3) {
// std::cout << "(" << refinedPositions[i] <<
// ", " << refinedPositions[i+1] <<
// "," << refinedPositions[i+2] << ")\n";
// }

View File

@ -113,16 +113,16 @@ PxOsdUtilMesh<T>::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<T>::Initialize(const PxOsdUtilSubdivTopology &topology,
// names.size() * NumRefinedFaces * 4
template <class T> void
PxOsdUtilMesh<T>::GetRefinedFVData(
int level, const vector<string>& names, vector<float>* outdata)
const vector<string>& names, vector<float>* outdata)
{
int level = _t.refinementLevel;
// First some sanity checking.
if (!outdata) {
return;

View File

@ -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<std::string>& names,
void GetRefinedFVData(const std::vector<std::string>& names,
std::vector<float>* fvdata);
OpenSubdiv::OPENSUBDIV_VERSION::HbrMesh<T> *GetHbrMesh() { return _hmesh;}

View File

@ -29,7 +29,8 @@
#include <osd/vertex.h>
#include <fstream>
#include <sstream>
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<OsdVertex> 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<OsdVertex> *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<OsdVertex> 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<OsdVertex>* 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<float>* 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();

View File

@ -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<std::string>& names,
void GetRefinedFVData(const std::vector<std::string>& names,
std::vector<float>* 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;
};

View File

@ -26,6 +26,7 @@
#include <sstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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; i<numFaces; ++i) {
@ -126,7 +127,7 @@ PxOsdUtilSubdivTopology::Print() const
{
std::cout << "Mesh " << name << "\n";
std::cout << "\tnumVertices = " << numVertices << "\n";
std::cout << "\tmaxLevels = " << maxLevels << "\n";
std::cout << "\trefinementLevel = " << refinementLevel << "\n";
std::cout << "\tindices ( " << indices.size() << ") : ";
for (int i=0; i<(int)indices.size(); ++i) {
std::cout << indices[i] << ", ";
@ -265,7 +266,7 @@ PxOsdUtilSubdivTopology::ParseFromObjString(
}
}
numVertices = (int)pointPositions->size()/3;
numVertices = pointPositions->size()/3;
return true;
}

View File

@ -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<int> indices;
std::vector<int> nverts;
std::vector<std::string> vvNames;

View File

@ -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(

View File

@ -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<std::string>& names,
std::vector<float>* fvdata) {
_refiner->GetRefinedFVData(subdivisionLevel, names, fvdata);
_refiner->GetRefinedFVData(names, fvdata);
}