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/editmesh_extrude_spin_gizmo.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c41
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c46
-rw-r--r--source/blender/editors/mesh/editmesh_preselect_edgering.c28
-rw-r--r--source/blender/editors/mesh/editmesh_select.c28
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c262
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c4
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c5
-rw-r--r--source/blender/editors/mesh/mesh_data.c11
-rw-r--r--source/blender/editors/mesh/mesh_intern.h5
-rw-r--r--source/blender/editors/mesh/mesh_mirror.c5
11 files changed, 241 insertions, 198 deletions
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
index 38d530ba911..1af489b60ce 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
@@ -468,7 +468,9 @@ void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
gzgt->setup = gizmo_mesh_spin_init_setup;
- gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
+ /* This works well with right click selection but overrides left-mouse selection
+ * when clicking which is needed to create a full 360 degree revolution, see: T89912. */
+ // gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
gzgt->refresh = gizmo_mesh_spin_init_refresh;
gzgt->message_subscribe = gizmo_mesh_spin_init_message_subscribe;
gzgt->draw_prepare = gizmo_mesh_spin_init_draw_prepare;
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 73f6a3f3238..3e3593d18fd 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2630,24 +2630,24 @@ static void knife_init_colors(KnifeColors *colors)
}
/* called when modal loop selection gets set up... */
-static void knifetool_init(bContext *C,
+static void knifetool_init(ViewContext *vc,
KnifeTool_OpData *kcd,
const bool only_select,
const bool cut_through,
const bool is_interactive)
{
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
+ kcd->vc = *vc;
+
+ Scene *scene = vc->scene;
+ Object *obedit = vc->obedit;
/* assign the drawing handle for drawing preview line... */
kcd->scene = scene;
kcd->ob = obedit;
- kcd->region = CTX_wm_region(C);
+ kcd->region = vc->region;
invert_m4_m4_safe_ortho(kcd->ob_imat, kcd->ob->obmat);
- em_setup_viewcontext(C, &kcd->vc);
-
kcd->em = BKE_editmesh_from_object(kcd->ob);
/* cut all the way through the mesh if use_occlude_geometry button not pushed */
@@ -2694,14 +2694,14 @@ static void knifetool_init(bContext *C,
}
/* called when modal loop selection is done... */
-static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd)
+static void knifetool_exit_ex(KnifeTool_OpData *kcd)
{
if (!kcd) {
return;
}
if (kcd->is_interactive) {
- WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_cursor_modal_restore(kcd->vc.win);
/* deactivate the extra drawing stuff in 3D-View */
ED_region_draw_cb_exit(kcd->region->type, kcd->draw_handle);
@@ -2735,10 +2735,10 @@ static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd)
/* destroy kcd itself */
MEM_freeN(kcd);
}
-static void knifetool_exit(bContext *C, wmOperator *op)
+static void knifetool_exit(wmOperator *op)
{
KnifeTool_OpData *kcd = op->customdata;
- knifetool_exit_ex(C, kcd);
+ knifetool_exit_ex(kcd);
op->customdata = NULL;
}
@@ -2827,10 +2827,10 @@ static void knifetool_finish(wmOperator *op)
/** \name Operator (#MESH_OT_knife_tool)
* \{ */
-static void knifetool_cancel(bContext *C, wmOperator *op)
+static void knifetool_cancel(bContext *UNUSED(C), wmOperator *op)
{
/* this is just a wrapper around exit() */
- knifetool_exit(C, op);
+ knifetool_exit(op);
}
wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
@@ -2872,7 +2872,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
bool do_refresh = false;
if (!obedit || obedit->type != OB_MESH || BKE_editmesh_from_object(obedit) != kcd->em) {
- knifetool_exit(C, op);
+ knifetool_exit(op);
ED_workspace_status_text(C, NULL);
return OPERATOR_FINISHED;
}
@@ -2893,7 +2893,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* finish */
ED_region_tag_redraw(kcd->region);
- knifetool_exit(C, op);
+ knifetool_exit(op);
ED_workspace_status_text(C, NULL);
return OPERATOR_CANCELLED;
@@ -2902,7 +2902,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_region_tag_redraw(kcd->region);
knifetool_finish(op);
- knifetool_exit(C, op);
+ knifetool_exit(op);
ED_workspace_status_text(C, NULL);
return OPERATOR_FINISHED;
@@ -3066,8 +3066,11 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const bool cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry");
const bool wait_for_input = RNA_boolean_get(op->ptr, "wait_for_input");
+ ViewContext vc;
KnifeTool_OpData *kcd;
+ em_setup_viewcontext(C, &vc);
+
if (only_select) {
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -3080,7 +3083,7 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* alloc new customdata */
kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
- knifetool_init(C, kcd, only_select, cut_through, true);
+ knifetool_init(&vc, kcd, only_select, cut_through, true);
op->flag |= OP_IS_MODAL_CURSOR_REGION;
@@ -3165,7 +3168,7 @@ static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
/**
* \param use_tag: When set, tag all faces inside the polylines.
*/
-void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
+void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_through)
{
KnifeTool_OpData *kcd;
@@ -3176,7 +3179,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
kcd = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
- knifetool_init(C, kcd, only_select, cut_through, is_interactive);
+ knifetool_init(vc, kcd, only_select, cut_through, is_interactive);
kcd->ignore_edge_snapping = true;
kcd->ignore_vert_snapping = true;
@@ -3313,7 +3316,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
#undef F_ISECT_SET_OUTSIDE
}
- knifetool_exit_ex(C, kcd);
+ knifetool_exit_ex(kcd);
kcd = NULL;
}
}
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 09b17acf56d..669a09b3fd3 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -32,6 +32,8 @@
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
+#include "BKE_layer.h"
+#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
@@ -114,7 +116,7 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
BKE_nurbList_free(&nurbslist);
if (me_eval_needs_free) {
- BKE_mesh_free((struct Mesh *)me_eval);
+ BKE_id_free(NULL, (ID *)me_eval);
}
}
@@ -124,21 +126,39 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
static int knifeproject_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
const bool cut_through = RNA_boolean_get(op->ptr, "cut_through");
LinkNode *polys = NULL;
CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
- if (ob != obedit) {
- polys = knifeproject_poly_from_object(C, scene, ob, polys);
+ if (BKE_object_is_in_editmode(ob)) {
+ continue;
}
+ polys = knifeproject_poly_from_object(C, scene, ob, polys);
}
CTX_DATA_END;
- if (polys) {
- EDBM_mesh_knife(C, polys, true, cut_through);
+ if (polys == NULL) {
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "No other selected objects have wire or boundary edges to use for projection");
+ return OPERATOR_CANCELLED;
+ }
+
+ ViewContext vc;
+ em_setup_viewcontext(C, &vc);
+
+ /* TODO: Ideally meshes would occlude each other, currently they don't
+ * since each knife-project runs as a separate operation. */
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ vc.view_layer, vc.v3d, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ED_view3d_viewcontext_init_object(&vc, obedit);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ EDBM_mesh_knife(&vc, polys, true, cut_through);
/* select only tagged faces */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
@@ -148,16 +168,12 @@ static int knifeproject_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
BM_mesh_select_mode_flush(em->bm);
-
- BLI_linklist_freeN(polys);
-
- return OPERATOR_FINISHED;
}
+ MEM_freeN(objects);
+
+ BLI_linklist_freeN(polys);
- BKE_report(op->reports,
- RPT_ERROR,
- "No other selected objects have wire or boundary edges to use for projection");
- return OPERATOR_CANCELLED;
+ return OPERATOR_FINISHED;
}
void MESH_OT_knife_project(wmOperatorType *ot)
diff --git a/source/blender/editors/mesh/editmesh_preselect_edgering.c b/source/blender/editors/mesh/editmesh_preselect_edgering.c
index 43e36957dc9..c58f29917b1 100644
--- a/source/blender/editors/mesh/editmesh_preselect_edgering.c
+++ b/source/blender/editors/mesh/editmesh_preselect_edgering.c
@@ -20,6 +20,8 @@
#include "MEM_guardedalloc.h"
+#include "DNA_userdef_types.h"
+
#include "BLI_math.h"
#include "BLI_stack.h"
@@ -160,16 +162,21 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl
}
GPU_depth_test(GPU_DEPTH_NONE);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
GPU_matrix_mul(matrix);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformThemeColor3(TH_GIZMO_PRIMARY);
-
if (psel->edges_len > 0) {
+ float viewport[4];
+ GPU_viewport_size_get_f(viewport);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+ immUniform2fv("viewportSize", &viewport[2]);
+ immUniformThemeColor3(TH_GIZMO_PRIMARY);
+ immUniform1f("lineWidth", U.pixelsize);
immBegin(GPU_PRIM_LINES, psel->edges_len * 2);
for (int i = 0; i < psel->edges_len; i++) {
@@ -178,10 +185,18 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl
}
immEnd();
+ immUnbindProgram();
}
if (psel->verts_len > 0) {
- GPU_point_size(3.0f);
+ GPU_program_point_size(true);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ immUniformThemeColor3(TH_GIZMO_PRIMARY);
+
+ /* Same size as an edit mode vertex */
+ immUniform1f("size",
+ 2.0 * U.pixelsize *
+ (max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f)));
immBegin(GPU_PRIM_POINTS, psel->verts_len);
@@ -190,14 +205,15 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl
}
immEnd();
+ immUnbindProgram();
+ GPU_program_point_size(false);
}
- immUnbindProgram();
-
GPU_matrix_pop();
/* Reset default */
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
+ GPU_blend(GPU_BLEND_NONE);
}
static void view3d_preselect_mesh_edgering_update_verts_from_edge(
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 830c9abb41e..8e38d41f971 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1860,10 +1860,16 @@ void MESH_OT_loop_select(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "Extend the selection");
- RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
- RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
- RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "Select ring");
+ PropertyRNA *prop;
+
+ prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "Extend the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "Select ring");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
void MESH_OT_edgering_select(wmOperatorType *ot)
@@ -1880,10 +1886,16 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
- RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
- RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
- RNA_def_boolean(ot->srna, "ring", 1, "Select Ring", "Select ring");
+ /* Properties. */
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "ring", 1, "Select Ring", "Select ring");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 41a9f426798..956658bd2b7 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -467,40 +467,50 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const int type = RNA_enum_get(op->ptr, "type");
- BM_custom_loop_normals_to_vector_layer(em->bm);
-
switch (type) {
case MESH_DELETE_VERT: /* Erase Vertices */
- if (!(em->bm->totvertsel &&
- EDBM_op_callf(em, op, "delete geom=%hv context=%i", BM_ELEM_SELECT, DEL_VERTS))) {
+ if (em->bm->totvertsel == 0) {
+ continue;
+ }
+ BM_custom_loop_normals_to_vector_layer(em->bm);
+ if (!EDBM_op_callf(em, op, "delete geom=%hv context=%i", BM_ELEM_SELECT, DEL_VERTS)) {
continue;
}
break;
case MESH_DELETE_EDGE: /* Erase Edges */
- if (!(em->bm->totedgesel &&
- EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_EDGES))) {
+ if (em->bm->totedgesel == 0) {
+ continue;
+ }
+ BM_custom_loop_normals_to_vector_layer(em->bm);
+ if (!EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_EDGES)) {
continue;
}
break;
case MESH_DELETE_FACE: /* Erase Faces */
- if (!(em->bm->totfacesel &&
- EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES))) {
+ if (em->bm->totfacesel == 0) {
+ continue;
+ }
+ BM_custom_loop_normals_to_vector_layer(em->bm);
+ if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES)) {
continue;
}
break;
- case MESH_DELETE_EDGE_FACE:
- /* Edges and Faces */
- if (!((em->bm->totedgesel || em->bm->totfacesel) &&
- EDBM_op_callf(
- em, op, "delete geom=%hef context=%i", BM_ELEM_SELECT, DEL_EDGESFACES))) {
+ case MESH_DELETE_EDGE_FACE: /* Edges and Faces */
+ if ((em->bm->totedgesel == 0) && (em->bm->totfacesel == 0)) {
+ continue;
+ }
+ BM_custom_loop_normals_to_vector_layer(em->bm);
+ if (!EDBM_op_callf(
+ em, op, "delete geom=%hef context=%i", BM_ELEM_SELECT, DEL_EDGESFACES)) {
continue;
}
break;
- case MESH_DELETE_ONLY_FACE:
- /* Only faces. */
- if (!(em->bm->totfacesel &&
- EDBM_op_callf(
- em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_ONLYFACES))) {
+ case MESH_DELETE_ONLY_FACE: /* Only faces. */
+ if (em->bm->totfacesel == 0) {
+ continue;
+ }
+ BM_custom_loop_normals_to_vector_layer(em->bm);
+ if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_ONLYFACES)) {
continue;
}
break;
@@ -2183,6 +2193,61 @@ static bool flip_custom_normals(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
/* -------------------------------------------------------------------- */
/** \name Flip Normals Operator
* \{ */
+
+static void edbm_flip_normals_custom_loop_normals(Object *obedit, BMEditMesh *em)
+{
+ if (!CustomData_has_layer(&em->bm->ldata, CD_CUSTOMLOOPNORMAL)) {
+ return;
+ }
+
+ /* The mesh has custom normal data, flip them. */
+ BMesh *bm = em->bm;
+
+ BM_lnorspace_update(bm);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ negate_v3(lnor_ed->nloc);
+
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
+ }
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
+}
+
+static void edbm_flip_normals_face_winding(wmOperator *op, Object *obedit, BMEditMesh *em)
+{
+
+ bool has_flipped_faces = false;
+
+ /* See if we have any custom normals to flip. */
+ BMLoopNorEditDataArray *lnors_ed_arr = flip_custom_normals_init_data(em->bm);
+
+ if (EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true)) {
+ has_flipped_faces = true;
+ }
+
+ if (flip_custom_normals(em->bm, lnors_ed_arr) || has_flipped_faces) {
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
+ }
+
+ if (lnors_ed_arr != NULL) {
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ }
+}
+
static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
{
const bool only_clnors = RNA_boolean_get(op->ptr, "only_clnors");
@@ -2197,56 +2262,16 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (only_clnors) {
- if (CustomData_has_layer(&em->bm->ldata, CD_CUSTOMLOOPNORMAL)) {
- /* The mesh has custom normal data, flip them. */
- BMesh *bm = em->bm;
-
- BM_lnorspace_update(bm);
- BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
- BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
-
- for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
- negate_v3(lnor_ed->nloc);
-
- BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[lnor_ed->loop_index],
- lnor_ed->nloc,
- lnor_ed->clnors_data);
- }
- BM_loop_normal_editdata_array_free(lnors_ed_arr);
- EDBM_update(obedit->data,
- &(const struct EDBMUpdate_Params){
- .calc_looptri = true,
- .calc_normals = false,
- .is_destructive = false,
- });
+ if ((em->bm->totvertsel == 0) && (em->bm->totedgesel == 0) && (em->bm->totfacesel == 0)) {
+ continue;
}
- continue;
- }
-
- if (em->bm->totfacesel == 0) {
- continue;
- }
-
- bool has_flipped_faces = false;
-
- /* See if we have any custom normals to flip. */
- BMLoopNorEditDataArray *lnors_ed_arr = flip_custom_normals_init_data(em->bm);
-
- if (EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true)) {
- has_flipped_faces = true;
- }
-
- if (flip_custom_normals(em->bm, lnors_ed_arr) || has_flipped_faces) {
- EDBM_update(obedit->data,
- &(const struct EDBMUpdate_Params){
- .calc_looptri = true,
- .calc_normals = false,
- .is_destructive = false,
- });
+ edbm_flip_normals_custom_loop_normals(obedit, em);
}
-
- if (lnors_ed_arr != NULL) {
- BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ else {
+ if (em->bm->totfacesel == 0) {
+ continue;
+ }
+ edbm_flip_normals_face_winding(op, obedit, em);
}
}
@@ -2748,9 +2773,6 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
{
- BMIter fiter;
- BMFace *f;
- int tot_invalid = 0;
int tot_unselected = 0;
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -2777,22 +2799,6 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
if (em->bm->totvertsel == 0) {
tot_unselected++;
- tot_invalid++;
- continue;
- }
-
- bool is_invalid = false;
- /* Check if select faces are triangles. */
- BM_ITER_MESH (f, &fiter, em->bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- if (f->len > 4) {
- tot_invalid++;
- is_invalid = true;
- break;
- }
- }
- }
- if (is_invalid) {
continue;
}
@@ -2841,10 +2847,6 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No selected vertex");
return OPERATOR_CANCELLED;
}
- if (tot_invalid == objects_len) {
- BKE_report(op->reports, RPT_WARNING, "Selected faces must be triangles or quads");
- return OPERATOR_CANCELLED;
- }
return OPERATOR_FINISHED;
}
@@ -4666,7 +4668,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int type = RNA_enum_get(op->ptr, "type");
- int retval = 0;
+ bool changed_multi = false;
if (ED_operator_editmesh(C)) {
uint bases_len = 0;
@@ -4676,6 +4678,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
for (uint bs_index = 0; bs_index < bases_len; bs_index++) {
Base *base = bases[bs_index];
BMEditMesh *em = BKE_editmesh_from_object(base->object);
+ bool changed = false;
if (type == 0) {
if ((em->bm->totvertsel == 0) && (em->bm->totedgesel == 0) && (em->bm->totfacesel == 0)) {
@@ -4690,20 +4693,20 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
/* editmode separate */
switch (type) {
case MESH_SEPARATE_SELECTED:
- retval = mesh_separate_selected(bmain, scene, view_layer, base, em->bm);
+ changed = mesh_separate_selected(bmain, scene, view_layer, base, em->bm);
break;
case MESH_SEPARATE_MATERIAL:
- retval = mesh_separate_material(bmain, scene, view_layer, base, em->bm);
+ changed = mesh_separate_material(bmain, scene, view_layer, base, em->bm);
break;
case MESH_SEPARATE_LOOSE:
- retval = mesh_separate_loose(bmain, scene, view_layer, base, em->bm);
+ changed = mesh_separate_loose(bmain, scene, view_layer, base, em->bm);
break;
default:
BLI_assert(0);
break;
}
- if (retval) {
+ if (changed) {
EDBM_update(base->object->data,
&(const struct EDBMUpdate_Params){
.calc_looptri = true,
@@ -4711,6 +4714,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
.is_destructive = true,
});
}
+ changed_multi |= changed;
}
MEM_freeN(bases);
}
@@ -4727,7 +4731,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
Mesh *me = ob->data;
if (!ID_IS_LINKED(me)) {
BMesh *bm_old = NULL;
- int retval_iter = 0;
+ bool changed = false;
bm_old = BM_mesh_create(&bm_mesh_allocsize_default,
&((struct BMeshCreateParams){
@@ -4738,17 +4742,17 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
switch (type) {
case MESH_SEPARATE_MATERIAL:
- retval_iter = mesh_separate_material(bmain, scene, view_layer, base_iter, bm_old);
+ changed = mesh_separate_material(bmain, scene, view_layer, base_iter, bm_old);
break;
case MESH_SEPARATE_LOOSE:
- retval_iter = mesh_separate_loose(bmain, scene, view_layer, base_iter, bm_old);
+ changed = mesh_separate_loose(bmain, scene, view_layer, base_iter, bm_old);
break;
default:
BLI_assert(0);
break;
}
- if (retval_iter) {
+ if (changed) {
BM_mesh_bm_to_me(bmain,
bm_old,
me,
@@ -4762,14 +4766,14 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
BM_mesh_free(bm_old);
- retval |= retval_iter;
+ changed_multi |= changed;
}
}
}
CTX_DATA_END;
}
- if (retval) {
+ if (changed_multi) {
/* delay depsgraph recalc until all objects are duplicated */
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
@@ -5572,24 +5576,24 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, CTX_wm_view3d(C), &objects_len);
- bool is_face_pair;
+ const bool do_seam = RNA_boolean_get(op->ptr, "seam");
+ const bool do_sharp = RNA_boolean_get(op->ptr, "sharp");
+ const bool do_uvs = RNA_boolean_get(op->ptr, "uvs");
+ const bool do_vcols = RNA_boolean_get(op->ptr, "vcols");
+ const bool do_materials = RNA_boolean_get(op->ptr, "materials");
+ float angle_face_threshold, angle_shape_threshold;
+ bool is_face_pair;
{
int totelem_sel[3];
EDBM_mesh_stats_multi(objects, objects_len, NULL, totelem_sel);
is_face_pair = (totelem_sel[2] == 2);
}
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
-
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- bool do_seam, do_sharp, do_uvs, do_vcols, do_materials;
- float angle_face_threshold, angle_shape_threshold;
+ /* When joining exactly 2 faces, no limit.
+ * this is useful for one off joins while editing. */
+ {
PropertyRNA *prop;
-
- /* When joining exactly 2 faces, no limit.
- * this is useful for one off joins while editing. */
prop = RNA_struct_find_property(op->ptr, "face_threshold");
if (is_face_pair && (RNA_property_is_set(op->ptr, prop) == false)) {
angle_face_threshold = DEG2RADF(180.0f);
@@ -5605,12 +5609,15 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
else {
angle_shape_threshold = RNA_property_float_get(op->ptr, prop);
}
+ }
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
- do_seam = RNA_boolean_get(op->ptr, "seam");
- do_sharp = RNA_boolean_get(op->ptr, "sharp");
- do_uvs = RNA_boolean_get(op->ptr, "uvs");
- do_vcols = RNA_boolean_get(op->ptr, "vcols");
- do_materials = RNA_boolean_get(op->ptr, "materials");
+ if (em->bm->totfacesel == 0) {
+ continue;
+ }
BM_custom_loop_normals_to_vector_layer(em->bm);
@@ -6335,7 +6342,7 @@ static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op)
BMesh *bm = em->bm;
if (!EDBM_op_callf(em, op, "dissolve_degenerate edges=%he dist=%f", BM_ELEM_SELECT, thresh)) {
- return OPERATOR_CANCELLED;
+ continue;
}
/* tricky to maintain correct selection here, so just flush up from verts */
@@ -8620,7 +8627,7 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *
RNA_enum_set(op->ptr, "mode", mode);
}
- /* Only handle mousemove event in case we are in mouse mode. */
+ /* Only handle mouse-move event in case we are in mouse mode. */
if (event->type == MOUSEMOVE || force_mousemove) {
if (mode == EDBM_CLNOR_POINTTO_MODE_MOUSE) {
ARegion *region = CTX_wm_region(C);
@@ -9527,6 +9534,10 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
+ if (bm->totfacesel == 0) {
+ continue;
+ }
+
BMFace *f;
BMVert *v;
BMEdge *e;
@@ -9538,18 +9549,11 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
BKE_editmesh_ensure_autosmooth(em, obedit->data);
BKE_editmesh_lnorspace_update(em, obedit->data);
- float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, __func__);
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
- const int v_index = BM_elem_index_get(v);
- add_v3_v3(vnors[v_index], f->no);
- }
- }
- }
- for (int i = 0; i < bm->totvert; i++) {
- if (!is_zero_v3(vnors[i]) && normalize_v3(vnors[i]) < CLNORS_VALID_VEC_LEN) {
- zero_v3(vnors[i]);
+ float(*vnors)[3] = MEM_mallocN(sizeof(*vnors) * bm->totvert, __func__);
+ {
+ int v_index;
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, v_index) {
+ BM_vert_calc_normal_ex(v, BM_ELEM_SELECT, vnors[v_index]);
}
}
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index fc9e1aa8b1a..f52cd94b8dc 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -755,11 +755,11 @@ static void undomesh_free_data(UndoMesh *um)
#endif
if (me->key) {
- BKE_key_free(me->key);
+ BKE_key_free_data(me->key);
MEM_freeN(me->key);
}
- BKE_mesh_free(me);
+ BKE_mesh_free_data_for_undo(me);
}
static Object *editmesh_object_from_context(bContext *C)
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 85c646d689c..c6a8e771362 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -355,10 +355,7 @@ void EDBM_mesh_clear(BMEditMesh *em)
/* free tessellation data */
em->tottri = 0;
- if (em->looptris) {
- MEM_freeN(em->looptris);
- em->looptris = NULL;
- }
+ MEM_SAFE_FREE(em->looptris);
}
void EDBM_mesh_load(Main *bmain, Object *ob)
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index b2379610f65..c075d2550cb 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -1007,15 +1007,8 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator
if (me->flag & ME_AUTOSMOOTH) {
float(*polynors)[3] = MEM_mallocN(sizeof(*polynors) * (size_t)me->totpoly, __func__);
- BKE_mesh_calc_normals_poly(me->mvert,
- NULL,
- me->totvert,
- me->mloop,
- me->mpoly,
- me->totloop,
- me->totpoly,
- polynors,
- true);
+ BKE_mesh_calc_normals_poly(
+ me->mvert, me->totvert, me->mloop, me->totloop, me->mpoly, me->totpoly, polynors);
BKE_edges_sharp_from_angle_set(me->mvert,
me->totvert,
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index f25317e8e85..03c99e40d1e 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -150,7 +150,10 @@ void MESH_OT_face_split_by_edges(struct wmOperatorType *ot);
/* *** editmesh_knife.c *** */
void MESH_OT_knife_tool(struct wmOperatorType *ot);
void MESH_OT_knife_project(struct wmOperatorType *ot);
-void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, bool use_tag, bool cut_through);
+void EDBM_mesh_knife(struct ViewContext *vc,
+ struct LinkNode *polys,
+ bool use_tag,
+ bool cut_through);
struct wmKeyMap *knifetool_modal_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c
index 5eb69aab48b..1a3e6a59588 100644
--- a/source/blender/editors/mesh/mesh_mirror.c
+++ b/source/blender/editors/mesh/mesh_mirror.c
@@ -365,10 +365,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store)
{
- if (mesh_topo_store->index_lookup) {
- MEM_freeN(mesh_topo_store->index_lookup);
- }
- mesh_topo_store->index_lookup = NULL;
+ MEM_SAFE_FREE(mesh_topo_store->index_lookup);
mesh_topo_store->prev_vert_tot = -1;
mesh_topo_store->prev_edge_tot = -1;
}