mask editing
[blender.git] / source / blender / blenkernel / intern / mask.c
index b904b78ffddc7aefae74c00bf95b9b8a1a123ebe..99333411d8a1c53cef23c463ef6e1cb51ae7c290 100644 (file)
@@ -410,8 +410,6 @@ void BKE_mask_point_direction_switch(MaskSplinePoint *point)
        }
 }
 
-//typedef (float)[MASK_OBJECT_SHAPE_ELEM_SIZE] MaskLayerShapeElem;
-
 typedef struct MaskLayerShapeElem {
        float value[MASK_OBJECT_SHAPE_ELEM_SIZE];
 } MaskLayerShapeElem;
@@ -467,7 +465,8 @@ void BKE_mask_spline_direction_switch(MaskLayer *masklay, MaskSpline *spline)
 }
 
 
-float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, float start_u, const float co[2])
+float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point,
+                                 float start_u, const float co[2], const eMaskSign sign)
 {
        const float proj_eps         = 1e-3;
        const float proj_eps_squared = proj_eps * proj_eps;
@@ -475,6 +474,8 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, flo
        float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u;
        float ang = -1.0f;
 
+       BLI_assert(ABS(sign) <= 1); /* (-1, 0, 1) */
+
        while (u1 > 0.0f || u2 < 1.0f) {
                float n1[2], n2[2], co1[2], co2[2];
                float v1[2], v2[2];
@@ -485,20 +486,26 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, flo
                        BKE_mask_point_normal(spline, point, u1, n1);
                        sub_v2_v2v2(v1, co, co1);
 
-                       if (len_squared_v2(v1) > proj_eps_squared) {
-                               ang1 = angle_v2v2(v1, n1);
-                               if (ang1 > M_PI / 2.0f)
-                                       ang1 = M_PI  - ang1;
+                       if ((sign == MASK_PROJ_ANY) ||
+                           ((sign == MASK_PROJ_NEG) && (dot_v2v2(v1, n1) <= 0.0f)) ||
+                           ((sign == MASK_PROJ_POS) && (dot_v2v2(v1, n1) >= 0.0f)))
+                       {
 
-                               if (ang < 0.0f || ang1 < ang) {
-                                       ang = ang1;
+                               if (len_squared_v2(v1) > proj_eps_squared) {
+                                       ang1 = angle_v2v2(v1, n1);
+                                       if (ang1 > M_PI / 2.0f)
+                                               ang1 = M_PI  - ang1;
+
+                                       if (ang < 0.0f || ang1 < ang) {
+                                               ang = ang1;
+                                               u = u1;
+                                       }
+                               }
+                               else {
                                        u = u1;
+                                       break;
                                }
                        }
-                       else {
-                               u = u1;
-                               break;
-                       }
                }
 
                if (u2 <= 1.0f) {
@@ -506,20 +513,26 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, flo
                        BKE_mask_point_normal(spline, point, u2, n2);
                        sub_v2_v2v2(v2, co, co2);
 
-                       if (len_squared_v2(v2) > proj_eps_squared) {
-                               ang2 = angle_v2v2(v2, n2);
-                               if (ang2 > M_PI / 2.0f)
-                                       ang2 = M_PI  - ang2;
+                       if ((sign == MASK_PROJ_ANY) ||
+                           ((sign == MASK_PROJ_NEG) && (dot_v2v2(v2, n2) <= 0.0f)) ||
+                           ((sign == MASK_PROJ_POS) && (dot_v2v2(v2, n2) >= 0.0f)))
+                       {
+
+                               if (len_squared_v2(v2) > proj_eps_squared) {
+                                       ang2 = angle_v2v2(v2, n2);
+                                       if (ang2 > M_PI / 2.0f)
+                                               ang2 = M_PI  - ang2;
 
-                               if (ang2 < ang) {
-                                       ang = ang2;
+                                       if (ang2 < ang) {
+                                               ang = ang2;
+                                               u = u2;
+                                       }
+                               }
+                               else {
                                        u = u2;
+                                       break;
                                }
                        }
-                       else {
-                               u = u2;
-                               break;
-                       }
                }
 
                u1 -= du;