41#ifdef BEVEL_DEBUG_TIME
45#define BEVEL_EPSILON_D 1e-6
46#define BEVEL_EPSILON 1e-6f
47#define BEVEL_EPSILON_SQ 1e-12f
48#define BEVEL_EPSILON_BIG 1e-4f
49#define BEVEL_EPSILON_BIG_SQ 1e-8f
50#define BEVEL_EPSILON_ANG DEG2RADF(2.0f)
51#define BEVEL_SMALL_ANG DEG2RADF(10.0f)
53#define BEVEL_SMALL_ANG_DOT (1.0f - cosf(BEVEL_SMALL_ANG))
55#define BEVEL_EPSILON_ANG_DOT (1.0f - cosf(BEVEL_EPSILON_ANG))
56#define BEVEL_MAX_ADJUST_PCT 10.0f
57#define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f
58#define BEVEL_MATCH_SPEC_WEIGHT 0.2
151#define PRO_SQUARE_R 1e4f
152#define PRO_CIRCLE_R 2.0f
153#define PRO_LINE_R 1.0f
154#define PRO_SQUARE_IN_R 0.0f
389#define BM_ELEM_LONG_TAG (1 << 6)
447 const float direction_dot =
dot_v3v3(d1, d2);
495 int nj = (vm->
seg / 2) + 1;
496 int nk = vm->
seg + 1;
498 return &vm->
mesh[i * nk * nj + j * nk + k];
520 for (
int i = 0; i < bv->
edgecount; i++) {
521 if (bv->
edges[i].
e == bme) {
522 return &bv->
edges[i];
551 *r_bvother =
nullptr;
560 if (from_e ==
nullptr) {
568 }
while ((
e =
e->next) != from_e);
616 frep =
v->ebev->fprev;
617 if (
v->efirst->fprev != frep) {
618 frep2 =
v->efirst->fprev;
621 else if (
v->efirst) {
622 frep =
v->efirst->fprev;
624 if (
v->elast->fnext != frep) {
625 frep2 =
v->elast->fnext;
627 else if (
v->efirst->fnext != frep) {
628 frep2 =
v->efirst->fnext;
630 else if (
v->elast->fprev != frep) {
631 frep2 =
v->efirst->fprev;
634 else if (
v->efirst->fnext) {
635 frep =
v->efirst->fnext;
636 if (
v->elast->fnext != frep) {
637 frep2 =
v->elast->fnext;
640 else if (
v->elast->fprev) {
641 frep =
v->elast->fprev;
644 else if (
v->prev->elast) {
645 frep =
v->prev->elast->fnext;
646 if (
v->next->efirst) {
648 frep2 =
v->next->efirst->fprev;
651 frep =
v->next->efirst->fprev;
685 if ((facerep || (face_arr && face_arr[0])) && f) {
696 interp_f = face_arr[i];
704 bme = snap_edge_arr[i];
733 f->
mat_nr = short(mat_nr);
765 std::swap(lef1, lef2);
767 if (lef1->
f != f1 || lef2->
f != f2) {
781 BLI_assert(lv1f1->
v == v1 && lv1f1->
f == f1 && lv2f1->
v ==
v2 && lv2f1->
f == f1 &&
782 lv1f2->
v == v1 && lv1f2->
f == f2 && lv2f2->
v ==
v2 && lv2f2->
f == f2);
804 for (
int f = 0; f < totface; f++) {
805 if (face_component[f] == c1) {
806 face_component[f] = c2;
808 else if (face_component[f] == c2) {
809 face_component[f] = c1;
838 int *face_component =
static_cast<int *
>(
845 bool *in_stack =
static_cast<bool *
>(
MEM_malloc_arrayN(totface,
sizeof(
bool), __func__));
848 for (f = 0; f < totface; f++) {
849 face_component[f] = -1;
852 int current_component = -1;
853 for (f = 0; f < totface; f++) {
854 if (face_component[f] == -1 && !in_stack[f]) {
860 while (stack_top >= 0) {
861 BMFace *bmf = stack[stack_top];
864 in_stack[bmf_index] =
false;
865 if (face_component[bmf_index] != -1) {
868 face_component[bmf_index] = current_component;
879 if (bmf_other != bmf) {
881 if (face_component[bmf_other_index] != -1 || in_stack[bmf_other_index]) {
887 stack[stack_top] = bmf_other;
888 in_stack[bmf_other_index] =
true;
901 if (current_component <= 0) {
904 BMFace *top_face =
nullptr;
905 float top_face_z = -1e30f;
906 int top_face_component = -1;
907 BMFace *bot_face =
nullptr;
908 float bot_face_z = 1e30f;
909 int bot_face_component = -1;
910 for (f = 0; f < totface; f++) {
915 if (fz > top_face_z) {
918 top_face_component = face_component[f];
920 if (fz < bot_face_z) {
923 bot_face_component = face_component[f];
926 BLI_assert(top_face !=
nullptr && bot_face !=
nullptr);
929 if (bot_face_component != top_face_component) {
930 if (bot_face_component == 0) {
932 bot_face_component = top_face_component;
952#define VEC_VALUE_LEN 6
958 for (
int f = 0; f < nfaces; f++) {
960 if (bmf ==
nullptr) {
961 still_viable[f] =
false;
964 still_viable[f] =
true;
979 value_vecs[f][value_index++] = cent[2];
980 value_vecs[f][value_index++] = cent[0];
981 value_vecs[f][value_index++] = cent[1];
989 for (
int value_index = 0; num_viable > 1 && value_index <
VEC_VALUE_LEN; value_index++) {
990 for (
int f = 0; f < nfaces; f++) {
991 if (!still_viable[f] || f == best_f) {
998 if (value_vecs[f][value_index] < value_vecs[best_f][value_index]) {
1001 for (
int i = f - 1; i >= 0; i--) {
1002 if (still_viable[i]) {
1003 still_viable[i] =
false;
1008 else if (value_vecs[f][value_index] > value_vecs[best_f][value_index]) {
1009 still_viable[f] =
false;
1017 return face[best_f];
1027 for (
int i = 0; i < num_of_uv_layers; i++) {
1030 if (cd_loop_uv_offset == -1) {
1035 float uv[2] = {0.0f, 0.0f};
1067 else if (
l->
prev->
e == bme) {
1071 if (l1 ==
nullptr || l2 ==
nullptr) {
1075 for (
int i = 0; i < num_of_uv_layers; i++) {
1078 if (cd_loop_uv_offset == -1) {
1082 float uv[2] = {0.0f, 0.0f};
1113 float *l1 =
e->
e->
v1->
co;
1120 *ret_closer_v =
e->
e->
v1;
1124 *ret_closer_v =
e->
e->
v2;
1135 float dir1[3], dir2[3];
1154 else if (e2->
fprev) {
1172 float dir1[3], dir2[3], dirco[3], no[3];
1200 float dir1[3], dir2[3],
cross[3];
1203 if (e1->
v1 == e2->
v1) {
1208 else if (e1->
v1 == e2->
v2) {
1213 else if (e1->
v2 == e2->
v1) {
1218 else if (e1->
v2 == e2->
v2) {
1259 float d0, d3, d4, d5;
1265 bool no_offsets = f1 ==
nullptr || f2 ==
nullptr;
1282 d0 = d3 = d4 = d5 = bp->
offset;
1344 float dir1[3], dir2[3];
1348 float dir1n[3], dir2p[3];
1349 if (edges_between) {
1362 float norm_perp1[3];
1380 for (
EdgeHalf *eloop = e1; eloop != e2; eloop = eloop->
next) {
1381 if (eloop->fnext !=
nullptr) {
1399 d = d /
cosf(ang / 2.0f);
1419 float norm_v1[3], norm_v2[3];
1424 else if (!edges_between) {
1449 float norm_perp2[3];
1455 float off1a[3], off1b[3], off2a[3], off2b[3];
1472 if (isect_kind == 0) {
1490 if (isect_kind == 2) {
1525#define BEVEL_GOOD_ANGLE 0.1f
1538 float dir1[3], dir2[3];
1569 float sinang =
sinf(ang);
1609 bool retval =
false;
1614 float meet1[3], meet2[3];
1636 *r_sinratio = (ang1 == 0.0f) ? 1.0f :
sinf(ang2) /
sinf(ang1);
1644 *r_sinratio = (ang1 == 0.0f) ? 1.0f :
sinf(ang2) /
sinf(ang1);
1648 else if (ok1 && !ok2) {
1651 else if (!ok1 && ok2) {
1669 float dir[3], no[3];
1699 const float co_a[3],
1700 const float co_b[3],
1705#ifdef BEVEL_ASSERT_PROJECT
1716 bool do_linear_interp =
true;
1720 float start[3], end[3];
1724 do_linear_interp =
false;
1753 if (
e->prev->is_bev &&
e->next->is_bev && bv->
selcount >= 3) {
1755 float d3[3], d4[3], co4[3], meetco[3], isect2[3];
1765 do_linear_interp =
true;
1772 if (isect_kind != 0) {
1778 do_linear_interp =
true;
1791 do_linear_interp =
true;
1808 do_linear_interp =
false;
1818 do_linear_interp =
false;
1821 if (do_linear_interp) {
1854 float no[3], no2[3], no3[3];
1886 float d1[3], d2[3], no[3];
1894 float no2[3], no3[3];
1927 return lb->
next == la ? 1 : -1;
1952 const float vmid[3],
1956 float vb_vmid[3], va_vmid[3];
1968 float vo[3], vd[3], vddir[3];
2009 const float va[3],
const float vb[3],
const float vc[3],
const float vd[3],
float r_mat[4][4])
2050 return pow((1.0 -
pow(x, r)), (1.0 / r));
2052 return 1.0 -
pow((1.0 -
pow(1.0 - x, r)), (1.0 / r));
2076 if (nseg == bp->
seg) {
2094 const float map[4][4],
2096 const bool reversed,
2098 const double *xvals,
2099 const double *yvals,
2103 for (
int k = 0; k <= ns; k++) {
2113 const float p[3] = {
2114 reversed ?
float(yvals[ns - k]) :
float(xvals[k]),
2115 reversed ?
float(xvals[ns - k]) :
float(yvals[k]),
2122 interp_v3_v3v3(co, profile->start, profile->end,
float(k) /
float(ns));
2126 float *prof_co_k = r_prof_co + 3 * k;
2160 if (pro->
prof_co ==
nullptr) {
2183 float bottom_corner[3] = {0.0f, 0.0f, 0.0f};
2185 float top_corner[3] = {1.0f, 1.0f, 0.0f};
2221 float a =
max_ff(0.0f, co[0]);
2222 float b =
max_ff(0.0f, co[1]);
2223 float c =
max_ff(0.0f, co[2]);
2235 float dx = 1.0f -
x;
2236 float dy = 1.0f -
y;
2239 y = midline ? 1.0f :
y;
2243 x = midline ? 1.0f :
x;
2250 y = midline ? 0.0f :
y;
2254 x = midline ? 0.0f :
x;
2259 float rinv = 1.0f / r;
2268 y =
powf(1.0f / (1.0f +
powf(c /
b, r)), rinv);
2273 x =
powf(1.0f / (1.0f +
powf(
b / a, r) +
powf(c / a, r)), rinv);
2283#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) BM_elem_flag_test(eh->e, flag)
2299#define HASNOT_SEAMSHARP(eh, flag) \
2300 ((flag == BM_ELEM_SEAM && !BM_elem_flag_test(eh->e, BM_ELEM_SEAM)) || \
2301 (flag == BM_ELEM_SMOOTH && BM_elem_flag_test(eh->e, BM_ELEM_SMOOTH)))
2337 e->rightv->seam_len = flag_count;
2340 e->rightv->sharp_len = flag_count;
2343 }
while (
e != efirst);
2368 int idx_end = bcur->
index + extend_len;
2369 for (
int i = bcur->
index; i < idx_end; i++) {
2372 for (
int k = 1; k < vm->
seg; k++) {
2378 while (
e->v1 !=
v2 &&
e->v2 !=
v2) {
2391 while (
e->v1 != v3 &&
e->v2 != v3) {
2406 }
while (bcur != start);
2439 if (lother !=
l && fother) {
2473 if (cd_clnors_offset == -1) {
2481 if (cd_clnors_offset == -1) {
2503 float *pnorm =
nullptr;
2514 pnorm = lprev->
f->
no;
2517 pnorm = lnext->
f->
no;
2523 else if (fkind ==
F_VERT) {
2527 else if (fprevkind ==
F_RECON) {
2528 pnorm = lprev->
f->
no;
2530 else if (fnextkind ==
F_RECON) {
2531 pnorm = lnext->
f->
no;
2534 BMLoop *lprevprev, *lnextnext;
2536 estep = lprev->
prev->
e;
2540 lprevprev =
nullptr;
2547 lnextnext =
nullptr;
2552 pnorm = lprevprev->
f->
no;
2568 if (pnorm ==
norm) {
2585 if (cd_prop_int_idx == -1) {
2597 bool do_set_strength =
true;
2617 do_set_strength =
false;
2619 if (do_set_strength) {
2621 *strength_ptr = strength;
2632 v->any_seam =
false;
2634 v->any_seam |=
e->is_seam;
2635 if (
e ==
v->elast) {
2657 for (
int i = 0; i < bv->
edgecount; i++) {
2668 if (
e->fprev &&
e->fnext) {
2691 bool miter_profile =
false;
2692 bool reverse_profile =
false;
2717 v->efirst =
v->elast =
e;
2718 e->leftv =
e->rightv =
v;
2723 }
while ((
e =
e->next) != efirst);
2727 if (vm->
count == 2) {
2730 else if (bp->
seg == 1) {
2747 const bool construct)
2758 const float *no =
e->fprev ?
e->fprev->
no : (
e->fnext ?
e->fnext->
no :
nullptr);
2768 no =
e->fnext ?
e->fnext->
no : (
e->fprev ?
e->fprev->
no :
nullptr);
2783 e->next->leftv =
e->next->rightv = bndv;
2807 e->prev->leftv =
e->prev->rightv = bndv;
2823 e->leftv =
e->rightv = bndv;
2824 e->prev->rightv = bndv;
2834 for (
e =
e->next;
e->next != efirst;
e =
e->next) {
2839 e->leftv =
e->rightv = bndv;
2861 else if (vm->
count == 3) {
2862 bool use_tri_fan =
true;
2866 float profile_plane[4];
2870 use_tri_fan =
false;
2907 float co1[3], edge_dir[3], line_p[3];
2911 float d = bp->
offset / (bp->
seg / 2.0f);
2936 if (
v->is_arc_start) {
2940 float edge_dir[3], co[3];
2957 }
while (
v != vstart);
3020 int not_in_plane = 0;
3036 if (in_plane == 0 && not_in_plane == 0) {
3039 else if (not_in_plane > 0) {
3075 e3->leftv = e3->rightv =
v;
3113 if (
e->next == e2) {
3114 v2->efirst =
nullptr;
3115 v2->elast =
nullptr;
3118 v2->efirst =
e->next;
3120 e3->leftv = e3->rightv =
v2;
3128 if (
e->next == e2) {
3132 int between = in_plane + not_in_plane;
3133 int bet2 = between / 2;
3134 bool betodd = (between % 2) == 1;
3143 else if (betodd && i == bet2) {
3144 e3->profile_index = bp->
seg / 2;
3147 e3->profile_index = bp->
seg;
3185 }
while (
e != efirst);
3197 if (vm->
count == 2) {
3200 else if (efirst->
seg == 1) {
3217static void print_adjust_stats(
BoundVert *vstart)
3219 printf(
"\nSolution analysis\n");
3220 double even_residual2 = 0.0;
3221 double spec_residual2 = 0.0;
3222 double max_even_r = 0.0;
3223 double max_even_r_pct = 0.0;
3224 double max_spec_r = 0.0;
3225 double max_spec_r_pct = 0.0;
3226 printf(
"width matching\n");
3229 if (
v->adjchain !=
nullptr) {
3234 printf(
"e%d r(%f) vs l(%f): abs(delta)=%f, delta_pct=%f\n",
3240 even_residual2 += delta * delta;
3241 if (delta > max_even_r) {
3244 if (delta_pct > max_even_r_pct) {
3245 max_even_r_pct = delta_pct;
3249 }
while (
v &&
v != vstart);
3251 printf(
"spec matching\n");
3254 if (
v->adjchain !=
nullptr) {
3259 printf(
"e%d r(%f) vs r spec(%f): delta=%f, delta_pct=%f\n",
3265 spec_residual2 += delta * delta;
3266 delta =
fabs(delta);
3267 delta_pct =
fabs(delta_pct);
3268 if (delta > max_spec_r) {
3271 if (delta_pct > max_spec_r_pct) {
3272 max_spec_r_pct = delta_pct;
3277 printf(
"e%d l(%f) vs l spec(%f): delta=%f, delta_pct=%f\n",
3283 spec_residual2 += delta * delta;
3284 delta =
fabs(delta);
3285 delta_pct =
fabs(delta_pct);
3286 if (delta > max_spec_r) {
3289 if (delta_pct > max_spec_r_pct) {
3290 max_spec_r_pct = delta_pct;
3294 }
while (
v &&
v != vstart);
3296 printf(
"Analysis Result:\n");
3297 printf(
"even residual2 = %f, spec residual2 = %f\n", even_residual2, spec_residual2);
3298 printf(
"max even delta = %f, max as percent of spec = %f\n", max_even_r, max_even_r_pct);
3299 printf(
"max spec delta = %f, max as percent of spec = %f\n", max_spec_r, max_spec_r_pct);
3303#ifdef FAST_ADJUST_CODE
3312static bool adjust_the_cycle_or_chain_fast(
BoundVert *vstart,
int np,
bool iscycle)
3314 float *g =
MEM_mallocN(np *
sizeof(
float),
"beveladjust");
3315 float *g_prod =
MEM_mallocN(np *
sizeof(
float),
"beveladjust");
3318 float spec_sum = 0.0f;
3322 if (iscycle ||
v->adjchain !=
nullptr) {
3323 spec_sum +=
v->efirst->offset_r;
3326 spec_sum +=
v->elast->offset_l;
3330 }
while (
v &&
v != vstart);
3332 float gprod = 1.00f;
3333 float gprod_sum = 1.0f;
3334 for (i = np - 1; i > 0; i--) {
3349 if (gprod_sum == 0.0f) {
3354 float p = spec_sum / gprod_sum;
3360 if (iscycle ||
v->adjchain !=
nullptr) {
3363 eright->
offset_r = g_prod[(i + 1) % np] * p;
3364 if (iscycle ||
v != vstart) {
3375 }
while (
v &&
v != vstart);
3408 if ((*r_bv)->selcount == 1) {
3413 if ((*r_bv)->selcount == 2) {
3417 new_edge = new_edge->
next;
3418 }
while (!new_edge->
is_bev);
3425 float dir_start_edge[3];
3426 if (start_edge->
e->
v1 == (*r_bv)->v) {
3436 float second_best_dot = 0.0f, best_dot = 0.0f;
3438 while (new_edge != start_edge) {
3440 new_edge = new_edge->
next;
3444 float dir_new_edge[3];
3445 if (new_edge->
e->
v2 == (*r_bv)->v) {
3454 float new_dot =
dot_v3v3(dir_new_edge, dir_start_edge);
3455 if (new_dot > best_dot) {
3456 second_best_dot = best_dot;
3458 next_edge = new_edge;
3460 else if (new_dot > second_best_dot) {
3461 second_best_dot = new_dot;
3464 new_edge = new_edge->
next;
3495 for (
int i = 0; i < 2; i++) {
3496 EdgeHalf *edgehalf = start_edgehalf;
3498 bool toward_bv = (i == 0);
3515 toward_bv = !toward_bv;
3535 printf(
"\nadjust the %s (with eigen)\n", iscycle ?
"cycle" :
"chain");
3546 }
while (
v &&
v != vstart);
3548 printf(
" -> %d parms\n", np);
3551#ifdef FAST_ADJUST_CODE
3552 if (adjust_the_cycle_or_chain_fast(vstart, np, iscycle)) {
3557 int nrows = iscycle ? 3 * np : 3 * np - 3;
3565 EdgeHalf *eleft, *eright, *enextleft;
3568 if (iscycle || i < np - 1) {
3571 enextleft =
v->adjchain->elast;
3574 if (iscycle ||
v != vstart) {
3575 printf(
" dependent: e%d->offset_l = %f * p%d\n",
3596 int row = iscycle ? np + 2 * i : np - 1 + 2 * i;
3600 printf(
"b[%d]=%f * %f, for e%d->offset_r\n",
3611 solver, row, (i == np - 1) ? 0 : i + 1, weight *
v->adjchain->sinratio);
3614 printf(
"b[%d]=%f * %f, for e%d->offset_l\n",
3632 }
while (
v &&
v != vstart);
3638 for (i = 0; i < np; i++) {
3648 if (iscycle || i < np - 1) {
3655 if (iscycle ||
v != vstart) {
3672 }
while (
v &&
v != vstart);
3675 print_adjust_stats(vstart);
3726 v = vchainstart = vchainend = vanchor;
3728 bool iscycle =
false;
3730 while (
v->eon && !
v->visited && !iscycle) {
3741 v->adjchain = vnext;
3745 if (vnext != vchainstart) {
3755 v->adjchain =
nullptr;
3770 vchainstart = vnext;
3772 }
while (!
v->visited &&
v->eon);
3773 if (chainlen >= 3 && !vchainstart->
eon && !vchainend->
eon) {
3810 float dir1[3], dir3[3];
3869 BLI_assert(0 <= i && i <= n && 0 <= j && j <= ns && 0 <= k && k <= ns);
3871 if (!odd && j == ns2 && k == ns2) {
3874 if (j <= ns2 - 1 + odd && k <= ns2) {
3878 return mesh_vert(vm, (i + n - 1) % n, k, ns - j);
3880 return mesh_vert(vm, (i + 1) % n, ns - k, j);
3885 int ns2 = vm->
seg / 2;
3886 if (vm->
seg % 2 == 1) {
3887 return (j <= ns2 && k <= ns2);
3890 return ((j < ns2 && k <= ns2) || (j == ns2 && k == ns2 && i == 0));
3899 for (
int i = 0; i < n; i++) {
3900 for (
int j = 0; j <= ns2; j++) {
3901 for (
int k = 0; k <= ns; k++) {
3918 int ns2 = vm->
seg / 2;
3921 for (
int i = 0; i < n; i++) {
3948 return 0.065247584f;
3954 return 0.401983447f;
3957 return 0.523423277f;
3959 double k =
cos(
M_PI /
double(n));
3963 double k4 = k2 * k2;
3964 double k6 = k4 * k2;
3965 double y =
pow(
M_SQRT3 *
sqrt(64.0 * k6 - 144.0 * k4 + 135.0 * k2 - 27.0) + 9.0 * k, 1.0 / 3.0);
3966 double x = 0.480749856769136 * y - (0.231120424783545 * (12.0 * k2 - 9.0)) /
y;
3967 return (k * x + 2.0 * k2 - 1.0) / (x * x * (k * x + 1.0));
3978 for (
int k = 0; k < ns; k++) {
3980 frac[k + 1] = total;
3983 for (
int k = 1; k <= ns; k++) {
3995 float co[3], nextco[3];
4000 for (
int k = 0; k < ns; k++) {
4003 frac[k + 1] = total;
4007 for (
int k = 1; k <= ns; k++) {
4021 for (
int i = 0; i < n; i++) {
4022 if (f <=
frac[i + 1]) {
4023 float rest = f -
frac[i];
4028 *r_rest = rest / (
frac[i + 1] -
frac[i]);
4030 if (i == n - 1 && *r_rest == 1.0f) {
4047 int n_bndv = vm_in->
count;
4048 int ns_in = vm_in->
seg;
4049 int nseg2 = nseg / 2;
4061 for (
int i = 0; i < n_bndv; i++) {
4064 for (
int j = 0; j <= nseg2 - 1 + odd; j++) {
4065 for (
int k = 0; k <= nseg2; k++) {
4067 float fraction = new_frac[k];
4071 fraction = prev_new_frac[nseg - j];
4072 int k_in_prev =
interp_range(prev_frac, ns_in, fraction, &restkprev);
4073 int j_in = ns_in - k_in_prev;
4074 float restj = -restkprev;
4080 restj = 1.0f + restj;
4088 int j0inc = (restj <
BEVEL_EPSILON || j_in == ns_in) ? 0 : 1;
4089 int k0inc = (restk <
BEVEL_EPSILON || k_in == ns_in) ? 0 : 1;
4101 memcpy(prev_frac,
frac,
sizeof(
float) * (ns_in + 1));
4102 memcpy(prev_new_frac, new_frac,
sizeof(
float) * (nseg + 1));
4121 int n_boundary = vm_in->
count;
4122 int ns_in = vm_in->
seg;
4123 int ns_in2 = ns_in / 2;
4125 int ns_out = 2 * ns_in;
4129 for (
int i = 0; i < n_boundary; i++) {
4131 for (
int k = 1; k < ns_in; k++) {
4136 float co1[3], co2[3], acc[3];
4150 for (
int i = 0; i < n_boundary; i++) {
4151 for (
int k = 1; k < ns_out; k += 2) {
4156 float co1[3], co2[3], acc[3];
4172 for (
int i = 0; i < n_boundary; i++) {
4173 for (
int k = 0; k < ns_in; k++) {
4184 for (
int i = 0; i < n_boundary; i++) {
4185 for (
int j = 0; j < ns_in2; j++) {
4186 for (
int k = 0; k < ns_in2; k++) {
4199 for (
int i = 0; i < n_boundary; i++) {
4200 for (
int j = 0; j < ns_in2; j++) {
4201 for (
int k = 1; k <= ns_in2; k++) {
4214 for (
int i = 0; i < n_boundary; i++) {
4215 for (
int j = 1; j < ns_in2; j++) {
4216 for (
int k = 0; k < ns_in2; k++) {
4229 float gamma = 0.25f;
4230 float beta = -gamma;
4231 for (
int i = 0; i < n_boundary; i++) {
4232 for (
int j = 1; j < ns_in2; j++) {
4233 for (
int k = 1; k <= ns_in2; k++) {
4234 float co1[3], co2[3];
4262 float co1[3], co2[3];
4265 for (
int i = 0; i < n_boundary; i++) {
4271 mul_v3_fl(co, 1.0f /
float(n_boundary));
4274 for (
int i = 0; i < n_boundary; i++) {
4280 for (
int i = 0; i < n_boundary; i++) {
4281 int inext = (i + 1) % n_boundary;
4282 for (
int k = 0; k <= ns_out; k++) {
4285 if (k >= ns_in && k < ns_out) {
4301 for (
int i = 0; i < 3; i++) {
4302 float co[3] = {0.0f, 0.0f, 0.0f};
4306 for (
int i = 0; i < 3; i++) {
4307 for (
int j = 0; j <= ns2; j++) {
4308 for (
int k = 0; k <= ns2; k++) {
4314 co[(i + 1) % 3] =
float(k) * 2.0f /
float(nseg);
4315 co[(i + 2) % 3] =
float(j) * 2.0f /
float(nseg);
4336 for (
int i = 0; i < 3; i++) {
4337 float co[3] = {0.0f, 0.0f, 0.0f};
4349 for (
int i = 0; i < 3; i++) {
4350 for (
int k = 0; k <= ns2; k++) {
4352 co[i] = 1.0f -
float(k) *
b;
4353 co[(i + 1) % 3] = 0.0f;
4354 co[(i + 2) % 3] = 0.0f;
4356 co[(i + 1) % 3] = 1.0f -
float(k) *
b;
4357 co[(i + 2) % 3] = 0.0f;
4389 for (
int i = 0; i < 3; i++) {
4390 float co[3] = {0.0f, 0.0f, 0.0f};
4395 for (
int i = 0; i < 3; i++) {
4399 coc[(i + 1) % 3] = 1.0f;
4400 coc[(i + 2) % 3] = 0.0f;
4425 else if (r < 0.75f) {
4434 while (vm1->
seg < nseg) {
4437 if (vm1->
seg != nseg) {
4443 for (
int i = 0; i < 3; i++) {
4444 for (
int j = 0; j <= ns2; j++) {
4445 for (
int k = 0; k <= nseg; k++) {
4470 float totang = 0.0f;
4471 for (
int i = 0; i < bv->
edgecount; i++) {
4474 float absang =
fabsf(ang);
4478 else if (absang >= 3.0f *
float(
M_PI_4)) {
4493 (angdiff >
float(
M_PI_4)))
4507 float co0[3], co1[3], co2[3];
4519 for (
int i = 0; i < 3; i++) {
4520 for (
int j = 0; j <= ns2; j++) {
4521 for (
int k = 0; k <= ns; k++) {
4552 float boundverts_center[3] = {0.0f, 0.0f, 0.0f};
4553 for (
int i = 0; i < n_bndv; i++) {
4560 mul_v3_fl(boundverts_center, 1.0f /
float(n_bndv));
4566 float original_vertex[3], negative_fullest[3];
4568 sub_v3_v3v3(negative_fullest, boundverts_center, original_vertex);
4569 add_v3_v3(negative_fullest, boundverts_center);
4573 float center_direction[3];
4574 sub_v3_v3v3(center_direction, original_vertex, boundverts_center);
4593 }
while (vm1->
seg < nseg);
4594 if (vm1->
seg != nseg) {
4617 float edir[3], plane[4];
4621 float start_plane[3], end_plane[3], middle_plane[3];
4626 float m[4][4], minv[4][4];
4658 int half_ns = ns / 2;
4659 int ipipe1 = vpipe->
index;
4662 for (
int i = 0; i < n_bndv; i++) {
4663 for (
int j = 1; j <= half_ns; j++) {
4664 for (
int k = 0; k <= half_ns; k++) {
4671 float *profile_point_pipe1, *profile_point_pipe2, f;
4672 if (
ELEM(i, ipipe1, ipipe2)) {
4673 if (n_bndv == 3 && i == ipipe1) {
4676 profile_point_pipe2 =
mesh_vert(vm, i, 0, ring)->
co;
4677 profile_point_pipe1 =
mesh_vert(vm, i, ring, 0)->
co;
4679 f = ((k < j) ?
min_ff(j, k) : ((2.0f * ring) - j)) / (2.0f * ring);
4684 profile_point_pipe2 =
mesh_vert(vm, (i == ipipe1) ? ipipe2 : ipipe1, 0, ns - k)->co;
4691 profile_point_pipe2 =
mesh_vert(vm, i, j, ns)->
co;
4701 bool even = (ns % 2) == 0;
4702 bool midline = even && k == half_ns &&
4703 ((i == 0 && j == half_ns) ||
ELEM(i, ipipe1, ipipe2));
4723 if (
e->v1 ==
v ||
e->v2 ==
v) {
4724 if (*r_e1 ==
nullptr) {
4727 else if (*r_e2 ==
nullptr) {
4769 r_internal[n_internal++] =
v;
4770 if (n_internal == 3) {
4775 for (
int i = n_internal; i < 3; i++) {
4776 r_internal[i] =
nullptr;
4794 float axis_mat[3][3];
4804 float *co =
v->nv.v->
co;
4805 if (
ELEM(
v, unsnapped[0], unsnapped[1], unsnapped[2])) {
4809 float snap1[3], snap2[3];
4814 if (d1_sq <= d2_sq) {
4858 BMFace *any_bmf =
nullptr;
4859 bool consider_all_faces = bv->
selcount == 1;
4864 for (
int i = 0; i < bv->
edgecount; i++) {
4865 if (!bv->
edges[i].
is_bev && !consider_all_faces) {
4870 BMFace *ftwo[2] = {bmf1, bmf2};
4872 if (bmf !=
nullptr) {
4873 if (any_bmf ==
nullptr) {
4876 bool already_there =
false;
4877 for (
int j = fcount - 1; j >= 0; j--) {
4878 if (fchoices[j] == bmf) {
4879 already_there =
true;
4883 if (!already_there) {
4889 fchoices[fcount++] = bmf;
4906 int ns2 = vm->
seg / 2;
4908 BMEdge *frep_e1, *frep_e2;
4917 frep_e1 = frep_e2 =
nullptr;
4925 if (
ELEM(
v, frep_unsnapped[0], frep_unsnapped[1], frep_unsnapped[2])) {
4956 for (
int i = 0; i < n; i++) {
4957 for (
int k = 1; k < ns; k++) {
4959 if (i > 0 && k <= ns2) {
4962 else if (i == n - 1 && k > ns2) {
4971 for (
int i = 0; i < n; i++) {
5009 float ns2inv = 1.0f /
float(ns2);
5011 int clstride = 3 * (ns2 + 1);
5012 float *centerline =
static_cast<float *
>(
5013 MEM_mallocN(
sizeof(
float) * clstride * n_bndv,
"bevel"));
5014 bool *cset =
static_cast<bool *
>(
MEM_callocN(
sizeof(
bool) * n_bndv,
"bevel"));
5019 for (
int i = 0; i < n_bndv; i++) {
5049 float dir1[3], dir2[3], co1[3], co2[3];
5055 float meet1[3], meet2[3];
5080 float *on_edge_cur = centerline + clstride * i;
5081 int iprev = (i == 0) ? n_bndv - 1 : i - 1;
5082 float *on_edge_prev = centerline + clstride * iprev;
5106 for (
int i = 0; i < n_bndv; i++) {
5108 float *on_edge_cur = centerline + clstride * i;
5110 float co1[3], co2[3];
5115 float meet1[3], meet2[3];
5141 float co1[3], co2[3];
5144 for (
int i = 0; i < n_bndv; i++) {
5153 finalfrac = 0.5f /
sinf(ang);
5154 if (finalfrac > 0.8f) {
5161 ns2inv = 1.0f / (ns2 + finalfrac);
5164 float *p = centerline + clstride * i;
5167 for (
int j = 1; j <= ns2; j++) {
5176 for (
int i = 0; i < n_bndv; i++) {
5178 copy_v3_v3(co2, centerline + clstride * (i == 0 ? n_bndv - 1 : i - 1));
5179 for (
int j = 0; j < ns2 + odd; j++) {
5183 for (
int k = 1; k <= ns2; k++) {
5195 for (
int i = 0; i < n_bndv; i++) {
5196 int im1 = (i == 0) ? n_bndv - 1 : i - 1;
5197 for (
int j = 1; j < ns2 + odd; j++) {
5198 for (
int k = 1; k <= ns2; k++) {
5199 float meet1[3], meet2[3];
5201 centerline + clstride * im1 + 3 * k,
5203 centerline + clstride * i + 3 * j,
5210 centerline + clstride * im1 + 3 * k,
5213 else if (ikind == 1) {
5237 const bool *frep_beats_next)
5239 int previ = (i + n_bndv - 1) % n_bndv;
5240 int nexti = (i + 1) % n_bndv;
5242 if (frep_beats_next[previ] && bndv_rep_faces[previ] == center_frep) {
5245 if (!frep_beats_next[i] && bndv_rep_faces[nexti] == center_frep) {
5287 const bool *frep_beats_next,
5290 BLI_assert(0 <= i && i < n_bndv && 0 <= j && j < ns2 && 0 <= k && k <= ns2);
5291 for (
int corner = 0; corner < 4; corner++) {
5292 r_snap_edges[corner] =
nullptr;
5296 int previ = (i + n_bndv - 1) % n_bndv;
5298 int jj = corner < 2 ? j : j + 1;
5299 int kk =
ELEM(corner, 0, 3) ? k : k + 1;
5300 if (jj < ns2 && kk < ns2) {
5303 else if (jj < ns2 && kk == ns2) {
5305 if (!frep_beats_next[i]) {
5306 r_snap_edges[corner] = enext;
5309 else if (jj < ns2 && kk == ns2 + 1) {
5311 if (frep_beats_next[i]) {
5312 r_snap_edges[corner] = enext;
5315 else if (jj == ns2 && kk < ns2) {
5317 if (frep_beats_next[previ]) {
5318 r_snap_edges[corner] = eprev;
5321 else if (jj == ns2 && kk == ns2) {
5324 i, n_bndv, eprev, enext, bndv_rep_faces, center_frep, frep_beats_next);
5326 else if (jj == ns2 && kk == ns2 + 1) {
5328 int nexti = (i + 1) % n_bndv;
5330 nexti, n_bndv, enext, enextnext, bndv_rep_faces, center_frep, frep_beats_next);
5374 for (
int i = 0; i < n_bndv; i++) {
5375 for (
int j = 0; j <= ns2; j++) {
5376 for (
int k = 0; k <= ns; k++) {
5377 if (j == 0 &&
ELEM(k, 0, ns)) {
5394 int i = bndv->
index;
5399 BMVert **center_verts =
nullptr;
5400 BMEdge **center_edge_snaps =
nullptr;
5401 BMFace **center_face_interps =
nullptr;
5402 bool *frep_beats_next =
nullptr;
5403 BMFace *center_frep =
nullptr;
5410 for (
int i = 0; i < n_bndv; i++) {
5411 center_edge_snaps[i] =
nullptr;
5413 int inext = (i + 1) % n_bndv;
5414 BMFace *fchoices[2] = {bndv_rep_faces[i], bndv_rep_faces[inext]};
5416 frep_beats_next[i] = fwinner == bndv_rep_faces[i];
5422 int i = bndv->
index;
5424 BMFace *f = bndv_rep_faces[i];
5425 BMFace *f2 = bndv_rep_faces[inext];
5428 fc = frep_beats_next[i] ? f : f2;
5443 BMEdge *bmeprev = eprev ? eprev->
e :
nullptr;
5444 BMEdge *bmenext = enext ? enext->
e :
nullptr;
5452 for (
int j = 0; j < ns2; j++) {
5453 for (
int k = 0; k < ns2 + odd; k++) {
5459 BMVert *bmvs[4] = {bmv1, bmv2, bmv3, bmv4};
5469 BMEdge *se[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
5471 fr[0] = fr[1] = fr[2] = fr[3] = f2;
5473 if (k == ns2 && j == ns2 - 1) {
5480 se[0] = se[2] = bme;
5487 fr[0] = fr[1] = fr[2] = fr[3] = f;
5490 BMEdge *b2 = (
e &&
e->is_seam) ? bme :
nullptr;
5506 if (!
e ||
e->is_seam) {
5507 fr[0] = fr[1] = fr[2] = fr[3] = fc;
5515 center_verts[i] = bmvs[3];
5516 center_edge_snaps[i] = se[3];
5517 center_face_interps[i] = bv->
any_seam ? center_frep : f;
5525 if (j == ns2 - 1 && bndv->
prev->
ebev) {
5528 se[2] = se[1] !=
nullptr ? se[1] : se[3];
5541 int i = bndv->
index;
5543 for (
int ring = 1; ring < ns2; ring++) {
5565 bm, center_verts, n_bndv, center_face_interps, frep, center_edge_snaps, mat_nr,
true);
5587#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5588 printf(
"BEVEL BUILD CUTOFF\n");
5589# define F3(v) (v)[0], (v)[1], (v)[2]
5596 int i = bndv->
index;
5600 float down_direction[3];
5619#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5620 printf(
"Corner vertices:\n");
5621 for (
int j = 0; j < n_bndv; j++) {
5627 bool build_center_face =
true;
5636#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5637 printf(
"build_center_face: %d\n", build_center_face);
5641 if (build_center_face) {
5643 int i = bndv->
index;
5653 for (
int i = 1; i < n_bndv; i++) {
5661#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5662 printf(
"Building profile cutoff faces.\n");
5668 int i = bndv->
index;
5673#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5674 printf(
"Profile Number %d:\n", i);
5676 printf(
" Miter profile\n");
5682 for (
int k = 0; k < bp->
seg + 1; k++) {
5684#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5690 if (build_center_face) {
5692#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
5701 bp->
seg + 2 + build_center_face,
5710 if (build_center_face) {
5712 for (
int i = 0; i < n_bndv; i++) {
5729 BMEdge *repface_e1, *repface_e2;
5738 repface_e1 = repface_e2 =
nullptr;
5748 if (
ELEM(bndv, unsnapped[0], unsnapped[1], unsnapped[2])) {
5762 for (
int k = 1; k < bndv->
ebev->
seg; k++) {
5768 bmedges.
append(k < bndv->ebev->seg / 2 ?
nullptr : frep_e);
5805 while (f->
len > 3) {
5812 if (f_new->
len > f->
len) {
5814 if (l_new->
v == v_fan) {
5817 else if (l_new->
next->
v == v_fan) {
5818 l_fan = l_new->
next;
5820 else if (l_new->
prev->
v == v_fan) {
5821 l_fan = l_new->
prev;
5828 if (l_fan->
v == v_fan) {
5830 else if (l_fan->
next->
v == v_fan) {
5831 l_fan = l_fan->
next;
5833 else if (l_fan->
prev->
v == v_fan) {
5834 l_fan = l_fan->
prev;
5872 for (
int k = 1; k < ns; k++) {
5879 for (
int k = 1; k < ns; k++) {
5887 for (
int k = 0; k < ns; k++) {
5911 sizeof(
NewVert) * n * (ns2 + 1) * (ns + 1));
5921 int i = bndv->
index;
5927 if (weld && bndv->
ebev) {
5948 int i = bndv->
index;
5953 for (
int k = 1; k < ns; k++) {
5962 else if (n == 2 && !bndv->
ebev) {
5974 for (
int k = 1; k < ns; k++) {
5997 for (
int k = 1; k < ns; k++) {
6036 if (
e->fprev &&
e->fnext) {
6044#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_ELEM_API_FLAG_ENABLE((bme), _FLAG_OVERLAP)
6045#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE((bme), _FLAG_OVERLAP)
6046#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_ELEM_API_FLAG_TEST((bme), _FLAG_OVERLAP)
6076 for (
int sucindex = 0; sucindex < nsucs; sucindex++) {
6077 BMEdge *nextbme = sucs[sucindex];
6081 bv->
edges[j + 1].
e = nextbme;
6089 for (
int k = j + 1; k <= bestj; k++) {
6094 for (
int k = j + 1; k <= tryj; k++) {
6096 bv->
edges[k].
e =
nullptr;
6103 for (
int k = j + 1; k <= bestj; k++) {
6104 BLI_assert(save_path[k - (j + 1)] !=
nullptr);
6105 bv->
edges[k].
e = save_path[k - (j + 1)];
6118#ifdef FASTER_FASTORDER
6127 for (
int j = 1; j < bv->
edgecount; j++) {
6129 BMEdge *bmenext =
nullptr;
6137 if (bmenext ==
nullptr) {
6142 if (nsucs == 0 || (nsucs == 2 && j != 1) || nsucs > 2 ||
6145 for (
int k = 1; k < j; k++) {
6147 bv->
edges[k].
e =
nullptr;
6151 bv->
edges[j].
e = bmenext;
6169 for (
int i = 1; i < ntot; i++) {
6171 int num_shared_face = 0;
6172 BMEdge *first_suc =
nullptr;
6185 if (first_suc ==
nullptr) {
6190 if (num_shared_face >= 3) {
6194 if (num_shared_face == 1 || (i == 1 && num_shared_face == 2)) {
6196 e->
e = bme = first_suc;
6200 for (
int k = 1; k < i; k++) {
6202 bv->
edges[k].
e =
nullptr;
6219 bv->
edges[i].
e = first_bme;
6230 first_bme =
nullptr;
6247 for (
int i = 0; i < ntot; i++) {
6253 if (
e->fnext !=
nullptr || e2->
fprev !=
nullptr) {
6265 if (!bestf ||
l->
v == bv->
v) {
6270 e->fnext = e2->
fprev = bestf;
6290 BMEdge *first_bme =
nullptr;
6303 if (face_count == 1) {
6352 for (
int i = 0; i < tot_edges; i++) {
6363 e->is_rev = (bme->
v2 ==
v);
6364 e->leftv =
e->rightv =
nullptr;
6365 e->profile_index = 0;
6375 if (tot_edges > 1) {
6376 int ccw_test_sum = 0;
6377 for (
int i = 0; i < tot_edges; i++) {
6381 if (ccw_test_sum < 0) {
6382 for (
int i = 0; i <= (tot_edges / 2) - 1; i++) {
6383 std::swap(bv->
edges[i], bv->
edges[tot_edges - i - 1]);
6387 if (tot_edges % 2 == 1) {
6388 int i = tot_edges / 2;
6395 float vert_axis[3] = {0, 0, 0};
6411 for (
int i = 0; i < tot_edges; i++,
e++) {
6422 for (
int i = 0; i < tot_edges; i++,
e++) {
6423 e->next = &bv->
edges[(i + 1) % tot_edges];
6424 e->prev = &bv->
edges[(i + tot_edges - 1) % tot_edges];
6433 e->offset_l_spec = bp->
offset;
6439 e->offset_l_spec = 0.01f * bp->
offset;
6449 e->offset_l_spec = 0.01f * bp->
offset;
6470 e->offset_l_spec = bp->
offset;
6471 e->offset_r_spec = bp->
offset;
6476 e->offset_l_spec = bp->
offset;
6481 e->offset_r_spec =
e->offset_l_spec;
6487 e->offset_l_spec *= weight;
6488 e->offset_r_spec *= weight;
6497 e->offset_l_spec = bv->
offset;
6505 e->offset_l_spec = 0.01f * bp->
offset;
6517 e->offset_l_spec = 0.01f * bp->
offset;
6529 e->offset_l_spec = bv->
offset;
6533 e->offset_r_spec =
e->offset_l_spec;
6536 e->offset_l_spec =
e->offset_r_spec = 0.0f;
6538 e->offset_l =
e->offset_l_spec;
6539 e->offset_r =
e->offset_r_spec;
6541 if (
e->fprev &&
e->fnext) {
6550 if (tot_wire != 0) {
6567 bool do_rebuild =
false;
6587 if (
e->prev == eprev) {
6588 if (eprev->
prev ==
e) {
6590 go_ccw = (
e->fnext != f);
6596 else if (eprev->
prev ==
e) {
6611 bool on_profile_start =
false;
6617 if (
e->profile_index > 0) {
6618 vstart = vstart->
prev;
6619 on_profile_start =
true;
6623 vstart = eprev->
leftv;
6626 vstart = vstart->
next;
6627 on_profile_start =
true;
6630 BLI_assert(vstart !=
nullptr && vend !=
nullptr);
6632 if (!on_profile_start) {
6642 if (on_profile_start) {
6643 kstart =
e->profile_index;
6644 on_profile_start =
false;
6655 for (
int k = kstart; k <= kend; k++) {
6660 if (corner3special &&
v->ebev && !bv->
any_seam && k != vm->
seg) {
6669 int i =
v->prev->index;
6671 if (on_profile_start) {
6673 on_profile_start =
false;
6676 kstart = vm->
seg - 1;
6678 if (
e->rightv ==
v->prev &&
e->profile_index > 0) {
6679 kend =
e->profile_index;
6684 for (
int k = kstart; k >= kend; k--) {
6689 if (corner3special &&
v->ebev && !bv->
any_seam && k != 0) {
6714 BMEdge *bme_prev = ee[n - 1];
6715 for (
int k = 0; k < n; k++) {
6718 if (ee[k] != bme_new) {
6722 if (k < n - 1 && ee[k] == ee[k + 1]) {
6771 int faces_len, f_index;
6775 if (
LIKELY(faces !=
nullptr)) {
6776 for (f_index = 0; f_index < faces_len; f_index++) {
6777 BMFace *f = faces[f_index];
6783 if (faces != (
BMFace **)faces_stack) {
6797 for (
int i = 0; i < bv->
wirecount; i++) {
6800 BMVert *vclosest =
nullptr;
6802 BMVert *votherclosest =
nullptr;
6807 if (!bvother || !bvother->
vmesh) {
6818 vclosest = bndv->
nv.
v;
6819 votherclosest = bndvother->
nv.
v;
6827 vclosest = bndv->
nv.
v;
6828 votherclosest = vother;
6844 int i =
e->leftv->index;
6845 for (
int k = 1; k < nseg; k++) {
6882 BMEdge *bme_prev =
nullptr;
6883 BMEdge *bme_next =
nullptr;
6884 for (
int i = 0; i < 4; i++) {
6885 if (&bv->
edges[i] ==
e) {
6886 bme_prev = bv->
edges[(i + 3) % 4].
e;
6887 bme_next = bv->
edges[(i + 1) % 4].
e;
6900 for (
int i = 0; i < nseg; i++) {
6908 if (enable_smooth) {
6957 BMFace *faces[4] = {f1, f1, f2, f2};
6969 BMEdge *center_bme =
nullptr;
6970 BMFace *fchoices[2] = {f1, f2};
6971 BMFace *f_choice =
nullptr;
6972 int center_adj_k = -1;
6976 center_adj_k = f_choice == f1 ? mid + 2 : mid;
6979 for (
int k = 1; k <= nseg; k++) {
6983 if (odd && k == mid + 1) {
6989 if (f_choice == f1) {
6990 edges[0] = edges[1] =
nullptr;
6991 edges[2] = edges[3] = bme;
6994 edges[0] = edges[1] = bme;
6995 edges[2] = edges[3] =
nullptr;
7004 else if (odd && k == center_adj_k && e1->
is_seam) {
7012 edges[0] = edges[1] =
nullptr;
7013 edges[2] = edges[3] = bme;
7017 edges[0] = edges[1] = bme;
7018 edges[2] = edges[3] =
nullptr;
7023 else if (!odd && k == mid) {
7025 BMEdge *edges[4] = {
nullptr,
nullptr, bme, bme};
7030 else if (!odd && k == mid + 1) {
7032 BMEdge *edges[4] = {bme, bme,
nullptr,
nullptr};
7037 BMFace *f = (k <= mid) ? f1 : f2;
7093 const double tol = 1
e-13;
7094 const int maxiter = 10;
7097 double xmin = x0 +
M_SQRT2 / 2.0 * dtarget;
7101 double xmax = x0 + dtarget;
7109 double dmaxerr =
sqrt(
pow((xmax - x0), 2) +
pow((ymax - y0), 2)) - dtarget;
7110 double dminerr =
sqrt(
pow((xmin - x0), 2) +
pow((ymin - y0), 2)) - dtarget;
7112 double xnew = xmax - dmaxerr * (xmax - xmin) / (dmaxerr - dminerr);
7113 bool lastupdated_upper =
true;
7115 for (
int iter = 0; iter < maxiter; iter++) {
7117 double dnewerr =
sqrt(
pow((xnew - x0), 2) +
pow((ynew - y0), 2)) - dtarget;
7118 if (
fabs(dnewerr) < tol) {
7125 if (!lastupdated_upper) {
7126 xnew = (dmaxerr / 2 * xmin - dminerr * xmax) / (dmaxerr / 2 - dminerr);
7129 xnew = xmax - dmaxerr * (xmax - xmin) / (dmaxerr - dminerr);
7131 lastupdated_upper =
false;
7137 if (lastupdated_upper) {
7138 xnew = (dmaxerr * xmin - dminerr / 2 * xmax) / (dmaxerr - dminerr / 2);
7141 xnew = xmax - dmaxerr * (xmax - xmin) / (dmaxerr - dminerr);
7143 lastupdated_upper =
true;
7160 const int smoothitermax = 10;
7161 const double error_tol = 1
e-7;
7162 int imax = (seg + 1) / 2 - 1;
7164 bool seg_odd = seg % 2;
7170 mx =
pow(0.5, 1.0 / r);
7174 mx = 1 -
pow(0.5, 1.0 / r);
7178 for (
int i = 0; i <= imax; i++) {
7179 xvals[i] = i * mx / seg * 2;
7185 for (
int iter = 0; iter < smoothitermax; iter++) {
7192 for (
int i = 0; i < imax; i++) {
7193 double d =
sqrt(
pow((xvals[i + 1] - xvals[i]), 2) +
pow((yvals[i + 1] - yvals[i]), 2));
7205 sum +=
M_SQRT2 / 2 * (yvals[imax] - xvals[imax]);
7206 davg =
sum / (imax + 0.5);
7209 sum +=
sqrt(
pow((xvals[imax] - mx), 2) +
pow((yvals[imax] - mx), 2));
7210 davg =
sum / (imax + 1.0);
7213 bool precision_reached =
true;
7214 if (dmax - davg > error_tol) {
7215 precision_reached =
false;
7217 if (dmin - davg < error_tol) {
7218 precision_reached =
false;
7220 if (precision_reached) {
7225 for (
int i = 1; i <= imax; i++) {
7233 xvals[imax + 1] = mx;
7234 yvals[imax + 1] = mx;
7236 for (
int i = imax + 1; i <= seg; i++) {
7237 yvals[i] = xvals[seg - i];
7238 xvals[i] = yvals[seg - i];
7242 for (
int i = 0; i <= seg; i++) {
7243 double temp = xvals[i];
7244 xvals[i] = 1.0 - yvals[i];
7245 yvals[i] = 1.0 - temp;
7260 bool seg_odd = n % 2;
7266 for (
int i = 0; i <= n; i++) {
7267 xvals[i] =
double(i) / n;
7268 yvals[i] = 1.0 -
double(i) / n;
7273 double temp =
M_PI_2 / n;
7275 for (
int i = 0; i <= n; i++) {
7276 xvals[i] = sin(i * temp);
7277 yvals[i] =
cos(i * temp);
7284 for (
int i = 0; i <= n2; i++) {
7286 yvals[i] = 1.0 -
double(i) / n2;
7287 xvals[n - i] = yvals[i];
7288 yvals[n - i] = xvals[i];
7293 double temp = 1.0 / (n2 +
M_SQRT2 / 2.0);
7294 for (
int i = 0; i <= n2; i++) {
7296 yvals[i] = 1.0 -
double(i) * temp;
7297 xvals[n - i] = yvals[i];
7298 yvals[n - i] = xvals[i];
7306 for (
int i = 0; i <= n2; i++) {
7307 xvals[i] =
double(i) / n2;
7309 xvals[n - i] = yvals[i];
7310 yvals[n - i] = xvals[i];
7315 double temp = 1.0 / (n2 +
M_SQRT2 / 2);
7316 for (
int i = 0; i <= n2; i++) {
7317 xvals[i] =
double(i) * temp;
7319 xvals[n - i] = yvals[i];
7320 yvals[n - i] = xvals[i];
7339#define CIRCLE_FULLNESS_SEGS 11
7358 for (
int i = 0; i < nseg; i++) {
7369 fullness = circle_fullness[nseg - 1];
7373 if (nseg % 2 == 0) {
7374 fullness = 2.4506f * bp->
profile - 0.00000300f * nseg - 0.6266f;
7377 fullness = 2.3635f * bp->
profile + 0.000152f * nseg - 0.6060f;
7401 pro_spacing->
xvals =
nullptr;
7402 pro_spacing->
yvals =
nullptr;
7403 pro_spacing->
xvals_2 =
nullptr;
7404 pro_spacing->
yvals_2 =
nullptr;
7405 pro_spacing->
seg_2 = 0;
7419 sizeof(
double) * (seg_2 + 1));
7421 sizeof(
double) * (seg_2 + 1));
7427 for (
int i = 0; i < seg_2 + 1; i++) {
7448 for (
int i = 0; i < seg + 1; i++) {
7483 float no_collide_offset = bp->
offset + 1e6;
7484 float limit = no_collide_offset;
7485 if (bp->
offset == 0.0f) {
7486 return no_collide_offset;
7513 return bp->
offset > blen / 2.0f ? blen / 2.0f : blen;
7515 return no_collide_offset;
7517 if (ebother !=
nullptr) {
7528 if (eb->
fnext ==
nullptr) {
7529 return no_collide_offset;
7533 return no_collide_offset;
7535 if (lb->
next->
v == vc) {
7538 else if (lb->
v == vc) {
7542 return no_collide_offset;
7545 if (ea->
e == eb->
e || (ec && ec->
e == eb->
e)) {
7546 return no_collide_offset;
7557 float sin1 =
sinf(th1);
7558 float sin2 =
sinf(th2);
7559 if ((ka > 0.0f) + (kb > 0.0f) + (kc > 0.0f) >= 2) {
7560 float tan1 =
tanf(th1);
7561 float tan2 =
tanf(th2);
7562 float g = tan1 * tan2;
7563 float h = sin1 * sin2;
7564 float den = g * (ka * sin2 + kc * sin1) + kb * h * (tan1 + tan2);
7575 if (kb > 0.0f && ka == 0.0f ) {
7578 if (t >= 0.0f && t < limit) {
7582 if (kb > 0.0f && kc == 0.0f ) {
7585 if (t >= 0.0f && t < limit) {
7599 float no_collide_offset = bp->
offset + 1e6;
7600 if (bp->
offset == 0.0f) {
7601 return no_collide_offset;
7606 float kab = ka + kb;
7609 return no_collide_offset;
7621 float limited_offset = bp->
offset;
7632 for (
int i = 0; i < bv->
edgecount; i++) {
7636 if (collision_offset < limited_offset) {
7637 limited_offset = collision_offset;
7642 if (collision_offset < limited_offset) {
7643 limited_offset = collision_offset;
7649 if (limited_offset < bp->offset) {
7655 float offset_factor = limited_offset / bp->
offset;
7664 for (
int i = 0; i < bv->
edgecount; i++) {
7672 bp->
offset = limited_offset;
7678 const int offset_type,
7679 const int profile_type,
7681 const float profile,
7682 const bool affect_type,
7683 const bool use_weights,
7684 const bool limit_offset,
7686 const int vertex_group,
7688 const bool loop_slide,
7689 const bool mark_seam,
7690 const bool mark_sharp,
7691 const bool harden_normals,
7692 const int face_strength_mode,
7693 const int miter_outer,
7694 const int miter_inner,
7697 const int vmesh_method,
7698 const int bweight_offset_vert,
7699 const int bweight_offset_edge)
7710 bp.offset_type = offset_type;
7711 bp.seg =
max_ii(segments, 1);
7712 bp.profile = profile;
7714 bp.affect_type = affect_type;
7715 bp.use_weights = use_weights;
7716 bp.bweight_offset_vert = bweight_offset_vert;
7717 bp.bweight_offset_edge = bweight_offset_edge;
7718 bp.loop_slide = loop_slide;
7719 bp.limit_offset = limit_offset;
7723 bp.vertex_group = vertex_group;
7725 bp.mark_seam = mark_seam;
7726 bp.mark_sharp = mark_sharp;
7727 bp.harden_normals = harden_normals;
7728 bp.face_strength_mode = face_strength_mode;
7729 bp.miter_outer = miter_outer;
7730 bp.miter_inner = miter_inner;
7732 bp.face_hash =
nullptr;
7733 bp.profile_type = profile_type;
7734 bp.custom_profile = custom_profile;
7735 bp.vmesh_method = vmesh_method;
7737 if (bp.offset <= 0) {
7741#ifdef BEVEL_DEBUG_TIME
7751 if (profile >= 0.950f) {
7760 else if (bp.pro_super_r < 1
e-4) {
7793 if (!limit_offset && bv) {
7815 if (bp.offset_adjust) {
7872 if (bp.harden_normals) {
7909#ifdef BEVEL_DEBUG_TIME
7911 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_offset(const CustomData *data, eCustomDataType type)
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_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 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)
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_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])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct 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_use_calloc(struct 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)
typedef double(DMatrix)[4][4]
#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 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 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 bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v)
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 void bev_merge_edge_uvs(BMesh *bm, BMEdge *bme, 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 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)
static void bev_merge_end_uvs(BMesh *bm, BevVert *bv, EdgeHalf *e)
#define HASNOT_SEAMSHARP(eh, flag)
static bool edge_edge_angle_less_than_180(const BMEdge *e1, const BMEdge *e2, const BMFace *f)
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 int count_bound_vert_seams(BevVert *bv)
static VMesh * make_cube_corner_square_in(MemArena *mem_arena, int nseg)
static bool offset_meet_edge(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, float meetco[3], float *r_angle)
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 BMFace * bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMFace **face_arr, BMFace *facerep, BMEdge **snap_edge_arr, int mat_nr, bool do_interp)
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 bev_merge_uvs(BMesh *bm, BMVert *v)
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 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)
#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)
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)
#define CIRCLE_FULLNESS_SEGS
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_DEFAULT_ITER_STACK_SIZE
#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 char *name)
void BM_loop_interp_from_face(BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
void * BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len, void **stack_array, int stack_array_size)
Iterator as Array.
#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)
ATTR_WARN_UNUSED_RESULT BMesh * bm
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_PROFILE_SUPERELLIPSE
@ BEVEL_FACE_STRENGTH_NONE
@ BEVEL_FACE_STRENGTH_AFFECTED
@ BEVEL_FACE_STRENGTH_NEW
@ BEVEL_FACE_STRENGTH_ALL
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
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(float x, ccl_private int *ix)
draw_view in_light_buf[] float
blender::gpu::Batch * quad
void EIG_linear_solver_print_matrix(LinearSolver *solver)
LinearSolver * EIG_linear_least_squares_solver_new(int num_rows, int num_columns, int num_rhs)
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value)
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_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 cos(float3 v)
vector snap(vector a, vector b)
struct BMLoop * radial_next
struct MLoopNorSpaceArray * lnor_spacearr
MathLayerInfo math_layer_info
ProfileSpacing pro_spacing
ProfileSpacing pro_spacing_miter
const MDeformVert * dvert
const CurveProfile * custom_profile
CurveProfilePoint * segments
MLoopNorSpace ** lspacearr
ccl_device_inline float beta(float x, float y)