[Bf-blender-cvs] [c6d8300823b] blender-v2.91-release: Fix T82120: Arc miter bevel creates miters on straight edges

Hans Goudey noreply at git.blender.org
Tue Nov 3 05:35:04 CET 2020


Commit: c6d8300823b4e21729450531f2d5a6826ab5a4fa
Author: Hans Goudey
Date:   Mon Nov 2 22:34:57 2020 -0600
Branches: blender-v2.91-release
https://developer.blender.org/rBc6d8300823b4e21729450531f2d5a6826ab5a4fa

Fix T82120: Arc miter bevel creates miters on straight edges

In some situations where two beveled edges were very close to in-line
but not quite straight, bevel would build a miter when it shouldn't.
The code that chose whether to use a miter at each vertex was slightly
incorrect.

For outer miters there is a check for 3 or more selected edges, but an
inner miter can still be useful with only two beveled edges at a vertex,
so we can't use that here. Instead I changed the check for in-line edges
to run before determining whether the angle is reflex or not. The logic
ends up a bit more straightforward as well. This doesn't completely
remove the rather strange looking triangle vertex meshes at each corner,
but it does make it stable when locations are slightly adjusted.

The only other place this `edges_angle_kind` function was used is for
profile=1.0 vertex meshes. I tested and made sure that still works well.

Differential Revision: https://developer.blender.org/D9420

===================================================================

M	source/blender/bmesh/tools/bmesh_bevel.c

===================================================================

diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 3a6ae9883e2..e8ded83dfbe 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -59,6 +59,8 @@
 #define BEVEL_SMALL_ANG DEG2RADF(10.0f)
 /** Difference in dot products that corresponds to 10 degree difference between vectors. */
 #define BEVEL_SMALL_ANG_DOT 1 - cosf(BEVEL_SMALL_ANG)
+/** Difference in dot products that corresponds to 2.0 degree difference between vectors. */
+#define BEVEL_EPSILON_ANG_DOT 1 - cosf(BEVEL_EPSILON_ANG)
 #define BEVEL_MAX_ADJUST_PCT 10.0f
 #define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f
 #define BEVEL_MATCH_SPEC_WEIGHT 0.2
@@ -432,6 +434,18 @@ static bool nearly_parallel(const float d1[3], const float d2[3])
   return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_ANG);
 }
 
+/**
+ * \return True if d1 and d2 are parallel or nearly parallel.
+ */
+static bool nearly_parallel_normalized(const float d1[3], const float d2[3])
+{
+  BLI_ASSERT_UNIT_V3(d1);
+  BLI_ASSERT_UNIT_V3(d2);
+
+  const float direction_dot = dot_v3v3(d1, d2);
+  return compare_ff(fabsf(direction_dot), 1.0f, BEVEL_EPSILON_ANG_DOT);
+}
+
 /* Make a new BoundVert of the given kind, inserting it at the end of the circular linked
  * list with entry point bv->boundstart, and return it. */
 static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3])
@@ -1096,6 +1110,12 @@ static int edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v)
   sub_v3_v3v3(dir2, v->co, v2->co);
   normalize_v3(dir1);
   normalize_v3(dir2);
+
+  /* First check for in-line edges using a simpler test. */
+  if (nearly_parallel_normalized(dir1, dir2)) {
+    return ANGLE_STRAIGHT;
+  }
+
   /* Angles are in [0,pi]. Need to compare cross product with normal to see if they are reflex. */
   float cross[3];
   cross_v3_v3v3(cross, dir1, dir2);
@@ -1110,11 +1130,8 @@ static int edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v)
   else {
     no = v->no;
   }
-  float dot = dot_v3v3(cross, no);
-  if (fabsf(dot) < BEVEL_EPSILON_BIG) {
-    return ANGLE_STRAIGHT;
-  }
-  if (dot < 0.0f) {
+
+  if (dot_v3v3(cross, no) < 0.0f) {
     return ANGLE_LARGER;
   }
   return ANGLE_SMALLER;



More information about the Bf-blender-cvs mailing list