diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2014-06-12 02:43:38 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2014-06-12 02:43:38 +0400 |
commit | 7b5fe4f316234022a0ab761b694cd459ce98db2d (patch) | |
tree | 587707ad84568a05c07dccde0ae45c86c034e23e /source/blender/editors/transform/transform_snap.c | |
parent | fb6cb25c1c8797d239ca8f6c5d775eef50cc801f (diff) |
Fix flickering when transform snapping in edit mode and cursor is
slightly outside the mesh.
Reported by Thomas Beck on irc. Issue here is that the mesh bounding box
changes as we are transforming the vertices. Solution is to collide
against the initial bounding box. Unfortunately the snapping functions
are made in a way that a lot of code needed to be tweaked here, but the
change should be straightforward and harmless (famous last words, I
know).
Ideally we might want to even increase the size of the bounding box a
little (as seen in screen space) to allow snapping even in cases where,
cursor is slightly outside the bounding box, but since this is not so
straightforward to do for all cases, at least for me, leaving this as
a TODO.
Diffstat (limited to 'source/blender/editors/transform/transform_snap.c')
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 47 |
1 files changed, 27 insertions, 20 deletions
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 *********************************/ |