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 PXR_IMAGING_PLUGIN_HD_EMBREE_MESH_H
25 #define PXR_IMAGING_PLUGIN_HD_EMBREE_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/plugin/hdEmbree/meshSamplers.h"
34 
35 #include <embree3/rtcore.h>
36 #include <embree3/rtcore_ray.h>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
42 
65 class HdEmbreeMesh final : public HdMesh {
66 public:
67  HF_MALLOC_TAG_NEW("new HdEmbreeMesh");
68 
71  HdEmbreeMesh(SdfPath const& id);
72 
75  virtual ~HdEmbreeMesh() = default;
76 
81  virtual HdDirtyBits GetInitialDirtyBitsMask() const override;
82 
108  virtual void Sync(HdSceneDelegate* sceneDelegate,
109  HdRenderParam* renderParam,
110  HdDirtyBits* dirtyBits,
111  TfToken const &reprToken) override;
112 
117  virtual void Finalize(HdRenderParam *renderParam) override;
118 
119 protected:
120  // Initialize the given representation of this Rprim.
121  // This is called prior to syncing the prim, the first time the repr
122  // is used.
123  //
124  // reprToken is the name of the repr to initalize.
125  //
126  // dirtyBits is an in/out value. It is initialized to the dirty bits
127  // from the change tracker. InitRepr can then set additional dirty bits
128  // if additional data is required from the scene delegate when this
129  // repr is synced. InitRepr occurs before dirty bit propagation.
130  //
131  // See HdRprim::InitRepr()
132  virtual void _InitRepr(TfToken const &reprToken,
133  HdDirtyBits *dirtyBits) override;
134 
135  // This callback from Rprim gives the prim an opportunity to set
136  // additional dirty bits based on those already set. This is done
137  // before the dirty bits are passed to the scene delegate, so can be
138  // used to communicate that extra information is needed by the prim to
139  // process the changes.
140  //
141  // The return value is the new set of dirty bits, which replaces the bits
142  // passed in.
143  //
144  // See HdRprim::PropagateRprimDirtyBits()
145  virtual HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override;
146 
147 private:
148  // Helper functions for getting the prototype and instance contexts.
149  // These don't do null checks, so the user is responsible for calling them
150  // carefully.
151  HdEmbreePrototypeContext* _GetPrototypeContext();
152  HdEmbreeInstanceContext* _GetInstanceContext(RTCScene scene, size_t i);
153 
154  // Populate the embree geometry object based on scene data.
155  void _PopulateRtMesh(HdSceneDelegate *sceneDelegate,
156  RTCScene scene,
157  RTCDevice device,
158  HdDirtyBits *dirtyBits,
159  HdMeshReprDesc const &desc);
160 
161  // Populate _primvarSourceMap (our local cache of primvar data) based on
162  // authored scene data.
163  // Primvars will be turned into samplers in _PopulateRtMesh,
164  // through the help of the _CreatePrimvarSampler() method.
165  void _UpdatePrimvarSources(HdSceneDelegate* sceneDelegate,
166  HdDirtyBits dirtyBits);
167 
168  // Populate _primvarSourceMap with primvars that are computed.
169  // Return the names of the primvars that were successfully updated.
170  TfTokenVector _UpdateComputedPrimvarSources(HdSceneDelegate* sceneDelegate,
171  HdDirtyBits dirtyBits);
172 
173  // Populate a single primvar, with given name and data, in the prototype
174  // context. Overwrites the current mapping for the name, if necessary.
175  // This function's main purpose is to resolve the (interpolation, refined)
176  // tuple into the concrete primvar sampler type.
177  void _CreatePrimvarSampler(TfToken const& name, VtValue const& data,
178  HdInterpolation interpolation,
179  bool refined);
180 
181  // Utility function to call rtcNewSubdivisionMesh and populate topology.
182  RTCGeometry _CreateEmbreeSubdivMesh(RTCScene scene, RTCDevice device);
183  // Utility function to call rtcNewTriangleMesh and populate topology.
184  RTCGeometry _CreateEmbreeTriangleMesh(RTCScene scene, RTCDevice device);
185 
186  // An embree intersection filter callback, for doing backface culling.
187  static void _EmbreeCullFaces(const RTCFilterFunctionNArguments* args);
188 
189 private:
190  // Every HdEmbreeMesh is treated as instanced; if there's no instancer,
191  // the prototype has a single identity istance. The prototype is stored
192  // as _rtcMeshId, in _rtcMeshScene.
193  unsigned _rtcMeshId;
194  RTCScene _rtcMeshScene;
195  // Each instance of the mesh in the top-level scene is stored in
196  // _rtcInstanceIds.
197  std::vector<unsigned> _rtcInstanceIds;
198 
199  // Cached scene data. VtArrays are reference counted, so as long as we
200  // only call const accessors keeping them around doesn't incur a buffer
201  // copy.
202  HdMeshTopology _topology;
203  GfMatrix4f _transform;
204  VtVec3fArray _points;
205 
206  // Derived scene data:
207  // - _triangulatedIndices holds a triangulation of the source topology,
208  // which can have faces of arbitrary arity.
209  // - _trianglePrimitiveParams holds a mapping from triangle index (in
210  // the triangulated topology) to authored face index.
211  // - _computedNormals holds per-vertex normals computed as an average of
212  // adjacent face normals.
213  VtVec3iArray _triangulatedIndices;
214  VtIntArray _trianglePrimitiveParams;
215  VtVec3fArray _computedNormals;
216 
217  // Derived scene data. Hd_VertexAdjacency is an acceleration datastructure
218  // for computing per-vertex smooth normals. _adjacencyValid indicates
219  // whether the datastructure has been rebuilt with the latest topology,
220  // and _normalsValid indicates whether _computedNormals has been
221  // recomputed with the latest points data.
222  Hd_VertexAdjacency _adjacency;
223  bool _adjacencyValid;
224  bool _normalsValid;
225 
226  // Draw styles.
227  bool _refined;
228  bool _smoothNormals;
229  bool _doubleSided;
230  HdCullStyle _cullStyle;
231 
232  // A local cache of primvar scene data. "data" is a copy-on-write handle to
233  // the actual primvar buffer, and "interpolation" is the interpolation mode
234  // to be used. This cache is used in _PopulateRtMesh to populate the
235  // primvar sampler map in the prototype context, which is used for shading.
236  struct PrimvarSource {
237  VtValue data;
238  HdInterpolation interpolation;
239  };
240  TfHashMap<TfToken, PrimvarSource, TfToken::HashFunctor> _primvarSourceMap;
241 
242  // An object used to manage allocation of embree user vertex buffers to
243  // primvars.
244  HdEmbreeRTCBufferAllocator _embreeBufferAllocator;
245 
246  // Embree recommends after creating one should hold onto the geometry
247  //
248  // "However, it is generally recommended to store the geometry handle
249  // inside the application's geometry representation and look up the
250  // geometry handle from that representation directly.""
251  //
252  // found this to be necessary in the case where multiple threads were
253  // commiting to the scene at the same time, and a geometry needed to be
254  // referenced again while other threads were committing
255  RTCGeometry _geometry;
256  std::vector<RTCGeometry> _rtcInstanceGeometries;
257 
258  // This class does not support copying.
259  HdEmbreeMesh(const HdEmbreeMesh&) = delete;
260  HdEmbreeMesh &operator =(const HdEmbreeMesh&) = delete;
261 };
262 
263 PXR_NAMESPACE_CLOSE_SCOPE
264 
265 #endif // PXR_IMAGING_PLUGIN_HD_EMBREE_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 ...
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:87
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:43
An HdEmbree representation of a subdivision surface or poly-mesh object.
Definition: mesh.h:65
Adapter class providing data exchange with the client scene graph.
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
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:106
HdEmbreeMesh(SdfPath const &id)
HdEmbreeMesh constructor.
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:166
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...