RenderMan  26.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RixShading.h
Go to the documentation of this file.
1 /*
2 # ------------------------------------------------------------------------------
3 #
4 # Copyright (c) 2022 Pixar. All rights reserved.
5 #
6 # The information in this file (the "Software") is provided for the exclusive
7 # use of the software licensees of Pixar ("Licensees"). Licensees have the
8 # right to incorporate the Software into other products for use by other
9 # authorized software licensees of Pixar, without fee. Except as expressly
10 # permitted herein, the Software may not be disclosed to third parties, copied
11 # or duplicated in any form, in whole or in part, without the prior written
12 # permission of Pixar.
13 #
14 # The copyright notices in the Software and this entire statement, including the
15 # above license grant, this restriction and the following disclaimer, must be
16 # included in all copies of the Software, in whole or in part, and all permitted
17 # derivative works of the Software, unless such copies or derivative works are
18 # solely in the form of machine-executable object code generated by a source
19 # language processor.
20 #
21 # PIXAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL PIXAR BE
23 # LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
25 # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
26 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. IN NO CASE WILL
27 # PIXAR'S TOTAL LIABILITY FOR ALL DAMAGES ARISING OUT OF OR IN CONNECTION WITH
28 # THE USE OR PERFORMANCE OF THIS SOFTWARE EXCEED $50.
29 #
30 # Pixar
31 # 1200 Park Ave
32 # Emeryville CA 94608
33 #
34 # ------------------------------------------------------------------------------
35 */
36 
37 #ifndef RixShading_h
38 #define RixShading_h
39 
40 #include <algorithm> // for fill_n
41 #include <cassert> // for assert
42 #include <cstddef> // for NULL, size_t
43 #include <cstring> // for memcpy
44 #include <new> // for operator new
45 #include <vector> // for vector
46 #include "RixInterfaces.h" // for RixContext
47 #include "RixRNG.h" // for random number generation
48 #include "RiTypesHelper.h" // for RtColorRGB, etc
49 
50 class RixBxdf;
51 class RixBxdfFactory;
52 class RixDisplacement;
53 class RixDisplayFilter;
54 class RixDisplayServices;
56 class RixLPEState;
57 class RixLight;
58 class RixLightFilter;
59 class RixOpacity;
60 class RixParameterList;
61 class RixPostLighting;
62 class RixSampleFilter;
64 struct RixBXLobeTraits;
65 struct RixSCParamInfo;
66 struct RtHitPoint;
67 struct RtRayGeometry;
68 
97 #define k_RixShadingVersion 240 // XXY (XX: MAJOR, Y:MINOR)
98 
100 {
104 };
105 
110 {
121 };
122 
128 {
129  // delivered in primary thread...
132  k_RixSCInstanceEdit, // Currently unused
133  k_RixSCCancel, // Currently unused
134  k_RixSCCheckpointRecover, // Restarting at "int increment"
135  // delivered by one (arbitrary) thread...
136  k_RixSCCheckpointWrite, // Writing "int increment" for "string reason" ("checkpoint",
137  // "exiting", or "finished").
138  k_RixSCIncrementBarrier, // Indicates "int increment" about to begin (only sent if
139  // wantsIncrementBarrier is true.)
140 };
141 
169 {
170 public:
171  virtual int GetVersion() const
172  {
173  return m_version;
174  }
175  virtual int GetInterface() const
176  {
177  return k_RixInvalid;
178  }
179 
190  virtual int Init(RixContext& ctx, RtUString const pluginPath) = 0;
191 
195  virtual void Finalize(RixContext& ctx) = 0;
196 
209  virtual RixSCParamInfo const* GetParamTable() = 0;
210 
215  virtual void Synchronize(RixContext& ctx, RixSCSyncMsg syncMsg,
216  RixParameterList const* syncParams) = 0;
217 
275  {
276  k_None = 0x00000000,
277  k_All = 0xFFFFFFFF
278  };
279 
281  {
283  : data(NULL),
284  datalen(0),
285  freefunc(NULL),
286  paramtable(NULL),
288  {}
289  void* data;
290  size_t datalen;
291  void (*freefunc)(void*);
294  };
295 
303  virtual void CreateInstanceData(RixContext& rixCtx, RtUString const handle,
304  RixParameterList const* parameterList,
305  InstanceData* instanceData)
306  {
307  PIXAR_ARGUSED(rixCtx);
308  PIXAR_ARGUSED(handle);
309  PIXAR_ARGUSED(parameterList);
310  PIXAR_ARGUSED(instanceData);
311  }
312 
326  virtual void SynchronizeInstanceData(RixContext& rixCtx, RtUString const handle,
327  RixParameterList const* instanceParams,
328  uint32_t const editHints,
329  InstanceData* instanceData)
330  {
331  PIXAR_ARGUSED(rixCtx);
332  PIXAR_ARGUSED(handle);
333  PIXAR_ARGUSED(instanceParams);
334  PIXAR_ARGUSED(editHints);
335  PIXAR_ARGUSED(instanceData);
336  }
337 
338 protected:
339  RixShadingPlugin(int version) : m_version(version)
340  {}
342  {}
344 };
345 
350 {
352  k_RixSCAnyType, // signals a dynamic binding scenario
363  k_RixSCBxdf, // always uniform
364  k_RixSCLightFilter, // always uniform
365  k_RixSCStructBegin, // always uniform
366  k_RixSCStructEnd, // always uniform
367  k_RixSCSampleFilter, // always uniform
368  k_RixSCDisplayFilter, // always uniform
370 };
371 
375 PRMAN_INLINE size_t
377 {
378  size_t typeSize = 0;
379  switch(type)
380  {
381  case k_RixSCInteger:
382  typeSize = sizeof(int);
383  break;
384  case k_RixSCFloat:
385  typeSize = sizeof(float);
386  break;
387  case k_RixSCFloat2:
388  typeSize = sizeof(RtFloat2);
389  break;
390  case k_RixSCFloat3:
391  typeSize = sizeof(RtFloat3);
392  break;
393  case k_RixSCColor:
394  typeSize = sizeof(RtColorRGB);
395  break;
396  case k_RixSCPoint:
397  typeSize = sizeof(RtPoint3);
398  break;
399  case k_RixSCVector:
400  typeSize = sizeof(RtVector3);
401  break;
402  case k_RixSCNormal:
403  typeSize = sizeof(RtNormal3);
404  break;
405  case k_RixSCMatrix:
406  typeSize = sizeof(RtMatrix4x4);
407  break;
408  case k_RixSCString:
409  typeSize = sizeof(RtUString);
410  break;
411  case k_RixSCBxdf:
412  case k_RixSCLightFilter:
413  case k_RixSCSampleFilter:
415  typeSize = sizeof(void*);
416  break;
417  case k_RixSCStructBegin:
418  case k_RixSCStructEnd:
419  case k_RixSCInvalidType:
420  case k_RixSCAnyType:
421  default:
422  typeSize = 0;
423  break;
424  }
425  return typeSize;
426 }
427 
433 {
435  k_RixSCUniform, // needs an eval per shading "grid"
436  k_RixSCVarying, // needs an eval per shading point
438 };
439 
454 {
455  // clang-format off
457  k_RixSCOutput = 1 << 0,
465  // use Input + output at the same time to indicate invalid
467  // clang-format on
468 };
469 
475 {
480 };
481 
487 {
491 };
492 
500 {
501  k_RayDepth, // ray depth (scattering events)
506  k_RayTrueDepth // ray depth (scattering events + volume envelopes etc.)
507 };
508 
513 {
514  // most common constructor of POD parameters.
515  RixSCParamInfo(RtUString const _name, RixSCType t, RixSCAccess a = k_RixSCInput,
516  int length = -1)
517  : name(_name), customtype(US_NULL), type(t), access(a), arraylen(length)
518  {}
519 
520  // full constructor
521  RixSCParamInfo(RtUString const structName, RtUString const _name, RixSCType t,
522  RixSCAccess a = k_RixSCInput, int length = -1)
523  : name(_name), customtype(structName), type(t), access(a), arraylen(length)
524  {}
525 
526  // default constructor, useful to signal end of paraminfo table
528  : name(US_NULL),
529  customtype(US_NULL),
532  arraylen(-1)
533  {}
534 
535  RtUString name;
536  RtUString customtype; // NULL unless struct
539  int arraylen; // -1 means no array, 0 means empty
540  bool IsArray() const
541  {
542  return (arraylen != -1);
543  }
544 };
545 
554 {
568 };
569 
577 {
578 public:
579  virtual int GetNumParams() const = 0;
580 
587  virtual int GetParamId(const RtUString name, int* paramId) const = 0;
588 
592  virtual int GetParamId(int plistIndex, int* paramId) const = 0;
593 
599  virtual int GetParamInfo(int paramId, RixSCType* type, RixSCConnectionInfo* cInfo,
600  int* arrayLength = NULL) const = 0;
601 
604  int GetParamInfo(int paramId, RixSCType* type, bool* isConnected, int* arrayLength = NULL) const
605  {
606  RixSCConnectionInfo cInfo;
607  int err = GetParamInfo(paramId, type, &cInfo, arrayLength);
608  if (isConnected) *isConnected = (cInfo == k_RixSCNetworkValue);
609  return err;
610  }
611 
622  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, int* result) const = 0;
623  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, float* result) const = 0;
624  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtColorRGB* result) const = 0;
625  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtFloat3* result) const = 0;
626  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtMatrix4x4* result) const = 0;
627  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtUString* result) const = 0;
628  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RixLightFilter** result,
629  void const** instance) const = 0;
630  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RixSampleFilter** result,
631  void const** instance) const = 0;
632  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RixDisplayFilter** result,
633  void const** instance) const = 0;
634 
635 protected:
637  {}
638 };
639 
665 {
666 public:
673  struct Id
674  {
675  Id() : shadingCtxNum(-6666)
676  {}
677  Id(unsigned int i) : shadingCtxNum(static_cast<short>(i & 0xFFFF))
678  {}
679  // Convert to a serialized integral representation.
680  unsigned int Serialize() const
681  {
682  return shadingCtxNum;
683  }
684  void Invalidate()
685  {
686  shadingCtxNum = -6666;
687  }
688  bool IsValid() const
689  {
690  return shadingCtxNum != -6666;
691  }
693  } shadingCtxId;
694 
697  int numPts;
698 
701  struct
702  {
703  // clang-format off
704  unsigned eyePath : 1;
705  unsigned lightPath : 1;
706  unsigned primaryHit : 1;
707  unsigned missContext : 1;
708  unsigned reyesGrid : 1;
709  unsigned aggregateVolume : 1;
712  // clang-format on
713 
717 
721 
722  // The opacity shader is non-NULL when computing presence and
723  // transmission.
725 
726  // The displacement shader is non-NULL when computing displacement
728 
729  // The subsurface shader is non-NULL when invoking subsurf. integrators
731 
732  // The volume shader is non-NULL when invoking volume integrators.
734 
735  // The postlighting shader is non-NULL when invoking postlighting
737  } scTraits; // "uniform" traits associated with the shading context
738 
739  bool HasHits() const
740  {
741  return (scTraits.missContext == 0);
742  }
743  bool HasMisses() const
744  {
745  return (scTraits.missContext == 1);
746  }
747 
748  RixBxdf* GetBxdf() const
749  {
750  assert(scTraits.shadingMode == k_RixSCScatterQuery ||
751  scTraits.shadingMode == k_RixSCVolumeScatterQuery ||
752  scTraits.shadingMode == k_RixSCVolumeTransmissionQuery ||
753  scTraits.shadingMode == k_RixSCBakePatternQuery ||
754  scTraits.shadingMode == k_RixSCBakeIntegratorQuery);
755  return scTraits.bxdf;
756  }
757 
759  {
760  assert(scTraits.shadingMode == k_RixSCOpacityQuery ||
761  scTraits.shadingMode == k_RixSCPresenceQuery ||
763  return scTraits.opacity;
764  }
765 
767  {
768  assert(scTraits.shadingMode == k_RixSCDisplacementQuery);
769  return scTraits.displacement;
770  }
771 
773  {
774  assert(scTraits.shadingMode == k_RixSCScatterQuery ||
775  scTraits.shadingMode == k_RixSCVolumeScatterQuery ||
777  return scTraits.subsurface;
778  }
779 
781  {
782  assert(scTraits.shadingMode == k_RixSCScatterQuery ||
783  scTraits.shadingMode == k_RixSCVolumeScatterQuery ||
784  scTraits.shadingMode == k_RixSCVolumeTransmissionQuery ||
785  scTraits.shadingMode == k_RixSCEmissionQuery);
786  return scTraits.volume;
787  }
788 
790  {
791  assert(scTraits.shadingMode == k_RixSCScatterQuery ||
792  scTraits.shadingMode == k_RixSCVolumeScatterQuery ||
793  scTraits.shadingMode == k_RixSCBakeQuery ||
794  scTraits.shadingMode == k_RixSCBakeIntegratorQuery);
795  return scTraits.postlighting;
796  }
797 
798  virtual bool HasSubsurface() const = 0;
799  virtual RixVolumeIntegrator* BeginSubsurface(int numRays, RtRayGeometry* rays) const = 0;
800  virtual void EndSubsurface(RixVolumeIntegrator*) const = 0;
801 
812  virtual bool HasVolume(RixSCVolumeSelector) const = 0;
814  RtRayGeometry* rays) const = 0;
815  virtual void EndVolume(RixVolumeIntegrator*) const = 0;
818  {
819  return BeginVolume(k_RixSCIncidentVolume, numRays, rays);
820  }
822  {
823  return BeginVolume(k_RixSCOppositeVolume, numRays, rays);
824  }
825 
828  virtual std::vector<const RixShadingContext*> const* GetOverlappingVolumes() const = 0;
829 
834  enum BuiltinVolume // built-in subsurface interior integrator
835  {
836  k_SSDiffusion, // sss using Burley's normalized diffusion model
837  k_SSPathTraced // sss using brute-force volume scattering
838  };
840  void* instanceData) const = 0;
841 
849 
855  int* rayId;
856 
861  RtColorRGB* transmission;
862 
865  RtColorRGB* matteTransmission;
866 
869  RtColorRGB* pointWeight;
870 
874 
875  // When dealing with non-fully-opaque surfaces, and when using probabilistic hit-testing, the
876  // total opacity (product of the `presence` and the `opacity` values returned by RixOpacity) can
877  // be interpreted as the probability that we actually hit the surface.
878  //
879  // When only considering a scalar presence value (i.e. opacity is one, so the total opacity is
880  // monochromatic), the hit probability is usually the inverse of the scalar presence value, and
881  // no special weighting needs to be applied to the shading on hits.
882  //
883  // However, when dealing with arbitrary (i.e. colored) total opacity, it is necessary to weight
884  // the shading on hit by the product of:
885  // - `opacityThroughput`: a colored weight resulting from stochastic continuations that
886  // happened before reaching the selected hit
887  // - `opacityStochasticWeight`: inverse of the local probability of having selected the hit,
888  // knowing that we have reached it
889  // - `opacity`: the total opacity of the selected hit
890 
891  // Per-point colored weight resulting from stochastic continuations that happened before
892  // reaching the selected hit.
893  //
894  // If no probabilistic hit-testing was involved before reaching the current point, or if the ray
895  // only went through surfaces with monochromatic opacity, then this quantity is [1 1 1]. If the
896  // ray went through surfaces with colored opacity, then this quantity is the total transmission
897  // (up to the current point) divided by the probability of reaching this point.
898  RtColorRGB* opacityThroughput;
899 
900  // Per-point combined opacity: the product of presence and opacity for the current point.
901  RtColorRGB* opacity;
902 
903  // Per-point probabilistic hit-testing weight.
904  //
905  // If the current hit's opacity is monochromatic, or if the `opacityThroughput` up to it is
906  // monochromatic, then this quantity only depends on the hit's total opacity. Otherwise, this
907  // weight also depends on the accumulated transmission up to the hit.
909 
911  mutable void* lightingServicesData;
912 
913  // The light shader is non-NULL when the shading context contains
914  // points on the surface of a light
915  RixLight const* light;
916 
917  // This is accessed and used by patterns to generate random numbers
918  // A NULL value of m_rngCtx means the integrator in use does not support
919  // this functionality. Pattern writer needs to check against NULL pointer
920  // before using m_rngCtx. See PxrRand pattern for example code.
921  mutable RixRNG* m_rngCtx;
922  virtual void SetupRngCtxForPattern() const = 0;
923 
928  {
930  };
931  virtual RixBxdf* GetBuiltinBxdf(BuiltinBxdf, RixBxdfFactory*) const = 0;
932 
937  virtual RixDisplayServices* GetDisplayServices(int version = 1) const = 0;
938 
940  {
941  // clang-format off
942  k_P = 0,
944  k_Po,
960  k_u,
961  k_v,
962  k_w,
988  // clang-format on
989  };
990  virtual void GetBuiltinVar(BuiltinVar, int const** var) const = 0;
991  virtual void GetBuiltinVar(BuiltinVar, float const** var) const = 0;
992  virtual void GetBuiltinVar(BuiltinVar, RtFloat3 const** var) const = 0;
993  virtual void GetBuiltinVar(BuiltinVar, RixLPEState* const** var) const = 0;
994 
1020  virtual void SetBuiltinVar(BuiltinVar, float* var) = 0;
1021  virtual void SetBuiltinVar(BuiltinVar, RtFloat3* var) = 0;
1022 
1033  virtual RixSCDetail GetPrimVar(const RtUString name, RixSCType* type, int* arraylen) const = 0;
1034 
1035  virtual RixSCDetail GetPrimVar(const RtUString name, float fill, float const** var,
1036  float const** radius = NULL) const = 0;
1037 
1038  virtual RixSCDetail GetPrimVar(const RtUString name, RtFloat2 fill, RtFloat2 const** var,
1039  float const** radius = NULL) const = 0;
1040 
1041  virtual RixSCDetail GetPrimVar(const RtUString name, RtFloat3 fill, RtFloat3 const** var,
1042  float const** radius = NULL) const = 0;
1043 
1044  virtual RixSCDetail GetPrimVar(const RtUString name, RtUString const** var) const = 0;
1045 
1046  virtual RixSCDetail GetPrimVar(const RtUString name, RtMatrix4x4 const& fill,
1047  RtMatrix4x4 const** var) const = 0;
1048 
1054 
1055  virtual RixSCDetail GetPrimVar(const RtUString name, float const** var, float const** dXdu,
1056  float const** dXdv) const = 0;
1057 
1058  virtual RixSCDetail GetPrimVar(const RtUString name, RtFloat2 const** var, float const** dXdu,
1059  float const** dYdu, float const** dXdv,
1060  float const** dYdv) const = 0;
1061 
1062  virtual RixSCDetail GetPrimVar(const RtUString name, RtFloat3 const** var, float const** dXdu,
1063  float const** dYdu, float const** dZdu, float const** dXdv,
1064  float const** dYdv, float const** dZdv) const = 0;
1065 
1082  virtual void SetPrimVar(const RtUString name, RixSCDetail d, float* var, float* radius) = 0;
1083 
1084  virtual void SetPrimVar(const RtUString name, RixSCDetail d, RtFloat2* var, float* radius) = 0;
1085 
1086  virtual void SetPrimVar(const RtUString name, RixSCDetail d, RtFloat3* var, float* radius) = 0;
1087 
1088  virtual void SetPrimVar(const RtUString name, RixSCDetail d, RtUString* var) = 0;
1089 
1090  virtual void SetPrimVar(const RtUString name, RixSCDetail d, RtMatrix4x4* var) = 0;
1091 
1102  virtual bool GetProperty(RayProperty, void const* /* result */) const
1103  {
1104  return false;
1105  }
1106 
1107  // Shading context obtains the pointer to the corresponding
1108  // integrator and integrator context.
1109  // The integrator is responsible for setting the values.
1110  virtual bool SetProperty(RayProperty, void const* /* in */) const
1111  {
1112  return false;
1113  }
1114 
1116  {
1120  };
1121 
1126  virtual int Transform(TransformInterpretation interp, const RtUString fromSpace,
1127  const RtUString toSpace, RtFloat3* var, float* radius = NULL) const = 0;
1128 
1135  virtual int GetTransform(const RtUString fromSpace, const RtUString toSpace,
1136  RtMatrix4x4 const** matrix, int* numMatrices) const = 0;
1137 
1143  virtual RixShadingContext* CreateMutableContext() const = 0;
1144 
1149  virtual RixShadingContext const* GetPrimaryContext() const = 0;
1150 
1153  virtual RixIntegratorContext* GetIntegratorContext() const = 0;
1154 
1161  virtual RixShadingContext const* GetContextById(RixShadingContext::Id sCtxId) const = 0;
1162 
1197 
1198  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, int const** result,
1199  int const* dflt = NULL, bool promoteToVarying = false) const = 0;
1200 
1201  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, float const** result,
1202  float const* dflt = NULL,
1203  bool promoteToVarying = false) const = 0;
1204 
1205  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtColorRGB const** result,
1206  RtColorRGB const* dflt = NULL,
1207  bool promoteToVarying = false) const = 0;
1208 
1209  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtFloat3 const** result,
1210  RtFloat3 const* dflt = NULL,
1211  bool promoteToVarying = false) const = 0;
1212 
1213  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtMatrix4x4 const** result,
1214  RtMatrix4x4 const* dflt = NULL,
1215  bool promoteToVarying = false) const = 0;
1216 
1217  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RtUString const** result,
1218  RtUString const* dflt = NULL,
1219  bool promoteToVarying = false) const = 0;
1220 
1221  virtual RixSCDetail EvalParam(int paramId, int arrayIndex, RixBxdfFactory** result,
1222  RixBxdfFactory* dflt = NULL,
1223  bool promoteToVarying = false) const = 0;
1224 
1226  {
1229  };
1230 
1237  template <class T>
1238  RixSCDetail EvalAndCopyParam(int paramId, int arrayIndex, T** result, T const* dflt = NULL,
1239  bool promoteToVarying = false, MemCategory mcat = k_BxdfMem) const
1240  {
1241  T const* constResult;
1242  RixSCDetail d = EvalParam(paramId, arrayIndex, &constResult, dflt);
1243  switch (d)
1244  {
1245  case k_RixSCVarying:
1246  *result = (T*)Allocate(this->numPts, sizeof(T), mcat);
1247  memcpy(*result, constResult, this->numPts * sizeof(T));
1248  break;
1249  case k_RixSCUniform:
1250  if (promoteToVarying)
1251  {
1252  *result = (T*)Allocate(this->numPts, sizeof(T), mcat);
1253  std::fill_n(*result, this->numPts, constResult[0]);
1254  }
1255  else
1256  {
1257  *result = (T*)Allocate(1, sizeof(T), mcat);
1258  (*result)[0] = constResult[0];
1259  }
1260  break;
1261  default:
1262  *result = 0x0;
1263  break;
1264  }
1265  return d;
1266  }
1267 
1273  virtual int GetParamId(const RtUString name, int* paramId) const = 0;
1274 
1280  virtual int GetParamInfo(int paramId, RixSCType* type, RixSCConnectionInfo* cInfo,
1281  int* arrayLength = NULL) const = 0;
1282 
1285  int GetParamInfo(int paramId, RixSCType* type, bool* isConnected, int* arrayLength = NULL) const
1286  {
1287  RixSCConnectionInfo cInfo;
1288  int err = GetParamInfo(paramId, type, &cInfo, arrayLength);
1289  if (isConnected) *isConnected = (cInfo == k_RixSCNetworkValue);
1290  return err;
1291  }
1292 
1315  virtual void GetNearestHits(int numRays, RtRayGeometry const* rays,
1316  // result:
1317  RtHitPoint* hits,
1318  // optional parameters:
1319  const RtUString subset = US_NULL,
1320  const RtUString excludeSubset = US_NULL,
1321  RtHitSides hitSides = k_SidesBoth) const = 0;
1322 
1328  virtual bool GetLightEmission(RtColorRGB* emission, int* lightGroupIds = NULL) const = 0;
1329 
1338  virtual void* Allocate(size_t n, size_t size, MemCategory m) const = 0;
1339 
1347  template <class T>
1348  T* New(size_t nObjs, MemCategory cat = k_BxdfMem) const
1349  {
1350  T* mem = static_cast<T*>(Allocate(nObjs, sizeof(T), cat));
1351  return new (mem) T[nObjs];
1352  }
1353 
1366  {
1367  public:
1368  Allocator(RixShadingContext const* sCtx) : m_sCtx(sCtx)
1369  {}
1370  template <typename T>
1371  T* Allocate(int num)
1372  {
1373  if (num == 0) return NULL;
1374  return (T*)m_sCtx->Allocate(num, sizeof(T), k_BxdfMem);
1375  }
1376  template <typename T>
1377  T* AllocFor(MemCategory memcat, int num)
1378  {
1379  if (num == 0) return NULL;
1380  return (T*)m_sCtx->Allocate(num, sizeof(T), memcat);
1381  }
1382  template <typename T>
1383  T* AllocForVolume(int num)
1384  {
1385  // currently the memory-pool lifetime of volumes matches
1386  // that of Bxdf.
1387  if (num == 0) return NULL;
1388  return (T*)m_sCtx->Allocate(num, sizeof(T), k_BxdfMem);
1389  }
1390  template <typename T>
1391  T* AllocForBxdf(int num)
1392  {
1393  if (num == 0) return NULL;
1394  return (T*)m_sCtx->Allocate(num, sizeof(T), k_BxdfMem);
1395  }
1396  template <typename T>
1397  T* AllocForPattern(int num)
1398  {
1399  if (num == 0) return NULL;
1400  return (T*)m_sCtx->Allocate(num, sizeof(T), k_PatternMem);
1401  }
1402 
1403  private:
1404  RixShadingContext const* m_sCtx;
1405  };
1406 
1407 protected:
1409  {}
1410 
1411  // Hide these interfaces. These are not useful/relevant for clients to
1412  // directly call. However, they need to be accessed by the
1413  // RixVolumeIntegrator internals, so allow access for this class only.
1414  friend class RixVolumeIntegrator;
1415  // LightVertexCache::RayDensityEstimation() in UPBP needs to call
1416  // BeginVolumeSampling() so allow it access, too.
1417  friend class LightVertexCache;
1418  virtual RixShadingContext* BeginVolumeSampling() const = 0;
1420  RixBXLobeTraits const* exposeVol = NULL,
1421  int const* membership = NULL) const = 0;
1422 
1423  mutable RixRNG::SampleCtx* m_rngSampleCtx; // assembled by querying into the integrator
1424 };
1425 
1426 #endif