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),
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;
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;
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);
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);
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) {
2875 bevp0->dupe_tag =
true;
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++) {
5355 bool is_valid =
true;
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++) {
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
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], 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)
@ IDWALK_DO_DEPRECATED_POINTERS
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
#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
@ CU_TEXSPACE_FLAG_AUTO_EVALUATED
#define BEZT_IS_AUTOH(bezt)
#define BEZT_ISSEL_ANY(bezt)
@ HD_AUTOTYPE_LOCKED_FINAL
#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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
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
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
static T sum(const btAlignedObjectArray< T > &items)
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)
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)
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)
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