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; }
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;
859 template <
typename T>
866 fpreal b1 = om * dt - (x1 + ia * dt);
867 fpreal b2 = oa * dt - ia * dt;
875 return x0 + kt*(x1 + kt*(x2 + kt*(x3 + kt*(x4 + kt*x5))));
877 return x1 + kt*(2*x2 + kt*(3*x3 + kt*(4*x4 + kt*5*x5)));
879 return 2*x2 + kt*(6*x3 + kt*(12*x4 + kt*20*x5));
881 return 6*x3 + kt*(24*x4 + kt*60*x5);
883 return 24*x4 + kt*120*x5;
899 int64 getSizeOfValues()
const
900 {
return myKnotLength*myVectorSize*
sizeof(
fpreal64); }
901 int64 getSizeOfBases()
const
904 template <
typename T>
905 inline void combineKeys(
T *
result,
int vector_size,
910 template <
typename T>
913 bool do_multi)
const;
915 template <
typename T>
916 inline void setValueInternal(
int key,
const T *
value,
int size);
918 template <
typename T>
922 template <
typename T>
925 int knot_segment_hint,
int order)
const;
941 #if defined(CPU_HAS_SIMD_INSTR)
942 v4uf row1(1/6., 4/6., 1/6., 0/6.);
943 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
944 v4uf row3(3/6., -6/6., 3/6., 0/6.);
945 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
947 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
948 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
949 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
957 weights += row2 * vt;
958 weights += row3 * vt2;
959 weights += row4 * vt3;
962 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
963 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
965 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
966 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
968 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
969 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
971 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
982 value = cvs[0] * weights[0];
983 value += cvs[1] * weights[1];
984 value += cvs[2] * weights[2];
985 value += cvs[3] * weights[3];
995 #if defined(CPU_HAS_SIMD_INSTR)
996 v4uf row1(1/6., 4/6., 1/6., 0/6.);
997 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
998 v4uf row3(3/6., -6/6., 3/6., 0/6.);
999 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1009 weights += row2 * vt;
1010 weights += row3 * vt2;
1011 weights += row4 * vt3;
1014 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
1015 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
1028 value = cvs[0] * weights[0];
1029 value += cvs[1] * weights[1];
1030 value += cvs[2] * weights[2];
1031 value += cvs[3] * weights[3];
1042 curseg = SYSfastFloor(start_t);
1043 curseg =
SYSclamp(curseg, 0, nseg-1);
1044 float t = start_t - curseg;
1046 #if defined(CPU_HAS_SIMD_INSTR)
1047 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1048 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1049 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1050 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1052 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1053 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1054 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1056 for (
int i = 0; i < len_t; i++)
1064 weights += row2 *
t;
1065 weights += row3 * t2;
1066 weights += row4 * t3;
1068 v4uf vx = vcvsx * weights;
1069 vx += vx.
swizzle<1, 1, 3, 3>();
1070 vx += vx.
swizzle<2, 2, 2, 2>();
1071 v4uf vy = vcvsy * weights;
1072 vy += vy.
swizzle<1, 1, 3, 3>();
1073 vy += vy.
swizzle<2, 2, 2, 2>();
1074 v4uf vz = vcvsz * weights;
1075 vz += vz.
swizzle<1, 1, 3, 3>();
1076 vz += vz.
swizzle<2, 2, 2, 2>();
1077 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1083 while (curseg < nseg-1)
1092 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1093 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1094 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1099 for (
int i = 0; i < len_t; i++)
1101 results[i] =
evalOpen(&cvs[curseg], t);
1105 while (curseg < nseg-1)
1122 curseg = SYSfastFloor(start_t);
1123 curseg =
SYSclamp(curseg, 0, nseg-1);
1124 float t = start_t - curseg;
1126 #if defined(CPU_HAS_SIMD_INSTR)
1127 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1128 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1129 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1130 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1132 v4uf vcvs(&cvs[curseg]);
1134 for (
int i = 0; i < len_t; i++)
1142 weights += row2 *
t;
1143 weights += row3 * t2;
1144 weights += row4 * t3;
1146 v4uf v = vcvs * weights;
1155 while (curseg < nseg-1)
1164 vcvs =
v4uf(&cvs[curseg]);
1169 for (
int i = 0 ; i < len_t; i++)
1171 results[i] =
evalOpen(&cvs[curseg], t);
1175 while (curseg < nseg-1)
1191 #if defined(CPU_HAS_SIMD_INSTR)
1199 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
1200 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
1201 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
1209 weights += row2 * vt;
1210 weights += row3 * vt2;
1211 weights += row4 * vt3;
1214 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
1215 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
1217 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
1218 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
1220 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
1221 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
1223 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
1234 value = cvs[0] * weights[0];
1235 value += cvs[1] * weights[1];
1236 value += cvs[2] * weights[2];
1237 value += cvs[3] * weights[3];
1247 #if defined(CPU_HAS_SIMD_INSTR)
1262 weights += row2 *
t;
1263 weights += row3 * t2;
1264 weights += row4 * t3;
1268 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
1269 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
1282 value = cvs[0] * weights[0];
1283 value += cvs[1] * weights[1];
1284 value += cvs[2] * weights[2];
1285 value += cvs[3] * weights[3];
1296 curseg = SYSfastFloor(start_t);
1297 curseg =
SYSclamp(curseg, 0, nseg-1);
1298 float t = start_t - curseg;
1300 #if defined(CPU_HAS_SIMD_INSTR)
1308 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1309 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1310 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1312 for (
int i = 0; i < len_t; i++)
1320 weights += row2 *
t;
1321 weights += row3 * t2;
1322 weights += row4 * t3;
1324 v4uf vx = vcvsx * weights;
1325 vx += vx.
swizzle<1, 1, 3, 3>();
1326 vx += vx.
swizzle<2, 2, 2, 2>();
1327 v4uf vy = vcvsy * weights;
1328 vy += vy.
swizzle<1, 1, 3, 3>();
1329 vy += vy.
swizzle<2, 2, 2, 2>();
1330 v4uf vz = vcvsz * weights;
1331 vz += vz.
swizzle<1, 1, 3, 3>();
1332 vz += vz.
swizzle<2, 2, 2, 2>();
1333 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1339 while (curseg < nseg-1)
1351 row2 =
v4uf(weightmatrix.
data()+4);
1352 row3 =
v4uf(weightmatrix.
data()+8);
1353 row4 =
v4uf(weightmatrix.
data()+12);
1355 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1356 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1357 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1362 for (
int i = 0; i < len_t; i++)
1364 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1368 while (curseg < nseg-1)
1385 curseg = SYSfastFloor(start_t);
1386 curseg =
SYSclamp(curseg, 0, nseg-1);
1387 float t = start_t - curseg;
1389 #if defined(CPU_HAS_SIMD_INSTR)
1397 v4uf vcvs(&cvs[curseg]);
1399 for (
int i = 0; i < len_t; i++)
1407 weights += row2 *
t;
1408 weights += row3 * t2;
1409 weights += row4 * t3;
1411 v4uf v = vcvs * weights;
1420 while (curseg < nseg-1)
1432 row2 =
v4uf(weightmatrix.
data()+4);
1433 row3 =
v4uf(weightmatrix.
data()+8);
1434 row4 =
v4uf(weightmatrix.
data()+12);
1436 vcvs =
v4uf(&cvs[curseg]);
1441 for (
int i = 0 ; i < len_t; i++)
1443 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1447 while (curseg < nseg-1)
1469 UT_Vector3 a = -cvs[0] + cvs[1] * 3.0F + cvs[2] * (-3.0F) + cvs[3];
1474 UT_Vector3 b = cvs[0] + cvs[1] * (-2.0F) + cvs[2];
1480 enlargeBoundingBoxCommon<UT_SplineCubic::evalOpen<float> >(box, cvs,
a,
b, c, rootmin, rootmax);
1509 enlargeBoundingBoxCommon<UT_SplineCubic::evalSubDStart<float> >(box, cvs,
a,
b, c, rootmin, rootmax);
1538 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)
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)
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