Bevel: better attachment points for unbeveled edges, arc miter.
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user