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_SCENE_DELEGATE_H
25 #define PXR_IMAGING_HD_SCENE_DELEGATE_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hd/api.h"
29 #include "pxr/imaging/hd/version.h"
30 
31 #include "pxr/imaging/hd/aov.h"
32 #include "pxr/imaging/hd/basisCurvesTopology.h"
33 #include "pxr/imaging/hd/enums.h"
34 #include "pxr/imaging/hd/meshTopology.h"
35 #include "pxr/imaging/hd/renderIndex.h"
36 #include "pxr/imaging/hd/repr.h"
37 #include "pxr/imaging/hd/timeSampleArray.h"
38 
39 #include "pxr/imaging/pxOsd/subdivTags.h"
40 
41 #include "pxr/base/vt/array.h"
42 #include "pxr/base/vt/dictionary.h"
43 #include "pxr/base/vt/value.h"
44 #include "pxr/usd/sdf/path.h"
45 
46 #include "pxr/base/gf/vec2i.h"
47 #include "pxr/base/tf/hash.h"
48 
49 #include <memory>
50 #include <vector>
51 
52 PXR_NAMESPACE_OPEN_SCOPE
53 
54 class HdExtComputationContext;
55 
56 /// A shared pointer to a vector of id's.
57 typedef std::shared_ptr<SdfPathVector> HdIdVectorSharedPtr;
58 
59 /// Instancer context: a pair of instancer paths and instance indices.
60 typedef std::vector<std::pair<SdfPath, int>> HdInstancerContext;
61 
62 /// \class HdSyncRequestVector
63 ///
64 /// The SceneDelegate is requested to synchronize prims as the result of
65 /// executing a specific render pass, the following data structure is passed
66 /// back to the delegate to drive synchronization.
67 ///
68 struct HdSyncRequestVector {
69     // The Prims to synchronize in this request.
70     SdfPathVector IDs;
71 
72     // The HdChangeTracker::DirtyBits that are set for each Prim.
73     std::vector<HdDirtyBits> dirtyBits;
74 };
75 
76 /// \struct HdDisplayStyle
77 ///
78 /// Describes how the geometry of a prim should be displayed.
79 ///
80 struct HdDisplayStyle {
81     /// The prim refine level, in the range [0, 8].
82     int refineLevel;
83 
84     /// Is the prim flat shaded.
85     bool flatShadingEnabled;
86 
87     /// Is the prim displacement shaded.
88     bool displacementEnabled;
89 
90     /// Does the prim act "transparent" to allow occluded selection to show
91     /// through?
92     bool occludedSelectionShowsThrough;
93 
94     /// Creates a default DisplayStyle.
95     /// - refineLevel is 0.
96     /// - flatShading is disabled.
97     /// - displacement is enabled.
HdDisplayStyleHdDisplayStyle98     HdDisplayStyle()
99         : refineLevel(0)
100         , flatShadingEnabled(false)
101         , displacementEnabled(true)
102         , occludedSelectionShowsThrough(false)
103     { }
104 
105     /// Creates a DisplayStyle.
106     /// \param refineLevel_ the refine level to display.
107     ///        Valid range is [0, 8].
108     /// \param flatShading enables flat shading, defaults to false.
109     /// \param displacement enables displacement shading, defaults to false.
110     /// \param occludedSelectionShowsThrough controls whether the prim lets
111     ///        occluded selection show through it, defaults to false.
112     HdDisplayStyle(int refineLevel_,
113                    bool flatShading = false,
114                    bool displacement = true,
115                    bool occludedSelectionShowsThrough_ = false)
116         : refineLevel(std::max(0, refineLevel_))
117         , flatShadingEnabled(flatShading)
118         , displacementEnabled(displacement)
119         , occludedSelectionShowsThrough(occludedSelectionShowsThrough_)
120     {
121         if (refineLevel_ < 0) {
122             TF_CODING_ERROR("negative refine level is not supported");
123         } else if (refineLevel_ > 8) {
124             TF_CODING_ERROR("refine level > 8 is not supported");
125         }
126     }
127 
128     HdDisplayStyle(HdDisplayStyle const& rhs) = default;
129     ~HdDisplayStyle() = default;
130 
131     bool operator==(HdDisplayStyle const& rhs) const {
132         return refineLevel == rhs.refineLevel
133             && flatShadingEnabled == rhs.flatShadingEnabled
134             && displacementEnabled == rhs.displacementEnabled
135             && occludedSelectionShowsThrough ==
136                 rhs.occludedSelectionShowsThrough;
137     }
138     bool operator!=(HdDisplayStyle const& rhs) const {
139         return !(*this == rhs);
140     }
141 };
142 
143 /// \struct HdPrimvarDescriptor
144 ///
145 /// Describes a primvar.
146 struct HdPrimvarDescriptor {
147     /// Name of the primvar.
148     TfToken name;
149     /// Interpolation (data-sampling rate) of the primvar.
150     HdInterpolation interpolation;
151     /// Optional "role" indicating a desired interpretation --
152     /// for example, to distinguish color/vector/point/normal.
153     /// See HdPrimvarRoleTokens; default is HdPrimvarRoleTokens->none.
154     TfToken role;
155     /// Optional bool, true if primvar is indexed. This value should be checked
156     /// before calling "GetIndexedPrimvar"
157     bool indexed;
158 
HdPrimvarDescriptorHdPrimvarDescriptor159     HdPrimvarDescriptor()
160     : interpolation(HdInterpolationConstant)
161     , role(HdPrimvarRoleTokens->none)
162     , indexed(false)
163     {}
164     HdPrimvarDescriptor(TfToken const& name_,
165                         HdInterpolation interp_,
166                         TfToken const& role_=HdPrimvarRoleTokens->none,
167                         bool indexed_=false)
nameHdPrimvarDescriptor168         : name(name_), interpolation(interp_), role(role_), indexed(indexed_)
169     { }
170     bool operator==(HdPrimvarDescriptor const& rhs) const {
171         return name == rhs.name && role == rhs.role
172             && interpolation == rhs.interpolation;
173     }
174     bool operator!=(HdPrimvarDescriptor const& rhs) const {
175         return !(*this == rhs);
176     }
177 };
178 
179 typedef std::vector<HdPrimvarDescriptor> HdPrimvarDescriptorVector;
180 
181 /// \struct HdExtComputationPrimvarDescriptor
182 ///
183 /// Extends HdPrimvarDescriptor to describe a primvar that takes
184 /// data from the output of an ExtComputation.
185 ///
186 /// The structure contains the id of the source ExtComputation in the
187 /// render index, the name of an output from that computation from which
188 /// the primvar will take data along with a valueType which describes
189 /// the type of the expected data.
190 struct HdExtComputationPrimvarDescriptor : public HdPrimvarDescriptor {
191     SdfPath sourceComputationId;
192     TfToken sourceComputationOutputName;
193     HdTupleType valueType;
194 
HdExtComputationPrimvarDescriptorHdExtComputationPrimvarDescriptor195     HdExtComputationPrimvarDescriptor() {}
HdExtComputationPrimvarDescriptorHdExtComputationPrimvarDescriptor196     HdExtComputationPrimvarDescriptor(
197         TfToken const& name_,
198         HdInterpolation interp_,
199         TfToken const & role_,
200         SdfPath const & sourceComputationId_,
201         TfToken const & sourceComputationOutputName_,
202         HdTupleType const & valueType_)
203         : HdPrimvarDescriptor(name_, interp_, role_, false)
204         , sourceComputationId(sourceComputationId_)
205         , sourceComputationOutputName(sourceComputationOutputName_)
206         , valueType(valueType_)
207     { }
208     bool operator==(HdExtComputationPrimvarDescriptor const& rhs) const {
209         return HdPrimvarDescriptor::operator==(rhs) &&
210             sourceComputationId == rhs.sourceComputationId &&
211             sourceComputationOutputName == rhs.sourceComputationOutputName &&
212             valueType == rhs.valueType;
213     }
214     bool operator!=(HdExtComputationPrimvarDescriptor const& rhs) const {
215         return !(*this == rhs);
216     }
217 };
218 
219 typedef std::vector<HdExtComputationPrimvarDescriptor>
220         HdExtComputationPrimvarDescriptorVector;
221 
222 /// \struct HdExtComputationInputDescriptor
223 ///
224 /// Describes an input to an ExtComputation that takes data from
225 /// the output of another ExtComputation.
226 ///
227 /// The structure contains the name of the input and the id of the
228 /// source ExtComputation in the render index, and which output of
229 /// that computation to bind the input to.
230 struct HdExtComputationInputDescriptor {
231     TfToken name;
232     SdfPath sourceComputationId;
233     TfToken sourceComputationOutputName;
234 
HdExtComputationInputDescriptorHdExtComputationInputDescriptor235     HdExtComputationInputDescriptor() {}
HdExtComputationInputDescriptorHdExtComputationInputDescriptor236     HdExtComputationInputDescriptor(
237         TfToken const & name_,
238         SdfPath const & sourceComputationId_,
239         TfToken const & sourceComputationOutputName_)
240     : name(name_), sourceComputationId(sourceComputationId_)
241     , sourceComputationOutputName(sourceComputationOutputName_)
242     { }
243 
244     bool operator==(HdExtComputationInputDescriptor const& rhs) const {
245         return name == rhs.name &&
246                sourceComputationId == rhs.sourceComputationId &&
247                sourceComputationOutputName == rhs.sourceComputationOutputName;
248     }
249     bool operator!=(HdExtComputationInputDescriptor const& rhs) const {
250         return !(*this == rhs);
251     }
252 };
253 
254 typedef std::vector<HdExtComputationInputDescriptor>
255         HdExtComputationInputDescriptorVector;
256 
257 /// \struct HdExtComputationOutputDescriptor
258 ///
259 /// Describes an output of an ExtComputation.
260 ///
261 /// The structure contains the name of the output along with a valueType
262 /// which describes the type of the computation output data.
263 struct HdExtComputationOutputDescriptor {
264     TfToken name;
265     HdTupleType valueType;
266 
HdExtComputationOutputDescriptorHdExtComputationOutputDescriptor267     HdExtComputationOutputDescriptor() {}
HdExtComputationOutputDescriptorHdExtComputationOutputDescriptor268     HdExtComputationOutputDescriptor(
269         TfToken const & name_,
270         HdTupleType const & valueType_)
271     : name(name_), valueType(valueType_)
272     { }
273 
274     bool operator==(HdExtComputationOutputDescriptor const& rhs) const {
275         return name == rhs.name &&
276                valueType == rhs.valueType;
277     }
278     bool operator!=(HdExtComputationOutputDescriptor const& rhs) const {
279         return !(*this == rhs);
280     }
281 };
282 
283 typedef std::vector<HdExtComputationOutputDescriptor>
284         HdExtComputationOutputDescriptorVector;
285 
286 /// \struct HdVolumeFieldDescriptor
287 ///
288 /// Description of a single field related to a volume primitive.
289 ///
290 struct HdVolumeFieldDescriptor {
291     TfToken fieldName;
292     TfToken fieldPrimType;
293     SdfPath fieldId;
294 
HdVolumeFieldDescriptorHdVolumeFieldDescriptor295     HdVolumeFieldDescriptor() {}
HdVolumeFieldDescriptorHdVolumeFieldDescriptor296     HdVolumeFieldDescriptor(
297         TfToken const & fieldName_,
298         TfToken const & fieldPrimType_,
299         SdfPath const & fieldId_)
300     : fieldName(fieldName_), fieldPrimType(fieldPrimType_), fieldId(fieldId_)
301     { }
302 };
303 
304 typedef std::vector<HdVolumeFieldDescriptor>
305 	HdVolumeFieldDescriptorVector;
306 
307 /// \class HdSceneDelegate
308 ///
309 /// Adapter class providing data exchange with the client scene graph.
310 ///
311 class HdSceneDelegate {
312 public:
313     /// Constructor used for nested delegate objects which share a RenderIndex.
314     HD_API
315     HdSceneDelegate(HdRenderIndex *parentIndex,
316                     SdfPath const& delegateID);
317 
318     HD_API
319     virtual ~HdSceneDelegate();
320 
321     /// Returns the RenderIndex owned by this delegate.
GetRenderIndex()322     HdRenderIndex& GetRenderIndex() { return *_index; }
323 
324     /// Returns the ID of this delegate, which is used as a prefix for all
325     /// objects it creates in the RenderIndex.
326     ///
327     /// The default value is SdfPath::AbsoluteRootPath().
GetDelegateID()328     SdfPath const& GetDelegateID() const { return _delegateID; }
329 
330     /// Synchronizes the delegate state for the given request vector.
331     HD_API
332     virtual void Sync(HdSyncRequestVector* request);
333 
334     /// Opportunity for the delegate to clean itself up after
335     /// performing parallel work during sync phase
336     HD_API
337     virtual void PostSyncCleanup();
338 
339     // -----------------------------------------------------------------------//
340     /// \name Options
341     // -----------------------------------------------------------------------//
342 
343     /// Returns true if the named option is enabled by the delegate.
344     HD_API
345     virtual bool IsEnabled(TfToken const& option) const;
346 
347 
348     // -----------------------------------------------------------------------//
349     /// \name Rprim Aspects
350     // -----------------------------------------------------------------------//
351 
352     /// Gets the topological mesh data for a given prim.
353     HD_API
354     virtual HdMeshTopology GetMeshTopology(SdfPath const& id);
355 
356     /// Gets the topological curve data for a given prim.
357     HD_API
358     virtual HdBasisCurvesTopology GetBasisCurvesTopology(SdfPath const& id);
359 
360     /// Gets the subdivision surface tags (sharpness, holes, etc).
361     HD_API
362     virtual PxOsdSubdivTags GetSubdivTags(SdfPath const& id);
363 
364 
365     /// Gets the axis aligned bounds of a prim.
366     /// The returned bounds are in the local space of the prim
367     /// (transform is yet to be applied) and should contain the
368     /// bounds of any child prims.
369     ///
370     /// The returned bounds does not include any displacement that
371     /// might occur as the result of running shaders on the prim.
372     HD_API
373     virtual GfRange3d GetExtent(SdfPath const & id);
374 
375     /// Returns the object space transform, including all parent transforms.
376     HD_API
377     virtual GfMatrix4d GetTransform(SdfPath const & id);
378 
379     /// Returns the authored visible state of the prim.
380     HD_API
381     virtual bool GetVisible(SdfPath const & id);
382 
383     /// Returns the doubleSided state for the given prim.
384     HD_API
385     virtual bool GetDoubleSided(SdfPath const & id);
386 
387     /// Returns the cullstyle for the given prim.
388     HD_API
389     virtual HdCullStyle GetCullStyle(SdfPath const &id);
390 
391     /// Returns the shading style for the given prim.
392     HD_API
393     virtual VtValue GetShadingStyle(SdfPath const &id);
394 
395     /// Returns the refinement level for the given prim in the range [0,8].
396     ///
397     /// The refinement level indicates how many iterations to apply when
398     /// subdividing subdivision surfaces or other refinable primitives.
399     HD_API
400     virtual HdDisplayStyle GetDisplayStyle(SdfPath const& id);
401 
402     /// Returns a named value.
403     HD_API
404     virtual VtValue Get(SdfPath const& id, TfToken const& key);
405 
406     /// Returns a named primvar value. If \a *outIndices is not nullptr and the
407     /// primvar has indices, it will return the unflattened primvar and set
408     /// \a *outIndices to the primvar's associated indices, clearing the array
409     /// if the primvar is not indexed.
410     HD_API
411     virtual VtValue GetIndexedPrimvar(SdfPath const& id,
412                                       TfToken const& key,
413                                       VtIntArray *outIndices);
414 
415     /// Returns the authored repr (if any) for the given prim.
416     HD_API
417     virtual HdReprSelector GetReprSelector(SdfPath const &id);
418 
419     /// Returns the render tag that will be used to bucket prims during
420     /// render pass bucketing.
421     HD_API
422     virtual TfToken GetRenderTag(SdfPath const& id);
423 
424     /// Returns the prim categories.
425     HD_API
426     virtual VtArray<TfToken> GetCategories(SdfPath const& id);
427 
428     /// Returns the categories for all instances in the instancer.
429     HD_API
430     virtual std::vector<VtArray<TfToken>>
431     GetInstanceCategories(SdfPath const &instancerId);
432 
433     /// Returns the coordinate system bindings, or a nullptr if none are bound.
434     HD_API
435     virtual HdIdVectorSharedPtr GetCoordSysBindings(SdfPath const& id);
436 
437     // -----------------------------------------------------------------------//
438     /// \name Motion samples
439     // -----------------------------------------------------------------------//
440 
441     /// Store up to \a maxSampleCount transform samples in \a *sampleValues.
442     /// Returns the union of the authored samples and the boundaries
443     /// of the current camera shutter interval. If this number is greater
444     /// than maxSampleCount, you might want to call this function again
445     /// to get all the authored data.
446     /// Sample times are relative to the scene delegate's current time.
447     /// \see GetTransform()
448     HD_API
449     virtual size_t
450     SampleTransform(SdfPath const & id,
451                     size_t maxSampleCount,
452                     float *sampleTimes,
453                     GfMatrix4d *sampleValues);
454 
455     /// Convenience form of SampleTransform() that takes an HdTimeSampleArray.
456     /// This function returns the union of the authored transform samples
457     /// and the boundaries of the current camera shutter interval.
458     template <unsigned int CAPACITY>
459     void
SampleTransform(SdfPath const & id,HdTimeSampleArray<GfMatrix4d,CAPACITY> * sa)460     SampleTransform(SdfPath const & id,
461                     HdTimeSampleArray<GfMatrix4d, CAPACITY> *sa) {
462         size_t authoredSamples =
463             SampleTransform(id, CAPACITY, sa->times.data(), sa->values.data());
464         if (authoredSamples > CAPACITY) {
465             sa->Resize(authoredSamples);
466             size_t authoredSamplesSecondAttempt =
467                 SampleTransform(
468                     id,
469                     authoredSamples,
470                     sa->times.data(),
471                     sa->values.data());
472             // Number of samples should be consisntent through multiple
473             // invokations of the sampling function.
474             TF_VERIFY(authoredSamples == authoredSamplesSecondAttempt);
475         }
476         sa->count = authoredSamples;
477     }
478 
479     /// Store up to \a maxSampleCount transform samples in \a *sampleValues.
480     /// Returns the union of the authored samples and the boundaries
481     /// of the current camera shutter interval. If this number is greater
482     /// than maxSampleCount, you might want to call this function again
483     /// to get all the authored data.
484     /// Sample times are relative to the scene delegate's current time.
485     /// \see GetInstancerTransform()
486     HD_API
487     virtual size_t
488     SampleInstancerTransform(SdfPath const &instancerId,
489                              size_t maxSampleCount,
490                              float *sampleTimes,
491                              GfMatrix4d *sampleValues);
492 
493     /// Convenience form of SampleInstancerTransform()
494     /// that takes an HdTimeSampleArray.
495     /// This function returns the union of the authored samples
496     /// and the boundaries of the current camera shutter interval.
497     template <unsigned int CAPACITY>
498     void
SampleInstancerTransform(SdfPath const & instancerId,HdTimeSampleArray<GfMatrix4d,CAPACITY> * sa)499     SampleInstancerTransform(SdfPath const &instancerId,
500                              HdTimeSampleArray<GfMatrix4d, CAPACITY> *sa) {
501         size_t authoredSamples =
502             SampleInstancerTransform(
503                 instancerId,
504                 CAPACITY,
505                 sa->times.data(),
506                 sa->values.data());
507         if (authoredSamples > CAPACITY) {
508             sa->Resize(authoredSamples);
509             size_t authoredSamplesSecondAttempt =
510                 SampleInstancerTransform(
511                     instancerId,
512                     authoredSamples,
513                     sa->times.data(),
514                     sa->values.data());
515             // Number of samples should be consisntent through multiple
516             // invokations of the sampling function.
517             TF_VERIFY(authoredSamples == authoredSamplesSecondAttempt);
518         }
519         sa->count = authoredSamples;
520     }
521 
522     /// Store up to \a maxSampleCount primvar samples in \a *samplesValues.
523     /// Returns the union of the authored samples and the boundaries
524     /// of the current camera shutter interval. If this number is greater
525     /// than maxSampleCount, you might want to call this function again
526     /// to get all the authored data.
527     ///
528     /// Sample values that are array-valued will have a size described
529     /// by the HdPrimvarDescriptor as applied to the toplogy.
530     ///
531     /// For example, this means that a mesh that is fracturing over time
532     /// will return samples with the same number of points; the number
533     /// of points will change as the scene delegate is resynchronized
534     /// to represent the scene at a time with different topology.
535     ///
536     /// Sample times are relative to the scene delegate's current time.
537     ///
538     /// \see Get()
539     HD_API
540     virtual size_t
541     SamplePrimvar(SdfPath const& id,
542                   TfToken const& key,
543                   size_t maxSampleCount,
544                   float *sampleTimes,
545                   VtValue *sampleValues);
546 
547     /// Convenience form of SamplePrimvar() that takes an HdTimeSampleArray.
548     /// This function returns the union of the authored samples
549     /// and the boundaries of the current camera shutter interval.
550     template <unsigned int CAPACITY>
551     void
552     SamplePrimvar(SdfPath const &id,
553                   TfToken const& key,
554                   HdTimeSampleArray<VtValue, CAPACITY> *sa);
555 
556     /// SamplePrimvar() for getting an unflattened primvar and its indices. If
557     /// \a *sampleIndices is not nullptr and the primvar has indices, it will
558     /// return unflattened primvar samples in \a *sampleValues and the primvar's
559     /// sampled indices in \a *sampleIndices, clearing the \a *sampleIndices
560     /// array if the primvar is not indexed.
561     HD_API
562     virtual size_t
563     SampleIndexedPrimvar(SdfPath const& id,
564                          TfToken const& key,
565                          size_t maxSampleCount,
566                          float *sampleTimes,
567                          VtValue *sampleValues,
568                          VtIntArray *sampleIndices);
569 
570     /// Convenience form of SampleIndexedPrimvar() that takes
571     /// HdTimeSampleArrays. This function returns the union of the authored
572     /// samples and the boundaries of the current camera shutter interval.
573     template <unsigned int CAPACITY>
574     void
575     SampleIndexedPrimvar(SdfPath const &id,
576                          TfToken const& key,
577                          HdIndexedTimeSampleArray<VtValue, CAPACITY> *sa);
578 
579     // -----------------------------------------------------------------------//
580     /// \name Instancer prototypes
581     // -----------------------------------------------------------------------//
582 
583     /// Gets the extracted indices array of the prototype id used in the
584     /// instancer.
585     ///
586     /// example
587     ///  instances:  0, 1, 2, 3, 4, 5
588     ///  protoypes:  A, B, A, A, B, C
589     ///
590     ///    GetInstanceIndices(A) : [0, 2, 3]
591     ///    GetInstanceIndices(B) : [1, 4]
592     ///    GetInstanceIndices(C) : [5]
593     ///    GetInstanceIndices(D) : []
594     ///
595     HD_API
596     virtual VtIntArray GetInstanceIndices(SdfPath const &instancerId,
597                                           SdfPath const &prototypeId);
598 
599     /// Returns the instancer transform.
600     HD_API
601     virtual GfMatrix4d GetInstancerTransform(SdfPath const &instancerId);
602 
603     /// Returns the parent instancer of the given rprim or instancer.
604     HD_API
605     virtual SdfPath GetInstancerId(SdfPath const& primId);
606 
607     /// Returns a list of prototypes of this instancer. The intent is to let
608     /// renderers cache instance indices by giving them a complete set of prims
609     /// to call GetInstanceIndices(instancer, prototype) on.
610     /// XXX: This is currently unused, but may be used in the future.
611     HD_API
612     virtual SdfPathVector GetInstancerPrototypes(SdfPath const& instancerId);
613 
614     // -----------------------------------------------------------------------//
615     /// \name Path Translation
616     // -----------------------------------------------------------------------//
617 
618     /// Returns the scene address of the prim corresponding to the given
619     /// rprim/instance index. This is designed to give paths in scene namespace,
620     /// rather than hydra namespace, so it always strips the delegate ID.
621     HD_API
622     virtual SdfPath GetScenePrimPath(SdfPath const& rprimId,
623                                      int instanceIndex,
624                                      HdInstancerContext *instancerContext = nullptr);
625 
626     // -----------------------------------------------------------------------//
627     /// \name Material Aspects
628     // -----------------------------------------------------------------------//
629 
630     /// Returns the material ID bound to the rprim \p rprimId.
631     HD_API
632     virtual SdfPath GetMaterialId(SdfPath const &rprimId);
633 
634     // Returns a material resource which contains the information
635     // needed to create a material.
636     HD_API
637     virtual VtValue GetMaterialResource(SdfPath const &materialId);
638 
639     // -----------------------------------------------------------------------//
640     /// \name Renderbuffer Aspects
641     // -----------------------------------------------------------------------//
642 
643     /// Returns the allocation descriptor for a given render buffer prim.
644     HD_API
645     virtual HdRenderBufferDescriptor GetRenderBufferDescriptor(SdfPath const& id);
646 
647     // -----------------------------------------------------------------------//
648     /// \name Light Aspects
649     // -----------------------------------------------------------------------//
650 
651     // Returns a single value for a given light and parameter.
652     HD_API
653     virtual VtValue GetLightParamValue(SdfPath const &id,
654                                        TfToken const &paramName);
655 
656     // -----------------------------------------------------------------------//
657     /// \name Camera Aspects
658     // -----------------------------------------------------------------------//
659 
660     /// Returns a single value for a given camera and parameter.
661     /// See HdCameraTokens for the list of paramters.
662     HD_API
663     virtual VtValue GetCameraParamValue(SdfPath const& cameraId,
664                                         TfToken const& paramName);
665 
666     // -----------------------------------------------------------------------//
667     /// \name Volume Aspects
668     // -----------------------------------------------------------------------//
669 
670     HD_API
671     virtual HdVolumeFieldDescriptorVector
672     GetVolumeFieldDescriptors(SdfPath const &volumeId);
673 
674     // -----------------------------------------------------------------------//
675     /// \name ExtComputation Aspects
676     // -----------------------------------------------------------------------//
677 
678     ///
679     /// For the given computation id, returns a list of inputs which
680     /// will be requested from the scene delegate using the Get() method.
681     ///
682     /// See GetExtComputationInputDescriptors and
683     /// GetExtComputationOutpuDescriptors for descriptions of other
684     /// computation inputs and outputs.
685     HD_API
686     virtual TfTokenVector
687     GetExtComputationSceneInputNames(SdfPath const& computationId);
688 
689     ///
690     /// For the given computation id, returns a list of computation
691     /// input descriptors.
692     ///
693     /// See HdExtComputationInputDecriptor
694     HD_API
695     virtual HdExtComputationInputDescriptorVector
696     GetExtComputationInputDescriptors(SdfPath const& computationId);
697 
698     /// For the given computation id, returns a list of computation
699     /// output descriptors.
700     ///
701     /// See HdExtComputationOutputDescriptor
702     HD_API
703     virtual HdExtComputationOutputDescriptorVector
704     GetExtComputationOutputDescriptors(SdfPath const& computationId);
705 
706 
707     /// Returns a list of primvar names that should be bound to
708     /// a generated output from  an ExtComputation for the given prim id and
709     /// interpolation mode.  Binding information is obtained through
710     /// GetExtComputationPrimvarDesc()
711     /// Returns a structure describing source information for a primvar
712     /// that is bound to an ExtComputation.  See HdExtComputationPrimvarDesc
713     /// for the expected information to be returned.
714     HD_API
715     virtual HdExtComputationPrimvarDescriptorVector
716     GetExtComputationPrimvarDescriptors(SdfPath const& id,
717                                         HdInterpolation interpolationMode);
718 
719     /// Returns a single value for a given computation id and input token.
720     /// The token may be a computation input or a computation config parameter.
721     HD_API
722     virtual VtValue GetExtComputationInput(SdfPath const& computationId,
723                                            TfToken const& input);
724 
725     /// Return up to \a maxSampleCount samples for a given computation id and
726     /// input token.
727     /// The token may be a computation input or a computation config parameter.
728     /// Returns the union of the authored samples and the boundaries
729     /// of the current camera shutter interval. If this number is greater
730     /// than maxSampleCount, you might want to call this function again
731     /// to get all the authored data.
732     HD_API
733     virtual size_t SampleExtComputationInput(SdfPath const& computationId,
734                                              TfToken const& input,
735                                              size_t maxSampleCount,
736                                              float *sampleTimes,
737                                              VtValue *sampleValues);
738 
739     /// Convenience form of SampleExtComputationInput() that takes an
740     /// HdTimeSampleArray.
741     /// Returns the union of the authored samples and the boundaries
742     /// of the current camera shutter interval.
743     template <unsigned int CAPACITY>
SampleExtComputationInput(SdfPath const & computationId,TfToken const & input,HdTimeSampleArray<VtValue,CAPACITY> * sa)744     void SampleExtComputationInput(SdfPath const& computationId,
745                                    TfToken const& input,
746                                    HdTimeSampleArray<VtValue, CAPACITY> *sa) {
747         size_t authoredSamples = SampleExtComputationInput(
748                 computationId, input, CAPACITY,
749                 sa->times.data(), sa->values.data());
750 
751         if (authoredSamples > CAPACITY) {
752             sa->Resize(authoredSamples);
753             size_t authoredSamplesSecondAttempt = SampleExtComputationInput(
754                     computationId, input, authoredSamples,
755                     sa->times.data(), sa->values.data());
756             // Number of samples should be consisntent through multiple
757             // invokations of the sampling function.
758             TF_VERIFY(authoredSamples == authoredSamplesSecondAttempt);
759         }
760         sa->count = authoredSamples;
761     }
762 
763     /// Returns the kernel source assigned to the computation at the path id.
764     /// If the string is empty the computation has no GPU kernel and the
765     /// CPU callback should be used.
766     HD_API
767     virtual std::string GetExtComputationKernel(SdfPath const& computationId);
768 
769     /// Requests the scene delegate run the ExtComputation with the given id.
770     /// The context contains the input values that delegate requested through
771     /// GetExtComputationInputNames().
772     ///
773     /// The scene delegate is expected to set each output identified by
774     /// GetExtComputationOutputNames() on the context.
775     ///
776     /// Hydra may invoke the computation on a different thread from
777     /// what HdEngine::Execute() was called on.  It may also invoke
778     /// many computations in parallel.
779     HD_API
780     virtual void InvokeExtComputation(SdfPath const& computationId,
781                                       HdExtComputationContext *context);
782 
783     // -----------------------------------------------------------------------//
784     /// \name Primitive Variables
785     // -----------------------------------------------------------------------//
786 
787     /// Returns descriptors for all primvars of the given interpolation type.
788     HD_API
789     virtual HdPrimvarDescriptorVector
790     GetPrimvarDescriptors(SdfPath const& id, HdInterpolation interpolation);
791 
792     // -----------------------------------------------------------------------//
793     /// \name Task Aspects
794     // -----------------------------------------------------------------------//
795     HD_API
796     virtual TfTokenVector GetTaskRenderTags(SdfPath const& taskId);
797 
798 private:
799     HdRenderIndex *_index;
800     SdfPath _delegateID;
801 
802     HdSceneDelegate() = delete;
803     HdSceneDelegate(HdSceneDelegate &) =  delete;
804     HdSceneDelegate &operator=(HdSceneDelegate &) =  delete;
805 };
806 
807 template <unsigned int CAPACITY>
808 void
SamplePrimvar(SdfPath const & id,TfToken const & key,HdTimeSampleArray<VtValue,CAPACITY> * sa)809 HdSceneDelegate::SamplePrimvar(SdfPath const &id,
810                                TfToken const& key,
811                                HdTimeSampleArray<VtValue, CAPACITY> *sa) {
812     size_t authoredSamples =
813         SamplePrimvar(
814             id,
815             key,
816             CAPACITY,
817             sa->times.data(),
818             sa->values.data());
819     if (authoredSamples > CAPACITY) {
820         sa->Resize(authoredSamples);
821         size_t authoredSamplesSecondAttempt =
822             SamplePrimvar(
823                 id,
824                 key,
825                 authoredSamples,
826                 sa->times.data(),
827                 sa->values.data());
828         // Number of samples should be consistent through multiple
829         // invocations of the sampling function.
830         TF_VERIFY(authoredSamples == authoredSamplesSecondAttempt);
831     }
832     sa->count = authoredSamples;
833 }
834 
835 template <unsigned int CAPACITY>
836 void
SampleIndexedPrimvar(SdfPath const & id,TfToken const & key,HdIndexedTimeSampleArray<VtValue,CAPACITY> * sa)837 HdSceneDelegate::SampleIndexedPrimvar(SdfPath const &id,
838                          TfToken const& key,
839                          HdIndexedTimeSampleArray<VtValue, CAPACITY> *sa) {
840     size_t authoredSamples =
841         SampleIndexedPrimvar(
842             id,
843             key,
844             CAPACITY,
845             sa->times.data(),
846             sa->values.data(),
847             sa->indices.data());
848     if (authoredSamples > CAPACITY) {
849         sa->Resize(authoredSamples);
850         size_t authoredSamplesSecondAttempt =
851             SampleIndexedPrimvar(
852                 id,
853                 key,
854                 authoredSamples,
855                 sa->times.data(),
856                 sa->values.data(),
857                 sa->indices.data());
858         // Number of samples should be consistent through multiple
859         // invocations of the sampling function.
860         TF_VERIFY(authoredSamples == authoredSamplesSecondAttempt);
861     }
862     sa->count = authoredSamples;
863 }
864 
865 PXR_NAMESPACE_CLOSE_SCOPE
866 
867 #endif //PXR_IMAGING_HD_SCENE_DELEGATE_H
868