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_add.c113
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c18
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c3
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c2
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c2
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c140
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c8
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c3
-rw-r--r--source/blender/editors/mesh/mesh_ops.c12
9 files changed, 255 insertions, 46 deletions
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 1484dcfa92d..3c426e5d2b1 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -59,6 +59,7 @@ static Object *make_prim_init(bContext *C,
const char *idname,
const float loc[3],
const float rot[3],
+ const float scale[3],
ushort local_view_bits,
MakePrimitiveData *r_creation_data)
{
@@ -76,6 +77,13 @@ static Object *make_prim_init(bContext *C,
ED_object_new_primitive_matrix(C, obedit, loc, rot, r_creation_data->mat);
+ if (scale && !equals_v3v3(scale, (const float[3]){1.0f, 1.0f, 1.0f})) {
+ float scale_half[3];
+ copy_v3_v3(scale_half, scale);
+ mul_v3_fl(scale_half, 0.5f);
+ rescale_m4(r_creation_data->mat, scale_half);
+ }
+
return obedit;
}
@@ -112,9 +120,16 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Plane"), loc, rot, local_view_bits, &creation_data);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Plane"),
+ loc,
+ rot,
+ NULL,
+ local_view_bits,
+ &creation_data);
+
em = BKE_editmesh_from_object(obedit);
if (calc_uvs) {
@@ -164,15 +179,22 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op)
MakePrimitiveData creation_data;
Object *obedit;
BMEditMesh *em;
- float loc[3], rot[3];
+ float loc[3], rot[3], scale[3];
bool enter_editmode;
ushort local_view_bits;
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Cube"), loc, rot, local_view_bits, &creation_data);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, scale, &enter_editmode, &local_view_bits, NULL);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Cube"),
+ loc,
+ rot,
+ scale,
+ local_view_bits,
+ &creation_data);
+
em = BKE_editmesh_from_object(obedit);
if (calc_uvs) {
@@ -237,9 +259,16 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
cap_tri = (cap_end == 2);
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Circle"), loc, rot, local_view_bits, &creation_data);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Circle"),
+ loc,
+ rot,
+ NULL,
+ local_view_bits,
+ &creation_data);
+
em = BKE_editmesh_from_object(obedit);
if (calc_uvs) {
@@ -294,7 +323,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
MakePrimitiveData creation_data;
Object *obedit;
BMEditMesh *em;
- float loc[3], rot[3];
+ float loc[3], rot[3], scale[3];
bool enter_editmode;
ushort local_view_bits;
const int end_fill_type = RNA_enum_get(op->ptr, "end_fill_type");
@@ -303,11 +332,13 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, scale, &enter_editmode, &local_view_bits, NULL);
obedit = make_prim_init(C,
CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Cylinder"),
loc,
rot,
+ scale,
local_view_bits,
&creation_data);
em = BKE_editmesh_from_object(obedit);
@@ -368,7 +399,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
MakePrimitiveData creation_data;
Object *obedit;
BMEditMesh *em;
- float loc[3], rot[3];
+ float loc[3], rot[3], scale[3];
bool enter_editmode;
ushort local_view_bits;
const int end_fill_type = RNA_enum_get(op->ptr, "end_fill_type");
@@ -377,9 +408,15 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Cone"), loc, rot, local_view_bits, &creation_data);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, scale, &enter_editmode, &local_view_bits, NULL);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Cone"),
+ loc,
+ rot,
+ scale,
+ local_view_bits,
+ &creation_data);
em = BKE_editmesh_from_object(obedit);
if (calc_uvs) {
@@ -447,9 +484,15 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Grid"), loc, rot, local_view_bits, &creation_data);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Grid"),
+ loc,
+ rot,
+ NULL,
+ local_view_bits,
+ &creation_data);
em = BKE_editmesh_from_object(obedit);
if (calc_uvs) {
@@ -514,10 +557,16 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Y', loc, rot, &enter_editmode, &local_view_bits, NULL);
+ ED_object_add_generic_get_opts(
+ C, op, 'Y', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Suzanne"), loc, rot, local_view_bits, &creation_data);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Suzanne"),
+ loc,
+ rot,
+ NULL,
+ local_view_bits,
+ &creation_data);
dia = RNA_float_get(op->ptr, "size") / 2.0f;
mul_mat3_m4_fl(creation_data.mat, dia);
@@ -567,15 +616,21 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
MakePrimitiveData creation_data;
Object *obedit;
BMEditMesh *em;
- float loc[3], rot[3];
+ float loc[3], rot[3], scale[3];
bool enter_editmode;
ushort local_view_bits;
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
- obedit = make_prim_init(
- C, CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Sphere"), loc, rot, local_view_bits, &creation_data);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, scale, &enter_editmode, &local_view_bits, NULL);
+ obedit = make_prim_init(C,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Sphere"),
+ loc,
+ rot,
+ scale,
+ local_view_bits,
+ &creation_data);
em = BKE_editmesh_from_object(obedit);
if (calc_uvs) {
@@ -629,17 +684,19 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
MakePrimitiveData creation_data;
Object *obedit;
BMEditMesh *em;
- float loc[3], rot[3];
+ float loc[3], rot[3], scale[3];
bool enter_editmode;
ushort local_view_bits;
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
WM_operator_view3d_unit_defaults(C, op);
- ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL);
+ ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, scale, &enter_editmode, &local_view_bits, NULL);
obedit = make_prim_init(C,
CTX_DATA_(BLT_I18NCONTEXT_ID_MESH, "Icosphere"),
loc,
rot,
+ scale,
local_view_bits,
&creation_data);
em = BKE_editmesh_from_object(obedit);
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 23f622ac359..bf6c5a2f829 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -226,6 +226,7 @@ static bool edbm_extrude_ex(Object *obedit,
char htype,
const char hflag,
const bool use_normal_flip,
+ const bool use_dissolve_ortho_edges,
const bool use_mirror,
const bool use_select_history)
{
@@ -241,6 +242,7 @@ static bool edbm_extrude_ex(Object *obedit,
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
BMO_slot_bool_set(extop.slots_in, "use_normal_flip", use_normal_flip);
+ BMO_slot_bool_set(extop.slots_in, "use_dissolve_ortho_edges", use_dissolve_ortho_edges);
BMO_slot_bool_set(extop.slots_in, "use_select_history", use_select_history);
BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", htype, hflag);
@@ -312,7 +314,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
mul_v3_m3v3(offset_local, tmat, offset);
for (int a = 0; a < steps; a++) {
- edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, true);
+ edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, false, true);
BMO_op_callf(
em->bm, BMO_FLAG_DEFAULTS, "translate vec=%v verts=%hv", offset_local, BM_ELEM_SELECT);
}
@@ -359,6 +361,7 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
{
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
+ const bool use_dissolve_ortho_edges = RNA_boolean_get(op->ptr, "use_dissolve_ortho_edges");
const char htype = edbm_extrude_htype_from_em_select(em);
enum { NONE = 0, ELEM_FLAG, VERT_ONLY, EDGE_ONLY } nr;
bool changed = false;
@@ -401,7 +404,14 @@ static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
case NONE:
return false;
case ELEM_FLAG:
- changed = edbm_extrude_ex(obedit, em, htype, BM_ELEM_SELECT, use_normal_flip, true, true);
+ changed = edbm_extrude_ex(obedit,
+ em,
+ htype,
+ BM_ELEM_SELECT,
+ use_normal_flip,
+ use_dissolve_ortho_edges,
+ true,
+ true);
break;
case VERT_ONLY:
changed = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
@@ -465,6 +475,7 @@ void MESH_OT_extrude_region(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "use_normal_flip", false, "Flip Normals", "");
+ RNA_def_boolean(ot->srna, "use_dissolve_ortho_edges", false, "Dissolve Orthogonal Edges", "");
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
}
@@ -519,6 +530,7 @@ void MESH_OT_extrude_context(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "use_normal_flip", false, "Flip Normals", "");
+ RNA_def_boolean(ot->srna, "use_dissolve_ortho_edges", false, "Dissolve Orthogonal Edges", "");
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
}
@@ -840,7 +852,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
}
}
- edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, false, true, true);
+ edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, false, false, true, true);
EDBM_op_callf(
vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", BM_ELEM_SELECT, local_center, mat);
EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v", BM_ELEM_SELECT, ofs);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 08bbe9ae0e7..0f52911c603 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -372,7 +372,8 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
if (is_interactive) {
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *ob_iter = bases[base_index]->object;
- if (modifiers_isDeformedByLattice(ob_iter) || modifiers_isDeformedByArmature(ob_iter)) {
+ if (BKE_modifiers_is_deformed_by_lattice(ob_iter) ||
+ BKE_modifiers_is_deformed_by_armature(ob_iter)) {
BKE_report(
op->reports, RPT_WARNING, "Loop cut does not work well on deformed edit mesh display");
break;
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index c02ef9835a0..739bc5bdf7c 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -224,7 +224,7 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "add_solidify")) {
ED_object_modifier_add(
op->reports, bmain, scene, new_ob, "mask_extract_solidify", eModifierType_Solidify);
- SolidifyModifierData *sfmd = (SolidifyModifierData *)modifiers_findByName(
+ SolidifyModifierData *sfmd = (SolidifyModifierData *)BKE_modifiers_findby_name(
new_ob, "mask_extract_solidify");
if (sfmd) {
sfmd->offset = -0.05f;
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index 5106108a16c..365c5b5d264 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -1059,7 +1059,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (type == SIMVERT_VGROUP) {
/* We store the names of the vertex groups, so we can select
- * vertex groups with the same name in different objects. */
+ * vertex groups with the same name in different objects. */
const int dvert_tot = BLI_listbase_count(&ob->defbase);
for (int i = 0; i < dvert_tot; i++) {
if (dvert_selected & (1 << i)) {
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 5c7c95b59d7..684bb73dc0e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1970,6 +1970,84 @@ void MESH_OT_duplicate(wmOperatorType *ot)
RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
}
+static BMLoopNorEditDataArray *flip_custom_normals_init_data(BMesh *bm)
+{
+ BMLoopNorEditDataArray *lnors_ed_arr = NULL;
+ if (CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
+ /* The mesh has custom normal data, update these too.
+ * Otherwise they will be left in a mangled state.
+ */
+ BM_lnorspace_update(bm);
+ lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, true);
+ }
+
+ return lnors_ed_arr;
+}
+
+static bool flip_custom_normals(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
+{
+ if (!lnors_ed_arr) {
+ return false;
+ }
+
+ if (lnors_ed_arr->totloop == 0) {
+ /* No loops normals to flip, exit early! */
+ return false;
+ }
+
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ BM_lnorspace_update(bm);
+
+ /* We need to recreate the custom normal array because the clnors_data will
+ * be mangled because we swapped the loops around when we flipped the faces. */
+ BMLoopNorEditDataArray *lnors_ed_arr_new_full = BM_loop_normal_editdata_array_init(bm, true);
+
+ {
+ /* We need to recalculate all loop normals in the affected area. Even the ones that are not
+ * going to be flipped because the clnors data is mangled. */
+
+ BMLoopNorEditData *lnor_ed_new_full = lnors_ed_arr_new_full->lnor_editdata;
+ for (int i = 0; i < lnors_ed_arr_new_full->totloop; i++, lnor_ed_new_full++) {
+
+ BMLoopNorEditData *lnor_ed =
+ lnors_ed_arr->lidx_to_lnor_editdata[lnor_ed_new_full->loop_index];
+
+ BLI_assert(lnor_ed != NULL);
+
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed_new_full->loop_index],
+ lnor_ed->nloc,
+ lnor_ed_new_full->clnors_data);
+ }
+ }
+
+ BMFace *f;
+ BMLoop *l;
+ BMIter iter_f, iter_l;
+ BM_ITER_MESH (f, &iter_f, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ continue;
+ }
+ /* Flip all the custom loop normals on the selected faces. */
+
+ BM_ITER_ELEM (l, &iter_l, f, BM_LOOPS_OF_FACE) {
+
+ int loop_index = BM_elem_index_get(l);
+
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lidx_to_lnor_editdata[loop_index];
+ BMLoopNorEditData *lnor_ed_new = lnors_ed_arr_new_full->lidx_to_lnor_editdata[loop_index];
+ BLI_assert(lnor_ed != NULL && lnor_ed_new != NULL);
+
+ negate_v3(lnor_ed->nloc);
+
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[loop_index], lnor_ed->nloc, lnor_ed_new->clnors_data);
+ }
+ }
+ BM_loop_normal_editdata_array_free(lnors_ed_arr_new_full);
+ return true;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1977,6 +2055,8 @@ void MESH_OT_duplicate(wmOperatorType *ot)
* \{ */
static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
{
+ const bool only_clnors = RNA_boolean_get(op->ptr, "only_clnors");
+
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
@@ -1986,15 +2066,48 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- if (em->bm->totfacesel == 0) {
+ 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_generic(obedit->data, true, false);
+ }
continue;
}
- if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true)) {
+ if (em->bm->totfacesel == 0) {
continue;
}
- EDBM_update_generic(obedit->data, true, false);
+ 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_generic(obedit->data, true, false);
+ }
+
+ if (lnors_ed_arr != NULL) {
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ }
}
MEM_freeN(objects);
@@ -2014,6 +2127,12 @@ void MESH_OT_flip_normals(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna,
+ "only_clnors",
+ false,
+ "Custom Normals Only",
+ "Only flip the custom loop normals of the selected elements");
}
/** \} */
@@ -2276,6 +2395,7 @@ void MESH_OT_reveal(wmOperatorType *ot)
static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
+ const bool inside = RNA_boolean_get(op->ptr, "inside");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
@@ -2288,11 +2408,23 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
continue;
}
+ BMLoopNorEditDataArray *lnors_ed_arr = NULL;
+
+ if (inside) {
+ /* Save custom normal data for later so we can flip them correctly. */
+ lnors_ed_arr = flip_custom_normals_init_data(em->bm);
+ }
+
if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf", BM_ELEM_SELECT)) {
continue;
}
- if (RNA_boolean_get(op->ptr, "inside")) {
+
+ if (inside) {
EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true);
+ flip_custom_normals(em->bm, lnors_ed_arr);
+ if (lnors_ed_arr != NULL) {
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ }
}
EDBM_update_generic(obedit->data, true, false);
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 48ec41027ff..e4ecfa9c680 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -397,9 +397,7 @@ struct UMArrayData {
UndoMesh *um;
const UndoMesh *um_ref; /* can be NULL */
};
-static void um_arraystore_compact_cb(TaskPool *__restrict UNUSED(pool),
- void *taskdata,
- int UNUSED(threadid))
+static void um_arraystore_compact_cb(TaskPool *__restrict UNUSED(pool), void *taskdata)
{
struct UMArrayData *um_data = taskdata;
um_arraystore_compact_with_info(um_data->um, um_data->um_ref);
@@ -541,9 +539,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
# ifdef USE_ARRAY_STORE_THREAD
if (um_arraystore.task_pool == NULL) {
- TaskScheduler *scheduler = BLI_task_scheduler_get();
- um_arraystore.task_pool = BLI_task_pool_create_background(
- scheduler, NULL, TASK_PRIORITY_LOW);
+ um_arraystore.task_pool = BLI_task_pool_create_background(NULL, TASK_PRIORITY_LOW);
}
struct UMArrayData *um_data = MEM_mallocN(sizeof(*um_data), __func__);
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index a26003d78ed..b5346a9061a 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -1647,14 +1647,13 @@ bool BMBVH_EdgeVisible(struct BMBVHTree *tree,
void EDBM_project_snap_verts(
bContext *C, Depsgraph *depsgraph, ARegion *region, Object *obedit, BMEditMesh *em)
{
- Main *bmain = CTX_data_main(C);
BMIter iter;
BMVert *eve;
ED_view3d_init_mats_rv3d(obedit, region->regiondata);
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- bmain, CTX_data_scene(C), 0, region, CTX_wm_view3d(C));
+ CTX_data_scene(C), 0, region, CTX_wm_view3d(C));
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 66b2c66f2aa..c52a5956ac4 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -277,6 +277,18 @@ void ED_operatormacros_mesh(void)
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
RNA_boolean_set(otmacro->ptr, "mirror", false);
+ ot = WM_operatortype_append_macro(
+ "MESH_OT_extrude_region_dissolve_move_intersect",
+ "Extrude, Dissolve, Move and Intersect",
+ "Extrude, dissolves edges whose faces form a flat surface and intersect new edges",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_region");
+ RNA_boolean_set(otmacro->ptr, "use_dissolve_ortho_edges", true);
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
+ RNA_boolean_set(otmacro->ptr, "use_automerge_and_split", true);
+
ot = WM_operatortype_append_macro("MESH_OT_extrude_context_move",
"Extrude Region and Move",
"Extrude region together along the average normal",