OpenSubdiv/opensubdiv/osdutil/refiner.h

129 lines
4.4 KiB
C
Raw Normal View History

#ifndef PXOSDUTIL_REFINER_H
#define PXOSDUTIL_REFINER_H
#include "mesh.h"
#include <string>
#include <vector>
#include <osd/cpuVertexBuffer.h>
#include <osd/cpuComputeContext.h>
#include <far/mesh.h>
//----------------------------------------------------------------------------
// A simple class that wraps several OpenSubdiv classes for tessellating
// a subdivision surface into quads and extracting position and topology
// data. Single and multithreaded CPU evaluation is supported.
//
// At initialization time this class takes polygonal mesh topology as
// vectors of ints, constructs an HbrMesh from that with topology checking
// and does uniform subdivision on that to make a FarMesh.
//
// At runtime Osd vertex buffers, compute controllers, and compute contexts
// are used for fast evaluation of the surface given the FarMesh.
//----------------------------------------------------------------------------
class PxOsdUtilRefiner {
public:
PxOsdUtilRefiner();
~PxOsdUtilRefiner();
// Returns false on error. If errorMessage is non-NULL it'll
// be populated upon error.
//
// If successful the HbrMesh and FarMesh will be created, and
// all variables will be populated for later calls to Refine.
//
bool Initialize(
const PxOsdUtilSubdivTopology &topology, bool adaptive,
std::string *errorMessage = NULL);
// Fetch the topology of the post-refined mesh. The "quads" vector
// will be filled with 4 ints per quad which index into a vector
// of positions.
bool GetRefinedQuads(std::vector<int>* quads,
std::string *errorMessage = NULL) const;
// Fetch the U/V coordinates of the refined quads in the U/V space
// of their parent coarse face
bool GetRefinedPtexUvs(std::vector<float>* subfaceUvs,
std::vector<int>* ptexIndices,
std::string *errorMessage = NULL) const;
// 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,
std::vector<float>* fvdata) {
_mesh->GetRefinedFVData(subdivisionLevel, names, fvdata);
}
// Const access to far mesh
const OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* GetFarMesh() {
return _farMesh;
}
const std::string &GetName();
bool GetAdaptive() { return _adaptive; }
OpenSubdiv::HbrMesh<OpenSubdiv::OsdVertex> *GetHbrMesh();
const PxOsdUtilSubdivTopology &GetTopology() const {return _mesh->GetTopology();}
bool IsRefined() {return _isRefined;}
int GetNumRefinedVertices() { return _numRefinedVerts;}
int GetFirstVertexOffset() { return _firstVertexOffset;}
private:
// 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.
bool _adaptive;
// The next block of member variables are the OpenSubdiv meshe
// classes used to generate the refined subdivision surface
//
// The lowest level mesh, it definies the polygonal topology
// and is used for refinement.
PxOsdUtilMesh *_mesh;
// A mesh of patches (adaptive), or quads (uniform) generated
// by performing feature adaptive or uniform subdivision on the hbrMesh.
// Uniform and adaptive each get their own far mesh as uniform and
// adaptive code in far result in very different meshes
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* _farMesh;
// Pointer to patch parameters stored within _farMesh.
// These describe additional per-patch information, used here to
// extract the U/V values at the corners of each tessellated quad.
/// XXX: Maybe not cache, get from far mesh each time?
const OpenSubdiv::FarPatchTables::PatchParamTable* _patchParamTable;
// Cached counts within _farMesh
/// XXX: Maybe not cache, get from far mesh each time?
int _firstVertexOffset;
int _firstPatchOffset;
int _numRefinedVerts;
int _numUniformQuads; // zero if adaptive = true
int _numPatches; // zero if adaptive = false
int _level;
bool _isRefined;
};
#endif /* PXOSDUTIL_REFINER_H */