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:
authorHoward Trickey <howard.trickey@gmail.com>2014-05-29 15:32:16 +0400
committerHoward Trickey <howard.trickey@gmail.com>2014-05-29 15:32:16 +0400
commit6bde9a52f9270841331c7762a5df9505894d962a (patch)
treece2166554d1f9dd8db7a204ffa1bbd87477e319b /source/blender/bmesh/tools/bmesh_bevel.c
parent6c721a86ffae49b7ce34b8a83fbe9346faefd043 (diff)
Fix T39174 Bevel didn't maintain edge attributes.
When rebuilding the polygons that touch bevel-involved vertices, need to copy the edge attributes from corresponding original edges. Special treatment of corner segments, to maintain continuity of smooth and seam attributes. Another fix: if have four meeting edges, two opposite ones beveled and the other two not, propgate the non-beveled-edges attributes across the line that joins them (perpendicular to the bevel).
Diffstat (limited to 'source/blender/bmesh/tools/bmesh_bevel.c')
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c125
1 files changed, 119 insertions, 6 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 1f3002e05f9..f436c1fc919 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -3082,19 +3082,24 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
BoundVert *v, *vstart, *vend;
EdgeHalf *e, *eprev;
VMesh *vm;
- int i, k;
+ int i, k, n;
bool do_rebuild = false;
BMVert *bmv;
+ BMEdge *bme, *bme_new, *bme_prev;
+ BMFace *f_new;
BMVert **vv = NULL;
BMVert **vv_fix = NULL;
+ BMEdge **ee = NULL;
BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
BLI_array_staticdeclare(vv_fix, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
lprev = l->prev;
bv = find_bevvert(bp, l->v);
e = find_edge_half(bv, l->e);
+ bme = e->e;
eprev = find_edge_half(bv, lprev->e);
BLI_assert(e != NULL && eprev != NULL);
vstart = eprev->leftv;
@@ -3105,6 +3110,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
v = vstart;
vm = bv->vmesh;
BLI_array_append(vv, v->nv.v);
+ BLI_array_append(ee, bme);
while (v != vend) {
if (vm->mesh_kind == M_NONE && v->ebev && v->ebev->seg > 1 && v->ebev != e && v->ebev != eprev) {
/* case of 3rd face opposite a beveled edge, with no vmesh */
@@ -3113,6 +3119,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
for (k = 1; k < e->seg; k++) {
bmv = mesh_vert(vm, i, 0, k)->v;
BLI_array_append(vv, bmv);
+ BLI_array_append(ee, bme);
/* may want to merge UVs of these later */
if (!e->is_seam)
BLI_array_append(vv_fix, bmv);
@@ -3124,25 +3131,57 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
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);
}
}
v = v->prev;
BLI_array_append(vv, v->nv.v);
+ BLI_array_append(ee, bme);
}
do_rebuild = true;
}
else {
BLI_array_append(vv, l->v);
+ BLI_array_append(ee, l->e);
}
}
if (do_rebuild) {
- BMFace *f_new = bev_create_ngon(bm, vv, BLI_array_count(vv), NULL, f, true);
+ n = BLI_array_count(vv);
+ f_new = bev_create_ngon(bm, vv, n, NULL, f, true);
for (k = 0; k < BLI_array_count(vv_fix); k++) {
bev_merge_uvs(bm, vv_fix[k]);
}
+ /* copy attributes from old edges */
+ BLI_assert(n == BLI_array_count(ee));
+ bme_prev = ee[n - 1];
+ for (k = 0; k < n; k++) {
+ bme_new = BM_edge_exists(vv[k], vv[(k + 1) % n]);
+ BLI_assert(ee[k] && bme_new);
+ if (ee[k] != bme_new) {
+ BM_elem_attrs_copy(bm, bm, ee[k], bme_new);
+ /* want to undo seam and smooth for corner segments
+ * if those attrs aren't contiguous around face */
+ if (k < n - 1 && ee[k] == ee[k + 1]) {
+ if (BM_elem_flag_test(ee[k], BM_ELEM_SEAM) &&
+ !BM_elem_flag_test(bme_prev, BM_ELEM_SEAM))
+ {
+ BM_elem_flag_disable(bme_new, BM_ELEM_SEAM);
+ }
+ /* actually want "sharp" to be contiguous, so reverse the test */
+ if (!BM_elem_flag_test(ee[k], BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test(bme_prev, BM_ELEM_SMOOTH))
+ {
+ BM_elem_flag_enable(bme_new, BM_ELEM_SMOOTH);
+ }
+ }
+ else
+ bme_prev = ee[k];
+ }
+ }
+
/* don't select newly created boundary faces... */
if (f_new) {
BM_elem_flag_disable(f_new, BM_ELEM_TAG);
@@ -3150,6 +3189,8 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
}
BLI_array_free(vv);
+ BLI_array_free(vv_fix);
+ BLI_array_free(ee);
return do_rebuild;
}
@@ -3243,6 +3284,70 @@ static void bev_merge_end_uvs(BMesh *bm, BevVert *bv, EdgeHalf *e)
}
/*
+ * Is this BevVert the special case of a weld (no vmesh) where there are
+ * four edges total, two are beveled, and the other two are on opposite sides?
+ */
+static bool bevvert_is_weld_cross(BevVert *bv)
+{
+ return (bv->edgecount == 4 && bv->selcount == 2 &&
+ ((bv->edges[0].is_bev && bv->edges[2].is_bev) ||
+ (bv->edges[1].is_bev && bv->edges[3].is_bev)));
+}
+
+/*
+ * Copy edge attribute data across the non-beveled crossing edges of a cross weld.
+ *
+ * Situation looks like this:
+ *
+ * e->next
+ * |
+ * -------3-------
+ * -------2-------
+ * -------1------- e
+ * -------0------
+ * |
+ * e->prev
+ *
+ * where e is the EdgeHalf of one of the beveled edges,
+ * e->next and e->prev are EdgeHalfs for the unbeveled edges of the cross
+ * and their attributes are to be copied to the edges 01, 12, 23.
+ * The vert i is mesh_vert(vm, vmindex, 0, i)->v
+ */
+static void weld_cross_attrs_copy(BMesh *bm, BevVert *bv, VMesh *vm, int vmindex, EdgeHalf *e)
+{
+ BMEdge *bme_prev, *bme_next, *bme;
+ int i, nseg;
+ bool disable_seam, enable_smooth;
+
+ bme_prev = bme_next = NULL;
+ for (i = 0; i < 4; i++) {
+ if (&bv->edges[i] == e) {
+ bme_prev = bv->edges[(i + 3) % 4].e;
+ bme_next = bv->edges[(i + 1) % 4].e;
+ break;
+ }
+ }
+ BLI_assert(bme_prev && bme_next);
+
+ /* want seams and sharp edges to cross only if that way on both sides */
+ disable_seam = BM_elem_flag_test(bme_prev, BM_ELEM_SEAM) != BM_elem_flag_test(bme_next, BM_ELEM_SEAM);
+ enable_smooth = BM_elem_flag_test(bme_prev, BM_ELEM_SMOOTH) != BM_elem_flag_test(bme_next, BM_ELEM_SMOOTH);
+
+ nseg = e->seg;
+ for (i = 0; i < nseg; i++) {
+ bme = BM_edge_exists(mesh_vert(vm, vmindex, 0, i)->v,
+ mesh_vert(vm, vmindex, 0, i + 1)->v);
+ BLI_assert(bme);
+ BM_elem_attrs_copy(bm, bm, bme_prev, bme);
+ if (disable_seam)
+ BM_elem_flag_disable(bme, BM_ELEM_SEAM);
+ if (enable_smooth)
+ BM_elem_flag_enable(bme, BM_ELEM_SMOOTH);
+ }
+}
+
+
+/*
* Build the polygons along the selected Edge
*/
static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
@@ -3286,15 +3391,15 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
f1 = e1->fprev;
f2 = e1->fnext;
+ i1 = e1->leftv->index;
+ i2 = e2->leftv->index;
+ vm1 = bv1->vmesh;
+ vm2 = bv2->vmesh;
if (nseg == 1) {
bev_create_quad_straddle(bm, bmv1, bmv2, bmv3, bmv4, f1, f2, e1->is_seam);
}
else {
- i1 = e1->leftv->index;
- i2 = e2->leftv->index;
- vm1 = bv1->vmesh;
- vm2 = bv2->vmesh;
bmv1i = bmv1;
bmv2i = bmv2;
odd = nseg % 2;
@@ -3330,6 +3435,14 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
BLI_assert(bme1 && bme2);
BM_elem_attrs_copy(bm, bm, bme, bme1);
BM_elem_attrs_copy(bm, bm, bme, bme2);
+
+ /* If either end is a "weld cross", want continuity of edge attributes across end edge(s) */
+ if (bevvert_is_weld_cross(bv1)) {
+ weld_cross_attrs_copy(bm, bv1, vm1, i1, e1);
+ }
+ if (bevvert_is_weld_cross(bv2)) {
+ weld_cross_attrs_copy(bm, bv2, vm2, i2, e2);
+ }
}
/* Returns the square of the length of the chord from parameter u0 to parameter u1