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')
-rw-r--r--source/blender/editors/mesh/editface.c4
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c8
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c10
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c5
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c2
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c4
-rw-r--r--source/blender/editors/mesh/editmesh_path.c1
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c4
-rw-r--r--source/blender/editors/mesh/editmesh_select.c11
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c15
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c57
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c17
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c202
-rw-r--r--source/blender/editors/mesh/mesh_data.c7
-rw-r--r--source/blender/editors/mesh/mesh_mirror.c5
-rw-r--r--source/blender/editors/mesh/meshtools.c33
18 files changed, 195 insertions, 202 deletions
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index b7ee50a9461..648008a4779 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -65,7 +65,7 @@ void paintface_flush_flags(struct bContext *C, Object *ob, short flag)
return;
}
- /* note, call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags */
+ /* NOTE: call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags. */
/* we could call this directly in all areas that change selection,
* since this could become slow for realtime updates (circle-select for eg) */
@@ -433,7 +433,7 @@ bool paintface_mouse_select(
/* image window redraw */
paintface_flush_flags(C, ob, SELECT);
- ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
+ ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
return true;
}
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 110f1975d8d..01736f2919a 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -279,7 +279,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
for (int i = 0; i < NUM_VALUE_KINDS; i++) {
opdata->shift_value[i] = -1.0f;
opdata->initial_length[i] = -1.0f;
- /* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
+ /* NOTE: scale for #OFFSET_VALUE will get overwritten in #edbm_bevel_invoke. */
opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
initNumInput(&opdata->num_input[i]);
@@ -347,7 +347,7 @@ static bool edbm_bevel_calc(wmOperator *op)
/* revert to original mesh */
if (opdata->is_modal) {
- EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false);
+ EDBM_redo_state_restore(&opdata->ob_store[ob_index].mesh_backup, em, false);
}
const int material = CLAMPIS(material_init, -1, obedit->totcol - 1);
@@ -436,7 +436,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, NULL, false);
+ EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
}
ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel);
if (v3d) {
@@ -456,7 +456,7 @@ static void edbm_bevel_cancel(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
Object *obedit = opdata->ob_store[ob_index].ob;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
+ EDBM_redo_state_restore_and_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
EDBM_update(obedit->data,
&(const struct EDBMUpdate_Params){
.calc_looptri = false,
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index 42cf36dda81..3c8afe8e7db 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -67,7 +67,7 @@ typedef struct {
/* Aligned with objects array. */
struct {
- BMBackup mesh;
+ BMBackup mesh_backup;
bool is_valid;
bool is_dirty;
} * backup;
@@ -160,7 +160,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (em->bm->totedgesel != 0) {
opdata->backup[ob_index].is_valid = true;
- opdata->backup[ob_index].mesh = EDBM_redo_state_store(em);
+ opdata->backup[ob_index].mesh_backup = EDBM_redo_state_store(em);
}
}
@@ -184,7 +184,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata)
for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) {
if (opdata->backup[ob_index].is_valid) {
- EDBM_redo_state_free(&opdata->backup[ob_index].mesh, NULL, false);
+ EDBM_redo_state_free(&opdata->backup[ob_index].mesh_backup);
}
}
MEM_freeN(opdata->backup);
@@ -280,7 +280,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
/* -------------------------------------------------------------------- */
/* Modal support */
- /* Note: keep this isolated, exec can work without this */
+ /* NOTE: keep this isolated, exec can work without this. */
if (opdata != NULL) {
mesh_bisect_interactive_calc(C, op, plane_co, plane_no);
/* Write back to the props. */
@@ -301,7 +301,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
if (opdata != NULL) {
if (opdata->backup[ob_index].is_dirty) {
- EDBM_redo_state_restore(opdata->backup[ob_index].mesh, em, false);
+ EDBM_redo_state_restore(&opdata->backup[ob_index].mesh_backup, em, false);
opdata->backup[ob_index].is_dirty = false;
}
}
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 1c27ab00715..18f51ae9df2 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -209,7 +209,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, NULL, false);
+ EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
}
ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel);
if (v3d) {
@@ -235,7 +235,7 @@ static void edbm_inset_cancel(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
Object *obedit = opdata->ob_store[ob_index].ob;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
+ EDBM_redo_state_restore_and_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
EDBM_update(obedit->data,
&(const struct EDBMUpdate_Params){
.calc_looptri = false,
@@ -276,7 +276,7 @@ static bool edbm_inset_calc(wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (opdata->is_modal) {
- EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false);
+ EDBM_redo_state_restore(&opdata->ob_store[ob_index].mesh_backup, em, false);
}
if (use_individual) {
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 0e2dd492e06..73f6a3f3238 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -157,7 +157,7 @@ typedef struct KnifePosData {
typedef struct KnifeTool_OpData {
ARegion *region; /* region that knifetool was activated in */
void *draw_handle; /* for drawing preview loop */
- ViewContext vc; /* note: _don't_ use 'mval', instead use the one we define below */
+ ViewContext vc; /* NOTE: _don't_ use 'mval', instead use the one we define below. */
float mval[2]; /* mouse value with snapping applied */
// bContext *C;
@@ -1475,7 +1475,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
}
}
- /* Note: as following loop progresses, the 'v' fields of
+ /* NOTE: as following loop progresses, the 'v' fields of
* the linehits will be filled in (as edges are split or
* in-face verts are made), so it may be true that both
* the v and the kfe or f fields will be non-NULL. */
@@ -1760,7 +1760,7 @@ static bool point_is_visible(KnifeTool_OpData *kcd,
if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
float view_clip[2][3];
- /* note: view_clip[0] should never get clipped */
+ /* NOTE: view_clip[0] should never get clipped. */
copy_v3_v3(view_clip[0], p_ofs);
madd_v3_v3v3fl(view_clip[1], p_ofs, view, dist);
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index aa144dd3f3c..09b17acf56d 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -30,6 +30,7 @@
#include "BKE_context.h"
#include "BKE_curve.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
@@ -59,7 +60,7 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ARegion *region = CTX_wm_region(C);
- struct Mesh *me_eval;
+ const struct Mesh *me_eval;
bool me_eval_needs_free;
if (ob->type == OB_MESH || ob->runtime.data_eval) {
@@ -113,7 +114,7 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
BKE_nurbList_free(&nurbslist);
if (me_eval_needs_free) {
- BKE_mesh_free(me_eval);
+ BKE_mesh_free((struct Mesh *)me_eval);
}
}
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 71319338a53..0a4fecde6ea 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -241,7 +241,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
* in editmesh_select.c (around line 1000)... */
/* sets as active, useful for other tools */
if (em->selectmode & SCE_SELECT_VERTEX) {
- /* low priority TODO, get vertrex close to mouse */
+ /* low priority TODO: get vertrex close to mouse. */
BM_select_history_store(em->bm, lcd->eed->v1);
}
if (em->selectmode & SCE_SELECT_EDGE) {
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 993905462db..cccfc7e934c 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -126,7 +126,7 @@ static int geometry_extract_apply(bContext *C,
.calc_face_normal = true,
}));
- BMEditMesh *em = BKE_editmesh_create(bm, false);
+ BMEditMesh *em = BKE_editmesh_create(bm);
/* Generate the tags for deleting geometry in the extracted object. */
tag_fn(bm, params);
@@ -206,7 +206,7 @@ static int geometry_extract_apply(bContext *C,
}),
mesh);
- BKE_editmesh_free(em);
+ BKE_editmesh_free_data(em);
MEM_freeN(em);
if (new_mesh->totvert == 0) {
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 593545ddcef..30a453a32ee 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -29,6 +29,7 @@
#include "DNA_windowmanager_types.h"
#ifdef WITH_FREESTYLE
+# include "BKE_customdata.h"
# include "DNA_meshdata_types.h"
#endif
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 8626520ec37..5a2a090b725 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -927,7 +927,7 @@ static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obed
/* single edge, extend */
if (i == 1 && e_best->l) {
- /* note: if the case of 3 edges has one change in loop stepping,
+ /* NOTE: if the case of 3 edges has one change in loop stepping,
* if this becomes more involved we may be better off splitting
* the 3 edge case into its own else-if branch */
if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == false)) {
@@ -975,7 +975,7 @@ static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obed
BM_mesh_edgesplit(em->bm, true, true, true);
- /* note: the output of the bmesh operator is ignored, since we built
+ /* NOTE: the output of the bmesh operator is ignored, since we built
* the contiguous loop pairs to split already, its possible that some
* edge did not split even though it was tagged which would not work
* as expected (but not crash), however there are checks to ensure
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index d8973e100bc..830c9abb41e 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -35,6 +35,8 @@
#include "BLI_utildefines_stack.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_report.h"
@@ -434,7 +436,7 @@ struct NearestEdgeUserData {
struct NearestEdgeUserData_Hit hit_cycle;
};
-/* note; uses v3d, so needs active 3d window */
+/* NOTE: uses v3d, so needs active 3d window. */
static void find_nearest_edge__doClosest(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
@@ -964,7 +966,7 @@ static bool unified_findnearest(ViewContext *vc,
}
}
- /* return only one of 3 pointers, for frontbuffer redraws */
+ /* Return only one of 3 pointers, for front-buffer redraws. */
if (hit.v.ele) {
hit.f.ele = NULL;
hit.e.ele = NULL;
@@ -3446,7 +3448,7 @@ static void edbm_select_linked_pick_ex(BMEditMesh *em, BMElem *ele, bool sel, in
select_linked_delimit_begin(bm, delimit);
}
- /* Note: logic closely matches 'edbm_select_linked_exec', keep in sync */
+ /* NOTE: logic closely matches #edbm_select_linked_exec, keep in sync. */
if (ele->head.htype == BM_VERT) {
BMVert *eve = (BMVert *)ele;
@@ -4739,10 +4741,11 @@ static bool edbm_select_ungrouped_poll(bContext *C)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+ const ListBase *defbase = BKE_object_defgroup_list(obedit);
if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
CTX_wm_operator_poll_msg_set(C, "Must be in vertex selection mode");
}
- else if (BLI_listbase_is_empty(&obedit->defbase) || cd_dvert_offset == -1) {
+ else if (BLI_listbase_is_empty(defbase) || cd_dvert_offset == -1) {
CTX_wm_operator_poll_msg_set(C, "No weights/vertex groups on object");
}
else {
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index 2ffeaa06751..c452f7a7487 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -29,6 +29,8 @@
#include "BLI_math.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_material.h"
@@ -559,7 +561,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
* \{ */
/**
- * Note: This is not normal, but the edge direction itself and always in
+ * NOTE: This is not normal, but the edge direction itself and always in
* a positive quadrant (tries z, y then x).
* Therefore we need to use the entire object transformation matrix.
*/
@@ -1041,7 +1043,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (cd_dvert_offset == -1) {
continue;
}
- defbase_len = BLI_listbase_count(&ob->defbase);
+ defbase_len = BKE_object_defgroup_count(ob);
if (defbase_len == 0) {
continue;
}
@@ -1090,8 +1092,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
/* We store the names of the vertex groups, so we can select
* vertex groups with the same name in different objects. */
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+
int i = 0;
- LISTBASE_FOREACH (bDeformGroup *, dg, &ob->defbase) {
+ LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
if (BLI_BITMAP_TEST(defbase_selected, i)) {
BLI_gset_add(gset, dg->name);
}
@@ -1128,7 +1132,8 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (cd_dvert_offset == -1) {
continue;
}
- defbase_len = BLI_listbase_count(&ob->defbase);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ defbase_len = BLI_listbase_count(defbase);
if (defbase_len == 0) {
continue;
}
@@ -1141,7 +1146,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
GSetIterator gs_iter;
GSET_ITER (gs_iter, gset) {
const char *name = BLI_gsetIterator_getKey(&gs_iter);
- int vgroup_id = BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name));
+ int vgroup_id = BLI_findstringindex(defbase, name, offsetof(bDeformGroup, name));
if (vgroup_id != -1) {
BLI_BITMAP_ENABLE(defbase_selected, vgroup_id);
found_any = true;
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index fe9656d277e..41a9f426798 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -44,6 +44,7 @@
#include "BLI_string.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_key.h"
@@ -145,7 +146,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-/* Note, these values must match delete_mesh() event values */
+/* NOTE: these values must match delete_mesh() event values. */
static const EnumPropertyItem prop_mesh_cornervert_types[] = {
{SUBD_CORNER_INNERVERT, "INNERVERT", 0, "Inner Vert", ""},
{SUBD_CORNER_PATH, "PATH", 0, "Path", ""},
@@ -245,7 +246,7 @@ static void mesh_operator_edgering_props(wmOperatorType *ot,
const int cuts_min,
const int cuts_default)
{
- /* Note, these values must match delete_mesh() event values */
+ /* NOTE: these values must match delete_mesh() event values. */
static const EnumPropertyItem prop_subd_edgering_types[] = {
{SUBD_RING_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
{SUBD_RING_INTERP_PATH, "PATH", 0, "Blend Path", ""},
@@ -431,7 +432,7 @@ void MESH_OT_unsubdivide(wmOperatorType *ot)
/** \name Delete Operator
* \{ */
-/* Note, these values must match delete_mesh() event values */
+/* NOTE: these values must match delete_mesh() event values. */
enum {
MESH_DELETE_VERT = 0,
MESH_DELETE_EDGE = 1,
@@ -973,7 +974,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
#ifdef USE_FACE_CREATE_SEL_EXTEND
/* normally we would want to leave the new geometry selected,
* but being able to press F many times to add geometry is too useful! */
- if (ele_desel && (BMO_slot_buffer_count(bmop.slots_out, "faces.out") == 1) &&
+ if (ele_desel && (BMO_slot_buffer_len(bmop.slots_out, "faces.out") == 1) &&
(ele_desel_face = BMO_slot_buffer_get_first(bmop.slots_out, "faces.out"))) {
edbm_add_edge_face_exec__tricky_finalize_sel(em->bm, ele_desel, ele_desel_face);
}
@@ -1264,9 +1265,12 @@ static bool edbm_connect_vert_pair(BMEditMesh *em, struct Mesh *me, wmOperator *
}
}
if (checks_succeded) {
+ BMBackup em_backup = EDBM_redo_state_store(em);
+
BM_custom_loop_normals_to_vector_layer(bm);
BMO_op_exec(bm, &bmop);
+ const bool failure = BMO_error_occurred_at_level(bm, BMO_ERROR_FATAL);
len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
if (len && is_pair) {
@@ -1275,8 +1279,14 @@ static bool edbm_connect_vert_pair(BMEditMesh *em, struct Mesh *me, wmOperator *
em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
}
- if (!EDBM_op_finish(em, &bmop, op, true)) {
+ bool em_backup_free = true;
+ if (!EDBM_op_finish(em, &bmop, op, false)) {
+ len = 0;
+ }
+ else if (failure) {
len = 0;
+ EDBM_redo_state_restore_and_free(&em_backup, em, true);
+ em_backup_free = false;
}
else {
/* so newly created edges get the selection state from the vertex */
@@ -1291,6 +1301,10 @@ static bool edbm_connect_vert_pair(BMEditMesh *em, struct Mesh *me, wmOperator *
.is_destructive = true,
});
}
+
+ if (em_backup_free) {
+ EDBM_redo_state_free(&em_backup);
+ }
}
MEM_freeN(verts);
@@ -2331,7 +2345,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
BMO_slot_buffer_hflag_enable(
em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
- const int tot_rotate = BMO_slot_buffer_count(bmop.slots_out, "edges.out");
+ const int tot_rotate = BMO_slot_buffer_len(bmop.slots_out, "edges.out");
const int tot_failed = tot - tot_rotate;
tot_rotate_all += tot_rotate;
@@ -3012,10 +3026,8 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "rotate_uvs faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
if (!EDBM_op_finish(em, &bmop, op, true)) {
@@ -3050,13 +3062,10 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "reverse_uvs faces=%hf", BM_ELEM_SELECT);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
- /* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
@@ -3091,13 +3100,10 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "rotate_colors faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
- /* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
@@ -3133,15 +3139,12 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "reverse_colors faces=%hf", BM_ELEM_SELECT);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
- /* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, true)) {
- return OPERATOR_CANCELLED;
+ continue;
}
EDBM_update(obedit->data,
@@ -4222,7 +4225,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
/* for ED_view3d_project_float_object */
ED_view3d_init_mats_rv3d(obedit, region->regiondata);
- /* TODO, investigate using index lookup for screen_vert_coords() rather than a hash table */
+ /* TODO: investigate using index lookup for #screen_vert_coords() rather than a hash table. */
/* the floating point coordinates of verts in screen space will be
* stored in a hash table according to the vertices pointer */
@@ -5737,7 +5740,7 @@ static int edbm_decimate_exec(bContext *C, wmOperator *op)
float *vweights = MEM_mallocN(sizeof(*vweights) * bm->totvert, __func__);
{
const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
- const int defbase_act = obedit->actdef - 1;
+ const int defbase_act = BKE_object_defgroup_active_index_get(obedit) - 1;
if (use_vertex_group && (cd_dvert_offset == -1)) {
BKE_report(op->reports, RPT_WARNING, "No active vertex group");
@@ -5874,7 +5877,7 @@ void MESH_OT_decimate(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* Note, keep in sync with 'rna_def_modifier_decimate' */
+ /* NOTE: keep in sync with 'rna_def_modifier_decimate'. */
RNA_def_float(ot->srna, "ratio", 1.0f, 0.0f, 1.0f, "Ratio", "", 0.0f, 1.0f);
RNA_def_boolean(ot->srna,
@@ -6558,7 +6561,7 @@ enum {
typedef struct BMElemSort {
/** Sort factor */
float srt;
- /** Original index of this element _in its mempool_ */
+ /** Original index of this element (in its #BLI_mempool). */
int org_idx;
} BMElemSort;
@@ -6751,7 +6754,7 @@ static void sort_bmelem_flag(bContext *C,
BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) {
if (BM_elem_flag_test(fa, flag)) {
/* Reverse materials' order, not order of faces inside each mat! */
- /* Note: cannot use totcol, as mat_nr may sometimes be greater... */
+ /* NOTE: cannot use totcol, as mat_nr may sometimes be greater... */
float srt = reverse ? (float)(MAXMAT - fa->mat_nr) : (float)fa->mat_nr;
pb[i] = false;
sb[affected[2]].org_idx = i;
@@ -7304,7 +7307,7 @@ static int edbm_bridge_edge_loops_for_single_editmesh(wmOperator *op,
BMO_op_exec(em->bm, &bmop);
- if (!BMO_error_occurred(em->bm)) {
+ if (!BMO_error_occurred_at_level(em->bm, BMO_ERROR_CANCEL)) {
/* when merge is used the edges are joined and remain selected */
if (use_merge == false) {
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
@@ -7670,7 +7673,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
BMO_op_exec(em->bm, &bmop);
/* Hull fails if input is coplanar */
- if (BMO_error_occurred(em->bm)) {
+ if (BMO_error_occurred_at_level(em->bm, BMO_ERROR_CANCEL)) {
EDBM_op_finish(em, &bmop, op, true);
continue;
}
@@ -8385,7 +8388,7 @@ static void point_normals_update_header(bContext *C, wmOperator *op)
ED_area_status_text(CTX_wm_area(C), header);
}
-/* TODO move that to generic function in BMesh? */
+/* TODO: move that to generic function in BMesh? */
static void bmesh_selected_verts_center_calc(BMesh *bm, float *r_center)
{
BMVert *v;
@@ -9691,7 +9694,7 @@ static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
BKE_lnor_space_custom_data_to_normal(
bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->clnors_data, current_normal);
- /* Note: again, this is not true spherical interpolation that normals would need...
+ /* NOTE: again, this is not true spherical interpolation that normals would need...
* But it's probably good enough for now. */
mul_v3_fl(current_normal, 1.0f - factor);
mul_v3_fl(smooth_normal[i], factor);
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 112de68b52c..fc9e1aa8b1a 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -33,6 +33,7 @@
#include "BLI_listbase.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_key.h"
#include "BKE_layer.h"
@@ -671,7 +672,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
em->bm->shapenr = um->shapenr;
- EDBM_mesh_free(em);
+ EDBM_mesh_free_data(em);
bm = BM_mesh_create(&allocsize,
&((struct BMeshCreateParams){
@@ -681,13 +682,21 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
BM_mesh_bm_from_me(bm,
&um->me,
(&(struct BMeshFromMeshParams){
- .calc_face_normal = true,
+ /* Handled with tessellation. */
+ .calc_face_normal = false,
.active_shapekey = um->shapenr,
}));
- em_tmp = BKE_editmesh_create(bm, true);
+ em_tmp = BKE_editmesh_create(bm);
*em = *em_tmp;
+ /* Calculate face normals and tessellation at once since it's multi-threaded.
+ * The vertex normals are stored in the undo-mesh, so this doesn't need to be updated. */
+ BKE_editmesh_looptri_calc_ex(em,
+ &(const struct BMeshCalcTessellation_Params){
+ .face_normals = true,
+ });
+
em->selectmode = um->selectmode;
bm->selectmode = um->selectmode;
@@ -865,7 +874,7 @@ static void mesh_undosys_step_decode(struct bContext *C,
BMEditMesh *em = me->edit_mesh;
undomesh_to_editmesh(&elem->data, obedit, em, me->key);
em->needs_flush_to_id = 1;
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
}
/* The first element is always active */
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 141b69f0465..85c646d689c 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -68,6 +68,9 @@
* just as the undo stack would.
* So leaving this as an interface for further work */
+/**
+ * Save a copy of the #BMesh for restoring later.
+ */
BMBackup EDBM_redo_state_store(BMEditMesh *em)
{
BMBackup backup;
@@ -75,42 +78,41 @@ BMBackup EDBM_redo_state_store(BMEditMesh *em)
return backup;
}
-void EDBM_redo_state_restore(BMBackup backup, BMEditMesh *em, int recalctess)
+void EDBM_redo_state_restore(BMBackup *backup, BMEditMesh *em, bool recalc_looptri)
{
BMesh *tmpbm;
- if (!em || !backup.bmcopy) {
- return;
- }
BM_mesh_data_free(em->bm);
- tmpbm = BM_mesh_copy(backup.bmcopy);
+ tmpbm = BM_mesh_copy(backup->bmcopy);
*em->bm = *tmpbm;
MEM_freeN(tmpbm);
tmpbm = NULL;
- if (recalctess) {
+ if (recalc_looptri) {
BKE_editmesh_looptri_calc(em);
}
}
-void EDBM_redo_state_free(BMBackup *backup, BMEditMesh *em, int recalctess)
+/**
+ * Delete the backup, flushing it to an edit-mesh.
+ */
+void EDBM_redo_state_restore_and_free(BMBackup *backup, BMEditMesh *em, bool recalc_looptri)
{
- if (em && backup->bmcopy) {
- BM_mesh_data_free(em->bm);
- *em->bm = *backup->bmcopy;
- }
- else if (backup->bmcopy) {
- BM_mesh_data_free(backup->bmcopy);
+ BM_mesh_data_free(em->bm);
+ *em->bm = *backup->bmcopy;
+ MEM_freeN(backup->bmcopy);
+ backup->bmcopy = NULL;
+ if (recalc_looptri) {
+ BKE_editmesh_looptri_calc(em);
}
+}
+void EDBM_redo_state_free(BMBackup *backup)
+{
if (backup->bmcopy) {
+ BM_mesh_data_free(backup->bmcopy);
MEM_freeN(backup->bmcopy);
}
- backup->bmcopy = NULL;
-
- if (recalctess && em) {
- BKE_editmesh_looptri_calc(em);
- }
}
/** \} */
@@ -132,75 +134,76 @@ bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
va_end(list);
return true;
}
-/* returns 0 on error, 1 on success. executes and finishes a bmesh operator */
+/**
+ * The return value:
+ * - False on error (the mesh must not be changed).
+ * - True 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;
+#ifndef NDEBUG
+ struct {
+ int verts_len, edges_len, loops_len, faces_len;
+ } em_state_prev = {
+ .verts_len = em->bm->totvert,
+ .edges_len = em->bm->totedge,
+ .loops_len = em->bm->totloop,
+ .faces_len = em->bm->totface,
+ };
+#endif
- if (do_report) {
- BKE_report(op->reports, RPT_ERROR, errmsg);
- }
+ BMO_op_finish(em->bm, bmop);
- EDBM_mesh_free(em);
- *em = *emcopy;
-
- MEM_freeN(emcopy);
- em->emcopyusers = 0;
- em->emcopy = NULL;
-
- /**
- * Note, we could pass in the mesh, however this is an exceptional case, allow a slow lookup.
- *
- * This is needed because the COW mesh makes a full copy of the #BMEditMesh
- * instead of sharing the pointer, tagging since this has been freed above,
- * the #BMEditMesh.emcopy needs to be flushed to the COW edit-mesh, see T55457.
- */
- {
- Main *bmain = G_MAIN;
- for (Mesh *mesh = bmain->meshes.first; mesh; mesh = mesh->id.next) {
- if (mesh->edit_mesh == em) {
- DEG_id_tag_update(&mesh->id, ID_RECALC_COPY_ON_WRITE);
- break;
- }
+ bool changed = false;
+ bool changed_was_set = false;
+
+ eBMOpErrorLevel level;
+ while (BMO_error_pop(em->bm, &errmsg, NULL, &level)) {
+ ReportType type = RPT_INFO;
+ switch (level) {
+ case BMO_ERROR_CANCEL: {
+ changed_was_set = true;
+ break;
+ }
+ case BMO_ERROR_WARN: {
+ type = RPT_WARNING;
+ changed_was_set = true;
+ changed = true;
+ break;
+ }
+ case BMO_ERROR_FATAL: {
+ type = RPT_ERROR;
+ changed_was_set = true;
+ changed = true;
+ break;
}
}
- /* when copying, tessellation isn't to for faster copying,
- * but means we need to re-tessellate here */
- if (em->looptris == NULL) {
- BKE_editmesh_looptri_calc(em);
+ if (do_report) {
+ BKE_report(op->reports, type, errmsg);
}
-
- return false;
}
-
- em->emcopyusers--;
- if (em->emcopyusers < 0) {
- printf("warning: em->emcopyusers was less than zero.\n");
+ if (changed_was_set == false) {
+ changed = true;
}
- if (em->emcopyusers <= 0) {
- BKE_editmesh_free(em->emcopy);
- MEM_freeN(em->emcopy);
- em->emcopy = NULL;
+#ifndef NDEBUG
+ if (changed == false) {
+ BLI_assert((em_state_prev.verts_len == em->bm->totvert) &&
+ (em_state_prev.edges_len == em->bm->totedge) &&
+ (em_state_prev.loops_len == em->bm->totloop) &&
+ (em_state_prev.faces_len == em->bm->totface));
}
+#endif
- return true;
+ return changed;
}
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
@@ -217,11 +220,6 @@ bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
BMO_op_exec(bm, &bmop);
va_end(list);
@@ -249,11 +247,6 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em,
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
BMO_op_exec(bm, &bmop);
slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out);
@@ -284,11 +277,6 @@ bool EDBM_op_call_silentf(BMEditMesh *em, const char *fmt, ...)
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
BMO_op_exec(bm, &bmop);
va_end(list);
@@ -317,17 +305,13 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
if (me->edit_mesh) {
/* this happens when switching shape keys */
- EDBM_mesh_free(me->edit_mesh);
+ EDBM_mesh_free_data(me->edit_mesh);
MEM_freeN(me->edit_mesh);
}
- /* currently executing operators re-tessellates, so we can avoid doing here
- * but at some point it may need to be added back. */
-#if 0
- me->edit_mesh = BKE_editmesh_create(bm, true);
-#else
- me->edit_mesh = BKE_editmesh_create(bm, false);
-#endif
+ /* Executing operators re-tessellates,
+ * so we can avoid doing here but at some point it may need to be added back. */
+ me->edit_mesh = BKE_editmesh_create(bm);
me->edit_mesh->selectmode = me->edit_mesh->bm->selectmode = select_mode;
me->edit_mesh->mat_nr = (ob->actcol > 0) ? ob->actcol - 1 : 0;
@@ -338,7 +322,8 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
/**
* \warning This can invalidate the #Mesh runtime cache of other objects (for linked duplicates).
- * Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913
+ * Most callers should run #DEG_id_tag_update on `ob->data`, see: T46738, T46913.
+ * This ensures #BKE_object_free_derived_caches runs on all objects that use this mesh.
*/
void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
{
@@ -358,25 +343,6 @@ void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
.calc_object_remap = true,
.update_shapekey_indices = !free_data,
}));
-
- /* Free derived mesh. usually this would happen through depsgraph but there
- * are exceptions like file save that will not cause this, and we want to
- * avoid ending up with an invalid derived mesh then.
- *
- * Do it for all objects which shares the same mesh datablock, since their
- * derived meshes might also be referencing data which was just freed,
- *
- * Annoying enough, but currently seems most efficient way to avoid access
- * of freed data on scene update, especially in cases when there are dependency
- * cycles.
- */
-#if 0
- for (Object *other_object = bmain->objects.first; other_object != NULL; other_object = other_object->id.next) {
- if (other_object->data == ob->data) {
- BKE_object_free_derived_caches(other_object);
- }
- }
-#endif
}
void EDBM_mesh_clear(BMEditMesh *em)
@@ -384,8 +350,8 @@ void EDBM_mesh_clear(BMEditMesh *em)
/* clear bmesh */
BM_mesh_clear(em->bm);
- /* free derived meshes */
- BKE_editmesh_free_derivedmesh(em);
+ /* Free evaluated meshes & cache. */
+ BKE_editmesh_free_derived_caches(em);
/* free tessellation data */
em->tottri = 0;
@@ -401,9 +367,9 @@ void EDBM_mesh_load(Main *bmain, Object *ob)
}
/**
- * Should only be called on the active editmesh, otherwise call #BKE_editmesh_free
+ * Should only be called on the active edit-mesh, otherwise call #BKE_editmesh_free_data.
*/
-void EDBM_mesh_free(BMEditMesh *em)
+void EDBM_mesh_free_data(BMEditMesh *em)
{
/* These tables aren't used yet, so it's not strictly necessary
* to 'end' them but if someone tries to start using them,
@@ -411,7 +377,7 @@ void EDBM_mesh_free(BMEditMesh *em)
ED_mesh_mirror_spatial_table_end(NULL);
ED_mesh_mirror_topo_table_end(NULL);
- BKE_editmesh_free(em);
+ BKE_editmesh_free_data(em);
}
/** \} */
@@ -1472,7 +1438,7 @@ void EDBM_update(Mesh *mesh, const struct EDBMUpdate_Params *params)
}
if (params->is_destructive) {
- /* TODO. we may be able to remove this now! - Campbell */
+ /* TODO(campbell): we may be able to remove this now! */
// BM_mesh_elem_table_free(em->bm, BM_ALL_NOLOOP);
}
else {
@@ -1483,8 +1449,8 @@ void EDBM_update(Mesh *mesh, const struct EDBMUpdate_Params *params)
BM_lnorspace_invalidate(em->bm, false);
em->bm->spacearr_dirty &= ~BM_SPACEARR_BMO_SET;
}
- /* don't keep stale derivedMesh data around, see: T38872. */
- BKE_editmesh_free_derivedmesh(em);
+ /* Don't keep stale evaluated mesh data around, see: T38872. */
+ BKE_editmesh_free_derived_caches(em);
#ifdef DEBUG
{
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 7c6dc6516ed..73b3fb9724e 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -34,6 +34,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
@@ -252,7 +253,7 @@ void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
-/* note: keep in sync with ED_mesh_color_add */
+/* NOTE: keep in sync with #ED_mesh_color_add. */
int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
{
BMEditMesh *em;
@@ -377,7 +378,7 @@ bool ED_mesh_uv_texture_remove_named(Mesh *me, const char *name)
return false;
}
-/* note: keep in sync with ED_mesh_uv_texture_add */
+/* NOTE: keep in sync with #ED_mesh_uv_texture_add. */
int ED_mesh_color_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
{
BMEditMesh *em;
@@ -483,7 +484,7 @@ bool ED_mesh_color_remove_named(Mesh *me, const char *name)
/*********************** Sculpt Vertex colors operators ************************/
-/* note: keep in sync with ED_mesh_uv_texture_add */
+/* NOTE: keep in sync with #ED_mesh_uv_texture_add. */
int ED_mesh_sculpt_color_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
{
BMEditMesh *em;
diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c
index 25d3eaf11d4..5eb69aab48b 100644
--- a/source/blender/editors/mesh/mesh_mirror.c
+++ b/source/blender/editors/mesh/mesh_mirror.c
@@ -308,8 +308,9 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
last = 0;
- /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2,
- * but you can't ever access the last 'a' index of MirrTopoPairs */
+ /* Get the pairs out of the sorted hashes.
+ * NOTE: `totvert + 1` means we can use the previous 2,
+ * but you can't ever access the last 'a' index of #MirrTopoPairs. */
if (em) {
BMVert **vtable = em->bm->vtable;
for (a = 1; a <= totvert; a++) {
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index f306612f295..27fb21e1dfb 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -390,7 +390,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* Apply parent transform if the active object's parent was joined to it.
- * Note: This doesn't apply recursive parenting. */
+ * NOTE: This doesn't apply recursive parenting. */
if (join_parent) {
ob->parent = NULL;
BKE_object_apply_mat4_ex(ob, ob->obmat, ob->parent, ob->parentinv, false);
@@ -475,16 +475,17 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me = ob_iter->data;
/* Join this object's vertex groups to the base one's */
- for (dg = ob_iter->defbase.first; dg; dg = dg->next) {
+ for (dg = me->vertex_group_names.first; dg; dg = dg->next) {
/* See if this group exists in the object (if it doesn't, add it to the end) */
if (!BKE_object_defgroup_find_name(ob, dg->name)) {
odg = MEM_mallocN(sizeof(bDeformGroup), "join deformGroup");
memcpy(odg, dg, sizeof(bDeformGroup));
- BLI_addtail(&ob->defbase, odg);
+ BLI_addtail(&mesh_active->vertex_group_names, odg);
}
}
- if (ob->defbase.first && ob->actdef == 0) {
- ob->actdef = 1;
+ if (!BLI_listbase_is_empty(&mesh_active->vertex_group_names) &&
+ me->vertex_group_active_index == 0) {
+ me->vertex_group_active_index = 1;
}
/* Join this object's face maps to the base one's. */
@@ -1060,7 +1061,7 @@ static float *editmesh_get_mirror_uv(
cent_vec[1] = face_cent[1];
}
- /* TODO - Optimize */
+ /* TODO: Optimize. */
{
BMIter iter;
BMFace *efa;
@@ -1473,19 +1474,21 @@ bool ED_mesh_pick_vert(
MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
{
- if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
+ if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH) {
Mesh *me = ob->data;
- BMesh *bm = me->edit_mesh->bm;
- const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
+ if (!BLI_listbase_is_empty(&me->vertex_group_names)) {
+ BMesh *bm = me->edit_mesh->bm;
+ const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
- if (cd_dvert_offset != -1) {
- BMVert *eve = BM_mesh_active_vert_get(bm);
+ if (cd_dvert_offset != -1) {
+ BMVert *eve = BM_mesh_active_vert_get(bm);
- if (eve) {
- if (r_eve) {
- *r_eve = eve;
+ if (eve) {
+ if (r_eve) {
+ *r_eve = eve;
+ }
+ return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
- return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
}
}