Add symmetrize operator for dynamic-topology sculpt mode

This commit is contained in:
Nicholas Bishop 2012-12-30 18:31:01 +00:00
parent 37ed697d5c
commit ab960eea88
6 changed files with 81 additions and 15 deletions

@ -361,6 +361,12 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
BMFace *f_new;
int i;
/* TODO: calling symmetrize in dynamic-topology sculpt mode
* frequently tries to create faces of length less than two,
* should investigate further */
if (len < 3)
return NULL;
for (i = 0; i < len; i++) {
int j = (i + 1) % len;
fe[i] = BM_edge_exists(fv[i], fv[j]);
@ -374,6 +380,7 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
BM_elem_attrs_copy(bm, bm, example, f_new);
BM_face_select_set(bm, f_new, TRUE);
BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM);
return f_new;
}

@ -5734,18 +5734,6 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
void MESH_OT_symmetrize(struct wmOperatorType *ot)
{
static EnumPropertyItem axis_direction_items[] = {
{BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
{BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
{BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
{BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
{BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
{BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
ot->name = "Symmetrize";
ot->description = "Enforce symmetry (both form and topological) across an axis";
@ -5758,7 +5746,7 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items,
ot->prop = RNA_def_enum(ot->srna, "direction", symmetrize_direction_items,
BMO_SYMMETRIZE_NEGATIVE_X,
"Direction", "Which sides to copy from and to");
}

@ -4712,6 +4712,50 @@ static void SCULPT_OT_optimize(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/********************* Dynamic topology symmetrize ********************/
static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_active_object(C);
const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
SculptSession *ss = ob->sculpt;
/* To simplify undo for symmetrize, all BMesh elements are logged
* as deleted, then after symmetrize operation all BMesh elements
* are logged as added (as opposed to attempting to store just the
* parts that symmetrize modifies) */
sculpt_undo_push_begin("Dynamic topology symmetrize");
sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_SYMMETRIZE);
BM_log_before_all_removed(ss->bm, ss->bm_log);
/* Symmetrize and re-triangulate */
BMO_op_callf(ss->bm, BMO_FLAG_DEFAULTS,
"symmetrize input=%avef direction=%i",
sd->symmetrize_direction);
sculpt_dynamic_topology_triangulate(ss->bm);
/* Finish undo */
BM_log_all_added(ss->bm, ss->bm_log);
sculpt_undo_push_end();
/* Redraw */
sculpt_pbvh_clear(ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
static void SCULPT_OT_symmetrize(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Symmetrize";
ot->idname = "SCULPT_OT_symmetrize";
/* api callbacks */
ot->exec = sculpt_symmetrize_exec;
ot->poll = sculpt_and_dynamic_topology_poll;
}
/**** Toggle operator for turning sculpt mode on or off ****/
static void sculpt_init_session(Scene *scene, Object *ob)
@ -4887,4 +4931,5 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_set_persistent_base);
WM_operatortype_append(SCULPT_OT_dynamic_topology_toggle);
WM_operatortype_append(SCULPT_OT_optimize);
WM_operatortype_append(SCULPT_OT_symmetrize);
}

@ -832,6 +832,11 @@ typedef struct Sculpt {
/* Maximum edge length for dynamic topology sculpting (in pixels) */
int detail_size;
/* Direction used for SCULPT_OT_symmetrize operator */
int symmetrize_direction;
int pad;
} Sculpt;
typedef struct UvSculpt {

@ -90,6 +90,8 @@ extern EnumPropertyItem brush_sculpt_tool_items[];
extern EnumPropertyItem brush_vertex_tool_items[];
extern EnumPropertyItem brush_image_tool_items[];
extern EnumPropertyItem symmetrize_direction_items[];
extern EnumPropertyItem texture_type_items[];
extern EnumPropertyItem lamp_type_items[];

@ -40,6 +40,9 @@
#include "WM_api.h"
#include "WM_types.h"
#include "BLI_utildefines.h"
#include "bmesh.h"
static EnumPropertyItem particle_edit_hair_brush_items[] = {
{PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush"},
{PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"},
@ -52,6 +55,18 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
{0, NULL, 0, NULL, NULL}
};
EnumPropertyItem symmetrize_direction_items[] = {
{BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
{BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
{BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
{BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
{BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
{BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
{0, NULL, 0, NULL, NULL},
};
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@ -341,6 +356,10 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Collapse Short Edges",
"In dynamic-topology mode, collapse short edges "
"in addition to subdividing long ones");
prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, symmetrize_direction_items);
RNA_def_property_ui_text(prop, "Direction", "Source and destination for symmetrize operator");
}