Merged changes in the trunk up to revision 49090.
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_numinput.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_transform.h"
|
||||
@@ -2789,120 +2790,158 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
|
||||
RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
|
||||
}
|
||||
|
||||
static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
|
||||
static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
|
||||
{
|
||||
Base *basenew;
|
||||
Base *base_new;
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
Object *obedit = editbase->object;
|
||||
Mesh *me = obedit->data;
|
||||
BMEditMesh *em = me->edit_btmesh;
|
||||
Object *obedit = base_old->object;
|
||||
BMesh *bm_new;
|
||||
|
||||
if (!em)
|
||||
return FALSE;
|
||||
|
||||
|
||||
bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
|
||||
CustomData_copy(&em->bm->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&em->bm->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&em->bm->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&em->bm->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
|
||||
CustomData_bmesh_init_pool(&bm_new->vdata, bm_mesh_allocsize_default.totvert, BM_VERT);
|
||||
CustomData_bmesh_init_pool(&bm_new->edata, bm_mesh_allocsize_default.totedge, BM_EDGE);
|
||||
CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
|
||||
CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
|
||||
|
||||
basenew = ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH); /* 0 = fully linked */
|
||||
assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
|
||||
|
||||
ED_base_object_select(basenew, BA_DESELECT);
|
||||
|
||||
EDBM_op_callf(em, wmop, "duplicate geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new);
|
||||
EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES);
|
||||
base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
|
||||
/* DAG_scene_sort(bmain, scene); */ /* normally would call directly after but in this case delay recalc */
|
||||
assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
|
||||
|
||||
ED_base_object_select(base_new, BA_SELECT);
|
||||
|
||||
BMO_op_callf(bm_old, "duplicate geom=%hvef dest=%p", BM_ELEM_TAG, bm_new);
|
||||
BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_FACES);
|
||||
|
||||
/* clean up any loose edges */
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN))
|
||||
continue;
|
||||
|
||||
BM_ITER_MESH (e, &iter, bm_old, BM_EDGES_OF_MESH) {
|
||||
if (!BM_edge_is_wire(e)) {
|
||||
BM_edge_select_set(em->bm, e, FALSE);
|
||||
BM_elem_flag_disable(e, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_EDGES);
|
||||
BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_EDGES);
|
||||
|
||||
/* clean up any loose verts */
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_HIDDEN))
|
||||
continue;
|
||||
|
||||
BM_ITER_MESH (v, &iter, bm_old, BM_VERTS_OF_MESH) {
|
||||
if (BM_vert_edge_count(v) != 0) {
|
||||
BM_vert_select_set(em->bm, v, FALSE);
|
||||
BM_elem_flag_disable(v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS);
|
||||
BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_VERTS);
|
||||
|
||||
BM_mesh_normals_update(bm_new, TRUE);
|
||||
BM_mesh_normals_update(bm_new, FALSE);
|
||||
|
||||
BM_mesh_bm_to_me(bm_new, base_new->object->data, FALSE);
|
||||
|
||||
BM_mesh_bm_to_me(bm_new, basenew->object->data, FALSE);
|
||||
|
||||
BM_mesh_free(bm_new);
|
||||
((Mesh *)basenew->object->data)->edit_btmesh = NULL;
|
||||
((Mesh *)base_new->object->data)->edit_btmesh = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int mesh_separate_material(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
|
||||
static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
|
||||
{
|
||||
/* tag -> select */
|
||||
BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, TRUE, BM_ELEM_SELECT);
|
||||
|
||||
return mesh_separate_tagged(bmain, scene, base_old, bm_old);
|
||||
}
|
||||
|
||||
/* flush a hflag to from verts to edges/faces */
|
||||
static void bm_mesh_hflag_flush_vert(BMesh *bm, const char hflag)
|
||||
{
|
||||
BMEdge *e;
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
BMFace *f;
|
||||
|
||||
BMIter eiter;
|
||||
BMIter fiter;
|
||||
|
||||
int ok;
|
||||
|
||||
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e->v1, hflag) &&
|
||||
BM_elem_flag_test(e->v2, hflag))
|
||||
{
|
||||
BM_elem_flag_enable(e, hflag);
|
||||
}
|
||||
else {
|
||||
BM_elem_flag_disable(e, hflag);
|
||||
}
|
||||
}
|
||||
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
|
||||
ok = TRUE;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
if (!BM_elem_flag_test(l_iter->v, hflag)) {
|
||||
ok = FALSE;
|
||||
break;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
BM_elem_flag_set(f, hflag, ok);
|
||||
}
|
||||
}
|
||||
|
||||
static int mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
|
||||
{
|
||||
BMFace *f_cmp, *f;
|
||||
BMIter iter;
|
||||
int result = FALSE;
|
||||
Object *obedit = editbase->object;
|
||||
BMEditMesh *em = BMEdit_FromObject(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
|
||||
|
||||
while ((f_cmp = BM_iter_at_index(bm, BM_FACES_OF_MESH, NULL, 0))) {
|
||||
while ((f_cmp = BM_iter_at_index(bm_old, BM_FACES_OF_MESH, NULL, 0))) {
|
||||
const short mat_nr = f_cmp->mat_nr;
|
||||
int tot = 0;
|
||||
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH (f, &iter, bm_old, BM_FACES_OF_MESH) {
|
||||
if (f->mat_nr == mat_nr) {
|
||||
BM_face_select_set(bm, f, TRUE);
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
|
||||
BM_elem_flag_enable(l_iter->e, BM_ELEM_TAG);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
|
||||
/* leave the current object with some materials */
|
||||
if (tot == bm->totface) {
|
||||
if (tot == bm_old->totface) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move selection into a separate object */
|
||||
result |= mesh_separate_selected(bmain, scene, editbase, wmop);
|
||||
result |= mesh_separate_tagged(bmain, scene, base_old, bm_old);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
|
||||
static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
|
||||
{
|
||||
int i;
|
||||
BMEdge *e;
|
||||
BMVert *v_seed;
|
||||
BMWalker walker;
|
||||
int result = FALSE;
|
||||
Object *obedit = editbase->object;
|
||||
BMEditMesh *em = BMEdit_FromObject(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
int max_iter = bm->totvert;
|
||||
int max_iter = bm_old->totvert;
|
||||
|
||||
/* Clear all selected vertices */
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
|
||||
|
||||
/* A "while (true)" loop should work here as each iteration should
|
||||
* select and remove at least one vertex and when all vertices
|
||||
@@ -2910,8 +2949,9 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOper
|
||||
* behavior by limiting iterations to the number of vertices in the
|
||||
* original mesh.*/
|
||||
for (i = 0; i < max_iter; i++) {
|
||||
int tot = 0;
|
||||
/* Get a seed vertex to start the walk */
|
||||
v_seed = BM_iter_at_index(bm, BM_VERTS_OF_MESH, NULL, 0);
|
||||
v_seed = BM_iter_at_index(bm_old, BM_VERTS_OF_MESH, NULL, 0);
|
||||
|
||||
/* No vertices available, can't do anything */
|
||||
if (v_seed == NULL) {
|
||||
@@ -2919,33 +2959,33 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOper
|
||||
}
|
||||
|
||||
/* Select the seed explicitly, in case it has no edges */
|
||||
BM_vert_select_set(bm, v_seed, TRUE);
|
||||
BM_elem_flag_enable(v_seed, BM_ELEM_TAG);
|
||||
|
||||
/* Walk from the single vertex, selecting everything connected
|
||||
* to it */
|
||||
BMW_init(&walker, bm, BMW_SHELL,
|
||||
BMW_init(&walker, bm_old, BMW_SHELL,
|
||||
BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_NOP, /* BMESH_TODO - should be BMW_FLAG_TEST_HIDDEN ? */
|
||||
BMW_NIL_LAY);
|
||||
|
||||
e = BMW_begin(&walker, v_seed);
|
||||
for (; e; e = BMW_step(&walker)) {
|
||||
BM_vert_select_set(bm, e->v1, TRUE);
|
||||
BM_vert_select_set(bm, e->v2, TRUE);
|
||||
if (!BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { BM_elem_flag_enable(e->v1, BM_ELEM_TAG); tot++; }
|
||||
if (!BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { BM_elem_flag_enable(e->v2, BM_ELEM_TAG); tot++; }
|
||||
}
|
||||
BMW_end(&walker);
|
||||
|
||||
/* Flush the selection to get edge/face selections matching
|
||||
* the vertex selection */
|
||||
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
|
||||
|
||||
if (bm->totvert == bm->totvertsel) {
|
||||
if (bm_old->totvert == tot) {
|
||||
/* Every vertex selected, nothing to separate, work is done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Flush the selection to get edge/face selections matching
|
||||
* the vertex selection */
|
||||
bm_mesh_hflag_flush_vert(bm_old, BM_ELEM_TAG);
|
||||
|
||||
/* Move selection into a separate object */
|
||||
result |= mesh_separate_selected(bmain, scene, editbase, wmop);
|
||||
result |= mesh_separate_tagged(bmain, scene, base_old, bm_old);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2955,19 +2995,65 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Base *base = CTX_data_active_base(C);
|
||||
int retval = 0, type = RNA_enum_get(op->ptr, "type");
|
||||
|
||||
if (type == 0)
|
||||
retval = mesh_separate_selected(bmain, scene, base, op);
|
||||
else if (type == 1)
|
||||
retval = mesh_separate_material(bmain, scene, base, op);
|
||||
else if (type == 2)
|
||||
retval = mesh_separate_loose(bmain, scene, base, op);
|
||||
if (ED_operator_editmesh(C)) {
|
||||
Base *base = CTX_data_active_base(C);
|
||||
BMEditMesh *em = BMEdit_FromObject(base->object);
|
||||
|
||||
/* editmode separate */
|
||||
if (type == 0) retval = mesh_separate_selected(bmain, scene, base, em->bm);
|
||||
else if (type == 1) retval = mesh_separate_material(bmain, scene, base, em->bm);
|
||||
else if (type == 2) retval = mesh_separate_loose(bmain, scene, base, em->bm);
|
||||
else BLI_assert(0);
|
||||
|
||||
if (retval) {
|
||||
EDBM_update_generic(C, em, TRUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (type == 0) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* object mode separate */
|
||||
CTX_DATA_BEGIN(C, Base *, base_iter, selected_editable_bases)
|
||||
{
|
||||
Object *ob = base_iter->object;
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me = ob->data;
|
||||
if (me->id.lib == NULL) {
|
||||
BMesh *bm_old = NULL;
|
||||
int retval_iter = 0;
|
||||
|
||||
bm_old = BM_mesh_create(&bm_mesh_allocsize_default);
|
||||
|
||||
BM_mesh_bm_from_me(bm_old, me, FALSE, 0);
|
||||
|
||||
if (type == 1) retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
|
||||
else if (type == 2) retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
|
||||
else BLI_assert(0);
|
||||
|
||||
if (retval_iter) {
|
||||
BM_mesh_bm_to_me(bm_old, me, FALSE);
|
||||
|
||||
DAG_id_tag_update(&me->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
|
||||
}
|
||||
|
||||
BM_mesh_free(bm_old);
|
||||
|
||||
retval |= retval_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
BMEditMesh *em = BMEdit_FromObject(base->object);
|
||||
EDBM_update_generic(C, em, TRUE);
|
||||
/* delay depsgraph recalc until all objects are duplicated */
|
||||
DAG_scene_sort(bmain, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -2994,7 +3080,7 @@ void MESH_OT_separate(wmOperatorType *ot)
|
||||
/* api callbacks */
|
||||
ot->invoke = WM_menu_invoke;
|
||||
ot->exec = edbm_separate_exec;
|
||||
ot->poll = ED_operator_editmesh;
|
||||
ot->poll = ED_operator_scene_editable; /* object and editmode */
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
@@ -4305,23 +4391,31 @@ typedef struct {
|
||||
int mcenter[2];
|
||||
float initial_length;
|
||||
int is_modal;
|
||||
NumInput num_input;
|
||||
float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */
|
||||
} BevelData;
|
||||
|
||||
#define HEADER_LENGTH 180
|
||||
|
||||
static void edbm_bevel_update_header(wmOperator *op, bContext *C)
|
||||
{
|
||||
static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RMB), factor: %f, Use Dist (D): %s: Use Even (E): %s";
|
||||
static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RMB), factor: %s, Use Dist (D): %s: Use Even (E): %s";
|
||||
|
||||
char msg[HEADER_LENGTH];
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
BevelData *opdata = op->customdata;
|
||||
|
||||
if (sa) {
|
||||
char factor_str[NUM_STR_REP_LEN];
|
||||
if (hasNumInput(&opdata->num_input))
|
||||
outputNumInput(&opdata->num_input, factor_str);
|
||||
else
|
||||
BLI_snprintf(factor_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "percent"));
|
||||
BLI_snprintf(msg, HEADER_LENGTH, str,
|
||||
RNA_float_get(op->ptr, "percent"),
|
||||
factor_str,
|
||||
RNA_boolean_get(op->ptr, "use_dist") ? "On" : "Off",
|
||||
RNA_boolean_get(op->ptr, "use_even") ? "On" : "Off"
|
||||
);
|
||||
);
|
||||
|
||||
ED_area_headerprint(sa, msg);
|
||||
}
|
||||
@@ -4384,7 +4478,11 @@ static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal)
|
||||
opdata->li = li;
|
||||
opdata->weights = NULL;
|
||||
opdata->is_modal = is_modal;
|
||||
|
||||
opdata->shift_factor = -1.0f;
|
||||
|
||||
initNumInput(&opdata->num_input);
|
||||
opdata->num_input.flag = NUM_NO_NEGATIVE;
|
||||
|
||||
/* avoid the cost of allocating a bm copy */
|
||||
if (is_modal)
|
||||
opdata->mesh_backup = EDBM_redo_state_store(em);
|
||||
@@ -4523,8 +4621,21 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
BevelData *opdata = op->customdata;
|
||||
// Scene *scene = CTX_data_scene(C);
|
||||
|
||||
if (event->val == KM_PRESS) {
|
||||
/* Try to handle numeric inputs... */
|
||||
float factor;
|
||||
|
||||
if (handleNumInput(&opdata->num_input, event)) {
|
||||
applyNumInput(&opdata->num_input, &factor);
|
||||
CLAMP(factor, 0.0f, 1.0f);
|
||||
RNA_float_set(op->ptr, "percent", factor);
|
||||
|
||||
edbm_bevel_calc(C, op);
|
||||
edbm_bevel_update_header(op, C);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
}
|
||||
switch (event->type) {
|
||||
case ESCKEY:
|
||||
case RIGHTMOUSE:
|
||||
@@ -4532,22 +4643,32 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
case MOUSEMOVE:
|
||||
{
|
||||
float factor;
|
||||
float mdiff[2];
|
||||
if (!hasNumInput(&opdata->num_input)) {
|
||||
float factor;
|
||||
float mdiff[2];
|
||||
|
||||
mdiff[0] = opdata->mcenter[0] - event->mval[0];
|
||||
mdiff[1] = opdata->mcenter[1] - event->mval[1];
|
||||
mdiff[0] = opdata->mcenter[0] - event->mval[0];
|
||||
mdiff[1] = opdata->mcenter[1] - event->mval[1];
|
||||
|
||||
factor = len_v2(mdiff) / opdata->initial_length;
|
||||
factor = MAX2(1.0f - factor, 0.0f);
|
||||
factor = -len_v2(mdiff) / opdata->initial_length + 1.0f;
|
||||
|
||||
RNA_float_set(op->ptr, "percent", factor);
|
||||
/* Fake shift-transform... */
|
||||
if (event->shift) {
|
||||
if (opdata->shift_factor < 0.0f)
|
||||
opdata->shift_factor = RNA_float_get(op->ptr, "percent");
|
||||
factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
|
||||
}
|
||||
else if (opdata->shift_factor >= 0.0f)
|
||||
opdata->shift_factor = -1.0f;
|
||||
|
||||
edbm_bevel_calc(C, op);
|
||||
edbm_bevel_update_header(op, C);
|
||||
CLAMP(factor, 0.0f, 1.0f);
|
||||
|
||||
RNA_float_set(op->ptr, "percent", factor);
|
||||
|
||||
edbm_bevel_calc(C, op);
|
||||
edbm_bevel_update_header(op, C);
|
||||
}
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
case LEFTMOUSE:
|
||||
case PADENTER:
|
||||
@@ -4598,8 +4719,8 @@ void MESH_OT_bevel(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f);
|
||||
// XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users.
|
||||
// RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8);
|
||||
/* XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. */
|
||||
/* RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); */
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_even", FALSE, "Even", "Calculate evenly spaced bevel");
|
||||
RNA_def_boolean(ot->srna, "use_dist", FALSE, "Distance", "Interpret the percent in blender units");
|
||||
@@ -4643,26 +4764,36 @@ typedef struct {
|
||||
int modify_depth;
|
||||
int is_modal;
|
||||
float initial_length;
|
||||
int shift;
|
||||
float shift_amount;
|
||||
BMBackup backup;
|
||||
BMEditMesh *em;
|
||||
NumInput num_input;
|
||||
} InsetData;
|
||||
|
||||
static void edbm_inset_update_header(wmOperator *op, bContext *C)
|
||||
{
|
||||
InsetData *opdata = op->customdata;
|
||||
|
||||
static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %f, depth (Ctrl to tweak): %f (%s), Outset (O): (%s)";
|
||||
static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %s, depth (Ctrl to tweak): %s (%s), Outset (O): (%s)";
|
||||
|
||||
char msg[HEADER_LENGTH];
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
|
||||
if (sa) {
|
||||
char flts_str[NUM_STR_REP_LEN * 2];
|
||||
if (hasNumInput(&opdata->num_input))
|
||||
outputNumInput(&opdata->num_input, flts_str);
|
||||
else {
|
||||
BLI_snprintf(flts_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "thickness"));
|
||||
BLI_snprintf(flts_str + NUM_STR_REP_LEN, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "depth"));
|
||||
}
|
||||
BLI_snprintf(msg, HEADER_LENGTH, str,
|
||||
RNA_float_get(op->ptr, "thickness"),
|
||||
RNA_float_get(op->ptr, "depth"),
|
||||
flts_str,
|
||||
flts_str + NUM_STR_REP_LEN,
|
||||
opdata->modify_depth ? "On" : "Off",
|
||||
RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off"
|
||||
);
|
||||
);
|
||||
|
||||
ED_area_headerprint(sa, msg);
|
||||
}
|
||||
@@ -4680,9 +4811,14 @@ static int edbm_inset_init(bContext *C, wmOperator *op, int is_modal)
|
||||
opdata->old_thickness = 0.01;
|
||||
opdata->old_depth = 0.0;
|
||||
opdata->modify_depth = FALSE;
|
||||
opdata->shift = FALSE;
|
||||
opdata->shift_amount = 0.0f;
|
||||
opdata->is_modal = is_modal;
|
||||
opdata->em = em;
|
||||
|
||||
initNumInput(&opdata->num_input);
|
||||
opdata->num_input.idx_max = 1; /* Two elements. */
|
||||
|
||||
if (is_modal)
|
||||
opdata->backup = EDBM_redo_state_store(em);
|
||||
|
||||
@@ -4814,34 +4950,17 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
InsetData *opdata;
|
||||
InsetData *opdata = op->customdata;
|
||||
|
||||
opdata = op->customdata;
|
||||
if (event->val == KM_PRESS) {
|
||||
/* Try to handle numeric inputs... */
|
||||
float amounts[2];
|
||||
|
||||
switch (event->type) {
|
||||
case ESCKEY:
|
||||
case RIGHTMOUSE:
|
||||
edbm_inset_cancel(C, op);
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
case MOUSEMOVE:
|
||||
{
|
||||
float mdiff[2];
|
||||
float amount;
|
||||
|
||||
mdiff[0] = opdata->mcenter[0] - event->mval[0];
|
||||
mdiff[1] = opdata->mcenter[1] - event->mval[1];
|
||||
|
||||
if (opdata->modify_depth) {
|
||||
amount = opdata->old_depth + (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length;
|
||||
RNA_float_set(op->ptr, "depth", amount);
|
||||
}
|
||||
else {
|
||||
amount = opdata->old_thickness - (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length;
|
||||
amount = MAX2(amount, 0.0f);
|
||||
|
||||
RNA_float_set(op->ptr, "thickness", amount);
|
||||
}
|
||||
if (handleNumInput(&opdata->num_input, event)) {
|
||||
applyNumInput(&opdata->num_input, amounts);
|
||||
amounts[0] = MAX2(amounts[0], 0.0f);
|
||||
RNA_float_set(op->ptr, "thickness", amounts[0]);
|
||||
RNA_float_set(op->ptr, "depth", amounts[1]);
|
||||
|
||||
if (edbm_inset_calc(C, op)) {
|
||||
edbm_inset_update_header(op, C);
|
||||
@@ -4852,6 +4971,45 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (event->type) {
|
||||
case ESCKEY:
|
||||
case RIGHTMOUSE:
|
||||
edbm_inset_cancel(C, op);
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
case MOUSEMOVE:
|
||||
if (!hasNumInput(&opdata->num_input)) {
|
||||
float mdiff[2];
|
||||
float amount;
|
||||
|
||||
mdiff[0] = opdata->mcenter[0] - event->mval[0];
|
||||
mdiff[1] = opdata->mcenter[1] - event->mval[1];
|
||||
|
||||
if (opdata->modify_depth)
|
||||
amount = opdata->old_depth + len_v2(mdiff) / opdata->initial_length - 1.0f;
|
||||
else
|
||||
amount = opdata->old_thickness - len_v2(mdiff) / opdata->initial_length + 1.0f;
|
||||
|
||||
/* Fake shift-transform... */
|
||||
if (opdata->shift)
|
||||
amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount;
|
||||
|
||||
if (opdata->modify_depth)
|
||||
RNA_float_set(op->ptr, "depth", amount);
|
||||
else {
|
||||
amount = MAX2(amount, 0.0f);
|
||||
RNA_float_set(op->ptr, "thickness", amount);
|
||||
}
|
||||
|
||||
if (edbm_inset_calc(C, op))
|
||||
edbm_inset_update_header(op, C);
|
||||
else {
|
||||
edbm_inset_cancel(C, op);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
||||
case LEFTMOUSE:
|
||||
case PADENTER:
|
||||
@@ -4860,6 +5018,20 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
edbm_inset_exit(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
case LEFTSHIFTKEY:
|
||||
case RIGHTSHIFTKEY:
|
||||
if (event->val == KM_PRESS) {
|
||||
if (opdata->modify_depth)
|
||||
opdata->shift_amount = RNA_float_get(op->ptr, "depth");
|
||||
else
|
||||
opdata->shift_amount = RNA_float_get(op->ptr, "thickness");
|
||||
opdata->shift = TRUE;
|
||||
}
|
||||
else {
|
||||
opdata->shift_amount = 0.0f;
|
||||
opdata->shift = FALSE;
|
||||
}
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
||||
case LEFTCTRLKEY:
|
||||
case RIGHTCTRLKEY:
|
||||
@@ -4871,10 +5043,14 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
if (event->val == KM_PRESS) {
|
||||
opdata->old_thickness = RNA_float_get(op->ptr, "thickness");
|
||||
if (opdata->shift)
|
||||
opdata->shift_amount = opdata->old_thickness;
|
||||
opdata->modify_depth = TRUE;
|
||||
}
|
||||
else {
|
||||
opdata->old_depth = RNA_float_get(op->ptr, "depth");
|
||||
if (opdata->shift)
|
||||
opdata->shift_amount = opdata->old_depth;
|
||||
opdata->modify_depth = FALSE;
|
||||
}
|
||||
opdata->initial_length = len_v2(mlen);
|
||||
@@ -5010,7 +5186,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = BMEdit_FromObject(obedit);
|
||||
BMOperator bmop;
|
||||
|
||||
|
||||
EDBM_op_init(em, &bmop, op, "convex_hull input=%hvef "
|
||||
"use_existing_faces=%b",
|
||||
BM_ELEM_SELECT,
|
||||
|
||||
Reference in New Issue
Block a user