/* returns 0 on error, 1 on success. executes and finishes a bmesh operator */ bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool do_report) { const char *errmsg; BMO_op_finish(em->bm, bmop); if (BMO_error_get(em->bm, &errmsg, NULL)) { BMEditMesh *emcopy = em->emcopy; if (do_report) { BKE_report(op->reports, RPT_ERROR, errmsg); } EDBM_mesh_free(em); *em = *emcopy; MEM_freeN(emcopy); em->emcopyusers = 0; em->emcopy = NULL; /* when copying, tessellation isn't to for faster copying, * but means we need to re-tessellate here */ if (em->looptris == NULL) { BKE_editmesh_tessface_calc(em); } return false; } else { em->emcopyusers--; if (em->emcopyusers < 0) { printf("warning: em->emcopyusers was less than zero.\n"); } if (em->emcopyusers <= 0) { BKE_editmesh_free(em->emcopy); MEM_freeN(em->emcopy); em->emcopy = NULL; } return true; } }
/* frees all editmode stuff */ void ED_editors_exit(bContext *C) { Main *bmain = CTX_data_main(C); Scene *sce; if (!bmain) return; /* frees all editmode undos */ if (G_MAIN->wm.first) { wmWindowManager *wm = G_MAIN->wm.first; /* normally we don't check for NULL undo stack, do here since it may run in different context. */ if (wm->undo_stack) { BKE_undosys_stack_destroy(wm->undo_stack); wm->undo_stack = NULL; } } for (sce = bmain->scene.first; sce; sce = sce->id.next) { if (sce->obedit) { Object *ob = sce->obedit; if (ob) { if (ob->type == OB_MESH) { Mesh *me = ob->data; if (me->edit_btmesh) { EDBM_mesh_free(me->edit_btmesh); MEM_freeN(me->edit_btmesh); me->edit_btmesh = NULL; } } else if (ob->type == OB_ARMATURE) { ED_armature_edit_free(ob->data); } } } } /* global in meshtools... */ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); ED_mesh_mirror_topo_table(NULL, NULL, 'e'); }
/* frees all editmode stuff */ void ED_editors_exit(bContext *C) { Main *bmain = CTX_data_main(C); Scene *sce; if (!bmain) return; /* frees all editmode undos */ undo_editmode_clear(); ED_undo_paint_free(); for (sce = bmain->scene.first; sce; sce = sce->id.next) { if (sce->obedit) { Object *ob = sce->obedit; if (ob) { if (ob->type == OB_MESH) { Mesh *me = ob->data; if (me->edit_btmesh) { EDBM_mesh_free(me->edit_btmesh); MEM_freeN(me->edit_btmesh); me->edit_btmesh = NULL; } } else if (ob->type == OB_ARMATURE) { ED_armature_edit_free(ob->data); } } } } /* global in meshtools... */ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e'); ED_mesh_mirror_topo_table(NULL, 'e'); }
void ED_object_exit_editmode(bContext *C, int flag) { /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); int freedata = flag & EM_FREEDATA; if (obedit==NULL) return; if (flag & EM_WAITCURSOR) waitcursor(1); if (obedit->type==OB_MESH) { Mesh *me= obedit->data; // if (EM_texFaceCheck()) if (me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) { error("Too many vertices"); return; } EDBM_mesh_load(obedit); if (freedata) { EDBM_mesh_free(me->edit_btmesh); MEM_freeN(me->edit_btmesh); me->edit_btmesh= NULL; } if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) { mesh_octree_table(NULL, NULL, NULL, 'e'); mesh_mirrtopo_table(NULL, 'e'); } } else if (obedit->type==OB_ARMATURE) { ED_armature_from_edit(obedit); if (freedata) ED_armature_edit_free(obedit); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { load_editNurb(obedit); if (freedata) free_editNurb(obedit); } else if (obedit->type==OB_FONT && freedata) { load_editText(obedit); if (freedata) free_editText(obedit); } else if (obedit->type==OB_LATTICE) { load_editLatt(obedit); if (freedata) free_editLatt(obedit); } else if (obedit->type==OB_MBALL) { load_editMball(obedit); if (freedata) free_editMball(obedit); } /* freedata only 0 now on file saves and render */ if (freedata) { ListBase pidlist; PTCacheID *pid; /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context /* flag object caches as outdated */ BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0); for (pid=pidlist.first; pid; pid=pid->next) { if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } BLI_freelistN(&pidlist); BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED); /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_tag_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); if (flag & EM_DO_UNDO) ED_undo_push(C, "Editmode"); if (flag & EM_WAITCURSOR) waitcursor(0); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); obedit->mode &= ~OB_MODE_EDIT; } }