72 value = cvs[0] * weights[0];
73 value += cvs[1] * weights[1];
74 value += cvs[2] * weights[2];
75 value += cvs[3] * weights[3];
83 static void evalRangeOpen(
T *results,
const T *cvs,
float start_t,
float step_t,
int len_t,
int nseg)
86 curseg = SYSfastFloor(start_t);
87 curseg =
SYSclamp(curseg, 0, nseg-1);
88 float t = start_t - curseg;
90 for (
int i = 0; i < len_t; i++)
92 results[i] = evalOpen(&cvs[curseg], t);
96 while (curseg < nseg-1)
111 template <
typename T>
112 static T evalClosed(
const T *cvs,
float t,
int seg,
int nseg,
bool deriv =
false)
114 UT_Matrix4 weightmatrix = getClosedWeights(seg, nseg, deriv);
123 value = cvs[0] * weights[0];
124 value += cvs[1] * weights[1];
125 value += cvs[2] * weights[2];
126 value += cvs[3] * weights[3];
133 template <
typename T>
134 static void evalRangeClosed(
T *results,
const T *cvs,
float start_t,
float step_t,
int len_t,
int nseg,
bool deriv =
false)
137 curseg = SYSfastFloor(start_t);
138 curseg =
SYSclamp(curseg, 0, nseg-1);
139 float t = start_t - curseg;
141 for (
int i = 0; i < len_t; i++)
143 results[i] = evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
147 while (curseg < nseg-1)
158 template <
typename T>
162 const float onesixth = 0.16666666666666667f;
163 float onesixtht3 = onesixth*t*t*
t;
164 float w0 = 1 - t + onesixtht3;
165 float w1 = t - 2*onesixtht3;
166 float w2 = onesixtht3;
174 template <
typename T>
180 const float onesixth = 0.16666666666666667f;
181 float onesixtht3 = onesixth*t*t*
t;
182 float w0 = 1 - t + onesixtht3;
183 float w1 = t - 2*onesixtht3;
184 float w2 = onesixtht3;
193 template <
float (func)(const
float *,
float)>
197 float rootmin,
float rootmax)
216 for (
int DIM = 0; DIM < 3; DIM++)
224 if (abc[DIM] >= 0 && b2a[DIM] >= 0)
233 fcvs[0] = cvs[0][DIM];
234 fcvs[1] = cvs[1][DIM];
235 fcvs[2] = cvs[2][DIM];
236 fcvs[3] = cvs[3][DIM];
239 if (t1 > rootmin && t1 < rootmax)
241 float v =
func(fcvs, t1);
245 if (nroots == 2 && t2 > rootmin && t2 < rootmax)
247 float v =
func(fcvs, t2);
273 4/6., 0/6., -6/6., 3/6.,
274 1/6., 3/6., 3/6., -3/6.,
275 0/6., 0/6., 0/6., 1/6. );
280 -3/6., 0/6., 3/6., 0/6.,
281 3/6., -6/6., 3/6., 0/6.,
282 -1/6., 3/6., -3/6., 1/6. );
293 T val = cvs[0]*coeff[0] + cvs[1]*coeff[1] + cvs[2]*coeff[2] + cvs[3]*coeff[3];
322 diff = cvs[i+1]-cvs[i];
325 c0 = 0.5*(cvs[i-1]+cvs[i+1]) - cvs[i];
330 c1 = 0.5*(cvs[i]+cvs[i+2]) - cvs[i+1];
338 float ti3 = ti*ti*ti/3;
340 return p0 + (diff*t + (c0*ti3 + c1*t3));
347 return diff + (c1*t2 - c0*ti2);
429 0.25, 0.75, 0.75, -1.75,
442 7/12., 0.25, -1.25, 7/12.,
443 1/6., 0.5, 0.5, -7/12.,
447 7/12., -0.25, -1.25, 11/12.,
448 0.25, 0.75, 0.75, -1.75,
454 if (seg >= 2 && seg < nseg-2)
456 4/6., 0/6., -6/6., 3/6.,
457 1/6., 3/6., 3/6., -3/6.,
458 0/6., 0/6., 0/6., 1/6. );
466 7/12., 0.25, -1.25, 7/12.,
467 1/6., 0.5, 0.5, -0.5,
469 else if (seg == nseg-2)
472 1/6., 0.5, 0.5, -7/12.,
476 7/12., -.25, -1.25, 11/12.,
477 0.25, 0.75, 0.75, -1.75,
520 -0.25, -2.5, 11/4., 0,
527 if (seg >= 2 && seg < nseg-2)
542 else if (seg == nseg-2)
549 -.25, -2.5, 11/4., 0,
577 -1, 1.75, -1, 0.25 );
582 -0.25, 1, -1.75, 1 );
591 -1,1.75,-11/12.,1/6. );
596 -.25,7/12.,-7/12.,0.25 );
601 -1/6.,11/12.,-1.75, 1 );
607 if (seg >= 2 && seg < nseg-2)
609 -3/6., 0/6., 3/6., 0/6.,
610 3/6., -6/6., 3/6., 0/6.,
611 -1/6., 3/6., -3/6., 1/6. );
616 -1,1.75,-11/12., 1/6. );
621 -0.25,7/12., -0.5, 1/6. );
622 else if (seg == nseg-2)
626 -1/6., 0.5,-7/12.,0.25 );
629 -3/6., -.25, 0.75, 0,
631 -1/6.,11/12.,-1.75, 1 );
664 -3, 5.25, -11/4., .5,
669 -.75,7/4.,-7/4.,0.75,
674 -.5, 11/4., -5.25, 3,
681 if (seg >= 2 && seg < nseg-2)
684 -0.5, 1.5, -1.5, 0.5,
689 -3, 5.25, -11/4., .5,
694 -0.75, 7/4., -1.5, .5,
697 else if (seg == nseg-2)
700 -0.5, 1.5, -7/4., 0.75,
727 int64 getMemoryUsage(
bool inclusive)
const;
736 { myGlobalBasis =
b; }
740 void setSize(
int nkeys,
int vector_size);
780 int knot_segment_hint = -1,
781 int order = 0)
const;
784 int knot_segment_hint = -1,
785 int order = 0)
const;
827 int *parm_knot_segment =
nullptr,
828 int order = 0)
const;
835 template <
typename T>
840 T x3 = 2*(iv - ov) + (im + om)*dt;
841 T x2 = ov - iv - im*dt - x3;
845 return x0 + kt*(x1 + kt*(x2 + kt*x3));
847 return x1 + kt*(2*x2 + kt*3*x3);
849 return 2*x2 + kt*6*x3;
865 int64 getSizeOfValues()
const
866 {
return myKnotLength*myVectorSize*
sizeof(
fpreal64); }
867 int64 getSizeOfBases()
const
870 template <
typename T>
871 inline void combineKeys(
T *
result,
int vector_size,
876 template <
typename T>
879 bool do_multi)
const;
881 template <
typename T>
882 inline void setValueInternal(
int key,
const T *
value,
int size);
884 template <
typename T>
888 template <
typename T>
891 int knot_segment_hint,
int order)
const;
907 #if defined(CPU_HAS_SIMD_INSTR)
908 v4uf row1(1/6., 4/6., 1/6., 0/6.);
909 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
910 v4uf row3(3/6., -6/6., 3/6., 0/6.);
911 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
913 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
914 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
915 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
923 weights += row2 * vt;
924 weights += row3 * vt2;
925 weights += row4 * vt3;
928 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
929 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
931 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
932 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
934 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
935 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
937 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
948 value = cvs[0] * weights[0];
949 value += cvs[1] * weights[1];
950 value += cvs[2] * weights[2];
951 value += cvs[3] * weights[3];
961 #if defined(CPU_HAS_SIMD_INSTR)
962 v4uf row1(1/6., 4/6., 1/6., 0/6.);
963 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
964 v4uf row3(3/6., -6/6., 3/6., 0/6.);
965 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
975 weights += row2 * vt;
976 weights += row3 * vt2;
977 weights += row4 * vt3;
980 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
981 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
994 value = cvs[0] * weights[0];
995 value += cvs[1] * weights[1];
996 value += cvs[2] * weights[2];
997 value += cvs[3] * weights[3];
1008 curseg = SYSfastFloor(start_t);
1009 curseg =
SYSclamp(curseg, 0, nseg-1);
1010 float t = start_t - curseg;
1012 #if defined(CPU_HAS_SIMD_INSTR)
1013 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1014 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1015 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1016 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1018 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1019 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1020 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1022 for (
int i = 0; i < len_t; i++)
1030 weights += row2 *
t;
1031 weights += row3 * t2;
1032 weights += row4 * t3;
1035 vx += vx.
swizzle<1, 1, 3, 3>();
1036 vx += vx.
swizzle<2, 2, 2, 2>();
1038 vy += vy.
swizzle<1, 1, 3, 3>();
1039 vy += vy.
swizzle<2, 2, 2, 2>();
1041 vz += vz.
swizzle<1, 1, 3, 3>();
1042 vz += vz.
swizzle<2, 2, 2, 2>();
1043 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1049 while (curseg < nseg-1)
1058 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1059 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1060 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1065 for (
int i = 0; i < len_t; i++)
1067 results[i] =
evalOpen(&cvs[curseg], t);
1071 while (curseg < nseg-1)
1088 curseg = SYSfastFloor(start_t);
1089 curseg =
SYSclamp(curseg, 0, nseg-1);
1090 float t = start_t - curseg;
1092 #if defined(CPU_HAS_SIMD_INSTR)
1093 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1094 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1095 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1096 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1098 v4uf vcvs(&cvs[curseg]);
1100 for (
int i = 0; i < len_t; i++)
1108 weights += row2 *
t;
1109 weights += row3 * t2;
1110 weights += row4 * t3;
1121 while (curseg < nseg-1)
1130 vcvs =
v4uf(&cvs[curseg]);
1135 for (
int i = 0 ; i < len_t; i++)
1137 results[i] =
evalOpen(&cvs[curseg], t);
1141 while (curseg < nseg-1)
1157 #if defined(CPU_HAS_SIMD_INSTR)
1165 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
1166 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
1167 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
1175 weights += row2 * vt;
1176 weights += row3 * vt2;
1177 weights += row4 * vt3;
1180 vcvsx += vcvsx.swizzle<1, 1, 3, 3>();
1181 vcvsx += vcvsx.swizzle<2, 2, 2, 2>();
1183 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
1184 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
1186 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
1187 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
1189 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
1200 value = cvs[0] * weights[0];
1201 value += cvs[1] * weights[1];
1202 value += cvs[2] * weights[2];
1203 value += cvs[3] * weights[3];
1213 #if defined(CPU_HAS_SIMD_INSTR)
1228 weights += row2 *
t;
1229 weights += row3 * t2;
1230 weights += row4 * t3;
1234 vcvs += vcvs.swizzle<1, 1, 3, 3>();
1235 vcvs += vcvs.swizzle<2, 2, 2, 2>();
1248 value = cvs[0] * weights[0];
1249 value += cvs[1] * weights[1];
1250 value += cvs[2] * weights[2];
1251 value += cvs[3] * weights[3];
1262 curseg = SYSfastFloor(start_t);
1263 curseg =
SYSclamp(curseg, 0, nseg-1);
1264 float t = start_t - curseg;
1266 #if defined(CPU_HAS_SIMD_INSTR)
1274 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1275 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1276 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1278 for (
int i = 0; i < len_t; i++)
1286 weights += row2 *
t;
1287 weights += row3 * t2;
1288 weights += row4 * t3;
1291 vx += vx.
swizzle<1, 1, 3, 3>();
1292 vx += vx.
swizzle<2, 2, 2, 2>();
1294 vy += vy.
swizzle<1, 1, 3, 3>();
1295 vy += vy.
swizzle<2, 2, 2, 2>();
1297 vz += vz.
swizzle<1, 1, 3, 3>();
1298 vz += vz.
swizzle<2, 2, 2, 2>();
1299 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1305 while (curseg < nseg-1)
1317 row2 =
v4uf(weightmatrix.
data()+4);
1318 row3 =
v4uf(weightmatrix.
data()+8);
1319 row4 =
v4uf(weightmatrix.
data()+12);
1321 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1322 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1323 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1328 for (
int i = 0; i < len_t; i++)
1330 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1334 while (curseg < nseg-1)
1351 curseg = SYSfastFloor(start_t);
1352 curseg =
SYSclamp(curseg, 0, nseg-1);
1353 float t = start_t - curseg;
1355 #if defined(CPU_HAS_SIMD_INSTR)
1363 v4uf vcvs(&cvs[curseg]);
1365 for (
int i = 0; i < len_t; i++)
1373 weights += row2 *
t;
1374 weights += row3 * t2;
1375 weights += row4 * t3;
1386 while (curseg < nseg-1)
1398 row2 =
v4uf(weightmatrix.
data()+4);
1399 row3 =
v4uf(weightmatrix.
data()+8);
1400 row4 =
v4uf(weightmatrix.
data()+12);
1402 vcvs =
v4uf(&cvs[curseg]);
1407 for (
int i = 0 ; i < len_t; i++)
1409 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1413 while (curseg < nseg-1)
1435 UT_Vector3 a = -cvs[0] + cvs[1] * 3.0F + cvs[2] * (-3.0F) + cvs[3];
1440 UT_Vector3 b = cvs[0] + cvs[1] * (-2.0F) + cvs[2];
1446 enlargeBoundingBoxCommon<UT_SplineCubic::evalOpen<float> >(
box, cvs,
a,
b,
c, rootmin, rootmax);
1475 enlargeBoundingBoxCommon<UT_SplineCubic::evalSubDStart<float> >(
box, cvs,
a,
b,
c, rootmin, rootmax);
1504 enlargeBoundingBoxCommon<UT_SplineCubic::evalSubDEnd<float> >(
box, cvs,
a,
b,
c, rootmin, rootmax);
static const UT_Matrix4 theHermiteDerivBasis
static UT_Matrix4 getClosedWeightsTranspose(int seg, int nseg, bool deriv=false)
UT_SPLINE_BASIS getGlobalBasis() const
Query the basis or knot length of the spline.
static T evalClosed(const T *cvs, float t, int seg, int nseg, bool deriv=false)
GLboolean GLboolean GLboolean b
GLuint GLdouble GLdouble GLint GLint order
int getKnotLength() const
static UT_Matrix4 getOpenWeightsTranspose()
static void evalRangeClosed(T *results, const T *cvs, float start_t, float step_t, int len_t, int nseg, bool deriv=false)
UT_Vector3T< float > UT_Vector3
void setGlobalBasis(UT_SPLINE_BASIS b)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
GLuint const GLchar * name
static T evalSubDStart(const T *cvs, float t)
static UT_Matrix4 getClosedWeights(int seg, int nseg, bool deriv=false)
static void evalRangeOpen(T *results, const T *cvs, float start_t, float step_t, int len_t, int nseg)
fpreal64 getTension() const
UT_Matrix4T< float > UT_Matrix4
static const UT_Matrix4 theInterpFirstBasis
static UT_Matrix4 getOpenWeights()
static const UT_Matrix4 theHermiteBasis
int getVectorSize() const
GLuint GLfloat GLfloat GLfloat x1
GLboolean GLboolean GLboolean GLboolean a
GLsizei GLenum const void * indices
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GLdouble GLdouble GLdouble z
static void enlargeBoundingBoxOpen(UT_BoundingBox &box, const UT_Vector3 *cvs, float rootmin, float rootmax)
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
#define SYS_STATIC_FORCE_INLINE
static const UT_Matrix4 theOpenDerivBasis
static const UT_Matrix4 theSubDFirstBasis
static const UT_Matrix4 theOpenBasis
static T evalCubic(T kt, T dt, T iv, T im, T ov, T om, int order=0)
static void enlargeBoundingBoxSubDStart(UT_BoundingBox &box, const UT_Vector3 *cvs, float rootmin, float rootmax)
static T evalSubDCurve(const T *cvs, float t, int npts, bool deriv=false)
GLsizei const GLint box[]
const T * data() const
Return the raw matrix data.
static T evalMatrix(const UT_Matrix4 &basis, const T cvs[4], float t)
static void enlargeBoundingBoxSubDEnd(UT_BoundingBox &box, const UT_Vector3 *cvs, float rootmin, float rootmax)
static T evalOpen(const T *cvs, float t)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
OIIO_API bool copy(string_view from, string_view to, std::string &err)
UT_Vector3T< T > colVecMult(const UT_Matrix3T< S > &m, const UT_Vector3T< T > &v)
static T evalSubDEnd(const T *cvs, float t)
SYS_STATIC_FORCE_INLINE void enlargeBoundingBoxCommon(UT_BoundingBox &box, const UT_Vector3 *cvs, const UT_Vector3 &a, const UT_Vector3 &b, const UT_Vector3 &c, float rootmin, float rootmax)
GLsizei const GLfloat * value
SYS_FORCE_INLINE v4uf swizzle() const
static const UT_Matrix4 theInterpBasis
UT_API UT_SPLINE_BASIS UTsplineBasisFromName(const char *name)
static int quadratic(T a, T b, T c, T &v0, T &v1)
UT_API const char * UTnameFromSplineBasis(UT_SPLINE_BASIS basis)
static const UT_Matrix4 theSubDFirstDerivBasis