From a7b44c82e5b90e83a588fabb22fda5ac41891bdf Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 29 Oct 2013 02:42:51 +0000 Subject: Triangulate Modifier: using different ngon and quad methods Quads: Beauty, Fixed, Fixed Alternate, Shortest Diagonal Ngons: Beauty, Scanfill * Shortest Diagonal is the default method in the modifier (popular elsewhere), but beauty is the default in Ctrl+T). * Remove the need for output slot and beauty operator to be called after Clt+T Patch with collaborations and reviewed by Campbell Barton --- .../startup/bl_ui/properties_data_modifier.py | 9 ++- source/blender/blenloader/intern/readfile.c | 20 +++++++ source/blender/bmesh/intern/bmesh_opdefines.c | 3 +- source/blender/bmesh/intern/bmesh_polygon.c | 66 +++++++++++++++++++++- source/blender/bmesh/intern/bmesh_polygon.h | 3 +- source/blender/bmesh/operators/bmo_triangulate.c | 6 +- source/blender/bmesh/tools/bmesh_beautify.c | 27 +++++---- source/blender/bmesh/tools/bmesh_beautify.h | 4 ++ source/blender/bmesh/tools/bmesh_triangulate.c | 12 ++-- source/blender/bmesh/tools/bmesh_triangulate.h | 2 +- source/blender/editors/mesh/editmesh_tools.c | 18 ++---- source/blender/editors/mesh/mesh_ops.c | 7 ++- source/blender/editors/sculpt_paint/sculpt.c | 2 +- source/blender/makesdna/DNA_modifier_types.h | 18 +++++- source/blender/makesrna/RNA_enum_types.h | 3 + source/blender/makesrna/intern/rna_modifier.c | 27 ++++++++- source/blender/modifiers/intern/MOD_triangulate.c | 9 +-- 17 files changed, 188 insertions(+), 48 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 9bfc14f1f28..288330084b9 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1099,7 +1099,14 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "use_z_symmetry") def TRIANGULATE(self, layout, ob, md): - layout.prop(md, "use_beauty") + row = layout.row() + + col = row.column() + col.label(text="Quad Method:") + col.prop(md, "quad_method", text="") + col = row.column() + col.label(text="Ngon Method:") + col.prop(md, "ngon_method", text="") def UV_WARP(self, layout, ob, md): split = layout.split() diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 51158fc5321..10c71c79b55 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9758,6 +9758,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (!DNA_struct_elem_find(fd->filesdna, "TriangulateModifierData", "int", "quad_method")) { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Triangulate) { + TriangulateModifierData *tmd = (TriangulateModifierData *)md; + if ((tmd->flag & MOD_TRIANGULATE_BEAUTY)) { + tmd->quad_method = MOD_TRIANGULATE_QUAD_BEAUTY; + tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY; + } + else { + tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; + tmd->ngon_method = MOD_TRIANGULATE_NGON_SCANFILL; + } + } + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */ diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 775cb24b8c9..ea533837b04 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1028,7 +1028,8 @@ static BMOpDefine bmo_triangulate_def = { "triangulate", /* slots_in */ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, - {"use_beauty", BMO_OP_SLOT_BOOL}, + {"quad_method", BMO_OP_SLOT_INT}, + {"ngon_method", BMO_OP_SLOT_INT}, {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 12ec3da9b69..e88fdb8a7e8 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -29,6 +29,7 @@ */ #include "DNA_listBase.h" +#include "DNA_modifier_types.h" #include "BLI_alloca.h" #include "BLI_math.h" @@ -817,7 +818,9 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3]) void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **r_faces_new, MemArena *sf_arena, - const bool use_beauty, const bool use_tag) + const int quad_method, + const int ngon_method, + const bool use_tag) { BMLoop *l_iter, *l_first, *l_new; BMFace *f_new; @@ -825,6 +828,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, int nf_i = 0; BMEdge **edge_array; int edge_array_len; + bool use_beauty = (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY); #define SF_EDGE_IS_BOUNDARY 0xff @@ -832,9 +836,67 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, if (f->len == 4) { + BMVert *v1, *v2; l_first = BM_FACE_FIRST_LOOP(f); - f_new = BM_face_split(bm, f, l_first->v, l_first->next->next->v, &l_new, NULL, false); + switch (quad_method) { + case MOD_TRIANGULATE_QUAD_FIXED: + { + v1 = l_first->v; + v2 = l_first->next->next->v; + break; + } + case MOD_TRIANGULATE_QUAD_ALTERNATE: + { + v1 = l_first->next->v; + v2 = l_first->prev->v; + break; + } + case MOD_TRIANGULATE_QUAD_SHORTEDGE: + { + BMVert *v3, *v4; + float d1, d2; + + v1 = l_first->v; + v2 = l_first->next->next->v; + v3 = l_first->next->v; + v4 = l_first->prev->v; + + d1 = len_squared_v3v3(v1->co, v2->co); + d2 = len_squared_v3v3(v3->co, v4->co); + + if (d2 < d1) { + v1 = v3; + v2 = v4; + } + break; + } + case MOD_TRIANGULATE_QUAD_BEAUTY: + default: + { + BMVert *v3, *v4; + float cost; + + v1 = l_first->next->v; + v2 = l_first->next->next->v; + v3 = l_first->prev->v; + v4 = l_first->v; + + cost = BM_verts_calc_rotate_beauty(v1, v2, v3, v4, 0, 0); + + if (cost < 0.0f) { + v1 = v4; + //v2 = v2; + } + else { + //v1 = v1; + v2 = v3; + } + break; + } + } + + f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, false); copy_v3_v3(f_new->no, f->no); if (use_tag) { diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index b7117621273..4759c73cb4d 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -54,7 +54,8 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3]) ATTR_WARN_UNUSED_R void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **newfaces, struct MemArena *sf_arena, - const bool use_beauty, const bool use_tag) ATTR_NONNULL(1, 2); + const int quad_method, const int ngon_method, + const bool use_tag) ATTR_NONNULL(1, 2); void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index ca45289520b..a1de265bc56 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -42,13 +42,15 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op) { - const bool use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty"); + const int quad_method = BMO_slot_int_get(op->slots_in, "quad_method"); + const int ngon_method = BMO_slot_int_get(op->slots_in, "ngon_method"); + BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out"); BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false); BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false); - BM_mesh_triangulate(bm, use_beauty, true, op, slot_facemap_out); + BM_mesh_triangulate(bm, quad_method, ngon_method, true, op, slot_facemap_out); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c index af9345b903c..1a1201c015e 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.c +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -252,19 +252,13 @@ static float bm_edge_calc_rotate_beauty__angle( return FLT_MAX; } -static float bm_edge_calc_rotate_beauty(const BMEdge *e, const short flag, const short method) +float BM_verts_calc_rotate_beauty( +const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4, const short flag, const short method) { /* not a loop (only to be able to break out) */ do { - const float *v1, *v2, *v3, *v4; - - v1 = e->l->prev->v->co; /* first face co */ - v2 = e->l->v->co; /* e->v1 or e->v2*/ - v3 = e->l->radial_next->prev->v->co; /* second face co */ - v4 = e->l->next->v->co; /* e->v1 or e->v2*/ - if (flag & VERT_RESTRICT_TAG) { - BMVert *v_a = e->l->prev->v, *v_b = e->l->radial_next->prev->v; + const BMVert *v_a = v1, *v_b = v3; if (BM_elem_flag_test(v_a, BM_ELEM_TAG) == BM_elem_flag_test(v_b, BM_ELEM_TAG)) { break; } @@ -277,15 +271,26 @@ static float bm_edge_calc_rotate_beauty(const BMEdge *e, const short flag, const switch (method) { case 0: - return bm_edge_calc_rotate_beauty__area(v1, v2, v3, v4); + return bm_edge_calc_rotate_beauty__area(v1->co, v2->co, v3->co, v4->co); default: - return bm_edge_calc_rotate_beauty__angle(v1, v2, v3, v4); + return bm_edge_calc_rotate_beauty__angle(v1->co, v2->co, v3->co, v4->co); } } while (false); return FLT_MAX; } +static float bm_edge_calc_rotate_beauty(const BMEdge *e, const short flag, const short method) +{ + const BMVert *v1, *v2, *v3, *v4; + v1 = e->l->prev->v; /* first vert co */ + v2 = e->l->v; /* e->v1 or e->v2*/ + v3 = e->l->radial_next->prev->v; /* second vert co */ + v4 = e->l->next->v; /* e->v1 or e->v2*/ + + return BM_verts_calc_rotate_beauty(v1, v2, v3, v4, flag, method); +} + /* -------------------------------------------------------------------- */ /* Update the edge cost of rotation in the heap */ diff --git a/source/blender/bmesh/tools/bmesh_beautify.h b/source/blender/bmesh/tools/bmesh_beautify.h index 210e265d706..7cc17008b50 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.h +++ b/source/blender/bmesh/tools/bmesh_beautify.h @@ -35,4 +35,8 @@ void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_ const short flag, const short method, const short oflag_edge, const short oflag_face); +float BM_verts_calc_rotate_beauty(const BMVert *v1, const BMVert *v2, + const BMVert *v3, const BMVert *v4, + const short flag, const short method); + #endif /* __BMESH_BEAUTIFY_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index 34ff493a026..59c2aa4331d 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -42,14 +42,16 @@ /** * a version of #BM_face_triangulate that maps to #BMOpSlot */ -static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena, const bool use_beauty, const bool use_tag, +static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena, + const int quad_method, const int ngon_method, + const bool use_tag, BMOperator *op, BMOpSlot *slot_facemap_out) { const int faces_array_tot = face->len - 3; BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot); BLI_assert(face->len > 3); - BM_face_triangulate(bm, face, faces_array, sf_arena, use_beauty, use_tag); + BM_face_triangulate(bm, face, faces_array, sf_arena, quad_method, ngon_method, use_tag); if (faces_array) { int i; @@ -61,7 +63,7 @@ static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_ar } -void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, +void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out) { BMIter iter; @@ -75,7 +77,7 @@ void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { if (face->len > 3) { if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { - bm_face_triangulate_mapping(bm, face, sf_arena, use_beauty, tag_only, + bm_face_triangulate_mapping(bm, face, sf_arena, quad_method, ngon_method, tag_only, op, slot_facemap_out); } } @@ -85,7 +87,7 @@ void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { if (face->len > 3) { if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { - BM_face_triangulate(bm, face, NULL, sf_arena, use_beauty, tag_only); + BM_face_triangulate(bm, face, NULL, sf_arena, quad_method, ngon_method, tag_only); } } } diff --git a/source/blender/bmesh/tools/bmesh_triangulate.h b/source/blender/bmesh/tools/bmesh_triangulate.h index 141aa2f82b4..550109ffef9 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.h +++ b/source/blender/bmesh/tools/bmesh_triangulate.h @@ -30,7 +30,7 @@ #ifndef __BMESH_TRIANGULATE_H__ #define __BMESH_TRIANGULATE_H__ -void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, +void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out); #endif /* __BMESH_TRIANGULATE_H__ */ diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index e557b07dba2..b35ed10b157 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3204,21 +3204,12 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMOperator bmop; - const bool use_beauty = RNA_boolean_get(op->ptr, "use_beauty"); + const int quad_method = RNA_enum_get(op->ptr, "quad_method"); + const int ngon_method = RNA_enum_get(op->ptr, "ngon_method"); - EDBM_op_init(em, &bmop, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty); + EDBM_op_init(em, &bmop, op, "triangulate faces=%hf quad_method=%i ngon_method=%i", BM_ELEM_SELECT, quad_method, ngon_method); BMO_op_exec(em->bm, &bmop); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); - - /* now call beauty fill */ - if (use_beauty) { - EDBM_op_call_and_selectf( - em, op, "geom.out", true, - "beautify_fill faces=%S edges=%S", - &bmop, "faces.out", &bmop, "edges.out"); - } - if (!EDBM_op_finish(em, &bmop, op, true)) { return OPERATOR_CANCELLED; } @@ -3243,7 +3234,8 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "use_beauty", 1, "Beauty", "Use best triangulation division"); + RNA_def_enum(ot->srna, "quad_method", modifier_triangulate_quad_method_items, MOD_TRIANGULATE_QUAD_BEAUTY, "Quad Method", "Method for splitting the quads into triangles"); + RNA_def_enum(ot->srna, "ngon_method", modifier_triangulate_ngon_method_items, MOD_TRIANGULATE_NGON_BEAUTY, "Ngon Method", "Method for splitting the ngons into triangles"); } static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 86f69ab8538..3c42beb8b12 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -29,6 +29,7 @@ */ #include "DNA_scene_types.h" +#include "DNA_modifier_types.h" #include "BLI_math.h" @@ -359,9 +360,11 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_beautify_fill", FKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0); kmi = WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "use_beauty", true); + RNA_enum_set(kmi->ptr, "quad_method", MOD_TRIANGULATE_QUAD_BEAUTY); + RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_BEAUTY); kmi = WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "use_beauty", false); + RNA_enum_set(kmi->ptr, "quad_method", MOD_TRIANGULATE_QUAD_FIXED); + RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_SCANFILL); WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a7a7b6ab84a..7c2c77d9041 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4660,7 +4660,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot) static void sculpt_dynamic_topology_triangulate(BMesh *bm) { if (bm->totloop != bm->totface * 3) { - BM_mesh_triangulate(bm, false, false, NULL, NULL); + BM_mesh_triangulate(bm, false, MOD_TRIANGULATE_QUAD_FIXED, MOD_TRIANGULATE_NGON_SCANFILL, NULL, NULL); } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 799968335b7..43de7166c4f 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1177,11 +1177,27 @@ typedef struct TriangulateModifierData { ModifierData modifier; int flag; + int quad_method; + int ngon_method; int pad; } TriangulateModifierData; enum { - MOD_TRIANGULATE_BEAUTY = (1 << 0), + MOD_TRIANGULATE_BEAUTY = (1 << 0), /* deprecated */ +}; + +/* Triangulate methods - NGons */ +enum { + MOD_TRIANGULATE_NGON_BEAUTY = 0, + MOD_TRIANGULATE_NGON_SCANFILL, +}; + +/* Triangulate methods - Quads */ +enum { + MOD_TRIANGULATE_QUAD_BEAUTY = 0, + MOD_TRIANGULATE_QUAD_FIXED, + MOD_TRIANGULATE_QUAD_ALTERNATE, + MOD_TRIANGULATE_QUAD_SHORTEDGE }; typedef struct LaplacianSmoothModifierData { diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index d33d3df8a5e..5a7df0e0080 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -60,6 +60,9 @@ extern EnumPropertyItem constraint_type_items[]; extern EnumPropertyItem boidrule_type_items[]; extern EnumPropertyItem sequence_modifier_type_items[]; +extern EnumPropertyItem modifier_triangulate_quad_method_items[]; +extern EnumPropertyItem modifier_triangulate_ngon_method_items[]; + extern EnumPropertyItem image_type_items[]; extern EnumPropertyItem image_color_mode_items[]; extern EnumPropertyItem image_depth_mode_items[]; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 57eeba61a73..276d8e0a678 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -109,6 +109,20 @@ EnumPropertyItem modifier_type_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem modifier_triangulate_quad_method_items[] = { + {MOD_TRIANGULATE_QUAD_BEAUTY, "BEAUTY", 0, "Beauty ", "Split the quads in nice triangles, slower method"}, + {MOD_TRIANGULATE_QUAD_FIXED, "FIXED", 0, "Fixed", "Split the quads on the first and third vertices"}, + {MOD_TRIANGULATE_QUAD_ALTERNATE, "FIXED_ALTERNATE", 0, "Fixed Alternate", "Split the quads on the 2nd and 4th vertices"}, + {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORTEST_DIAGONAL", 0, "Shortest Diagonal", "Split the quads based on the distance between the vertices"}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem modifier_triangulate_ngon_method_items[] = { + {MOD_TRIANGULATE_NGON_SCANFILL, "SCANFILL", 0, "Scanfill", "Split the ngons using a scanfill algorithm "}, + {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY", 0, "Beauty", "Arrange the new triangles nicely, slower method"}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "DNA_particle_types.h" @@ -3500,9 +3514,16 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna) RNA_def_struct_sdna(srna, "TriangulateModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_TRIANGULATE); - prop = RNA_def_property(srna, "use_beauty", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_TRIANGULATE_BEAUTY); - RNA_def_property_ui_text(prop, "Beauty Subdivide", "Subdivide across shortest diagonal"); + prop = RNA_def_property(srna, "quad_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "quad_method"); + RNA_def_property_enum_items(prop, modifier_triangulate_quad_method_items); + RNA_def_property_ui_text(prop, "Quad Method", "Method for splitting the quads into triangles"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "ngon_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "ngon_method"); + RNA_def_property_enum_items(prop, modifier_triangulate_ngon_method_items); + RNA_def_property_ui_text(prop, "Ngon Method", "Method for splitting the ngons into triangles"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); } diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index ffc813068b8..d519c981a23 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -36,7 +36,7 @@ #include "bmesh.h" #include "bmesh_tools.h" -static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag) +static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int quad_method, const int ngon_method) { DerivedMesh *result; BMesh *bm; @@ -45,7 +45,7 @@ static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag) bm = DM_to_bmesh(dm, true); - BM_mesh_triangulate(bm, (flag & MOD_TRIANGULATE_BEAUTY), false, NULL, NULL); + BM_mesh_triangulate(bm, quad_method, ngon_method, false, NULL, NULL); result = CDDM_from_bmesh(bm, FALSE); BM_mesh_free(bm); @@ -69,7 +69,8 @@ static void initData(ModifierData *md) /* Enable in editmode by default */ md->mode |= eModifierMode_Editmode; - tmd->flag = MOD_TRIANGULATE_BEAUTY; + tmd->quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; + tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY; } @@ -88,7 +89,7 @@ static DerivedMesh *applyModifier(ModifierData *md, { TriangulateModifierData *tmd = (TriangulateModifierData *)md; DerivedMesh *result; - if (!(result = triangulate_dm(dm, tmd->flag))) { + if (!(result = triangulate_dm(dm, tmd->quad_method, tmd->ngon_method))) { return dm; } -- cgit v1.2.3