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