Merge branch 'blender2.7'
[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 blender/editors/mesh/editface.c
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, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
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 void 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) return;
293
294         if (action == SEL_TOGGLE) {
295                 action = SEL_SELECT;
296
297                 mpoly = me->mpoly;
298                 a = me->totpoly;
299                 while (a--) {
300                         if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) {
301                                 action = SEL_DESELECT;
302                                 break;
303                         }
304                         mpoly++;
305                 }
306         }
307
308         mpoly = me->mpoly;
309         a = me->totpoly;
310         while (a--) {
311                 if ((mpoly->flag & ME_HIDE) == 0) {
312                         switch (action) {
313                                 case SEL_SELECT:
314                                         mpoly->flag |= ME_FACE_SEL;
315                                         break;
316                                 case SEL_DESELECT:
317                                         mpoly->flag &= ~ME_FACE_SEL;
318                                         break;
319                                 case SEL_INVERT:
320                                         mpoly->flag ^= ME_FACE_SEL;
321                                         break;
322                         }
323                 }
324                 mpoly++;
325         }
326
327         if (flush_flags) {
328                 paintface_flush_flags(C, ob, SELECT);
329         }
330 }
331
332 bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
333 {
334         const Mesh *me;
335         const MPoly *mp;
336         const MLoop *ml;
337         const MVert *mvert;
338         int a, b;
339         bool ok = false;
340         float vec[3], bmat[3][3];
341
342         me = BKE_mesh_from_object(ob);
343         if (!me || !me->mloopuv) {
344                 return ok;
345         }
346
347         copy_m3_m4(bmat, ob->obmat);
348
349         mvert = me->mvert;
350         mp = me->mpoly;
351         for (a = me->totpoly; a > 0; a--, mp++) {
352                 if (mp->flag & ME_HIDE || !(mp->flag & ME_FACE_SEL))
353                         continue;
354
355                 ml = me->mloop + mp->totloop;
356                 for (b = 0; b < mp->totloop; b++, ml++) {
357                         mul_v3_m3v3(vec, bmat, mvert[ml->v].co);
358                         add_v3_v3v3(vec, vec, ob->obmat[3]);
359                         minmax_v3v3_v3(r_min, r_max, vec);
360                 }
361
362                 ok = true;
363         }
364
365         return ok;
366 }
367
368 bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], bool extend, bool deselect, bool toggle)
369 {
370         Mesh *me;
371         MPoly *mpoly, *mpoly_sel;
372         unsigned int a, index;
373
374         /* Get the face under the cursor */
375         me = BKE_mesh_from_object(ob);
376
377         if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE))
378                 return false;
379
380         if (index >= me->totpoly)
381                 return false;
382
383         mpoly_sel = me->mpoly + index;
384         if (mpoly_sel->flag & ME_HIDE) return false;
385
386         /* clear flags */
387         mpoly = me->mpoly;
388         a = me->totpoly;
389         if (!extend && !deselect && !toggle) {
390                 while (a--) {
391                         mpoly->flag &= ~ME_FACE_SEL;
392                         mpoly++;
393                 }
394         }
395
396         me->act_face = (int)index;
397
398         if (extend) {
399                 mpoly_sel->flag |= ME_FACE_SEL;
400         }
401         else if (deselect) {
402                 mpoly_sel->flag &= ~ME_FACE_SEL;
403         }
404         else if (toggle) {
405                 if (mpoly_sel->flag & ME_FACE_SEL)
406                         mpoly_sel->flag &= ~ME_FACE_SEL;
407                 else
408                         mpoly_sel->flag |= ME_FACE_SEL;
409         }
410         else {
411                 mpoly_sel->flag |= ME_FACE_SEL;
412         }
413
414         /* image window redraw */
415
416         paintface_flush_flags(C, ob, SELECT);
417         ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
418         return true;
419 }
420
421 int do_paintface_box_select(ViewContext *vc, rcti *rect, int sel_op)
422 {
423         Object *ob = vc->obact;
424         Mesh *me;
425         MPoly *mpoly;
426         struct ImBuf *ibuf;
427         unsigned int *rt;
428         char *selar;
429         int a, index;
430         const int size[2] = {
431             BLI_rcti_size_x(rect) + 1,
432             BLI_rcti_size_y(rect) + 1};
433
434         me = BKE_mesh_from_object(ob);
435
436         if ((me == NULL) || (me->totpoly == 0) || (size[0] * size[1] <= 0)) {
437                 return OPERATOR_CANCELLED;
438         }
439
440         selar = MEM_callocN(me->totpoly + 1, "selar");
441
442         if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
443                 paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
444         }
445
446         ED_view3d_backbuf_validate(vc);
447
448         ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
449         rt = ibuf->rect;
450         view3d_opengl_read_pixels(vc->ar, rect->xmin, rect->ymin, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
451         if (ENDIAN_ORDER == B_ENDIAN) {
452                 IMB_convert_rgba_to_abgr(ibuf);
453         }
454         GPU_select_to_index_array(ibuf->rect, size[0] * size[1]);
455
456         a = size[0] * size[1];
457         while (a--) {
458                 if (*rt) {
459                         index = *rt;
460                         if (index <= me->totpoly) {
461                                 selar[index] = 1;
462                         }
463                 }
464                 rt++;
465         }
466
467         mpoly = me->mpoly;
468         for (a = 1; a <= me->totpoly; a++, mpoly++) {
469                 if ((mpoly->flag & ME_HIDE) == 0) {
470                         const bool is_select = mpoly->flag & ME_FACE_SEL;
471                         const bool is_inside = (selar[a] != 0);
472                         const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
473                         if (sel_op_result != -1) {
474                                 SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
475                         }
476                 }
477         }
478
479         IMB_freeImBuf(ibuf);
480         MEM_freeN(selar);
481
482 #ifdef __APPLE__
483         glReadBuffer(GL_BACK);
484 #endif
485
486         paintface_flush_flags(vc->C, vc->obact, SELECT);
487
488         return OPERATOR_FINISHED;
489 }
490
491
492 /*  (similar to void paintface_flush_flags(Object *ob))
493  * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
494  * use in object mode when selecting vertices (while painting) */
495 void paintvert_flush_flags(Object *ob)
496 {
497         Mesh *me = BKE_mesh_from_object(ob);
498         Mesh *me_eval = ob->runtime.mesh_eval;
499         MVert *mvert_eval, *mv;
500         const int *index_array = NULL;
501         int totvert;
502         int i;
503
504         if (me == NULL)
505                 return;
506
507         /* we could call this directly in all areas that change selection,
508          * since this could become slow for realtime updates (circle-select for eg) */
509         BKE_mesh_flush_select_from_verts(me);
510
511         if (me_eval == NULL)
512                 return;
513
514         index_array = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
515
516         mvert_eval = me_eval->mvert;
517         totvert = me_eval->totvert;
518
519         mv = mvert_eval;
520
521         if (index_array) {
522                 int orig_index;
523                 for (i = 0; i < totvert; i++, mv++) {
524                         orig_index = index_array[i];
525                         if (orig_index != ORIGINDEX_NONE) {
526                                 mv->flag = me->mvert[index_array[i]].flag;
527                         }
528                 }
529         }
530         else {
531                 for (i = 0; i < totvert; i++, mv++) {
532                         mv->flag = me->mvert[i].flag;
533                 }
534         }
535
536         BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL);
537 }
538
539 void paintvert_tag_select_update(struct bContext *C, struct Object *ob)
540 {
541         DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
542         WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
543 }
544
545 /*  note: if the caller passes false to flush_flags,
546  *  then they will need to run paintvert_flush_flags(ob) themselves */
547 void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
548 {
549         Mesh *me;
550         MVert *mvert;
551         int a;
552
553         me = BKE_mesh_from_object(ob);
554         if (me == NULL) return;
555
556         if (action == SEL_TOGGLE) {
557                 action = SEL_SELECT;
558
559                 mvert = me->mvert;
560                 a = me->totvert;
561                 while (a--) {
562                         if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
563                                 action = SEL_DESELECT;
564                                 break;
565                         }
566                         mvert++;
567                 }
568         }
569
570         mvert = me->mvert;
571         a = me->totvert;
572         while (a--) {
573                 if ((mvert->flag & ME_HIDE) == 0) {
574                         switch (action) {
575                                 case SEL_SELECT:
576                                         mvert->flag |= SELECT;
577                                         break;
578                                 case SEL_DESELECT:
579                                         mvert->flag &= ~SELECT;
580                                         break;
581                                 case SEL_INVERT:
582                                         mvert->flag ^= SELECT;
583                                         break;
584                         }
585                 }
586                 mvert++;
587         }
588
589         /* handle mselect */
590         if (action == SEL_SELECT) {
591                 /* pass */
592         }
593         else if (ELEM(action, SEL_DESELECT, SEL_INVERT)) {
594                 BKE_mesh_mselect_clear(me);
595         }
596         else {
597                 BKE_mesh_mselect_validate(me);
598         }
599
600         if (flush_flags) {
601                 paintvert_flush_flags(ob);
602         }
603 }
604
605 void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
606 {
607         Mesh *me = BKE_mesh_from_object(ob);
608         MVert *mv;
609         MDeformVert *dv;
610         int a, tot;
611
612         if (me == NULL || me->dvert == NULL) {
613                 return;
614         }
615
616         if (!extend) {
617                 paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
618         }
619
620         dv = me->dvert;
621         tot = me->totvert;
622
623         for (a = 0, mv = me->mvert; a < tot; a++, mv++, dv++) {
624                 if ((mv->flag & ME_HIDE) == 0) {
625                         if (dv->dw == NULL) {
626                                 /* if null weight then not grouped */
627                                 mv->flag |= SELECT;
628                         }
629                 }
630         }
631
632         if (flush_flags) {
633                 paintvert_flush_flags(ob);
634         }
635 }