fix [#30651] bpy.ops.object.mode_set(...) editmode removes faces.

problem was that BMesh had tessellation call when undo pushes were called.

if python called an operator with no undo push, tessfaces would not be created.

fix this by making it the responsibility of each editmesh operator to re-tessellate, as it is with notifiers and depsgraph.
added EDBM_update_generic() function to add notifier, tag for depsgraph update and optionally re-tessellate.
This commit is contained in:
Campbell Barton
2012-03-27 00:01:35 +00:00
parent 4d802ff682
commit ca05219f3e
13 changed files with 109 additions and 193 deletions

View File

@@ -80,10 +80,6 @@ typedef struct BMEditMesh {
int mirr_free_arrays;
} BMEditMesh;
/* undo triggers editmesh tessface update, this is odd but works OK.
* BMESH_TODO, look into having the update elsewhere. */
#define BMESH_EM_UNDO_RECALC_TESSFACE_WORKAROUND
void BMEdit_RecalcTessellation(BMEditMesh *tm);
BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate);
BMEditMesh *BMEdit_Copy(BMEditMesh *tm);

View File

@@ -2716,7 +2716,6 @@ void DAG_id_tag_update(ID *id, short flag)
/* flag is for objects and particle systems */
if (flag) {
Object *ob;
ParticleSystem *psys;
short idtype = GS(id->name);
if (idtype == ID_OB) {
@@ -2725,6 +2724,7 @@ void DAG_id_tag_update(ID *id, short flag)
ob->recalc |= (flag & OB_RECALC_ALL);
}
else if (idtype == ID_PA) {
ParticleSystem *psys;
/* this is weak still, should be done delayed as well */
for (ob=bmain->object.first; ob; ob=ob->id.next) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {

View File

@@ -511,7 +511,8 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram
BKE_animsys_evaluate_animdata(scene, &cu->id, cu->adt, frame, ADT_RECALC_ANIM);
}
ob->recalc |= OB_RECALC_ALL;
/* was originally OB_RECALC_ALL - TODO - which flags are really needed??? */
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, frame, ADT_RECALC_ANIM);
if (flags & UPDATE_MESH) {
/* ignore cache clear during subframe updates

View File

@@ -168,6 +168,8 @@ void EDBM_validate_selections(struct BMEditMesh *em);
void EDBM_hide_mesh(struct BMEditMesh *em, int swap);
void EDBM_reveal_mesh(struct BMEditMesh *em);
void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short do_tessface);
int EDBM_check_backbuf(unsigned int index);
int EDBM_mask_init_backbuf_border(struct ViewContext *vc, int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax);
void EDBM_free_backbuf(void);

View File

@@ -98,29 +98,20 @@ static void make_prim_init(bContext *C, const char *idname,
ED_object_enter_editmode(C, EM_DO_UNDO | EM_IGNORE_LAYER); /* rare cases the active layer is messed up */
*state = 1;
}
else {
DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
}
*dia *= new_primitive_matrix(C, loc, rot, mat);
}
static void make_prim_finish(bContext *C, int *state, int enter_editmode)
{
Object *obedit;
Mesh *me;
BMEditMesh *em;
obedit = CTX_data_edit_object(C);
me = obedit->data;
em = me->edit_btmesh;
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
/* Primitive has all verts selected, use vert select flush
* to push this up to edges & faces. */
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
/* userdef */
if (*state && !enter_editmode) {

View File

@@ -2601,8 +2601,7 @@ static void knifetool_finish(bContext *C, wmOperator *op)
knife_make_cuts(kcd);
#endif
DAG_id_tag_update(kcd->ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, kcd->ob->data);
EDBM_update_generic(C, kcd->em, TRUE);
}
/* copied from paint_image.c */

View File

@@ -115,6 +115,7 @@ void EDBM_automerge(Scene *scene, Object *obedit, int update)
BMO_op_callf(em->bm, "automerge verts=%hv dist=%f", BM_ELEM_SELECT, scene->toolsettings->doublimit);
if (update) {
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
BMEdit_RecalcTessellation(em);
}
}
}
@@ -722,9 +723,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* dependencies graph and notification stuff */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -763,9 +762,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* dependencies graph and notification stuff */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -807,9 +804,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
/* dependencies graph and notification stuff */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1356,7 +1351,6 @@ static int edgetag_shortest_path(Scene *scene, BMEditMesh *em, BMEdge *source, B
/* since you want to create paths with multiple selects, it doesn't have extend option */
static void mouse_mesh_shortest_path(bContext *C, int mval[2])
{
Object *ob = CTX_data_edit_object(C);
ViewContext vc;
BMEditMesh *em;
BMEdge *e;
@@ -1416,8 +1410,7 @@ static void mouse_mesh_shortest_path(bContext *C, int mval[2])
break;
}
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
EDBM_update_generic(C, em, FALSE);
}
}
@@ -2172,8 +2165,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, FALSE);
return OPERATOR_FINISHED;
}

View File

@@ -107,8 +107,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
RNA_boolean_get(op->ptr, "quadtri"),
TRUE, RNA_int_get(op->ptr, "seed"));
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -407,8 +406,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
EDBM_RecalcNormals(em);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -528,9 +526,8 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
* like this one don't push undo data until after modal mode is
* done.*/
EDBM_RecalcNormals(em);
BMEdit_RecalcTessellation(em);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -879,11 +876,9 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
* like this one don't push undo data until after modal mode is
* done. */
EDBM_RecalcNormals(vc.em);
BMEdit_RecalcTessellation(vc.em);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, vc.obedit->data);
DAG_id_tag_update(vc.obedit->data, OB_RECALC_DATA);
EDBM_update_generic(C, vc.em, TRUE);
return OPERATOR_FINISHED;
}
@@ -947,9 +942,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA | ND_SELECT, obedit);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -981,9 +974,8 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op)
if (!EDBM_CallOpf(em, op, "collapse edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA | ND_SELECT, obedit);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1010,9 +1002,8 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op)
if (!EDBM_CallOpf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA | ND_SELECT, obedit);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1048,8 +1039,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1102,8 +1092,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op)
}
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1157,9 +1146,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op)
}
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1199,8 +1186,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1236,8 +1222,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1275,8 +1260,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1315,8 +1299,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
if (!EDBM_CallOpf(em, op, "reversefaces faces=%hf", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1396,8 +1379,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1427,9 +1409,8 @@ static int edbm_hide_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BMEdit_FromObject(obedit);
EDBM_hide_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1459,8 +1440,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op))
EDBM_reveal_mesh(em);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1493,8 +1473,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "inside"))
EDBM_CallOpf(em, op, "reversefaces faces=%hf", BM_ELEM_SELECT);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1571,8 +1550,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
EDBM_EndMirrorCache(em);
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -1617,8 +1595,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
mesh_set_smooth_faces(em, 1);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, FALSE);
return OPERATOR_FINISHED;
}
@@ -1645,8 +1622,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
mesh_set_smooth_faces(em, 0);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, FALSE);
return OPERATOR_FINISHED;
}
@@ -1689,9 +1665,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* dependencies graph and notification stuff */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1714,9 +1688,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* dependencies graph and notification stuff */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1743,11 +1715,8 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
}
/* dependencies graph and notification stuff */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
/* DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
* WM_event_add_notifier(C, NC_OBJECT | ND_GEOM_SELECT, ob);
*/
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
}
@@ -1770,8 +1739,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1952,8 +1920,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op)
if (!status)
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -2052,9 +2019,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s", count, (count == 1) ? "ex" : "ices");
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -2132,13 +2097,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
/* dependencies graph and notification stuff */
/* DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
* WM_event_add_notifier(C, NC_OBJECT | ND_GEOM_SELECT, ob);
*/
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
EDBM_update_generic(C, em, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -2409,9 +2368,8 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (bm->totvertsel == 0) {
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -2437,7 +2395,7 @@ void MESH_OT_rip(wmOperatorType *ot)
/************************ Shape Operators *************************/
/* BMESH_TODO this should be properly encapsulated in a bmop. but later.*/
static void shape_propagate(Object *obedit, BMEditMesh *em, wmOperator *op)
static void shape_propagate(BMEditMesh *em, wmOperator *op)
{
BMIter iter;
BMVert *eve = NULL;
@@ -2467,8 +2425,6 @@ static void shape_propagate(Object *obedit, BMEditMesh *em, wmOperator *op)
}
}
#endif
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
}
@@ -2478,10 +2434,9 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
Mesh *me = obedit->data;
BMEditMesh *em = me->edit_btmesh;
shape_propagate(obedit, em, op);
shape_propagate(em, op);
DAG_id_tag_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
EDBM_update_generic(C, em, FALSE);
return OPERATOR_FINISHED;
}
@@ -2540,8 +2495,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
copy_v3_v3(sco, co);
}
DAG_id_tag_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -2714,8 +2668,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3039,8 +2992,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3229,10 +3181,11 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
retval = mesh_separate_material(bmain, scene, base, op);
else if (type == 2)
retval = mesh_separate_loose(bmain, scene, base, op);
if (retval) {
DAG_id_tag_update(base->object->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, base->object->data);
BMEditMesh *em = BMEdit_FromObject(base->object);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3285,9 +3238,8 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
if (!EDBM_FinishOp(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
@@ -3315,8 +3267,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
if (!EDBM_CallOpf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3346,8 +3297,7 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
if (!EDBM_CallOpf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty))
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3387,8 +3337,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3438,9 +3387,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA | ND_SELECT, obedit);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3477,8 +3424,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3519,11 +3465,9 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
}
/* Geometry has changed, need to recalc normals and looptris */
BMEdit_RecalcTessellation(em);
EDBM_RecalcNormals(em);
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3581,8 +3525,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -3705,8 +3648,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -4325,8 +4267,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op)
EDBM_RecalcNormals(em);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -4414,8 +4355,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
EDBM_RecalcNormals(em);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -4450,8 +4390,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
if (!EDBM_CallOpf(em, op, "bridge_loops edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
@@ -4501,9 +4440,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
EDBM_update_generic(C, em, TRUE);
return OPERATOR_FINISHED;
}
}

View File

@@ -41,6 +41,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_bmesh.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
@@ -147,7 +148,6 @@ int EDBM_FinishOp(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const int re
BMEdit_Free(em);
*em = *emcopy;
BMEdit_RecalcTessellation(em);
MEM_freeN(emcopy);
em->emcopyusers = 0;
@@ -523,14 +523,6 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata)
/* make sure shape keys work */
um->me.key = obme->key ? copy_key_nolib(obme->key) : NULL;
#ifdef BMESH_EM_UNDO_RECALC_TESSFACE_WORKAROUND
/* we recalc the tessellation here, to avoid seeding calls to
* BMEdit_RecalcTessellation throughout the code. */
BMEdit_RecalcTessellation(em);
#endif
/* BM_mesh_validate(em->bm); */ /* for troubleshooting */
BMO_op_callf(em->bm, "bmesh_to_mesh mesh=%p notessellation=%b", &um->me, TRUE);
@@ -1231,6 +1223,20 @@ void EDBM_reveal_mesh(BMEditMesh *em)
EDBM_selectmode_flush(em);
}
/* so many tools call these that we better make it a generic function.
*/
void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface)
{
Object *ob = em->ob;
/* order of calling isn't important */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
if (do_tessface) {
BMEdit_RecalcTessellation(em);
}
}
/* * Selection History ***************************************************** */
/* these wrap equivalent bmesh functions. I'm in two minds of it we should
* just use the bm functions directly; on the one hand, there's no real

View File

@@ -440,11 +440,17 @@ void ED_object_enter_editmode(bContext *C, int flag)
ob->mode= OB_MODE_EDIT;
if (ob->type==OB_MESH) {
BMEditMesh *em;
ok= 1;
scene->obedit= ob; // context sees this
scene->obedit = ob; /* context sees this */
EDBM_MakeEditBMesh(CTX_data_tool_settings(C), scene, ob);
em = BMEdit_FromObject(ob);
if (LIKELY(em)) {
BMEdit_RecalcTessellation(em);
}
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene);
}
else if (ob->type==OB_ARMATURE) {

View File

@@ -48,8 +48,6 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_screen.h"
#include "BKE_tessmesh.h" /* BMESH_EM_UNDO_RECALC_TESSFACE_WORKAROUND */
#include "ED_armature.h"
#include "ED_particle.h"
@@ -88,19 +86,6 @@ void ED_undo_push(bContext *C, const char *str)
printf("undo push %s\n", str);
if (obedit) {
#ifdef BMESH_EM_UNDO_RECALC_TESSFACE_WORKAROUND
/* undo is causing tessface recalc, so without we need to do explicitly */
if (U.undosteps == 0) {
if (obedit->type == OB_MESH) {
Mesh *me= obedit->data;
BMEdit_RecalcTessellation(me->edit_btmesh);
}
}
#endif /* BMESH_EM_UNDO_RECALC_TESSFACE_WORKAROUND */
if (U.undosteps == 0) return;
if (obedit->type==OB_MESH)

View File

@@ -439,13 +439,14 @@ typedef struct DupliObject {
// #define OB_RADIO 2048 /* deprecated */
#define OB_FROMGROUP 4096
/* WARNING - when adding flags check on PSYS_RECALC */
/* ob->recalc (flag bits!) */
#define OB_RECALC_OB 1
#define OB_RECALC_DATA 2
/* time flag is set when time changes need recalc, so baked systems can ignore it */
#define OB_RECALC_TIME 4
/* only use for matching any flag, NOT as an argument since more flags may be added. */
#define OB_RECALC_ALL (OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME)
#define OB_RECALC_OB (1 << 0)
#define OB_RECALC_DATA (1 << 1)
/* time flag is set when time changes need recalc, so baked systems can ignore it */
#define OB_RECALC_TIME (1 << 2)
/* only use for matching any flag, NOT as an argument since more flags may be added. */
#define OB_RECALC_ALL (OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME)
/* controller state */
#define OB_MAX_STATES 30

View File

@@ -481,13 +481,13 @@ typedef struct ParticleSystem
#define PART_CHILD_FACES 2
/* psys->recalc */
/* starts from 8 so that the first bits can be ob->recalc */
#define PSYS_RECALC_REDO 8 /* only do pathcache etc */
#define PSYS_RECALC_RESET 16 /* reset everything including pointcache */
#define PSYS_RECALC_TYPE 32 /* handle system type change */
#define PSYS_RECALC_CHILD 64 /* only child settings changed */
#define PSYS_RECALC_PHYS 128 /* physics type changed */
#define PSYS_RECALC 248
/* starts from (1 << 3) so that the first bits can be ob->recalc */
#define PSYS_RECALC_REDO (1 << 3) /* only do pathcache etc */
#define PSYS_RECALC_RESET (1 << 4) /* reset everything including pointcache */
#define PSYS_RECALC_TYPE (1 << 5) /* handle system type change */
#define PSYS_RECALC_CHILD (1 << 6) /* only child settings changed */
#define PSYS_RECALC_PHYS (1 << 7) /* physics type changed */
#define PSYS_RECALC (PSYS_RECALC_REDO | PSYS_RECALC_RESET | PSYS_RECALC_TYPE | PSYS_RECALC_CHILD | PSYS_RECALC_PHYS)
/* psys->flag */
#define PSYS_CURRENT 1