Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/mesh/meshtools.c')
-rw-r--r--source/blender/editors/mesh/meshtools.c243
1 files changed, 206 insertions, 37 deletions
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 6953473a792..786b27ee816 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -42,12 +42,12 @@
#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"
@@ -60,6 +60,10 @@
#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 +80,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 +208,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 +282,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 +293,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 +489,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 +506,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 +517,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,9 +588,9 @@ 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);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@ -600,6 +606,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
{
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;
@@ -648,7 +655,7 @@ 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);
+ dm = mesh_get_derived_deform(depsgraph, scene, base->object, CD_MASK_BAREMESH);
if (!dm) continue;
@@ -679,15 +686,40 @@ 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, DerivedMesh *dm, char mode)
{
if (mode == 'u') { /* use table */
- if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, ob->mode, &mesh_topo_store)) {
+ if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, &mesh_topo_store)) {
ED_mesh_mirror_topo_table(ob, dm, '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, dm, &mesh_topo_store, false);
+ }
+ else if (mode == 'e') { /* end table */
+ ED_mesh_mirrtopo_free(&mesh_topo_store);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ return 0;
+}
+
+/* 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__real_mesh(
+ Object *ob, Mesh *mesh, char mode)
+{
+ if (mode == 'u') { /* use table */
+ if (ED_mesh_mirrtopo_recalc_check__real_mesh(ob->data, mesh, &mesh_topo_store)) {
+ ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 's');
+ }
+ }
+ else if (mode == 's') { /* start table */
+ ED_mesh_mirrtopo_init__real_mesh(ob->data, mesh, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
@@ -734,6 +766,38 @@ int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool us
}
}
+static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int index)
+{
+ Mesh *me = ob->data;
+ MVert *mvert = mesh ? mesh->mvert : me->mvert;
+ float vec[3];
+
+ mvert = &mvert[index];
+ vec[0] = -mvert->co[0];
+ vec[1] = mvert->co[1];
+ vec[2] = mvert->co[2];
+
+ return ED_mesh_mirror_spatial_table__real_mesh(ob, NULL, mesh, vec, 'u');
+}
+
+static int mesh_get_x_mirror_vert_topo__real_mesh(Object *ob, Mesh *mesh, int index)
+{
+ if (ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 'u') == -1)
+ return -1;
+
+ return mesh_topo_store.index_lookup[index];
+}
+
+int mesh_get_x_mirror_vert__real_mesh(Object *ob, Mesh *mesh, int index, const bool use_topology)
+{
+ if (use_topology) {
+ return mesh_get_x_mirror_vert_topo__real_mesh(ob, mesh, index);
+ }
+ else {
+ return mesh_get_x_mirror_vert_spatial__real_mesh(ob, mesh, index);
+ }
+}
+
static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, const float co[3])
{
float vec[3];
@@ -987,6 +1051,66 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm)
return mirrorfaces;
}
+/* This is a Mesh-based copy of mesh_get_x_mirror_faces() */
+int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh)
+{
+ Mesh *me = ob->data;
+ MVert *mv, *mvert;
+ MFace mirrormf, *mf, *hashmf, *mface;
+ GHash *fhash;
+ int *mirrorverts, *mirrorfaces;
+
+ BLI_assert(em == NULL); /* Does not work otherwise, currently... */
+
+ const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
+ const int totvert = mesh ? mesh->totvert : me->totvert;
+ const int totface = mesh ? mesh->totface : me->totface;
+ int a;
+
+ mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
+ mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
+
+ mvert = mesh ? mesh->mvert : me->mvert;
+ mface = mesh ? mesh->mface : me->mface;
+
+ ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
+
+ for (a = 0, mv = mvert; a < totvert; a++, mv++)
+ mirrorverts[a] = mesh_get_x_mirror_vert__real_mesh(ob, mesh, a, use_topology);
+
+ ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, 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++)
+ BLI_ghash_insert(fhash, mf, mf);
+
+ for (a = 0, mf = mface; a < totface; a++, mf++) {
+ mirrormf.v1 = mirrorverts[mf->v3];
+ mirrormf.v2 = mirrorverts[mf->v2];
+ mirrormf.v3 = mirrorverts[mf->v1];
+ mirrormf.v4 = (mf->v4) ? mirrorverts[mf->v4] : 0;
+
+ /* make sure v4 is not 0 if a quad */
+ if (mf->v4 && mirrormf.v4 == 0) {
+ SWAP(unsigned int, mirrormf.v1, mirrormf.v3);
+ SWAP(unsigned int, mirrormf.v2, mirrormf.v4);
+ }
+
+ hashmf = BLI_ghash_lookup(fhash, &mirrormf);
+ if (hashmf) {
+ mirrorfaces[a * 2] = hashmf - mface;
+ mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf);
+ }
+ else
+ mirrorfaces[a * 2] = -1;
+ }
+
+ BLI_ghash_free(fhash, NULL, NULL);
+ MEM_freeN(mirrorverts);
+
+ return mirrorfaces;
+}
+
/* selection, vertex and face */
/* returns 0 if not found, otherwise 1 */
@@ -1030,21 +1154,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;
}
}
@@ -1056,6 +1181,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;
@@ -1066,7 +1192,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;
@@ -1074,36 +1200,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);
}
}
@@ -1111,15 +1239,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;
@@ -1193,7 +1318,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);
+ DerivedMesh *dm = mesh_get_derived_final(vc.depsgraph, vc.scene, ob, CD_MASK_BAREMESH);
ARegion *ar = vc.ar;
RegionView3D *rv3d = ar->regiondata;
@@ -1279,3 +1404,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);
+ }
+}