50#ifdef BEVEL_DEBUG_TIME
54#define BEVEL_EPSILON_D 1e-6
55#define BEVEL_EPSILON 1e-6f
56#define BEVEL_EPSILON_SQ 1e-12f
57#define BEVEL_EPSILON_BIG 1e-4f
58#define BEVEL_EPSILON_BIG_SQ 1e-8f
59#define BEVEL_EPSILON_ANG DEG2RADF(2.0f)
60#define BEVEL_SMALL_ANG DEG2RADF(10.0f)
62#define BEVEL_SMALL_ANG_DOT (1.0f - cosf(BEVEL_SMALL_ANG))
64#define BEVEL_EPSILON_ANG_DOT (1.0f - cosf(BEVEL_EPSILON_ANG))
65#define BEVEL_MAX_ADJUST_PCT 10.0f
66#define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f
67#define BEVEL_MATCH_SPEC_WEIGHT 0.2
160#define PRO_SQUARE_R 1e4f
161#define PRO_CIRCLE_R 2.0f
162#define PRO_LINE_R 1.0f
163#define PRO_SQUARE_IN_R 0.0f
421#define BM_ELEM_LONG_TAG (1 << 6)
431 if (
bm->use_toolflags) {
438 if (
bm->use_toolflags) {
445 if (
bm->use_toolflags) {
479 const float direction_dot =
dot_v3v3(d1, d2);
527 int nj = (vm->
seg / 2) + 1;
528 int nk = vm->
seg + 1;
530 return &vm->
mesh[
i * nk * nj + j * nk + k];
589 *r_bvother =
nullptr;
598 if (from_e ==
nullptr) {
606 }
while ((
e =
e->next) != from_e);
634 if (
l->prev->e == bme2 ||
l->next->e == bme2) {
654 if (frep_arr && frep_arr[0]) {
690 if (!uv_vert_buckets) {
704 bool is_bucket_found =
false;
720 bool is_orig_uv_verts_connected =
false;
722 for (
UVVertBucket &orig_uv_vert_bucket : orig_uv_vert_buckets) {
723 if (orig_uv_vert_bucket.contains(orig_l) && orig_uv_vert_bucket.contains(orig_l2)) {
724 is_orig_uv_verts_connected =
true;
738 if (uv_vert_bucket.contains(l2)) {
739 uv_vert_bucket.add(
l);
740 is_bucket_found =
true;
745 if (is_bucket_found) {
749 if (!is_bucket_found) {
769 for (
int i = 0;
i < num_uv_layers; ++
i) {
776 bool is_overlap_found =
false;
778 for (
BMLoop *l2 : uv_vert_bucket) {
781 uv_vert_bucket.add(
l);
782 is_overlap_found =
true;
786 if (is_overlap_found) {
790 if (!is_overlap_found) {
813 for (
int i = 0;
i < num_uv_layers; ++
i) {
817 int num_uv_verts = uv_vert_bucket.size();
818 if (num_uv_verts <= 1) {
821 float uv[2] = {0.0f, 0.0f};
822 for (
BMLoop *
l : uv_vert_bucket) {
826 mul_v2_fl(uv, 1.0f /
float(num_uv_verts));
827 for (
BMLoop *
l : uv_vert_bucket) {
849 frep =
v->ebev->fprev;
850 if (
v->efirst->fprev != frep) {
851 frep2 =
v->efirst->fprev;
854 else if (
v->efirst) {
855 frep =
v->efirst->fprev;
857 if (
v->elast->fnext != frep) {
858 frep2 =
v->elast->fnext;
860 else if (
v->efirst->fnext != frep) {
861 frep2 =
v->efirst->fnext;
863 else if (
v->elast->fprev != frep) {
864 frep2 =
v->efirst->fprev;
867 else if (
v->efirst->fnext) {
868 frep =
v->efirst->fnext;
869 if (
v->elast->fnext != frep) {
870 frep2 =
v->elast->fnext;
873 else if (
v->elast->fprev) {
874 frep =
v->elast->fprev;
877 else if (
v->prev->elast) {
878 frep =
v->prev->elast->fnext;
879 if (
v->next->efirst) {
881 frep2 =
v->next->efirst->fprev;
884 frep =
v->next->efirst->fprev;
924 if (facerep || (face_arr && face_arr[0])) {
935 interp_f = face_arr[
i];
943 bme = snap_edge_arr[
i];
970 f->
mat_nr = short(mat_nr);
982 const int offset =
bm->ldata.layers[layer_index].offset;
983 const int type =
bm->ldata.layers[layer_index].type;
994 if (
bm->ldata.totlayer == 0) {
1005 if (lef1->
f == f2) {
1006 std::swap(lef1, lef2);
1008 if (lef1->
f != f1 || lef2->
f != f2) {
1022 BLI_assert(lv1f1->
v == v1 && lv1f1->
f == f1 && lv2f1->
v ==
v2 && lv2f1->
f == f1 &&
1023 lv1f2->
v == v1 && lv1f2->
f == f2 && lv2f2->
v ==
v2 && lv2f2->
f == f2);
1024 for (
int i = 0;
i <
bm->ldata.totlayer;
i++) {
1045 for (
int f = 0; f < totface; f++) {
1046 if (face_component[f] == c1) {
1047 face_component[f] = c2;
1049 else if (face_component[f] == c2) {
1050 face_component[f] = c1;
1086 for (
int i = 0;
i <
bm->ldata.totlayer;
i++) {
1098 int totface =
bm->totface;
1099 int *face_component =
static_cast<int *
>(
1109 for (f = 0; f < totface; f++) {
1110 face_component[f] = -1;
1111 in_stack[f] =
false;
1113 int current_component = -1;
1114 for (f = 0; f < totface; f++) {
1115 if (face_component[f] == -1 && !in_stack[f]) {
1117 current_component++;
1121 while (stack_top >= 0) {
1122 BMFace *bmf = stack[stack_top];
1125 in_stack[bmf_index] =
false;
1126 if (face_component[bmf_index] != -1) {
1129 face_component[bmf_index] = current_component;
1140 if (bmf_other != bmf) {
1142 if (face_component[bmf_other_index] != -1 || in_stack[bmf_other_index]) {
1148 stack[stack_top] = bmf_other;
1149 in_stack[bmf_other_index] =
true;
1162 if (current_component <= 0) {
1165 BMFace *top_face =
nullptr;
1166 float top_face_z = -1e30f;
1167 int top_face_component = -1;
1168 BMFace *bot_face =
nullptr;
1169 float bot_face_z = 1e30f;
1170 int bot_face_component = -1;
1171 for (f = 0; f < totface; f++) {
1176 if (fz > top_face_z) {
1179 top_face_component = face_component[f];
1181 if (fz < bot_face_z) {
1184 bot_face_component = face_component[f];
1187 BLI_assert(top_face !=
nullptr && bot_face !=
nullptr);
1190 if (bot_face_component != top_face_component) {
1191 if (bot_face_component == 0) {
1193 bot_face_component = top_face_component;
1213#define VEC_VALUE_LEN 6
1219 for (
int f = 0; f < nfaces; f++) {
1221 if (bmf ==
nullptr) {
1222 still_viable[f] =
false;
1225 still_viable[f] =
true;
1228 int value_index = 0;
1240 value_vecs[f][value_index++] = cent[2];
1241 value_vecs[f][value_index++] = cent[0];
1242 value_vecs[f][value_index++] = cent[1];
1250 for (
int value_index = 0; num_viable > 1 && value_index <
VEC_VALUE_LEN; value_index++) {
1251 for (
int f = 0; f < nfaces; f++) {
1252 if (!still_viable[f] || f == best_f) {
1259 if (value_vecs[f][value_index] < value_vecs[best_f][value_index]) {
1262 for (
int i = f - 1;
i >= 0;
i--) {
1263 if (still_viable[
i]) {
1264 still_viable[
i] =
false;
1269 else if (value_vecs[f][value_index] > value_vecs[best_f][value_index]) {
1270 still_viable[f] =
false;
1278 return face[best_f];
1300 float *l1 =
e->e->v1->co;
1307 *ret_closer_v =
e->e->v1;
1311 *ret_closer_v =
e->e->v2;
1322 float dir1[3], dir2[3];
1341 else if (e2->
fprev) {
1359 float dir1[3], dir2[3], dirco[3], no[3];
1387 float dir1[3], dir2[3],
cross[3];
1390 if (e1->
v1 == e2->
v1) {
1395 else if (e1->
v1 == e2->
v2) {
1400 else if (e1->
v2 == e2->
v1) {
1405 else if (e1->
v2 == e2->
v2) {
1446 float d0, d3, d4, d5;
1452 bool no_offsets = f1 ==
nullptr || f2 ==
nullptr;
1469 d0 = d3 = d4 = d5 = bp->
offset;
1531 float dir1[3], dir2[3];
1535 float dir1n[3], dir2p[3];
1536 if (edges_between) {
1549 float norm_perp1[3];
1567 for (
EdgeHalf *eloop = e1; eloop != e2; eloop = eloop->
next) {
1568 if (eloop->fnext !=
nullptr) {
1586 d = d /
cosf(ang / 2.0f);
1606 float norm_v1[3], norm_v2[3];
1611 else if (!edges_between) {
1614 if (
dot_v3v3(norm_v1, f ? f->
no :
v->no) < 0.0f) {
1624 if (
dot_v3v3(norm_v1, f ? f->
no :
v->no) < 0.0f) {
1630 if (
dot_v3v3(norm_v2, f ? f->
no :
v->no) < 0.0f) {
1636 float norm_perp2[3];
1642 float off1a[3], off1b[3], off2a[3], off2b[3];
1659 if (isect_kind == 0) {
1677 if (isect_kind == 2) {
1712#define BEVEL_GOOD_ANGLE 0.1f
1725 float dir1[3], dir2[3];
1756 float sinang =
sinf(ang);
1796 bool retval =
false;
1801 float meet1[3], meet2[3];
1823 *r_sinratio = (ang1 == 0.0f) ? 1.0f :
sinf(ang2) /
sinf(ang1);
1831 *r_sinratio = (ang1 == 0.0f) ? 1.0f :
sinf(ang2) /
sinf(ang1);
1835 else if (ok1 && !ok2) {
1838 else if (!ok1 && ok2) {
1856 float dir[3], no[3];
1886 const float co_a[3],
1887 const float co_b[3],
1892#ifdef BEVEL_ASSERT_PROJECT
1903 bool do_linear_interp =
true;
1907 float start[3], end[3];
1911 do_linear_interp =
false;
1940 if (
e->prev->is_bev &&
e->next->is_bev && bv->
selcount >= 3) {
1942 float d3[3], d4[3], co4[3], meetco[3], isect2[3];
1952 do_linear_interp =
true;
1959 if (isect_kind != 0) {
1965 do_linear_interp =
true;
1978 do_linear_interp =
true;
1995 do_linear_interp =
false;
2005 do_linear_interp =
false;
2008 if (do_linear_interp) {
2041 float no[3], no2[3], no3[3];
2073 float d1[3], d2[3], no[3];
2081 float no2[3], no3[3];
2086 if (l1 != 0.0f && (l2 != 0.0f || l3 != 0.0f)) {
2114 return lb->
next == la ? 1 : -1;
2139 const float vmid[3],
2143 float vb_vmid[3], va_vmid[3];
2155 float vo[3], vd[3], vddir[3];
2196 const float va[3],
const float vb[3],
const float vc[3],
const float vd[3],
float r_mat[4][4])
2237 return pow((1.0 -
pow(
x, r)), (1.0 / r));
2239 return 1.0 -
pow((1.0 -
pow(1.0 -
x, r)), (1.0 / r));
2263 if (nseg == bp->
seg) {
2281 const float map[4][4],
2283 const bool reversed,
2285 const double *xvals,
2286 const double *yvals,
2290 for (
int k = 0; k <= ns; k++) {
2300 const float p[3] = {
2301 reversed ?
float(yvals[ns - k]) :
float(xvals[k]),
2302 reversed ?
float(xvals[ns - k]) :
float(yvals[k]),
2313 float *prof_co_k = r_prof_co + 3 * k;
2347 if (pro->
prof_co ==
nullptr) {
2370 float bottom_corner[3] = {0.0f, 0.0f, 0.0f};
2372 float top_corner[3] = {1.0f, 1.0f, 0.0f};
2408 float a =
max_ff(0.0f, co[0]);
2409 float b =
max_ff(0.0f, co[1]);
2410 float c =
max_ff(0.0f, co[2]);
2422 float dx = 1.0f -
x;
2423 float dy = 1.0f -
y;
2426 y = midline ? 1.0f :
y;
2430 x = midline ? 1.0f :
x;
2437 y = midline ? 0.0f :
y;
2441 x = midline ? 0.0f :
x;
2446 float rinv = 1.0f / r;
2455 y =
powf(1.0f / (1.0f +
powf(c /
b, r)), rinv);
2470#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) BM_elem_flag_test(eh->e, flag)
2486#define HASNOT_SEAMSHARP(eh, flag) \
2487 ((flag == BM_ELEM_SEAM && !BM_elem_flag_test(eh->e, BM_ELEM_SEAM)) || \
2488 (flag == BM_ELEM_SMOOTH && BM_elem_flag_test(eh->e, BM_ELEM_SMOOTH)))
2524 e->rightv->seam_len = flag_count;
2527 e->rightv->sharp_len = flag_count;
2530 }
while (
e != efirst);
2555 int idx_end = bcur->
index + extend_len;
2556 for (
int i = bcur->
index;
i < idx_end;
i++) {
2559 for (
int k = 1; k < vm->
seg; k++) {
2565 while (
e->v1 !=
v2 &&
e->v2 !=
v2) {
2578 while (
e->v1 != v3 &&
e->v2 != v3) {
2593 }
while (bcur != start);
2624 BMLoop *lother =
l->radial_next;
2626 if (lother !=
l && fother) {
2661 if (cd_clnors_offset == -1) {
2669 if (cd_clnors_offset == -1) {
2675 if (cd_clnors_offset == -1) {
2697 float *pnorm =
nullptr;
2708 pnorm = lprev->
f->
no;
2711 pnorm = lnext->
f->
no;
2717 else if (fkind ==
F_VERT) {
2721 else if (fprevkind ==
F_RECON) {
2722 pnorm = lprev->
f->
no;
2724 else if (fnextkind ==
F_RECON) {
2725 pnorm = lnext->
f->
no;
2728 BMLoop *lprevprev, *lnextnext;
2730 estep = lprev->
prev->
e;
2734 lprevprev =
nullptr;
2741 lnextnext =
nullptr;
2746 pnorm = lprevprev->
f->
no;
2762 if (pnorm ==
norm) {
2779 if (cd_prop_int_idx == -1) {
2791 bool do_set_strength =
true;
2811 do_set_strength =
false;
2813 if (do_set_strength) {
2815 *strength_ptr = strength;
2826 v->any_seam =
false;
2828 v->any_seam |=
e->is_seam;
2829 if (
e ==
v->elast) {
2847 if (
e->fprev &&
e->fnext) {
2870 bool miter_profile =
false;
2871 bool reverse_profile =
false;
2896 v->efirst =
v->elast =
e;
2897 e->leftv =
e->rightv =
v;
2902 }
while ((
e =
e->next) != efirst);
2906 if (vm->
count == 2) {
2909 else if (bp->
seg == 1) {
2926 const bool construct)
2937 const float *no =
e->fprev ?
e->fprev->no : (
e->fnext ?
e->fnext->no :
nullptr);
2947 no =
e->fnext ?
e->fnext->no : (
e->fprev ?
e->fprev->no :
nullptr);
2962 e->next->leftv =
e->next->rightv = bndv;
2986 e->prev->leftv =
e->prev->rightv = bndv;
3002 e->leftv =
e->rightv = bndv;
3003 e->prev->rightv = bndv;
3013 for (
e =
e->next;
e->next != efirst;
e =
e->next) {
3018 e->leftv =
e->rightv = bndv;
3040 else if (vm->
count == 3) {
3041 bool use_tri_fan =
true;
3045 float profile_plane[4];
3049 use_tri_fan =
false;
3086 float co1[3], edge_dir[3], line_p[3];
3090 float d = bp->
offset / (bp->
seg / 2.0f);
3115 if (
v->is_arc_start) {
3119 float edge_dir[3], co[3];
3136 }
while (
v != vstart);
3199 int not_in_plane = 0;
3215 if (in_plane == 0 && not_in_plane == 0) {
3218 else if (not_in_plane > 0) {
3254 e3->leftv = e3->rightv =
v;
3292 if (
e->next == e2) {
3293 v2->efirst =
nullptr;
3294 v2->elast =
nullptr;
3297 v2->efirst =
e->next;
3299 e3->leftv = e3->rightv =
v2;
3307 if (
e->next == e2) {
3311 int between = in_plane + not_in_plane;
3312 int bet2 = between / 2;
3313 bool betodd = (between % 2) == 1;
3320 e3->profile_index = 0;
3322 else if (betodd &&
i == bet2) {
3323 e3->profile_index = bp->
seg / 2;
3326 e3->profile_index = bp->
seg;
3364 }
while (
e != efirst);
3376 if (vm->
count == 2) {
3379 else if (efirst->
seg == 1) {
3396static void print_adjust_stats(
BoundVert *vstart)
3398 printf(
"\nSolution analysis\n");
3399 double even_residual2 = 0.0;
3400 double spec_residual2 = 0.0;
3401 double max_even_r = 0.0;
3402 double max_even_r_pct = 0.0;
3403 double max_spec_r = 0.0;
3404 double max_spec_r_pct = 0.0;
3405 printf(
"width matching\n");
3408 if (
v->adjchain !=
nullptr) {
3413 printf(
"e%d r(%f) vs l(%f): abs(delta)=%f, delta_pct=%f\n",
3419 even_residual2 += delta * delta;
3420 if (delta > max_even_r) {
3423 if (delta_pct > max_even_r_pct) {
3424 max_even_r_pct = delta_pct;
3428 }
while (
v &&
v != vstart);
3430 printf(
"spec matching\n");
3433 if (
v->adjchain !=
nullptr) {
3438 printf(
"e%d r(%f) vs r spec(%f): delta=%f, delta_pct=%f\n",
3444 spec_residual2 += delta * delta;
3445 delta =
fabs(delta);
3446 delta_pct =
fabs(delta_pct);
3447 if (delta > max_spec_r) {
3450 if (delta_pct > max_spec_r_pct) {
3451 max_spec_r_pct = delta_pct;
3456 printf(
"e%d l(%f) vs l spec(%f): delta=%f, delta_pct=%f\n",
3462 spec_residual2 += delta * delta;
3463 delta =
fabs(delta);
3464 delta_pct =
fabs(delta_pct);
3465 if (delta > max_spec_r) {
3468 if (delta_pct > max_spec_r_pct) {
3469 max_spec_r_pct = delta_pct;
3473 }
while (
v &&
v != vstart);
3475 printf(
"Analysis Result:\n");
3476 printf(
"even residual2 = %f, spec residual2 = %f\n", even_residual2, spec_residual2);
3477 printf(
"max even delta = %f, max as percent of spec = %f\n", max_even_r, max_even_r_pct);
3478 printf(
"max spec delta = %f, max as percent of spec = %f\n", max_spec_r, max_spec_r_pct);
3482#ifdef FAST_ADJUST_CODE
3491static bool adjust_the_cycle_or_chain_fast(
BoundVert *vstart,
int np,
bool iscycle)
3493 float *g =
MEM_mallocN(np *
sizeof(
float),
"beveladjust");
3494 float *g_prod =
MEM_mallocN(np *
sizeof(
float),
"beveladjust");
3497 float spec_sum = 0.0f;
3501 if (iscycle ||
v->adjchain !=
nullptr) {
3502 spec_sum +=
v->efirst->offset_r;
3505 spec_sum +=
v->elast->offset_l;
3509 }
while (
v &&
v != vstart);
3511 float gprod = 1.00f;
3512 float gprod_sum = 1.0f;
3513 for (
i = np - 1;
i > 0;
i--) {
3528 if (gprod_sum == 0.0f) {
3533 float p = spec_sum / gprod_sum;
3539 if (iscycle ||
v->adjchain !=
nullptr) {
3542 eright->
offset_r = g_prod[(
i + 1) % np] * p;
3543 if (iscycle ||
v != vstart) {
3554 }
while (
v &&
v != vstart);
3587 if ((*r_bv)->selcount == 1) {
3592 if ((*r_bv)->selcount == 2) {
3596 new_edge = new_edge->
next;
3597 }
while (!new_edge->
is_bev);
3604 float dir_start_edge[3];
3605 if (start_edge->
e->
v1 == (*r_bv)->v) {
3615 float second_best_dot = 0.0f, best_dot = 0.0f;
3617 while (new_edge != start_edge) {
3619 new_edge = new_edge->
next;
3623 float dir_new_edge[3];
3624 if (new_edge->
e->
v2 == (*r_bv)->v) {
3633 float new_dot =
dot_v3v3(dir_new_edge, dir_start_edge);
3634 if (new_dot > best_dot) {
3635 second_best_dot = best_dot;
3637 next_edge = new_edge;
3639 else if (new_dot > second_best_dot) {
3640 second_best_dot = new_dot;
3643 new_edge = new_edge->
next;
3674 for (
int i = 0;
i < 2;
i++) {
3675 EdgeHalf *edgehalf = start_edgehalf;
3677 bool toward_bv = (
i == 0);
3694 toward_bv = !toward_bv;
3714 printf(
"\nadjust the %s (with eigen)\n", iscycle ?
"cycle" :
"chain");
3725 }
while (
v &&
v != vstart);
3727 printf(
" -> %d parms\n", np);
3730#ifdef FAST_ADJUST_CODE
3731 if (adjust_the_cycle_or_chain_fast(vstart, np, iscycle)) {
3736 int nrows = iscycle ? 3 * np : 3 * np - 3;
3744 EdgeHalf *eleft, *eright, *enextleft;
3747 if (iscycle ||
i < np - 1) {
3750 enextleft =
v->adjchain->elast;
3753 if (iscycle ||
v != vstart) {
3754 printf(
" dependent: e%d->offset_l = %f * p%d\n",
3775 int row = iscycle ? np + 2 *
i : np - 1 + 2 *
i;
3779 printf(
"b[%d]=%f * %f, for e%d->offset_r\n",
3790 solver, row, (
i == np - 1) ? 0 :
i + 1, weight *
v->adjchain->sinratio);
3793 printf(
"b[%d]=%f * %f, for e%d->offset_l\n",
3811 }
while (
v &&
v != vstart);
3817 for (
i = 0;
i < np;
i++) {
3827 if (iscycle ||
i < np - 1) {
3834 if (iscycle ||
v != vstart) {
3851 }
while (
v &&
v != vstart);
3854 print_adjust_stats(vstart);
3905 v = vchainstart = vchainend = vanchor;
3907 bool iscycle =
false;
3909 while (
v->eon && !
v->visited && !iscycle) {
3920 v->adjchain = vnext;
3924 if (vnext != vchainstart) {
3934 v->adjchain =
nullptr;
3949 vchainstart = vnext;
3951 }
while (!
v->visited &&
v->eon);
3952 if (chainlen >= 3 && !vchainstart->
eon && !vchainend->
eon) {
3989 float dir1[3], dir3[3];
4048 BLI_assert(0 <=
i &&
i <= n && 0 <= j && j <= ns && 0 <= k && k <= ns);
4050 if (!odd && j == ns2 && k == ns2) {
4053 if (j <= ns2 - 1 + odd && k <= ns2) {
4057 return mesh_vert(vm, (
i + n - 1) % n, k, ns - j);
4059 return mesh_vert(vm, (
i + 1) % n, ns - k, j);
4064 int ns2 = vm->
seg / 2;
4065 if (vm->
seg % 2 == 1) {
4066 return (j <= ns2 && k <= ns2);
4069 return ((j < ns2 && k <= ns2) || (j == ns2 && k == ns2 &&
i == 0));
4078 for (
int i = 0;
i < n;
i++) {
4079 for (
int j = 0; j <= ns2; j++) {
4080 for (
int k = 0; k <= ns; k++) {
4097 int ns2 = vm->
seg / 2;
4100 for (
int i = 0;
i < n;
i++) {
4127 return 0.065247584f;
4133 return 0.401983447f;
4136 return 0.523423277f;
4138 double k =
cos(
M_PI /
double(n));
4142 double k4 = k2 * k2;
4143 double k6 = k4 * k2;
4144 double y =
pow(
M_SQRT3 *
sqrt(64.0 * k6 - 144.0 * k4 + 135.0 * k2 - 27.0) + 9.0 * k, 1.0 / 3.0);
4145 double x = 0.480749856769136 *
y - (0.231120424783545 * (12.0 * k2 - 9.0)) /
y;
4146 return (k *
x + 2.0 * k2 - 1.0) / (
x *
x * (k *
x + 1.0));
4157 for (
int k = 0; k < ns; k++) {
4159 frac[k + 1] = total;
4162 for (
int k = 1; k <= ns; k++) {
4174 float co[3], nextco[3];
4179 for (
int k = 0; k < ns; k++) {
4182 frac[k + 1] = total;
4186 for (
int k = 1; k <= ns; k++) {
4200 for (
int i = 0;
i < n;
i++) {
4201 if (f <=
frac[
i + 1]) {
4202 float rest = f -
frac[
i];
4209 if (
i == n - 1 && *r_rest == 1.0f) {
4226 int n_bndv = vm_in->
count;
4227 int ns_in = vm_in->
seg;
4228 int nseg2 = nseg / 2;
4240 for (
int i = 0;
i < n_bndv;
i++) {
4243 for (
int j = 0; j <= nseg2 - 1 + odd; j++) {
4244 for (
int k = 0; k <= nseg2; k++) {
4246 float fraction = new_frac[k];
4250 fraction = prev_new_frac[nseg - j];
4251 int k_in_prev =
interp_range(prev_frac, ns_in, fraction, &restkprev);
4252 int j_in = ns_in - k_in_prev;
4253 float restj = -restkprev;
4259 restj = 1.0f + restj;
4267 int j0inc = (restj <
BEVEL_EPSILON || j_in == ns_in) ? 0 : 1;
4268 int k0inc = (restk <
BEVEL_EPSILON || k_in == ns_in) ? 0 : 1;
4280 memcpy(prev_frac,
frac,
sizeof(
float) * (ns_in + 1));
4281 memcpy(prev_new_frac, new_frac,
sizeof(
float) * (nseg + 1));
4300 int n_boundary = vm_in->
count;
4301 int ns_in = vm_in->
seg;
4302 int ns_in2 = ns_in / 2;
4304 int ns_out = 2 * ns_in;
4308 for (
int i = 0;
i < n_boundary;
i++) {
4310 for (
int k = 1; k < ns_in; k++) {
4315 float co1[3], co2[3], acc[3];
4329 for (
int i = 0;
i < n_boundary;
i++) {
4330 for (
int k = 1; k < ns_out; k += 2) {
4335 float co1[3], co2[3], acc[3];
4351 for (
int i = 0;
i < n_boundary;
i++) {
4352 for (
int k = 0; k < ns_in; k++) {
4363 for (
int i = 0;
i < n_boundary;
i++) {
4364 for (
int j = 0; j < ns_in2; j++) {
4365 for (
int k = 0; k < ns_in2; k++) {
4378 for (
int i = 0;
i < n_boundary;
i++) {
4379 for (
int j = 0; j < ns_in2; j++) {
4380 for (
int k = 1; k <= ns_in2; k++) {
4393 for (
int i = 0;
i < n_boundary;
i++) {
4394 for (
int j = 1; j < ns_in2; j++) {
4395 for (
int k = 0; k < ns_in2; k++) {
4408 float gamma = 0.25f;
4409 float beta = -gamma;
4410 for (
int i = 0;
i < n_boundary;
i++) {
4411 for (
int j = 1; j < ns_in2; j++) {
4412 for (
int k = 1; k <= ns_in2; k++) {
4413 float co1[3], co2[3];
4441 float co1[3], co2[3];
4444 for (
int i = 0;
i < n_boundary;
i++) {
4450 mul_v3_fl(co, 1.0f /
float(n_boundary));
4453 for (
int i = 0;
i < n_boundary;
i++) {
4459 for (
int i = 0;
i < n_boundary;
i++) {
4460 int inext = (
i + 1) % n_boundary;
4461 for (
int k = 0; k <= ns_out; k++) {
4464 if (k >= ns_in && k < ns_out) {
4480 for (
int i = 0;
i < 3;
i++) {
4481 float co[3] = {0.0f, 0.0f, 0.0f};
4485 for (
int i = 0;
i < 3;
i++) {
4486 for (
int j = 0; j <= ns2; j++) {
4487 for (
int k = 0; k <= ns2; k++) {
4493 co[(
i + 1) % 3] =
float(k) * 2.0f /
float(nseg);
4494 co[(
i + 2) % 3] =
float(j) * 2.0f /
float(nseg);
4515 for (
int i = 0;
i < 3;
i++) {
4516 float co[3] = {0.0f, 0.0f, 0.0f};
4528 for (
int i = 0;
i < 3;
i++) {
4529 for (
int k = 0; k <= ns2; k++) {
4532 co[(
i + 1) % 3] = 0.0f;
4533 co[(
i + 2) % 3] = 0.0f;
4535 co[(
i + 1) % 3] = 1.0f -
float(k) *
b;
4536 co[(
i + 2) % 3] = 0.0f;
4568 for (
int i = 0;
i < 3;
i++) {
4569 float co[3] = {0.0f, 0.0f, 0.0f};
4574 for (
int i = 0;
i < 3;
i++) {
4578 coc[(
i + 1) % 3] = 1.0f;
4579 coc[(
i + 2) % 3] = 0.0f;
4604 else if (r < 0.75f) {
4613 while (vm1->
seg < nseg) {
4616 if (vm1->
seg != nseg) {
4622 for (
int i = 0;
i < 3;
i++) {
4623 for (
int j = 0; j <= ns2; j++) {
4624 for (
int k = 0; k <= nseg; k++) {
4649 float totang = 0.0f;
4653 float absang =
fabsf(ang);
4657 else if (absang >= 3.0f *
float(
M_PI_4)) {
4672 (angdiff >
float(
M_PI_4)))
4686 float co0[3], co1[3], co2[3];
4698 for (
int i = 0;
i < 3;
i++) {
4699 for (
int j = 0; j <= ns2; j++) {
4700 for (
int k = 0; k <= ns; k++) {
4731 float boundverts_center[3] = {0.0f, 0.0f, 0.0f};
4732 for (
int i = 0;
i < n_bndv;
i++) {
4739 mul_v3_fl(boundverts_center, 1.0f /
float(n_bndv));
4745 float original_vertex[3], negative_fullest[3];
4747 sub_v3_v3v3(negative_fullest, boundverts_center, original_vertex);
4748 add_v3_v3(negative_fullest, boundverts_center);
4752 float center_direction[3];
4753 sub_v3_v3v3(center_direction, original_vertex, boundverts_center);
4772 }
while (vm1->
seg < nseg);
4773 if (vm1->
seg != nseg) {
4796 float edir[3], plane[4];
4800 float start_plane[3], end_plane[3], middle_plane[3];
4805 float m[4][4], minv[4][4];
4837 int half_ns = ns / 2;
4838 int ipipe1 = vpipe->
index;
4841 for (
int i = 0;
i < n_bndv;
i++) {
4842 for (
int j = 1; j <= half_ns; j++) {
4843 for (
int k = 0; k <= half_ns; k++) {
4850 float *profile_point_pipe1, *profile_point_pipe2, f;
4851 if (
ELEM(
i, ipipe1, ipipe2)) {
4852 if (n_bndv == 3 &&
i == ipipe1) {
4858 f = ((k < j) ?
min_ff(j, k) : ((2.0f * ring) - j)) / (2.0f * ring);
4863 profile_point_pipe2 =
mesh_vert(vm, (
i == ipipe1) ? ipipe2 : ipipe1, 0, ns - k)->
co;
4880 bool even = (ns % 2) == 0;
4881 bool midline = even && k == half_ns &&
4882 ((
i == 0 && j == half_ns) ||
ELEM(
i, ipipe1, ipipe2));
4902 if (
e->v1 ==
v ||
e->v2 ==
v) {
4903 if (*r_e1 ==
nullptr) {
4906 else if (*r_e2 ==
nullptr) {
4948 r_internal[n_internal++] =
v;
4949 if (n_internal == 3) {
4954 for (
int i = n_internal;
i < 3;
i++) {
4955 r_internal[
i] =
nullptr;
4973 float axis_mat[3][3];
4983 float *co =
v->nv.v->co;
4984 if (
ELEM(
v, unsnapped[0], unsnapped[1], unsnapped[2])) {
4988 float snap1[3], snap2[3];
4993 if (d1_sq <= d2_sq) {
5037 BMFace *any_bmf =
nullptr;
5038 bool consider_all_faces = bv->
selcount == 1;
5049 BMFace *ftwo[2] = {bmf1, bmf2};
5051 if (bmf !=
nullptr) {
5052 if (any_bmf ==
nullptr) {
5055 bool already_there =
false;
5056 for (
int j = fcount - 1; j >= 0; j--) {
5057 if (fchoices[j] == bmf) {
5058 already_there =
true;
5062 if (!already_there) {
5068 fchoices[fcount++] = bmf;
5085 int ns2 = vm->
seg / 2;
5087 BMEdge *frep_e1, *frep_e2;
5096 frep_e1 = frep_e2 =
nullptr;
5104 if (
ELEM(
v, frep_unsnapped[0], frep_unsnapped[1], frep_unsnapped[2])) {
5118 bp,
bm, vv.
data(), vv.
size(), vf.
data(), frep, ve.
data(), bv->
v,
nullptr, mat_nr,
true);
5136 for (
int i = 0;
i < n;
i++) {
5137 for (
int k = 1; k < ns; k++) {
5139 if (
i > 0 && k <= ns2) {
5142 else if (
i == n - 1 && k > ns2) {
5151 for (
int i = 0;
i < n;
i++) {
5189 float ns2inv = 1.0f /
float(ns2);
5191 int clstride = 3 * (ns2 + 1);
5198 for (
int i = 0;
i < n_bndv;
i++) {
5228 float dir1[3], dir2[3], co1[3], co2[3];
5234 float meet1[3], meet2[3];
5259 float *on_edge_cur = centerline + clstride *
i;
5260 int iprev = (
i == 0) ? n_bndv - 1 :
i - 1;
5261 float *on_edge_prev = centerline + clstride * iprev;
5285 for (
int i = 0;
i < n_bndv;
i++) {
5287 float *on_edge_cur = centerline + clstride *
i;
5289 float co1[3], co2[3];
5294 float meet1[3], meet2[3];
5320 float co1[3], co2[3];
5323 for (
int i = 0;
i < n_bndv;
i++) {
5332 finalfrac = 0.5f /
sinf(ang);
5333 finalfrac = std::min(finalfrac, 0.8f);
5338 ns2inv = 1.0f / (ns2 + finalfrac);
5341 float *p = centerline + clstride *
i;
5344 for (
int j = 1; j <= ns2; j++) {
5353 for (
int i = 0;
i < n_bndv;
i++) {
5355 copy_v3_v3(co2, centerline + clstride * (
i == 0 ? n_bndv - 1 :
i - 1));
5356 for (
int j = 0; j < ns2 + odd; j++) {
5360 for (
int k = 1; k <= ns2; k++) {
5372 for (
int i = 0;
i < n_bndv;
i++) {
5373 int im1 = (
i == 0) ? n_bndv - 1 :
i - 1;
5374 for (
int j = 1; j < ns2 + odd; j++) {
5375 for (
int k = 1; k <= ns2; k++) {
5376 float meet1[3], meet2[3];
5378 centerline + clstride * im1 + 3 * k,
5380 centerline + clstride *
i + 3 * j,
5387 centerline + clstride * im1 + 3 * k,
5390 else if (ikind == 1) {
5414 const bool *frep_beats_next)
5416 int previ = (
i + n_bndv - 1) % n_bndv;
5417 int nexti = (
i + 1) % n_bndv;
5419 if (frep_beats_next[previ] && bndv_rep_faces[previ] == center_frep) {
5422 if (!frep_beats_next[
i] && bndv_rep_faces[nexti] == center_frep) {
5464 const bool *frep_beats_next,
5467 BLI_assert(0 <=
i &&
i < n_bndv && 0 <= j && j < ns2 && 0 <= k && k <= ns2);
5468 for (
int corner = 0; corner < 4; corner++) {
5469 r_snap_edges[corner] =
nullptr;
5473 int previ = (
i + n_bndv - 1) % n_bndv;
5475 int jj = corner < 2 ? j : j + 1;
5476 int kk =
ELEM(corner, 0, 3) ? k : k + 1;
5477 if (jj < ns2 && kk < ns2) {
5480 else if (jj < ns2 && kk == ns2) {
5482 if (!frep_beats_next[
i]) {
5483 r_snap_edges[corner] = enext;
5486 else if (jj < ns2 && kk == ns2 + 1) {
5488 if (frep_beats_next[
i]) {
5489 r_snap_edges[corner] = enext;
5492 else if (jj == ns2 && kk < ns2) {
5494 if (frep_beats_next[previ]) {
5495 r_snap_edges[corner] = eprev;
5498 else if (jj == ns2 && kk == ns2) {
5501 i, n_bndv, eprev, enext, bndv_rep_faces, center_frep, frep_beats_next);
5503 else if (jj == ns2 && kk == ns2 + 1) {
5505 int nexti = (
i + 1) % n_bndv;
5507 nexti, n_bndv, enext, enextnext, bndv_rep_faces, center_frep, frep_beats_next);
5551 for (
int i = 0;
i < n_bndv;
i++) {
5552 for (
int j = 0; j <= ns2; j++) {
5553 for (
int k = 0; k <= ns; k++) {
5554 if (j == 0 &&
ELEM(k, 0, ns)) {
5576 BMVert **center_verts =
nullptr;
5577 BMEdge **center_edge_snaps =
nullptr;
5578 BMFace **center_face_interps =
nullptr;
5579 bool *frep_beats_next =
nullptr;
5580 BMFace *center_frep =
nullptr;
5587 for (
int i = 0;
i < n_bndv;
i++) {
5588 center_edge_snaps[
i] =
nullptr;
5590 int inext = (
i + 1) % n_bndv;
5591 BMFace *fchoices[2] = {bndv_rep_faces[
i], bndv_rep_faces[inext]};
5593 frep_beats_next[
i] = fwinner == bndv_rep_faces[
i];
5601 BMFace *f = bndv_rep_faces[
i];
5602 BMFace *f2 = bndv_rep_faces[inext];
5605 fc = frep_beats_next[
i] ? f : f2;
5620 BMEdge *bmeprev = eprev ? eprev->
e :
nullptr;
5621 BMEdge *bmenext = enext ? enext->
e :
nullptr;
5629 for (
int j = 0; j < ns2; j++) {
5630 for (
int k = 0; k < ns2 + odd; k++) {
5636 BMVert *bmvs[4] = {bmv1, bmv2, bmv3, bmv4};
5646 BMEdge *se[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
5648 fr[0] = fr[1] = fr[2] = fr[3] = f2;
5650 if (k == ns2 && j == ns2 - 1) {
5657 se[0] = se[2] = bme;
5664 fr[0] = fr[1] = fr[2] = fr[3] = f;
5667 BMEdge *b2 = (
e &&
e->is_seam) ? bme :
nullptr;
5683 if (!
e ||
e->is_seam) {
5684 fr[0] = fr[1] = fr[2] = fr[3] = fc;
5692 center_verts[
i] = bmvs[3];
5693 center_edge_snaps[
i] = se[3];
5694 center_face_interps[
i] = bv->
any_seam ? center_frep : f;
5702 if (j == ns2 - 1 && bndv->
prev->
ebev) {
5705 se[2] = se[1] !=
nullptr ? se[1] : se[3];
5709 bp,
bm, bmvs, 4, fr,
nullptr, se, bv->
v,
nullptr, mat_nr,
true);
5726 center_face_interps,
5754#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5755 printf(
"BEVEL BUILD CUTOFF\n");
5756# define F3(v) (v)[0], (v)[1], (v)[2]
5767 float down_direction[3];
5786#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5787 printf(
"Corner vertices:\n");
5788 for (
int j = 0; j < n_bndv; j++) {
5794 bool build_center_face =
true;
5803#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5804 printf(
"build_center_face: %d\n", build_center_face);
5808 if (build_center_face) {
5820 for (
int i = 1;
i < n_bndv;
i++) {
5828#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5829 printf(
"Building profile cutoff faces.\n");
5840#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5841 printf(
"Profile Number %d:\n",
i);
5843 printf(
" Miter profile\n");
5849 for (
int k = 0; k < bp->
seg + 1; k++) {
5851#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5857 if (build_center_face) {
5859#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5869 bp->
seg + 2 + build_center_face,
5880 if (build_center_face) {
5882 for (
int i = 0;
i < n_bndv;
i++) {
5888 bp,
bm, face_bmverts, n_bndv,
nullptr,
nullptr,
nullptr, bv->
v,
nullptr, bp->
mat_nr,
true);
5900 BMEdge *repface_e1, *repface_e2;
5909 repface_e1 = repface_e2 =
nullptr;
5919 if (
ELEM(bndv, unsnapped[0], unsnapped[1], unsnapped[2])) {
5933 for (
int k = 1; k < bndv->
ebev->
seg; k++) {
5939 bmedges.
append(k < bndv->ebev->seg / 2 ?
nullptr : frep_e);
5985 while (f->
len > 3) {
5992 if (f_new->
len > f->
len) {
5994 if (l_new->
v == v_fan) {
5997 else if (l_new->
next->
v == v_fan) {
5998 l_fan = l_new->
next;
6000 else if (l_new->
prev->
v == v_fan) {
6001 l_fan = l_new->
prev;
6008 if (l_fan->
v == v_fan) {
6010 else if (l_fan->
next->
v == v_fan) {
6011 l_fan = l_fan->
next;
6013 else if (l_fan->
prev->
v == v_fan) {
6014 l_fan = l_fan->
prev;
6052 for (
int k = 1; k < ns; k++) {
6059 for (
int k = 1; k < ns; k++) {
6067 for (
int k = 0; k < ns; k++) {
6091 sizeof(
NewVert) * n * (ns2 + 1) * (ns + 1));
6107 if (weld && bndv->
ebev) {
6133 for (
int k = 1; k < ns; k++) {
6142 else if (n == 2 && !bndv->
ebev) {
6154 for (
int k = 1; k < ns; k++) {
6177 for (
int k = 1; k < ns; k++) {
6216 if (
e->fprev &&
e->fnext) {
6224#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_ELEM_API_FLAG_ENABLE((bme), _FLAG_OVERLAP)
6225#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE((bme), _FLAG_OVERLAP)
6226#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_ELEM_API_FLAG_TEST((bme), _FLAG_OVERLAP)
6247 BMEdge *bme2 = (
l->v == bv->
v) ?
l->prev->e :
l->next->e;
6256 for (
int sucindex = 0; sucindex < nsucs; sucindex++) {
6257 BMEdge *nextbme = sucs[sucindex];
6261 bv->
edges[j + 1].
e = nextbme;
6269 for (
int k = j + 1; k <= bestj; k++) {
6274 for (
int k = j + 1; k <= tryj; k++) {
6276 bv->
edges[k].
e =
nullptr;
6283 for (
int k = j + 1; k <= bestj; k++) {
6284 BLI_assert(save_path[k - (j + 1)] !=
nullptr);
6285 bv->
edges[k].
e = save_path[k - (j + 1)];
6298#ifdef FASTER_FASTORDER
6307 for (
int j = 1; j < bv->
edgecount; j++) {
6309 BMEdge *bmenext =
nullptr;
6317 if (bmenext ==
nullptr) {
6322 if (nsucs == 0 || (nsucs == 2 && j != 1) || nsucs > 2 ||
6325 for (
int k = 1; k < j; k++) {
6327 bv->
edges[k].
e =
nullptr;
6331 bv->
edges[j].
e = bmenext;
6349 for (
int i = 1;
i < ntot;
i++) {
6351 int num_shared_face = 0;
6352 BMEdge *first_suc =
nullptr;
6365 if (first_suc ==
nullptr) {
6370 if (num_shared_face >= 3) {
6374 if (num_shared_face == 1 || (
i == 1 && num_shared_face == 2)) {
6376 e->e = bme = first_suc;
6380 for (
int k = 1; k <
i; k++) {
6382 bv->
edges[k].
e =
nullptr;
6410 first_bme =
nullptr;
6427 for (
int i = 0;
i < ntot;
i++) {
6433 if (
e->fnext !=
nullptr || e2->
fprev !=
nullptr) {
6444 if (
l->prev->e == bme2 ||
l->next->e == bme2) {
6445 if (!bestf ||
l->v == bv->
v) {
6450 e->fnext = e2->
fprev = bestf;
6470 BMEdge *first_bme =
nullptr;
6483 if (face_count == 1) {
6532 for (
int i = 0;
i < tot_edges;
i++) {
6543 e->is_rev = (bme->
v2 ==
v);
6544 e->leftv =
e->rightv =
nullptr;
6545 e->profile_index = 0;
6555 if (tot_edges > 1) {
6556 int ccw_test_sum = 0;
6557 for (
int i = 0;
i < tot_edges;
i++) {
6561 if (ccw_test_sum < 0) {
6562 for (
int i = 0;
i <= (tot_edges / 2) - 1;
i++) {
6567 if (tot_edges % 2 == 1) {
6568 int i = tot_edges / 2;
6575 float vert_axis[3] = {0, 0, 0};
6591 for (
int i = 0;
i < tot_edges;
i++,
e++) {
6602 for (
int i = 0;
i < tot_edges;
i++,
e++) {
6603 e->next = &bv->
edges[(
i + 1) % tot_edges];
6604 e->prev = &bv->
edges[(
i + tot_edges - 1) % tot_edges];
6613 e->offset_l_spec = bp->
offset;
6619 e->offset_l_spec = 0.01f * bp->
offset;
6629 e->offset_l_spec = 0.01f * bp->
offset;
6650 e->offset_l_spec = bp->
offset;
6651 e->offset_r_spec = bp->
offset;
6656 e->offset_l_spec = bp->
offset;
6661 e->offset_r_spec =
e->offset_l_spec;
6667 e->offset_l_spec *= weight;
6668 e->offset_r_spec *= weight;
6677 e->offset_l_spec = bv->
offset;
6685 e->offset_l_spec = 0.01f * bp->
offset;
6697 e->offset_l_spec = 0.01f * bp->
offset;
6709 e->offset_l_spec = bv->
offset;
6713 e->offset_r_spec =
e->offset_l_spec;
6716 e->offset_l_spec =
e->offset_r_spec = 0.0f;
6718 e->offset_l =
e->offset_l_spec;
6719 e->offset_r =
e->offset_r_spec;
6721 if (
e->fprev &&
e->fnext) {
6730 if (tot_wire != 0) {
6747 bool do_rebuild =
false;
6767 if (
e->prev == eprev) {
6768 if (eprev->
prev ==
e) {
6770 go_ccw = (
e->fnext != f);
6776 else if (eprev->
prev ==
e) {
6791 bool on_profile_start =
false;
6797 if (
e->profile_index > 0) {
6798 vstart = vstart->
prev;
6799 on_profile_start =
true;
6803 vstart = eprev->
leftv;
6806 vstart = vstart->
next;
6807 on_profile_start =
true;
6810 BLI_assert(vstart !=
nullptr && vend !=
nullptr);
6812 if (!on_profile_start) {
6815 nv_bv_map.
add(
v->nv.v,
l->v);
6821 if (on_profile_start) {
6822 kstart =
e->profile_index;
6823 on_profile_start =
false;
6834 for (
int k = kstart; k <= kend; k++) {
6839 nv_bv_map.
add(bmv,
l->v);
6846 int i =
v->prev->index;
6848 if (on_profile_start) {
6850 on_profile_start =
false;
6853 kstart = vm->
seg - 1;
6855 if (
e->rightv ==
v->prev &&
e->profile_index > 0) {
6856 kend =
e->profile_index;
6861 for (
int k = kstart; k >= kend; k--) {
6866 nv_bv_map.
add(bmv,
l->v);
6877 nv_bv_map.
add(
l->v,
l->v);
6883 bp,
bm, vv.
data(), n,
nullptr, f,
nullptr,
nullptr, &nv_bv_map, -1,
true);
6887 BMEdge *bme_prev = ee[n - 1];
6888 for (
int k = 0; k < n; k++) {
6891 if (ee[k] != bme_new) {
6895 if (k < n - 1 && ee[k] == ee[k + 1]) {
6952 if (!rebuilt_orig_faces.
contains(f)) {
6954 rebuilt_orig_faces.
add(f);
6971 BMVert *vclosest =
nullptr;
6973 BMVert *votherclosest =
nullptr;
6978 if (!bvother || !bvother->
vmesh) {
6989 vclosest = bndv->
nv.
v;
6990 votherclosest = bndvother->
nv.
v;
6998 vclosest = bndv->
nv.
v;
6999 votherclosest = vother;
7042 BMEdge *bme_prev =
nullptr;
7043 BMEdge *bme_next =
nullptr;
7044 for (
int i = 0;
i < 4;
i++) {
7046 bme_prev = bv->
edges[(
i + 3) % 4].
e;
7047 bme_next = bv->
edges[(
i + 1) % 4].
e;
7060 for (
int i = 0;
i < nseg;
i++) {
7068 if (enable_smooth) {
7134 BMFace *fchoices[2] = {f1, f2};
7135 BMFace *f_choice =
nullptr;
7136 int center_adj_k = -1;
7140 center_adj_k = f_choice == f1 ? mid + 2 : mid;
7143 for (
int k = 1; k <= nseg; k++) {
7149 if (odd && k == mid + 1) {
7155 if (f_choice == f1) {
7156 edges[0] = edges[1] =
nullptr;
7157 edges[2] = edges[3] = bme;
7160 edges[0] = edges[1] = bme;
7161 edges[2] = edges[3] =
nullptr;
7164 bp,
bm,
verts, 4,
nullptr, f_choice, edges,
nullptr, &nv_bv_map, mat_nr,
true);
7169 bp,
bm,
verts, 4,
faces, f_choice,
nullptr,
nullptr, &nv_bv_map, mat_nr,
true);
7172 else if (odd && k == center_adj_k && e1->
is_seam) {
7180 edges[0] = edges[1] =
nullptr;
7181 edges[2] = edges[3] = bme;
7185 edges[0] = edges[1] = bme;
7186 edges[2] = edges[3] =
nullptr;
7190 bp,
bm,
verts, 4,
nullptr, f_interp, edges,
nullptr, &nv_bv_map, mat_nr,
true);
7192 else if (!odd && k == mid) {
7194 BMEdge *edges[4] = {
nullptr,
nullptr, bme, bme};
7196 bp,
bm,
verts, 4,
nullptr, f1, edges,
nullptr, &nv_bv_map, mat_nr,
true);
7198 else if (!odd && k == mid + 1) {
7200 BMEdge *edges[4] = {bme, bme,
nullptr,
nullptr};
7202 bp,
bm,
verts, 4,
nullptr, f2, edges,
nullptr, &nv_bv_map, mat_nr,
true);
7206 BMFace *f = (k <= mid) ? f1 : f2;
7208 bp,
bm,
verts, 4,
nullptr, f,
nullptr,
nullptr, &nv_bv_map, mat_nr,
true);
7246 const double tol = 1
e-13;
7247 const int maxiter = 10;
7250 double xmin = x0 +
M_SQRT2 / 2.0 * dtarget;
7251 xmin = std::min(xmin, 1.0);
7252 double xmax = x0 + dtarget;
7253 xmax = std::min(xmax, 1.0);
7258 double dmaxerr =
sqrt(
pow((xmax - x0), 2) +
pow((ymax - y0), 2)) - dtarget;
7259 double dminerr =
sqrt(
pow((xmin - x0), 2) +
pow((ymin - y0), 2)) - dtarget;
7261 double xnew = xmax - dmaxerr * (xmax - xmin) / (dmaxerr - dminerr);
7262 bool lastupdated_upper =
true;
7264 for (
int iter = 0; iter < maxiter; iter++) {
7266 double dnewerr =
sqrt(
pow((xnew - x0), 2) +
pow((ynew - y0), 2)) - dtarget;
7267 if (
fabs(dnewerr) < tol) {
7274 if (!lastupdated_upper) {
7275 xnew = (dmaxerr / 2 * xmin - dminerr * xmax) / (dmaxerr / 2 - dminerr);
7278 xnew = xmax - dmaxerr * (xmax - xmin) / (dmaxerr - dminerr);
7280 lastupdated_upper =
false;
7286 if (lastupdated_upper) {
7287 xnew = (dmaxerr * xmin - dminerr / 2 * xmax) / (dmaxerr - dminerr / 2);
7290 xnew = xmax - dmaxerr * (xmax - xmin) / (dmaxerr - dminerr);
7292 lastupdated_upper =
true;
7309 const int smoothitermax = 10;
7310 const double error_tol = 1
e-7;
7311 int imax = (seg + 1) / 2 - 1;
7313 bool seg_odd = seg % 2;
7319 mx =
pow(0.5, 1.0 / r);
7323 mx = 1 -
pow(0.5, 1.0 / r);
7327 for (
int i = 0;
i <= imax;
i++) {
7328 xvals[
i] =
i * mx / seg * 2;
7334 for (
int iter = 0; iter < smoothitermax; iter++) {
7341 for (
int i = 0;
i < imax;
i++) {
7342 double d =
sqrt(
pow((xvals[
i + 1] - xvals[
i]), 2) +
pow((yvals[
i + 1] - yvals[
i]), 2));
7344 dmax = std::max(d, dmax);
7345 dmin = std::min(d, dmin);
7350 sum +=
M_SQRT2 / 2 * (yvals[imax] - xvals[imax]);
7351 davg =
sum / (imax + 0.5);
7354 sum +=
sqrt(
pow((xvals[imax] - mx), 2) +
pow((yvals[imax] - mx), 2));
7355 davg =
sum / (imax + 1.0);
7358 bool precision_reached =
true;
7359 if (dmax - davg > error_tol) {
7360 precision_reached =
false;
7362 if (dmin - davg < error_tol) {
7363 precision_reached =
false;
7365 if (precision_reached) {
7370 for (
int i = 1;
i <= imax;
i++) {
7378 xvals[imax + 1] = mx;
7379 yvals[imax + 1] = mx;
7381 for (
int i = imax + 1;
i <= seg;
i++) {
7382 yvals[
i] = xvals[seg -
i];
7383 xvals[
i] = yvals[seg -
i];
7387 for (
int i = 0;
i <= seg;
i++) {
7388 double temp = xvals[
i];
7389 xvals[
i] = 1.0 - yvals[
i];
7390 yvals[
i] = 1.0 - temp;
7405 bool seg_odd = n % 2;
7411 for (
int i = 0;
i <= n;
i++) {
7412 xvals[
i] = double(
i) / n;
7413 yvals[
i] = 1.0 - double(
i) / n;
7418 double temp =
M_PI_2 / n;
7420 for (
int i = 0;
i <= n;
i++) {
7421 xvals[
i] =
sin(
i * temp);
7422 yvals[
i] =
cos(
i * temp);
7429 for (
int i = 0;
i <= n2;
i++) {
7431 yvals[
i] = 1.0 - double(
i) / n2;
7432 xvals[n -
i] = yvals[
i];
7433 yvals[n -
i] = xvals[
i];
7438 double temp = 1.0 / (n2 +
M_SQRT2 / 2.0);
7439 for (
int i = 0;
i <= n2;
i++) {
7441 yvals[
i] = 1.0 - double(
i) * temp;
7442 xvals[n -
i] = yvals[
i];
7443 yvals[n -
i] = xvals[
i];
7451 for (
int i = 0;
i <= n2;
i++) {
7452 xvals[
i] = double(
i) / n2;
7454 xvals[n -
i] = yvals[
i];
7455 yvals[n -
i] = xvals[
i];
7460 double temp = 1.0 / (n2 +
M_SQRT2 / 2);
7461 for (
int i = 0;
i <= n2;
i++) {
7462 xvals[
i] = double(
i) * temp;
7464 xvals[n -
i] = yvals[
i];
7465 yvals[n -
i] = xvals[
i];
7484#define CIRCLE_FULLNESS_SEGS 11
7503 for (
int i = 0;
i < nseg;
i++) {
7514 fullness = circle_fullness[nseg - 1];
7518 if (nseg % 2 == 0) {
7519 fullness = 2.4506f * bp->
profile - 0.00000300f * nseg - 0.6266f;
7522 fullness = 2.3635f * bp->
profile + 0.000152f * nseg - 0.6060f;
7546 pro_spacing->
xvals =
nullptr;
7547 pro_spacing->
yvals =
nullptr;
7548 pro_spacing->
xvals_2 =
nullptr;
7549 pro_spacing->
yvals_2 =
nullptr;
7550 pro_spacing->
seg_2 = 0;
7564 sizeof(
double) * (seg_2 + 1));
7566 sizeof(
double) * (seg_2 + 1));
7572 for (
int i = 0;
i < seg_2 + 1;
i++) {
7593 for (
int i = 0;
i < seg + 1;
i++) {
7628 float no_collide_offset = bp->
offset + 1e6;
7629 float limit = no_collide_offset;
7630 if (bp->
offset == 0.0f) {
7631 return no_collide_offset;
7658 return bp->
offset > blen / 2.0f ? blen / 2.0f : blen;
7660 return no_collide_offset;
7662 if (ebother !=
nullptr) {
7673 if (eb->
fnext ==
nullptr) {
7674 return no_collide_offset;
7678 return no_collide_offset;
7680 if (lb->
next->
v == vc) {
7683 else if (lb->
v == vc) {
7687 return no_collide_offset;
7690 if (ea->
e == eb->
e || (ec && ec->
e == eb->
e)) {
7691 return no_collide_offset;
7698 float sin1 =
sinf(th1);
7699 float sin2 =
sinf(th2);
7700 float cos1 =
cosf(th1);
7701 float cos2 =
cosf(th2);
7706 float offsets_projected_on_B =
safe_divide(ka + cos1 * kb, sin1) +
7709 offsets_projected_on_B = bp->
offset * (
len_v3v3(vb->
co, vc->
co) / offsets_projected_on_B);
7711 limit = offsets_projected_on_B;
7720 if (kb > FLT_EPSILON && (ka == 0.0f || kc == 0.0f)) {
7727 float A_side_slide = 0.0f;
7728 float exterior_angle = 0.0f;
7731 while (exterior_angle < 0.0001f) {
7743 limit = std::min(A_side_slide * kb, limit);
7751 float C_side_slide = 0.0f;
7752 float exterior_angle = 0.0f;
7754 while (exterior_angle < 0.0001f) {
7766 limit = std::min(C_side_slide * kb, limit);
7780 float no_collide_offset = bp->
offset + 1e6;
7781 if (bp->
offset == 0.0f) {
7782 return no_collide_offset;
7787 float kab = ka + kb;
7790 return no_collide_offset;
7802 float limited_offset = bp->
offset;
7817 limited_offset = std::min(collision_offset, limited_offset);
7821 limited_offset = std::min(collision_offset, limited_offset);
7826 if (limited_offset < bp->offset) {
7832 float offset_factor = limited_offset / bp->
offset;
7849 bp->
offset = limited_offset;
7855 const int offset_type,
7856 const int profile_type,
7858 const float profile,
7859 const bool affect_type,
7860 const bool use_weights,
7861 const bool limit_offset,
7863 const int vertex_group,
7865 const bool loop_slide,
7866 const bool mark_seam,
7867 const bool mark_sharp,
7868 const bool harden_normals,
7869 const int face_strength_mode,
7870 const int miter_outer,
7871 const int miter_inner,
7874 const int vmesh_method,
7875 const int bweight_offset_vert,
7876 const int bweight_offset_edge)
7918#ifdef BEVEL_DEBUG_TIME
7928 if (profile >= 0.950f) {
7972 if (!limit_offset && bv) {
8047 for (
BMFace *f : rebuilt_orig_faces) {
8070 if (
bm->use_toolflags) {
8099#ifdef BEVEL_DEBUG_TIME
8101 printf(
"BMESH BEVEL TIME = %.3f\n", end_time - start_time);
void BKE_curveprofile_init(struct CurveProfile *profile, short segments_len)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_n_offset(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool CustomData_layer_has_math(const CustomData *data, int layer_n)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
bool CustomData_data_equals(eCustomDataType type, const void *data1, const void *data2)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
#define STD_UV_CONNECT_LIMIT
#define BLI_array_alloca(arr, realsize)
#define BLI_assert_msg(a, msg)
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_ghash_flag_set(GHash *gh, unsigned int flag)
MINLINE float max_ff(float a, float b)
MINLINE int power_of_2_max_i(int n)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int is_power_of_2_i(int n)
#define BLI_ASSERT_UNIT_V3(v)
MINLINE int compare_ff(float a, float b, float max_diff)
MINLINE float safe_divide(float a, float b)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float r_i1[3], float r_i2[3])
float dist_squared_to_plane_v3(const float p[3], const float plane[4])
float closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
bool isect_line_plane_v3(float r_isect_co[3], const float l1[3], const float l2[3], const float plane_co[3], const float plane_no[3]) ATTR_WARN_UNUSED_RESULT
float area_poly_v2(const float verts[][2], unsigned int nr)
void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3])
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_m4_v4(const float mat[4][4], float r[4])
float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
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 copy_v2_v2(float r[2], const float a[2])
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_v2_v2(float r[2], const float a[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
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_v2v2(const float v1[2], const float v2[2], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
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 copy_v3_fl(float r[3], float f)
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_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT
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])
MINLINE float normalize_v3(float n[3])
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_use_calloc(MemArena *ma) ATTR_NONNULL(1)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define POINTER_AS_INT(i)
#define MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID
Read Guarded memory(de)allocation.
#define MEM_SIZE_OPTIMAL(size)
static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
static float find_profile_fullness(BevelParams *bp)
static double find_superellipse_chord_endpoint(double x0, double dtarget, float r, bool rbig)
static void vmesh_center(VMesh *vm, float r_cent[3])
static int find_face_internal_boundverts(const BevVert *bv, const BMFace *f, BoundVert *(r_internal[3]))
static bool make_unit_square_map(const float va[3], const float vmid[3], const float vb[3], float r_mat[4][4])
static BevVert * find_bevvert(BevelParams *bp, BMVert *bmv)
#define BM_BEVEL_EDGE_TAG_DISABLE(bme)
static void regularize_profile_orientation(BevelParams *bp, BMEdge *bme)
static NewVert * mesh_vert(VMesh *vm, int i, int j, int k)
static void get_incident_edges(BMFace *f, BMVert *v, BMEdge **r_e1, BMEdge **r_e2)
static int count_ccw_edges_between(EdgeHalf *e1, EdgeHalf *e2)
static void move_profile_plane(BoundVert *bndv, BMVert *bmvert)
static bool fast_bevel_edge_order(BevVert *bv)
static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert *vpipe)
static BMFace * bev_create_ngon(BevelParams *bp, BMesh *bm, BMVert **vert_arr, const int totv, BMFace **face_arr, BMFace *facerep, BMEdge **snap_edge_arr, BMVert *bv, Map< BMVert *, BMVert * > *nv_bv_map, int mat_nr, bool do_interp)
static void bevel_extend_edge_data_ex(BevVert *bv, int flag)
#define BEVEL_EPSILON_ANG
static void build_boundary_terminal_edge(BevelParams *bp, BevVert *bv, EdgeHalf *efirst, const bool construct)
static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int nseg, float r_co[3])
#define BEVEL_SMALL_ANG_DOT
static BMFace * choose_rep_face(BevelParams *bp, BMFace **face, int nfaces)
static FKind get_face_kind(BevelParams *bp, BMFace *f)
static EdgeHalf * next_bev(BevVert *bv, EdgeHalf *from_e)
static UVFace * register_uv_face(BevelParams *bp, BMFace *fnew, BMFace *frep, BMFace **frep_arr)
static VMesh * interp_vmesh(BevelParams *bp, VMesh *vm_in, int nseg)
static void disable_flag_out_edge(BMesh *bm, BMEdge *bme)
static bool point_between_edges(const float co[3], BMVert *v, BMFace *f, EdgeHalf *e1, EdgeHalf *e2)
BLI_INLINE void adjust_bound_vert(BoundVert *bv, const float co[3])
static void swap_face_components(int *face_component, int totface, int c1, int c2)
static void snap_edges_for_vmesh_vert(int i, int j, int k, int ns, int ns2, int n_bndv, BMEdge *eprev, BMEdge *enext, BMEdge *enextnext, BMFace **bndv_rep_faces, BMFace *center_frep, const bool *frep_beats_next, BMEdge *r_snap_edges[4])
static void adjust_miter_inner_coords(BevelParams *bp, BevVert *bv, EdgeHalf *emiter)
static void offset_meet_lines_percent_or_absolute(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, BMVert *v, float r_l1a[3], float r_l1b[3], float r_l2a[3], float r_l2b[3])
#define BM_BEVEL_EDGE_TAG_TEST(bme)
static float sabin_gamma(int n)
static void weld_cross_attrs_copy(BMesh *bm, BevVert *bv, VMesh *vm, int vmindex, EdgeHalf *e)
static void bevel_set_weighted_normal_face_strength(BMesh *bm, BevelParams *bp)
static void flag_out_vert(BMesh *bm, BMVert *bmv)
static void flag_out_edge(BMesh *bm, BMEdge *bme)
#define BEVEL_EPSILON_ANG_DOT
static VMesh * make_cube_corner_adj_vmesh(BevelParams *bp)
static void record_face_kind(BevelParams *bp, BMFace *f, FKind fkind)
static int tri_corner_test(BevelParams *bp, BevVert *bv)
static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
static bool good_offset_on_edge_between(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v)
static bool bevvert_is_weld_cross(BevVert *bv)
static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
static void bevel_limit_offset(BevelParams *bp, BMesh *bm)
static VMesh * square_out_adj_vmesh(BevelParams *bp, BevVert *bv)
static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag)
static EdgeHalf * find_other_end_edge_half(BevelParams *bp, EdgeHalf *e, BevVert **r_bvother)
static void calculate_vm_profiles(BevelParams *bp, BevVert *bv, VMesh *vm)
static AngleKind edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v)
static void build_boundary_vertex_only(BevelParams *bp, BevVert *bv, bool construct)
static BMFace * frep_for_center_poly(BevelParams *bp, BevVert *bv)
static void offset_in_plane(EdgeHalf *e, const float plane_no[3], bool left, float r_co[3])
static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
static BMFace * bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv)
static void bevel_merge_uvs(BevelParams *bp, BMesh *bm)
static void closer_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float v[3])
static VMesh * make_cube_corner_square(MemArena *mem_arena, int nseg)
static BMEdge * snap_edge_for_center_vmesh_vert(int i, int n_bndv, BMEdge *eprev, BMEdge *enext, BMFace **bndv_rep_faces, BMFace *center_frep, const bool *frep_beats_next)
#define BM_BEVEL_EDGE_TAG_ENABLE(bme)
static void set_bound_vert_seams(BevVert *bv, bool mark_seam, bool mark_sharp)
static void move_weld_profile_planes(BevVert *bv, BoundVert *bndv1, BoundVert *bndv2)
#define HASNOT_SEAMSHARP(eh, flag)
static bool edge_edge_angle_less_than_180(const BMEdge *e1, const BMEdge *e2, const BMFace *f)
static void determine_uv_vert_connectivity(BevelParams *bp, BMesh *bm, BMVert *v)
static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg)
static void calculate_profile_segments(const Profile *profile, const float map[4][4], const bool use_map, const bool reversed, const int ns, const double *xvals, const double *yvals, float *r_prof_co)
static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv)
static void vmesh_copy_equiv_verts(VMesh *vm)
static VMesh * make_cube_corner_square_in(MemArena *mem_arena, int nseg)
static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v, Set< BMFace * > &rebuilt_orig_faces)
static bool offset_meet_edge(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, float meetco[3], float *r_angle)
static UVFace * find_uv_face(BevelParams *bp, BMFace *bmf)
static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_nr)
static EdgeHalf * find_edge_half(BevVert *bv, BMEdge *bme)
static bool edges_face_connected_at_vert(BMEdge *bme1, BMEdge *bme2)
static void make_unit_cube_map(const float va[3], const float vb[3], const float vc[3], const float vd[3], float r_mat[4][4])
static void adjust_offsets(BevelParams *bp, BMesh *bm)
static void offset_meet(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool edges_between, float meetco[3], const EdgeHalf *e_in_plane)
static bool offset_on_edge_between(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v, float meetco[3], float *r_sinratio)
static void bevel_edges_sharp_boundary(BMesh *bm, BevelParams *bp)
static void fill_profile_fracs(BevelParams *bp, BoundVert *bndv, float *frac, int ns)
static bool nearly_parallel(const float d1[3], const float d2[3])
static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh *vm1)
static bool is_canon(VMesh *vm, int i, int j, int k)
static bool is_outside_edge(EdgeHalf *e, const float co[3], BMVert **ret_closer_v)
static void find_even_superellipse_chords(int n, float r, double *xvals, double *yvals)
static VMesh * pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
static BevVert * bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
static BMEdge * find_closer_edge(float *co, BMEdge *e1, BMEdge *e2)
static int interp_range(const float *frac, int n, const float f, float *r_rest)
static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb)
static void set_profile_spacing(BevelParams *bp, ProfileSpacing *pro_spacing, bool custom)
static void slide_dist(EdgeHalf *e, BMVert *v, float d, float r_slideco[3])
static void fill_vmesh_fracs(VMesh *vm, float *frac, int i)
static void avg4(float co[3], const NewVert *v0, const NewVert *v1, const NewVert *v2, const NewVert *v3)
static NewVert * mesh_vert_canon(VMesh *vm, int i, int j, int k)
static float projected_boundary_area(BevVert *bv, BMFace *f)
#define BEVEL_EPSILON_BIG
static VMesh * new_adj_vmesh(MemArena *mem_arena, int count, int seg, BoundVert *bounds)
static EdgeHalf * next_edgehalf_bev(BevelParams *bp, EdgeHalf *start_edge, bool toward_bv, BevVert **r_bv)
static BoundVert * add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3])
static VMesh * adj_vmesh(BevelParams *bp, BevVert *bv)
static void math_layer_info_init(BevelParams *bp, BMesh *bm)
static VMesh * cubic_subdiv(BevelParams *bp, VMesh *vm_in)
void BM_mesh_bevel(BMesh *bm, const float offset, const int offset_type, const int profile_type, const int segments, const float profile, const bool affect_type, const bool use_weights, const bool limit_offset, const MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, const bool harden_normals, const int face_strength_mode, const int miter_outer, const int miter_inner, const float spread, const CurveProfile *custom_profile, const int vmesh_method, const int bweight_offset_vert, const int bweight_offset_edge)
static void update_uv_vert_map(BevelParams *bp, UVFace *uv_face, BMVert *bv, Map< BMVert *, BMVert * > *nv_bv_map)
static void bevel_harden_normals(BevelParams *bp, BMesh *bm)
Harden normals for bevel.
static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv)
static VMesh * tri_corner_adj_vmesh(BevelParams *bp, BevVert *bv)
static void snap_to_pipe_profile(BoundVert *vpipe, bool midline, float co[3])
static void find_bevel_edge_order(BMesh *bm, BevVert *bv, BMEdge *first_bme)
static float vertex_collide_offset(BevelParams *bp, EdgeHalf *ea)
static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, bool miter)
static int bevel_edge_order_extend(BMesh *bm, BevVert *bv, int i)
static void uv_vert_map_init(BevelParams *bp, BMesh *bm)
#define BEVEL_MATCH_SPEC_WEIGHT
static float edge_face_angle(EdgeHalf *e)
static void adjust_miter_coords(BevelParams *bp, BevVert *bv, EdgeHalf *emiter)
static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f2)
static void snap_to_superellipsoid(float co[3], const float super_r, bool midline)
static void bevel_reattach_wires(BMesh *bm, BevelParams *bp, BMVert *v)
static void find_even_superellipse_chords_general(int seg, float r, double *xvals, double *yvals)
static bool is_bad_uv_poly(BevVert *bv, BMFace *frep)
static bool contig_ldata_across_loops(BMesh *bm, BMLoop *l1, BMLoop *l2, int layer_index)
static bool nearly_parallel_normalized(const float d1[3], const float d2[3])
static BMFace * boundvert_rep_face(BoundVert *v, BMFace **r_fother)
Map< BMVert *, Vector< UVVertBucket > > UVVertMap
static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto, int ifrom, int jfrom, int kfrom)
static double superellipse_co(double x, float r, bool rbig)
static void bevel_extend_edge_data(BevVert *bv)
static bool eh_on_plane(EdgeHalf *e)
static void uv_vert_map_pop(BevelParams *bp, BMVert *v)
#define CIRCLE_FULLNESS_SEGS
Set< BMLoop * > UVVertBucket
static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f)
static BoundVert * pipe_test(BevVert *bv)
static void project_to_edge(const BMEdge *e, const float co_a[3], const float co_b[3], float projco[3])
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_DISK_EDGE_NEXT(e, v)
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
void BM_elem_attrs_copy(BMesh *bm, const BMCustomDataCopyMap &map, const BMVert *src, BMVert *dst)
void BM_vert_kill(BMesh *bm, BMVert *v)
void BM_face_kill(BMesh *bm, BMFace *f)
BMFace * BM_face_create_verts(BMesh *bm, BMVert **vert_arr, const int len, const BMFace *f_example, const eBMCreateFlag create_flag, const bool create_edges)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const StringRef name)
void BM_loop_interp_from_face(BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
void BM_lnorspace_update(BMesh *bm)
void BM_mesh_normals_update(BMesh *bm)
BMFace * BM_face_split(BMesh *bm, BMFace *f, BMLoop *l_a, BMLoop *l_b, BMLoop **r_l, BMEdge *example, const bool no_double)
Face Split.
#define BMO_edge_flag_test(bm, e, oflag)
#define BMO_edge_flag_enable(bm, e, oflag)
#define BMO_vert_flag_enable(bm, e, oflag)
#define BMO_vert_flag_test(bm, e, oflag)
#define BMO_edge_flag_disable(bm, e, oflag)
@ BEVEL_FACE_STRENGTH_NONE
@ BEVEL_FACE_STRENGTH_AFFECTED
@ BEVEL_FACE_STRENGTH_NEW
@ BEVEL_FACE_STRENGTH_ALL
@ BEVEL_PROFILE_SUPERELLIPSE
void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
bool BM_face_point_inside_test(const BMFace *f, const float co[3])
BMLoop * BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
int BM_edge_face_count(const BMEdge *e)
float BM_edge_calc_length(const BMEdge *e)
bool BM_vert_face_check(const BMVert *v)
BMLoop * BM_face_edge_share_loop(BMFace *f, BMEdge *e)
Return the Loop Shared by Face and Edge.
float BM_edge_calc_face_angle_signed_ex(const BMEdge *e, const float fallback)
BMESH EDGE/FACE ANGLE.
BMLoop * BM_face_vert_share_loop(BMFace *f, BMVert *v)
Return the Loop Shared by Face and Vertex.
BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
static T sum(const btAlignedObjectArray< T > &items)
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
SIMD_FORCE_INLINE btVector3 dot3(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) const
const Value * lookup_ptr(const Key &key) const
std::optional< Value > pop_try(const Key &key)
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
bool contains(const Key &key) const
void append(const T &value)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(const float x, ccl_private int *ix)
blender::gpu::Batch * quad
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float length(VecOp< float, D >) RET
void EIG_linear_solver_print_matrix(LinearSolver *solver)
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value)
LinearSolver * EIG_linear_least_squares_solver_new(int num_rows, int num_columns, int num_right_hand_sides)
void EIG_linear_solver_delete(LinearSolver *solver)
double EIG_linear_solver_variable_get(LinearSolver *solver, int rhs, int index)
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
bool EIG_linear_solver_solve(LinearSolver *solver)
static MemArena * mem_arena
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
ccl_device_inline float beta(const float x, const float y)
ccl_device_inline float2 fabs(const float2 a)
vector snap(vector a, vector b)
MathLayerInfo math_layer_info
ProfileSpacing pro_spacing
Vector< UVVertMap > uv_vert_maps
ProfileSpacing pro_spacing_miter
const MDeformVert * dvert
const CurveProfile * custom_profile
CurveProfilePoint * segments