Fix T63646: Box/Lasso select fails to de-select
[blender.git] / source / blender / editors / mesh / editface.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup edmesh
19  */
20
21 #include "MEM_guardedalloc.h"
22
23 #include "BLI_blenlib.h"
24 #include "BLI_math.h"
25 #include "BLI_bitmap.h"
26
27 #include "IMB_imbuf_types.h"
28 #include "IMB_imbuf.h"
29
30 #include "DNA_meshdata_types.h"
31 #include "DNA_mesh_types.h"
32 #include "DNA_object_types.h"
33
34 #include "BKE_context.h"
35 #include "BKE_customdata.h"
36 #include "BKE_global.h"
37 #include "BKE_mesh.h"
38
39 #include "BIF_gl.h"
40
41 #include "ED_mesh.h"
42 #include "ED_screen.h"
43 #include "ED_select_utils.h"
44 #include "ED_view3d.h"
45
46 #include "WM_api.h"
47 #include "WM_types.h"
48
49 #include "GPU_draw.h"
50
51 #include "DEG_depsgraph.h"
52 #include "DEG_depsgraph_query.h"
53
54 /* own include */
55
56 /* copy the face flags, most importantly selection from the mesh to the final derived mesh,
57  * use in object mode when selecting faces (while painting) */
58 void paintface_flush_flags(struct bContext *C, Object *ob, short flag)
59 {
60         Mesh *me = BKE_mesh_from_object(ob);
61         MPoly *polys, *mp_orig;
62         const int *index_array = NULL;
63         int totpoly;
64         int i;
65
66         BLI_assert((flag & ~(SELECT | ME_HIDE)) == 0);
67
68         if (me == NULL)
69                 return;
70
71         /* note, call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags */
72
73         /* we could call this directly in all areas that change selection,
74          * since this could become slow for realtime updates (circle-select for eg) */
75         if (flag & SELECT) {
76                 BKE_mesh_flush_select_from_polys(me);
77         }
78
79         Depsgraph *depsgraph = CTX_data_depsgraph(C);
80         Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
81
82         if (ob_eval == NULL) {
83                 return;
84         }
85
86         Mesh *me_orig = ob_eval->runtime.mesh_orig;
87         Mesh *me_eval = ob_eval->runtime.mesh_eval;
88         bool updated = false;
89
90         if (me_orig != NULL && me_eval != NULL && me_orig->totpoly == me->totpoly) {
91                 /* Update the COW copy of the mesh. */
92                 for (i = 0; i < me->totpoly; i++) {
93                         me_orig->mpoly[i].flag = me->mpoly[i].flag;
94                 }
95
96                 /* If the mesh has only deform modifiers, the evaluated mesh shares arrays. */
97                 if (me_eval->mpoly == me_orig->mpoly) {
98                         updated = true;
99                 }
100                 /* Mesh polys => Final derived polys */
101                 else if ((index_array = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
102                         polys = me_eval->mpoly;
103                         totpoly = me_eval->totpoly;
104
105                         /* loop over final derived polys */
106                         for (i = 0; i < totpoly; i++) {
107                                 if (index_array[i] != ORIGINDEX_NONE) {
108                                         /* Copy flags onto the final derived poly from the original mesh poly */
109                                         mp_orig = me->mpoly + index_array[i];
110                                         polys[i].flag = mp_orig->flag;
111
112                                 }
113                         }
114
115                         updated = true;
116                 }
117         }
118
119         if (updated) {
120                 if (flag & ME_HIDE) {
121                         BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_ALL);
122                 }
123                 else {
124                         BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_SELECT);
125                 }
126
127                 DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
128         }
129         else {
130                 DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
131         }
132
133         WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
134 }
135
136 void paintface_hide(bContext *C, Object *ob, const bool unselected)
137 {
138         Mesh *me;
139         MPoly *mpoly;
140         int a;
141
142         me = BKE_mesh_from_object(ob);
143         if (me == NULL || me->totpoly == 0) return;
144
145         mpoly = me->mpoly;
146         a = me->totpoly;
147         while (a--) {
148                 if ((mpoly->flag & ME_HIDE) == 0) {
149                         if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) {
150                                 mpoly->flag |= ME_HIDE;
151                         }
152                 }
153
154                 if (mpoly->flag & ME_HIDE) {
155                         mpoly->flag &= ~ME_FACE_SEL;
156                 }
157
158                 mpoly++;
159         }
160
161         BKE_mesh_flush_hidden_from_polys(me);
162
163         paintface_flush_flags(C, ob, SELECT | ME_HIDE);
164 }
165
166
167 void paintface_reveal(bContext *C, Object *ob, const bool select)
168 {
169         Mesh *me;
170         MPoly *mpoly;
171         int a;
172
173         me = BKE_mesh_from_object(ob);
174         if (me == NULL || me->totpoly == 0) return;
175
176         mpoly = me->mpoly;
177         a = me->totpoly;
178         while (a--) {
179                 if (mpoly->flag & ME_HIDE) {
180                         SET_FLAG_FROM_TEST(mpoly->flag, select, ME_FACE_SEL);
181                         mpoly->flag &= ~ME_HIDE;
182                 }
183                 mpoly++;
184         }
185
186         BKE_mesh_flush_hidden_from_polys(me);
187
188         paintface_flush_flags(C, ob, SELECT | ME_HIDE);
189 }
190
191 /* Set tface seams based on edge data, uses hash table to find seam edges. */
192
193 static void select_linked_tfaces_with_seams(Mesh *me, const unsigned int index, const bool select)
194 {
195         MPoly *mp;
196         MLoop *ml;
197         int a, b;
198         bool do_it = true;
199         bool mark = false;
200
201         BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__);
202         BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
203
204         if (index != (unsigned int)-1) {
205                 /* only put face under cursor in array */
206                 mp = &me->mpoly[index];
207                 BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
208                 BLI_BITMAP_ENABLE(poly_tag, index);
209         }
210         else {
211                 /* fill array by selection */
212                 mp = me->mpoly;
213                 for (a = 0; a < me->totpoly; a++, mp++) {
214                         if (mp->flag & ME_HIDE) {
215                                 /* pass */
216                         }
217                         else if (mp->flag & ME_FACE_SEL) {
218                                 BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
219                                 BLI_BITMAP_ENABLE(poly_tag, a);
220                         }
221                 }
222         }
223
224         while (do_it) {
225                 do_it = false;
226
227                 /* expand selection */
228                 mp = me->mpoly;
229                 for (a = 0; a < me->totpoly; a++, mp++) {
230                         if (mp->flag & ME_HIDE)
231                                 continue;
232
233                         if (!BLI_BITMAP_TEST(poly_tag, a)) {
234                                 mark = false;
235
236                                 ml = me->mloop + mp->loopstart;
237                                 for (b = 0; b < mp->totloop; b++, ml++) {
238                                         if ((me->medge[ml->e].flag & ME_SEAM) == 0) {
239                                                 if (BLI_BITMAP_TEST(edge_tag, ml->e)) {
240                                                         mark = true;
241                                                         break;
242                                                 }
243                                         }
244                                 }
245
246                                 if (mark) {
247                                         BLI_BITMAP_ENABLE(poly_tag, a);
248                                         BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
249                                         do_it = true;
250                                 }
251                         }
252                 }
253         }
254
255         MEM_freeN(edge_tag);
256
257         for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) {
258                 if (BLI_BITMAP_TEST(poly_tag, a)) {
259                         SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL);
260                 }
261         }
262
263         MEM_freeN(poly_tag);
264 }
265
266 void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const bool select)
267 {
268         Mesh *me;
269         unsigned int index = (unsigned int)-1;
270
271         me = BKE_mesh_from_object(ob);
272         if (me == NULL || me->totpoly == 0) return;
273
274         if (mval) {
275                 if (!ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
276                         return;
277                 }
278         }
279
280         select_linked_tfaces_with_seams(me, index, select);
281
282         paintface_flush_flags(C, ob, SELECT);
283 }
284
285 bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool flush_flags)
286 {
287         Mesh *me;
288         MPoly *mpoly;
289         int a;
290
291         me = BKE_mesh_from_object(ob);
292         if (me == NULL) {
293                 return false;
294         }
295
296         if (action == SEL_TOGGLE) {
297                 action = SEL_SELECT;
298
299                 mpoly = me->mpoly;
300                 a = me->totpoly;
301                 while (a--) {
302                         if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) {
303                                 action = SEL_DESELECT;
304                                 break;
305                         }
306                         mpoly++;
307                 }
308         }
309
310         bool changed = false;
311
312         mpoly = me->mpoly;
313         a = me->totpoly;
314         while (a--) {
315                 if ((mpoly->flag & ME_HIDE) == 0) {
316                         switch (action) {
317                                 case SEL_SELECT:
318                                         if ((mpoly->flag & ME_FACE_SEL) == 0) {
319                                                 mpoly->flag |= ME_FACE_SEL;
320                                                 changed = true;
321                                         }
322                                         break;
323                                 case SEL_DESELECT:
324                                         if ((mpoly->flag & ME_FACE_SEL) != 0) {
325                                                 mpoly->flag &= ~ME_FACE_SEL;
326                                                 changed = true;
327                                         }
328                                         break;
329                                 case SEL_INVERT:
330                                         mpoly->flag ^= ME_FACE_SEL;
331                                         changed = true;
332                                         break;
333                         }
334                 }
335                 mpoly++;
336         }
337
338         if (changed) {
339                 if (flush_flags) {
340                         paintface_flush_flags(C, ob, SELECT);
341                 }
342         }
343         return changed;
344 }
345
346 bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
347 {
348         const Mesh *me;
349         const MPoly *mp;
350         const MLoop *ml;
351         const MVert *mvert;
352         int a, b;
353         bool ok = false;
354         float vec[3], bmat[3][3];
355
356         me = BKE_mesh_from_object(ob);
357         if (!me || !me->mloopuv) {
358                 return ok;
359         }
360
361         copy_m3_m4(bmat, ob->obmat);
362
363         mvert = me->mvert;
364         mp = me->mpoly;
365         for (a = me->totpoly; a > 0; a--, mp++) {
366                 if (mp->flag & ME_HIDE || !(mp->flag & ME_FACE_SEL))
367                         continue;
368
369                 ml = me->mloop + mp->totloop;
370                 for (b = 0; b < mp->totloop; b++, ml++) {
371                         mul_v3_m3v3(vec, bmat, mvert[ml->v].co);
372                         add_v3_v3v3(vec, vec, ob->obmat[3]);
373                         minmax_v3v3_v3(r_min, r_max, vec);
374                 }
375
376                 ok = true;
377         }
378
379         return ok;
380 }
381
382 bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], bool extend, bool deselect, bool toggle)
383 {
384         Mesh *me;
385         MPoly *mpoly_sel;
386         uint index;
387
388         /* Get the face under the cursor */
389         me = BKE_mesh_from_object(ob);
390
391         if (!ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
392                 return false;
393         }
394
395         if (index >= me->totpoly) {
396                 return false;
397         }
398
399         mpoly_sel = me->mpoly + index;
400         if (mpoly_sel->flag & ME_HIDE) return false;
401
402         /* clear flags */
403         if (!extend && !deselect && !toggle) {
404                 paintface_deselect_all_visible(C, ob, SEL_DESELECT, false);
405         }
406
407         me->act_face = (int)index;
408
409         if (extend) {
410                 mpoly_sel->flag |= ME_FACE_SEL;
411         }
412         else if (deselect) {
413                 mpoly_sel->flag &= ~ME_FACE_SEL;
414         }
415         else if (toggle) {
416                 if (mpoly_sel->flag & ME_FACE_SEL)
417                         mpoly_sel->flag &= ~ME_FACE_SEL;
418                 else
419                         mpoly_sel->flag |= ME_FACE_SEL;
420         }
421         else {
422                 mpoly_sel->flag |= ME_FACE_SEL;
423         }
424
425         /* image window redraw */
426
427         paintface_flush_flags(C, ob, SELECT);
428         ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
429         return true;
430 }
431
432 bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
433 {
434         Object *ob = vc->obact;
435         Mesh *me;
436
437         me = BKE_mesh_from_object(ob);
438         if ((me == NULL) || (me->totpoly == 0)) {
439                 return false;
440         }
441
442         bool changed = false;
443         if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
444                 changed |= paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
445         }
446
447         if (BLI_rcti_is_empty(rect)) {
448                 /* pass */
449         }
450         else {
451                 MPoly *mpoly;
452                 uint *rt;
453                 int a, index;
454
455                 char *selar = MEM_callocN(me->totpoly + 1, "selar");
456
457                 uint buf_len;
458                 uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
459
460                 rt = buf;
461
462                 a = buf_len;
463                 while (a--) {
464                         if (*rt) {
465                                 index = *rt;
466                                 if (index <= me->totpoly) {
467                                         selar[index] = 1;
468                                 }
469                         }
470                         rt++;
471                 }
472
473                 mpoly = me->mpoly;
474                 for (a = 1; a <= me->totpoly; a++, mpoly++) {
475                         if ((mpoly->flag & ME_HIDE) == 0) {
476                                 const bool is_select = mpoly->flag & ME_FACE_SEL;
477                                 const bool is_inside = (selar[a] != 0);
478                                 const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
479                                 if (sel_op_result != -1) {
480                                         SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
481                                         changed = true;
482                                 }
483                         }
484                 }
485
486                 MEM_freeN(buf);
487                 MEM_freeN(selar);
488
489 #ifdef __APPLE__
490                 glReadBuffer(GL_BACK);
491 #endif
492         }
493
494         if (changed) {
495                 paintface_flush_flags(vc->C, vc->obact, SELECT);
496         }
497         return changed;
498 }
499
500
501 /*  (similar to void paintface_flush_flags(Object *ob))
502  * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
503  * use in object mode when selecting vertices (while painting) */
504 void paintvert_flush_flags(Object *ob)
505 {
506         Mesh *me = BKE_mesh_from_object(ob);
507         Mesh *me_eval = ob->runtime.mesh_eval;
508         MVert *mvert_eval, *mv;
509         const int *index_array = NULL;
510         int totvert;
511         int i;
512
513         if (me == NULL)
514                 return;
515
516         /* we could call this directly in all areas that change selection,
517          * since this could become slow for realtime updates (circle-select for eg) */
518         BKE_mesh_flush_select_from_verts(me);
519
520         if (me_eval == NULL)
521                 return;
522
523         index_array = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
524
525         mvert_eval = me_eval->mvert;
526         totvert = me_eval->totvert;
527
528         mv = mvert_eval;
529
530         if (index_array) {
531                 int orig_index;
532                 for (i = 0; i < totvert; i++, mv++) {
533                         orig_index = index_array[i];
534                         if (orig_index != ORIGINDEX_NONE) {
535                                 mv->flag = me->mvert[index_array[i]].flag;
536                         }
537                 }
538         }
539         else {
540                 for (i = 0; i < totvert; i++, mv++) {
541                         mv->flag = me->mvert[i].flag;
542                 }
543         }
544
545         BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL);
546 }
547
548 void paintvert_tag_select_update(struct bContext *C, struct Object *ob)
549 {
550         DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
551         WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
552 }
553
554 /*  note: if the caller passes false to flush_flags,
555  *  then they will need to run paintvert_flush_flags(ob) themselves */
556 bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
557 {
558         Mesh *me;
559         MVert *mvert;
560         int a;
561
562         me = BKE_mesh_from_object(ob);
563         if (me == NULL) {
564                 return false;
565         }
566
567         if (action == SEL_TOGGLE) {
568                 action = SEL_SELECT;
569
570                 mvert = me->mvert;
571                 a = me->totvert;
572                 while (a--) {
573                         if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
574                                 action = SEL_DESELECT;
575                                 break;
576                         }
577                         mvert++;
578                 }
579         }
580
581         bool changed = false;
582         mvert = me->mvert;
583         a = me->totvert;
584         while (a--) {
585                 if ((mvert->flag & ME_HIDE) == 0) {
586                         switch (action) {
587                                 case SEL_SELECT:
588                                         if ((mvert->flag & SELECT) == 0) {
589                                                 mvert->flag |= SELECT;
590                                                 changed = true;
591                                         }
592                                         break;
593                                 case SEL_DESELECT:
594                                         if ((mvert->flag & SELECT) != 0) {
595                                                 mvert->flag &= ~SELECT;
596                                                 changed = true;
597                                         }
598                                         break;
599                                 case SEL_INVERT:
600                                         mvert->flag ^= SELECT;
601                                         changed = true;
602                                         break;
603                         }
604                 }
605                 mvert++;
606         }
607
608         if (changed) {
609                 /* handle mselect */
610                 if (action == SEL_SELECT) {
611                         /* pass */
612                 }
613                 else if (ELEM(action, SEL_DESELECT, SEL_INVERT)) {
614                         BKE_mesh_mselect_clear(me);
615                 }
616                 else {
617                         BKE_mesh_mselect_validate(me);
618                 }
619
620                 if (flush_flags) {
621                         paintvert_flush_flags(ob);
622                 }
623         }
624         return changed;
625 }
626
627 void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
628 {
629         Mesh *me = BKE_mesh_from_object(ob);
630         MVert *mv;
631         MDeformVert *dv;
632         int a, tot;
633
634         if (me == NULL || me->dvert == NULL) {
635                 return;
636         }
637
638         if (!extend) {
639                 paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
640         }
641
642         dv = me->dvert;
643         tot = me->totvert;
644
645         for (a = 0, mv = me->mvert; a < tot; a++, mv++, dv++) {
646                 if ((mv->flag & ME_HIDE) == 0) {
647                         if (dv->dw == NULL) {
648                                 /* if null weight then not grouped */
649                                 mv->flag |= SELECT;
650                         }
651                 }
652         }
653
654         if (flush_flags) {
655                 paintvert_flush_flags(ob);
656         }
657 }