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