diff options
Diffstat (limited to 'source/blender/editors/mesh/meshtools.c')
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 188 |
1 files changed, 121 insertions, 67 deletions
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 8980e1830cf..537056cd1ba 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -34,32 +34,38 @@ #include "MEM_guardedalloc.h" -#include "DNA_mesh_types.h" #include "DNA_key_types.h" #include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_deform.h" -#include "BKE_DerivedMesh.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_mesh_iterators.h" +#include "BKE_mesh_runtime.h" #include "BKE_material.h" #include "BKE_object.h" #include "BKE_object_deform.h" #include "BKE_report.h" #include "BKE_editmesh.h" #include "BKE_multires.h" +#include "BKE_layer.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" #include "ED_mesh.h" #include "ED_object.h" @@ -76,7 +82,7 @@ * return 0 if no join is made (error) and 1 if the join is done */ static void join_mesh_single( - Main *bmain, Scene *scene, + Depsgraph *depsgraph, Main *bmain, Scene *scene, Object *ob_dst, Object *ob_src, float imat[4][4], MVert **mvert_pp, MEdge **medge_pp, MLoop **mloop_pp, MPoly **mpoly_pp, CustomData *vdata, CustomData *edata, CustomData *ldata, CustomData *pdata, @@ -204,7 +210,7 @@ static void join_mesh_single( if (ob_src != ob_dst) { MultiresModifierData *mmd; - multiresModifier_prepare_join(scene, ob_src, ob_dst); + multiresModifier_prepare_join(depsgraph, scene, ob_src, ob_dst); if ((mmd = get_multires_modifier(scene, ob_src, true))) { ED_object_iter_other(bmain, ob_src, true, @@ -278,7 +284,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) bDeformGroup *dg, *odg; CustomData vdata, edata, fdata, ldata, pdata; - if (scene->obedit) { + if (ob->mode & OB_MODE_EDIT) { BKE_report(op->reports, RPT_WARNING, "Cannot join while in edit mode"); return OPERATOR_CANCELLED; } @@ -289,6 +295,8 @@ int join_mesh_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + Depsgraph *depsgraph = CTX_data_depsgraph(C); + /* count & check */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { @@ -483,7 +491,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) * active mesh will remain first ones in new result of the merge, in same order for CD layers, etc. See also T50084. */ join_mesh_single( - bmain, scene, + depsgraph, bmain, scene, ob, ob, imat, &mvert, &medge, &mloop, &mpoly, &vdata, &edata, &ldata, &pdata, @@ -500,7 +508,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* only join if this is a mesh */ if (base->object->type == OB_MESH) { join_mesh_single( - bmain, scene, + depsgraph, bmain, scene, ob, base->object, imat, &mvert, &medge, &mloop, &mpoly, &vdata, &edata, &ldata, &pdata, @@ -511,7 +519,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* free base, now that data is merged */ if (base->object != ob) { - ED_base_object_free_and_unlink(bmain, scene, base); + ED_object_base_free_and_unlink(bmain, scene, base->object); } } } @@ -582,10 +590,11 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* Due to dependnecy cycle some other object might access old derived data. */ BKE_object_free_derived_caches(ob); - DAG_relations_tag_update(bmain); /* removed objects, need to rebuild dag */ + DEG_relations_tag_update(bmain); /* removed objects, need to rebuild dag */ - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); return OPERATOR_FINISHED; @@ -601,9 +610,10 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Mesh *me = (Mesh *)ob->data; Mesh *selme = NULL; - DerivedMesh *dm = NULL; + Mesh *me_deformed = NULL; Key *key = me->key; KeyBlock *kb; bool ok = false, nonequal_verts = false; @@ -637,7 +647,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) /* first key added, so it was the basis. initialize it with the existing mesh */ kb = BKE_keyblock_add(key, NULL); - BKE_keyblock_convert_from_mesh(me, kb); + BKE_keyblock_convert_from_mesh(me, key, kb); } /* now ready to add new keys from selected meshes */ @@ -649,20 +659,21 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) selme = (Mesh *)base->object->data; if (selme->totvert == me->totvert) { - dm = mesh_get_derived_deform(scene, base->object, CD_MASK_BAREMESH); + me_deformed = mesh_get_eval_deform(depsgraph, scene, base->object, CD_MASK_BAREMESH); - if (!dm) continue; + if (!me_deformed) { + continue; + } kb = BKE_keyblock_add(key, base->object->id.name + 2); - DM_to_meshkey(dm, me, kb); - - dm->release(dm); + BKE_mesh_runtime_eval_to_meshkey(me_deformed, me, kb); } } } CTX_DATA_END; + DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); return OPERATOR_FINISHED; @@ -680,15 +691,15 @@ static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1}; /* mode is 's' start, or 'e' end, or 'u' use */ /* if end, ob can be NULL */ /* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */ -int ED_mesh_mirror_topo_table(Object *ob, DerivedMesh *dm, char mode) +int ED_mesh_mirror_topo_table(Object *ob, Mesh *me_eval, char mode) { if (mode == 'u') { /* use table */ - if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, ob->mode, &mesh_topo_store)) { - ED_mesh_mirror_topo_table(ob, dm, 's'); + if (ED_mesh_mirrtopo_recalc_check(ob->data, me_eval, &mesh_topo_store)) { + ED_mesh_mirror_topo_table(ob, me_eval, 's'); } } else if (mode == 's') { /* start table */ - ED_mesh_mirrtopo_init(ob->data, dm, ob->mode, &mesh_topo_store, false); + ED_mesh_mirrtopo_init(ob->data, me_eval, &mesh_topo_store, false); } else if (mode == 'e') { /* end table */ ED_mesh_mirrtopo_free(&mesh_topo_store); @@ -703,10 +714,10 @@ int ED_mesh_mirror_topo_table(Object *ob, DerivedMesh *dm, char mode) /** \} */ -static int mesh_get_x_mirror_vert_spatial(Object *ob, DerivedMesh *dm, int index) +static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *mesh, int index) { Mesh *me = ob->data; - MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert; + MVert *mvert = mesh ? mesh->mvert : me->mvert; float vec[3]; mvert = &mvert[index]; @@ -714,24 +725,24 @@ static int mesh_get_x_mirror_vert_spatial(Object *ob, DerivedMesh *dm, int index vec[1] = mvert->co[1]; vec[2] = mvert->co[2]; - return ED_mesh_mirror_spatial_table(ob, NULL, dm, vec, 'u'); + return ED_mesh_mirror_spatial_table(ob, NULL, mesh, vec, 'u'); } -static int mesh_get_x_mirror_vert_topo(Object *ob, DerivedMesh *dm, int index) +static int mesh_get_x_mirror_vert_topo(Object *ob, Mesh *mesh, int index) { - if (ED_mesh_mirror_topo_table(ob, dm, 'u') == -1) + if (ED_mesh_mirror_topo_table(ob, mesh, 'u') == -1) return -1; return mesh_topo_store.index_lookup[index]; } -int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool use_topology) +int mesh_get_x_mirror_vert(Object *ob, Mesh *me_eval, int index, const bool use_topology) { if (use_topology) { - return mesh_get_x_mirror_vert_topo(ob, dm, index); + return mesh_get_x_mirror_vert_topo(ob, me_eval, index); } else { - return mesh_get_x_mirror_vert_spatial(ob, dm, index); + return mesh_get_x_mirror_vert_spatial(ob, me_eval, index); } } @@ -928,8 +939,8 @@ static bool mirror_facecmp(const void *a, const void *b) return (mirror_facerotation((MFace *)a, (MFace *)b) == -1); } -/* BMESH_TODO, convert to MPoly (functions above also) */ -int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm) +/* This is a Mesh-based copy of mesh_get_x_mirror_faces() */ +int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) { Mesh *me = ob->data; MVert *mv, *mvert; @@ -940,22 +951,22 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm) BLI_assert(em == NULL); /* Does not work otherwise, currently... */ const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; - const int totvert = dm ? dm->getNumVerts(dm) : me->totvert; - const int totface = dm ? dm->getNumTessFaces(dm) : me->totface; + const int totvert = me_eval ? me_eval->totvert : me->totvert; + const int totface = me_eval ? me_eval->totface : me->totface; int a; mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts"); mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces"); - mvert = dm ? dm->getVertArray(dm) : me->mvert; - mface = dm ? dm->getTessFaceArray(dm) : me->mface; + mvert = me_eval ? me_eval->mvert : me->mvert; + mface = me_eval ? me_eval->mface : me->mface; - ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's'); + ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's'); for (a = 0, mv = mvert; a < totvert; a++, mv++) - mirrorverts[a] = mesh_get_x_mirror_vert(ob, dm, a, use_topology); + mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology); - ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 'e'); + ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 'e'); fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface); for (a = 0, mf = mface; a < totface; a++, mf++) @@ -1031,21 +1042,22 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int static void ed_mesh_pick_face_vert__mpoly_find( /* context */ struct ARegion *ar, const float mval[2], - /* mesh data */ - DerivedMesh *dm, MPoly *mp, MLoop *mloop, + /* mesh data (evaluated) */ + const MPoly *mp, + const MVert *mvert, const MLoop *mloop, /* return values */ float *r_len_best, int *r_v_idx_best) { const MLoop *ml; int j = mp->totloop; for (ml = &mloop[mp->loopstart]; j--; ml++) { - float co[3], sco[2], len; + float sco[2]; const int v_idx = ml->v; - dm->getVertCo(dm, v_idx, co); + const float *co = mvert[v_idx].co; if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - len = len_manhattan_v2v2(mval, sco); - if (len < *r_len_best) { - *r_len_best = len; + const float len_test = len_manhattan_v2v2(mval, sco); + if (len_test < *r_len_best) { + *r_len_best = len_test; *r_v_idx_best = v_idx; } } @@ -1057,6 +1069,7 @@ static void ed_mesh_pick_face_vert__mpoly_find( */ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); unsigned int poly_index; Mesh *me = ob->data; @@ -1067,7 +1080,7 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned struct ARegion *ar = CTX_wm_region(C); /* derived mesh to find deformed locations */ - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); int v_idx_best = ORIGINDEX_NONE; @@ -1075,36 +1088,38 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned const float mval_f[2] = {UNPACK2(mval)}; float len_best = FLT_MAX; - MPoly *dm_mpoly; - MLoop *dm_mloop; - unsigned int dm_mpoly_tot; + MPoly *me_eval_mpoly; + MLoop *me_eval_mloop; + MVert *me_eval_mvert; + unsigned int me_eval_mpoly_len; const int *index_mp_to_orig; - dm_mpoly = dm->getPolyArray(dm); - dm_mloop = dm->getLoopArray(dm); + me_eval_mpoly = me_eval->mpoly; + me_eval_mloop = me_eval->mloop; + me_eval_mvert = me_eval->mvert; - dm_mpoly_tot = dm->getNumPolys(dm); + me_eval_mpoly_len = me_eval->totpoly; - index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); /* tag all verts using this face */ if (index_mp_to_orig) { unsigned int i; - for (i = 0; i < dm_mpoly_tot; i++) { + for (i = 0; i < me_eval_mpoly_len; i++) { if (index_mp_to_orig[i] == poly_index) { ed_mesh_pick_face_vert__mpoly_find( ar, mval_f, - dm, &dm_mpoly[i], dm_mloop, + &me_eval_mpoly[i], me_eval_mvert, me_eval_mloop, &len_best, &v_idx_best); } } } else { - if (poly_index < dm_mpoly_tot) { + if (poly_index < me_eval_mpoly_len) { ed_mesh_pick_face_vert__mpoly_find( ar, mval_f, - dm, &dm_mpoly[poly_index], dm_mloop, + &me_eval_mpoly[poly_index], me_eval_mvert, me_eval_mloop, &len_best, &v_idx_best); } } @@ -1112,15 +1127,12 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned /* map 'dm -> me' index if possible */ if (v_idx_best != ORIGINDEX_NONE) { const int *index_mv_to_orig; - - index_mv_to_orig = dm->getVertDataArray(dm, CD_ORIGINDEX); + index_mv_to_orig = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX); if (index_mv_to_orig) { v_idx_best = index_mv_to_orig[v_idx_best]; } } - dm->release(dm); - if ((v_idx_best != ORIGINDEX_NONE) && (v_idx_best < me->totvert)) { *index = v_idx_best; return true; @@ -1194,7 +1206,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int } else { /* derived mesh to find deformed locations */ - DerivedMesh *dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH); + Mesh *me_eval = mesh_get_eval_final(vc.depsgraph, vc.scene, ob, CD_MASK_BAREMESH); ARegion *ar = vc.ar; RegionView3D *rv3d = ar->regiondata; @@ -1206,7 +1218,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int ED_view3d_init_mats_rv3d(ob, rv3d); - if (dm == NULL) { + if (me_eval == NULL) { return false; } @@ -1217,9 +1229,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int data.len_best = FLT_MAX; data.v_idx_best = -1; - dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data, DM_FOREACH_NOP); - - dm->release(dm); + BKE_mesh_foreach_mapped_vert(me_eval, ed_mesh_pick_vert__mapFunc, &data, MESH_FOREACH_NOP); if (data.v_idx_best == -1) { return false; @@ -1280,3 +1290,47 @@ MDeformVert *ED_mesh_active_dvert_get_only(Object *ob) return NULL; } } + +void EDBM_mesh_stats_multi( + struct Object **objects, const uint objects_len, + int totelem[3], int totelem_sel[3]) +{ + if (totelem) { + totelem[0] = 0; + totelem[1] = 0; + totelem[2] = 0; + } + if (totelem_sel) { + totelem_sel[0] = 0; + totelem_sel[1] = 0; + totelem_sel[2] = 0; + } + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + if (totelem) { + totelem[0] += bm->totvert; + totelem[1] += bm->totedge; + totelem[2] += bm->totface; + } + if (totelem_sel) { + totelem_sel[0] += bm->totvertsel; + totelem_sel[1] += bm->totedgesel; + totelem_sel[2] += bm->totfacesel; + } + } +} + + +void EDBM_mesh_elem_index_ensure_multi(Object **objects, const uint objects_len, const char htype) +{ + int elem_offset[4] = {0, 0, 0, 0}; + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BM_mesh_elem_index_ensure_ex(bm, htype, elem_offset); + } +} |