33#define DNA_DEPRECATED_ALLOW
89 std::optional<Library *> owner_library,
95 const Curve *curve_src = (
const Curve *)id_src;
114 reinterpret_cast<ID **
>(&curve_dst->
key),
152 for (
int i = 0;
i < curve->
totcol;
i++) {
215 if ((cu->
len_char32 == 0) && (cu->
str !=
nullptr) && (cu->
str[0] !=
'\0')) {
233 if (is_font ==
false) {
273 if (is_font ==
false) {
384 memcpy(cu->
str,
str, len_bytes + 1);
394 cu->
tb[0].
w = cu->
tb[0].
h = 0.0;
459 if (dimension_update) {
476 float texspace_location[3], texspace_size[3];
479 texspace_size[0] = (
bounds->max[0] -
bounds->min[0]) / 2.0f;
480 texspace_size[1] = (
bounds->max[1] -
bounds->min[1]) / 2.0f;
481 texspace_size[2] = (
bounds->max[2] -
bounds->min[2]) / 2.0f;
483 for (
int a = 0; a < 3; a++) {
484 if (texspace_size[a] == 0.0f) {
485 texspace_size[a] = 1.0f;
487 else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) {
488 texspace_size[a] = 0.00001f;
490 else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) {
491 texspace_size[a] = -0.00001f;
519 if (index - tot < tot_nu) {
520 copy_v3_v3(r_co, nu->bezt[index - tot].vec[1]);
525 tot_nu = nu->pntsu * nu->pntsv;
526 if (index - tot < tot_nu) {
543 tot += 3 * nu->pntsu;
546 tot += nu->pntsu * nu->pntsv;
562 tot += nu->pntsu * nu->pntsv;
615 if (newnu ==
nullptr) {
618 *newnu = blender::dna::shallow_copy(*nu);
652 *newnu = blender::dna::shallow_copy(*src);
655 std::swap(pntsu, pntsv);
657 newnu->
pntsu = pntsu;
658 newnu->
pntsv = pntsv;
694 bezt->
vec[0][2] = 0.0;
695 bezt->
vec[1][2] = 0.0;
696 bezt->
vec[2][2] = 0.0;
722 float radius_vector[3];
723 radius_vector[0] = radius_vector[1] = radius_vector[2] = bezt->
radius;
743 if (nu->
pntsv == 1 && use_radius) {
744 float radius_vector[3];
745 radius_vector[0] = radius_vector[1] = radius_vector[2] = bp->
radius;
768 int resolu = resolution ? resolution : nu->
resolu;
769 int pntsu = nu->
pntsu;
770 float *points, *pntsit, *prevpntsit;
777 prevbp = nu->
bp + (nu->
pntsu - 1);
808 for (
int j = 0; j < 3; j++) {
818 prevpntsit = pntsit = points;
833 if (nu->
pntsv == 1) {
840 b = pntsu * resolu + 1;
841 prevpntsit = points + 3 * (pntsu * resolu - 1);
845 b = (pntsu - 1) * resolu;
869 for (
i = 0, bp = &nu->
bp[nu->
pntsu];
i < number;
i++, bp++) {
883 for (
i = 0, bezt = &nu->
bezt[nu->
pntsu];
i < number;
i++, bezt++) {
892 const int totu = nu->
pntsu;
893 const int totv = nu->
pntsv;
898 else if (u < 0 || u >= totu) {
909 return (
v * totu) + u;
914 const int totu = nu->
pntsu;
915 const int totv = nu->
pntsv;
917 *r_u = (index % totu);
918 *r_v = (index / totu) % totv;
929 bezt_next = nu->
bezt;
936 bezt_next = bezt + 1;
948 if (bp == &nu->
bp[nu->
pntsu - 1]) {
970 if (bezt == nu->
bezt) {
979 bezt_prev = bezt - 1;
994 bp_prev = &nu->
bp[nu->
pntsu - 1];
1010 float dir_prev[3], dir_next[3];
1024 float dir_prev[3], dir_next[3];
1050 float dir_mid[3], tvec[3];
1087 float dir_prev[3] = {0.0f}, dir_next[3] = {0.0f};
1101 float dir_mid[3], tvec[3];
1112static void calcknots(
float *knots,
const int pnts,
const short order,
const short flag)
1118 const int repeat_inner = is_bezier ? order - 1 : 1;
1120 const int head = is_end_point ? (order - (
is_cyclic ? 1 : 0)) :
1121 (is_bezier ?
min_ii(2, repeat_inner) : 1);
1124 const int tail =
is_cyclic ? 2 * order - 1 : (is_end_point ? order : 0);
1126 const int knot_count = pnts + order + (
is_cyclic ? order - 1 : 0);
1129 float current = 0.0f;
1131 const int offset = is_end_point &&
is_cyclic ? 1 : 0;
1137 for (
const int i :
IndexRange(offset, knot_count - offset - tail)) {
1146 const int tail_index = knot_count - tail;
1148 knots[tail_index +
i] = current + (knots[
i] - knots[0]);
1200 float t,
short order,
int pnts,
const float *knots,
float *basis,
int *start,
int *end)
1203 int i, i1 = 0, i2 = 0, j, orderpluspnts, opp2, o2;
1205 orderpluspnts = order + pnts;
1206 opp2 = orderpluspnts - 1;
1212 else if (t > knots[opp2]) {
1218 for (
i = 0;
i < opp2;
i++) {
1219 if (knots[
i] != knots[
i + 1] && t >= knots[
i] && t <= knots[
i + 1]) {
1222 i1 = std::max(i1, 0);
1237 for (j = 2; j <= order; j++) {
1239 if (i2 + j >= orderpluspnts) {
1243 for (
i = i1;
i <= i2;
i++) {
1244 if (basis[
i] != 0.0f) {
1245 d = ((t - knots[
i]) * basis[
i]) / (knots[
i + j - 1] - knots[
i]);
1251 if (basis[
i + 1] != 0.0f) {
1252 e = ((knots[
i + j] - t) * basis[
i + 1]) / (knots[
i + j] - knots[
i + 1]);
1265 for (
i = i1;
i <= i2;
i++) {
1266 if (basis[
i] > 0.0f) {
1268 if (*start == 1000) {
1278 float *basisu, *basis, *basisv, *
sum, *fp, *
in;
1279 float u,
v, ustart, uend, ustep, vstart, vend, vstep, sumdiv;
1280 int i, j, iofs, jofs, cycl,
len, curu, curv;
1281 int istart, iend, jsta, jen, *jstart, *jend, ratcomp;
1283 int totu = nu->
pntsu * resolu, totv = nu->
pntsv * resolv;
1294 if (coord_array ==
nullptr) {
1310 if (bp->
vec[3] != 1.0f) {
1318 ustart = fp[nu->
orderu - 1];
1323 uend = fp[nu->
pntsu];
1330 vstart = fp[nu->
orderv - 1];
1336 vend = fp[nu->
pntsv];
1376 jsta = jstart[curv];
1383 for (j = jsta; j <= jen; j++) {
1385 if (j >= nu->
pntsv) {
1386 jofs = (j - nu->
pntsv);
1391 bp = nu->
bp + nu->
pntsu * jofs + istart - 1;
1393 for (
i = istart;
i <= iend;
i++, fp++) {
1396 bp = nu->
bp + nu->
pntsu * jofs + iofs;
1403 *fp = basisu[
i] * basis[j] * bp->
vec[3];
1407 *fp = basisu[
i] * basis[j];
1414 for (j = jsta; j <= jen; j++) {
1415 for (
i = istart;
i <= iend;
i++, fp++) {
1425 for (j = jsta; j <= jen; j++) {
1427 if (j >= nu->
pntsv) {
1428 jofs = (j - nu->
pntsv);
1433 bp = nu->
bp + nu->
pntsu * jofs + istart - 1;
1435 for (
i = istart;
i <= iend;
i++, fp++) {
1438 bp = nu->
bp + nu->
pntsu * jofs + iofs;
1454 if (rowstride != 0) {
1455 in = (
float *)(((
uchar *)
in) + (rowstride - 3 * totv *
sizeof(*
in)));
1470 float *radius_array,
1471 float *weight_array,
1475 const float eps = 1e-6f;
1477 float u, ustart, uend, ustep, sumdiv;
1478 float *basisu, *
sum, *fp;
1479 float *coord_fp = coord_array, *tilt_fp = tilt_array, *radius_fp = radius_array,
1480 *weight_fp = weight_array;
1481 int i,
len, istart, iend, cycl;
1483 if (nu->
knotsu ==
nullptr) {
1489 if (coord_array ==
nullptr) {
1508 ustart = fp[nu->
orderu - 1];
1513 uend = fp[nu->
pntsu];
1533 bp = nu->
bp + istart - 1;
1534 for (
i = istart;
i <= iend;
i++, fp++) {
1542 *fp = basisu[
i] * bp->
vec[3];
1545 if ((sumdiv != 0.0f) && (sumdiv < 1.0f - eps || sumdiv > 1.0f +
eps)) {
1548 for (
i = istart;
i <= iend;
i++, fp++) {
1557 bp = nu->
bp + istart - 1;
1558 for (
i = istart;
i <= iend;
i++, fp++) {
1570 (*tilt_fp) += (*fp) * bp->
tilt;
1574 (*radius_fp) += (*fp) * bp->
radius;
1578 (*weight_fp) += (*fp) * bp->
weight;
1606 const bool use_cyclic_duplicate_endpoint)
1609 const uint points_len = (segments * resolu) + (
is_cyclic ? (use_cyclic_duplicate_endpoint) : 1);
1614 const uint bezt_array_len,
1617 const bool use_cyclic_duplicate_endpoint,
1624 bezt_array_len, resolu,
is_cyclic, use_cyclic_duplicate_endpoint);
1625 float *r_points_offset = r_points;
1627 const uint resolu_stride = resolu * stride;
1628 const uint bezt_array_last = bezt_array_len - 1;
1630 for (
uint i = 0;
i < bezt_array_last;
i++) {
1632 const BezTriple *bezt_next = &bezt_array[
i + 1];
1634 bezt_curr->
vec[2][axis],
1635 bezt_next->
vec[0][axis],
1636 bezt_next->
vec[1][axis],
1640 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, resolu_stride);
1644 const BezTriple *bezt_curr = &bezt_array[bezt_array_last];
1645 const BezTriple *bezt_next = &bezt_array[0];
1647 bezt_curr->
vec[2][axis],
1648 bezt_next->
vec[0][axis],
1649 bezt_next->
vec[1][axis],
1653 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, resolu_stride);
1654 if (use_cyclic_duplicate_endpoint) {
1655 *r_points_offset = *r_points;
1656 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, stride);
1660 float *r_points_last = (
float *)
POINTER_OFFSET(r_points, bezt_array_last * resolu_stride);
1661 *r_points_last = bezt_array[bezt_array_last].
vec[1][axis];
1662 r_points_offset = (
float *)
POINTER_OFFSET(r_points_offset, stride);
1670 float q0,
float q1,
float q2,
float q3,
float *p,
int it,
int stride)
1672 float rt0, rt1, rt2, rt3, f;
1677 rt1 = 3.0f * (q1 - q0) / f;
1679 rt2 = 3.0f * (q0 - 2.0f * q1 + q2) / f;
1681 rt3 = (q3 - q0 + 3.0f * (q1 - q2)) / f;
1684 q1 = rt1 + rt2 + rt3;
1685 q2 = 2 * rt2 + 6 * rt3;
1688 for (a = 0; a <= it; a++) {
1698 float q0,
float q1,
float q2,
float q3,
float *p,
int it,
int stride)
1700 float rt0, rt1, rt2, f;
1703 f = 1.0f /
float(it);
1705 rt0 = 3.0f * (q1 - q0);
1706 rt1 = f * (3.0f * (q3 - q0) + 9.0f * (q1 - q2));
1707 rt2 = 6.0f * (q0 + q2) - 12.0f * q1;
1710 q1 = f * (rt1 + rt2);
1711 q2 = 2.0f * f * rt1;
1713 for (a = 0; a <= it; a++) {
1733 for (
int a = 0; a <= it; a++) {
1736 for (
int i = 0;
i < 3;
i++) {
1737 p[
i] = (-6.0f * t + 6.0f) * p0[
i] + (18.0f * t - 12.0f) * p1[
i] +
1738 (-18.0f * t + 6.0f) * p2[
i] + (6.0f * t) * p3[
i];
1763 deler = (v1[cox] -
v2[cox]) * (v3[coy] - v4[coy]) - (v3[cox] - v4[cox]) * (v1[coy] -
v2[coy]);
1764 if (deler == 0.0f) {
1768 *lambda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]);
1769 *lambda = -(*lambda / deler);
1771 deler = v3[coy] - v4[coy];
1773 deler = v3[cox] - v4[cox];
1774 *mu = -(*lambda * (
v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler;
1777 *mu = -(*lambda * (
v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler;
1779 vec[cox] = *lambda * (
v2[cox] - v1[cox]) + v1[cox];
1780 vec[coy] = *lambda * (
v2[coy] - v1[coy]) + v1[coy];
1782 if (*lambda >= 0.0f && *lambda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) {
1783 if (*lambda == 0.0f || *lambda == 1.0f || *mu == 0.0f || *mu == 1.0f) {
1796 float min,
max, vec[3], hvec1[3],
hvec2[3], lab, mu;
1797 int nr, links = 0, rechts = 0, mode;
1802 hvec1[0] = bevp->
vec[0];
1803 hvec1[1] = bevp->
vec[1];
1813 prevbevp = bevp + (nr - 1);
1823 if (
min <= hvec1[1] &&
max >= hvec1[1]) {
1829 if (mode >= 0 && lab != 0.0f) {
1830 if (vec[0] < hvec1[0]) {
1843 return (links & 1) && (rechts & 1);
1856 if (x1->
left > x2->left) {
1859 if (x1->
left < x2->left) {
1868 float x1,
float y1,
float x2,
float y2,
float *r_sina,
float *r_cosa)
1870 float t01, t02, x3, y3;
1872 t01 =
sqrtf(x1 * x1 + y1 * y1);
1873 t02 =
sqrtf(x2 * x2 + y2 * y2);
1886 t02 = x1 * x2 + y1 * y2;
1887 if (
fabsf(t02) >= 1.0f) {
1901 if (x3 == 0 && y3 == 0) {
1906 t01 =
sqrtf(x3 * x3 + y3 * y3);
1911 *r_sina = -y3 / t02;
1919 float *radius_array,
1920 float *weight_array,
1925 float fac, dfac, t[4];
1928 if (tilt_array ==
nullptr && radius_array ==
nullptr) {
1935 if (prevbezt == nu->
bezt) {
1944 pprev = prevbezt - 1;
1961 dfac = 1.0f /
float(resolu);
1963 for (a = 0; a < resolu; a++, fac += dfac) {
1967 *tilt_array = prevbezt->
tilt +
1968 (bezt->
tilt - prevbezt->
tilt) * (3.0f * fac * fac - 2.0f * fac * fac * fac);
1972 *tilt_array = t[0] * pprev->
tilt + t[1] * prevbezt->
tilt + t[2] * bezt->
tilt +
1985 (3.0f * fac * fac - 2.0f * fac * fac * fac);
1993 *radius_array = t[0] * pprev->
radius + t[1] * prevbezt->
radius + t[2] * bezt->
radius +
1994 t[3] *
next->radius;
2003 (3.0f * fac * fac - 2.0f * fac * fac * fac);
2022 bevp1 = bevp2 + (bl->
nr - 1);
2082 bevp1 = bevp2 + (bl->
nr - 1);
2104 bevp1 = bevp2 + (bl->
nr - 1);
2126 float bevp0_quat[4];
2131 bevp1 = bevp2 + (bl->
nr - 1);
2136 if (bl->
poly == -1) {
2153 float zaxis[3] = {0, 0, 1},
cross[3], q2[4];
2225 bevp1 = bevp2 + (bl->
nr - 1);
2231 if (nr >= nr_init) {
2244 if (bl->
poly != -1) {
2257 float vec_1[3] = {0, 1, 0}, vec_2[3] = {0, 1, 0},
angle, ang_fac, cross_tmp[3];
2263 bevp_first += bl->
nr - 1;
2264 bevp_last = bevp_first;
2292 bevp1 = bevp2 + (bl->
nr - 1);
2318 bevp1 = bevp2 + (bl->
nr - 1);
2336 bevp1 = bevp2 + (bl->
nr - 1);
2353 bevp1 = bevp2 + (bl->
nr - 1);
2362 const float zero[3] = {0, 0, 0};
2376 switch (twist_mode) {
2425 const float x1 = bevp1->
vec[0] - bevp2->
vec[0];
2426 const float y1 = bevp1->
vec[1] - bevp2->
vec[1];
2444 if (bl->
poly != -1) {
2446 bevp1 = bevp2 + (bl->
nr - 1);
2459 const float x1 = bevp1->
vec[0] - bevp0->
vec[0];
2460 const float x2 = bevp1->
vec[0] - bevp2->
vec[0];
2461 const float y1 = bevp1->
vec[1] - bevp0->
vec[1];
2462 const float y2 = bevp1->
vec[1] - bevp2->
vec[1];
2478 if (bl->
poly == -1) {
2491 bevp += (bl->
nr - 1);
2501 if (nu->
pntsu > 1) {
2506 last_bevp = first_bevp + (bl->
nr - 1);
2519 if (bl->seglen !=
nullptr) {
2522 if (bl->segbevcount !=
nullptr) {
2525 if (bl->bevpoints !=
nullptr) {
2547 BevPoint *bevp2, *bevp1 =
nullptr, *bevp0;
2548 const float threshold = 0.00001f;
2550 float *seglen =
nullptr;
2552 int a,
b, nr, poly, resolu = 0,
len = 0, segcount;
2554 bool do_tilt, do_radius, do_weight;
2555 bool is_editmode =
false;
2559 const bool need_seglen =
ELEM(
2563 bev = &ob->
runtime->curve_cache->bev;
2579 if (nu->hide && is_editmode) {
2609 resolu = nu->resolu;
2640 if (seglen !=
nullptr &&
len != 0) {
2644 if (*seglen > threshold) {
2664 len = segcount * resolu + 1;
2682 if (seglen !=
nullptr) {
2691 prevbezt = nu->bezt + (nu->pntsu - 1);
2714 if (seglen !=
nullptr) {
2719 if (bevp->
offset > threshold) {
2730 for (j = 0; j < 3; j++) {
2732 prevbezt->
vec[2][j],
2744 do_tilt ? &bevp->
tilt :
nullptr,
2745 do_radius ? &bevp->
radius :
nullptr,
2746 do_weight ? &bevp->
weight :
nullptr,
2761 if (seglen !=
nullptr) {
2764 for (j = 0; j < resolu; j++) {
2769 if (bevp->
offset > threshold) {
2799 if (nu->pntsv == 1) {
2800 len = (resolu * segcount);
2820 do_tilt ? &bevp->
tilt :
nullptr,
2821 do_radius ? &bevp->
radius :
nullptr,
2822 do_weight ? &bevp->
weight :
nullptr,
2827 if (seglen !=
nullptr) {
2836 for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) {
2838 if (bevp->
offset > threshold) {
2865 const float threshold_resolu = 0.00001f / resolu;
2869 bevp1 = bl->bevpoints;
2870 bevp0 = bevp1 + (nr - 1);
2873 bevp0 = bl->bevpoints;
2879 if (seglen !=
nullptr) {
2881 bevp0->dupe_tag =
true;
2887 bevp0->dupe_tag =
true;
2897 if (bl->nr == 0 || bl->dupe_nr == 0) {
2901 nr = bl->nr - bl->dupe_nr + 1;
2903 memcpy(blnew, bl,
sizeof(
BevList));
2910 blnew->
seglen = bl->seglen;
2914 bevp0 = bl->bevpoints;
2918 if (bevp0->dupe_tag == 0) {
2919 memcpy(bevp1, bevp0,
sizeof(
BevPoint));
2925 if (bl->bevpoints !=
nullptr) {
2935 if (bl->nr && bl->poly >= 0) {
2949 bevp = bl->bevpoints;
2950 bevp1 = bl->bevpoints;
2954 if (
min > bevp->
vec[0]) {
2963 bevp = bl->bevpoints;
2964 if (bevp1 == bevp) {
2965 bevp0 = bevp + (bl->nr - 1);
2970 bevp = bevp + (bl->nr - 1);
2971 if (bevp1 == bevp) {
2972 bevp2 = bl->bevpoints;
2978 inp = ((bevp1->
vec[0] - bevp0->vec[0]) * (bevp0->vec[1] - bevp2->
vec[1]) +
2979 (bevp0->vec[1] - bevp1->
vec[1]) * (bevp0->vec[0] - bevp2->
vec[0]));
2994 for (a = 1; a < poly; a++, sd++) {
2996 sd1 = sortdata + (a - 1);
2997 for (
b = a - 1;
b >= 0;
b--, sd1--) {
3010 for (a = 0; a < poly; a++, sd++) {
3014 bevp2 = bevp1 + (bl->
nr - 1);
3017 std::swap(*bevp1, *bevp2);
3035 else if (bl->nr == 2) {
3050 else if (bl->nr == 2) {
3068 char fcurve_smoothing)
3071#define p2_h1 ((p2) - 3)
3072#define p2_h2 ((p2) + 3)
3074 const float *p1, *p3;
3077 float dvec_a[3], dvec_b[3];
3078 float len, len_a, len_b;
3079 const float eps = 1
e-5;
3084 if (bezt->
h1 == 0 && bezt->
h2 == 0) {
3090 if (prev ==
nullptr) {
3092 pt[0] = 2.0f * p2[0] - p3[0];
3093 pt[1] = 2.0f * p2[1] - p3[1];
3094 pt[2] = 2.0f * p2[2] - p3[2];
3101 if (
next ==
nullptr) {
3102 pt[0] = 2.0f * p2[0] - p1[0];
3103 pt[1] = 2.0f * p2[1] - p1[1];
3104 pt[2] = 2.0f * p2[2] - p1[2];
3123 if (len_a == 0.0f) {
3126 if (len_b == 0.0f) {
3132 tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
3133 tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
3134 tvec[2] = dvec_b[2] / len_b + dvec_a[2] / len_a;
3140 len = 6.0f / 2.5614f;
3153 bool leftviolate =
false, rightviolate =
false;
3156 len_a = std::min(len_a, 5.0f * len_b);
3157 len_b = std::min(len_b, 5.0f * len_a);
3165 float ydiff1 = prev->vec[1][1] - bezt->
vec[1][1];
3166 float ydiff2 =
next->vec[1][1] - bezt->
vec[1][1];
3167 if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) {
3168 bezt->
vec[0][1] = bezt->
vec[1][1];
3172 if (ydiff1 <= 0.0f) {
3173 if (prev->vec[1][1] > bezt->
vec[0][1]) {
3174 bezt->
vec[0][1] = prev->vec[1][1];
3179 if (prev->vec[1][1] < bezt->
vec[0][1]) {
3180 bezt->
vec[0][1] = prev->vec[1][1];
3192 float ydiff1 = prev->vec[1][1] - bezt->
vec[1][1];
3193 float ydiff2 =
next->vec[1][1] - bezt->
vec[1][1];
3194 if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) {
3195 bezt->
vec[2][1] = bezt->
vec[1][1];
3199 if (ydiff1 <= 0.0f) {
3200 if (
next->vec[1][1] < bezt->
vec[2][1]) {
3201 bezt->
vec[2][1] =
next->vec[1][1];
3202 rightviolate =
true;
3206 if (
next->vec[1][1] > bezt->
vec[2][1]) {
3207 bezt->
vec[2][1] =
next->vec[1][1];
3208 rightviolate =
true;
3214 if (leftviolate || rightviolate) {
3217 float h1_x =
p2_h1[0] - p2[0];
3218 float h2_x = p2[0] -
p2_h2[0];
3221 p2_h2[1] = p2[1] + ((p2[1] -
p2_h1[1]) / h1_x) * h2_x;
3224 p2_h1[1] = p2[1] + ((p2[1] -
p2_h2[1]) / h2_x) * h1_x;
3252 if (len_a == 0.0f) {
3255 if (len_b == 0.0f) {
3259 const float len_ratio = len_a / len_b;
3261 if (bezt->
f1 & handle_sel_flag) {
3264 len = 1.0f / len_ratio;
3290 len = 1.0f / len_ratio;
3310 if (nu->
pntsu < 2) {
3317 prev = bezt + (a - 1);
3335 else if (
next !=
nullptr) {
3355 size_t num_floats = 0, num_chars = 0;
3357 while (floats && floats[num_floats]) {
3361 while (chars && chars[num_chars]) {
3371 float *fptr = (
float *)buffer;
3373 for (
int i = 0;
i < num_floats;
i++, fptr +=
count) {
3377 char *cptr = (
char *)fptr;
3379 for (
int i = 0;
i < num_chars;
i++, cptr +=
count) {
3439 float *a0, *b0, *c0, *d0;
3440 float **arrays[] = {&a0, &b0, &c0, &d0,
nullptr};
3441 char *is_locked, *num_unlocks;
3442 char **flagarrays[] = {&is_locked, &num_unlocks,
nullptr};
3444 void *tmps =
allocate_arrays(solve_count, arrays, flagarrays,
"tridiagonal_solve_with_limits");
3449 memcpy(a0, a,
sizeof(
float) * solve_count);
3450 memcpy(b0,
b,
sizeof(
float) * solve_count);
3451 memcpy(c0, c,
sizeof(
float) * solve_count);
3452 memcpy(d0, d,
sizeof(
float) * solve_count);
3454 memset(is_locked, 0, solve_count);
3455 memset(num_unlocks, 0, solve_count);
3457 bool overshoot, unlocked;
3466 bool all =
false, locked =
false;
3468 overshoot = unlocked =
false;
3471 for (
int i = 0;
i < solve_count;
i++) {
3472 if (h[
i] >= hmin[
i] && h[
i] <= hmax[
i]) {
3478 float target = h[
i] > hmax[
i] ? hmax[
i] : hmin[
i];
3481 if (target != 0.0f ||
all) {
3491 }
while (overshoot && !locked);
3496 for (
int i = 0;
i < solve_count;
i++) {
3498 if (!is_locked[
i] || num_unlocks[
i] >= 2) {
3505 if ((relax > 0 && h[
i] < hmax[
i]) || (relax < 0 && h[
i] > hmin[
i])) {
3514 }
while (overshoot || unlocked);
3593 float *a,
float *
b,
float *c,
float *d,
const float *dy,
const float *
l,
int i)
3596 b[
i] = 2.0f * (
l[
i] + 1);
3597 c[
i] = 1.0f /
l[
i + 1];
3598 d[
i] = dy[
i] *
l[
i] *
l[
i] + dy[
i + 1];
3602 float *a,
float *
b,
float *c,
float *d,
const float *dy,
const float *
l,
int i)
3606 c[
i] = 1.0f /
l[
i + 1];
3611 float *a,
float *
b,
float *c,
float *d,
const float *dy,
const float *
l,
int i)
3616 d[
i] = dy[
i] *
l[
i] *
l[
i];
3621 float *hmax,
float *hmin,
int i,
float dy,
bool no_reverse,
bool no_overshoot)
3639 else if (no_reverse || no_overshoot) {
3640 hmax[
i] = hmin[
i] = 0.0f;
3647 const float newval[3],
3652 int idx = right ? 2 : 0;
3653 char hr = right ? bezt->
h2 : bezt->
h1;
3654 char hm = right ? bezt->
h1 : bezt->
h2;
3684 tmp[1] = bezt->
vec[1][1] + dy;
3698 float fac = dx / (hsize[0] + dx / 3.0f);
3702 return 1.0f - 3.0f * hsize[0] / dx;
3708 float *dx, *dy, *
l, *a, *
b, *c, *d, *h, *hmax, *hmin;
3709 float **arrays[] = {&dx, &dy, &
l, &a, &
b, &c, &d, &h, &hmax, &hmin,
nullptr};
3711 int solve_count =
count;
3722 bool full_cycle = (start == 0 &&
count == total && cycle);
3726 &bezt[(start +
count > total) ? start +
count - total : start +
count - 1];
3730 bezt_last, bezt_last->
h1, start +
count == total);
3732 if (
count == 2 && !full_cycle && solve_first == solve_last) {
3747 for (
int i = 1, j = start + 1;
i <
count;
i++, j++) {
3748 dx[
i] = bezt[j].
vec[1][0] - bezt[j - 1].
vec[1][0];
3749 dy[
i] = bezt[j].
vec[1][1] - bezt[j - 1].
vec[1][1];
3752 if (cycle && j == total - 1) {
3760 dx[0] = dx[
count - 1];
3761 dy[0] = dy[
count - 1];
3763 l[0] =
l[
count - 1] = dx[1] / dx[0];
3769 for (
int i = 1;
i <
count - 1;
i++) {
3770 l[
i] = dx[
i + 1] / dx[
i];
3782 for (
int i = 1, j = start + 1;
i <
count;
i++, j++) {
3783 clamped_prev = clamped_cur;
3786 if (cycle && j == total - 1) {
3791 bezier_clamp(hmax, hmin,
i - 1, dy[
i], clamped_prev, clamped_prev);
3797 float first_handle_adj = 0.0f, last_handle_adj = 0.0f;
3801 int i = solve_count =
count - 1;
3803 hmin[0] =
max_ff(hmin[0], hmin[
i]);
3804 hmax[0] =
min_ff(hmax[0], hmax[
i]);
3806 solve_first = solve_last =
true;
3837 for (
int i = 1;
i <
count - 1;
i++) {
3844 if (
count > 2 || solve_last) {
3845 b[1] +=
l[1] * first_handle_adj;
3848 if (
count > 2 || solve_first) {
3849 b[
count - 2] += last_handle_adj;
3857 h[
count - 1] = h[0];
3860 for (
int i = 1, j = start + 1;
i <
count - 1;
i++, j++) {
3861 bool end = (j == total - 1);
3897 int search_base = 0;
3900 for (
int i = 1;
i < total - 1;
i++) {
3908 if (search_base == 0) {
3916 int start = search_base,
count = 1;
3918 for (
int i = 1, j = start + 1;
i < total;
i++, j++) {
3920 if (j == total - 1 && cyclic) {
3950 const bool is_fcurve,
3951 const char smoothing)
3971 for (
i = nu->
pntsu, bezt = nu->
bezt;
i--; bezt++) {
3989 if (nu->
pntsu > 1) {
3998 if (nu->
pntsu > 1) {
3999 const char h1_back = bezt->
h1, h2_back = bezt->
h2;
4011#define SEL_F1 (1 << 0)
4012#define SEL_F2 (1 << 1)
4013#define SEL_F3 (1 << 2)
4021 switch (handle_mode) {
4027 if (bezt->
f2 & sel_flag) {
4033 if (bezt->
f1 & sel_flag) {
4036 if (bezt->
f2 & sel_flag) {
4039 if (bezt->
f3 & sel_flag) {
4051 const bool use_around_local)
4054 if (use_around_local) {
4086 const bool use_around_local)
4108 const float eps = 0.0001f;
4109 const float eps_sq =
eps *
eps;
4111 if (nu ==
nullptr || nu->
bezt ==
nullptr) {
4121 bool align =
false, leftsmall =
false, rightsmall =
false;
4207 if ((
flag & (1 << 0)) || (
flag & (1 << 2))) {
4208 if (
flag & (1 << 0)) {
4211 if (
flag & (1 << 2)) {
4214 if (bezt->
h1 != bezt->
h2) {
4238 else if (code == 6) {
4267 if (
flag & (1 << 0)) {
4270 if (
flag & (1 << 2)) {
4285 const bool calc_length,
4296 bool changed =
false;
4298 for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
4300 const bool h1_select = (bezt->
f1 &
flag) ==
flag;
4301 const bool h2_select = (bezt->
f3 &
flag) ==
flag;
4303 if (h1_select || h2_select) {
4305 float co1_back[3], co2_back[3];
4366 a = nu->pntsu * nu->pntsv;
4378 bool changed =
false;
4382 for (
int i = 0;
i < nu->pntsu;
i++) {
4384 uint8_t old_f1 = bezt->
f1, old_f2 = bezt->
f2, old_f3 = bezt->
f3;
4390 changed |= (old_f1 != bezt->
f1) || (old_f2 != bezt->
f2) || (old_f3 != bezt->
f3);
4394 for (
int i = 0;
i < nu->pntsu * nu->pntsv;
i++) {
4396 uint8_t old_f1 = bp->
f1;
4399 changed |= (old_f1 != bp->
f1);
4411 float *fp1, *fp2, *tempf;
4421 bezt2 = bezt1 + (a - 1);
4427 if (bezt1 != bezt2) {
4428 std::swap(*bezt1, *bezt2);
4433 if (bezt1 != bezt2) {
4437 std::swap(bezt1->
h1, bezt1->
h2);
4438 std::swap(bezt1->
f1, bezt1->
f3);
4440 if (bezt1 != bezt2) {
4441 std::swap(bezt2->
h1, bezt2->
h2);
4442 std::swap(bezt2->
f1, bezt2->
f3);
4454 else if (nu->
pntsv == 1) {
4457 bp2 = bp1 + (a - 1);
4459 while (bp1 != bp2 && a > 0) {
4460 std::swap(*bp1, *bp2);
4470 if (nu->
pntsu & 1) {
4479 fp2 = fp1 + (a - 1);
4481 while (fp1 != fp2 && a > 0) {
4482 std::swap(*fp1, *fp2);
4494 fp2[0] =
fabsf(fp1[1] - fp1[0]);
4505 fp1[0] = fp1[-1] + fp2[0];
4517 bp2 = bp1 + (a - 1);
4520 while (bp1 != bp2 && a > 0) {
4521 std::swap(*bp1, *bp2);
4536 for (
int i = 0;
i < nu->pntsu;
i++, bezt++) {
4537 vert_coords[index] = bezt->
vec[0];
4539 vert_coords[index] = bezt->
vec[1];
4541 vert_coords[index] = bezt->
vec[2];
4546 const BPoint *bp = nu->bp;
4547 for (
int i = 0;
i < nu->pntsu * nu->pntsv;
i++, bp++) {
4548 vert_coords[index] = bp->
vec;
4565 const bool constrain_2d)
4572 for (
int i = 0;
i < nu->pntsu;
i++, bezt++) {
4584 for (
int i = 0;
i < nu->pntsu * nu->pntsv;
i++, bp++) {
4600 const bool constrain_2d)
4607 for (
int i = 0;
i < nu->pntsu;
i++, bezt++) {
4619 for (
int i = 0;
i < nu->pntsu * nu->pntsv;
i++, bp++) {
4642 for (
int i = 0;
i < nu->pntsu;
i++, bezt++) {
4643 vert_coords[index] = &key[0];
4645 vert_coords[index] = &key[3];
4647 vert_coords[index] = &key[6];
4653 const BPoint *bp = nu->bp;
4655 for (
int i = 0;
i < nu->pntsu * nu->pntsv;
i++, bp++) {
4656 vert_coords[index] = key;
4671 for (
int i = 0;
i < nu->pntsu;
i++, bezt++) {
4672 bezt->
tilt = key[9];
4680 for (
int i = 0;
i < nu->pntsu * nu->pntsv;
i++, bp++) {
4694 int *r_points_needed)
4704 int points_needed = 0;
4706 const int remainder = pnts % (order - 1);
4707 points_needed = remainder > 0 ? order - 1 - remainder : 0;
4710 points_needed = order + 1 - pnts;
4712 if (points_needed) {
4713 *r_points_needed = points_needed;
4729 const size_t maxncpy)
4733 pnts, order,
flag, type, is_surf, &points_needed);
4745 BLI_strncpy(message_dst,
RPT_(
"At least two points required"), maxncpy);
4748 BLI_strncpy(message_dst,
RPT_(
"Must have more control points than Order"), maxncpy);
4753 RPT_(
"%d more %s row(s) needed for Bézier"),
4755 dir == 0 ?
"U" :
"V");
4759 message_dst, maxncpy,
RPT_(
"%d more point(s) needed for Bézier"), points_needed);
4796 bool changed =
false;
4806 bool changed =
false;
4816 const bool use_handles,
4817 const char **r_err_msg)
4832 bezt->
f1 = bezt->
f2 = bezt->
f3 = bp->
f1;
4861 nr = use_handles ? (3 * nu->
pntsu) : nu->
pntsu;
4868 (use_handles ==
false))
4882 const uint8_t *f = &bezt->
f1;
4883 for (c = 0; c < 3; c++, f++) {
4922 if (r_err_msg !=
nullptr) {
4923 *r_err_msg =
"At least 6 points required for conversion";
4978 if (nu ==
nullptr) {
4997 void *vert =
nullptr;
5034 void *vert =
nullptr;
5055 return (*r_vert !=
nullptr);
5084 const bool use_radius)
5087 return std::nullopt;
5089 float3 min(std::numeric_limits<float>::max());
5090 float3 max(std::numeric_limits<float>::lowest());
5109 nullptr, *cu,
FO_EDIT, &temp_nurb_lb,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
5131 for (bezt = nu->bezt;
i--; bezt++) {
5139 i = nu->pntsu * nu->pntsv;
5141 for (bp = nu->bp;
i--; bp++) {
5151 return (total != 0);
5155 const float mat[4][4],
5157 const bool do_props,
5158 const float unit_scale)
5169 for (bezt = nu->bezt;
i--; bezt++) {
5174 bezt->
radius *= unit_scale;
5176 if (!is_uniform_scaled) {
5185 i = nu->pntsu * nu->pntsv;
5186 for (bp = nu->bp;
i--; bp++) {
5189 bp->
radius *= unit_scale;
5195 if (do_keys && cu->
key) {
5197 float *fp = (
float *)kb->data;
5198 int n = kb->totelem;
5207 fp[10] *= unit_scale;
5216 fp[4] *= unit_scale;
5239 for (
BezTriple *bezt = nu->bezt;
i--; bezt++) {
5246 int i = nu->pntsu * nu->pntsv;
5247 for (
BPoint *bp = nu->bp;
i--; bp++) {
5253 if (do_keys && cu->
key) {
5255 float *fp = (
float *)kb->data;
5256 int n = kb->totelem;
5290 if (nu->mat_nr && nu->mat_nr >= index) {
5302 if (info->
mat_nr == index) {
5309 if (nu->mat_nr == index) {
5335 bool is_valid =
true;
5342 if (info->
mat_nr > max_idx) {
5351 if (nu->mat_nr > max_idx) {
5367 const short remap_len_short = short(remap_len);
5369#define MAT_NR_REMAP(n) \
5370 if (n < remap_len_short) { \
5371 BLI_assert(n >= 0 && remap[n] < remap_len_short); \
5378 int charinfo_len,
i;
5383 charinfo_len = ef->
len;
5390 for (
i = 0;
i <= charinfo_len;
i++) {
5432 float h1[2], h2[2], len1, len2,
len, fac;
5435 h1[0] = v1[0] -
v2[0];
5436 h1[1] = v1[1] -
v2[1];
5438 h2[0] = v4[0] - v3[0];
5439 h2[1] = v4[1] - v3[1];
5446 len = v4[0] - v1[0];
5447 len1 =
fabsf(h1[0]);
5448 len2 =
fabsf(h2[0]);
5451 if ((len1 + len2) == 0.0f) {
5458 if ((len1 + len2) >
len) {
5459 fac =
len / (len1 + len2);
5461 v2[0] = (v1[0] - fac * h1[0]);
5462 v2[1] = (v1[1] - fac * h1[1]);
5464 v3[0] = (v4[0] - fac * h2[0]);
5465 v3[1] = (v4[1] - fac * h2[1]);
5469std::optional<int> Curve::material_index_max()
const
5472 return std::nullopt;
5476 max_index = std::max<int>(max_index,
nurb->mat_nr);
@ NURB_HANDLE_TEST_KNOT_OR_EACH
@ NURB_HANDLE_TEST_KNOT_ONLY
#define CU_DO_RADIUS(cu, nu)
int eBezTriple_Flag__Alias
void(* BKE_curve_batch_cache_free_cb)(Curve *cu)
bool BKE_nurb_check_valid_v(const Nurb *nu)
void(* BKE_curve_batch_cache_dirty_tag_cb)(Curve *cu, int mode)
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)
IDTypeInfo IDType_ID_CU_LEGACY
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
void key_curve_position_weights(float t, float data[4], KeyInterpolationType type)
struct ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, std::optional< const ID * > new_owner_id, ID **new_id_p, int flag)
void * BKE_libblock_alloc(Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
void BKE_id_blend_write(BlendWriter *writer, ID *id)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
VFont * BKE_vfont_builtin_ensure()
bool BKE_vfont_to_curve_ex(Object *ob, const Curve &cu, eEditFontMode mode, ListBase *r_nubase, const char32_t **r_text, int *r_text_len, bool *r_text_free, CharTrans **r_chartransdata, float *r_font_size_eval)
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(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 int clamp_i(int value, int min, int max)
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_write_float_array(BlendWriter *writer, int64_t num, const float *data_ptr)
void BLO_read_float_array(BlendDataReader *reader, int64_t 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_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)
#define BLO_read_struct(reader, struct_name, ptr_p)
void BLO_write_pointer_array(BlendWriter *writer, int64_t num, const void *data_ptr)
void BLO_read_pointer_array(BlendDataReader *reader, int64_t array_size, void **ptr_p)
#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)
T * DEG_get_original(T *id)
#define FILTER_ID_CU_LEGACY
@ CU_TEXSPACE_FLAG_AUTO_EVALUATED
@ HD_AUTOTYPE_LOCKED_FINAL
#define BEZT_IS_AUTOH(bezt)
#define BEZT_ISSEL_ANY(bezt)
#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)
BMesh const char void * data
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
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
static T sum(const btAlignedObjectArray< T > &items)
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)
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_init(Curve *cu, const short curve_type)
static void make_bevel_list_segment_3D(BevList *bl)
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_nurbs_vert_coords_apply_with_mat4(ListBase *lb, const Span< float3 > vert_coords, const float4x4 &transform, const bool constrain_2d)
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_nurbs_vert_coords_get(const ListBase *lb, MutableSpan< float3 > vert_coords)
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_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)
void BKE_curve_nurbs_vert_coords_apply(ListBase *lb, const Span< float3 > vert_coords, const bool constrain_2d)
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)
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)
Array< float3 > BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb)
static void nurb_handles_calc__align_selected(Nurb *nu)
Array< float3 > BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb, const float *key)
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)
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_type_test(Object *ob, const bool dimension_update)
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)
void BKE_nurb_knot_alloc_u(Nurb *nu)
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)
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
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)
static bool is_cyclic(const Nurb *nu)
bool all(VecOp< bool, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float length(VecOp< float, D >) RET
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
MatBase< float, 4, 4 > float4x4
VecBase< float, 3 > float3
char edit_data_from_original
struct CurveProfile * bevel_profile
struct EditFont * editfont
struct CharInfo * strinfo
struct Object * textoncurve
float texspace_location[3]
EditFontSelBox * selboxes
ObjectRuntimeHandle * runtime