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:
Diffstat (limited to 'source/blender/bmesh/tools/bmesh_bevel.c')
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c102
1 files changed, 102 insertions, 0 deletions
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)) {