#ifndef PXOSDUTIL_REFINER_H #define PXOSDUTIL_REFINER_H #include "mesh.h" #include #include #include #include #include //---------------------------------------------------------------------------- // 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* 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* subfaceUvs, std::vector* 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& names, std::vector* fvdata) { _mesh->GetRefinedFVData(subdivisionLevel, names, fvdata); } // Const access to far mesh const OpenSubdiv::FarMesh* GetFarMesh() { return _farMesh; } const std::string &GetName(); bool GetAdaptive() { return _adaptive; } OpenSubdiv::HbrMesh *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* _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 */