All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mesh.h
Go to the documentation of this file.
1 //
2 // Copyright 2013 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef OSD_MESH_H
26 #define OSD_MESH_H
27 
28 #include "../version.h"
29 
30 #include "../far/kernelBatch.h"
31 #include "../far/topologyRefiner.h"
32 #include "../far/patchTablesFactory.h"
33 #include "../far/stencilTables.h"
34 #include "../far/stencilTablesFactory.h"
35 
36 #include "../osd/error.h"
37 #include "../osd/vertex.h"
38 #include "../osd/vertexDescriptor.h"
39 
40 #include <bitset>
41 #include <cassert>
42 #include <cstring>
43 
44 namespace OpenSubdiv {
45 namespace OPENSUBDIV_VERSION {
46 
47 namespace Osd {
48 
49 enum MeshBits {
55 };
56 typedef std::bitset<NUM_MESH_BITS> MeshBitset;
57 
58 template <class DRAW_CONTEXT>
60 public:
61  typedef DRAW_CONTEXT DrawContext;
62  typedef typename DrawContext::VertexBufferBinding VertexBufferBinding;
63 
64 public:
66 
67  virtual ~MeshInterface() { }
68 
69  virtual int GetNumVertices() const = 0;
70 
71  virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts) = 0;
72 
73  virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts) = 0;
74 
75  virtual void Refine() = 0;
76 
77  virtual void Refine(VertexBufferDescriptor const *vertexDesc,
78  VertexBufferDescriptor const *varyingDesc,
79  bool interleaved) = 0;
80 
81  virtual void Synchronize() = 0;
82 
83  virtual DrawContext * GetDrawContext() = 0;
84 
86 
88 
89  virtual void SetFVarDataChannel(int fvarWidth, std::vector<float> const & fvarData) = 0;
90 
91 protected:
92 
93  static inline int getNumVertices(Far::TopologyRefiner const & refiner) {
94  return refiner.IsUniform() ?
95  refiner.GetNumVertices(0) + refiner.GetNumVertices(refiner.GetMaxLevel()) :
96  refiner.GetNumVerticesTotal();
97  }
98 
99  static inline void refineMesh(Far::TopologyRefiner & refiner, int level, bool adaptive) {
100 
101  bool fullTopologyInLastLevel = refiner.GetNumFVarChannels()>0;
102 
103  if (adaptive) {
104  refiner.RefineAdaptive(level, fullTopologyInLastLevel);
105  } else {
106  refiner.RefineUniform(level, fullTopologyInLastLevel);
107  }
108  }
109 };
110 
111 
112 
113 template <class VERTEX_BUFFER, class COMPUTE_CONTROLLER, class DRAW_CONTEXT>
114 class Mesh : public MeshInterface<DRAW_CONTEXT> {
115 public:
116  typedef VERTEX_BUFFER VertexBuffer;
117  typedef COMPUTE_CONTROLLER ComputeController;
118  typedef typename ComputeController::ComputeContext ComputeContext;
119  typedef DRAW_CONTEXT DrawContext;
120  typedef typename DrawContext::VertexBufferBinding VertexBufferBinding;
121 
122  Mesh(ComputeController * computeController,
123  Far::TopologyRefiner * refiner,
124  int numVertexElements,
125  int numVaryingElements,
126  int level,
127  MeshBitset bits = MeshBitset()) :
128 
129  _refiner(refiner),
130  _vertexBuffer(0),
131  _varyingBuffer(0),
132  _computeContext(0),
133  _computeController(computeController),
134  _drawContext(0) {
135 
136  assert(_refiner);
137 
138  MeshInterface<DRAW_CONTEXT>::refineMesh(*_refiner, level, bits.test(MeshAdaptive));
139 
140  initializeVertexBuffers(numVertexElements, numVaryingElements, bits);
141 
142  initializeComputeContext(numVertexElements, numVaryingElements);
143 
144  initializeDrawContext(numVertexElements, bits);
145  }
146 
147  Mesh(ComputeController * computeController,
148  Far::TopologyRefiner * refiner,
149  VertexBuffer * vertexBuffer,
150  VertexBuffer * varyingBuffer,
151  ComputeContext * computeContext,
152  DrawContext * drawContext) :
153 
154  _refiner(refiner),
155  _vertexBuffer(vertexBuffer),
156  _varyingBuffer(varyingBuffer),
157  _computeContext(computeContext),
158  _computeController(computeController),
159  _drawContext(drawContext) { }
160 
161  virtual ~Mesh() {
162  delete _refiner;
163  delete _patchTables;
164  delete _vertexBuffer;
165  delete _varyingBuffer;
166  delete _computeContext;
167  delete _drawContext;
168  }
169 
170  virtual int GetNumVertices() const {
171  assert(_refiner);
173  }
174 
175  virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts) {
176  _vertexBuffer->UpdateData(vertexData, startVertex, numVerts);
177  }
178 
179  virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts) {
180  _varyingBuffer->UpdateData(varyingData, startVertex, numVerts);
181  }
182 
183  virtual void Refine() {
184  _computeController->Compute(_computeContext, _kernelBatches, _vertexBuffer, _varyingBuffer);
185  }
186 
187  virtual void Refine(VertexBufferDescriptor const *vertexDesc, VertexBufferDescriptor const *varyingDesc) {
188  _computeController->Refine(_computeContext, _kernelBatches, _vertexBuffer, _varyingBuffer, vertexDesc, varyingDesc);
189  }
190 
191  virtual void Synchronize() {
192  _computeController->Synchronize();
193  }
194 
196  return VertexBufferBinding(0);
197  }
198 
200  return VertexBufferBinding(0);
201  }
202 
204  return _drawContext;
205  }
206 
207  virtual void SetFVarDataChannel(int fvarWidth, std::vector<float> const & fvarData) {
208  if (_patchTables and _drawContext and fvarWidth and (not fvarData.empty())) {
209  _drawContext->SetFVarDataTexture(*_patchTables, fvarWidth, fvarData);
210  }
211  }
212 
213 private:
214 
215  void initializeComputeContext(int numVertexElements,
216  int numVaryingElements ) {
217 
218  assert(_refiner);
219 
221  options.generateOffsets=true;
222  options.generateAllLevels=_refiner->IsUniform() ? false : true;
223 
224  Far::StencilTables const * vertexStencils=0, * varyingStencils=0;
225 
226  if (numVertexElements>0) {
227 
228  vertexStencils = Far::StencilTablesFactory::Create(*_refiner, options);
229 
230  _kernelBatches.push_back(Far::StencilTablesFactory::Create(*vertexStencils));
231  }
232 
233  if (numVaryingElements>0) {
234 
236 
237  varyingStencils = Far::StencilTablesFactory::Create(*_refiner, options);
238  }
239 
240  _computeContext = ComputeContext::Create(vertexStencils, varyingStencils);
241 
242  delete vertexStencils;
243  delete varyingStencils;
244  }
245 
246  void initializeDrawContext(int numElements, MeshBitset bits) {
247 
248  assert(_refiner and _vertexBuffer);
249 
250  Far::PatchTablesFactory::Options options;
251  options.generateFVarTables = bits.test(MeshFVarData);
252 
253  _patchTables = Far::PatchTablesFactory::Create(*_refiner);
254 
255  _drawContext = DrawContext::Create(
256  _patchTables, numElements, bits.test(MeshFVarData));
257 
258  _drawContext->UpdateVertexTexture(_vertexBuffer);
259  }
260 
261  int initializeVertexBuffers(int numVertexElements,
262  int numVaryingElements, MeshBitset bits) {
263 
264  int numVertices = MeshInterface<DRAW_CONTEXT>::getNumVertices(*_refiner);
265 
266  int numElements = numVertexElements +
267  (bits.test(MeshInterleaveVarying) ? numVaryingElements : 0);
268 
269  if (numVertexElements) {
270 
271  _vertexBuffer = VertexBuffer::Create(numElements, numVertices);
272  }
273 
274  if (numVaryingElements>0 and (not bits.test(MeshInterleaveVarying))) {
275  _varyingBuffer = VertexBuffer::Create(numVaryingElements, numVertices);
276  }
277  return numElements;
278  }
279 
280  Far::TopologyRefiner * _refiner;
281  Far::PatchTables * _patchTables;
282  Far::KernelBatchVector _kernelBatches;
283 
284  VertexBuffer * _vertexBuffer,
285  * _varyingBuffer;
286 
287  ComputeContext * _computeContext;
288  ComputeController * _computeController;
289 
290  DrawContext *_drawContext;
291 };
292 
293 } // end namespace Osd
294 
295 } // end namespace OPENSUBDIV_VERSION
296 using namespace OPENSUBDIV_VERSION;
297 
298 } // end namespace OpenSubdiv
299 
300 #endif // OSD_MESH_H
301 
virtual DrawContext * GetDrawContext()
Definition: mesh.h:203
COMPUTE_CONTROLLER ComputeController
Definition: mesh.h:117
int generateOffsets
populate optional &quot;_offsets&quot; field
virtual VertexBufferBinding BindVaryingBuffer()=0
static PatchTables * Create(TopologyRefiner const &refiner, Options options=Options())
Factory constructor for PatchTables.
static void refineMesh(Far::TopologyRefiner &refiner, int level, bool adaptive)
Definition: mesh.h:99
int GetNumFVarChannels() const
Returns the number of face-varying channels in the tables.
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)
Definition: mesh.h:175
Describes vertex elements in interleaved data buffers.
int GetNumVertices(int level) const
Returns the number of vertices at a given level of refinement.
virtual void SetFVarDataChannel(int fvarWidth, std::vector< float > const &fvarData)
Definition: mesh.h:207
DrawContext::VertexBufferBinding VertexBufferBinding
Definition: mesh.h:62
std::vector< KernelBatch > KernelBatchVector
Definition: kernelBatch.h:73
virtual void SetFVarDataChannel(int fvarWidth, std::vector< float > const &fvarData)=0
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)=0
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)
Definition: mesh.h:179
DrawContext::VertexBufferBinding VertexBufferBinding
Definition: mesh.h:120
virtual void Refine(VertexBufferDescriptor const *vertexDesc, VertexBufferDescriptor const *varyingDesc)
Definition: mesh.h:187
Mesh(ComputeController *computeController, Far::TopologyRefiner *refiner, VertexBuffer *vertexBuffer, VertexBuffer *varyingBuffer, ComputeContext *computeContext, DrawContext *drawContext)
Definition: mesh.h:147
int GetNumVerticesTotal() const
Returns the total number of vertices in all levels.
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)=0
virtual int GetNumVertices() const
Definition: mesh.h:170
void RefineAdaptive(int maxLevel, bool fullTopologyInLastLevel=false)
Feature Adaptive topology refinement.
std::bitset< NUM_MESH_BITS > MeshBitset
Definition: mesh.h:56
ComputeController::ComputeContext ComputeContext
Definition: mesh.h:118
virtual VertexBufferBinding BindVertexBuffer()=0
Mesh(ComputeController *computeController, Far::TopologyRefiner *refiner, int numVertexElements, int numVaryingElements, int level, MeshBitset bits=MeshBitset())
Definition: mesh.h:122
int GetMaxLevel() const
Returns the highest level of refinement.
virtual VertexBufferBinding BindVaryingBuffer()
Definition: mesh.h:199
static StencilTables const * Create(TopologyRefiner const &refiner, Options options=Options())
Instantiates StencilTables from TopologyRefiner that have been refined uniformly or adaptively...
bool IsUniform() const
Returns true if uniform subdivision has been applied.
Stores topology data for a specified set of refinement options.
void RefineUniform(int maxLevel, bool fullTopologyInLastLevel=false)
Refine the topology uniformly.
virtual VertexBufferBinding BindVertexBuffer()
Definition: mesh.h:195
static int getNumVertices(Far::TopologyRefiner const &refiner)
Definition: mesh.h:93