Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / transform / transform_snap_object.c
index bf4a3116eeba9ebb1bdc1b0228b25e209467eaf6..b11a2d5d01eeb6819f9f856f81a761cf0e7fd9f8 100644 (file)
@@ -992,7 +992,7 @@ static bool snapEditMesh(
                float imat[4][4];
                float timat[3][3]; /* transpose inverse matrix for normals */
                float ray_start_local[3], ray_normal_local[3];
-               float local_scale, local_depth, len_diff;
+               float local_scale, local_depth;
 
                invert_m4_m4(imat, obmat);
                transpose_m3_m4(timat, imat);
@@ -1089,6 +1089,7 @@ static bool snapEditMesh(
                 * been *inside* boundbox, leading to snap failures (see T38409).
                 * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
                 */
+               float len_diff = 0.0f;
                if (do_ray_start_correction) {
                        /* We *need* a reasonably valid len_diff in this case.
                         * Use BHVTree to find the closest face from ray_start_local.
@@ -1098,27 +1099,24 @@ static bool snapEditMesh(
                                nearest.index = -1;
                                nearest.dist_sq = FLT_MAX;
                                /* Compute and store result. */
-                               BLI_bvhtree_find_nearest(
-                                       treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata);
-                               if (nearest.index != -1) {
+                               if (BLI_bvhtree_find_nearest(
+                                       treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata) != -1)
+                               {
                                        len_diff = sqrtf(nearest.dist_sq);
+                                       float ray_org_local[3];
+
+                                       copy_v3_v3(ray_org_local, ray_origin);
+                                       mul_m4_v3(imat, ray_org_local);
+
+                                       /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far
+                                       * away ray_start values (as returned in case of ortho view3d), see T38358.
+                                       */
+                                       len_diff -= local_scale;  /* make temp start point a bit away from bbox hit point. */
+                                       madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local,
+                                                      len_diff - len_v3v3(ray_start_local, ray_org_local));
+                                       local_depth -= len_diff;
                                }
                        }
-                       float ray_org_local[3];
-
-                       copy_v3_v3(ray_org_local, ray_origin);
-                       mul_m4_v3(imat, ray_org_local);
-
-                       /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far
-                        * away ray_start values (as returned in case of ortho view3d), see T38358.
-                        */
-                       len_diff -= local_scale;  /* make temp start point a bit away from bbox hit point. */
-                       madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local,
-                                      len_diff - len_v3v3(ray_start_local, ray_org_local));
-                       local_depth -= len_diff;
-               }
-               else {
-                       len_diff = 0.0f;
                }
 
                switch (snap_to) {
@@ -1316,41 +1314,39 @@ static bool snapObject(
 
 static bool snapObjectsRay(
         SnapObjectContext *sctx,
-        SnapSelect snap_select, const short snap_to,
+        const unsigned short snap_to, const SnapSelect snap_select,
+        const bool use_object_edit_cage,
         const float mval[2], float *dist_px,
-        /* special handling of active and edit objects */
-        Base *base_act, Object *obedit,
         const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth,
         /* return args */
         float r_loc[3], float r_no[3], int *r_index,
         Object **r_ob, float r_obmat[4][4],
         ListBase *r_hit_list)
 {
-       Base *base;
        bool retval = false;
-       bool snap_obedit_first = snap_select == SNAP_ALL && obedit;
        unsigned int ob_index = 0;
+       Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+       Base *base_act = sctx->scene->basact;
 
-       if (snap_obedit_first) {
-               Object *ob = obedit;
-
-               retval |= snapObject(
-                       sctx, ob, ob->obmat, true, snap_to,
-                       mval, dist_px, ob_index++,
-                       ray_start, ray_normal, ray_origin, ray_depth,
-                       r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
+       bool ignore_object_selected = false, ignore_object_active = false;
+       switch (snap_select) {
+               case SNAP_ALL:
+                       break;
+               case SNAP_NOT_SELECTED:
+                       ignore_object_selected = true;
+                       break;
+               case SNAP_NOT_ACTIVE:
+                       ignore_object_active = true;
+                       break;
        }
-
-       for (base = sctx->scene->base.first; base != NULL; base = base->next) {
+       for (Base *base = sctx->scene->base.first; base != NULL; base = base->next) {
                if ((BASE_VISIBLE_BGMODE(sctx->v3d_data.v3d, sctx->scene, base)) &&
                    (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 &&
 
-                   ((snap_select == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) ||
-                    (ELEM(snap_select, SNAP_ALL, SNAP_NOT_OBEDIT) && base != base_act)))
+                   !((ignore_object_selected && (base->flag & (SELECT | BA_WAS_SEL))) ||
+                     (ignore_object_active && base == base_act)))
                {
                        Object *ob = base->object;
-                       Object *ob_snap = ob;
-                       bool use_obedit = false;
 
                        if (ob->transflag & OB_DUPLI) {
                                DupliObject *dupli_ob;
@@ -1370,19 +1366,8 @@ static bool snapObjectsRay(
                                free_object_duplilist(lb);
                        }
 
-                       if (obedit) {
-                               if ((ob == obedit) &&
-                                  (snap_obedit_first || (snap_select == SNAP_NOT_OBEDIT)))
-                               {
-                                       continue;
-                               }
-
-                               if (ob->data == obedit->data) {
-                                       /* for linked objects, use the same object but a different matrix */
-                                       use_obedit = true;
-                                       ob_snap = obedit;
-                               }
-                       }
+                       bool use_obedit = (obedit != NULL) && (ob->data == obedit->data);
+                       Object *ob_snap = use_obedit ? obedit : ob;
 
                        retval |= snapObject(
                                sctx, ob_snap, ob->obmat, use_obedit, snap_to,
@@ -1487,22 +1472,18 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
 
 bool ED_transform_snap_object_project_ray_ex(
         SnapObjectContext *sctx,
+        const unsigned short snap_to,
         const struct SnapObjectParams *params,
         const float ray_start[3], const float ray_normal[3], float *ray_depth,
         float r_loc[3], float r_no[3], int *r_index,
         Object **r_ob, float r_obmat[4][4])
 {
-       Base *base_act = params->use_object_active ? sctx->scene->basact : NULL;
-       Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL;
-
        return snapObjectsRay(
                sctx,
-               params->snap_select, params->snap_to,
+               snap_to, params->snap_select, params->use_object_edit_cage,
                NULL, NULL,
-               base_act, obedit,
                ray_start, ray_normal, ray_start, ray_depth,
-               r_loc, r_no, r_index,
-               r_ob, r_obmat, NULL);
+               r_loc, r_no, r_index, r_ob, r_obmat, NULL);
 }
 
 /**
@@ -1514,14 +1495,12 @@ bool ED_transform_snap_object_project_ray_ex(
  */
 bool ED_transform_snap_object_project_ray_all(
         SnapObjectContext *sctx,
+        const unsigned short snap_to,
         const struct SnapObjectParams *params,
         const float ray_start[3], const float ray_normal[3],
         float ray_depth, bool sort,
         ListBase *r_hit_list)
 {
-       Base *base_act = params->use_object_active ? sctx->scene->basact : NULL;
-       Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL;
-
        if (ray_depth == -1.0f) {
                ray_depth = BVH_RAYCAST_DIST_MAX;
        }
@@ -1532,9 +1511,8 @@ bool ED_transform_snap_object_project_ray_all(
 
        bool retval = snapObjectsRay(
                sctx,
-               params->snap_select, params->snap_to,
+               snap_to, params->snap_select, params->use_object_edit_cage,
                NULL, NULL,
-               base_act, obedit,
                ray_start, ray_normal, ray_start, &ray_depth,
                NULL, NULL, NULL, NULL, NULL,
                r_hit_list);
@@ -1560,6 +1538,7 @@ bool ED_transform_snap_object_project_ray_all(
  */
 static bool transform_snap_context_project_ray_impl(
         SnapObjectContext *sctx,
+        const struct SnapObjectParams *params,
         const float ray_start[3], const float ray_normal[3], float *ray_depth,
         float r_co[3], float r_no[3])
 {
@@ -1568,11 +1547,8 @@ static bool transform_snap_context_project_ray_impl(
        /* try snap edge, then face if it fails */
        ret = ED_transform_snap_object_project_ray_ex(
                sctx,
-               &(const struct SnapObjectParams){
-                   .snap_select = SNAP_ALL,
-                   .snap_to = SCE_SNAP_MODE_FACE,
-                   .use_object_edit = (sctx->scene->obedit != NULL),
-               },
+               SCE_SNAP_MODE_FACE,
+               params,
                ray_start, ray_normal, ray_depth,
                r_co, r_no, NULL,
                NULL, NULL);
@@ -1582,6 +1558,7 @@ static bool transform_snap_context_project_ray_impl(
 
 bool ED_transform_snap_object_project_ray(
         SnapObjectContext *sctx,
+        const struct SnapObjectParams *params,
         const float ray_origin[3], const float ray_direction[3], float *ray_depth,
         float r_co[3], float r_no[3])
 {
@@ -1598,12 +1575,14 @@ bool ED_transform_snap_object_project_ray(
 
        return transform_snap_context_project_ray_impl(
                sctx,
+               params,
                ray_origin, ray_direction, ray_depth,
                r_co, r_no);
 }
 
 static bool transform_snap_context_project_view3d_mixed_impl(
         SnapObjectContext *sctx,
+        const unsigned short snap_to_flag,
         const struct SnapObjectParams *params,
         const float mval[2], float *dist_px,
         bool use_depth,
@@ -1619,22 +1598,18 @@ static bool transform_snap_context_project_view3d_mixed_impl(
 
        const int  elem_type[3] = {SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE, SCE_SNAP_MODE_FACE};
 
-       BLI_assert(params->snap_to_flag != 0);
-       BLI_assert((params->snap_to_flag & ~(1 | 2 | 4)) == 0);
-
-       struct SnapObjectParams params_temp = *params;
+       BLI_assert(snap_to_flag != 0);
+       BLI_assert((snap_to_flag & ~(1 | 2 | 4)) == 0);
 
        for (int i = 0; i < 3; i++) {
-               if ((params->snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) {
+               if ((snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) {
                        if (use_depth == false) {
                                ray_depth = BVH_RAYCAST_DIST_MAX;
                        }
 
-                       params_temp.snap_to = elem_type[i];
-
                        if (ED_transform_snap_object_project_view3d(
                                sctx,
-                               &params_temp,
+                               elem_type[i], params,
                                mval, dist_px, &ray_depth,
                                r_co, r_no))
                        {
@@ -1661,6 +1636,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
  */
 bool ED_transform_snap_object_project_view3d_mixed(
         SnapObjectContext *sctx,
+        const unsigned short snap_to_flag,
         const struct SnapObjectParams *params,
         const float mval_fl[2], float *dist_px,
         bool use_depth,
@@ -1668,13 +1644,14 @@ bool ED_transform_snap_object_project_view3d_mixed(
 {
        return transform_snap_context_project_view3d_mixed_impl(
                sctx,
-               params,
+               snap_to_flag, params,
                mval_fl, dist_px, use_depth,
                r_co, r_no);
 }
 
 bool ED_transform_snap_object_project_view3d_ex(
         SnapObjectContext *sctx,
+        const unsigned short snap_to,
         const struct SnapObjectParams *params,
         const float mval[2], float *dist_px,
         float *ray_depth,
@@ -1695,19 +1672,17 @@ bool ED_transform_snap_object_project_view3d_ex(
                return false;
        }
 
-       Base *base_act = params->use_object_active ? sctx->scene->basact : NULL;
-       Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL;
        return snapObjectsRay(
                sctx,
-               params->snap_select, params->snap_to,
+               snap_to, params->snap_select, params->use_object_edit_cage,
                mval, dist_px,
-               base_act, obedit,
                ray_start, ray_normal, ray_orgigin, ray_depth,
                r_loc, r_no, r_index, NULL, NULL, NULL);
 }
 
 bool ED_transform_snap_object_project_view3d(
         SnapObjectContext *sctx,
+        const unsigned short snap_to,
         const struct SnapObjectParams *params,
         const float mval[2], float *dist_px,
         float *ray_depth,
@@ -1715,6 +1690,7 @@ bool ED_transform_snap_object_project_view3d(
 {
        return ED_transform_snap_object_project_view3d_ex(
                sctx,
+               snap_to,
                params,
                mval, dist_px,
                ray_depth,
@@ -1733,8 +1709,6 @@ bool ED_transform_snap_object_project_all_view3d_ex(
 {
        float ray_start[3], ray_normal[3];
 
-       BLI_assert(params->snap_to == SCE_SNAP_MODE_FACE);
-
        if (!ED_view3d_win_to_ray_ex(
                sctx->v3d_data.ar, sctx->v3d_data.v3d,
                mval, NULL, ray_normal, ray_start, true))
@@ -1744,6 +1718,7 @@ bool ED_transform_snap_object_project_all_view3d_ex(
 
        return ED_transform_snap_object_project_ray_all(
                sctx,
+               SCE_SNAP_MODE_FACE,
                params,
                ray_start, ray_normal, ray_depth, sort,
                r_hit_list);