Added ability to harden normals.
Uses 2 different params: mode and strength. There are still some hiccups with how 2.8 interacts with normals. Will resolve as support gets better
This commit is contained in:
parent
18a8bb5c16
commit
0c6410ec0c
|
@ -1225,6 +1225,41 @@ void BM_lnorspace_update(BMesh *bm)
|
|||
}
|
||||
}
|
||||
|
||||
void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges)
|
||||
{
|
||||
BMFace *f;
|
||||
BMEdge *e;
|
||||
BMIter fiter, eiter;
|
||||
BMLoop *l_curr, *l_first;
|
||||
|
||||
if (do_edges) {
|
||||
int index_edge;
|
||||
BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) {
|
||||
BMLoop *l_a, *l_b;
|
||||
|
||||
BM_elem_index_set(e, index_edge); /* set_inline */
|
||||
BM_elem_flag_disable(e, BM_ELEM_TAG);
|
||||
if (BM_edge_loop_pair(e, &l_a, &l_b)) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
bm->elem_index_dirty &= ~BM_EDGE;
|
||||
}
|
||||
|
||||
int index_face, index_loop = 0;
|
||||
BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) {
|
||||
BM_elem_index_set(f, index_face); /* set_inline */
|
||||
l_curr = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BM_elem_index_set(l_curr, index_loop++); /* set_inline */
|
||||
BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
|
||||
} while ((l_curr = l_curr->next) != l_first);
|
||||
}
|
||||
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auxillary function only used by rebuild to detect if any spaces were not marked as invalid.
|
||||
* Reports error if any of the lnor spaces change after rebuilding, meaning that all the possible
|
||||
|
|
|
@ -59,6 +59,7 @@ void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]);
|
|||
void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all);
|
||||
void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor);
|
||||
void BM_lnorspace_update(BMesh *bm);
|
||||
void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges);
|
||||
#ifndef NDEBUG
|
||||
void BM_lnorspace_err(BMesh *bm);
|
||||
#endif
|
||||
|
|
|
@ -1738,12 +1738,15 @@ static BMOpDefine bmo_bevel_def = {
|
|||
{"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */
|
||||
{"mark_seam", BMO_OP_SLOT_BOOL},
|
||||
{"mark_sharp", BMO_OP_SLOT_BOOL},
|
||||
{"strength", BMO_OP_SLOT_FLT},
|
||||
{"hnmode", BMO_OP_SLOT_INT},
|
||||
{{'\0'}},
|
||||
},
|
||||
/* slots_out */
|
||||
{{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
|
||||
{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
|
||||
{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
|
||||
{"normals.out", BMO_OP_SLOT_MAPPING},
|
||||
{{'\0'}},
|
||||
},
|
||||
|
||||
|
|
|
@ -127,6 +127,11 @@ enum {
|
|||
BEVEL_AMT_PERCENT
|
||||
};
|
||||
|
||||
enum {
|
||||
BEVEL_HN_FACE,
|
||||
BEVEL_HN_ADJ,
|
||||
};
|
||||
|
||||
extern const BMOpDefine *bmo_opdefines[];
|
||||
extern const int bmo_opdefines_total;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
|
|||
const bool loop_slide = BMO_slot_bool_get(op->slots_in, "loop_slide");
|
||||
const bool mark_seam = BMO_slot_bool_get(op->slots_in, "mark_seam");
|
||||
const bool mark_sharp = BMO_slot_bool_get(op->slots_in, "mark_sharp");
|
||||
const int hnmode = BMO_slot_int_get(op->slots_in, "hnmode");
|
||||
|
||||
if (offset > 0) {
|
||||
BMOIter siter;
|
||||
|
@ -65,7 +66,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp);
|
||||
BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp, 0/*hnmode*/, op);
|
||||
|
||||
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
|
||||
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "BLI_array.h"
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
|
@ -207,6 +208,7 @@ typedef struct BevelParams {
|
|||
const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */
|
||||
int vertex_group; /* vertex group index, maybe set if vertex_only */
|
||||
int mat_nr; /* if >= 0, material number for bevel; else material comes from adjacent faces */
|
||||
int hnmode;
|
||||
} BevelParams;
|
||||
|
||||
// #pragma GCC diagnostic ignored "-Wpadded"
|
||||
|
@ -1648,6 +1650,76 @@ static void bevel_extend_edge_data(BevVert *bv)
|
|||
} while (bcur != start);
|
||||
}
|
||||
|
||||
static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, BMOperator *op)
|
||||
{
|
||||
int mode = 1;
|
||||
|
||||
VMesh *vm = bv->vmesh;
|
||||
BoundVert *bcur = vm->boundstart, *bstart = bcur;
|
||||
int ns = vm->seg, ns2 = ns / 2;
|
||||
|
||||
BMEdge *e;
|
||||
BMIter eiter;
|
||||
|
||||
BMOpSlot *nslot = BMO_slot_get(op->slots_out, "normals.out");
|
||||
float n_final[3] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (bp->hnmode == BEVEL_HN_FACE) {
|
||||
BLI_bitmap *faces = BLI_BITMAP_NEW(bm->totface, __func__);
|
||||
BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
|
||||
BMFace *f_a, *f_b;
|
||||
BM_edge_face_pair(e, &f_a, &f_b);
|
||||
|
||||
if (f_a && !BLI_BITMAP_TEST(faces, BM_elem_index_get(f_a))) {
|
||||
int f_area = BM_face_calc_area(f_a);
|
||||
float f_no[3];
|
||||
copy_v3_v3(f_no, f_a->no);
|
||||
mul_v3_fl(f_no, f_area);
|
||||
add_v3_v3(n_final, f_no);
|
||||
BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f_a));
|
||||
}
|
||||
if (f_b && !BLI_BITMAP_TEST(faces, BM_elem_index_get(f_b))) {
|
||||
int f_area = BM_face_calc_area(f_b);
|
||||
float f_no[3];
|
||||
copy_v3_v3(f_no, f_b->no);
|
||||
mul_v3_fl(f_no, f_area);
|
||||
add_v3_v3(n_final, f_no);
|
||||
BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f_b));
|
||||
}
|
||||
}
|
||||
}
|
||||
MEM_freeN(faces);
|
||||
normalize_v3(n_final);
|
||||
}
|
||||
else if (bp->hnmode == BEVEL_HN_ADJ) {
|
||||
BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
if (e->v1 == bv->v) {
|
||||
add_v3_v3(n_final, e->v2->no);
|
||||
}
|
||||
else {
|
||||
add_v3_v3(n_final, e->v1->no);
|
||||
}
|
||||
}
|
||||
}
|
||||
normalize_v3(n_final);
|
||||
}
|
||||
|
||||
do {
|
||||
if (BMO_slot_map_contains(nslot, bcur->nv.v) != true) {
|
||||
|
||||
float(*custom_normal) = MEM_callocN(sizeof(*custom_normal) * 3, __func__);
|
||||
add_v3_v3(custom_normal, n_final);
|
||||
normalize_v3(custom_normal);
|
||||
|
||||
BMO_slot_map_insert(op, nslot, bcur->nv.v, custom_normal);
|
||||
}
|
||||
bcur = bcur->next;
|
||||
} while (bcur != bstart);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -5482,7 +5554,8 @@ void BM_mesh_bevel(
|
|||
const float segments, 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 bool loop_slide, const bool mark_seam, const bool mark_sharp,
|
||||
const int hnmode, BMOperator *op)
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert *v, *v_next;
|
||||
|
@ -5505,6 +5578,7 @@ void BM_mesh_bevel(
|
|||
bp.mat_nr = mat;
|
||||
bp.mark_seam = mark_seam;
|
||||
bp.mark_sharp = mark_sharp;
|
||||
bp.hnmode = hnmode;
|
||||
|
||||
if (profile >= 0.999f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */
|
||||
bp.pro_super_r = PRO_SQUARE_R;
|
||||
|
@ -5561,6 +5635,13 @@ void BM_mesh_bevel(
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
|
@ -5571,9 +5652,7 @@ void BM_mesh_bevel(
|
|||
|
||||
BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
BevVert *bv = find_bevvert(&bp, v);
|
||||
BLI_assert(bv != NULL);
|
||||
bevel_extend_edge_data(bv);
|
||||
BLI_assert(find_bevvert(&bp, v) != NULL);
|
||||
BM_vert_kill(bm, v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ void BM_mesh_bevel(
|
|||
BMesh *bm, const float offset, const int offset_type, const float segments,
|
||||
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 mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp,
|
||||
const int hnmode, BMOperator *op);
|
||||
|
||||
#endif /* __BMESH_BEVEL_H__ */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_linklist_stack.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "BKE_editmesh.h"
|
||||
#include "BKE_unit.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_access.h"
|
||||
|
@ -134,6 +136,88 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_strength, int hnmode)
|
||||
{
|
||||
BKE_editmesh_lnorspace_update(em);
|
||||
BM_normals_loops_edges_tag(em->bm, true);
|
||||
int cd_clnors_offset = CustomData_get_offset(&em->bm->ldata, CD_CUSTOMLOOPNORMAL);
|
||||
|
||||
BMesh *bm = em->bm;
|
||||
BMFace *f;
|
||||
BMLoop *l, *l_cur, *l_first;
|
||||
BMIter fiter;
|
||||
|
||||
BMOpSlot *nslot = BMO_slot_get(bmop->slots_out, "normals.out");
|
||||
|
||||
BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
|
||||
l_cur = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
if (BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) ||
|
||||
(!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur))))
|
||||
{
|
||||
if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) {
|
||||
const int loop_index = BM_elem_index_get(l_cur);
|
||||
short *clnors = BM_ELEM_CD_GET_VOID_P(l_cur, cd_clnors_offset);
|
||||
BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors);
|
||||
}
|
||||
else {
|
||||
BMVert *v_pivot = l_cur->v;
|
||||
float *calc_n = BLI_ghash_lookup(nslot->data.ghash, v_pivot);
|
||||
|
||||
BMEdge *e_next;
|
||||
const BMEdge *e_org = l_cur->e;
|
||||
BMLoop *lfan_pivot, *lfan_pivot_next;
|
||||
|
||||
lfan_pivot = l_cur;
|
||||
e_next = lfan_pivot->e;
|
||||
BLI_SMALLSTACK_DECLARE(loops, BMLoop *);
|
||||
float cn_wght[3] = { 0.0f, 0.0f, 0.0f }, cn_unwght[3] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
while (true) {
|
||||
lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
|
||||
if (lfan_pivot_next) {
|
||||
BLI_assert(lfan_pivot_next->v == v_pivot);
|
||||
}
|
||||
else {
|
||||
e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
|
||||
}
|
||||
BLI_SMALLSTACK_PUSH(loops, lfan_pivot);
|
||||
float cur[3];
|
||||
mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f));
|
||||
add_v3_v3(cn_wght, cur);
|
||||
if(BM_elem_flag_test(lfan_pivot->f, BM_ELEM_SELECT))
|
||||
add_v3_v3(cn_unwght, cur);
|
||||
|
||||
if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
|
||||
break;
|
||||
}
|
||||
lfan_pivot = lfan_pivot_next;
|
||||
}
|
||||
|
||||
normalize_v3(cn_wght);
|
||||
normalize_v3(cn_unwght);
|
||||
if (calc_n) {
|
||||
mul_v3_fl(calc_n, face_strength);
|
||||
mul_v3_fl(cn_wght, 1.0f - face_strength);
|
||||
add_v3_v3(calc_n, cn_wght);
|
||||
normalize_v3(calc_n);
|
||||
}
|
||||
while ((l = BLI_SMALLSTACK_POP(loops))) {
|
||||
const int l_index = BM_elem_index_get(l);
|
||||
short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
|
||||
if (calc_n) {
|
||||
BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], calc_n, clnors);
|
||||
}
|
||||
else
|
||||
BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], cn_unwght, clnors);
|
||||
}
|
||||
BLI_ghash_remove(nslot->data.ghash, v_pivot, NULL, MEM_freeN);
|
||||
}
|
||||
}
|
||||
} while ((l_cur = l_cur->next) != l_first);
|
||||
}
|
||||
}
|
||||
|
||||
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
@ -226,6 +310,8 @@ static bool edbm_bevel_calc(wmOperator *op)
|
|||
const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
|
||||
const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
|
||||
const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
|
||||
const float strength = RNA_float_get(op->ptr, "strength");
|
||||
const int hnmode = RNA_enum_get(op->ptr, "hnmode");
|
||||
|
||||
|
||||
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
|
||||
|
@ -242,9 +328,9 @@ static bool edbm_bevel_calc(wmOperator *op)
|
|||
|
||||
EDBM_op_init(em, &bmop, op,
|
||||
"bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b "
|
||||
"material=%i loop_slide=%b mark_seam=%b mark_sharp=%b",
|
||||
"material=%i loop_slide=%b mark_seam=%b mark_sharp=%b strength=%f hnmode=%i",
|
||||
BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
|
||||
clamp_overlap, material, loop_slide, mark_seam, mark_sharp);
|
||||
clamp_overlap, material, loop_slide, mark_seam, mark_sharp, strength, hnmode);
|
||||
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
|
||||
|
@ -255,6 +341,8 @@ static bool edbm_bevel_calc(wmOperator *op)
|
|||
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
|
||||
}
|
||||
|
||||
bevel_harden_normals(em, &bmop, strength, hnmode);
|
||||
|
||||
/* no need to de-select existing geometry */
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
continue;
|
||||
|
@ -663,6 +751,12 @@ void MESH_OT_bevel(wmOperatorType *ot)
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static EnumPropertyItem harden_normals_items[] = {
|
||||
{ BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" },
|
||||
{ BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" },
|
||||
{ 0, NULL, 0, NULL, NULL },
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Bevel";
|
||||
ot->description = "Edge Bevel";
|
||||
|
@ -692,4 +786,6 @@ void MESH_OT_bevel(wmOperatorType *ot)
|
|||
RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp");
|
||||
RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material",
|
||||
"Material for bevel faces (-1 means use adjacent faces)", -1, 100);
|
||||
RNA_def_float(ot->srna, "strength", 0.5f, 0.0f, 1.0f, "Normal Strength", "Strength of calculated normal", 0.0f, 1.0f);
|
||||
RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_FACE, "Normal Mode", "Weighting mode for Harden Normals");
|
||||
}
|
||||
|
|
|
@ -7426,41 +7426,6 @@ void MESH_OT_point_normals(struct wmOperatorType *ot)
|
|||
|
||||
/********************** Split/Merge Loop Normals **********************/
|
||||
|
||||
static void normals_splitmerge_loops_edges_tag(BMesh *bm, const bool do_edges)
|
||||
{
|
||||
BMFace *f;
|
||||
BMEdge *e;
|
||||
BMIter fiter, eiter;
|
||||
BMLoop *l_curr, *l_first;
|
||||
|
||||
if (do_edges) {
|
||||
int index_edge;
|
||||
BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) {
|
||||
BMLoop *l_a, *l_b;
|
||||
|
||||
BM_elem_index_set(e, index_edge); /* set_inline */
|
||||
BM_elem_flag_disable(e, BM_ELEM_TAG);
|
||||
if (BM_edge_loop_pair(e, &l_a, &l_b)) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
bm->elem_index_dirty &= ~BM_EDGE;
|
||||
}
|
||||
|
||||
int index_face, index_loop = 0;
|
||||
BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) {
|
||||
BM_elem_index_set(f, index_face); /* set_inline */
|
||||
l_curr = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BM_elem_index_set(l_curr, index_loop++); /* set_inline */
|
||||
BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
|
||||
} while ((l_curr = l_curr->next) != l_first);
|
||||
}
|
||||
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
|
||||
}
|
||||
|
||||
static void normals_merge(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
|
||||
{
|
||||
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
|
||||
|
@ -7469,7 +7434,7 @@ static void normals_merge(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
|
|||
|
||||
BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR);
|
||||
|
||||
normals_splitmerge_loops_edges_tag(bm, false);
|
||||
BM_normals_loops_edges_tag(bm, false);
|
||||
|
||||
for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
|
||||
if (BM_elem_flag_test(lnor_ed->loop, BM_ELEM_TAG)) {
|
||||
|
@ -7512,7 +7477,7 @@ static void normals_split(BMesh *bm)
|
|||
|
||||
BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR);
|
||||
|
||||
normals_splitmerge_loops_edges_tag(bm, true);
|
||||
BM_normals_loops_edges_tag(bm, true);
|
||||
|
||||
const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
|
||||
BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
|
||||
|
@ -7695,7 +7660,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op)
|
|||
weight = (weight - 1) * 25;
|
||||
}
|
||||
|
||||
normals_splitmerge_loops_edges_tag(bm, true);
|
||||
BM_normals_loops_edges_tag(bm, true);
|
||||
|
||||
Heap *loop_weight = BLI_heap_new();
|
||||
|
||||
|
|
|
@ -334,6 +334,8 @@ typedef struct BevelModifierData {
|
|||
/* if the MOD_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */
|
||||
float bevel_angle;
|
||||
/* if the MOD_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */
|
||||
int hnmode;
|
||||
float strength;
|
||||
char defgrp_name[64];
|
||||
} BevelModifierData;
|
||||
|
||||
|
@ -371,6 +373,12 @@ enum {
|
|||
MOD_BEVEL_MARK_SHARP = (1 << 1),
|
||||
};
|
||||
|
||||
/* BevelModifierData->hnmode */
|
||||
enum {
|
||||
MOD_BEVEL_HN_FACE,
|
||||
MOD_BEVEL_HN_ADJ,
|
||||
};
|
||||
|
||||
typedef struct SmokeModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
|
|
|
@ -3028,6 +3028,12 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
|
|||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem prop_harden_normals_items[] = {
|
||||
{ MOD_BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" },
|
||||
{ MOD_BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" },
|
||||
{ 0, NULL, 0, NULL, NULL },
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "BevelModifier", "Modifier");
|
||||
RNA_def_struct_ui_text(srna, "Bevel Modifier", "Bevel modifier to make edges and vertices more rounded");
|
||||
RNA_def_struct_sdna(srna, "BevelModifierData");
|
||||
|
@ -3114,6 +3120,17 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
|
|||
RNA_def_property_boolean_sdna(prop, NULL, "edge_flags", MOD_BEVEL_MARK_SHARP);
|
||||
RNA_def_property_ui_text(prop, "Mark Sharp", "Mark beveled edges as sharp");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "hnmode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, prop_harden_normals_items);
|
||||
RNA_def_property_ui_text(prop, "Normal Mode", "Weighting mode for Harden Normals");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0, 10);
|
||||
RNA_def_property_ui_range(prop, 0, 10, 1, 2);
|
||||
RNA_def_property_ui_text(prop, "Normal Strength", "Strength of calculated normal");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
|
||||
|
|
|
@ -169,7 +169,7 @@ 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);
|
||||
dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL);
|
||||
|
||||
result = BKE_bmesh_to_mesh_nomain(bm, &(struct BMeshToMeshParams){0});
|
||||
|
||||
|
|
Loading…
Reference in New Issue