fix for lasso selection (in non-zbuf mode) when the line intersected its self.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 4 Oct 2013 10:48:24 +0000 (10:48 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 4 Oct 2013 10:48:24 +0000 (10:48 +0000)
isect_point_poly_v2() - add argument to check overlapping areas.

source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/intern/lasso.c
source/blender/blenlib/intern/math_geom.c
source/blender/bmesh/tools/bmesh_bisect_plane.c
source/blender/editors/mesh/editmesh_knife.c

index d3f6c7ef14b7bb8445f1c1050b2062c1e5e6c214..c7ef410a606a50e967fdf9f5c26cea8af19d242f 100644 (file)
@@ -155,8 +155,8 @@ bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
                               const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2], const float epsilon);
 
 /* point in polygon */
-bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr);
-bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr);
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool use_overlap);
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr, const bool use_overlap);
 
 int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
 
index 8e22d6f11825e18889c0cff395773e0e07de630e..e89f7fd795bd4d6f0ec857b010cbdc5678d28cec 100644 (file)
@@ -63,7 +63,7 @@ bool BLI_lasso_is_point_inside(const int mcords[][2], const unsigned int moves,
        }
        else {
                int pt[2] = {sx, sy};
-               return isect_point_poly_v2_int(pt, mcords, moves);
+               return isect_point_poly_v2_int(pt, mcords, moves, true);
        }
 }
 
index 65cfac860212d5d686b7ceccbdc514a531cda400..e45714f33da3987d073aa1f9a519fcf4db2e9441 100644 (file)
@@ -712,7 +712,8 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2],
 }
 
 /* point in polygon (keep float and int versions in sync) */
-bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr)
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr,
+                         const bool use_overlap)
 {
        /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
        float angletot = 0.0;
@@ -749,9 +750,18 @@ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsign
                p1 = p2;
        }
 
-       return (fabsf(angletot) > 4.0f);
+       angletot = fabsf(angletot);
+       if (use_overlap) {
+               const int nested = floorf((angletot / (float)(M_PI * 2.0)) + 0.00001f);
+               angletot -= nested * (float)(M_PI * 2.0);
+               return (angletot > 4.0f) != (nested % 2);
+       }
+       else {
+               return (angletot > 4.0f);
+       }
 }
-bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr)
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr,
+                             const bool use_overlap)
 {
        /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
        float angletot = 0.0;
@@ -788,7 +798,15 @@ bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsign
                p1 = p2;
        }
 
-       return (fabsf(angletot) > 4.0f);
+       angletot = fabsf(angletot);
+       if (use_overlap) {
+               const int nested = floorf((angletot / (float)(M_PI * 2.0)) + 0.00001f);
+               angletot -= nested * (float)(M_PI * 2.0);
+               return (angletot > 4.0f) != (nested % 2);
+       }
+       else {
+               return (angletot > 4.0f);
+       }
 }
 
 /* point in tri */
index e45ee75b8cde81eb1310b58ce714245e0c0488f1..4633d0db788dc7d5ec97e705c31ec0774567a922 100644 (file)
@@ -237,7 +237,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
                                            face_verts_proj_2d[BM_VERT_LOOPINDEX(v_a)],
                                            face_verts_proj_2d[BM_VERT_LOOPINDEX(v_b)]);
 
-                               if (isect_point_poly_v2(co_mid, (const float (*)[2])face_verts_proj_2d, f_len_orig)) {
+                               if (isect_point_poly_v2(co_mid, (const float (*)[2])face_verts_proj_2d, f_len_orig, false)) {
                                        BMLoop *l_a, *l_b;
                                        bool found = false;
                                        unsigned int j;
index 43cb15e065e6e7a5cea8253c18823d7fa6e48274..5e88ecabd35e254c257fbf843edd2a08d74d5084 100644 (file)
@@ -3525,7 +3525,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f,
                while (p) {
                        const float (*mval_fl)[2] = p->link;
                        const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
-                       isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1);
+                       isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
                        p = p->next;
                }