diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 475ffd23617..56c39e409ec 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1088,7 +1088,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S mval[1] = dd->mval[1]; /* try to snap to closer object */ - found = snapObjectsContext(C, mval, &dist_px, vec, no, SNAP_NOT_SELECTED); + found = snapObjectsContext(C, mval, &dist_px, vec, no, SNAP_NOT_SELECTED, NULL); if (found == 1) { pt->type = dd->type; pt->mode = PT_SNAP; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 61fe30e4ec5..0512980ec1f 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5240,7 +5240,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) const float mval[2] = {UNPACK2(event->mval)}; float no_dummy[3]; float dist_px_dummy; - snapObjectsContext(C, mval, &dist_px_dummy, location, no_dummy, SNAP_NOT_OBEDIT); + snapObjectsContext(C, mval, &dist_px_dummy, location, no_dummy, SNAP_NOT_OBEDIT, NULL); } RNA_float_set_array(op->ptr, "location", location); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 41ff9b88da9..cfe6a7b166d 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -110,6 +110,7 @@ struct ScrArea; struct Base; struct Scene; struct Object; +struct BoundBox; /* UNUSED */ // int BIF_snappingSupported(struct Object *obedit); @@ -180,15 +181,15 @@ typedef enum SnapMode { bool peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, const float mval[2], SnapMode mode); bool peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, const float mval[2], SnapMode mode); bool snapObjectsTransform(struct TransInfo *t, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode); -bool snapObjectsContext(struct bContext *C, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode); +bool snapObjectsContext(struct bContext *C, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode, struct BoundBox *bb_init); /* taks args for all settings */ bool snapObjectsEx(struct Scene *scene, struct Base *base_act, struct View3D *v3d, struct ARegion *ar, struct Object *obedit, short snap_mode, const float mval[2], float *r_dist_px, - float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode); + float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode, struct BoundBox *bb_init); bool snapObjectsRayEx(struct Scene *scene, struct Base *base_act, struct View3D *v3d, struct ARegion *ar, struct Object *obedit, short snap_mode, struct Object **r_ob, float r_obmat[4][4], const float ray_start[3], const float ray_normal[3], float *r_ray_dist, - const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode); + const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode, struct BoundBox *bb_init); bool snapNodesTransform(struct TransInfo *t, const int mval[2], float *r_dist_px, float r_loc[2], char *r_node_border, SnapMode mode); bool snapNodesContext(struct bContext *C, const int mval[2], float *r_dist_px, float r_loc[2], char *r_node_border, SnapMode mode); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 55ad303d0e1..12e7f005e51 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -305,7 +305,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) float mval[2], co_proj[3], no_dummy[3]; float dist_px_dummy; if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - if (snapObjectsContext(C, mval, &dist_px_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) { + if (snapObjectsContext(C, mval, &dist_px_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT, NULL)) { mul_v3_m4v3(eve->co, obedit->imat, co_proj); } } diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 9d0a70ea9d0..6288b8c27cf 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -97,17 +97,17 @@ static bool ED_view3d_snap_co(bContext *C, float r_co[3], float r_no[3], const f /* try snap edge, then face if it fails */ if (use_vert) { ret |= snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_VERTEX, - co_ss, &dist_px, r_co, r_no_ptr, &ray_dist, SNAP_ALL); + co_ss, &dist_px, r_co, r_no_ptr, &ray_dist, SNAP_ALL, NULL); } if (use_edge && (ret == false || use_depth)) { if (use_depth == false) ray_dist = TRANSFORM_DIST_MAX_RAY; ret |= snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_EDGE, - co_ss, &dist_px, r_co, r_no_ptr, &ray_dist, SNAP_ALL); + co_ss, &dist_px, r_co, r_no_ptr, &ray_dist, SNAP_ALL, NULL); } if (use_face && (ret == false || use_depth)) { if (use_depth == false) ray_dist = TRANSFORM_DIST_MAX_RAY; ret |= snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_FACE, - co_ss, &dist_px, r_co, r_no_ptr, &ray_dist, SNAP_ALL); + co_ss, &dist_px, r_co, r_no_ptr, &ray_dist, SNAP_ALL, NULL); } return ret; @@ -130,7 +130,7 @@ static bool ED_view3d_snap_ray(bContext *C, float r_co[3], ret = snapObjectsRayEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, &ray_dist, - NULL, &dist_px, r_co, r_no_dummy, SNAP_ALL); + NULL, &dist_px, r_co, r_no_dummy, SNAP_ALL, NULL); return ret; } diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 1c3e223f3ed..991c38fd778 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -393,7 +393,7 @@ static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *w ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, r_distance, - NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL); + NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL, NULL); /* artifically scale the distance to the scene size */ *r_distance /= walk->grid; @@ -426,7 +426,7 @@ static bool walk_ray_cast(bContext *C, RegionView3D *rv3d, WalkInfo *walk, float ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, ray_distance, - NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL); + NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL, NULL); /* dot is positive if both rays are facing the same direction */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index ae7e21f3824..4915297d034 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -38,6 +38,7 @@ #include "ED_view3d.h" #include "DNA_listBase.h" +#include "DNA_object_types.h" #include "BLI_smallhash.h" #include "BKE_editmesh.h" @@ -98,6 +99,7 @@ typedef struct TransSnap { void (*targetSnap)(struct TransInfo *); /* Get the transform distance between two points (used by Closest snap) */ float (*distance)(struct TransInfo *, const float p1[3], const float p2[3]); + struct BoundBox BB_init; } TransSnap; typedef struct TransCon { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 9afc12a5270..2da6b92c9d0 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -514,6 +514,10 @@ static void initSnappingMode(TransInfo *t) else { t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_OBEDIT; } + + /* store the original bounding box - + * we could slightly increase the size in screen space but leaving as TODO */ + t->tsnap.BB_init = *BKE_object_boundbox_get(obedit); } /* Particles edit mode*/ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist @@ -1489,13 +1493,12 @@ static bool snapCurve(short snap_mode, ARegion *ar, Object *ob, Curve *cu, float static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float ray_origin[3], - const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) + const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth, BoundBox *bb_init) { bool retval = false; int totvert = dm->getNumVerts(dm); if (totvert > 0) { - BoundBox *bb; float imat[4][4]; float timat[3][3]; /* transpose inverse matrix for normals */ float ray_start_local[3], ray_normal_local[3], local_scale, len_diff = TRANSFORM_DIST_MAX_RAY; @@ -1513,8 +1516,9 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes /* local scale in normal direction */ local_scale = normalize_v3(ray_normal_local); - bb = BKE_object_boundbox_get(ob); - if (!BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, &len_diff)) { + if (!bb_init) + bb_init = BKE_object_boundbox_get(ob); + if (!BKE_boundbox_ray_hit_check(bb_init, ray_start_local, ray_normal_local, &len_diff)) { return retval; } @@ -1806,24 +1810,27 @@ static bool snapCamera(short snap_mode, ARegion *ar, Scene *scene, Object *objec static bool snapObject(Scene *scene, short snap_mode, ARegion *ar, Object *ob, float obmat[4][4], bool use_obedit, Object **r_ob, float r_obmat[4][4], const float ray_start[3], const float ray_normal[3], const float ray_origin[3], - const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) + const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth, BoundBox *bb_init) { bool retval = false; if (ob->type == OB_MESH) { BMEditMesh *em; DerivedMesh *dm; + BoundBox *bb; if (use_obedit) { em = BKE_editmesh_from_object(ob); dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); + bb = bb_init; } else { em = NULL; dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + bb = NULL; } - retval = snapDerivedMesh(snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_depth); + retval = snapDerivedMesh(snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_depth, bb); dm->release(dm); } @@ -1854,7 +1861,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D Object **r_ob, float r_obmat[4][4], const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *r_ray_dist, - const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode) + const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode, BoundBox *bb_init) { Base *base; bool retval = false; @@ -1864,7 +1871,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, true, r_ob, r_obmat, - ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist, bb_init); } /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA @@ -1877,7 +1884,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D Object *ob = base->object; retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, false, r_ob, r_obmat, - ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist, NULL); } for (base = FIRSTBASE; base != NULL; base = base->next) { @@ -1896,7 +1903,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { retval |= snapObject(scene, snap_mode, ar, dupli_ob->ob, dupli_ob->mat, false, r_ob, r_obmat, - ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist, NULL); } free_object_duplilist(lb); @@ -1904,7 +1911,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, false, r_ob, r_obmat, - ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist, NULL); } } @@ -1912,7 +1919,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D } static bool snapObjects(Scene *scene, short snap_mode, Base *base_act, View3D *v3d, ARegion *ar, Object *obedit, const float mval[2], float *r_dist_px, - float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode) + float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode, BoundBox *bb_init) { float ray_start[3], ray_normal[3], ray_orgigin[3]; @@ -1923,17 +1930,17 @@ static bool snapObjects(Scene *scene, short snap_mode, Base *base_act, View3D *v return snapObjectsRay(scene, snap_mode, base_act, v3d, ar, obedit, NULL, NULL, ray_start, ray_normal, ray_orgigin, r_ray_dist, - mval, r_dist_px, r_loc, r_no, mode); + mval, r_dist_px, r_loc, r_no, mode, bb_init); } bool snapObjectsTransform(TransInfo *t, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode) { float ray_dist = TRANSFORM_DIST_MAX_RAY; return snapObjects(t->scene, t->scene->toolsettings->snap_mode, t->scene->basact, t->view, t->ar, t->obedit, - mval, r_dist_px, r_loc, r_no, &ray_dist, mode); + mval, r_dist_px, r_loc, r_no, &ray_dist, mode, &t->tsnap.BB_init); } -bool snapObjectsContext(bContext *C, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode) +bool snapObjectsContext(bContext *C, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode, BoundBox *bb_init) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; @@ -1943,26 +1950,26 @@ bool snapObjectsContext(bContext *C, const float mval[2], float *r_dist_px, floa float ray_dist = TRANSFORM_DIST_MAX_RAY; return snapObjects(scene, scene->toolsettings->snap_mode, scene->basact, v3d, ar, obedit, - mval, r_dist_px, r_loc, r_no, &ray_dist, mode); + mval, r_dist_px, r_loc, r_no, &ray_dist, mode, bb_init); } bool snapObjectsEx(Scene *scene, Base *base_act, View3D *v3d, ARegion *ar, Object *obedit, short snap_mode, const float mval[2], float *r_dist_px, - float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode) + float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode, struct BoundBox *bb_init) { return snapObjects(scene, snap_mode, base_act, v3d, ar, obedit, mval, r_dist_px, - r_loc, r_no, r_ray_dist, mode); + r_loc, r_no, r_ray_dist, mode, bb_init); } bool snapObjectsRayEx(Scene *scene, Base *base_act, View3D *v3d, ARegion *ar, Object *obedit, short snap_mode, Object **r_ob, float r_obmat[4][4], const float ray_start[3], const float ray_normal[3], float *r_ray_dist, - const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode) + const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode, struct BoundBox *bb_init) { return snapObjectsRay(scene, snap_mode, base_act, v3d, ar, obedit, r_ob, r_obmat, ray_start, ray_normal, ray_start, r_ray_dist, - mval, r_dist_px, r_loc, r_no, mode); + mval, r_dist_px, r_loc, r_no, mode, bb_init); } /******************** PEELING *********************************/ diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 84134e7cd3a..c6a8bf5aca4 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -126,7 +126,7 @@ static void rna_Scene_ray_cast(Scene *scene, float ray_start[3], float ray_end[3 if (snapObjectsRayEx(scene, NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, r_ob, (float(*)[4])r_obmat, ray_start, ray_nor, &ray_dist, - NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL)) + NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL, NULL)) { *r_success = true; }