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:
authorYimingWu <xp8110@outlook.com>2019-10-24 15:36:28 +0300
committerYimingWu <xp8110@outlook.com>2019-10-24 15:36:28 +0300
commite910924b37a3fdffeb38ac14c656c16f107a9c0d (patch)
treeab626478bbb650837fd54140cfbb30a04edb6a26 /source/blender/editors/mesh
parentf60406ff257c3309418413b5af76373010fb2a6f (diff)
parent42eef8f81a6aea27094985347ab802dc6bb91a61 (diff)
Merge remote-tracking branch 'origin/master' into soc-2019-npr
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c3
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c2
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c1
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c32
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c20
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c1
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c24
-rw-r--r--source/blender/editors/mesh/editmesh_select.c6
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c202
-rw-r--r--source/blender/editors/mesh/mesh_data.c141
-rw-r--r--source/blender/editors/mesh/meshtools.c38
12 files changed, 287 insertions, 189 deletions
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index b4ef2620895..7afd72f33c9 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -148,9 +148,10 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%.1f%%", RNA_float_get(op->ptr, "offset_pct"));
}
else {
+ double offset_val = (double)RNA_float_get(op->ptr, "offset");
bUnit_AsString2(offset_str,
NUM_STR_REP_LEN,
- (double)RNA_float_get(op->ptr, "offset"),
+ offset_val * sce->unit.scale_length,
3,
B_UNIT_LENGTH,
&sce->unit,
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index 283e147b77b..4a511bbb5a2 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -455,7 +455,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot)
0.00001,
0.1);
- WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);
+ WM_operator_properties_gesture_straightline(ot, WM_CURSOR_EDIT);
#ifdef USE_GIZMO
WM_gizmogrouptype_append(MESH_GGT_bisect);
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
index 7155348fed5..993898bddd5 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
@@ -522,7 +522,6 @@ typedef struct GizmoGroupData_SpinRedo {
PropertyRNA *prop_axis_no;
PropertyRNA *prop_angle;
- float rotate_axis[3];
#ifdef USE_ANGLE_Z_ORIENT
/* Apply 'orient_mat' for the final value. */
float orient_axis_relative[3];
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index 370cc6a2a6d..ec740447f93 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -101,17 +101,19 @@ static int bm_face_isect_pair_swap(BMFace *f, void *UNUSED(user_data))
/**
* Use for intersect and boolean.
*/
-static void edbm_intersect_select(BMEditMesh *em)
+static void edbm_intersect_select(BMEditMesh *em, bool do_select)
{
- BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+ if (do_select) {
+ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
- if (em->bm->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
- BMIter iter;
- BMEdge *e;
+ if (em->bm->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
+ BMIter iter;
+ BMEdge *e;
- BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
- BM_edge_select_set(em->bm, e, true);
+ BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ BM_edge_select_set(em->bm, e, true);
+ }
}
}
}
@@ -210,10 +212,9 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
em->bm, BM_elem_cb_check_hflag_enabled_simple(const BMFace *, BM_ELEM_SELECT));
}
- if (has_isect) {
- edbm_intersect_select(em);
- }
- else {
+ edbm_intersect_select(em, has_isect);
+
+ if (!has_isect) {
isect_len++;
}
}
@@ -317,10 +318,9 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
boolean_operation,
eps);
- if (has_isect) {
- edbm_intersect_select(em);
- }
- else {
+ edbm_intersect_select(em, has_isect);
+
+ if (!has_isect) {
isect_len++;
}
}
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 61f9dc43c0f..395c614f328 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2777,7 +2777,7 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
op->flag |= OP_IS_MODAL_CURSOR_REGION;
/* add a modal handler for this operator - handles loop selection */
- WM_cursor_modal_set(CTX_wm_window(C), BC_KNIFECURSOR);
+ WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_KNIFE);
WM_event_add_modal_handler(C, op);
knifetool_update_mval_i(kcd, event->mval);
@@ -2804,8 +2804,8 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{KNF_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
{KNF_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {KNF_MODAL_MIDPOINT_ON, "SNAP_MIDPOINTS_ON", 0, "Snap To Midpoints On", ""},
- {KNF_MODAL_MIDPOINT_OFF, "SNAP_MIDPOINTS_OFF", 0, "Snap To Midpoints Off", ""},
+ {KNF_MODAL_MIDPOINT_ON, "SNAP_MIDPOINTS_ON", 0, "Snap to Midpoints On", ""},
+ {KNF_MODAL_MIDPOINT_OFF, "SNAP_MIDPOINTS_OFF", 0, "Snap to Midpoints Off", ""},
{KNF_MODEL_IGNORE_SNAP_ON, "IGNORE_SNAP_ON", 0, "Ignore Snapping On", ""},
{KNF_MODEL_IGNORE_SNAP_OFF, "IGNORE_SNAP_OFF", 0, "Ignore Snapping Off", ""},
{KNF_MODAL_ANGLE_SNAP_TOGGLE, "ANGLE_SNAP_TOGGLE", 0, "Toggle Angle Snapping", ""},
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 3d34a4ad3b5..a709bd010aa 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -22,6 +22,7 @@
*/
#include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BLI_math.h"
@@ -142,10 +143,21 @@ static int knifeproject_exec(bContext *C, wmOperator *op)
/* select only tagged faces */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
- /* not essential, but switch out of vertex mode since the
- * selected regions wont be nicely isolated after flushing.
- * note: call after de-select to avoid selection flushing */
- EDBM_selectmode_disable(scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
+ if (ob->type == OB_MESH) {
+ Mesh *me = (Mesh *)ob->data;
+ BMEditMesh *embm = me->edit_mesh;
+ if (embm) {
+ /* not essential, but switch out of vertex mode since the
+ * selected regions wont be nicely isolated after flushing.
+ * note: call after de-select to avoid selection flushing.
+ * note: do this on all participating meshes so this is in sync
+ * e.g. for later selection picking, see T68852.*/
+ EDBM_selectmode_disable(scene, embm, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
+ }
+ }
+ }
+ CTX_DATA_END;
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 3be94cf99c1..3c3e91e8afe 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -386,7 +386,6 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
bool ok = true;
if (is_interactive == false) {
if (exec_data.base_index >= bases_len) {
- return OPERATOR_CANCELLED;
ok = false;
}
else {
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 6d51e1d3393..8d98a3bf231 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -101,16 +101,21 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op)
BMIter face_iter;
/* Delete all unmasked faces */
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+ BLI_assert(cd_vert_mask_offset != -1);
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
float mask_threshold = RNA_float_get(op->ptr, "mask_threshold");
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- bool delete_face = false;
+ bool keep_face = true;
BM_ITER_ELEM (v, &face_iter, f, BM_VERTS_OF_FACE) {
- float mask = BM_elem_float_data_get(&bm->vdata, v, CD_PAINT_MASK);
- delete_face = mask < mask_threshold;
+ const float mask = BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
+ if (mask < mask_threshold) {
+ keep_face = false;
+ break;
+ }
}
- BM_elem_flag_set(f, BM_ELEM_TAG, delete_face);
+ BM_elem_flag_set(f, BM_ELEM_TAG, !keep_face);
}
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
@@ -173,15 +178,16 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op)
}
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
- BKE_editmesh_free_derivedmesh(em);
BKE_mesh_free(new_mesh);
new_mesh = BKE_mesh_from_bmesh_nomain(bm,
(&(struct BMeshToMeshParams){
.calc_object_remap = false,
- }));
+ }),
+ mesh);
- BM_mesh_free(bm);
+ BKE_editmesh_free(em);
+ MEM_freeN(em);
if (new_mesh->totvert == 0) {
BKE_mesh_free(new_mesh);
@@ -195,8 +201,6 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op)
Object *new_ob = ED_object_add_type(C, OB_MESH, NULL, ob->loc, ob->rot, false, local_view_bits);
BKE_mesh_nomain_to_mesh(new_mesh, new_ob->data, new_ob, &CD_MASK_EVERYTHING, true);
- BKE_mesh_free(new_mesh);
-
if (RNA_boolean_get(op->ptr, "apply_shrinkwrap")) {
BKE_shrinkwrap_mesh_nearest_surface_deform(C, new_ob, ob);
}
@@ -211,6 +215,8 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op)
}
}
+ BKE_mesh_calc_normals(new_ob->data);
+
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob);
BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL);
DEG_relations_tag_update(bmain);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index cad9e9a3d06..3e59a884696 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2642,8 +2642,9 @@ bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len)
bool EDBM_mesh_deselect_all_multi(struct bContext *C)
{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc);
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
vc.view_layer, vc.v3d, &bases_len);
@@ -4219,7 +4220,8 @@ void MESH_OT_select_nth(wmOperatorType *ot)
void em_setup_viewcontext(bContext *C, ViewContext *vc)
{
- ED_view3d_viewcontext_init(C, vc);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ED_view3d_viewcontext_init(C, vc, depsgraph);
if (vc->obedit) {
vc->em = BKE_editmesh_from_object(vc->obedit);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 0c4db012786..a20ae5fc1ac 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -3161,7 +3161,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
}
MEM_freeN(objects);
- BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count_multi);
+ BKE_reportf(op->reports, RPT_INFO, "Removed %d vertice(s)", count_multi);
return OPERATOR_FINISHED;
}
@@ -3872,7 +3872,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
/* internal */
RNA_def_int(
- ot->srna, "cursor", BC_KNIFECURSOR, 0, BC_NUMCURSORS, "Cursor", "", 0, BC_NUMCURSORS);
+ ot->srna, "cursor", WM_CURSOR_KNIFE, 0, WM_CURSOR_NUM, "Cursor", "", 0, WM_CURSOR_NUM);
}
/** \} */
@@ -3946,6 +3946,61 @@ static Base *mesh_separate_tagged(
return base_new;
}
+static Base *mesh_separate_arrays(Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ Base *base_old,
+ BMesh *bm_old,
+ BMVert **verts,
+ uint verts_len,
+ BMEdge **edges,
+ uint edges_len,
+ BMFace **faces,
+ uint faces_len)
+{
+ Base *base_new;
+ Object *obedit = base_old->object;
+ BMesh *bm_new;
+
+ bm_new = BM_mesh_create(&bm_mesh_allocsize_default,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+
+ CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
+ CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
+ CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
+ CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
+
+ CustomData_bmesh_init_pool(&bm_new->vdata, verts_len, BM_VERT);
+ CustomData_bmesh_init_pool(&bm_new->edata, edges_len, BM_EDGE);
+ CustomData_bmesh_init_pool(&bm_new->ldata, faces_len * 3, BM_LOOP);
+ CustomData_bmesh_init_pool(&bm_new->pdata, faces_len, BM_FACE);
+
+ base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, USER_DUP_MESH);
+
+ /* normally would call directly after but in this case delay recalc */
+ /* DAG_relations_tag_update(bmain); */
+
+ /* new in 2.5 */
+ assign_matarar(bmain, base_new->object, give_matarar(obedit), *give_totcolp(obedit));
+
+ ED_object_base_select(base_new, BA_SELECT);
+
+ BM_mesh_copy_arrays(bm_old, bm_new, verts, verts_len, edges, edges_len, faces, faces_len);
+
+ for (uint i = 0; i < verts_len; i++) {
+ BM_vert_kill(bm_old, verts[i]);
+ }
+
+ BM_mesh_bm_to_me(bmain, bm_new, base_new->object->data, (&(struct BMeshToMeshParams){0}));
+
+ BM_mesh_free(bm_new);
+ ((Mesh *)base_new->object->data)->edit_mesh = NULL;
+
+ return base_new;
+}
+
static bool mesh_separate_selected(
Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_old, BMesh *bm_old)
{
@@ -3959,41 +4014,6 @@ static bool mesh_separate_selected(
return (mesh_separate_tagged(bmain, scene, view_layer, base_old, bm_old) != NULL);
}
-/* 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;
-
- bool 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);
- }
-}
-
/**
* Sets an object to a single material. from one of its slots.
*
@@ -4109,72 +4129,64 @@ static bool mesh_separate_material(
static bool mesh_separate_loose(
Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_old, BMesh *bm_old)
{
- int i;
- BMEdge *e;
- BMVert *v_seed;
- BMWalker walker;
- bool result = false;
- int max_iter = bm_old->totvert;
+ /* Without this, we duplicate the object mode mesh for each loose part.
+ * This can get very slow especially for large meshes with many parts
+ * which would duplicate the mesh on entering edit-mode. */
+ const bool clear_object_data = true;
- /* Clear all selected vertices */
- BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+ bool result = false;
- /* A "while (true)" loop should work here as each iteration should
- * select and remove at least one vertex and when all vertices
- * are selected the loop will break out. But guard against bad
- * 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_old, BM_VERTS_OF_MESH, NULL, 0);
+ BMVert **vert_groups = MEM_mallocN(sizeof(*vert_groups) * bm_old->totvert, __func__);
+ BMEdge **edge_groups = MEM_mallocN(sizeof(*edge_groups) * bm_old->totedge, __func__);
+ BMFace **face_groups = MEM_mallocN(sizeof(*face_groups) * bm_old->totface, __func__);
+
+ int(*groups)[3] = NULL;
+ int groups_len = BM_mesh_calc_edge_groups_as_arrays(
+ bm_old, vert_groups, edge_groups, face_groups, &groups);
+ if (groups_len <= 1) {
+ goto finally;
+ }
+
+ if (clear_object_data) {
+ ED_mesh_geometry_clear(base_old->object->data);
+ }
+
+ /* Separate out all groups except the first. */
+ uint group_ofs[3] = {UNPACK3(groups[0])};
+ for (int i = 1; i < groups_len; i++) {
+ Base *base_new = mesh_separate_arrays(bmain,
+ scene,
+ view_layer,
+ base_old,
+ bm_old,
+ vert_groups + group_ofs[0],
+ groups[i][0],
+ edge_groups + group_ofs[1],
+ groups[i][1],
+ face_groups + group_ofs[2],
+ groups[i][2]);
+ result |= (base_new != NULL);
- /* No vertices available, can't do anything */
- if (v_seed == NULL) {
- break;
- }
+ group_ofs[0] += groups[i][0];
+ group_ofs[1] += groups[i][1];
+ group_ofs[2] += groups[i][2];
+ }
- /* Select the seed explicitly, in case it has no edges */
- if (!BM_elem_flag_test(v_seed, BM_ELEM_TAG)) {
- BM_elem_flag_enable(v_seed, BM_ELEM_TAG);
- tot++;
- }
+ Mesh *me_old = base_old->object->data;
+ BMEditMesh *em_old = me_old->edit_mesh;
- /* Walk from the single vertex, selecting everything connected
- * to it */
- BMW_init(&walker,
- bm_old,
- BMW_VERT_SHELL,
- BMW_MASK_NOP,
- BMW_MASK_NOP,
- BMW_MASK_NOP,
- BMW_FLAG_NOP,
- BMW_NIL_LAY);
+ BM_mesh_elem_hflag_disable_all(em_old->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
- for (e = BMW_begin(&walker, v_seed); e; e = BMW_step(&walker)) {
- 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);
-
- if (bm_old->totvert == tot) {
- /* Every vertex selected, nothing to separate, work is done */
- break;
- }
+ if (clear_object_data) {
+ BM_mesh_bm_to_me(NULL, em_old->bm, me_old, (&(struct BMeshToMeshParams){0}));
+ }
- /* Flush the selection to get edge/face selections matching
- * the vertex selection */
- bm_mesh_hflag_flush_vert(bm_old, BM_ELEM_TAG);
+finally:
+ MEM_freeN(vert_groups);
+ MEM_freeN(edge_groups);
+ MEM_freeN(face_groups);
- /* Move selection into a separate object */
- result |= (mesh_separate_tagged(bmain, scene, view_layer, base_old, bm_old) != NULL);
- }
+ MEM_freeN(groups);
return result;
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 569994bead1..7007ff29401 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -880,14 +880,14 @@ void MESH_OT_customdata_custom_splitnormals_clear(wmOperatorType *ot)
void ED_mesh_update(Mesh *mesh, bContext *C, bool calc_edges, bool calc_edges_loose)
{
- if (calc_edges_loose && mesh->totedge) {
- BKE_mesh_calc_edges_loose(mesh);
- }
-
if (calc_edges || ((mesh->totpoly || mesh->totface) && mesh->totedge == 0)) {
BKE_mesh_calc_edges(mesh, calc_edges, true);
}
+ if (calc_edges_loose && mesh->totedge) {
+ BKE_mesh_calc_edges_loose(mesh);
+ }
+
/* Default state is not to have tessface's so make sure this is the case. */
BKE_mesh_tessface_clear(mesh);
@@ -1023,73 +1023,104 @@ static void mesh_add_polys(Mesh *mesh, int len)
mesh->totpoly = totpoly;
}
-static void mesh_remove_verts(Mesh *mesh, int len)
+/* -------------------------------------------------------------------- */
+/** \name Add Geometry
+ * \{ */
+
+void ED_mesh_verts_add(Mesh *mesh, ReportList *reports, int count)
{
- int totvert;
+ if (mesh->edit_mesh) {
+ BKE_report(reports, RPT_ERROR, "Cannot add vertices in edit mode");
+ return;
+ }
+ mesh_add_verts(mesh, count);
+}
- if (len == 0) {
+void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
+{
+ if (mesh->edit_mesh) {
+ BKE_report(reports, RPT_ERROR, "Cannot add edges in edit mode");
+ return;
+ }
+ mesh_add_edges(mesh, count);
+}
+
+void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count)
+{
+ if (mesh->edit_mesh) {
+ BKE_report(reports, RPT_ERROR, "Cannot add loops in edit mode");
return;
}
+ mesh_add_loops(mesh, count);
+}
- totvert = mesh->totvert - len;
- CustomData_free_elem(&mesh->vdata, totvert, len);
+void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count)
+{
+ if (mesh->edit_mesh) {
+ BKE_report(reports, RPT_ERROR, "Cannot add polygons in edit mode");
+ return;
+ }
+ mesh_add_polys(mesh, count);
+}
- /* set final vertex list size */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Remove Geometry
+ * \{ */
+
+static void mesh_remove_verts(Mesh *mesh, int len)
+{
+ if (len == 0) {
+ return;
+ }
+ const int totvert = mesh->totvert - len;
+ CustomData_free_elem(&mesh->vdata, totvert, len);
mesh->totvert = totvert;
}
static void mesh_remove_edges(Mesh *mesh, int len)
{
- int totedge;
-
if (len == 0) {
return;
}
-
- totedge = mesh->totedge - len;
+ const int totedge = mesh->totedge - len;
CustomData_free_elem(&mesh->edata, totedge, len);
-
mesh->totedge = totedge;
}
-#if 0
-void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
+static void mesh_remove_loops(Mesh *mesh, int len)
{
- if (mesh->edit_mesh) {
- BKE_report(reports, RPT_ERROR, "Cannot add geometry in edit mode");
+ if (len == 0) {
return;
}
-
- if (verts) {
- mesh_add_verts(mesh, verts);
- }
- if (edges) {
- mesh_add_edges(mesh, edges);
- }
- if (faces) {
- mesh_add_faces(mesh, faces);
- }
+ const int totloop = mesh->totloop - len;
+ CustomData_free_elem(&mesh->ldata, totloop, len);
+ mesh->totloop = totloop;
}
-#endif
-void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
+static void mesh_remove_polys(Mesh *mesh, int len)
{
- if (mesh->edit_mesh) {
- BKE_report(reports, RPT_ERROR, "Cannot add edges in edit mode");
+ if (len == 0) {
return;
}
-
- mesh_add_edges(mesh, count);
+ const int totpoly = mesh->totpoly - len;
+ CustomData_free_elem(&mesh->pdata, totpoly, len);
+ mesh->totpoly = totpoly;
}
-void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
+void ED_mesh_verts_remove(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_mesh) {
- BKE_report(reports, RPT_ERROR, "Cannot add vertices in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode");
+ return;
+ }
+ else if (count > mesh->totvert) {
+ BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains");
return;
}
- mesh_add_verts(mesh, count);
+ mesh_remove_verts(mesh, count);
}
void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count)
@@ -1106,40 +1137,44 @@ void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count)
mesh_remove_edges(mesh, count);
}
-void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count)
+void ED_mesh_loops_remove(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_mesh) {
- BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot remove loops in edit mode");
return;
}
- else if (count > mesh->totvert) {
- BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains");
+ else if (count > mesh->totloop) {
+ BKE_report(reports, RPT_ERROR, "Cannot remove more loops than the mesh contains");
return;
}
- mesh_remove_verts(mesh, count);
+ mesh_remove_loops(mesh, count);
}
-void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count)
+void ED_mesh_polys_remove(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_mesh) {
- BKE_report(reports, RPT_ERROR, "Cannot add loops in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot remove polys in edit mode");
+ return;
+ }
+ else if (count > mesh->totpoly) {
+ BKE_report(reports, RPT_ERROR, "Cannot remove more polys than the mesh contains");
return;
}
- mesh_add_loops(mesh, count);
+ mesh_remove_polys(mesh, count);
}
-void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count)
+void ED_mesh_geometry_clear(Mesh *mesh)
{
- if (mesh->edit_mesh) {
- BKE_report(reports, RPT_ERROR, "Cannot add polygons in edit mode");
- return;
- }
-
- mesh_add_polys(mesh, count);
+ mesh_remove_verts(mesh, mesh->totvert);
+ mesh_remove_edges(mesh, mesh->totedge);
+ mesh_remove_loops(mesh, mesh->totloop);
+ mesh_remove_polys(mesh, mesh->totpoly);
}
+/** \} */
+
void ED_mesh_report_mirror_ex(wmOperator *op, int totmirr, int totfail, char selectmode)
{
const char *elem_type;
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index c68f5963cbd..a918996563f 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -54,6 +54,7 @@
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
+#include "BKE_object_facemap.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -267,6 +268,22 @@ static void join_mesh_single(Depsgraph *depsgraph,
mpoly->loopstart += *loopofs;
mpoly->mat_nr = matmap ? matmap[mpoly->mat_nr] : 0;
}
+
+ /* Face maps. */
+ int *fmap = CustomData_get(pdata, *polyofs, CD_FACEMAP);
+ int *fmap_src = CustomData_get(&me->pdata, 0, CD_FACEMAP);
+
+ /* Remap to correct new face-map indices, if needed. */
+ if (fmap_src) {
+ BLI_assert(fmap != NULL);
+ int *fmap_index_map;
+ int fmap_index_map_len;
+ fmap_index_map = BKE_object_facemap_index_map_create(ob_src, ob_dst, &fmap_index_map_len);
+ BKE_object_facemap_index_map_apply(fmap, me->totpoly, fmap_index_map, fmap_index_map_len);
+ if (fmap_index_map != NULL) {
+ MEM_freeN(fmap_index_map);
+ }
+ }
}
/* these are used for relinking (cannot be set earlier, or else reattaching goes wrong) */
@@ -403,7 +420,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
key->type = KEY_RELATIVE;
}
- /* first pass over objects - copying materials and vertexgroups across */
+ /* First pass over objects: Copying materials, vertex-groups & face-maps across. */
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
/* only act if a mesh, and not the one we're joining to */
if ((ob != ob_iter) && (ob_iter->type == OB_MESH)) {
@@ -422,6 +439,19 @@ int join_mesh_exec(bContext *C, wmOperator *op)
ob->actdef = 1;
}
+ /* Join this object's face maps to the base one's. */
+ for (bFaceMap *fmap = ob_iter->fmaps.first; fmap; fmap = fmap->next) {
+ /* See if this group exists in the object (if it doesn't, add it to the end) */
+ if (BKE_object_facemap_find_name(ob, fmap->name) == NULL) {
+ bFaceMap *fmap_new = MEM_callocN(sizeof(bFaceMap), "join faceMap");
+ memcpy(fmap_new, fmap, sizeof(bFaceMap));
+ BLI_addtail(&ob->fmaps, fmap_new);
+ }
+ }
+ if (ob->fmaps.first && ob->actfmap == 0) {
+ ob->actfmap = 1;
+ }
+
if (me->totvert) {
/* Add this object's materials to the base one's if they don't exist already
* (but only if limits not exceeded yet) */
@@ -1110,7 +1140,8 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px,
return false;
}
- ED_view3d_viewcontext_init(C, &vc);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
ED_view3d_select_id_validate(&vc);
if (dist_px) {
@@ -1291,7 +1322,8 @@ bool ED_mesh_pick_vert(
return false;
}
- ED_view3d_viewcontext_init(C, &vc);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
ED_view3d_select_id_validate(&vc);
if (use_zbuf) {