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:
authorHans Goudey <h.goudey@me.com>2020-11-03 07:34:57 +0300
committerHans Goudey <h.goudey@me.com>2020-11-03 07:34:57 +0300
commitc6d8300823b4e21729450531f2d5a6826ab5a4fa (patch)
tree57cab7a30eb191c5408b228fd787ae4e999423fb
parent42f6aada98a655bce975a8dc24aa67e33200fbd9 (diff)
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
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c27
1 files changed, 22 insertions, 5 deletions
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;