Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Trickey <howard.trickey@gmail.com>2014-06-12 18:22:10 +0400
committerHoward Trickey <howard.trickey@gmail.com>2014-06-12 18:22:10 +0400
commit8c2b5ffb118d065af4d34ff84f1493d914d948db (patch)
tree8d3e1cd56d1f75e01dfbf6d0b385a9eda574294f
parent9d0cf523b5ba452d6152e2d38c69014c1ecdfb34 (diff)
Fix Bevel bug T39746, small scale gives flat profile.
With very small meshes or very small bevel amounts, the bevel profile would be flat even if a round one was requested. Problem was that the code was checking the length of a cross product for closeness to zero to test coplanarity. Needed to normalize things before making that test to account for scale.
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 9f9b3de6756..45ebe144b5e 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -52,6 +52,7 @@
#define BEVEL_EPSILON_D 1e-6
#define BEVEL_EPSILON 1e-6f
#define BEVEL_EPSILON_SQ 1e-12f
+#define BEVEL_EPSILON_BIG 1e-4
/* happens far too often, uncomment for development */
// #define BEVEL_ASSERT_PROJECT
@@ -585,7 +586,7 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, float
sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
ang = angle_v3v3(dir1, dir2);
- if (ang < 100.0f * BEVEL_EPSILON) {
+ if (ang < BEVEL_EPSILON_BIG) {
/* special case: e1 and e2 are parallel; put offset point perp to both, from v.
* need to find a suitable plane.
* if offsets are different, we're out of luck:
@@ -606,7 +607,7 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, float
e2->offset_l = d;
copy_v3_v3(meetco, off1a);
}
- else if (fabsf(ang - (float)M_PI) < 100.0f * BEVEL_EPSILON) {
+ else if (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_BIG) {
/* special case e1 and e2 are antiparallel, so bevel is into
* a zero-area face. Just make the offset point on the
* common line, at offset distance from v. */
@@ -811,11 +812,11 @@ static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, Ed
add_v3_v3v3(off2b, off2a, dir2);
ang = angle_v3v3(dir1, dir2);
- if (ang < 100.0f * BEVEL_EPSILON) {
+ if (ang < BEVEL_EPSILON_BIG) {
/* lines are parallel; put intersection on emid */
offset_on_edge_between(bp, e1, e2, emid, v, meetco);
}
- else if (fabsf(ang - (float)M_PI) < 100.0f * BEVEL_EPSILON) {
+ else if (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_BIG) {
slide_dist(e2, v, e2->offset_l, meetco);
d = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e1->e, v)->co);
if (fabsf(d - e1->offset_r) > BEVEL_EPSILON)
@@ -892,7 +893,7 @@ static void set_profile_params(BevelParams *bp, BoundVert *bndv)
{
EdgeHalf *e;
Profile *pro;
- float co1[3], co2[3], co3[3], d1[3], d2[3];
+ float co1[3], co2[3], co3[3], d1[3], d2[3], d3[3], l;
bool do_linear_interp;
copy_v3_v3(co1, bndv->nv.co);
@@ -905,6 +906,7 @@ static void set_profile_params(BevelParams *bp, BoundVert *bndv)
pro->super_r = bp->pro_super_r;
/* projection direction is direction of the edge */
sub_v3_v3v3(pro->proj_dir, e->e->v1->co, e->e->v2->co);
+ normalize_v3(pro->proj_dir);
project_to_edge(e->e, co1, co2, pro->midco);
/* put arc endpoints on plane with normal proj_dir, containing midco */
add_v3_v3v3(co3, co1, pro->proj_dir);
@@ -920,12 +922,18 @@ static void set_profile_params(BevelParams *bp, BoundVert *bndv)
/* default plane to project onto is the one with triangle co1 - midco - co2 in it */
sub_v3_v3v3(d1, pro->midco, co1);
sub_v3_v3v3(d2, pro->midco, co2);
+ normalize_v3(d1);
+ normalize_v3(d2);
cross_v3_v3v3(pro->plane_no, d1, d2);
- if (normalize_v3(pro->plane_no) < BEVEL_EPSILON) {
- /* co1 - midco -co2 are collinear - project onto that plane */
- cross_v3_v3v3(co3, d1, pro->proj_dir);
- cross_v3_v3v3(pro->plane_no, d1, co3);
- if (normalize_v3(pro->plane_no) < BEVEL_EPSILON) {
+ l = normalize_v3(pro->plane_no);
+ if (l <= BEVEL_EPSILON_BIG) {
+ /* co1 - midco -co2 are collinear - project plane that contains that line
+ * and is perpendicular to the plane containing it and the beveled edge */
+ cross_v3_v3v3(d3, d1, pro->proj_dir);
+ normalize_v3(d3);
+ cross_v3_v3v3(pro->plane_no, d1, d3);
+ l = normalize_v3(pro->plane_no);
+ if (l <= BEVEL_EPSILON_BIG) {
/* whole profile is collinear with edge: just interpolate */
do_linear_interp = true;
}
@@ -958,9 +966,9 @@ static void move_profile_plane(BoundVert *bndv, EdgeHalf *e1, EdgeHalf *e2)
sub_v3_v3v3(d2, e2->e->v1->co, e2->e->v2->co);
cross_v3_v3v3(no, d1, d2);
cross_v3_v3v3(no2, d1, bndv->profile.proj_dir);
- if (normalize_v3(no) > BEVEL_EPSILON && normalize_v3(no2) > BEVEL_EPSILON) {
+ if (normalize_v3(no) > BEVEL_EPSILON_BIG && normalize_v3(no2) > BEVEL_EPSILON_BIG) {
dot = fabsf(dot_v3v3(no, no2));
- if (fabsf(dot - 1.0f) > BEVEL_EPSILON)
+ if (fabsf(dot - 1.0f) > BEVEL_EPSILON_BIG)
copy_v3_v3(bndv->profile.plane_no, no);
}
}
@@ -1700,7 +1708,7 @@ static BoundVert *pipe_test(BevVert *bv)
sub_v3_v3v3(dir3, BM_edge_other_vert(v3->ebev->e, bv->v)->co, bv->v->co);
normalize_v3(dir1);
normalize_v3(dir3);
- if (angle_v3v3(dir1, dir3) < 100.0f * BEVEL_EPSILON) {
+ if (angle_v3v3(dir1, dir3) < BEVEL_EPSILON_BIG) {
epipe = v1->ebev;
break;
}