Refactored bevel normal editing functionality.
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
|
#include "DNA_modifier_types.h"
|
||||||
|
|
||||||
#include "BLI_array.h"
|
#include "BLI_array.h"
|
||||||
#include "BLI_alloca.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 bool vertex_only, const bool use_weights, const bool limit_offset,
|
||||||
const struct MDeformVert *dvert, const int vertex_group, const int mat,
|
const struct MDeformVert *dvert, const int vertex_group, const int mat,
|
||||||
const bool loop_slide, const bool mark_seam, const bool mark_sharp,
|
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;
|
BMIter iter;
|
||||||
BMVert *v, *v_next;
|
BMVert *v, *v_next;
|
||||||
@@ -5659,6 +5660,9 @@ void BM_mesh_bevel(
|
|||||||
BevelParams bp = {NULL};
|
BevelParams bp = {NULL};
|
||||||
GHashIterator giter;
|
GHashIterator giter;
|
||||||
|
|
||||||
|
BMOperator *op;
|
||||||
|
BevelModNorEditData *clnordata;
|
||||||
|
|
||||||
bp.offset = offset;
|
bp.offset = offset;
|
||||||
bp.offset_type = offset_type;
|
bp.offset_type = offset_type;
|
||||||
bp.seg = segments;
|
bp.seg = segments;
|
||||||
@@ -5687,6 +5691,14 @@ void BM_mesh_bevel(
|
|||||||
BLI_memarena_use_calloc(bp.mem_arena);
|
BLI_memarena_use_calloc(bp.mem_arena);
|
||||||
set_profile_spacing(&bp);
|
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 */
|
/* Analyze input vertices, sorting edges and assigning initial new vertex positions */
|
||||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||||
@@ -5712,11 +5724,6 @@ void BM_mesh_bevel(
|
|||||||
adjust_offsets(&bp);
|
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 */
|
/* 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 */
|
/* 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) {
|
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||||
@@ -5736,10 +5743,11 @@ void BM_mesh_bevel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bm->use_toolflags) {
|
/* Extend edge data like sharp edges and precompute normals for harden */
|
||||||
GHASH_ITER(giter, bp.vert_hash) {
|
GHASH_ITER(giter, bp.vert_hash) {
|
||||||
bv = BLI_ghashIterator_getValue(&giter);
|
bv = BLI_ghashIterator_getValue(&giter);
|
||||||
bevel_extend_edge_data(bv);
|
bevel_extend_edge_data(bv);
|
||||||
|
if (bm->use_toolflags) {
|
||||||
bevel_harden_normals_mode(bm, &bp, bv, op);
|
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
|
/* When called from operator (as opposed to modifier), bm->use_toolflags
|
||||||
* will be set, and we to transfer the oflags to BM_ELEM_TAGs */
|
* will be set, and we to transfer the oflags to BM_ELEM_TAGs */
|
||||||
if (bm->use_toolflags) {
|
if (bm->use_toolflags) {
|
||||||
|
|||||||
@@ -34,6 +34,6 @@ void BM_mesh_bevel(
|
|||||||
const float profile, const bool vertex_only, const bool use_weights,
|
const float profile, const bool vertex_only, const bool use_weights,
|
||||||
const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group,
|
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 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__ */
|
#endif /* __BMESH_BEVEL_H__ */
|
||||||
|
|||||||
@@ -318,6 +318,11 @@ enum {
|
|||||||
MOD_EDGESPLIT_FROMFLAG = (1 << 2),
|
MOD_EDGESPLIT_FROMFLAG = (1 << 2),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct BevelModNorEditData {
|
||||||
|
struct GHash *faceHash;
|
||||||
|
struct GHash *vert_hash;
|
||||||
|
} BevelModNorEditData;
|
||||||
|
|
||||||
typedef struct BevelModifierData {
|
typedef struct BevelModifierData {
|
||||||
ModifierData modifier;
|
ModifierData modifier;
|
||||||
|
|
||||||
@@ -337,6 +342,7 @@ typedef struct BevelModifierData {
|
|||||||
int hnmode;
|
int hnmode;
|
||||||
float hn_strength;
|
float hn_strength;
|
||||||
char defgrp_name[64];
|
char defgrp_name[64];
|
||||||
|
struct BevelModNorEditData clnordata;
|
||||||
} BevelModifierData;
|
} BevelModifierData;
|
||||||
|
|
||||||
/* BevelModifierData->flags and BevelModifierData->lim_flags */
|
/* BevelModifierData->flags and BevelModifierData->lim_flags */
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn
|
|||||||
e_next = lfan_pivot->e;
|
e_next = lfan_pivot->e;
|
||||||
BLI_SMALLSTACK_DECLARE(loops, BMLoop *);
|
BLI_SMALLSTACK_DECLARE(loops, BMLoop *);
|
||||||
float cn_wght[3] = { 0.0f, 0.0f, 0.0f };
|
float cn_wght[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
|
bool normal_to_recon_face = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
|
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)
|
* 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,
|
BM_mesh_bevel(bm, bmd->value, offset_type, bmd->res, bmd->profile,
|
||||||
vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp,
|
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)
|
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);
|
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)
|
if(set_wn_strength)
|
||||||
bevel_set_weighted_normal_face_strength(bm, md->scene);
|
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->ftoolflagpool == NULL); /* make sure we never alloc'd these */
|
||||||
BM_mesh_free(bm);
|
BM_mesh_free(bm);
|
||||||
|
|
||||||
|
BLI_ghash_free(bmd->clnordata.faceHash, NULL, NULL);
|
||||||
|
|
||||||
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user