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,
728 int64 getMemoryUsage(
bool inclusive)
const;
737 { myGlobalBasis =
b; }
745 void setSize(
int nkeys,
int vector_size);
785 int knot_segment_hint = -1,
786 int order = 0)
const;
789 int knot_segment_hint = -1,
790 int order = 0)
const;
832 int *parm_knot_segment =
nullptr,
833 int order = 0)
const;
840 template <
typename T>
845 T x3 = 2*(iv - ov) + (im + om)*dt;
846 T x2 = ov - iv - im*dt - x3;
850 return x0 + kt*(x1 + kt*(x2 + kt*x3));
852 return x1 + kt*(2*x2 + kt*3*x3);
854 return 2*x2 + kt*6*x3;
864 template <
typename T>
871 fpreal b1 = om * dt - (x1 + ia * dt);
872 fpreal b2 = oa * dt - ia * dt;
880 return x0 + kt*(x1 + kt*(x2 + kt*(x3 + kt*(x4 + kt*x5))));
882 return x1 + kt*(2*x2 + kt*(3*x3 + kt*(4*x4 + kt*5*x5)));
884 return 2*x2 + kt*(6*x3 + kt*(12*x4 + kt*20*x5));
886 return 6*x3 + kt*(24*x4 + kt*60*x5);
888 return 24*x4 + kt*120*x5;
904 int64 getSizeOfValues()
const
905 {
return myKnotLength*myVectorSize*
sizeof(
fpreal64); }
906 int64 getSizeOfBases()
const
909 template <
typename T>
910 inline void combineKeys(
T *
result,
int vector_size,
915 template <
typename T>
918 bool do_multi)
const;
920 template <
typename T>
921 inline void setValueInternal(
int key,
const T *
value,
int size);
923 template <
typename T>
927 template <
typename T>
930 int knot_segment_hint,
int order)
const;
946 #if defined(CPU_HAS_SIMD_INSTR)
947 v4uf row1(1/6., 4/6., 1/6., 0/6.);
948 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
949 v4uf row3(3/6., -6/6., 3/6., 0/6.);
950 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
952 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
953 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
954 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
962 weights += row2 * vt;
963 weights += row3 * vt2;
964 weights += row4 * vt3;
967 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
968 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
970 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
971 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
973 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
974 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
976 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
987 value = cvs[0] * weights[0];
988 value += cvs[1] * weights[1];
989 value += cvs[2] * weights[2];
990 value += cvs[3] * weights[3];
1000 #if defined(CPU_HAS_SIMD_INSTR)
1001 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1002 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1003 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1004 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1014 weights += row2 * vt;
1015 weights += row3 * vt2;
1016 weights += row4 * vt3;
1019 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
1020 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
1033 value = cvs[0] * weights[0];
1034 value += cvs[1] * weights[1];
1035 value += cvs[2] * weights[2];
1036 value += cvs[3] * weights[3];
1047 curseg = SYSfastFloor(start_t);
1048 curseg =
SYSclamp(curseg, 0, nseg-1);
1049 float t = start_t - curseg;
1051 #if defined(CPU_HAS_SIMD_INSTR)
1052 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1053 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1054 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1055 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1057 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1058 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1059 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1061 for (
int i = 0; i < len_t; i++)
1069 weights += row2 *
t;
1070 weights += row3 * t2;
1071 weights += row4 * t3;
1073 v4uf vx = vcvsx * weights;
1074 vx += vx.
swizzle<1, 1, 3, 3>();
1075 vx += vx.
swizzle<2, 2, 2, 2>();
1076 v4uf vy = vcvsy * weights;
1077 vy += vy.
swizzle<1, 1, 3, 3>();
1078 vy += vy.
swizzle<2, 2, 2, 2>();
1079 v4uf vz = vcvsz * weights;
1080 vz += vz.
swizzle<1, 1, 3, 3>();
1081 vz += vz.
swizzle<2, 2, 2, 2>();
1082 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1088 while (curseg < nseg-1)
1097 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1098 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1099 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1104 for (
int i = 0; i < len_t; i++)
1106 results[i] =
evalOpen(&cvs[curseg], t);
1110 while (curseg < nseg-1)
1127 curseg = SYSfastFloor(start_t);
1128 curseg =
SYSclamp(curseg, 0, nseg-1);
1129 float t = start_t - curseg;
1131 #if defined(CPU_HAS_SIMD_INSTR)
1132 v4uf row1(1/6., 4/6., 1/6., 0/6.);
1133 v4uf row2(-3/6., 0/6., 3/6., 0/6.);
1134 v4uf row3(3/6., -6/6., 3/6., 0/6.);
1135 v4uf row4(-1/6., 3/6., -3/6., 1/6. );
1137 v4uf vcvs(&cvs[curseg]);
1139 for (
int i = 0; i < len_t; i++)
1147 weights += row2 *
t;
1148 weights += row3 * t2;
1149 weights += row4 * t3;
1151 v4uf v = vcvs * weights;
1160 while (curseg < nseg-1)
1169 vcvs =
v4uf(&cvs[curseg]);
1174 for (
int i = 0 ; i < len_t; i++)
1176 results[i] =
evalOpen(&cvs[curseg], t);
1180 while (curseg < nseg-1)
1196 #if defined(CPU_HAS_SIMD_INSTR)
1204 v4uf vcvsx(cvs[0].
x(), cvs[1].
x(), cvs[2].
x(), cvs[3].
x());
1205 v4uf vcvsy(cvs[0].
y(), cvs[1].
y(), cvs[2].
y(), cvs[3].
y());
1206 v4uf vcvsz(cvs[0].
z(), cvs[1].
z(), cvs[2].
z(), cvs[3].
z());
1214 weights += row2 * vt;
1215 weights += row3 * vt2;
1216 weights += row4 * vt3;
1219 vcvsx += vcvsx.
swizzle<1, 1, 3, 3>();
1220 vcvsx += vcvsx.
swizzle<2, 2, 2, 2>();
1222 vcvsy += vcvsy.
swizzle<1, 1, 3, 3>();
1223 vcvsy += vcvsy.
swizzle<2, 2, 2, 2>();
1225 vcvsz += vcvsz.
swizzle<1, 1, 3, 3>();
1226 vcvsz += vcvsz.
swizzle<2, 2, 2, 2>();
1228 return UT_Vector3( vcvsx[0], vcvsy[0], vcvsz[0] );
1239 value = cvs[0] * weights[0];
1240 value += cvs[1] * weights[1];
1241 value += cvs[2] * weights[2];
1242 value += cvs[3] * weights[3];
1252 #if defined(CPU_HAS_SIMD_INSTR)
1267 weights += row2 *
t;
1268 weights += row3 * t2;
1269 weights += row4 * t3;
1273 vcvs += vcvs.
swizzle<1, 1, 3, 3>();
1274 vcvs += vcvs.
swizzle<2, 2, 2, 2>();
1287 value = cvs[0] * weights[0];
1288 value += cvs[1] * weights[1];
1289 value += cvs[2] * weights[2];
1290 value += cvs[3] * weights[3];
1301 curseg = SYSfastFloor(start_t);
1302 curseg =
SYSclamp(curseg, 0, nseg-1);
1303 float t = start_t - curseg;
1305 #if defined(CPU_HAS_SIMD_INSTR)
1313 v4uf vcvsx(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1314 v4uf vcvsy(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1315 v4uf vcvsz(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1317 for (
int i = 0; i < len_t; i++)
1325 weights += row2 *
t;
1326 weights += row3 * t2;
1327 weights += row4 * t3;
1329 v4uf vx = vcvsx * weights;
1330 vx += vx.
swizzle<1, 1, 3, 3>();
1331 vx += vx.
swizzle<2, 2, 2, 2>();
1332 v4uf vy = vcvsy * weights;
1333 vy += vy.
swizzle<1, 1, 3, 3>();
1334 vy += vy.
swizzle<2, 2, 2, 2>();
1335 v4uf vz = vcvsz * weights;
1336 vz += vz.
swizzle<1, 1, 3, 3>();
1337 vz += vz.
swizzle<2, 2, 2, 2>();
1338 results[i] =
UT_Vector3( vx[0], vy[0], vz[0] );
1344 while (curseg < nseg-1)
1356 row2 =
v4uf(weightmatrix.
data()+4);
1357 row3 =
v4uf(weightmatrix.
data()+8);
1358 row4 =
v4uf(weightmatrix.
data()+12);
1360 vcvsx =
v4uf(cvs[curseg].
x(), cvs[curseg+1].
x(), cvs[curseg+2].
x(), cvs[curseg+3].
x());
1361 vcvsy =
v4uf(cvs[curseg].
y(), cvs[curseg+1].
y(), cvs[curseg+2].
y(), cvs[curseg+3].
y());
1362 vcvsz =
v4uf(cvs[curseg].
z(), cvs[curseg+1].
z(), cvs[curseg+2].
z(), cvs[curseg+3].
z());
1367 for (
int i = 0; i < len_t; i++)
1369 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1373 while (curseg < nseg-1)
1390 curseg = SYSfastFloor(start_t);
1391 curseg =
SYSclamp(curseg, 0, nseg-1);
1392 float t = start_t - curseg;
1394 #if defined(CPU_HAS_SIMD_INSTR)
1402 v4uf vcvs(&cvs[curseg]);
1404 for (
int i = 0; i < len_t; i++)
1412 weights += row2 *
t;
1413 weights += row3 * t2;
1414 weights += row4 * t3;
1416 v4uf v = vcvs * weights;
1425 while (curseg < nseg-1)
1437 row2 =
v4uf(weightmatrix.
data()+4);
1438 row3 =
v4uf(weightmatrix.
data()+8);
1439 row4 =
v4uf(weightmatrix.
data()+12);
1441 vcvs =
v4uf(&cvs[curseg]);
1446 for (
int i = 0 ; i < len_t; i++)
1448 results[i] =
evalClosed(&cvs[curseg], t, curseg, nseg, deriv);
1452 while (curseg < nseg-1)
1474 UT_Vector3 a = -cvs[0] + cvs[1] * 3.0F + cvs[2] * (-3.0F) + cvs[3];
1479 UT_Vector3 b = cvs[0] + cvs[1] * (-2.0F) + cvs[2];
1485 enlargeBoundingBoxCommon<UT_SplineCubic::evalOpen<float> >(box, cvs,
a,
b,
c, rootmin, rootmax);
1514 enlargeBoundingBoxCommon<UT_SplineCubic::evalSubDStart<float> >(box, cvs,
a,
b,
c, rootmin, rootmax);
1543 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