Triangulate Modifier: using different ngon and quad methods
authorDalai Felinto <dfelinto@gmail.com>
Tue, 29 Oct 2013 02:42:51 +0000 (02:42 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Tue, 29 Oct 2013 02:42:51 +0000 (02:42 +0000)
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

17 files changed:
release/scripts/startup/bl_ui/properties_data_modifier.py
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/bmesh_polygon.h
source/blender/bmesh/operators/bmo_triangulate.c
source/blender/bmesh/tools/bmesh_beautify.c
source/blender/bmesh/tools/bmesh_beautify.h
source/blender/bmesh/tools/bmesh_triangulate.c
source/blender/bmesh/tools/bmesh_triangulate.h
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/intern/MOD_triangulate.c

index 9bfc14f1f282417d98b7e557f1dcec6a5c28a86e..288330084b958a1f296a94e01aa85c287d451d4c 100644 (file)
@@ -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()
index 51158fc5321e3aee166c0c11e4ad1ad1bdc2c7ac..10c71c79b55f3126b731e69a0ab6d1d67de0e144 100644 (file)
@@ -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! */
 
index 775cb24b8c95eea1b3744729928f867ffb4d06bb..ea533837b048b0dad2812dffbb10e6532fd23cde 100644 (file)
@@ -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 */
index 12ec3da9b696072d519812786cdb6d757099ecd6..e88fdb8a7e83cd1eeceabec90a115e70de0bc219 100644 (file)
@@ -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) {
index b71176212736007ae08c4e6631d7330edf187543..4759c73cb4dcd7db1389c7609efce4f5de654558 100644 (file)
@@ -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();
 
index ca45289520b49ba73be9055791b9ff32dfd1562d..a1de265bc56f8d528dba1d54d6da7daaa0a53534 100644 (file)
 
 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);
index af9345b903c9ee9498469728aa275fa2198646e5..1a1201c015e99c7f5f864962d4314f97ef425aba 100644 (file)
@@ -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 */
 
index 210e265d706c95f6602f81af80525ffe76e88160..7cc17008b50e35ea78469092e1e74b72b8f9f980 100644 (file)
@@ -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__ */
index 34ff493a026ec782cda17a6b0852c5df9f81b96e..59c2aa4331dc5e6e47d68b1453515f825484e584 100644 (file)
 /**
  * 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);
                                }
                        }
                }
index 141aa2f82b45b755e11e7397ce8c73f582ce3ebd..550109ffef9eaf4a197a2e1eaf0a5812dc3cbe6f 100644 (file)
@@ -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__ */
index e557b07dba2cb868e2d3a94749883e39dff97a47..b35ed10b157bf9f1ae5fda1c954b2a2845bbe9dc 100644 (file)
@@ -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)
index 86f69ab8538a299cb6ea7dc08df12bd2719fe7a4..3c42beb8b12cb01b058f29b3800a6a0e05c48079 100644 (file)
@@ -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);
 
index a7a7b6ab84a51cb42c4ce4c48c11083b5e09730a..7c2c77d90419e468db00f42f5884ad607071094a 100644 (file)
@@ -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);
        }
 }
 
index 799968335b77714b67f72448e36271291bfe58c8..43de7166c4f280d47f32c12b86486e597bc252a9 100644 (file)
@@ -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 {
index d33d3df8a5edb9ddc906548d2eeae8281f719638..5a7df0e0080d5d20318d6c9ad31ea926a52ec915 100644 (file)
@@ -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[];
index 57eeba61a737c0300f5c92181eed1826ad3f2440..276d8e0a67838fbe337704fc9f023266165fcd4b 100644 (file)
@@ -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");
 }
 
index ffc813068b8114c74059e96da9ce96b693127e21..d519c981a237016e6cf8d4ecbe3daa49071b78bd 100644 (file)
@@ -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;
        }