Merge branch 'blender2.7' into master.
[blender.git] / source / blender / editors / mesh / editmesh_rip.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2004 by Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Joseph Eagar
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/mesh/editmesh_rip.c
29  *  \ingroup edmesh
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_object_types.h"
35
36 #include "BLI_math.h"
37 #include "BLI_array.h"
38
39 #include "BKE_context.h"
40 #include "BKE_report.h"
41 #include "BKE_editmesh.h"
42 #include "BKE_layer.h"
43
44 #include "RNA_define.h"
45 #include "RNA_access.h"
46
47 #include "WM_types.h"
48
49 #include "ED_mesh.h"
50 #include "ED_screen.h"
51 #include "ED_transform.h"
52 #include "ED_view3d.h"
53
54 #include "bmesh.h"
55 #include "bmesh_tools.h"
56
57 #include "mesh_intern.h"  /* own include */
58
59 /**
60  * helper to find edge for edge_rip,
61  *
62  * \param inset: is used so we get some useful distance
63  * when comparing multiple edges that meet at the same
64  * point and would result in the same distance.
65  */
66 #define INSET_DEFAULT 0.00001f
67 static float edbm_rip_edgedist_squared(
68         ARegion *ar, float mat[4][4],
69         const float co1[3], const float co2[3], const float mvalf[2],
70         const float inset)
71 {
72         float vec1[2], vec2[2], dist_sq;
73
74         ED_view3d_project_float_v2_m4(ar, co1, vec1, mat);
75         ED_view3d_project_float_v2_m4(ar, co2, vec2, mat);
76
77         if (inset != 0.0f) {
78                 const float dist_2d = len_v2v2(vec1, vec2);
79                 if (dist_2d > FLT_EPSILON) {
80                         const float dist = inset / dist_2d;
81                         BLI_assert(isfinite(dist));
82                         interp_v2_v2v2(vec1, vec1, vec2, dist);
83                         interp_v2_v2v2(vec2, vec2, vec1, dist);
84                 }
85         }
86
87         dist_sq = dist_squared_to_line_segment_v2(mvalf, vec1, vec2);
88         BLI_assert(isfinite(dist_sq));
89
90         return dist_sq;
91 }
92
93 #if 0
94 static float edbm_rip_linedist(
95         ARegion *ar, float mat[4][4],
96         const float co1[3], const float co2[3], const float mvalf[2])
97 {
98         float vec1[2], vec2[2];
99
100         ED_view3d_project_float_v2_m4(ar, co1, vec1, mat);
101         ED_view3d_project_float_v2_m4(ar, co2, vec2, mat);
102
103         return dist_to_line_v2(mvalf, vec1, vec2);
104 }
105 #endif
106
107 /* calculaters a point along the loop tangent which can be used to measure against edges */
108 static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3])
109 {
110         BM_loop_calc_face_tangent(l, l_mid_co);
111
112         /* scale to average of surrounding edge size, only needs to be approx, but should
113          * be roughly equivalent to the check below which uses the middle of the edge. */
114         mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f);
115
116         add_v3_v3(l_mid_co, l->v->co);
117 }
118
119
120 static float edbm_rip_edge_side_measure(
121         BMEdge *e, BMLoop *e_l,
122         ARegion *ar,
123         float projectMat[4][4], const float fmval[2])
124 {
125         float cent[3] = {0, 0, 0}, mid[3];
126
127         float vec[2];
128         float fmval_tweak[2];
129         float e_v1_co[2], e_v2_co[2];
130         float score;
131
132         BMVert *v1_other;
133         BMVert *v2_other;
134
135         BLI_assert(BM_vert_in_edge(e, e_l->v));
136
137         /* method for calculating distance:
138          *
139          * for each edge: calculate face center, then made a vector
140          * from edge midpoint to face center.  offset edge midpoint
141          * by a small amount along this vector. */
142
143         /* rather then the face center, get the middle of
144          * both edge verts connected to this one */
145         v1_other = BM_face_other_vert_loop(e_l->f, e->v2, e->v1)->v;
146         v2_other = BM_face_other_vert_loop(e_l->f, e->v1, e->v2)->v;
147         mid_v3_v3v3(cent, v1_other->co, v2_other->co);
148         mid_v3_v3v3(mid, e->v1->co, e->v2->co);
149
150         ED_view3d_project_float_v2_m4(ar, cent, cent, projectMat);
151         ED_view3d_project_float_v2_m4(ar, mid, mid, projectMat);
152
153         ED_view3d_project_float_v2_m4(ar, e->v1->co, e_v1_co, projectMat);
154         ED_view3d_project_float_v2_m4(ar, e->v2->co, e_v2_co, projectMat);
155
156         sub_v2_v2v2(vec, cent, mid);
157         normalize_v2_length(vec, 0.01f);
158
159         /* rather then adding to both verts, subtract from the mouse */
160         sub_v2_v2v2(fmval_tweak, fmval, vec);
161
162         score = len_v2v2(e_v1_co, e_v2_co);
163
164         if (dist_squared_to_line_segment_v2(fmval_tweak, e_v1_co, e_v2_co) >
165             dist_squared_to_line_segment_v2(fmval,       e_v1_co, e_v2_co))
166         {
167                 return score;
168         }
169         else {
170                 return -score;
171         }
172 }
173
174
175 /* - Advanced selection handling 'ripsel' functions ----- */
176
177 /**
178  * How rip selection works
179  *
180  * Firstly - rip is basically edge split with side-selection & grab.
181  * Things would be much more simple if we didn't have to worry about side selection
182  *
183  * The method used for checking the side of selection is as follows...
184  * - First tag all rip-able edges.
185  * - Build a contiguous edge list by looping over tagged edges and following each ones tagged siblings in both
186  *   directions.
187  *   - The loops are not stored in an array, Instead both loops on either side of each edge has its index values set
188  *     to count down from the last edge, this way, once we have the 'last' edge its very easy to walk down the
189  *     connected edge loops.
190  *     The reason for using loops like this is because when the edges are split we don't which face user gets the newly
191  *     created edge (its as good as random so we cant assume new edges will be on once side).
192  *     After splitting, its very simple to walk along boundary loops since each only has one edge from a single side.
193  * - The end loop pairs are stored in an array however to support multiple edge-selection-islands, so you can rip
194  *   multiple selections at once.
195  * - * Execute the split *
196  * - For each #EdgeLoopPair walk down both sides of the split using the loops and measure which is facing the mouse.
197  * - Deselect the edge loop facing away.
198  *
199  * Limitation!
200  * This currently works very poorly with intersecting edge islands (verts with more than 2 tagged edges)
201  * This is nice to but for now not essential.
202  *
203  * - campbell.
204  */
205
206
207 #define IS_VISIT_POSSIBLE(e)   (BM_edge_is_manifold(e) && BM_elem_flag_test(e, BM_ELEM_TAG))
208 #define IS_VISIT_DONE(e) ((e)->l && (BM_elem_index_get((e)->l) != INVALID_UID))
209 #define INVALID_UID INT_MIN
210
211 /* mark, assign uid and step */
212 static BMEdge *edbm_ripsel_edge_mark_step(BMVert *v, const int uid)
213 {
214         BMIter iter;
215         BMEdge *e;
216         BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
217                 if (IS_VISIT_POSSIBLE(e) && !IS_VISIT_DONE(e)) {
218                         BMLoop *l_a, *l_b;
219
220                         BM_edge_loop_pair(e, &l_a, &l_b); /* no need to check, we know this will be true */
221
222                         /* so (IS_VISIT_DONE == true) */
223                         BM_elem_index_set(l_a, uid);  /* set_dirty */
224                         BM_elem_index_set(l_b, uid);  /* set_dirty */
225
226                         return e;
227                 }
228         }
229         return NULL;
230 }
231
232 typedef struct EdgeLoopPair {
233         BMLoop *l_a;
234         BMLoop *l_b;
235 } EdgeLoopPair;
236
237 static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
238 {
239         BMIter fiter;
240         BMIter liter;
241
242         BMFace *f;
243         BMLoop *l;
244
245         int uid_start;
246         int uid_end;
247         int uid = bm->totedge; /* can start anywhere */
248
249         EdgeLoopPair *eloop_pairs = NULL;
250         BLI_array_declare(eloop_pairs);
251         EdgeLoopPair *lp;
252
253         /* initialize loops with dummy invalid index values */
254         BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
255                 BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
256                         BM_elem_index_set(l, INVALID_UID);  /* set_dirty */
257                 }
258         }
259         bm->elem_index_dirty |= BM_LOOP;
260
261         /* set contiguous loops ordered 'uid' values for walking after split */
262         while (true) {
263                 int tot = 0;
264                 BMIter eiter;
265                 BMEdge *e_step;
266                 BMVert *v_step;
267                 BMEdge *e;
268                 BMEdge *e_first;
269                 BMEdge *e_last;
270
271                 e_first = NULL;
272                 BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
273                         if (IS_VISIT_POSSIBLE(e) && !IS_VISIT_DONE(e)) {
274                                 e_first = e;
275                                 break;
276                         }
277                 }
278
279                 if (e_first == NULL) {
280                         break;
281                 }
282
283                 /* initialize  */
284                 e_first = e;
285                 v_step = e_first->v1;
286                 e_step = NULL; /* quiet warning, will never remain this value */
287
288                 uid_start = uid;
289                 while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) {
290                         v_step = BM_edge_other_vert((e_step = e), v_step);
291                         uid++; /* only different line */
292                         tot++;
293                 }
294
295                 /* this edges loops have the highest uid's, store this to walk down later */
296                 e_last = e_step;
297
298                 /* always store the highest 'uid' edge for the stride */
299                 uid_end = uid - 1;
300                 uid = uid_start - 1;
301
302                 /* initialize */
303                 v_step = e_first->v1;
304
305                 while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) {
306                         v_step = BM_edge_other_vert((e_step = e), v_step);
307                         uid--; /* only different line */
308                         tot++;
309                 }
310
311                 /* stride far enough not to _ever_ overlap range */
312                 uid_start = uid;
313                 uid = uid_end + bm->totedge;
314
315                 lp = BLI_array_append_ret(eloop_pairs);
316                 BM_edge_loop_pair(e_last, &lp->l_a, &lp->l_b); /* no need to check, we know this will be true */
317
318
319                 BLI_assert(tot == uid_end - uid_start);
320
321 #if 0
322                 printf("%s: found contiguous edge loop of (%d)\n", __func__, uid_end - uid_start);
323 #endif
324
325         }
326
327         /* null terminate */
328         lp = BLI_array_append_ret(eloop_pairs);
329         lp->l_a = lp->l_b = NULL;
330
331         return eloop_pairs;
332 }
333
334
335 /* - De-Select the worst rip-edge side -------------------------------- */
336
337
338 static BMEdge *edbm_ripsel_edge_uid_step(BMEdge *e_orig, BMVert **v_prev)
339 {
340         BMIter eiter;
341         BMEdge *e;
342         BMVert *v = BM_edge_other_vert(e_orig, *v_prev);
343         const int uid_cmp = BM_elem_index_get(e_orig->l) - 1;
344
345         BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
346                 if (BM_elem_index_get(e->l) == uid_cmp) {
347                         *v_prev = v;
348                         return e;
349                 }
350         }
351         return NULL;
352 }
353
354 static BMVert *edbm_ripsel_edloop_pair_start_vert(BMEdge *e)
355 {
356         /* try step in a direction, if it fails we know do go the other way */
357         BMVert *v_test = e->v1;
358         return (edbm_ripsel_edge_uid_step(e, &v_test)) ? e->v1 : e->v2;
359 }
360
361 static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs,
362                                         ARegion *ar, float projectMat[4][4], float fmval[2])
363 {
364         EdgeLoopPair *lp;
365
366         for (lp = eloop_pairs; lp->l_a; lp++) {
367                 BMEdge *e;
368                 BMVert *v_prev;
369
370                 float score_a = 0.0f;
371                 float score_b = 0.0f;
372
373                 e = lp->l_a->e;
374                 v_prev = edbm_ripsel_edloop_pair_start_vert(e);
375                 for (; e; e = edbm_ripsel_edge_uid_step(e, &v_prev)) {
376                         score_a += edbm_rip_edge_side_measure(e, e->l, ar, projectMat, fmval);
377                 }
378                 e = lp->l_b->e;
379                 v_prev = edbm_ripsel_edloop_pair_start_vert(e);
380                 for (; e; e = edbm_ripsel_edge_uid_step(e, &v_prev)) {
381                         score_b += edbm_rip_edge_side_measure(e, e->l, ar, projectMat, fmval);
382                 }
383
384                 e = (score_a > score_b) ? lp->l_a->e : lp->l_b->e;
385                 v_prev = edbm_ripsel_edloop_pair_start_vert(e);
386                 for (; e; e = edbm_ripsel_edge_uid_step(e, &v_prev)) {
387                         BM_edge_select_set(bm, e, false);
388                 }
389         }
390 }
391 /* --- end 'ripsel' selection handling code --- */
392
393
394 /* --- face-fill code --- */
395 /**
396  * return an un-ordered array of loop pairs
397  * use for rebuilding face-fill
398  *
399  * \note the method currently used fails for edges with 3+ face users and gives
400  *       nasty holes in the mesh, there isnt a good way of knowing ahead of time
401  *       which loops will be split apart (its possible to figure out but quite involved).
402  *       So for now this is a known limitation of current rip-fill option.
403  */
404
405 typedef struct UnorderedLoopPair {
406         BMLoop *l_pair[2];
407         char    flag;
408 } UnorderedLoopPair;
409 enum {
410         ULP_FLIP_0 = (1 << 0),
411         ULP_FLIP_1 = (1 << 1)
412 };
413
414 static UnorderedLoopPair *edbm_tagged_loop_pairs_to_fill(BMesh *bm)
415 {
416         BMIter iter;
417         BMEdge *e;
418
419         unsigned int total_tag = 0;
420         /* count tags, could be pre-calculated */
421         BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
422                 if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
423                         total_tag++;
424                 }
425         }
426
427         if (total_tag) {
428                 UnorderedLoopPair *uloop_pairs = MEM_mallocN(total_tag * sizeof(UnorderedLoopPair), __func__);
429                 UnorderedLoopPair *ulp = uloop_pairs;
430
431                 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
432                         if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
433                                 BMLoop *l1, *l2;
434                                 if (BM_edge_loop_pair(e, &l1, &l2)) {
435                                         BMVert *v_cmp = l1->e->v1;
436                                         ulp->flag = (((l1->v != v_cmp) ? ULP_FLIP_0 : 0) |
437                                                      ((l2->v == v_cmp) ? ULP_FLIP_1 : 0));
438                                 }
439                                 else {
440                                         ulp->flag = 0;
441                                 }
442                                 ulp->l_pair[0] = l1;
443                                 ulp->l_pair[1] = l2;
444
445                                 ulp++;
446                         }
447                 }
448
449                 return uloop_pairs;
450         }
451         else {
452                 return NULL;
453         }
454 }
455
456 static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *uloop_pairs)
457 {
458         UnorderedLoopPair *ulp;
459         unsigned int total_tag = MEM_allocN_len(uloop_pairs) / sizeof(UnorderedLoopPair);
460         unsigned int i;
461
462         for (i = 0, ulp = uloop_pairs; i < total_tag; i++, ulp++) {
463                 if ((ulp->l_pair[0]    && ulp->l_pair[1]) &&
464                     (ulp->l_pair[0]->e != ulp->l_pair[1]->e))
465                 {
466                         /* time has come to make a face! */
467                         BMVert *v_shared = BM_edge_share_vert(ulp->l_pair[0]->e, ulp->l_pair[1]->e);
468                         BMFace *f, *f_example = ulp->l_pair[0]->f;
469                         BMLoop *l_iter;
470                         BMVert *f_verts[4];
471
472                         if (v_shared == NULL) {
473                                 /* quad */
474                                 f_verts[0] = ulp->l_pair[0]->e->v1;
475                                 f_verts[1] = ulp->l_pair[1]->e->v1;
476                                 f_verts[2] = ulp->l_pair[1]->e->v2;
477                                 f_verts[3] = ulp->l_pair[0]->e->v2;
478
479                                 if (ulp->flag & ULP_FLIP_0) {
480                                         SWAP(BMVert *, f_verts[0], f_verts[3]);
481                                 }
482                                 if (ulp->flag & ULP_FLIP_1) {
483                                         SWAP(BMVert *, f_verts[1], f_verts[2]);
484                                 }
485                         }
486                         else {
487                                 /* tri */
488                                 f_verts[0] = v_shared;
489                                 f_verts[1] = BM_edge_other_vert(ulp->l_pair[0]->e, v_shared);
490                                 f_verts[2] = BM_edge_other_vert(ulp->l_pair[1]->e, v_shared);
491                                 f_verts[3] = NULL;
492
493                                 /* don't use the flip flags */
494                                 if (v_shared == ulp->l_pair[0]->v) {
495                                         SWAP(BMVert *, f_verts[0], f_verts[1]);
496                                 }
497                         }
498
499                         /* face should never exist */
500                         BLI_assert(!BM_face_exists(f_verts, f_verts[3] ? 4 : 3));
501
502                         f = BM_face_create_verts(bm, f_verts, f_verts[3] ? 4 : 3, f_example, BM_CREATE_NOP, true);
503
504                         l_iter = BM_FACE_FIRST_LOOP(f);
505
506                         if (f_verts[3]) {
507                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
508                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter); l_iter = l_iter->next;
509                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter); l_iter = l_iter->next;
510                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter);
511                         }
512                         else {
513                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
514                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
515                                 BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
516                         }
517
518                 }
519         }
520 }
521
522 /* --- end 'face-fill' code --- */
523
524 /**
525  * This is the main vert ripping function (rip when one vertex is selected)
526  */
527 static int edbm_rip_invoke__vert(bContext *C, const wmEvent *event, Object *obedit, bool do_fill)
528 {
529         UnorderedLoopPair *fill_uloop_pairs = NULL;
530         ARegion *ar = CTX_wm_region(C);
531         RegionView3D *rv3d = CTX_wm_region_view3d(C);
532         BMEditMesh *em = BKE_editmesh_from_object(obedit);
533         BMesh *bm = em->bm;
534         BMIter iter, liter;
535         BMLoop *l;
536         BMEdge *e_best;
537         BMVert *v;
538         const int totvert_orig = bm->totvert;
539         int i;
540         float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
541         float dist_sq = FLT_MAX;
542         float d;
543         bool is_wire, is_manifold_region;
544
545         BMEditSelection ese;
546         int totboundary_edge = 0;
547
548         ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
549
550         /* find selected vert - same some time and check history first */
551         if (BM_select_history_active_get(bm, &ese) && ese.htype == BM_VERT) {
552                 v = (BMVert *)ese.ele;
553         }
554         else {
555                 ese.ele = NULL;
556
557                 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
558                         if (BM_elem_flag_test(v, BM_ELEM_SELECT))
559                                 break;
560                 }
561         }
562
563         /* (v == NULL) should be impossible */
564         if ((v == NULL) || (v->e == NULL)) {
565                 return OPERATOR_CANCELLED;
566         }
567
568         is_wire = BM_vert_is_wire(v);
569         is_manifold_region = BM_vert_is_manifold_region(v);
570
571         e_best = NULL;
572
573         {
574                 BMEdge *e;
575                 /* find closest edge to mouse cursor */
576                 BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
577                         /* consider wire as boundary for this purpose,
578                          * otherwise we can't a face away from a wire edge */
579                         totboundary_edge += (BM_edge_is_boundary(e) || BM_edge_is_wire(e));
580                         if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
581                                 if ((is_manifold_region == false) || BM_edge_is_manifold(e)) {
582                                         d = edbm_rip_edgedist_squared(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT);
583                                         if ((e_best == NULL) || (d < dist_sq)) {
584                                                 dist_sq = d;
585                                                 e_best = e;
586                                         }
587                                 }
588                         }
589                 }
590         }
591
592         if (e_best && e_best->l && (is_manifold_region == false)) {
593                 /* Try to split off a non-manifold fan (when we have multiple disconnected fans) */
594                 BMLoop *l_sep = e_best->l->v == v ? e_best->l : e_best->l->next;
595                 BMVert *v_new;
596
597                 BLI_assert(l_sep->v == v);
598                 v_new = BM_face_loop_separate_multi_isolated(bm, l_sep);
599                 BLI_assert(BM_vert_find_first_loop(v));
600
601                 BM_vert_select_set(bm, v, false);
602                 BM_select_history_remove(bm, v);
603
604                 BM_vert_select_set(bm, v_new, true);
605                 if (ese.ele) {
606                         BM_select_history_store(bm, v_new);
607                 }
608
609                 if (do_fill) {
610                         BM_edge_create(bm, v, v_new, NULL, BM_CREATE_NOP);
611                 }
612
613                 return OPERATOR_FINISHED;
614         }
615
616         /* if we are ripping a single vertex from 3 faces,
617          * then measure the distance to the face corner as well as the edge */
618         if (BM_vert_face_count_is_equal(v, 3) &&
619             BM_vert_edge_count_is_equal(v, 3))
620         {
621                 BMEdge *e_all[3];
622                 BMLoop *l_all[3];
623                 int i1, i2;
624
625                 BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3);
626                 BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3);
627
628                 /* not do a loop similar to the one above, but test against loops */
629                 for (i1 = 0; i1 < 3; i1++) {
630                         /* consider wire as boundary for this purpose,
631                          * otherwise we can't a face away from a wire edge */
632                         float l_mid_co[3];
633                         l = l_all[i1];
634                         edbm_calc_loop_co(l, l_mid_co);
635                         d = edbm_rip_edgedist_squared(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT);
636                         if ((e_best == NULL) || (d < dist_sq)) {
637                                 dist_sq = d;
638
639                                 /* find the edge that is not in this loop */
640                                 e_best = NULL;
641                                 for (i2 = 0; i2 < 3; i2++) {
642                                         if (!BM_edge_in_loop(e_all[i2], l)) {
643                                                 e_best = e_all[i2];
644                                                 break;
645                                         }
646                                 }
647                                 BLI_assert(e_best != NULL);
648                         }
649                 }
650         }
651
652         /* should we go ahead with edge rip or do we need to do special case, split off vertex?:
653          * split off vertex if...
654          * - we cant find an edge - this means we are ripping a faces vert that is connected to other
655          *   geometry only at the vertex.
656          * - the boundary edge total is greater than 2,
657          *   in this case edge split _can_ work but we get far nicer results if we use this special case.
658          * - there are only 2 edges but we are a wire vert. */
659         if ((is_wire == false && totboundary_edge > 2) ||
660             (is_wire == true  && totboundary_edge > 1))
661         {
662                 BMVert **vout;
663                 int vout_len;
664
665                 BM_vert_select_set(bm, v, false);
666
667                 bmesh_kernel_vert_separate(bm, v, &vout, &vout_len, true);
668
669                 if (vout_len < 2) {
670                         MEM_freeN(vout);
671                         /* set selection back to avoid active-unselected vertex */
672                         BM_vert_select_set(bm, v, true);
673                         /* should never happen */
674                         return OPERATOR_CANCELLED;
675                 }
676                 else {
677                         int vi_best = 0;
678
679                         if (ese.ele) {
680                                 BM_select_history_remove(bm, ese.ele);
681                         }
682
683                         dist_sq = FLT_MAX;
684
685                         /* in the loop below we find the best vertex to drag based on its connected geometry,
686                          * either by its face corner, or connected edge (when no faces are attached) */
687                         for (i = 0; i < vout_len; i++) {
688
689                                 if (BM_vert_is_wire(vout[i]) == false) {
690                                         /* find the best face corner */
691                                         BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) {
692                                                 if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
693                                                         float l_mid_co[3];
694
695                                                         edbm_calc_loop_co(l, l_mid_co);
696                                                         d = edbm_rip_edgedist_squared(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT);
697
698                                                         if (d < dist_sq) {
699                                                                 dist_sq = d;
700                                                                 vi_best = i;
701                                                         }
702                                                 }
703                                         }
704                                 }
705                                 else {
706                                         BMEdge *e;
707                                         /* a wire vert, find the best edge */
708                                         BM_ITER_ELEM (e, &iter, vout[i], BM_EDGES_OF_VERT) {
709                                                 if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
710                                                         float e_mid_co[3];
711
712                                                         mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co);
713                                                         d = edbm_rip_edgedist_squared(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT);
714
715                                                         if (d < dist_sq) {
716                                                                 dist_sq = d;
717                                                                 vi_best = i;
718                                                         }
719                                                 }
720                                         }
721                                 }
722                         }
723
724                         /* vout[0]  == best
725                          * vout[1]  == glue
726                          * vout[2+] == splice with glue (when vout_len > 2)
727                          */
728                         if (vi_best != 0) {
729                                 SWAP(BMVert *, vout[0], vout[vi_best]);
730                                 vi_best = 0;
731                         }
732
733                         /* select the vert from the best region */
734                         v = vout[vi_best];
735                         BM_vert_select_set(bm, v, true);
736
737                         if (ese.ele) {
738                                 BM_select_history_store(bm, v);
739                         }
740
741                         /* splice all others back together */
742                         if (vout_len > 2) {
743                                 for (i = 2; i < vout_len; i++) {
744                                         BM_vert_splice(bm, vout[1], vout[i]);
745                                 }
746                         }
747
748                         if (do_fill) {
749                                 /* match extrude vert-order */
750                                 BM_edge_create(bm, vout[1], vout[0], NULL, BM_CREATE_NOP);
751                         }
752
753                         MEM_freeN(vout);
754
755                         return OPERATOR_FINISHED;
756                 }
757         }
758
759         if (!e_best) {
760                 return OPERATOR_CANCELLED;
761         }
762
763         /* *** Execute the split! *** */
764         /* unlike edge split, for single vertex split we only use the operator in one of the cases
765          * but both allocate fill */
766
767         {
768                 BMVert *v_rip;
769                 BMLoop *larr[2];
770                 int larr_len = 0;
771
772                 /* rip two adjacent edges */
773                 if (BM_edge_is_boundary(e_best) || BM_vert_face_count_is_equal(v, 2)) {
774                         /* Don't run the edge split operator in this case */
775
776                         l = BM_edge_vert_share_loop(e_best->l, v);
777                         larr[larr_len] = l;
778                         larr_len++;
779
780                         /* only tag for face-fill (we don't call the operator) */
781                         if (BM_edge_is_boundary(e_best)) {
782                                 BM_elem_flag_enable(e_best, BM_ELEM_TAG);
783                         }
784                         else {
785                                 BM_elem_flag_enable(l->e, BM_ELEM_TAG);
786                                 BM_elem_flag_enable(l->prev->e, BM_ELEM_TAG);
787                         }
788                 }
789                 else {
790                         if (BM_edge_is_manifold(e_best)) {
791                                 BMLoop *l_iter, *l_first;
792                                 l_iter = l_first = e_best->l;
793                                 do {
794                                         larr[larr_len] = BM_edge_vert_share_loop(l_iter, v);
795
796                                         if (do_fill) {
797                                                 /* Only needed when filling...
798                                                  * Also, we never want to tag best edge, that one won't change during split. See T44618. */
799                                                 if (larr[larr_len]->e == e_best) {
800                                                         BM_elem_flag_enable(larr[larr_len]->prev->e, BM_ELEM_TAG);
801                                                 }
802                                                 else {
803                                                         BM_elem_flag_enable(larr[larr_len]->e, BM_ELEM_TAG);
804                                                 }
805                                         }
806                                         larr_len++;
807                                 } while ((l_iter = l_iter->radial_next) != l_first);
808                         }
809                         else {
810                                 /* looks like there are no split edges, we could just return/report-error? - Campbell */
811                         }
812                 }
813
814                 /* keep directly before edgesplit */
815                 if (do_fill) {
816                         fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
817                 }
818
819                 if (larr_len) {
820                         v_rip = BM_face_loop_separate_multi(bm, larr, larr_len);
821                 }
822                 else {
823                         v_rip = NULL;
824                 }
825
826                 if (v_rip) {
827                         BM_vert_select_set(bm, v_rip, true);
828                 }
829                 else {
830                         if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs);
831                         return OPERATOR_CANCELLED;
832                 }
833         }
834
835         {
836                 /* --- select which vert --- */
837                 BMVert *v_best = NULL;
838                 float l_corner_co[3];
839
840                 dist_sq = FLT_MAX;
841                 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
842                         if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
843                                 /* disable by default, re-enable winner at end */
844                                 BM_vert_select_set(bm, v, false);
845                                 BM_select_history_remove(bm, v);
846
847                                 BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
848
849                                         /* check if v_best is null in the _rare_ case there are numeric issues */
850                                         edbm_calc_loop_co(l, l_corner_co);
851                                         d = edbm_rip_edgedist_squared(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT);
852                                         if ((v_best == NULL) || (d < dist_sq)) {
853                                                 v_best = v;
854                                                 dist_sq = d;
855                                         }
856                                 }
857                         }
858                 }
859
860                 if (v_best) {
861                         BM_vert_select_set(bm, v_best, true);
862                         if (ese.ele) {
863                                 BM_select_history_store(bm, v_best);
864                         }
865                 }
866         }
867
868         if (do_fill && fill_uloop_pairs) {
869                 edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs);
870                 MEM_freeN(fill_uloop_pairs);
871         }
872
873
874         if (totvert_orig == bm->totvert) {
875                 return OPERATOR_CANCELLED;
876         }
877
878         return OPERATOR_FINISHED;
879 }
880
881 /**
882  * This is the main edge ripping function
883  */
884 static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obedit, bool do_fill)
885 {
886         UnorderedLoopPair *fill_uloop_pairs = NULL;
887         ARegion *ar = CTX_wm_region(C);
888         RegionView3D *rv3d = CTX_wm_region_view3d(C);
889         BMEditMesh *em = BKE_editmesh_from_object(obedit);
890         BMesh *bm = em->bm;
891         BMIter iter, eiter;
892         BMLoop *l;
893         BMEdge *e_best;
894         BMVert *v;
895         const int totedge_orig = bm->totedge;
896         float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
897
898         EdgeLoopPair *eloop_pairs;
899
900         ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
901
902         /* important this runs on the original selection, before tampering with tagging */
903         eloop_pairs = edbm_ripsel_looptag_helper(bm);
904
905         /* expand edge selection */
906         BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
907                 BMEdge *e;
908                 bool all_manifold;
909                 int totedge_manifold;  /* manifold, visible edges */
910                 int i;
911
912                 e_best = NULL;
913                 i = 0;
914                 totedge_manifold = 0;
915                 all_manifold = true;
916                 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
917
918                         if (!BM_edge_is_wire(e) &&
919                             !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
920                         {
921                                 /* important to check selection rather then tag here
922                                  * else we get feedback loop */
923                                 if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
924                                         e_best = e;
925                                         i++;
926                                 }
927                                 totedge_manifold++;
928                         }
929
930                         /** #BM_vert_other_disk_edge has no hidden checks so don't check hidden here */
931                         if ((all_manifold == true) && (BM_edge_is_manifold(e) == false)) {
932                                 all_manifold = false;
933                         }
934                 }
935
936                 /* single edge, extend */
937                 if (i == 1 && e_best->l) {
938                         /* note: if the case of 3 edges has one change in loop stepping,
939                          * if this becomes more involved we may be better off splitting
940                          * the 3 edge case into its own else-if branch */
941                         if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == false)) {
942                                 BMLoop *l_a = e_best->l;
943                                 BMLoop *l_b = l_a->radial_next;
944
945                                 /* find the best face to follow, this way the edge won't point away from
946                                  * the mouse when there are more than 4 (takes the shortest face fan around) */
947                                 l = (edbm_rip_edge_side_measure(e_best, l_a, ar, projectMat, fmval) <
948                                      edbm_rip_edge_side_measure(e_best, l_b, ar, projectMat, fmval)) ? l_a : l_b;
949
950                                 l = BM_loop_other_edge_loop(l, v);
951                                 /* important edge is manifold else we can be attempting to split off a fan that don't budge,
952                                  * not crashing but adds duplicate edge. */
953                                 if (BM_edge_is_manifold(l->e)) {
954                                         l = l->radial_next;
955
956                                         if (totedge_manifold != 3)
957                                                 l = BM_loop_other_edge_loop(l, v);
958
959                                         if (l) {
960                                                 BLI_assert(!BM_elem_flag_test(l->e, BM_ELEM_TAG));
961                                                 BM_elem_flag_enable(l->e, BM_ELEM_TAG);
962                                         }
963                                 }
964                         }
965                         else {
966                                 e = BM_vert_other_disk_edge(v, e_best);
967
968                                 if (e) {
969                                         BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG));
970                                         BM_elem_flag_enable(e, BM_ELEM_TAG);
971                                 }
972                         }
973                 }
974         }
975
976         /* keep directly before edgesplit */
977         if (do_fill) {
978                 fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
979         }
980
981         BM_mesh_edgesplit(em->bm, true, true, true);
982
983         /* note: the output of the bmesh operator is ignored, since we built
984          * the contiguous loop pairs to split already, its possible that some
985          * edge did not split even though it was tagged which would not work
986          * as expected (but not crash), however there are checks to ensure
987          * tagged edges will split. So far its not been an issue. */
988         edbm_ripsel_deselect_helper(bm, eloop_pairs,
989                                     ar, projectMat, fmval);
990         MEM_freeN(eloop_pairs);
991
992         /* deselect loose verts */
993         BM_mesh_select_mode_clean_ex(bm, SCE_SELECT_EDGE);
994
995         if (do_fill && fill_uloop_pairs) {
996                 edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs);
997                 MEM_freeN(fill_uloop_pairs);
998         }
999
1000         if (totedge_orig == bm->totedge) {
1001                 return OPERATOR_CANCELLED;
1002         }
1003
1004         BM_select_history_validate(bm);
1005
1006         return OPERATOR_FINISHED;
1007 }
1008
1009 /* based on mouse cursor position, it defines how is being ripped */
1010 static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1011 {
1012         ViewLayer *view_layer = CTX_data_view_layer(C);
1013         uint objects_len = 0;
1014         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
1015         const bool do_fill = RNA_boolean_get(op->ptr, "use_fill");
1016
1017         bool no_vertex_selected = true;
1018         bool error_face_selected = true;
1019         bool error_disconnected_vertices = true;
1020         bool error_rip_failed = true;
1021
1022         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1023                 Object *obedit = objects[ob_index];
1024                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1025
1026                 BMesh *bm = em->bm;
1027                 BMIter iter;
1028                 BMEdge *e;
1029                 const bool singlesel = (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0);
1030                 int ret;
1031
1032                 if (em->bm->totvertsel == 0) {
1033                         continue;
1034                 }
1035                 no_vertex_selected = false;
1036
1037                 /* running in face mode hardly makes sense, so convert to region loop and rip */
1038                 if (bm->totfacesel) {
1039                         /* highly nifty but hard to support since the operator can fail and we're left
1040                          * with modified selection */
1041                         // WM_operator_name_call(C, "MESH_OT_region_to_loop", WM_OP_INVOKE_DEFAULT, NULL);
1042                         continue;
1043                 }
1044                 error_face_selected = false;
1045
1046                 /* we could support this, but not for now */
1047                 if ((bm->totvertsel > 1) && (bm->totedgesel == 0)) {
1048                         continue;
1049                 }
1050                 error_disconnected_vertices = false;
1051
1052                 /* note on selection:
1053                  * When calling edge split we operate on tagged edges rather then selected
1054                  * this is important because the edges to operate on are extended by one,
1055                  * but the selection is left alone.
1056                  *
1057                  * After calling edge split - the duplicated edges have the same selection state as the
1058                  * original, so all we do is de-select the far side from the mouse and we have a
1059                  * useful selection for grabbing.
1060                  */
1061
1062                 /* BM_ELEM_SELECT --> BM_ELEM_TAG */
1063                 BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
1064                         BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
1065                 }
1066
1067                 /* split 2 main parts of this operator out into vertex and edge ripping */
1068                 if (singlesel) {
1069                         ret = edbm_rip_invoke__vert(C, event, obedit, do_fill);
1070                 }
1071                 else {
1072                         ret = edbm_rip_invoke__edge(C, event, obedit, do_fill);
1073                 }
1074
1075                 if (ret != OPERATOR_FINISHED) {
1076                         continue;
1077                 }
1078
1079                 BLI_assert(singlesel ? (bm->totvertsel > 0) : (bm->totedgesel > 0));
1080
1081                 if (bm->totvertsel == 0) {
1082                         continue;
1083                 }
1084                 error_rip_failed = false;
1085
1086                 EDBM_update_generic(em, true, true);
1087         }
1088
1089         MEM_freeN(objects);
1090
1091         if (no_vertex_selected) {
1092                 /* Ignore it. */
1093                 return OPERATOR_CANCELLED;
1094         }
1095         else if (error_face_selected) {
1096                 BKE_report(op->reports, RPT_ERROR, "Cannot rip selected faces");
1097                 return OPERATOR_CANCELLED;
1098         }
1099         else if (error_disconnected_vertices) {
1100                 BKE_report(op->reports, RPT_ERROR, "Cannot rip multiple disconnected vertices");
1101                 return OPERATOR_CANCELLED;
1102         }
1103         else if (error_rip_failed) {
1104                 BKE_report(op->reports, RPT_ERROR, "Rip failed");
1105                 return OPERATOR_CANCELLED;
1106         }
1107         /* No errors, everything went fine. */
1108         return OPERATOR_FINISHED;
1109 }
1110
1111
1112 void MESH_OT_rip(wmOperatorType *ot)
1113 {
1114         /* identifiers */
1115         ot->name = "Rip";
1116         ot->idname = "MESH_OT_rip";
1117         ot->description = "Disconnect vertex or edges from connected geometry";
1118
1119         /* api callbacks */
1120         ot->invoke = edbm_rip_invoke;
1121         ot->poll = EDBM_view3d_poll;
1122
1123         /* flags */
1124         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1125
1126         /* to give to transform */
1127         Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY);
1128         RNA_def_boolean(ot->srna, "use_fill", false, "Fill", "Fill the ripped region");
1129 }