[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53730] trunk/blender/source/blender/ editors/mesh/editmesh_knife.c: Fix knife angle constraint bug #33813 by changing knife mvals to floats.
Howard Trickey
howard.trickey at gmail.com
Fri Jan 11 15:13:26 CET 2013
Revision: 53730
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53730
Author: howardt
Date: 2013-01-11 14:13:22 +0000 (Fri, 11 Jan 2013)
Log Message:
-----------
Fix knife angle constraint bug #33813 by changing knife mvals to floats.
The problem was that by snapping the integer mouse values to
lines through the previous point, the angle was slightly off.
Modified Paths:
--------------
trunk/blender/source/blender/editors/mesh/editmesh_knife.c
Modified: trunk/blender/source/blender/editors/mesh/editmesh_knife.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_knife.c 2013-01-11 04:34:15 UTC (rev 53729)
+++ trunk/blender/source/blender/editors/mesh/editmesh_knife.c 2013-01-11 14:13:22 UTC (rev 53730)
@@ -128,7 +128,7 @@
BMFace *bmface;
int is_space;
- int mval[2]; /* mouse screen position */
+ float mval[2]; /* mouse screen position (may be non-integral if snapped to something) */
} KnifePosData;
/* struct for properties used while drawing */
@@ -204,10 +204,10 @@
static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f);
#if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
float r_origin[3], float r_ray[3]);
#endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_dest[3]);
static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
@@ -225,6 +225,10 @@
ED_area_headerprint(CTX_wm_area(C), header);
}
+static inline int round_ftoi(float x)
+{
+ return x > 0.0f ? (int)(x + 0.5f) : (int)(x - 0.5f);
+}
static void knife_project_v3(KnifeTool_OpData *kcd, const float co[3], float sco[3])
{
@@ -238,8 +242,8 @@
kpd->vert = NULL;
kpd->edge = NULL;
kpd->bmface = NULL;
- kpd->mval[0] = 0;
- kpd->mval[1] = 0;
+ kpd->mval[0] = 0.0f;
+ kpd->mval[1] = 0.0f;
}
static ListBase *knife_empty_list(KnifeTool_OpData *kcd)
@@ -1420,17 +1424,14 @@
/* this works but gives numeric problems [#33400] */
#if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
float r_origin[3], float r_ray[3])
{
bglMats mats;
- float mval[2], imat[3][3];
+ float imat[3][3];
knife_bgl_get_mats(kcd, &mats);
- mval[0] = (float)mval_i[0];
- mval[1] = (float)mval_i[1];
-
/* unproject to find view ray */
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
@@ -1452,23 +1453,19 @@
}
#endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_origin_ofs[3])
{
bglMats mats;
- float mval[2];
knife_bgl_get_mats(kcd, &mats);
- mval[0] = (float)mval_i[0];
- mval[1] = (float)mval_i[1];
-
/* unproject to find view ray */
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
/* transform into object space */
- invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
+ invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
mul_m4_v3(kcd->ob->imat, r_origin);
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
@@ -1483,7 +1480,7 @@
float ray[3];
/* unproject to find view ray */
- knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
f = BMBVH_RayCast(kcd->bmbvh, origin, ray, co, cageco);
@@ -1641,8 +1638,8 @@
/* update mouse coordinates to the snapped-to edge's screen coordinates
* this is important for angle snap, which uses the previous mouse position */
edgesnap = new_knife_vert(kcd, p, cagep);
- kcd->curr.mval[0] = (int)edgesnap->sco[0];
- kcd->curr.mval[1] = (int)edgesnap->sco[1];
+ kcd->curr.mval[0] = edgesnap->sco[0];
+ kcd->curr.mval[1] = edgesnap->sco[1];
}
else {
@@ -1720,8 +1717,8 @@
/* update mouse coordinates to the snapped-to vertex's screen coordinates
* this is important for angle snap, which uses the previous mouse position */
- kcd->curr.mval[0] = (int)curv->sco[0];
- kcd->curr.mval[1] = (int)curv->sco[1];
+ kcd->curr.mval[0] = curv->sco[0];
+ kcd->curr.mval[1] = curv->sco[1];
}
return curv;
@@ -1740,48 +1737,56 @@
return NULL;
}
+/* update both kcd->curr.mval and kcd->vc.mval to snap to required angle */
static void knife_snap_angle(KnifeTool_OpData *kcd)
{
- int dx, dy;
+ float dx, dy;
float w, abs_tan;
- dx = kcd->vc.mval[0] - kcd->prev.mval[0];
- dy = kcd->vc.mval[1] - kcd->prev.mval[1];
- if (dx == 0 || dy == 0)
+ dx = kcd->curr.mval[0] - kcd->prev.mval[0];
+ dy = kcd->curr.mval[1] - kcd->prev.mval[1];
+ if (dx == 0.0f && dy == 0.0f)
return;
- w = (float)dy / (float)dx;
+ if (dx == 0.0f) {
+ kcd->angle_snapping = ANGLE_90;
+ kcd->curr.mval[0] =kcd->prev.mval[0];
+ }
+
+ w = dy / dx;
abs_tan = fabsf(w);
if (abs_tan <= 0.4142f) { /* tan(22.5 degrees) = 0.4142 */
kcd->angle_snapping = ANGLE_0;
- kcd->vc.mval[1] = kcd->prev.mval[1];
+ kcd->curr.mval[1] = kcd->prev.mval[1];
}
else if (abs_tan < 2.4142f) { /* tan(67.5 degrees) = 2.4142 */
if (w > 0) {
kcd->angle_snapping = ANGLE_45;
- kcd->vc.mval[1] = kcd->prev.mval[1] + dx;
+ kcd->curr.mval[1] = kcd->prev.mval[1] + dx;
}
else {
kcd->angle_snapping = ANGLE_135;
- kcd->vc.mval[1] = kcd->prev.mval[1] - dx;
+ kcd->curr.mval[1] = kcd->prev.mval[1] - dx;
}
}
else {
kcd->angle_snapping = ANGLE_90;
- kcd->vc.mval[0] = kcd->prev.mval[0];
+ kcd->curr.mval[0] = kcd->prev.mval[0];
}
+
+ kcd->vc.mval[0] = round_ftoi(kcd->curr.mval[0]);
+ kcd->vc.mval[1] = round_ftoi(kcd->curr.mval[1]);
}
/* update active knife edge/vert pointers */
static int knife_update_active(KnifeTool_OpData *kcd)
{
+ knife_pos_data_clear(&kcd->curr);
+ kcd->curr.mval[0] = (float)kcd->vc.mval[0];
+ kcd->curr.mval[1] = (float)kcd->vc.mval[1];
if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
knife_snap_angle(kcd);
- knife_pos_data_clear(&kcd->curr);
- kcd->curr.mval[0] = kcd->vc.mval[0];
- kcd->curr.mval[1] = kcd->vc.mval[1];
-
/* XXX knife_snap_angle updates the view coordinate mouse values to constrained angles,
* which current mouse values are set to current mouse values are then used
* for vertex and edge snap detection, without regard to the exact angle constraint */
@@ -1799,7 +1804,7 @@
float origin[3];
float origin_ofs[3];
- knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, origin_ofs, origin);
}
@@ -2929,11 +2934,11 @@
}
}
-static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval_i[2])
{
knife_recalc_projmat(kcd);
- kcd->vc.mval[0] = mval[0];
- kcd->vc.mval[1] = mval[1];
+ kcd->vc.mval[0] = mval_i[0];
+ kcd->vc.mval[1] = mval_i[1];
if (knife_update_active(kcd)) {
ED_region_tag_redraw(kcd->ar);
More information about the Bf-blender-cvs
mailing list