All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mesh.h
1 //
2 // Copyright 2017 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 HDEMBREE_MESH_H
25 #define HDEMBREE_MESH_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hd/mesh.h"
29 #include "pxr/imaging/hd/enums.h"
30 #include "pxr/imaging/hd/vertexAdjacency.h"
31 #include "pxr/base/gf/matrix4f.h"
32 
33 #include "pxr/imaging/hdEmbree/meshSamplers.h"
34 
35 #include <embree2/rtcore.h>
36 #include <embree2/rtcore_ray.h>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
42 
68 class HdEmbreeMesh final : public HdMesh {
69 public:
70  HF_MALLOC_TAG_NEW("new HdEmbreeMesh");
71 
76  HdEmbreeMesh(SdfPath const& id,
77  SdfPath const& instancerId = SdfPath());
78 
81  virtual ~HdEmbreeMesh() = default;
82 
87  virtual HdDirtyBits GetInitialDirtyBitsMask() const override;
88 
114  virtual void Sync(HdSceneDelegate* sceneDelegate,
115  HdRenderParam* renderParam,
116  HdDirtyBits* dirtyBits,
117  TfToken const &reprToken) override;
118 
123  virtual void Finalize(HdRenderParam *renderParam) override;
124 
125 protected:
126  // Initialize the given representation of this Rprim.
127  // This is called prior to syncing the prim, the first time the repr
128  // is used.
129  //
130  // reprToken is the name of the repr to initalize.
131  //
132  // dirtyBits is an in/out value. It is initialized to the dirty bits
133  // from the change tracker. InitRepr can then set additional dirty bits
134  // if additional data is required from the scene delegate when this
135  // repr is synced. InitRepr occurs before dirty bit propagation.
136  //
137  // See HdRprim::InitRepr()
138  virtual void _InitRepr(TfToken const &reprToken,
139  HdDirtyBits *dirtyBits) override;
140 
141  // This callback from Rprim gives the prim an opportunity to set
142  // additional dirty bits based on those already set. This is done
143  // before the dirty bits are passed to the scene delegate, so can be
144  // used to communicate that extra information is needed by the prim to
145  // process the changes.
146  //
147  // The return value is the new set of dirty bits, which replaces the bits
148  // passed in.
149  //
150  // See HdRprim::PropagateRprimDirtyBits()
151  virtual HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override;
152 
153 private:
154  // Helper functions for getting the prototype and instance contexts.
155  // These don't do null checks, so the user is responsible for calling them
156  // carefully.
157  HdEmbreePrototypeContext* _GetPrototypeContext();
158  HdEmbreeInstanceContext* _GetInstanceContext(RTCScene scene, size_t i);
159 
160  // Populate the embree geometry object based on scene data.
161  void _PopulateRtMesh(HdSceneDelegate *sceneDelegate,
162  RTCScene scene,
163  RTCDevice device,
164  HdDirtyBits *dirtyBits,
165  HdMeshReprDesc const &desc);
166 
167  // Populate _primvarSourceMap (our local cache of primvar data) based on
168  // authored scene data.
169  // Primvars will be turned into samplers in _PopulateRtMesh,
170  // through the help of the _CreatePrimvarSampler() method.
171  void _UpdatePrimvarSources(HdSceneDelegate* sceneDelegate,
172  HdDirtyBits dirtyBits);
173 
174  // Populate _primvarSourceMap with primvars that are computed.
175  // Return the names of the primvars that were successfully updated.
176  TfTokenVector _UpdateComputedPrimvarSources(HdSceneDelegate* sceneDelegate,
177  HdDirtyBits dirtyBits);
178 
179  // Populate a single primvar, with given name and data, in the prototype
180  // context. Overwrites the current mapping for the name, if necessary.
181  // This function's main purpose is to resolve the (interpolation, refined)
182  // tuple into the concrete primvar sampler type.
183  void _CreatePrimvarSampler(TfToken const& name, VtValue const& data,
184  HdInterpolation interpolation,
185  bool refined);
186 
187  // Utility function to call rtcNewSubdivisionMesh and populate topology.
188  void _CreateEmbreeSubdivMesh(RTCScene scene);
189  // Utility function to call rtcNewTriangleMesh and populate topology.
190  void _CreateEmbreeTriangleMesh(RTCScene scene);
191 
192  // An embree intersection filter callback, for doing backface culling.
193  static void _EmbreeCullFaces(void *userData, RTCRay &ray);
194 
195 private:
196  // Every HdEmbreeMesh is treated as instanced; if there's no instancer,
197  // the prototype has a single identity istance. The prototype is stored
198  // as _rtcMeshId, in _rtcMeshScene.
199  unsigned _rtcMeshId;
200  RTCScene _rtcMeshScene;
201  // Each instance of the mesh in the top-level scene is stored in
202  // _rtcInstanceIds.
203  std::vector<unsigned> _rtcInstanceIds;
204 
205  // Cached scene data. VtArrays are reference counted, so as long as we
206  // only call const accessors keeping them around doesn't incur a buffer
207  // copy.
208  HdMeshTopology _topology;
209  GfMatrix4f _transform;
210  VtVec3fArray _points;
211 
212  // Derived scene data:
213  // - _triangulatedIndices holds a triangulation of the source topology,
214  // which can have faces of arbitrary arity.
215  // - _trianglePrimitiveParams holds a mapping from triangle index (in
216  // the triangulated topology) to authored face index.
217  // - _computedNormals holds per-vertex normals computed as an average of
218  // adjacent face normals.
219  VtVec3iArray _triangulatedIndices;
220  VtIntArray _trianglePrimitiveParams;
221  VtVec3fArray _computedNormals;
222 
223  // Derived scene data. Hd_VertexAdjacency is an acceleration datastructure
224  // for computing per-vertex smooth normals. _adjacencyValid indicates
225  // whether the datastructure has been rebuilt with the latest topology,
226  // and _normalsValid indicates whether _computedNormals has been
227  // recomputed with the latest points data.
228  Hd_VertexAdjacency _adjacency;
229  bool _adjacencyValid;
230  bool _normalsValid;
231 
232  // Draw styles.
233  bool _refined;
234  bool _smoothNormals;
235  bool _doubleSided;
236  HdCullStyle _cullStyle;
237 
238  // A local cache of primvar scene data. "data" is a copy-on-write handle to
239  // the actual primvar buffer, and "interpolation" is the interpolation mode
240  // to be used. This cache is used in _PopulateRtMesh to populate the
241  // primvar sampler map in the prototype context, which is used for shading.
242  struct PrimvarSource {
243  VtValue data;
244  HdInterpolation interpolation;
245  };
246  TfHashMap<TfToken, PrimvarSource, TfToken::HashFunctor> _primvarSourceMap;
247 
248  // An object used to manage allocation of embree user vertex buffers to
249  // primvars.
250  HdEmbreeRTCBufferAllocator _embreeBufferAllocator;
251 
252  // This class does not support copying.
253  HdEmbreeMesh(const HdEmbreeMesh&) = delete;
254  HdEmbreeMesh &operator =(const HdEmbreeMesh&) = delete;
255 };
256 
257 PXR_NAMESPACE_CLOSE_SCOPE
258 
259 #endif // HDEMBREE_MESH_H
Stores a 4x4 matrix of float elements.
Definition: matrix4f.h:88
Descriptor to configure the drawItem(s) for a repr.
Definition: mesh.h:54
virtual void Sync(HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits, TfToken const &reprToken) override
Pull invalidated scene data and prepare/update the renderable representation.
The HdRenderParam is an opaque (to core Hydra) handle, to an object that is obtained from the render ...
HdEmbreeMesh(SdfPath const &id, SdfPath const &instancerId=SdfPath())
HdEmbreeMesh constructor.
virtual void _InitRepr(TfToken const &reprToken, HdDirtyBits *dirtyBits) override
Initialize the given representation of this Rprim.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
A small bit of state attached to each bit of instanced geometry in embree, for the benefit of HdEmbre...
Definition: context.h:62
Utility class to track which embree user vertex buffers are currently in use.
Definition: meshSamplers.h:48
An HdEmbree representation of a subdivision surface or poly-mesh object.
Definition: mesh.h:68
Adapter class providing data exchange with the client scene graph.
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:438
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:287
A small bit of state attached to each bit of prototype geometry in embree, for the benefit of HdEmbre...
Definition: context.h:45
virtual HdDirtyBits GetInitialDirtyBitsMask() const override
Inform the scene graph which state needs to be downloaded in the first Sync() call: in this case...
Hydra Schema for a subdivision surface or poly-mesh object.
Definition: mesh.h:105
Topology data for meshes.
Definition: meshTopology.h:55
virtual void Finalize(HdRenderParam *renderParam) override
Release any resources this class is holding onto: in this case, destroy the geometry object in the em...
virtual ~HdEmbreeMesh()=default
HdEmbreeMesh destructor.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:182
virtual HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override
This callback from Rprim gives the prim an opportunity to set additional dirty bits based on those al...