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);
256 static inline void enlargeBoundingBoxOpen(
UT_BoundingBox &box,
const UT_Vector3 *cvs,
float rootmin,
float rootmax);
260 static inline void enlargeBoundingBoxSubDStart(
UT_BoundingBox &box,
const UT_Vector3 *cvs,
float rootmin,
float rootmax);
264 static inline void enlargeBoundingBoxSubDEnd(
UT_BoundingBox &box,
const UT_Vector3 *cvs,
float rootmin,
float rootmax);
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; }
744 void setSize(
int nkeys,
int vector_size);
784 int knot_segment_hint = -1,
785 int order = 0)
const;
788 int knot_segment_hint = -1,
789 int order = 0)
const;
831 int *parm_knot_segment =
nullptr,
832 int order = 0)
const;
839 template <
typename T>
844 T x3 = 2*(iv - ov) + (im + om)*dt;
845 T x2 = ov - iv - im*dt - x3;
849 return x0 + kt*(x1 + kt*(x2 + kt*x3));
851 return x1 + kt*(2*x2 + kt*3*x3);
853 return 2*x2 + kt*6*x3;
863 template <
typename T>
870 fpreal b1 = om * dt - (x1 + ia * dt);
871 fpreal b2 = oa * dt - ia * dt;
879 return x0 + kt*(x1 + kt*(x2 + kt*(x3 + kt*(x4 + kt*x5))));
881 return x1 + kt*(2*x2 + kt*(3*x3 + kt*(4*x4 + kt*5*x5)));
883 return 2*x2 + kt*(6*x3 + kt*(12*x4 + kt*20*x5));
885 return 6*x3 + kt*(24*x4 + kt*60*x5);
887 return 24*x4 + kt*120*x5;
903 int64 getSizeOfValues()
const
904 {
return myKnotLength*myVectorSize*
sizeof(
fpreal64); }
905 int64 getSizeOfBases()
const
908 template <
typename T>
909 inline void combineKeys(
T *
result,
int vector_size,
914 template <
typename T>
917 bool do_multi)
const;
919 template <
typename T>
920 inline void setValueInternal(
int key,
const T *
value,
int size);
922 template <
typename T>
926 template <
typename T>
929 int knot_segment_hint,
int order)
const;
945 #if defined(CPU_HAS_SIMD_INSTR)
946 v4uf row1(1/6., 4/6., 1/6., 0/6.);
947 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
948 v4uf row3(3/6., -6/6., 3/6., 0/6.);
949 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
951 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
952 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
953 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
961 weights += row2 * vt;
962 weights += row3 * vt2;
963 weights += row4 * vt3;
966 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
967 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
969 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
970 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
972 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
973 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
975 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
986 value = cvs[0] * weights[0];
987 value += cvs[1] * weights[1];
988 value += cvs[2] * weights[2];
989 value += cvs[3] * weights[3];
999 #if defined(CPU_HAS_SIMD_INSTR)
1000 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1001 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1002 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1003 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1013 weights += row2 * vt;
1014 weights += row3 * vt2;
1015 weights += row4 * vt3;
1018 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
1019 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
1032 value = cvs[0] * weights[0];
1033 value += cvs[1] * weights[1];
1034 value += cvs[2] * weights[2];
1035 value += cvs[3] * weights[3];
1046 curseg = SYSfastFloor(start_t);
1047 curseg =
SYSclamp(curseg, 0, nseg-1);
1048 float t = start_t - curseg;
1050 #if defined(CPU_HAS_SIMD_INSTR)
1051 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1052 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1053 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1054 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1056 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1057 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1058 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1060 for (
int i = 0; i < len_t; i++)
1068 weights += row2 *
t;
1069 weights += row3 * t2;
1070 weights += row4 * t3;
1072 v4uf vx = vcvsx * weights;
1073 vx += vx.
swizzle<1, 1, 3, 3>();
1074 vx += vx.
swizzle<2, 2, 2, 2>();
1075 v4uf vy = vcvsy * weights;
1076 vy += vy.
swizzle<1, 1, 3, 3>();
1077 vy += vy.
swizzle<2, 2, 2, 2>();
1078 v4uf vz = vcvsz * weights;
1079 vz += vz.
swizzle<1, 1, 3, 3>();
1080 vz += vz.
swizzle<2, 2, 2, 2>();
1081 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1087 while (curseg < nseg-1)
1096 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1097 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1098 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1103 for (
int i = 0; i < len_t; i++)
1105 results[i] =
evalOpen(&cvs[curseg], t);
1109 while (curseg < nseg-1)
1126 curseg = SYSfastFloor(start_t);
1127 curseg =
SYSclamp(curseg, 0, nseg-1);
1128 float t = start_t - curseg;
1130 #if defined(CPU_HAS_SIMD_INSTR)
1131 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1132 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1133 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1134 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1136 v4uf vcvs(&cvs[curseg]);
1138 for (
int i = 0; i < len_t; i++)
1146 weights += row2 *
t;
1147 weights += row3 * t2;
1148 weights += row4 * t3;
1150 v4uf v = vcvs * weights;
1159 while (curseg < nseg-1)
1168 vcvs =
v4uf(&cvs[curseg]);
1173 for (
int i = 0 ; i < len_t; i++)
1175 results[i] =
evalOpen(&cvs[curseg], t);
1179 while (curseg < nseg-1)
1195 #if defined(CPU_HAS_SIMD_INSTR)
1203 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
1204 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
1205 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
1213 weights += row2 * vt;
1214 weights += row3 * vt2;
1215 weights += row4 * vt3;
1218 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
1219 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
1221 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
1222 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
1224 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
1225 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
1227 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
1238 value = cvs[0] * weights[0];
1239 value += cvs[1] * weights[1];
1240 value += cvs[2] * weights[2];
1241 value += cvs[3] * weights[3];
1251 #if defined(CPU_HAS_SIMD_INSTR)
1266 weights += row2 *
t;
1267 weights += row3 * t2;
1268 weights += row4 * t3;
1272 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
1273 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
1286 value = cvs[0] * weights[0];
1287 value += cvs[1] * weights[1];
1288 value += cvs[2] * weights[2];
1289 value += cvs[3] * weights[3];
1300 curseg = SYSfastFloor(start_t);
1301 curseg =
SYSclamp(curseg, 0, nseg-1);
1302 float t = start_t - curseg;
1304 #if defined(CPU_HAS_SIMD_INSTR)
1312 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1313 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1314 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1316 for (
int i = 0; i < len_t; i++)
1324 weights += row2 *
t;
1325 weights += row3 * t2;
1326 weights += row4 * t3;
1328 v4uf vx = vcvsx * weights;
1329 vx += vx.
swizzle<1, 1, 3, 3>();
1330 vx += vx.
swizzle<2, 2, 2, 2>();
1331 v4uf vy = vcvsy * weights;
1332 vy += vy.
swizzle<1, 1, 3, 3>();
1333 vy += vy.
swizzle<2, 2, 2, 2>();
1334 v4uf vz = vcvsz * weights;
1335 vz += vz.
swizzle<1, 1, 3, 3>();
1336 vz += vz.
swizzle<2, 2, 2, 2>();
1337 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1343 while (curseg < nseg-1)
1355 row2 =
v4uf(weightmatrix.
data()+4);
1356 row3 =
v4uf(weightmatrix.
data()+8);
1357 row4 =
v4uf(weightmatrix.
data()+12);
1359 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1360 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1361 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1366 for (
int i = 0; i < len_t; i++)
1368 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1372 while (curseg < nseg-1)
1389 curseg = SYSfastFloor(start_t);
1390 curseg =
SYSclamp(curseg, 0, nseg-1);
1391 float t = start_t - curseg;
1393 #if defined(CPU_HAS_SIMD_INSTR)
1401 v4uf vcvs(&cvs[curseg]);
1403 for (
int i = 0; i < len_t; i++)
1411 weights += row2 *
t;
1412 weights += row3 * t2;
1413 weights += row4 * t3;
1415 v4uf v = vcvs * weights;
1424 while (curseg < nseg-1)
1436 row2 =
v4uf(weightmatrix.
data()+4);
1437 row3 =
v4uf(weightmatrix.
data()+8);
1438 row4 =
v4uf(weightmatrix.
data()+12);
1440 vcvs =
v4uf(&cvs[curseg]);
1445 for (
int i = 0 ; i < len_t; i++)
1447 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1451 while (curseg < nseg-1)
1473 UT_Vector3 a = -cvs[0] + cvs[1] * 3.0F + cvs[2] * (-3.0F) + cvs[3];
1478 UT_Vector3 b = cvs[0] + cvs[1] * (-2.0F) + cvs[2];
1484 enlargeBoundingBoxCommon<UT_SplineCubic::evalOpen<float> >(box, cvs,
a,
b,
c, rootmin, rootmax);
1513 enlargeBoundingBoxCommon<UT_SplineCubic::evalSubDStart<float> >(box, cvs,
a,
b,
c, rootmin, rootmax);
1542 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)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
GLsizei GLenum const void * indices
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
int getKnotLength() const
GLsizei const GLfloat * value
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
GLdouble GLdouble GLdouble z
GLboolean GLboolean GLboolean GLboolean a
void setGlobalBasis(UT_SPLINE_BASIS b)
**But if you need a result
static T evalSubDStart(const T *cvs, float t)
__hostdev__ void setValue(uint32_t offset, bool v)
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
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GLdouble GLdouble GLint GLint order
static void enlargeBoundingBoxOpen(UT_BoundingBox &box, const UT_Vector3 *cvs, float rootmin, float rootmax)
#define SYS_STATIC_FORCE_INLINE
static const UT_Matrix4 theOpenDerivBasis
static const UT_Matrix4 theSubDFirstBasis
GLuint const GLchar * name
static const UT_Matrix4 theOpenBasis
GLboolean GLboolean GLboolean b
static T evalCubic(T kt, T dt, T iv, T im, T ov, T om, int order=0)
static T evalQuintic(T kt, T dt, T iv, T im, T ia, T ov, T om, T oa, 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)
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)
LeafData & operator=(const LeafData &)=delete
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)
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