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:
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 0d16d0af114..62465ea9849 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -365,13 +365,19 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
}
/* Like offset_meet, but here f1 and f2 must not be NULL and give the
- * planes in which to run the offset lines. They may not meet exactly,
- * but the line intersection routine will find the closest approach point. */
-static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
- BMFace *f1, BMFace *f2, float meetco[3])
+ * planes in which to run the offset lines.
+ * They may not meet exactly: the offsets for the edges may be different
+ * or both the planes and the lines may be angled so that they can't meet.
+ * In that case, pick a close point on emid, which should be the dividing
+ * edge between the two planes.
+ * TODO: should have a global 'offset consistency' prepass to adjust offset
+ * widths so that all edges have the same offset at both ends. */
+static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
+ BMVert *v, BMFace *f1, BMFace *f2, float meetco[3])
{
float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3],
- off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
+ off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3];
+ int iret;
BLI_assert(f1 != NULL && f2 != NULL);
@@ -397,9 +403,21 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
/* lines are parallel; off1a is a good meet point */
copy_v3_v3(meetco, off1a);
}
- else if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
- /* another test says they are parallel */
- copy_v3_v3(meetco, off1a);
+ else {
+ iret =isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2);
+ if (iret == 0) {
+ /* lines colinear: another test says they are parallel. so shouldn't happen */
+ copy_v3_v3(meetco, off1a);
+ }
+ else if (iret == 2) {
+ /* lines are not coplanar; meetco and isect2 are nearest to first and second lines */
+ if (len_v3v3(meetco, isect2) > 100.0f * (float)BEVEL_EPSILON) {
+ /* offset lines don't meet: project average onto emid; this is not ideal (see TODO above) */
+ mid_v3_v3v3(co, meetco, isect2);
+ closest_to_line_v3(meetco, co, v->co, BM_edge_other_vert(emid->e, v)->co);
+ }
+ }
+ /* else iret == 1 and the lines are coplanar so meetco has the intersection */
}
}
@@ -753,8 +771,7 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
if (e->prev->prev->is_bev) {
BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */
/* find meet point between e->prev->prev and e and attach e->prev there */
- /* TODO: fix case when one or both faces in following are NULL */
- offset_in_two_planes(e->prev->prev, e, bv->v,
+ offset_in_two_planes(e->prev->prev, e, e->prev, bv->v,
e->prev->prev->fnext, e->fprev, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev->prev;