From 368a64fe041ee0950584f5b51e2f64036edb31d0 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 2 Jul 2018 22:55:33 +0530 Subject: Refactored bevel normal editing functionality. --- source/blender/bmesh/tools/bmesh_bevel.c | 39 ++++++++-------- source/blender/bmesh/tools/bmesh_bevel.h | 2 +- source/blender/makesdna/DNA_modifier_types.h | 6 +++ source/blender/modifiers/intern/MOD_bevel.c | 69 ++++++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 25 deletions(-) (limited to 'source/blender') diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 9259be7b240..789c2ae4c63 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -34,6 +34,7 @@ #include "DNA_object_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "BLI_array.h" #include "BLI_alloca.h" @@ -5650,7 +5651,7 @@ void BM_mesh_bevel( const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const int hnmode, BMOperator *op) + const int hnmode, void *mod_bmop_customdata) { BMIter iter; BMVert *v, *v_next; @@ -5659,6 +5660,9 @@ void BM_mesh_bevel( BevelParams bp = {NULL}; GHashIterator giter; + BMOperator *op; + BevelModNorEditData *clnordata; + bp.offset = offset; bp.offset_type = offset_type; bp.seg = segments; @@ -5687,6 +5691,14 @@ void BM_mesh_bevel( BLI_memarena_use_calloc(bp.mem_arena); set_profile_spacing(&bp); + if (bm->use_toolflags) + op = mod_bmop_customdata; + else { + clnordata = mod_bmop_customdata; + clnordata->faceHash = BLI_ghash_ptr_new(__func__); + bp.faceHash = clnordata->faceHash; + } + /* Analyze input vertices, sorting edges and assigning initial new vertex positions */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { @@ -5712,11 +5724,6 @@ void BM_mesh_bevel( adjust_offsets(&bp); } - const bool do_fix_shading = (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA); - if (do_fix_shading) { - bp.faceHash = BLI_ghash_ptr_new(__func__); - } - /* Build the meshes around vertices, now that positions are final */ /* Note: could use GHASH_ITER over bp.vert_hash when backward compatibility no longer matters */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -5736,10 +5743,11 @@ void BM_mesh_bevel( } } - if (bm->use_toolflags) { - GHASH_ITER(giter, bp.vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - bevel_extend_edge_data(bv); + /* Extend edge data like sharp edges and precompute normals for harden */ + GHASH_ITER(giter, bp.vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + bevel_extend_edge_data(bv); + if (bm->use_toolflags) { bevel_harden_normals_mode(bm, &bp, bv, op); } } @@ -5759,17 +5767,6 @@ void BM_mesh_bevel( } } - if (do_fix_shading) { - BM_mesh_normals_update(bm); - BM_lnorspace_update(bm); - GHASH_ITER(giter, bp.vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - if (bv->fix_shading) - bevel_fix_normal_shading_continuity(&bp, bm, bv); - } - BLI_ghash_free(bp.faceHash, NULL, NULL); - } - /* When called from operator (as opposed to modifier), bm->use_toolflags * will be set, and we to transfer the oflags to BM_ELEM_TAGs */ if (bm->use_toolflags) { diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index f43289aac27..5cf8b1e78bb 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -34,6 +34,6 @@ void BM_mesh_bevel( const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const int hnmode, BMOperator *op); + const int hnmode, void *mod_bmop_customdata); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 7ae9383a907..33381be0ef5 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -318,6 +318,11 @@ enum { MOD_EDGESPLIT_FROMFLAG = (1 << 2), }; +typedef struct BevelModNorEditData { + struct GHash *faceHash; + struct GHash *vert_hash; +} BevelModNorEditData; + typedef struct BevelModifierData { ModifierData modifier; @@ -337,6 +342,7 @@ typedef struct BevelModifierData { int hnmode; float hn_strength; char defgrp_name[64]; + struct BevelModNorEditData clnordata; } BevelModifierData; /* BevelModifierData->flags and BevelModifierData->lim_flags */ diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 735436f3971..b30d6c2e669 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -140,6 +140,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn e_next = lfan_pivot->e; BLI_SMALLSTACK_DECLARE(loops, BMLoop *); float cn_wght[3] = { 0.0f, 0.0f, 0.0f }; + bool normal_to_recon_face = false; while (true) { lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); @@ -208,6 +209,62 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn } } +static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *bm) +{ + BM_mesh_normals_update(bm); + BM_lnorspace_update(bm); + + GHash *faceHash = bmd->clnordata.faceHash; + BMEdge *e; + BMLoop *l; + BMIter liter, eiter; + + int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + float ref = 10.0f; + + BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) { + 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) { + + for (int i = 0; i < 2; i++) { + BMVert *v = (i == 0) ? e->v1 : e->v2; + BM_ITER_ELEM(l, &liter, v, 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 n_final[3], pow_a[3], pow_b[3]; + + zero_v3(n_final); + copy_v3_v3(pow_a, f_a->no); + copy_v3_v3(pow_b, f_b->no); + if (_f_a) { + mul_v3_fl(pow_a, bmd->res / ref); + mul_v3_fl(pow_b, ref / bmd->res); + } + else { + mul_v3_fl(pow_b, bmd->res / ref); + mul_v3_fl(pow_a, ref / bmd->res); + } + add_v3_v3(n_final, pow_a); + add_v3_v3(n_final, pow_b); + normalize_v3(n_final); + + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + } + } + } + } + } +} + /* * This calls the new bevel code (added since 2.64) */ @@ -301,10 +358,14 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes BM_mesh_bevel(bm, bmd->value, offset_type, bmd->res, bmd->profile, vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, - dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL); + dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, &bmd->clnordata); - if (bmd->hnmode != MOD_BEVEL_HN_NONE && bmd->hnmode != MOD_BEVEL_FIX_SHA) - bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); + if (bmd->hnmode != MOD_BEVEL_HN_NONE) { + if (bmd->hnmode != BEVEL_HN_FIX_SHA) + bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); + else + bevel_fix_normal_shading_continuity(bmd, bm); + } if(set_wn_strength) bevel_set_weighted_normal_face_strength(bm, md->scene); @@ -316,6 +377,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ BM_mesh_free(bm); + BLI_ghash_free(bmd->clnordata.faceHash, NULL, NULL); + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; return result; -- cgit v1.2.3