forked from bartvdbraak/blender
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
This commit is contained in:
parent
427844c28d
commit
a7b44c82e5
@ -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()
|
||||
|
@ -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! */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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[];
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user