diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2019-02-07 18:42:28 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2019-02-07 18:42:28 +0300 |
commit | dec4f6d7ed9886e36e76df2210bf50e6bb7bb799 (patch) | |
tree | b4450be2b6557b0b967cc84e0821254893a97796 /source/blender/bmesh | |
parent | 4c42e949e98fea9b9c8b64d9062a379749b77aa1 (diff) |
Bevel: better attachment points for unbeveled edges, arc miter.
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.c | 139 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.h | 2 |
2 files changed, 98 insertions, 43 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 5dea6da7b1d..5833e3427a4 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -14,7 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/** \file \ingroup bmesh +/** \file bmesh_bevel.c * * Main functions for beveling a BMesh (used by the tool and modifier) */ @@ -76,6 +76,7 @@ typedef struct EdgeHalf { BMFace *fnext; /* face between this edge and next, if any */ struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */ struct BoundVert *rightv; /* right boundary vert, if beveled */ + int profile_index; /* offset into profile to attach non-beveled edge */ int seg; /* how many segments for the bevel */ float offset_l; /* offset for this edge, on left side */ float offset_r; /* offset for this edge, on right side */ @@ -2212,7 +2213,7 @@ static void adjust_miter_coords(BevelParams *bp, BevVert *bv, EdgeHalf *emiter) adjust_bound_vert(v1, co1); /* co3 is similar, but plane is through v3next and line is other side of miter edge */ - emiter_other = v3->efirst; + emiter_other = v3->elast; /*v3->efirst;*/ vother = BM_edge_other_vert(emiter_other->e, bv->v); sub_v3_v3v3(edge_dir, bv->v->co, vother->co); normalize_v3(edge_dir); @@ -2366,17 +2367,33 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) e3->leftv = e3->rightv = v; } ang_kind = edges_angle_kind(e, e2, bv->v); + + /* Are we doing special mitering? + * ang_kind is -1, 0, 1 as angle is <, =, > 180 degrees. + * There can only be one outer reflex angle, so only one outer miter, + * and emiter will be set to the first edge of such an edge. + * A miter kind of BEVEL_MITER_SHARP means no special miter */ + if ((miter_outer != BEVEL_MITER_SHARP && !emiter && ang_kind == 1) || (miter_inner != BEVEL_MITER_SHARP && ang_kind == -1)) { if (ang_kind == 1) - emiter = e; /* a reflex angle, i.e., the (only) outer miter, if any */ + emiter = e; /* make one or two more boundverts; for now all will have same co */ v1 = v; v1->ebev = NULL; + if (ang_kind == 1 && miter_outer == BEVEL_MITER_PATCH) + v2 = add_new_bound_vert(mem_arena, vm, co); + else + v2 = NULL; + v3 = add_new_bound_vert(mem_arena, vm, co); + v3->ebev = e2; + v3->efirst = e2; + v3->elast = e2; + v3->eon = NULL; + e2->leftv = v3; if (ang_kind == 1 && miter_outer == BEVEL_MITER_PATCH) { v1->is_patch_start = true; - v2 = add_new_bound_vert(mem_arena, vm, co); v2->eon = v1->eon; v2->sinratio = v1->sinratio; v2->ebev = NULL; @@ -2398,22 +2415,29 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) else { v1->is_arc_start = true; copy_v3_v3(v1->profile.midco, co); - v2 = NULL; if (e->next == e2) { v1->elast = v1->efirst; } else { + int between = nip + nnip; + int bet2 = between / 2; + bool betodd = (between % 2) == 1; + int i = 0; + /* Put first half of in-between edges at index 0, + * second half at index bp->seg. + * If between is odd, put middle one at midindex */ for (e3 = e->next; e3 != e2; e3 = e3->next) { v1->elast = e3; + if (i < bet2) + e3->profile_index = 0; + else if (betodd && i == bet2) + e3->profile_index = bp->seg / 2; + else + e3->profile_index = bp->seg; + i++; } } } - v3 = add_new_bound_vert(mem_arena, vm, co); - v3->ebev = e2; - v3->efirst = e2; - v3->elast = e2; - v3->eon = NULL; - e2->leftv = v3; } } else { @@ -4933,6 +4957,8 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) e->seg = 0; } e->is_rev = (bme->v2 == v); + e->leftv = e->rightv = NULL; + e->profile_index = 0; } /* now done with tag flag */ @@ -5059,9 +5085,9 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) BoundVert *v, *vstart, *vend; EdgeHalf *e, *eprev; VMesh *vm; - int i, k, n; + int i, k, n, kstart, kend; bool do_rebuild = false; - bool go_ccw, corner3special, keep; + bool go_ccw, corner3special, keep, on_profile_start; BMVert *bmv; BMEdge *bme, *bme_new, *bme_prev; BMFace *f_new, *f_other; @@ -5108,56 +5134,85 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) go_ccw = false; } } + on_profile_start = false; if (go_ccw) { vstart = eprev->rightv; vend = e->leftv; + if (e->profile_index > 0) { + vstart = vstart->prev; + on_profile_start = true; + } } else { vstart = eprev->leftv; vend = e->rightv; + if (eprev->profile_index > 0) { + vstart = vstart->next; + on_profile_start = true; + } } BLI_assert(vstart != NULL && vend != NULL); v = vstart; - BLI_array_append(vv, v->nv.v); - BLI_array_append(ee, bme); - /* check for special case: multisegment 3rd face opposite a beveled edge with no vmesh */ - corner3special = (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev); + if (!on_profile_start) { + BLI_array_append(vv, v->nv.v); + BLI_array_append(ee, bme); + } while (v != vend) { + /* check for special case: multisegment 3rd face opposite a beveled edge with no vmesh */ + corner3special = (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev); if (go_ccw) { - if (vm->seg > 1) { - if (vm->mesh_kind == M_ADJ || bp->vertex_only || corner3special) { - i = v->index; - for (k = 1; k < vm->seg; k++) { - bmv = mesh_vert(vm, i, 0, k)->v; - BLI_array_append(vv, bmv); - BLI_array_append(ee, bme); /* TODO: maybe better edge here */ - if (corner3special && v->ebev && !v->ebev->is_seam) - BLI_array_append(vv_fix, bmv); - } + i = v->index; + if (on_profile_start) { + kstart = e->profile_index; + on_profile_start = false; + } + else { + kstart = 1; + } + if (eprev->rightv == v && eprev->profile_index > 0) { + kend = eprev->profile_index; + } + else { + kend = vm->seg; + } + for (k = kstart; k <= kend; k++) { + bmv = mesh_vert(vm, i, 0, k)->v; + if (bmv) { + BLI_array_append(vv, bmv); + BLI_array_append(ee, bme); /* TODO: maybe better edge here */ + if (corner3special && v->ebev && !v->ebev->is_seam && k != vm->seg) + BLI_array_append(vv_fix, bmv); } } v = v->next; } else { /* going cw */ - if (vm->seg > 1) { - if (vm->mesh_kind == M_ADJ || bp->vertex_only || - (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev)) - { - i = v->prev->index; - for (k = vm->seg - 1; k > 0; k--) { - bmv = mesh_vert(vm, i, 0, k)->v; - BLI_array_append(vv, bmv); - BLI_array_append(ee, bme); - if (corner3special && v->ebev && !v->ebev->is_seam) - BLI_array_append(vv_fix, bmv); - } + i = v->prev->index; + if (on_profile_start) { + kstart = eprev->profile_index; + on_profile_start = false; + } + else { + kstart = vm->seg - 1; + } + if (e->rightv == v->prev && e->profile_index > 0) { + kend = e->profile_index; + } + else { + kend = 0; + } + for (k = kstart; k >= kend; k--) { + bmv = mesh_vert(vm, i, 0, k)->v; + if (bmv) { + BLI_array_append(vv, bmv); + BLI_array_append(ee, bme); + if (corner3special && v->ebev && !v->ebev->is_seam && k != 0) + BLI_array_append(vv_fix, bmv); } } v = v->prev; } - BLI_array_append(vv, v->nv.v); - BLI_array_append(ee, bme); } do_rebuild = true; } @@ -6047,7 +6102,7 @@ void BM_mesh_bevel( bp.use_weights = use_weights; bp.loop_slide = loop_slide; bp.limit_offset = limit_offset; - bp.offset_adjust = false; // DEBUG true; + bp.offset_adjust = false; bp.dvert = dvert; bp.vertex_group = vertex_group; bp.mat_nr = mat; diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index 9d8e4de2772..bb4c3191c4b 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -17,7 +17,7 @@ #ifndef __BMESH_BEVEL_H__ #define __BMESH_BEVEL_H__ -/** \file \ingroup bmesh +/** \file bmesh_bevel.h */ struct MDeformVert; |