From 3504b27c5074d49ed19f86c212c584f37a343d33 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Wed, 27 Jun 2018 20:19:15 +0530 Subject: Patch to fix shading continuity. Added it as extension to harden. Tried out different methods to fix normals, Though as with width and segments changes shape, orientation of new polys a non-smooth method of fix was not possible. Current method aggregates vertex normals into a smooth fan without affecting edge shading. Still need to fix the crease at new vertex edges --- source/blender/bmesh/intern/bmesh_operators.h | 1 + source/blender/bmesh/tools/bmesh_bevel.c | 102 ++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 1b5694c3ee8..9f6ac50a3e5 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -131,6 +131,7 @@ enum { BEVEL_HN_NONE, BEVEL_HN_FACE, BEVEL_HN_ADJ, + BEVEL_HN_FIX_SHA, }; extern const BMOpDefine *bmo_opdefines[]; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 186d3a3c8e0..132436c70f0 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -44,6 +44,7 @@ #include "BKE_customdata.h" #include "BKE_deform.h" +#include "BKE_mesh.h" #include "eigen_capi.h" @@ -1721,6 +1722,85 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B } while (bcur != bstart); } +static void bevel_fix_normal_shading_continuity(BevelParams *bp, BMesh *bm, BevVert *bv, GHash *faceHash) +{ + VMesh *vm = bv->vmesh; + BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; + int ns = vm->seg; + int ns2 = ns / 2; + int count = 0; + + BMFace *f; + BMLoop *l; + BMIter liter, fiter; + + int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + + if (BLI_ghash_haskey(faceHash, f)) { + BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); + } + } + } + + do { + for (int i = 0; i <= ns; i++) { + BMVert *v1 = mesh_vert(vm, bcur->index, 0, i)->v, *v2; + BMEdge *e; + BMIter eiter; + + BM_ITER_ELEM(e, &eiter, v1, BM_EDGES_OF_VERT) { + BMFace *f_a, *f_b; + BM_edge_face_pair(e, &f_a, &f_b); + + bool _f_a = false, _f_b = false; + if (f_a) + _f_a = BLI_ghash_haskey(faceHash, f_a); + if (f_b) + _f_b = BLI_ghash_haskey(faceHash, f_b); + if (_f_a ^ _f_b) { + + BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { + + if (l->f == f_a || l->f == f_b) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + float res[3]; + copy_v3_v3(res, f_a->no); + add_v3_v3(res, f_b->no); + mul_v3_fl(res, 0.5f); + normalize_v3(res); + + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], res, clnors); + } + } + } + } + + float res_n[3]; + zero_v3(res_n); + BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { + if (!BLI_ghash_haskey(faceHash, l->f)) { + add_v3_v3(res_n, l->f->no); + } + } + normalize_v3(res_n); + BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { + if (BLI_ghash_haskey(faceHash, l->f)) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm ->lnor_spacearr->lspacearr[l_index], res_n, clnors); + } + } + } + bcur = bcur->next; + } while (bcur != start); +} + /* Set the any_seam property for a BevVert and all its BoundVerts */ static void set_bound_vert_seams(BevVert *bv, bool mark_seam, bool mark_sharp) { @@ -5648,6 +5728,17 @@ void BM_mesh_bevel( } } + GHash *faceHash; + if (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA) { + faceHash = BLI_ghash_ptr_new(__func__); + BMFace *f; + BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_TAG)) { + BLI_ghash_insert(faceHash, f, NULL); + } + } + } + /* Build polygons for edges */ if (!bp.vertex_only) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -5664,6 +5755,7 @@ void BM_mesh_bevel( bevel_harden_normals_mode(bm, &bp, bv, op); } + /* Rebuild face polygons around affected vertices */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { @@ -5672,6 +5764,16 @@ void BM_mesh_bevel( } } + if (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA) { + BM_mesh_normals_update(bm); + BM_lnorspace_update(bm); + GHASH_ITER(giter, bp.vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + if (!bm->use_toolflags) + bevel_fix_normal_shading_continuity(&bp, bm, bv, faceHash); + } + BLI_ghash_free(faceHash, NULL, NULL); + } BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { -- cgit v1.2.3