1 // Copyright Contributors to the Open Shading Language project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
4 
5 /////////////////////////////////////////////////////////////////////////
6 /// \file
7 ///
8 /// Shader interpreter implementation of spline
9 /// operator
10 ///
11 /////////////////////////////////////////////////////////////////////////
12 
13 
14 
15 // If enabled, derivatives associated with the knot vectors are
16 // ignored
17 //#define SKIP_KNOT_DERIVS 1
18 
19 
20 #include "oslexec_pvt.h"
21 #include <OSL/dual_vec.h>
22 #include <OSL/Imathx/Imathx.h>
23 #include <OSL/device_string.h>
24 
25 #include <OpenImageIO/fmath.h>
26 #include "splineimpl.h"
27 
28 OSL_NAMESPACE_ENTER
29 
30 namespace pvt {
31 
32 
osl_spline_fff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)33 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_fff(void *out, const char *spline_, void *x,
34                                  void* knots, int knot_count, int knot_arraylen)
35 {
36   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<float, float, float, float, false>
37       (*(float *)out, *(float *)x, (float *)knots, knot_count, knot_arraylen);
38 }
39 
osl_spline_dfdfdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)40 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dfdfdf(void *out, const char *spline_, void *x,
41                                     void* knots, int knot_count, int knot_arraylen)
42 {
43   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<float>, Dual2<float>, Dual2<float>, float, true>
44       (DFLOAT(out), DFLOAT(x), (float *) knots, knot_count, knot_arraylen);
45 }
46 
osl_spline_dffdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)47 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dffdf(void *out, const char *spline_, void *x,
48                                    void* knots, int knot_count, int knot_arraylen)
49 {
50   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<float>, float, Dual2<float>, float, true>
51       (DFLOAT(out), *(float *)x, (float *) knots, knot_count, knot_arraylen);
52 }
53 
osl_spline_dfdff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)54 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dfdff(void *out, const char *spline_, void *x,
55                                    void* knots, int knot_count, int knot_arraylen)
56 {
57   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<float>, Dual2<float>, float, float, false>
58       (DFLOAT(out), DFLOAT(x), (float *) knots, knot_count, knot_arraylen);
59 }
60 
osl_spline_vfv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)61 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_vfv(void *out, const char *spline_, void *x,
62                                  void *knots, int knot_count, int knot_arraylen)
63 {
64   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Vec3, float, Vec3, Vec3, false>
65       (*(Vec3 *)out, *(float *)x, (Vec3 *) knots, knot_count, knot_arraylen);
66 }
67 
osl_spline_dvdfv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)68 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dvdfv(void *out, const char *spline_, void *x,
69                                    void *knots, int knot_count, int knot_arraylen)
70 {
71   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<Vec3>, Dual2<float>, Vec3, Vec3, false>
72       (DVEC(out), DFLOAT(x), (Vec3 *) knots, knot_count, knot_arraylen);
73 }
74 
osl_spline_dvfdv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)75 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dvfdv(void *out, const char *spline_, void *x,
76                                     void *knots, int knot_count, int knot_arraylen)
77 {
78   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<Vec3>, float, Dual2<Vec3>, Vec3, true>
79       (DVEC(out), *(float *)x, (Vec3 *) knots, knot_count, knot_arraylen);
80 }
81 
osl_spline_dvdfdv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)82 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dvdfdv(void *out, const char *spline_, void *x,
83                                     void *knots, int knot_count, int knot_arraylen)
84 {
85   Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<Vec3>, Dual2<float>, Dual2<Vec3>, Vec3, true>
86       (DVEC(out), DFLOAT(x), (Vec3 *) knots, knot_count, knot_arraylen);
87 }
88 
osl_splineinverse_fff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)89 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_fff(void *out, const char *spline_, void *x,
90                                        void* knots, int knot_count, int knot_arraylen)
91 {
92     // Version with no derivs
93   Spline::SplineInterp::create(HDSTR(spline_)).inverse<float>
94       (*(float *)out, *(float *)x, (float *) knots, knot_count, knot_arraylen);
95 }
96 
osl_splineinverse_dfdff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)97 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_dfdff(void *out, const char *spline_, void *x,
98                                          void* knots, int knot_count, int knot_arraylen)
99 {
100     // x has derivs, so return derivs as well
101   Spline::SplineInterp::create(HDSTR(spline_)).inverse<Dual2<float> >
102       (DFLOAT(out), DFLOAT(x), (float *) knots, knot_count, knot_arraylen);
103 }
104 
osl_splineinverse_dfdfdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)105 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_dfdfdf(void *out, const char *spline_, void *x,
106                                           void* knots, int knot_count, int knot_arraylen)
107 {
108     // Ignore knot derivatives
109     osl_splineinverse_dfdff (out, spline_, x, (float *) knots, knot_count, knot_arraylen);
110 }
111 
osl_splineinverse_dffdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)112 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_dffdf(void *out, const char *spline_, void *x,
113                                          void* knots, int knot_count, int knot_arraylen)
114 {
115     // Ignore knot derivs
116     float outtmp = 0;
117     osl_splineinverse_fff (&outtmp, spline_, x, (float *) knots, knot_count, knot_arraylen);
118     DFLOAT(out) = outtmp;
119 }
120 
121 
122 
123 } // namespace pvt
124 OSL_NAMESPACE_EXIT
125