32#define DNA_DEPRECATED_ALLOW
84 std::optional<Library *> owner_library,
90 const Curve *curve_src = (
const Curve *)id_src;
109 reinterpret_cast<ID **
>(&curve_dst->
key),
125 if (!curve->edit_data_from_original) {
148 for (
int i = 0; i < curve->totcol; i++) {
221 if (cu->
vfont ==
nullptr) {
253 if (cu->
vfont ==
nullptr) {
351 cu->
type = curve_type;
373 cu->
tb[0].
w = cu->
tb[0].
h = 0.0;
474 float texspace_location[3], texspace_size[3];
477 texspace_size[0] = (
bounds->max[0] -
bounds->min[0]) / 2.0f;
478 texspace_size[1] = (
bounds->max[1] -
bounds->min[1]) / 2.0f;
479 texspace_size[2] = (
bounds->max[2] -
bounds->min[2]) / 2.0f;
481 for (
int a = 0; a < 3; a++) {
482 if (texspace_size[a] == 0.0f) {
483 texspace_size[a] = 1.0f;
485 else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) {
486 texspace_size[a] = 0.00001f;
488 else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) {
489 texspace_size[a] = -0.00001f;
517 if (index - tot < tot_nu) {
518 copy_v3_v3(r_co, nu->bezt[index - tot].vec[1]);
523 tot_nu = nu->pntsu * nu->pntsv;
524 if (index - tot < tot_nu) {
541 tot += 3 * nu->pntsu;
544 tot += nu->pntsu * nu->pntsv;
560 tot += nu->pntsu * nu->pntsv;
614 if (newnu ==
nullptr) {
617 *newnu = blender::dna::shallow_copy(*nu);
651 *newnu = blender::dna::shallow_copy(*src);
654 std::swap(pntsu, pntsv);
656 newnu->
pntsu = pntsu;
657 newnu->
pntsv = pntsv;
693 bezt->
vec[0][2] = 0.0;
694 bezt->
vec[1][2] = 0.0;
695 bezt->
vec[2][2] = 0.0;
721 float radius_vector[3];
722 radius_vector[0] = radius_vector[1] = radius_vector[2] = bezt->
radius;
742 if (nu->
pntsv == 1 && use_radius) {
743 float radius_vector[3];
744 radius_vector[0] = radius_vector[1] = radius_vector[2] = bp->
radius;
767 int resolu = resolution ? resolution : nu->
resolu;
768 int pntsu = nu->
pntsu;
769 float *points, *pntsit, *prevpntsit;
776 prevbp = nu->
bp + (nu->
pntsu - 1);
790 points = (
float *)
MEM_mallocN(
sizeof(
float[3]) * (resolu + 1),
"getLength_bezier");
807 for (
int j = 0; j < 3; j++) {
817 prevpntsit = pntsit = points;
821 length +=
len_v3v3(prevpntsit, pntsit);
832 if (nu->
pntsv == 1) {
834 points = (
float *)
MEM_callocN(
sizeof(
float[3]) * pntsu * resolu,
"getLength_nurbs");
839 b = pntsu * resolu + 1;
840 prevpntsit = points + 3 * (pntsu * resolu - 1);
844 b = (pntsu - 1) * resolu;
850 length +=
len_v3v3(prevpntsit, pntsit);
868 for (i = 0, bp = &nu->
bp[nu->
pntsu]; i < number; i++, bp++) {
882 for (i = 0, bezt = &nu->
bezt[nu->
pntsu]; i < number; i++, bezt++) {
891 const int totu = nu->
pntsu;
892 const int totv = nu->
pntsv;
897 else if (u < 0 || u >= totu) {
908 return (
v * totu) + u;
913 const int totu = nu->
pntsu;
914 const int totv = nu->
pntsv;
916 *r_u = (index % totu);
917 *r_v = (index / totu) % totv;
928 bezt_next = nu->
bezt;
935 bezt_next = bezt + 1;
947 if (bp == &nu->
bp[nu->
pntsu - 1]) {
969 if (bezt == nu->
bezt) {
978 bezt_prev = bezt - 1;
993 bp_prev = &nu->
bp[nu->
pntsu - 1];
1009 float dir_prev[3], dir_next[3];
1023 float dir_prev[3], dir_next[3];
1049 float dir_mid[3], tvec[3];
1086 float dir_prev[3] = {0.0f}, dir_next[3] = {0.0f};
1100 float dir_mid[3], tvec[3];
1111static void calcknots(
float *knots,
const int pnts,
const short order,
const short flag)
1117 const int repeat_inner = is_bezier ? order - 1 : 1;
1119 const int head = is_end_point ? (order - (
is_cyclic ? 1 : 0)) :
1120 (is_bezier ?
min_ii(2, repeat_inner) : 1);
1123 const int tail =
is_cyclic ? 2 * order - 1 : (is_end_point ? order : 0);
1125 const int knot_count = pnts + order + (
is_cyclic ? order - 1 : 0);
1128 float current = 0.0f;
1130 const int offset = is_end_point &&
is_cyclic ? 1 : 0;
1136 for (
const int i :
IndexRange(offset, knot_count - offset - tail)) {
1145 const int tail_index = knot_count - tail;
1147 knots[tail_index + i] = current + (knots[i] - knots[0]);
1192 float t,
short order,
int pnts,
const float *knots,
float *basis,
int *start,
int *end)
1195 int i, i1 = 0, i2 = 0, j, orderpluspnts, opp2, o2;
1197 orderpluspnts = order + pnts;
1198 opp2 = orderpluspnts - 1;
1204 else if (t > knots[opp2]) {
1210 for (i = 0; i < opp2; i++) {
1211 if (knots[i] != knots[i + 1] && t >= knots[i] && t <= knots[i + 1]) {
1231 for (j = 2; j <= order; j++) {
1233 if (i2 + j >= orderpluspnts) {
1237 for (i = i1; i <= i2; i++) {
1238 if (basis[i] != 0.0f) {
1239 d = ((t - knots[i]) * basis[i]) / (knots[i + j - 1] - knots[i]);
1245 if (basis[i + 1] != 0.0f) {
1246 e = ((knots[i + j] - t) * basis[i + 1]) / (knots[i + j] - knots[i + 1]);
1259 for (i = i1; i <= i2; i++) {
1260 if (basis[i] > 0.0f) {
1262 if (*start == 1000) {
1272 float *basisu, *basis, *basisv, *
sum, *fp, *in;
1273 float u,
v, ustart, uend, ustep, vstart, vend, vstep, sumdiv;
1274 int i, j, iofs, jofs, cycl,
len, curu, curv;
1275 int istart, iend, jsta, jen, *jstart, *jend, ratcomp;
1277 int totu = nu->
pntsu * resolu, totv = nu->
pntsv * resolv;
1288 if (coord_array ==
nullptr) {
1304 if (bp->
vec[3] != 1.0f) {
1312 ustart = fp[nu->
orderu - 1];
1317 uend = fp[nu->
pntsu];
1324 vstart = fp[nu->
orderv - 1];
1330 vend = fp[nu->
pntsv];
1370 jsta = jstart[curv];
1377 for (j = jsta; j <= jen; j++) {
1379 if (j >= nu->
pntsv) {
1380 jofs = (j - nu->
pntsv);
1385 bp = nu->
bp + nu->
pntsu * jofs + istart - 1;
1387 for (i = istart; i <= iend; i++, fp++) {
1388 if (i >= nu->
pntsu) {
1389 iofs = i - nu->
pntsu;
1390 bp = nu->
bp + nu->
pntsu * jofs + iofs;
1397 *fp = basisu[i] * basis[j] * bp->
vec[3];
1401 *fp = basisu[i] * basis[j];
1408 for (j = jsta; j <= jen; j++) {
1409 for (i = istart; i <= iend; i++, fp++) {
1419 for (j = jsta; j <= jen; j++) {
1421 if (j >= nu->
pntsv) {
1422 jofs = (j - nu->
pntsv);
1427 bp = nu->
bp + nu->
pntsu * jofs + istart - 1;
1429 for (i = istart; i <= iend; i++, fp++) {
1430 if (i >= nu->
pntsu) {
1431 iofs = i - nu->
pntsu;
1432 bp = nu->
bp + nu->
pntsu * jofs + iofs;
1448 if (rowstride != 0) {
1449 in = (
float *)(((
uchar *)in) + (rowstride - 3 * totv *
sizeof(*in)));
1464 float *radius_array,
1465 float *weight_array,
1469 const float eps = 1e-6f;
1471 float u, ustart, uend, ustep, sumdiv;
1472 float *basisu, *
sum, *fp;
1473 float *coord_fp = coord_array, *tilt_fp = tilt_array, *radius_fp = radius_array,
1474 *weight_fp = weight_array;
1475 int i,
len, istart, iend, cycl;
1477 if (nu->
knotsu ==
nullptr) {
1483 if (coord_array ==
nullptr) {
1502 ustart = fp[nu->
orderu - 1];
1507 uend = fp[nu->
pntsu];
1527 bp = nu->
bp + istart - 1;
1528 for (i = istart; i <= iend; i++, fp++) {
1529 if (i >= nu->
pntsu) {
1530 bp = nu->
bp + (i - nu->
pntsu);
1536 *fp = basisu[i] * bp->
vec[3];
1539 if ((sumdiv != 0.0f) && (sumdiv < 1.0f -
eps || sumdiv > 1.0f +
eps)) {
1542 for (i = istart; i <= iend; i++, fp++) {
1551 bp = nu->
bp + istart - 1;
1552 for (i = istart; i <= iend; i++, fp++) {
1553 if (i >= nu->
pntsu) {
1554 bp = nu->
bp + (i - nu->
pntsu);
1564 (*tilt_fp) += (*fp) * bp->
tilt;
1568 (*radius_fp) += (*fp) * bp->
radius;
1572 (*weight_fp) += (*fp) * bp->
weight;
1600 const bool use_cyclic_duplicate_endpoint)
1603 const uint points_len = (segments * resolu) + (
is_cyclic ? (use_cyclic_duplicate_endpoint) : 1);
1608 const uint bezt_array_len,
1611 const bool use_cyclic_duplicate_endpoint,
1618 bezt_array_len, resolu,
is_cyclic, use_cyclic_duplicate_endpoint);
1619 float *r_points_offset = r_points;
1621 const uint resolu_stride = resolu * stride;
1622 const uint bezt_array_last = bezt_array_len - 1;
1624 for (
uint i = 0; i < bezt_array_last; i++) {
1625 const BezTriple *bezt_curr = &bezt_array[i];
1626 const BezTriple *bezt_next = &bezt_array[i + 1];
1628 bezt_curr->
vec[2][axis],
1629 bezt_next->
vec[0][axis],
1630 bezt_next->
vec[1][axis],
1634 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, resolu_stride);
1638 const BezTriple *bezt_curr = &bezt_array[bezt_array_last];
1639 const BezTriple *bezt_next = &bezt_array[0];
1641 bezt_curr->
vec[2][axis],
1642 bezt_next->
vec[0][axis],
1643 bezt_next->
vec[1][axis],
1647 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, resolu_stride);
1648 if (use_cyclic_duplicate_endpoint) {
1649 *r_points_offset = *r_points;
1650 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, stride);
1654 float *r_points_last = (
float *)
POINTER_OFFSET(r_points, bezt_array_last * resolu_stride);
1655 *r_points_last = bezt_array[bezt_array_last].
vec[1][axis];
1656 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, stride);
1664 float q0,
float q1,
float q2,
float q3,
float *p,
int it,
int stride)
1666 float rt0, rt1, rt2, rt3, f;
1671 rt1 = 3.0f * (
q1 - q0) / f;
1673 rt2 = 3.0f * (q0 - 2.0f *
q1 + q2) / f;
1675 rt3 = (q3 - q0 + 3.0f * (
q1 - q2)) / f;
1678 q1 = rt1 + rt2 + rt3;
1679 q2 = 2 * rt2 + 6 * rt3;
1682 for (a = 0; a <= it; a++) {
1692 float q0,
float q1,
float q2,
float q3,
float *p,
int it,
int stride)
1694 float rt0, rt1, rt2, f;
1697 f = 1.0f /
float(it);
1699 rt0 = 3.0f * (
q1 - q0);
1700 rt1 = f * (3.0f * (q3 - q0) + 9.0f * (
q1 - q2));
1701 rt2 = 6.0f * (q0 + q2) - 12.0f *
q1;
1704 q1 = f * (rt1 + rt2);
1705 q2 = 2.0f * f * rt1;
1707 for (a = 0; a <= it; a++) {
1727 for (
int a = 0; a <= it; a++) {
1730 for (
int i = 0; i < 3; i++) {
1731 p[i] = (-6.0f * t + 6.0f) * p0[i] + (18.0f * t - 12.0f) * p1[i] +
1732 (-18.0f * t + 6.0f) * p2[i] + (6.0f * t) * p3[i];
1757 deler = (v1[cox] -
v2[cox]) * (v3[coy] - v4[coy]) - (v3[cox] - v4[cox]) * (v1[coy] -
v2[coy]);
1758 if (deler == 0.0f) {
1762 *lambda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]);
1763 *lambda = -(*lambda / deler);
1765 deler = v3[coy] - v4[coy];
1767 deler = v3[cox] - v4[cox];
1768 *mu = -(*lambda * (
v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler;
1771 *mu = -(*lambda * (
v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler;
1773 vec[cox] = *lambda * (
v2[cox] - v1[cox]) + v1[cox];
1774 vec[coy] = *lambda * (
v2[coy] - v1[coy]) + v1[coy];
1776 if (*lambda >= 0.0f && *lambda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) {
1777 if (*lambda == 0.0f || *lambda == 1.0f || *mu == 0.0f || *mu == 1.0f) {
1790 float min,
max, vec[3], hvec1[3], hvec2[3], lab, mu;
1791 int nr, links = 0, rechts = 0, mode;
1796 hvec1[0] = bevp->
vec[0];
1797 hvec1[1] = bevp->
vec[1];
1807 prevbevp = bevp + (nr - 1);
1814 max = prevbevp->
vec[1];
1817 if (
min <= hvec1[1] && max >= hvec1[1]) {
1819 mode =
cu_isectLL(prevbevp->
vec, bevp->
vec, hvec1, hvec2, 0, 1, &lab, &mu, vec);
1823 if (mode >= 0 && lab != 0.0f) {
1824 if (vec[0] < hvec1[0]) {
1837 return (links & 1) && (rechts & 1);
1850 if (x1->
left > x2->left) {
1853 if (x1->
left < x2->left) {
1862 float x1,
float y1,
float x2,
float y2,
float *r_sina,
float *r_cosa)
1864 float t01, t02, x3, y3;
1866 t01 =
sqrtf(x1 * x1 + y1 * y1);
1867 t02 =
sqrtf(x2 * x2 + y2 * y2);
1880 t02 = x1 * x2 + y1 * y2;
1881 if (
fabsf(t02) >= 1.0f) {
1895 if (x3 == 0 && y3 == 0) {
1900 t01 =
sqrtf(x3 * x3 + y3 * y3);
1905 *r_sina = -y3 / t02;
1913 float *radius_array,
1914 float *weight_array,
1919 float fac, dfac, t[4];
1922 if (tilt_array ==
nullptr && radius_array ==
nullptr) {
1929 if (prevbezt == nu->
bezt) {
1938 pprev = prevbezt - 1;
1955 dfac = 1.0f /
float(resolu);
1957 for (a = 0; a < resolu; a++, fac += dfac) {
1961 *tilt_array = prevbezt->
tilt +
1962 (bezt->
tilt - prevbezt->
tilt) * (3.0f * fac * fac - 2.0f * fac * fac * fac);
1966 *tilt_array = t[0] * pprev->
tilt + t[1] * prevbezt->
tilt + t[2] * bezt->
tilt +
1979 (3.0f * fac * fac - 2.0f * fac * fac * fac);
1987 *radius_array = t[0] * pprev->
radius + t[1] * prevbezt->
radius + t[2] * bezt->
radius +
1988 t[3] *
next->radius;
1997 (3.0f * fac * fac - 2.0f * fac * fac * fac);
2016 bevp1 = bevp2 + (bl->
nr - 1);
2076 bevp1 = bevp2 + (bl->
nr - 1);
2098 bevp1 = bevp2 + (bl->
nr - 1);
2120 float bevp0_quat[4];
2125 bevp1 = bevp2 + (bl->
nr - 1);
2130 if (bl->
poly == -1) {
2147 float zaxis[3] = {0, 0, 1},
cross[3], q2[4];
2219 bevp1 = bevp2 + (bl->
nr - 1);
2225 if (nr >= nr_init) {
2238 if (bl->
poly != -1) {
2251 float vec_1[3] = {0, 1, 0}, vec_2[3] = {0, 1, 0},
angle, ang_fac, cross_tmp[3];
2257 bevp_first += bl->
nr - 1;
2258 bevp_last = bevp_first;
2286 bevp1 = bevp2 + (bl->
nr - 1);
2291 ang_fac = angle * (1.0f - (
float(nr) / bl->
nr));
2312 bevp1 = bevp2 + (bl->
nr - 1);
2330 bevp1 = bevp2 + (bl->
nr - 1);
2347 bevp1 = bevp2 + (bl->
nr - 1);
2356 const float zero[3] = {0, 0, 0};
2370 switch (twist_mode) {
2419 const float x1 = bevp1->
vec[0] - bevp2->
vec[0];
2420 const float y1 = bevp1->
vec[1] - bevp2->
vec[1];
2438 if (bl->
poly != -1) {
2440 bevp1 = bevp2 + (bl->
nr - 1);
2453 const float x1 = bevp1->
vec[0] - bevp0->
vec[0];
2454 const float x2 = bevp1->
vec[0] - bevp2->
vec[0];
2455 const float y1 = bevp1->
vec[1] - bevp0->
vec[1];
2456 const float y2 = bevp1->
vec[1] - bevp2->
vec[1];
2472 if (bl->
poly == -1) {
2485 bevp += (bl->
nr - 1);
2495 if (nu->
pntsu > 1) {
2500 last_bevp = first_bevp + (bl->
nr - 1);
2513 if (bl->seglen !=
nullptr) {
2516 if (bl->segbevcount !=
nullptr) {
2519 if (bl->bevpoints !=
nullptr) {
2541 BevPoint *bevp2, *bevp1 =
nullptr, *bevp0;
2542 const float threshold = 0.00001f;
2544 float *seglen =
nullptr;
2546 int a,
b, nr, poly, resolu = 0,
len = 0, segcount;
2548 bool do_tilt, do_radius, do_weight;
2549 bool is_editmode =
false;
2553 const bool need_seglen =
ELEM(
2557 bev = &ob->
runtime->curve_cache->bev;
2573 if (nu->hide && is_editmode) {
2603 resolu = nu->resolu;
2610 BevList *bl = MEM_cnew<BevList>(__func__);
2634 if (seglen !=
nullptr &&
len != 0) {
2638 if (*seglen > threshold) {
2658 len = segcount * resolu + 1;
2660 BevList *bl = MEM_cnew<BevList>(__func__);
2676 if (seglen !=
nullptr) {
2685 prevbezt = nu->bezt + (nu->pntsu - 1);
2708 if (seglen !=
nullptr) {
2713 if (bevp->
offset > threshold) {
2724 for (j = 0; j < 3; j++) {
2726 prevbezt->
vec[2][j],
2738 do_tilt ? &bevp->
tilt :
nullptr,
2739 do_radius ? &bevp->
radius :
nullptr,
2740 do_weight ? &bevp->
weight :
nullptr,
2755 if (seglen !=
nullptr) {
2758 for (j = 0; j < resolu; j++) {
2763 if (bevp->
offset > threshold) {
2793 if (nu->pntsv == 1) {
2794 len = (resolu * segcount);
2796 BevList *bl = MEM_cnew<BevList>(__func__);
2814 do_tilt ? &bevp->
tilt :
nullptr,
2815 do_radius ? &bevp->
radius :
nullptr,
2816 do_weight ? &bevp->
weight :
nullptr,
2821 if (seglen !=
nullptr) {
2830 for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) {
2832 if (bevp->
offset > threshold) {
2859 const float threshold_resolu = 0.00001f / resolu;
2863 bevp1 = bl->bevpoints;
2864 bevp0 = bevp1 + (nr - 1);
2867 bevp0 = bl->bevpoints;
2873 if (seglen !=
nullptr) {
2881 bevp0->dupe_tag =
true;
2891 if (bl->nr == 0 || bl->dupe_nr == 0) {
2895 nr = bl->nr - bl->dupe_nr + 1;
2897 memcpy(blnew, bl,
sizeof(
BevList));
2904 blnew->
seglen = bl->seglen;
2908 bevp0 = bl->bevpoints;
2912 if (bevp0->dupe_tag == 0) {
2913 memcpy(bevp1, bevp0,
sizeof(
BevPoint));
2919 if (bl->bevpoints !=
nullptr) {
2929 if (bl->nr && bl->poly >= 0) {
2943 bevp = bl->bevpoints;
2944 bevp1 = bl->bevpoints;
2948 if (
min > bevp->
vec[0]) {
2957 bevp = bl->bevpoints;
2958 if (bevp1 == bevp) {
2959 bevp0 = bevp + (bl->nr - 1);
2964 bevp = bevp + (bl->nr - 1);
2965 if (bevp1 == bevp) {
2966 bevp2 = bl->bevpoints;
2972 inp = ((bevp1->
vec[0] - bevp0->vec[0]) * (bevp0->vec[1] - bevp2->
vec[1]) +
2973 (bevp0->vec[1] - bevp1->
vec[1]) * (bevp0->vec[0] - bevp2->
vec[0]));
2988 for (a = 1; a < poly; a++, sd++) {
2990 sd1 = sortdata + (a - 1);
2991 for (
b = a - 1;
b >= 0;
b--, sd1--) {
3004 for (a = 0; a < poly; a++, sd++) {
3008 bevp2 = bevp1 + (bl->
nr - 1);
3011 std::swap(*bevp1, *bevp2);
3029 else if (bl->nr == 2) {
3044 else if (bl->nr == 2) {
3062 char fcurve_smoothing)
3065#define p2_h1 ((p2)-3)
3066#define p2_h2 ((p2) + 3)
3068 const float *p1, *p3;
3071 float dvec_a[3], dvec_b[3];
3072 float len, len_a, len_b;
3073 const float eps = 1
e-5;
3078 if (bezt->
h1 == 0 && bezt->
h2 == 0) {
3084 if (prev ==
nullptr) {
3086 pt[0] = 2.0f * p2[0] - p3[0];
3087 pt[1] = 2.0f * p2[1] - p3[1];
3088 pt[2] = 2.0f * p2[2] - p3[2];
3095 if (
next ==
nullptr) {
3096 pt[0] = 2.0f * p2[0] - p1[0];
3097 pt[1] = 2.0f * p2[1] - p1[1];
3098 pt[2] = 2.0f * p2[2] - p1[2];
3117 if (len_a == 0.0f) {
3120 if (len_b == 0.0f) {
3126 tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
3127 tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
3128 tvec[2] = dvec_b[2] / len_b + dvec_a[2] / len_a;
3134 len = 6.0f / 2.5614f;
3147 bool leftviolate =
false, rightviolate =
false;
3150 if (len_a > 5.0f * len_b) {
3151 len_a = 5.0f * len_b;
3153 if (len_b > 5.0f * len_a) {
3154 len_b = 5.0f * len_a;
3163 float ydiff1 = prev->vec[1][1] - bezt->
vec[1][1];
3164 float ydiff2 =
next->vec[1][1] - bezt->
vec[1][1];
3165 if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) {
3166 bezt->
vec[0][1] = bezt->
vec[1][1];
3170 if (ydiff1 <= 0.0f) {
3171 if (prev->vec[1][1] > bezt->
vec[0][1]) {
3172 bezt->
vec[0][1] = prev->vec[1][1];
3177 if (prev->vec[1][1] < bezt->
vec[0][1]) {
3178 bezt->
vec[0][1] = prev->vec[1][1];
3190 float ydiff1 = prev->vec[1][1] - bezt->
vec[1][1];
3191 float ydiff2 =
next->vec[1][1] - bezt->
vec[1][1];
3192 if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) {
3193 bezt->
vec[2][1] = bezt->
vec[1][1];
3197 if (ydiff1 <= 0.0f) {
3198 if (
next->vec[1][1] < bezt->
vec[2][1]) {
3199 bezt->
vec[2][1] =
next->vec[1][1];
3200 rightviolate =
true;
3204 if (
next->vec[1][1] > bezt->
vec[2][1]) {
3205 bezt->
vec[2][1] =
next->vec[1][1];
3206 rightviolate =
true;
3212 if (leftviolate || rightviolate) {
3215 float h1_x =
p2_h1[0] - p2[0];
3216 float h2_x = p2[0] -
p2_h2[0];
3219 p2_h2[1] = p2[1] + ((p2[1] -
p2_h1[1]) / h1_x) * h2_x;
3222 p2_h1[1] = p2[1] + ((p2[1] -
p2_h2[1]) / h2_x) * h1_x;
3250 if (len_a == 0.0f) {
3253 if (len_b == 0.0f) {
3257 const float len_ratio = len_a / len_b;
3259 if (bezt->
f1 & handle_sel_flag) {
3262 len = 1.0f / len_ratio;
3288 len = 1.0f / len_ratio;
3308 if (nu->
pntsu < 2) {
3315 prev = bezt + (a - 1);
3333 else if (
next !=
nullptr) {
3353 size_t num_floats = 0, num_chars = 0;
3355 while (floats && floats[num_floats]) {
3359 while (chars && chars[num_chars]) {
3369 float *fptr = (
float *)buffer;
3371 for (
int i = 0; i < num_floats; i++, fptr +=
count) {
3375 char *cptr = (
char *)fptr;
3377 for (
int i = 0; i < num_chars; i++, cptr +=
count) {
3437 float *a0, *b0, *c0, *d0;
3438 float **arrays[] = {&a0, &b0, &c0, &d0,
nullptr};
3439 char *is_locked, *num_unlocks;
3440 char **flagarrays[] = {&is_locked, &num_unlocks,
nullptr};
3442 void *tmps =
allocate_arrays(solve_count, arrays, flagarrays,
"tridiagonal_solve_with_limits");
3447 memcpy(a0, a,
sizeof(
float) * solve_count);
3448 memcpy(b0,
b,
sizeof(
float) * solve_count);
3449 memcpy(c0, c,
sizeof(
float) * solve_count);
3450 memcpy(d0, d,
sizeof(
float) * solve_count);
3452 memset(is_locked, 0, solve_count);
3453 memset(num_unlocks, 0, solve_count);
3455 bool overshoot, unlocked;
3464 bool all =
false, locked =
false;
3466 overshoot = unlocked =
false;
3469 for (
int i = 0; i < solve_count; i++) {
3470 if (h[i] >= hmin[i] && h[i] <= hmax[i]) {
3476 float target = h[i] > hmax[i] ? hmax[i] : hmin[i];
3479 if (target != 0.0f || all) {
3489 }
while (overshoot && !locked);
3494 for (
int i = 0; i < solve_count; i++) {
3496 if (!is_locked[i] || num_unlocks[i] >= 2) {
3503 if ((relax > 0 && h[i] < hmax[i]) || (relax < 0 && h[i] > hmin[i])) {
3512 }
while (overshoot || unlocked);
3591 float *a,
float *
b,
float *c,
float *d,
const float *dy,
const float *
l,
int i)
3594 b[i] = 2.0f * (
l[i] + 1);
3595 c[i] = 1.0f /
l[i + 1];
3596 d[i] = dy[i] *
l[i] *
l[i] + dy[i + 1];
3600 float *a,
float *
b,
float *c,
float *d,
const float *dy,
const float *
l,
int i)
3604 c[i] = 1.0f /
l[i + 1];
3609 float *a,
float *
b,
float *c,
float *d,
const float *dy,
const float *
l,
int i)
3614 d[i] = dy[i] *
l[i] *
l[i];
3619 float *hmax,
float *hmin,
int i,
float dy,
bool no_reverse,
bool no_overshoot)
3623 hmax[i] =
min_ff(hmax[i], dy);
3634 hmin[i] =
max_ff(hmin[i], dy);
3637 else if (no_reverse || no_overshoot) {
3638 hmax[i] = hmin[i] = 0.0f;
3645 const float newval[3],
3650 int idx = right ? 2 : 0;
3651 char hr = right ? bezt->
h2 : bezt->
h1;
3652 char hm = right ? bezt->
h1 : bezt->
h2;
3682 tmp[1] = bezt->
vec[1][1] + dy;
3696 float fac = dx / (hsize[0] + dx / 3.0f);
3700 return 1.0f - 3.0f * hsize[0] / dx;
3706 float *dx, *dy, *
l, *a, *
b, *c, *d, *h, *hmax, *hmin;
3707 float **arrays[] = {&dx, &dy, &
l, &a, &
b, &c, &d, &h, &hmax, &hmin,
nullptr};
3709 int solve_count =
count;
3720 bool full_cycle = (start == 0 &&
count == total && cycle);
3724 &bezt[(start +
count > total) ? start +
count - total : start +
count - 1];
3728 bezt_last, bezt_last->
h1, start +
count == total);
3730 if (
count == 2 && !full_cycle && solve_first == solve_last) {
3745 for (
int i = 1, j = start + 1; i <
count; i++, j++) {
3746 dx[i] = bezt[j].
vec[1][0] - bezt[j - 1].
vec[1][0];
3747 dy[i] = bezt[j].
vec[1][1] - bezt[j - 1].
vec[1][1];
3750 if (cycle && j == total - 1) {
3758 dx[0] = dx[
count - 1];
3759 dy[0] = dy[
count - 1];
3761 l[0] =
l[
count - 1] = dx[1] / dx[0];
3767 for (
int i = 1; i <
count - 1; i++) {
3768 l[i] = dx[i + 1] / dx[i];
3775 for (
int i = 0; i <
count; i++) {
3780 for (
int i = 1, j = start + 1; i <
count; i++, j++) {
3781 clamped_prev = clamped_cur;
3784 if (cycle && j == total - 1) {
3789 bezier_clamp(hmax, hmin, i - 1, dy[i], clamped_prev, clamped_prev);
3790 bezier_clamp(hmax, hmin, i, dy[i] *
l[i], clamped_cur, clamped_cur);
3795 float first_handle_adj = 0.0f, last_handle_adj = 0.0f;
3799 int i = solve_count =
count - 1;
3801 hmin[0] =
max_ff(hmin[0], hmin[i]);
3802 hmax[0] =
min_ff(hmax[0], hmax[i]);
3804 solve_first = solve_last =
true;
3835 for (
int i = 1; i <
count - 1; i++) {
3842 if (
count > 2 || solve_last) {
3843 b[1] +=
l[1] * first_handle_adj;
3846 if (
count > 2 || solve_first) {
3847 b[
count - 2] += last_handle_adj;
3855 h[
count - 1] = h[0];
3858 for (
int i = 1, j = start + 1; i <
count - 1; i++, j++) {
3859 bool end = (j == total - 1);
3895 int search_base = 0;
3898 for (
int i = 1; i < total - 1; i++) {
3906 if (search_base == 0) {
3914 int start = search_base,
count = 1;
3916 for (
int i = 1, j = start + 1; i < total; i++, j++) {
3918 if (j == total - 1 && cyclic) {
3948 const bool is_fcurve,
3949 const char smoothing)
3969 for (i = nu->
pntsu, bezt = nu->
bezt; i--; bezt++) {
3987 if (nu->
pntsu > 1) {
3996 if (nu->
pntsu > 1) {
3997 const char h1_back = bezt->
h1, h2_back = bezt->
h2;
4009#define SEL_F1 (1 << 0)
4010#define SEL_F2 (1 << 1)
4011#define SEL_F3 (1 << 2)
4019 switch (handle_mode) {
4025 if (bezt->
f2 & sel_flag) {
4031 if (bezt->
f1 & sel_flag) {
4034 if (bezt->
f2 & sel_flag) {
4037 if (bezt->
f3 & sel_flag) {
4049 const bool use_around_local)
4052 if (use_around_local) {
4084 const bool use_around_local)
4106 const float eps = 0.0001f;
4107 const float eps_sq =
eps *
eps;
4109 if (nu ==
nullptr || nu->
bezt ==
nullptr) {
4119 bool align =
false, leftsmall =
false, rightsmall =
false;
4205 if ((
flag & (1 << 0)) || (
flag & (1 << 2))) {
4206 if (
flag & (1 << 0)) {
4209 if (
flag & (1 << 2)) {
4212 if (bezt->
h1 != bezt->
h2) {
4236 else if (code == 6) {
4265 if (
flag & (1 << 0)) {
4268 if (
flag & (1 << 2)) {
4283 const bool calc_length,
4294 bool changed =
false;
4296 for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
4298 const bool h1_select = (bezt->
f1 &
flag) ==
flag;
4299 const bool h2_select = (bezt->
f3 &
flag) ==
flag;
4301 if (h1_select || h2_select) {
4303 float co1_back[3], co2_back[3];
4364 a = nu->pntsu * nu->pntsv;
4376 bool changed =
false;
4380 for (
int i = 0; i < nu->pntsu; i++) {
4382 uint8_t old_f1 = bezt->
f1, old_f2 = bezt->
f2, old_f3 = bezt->
f3;
4388 changed |= (old_f1 != bezt->
f1) || (old_f2 != bezt->
f2) || (old_f3 != bezt->
f3);
4392 for (
int i = 0; i < nu->pntsu * nu->pntsv; i++) {
4397 changed |= (old_f1 != bp->
f1);
4409 float *fp1, *fp2, *tempf;
4419 bezt2 = bezt1 + (a - 1);
4425 if (bezt1 != bezt2) {
4426 std::swap(*bezt1, *bezt2);
4431 if (bezt1 != bezt2) {
4435 std::swap(bezt1->
h1, bezt1->
h2);
4436 std::swap(bezt1->
f1, bezt1->
f3);
4438 if (bezt1 != bezt2) {
4439 std::swap(bezt2->
h1, bezt2->
h2);
4440 std::swap(bezt2->
f1, bezt2->
f3);
4452 else if (nu->
pntsv == 1) {
4455 bp2 = bp1 + (a - 1);
4457 while (bp1 != bp2 && a > 0) {
4458 std::swap(*bp1, *bp2);
4468 if (nu->
pntsu & 1) {
4477 fp2 = fp1 + (a - 1);
4479 while (fp1 != fp2 && a > 0) {
4480 std::swap(*fp1, *fp2);
4492 fp2[0] =
fabsf(fp1[1] - fp1[0]);
4503 fp1[0] = fp1[-1] + fp2[0];
4515 bp2 = bp1 + (a - 1);
4518 while (bp1 != bp2 && a > 0) {
4519 std::swap(*bp1, *bp2);
4530 float *co = vert_coords[0];
4534 for (
int i = 0; i < nu->pntsu; i++, bezt++) {
4544 const BPoint *bp = nu->bp;
4545 for (
int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
4559 vert_len,
sizeof(*vert_coords), __func__);
4561 *r_vert_len = vert_len;
4566 const float (*vert_coords)[3],
4567 const float mat[4][4],
4568 const bool constrain_2d)
4570 const float *co = vert_coords[0];
4576 for (
int i = 0; i < nu->pntsu; i++, bezt++) {
4588 for (
int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
4603 const float (*vert_coords)[3],
4604 const bool constrain_2d)
4606 const float *co = vert_coords[0];
4612 for (
int i = 0; i < nu->pntsu; i++, bezt++) {
4624 for (
int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
4648 for (
int i = 0; i < nu->pntsu; i++, bezt++) {
4659 const BPoint *bp = nu->bp;
4661 for (
int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
4668 *r_vert_len = vert_len;
4678 for (
int i = 0; i < nu->pntsu; i++, bezt++) {
4679 bezt->
tilt = key[9];
4687 for (
int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
4701 int *r_points_needed)
4711 int points_needed = 0;
4713 const int remainder = pnts % (order - 1);
4714 points_needed = remainder > 0 ? order - 1 - remainder : 0;
4717 points_needed = order + 1 - pnts;
4719 if (points_needed) {
4720 *r_points_needed = points_needed;
4736 const size_t maxncpy)
4740 pnts, order,
flag, type, is_surf, &points_needed);
4752 BLI_strncpy(message_dst,
RPT_(
"At least two points required"), maxncpy);
4755 BLI_strncpy(message_dst,
RPT_(
"Must have more control points than Order"), maxncpy);
4760 RPT_(
"%d more %s row(s) needed for Bézier"),
4762 dir == 0 ?
"U" :
"V");
4766 message_dst, maxncpy,
RPT_(
"%d more point(s) needed for Bézier"), points_needed);
4803 bool changed =
false;
4813 bool changed =
false;
4823 const bool use_handles,
4824 const char **r_err_msg)
4839 bezt->
f1 = bezt->
f2 = bezt->
f3 = bp->
f1;
4868 nr = use_handles ? (3 * nu->
pntsu) : nu->
pntsu;
4875 (use_handles ==
false))
4890 for (c = 0; c < 3; c++, f++) {
4929 if (r_err_msg !=
nullptr) {
4930 *r_err_msg =
"At least 6 points required for conversion";
4985 if (nu ==
nullptr) {
5004 void *vert =
nullptr;
5041 void *vert =
nullptr;
5062 return (*r_vert !=
nullptr);
5091 const bool use_radius)
5094 return std::nullopt;
5096 float3 min(std::numeric_limits<float>::max());
5097 float3 max(std::numeric_limits<float>::lowest());
5116 const_cast<Curve *
>(cu),
5144 for (bezt = nu->bezt; i--; bezt++) {
5152 i = nu->pntsu * nu->pntsv;
5154 for (bp = nu->bp; i--; bp++) {
5164 return (total != 0);
5168 const float mat[4][4],
5170 const bool do_props,
5171 const float unit_scale)
5182 for (bezt = nu->bezt; i--; bezt++) {
5187 bezt->
radius *= unit_scale;
5189 if (!is_uniform_scaled) {
5198 i = nu->pntsu * nu->pntsv;
5199 for (bp = nu->bp; i--; bp++) {
5202 bp->
radius *= unit_scale;
5208 if (do_keys && cu->
key) {
5210 float *fp = (
float *)kb->data;
5211 int n = kb->totelem;
5220 fp[10] *= unit_scale;
5229 fp[4] *= unit_scale;
5252 for (
BezTriple *bezt = nu->bezt; i--; bezt++) {
5259 int i = nu->pntsu * nu->pntsv;
5260 for (
BPoint *bp = nu->bp; i--; bp++) {
5266 if (do_keys && cu->
key) {
5268 float *fp = (
float *)kb->data;
5269 int n = kb->totelem;
5297 for (
int i = cu->
len_char32 - 1; i >= 0; i--, info++) {
5305 if (nu->mat_nr && nu->mat_nr >= index) {
5318 for (
int i = cu->
len_char32 - 1; i >= 0; i--, info++) {
5319 if (info->
mat_nr == index) {
5326 if (nu->mat_nr == index) {
5341 for (
int i = cu->
len_char32 - 1; i >= 0; i--, info++) {
5361 for (i = cu->
len_char32 - 1; i >= 0; i--, info++) {
5362 if (info->
mat_nr > max_idx) {
5371 if (nu->mat_nr > max_idx) {
5388 const short remap_len_short = short(remap_len);
5390#define MAT_NR_REMAP(n) \
5391 if (n < remap_len_short) { \
5392 BLI_assert(n >= 0 && remap[n] < remap_len_short); \
5399 int charinfo_len, i;
5404 charinfo_len = ef->
len;
5411 for (i = 0; i <= charinfo_len; i++) {
5437 nu->flag &= ~CU_SMOOTH;
5453 float h1[2], h2[2], len1, len2,
len, fac;
5456 h1[0] = v1[0] -
v2[0];
5457 h1[1] = v1[1] -
v2[1];
5459 h2[0] = v4[0] - v3[0];
5460 h2[1] = v4[1] - v3[1];
5467 len = v4[0] - v1[0];
5468 len1 =
fabsf(h1[0]);
5469 len2 =
fabsf(h2[0]);
5472 if ((len1 + len2) == 0.0f) {
5479 if ((len1 + len2) >
len) {
5480 fac =
len / (len1 + len2);
5482 v2[0] = (v1[0] - fac * h1[0]);
5483 v2[1] = (v1[1] - fac * h1[1]);
5485 v3[0] = (v4[0] - fac * h2[0]);
5486 v3[1] = (v4[1] - fac * h2[1]);
@ NURB_HANDLE_TEST_KNOT_OR_EACH
@ NURB_HANDLE_TEST_KNOT_ONLY
#define CU_DO_RADIUS(cu, nu)
int eBezTriple_Flag__Alias
struct CurveProfile * BKE_curveprofile_copy(const struct CurveProfile *profile)
void BKE_curveprofile_blend_read(struct BlendDataReader *reader, struct CurveProfile *profile)
void BKE_curveprofile_blend_write(struct BlendWriter *writer, const struct CurveProfile *profile)
void BKE_curveprofile_free(struct CurveProfile *profile)
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
void key_curve_position_weights(float t, float data[4], int type)
void * BKE_libblock_alloc(Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
struct ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, const ID *new_owner_id, ID **new_id_p, int flag)
void BKE_id_blend_write(BlendWriter *writer, ID *id)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
@ IDWALK_DO_DEPRECATED_POINTERS
#define BKE_LIB_FOREACHID_PROCESS_ID_NOCHECK(data_, id_, cb_flag_)
VFont * BKE_vfont_builtin_get()
bool BKE_vfont_to_curve_ex(Object *ob, Curve *cu, eEditFontMode mode, ListBase *r_nubase, const char32_t **r_text, int *r_text_len, bool *r_text_free, CharTrans **r_chartransdata)
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int mod_i(int i, int n)
MINLINE float safe_acosf(float a)
float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l2[3])
float mat4_to_scale(const float mat[4][4])
bool is_uniform_scaled_m4(const float m[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void vec_to_quat(float q[4], const float vec[3], short axis, short upflag)
float normalize_qt(float q[4])
void mul_qt_v3(const float q[4], float r[3])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
void copy_qt_qt(float q[4], const float a[4])
bool BLI_tridiagonal_solve_cyclic(const float *a, const float *b, const float *c, const float *d, float *r_x, int count)
Solve a possibly cyclic tridiagonal system using the Sherman-Morrison formula.
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], float dist)
MINLINE float normalize_v3(float n[3])
void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define BLI_SCOPED_DEFER(function_to_defer)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONNULL(1
#define ARRAY_HAS_ITEM(arr_item, arr_start, arr_len)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define POINTER_OFFSET(v, ofs)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
void BLO_read_pointer_array(BlendDataReader *reader, int array_size, void **ptr_p)
#define BLO_read_struct(reader, struct_name, ptr_p)
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
#define BLT_I18NCONTEXT_ID_CURVE_LEGACY
void DEG_id_tag_update(ID *id, unsigned int flags)
bool DEG_is_active(const Depsgraph *depsgraph)
void DEG_debug_print_eval(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
ID * DEG_get_original_id(ID *id)
#define FILTER_ID_CU_LEGACY
#define BEZT_IS_AUTOH(bezt)
#define BEZT_ISSEL_ANY(bezt)
@ HD_AUTOTYPE_LOCKED_FINAL
@ CU_TEXSPACE_FLAG_AUTO_EVALUATED
struct BezTriple BezTriple
#define DNA_struct_default_get(struct_name)
#define KEYELEM_ELEM_LEN_BPOINT
#define KEYELEM_FLOAT_LEN_BEZTRIPLE
#define KEYELEM_FLOAT_LEN_BPOINT
#define KEYELEM_ELEM_LEN_BEZTRIPLE
Object is a sort of wrapper for general info.
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
static void smooth_iter(CorrectiveSmoothModifierData *csmd, Mesh *mesh, blender::MutableSpan< blender::float3 > vertexCos, const float *smooth_weights, uint iterations)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
static T sum(const btAlignedObjectArray< T > &items)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
local_group_size(16, 16) .push_constant(Type b
void BKE_nurb_handles_autocalc(Nurb *nu, uint8_t flag)
static void bevel_list_flip_tangents(BevList *bl)
static void makeknots(Nurb *nu, short uv)
void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
bool BKE_nurbList_flag_set_from_flag(ListBase *editnurb, uint8_t from_flag, uint8_t flag)
static void basisNurb(float t, short order, int pnts, const float *knots, float *basis, int *start, int *end)
void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt)
void BKE_curve_batch_cache_dirty_tag(Curve *cu, int mode)
static void curve_copy_data(Main *bmain, std::optional< Library * > owner_library, ID *id_dst, const ID *id_src, const int flag)
void BKE_nurb_index_to_uv(Nurb *nu, int index, int *r_u, int *r_v)
void BKE_nurb_handles_calc(Nurb *nu)
const ListBase * BKE_curve_editNurbs_get_for_read(const Curve *cu)
static void bezier_eq_noaccel_left(float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
void BKE_curve_translate(Curve *cu, const float offset[3], const bool do_keys)
static void nurbList_handles_swap_select(Nurb *nu)
static void make_bevel_list_segment_2D(BevList *bl)
void BKE_curve_editNurb_free(Curve *cu)
bool BKE_curve_center_median(Curve *cu, float cent[3])
void BKE_nurb_makeFaces(const Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv)
static void curve_editNurb_keyIndex_cv_free_cb(void *val)
void BKE_curve_smooth_flag_set(Curve *cu, const bool use_smooth)
IDTypeInfo IDType_ID_CU_LEGACY
void BKE_curve_correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2])
static bool bevelinside(const BevList *bl1, const BevList *bl2)
void BKE_nurb_project_2d(Nurb *nu)
static void calc_nurb_minmax(const Nurb *nu, bool use_radius, float min[3], float max[3])
static void bevel_list_calc_bisect(BevList *bl)
void BKE_curve_texspace_ensure(Curve *cu)
static void curve_init_data(ID *id)
static void free_arrays(void *buffer)
void BKE_nurb_bpoint_calc_plane(Nurb *nu, BPoint *bp, float r_plane[3])
void BKE_nurbList_handles_autocalc(ListBase *editnurb, uint8_t flag)
static void make_bevel_list_3D_minimum_twist(BevList *bl)
static void curve_blend_read_data(BlendDataReader *reader, ID *id)
void BKE_nurb_bezt_handle_test(BezTriple *bezt, const eBezTriple_Flag__Alias sel_flag, const eNurbHandleTest_Mode handle_mode, const bool use_around_local)
void BKE_nurb_bezt_calc_normal(Nurb *, BezTriple *bezt, float r_normal[3])
static void minimum_twist_between_two_points(BevPoint *bevp_curr, const BevPoint *bevp_prev)
static void curve_foreach_id(ID *id, LibraryForeachIDData *data)
void BKE_nurb_handles_test(Nurb *nu, const eNurbHandleTest_Mode handle_mode, const bool use_around_local)
void BKE_curve_transform_ex(Curve *cu, const float mat[4][4], const bool do_keys, const bool do_props, const float unit_scale)
static void forward_diff_bezier_cotangent(const float p0[3], const float p1[3], const float p2[3], const float p3[3], float p[3], int it, int stride)
static void bevel_list_smooth(BevList *bl, int smooth_iter)
void BKE_nurb_free(Nurb *nu)
void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb, const float(*vert_coords)[3], const float mat[4][4], const bool constrain_2d)
void BKE_curve_init(Curve *cu, const short curve_type)
static void make_bevel_list_segment_3D(BevList *bl)
void BKE_curve_type_test(Object *ob)
static void make_bevel_list_3D_tangent(BevList *bl)
void BKE_curve_bevelList_free(ListBase *bev)
ListBase * BKE_curve_nurbs_get(Curve *cu)
void BKE_curve_nurb_active_set(Curve *cu, const Nurb *nu)
static int vergxcobev(const void *a1, const void *a2)
void BKE_curve_texspace_calc(Curve *cu)
static void make_bevel_list_2D(BevList *bl)
Nurb * BKE_curve_nurb_active_get(Curve *cu)
const ListBase * BKE_curve_nurbs_get_for_read(const Curve *cu)
static bool is_free_auto_point(BezTriple *bezt)
short BKE_nurb_bezt_handle_test_calc_flag(const BezTriple *bezt, const eBezTriple_Flag__Alias sel_flag, const eNurbHandleTest_Mode handle_mode)
bool BKE_nurb_check_valid_uv(const Nurb *nu)
void(* BKE_curve_batch_cache_free_cb)(Curve *cu)
void BKE_curve_batch_cache_free(Curve *cu)
void BKE_nurb_makeCurve(const Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride)
float BKE_nurb_calc_length(const Nurb *nu, int resolution)
void BKE_curve_transform(Curve *cu, const float mat[4][4], const bool do_keys, const bool do_props)
bool BKE_nurb_type_convert(Nurb *nu, const short type, const bool use_handles, const char **r_err_msg)
void BKE_curve_editNurb_keyIndex_free(GHash **keyindex)
static void make_bevel_list_3D_zup(BevList *bl)
void BKE_curve_nurb_vert_active_set(Curve *cu, const Nurb *nu, const void *vert)
static void * allocate_arrays(int count, float ***floats, char ***chars, const char *name)
static void calchandlesNurb_intern(Nurb *nu, eBezTriple_Flag handle_sel_flag, bool skip_align)
void BKE_nurb_knot_calc_u(Nurb *nu)
void BKE_nurb_handle_smooth_fcurve(BezTriple *bezt, int total, bool cyclic)
static float bezier_calc_handle_adj(float hsize[2], float dx)
static void bevel_list_apply_tilt(BevList *bl)
void BKE_curve_nurbs_vert_coords_get(const ListBase *lb, float(*vert_coords)[3], int vert_len)
void BKE_curve_dimension_update(Curve *cu)
void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key)
void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2)
static bool tridiagonal_solve_with_limits(float *a, float *b, float *c, float *d, float *h, const float *hmin, const float *hmax, int solve_count)
void BKE_nurb_handle_calc(BezTriple *bezt, BezTriple *prev, BezTriple *next, const bool is_fcurve, const char smoothing)
std::optional< blender::Bounds< blender::float3 > > BKE_curve_minmax(const Curve *cu, bool use_radius)
void * BKE_curve_vert_active_get(Curve *cu)
bool BKE_nurb_order_clamp_u(Nurb *nu)
static void calcknots(float *knots, const int pnts, const short order, const short flag)
void BKE_nurbList_handles_set(ListBase *editnurb, eNurbHandleTest_Mode handle_mode, const char code)
static void bezier_lock_unknown(float *a, float *b, float *c, float *d, int i, float value)
static void bezier_handle_calc_smooth_fcurve(BezTriple *bezt, int total, int start, int count, bool cycle)
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
static void bezier_eq_noaccel_right(float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
void BKE_nurbList_free(ListBase *lb)
void BKE_curve_material_remap(Curve *cu, const uint *remap, uint remap_len)
static void curve_blend_write(BlendWriter *writer, ID *id, const void *id_address)
void BKE_curve_editfont_free(Curve *cu)
ListBase * BKE_curve_editNurbs_get(Curve *cu)
bool BKE_nurb_check_valid_v(const Nurb *nu)
static void calchandleNurb_intern(BezTriple *bezt, const BezTriple *prev, const BezTriple *next, eBezTriple_Flag handle_sel_flag, bool is_fcurve, bool skip_align, char fcurve_smoothing)
int BKE_nurbList_verts_count(const ListBase *nurb)
void BKE_curve_nurbs_vert_coords_apply(ListBase *lb, const float(*vert_coords)[3], const bool constrain_2d)
static void bevlist_firstlast_direction_calc_from_bpoint(const Nurb *nu, BevList *bl)
void BKE_curve_material_index_remove(Curve *cu, int index)
int BKE_nurb_index_from_uv(Nurb *nu, int u, int v)
void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_render)
void BKE_curve_forward_diff_tangent_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
static void nurb_handles_calc__align_selected(Nurb *nu)
void BKE_nurb_knot_calc_v(Nurb *nu)
static std::optional< blender::Bounds< blender::float3 > > calc_nurblist_bounds(const ListBase *nurbs, const bool use_radius)
static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode)
static bool bezier_check_solve_end_handle(BezTriple *bezt, char htype, bool end)
short BKE_curve_type_get(const Curve *cu)
Curve * BKE_curve_add(Main *bmain, const char *name, int type)
void(* BKE_curve_batch_cache_dirty_tag_cb)(Curve *cu, int mode)
bool BKE_curve_material_index_used(const Curve *cu, int index)
void BKE_nurb_direction_switch(Nurb *nu)
void BKE_curve_nurb_vert_active_validate(Curve *cu)
void BKE_curve_material_index_clear(Curve *cu)
void BKE_curve_eval_geometry(Depsgraph *depsgraph, Curve *curve)
bool BKE_curve_nurb_vert_active_get(Curve *cu, Nurb **r_nu, void **r_vert)
BPoint * BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp)
bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
bool BKE_nurb_check_valid_u(const Nurb *nu)
void BKE_nurb_bezierPoints_add(Nurb *nu, int number)
static float bezier_relax_direction(const float *a, const float *b, const float *c, const float *d, const float *h, int i, int count)
BPoint * BKE_nurb_bpoint_get_next(Nurb *nu, BPoint *bp)
void BKE_nurbList_flag_set(ListBase *editnurb, uint8_t flag, bool set)
static void bezier_output_handle_inner(BezTriple *bezt, bool right, const float newval[3], bool endpoint)
BezTriple * BKE_nurb_bezt_get_next(Nurb *nu, BezTriple *bezt)
static NURBSValidationStatus nurb_check_valid(const int pnts, const short order, const short flag, const short type, const bool is_surf, int *r_points_needed)
void BKE_nurb_bpoint_calc_normal(Nurb *nu, BPoint *bp, float r_normal[3])
static void curve_free_data(ID *id)
Nurb * BKE_nurb_duplicate(const Nurb *nu)
bool BKE_nurb_order_clamp_v(Nurb *nu)
static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3], short cox, short coy, float *lambda, float *mu, float vec[3])
static void bezier_restore_equation(float *a, float *b, float *c, float *d, const float *a0, const float *b0, const float *c0, const float *d0, int i)
bool BKE_nurb_valid_message(const int pnts, const short order, const short flag, const short type, const bool is_surf, const int dir, char *message_dst, const size_t maxncpy)
void BKE_curve_rect_from_textbox(const Curve *cu, const TextBox *tb, rctf *r_rect)
void BKE_curve_editNurb_keyIndex_delCV(GHash *keyindex, const void *cv)
int BKE_nurbList_verts_count_without_handles(const ListBase *nurb)
static void bezier_output_handle(BezTriple *bezt, bool right, float dy, bool endpoint)
float(* BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb, float *key, int *r_vert_len))[3]
Nurb * BKE_nurb_copy(Nurb *src, int pntsu, int pntsv)
static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *r_sina, float *r_cosa)
int BKE_curve_nurb_vert_index_get(const Nurb *nu, const void *vert)
static void bezier_eq_continuous(float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
static void bezier_clamp(float *hmax, float *hmin, int i, float dy, bool no_reverse, bool no_overshoot)
uint BKE_curve_calc_coords_axis_len(const uint bezt_array_len, const uint resolu, const bool is_cyclic, const bool use_cyclic_duplicate_endpoint)
static void tilt_bezpart(const BezTriple *prevbezt, const BezTriple *bezt, const Nurb *nu, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride)
void BKE_nurb_bezt_calc_plane(Nurb *nu, BezTriple *bezt, float r_plane[3])
@ MorePointsThanOrderRequired
@ AtLeastTwoPointsRequired
@ MorePointsForBezierRequired
@ MoreRowsForBezierRequired
float(* BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb, int *r_vert_len))[3]
void BKE_nurb_handle_calc_ex(BezTriple *bezt, BezTriple *prev, BezTriple *next, const eBezTriple_Flag__Alias handle_sel_flag, const bool is_fcurve, const char smoothing)
void BKE_nurbList_handles_recalculate(ListBase *editnurb, const bool calc_length, const uint8_t flag)
BezTriple * BKE_nurb_bezt_get_prev(Nurb *nu, BezTriple *bezt)
void BKE_curve_calc_coords_axis(const BezTriple *bezt_array, const uint bezt_array_len, const uint resolu, const bool is_cyclic, const bool use_cyclic_duplicate_endpoint, const uint axis, const uint stride, float *r_points)
bool BKE_curve_material_index_validate(Curve *cu)
void BKE_nurb_points_add(Nurb *nu, int number)
const Depsgraph * depsgraph
static bool is_cyclic(const Nurb *nu)
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float3 cos(float3 v)
struct CurveProfile * bevel_profile
struct EditFont * editfont
struct CharInfo * strinfo
float texspace_location[3]
EditFontSelBox * selboxes
ObjectRuntimeHandle * runtime