// // Copyright 2013 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // #ifndef OSD_CPU_EVAL_LIMIT_CONTEXT_H #define OSD_CPU_EVAL_LIMIT_CONTEXT_H #include "../version.h" #include "../osd/evalLimitContext.h" #include "../osd/vertexDescriptor.h" #include "../far/patchTables.h" #include "../far/patchMap.h" #include #include namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { class OsdCpuEvalLimitContext : public OsdEvalLimitContext { public: /// \brief Factory /// Returns an EvalLimitContext from the given far patch tables. /// Note : the patchtables is expected to be feature-adaptive and have ptex /// coordinates tables. /// /// @param patchTables a pointer to an initialized FarPatchTables /// /// @param requireFVarData flag for generating face-varying data /// static OsdCpuEvalLimitContext * Create(FarPatchTables const *patchTables, bool requireFVarData=false); virtual ~OsdCpuEvalLimitContext(); /// A container able to bind vertex buffer data as input or output streams. class DataStream { public: /// Constructor DataStream() : _data(0) { } /// Binds the stream to the context (and moves the data to the appropriate /// compute device) /// /// @param data a valid OsdVertexBuffer /// template void Bind( BUFFER * data ) { _data = data ? data->BindCpuBuffer() : 0; } /// True if the stream has been bound bool IsBound() const { return (_data!=NULL); } /// Unbinds the stream void Unbind() { _data=0; } protected: float * _data; }; /// \brief Input (const) data stream class InputDataStream : public DataStream { public: /// Const accessor float const * GetData() const { return _data; } }; /// \brief Output (const) data stream class OutputDataStream : public DataStream { public: /// Non-cont accessor float * GetData() { return _data; } }; /// Vertex-interpolated streams struct VertexData { /// input vertex-interpolated data descriptor OsdVertexBufferDescriptor inDesc; /// input vertex-interpolated data stream InputDataStream in; /// output vertex-interpolated data descriptor OsdVertexBufferDescriptor outDesc; /// output vertex-interpolated data stream and parametric derivative streams OutputDataStream out, outDu, outDv; /// Binds the vertex-interpolated data streams /// /// @param iDesc data descriptor shared by all input data buffers /// /// @param inQ input vertex data /// /// @param oDesc data descriptor shared by all output data buffers /// /// @param outQ output vertex data /// /// @param outdQu output derivative along "u" of the vertex data (optional) /// /// @param outdQv output derivative along "v" of the vertex data (optional) /// template void Bind( OsdVertexBufferDescriptor const & iDesc, VERTEX_BUFFER *inQ, OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ, OUTPUT_BUFFER *outdQu=0, OUTPUT_BUFFER *outdQv=0) { inDesc = iDesc; in.Bind( inQ ); outDesc = oDesc; out.Bind( outQ ); outDu.Bind( outdQu ); outDv.Bind( outdQv ); } /// True if both the mandatory input and output streams have been bound bool IsBound() const { return in.IsBound() and out.IsBound(); } /// Unbind the vertex data streams void Unbind(); }; /// Returns an Eval data descriptor of the vertex-interpolated data currently /// bound to this EvalLimitContext. VertexData & GetVertexData() { return _vertexData; } /// Varying-interpolated streams struct VaryingData { /// input varying-interpolated data descriptor OsdVertexBufferDescriptor inDesc; /// input varying-interpolated data stream InputDataStream in; /// output varying-interpolated data descriptor OsdVertexBufferDescriptor outDesc; /// output varying-interpolated data stream OutputDataStream out; /// Binds the varying-interpolated data streams /// /// @param iDesc data descriptor shared by all input data buffers /// /// @param inQ input varying data /// /// @param oDesc data descriptor shared by all output data buffers /// /// @param outQ output varying data /// template void Bind( OsdVertexBufferDescriptor const & iDesc, VARYING_BUFFER *inQ, OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) { inDesc = iDesc; in.Bind( inQ ); outDesc = oDesc; out.Bind( outQ ); } /// True if both the mandatory input and output streams have been bound bool IsBound() const { return in.IsBound() and out.IsBound(); } /// Unbind the vertex data streams void Unbind(); }; /// Returns an Eval data descriptor of the varying-interpolated data currently /// bound to this EvalLimitContext. VaryingData & GetVaryingData() { return _varyingData; } /// Face-Varying-interpolated streams struct FaceVaryingData { /// input face-varying-interpolated data descriptor OsdVertexBufferDescriptor inDesc; /// output face-varying-interpolated data descriptor OsdVertexBufferDescriptor outDesc; /// output face-varying-interpolated data stream and parametric derivative streams OutputDataStream out; /// Binds the face-varying-interpolated data streams /// /// Note : currently we only support bilinear boundary interpolation rules /// for face-varying data. Although Hbr supports 3 addition smooth rule sets, /// the feature-adaptive patch interpolation code currently does not support /// them, and neither does this EvalContext /// /// @param iDesc data descriptor shared by all input data buffers /// /// @param oDesc data descriptor shared by all output data buffers /// /// @param outQ output face-varying data /// template void Bind( OsdVertexBufferDescriptor const & iDesc, OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) { inDesc = iDesc; outDesc = oDesc; out.Bind( outQ ); } /// True if the output stream has been bound bool IsBound() const { return out.IsBound(); } /// Unbind the vertex data streams void Unbind(); }; /// Returns an Eval data descriptor of the face-varying-interpolated data /// currently bound to this EvalLimitContext. FaceVaryingData & GetFaceVaryingData() { return _faceVaryingData; } /// Returns the vector of patch arrays const FarPatchTables::PatchArrayVector & GetPatchArrayVector() const { return _patchArrays; } /// Returns the vector of per-patch parametric data const std::vector & GetPatchBitFields() const { return _patchBitFields; } /// The ordered array of control vertex indices for all the patches const std::vector & GetControlVertices() const { return _patches; } /// Returns the vertex-valence buffer used for Gregory patch computations FarPatchTables::VertexValenceTable const & GetVertexValenceTable() const { return _vertexValenceTable; } /// Returns the Quad-Offsets buffer used for Gregory patch computations FarPatchTables::QuadOffsetTable const & GetQuadOffsetTable() const { return _quadOffsetTable; } /// Returns the face-varying data patch table std::vector const & GetFVarData() const { return _fvarData; } /// Returns the number of floats in a datum of the face-varying data table int GetFVarWidth() const { return _fvarwidth; } /// Returns a map that can connect a faceId to a list of children patches FarPatchMap const & GetPatchMap() const { return *_patchMap; } /// Returns the highest valence of the vertices in the buffers int GetMaxValence() const { return _maxValence; } protected: explicit OsdCpuEvalLimitContext(FarPatchTables const *patchTables, bool requireFVarData); private: // Topology data for a mesh FarPatchTables::PatchArrayVector _patchArrays; // patch descriptor for each patch in the mesh FarPatchTables::PTable _patches; // patch control vertices std::vector _patchBitFields; // per-patch parametric info FarPatchTables::VertexValenceTable _vertexValenceTable; // extra Gregory patch data buffers FarPatchTables::QuadOffsetTable _quadOffsetTable; std::vector _fvarData; FarPatchMap * _patchMap; // map of the sub-patches given a face index VertexData _vertexData; // vertex-interpolated data descriptor VaryingData _varyingData; // varying-interpolated data descriptor FaceVaryingData _faceVaryingData; // face-varying-interpolated data descriptor int _maxValence, _fvarwidth; }; } // end namespace OPENSUBDIV_VERSION using namespace OPENSUBDIV_VERSION; } // end namespace OpenSubdiv #endif /* OSD_CPU_EVAL_LIMIT_CONTEXT_H */