Page MenuHome
Paste P434

Possible fix for T50165
ActivePublic

Authored by Kenrick (Prototype) on Jan 8 2017, 12:19 AM.
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 6ce7c10..56548d1 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -105,6 +105,16 @@ static void normalize_v2_m3_v3v3(float out[2], float axis_mat[3][3], const float
normalize_v2(out);
}
+static float angle_clockwise_v2v2(const float v1[2], const float v2[2]) {
+ float angle = dot_v2v2(v1, v2);
+
+ /* same formula as line_point_side_v2() with the first argument zero */
+ if (((v1[0] - v2[0]) * v2[1]) > (v2[0] * (v1[1] - v2[1]))) {
+ return angle;
+ } else {
+ return -2 - angle;
+ }
+}
/**
* \note Be sure to update #bm_face_split_edgenet_find_loop_pair_exists
@@ -152,33 +162,32 @@ static bool bm_face_split_edgenet_find_loop_pair(
}
e_pair[0] = BLI_SMALLSTACK_POP(edges_boundary);
- /* use to hold boundary OR wire edges */
- BLI_SMALLSTACK_DECLARE(edges_search, BMEdge *);
-
/* attempt one boundary and one wire, or 2 boundary */
- if (edges_wire_len == 0) {
- if (edges_boundary_len > 1) {
- e_pair[1] = BLI_SMALLSTACK_POP(edges_boundary);
-
- if (edges_boundary_len > 2) {
- BLI_SMALLSTACK_SWAP(edges_search, edges_boundary);
- }
- }
- else {
- /* one boundary and no wire */
- return false;
- }
+ if (edges_wire_len > 0) {
+ /* use one boundary and one wire */
+ e_pair[1] = BLI_SMALLSTACK_POP(edges_wire);
+ }
+ else if (edges_boundary_len > 1) {
+ /* use 2 boundaries */
+ e_pair[1] = BLI_SMALLSTACK_POP(edges_boundary);
}
else {
- e_pair[1] = BLI_SMALLSTACK_POP(edges_wire);
- if (edges_wire_len > 1) {
- BLI_SMALLSTACK_SWAP(edges_search, edges_wire);
- }
+ /* one boundary and no wire */
+ return false;
+ }
+
+ /* flip based on winding */
+ l_walk = bm_edge_flagged_radial_first(e_pair[0]);
+ swap = false;
+ if (face_normal == l_walk->f->no) {
+ swap = !swap;
+ }
+ if (l_walk->v != v_init) {
+ swap = !swap;
}
- /* if we swapped above, search this list for the best edge */
- if (!BLI_SMALLSTACK_IS_EMPTY(edges_search)) {
- /* find the best edge in 'edge_list' to use for 'e_pair[1]' */
+ /* if there are more edges, search for the best edge to use for 'e_pair[1]'*/
+ if (edges_wire_len > 1 || edges_boundary_len > 2) {
const BMVert *v_prev = BM_edge_other_vert(e_pair[0], v_init);
const BMVert *v_next = BM_edge_other_vert(e_pair[1], v_init);
@@ -186,32 +195,23 @@ static bool bm_face_split_edgenet_find_loop_pair(
normalize_v2_m3_v3v3(dir_prev, face_normal_matrix, v_prev->co, v_init->co);
normalize_v2_m3_v3v3(dir_next, face_normal_matrix, v_next->co, v_init->co);
- float angle_best_cos = dot_v2v2(dir_next, dir_prev);
+ float angle_best_cos = angle_clockwise_v2v2(dir_prev, dir_next);
BMEdge *e;
- while ((e = BLI_SMALLSTACK_POP(edges_search))) {
+ while ((e = BLI_SMALLSTACK_POP(edges_boundary)) || (e = BLI_SMALLSTACK_POP(edges_wire))) {
v_next = BM_edge_other_vert(e, v_init);
float dir_test[2];
normalize_v2_m3_v3v3(dir_test, face_normal_matrix, v_next->co, v_init->co);
- const float angle_test_cos = dot_v2v2(dir_prev, dir_test);
+ const float angle_test_cos = angle_clockwise_v2v2(dir_prev, dir_test);
- if (angle_test_cos > angle_best_cos) {
+ if (swap ? (angle_test_cos > angle_best_cos) : (angle_test_cos < angle_best_cos)) {
angle_best_cos = angle_test_cos;
e_pair[1] = e;
}
}
}
- /* flip based on winding */
- l_walk = bm_edge_flagged_radial_first(e_pair[0]);
- swap = false;
- if (face_normal == l_walk->f->no) {
- swap = !swap;
- }
- if (l_walk->v != v_init) {
- swap = !swap;
- }
if (swap) {
SWAP(BMEdge *, e_pair[0], e_pair[1]);
}
@@ -255,18 +255,16 @@ static bool bm_face_split_edgenet_find_loop_pair_exists(
}
/* attempt one boundary and one wire, or 2 boundary */
- if (edges_wire_len == 0) {
- if (edges_boundary_len >= 2) {
- /* pass */
- }
- else {
- /* one boundary and no wire */
- return false;
- }
+ if (edges_wire_len > 0) {
+ /* pass */
}
- else {
+ else if (edges_boundary_len > 1) {
/* pass */
}
+ else {
+ /* one boundary and no wire */
+ return false;
+ }
return true;
}
@@ -978,8 +976,8 @@ static int bm_face_split_edgenet_find_connection(
for (int j = 0; j < 2; j++) {
BMVert *v_iter = v_pair[j];
if (BM_elem_flag_test(v_iter, VERT_IS_VALID)) {
- if (direction_sign ? (v_iter->co[SORT_AXIS] >= v_origin->co[SORT_AXIS]) :
- (v_iter->co[SORT_AXIS] <= v_origin->co[SORT_AXIS]))
+ if (direction_sign ? (v_iter->co[SORT_AXIS] > v_origin->co[SORT_AXIS]) :
+ (v_iter->co[SORT_AXIS] < v_origin->co[SORT_AXIS]))
{
BLI_SMALLSTACK_PUSH(vert_search, v_iter);
BLI_SMALLSTACK_PUSH(vert_blacklist, v_iter);