Merge branch 'master' into blender28
[blender.git] / source / blender / editors / mesh / editmesh_intersect.c
index 86b1a58dd1e1531426808015d13c742e2762ba52..9af700aa6bf1d053cd09b09752ce3727618c8d92 100644 (file)
@@ -33,6 +33,7 @@
 #include "BLI_kdopbvh.h"
 #include "BLI_linklist_stack.h"
 
+#include "BKE_layer.h"
 #include "BKE_editmesh_bvh.h"
 #include "BKE_context.h"
 #include "BKE_report.h"
@@ -146,9 +147,6 @@ enum {
 
 static int edbm_intersect_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit = CTX_data_edit_object(C);
-       BMEditMesh *em = BKE_editmesh_from_object(obedit);
-       BMesh *bm = em->bm;
        const int mode = RNA_enum_get(op->ptr, "mode");
        int (*test_fn)(BMFace *, void *);
        bool use_separate_all = false;
@@ -186,29 +184,45 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
                default:  /* ISECT_SEPARATE_NONE */
                        break;
        }
+       ViewLayer *view_layer = CTX_data_view_layer(C);
+       uint objects_len = 0;
+       uint isect_len = 0;
+       Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+       for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+               Object *obedit = objects[ob_index];
+               BMEditMesh *em = BKE_editmesh_from_object(obedit);
 
-       has_isect = BM_mesh_intersect(
-               bm,
-               em->looptris, em->tottri,
-               test_fn, NULL,
-               use_self, use_separate_all, true, true, true, true,
-               -1,
-               eps);
-
-       if (use_separate_cut) {
-               /* detach selected/un-selected faces */
-               BM_mesh_separate_faces(
-                       bm,
-                       BM_elem_cb_check_hflag_enabled_simple(const BMFace *, BM_ELEM_SELECT));
-       }
+               if (em->bm->totfacesel == 0) {
+                       continue;
+               }
+
+               has_isect = BM_mesh_intersect(
+                       em->bm,
+                       em->looptris, em->tottri,
+                       test_fn, NULL,
+                       use_self, use_separate_all, true, true, true, true,
+                       -1,
+                       eps);
+
+               if (use_separate_cut) {
+                       /* detach selected/un-selected faces */
+                       BM_mesh_separate_faces(
+                               em->bm,
+                               BM_elem_cb_check_hflag_enabled_simple(const BMFace *, BM_ELEM_SELECT));
+               }
 
-       if (has_isect) {
-               edbm_intersect_select(em);
+               if (has_isect) {
+                       edbm_intersect_select(em);
+               }
+               else {
+                       isect_len++;
+               }
        }
-       else {
+       MEM_freeN(objects);
+
+       if (isect_len == objects_len) {
                BKE_report(op->reports, RPT_WARNING, "No intersections found");
        }
-
        return OPERATOR_FINISHED;
 }
 
@@ -266,9 +280,6 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
 
 static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit = CTX_data_edit_object(C);
-       BMEditMesh *em = BKE_editmesh_from_object(obedit);
-       BMesh *bm = em->bm;
        const int boolean_operation = RNA_enum_get(op->ptr, "operation");
        bool use_swap = RNA_boolean_get(op->ptr, "use_swap");
        const float eps = RNA_float_get(op->ptr, "threshold");
@@ -276,23 +287,39 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
        bool has_isect;
 
        test_fn = use_swap ? bm_face_isect_pair_swap : bm_face_isect_pair;
+       ViewLayer *view_layer = CTX_data_view_layer(C);
+       uint objects_len = 0;
+       uint isect_len = 0;
+       Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+       for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+               Object *obedit = objects[ob_index];
+               BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+               if (em->bm->totfacesel == 0) {
+                       continue;
+               }
 
-       has_isect = BM_mesh_intersect(
-               bm,
-               em->looptris, em->tottri,
-               test_fn, NULL,
-               false, false, true, true, false, true,
-               boolean_operation,
-               eps);
+               has_isect = BM_mesh_intersect(
+                       em->bm,
+                       em->looptris, em->tottri,
+                       test_fn, NULL,
+                       false, false, true, true, false, true,
+                       boolean_operation,
+                       eps);
 
 
-       if (has_isect) {
-               edbm_intersect_select(em);
+               if (has_isect) {
+                       edbm_intersect_select(em);
+               }
+               else {
+                       isect_len++;
+               }
        }
-       else {
+       MEM_freeN(objects);
+
+       if (isect_len == objects_len) {
                BKE_report(op->reports, RPT_WARNING, "No intersections found");
        }
-
        return OPERATOR_FINISHED;
 }
 
@@ -652,257 +679,270 @@ static BMEdge *bm_face_split_edge_find(
 
 static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Object *obedit = CTX_data_edit_object(C);
-       BMEditMesh *em = BKE_editmesh_from_object(obedit);
-       BMesh *bm = em->bm;
        const char hflag = BM_ELEM_TAG;
 
        BMEdge *e;
        BMIter iter;
 
-       BLI_SMALLSTACK_DECLARE(loop_stack, BMLoop *);
+       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(view_layer, &objects_len);
+       for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+               Object *obedit = objects[ob_index];
+               BMEditMesh *em = BKE_editmesh_from_object(obedit);
+               BMesh *bm = em->bm;
 
-       {
-               BMVert *v;
-               BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
-                       BM_elem_flag_disable(v, hflag);
+               if ((bm->totedgesel == 0) ||
+                   (bm->totfacesel == 0))
+               {
+                       continue;
                }
-       }
-
-       /* edge index is set to -1 then used to assosiate them with faces */
-       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-               if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) {
-                       BM_elem_flag_enable(e, hflag);
 
-                       BM_elem_flag_enable(e->v1, hflag);
-                       BM_elem_flag_enable(e->v2, hflag);
+               BLI_SMALLSTACK_DECLARE(loop_stack, BMLoop *);
 
+               {
+                       BMVert *v;
+                       BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+                               BM_elem_flag_disable(v, hflag);
+                       }
                }
-               else {
-                       BM_elem_flag_disable(e, hflag);
-               }
-               BM_elem_index_set(e, -1);  /* set_dirty */
-       }
-       bm->elem_index_dirty |= BM_EDGE;
 
-       {
-               BMFace *f;
-               int i;
-               BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
-                       if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
-                               BM_elem_flag_enable(f, hflag);
+               /* edge index is set to -1 then used to assosiate them with faces */
+               BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) {
+                               BM_elem_flag_enable(e, hflag);
+
+                               BM_elem_flag_enable(e->v1, hflag);
+                               BM_elem_flag_enable(e->v2, hflag);
+
                        }
                        else {
-                               BM_elem_flag_disable(f, hflag);
+                               BM_elem_flag_disable(e, hflag);
                        }
-                       BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG);
-                       BM_elem_index_set(f, i);  /* set_ok */
+                       BM_elem_index_set(e, -1);  /* set_dirty */
                }
-       }
-       bm->elem_index_dirty &= ~BM_FACE;
-
-       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-               if (BM_elem_flag_test(e, hflag)) {
-                       BMIter viter;
-                       BMVert *v;
-                       BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
-                               BMIter liter;
-                               BMLoop *l;
-
-                               unsigned int loop_stack_len;
-                               BMLoop *l_best = NULL;
-
-                               BLI_assert(BLI_SMALLSTACK_IS_EMPTY(loop_stack));
-                               loop_stack_len = 0;
-
-                               BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
-                                       if (BM_elem_flag_test(l->f, hflag)) {
-                                               BLI_SMALLSTACK_PUSH(loop_stack, l);
-                                               loop_stack_len++;
-                                       }
-                               }
+               bm->elem_index_dirty |= BM_EDGE;
 
-                               if (loop_stack_len == 0) {
-                                       /* pass */
-                               }
-                               else if (loop_stack_len == 1) {
-                                       l_best = BLI_SMALLSTACK_POP(loop_stack);
+               {
+                       BMFace *f;
+                       int i;
+                       BM_ITER_MESH_INDEX(f, &iter, bm, BM_FACES_OF_MESH, i) {
+                               if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+                                       BM_elem_flag_enable(f, hflag);
                                }
                                else {
-                                       /* complicated case, match the edge with a face-loop */
+                                       BM_elem_flag_disable(f, hflag);
+                               }
+                               BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG);
+                               BM_elem_index_set(f, i);  /* set_ok */
+                       }
+               }
+               bm->elem_index_dirty &= ~BM_FACE;
+
+               BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(e, hflag)) {
+                               BMIter viter;
+                               BMVert *v;
+                               BM_ITER_ELEM(v, &viter, e, BM_VERTS_OF_EDGE) {
+                                       BMIter liter;
+                                       BMLoop *l;
+
+                                       unsigned int loop_stack_len;
+                                       BMLoop *l_best = NULL;
+
+                                       BLI_assert(BLI_SMALLSTACK_IS_EMPTY(loop_stack));
+                                       loop_stack_len = 0;
+
+                                       BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+                                               if (BM_elem_flag_test(l->f, hflag)) {
+                                                       BLI_SMALLSTACK_PUSH(loop_stack, l);
+                                                       loop_stack_len++;
+                                               }
+                                       }
+
+                                       if (loop_stack_len == 0) {
+                                               /* pass */
+                                       }
+                                       else if (loop_stack_len == 1) {
+                                               l_best = BLI_SMALLSTACK_POP(loop_stack);
+                                       }
+                                       else {
+                                               /* complicated case, match the edge with a face-loop */
 
-                                       BMVert *v_other = BM_edge_other_vert(e, v);
-                                       float e_dir[3];
+                                               BMVert *v_other = BM_edge_other_vert(e, v);
+                                               float e_dir[3];
 
-                                       /* we want closest to zero */
-                                       float dot_best = FLT_MAX;
+                                               /* we want closest to zero */
+                                               float dot_best = FLT_MAX;
 
-                                       sub_v3_v3v3(e_dir, v_other->co, v->co);
-                                       normalize_v3(e_dir);
+                                               sub_v3_v3v3(e_dir, v_other->co, v->co);
+                                               normalize_v3(e_dir);
 
-                                       while ((l = BLI_SMALLSTACK_POP(loop_stack))) {
-                                               float dot_test;
+                                               while ((l = BLI_SMALLSTACK_POP(loop_stack))) {
+                                                       float dot_test;
 
-                                               /* Check dot first to save on expensive angle-comparison.
-                                                * ideal case is 90d difference == 0.0 dot */
-                                               dot_test = fabsf(dot_v3v3(e_dir, l->f->no));
-                                               if (dot_test < dot_best) {
+                                                       /* Check dot first to save on expensive angle-comparison.
+                                                        * ideal case is 90d difference == 0.0 dot */
+                                                       dot_test = fabsf(dot_v3v3(e_dir, l->f->no));
+                                                       if (dot_test < dot_best) {
 
-                                                       /* check we're in the correct corner (works with convex loops too) */
-                                                       if (angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, v_other->co,    l->f->no) <
-                                                           angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, l->next->v->co, l->f->no))
-                                                       {
-                                                               dot_best = dot_test;
-                                                               l_best = l;
+                                                               /* check we're in the correct corner (works with convex loops too) */
+                                                               if (angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, v_other->co, l->f->no) <
+                                                                   angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, l->next->v->co, l->f->no))
+                                                               {
+                                                                       dot_best = dot_test;
+                                                                       l_best = l;
+                                                               }
                                                        }
                                                }
                                        }
-                               }
 
-                               if (l_best) {
-                                       BM_elem_index_set(e, BM_elem_index_get(l_best->f));  /* set_dirty */
+                                       if (l_best) {
+                                               BM_elem_index_set(e, BM_elem_index_get(l_best->f));  /* set_dirty */
+                                       }
                                }
                        }
                }
-       }
 
-       {
-               BMFace *f;
-               BLI_buffer_declare_static(BMEdge **, edge_net_temp_buf, 0, 128);
+               {
+                       BMFace *f;
+                       BLI_buffer_declare_static(BMEdge **, edge_net_temp_buf, 0, 128);
 
-               BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
-                       if (BM_elem_flag_test(f, hflag)) {
-                               bm_face_split_by_edges(bm, f, hflag, &edge_net_temp_buf);
+                       BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
+                               if (BM_elem_flag_test(f, hflag)) {
+                                       bm_face_split_by_edges(bm, f, hflag, &edge_net_temp_buf);
+                               }
                        }
+                       BLI_buffer_free(&edge_net_temp_buf);
                }
-               BLI_buffer_free(&edge_net_temp_buf);
-       }
 
 #ifdef USE_NET_ISLAND_CONNECT
-       /* before overwriting edge index values, collect edges left untouched */
-       BLI_Stack *edges_loose = BLI_stack_new(sizeof(BMEdge * ), __func__);
-       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-               if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) {
-                       BLI_stack_push(edges_loose, &e);
+               /* before overwriting edge index values, collect edges left untouched */
+               BLI_Stack *edges_loose = BLI_stack_new(sizeof(BMEdge *), __func__);
+               BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) {
+                               BLI_stack_push(edges_loose, &e);
+                       }
                }
-       }
 #endif
 
-       EDBM_mesh_normals_update(em);
-       EDBM_update_generic(em, true, true);
+               EDBM_mesh_normals_update(em);
+               EDBM_update_generic(em, true, true);
 
 
 #ifdef USE_NET_ISLAND_CONNECT
-       /* we may have remaining isolated regions remaining,
-        * these will need to have connecting edges created */
-       if (!BLI_stack_is_empty(edges_loose)) {
-               GHash *face_edge_map = BLI_ghash_ptr_new(__func__);
+               /* we may have remaining isolated regions remaining,
+                * these will need to have connecting edges created */
+               if (!BLI_stack_is_empty(edges_loose)) {
+                       GHash *face_edge_map = BLI_ghash_ptr_new(__func__);
 
-               MemArena *mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+                       MemArena *mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
 
-               BM_mesh_elem_index_ensure(bm, BM_FACE);
+                       BM_mesh_elem_index_ensure(bm, BM_FACE);
 
-               {
-                       BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, false);
+                       {
+                               BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, false);
 
-                       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-                               BM_elem_index_set(e, -1);  /* set_dirty */
-                       }
+                               BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+                                       BM_elem_index_set(e, -1);  /* set_dirty */
+                               }
 
-                       while (!BLI_stack_is_empty(edges_loose)) {
-                               BLI_stack_pop(edges_loose, &e);
-                               float e_center[3];
-                               mid_v3_v3v3(e_center, e->v1->co, e->v2->co);
+                               while (!BLI_stack_is_empty(edges_loose)) {
+                                       BLI_stack_pop(edges_loose, &e);
+                                       float e_center[3];
+                                       mid_v3_v3v3(e_center, e->v1->co, e->v2->co);
 
-                               BMFace *f = BKE_bmbvh_find_face_closest(bmbvh, e_center, FLT_MAX);
-                               if (f) {
-                                       ghash_insert_face_edge_link(face_edge_map, f, e, mem_arena);
-                                       BM_elem_index_set(e, BM_elem_index_get(f));  /* set_dirty */
+                                       BMFace *f = BKE_bmbvh_find_face_closest(bmbvh, e_center, FLT_MAX);
+                                       if (f) {
+                                               ghash_insert_face_edge_link(face_edge_map, f, e, mem_arena);
+                                               BM_elem_index_set(e, BM_elem_index_get(f));  /* set_dirty */
+                                       }
                                }
-                       }
 
-                       BKE_bmbvh_free(bmbvh);
-               }
+                               BKE_bmbvh_free(bmbvh);
+                       }
 
-               bm->elem_index_dirty |= BM_EDGE;
+                       bm->elem_index_dirty |= BM_EDGE;
 
-               BM_mesh_elem_table_ensure(bm, BM_FACE);
+                       BM_mesh_elem_table_ensure(bm, BM_FACE);
 
-               /* detect edges chains that span faces
-                * and splice vertices into the closest edges */
-               {
-                       GHashIterator gh_iter;
-
-                       GHASH_ITER(gh_iter, face_edge_map) {
-                               BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
-                               struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
-                               LinkNode *e_link = e_ls_base->list;
-
-                               do {
-                                       e = e_link->link;
-
-                                       for (int j = 0; j < 2; j++) {
-                                               BMVert *v_pivot = (&e->v1)[j];
-                                               /* checking that \a v_pivot isn't in the face
-                                                * prevents attempting to splice the same vertex into an edge from multiple faces */
-                                               if (!BM_vert_in_face(v_pivot, f)) {
-                                                       float v_pivot_co[3];
-                                                       float v_pivot_fac;
-                                                       BMEdge *e_split = bm_face_split_edge_find(
-                                                               e, f, v_pivot, bm->ftable, bm->totface,
-                                                               v_pivot_co, &v_pivot_fac);
-
-                                                       if (e_split) {
-                                                               /* for degenerate cases this vertex may be in one of this edges radial faces */
-                                                               if (!bm_vert_in_faces_radial(v_pivot, e_split, f)) {
-                                                                       BMEdge *e_new;
-                                                                       BMVert *v_new = BM_edge_split(bm, e_split, e_split->v1, &e_new, v_pivot_fac);
-                                                                       if (v_new) {
-                                                                               /* we _know_ these don't share an edge */
-                                                                               BM_vert_splice(bm, v_pivot, v_new);
-                                                                               BM_elem_index_set(e_new, BM_elem_index_get(e_split));
+                       /* detect edges chains that span faces
+                        * and splice vertices into the closest edges */
+                       {
+                               GHashIterator gh_iter;
+
+                               GHASH_ITER(gh_iter, face_edge_map) {
+                                       BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+                                       struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
+                                       LinkNode *e_link = e_ls_base->list;
+
+                                       do {
+                                               e = e_link->link;
+
+                                               for (int j = 0; j < 2; j++) {
+                                                       BMVert *v_pivot = (&e->v1)[j];
+                                                       /* checking that \a v_pivot isn't in the face
+                                                        * prevents attempting to splice the same vertex into an edge from multiple faces */
+                                                       if (!BM_vert_in_face(v_pivot, f)) {
+                                                               float v_pivot_co[3];
+                                                               float v_pivot_fac;
+                                                               BMEdge *e_split = bm_face_split_edge_find(
+                                                                       e, f, v_pivot, bm->ftable, bm->totface,
+                                                                       v_pivot_co, &v_pivot_fac);
+
+                                                               if (e_split) {
+                                                                       /* for degenerate cases this vertex may be in one of this edges radial faces */
+                                                                       if (!bm_vert_in_faces_radial(v_pivot, e_split, f)) {
+                                                                               BMEdge *e_new;
+                                                                               BMVert *v_new = BM_edge_split(bm, e_split, e_split->v1, &e_new, v_pivot_fac);
+                                                                               if (v_new) {
+                                                                                       /* we _know_ these don't share an edge */
+                                                                                       BM_vert_splice(bm, v_pivot, v_new);
+                                                                                       BM_elem_index_set(e_new, BM_elem_index_get(e_split));
+                                                                               }
                                                                        }
                                                                }
                                                        }
                                                }
-                                       }
 
-                               } while ((e_link = e_link->next));
+                                       } while ((e_link = e_link->next));
+                               }
                        }
-               }
 
 
-               {
-                       MemArena *mem_arena_edgenet = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+                       {
+                               MemArena *mem_arena_edgenet = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
 
-                       GHashIterator gh_iter;
+                               GHashIterator gh_iter;
 
-                       GHASH_ITER(gh_iter, face_edge_map) {
-                               BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
-                               struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
+                               GHASH_ITER(gh_iter, face_edge_map) {
+                                       BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+                                       struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
 
-                               bm_face_split_by_edges_island_connect(
-                                       bm, f,
-                                       e_ls_base->list, e_ls_base->list_len,
-                                       mem_arena_edgenet);
+                                       bm_face_split_by_edges_island_connect(
+                                               bm, f,
+                                               e_ls_base->list, e_ls_base->list_len,
+                                               mem_arena_edgenet);
 
-                               BLI_memarena_clear(mem_arena_edgenet);
-                       }
+                                       BLI_memarena_clear(mem_arena_edgenet);
+                               }
 
-                       BLI_memarena_free(mem_arena_edgenet);
-               }
+                               BLI_memarena_free(mem_arena_edgenet);
+                       }
 
-               BLI_memarena_free(mem_arena);
+                       BLI_memarena_free(mem_arena);
 
-               BLI_ghash_free(face_edge_map, NULL, NULL);
+                       BLI_ghash_free(face_edge_map, NULL, NULL);
 
-               EDBM_mesh_normals_update(em);
-               EDBM_update_generic(em, true, true);
-       }
+                       EDBM_mesh_normals_update(em);
+                       EDBM_update_generic(em, true, true);
+               }
 
-       BLI_stack_free(edges_loose);
+               BLI_stack_free(edges_loose);
 #endif  /* USE_NET_ISLAND_CONNECT */
 
+       }
+       MEM_freeN(objects);
        return OPERATOR_FINISHED;
 }