mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-24 04:20:21 +00:00
Fixed problem with refinement level being hardwired to 1, fixed error messages,
other improvements.
This commit is contained in:
parent
9ad6b117c7
commit
def6542192
@ -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";
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user