ef2e01e05fb70b81ae9a66d86614e8e8f14262c8
[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         MPoly *mpoly;
437         uint *rt;
438         char *selar;
439         int a, index;
440
441         me = BKE_mesh_from_object(ob);
442         if ((me == NULL) || (me->totpoly == 0) || BLI_rcti_is_empty(rect)) {
443                 return false;
444         }
445
446         selar = MEM_callocN(me->totpoly + 1, "selar");
447
448         bool changed = false;
449         if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
450                 changed |= paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
451         }
452
453         uint buf_len;
454         uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
455
456         rt = buf;
457
458         a = buf_len;
459         while (a--) {
460                 if (*rt) {
461                         index = *rt;
462                         if (index <= me->totpoly) {
463                                 selar[index] = 1;
464                         }
465                 }
466                 rt++;
467         }
468
469         mpoly = me->mpoly;
470         for (a = 1; a <= me->totpoly; a++, mpoly++) {
471                 if ((mpoly->flag & ME_HIDE) == 0) {
472                         const bool is_select = mpoly->flag & ME_FACE_SEL;
473                         const bool is_inside = (selar[a] != 0);
474                         const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
475                         if (sel_op_result != -1) {
476                                 SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
477                                 changed = true;
478                         }
479                 }
480         }
481
482         MEM_freeN(buf);
483         MEM_freeN(selar);
484
485 #ifdef __APPLE__
486         glReadBuffer(GL_BACK);
487 #endif
488
489         if (changed) {
490                 paintface_flush_flags(vc->C, vc->obact, SELECT);
491         }
492         return changed;
493 }
494
495
496 /*  (similar to void paintface_flush_flags(Object *ob))
497  * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
498  * use in object mode when selecting vertices (while painting) */
499 void paintvert_flush_flags(Object *ob)
500 {
501         Mesh *me = BKE_mesh_from_object(ob);
502         Mesh *me_eval = ob->runtime.mesh_eval;
503         MVert *mvert_eval, *mv;
504         const int *index_array = NULL;
505         int totvert;
506         int i;
507
508         if (me == NULL)
509                 return;
510
511         /* we could call this directly in all areas that change selection,
512          * since this could become slow for realtime updates (circle-select for eg) */
513         BKE_mesh_flush_select_from_verts(me);
514
515         if (me_eval == NULL)
516                 return;
517
518         index_array = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
519
520         mvert_eval = me_eval->mvert;
521         totvert = me_eval->totvert;
522
523         mv = mvert_eval;
524
525         if (index_array) {
526                 int orig_index;
527                 for (i = 0; i < totvert; i++, mv++) {
528                         orig_index = index_array[i];
529                         if (orig_index != ORIGINDEX_NONE) {
530                                 mv->flag = me->mvert[index_array[i]].flag;
531                         }
532                 }
533         }
534         else {
535                 for (i = 0; i < totvert; i++, mv++) {
536                         mv->flag = me->mvert[i].flag;
537                 }
538         }
539
540         BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL);
541 }
542
543 void paintvert_tag_select_update(struct bContext *C, struct Object *ob)
544 {
545         DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
546         WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
547 }
548
549 /*  note: if the caller passes false to flush_flags,
550  *  then they will need to run paintvert_flush_flags(ob) themselves */
551 bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
552 {
553         Mesh *me;
554         MVert *mvert;
555         int a;
556
557         me = BKE_mesh_from_object(ob);
558         if (me == NULL) {
559                 return false;
560         }
561
562         if (action == SEL_TOGGLE) {
563                 action = SEL_SELECT;
564
565                 mvert = me->mvert;
566                 a = me->totvert;
567                 while (a--) {
568                         if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
569                                 action = SEL_DESELECT;
570                                 break;
571                         }
572                         mvert++;
573                 }
574         }
575
576         bool changed = false;
577         mvert = me->mvert;
578         a = me->totvert;
579         while (a--) {
580                 if ((mvert->flag & ME_HIDE) == 0) {
581                         switch (action) {
582                                 case SEL_SELECT:
583                                         if ((mvert->flag & SELECT) == 0) {
584                                                 mvert->flag |= SELECT;
585                                                 changed = true;
586                                         }
587                                         break;
588                                 case SEL_DESELECT:
589                                         if ((mvert->flag & SELECT) != 0) {
590                                                 mvert->flag &= ~SELECT;
591                                                 changed = true;
592                                         }
593                                         break;
594                                 case SEL_INVERT:
595                                         mvert->flag ^= SELECT;
596                                         changed = true;
597                                         break;
598                         }
599                 }
600                 mvert++;
601         }
602
603         if (changed) {
604                 /* handle mselect */
605                 if (action == SEL_SELECT) {
606                         /* pass */
607                 }
608                 else if (ELEM(action, SEL_DESELECT, SEL_INVERT)) {
609                         BKE_mesh_mselect_clear(me);
610                 }
611                 else {
612                         BKE_mesh_mselect_validate(me);
613                 }
614
615                 if (flush_flags) {
616                         paintvert_flush_flags(ob);
617                 }
618         }
619         return changed;
620 }
621
622 void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
623 {
624         Mesh *me = BKE_mesh_from_object(ob);
625         MVert *mv;
626         MDeformVert *dv;
627         int a, tot;
628
629         if (me == NULL || me->dvert == NULL) {
630                 return;
631         }
632
633         if (!extend) {
634                 paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
635         }
636
637         dv = me->dvert;
638         tot = me->totvert;
639
640         for (a = 0, mv = me->mvert; a < tot; a++, mv++, dv++) {
641                 if ((mv->flag & ME_HIDE) == 0) {
642                         if (dv->dw == NULL) {
643                                 /* if null weight then not grouped */
644                                 mv->flag |= SELECT;
645                         }
646                 }
647         }
648
649         if (flush_flags) {
650                 paintvert_flush_flags(ob);
651         }
652 }