mesh.h
1 //
2 // Copyright 2016 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 #ifndef PXR_IMAGING_HD_ST_MESH_H
25 #define PXR_IMAGING_HD_ST_MESH_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdSt/api.h"
29 #include "pxr/imaging/hd/version.h"
30 #include "pxr/imaging/hd/changeTracker.h"
31 #include "pxr/imaging/hd/drawingCoord.h"
32 #include "pxr/imaging/hd/mesh.h"
33 #include "pxr/imaging/hd/perfLog.h"
34 
35 #include "pxr/usd/sdf/path.h"
36 #include "pxr/base/vt/array.h"
37 
38 #include <memory>
39 
40 PXR_NAMESPACE_OPEN_SCOPE
41 
42 
43 class HdStDrawItem;
44 class HdSceneDelegate;
45 
46 using Hd_VertexAdjacencySharedPtr = std::shared_ptr<class Hd_VertexAdjacency>;
47 using HdBufferSourceSharedPtr = std::shared_ptr<class HdBufferSource>;
48 using HdSt_MeshTopologySharedPtr = std::shared_ptr<class HdSt_MeshTopology>;
49 
50 using HdStResourceRegistrySharedPtr =
51  std::shared_ptr<class HdStResourceRegistry>;
52 
55 class HdStMesh final : public HdMesh
56 {
57 public:
58  HF_MALLOC_TAG_NEW("new HdStMesh");
59 
60  HDST_API
61  HdStMesh(SdfPath const& id);
62 
63  HDST_API
64  ~HdStMesh() override;
65 
66  HDST_API
67  void UpdateRenderTag(HdSceneDelegate *delegate,
68  HdRenderParam *renderParam) override;
69 
70  HDST_API
71  void Sync(HdSceneDelegate *delegate,
72  HdRenderParam *renderParam,
73  HdDirtyBits *dirtyBits,
74  TfToken const &reprToken) override;
75 
76  HDST_API
77  void Finalize(HdRenderParam *renderParam) override;
78 
79  HDST_API
80  HdDirtyBits GetInitialDirtyBitsMask() const override;
81 
83  HDST_API
84  HdMeshTopologySharedPtr GetTopology() const override;
85 
87  HDST_API
88  static bool IsEnabledPackedNormals();
89 
90 protected:
91  HDST_API
92  void _InitRepr(TfToken const &reprToken, HdDirtyBits *dirtyBits) override;
93 
94  HDST_API
95  HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override;
96 
97  void _UpdateRepr(HdSceneDelegate *sceneDelegate,
98  HdRenderParam *renderParam,
99  TfToken const &reprToken,
100  HdDirtyBits *dirtyBitsState);
101 
102  HdBufferArrayRangeSharedPtr
103  _GetSharedPrimvarRange(uint64_t primvarId,
104  HdBufferSpecVector const &updatedOrAddedSpecs,
105  HdBufferSpecVector const &removedSpecs,
106  HdBufferArrayRangeSharedPtr const &curRange,
107  bool * isFirstInstance,
108  HdStResourceRegistrySharedPtr const &resourceRegistry) const;
109 
110  bool _MaterialHasPtex(const HdRenderIndex &renderIndex,
111  const SdfPath &materialId) const;
112 
113  bool _UseQuadIndices(const HdRenderIndex &renderIndex,
114  const HdSt_MeshTopologySharedPtr &topology) const;
115 
116  bool _MaterialHasLimitSurface(const HdRenderIndex &renderIndex,
117  const SdfPath &materialId) const;
118 
119  bool _UseLimitRefinement(const HdRenderIndex &renderIndex,
120  const HdMeshTopology &topology) const;
121 
122  bool _UseSmoothNormals(HdSt_MeshTopologySharedPtr const& topology) const;
123 
124  bool _UseFlatNormals(const HdMeshReprDesc &desc) const;
125 
126  void _UpdateDrawItem(HdSceneDelegate *sceneDelegate,
127  HdRenderParam *renderParam,
128  HdStDrawItem *drawItem,
129  HdDirtyBits *dirtyBits,
130  const TfToken &reprToken,
131  const HdReprSharedPtr &repr,
132  const HdMeshReprDesc &desc,
133  bool requireSmoothNormals,
134  bool requireFlatNormals,
135  int geomSubsetDescIndex);
136 
137  void _UpdateDrawItemGeometricShader(HdSceneDelegate *sceneDelegate,
138  HdRenderParam *renderParam,
139  HdStDrawItem *drawItem,
140  const HdMeshReprDesc &desc,
141  const SdfPath &materialId);
142 
143  void _UpdateShadersForAllReprs(HdSceneDelegate *sceneDelegate,
144  HdRenderParam *renderParam,
145  bool updateMaterialNetworkShader,
146  bool updateGeometricShader);
147 
148  void _UpdateMaterialTagsForAllReprs(HdSceneDelegate *sceneDelegate,
149  HdRenderParam *renderParam);
150 
151  void _PopulateTopology(HdSceneDelegate *sceneDelegate,
152  HdRenderParam *renderParam,
153  HdStDrawItem *drawItem,
154  HdDirtyBits *dirtyBits,
155  const TfToken &reprToken,
156  const HdReprSharedPtr &repr,
157  const HdMeshReprDesc &desc,
158  int geomSubsetDescIndex);
159 
160  void _UpdateDrawItemsForGeomSubsets(HdSceneDelegate *sceneDelegate,
161  HdRenderParam *renderParam,
162  HdStDrawItem *drawItem,
163  const TfToken &reprToken,
164  const HdReprSharedPtr &repr,
165  const HdGeomSubsets &geomSubsets,
166  size_t oldNumGeomSubsets);
167 
168  void _CreateTopologyRangeForGeomSubset(
169  HdStResourceRegistrySharedPtr resourceRegistry,
170  HdChangeTracker &changeTracker,
171  HdRenderParam *renderParam,
172  HdDrawItem *drawItem,
173  const TfToken &indexToken,
174  HdBufferSourceSharedPtr indicesSource,
175  HdBufferSourceSharedPtr fvarIndicesSource,
176  HdBufferSourceSharedPtr geomSubsetFaceIndicesHelperSource,
177  const VtIntArray &faceIndices,
178  bool refined);
179 
180  void _GatherFaceVaryingTopologies(HdSceneDelegate *sceneDelegate,
181  const HdReprSharedPtr &repr,
182  const HdMeshReprDesc &desc,
183  HdStDrawItem *drawItem,
184  int geomSubsetDescIndex,
185  HdDirtyBits *dirtyBits,
186  const SdfPath &id,
187  HdSt_MeshTopologySharedPtr topology);
188 
189  void _PopulateAdjacency(
190  HdStResourceRegistrySharedPtr const &resourceRegistry);
191 
192  void _PopulateVertexPrimvars(HdSceneDelegate *sceneDelegate,
193  HdRenderParam *renderParam,
194  const HdReprSharedPtr &repr,
195  const HdMeshReprDesc &desc,
196  HdStDrawItem *drawItem,
197  int geomSubsetDescIndex,
198  HdDirtyBits *dirtyBits,
199  bool requireSmoothNormals);
200 
201  void _PopulateFaceVaryingPrimvars(HdSceneDelegate *sceneDelegate,
202  HdRenderParam *renderParam,
203  const HdReprSharedPtr &repr,
204  const HdMeshReprDesc &desc,
205  HdStDrawItem *drawItem,
206  int geomSubsetDescIndex,
207  HdDirtyBits *dirtyBits);
208 
209  void _PopulateElementPrimvars(HdSceneDelegate *sceneDelegate,
210  HdRenderParam *renderParam,
211  const HdReprSharedPtr &repr,
212  const HdMeshReprDesc &desc,
213  HdStDrawItem *drawItem,
214  int geomSubsetDescIndex,
215  HdDirtyBits *dirtyBits,
216  bool requireFlatNormals);
217 
218  int _GetRefineLevelForDesc(const HdMeshReprDesc &desc) const;
219 
220  // Helper class for meshes to keep track of the topologies of their
221  // face-varying primvars. The face-varying topologies are later passed to
222  // the OSD refiner in an order that will correspond to their face-varying
223  // channel number. We keep a vector of only the topologies in use, paired
224  // with their associated primvar names.
225  class _FvarTopologyTracker
226  {
227  public:
228  const TopologyToPrimvarVector & GetTopologyToPrimvarVector() const {
229  return _topologies;
230  }
231 
232  // Add a primvar and its corresponding toplogy to the tracker
233  void AddOrUpdateTopology(const TfToken &primvar,
234  const VtIntArray &topology) {
235  for (size_t i = 0; i < _topologies.size(); ++i) {
236  // Found existing topology
237  if (_topologies[i].first == topology) {
238 
239  if (std::find(_topologies[i].second.begin(),
240  _topologies[i].second.end(),
241  primvar) == _topologies[i].second.end()) {
242  // Topology does not have that primvar assigned
243  RemovePrimvar(primvar);
244  _topologies[i].second.push_back(primvar);
245  }
246  return;
247  }
248  }
249 
250  // Found new topology
251  RemovePrimvar(primvar);
252  _topologies.push_back(
253  std::pair<VtIntArray, std::vector<TfToken>>(
254  topology, {primvar}));
255  }
256 
257  // Remove a primvar from the tracker.
258  void RemovePrimvar(const TfToken &primvar) {
259  for (size_t i = 0; i < _topologies.size(); ++i) {
260  _topologies[i].second.erase(std::find(
261  _topologies[i].second.begin(),
262  _topologies[i].second.end(),
263  primvar), _topologies[i].second.end());
264 
265  }
266  }
267 
268  // Remove unused topologies (topologies with no associated primvars), as
269  // we do not want to build stencil tables for them.
270  void RemoveUnusedTopologies() {
271  _topologies.erase(std::remove_if(
272  _topologies.begin(), _topologies.end(), NoPrimvars),
273  _topologies.end());
274  }
275 
276  // Get the face-varying channel given a primvar name. If the primvar is
277  // not in the tracker, returns -1.
278  int GetChannelFromPrimvar(const TfToken &primvar) const {
279  for (size_t i = 0; i < _topologies.size(); ++i) {
280  if (std::find(_topologies[i].second.begin(),
281  _topologies[i].second.end(),
282  primvar) !=
283  _topologies[i].second.end()) {
284  return i;
285  }
286  }
287  return -1;
288  }
289 
290  // Return a vector of all the face-varying topologies.
291  std::vector<VtIntArray> GetFvarTopologies() const {
292  std::vector<VtIntArray> fvarTopologies;
293  for (const auto& it : _topologies) {
294  fvarTopologies.push_back(it.first);
295  }
296  return fvarTopologies;
297  }
298 
299  size_t GetNumTopologies() const {
300  return _topologies.size();
301  }
302 
303  private:
304  // Helper function that returns true if a <topology, primvar vector> has
305  // no primvars.
306  static bool NoPrimvars(const std::pair<VtIntArray, std::vector<TfToken>>
307  &topology) {
308  return topology.second.empty();
309  }
310 
311  TopologyToPrimvarVector _topologies;
312  };
313 
314 private:
315  enum DrawingCoord {
316  HullTopology = HdDrawingCoord::CustomSlotsBegin,
317  PointsTopology,
318  FreeSlot // If the mesh topology has geom subsets, we might place
319  // them here as geom subsets are processed before instance
320  // primvars. The instance primvars will follow after. If there
321  // are no geom subsets, instance primvars start here.
322  };
323 
324  enum DirtyBits : HdDirtyBits {
325  DirtySmoothNormals = HdChangeTracker::CustomBitsBegin,
326  DirtyFlatNormals = (DirtySmoothNormals << 1),
327  DirtyIndices = (DirtyFlatNormals << 1),
328  DirtyHullIndices = (DirtyIndices << 1),
329  DirtyPointsIndices = (DirtyHullIndices << 1)
330  };
331 
332  HdSt_MeshTopologySharedPtr _topology;
333  Hd_VertexAdjacencySharedPtr _vertexAdjacency;
334 
335  HdTopology::ID _topologyId;
336  HdTopology::ID _vertexPrimvarId;
337  HdDirtyBits _customDirtyBitsInUse;
338 
339  HdType _pointsDataType;
340  HdInterpolation _sceneNormalsInterpolation;
341  HdCullStyle _cullStyle;
342  bool _hasMirroredTransform : 1;
343  bool _doubleSided : 1;
344  bool _flatShadingEnabled : 1;
345  bool _displacementEnabled : 1;
346  bool _limitNormals : 1;
347  bool _sceneNormals : 1;
348  bool _hasVaryingTopology : 1; // The prim's topology has changed since
349  // the prim was created
350  bool _displayOpacity : 1;
351  bool _occludedSelectionShowsThrough : 1;
352  bool _pointsShadingEnabled : 1;
353 
354  std::unique_ptr<_FvarTopologyTracker> _fvarTopologyTracker;
355 };
356 
357 
358 PXR_NAMESPACE_CLOSE_SCOPE
359 
360 #endif // PXR_IMAGING_HD_ST_MESH_H
The Hydra render index is a flattened representation of the client scene graph, which may be composed...
Definition: renderIndex.h:120
HDST_API HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override
This callback from Rprim gives the prim an opportunity to set additional dirty bits based on those al...
Descriptor to configure the drawItem(s) for a repr.
Definition: mesh.h:54
Tracks changes from the HdSceneDelegate, providing invalidation cues to the render engine.
Definition: changeTracker.h:51
HDST_API void _InitRepr(TfToken const &reprToken, HdDirtyBits *dirtyBits) override
Initialize the given representation of this Rprim.
The HdRenderParam is an opaque (to core Hydra) handle, to an object that is obtained from the render ...
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
Adapter class providing data exchange with the client scene graph.
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
A subdivision surface or poly-mesh object.
Definition: mesh.h:55
A draw item is a light-weight representation of an HdRprim's resources and material to be used for re...
Definition: drawItem.h:66
HDST_API HdMeshTopologySharedPtr GetTopology() const override
Topology (member) getter.
Hydra Schema for a subdivision surface or poly-mesh object.
Definition: mesh.h:106
Topology data for meshes.
Definition: meshTopology.h:55
HDST_API HdDirtyBits GetInitialDirtyBitsMask() const override
Returns the set of dirty bits that should be added to the change tracker for this prim,...
HDST_API void Finalize(HdRenderParam *renderParam) override
Finalizes object resources.
HDST_API void Sync(HdSceneDelegate *delegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits, TfToken const &reprToken) override
Pull invalidated scene data and prepare/update the renderable representation.
static HDST_API bool IsEnabledPackedNormals()
Returns whether packed (10_10_10 bits) normals to be used.