This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mesh.h
1//
2// Copyright 2017 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_IMAGING_PLUGIN_HD_EMBREE_MESH_H
8#define PXR_IMAGING_PLUGIN_HD_EMBREE_MESH_H
9
10#include "pxr/pxr.h"
11#include "pxr/imaging/hd/mesh.h"
12#include "pxr/imaging/hd/enums.h"
13#include "pxr/imaging/hd/vertexAdjacency.h"
15
16#include "pxr/imaging/plugin/hdEmbree/meshSamplers.h"
17
18#include <embree3/rtcore.h>
19#include <embree3/rtcore_ray.h>
20
21PXR_NAMESPACE_OPEN_SCOPE
22
25
48class HdEmbreeMesh final : public HdMesh {
49public:
50 HF_MALLOC_TAG_NEW("new HdEmbreeMesh");
51
55
58 virtual ~HdEmbreeMesh() = default;
59
64 virtual HdDirtyBits GetInitialDirtyBitsMask() const override;
65
91 virtual void Sync(HdSceneDelegate* sceneDelegate,
92 HdRenderParam* renderParam,
93 HdDirtyBits* dirtyBits,
94 TfToken const &reprToken) override;
95
100 virtual void Finalize(HdRenderParam *renderParam) override;
101
102protected:
103 // Initialize the given representation of this Rprim.
104 // This is called prior to syncing the prim, the first time the repr
105 // is used.
106 //
107 // reprToken is the name of the repr to initalize.
108 //
109 // dirtyBits is an in/out value. It is initialized to the dirty bits
110 // from the change tracker. InitRepr can then set additional dirty bits
111 // if additional data is required from the scene delegate when this
112 // repr is synced. InitRepr occurs before dirty bit propagation.
113 //
114 // See HdRprim::InitRepr()
115 virtual void _InitRepr(TfToken const &reprToken,
116 HdDirtyBits *dirtyBits) override;
117
118 // This callback from Rprim gives the prim an opportunity to set
119 // additional dirty bits based on those already set. This is done
120 // before the dirty bits are passed to the scene delegate, so can be
121 // used to communicate that extra information is needed by the prim to
122 // process the changes.
123 //
124 // The return value is the new set of dirty bits, which replaces the bits
125 // passed in.
126 //
127 // See HdRprim::PropagateRprimDirtyBits()
128 virtual HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override;
129
130private:
131 // Helper functions for getting the prototype and instance contexts.
132 // These don't do null checks, so the user is responsible for calling them
133 // carefully.
134 HdEmbreePrototypeContext* _GetPrototypeContext();
135 HdEmbreeInstanceContext* _GetInstanceContext(RTCScene scene, size_t i);
136
137 // Populate the embree geometry object based on scene data.
138 void _PopulateRtMesh(HdSceneDelegate *sceneDelegate,
139 RTCScene scene,
140 RTCDevice device,
141 HdDirtyBits *dirtyBits,
142 HdMeshReprDesc const &desc);
143
144 // Populate _primvarSourceMap (our local cache of primvar data) based on
145 // authored scene data.
146 // Primvars will be turned into samplers in _PopulateRtMesh,
147 // through the help of the _CreatePrimvarSampler() method.
148 void _UpdatePrimvarSources(HdSceneDelegate* sceneDelegate,
149 HdDirtyBits dirtyBits);
150
151 // Populate _primvarSourceMap with primvars that are computed.
152 // Return the names of the primvars that were successfully updated.
153 TfTokenVector _UpdateComputedPrimvarSources(HdSceneDelegate* sceneDelegate,
154 HdDirtyBits dirtyBits);
155
156 // Populate a single primvar, with given name and data, in the prototype
157 // context. Overwrites the current mapping for the name, if necessary.
158 // This function's main purpose is to resolve the (interpolation, refined)
159 // tuple into the concrete primvar sampler type.
160 void _CreatePrimvarSampler(TfToken const& name, VtValue const& data,
161 HdInterpolation interpolation,
162 bool refined);
163
164 // Utility function to call rtcNewSubdivisionMesh and populate topology.
165 RTCGeometry _CreateEmbreeSubdivMesh(RTCScene scene, RTCDevice device);
166 // Utility function to call rtcNewTriangleMesh and populate topology.
167 RTCGeometry _CreateEmbreeTriangleMesh(RTCScene scene, RTCDevice device);
168
169 // An embree intersection filter callback, for doing backface culling.
170 static void _EmbreeCullFaces(const RTCFilterFunctionNArguments* args);
171
172private:
173 // Every HdEmbreeMesh is treated as instanced; if there's no instancer,
174 // the prototype has a single identity instance. The prototype is stored
175 // as _rtcMeshId, in _rtcMeshScene.
176 unsigned _rtcMeshId;
177 RTCScene _rtcMeshScene;
178 // Each instance of the mesh in the top-level scene is stored in
179 // _rtcInstanceIds.
180 std::vector<unsigned> _rtcInstanceIds;
181
182 // Cached scene data. VtArrays are reference counted, so as long as we
183 // only call const accessors keeping them around doesn't incur a buffer
184 // copy.
185 HdMeshTopology _topology;
186 GfMatrix4f _transform;
187 VtVec3fArray _points;
188
189 // Derived scene data:
190 // - _triangulatedIndices holds a triangulation of the source topology,
191 // which can have faces of arbitrary arity.
192 // - _trianglePrimitiveParams holds a mapping from triangle index (in
193 // the triangulated topology) to authored face index.
194 // - _computedNormals holds per-vertex normals computed as an average of
195 // adjacent face normals.
196 VtVec3iArray _triangulatedIndices;
197 VtIntArray _trianglePrimitiveParams;
198 VtVec3fArray _computedNormals;
199
200 // Derived scene data. Hd_VertexAdjacency is an acceleration datastructure
201 // for computing per-vertex smooth normals. _adjacencyValid indicates
202 // whether the datastructure has been rebuilt with the latest topology,
203 // and _normalsValid indicates whether _computedNormals has been
204 // recomputed with the latest points data.
205 Hd_VertexAdjacency _adjacency;
206 bool _adjacencyValid;
207 bool _normalsValid;
208
209 // Draw styles.
210 bool _refined;
211 bool _smoothNormals;
212 bool _doubleSided;
213 HdCullStyle _cullStyle;
214
215 // A local cache of primvar scene data. "data" is a copy-on-write handle to
216 // the actual primvar buffer, and "interpolation" is the interpolation mode
217 // to be used. This cache is used in _PopulateRtMesh to populate the
218 // primvar sampler map in the prototype context, which is used for shading.
219 struct PrimvarSource {
220 VtValue data;
221 HdInterpolation interpolation;
222 };
223 TfHashMap<TfToken, PrimvarSource, TfToken::HashFunctor> _primvarSourceMap;
224
225 // An object used to manage allocation of embree user vertex buffers to
226 // primvars.
227 HdEmbreeRTCBufferAllocator _embreeBufferAllocator;
228
229 // Embree recommends after creating one should hold onto the geometry
230 //
231 // "However, it is generally recommended to store the geometry handle
232 // inside the application's geometry representation and look up the
233 // geometry handle from that representation directly.""
234 //
235 // found this to be necessary in the case where multiple threads were
236 // commiting to the scene at the same time, and a geometry needed to be
237 // referenced again while other threads were committing
238 RTCGeometry _geometry;
239 std::vector<RTCGeometry> _rtcInstanceGeometries;
240
241 // This class does not support copying.
242 HdEmbreeMesh(const HdEmbreeMesh&) = delete;
243 HdEmbreeMesh &operator =(const HdEmbreeMesh&) = delete;
244};
245
246PXR_NAMESPACE_CLOSE_SCOPE
247
248#endif // PXR_IMAGING_PLUGIN_HD_EMBREE_MESH_H
Stores a 4x4 matrix of float elements.
Definition: matrix4f.h:71
An HdEmbree representation of a subdivision surface or poly-mesh object.
Definition: mesh.h:48
virtual void Sync(HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits, TfToken const &reprToken) override
Pull invalidated scene data and prepare/update the renderable representation.
virtual ~HdEmbreeMesh()=default
HdEmbreeMesh destructor.
virtual HdDirtyBits GetInitialDirtyBitsMask() const override
Inform the scene graph which state needs to be downloaded in the first Sync() call: in this case,...
virtual void _InitRepr(TfToken const &reprToken, HdDirtyBits *dirtyBits) override
Initialize the given representation of this Rprim.
virtual void Finalize(HdRenderParam *renderParam) override
Release any resources this class is holding onto: in this case, destroy the geometry object in the em...
HdEmbreeMesh(SdfPath const &id)
HdEmbreeMesh constructor.
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...
Utility class to track which embree user vertex buffers are currently in use.
Definition: meshSamplers.h:27
Hydra Schema for a subdivision surface or poly-mesh object.
Definition: mesh.h:102
Topology data for meshes.
Definition: meshTopology.h:38
The HdRenderParam is an opaque (to core Hydra) handle, to an object that is obtained from the render ...
Adapter class providing data exchange with the client scene graph.
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:274
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:147
A small bit of state attached to each bit of instanced geometry in embree, for the benefit of HdEmbre...
Definition: context.h:46
A small bit of state attached to each bit of prototype geometry in embree, for the benefit of HdEmbre...
Definition: context.h:29
Descriptor to configure the drawItem(s) for a repr.
Definition: mesh.h:38
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440