57 const float *v_prev = l_first->
prev->
v->
co;
58 const float *v_curr = l_first->
v->
co;
66 l_iter = l_iter->
next;
68 v_curr = l_iter->
v->
co;
70 }
while (l_iter != l_first);
96 l_iter = l_iter->
next;
99 }
while (l_iter != l_first);
110 const BMLoop *l_first, *l_iter;
118 }
while ((l_iter = l_iter->
next) != l_first);
123 const bool use_fixed_quad,
131 *r_loops++ = (l_iter = l_first);
132 *r_loops++ = (l_iter = l_iter->
next);
133 *r_loops++ = (l_iter->
next);
139 else if (f->
len == 4 && use_fixed_quad) {
140 *r_loops++ = (l_iter = l_first);
141 *r_loops++ = (l_iter = l_iter->
next);
142 *r_loops++ = (l_iter = l_iter->
next);
143 *r_loops++ = (l_iter->
next);
154 float axis_mat[3][3];
166 }
while ((l_iter = l_iter->
next) != l_first);
184 const int tottri = f->
len - 2;
189 float area_best = -1.0f;
193 for (j = 0; j < tottri; j++) {
194 const float *p1 = loops[index[j][0]]->
v->
co;
195 const float *p2 = loops[index[j][1]]->
v->
co;
196 const float *p3 = loops[index[j][2]]->
v->
co;
198 if (area > area_best) {
205 ltri, loops[index[j_best][0]], loops[index[j_best][1]], loops[index[j_best][2]]);
214 const BMLoop *l_iter, *l_first;
221 }
while ((l_iter = l_iter->
next) != l_first);
228 const BMLoop *l_iter, *l_first;
240 }
while ((l_iter = l_iter->
next) != l_first);
247 const BMLoop *l_iter, *l_first;
256 cross += (luv_next[0] - luv[0]) * (luv_next[1] + luv[1]);
257 }
while ((l_iter = l_iter->
next) != l_first);
268 const BMLoop *l_iter, *l_first;
269 float perimeter = 0.0f;
274 }
while ((l_iter = l_iter->
next) != l_first);
281 const BMLoop *l_iter, *l_first;
283 float perimeter = 0.0f;
292 }
while ((l_iter = l_iter->
next) != l_first);
308 for (
int i_prev = 1, i_curr = 2, i_next = 0; i_next < 3; i_prev = i_curr, i_curr = i_next++) {
309 const float *co =
verts[i_curr]->co;
310 const float *co_other[2] = {
verts[i_prev]->co,
verts[i_next]->co};
315 float proj_pair[2][3];
321 const float lens[3] = {
326 const float difs[3] = {
327 fabsf(lens[1] - lens[2]),
328 fabsf(lens[2] - lens[0]),
329 fabsf(lens[0] - lens[1]),
333 int order[3] = {0, 1, 2};
342 const int index_next = (index + 1) % 3;
349 float r_tangent_a[3],
350 float r_tangent_b[3])
353 const int index_next = (index + 1) % 3;
354 const int index_prev = (index_next + 1) % 3;
360 float vec_prev[3], vec_next[3];
361 float tmp_prev[3], tmp_next[3];
377 const float *v_a =
verts[index]->co;
378 const float *v_b =
verts[(index + 1) % 3]->co;
379 const float *v_other =
verts[(index + 2) % 3]->co;
399 float vec[3], vec_a[3], vec_b[3];
418 float r_tangent_a[3],
419 float r_tangent_b[3])
423 float vec_a[3], vec_b[3];
442 float r_tangent_a[3],
443 float r_tangent_b[3])
451 float vec_prev[3], vec_next[3];
452 float tmp_prev[3], tmp_next[3];
473 else if (f->
len == 4) {
475 float r_tangent_dummy[3];
481 BMLoop *l_long_other =
nullptr;
483 float len_max_sq = 0.0f;
484 float vec_a[3], vec_b[3];
491 if (len_sq >= len_max_sq) {
492 l_long_other = l_iter;
495 }
while ((l_iter = l_iter->
prev) != l_last);
520 float dist_max_sq = 0.0f;
526 float co_other[3], vec[3];
528 co_other, l_iter->
v->
co, l_iter_other->
v->
co, l_iter_other->
next->
v->
co);
532 if (dist_sq > dist_max_sq) {
533 dist_max_sq = dist_sq;
536 }
while ((l_iter_other = l_iter_other->
next) != l_iter_last);
537 }
while ((l_iter = l_iter->
next) != l_first);
552 float dist_max_sq = 0.0f;
560 if (dist_sq > dist_max_sq) {
561 dist_max_sq = dist_sq;
564 }
while ((l_iter_other = l_iter_other->
next) != l_iter);
565 }
while ((l_iter = l_iter->
next) != l_first);
578 else if (f->
len == 4) {
596 else if (f->
len == 4) {
608 const BMLoop *l_iter, *l_first;
612 }
while ((l_iter = l_iter->
next) != l_first);
617 const BMLoop *l_iter, *l_first;
625 }
while ((l_iter = l_iter->
next) != l_first);
639 const BMLoop *l_iter, *l_first;
647 }
while ((l_iter = l_iter->
next) != l_first);
654 const BMLoop *l_iter, *l_first;
661 }
while ((l_iter = l_iter->
next) != l_first);
678 const float w = (w_curr + w_prev);
682 }
while ((l_iter = l_iter->
next) != l_first);
698 for (
i = 0;
i < nverts;
i++) {
719 float vec1[3], vec2[3], fac;
750 }
while ((
l =
l->radial_next) !=
e->l);
778 }
while ((
l =
l->radial_next) !=
e->l);
807 }
while ((
l =
l->radial_next) !=
e->l);
830 const float *co2 = (
l =
l->next)->
v->co;
831 const float *co3 = (
l =
l->next)->
v->co;
832 const float *co4 = (
l->next)->
v->co;
838 const float *co2 = (
l =
l->next)->
v->co;
839 const float *co3 = (
l->next)->
v->co;
888 BMVert **varr,
int varr_len,
float r_normal[3],
float r_center[3],
int *r_index_tangent)
890 const float varr_len_inv = 1.0f /
float(varr_len);
893 float center[3] = {0.0f, 0.0f, 0.0f};
894 for (
int i = 0;
i < varr_len;
i++) {
900 const float *co_a =
nullptr;
902 float dist_sq_max = -1.0f;
903 for (
int i = 0;
i < varr_len;
i++) {
905 if (!(dist_sq_test <= dist_sq_max)) {
908 dist_sq_max = dist_sq_test;
917 const float *co_b =
nullptr;
918 float dir_b[3] = {0.0f, 0.0f, 0.0f};
920 float dist_sq_max = -1.0f;
921 for (
int i = 0;
i < varr_len;
i++) {
922 if (varr[
i]->co == co_a) {
929 if (!(dist_sq_test <= dist_sq_max)) {
931 dist_sq_max = dist_sq_test;
945 const float *co_a_opposite =
nullptr;
946 const float *co_b_opposite =
nullptr;
951 for (
int i = 0;
i < varr_len;
i++) {
952 const float *co_test = varr[
i]->
co;
955 if (co_test != co_a) {
956 dot_test =
dot_v3v3(dir_a, co_test);
957 if (dot_test < dot_a_min) {
958 dot_a_min = dot_test;
959 co_a_opposite = co_test;
963 if (co_test != co_b) {
964 dot_test =
dot_v3v3(dir_b, co_test);
965 if (dot_test < dot_b_min) {
966 dot_b_min = dot_test;
967 co_b_opposite = co_test;
973 normal_quad_v3(r_normal, co_a, co_b, co_a_opposite, co_b_opposite);
977 if (r_center !=
nullptr) {
980 if (r_index_tangent !=
nullptr) {
981 *r_index_tangent = co_a_index;
992 const float *v_prev, *v_curr;
995 const BMLoop *l_iter = l_first;
1000 v_prev = l_last->
v->
co;
1002 v_curr = l_iter->
v->
co;
1005 }
while ((l_iter = l_iter->
next) != l_term);
1024 const int cd_loop_mdisp_offset,
1025 const bool use_loop_mdisp_flip)
1039 float axis_mat[3][3];
1062 int *r_faces_new_tot,
1064 int *r_edges_new_tot,
1066 const int quad_method,
1067 const int ngon_method,
1085 BLI_assert((r_faces_new ==
nullptr) == (r_faces_new_tot ==
nullptr));
1092 const int totfilltri = f->
len - 2;
1093 const int last_tri = f->
len - 3;
1105 switch (quad_method) {
1112 l_v1 = l_first->
next;
1113 l_v2 = l_first->
prev;
1123 l_v1 = l_first->
next;
1125 l_v3 = l_first->
prev;
1132 split_24 = ((d2 - d1) > 0.0f);
1138 split_24 = ((d2 - d1) < 0.0f);
1144 if (
UNLIKELY(flip_flag & (1 << 0))) {
1147 else if (
UNLIKELY(flip_flag & (1 << 1))) {
1170 loops[1] = l_v1->
next;
1172 loops[3] = l_v2->
next;
1179 float axis_mat[3][3];
1198 if (cd_loop_mdisp_offset != -1) {
1203 for (
i = 0;
i < totfilltri;
i++) {
1204 BMLoop *ltri[3] = {loops[tris[
i][0]], loops[tris[
i][1]], loops[tris[
i][2]]};
1206 BMVert *v_tri[3] = {ltri[0]->
v, ltri[1]->
v, ltri[2]->
v};
1222 }
while ((l_iter = l_iter->
radial_next) != l_new);
1231 if (
i != last_tri) {
1236 r_faces_new[nf_i++] = f_new;
1240 if (use_tag || r_edges_new) {
1244 l_iter = l_first = l_new;
1249 bool is_new_edge = (l_iter == l_iter->
radial_next);
1256 r_edges_new[ne_i++] =
e;
1260 }
while ((l_iter = l_iter->
next) != l_first);
1263 if (cd_loop_mdisp_offset != -1) {
1264 float f_new_center[3];
1279 if (r_faces_new_tot) {
1280 *r_faces_new_tot = nf_i;
1283 if (r_edges_new_tot) {
1284 *r_edges_new_tot = ne_i;
1290 float center[2] = {0.0f, 0.0f};
1291 float axis_mat[3][3];
1321 for (
i = 0;
i <
len;
i++) {
1330 for (
i = 0;
i <
len;
i++) {
1333 const float *co_pair[2] = {
1351 const int limit_init = f->
len - 3;
1355 l_prev = l_prev->
prev;
1359 l_next = l_next->
next;
1366 const float2 dir_other = side == 0 ? pair_dir : -pair_dir;
1371 loops[
i][0] =
nullptr;
1377#define EDGE_SHARE_VERT(e1, e2) \
1378 (ELEM((e1)[0], (e2)[0], (e2)[1]) || ELEM((e1)[1], (e2)[0], (e2)[1]))
1382 const float *f_edge[2] = {projverts[i_prev], projverts[
i]};
1383 for (j = 0; j <
len; j++) {
1384 if ((loops[j][0] !=
nullptr) && !
EDGE_SHARE_VERT(f_edge, edgeverts[j])) {
1386 loops[j][0] =
nullptr;
1393 for (
i = 0;
i <
len;
i++) {
1395 for (j =
i + 1; j <
len; j++) {
1396 if ((loops[j][0] !=
nullptr) && !
EDGE_SHARE_VERT(edgeverts[
i], edgeverts[j])) {
1400 loops[
i][0] =
nullptr;
1408#undef EDGE_SHARE_VERT
1415 for (
i = 0;
i <
len;
i++) {
1416 BMLoop *l_a_dummy, *l_b_dummy;
1418 loops[
i][0]->
v, loops[
i][1]->
v, &l_a_dummy, &l_b_dummy,
false))
1420 loops[
i][0] =
nullptr;
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
#define BLI_array_alloca(arr, realsize)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
bool isect_point_poly_v2(const float pt[2], const float verts[][2], unsigned int nr)
float closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
float area_squared_tri_v3(const float v1[3], const float v2[3], const float v3[3])
bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
#define ISECT_LINE_LINE_CROSS
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
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
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v2_v2(float r[2], const float a[2])
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 add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
MINLINE void add_v2_v2(float r[2], const float a[2])
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
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 bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void negate_v3(float r[3])
float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
void BLI_polyfill_calc(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3])
void BLI_polyfill_calc_arena(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3], struct MemArena *arena)
void BLI_polyfill_beautify(const float(*coords)[2], unsigned int coords_num, unsigned int(*tris)[3], struct MemArena *arena, struct Heap *eheap)
#define INIT_MINMAX(min, max)
#define ARRAY_SET_ITEMS(...)
@ MOD_TRIANGULATE_QUAD_SHORTEDGE
@ MOD_TRIANGULATE_QUAD_FIXED
@ MOD_TRIANGULATE_QUAD_LONGEDGE
@ MOD_TRIANGULATE_QUAD_BEAUTY
@ MOD_TRIANGULATE_QUAD_ALTERNATE
@ MOD_TRIANGULATE_NGON_BEAUTY
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
float BM_verts_calc_rotate_beauty(const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4, const short flag, const short method)
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
void BM_elem_attrs_copy(BMesh *bm, const BMCustomDataCopyMap &map, const BMVert *src, BMVert *dst)
void bmesh_face_swap_data(BMFace *f_a, BMFace *f_b)
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)
void bmesh_kernel_loop_reverse(BMesh *bm, BMFace *f, const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
Loop Reverse.
#define BM_elem_index_get(ele)
#define BM_elem_index_set(ele, index)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
void BM_face_interp_multires_ex(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset)
#define BM_ITER_ELEM(ele, iter, data, itype)
void BM_face_calc_tangent_from_vert_diagonal(const BMFace *f, float r_tangent[3])
void BM_face_as_array_loop_tri(BMFace *f, BMLoop *r_loops[3])
static void bm_face_calc_tangent_from_quad_edge_pair(const BMFace *f, float r_tangent[3])
void BM_face_calc_tangent_pair_from_edge(const BMFace *f, float r_tangent_a[3], float r_tangent_b[3])
float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset)
void poly_rotate_plane(const float normal[3], float(*verts)[3], const uint nverts)
POLY ROTATE PLANE.
void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len)
void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
static void bm_face_calc_poly_center_median_vertex_cos(const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
COMPUTE POLY CENTER (BMFace).
void BM_vert_normal_update(BMVert *v)
void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
static void bm_face_calc_tangent_pair_from_quad_edge_pair(const BMFace *f, float r_tangent_a[3], float r_tangent_b[3])
void BM_face_calc_tangent_from_edge_pair(const BMFace *f, float r_tangent[3])
void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4])
static int bm_vert_tri_find_unique_edge(BMVert *verts[3])
float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3])
void BM_face_calc_point_in_face(const BMFace *f, float r_co[3])
void BM_verts_calc_normal_from_cloud(BMVert **varr, int varr_len, float r_normal[3])
bool BM_face_point_inside_test(const BMFace *f, const float co[3])
float BM_face_calc_area_uv_signed(const BMFace *f, int cd_loop_uv_offset)
bool BM_vert_calc_normal(const BMVert *v, float r_no[3])
static float angle_signed_v2v2_pos(const float v1[2], const float v2[2])
void BM_vert_tri_calc_tangent_from_edge(BMVert *verts[3], float r_tangent[3])
void BM_vert_tri_calc_tangent_pair_from_edge(BMVert *verts[3], float r_tangent_a[3], float r_tangent_b[3])
void BM_face_calc_center_bounds_vcos(const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
void BM_face_normal_flip_ex(BMesh *bm, BMFace *f, const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
Face Flip Normal.
void BM_face_normal_update(BMFace *f)
void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3])
bool BM_vert_calc_normal_ex(const BMVert *v, const char hflag, float r_no[3])
void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4])
float BM_face_calc_normal_vcos(const BMesh *bm, const BMFace *f, float r_no[3], const Span< float3 > vertexCos)
void BM_face_normal_flip(BMesh *bm, BMFace *f)
void BM_face_calc_center_median_vcos(const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
void BM_verts_calc_normal_from_cloud_ex(BMVert **varr, int varr_len, float r_normal[3], float r_center[3], int *r_index_tangent)
void BM_face_calc_bounds_expand(const BMFace *f, float min[3], float max[3])
float BM_face_calc_area(const BMFace *f)
#define EDGE_SHARE_VERT(e1, e2)
float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3])
float BM_face_calc_normal(const BMFace *f, float r_no[3])
BMESH UPDATE FACE NORMAL.
float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float mat3[3][3])
void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **r_faces_new, int *r_faces_new_tot, BMEdge **r_edges_new, int *r_edges_new_tot, LinkNode **r_faces_double, const int quad_method, const int ngon_method, const bool use_tag, MemArena *pf_arena, Heap *pf_heap)
static float bm_face_calc_poly_normal_vertex_cos(const BMFace *f, float r_no[3], const Span< float3 > vertexCos)
COMPUTE POLY NORMAL (BMFace).
void BM_face_calc_tangent_from_edge(const BMFace *f, float r_tangent[3])
static void bm_loop_normal_accum(const BMLoop *l, float no[3])
void BM_vert_tri_calc_tangent_edge_pair(BMVert *verts[3], float r_tangent[3])
void BM_face_calc_tessellation(const BMFace *f, const bool use_fixed_quad, BMLoop **r_loops, uint(*r_index)[3])
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
void BM_face_calc_tangent_auto(const BMFace *f, float r_tangent[3])
static float bm_face_calc_poly_normal(const BMFace *f, float n[3])
COMPUTE POLY NORMAL (BMFace).
void BM_face_calc_tangent_from_edge_diagonal(const BMFace *f, float r_tangent[3])
void BM_face_calc_center_median_weighted(const BMFace *f, float r_cent[3])
void BM_vert_normal_update_all(BMVert *v)
void BM_face_calc_tangent_pair_auto(const BMFace *f, float r_tangent_a[3], float r_tangent_b[3])
float BM_face_calc_perimeter(const BMFace *f)
void BM_edge_normals_update(BMEdge *e)
bool BM_face_is_normal_valid(const BMFace *f)
BMFace * BM_vert_pair_share_face_by_angle(BMVert *v_a, BMVert *v_b, BMLoop **r_l_a, BMLoop **r_l_b, const bool allow_adjacent)
BMLoop * BM_face_find_longest_loop(BMFace *f)
float BM_edge_calc_length(const BMEdge *e)
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
BLI_INLINE BMEdge * bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float safe_acos_approx(float x)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< float, 2 > float2
VecBase< float, 3 > float3
struct BMLoop * radial_next