Changes to "Face Select" mode
[blender.git] / source / blender / src / editface.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33
34 #include <math.h>
35 #include <string.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_arithb.h"
41 #include "BLI_heap.h"
42 #include "BLI_edgehash.h"
43 #include "BLI_editVert.h"
44
45 #include "MTC_matrixops.h"
46
47 #include "IMB_imbuf_types.h"
48 #include "IMB_imbuf.h"
49
50 #include "DNA_image_types.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_meshdata_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_space_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_view3d_types.h"
58
59 #include "BKE_brush.h"
60 #include "BKE_customdata.h"
61 #include "BKE_depsgraph.h"
62 #include "BKE_DerivedMesh.h"
63 #include "BKE_displist.h"
64 #include "BKE_global.h"
65 #include "BKE_mesh.h"
66 #include "BKE_object.h"
67 #include "BKE_texture.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_customdata.h"
70
71 #include "BSE_view.h"
72 #include "BSE_edit.h"
73 #include "BSE_drawview.h"       /* for backdrawview3d */
74
75 #include "BIF_editsima.h"
76 #include "BIF_editmesh.h"
77 #include "BIF_interface.h"
78 #include "BIF_mywindow.h"
79 #include "BIF_toolbox.h"
80 #include "BIF_resources.h"
81 #include "BIF_screen.h"
82 #include "BIF_gl.h"
83 #include "BIF_graphics.h"
84 #include "BIF_space.h"  /* for allqueue */
85
86 #include "BDR_drawmesh.h"
87 #include "BDR_editface.h"
88 #include "BDR_vpaint.h"
89
90 #include "BDR_editface.h"
91 #include "BDR_vpaint.h"
92
93 #include "mydevice.h"
94 #include "blendef.h"
95 #include "butspace.h"
96 #include "multires.h"
97
98 #include "BSE_trans_types.h"
99
100 #include "BDR_unwrapper.h"
101 #include "BDR_editobject.h"
102
103 #include "BPY_extern.h"
104 #include "BPY_menus.h"
105
106 /* Pupmenu codes: */
107 #define UV_CUBE_MAPPING 2
108 #define UV_CYL_MAPPING 3
109 #define UV_SPHERE_MAPPING 4
110 #define UV_BOUNDS_MAPPING 5
111 #define UV_RESET_MAPPING 6
112 #define UV_WINDOW_MAPPING 7
113 #define UV_UNWRAP_MAPPING 8
114 #define UV_CYL_EX 32
115 #define UV_SPHERE_EX 34
116
117 /* Some macro tricks to make pupmenu construction look nicer :-)
118    Sorry, just did it for fun. */
119
120 #define _STR(x) " " #x
121 #define STRING(x) _STR(x)
122
123 #define MENUSTRING(string, code) string " %x" STRING(code)
124 #define MENUTITLE(string) string " %t|" 
125
126
127 /* returns 0 if not found, otherwise 1 */
128 int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
129 {
130         if (!me || me->totface==0)
131                 return 0;
132
133         if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
134                 check_backbuf();
135                 persp(PERSP_VIEW);
136         }
137
138         if (rect) {
139                 /* sample rect to increase changes of selecting, so that when clicking
140                    on an edge in the backbuf, we can still select a face */
141                 int dist;
142                 *index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist,0,NULL);
143         }
144         else
145                 /* sample only on the exact position */
146                 *index = sample_backbuf(mval[0], mval[1]);
147
148         if ((*index)<=0 || (*index)>(unsigned int)me->totface)
149                 return 0;
150
151         (*index)--;
152         
153         return 1;
154 }
155
156 /* returns 0 if not found, otherwise 1 */
157 static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
158 {
159         int dist;
160         unsigned int min = me->totface + 1;
161         unsigned int max = me->totface + me->totedge + 1;
162
163         if (me->totedge == 0)
164                 return 0;
165
166         if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
167                 check_backbuf();
168                 persp(PERSP_VIEW);
169         }
170
171         *index = sample_backbuf_rect(mval, 50, min, max, &dist,0,NULL);
172
173         if (*index == 0)
174                 return 0;
175
176         (*index)--;
177         
178         return 1;
179 }
180
181 /* only operates on the edit object - this is all thats needed at the moment */
182 static void uv_calc_center_vector(float *result, Object *ob, EditMesh *em)
183 {
184         float min[3], max[3], *cursx;
185         
186         EditFace *efa;
187         switch (G.vd->around) 
188         {
189         case V3D_CENTER: /* bounding box center */
190                 min[0]= min[1]= min[2]= 1e20f;
191                 max[0]= max[1]= max[2]= -1e20f; 
192
193                 for (efa= em->faces.first; efa; efa= efa->next) {
194                         if (efa->f & SELECT) {
195                                 DO_MINMAX(efa->v1->co, min, max);
196                                 DO_MINMAX(efa->v2->co, min, max);
197                                 DO_MINMAX(efa->v3->co, min, max);
198                                 if(efa->v4) DO_MINMAX(efa->v4->co, min, max);
199                         }
200                 }
201                 VecMidf(result, min, max);
202                 break;
203         case V3D_CURSOR: /*cursor center*/ 
204                 cursx= give_cursor();
205                 /* shift to objects world */
206                 result[0]= cursx[0]-ob->obmat[3][0];
207                 result[1]= cursx[1]-ob->obmat[3][1];
208                 result[2]= cursx[2]-ob->obmat[3][2];
209                 break;
210         case V3D_LOCAL: /*object center*/
211         case V3D_CENTROID: /* multiple objects centers, only one object here*/
212         default:
213                 result[0]= result[1]= result[2]= 0.0;
214                 break;
215         }
216 }
217
218 static void uv_calc_map_matrix(float result[][4], Object *ob, float upangledeg, float sideangledeg, float radius)
219 {
220         float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
221         float sideangle= 0.0, upangle= 0.0;
222         int k;
223
224         /* get rotation of the current view matrix */
225         Mat4CpyMat4(viewmatrix,G.vd->viewmat);
226         /* but shifting */
227         for( k= 0; k< 4; k++) viewmatrix[3][k] =0.0;
228
229         /* get rotation of the current object matrix */
230         Mat4CpyMat4(rotobj,ob->obmat);
231         /* but shifting */
232         for( k= 0; k< 4; k++) rotobj[3][k] =0.0;
233
234         Mat4Clr(*rotup);
235         Mat4Clr(*rotside);
236
237         /* compensate front/side.. against opengl x,y,z world definition */
238         /* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
239         /* i wanted to keep the reason here, so we're rotating*/
240         sideangle= M_PI * (sideangledeg + 180.0) /180.0;
241         rotside[0][0]= (float)cos(sideangle);
242         rotside[0][1]= -(float)sin(sideangle);
243         rotside[1][0]= (float)sin(sideangle);
244         rotside[1][1]= (float)cos(sideangle);
245         rotside[2][2]= 1.0f;
246       
247         upangle= M_PI * upangledeg /180.0;
248         rotup[1][1]= (float)cos(upangle)/radius;
249         rotup[1][2]= -(float)sin(upangle)/radius;
250         rotup[2][1]= (float)sin(upangle)/radius;
251         rotup[2][2]= (float)cos(upangle)/radius;
252         rotup[0][0]= (float)1.0/radius;
253
254         /* calculate transforms*/
255         Mat4MulSerie(result,rotup,rotside,viewmatrix,rotobj,NULL,NULL,NULL,NULL);
256 }
257
258 static void uv_calc_shift_project(float *target, float *shift, float rotmat[][4], int projectionmode, float *source, float *min, float *max)
259 {
260         float pv[3];
261
262         VecSubf(pv, source, shift);
263         Mat4MulVecfl(rotmat, pv);
264
265         switch(projectionmode) {
266         case B_UVAUTO_CYLINDER: 
267                 tubemap(pv[0], pv[1], pv[2], &target[0],&target[1]);
268                 /* split line is always zero */
269                 if (target[0] >= 1.0f) target[0] -= 1.0f;  
270                 break;
271
272         case B_UVAUTO_SPHERE: 
273                 spheremap(pv[0], pv[1], pv[2], &target[0],&target[1]);
274                 /* split line is always zero */
275                 if (target[0] >= 1.0f) target[0] -= 1.0f;
276                 break;
277
278         case 3: /* ortho special case for BOUNDS */
279                 target[0] = -pv[0];
280                 target[1] = pv[2];
281                 break;
282
283         case 4: 
284                 {
285                 /* very special case for FROM WINDOW */
286                 float pv4[4], dx, dy, x= 0.0, y= 0.0;
287
288                 dx= G.vd->area->winx;
289                 dy= G.vd->area->winy;
290
291                 VecCopyf(pv4, source);
292         pv4[3] = 1.0;
293
294                 /* rotmat is the object matrix in this case */
295         Mat4MulVec4fl(rotmat,pv4); 
296
297                 /* almost project_short */
298             Mat4MulVec4fl(G.vd->persmat,pv4);
299                 if (fabs(pv4[3]) > 0.00001) { /* avoid division by zero */
300                         target[0] = dx/2.0 + (dx/2.0)*pv4[0]/pv4[3];
301                         target[1] = dy/2.0 + (dy/2.0)*pv4[1]/pv4[3];
302                 }
303                 else {
304                         /* scaling is lost but give a valid result */
305                         target[0] = dx/2.0 + (dx/2.0)*pv4[0];
306                         target[1] = dy/2.0 + (dy/2.0)*pv4[1];
307                 }
308
309         /* G.vd->persmat seems to do this funky scaling */ 
310                 if(dx > dy) {
311                         y= (dx-dy)/2.0;
312                         dy = dx;
313                 }
314                 else {
315                         x= (dy-dx)/2.0;
316                         dx = dy;
317                 }
318                 target[0]= (x + target[0])/dx;
319                 target[1]= (y + target[1])/dy;
320
321                 }
322                 break;
323
324     default:
325                 target[0] = 0.0;
326                 target[1] = 1.0;
327         }
328
329         /* we know the values here and may need min_max later */
330         /* max requests independand from min; not fastest but safest */ 
331         if(min) {
332                 min[0] = MIN2(target[0], min[0]);
333                 min[1] = MIN2(target[1], min[1]);
334         }
335         if(max) {
336                 max[0] = MAX2(target[0], max[0]);
337                 max[1] = MAX2(target[1], max[1]);
338         }
339 }
340
341 void calculate_uv_map(unsigned short mapmode)
342 {
343         MTFace *tface;
344         Object *ob;
345         float dx, dy, rotatematrix[4][4], radius= 1.0, min[3], cent[3], max[3];
346         float fac= 1.0, upangledeg= 0.0, sideangledeg= 90.0;
347         int i, b, mi, n;
348
349         EditMesh *em = G.editMesh;
350         EditFace *efa;
351         
352         if(G.scene->toolsettings->uvcalc_mapdir==1)  {
353                 upangledeg= 90.0;
354                 sideangledeg= 0.0;
355         } else {
356                 upangledeg= 0.0;
357                 if(G.scene->toolsettings->uvcalc_mapalign==1) sideangledeg= 0.0;
358                 else sideangledeg= 90.0;
359         }
360         
361         /* add uvs if there not here */
362         if (!EM_texFaceCheck()) {
363                 if (em && em->faces.first)
364                         EM_add_data_layer(&em->fdata, CD_MTFACE);
365                 
366                 if (!EM_texFaceCheck())
367                         return;
368         }
369         
370         ob=OBACT;
371         
372         switch(mapmode) {
373         case B_UVAUTO_BOUNDS:
374                 min[0]= min[1]= 10000000.0;
375                 max[0]= max[1]= -10000000.0;
376
377                 cent[0] = cent[1] = cent[2] = 0.0; 
378                 uv_calc_map_matrix(rotatematrix, ob, upangledeg, sideangledeg, 1.0f);
379                 
380                 for (efa= em->faces.first; efa; efa= efa->next) {
381                         if (efa->f & SELECT) {
382                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
383                                 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,3, efa->v1->co, min,max);
384                                 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,3, efa->v2->co, min,max);
385                                 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,3, efa->v3->co,min,max);
386                                 if(efa->v4)
387                                         uv_calc_shift_project(tface->uv[3],cent,rotatematrix,3, efa->v4->co,min,max);
388                         }
389                 }
390                 
391                 /* rescale UV to be in 0..1,1/2,1/4,1/8 */
392                 dx= (max[0]-min[0]);
393                 dy= (max[1]-min[1]);
394
395                 for (efa= em->faces.first; efa; efa= efa->next) {
396                         if (efa->f & SELECT) {
397                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
398                                 if(efa->v4) b= 3; else b= 2;
399                                 for(; b>=0; b--) {
400                                         tface->uv[b][0]= ((tface->uv[b][0]-min[0])*fac)/dx;
401                                         tface->uv[b][1]= 1.0-fac+((tface->uv[b][1]-min[1])/* *fac */)/dy;
402                                 }
403                         }
404                 }
405                 break;
406
407         case B_UVAUTO_WINDOW:           
408                 cent[0] = cent[1] = cent[2] = 0.0; 
409                 Mat4CpyMat4(rotatematrix,ob->obmat);
410                 for (efa= em->faces.first; efa; efa= efa->next) {
411                         if (efa->f & SELECT) {
412                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
413                                 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,4, efa->v1->co, NULL,NULL);
414                                 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,4, efa->v2->co, NULL,NULL);
415                                 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,4, efa->v3->co, NULL,NULL);
416                                 if(efa->v4)
417                                         uv_calc_shift_project(tface->uv[3],cent,rotatematrix,4, efa->v4->co, NULL,NULL);
418                         }
419                 }
420                 break;
421
422         case B_UVAUTO_RESET:
423                 for (efa= em->faces.first; efa; efa= efa->next) {
424                         if (efa->f & SELECT) {
425                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
426                                 default_uv(tface->uv, 1.0);
427                         }
428                 }
429                 break;
430
431         case B_UVAUTO_CYLINDER:
432         case B_UVAUTO_SPHERE:
433                 uv_calc_center_vector(cent, ob, em);
434                         
435                 if(mapmode==B_UVAUTO_CYLINDER) radius = G.scene->toolsettings->uvcalc_radius;
436
437                 /* be compatible to the "old" sphere/cylinder mode */
438                 if (G.scene->toolsettings->uvcalc_mapdir== 2)
439                         Mat4One(rotatematrix);
440                 else 
441                         uv_calc_map_matrix(rotatematrix,ob,upangledeg,sideangledeg,radius);
442                 for (efa= em->faces.first; efa; efa= efa->next) {
443                         if (efa->f & SELECT) {
444                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
445                                 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,mapmode, efa->v1->co, NULL,NULL);
446                                 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,mapmode, efa->v2->co, NULL,NULL);
447                                 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,mapmode, efa->v3->co, NULL,NULL);
448                                 n = 3;       
449                                 if(efa->v4) {
450                                         uv_calc_shift_project(tface->uv[3],cent,rotatematrix,mapmode, efa->v4->co, NULL,NULL);
451                                         n=4;
452                                 }
453
454                                 mi = 0;
455                                 for (i = 1; i < n; i++)
456                                         if (tface->uv[i][0] > tface->uv[mi][0]) mi = i;
457
458                                 for (i = 0; i < n; i++) {
459                                         if (i != mi) {
460                                                 dx = tface->uv[mi][0] - tface->uv[i][0];
461                                                 if (dx > 0.5) tface->uv[i][0] += 1.0;
462                                         } 
463                                 } 
464                         }
465                 }
466
467                 break;
468
469         case B_UVAUTO_CUBE:
470                 {
471                 /* choose x,y,z axis for projetion depending on the largest normal */
472                 /* component, but clusters all together around the center of map */
473                 float no[3];
474                 short cox, coy;
475                 float *loc= ob->obmat[3];
476                 /*MVert *mv= me->mvert;*/
477                 float cubesize = G.scene->toolsettings->uvcalc_cubesize;
478
479                 for (efa= em->faces.first; efa; efa= efa->next) {
480                         if (efa->f & SELECT) {
481                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
482                                 CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, no);
483                                 
484                                 no[0]= fabs(no[0]);
485                                 no[1]= fabs(no[1]);
486                                 no[2]= fabs(no[2]);
487                                 
488                                 cox=0; coy= 1;
489                                 if(no[2]>=no[0] && no[2]>=no[1]);
490                                 else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2;
491                                 else { cox= 1; coy= 2; }
492                                 
493                                 tface->uv[0][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v1->co[cox]);
494                                 tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v1->co[coy]);
495                                 dx = floor(tface->uv[0][0]);
496                                 dy = floor(tface->uv[0][1]);
497                                 tface->uv[0][0] -= dx;
498                                 tface->uv[0][1] -= dy;
499                                 tface->uv[1][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v2->co[cox]);
500                                 tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v2->co[coy]);
501                                 tface->uv[1][0] -= dx;
502                                 tface->uv[1][1] -= dy;
503                                 tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v3->co[cox]);
504                                 tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v3->co[coy]);
505                                 tface->uv[2][0] -= dx;
506                                 tface->uv[2][1] -= dy;
507                                 if(efa->v4) {
508                                         tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v4->co[cox]);
509                                         tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v4->co[coy]);
510                                         tface->uv[3][0] -= dx;
511                                         tface->uv[3][1] -= dy;
512                                 }
513                         }
514                 }
515                 break;
516                 }
517         default:
518                 return;
519         } /* end switch mapmode */
520
521         /* clipping and wrapping */
522         if(G.sima && G.sima->flag & SI_CLIP_UV) {
523                 for (efa= em->faces.first; efa; efa= efa->next) {
524                         if (!(efa->f & SELECT)) continue;
525                         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
526                 
527                         dx= dy= 0;
528                         if(efa->v4) b= 3; else b= 2;
529                         for(; b>=0; b--) {
530                                 while(tface->uv[b][0] + dx < 0.0) dx+= 0.5;
531                                 while(tface->uv[b][0] + dx > 1.0) dx-= 0.5;
532                                 while(tface->uv[b][1] + dy < 0.0) dy+= 0.5;
533                                 while(tface->uv[b][1] + dy > 1.0) dy-= 0.5;
534                         }
535         
536                         if(efa->v4) b= 3; else b= 2;
537                         for(; b>=0; b--) {
538                                 tface->uv[b][0]+= dx;
539                                 CLAMP(tface->uv[b][0], 0.0, 1.0);
540                                 
541                                 tface->uv[b][1]+= dy;
542                                 CLAMP(tface->uv[b][1], 0.0, 1.0);
543                         }
544                 }
545         }
546
547         BIF_undo_push("UV calculation");
548
549         object_uvs_changed(OBACT);
550
551         allqueue(REDRAWVIEW3D, 0);
552         allqueue(REDRAWIMAGE, 0);
553 }
554
555 MTFace *get_active_tface(EditFace **act_efa, MCol **mcol)
556 {
557         EditMesh *em = G.editMesh;
558         EditFace *efa = NULL;
559         EditSelection *ese;
560         
561         if(!EM_texFaceCheck())
562                 return NULL;
563
564         for (ese = em->selected.last; ese; ese=ese->prev){
565                 if(ese->type == EDITFACE) {
566                         efa = (EditFace *)ese->data;
567                         break;
568                 }
569         }
570         
571         if (!efa) {
572                 for (efa= em->faces.first; efa; efa= efa->next) {
573                         if (efa->f & SELECT)
574                                 break;
575                 }
576         }
577         
578         if (efa) {
579                 if (mcol) {
580                         if (CustomData_has_layer(&em->fdata, CD_MCOL))
581                                 *mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
582                         else
583                                 *mcol = NULL;
584                 }
585                 if (act_efa) *act_efa = efa; 
586                 return CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
587         }
588         if (act_efa) *act_efa= NULL;
589         if(mcol) *mcol = NULL;
590         return NULL;
591 }
592
593 void default_uv(float uv[][2], float size)
594 {
595         int dy;
596         
597         if(size>1.0) size= 1.0;
598
599         dy= 1.0-size;
600         
601         uv[0][0]= 0;
602         uv[0][1]= size+dy;
603         
604         uv[1][0]= 0;
605         uv[1][1]= dy;
606         
607         uv[2][0]= size;
608         uv[2][1]= dy;
609         
610         uv[3][0]= size;
611         uv[3][1]= size+dy;
612 }
613
614 void make_tfaces(Mesh *me) 
615 {
616         if(!me->mtface) {
617                 if(me->mr) {
618                         multires_add_layer(me, &me->mr->fdata, CD_MTFACE,
619                                            CustomData_number_of_layers(&me->fdata, CD_MTFACE));
620                 }
621                 else {
622                         me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT,
623                                 NULL, me->totface);
624                 }
625         }
626 }
627
628 void reveal_tface()
629 {
630         Mesh *me;
631         MFace *mface;
632         int a;
633         
634         me= get_mesh(OBACT);
635         if(me==0 || me->totface==0) return;
636         
637         mface= me->mface;
638         a= me->totface;
639         while(a--) {
640                 if(mface->flag & ME_HIDE) {
641                         mface->flag |= ME_FACE_SEL;
642                         mface->flag -= ME_HIDE;
643                 }
644                 mface++;
645         }
646
647         BIF_undo_push("Reveal face");
648
649         object_tface_flags_changed(OBACT, 0);
650 }
651
652 void hide_tface()
653 {
654         Mesh *me;
655         MFace *mface;
656         int a;
657         
658         me= get_mesh(OBACT);
659         if(me==0 || me->totface==0) return;
660         
661         if(G.qual & LR_ALTKEY) {
662                 reveal_tface();
663                 return;
664         }
665         
666         mface= me->mface;
667         a= me->totface;
668         while(a--) {
669                 if(mface->flag & ME_HIDE);
670                 else {
671                         if(G.qual & LR_SHIFTKEY) {
672                                 if( (mface->flag & ME_FACE_SEL)==0) mface->flag |= ME_HIDE;
673                         }
674                         else {
675                                 if( (mface->flag & ME_FACE_SEL)) mface->flag |= ME_HIDE;
676                         }
677                 }
678                 if(mface->flag & ME_HIDE) mface->flag &= ~ME_FACE_SEL;
679                 
680                 mface++;
681         }
682
683         BIF_undo_push("Hide face");
684
685         object_tface_flags_changed(OBACT, 0);
686 }
687
688 void select_linked_tfaces(int mode)
689 {
690         Object *ob;
691         Mesh *me;
692         short mval[2];
693         unsigned int index=0;
694
695         ob = OBACT;
696         me = get_mesh(ob);
697         if(me==0 || me->totface==0) return;
698
699         if (mode==0 || mode==1) {
700                 if (!(ob->lay & G.vd->lay))
701                         error("The active object is not in this layer");
702                         
703                 getmouseco_areawin(mval);
704                 if (!facesel_face_pick(me, mval, &index, 1)) return;
705         }
706
707         select_linked_tfaces_with_seams(mode, me, index);
708 }
709
710 void deselectall_tface()
711 {
712         Mesh *me;
713         MFace *mface;
714         int a, sel;
715                 
716         me= get_mesh(OBACT);
717         if(me==0) return;
718         
719         mface= me->mface;
720         a= me->totface;
721         sel= 0;
722         while(a--) {
723                 if(mface->flag & ME_HIDE);
724                 else if(mface->flag & ME_FACE_SEL) sel= 1;
725                 mface++;
726         }
727         
728         mface= me->mface;
729         a= me->totface;
730         while(a--) {
731                 if(mface->flag & ME_HIDE);
732                 else {
733                         if(sel) mface->flag &= ~ME_FACE_SEL;
734                         else mface->flag |= ME_FACE_SEL;
735                 }
736                 mface++;
737         }
738
739         BIF_undo_push("(De)select all faces");
740
741         object_tface_flags_changed(OBACT, 0);
742 }
743
744 void selectswap_tface(void)
745 {
746         Mesh *me;
747         MFace *mface;
748         int a;
749                 
750         me= get_mesh(OBACT);
751         if(me==0) return;
752         
753         mface= me->mface;
754         a= me->totface;
755         while(a--) {
756                 if(mface->flag & ME_HIDE);
757                 else {
758                         if(mface->flag & ME_FACE_SEL) mface->flag &= ~ME_FACE_SEL;
759                         else mface->flag |= ME_FACE_SEL;
760                 }
761                 mface++;
762         }
763
764         BIF_undo_push("Select inverse face");
765
766         object_tface_flags_changed(OBACT, 0);
767 }
768
769 void rotate_uv_tface()
770 {
771         Mesh *me;
772         MFace *mf;
773         MCol *mcol;
774         MTFace *tf;
775         short mode;
776         int a;
777         
778         me= get_mesh(OBACT);
779         if(me==0 || me->mtface==0) return;
780         
781         mode= pupmenu("Rotate %t|UV Co-ordinates %x1|Vertex Colors %x2");
782
783         if (mode == 1 && me->mtface) {
784                 tf= me->mtface;
785                 mf= me->mface;
786                 for(a=0; a<me->totface; a++, tf++, mf++) {
787                         if(mf->flag & ME_FACE_SEL) {
788                                 float u1= tf->uv[0][0];
789                                 float v1= tf->uv[0][1];
790                                 
791                                 tf->uv[0][0]= tf->uv[1][0];
792                                 tf->uv[0][1]= tf->uv[1][1];
793         
794                                 tf->uv[1][0]= tf->uv[2][0];
795                                 tf->uv[1][1]= tf->uv[2][1];
796         
797                                 if(mf->v4) {
798                                         tf->uv[2][0]= tf->uv[3][0];
799                                         tf->uv[2][1]= tf->uv[3][1];
800                                 
801                                         tf->uv[3][0]= u1;
802                                         tf->uv[3][1]= v1;
803                                 }
804                                 else {
805                                         tf->uv[2][0]= u1;
806                                         tf->uv[2][1]= v1;
807                                 }
808                         }
809                 }
810
811                 BIF_undo_push("Rotate UV face");
812                 object_uvs_changed(OBACT);
813         }
814         else if (mode == 2 && me->mcol) {
815                 tf= me->mtface;
816                 mcol= me->mcol;
817                 mf= me->mface;
818                 for(a=0; a<me->totface; a++, tf++, mf++, mcol+=4) {
819                         if(mf->flag & ME_FACE_SEL) {
820                                 MCol tmpcol= mcol[0];
821                                 
822                                 mcol[0]= mcol[1];
823                                 mcol[1]= mcol[2];
824         
825                                 if(mf->v4) {
826                                         mcol[2]= mcol[3];
827                                         mcol[3]= tmpcol;
828                                 }
829                                 else
830                                         mcol[2]= tmpcol;
831                         }
832                 }
833
834                 BIF_undo_push("Rotate color face");
835                 object_uvs_changed(OBACT);
836         }
837 }
838
839 void mirror_uv_tface()
840 {
841         Mesh *me;
842         MFace *mf;
843         MTFace *tf;
844         MCol *mcol;
845         short mode;
846         int a;
847         
848         me= get_mesh(OBACT);
849         if(me==0 || me->mtface==0) return;
850         
851         mode= pupmenu("Mirror %t|UV Co-ordinates %x1|Vertex Colors %x2");
852         
853         if (mode==1 && me->mtface) {
854                 mf= me->mface;
855                 tf= me->mtface;
856
857                 for (a=0; a<me->totface; a++, tf++, mf++) {
858                         if(mf->flag & ME_FACE_SEL) {
859                                 float u1= tf->uv[0][0];
860                                 float v1= tf->uv[0][1];
861                                 if(mf->v4) {
862                                         tf->uv[0][0]= tf->uv[3][0];
863                                         tf->uv[0][1]= tf->uv[3][1];
864                                 
865                                         tf->uv[3][0]= u1;
866                                         tf->uv[3][1]= v1;
867
868                                         u1= tf->uv[1][0];
869                                         v1= tf->uv[1][1];
870
871                                         tf->uv[1][0]= tf->uv[2][0];
872                                         tf->uv[1][1]= tf->uv[2][1];
873                                 
874                                         tf->uv[2][0]= u1;
875                                         tf->uv[2][1]= v1;
876                                 }
877                                 else {
878                                         tf->uv[0][0]= tf->uv[2][0];
879                                         tf->uv[0][1]= tf->uv[2][1];
880                                         tf->uv[2][0]= u1;
881                                         tf->uv[2][1]= v1;
882                                 }
883                         }
884                 }
885         }
886         else if(mode==2 && me->mcol) {
887                 mf= me->mface;
888                 tf= me->mtface;
889                 mcol= me->mcol;
890
891                 for (a=0; a<me->totface; a++, tf++, mf++, mcol+=4) {
892                         if(mf->flag & ME_FACE_SEL) {
893                                 MCol tmpcol= mcol[0];
894
895                                 if(mf->v4) {
896                                         mcol[0]= mcol[3];
897                                         mcol[3]= tmpcol;
898
899                                         tmpcol = mcol[1];
900                                         mcol[1]= mcol[2];
901                                         mcol[2]= tmpcol;
902                                 }
903                                 else {
904                                         mcol[0]= mcol[2];
905                                         mcol[2]= tmpcol;
906                                 }
907                         }
908                 }
909         }
910         
911         BIF_undo_push("Mirror UV face");
912
913         object_uvs_changed(OBACT);
914 }
915
916 int minmax_tface(float *min, float *max)
917 {
918         Object *ob;
919         Mesh *me;
920         MFace *mf;
921         MTFace *tf;
922         MVert *mv;
923         int a, ok=0;
924         float vec[3], bmat[3][3];
925         
926         ob = OBACT;
927         if (ob==0) return ok;
928         me= get_mesh(ob);
929         if(me==0 || me->mtface==0) return ok;
930         
931         Mat3CpyMat4(bmat, ob->obmat);
932
933         mv= me->mvert;
934         mf= me->mface;
935         tf= me->mtface;
936         for (a=me->totface; a>0; a--, mf++, tf++) {
937                 if (mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL))
938                         continue;
939
940                 VECCOPY(vec, (mv+mf->v1)->co);
941                 Mat3MulVecfl(bmat, vec);
942                 VecAddf(vec, vec, ob->obmat[3]);
943                 DO_MINMAX(vec, min, max);               
944
945                 VECCOPY(vec, (mv+mf->v2)->co);
946                 Mat3MulVecfl(bmat, vec);
947                 VecAddf(vec, vec, ob->obmat[3]);
948                 DO_MINMAX(vec, min, max);               
949
950                 VECCOPY(vec, (mv+mf->v3)->co);
951                 Mat3MulVecfl(bmat, vec);
952                 VecAddf(vec, vec, ob->obmat[3]);
953                 DO_MINMAX(vec, min, max);               
954
955                 if (mf->v4) {
956                         VECCOPY(vec, (mv+mf->v4)->co);
957                         Mat3MulVecfl(bmat, vec);
958                         VecAddf(vec, vec, ob->obmat[3]);
959                         DO_MINMAX(vec, min, max);
960                 }
961                 ok= 1;
962         }
963         return ok;
964 }
965
966 #define ME_SEAM_DONE ME_SEAM_LAST               /* reuse this flag */
967
968 static float seam_cut_cost(Mesh *me, int e1, int e2, int vert)
969 {
970         MVert *v = me->mvert + vert;
971         MEdge *med1 = me->medge + e1, *med2 = me->medge + e2;
972         MVert *v1 = me->mvert + ((med1->v1 == vert)? med1->v2: med1->v1);
973         MVert *v2 = me->mvert + ((med2->v1 == vert)? med2->v2: med2->v1);
974         float cost, d1[3], d2[3];
975
976         cost = VecLenf(v1->co, v->co);
977         cost += VecLenf(v->co, v2->co);
978
979         VecSubf(d1, v->co, v1->co);
980         VecSubf(d2, v2->co, v->co);
981
982         cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
983
984         return cost;
985 }
986
987 static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
988 {
989         int startadj, endadj = nedges[vertnum+1];
990
991         for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
992                 int adjnum = edges[startadj];
993                 MEdge *medadj = me->medge + adjnum;
994                 float newcost;
995
996                 if (medadj->flag & ME_SEAM_DONE)
997                         continue;
998
999                 newcost = cost[mednum] + seam_cut_cost(me, mednum, adjnum, vertnum);
1000
1001                 if (cost[adjnum] > newcost) {
1002                         cost[adjnum] = newcost;
1003                         prevedge[adjnum] = mednum;
1004                         BLI_heap_insert(heap, newcost, (void*)adjnum);
1005                 }
1006         }
1007 }
1008
1009 static int seam_shortest_path(Mesh *me, int source, int target)
1010 {
1011         Heap *heap;
1012         EdgeHash *ehash;
1013         float *cost;
1014         MEdge *med;
1015         int a, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
1016         MFace *mf;
1017
1018         /* mark hidden edges as done, so we don't use them */
1019         ehash = BLI_edgehash_new();
1020
1021         for (a=0, mf=me->mface; a<me->totface; a++, mf++) {
1022                 if (!(mf->flag & ME_HIDE)) {
1023                         BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
1024                         BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
1025                         if (mf->v4) {
1026                                 BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
1027                                 BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
1028                         }
1029                         else
1030                                 BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
1031                 }
1032         }
1033
1034         for (a=0, med=me->medge; a<me->totedge; a++, med++)
1035                 if (!BLI_edgehash_haskey(ehash, med->v1, med->v2))
1036                         med->flag |= ME_SEAM_DONE;
1037
1038         BLI_edgehash_free(ehash, NULL);
1039
1040         /* alloc */
1041         nedges = MEM_callocN(sizeof(*nedges)*me->totvert+1, "SeamPathNEdges");
1042         edges = MEM_mallocN(sizeof(*edges)*me->totedge*2, "SeamPathEdges");
1043         prevedge = MEM_mallocN(sizeof(*prevedge)*me->totedge, "SeamPathPrevious");
1044         cost = MEM_mallocN(sizeof(*cost)*me->totedge, "SeamPathCost");
1045
1046         /* count edges, compute adjacent edges offsets and fill adjacent edges */
1047         for (a=0, med=me->medge; a<me->totedge; a++, med++) {
1048                 nedges[med->v1+1]++;
1049                 nedges[med->v2+1]++;
1050         }
1051
1052         for (a=1; a<me->totvert; a++) {
1053                 int newswap = nedges[a+1];
1054                 nedges[a+1] = nedgeswap + nedges[a];
1055                 nedgeswap = newswap;
1056         }
1057         nedges[0] = nedges[1] = 0;
1058
1059         for (a=0, med=me->medge; a<me->totedge; a++, med++) {
1060                 edges[nedges[med->v1+1]++] = a;
1061                 edges[nedges[med->v2+1]++] = a;
1062
1063                 cost[a] = 1e20f;
1064                 prevedge[a] = -1;
1065         }
1066
1067         /* regular dijkstra shortest path, but over edges instead of vertices */
1068         heap = BLI_heap_new();
1069         BLI_heap_insert(heap, 0.0f, (void*)source);
1070         cost[source] = 0.0f;
1071
1072         while (!BLI_heap_empty(heap)) {
1073                 mednum = (int)BLI_heap_popmin(heap);
1074                 med = me->medge + mednum;
1075
1076                 if (mednum == target)
1077                         break;
1078
1079                 if (med->flag & ME_SEAM_DONE)
1080                         continue;
1081
1082                 med->flag |= ME_SEAM_DONE;
1083
1084                 seam_add_adjacent(me, heap, mednum, med->v1, nedges, edges, prevedge, cost);
1085                 seam_add_adjacent(me, heap, mednum, med->v2, nedges, edges, prevedge, cost);
1086         }
1087         
1088         MEM_freeN(nedges);
1089         MEM_freeN(edges);
1090         MEM_freeN(cost);
1091         BLI_heap_free(heap, NULL);
1092
1093         for (a=0, med=me->medge; a<me->totedge; a++, med++)
1094                 med->flag &= ~ME_SEAM_DONE;
1095
1096         if (mednum != target) {
1097                 MEM_freeN(prevedge);
1098                 return 0;
1099         }
1100
1101         /* follow path back to source and mark as seam */
1102         if (mednum == target) {
1103                 short allseams = 1;
1104
1105                 mednum = target;
1106                 do {
1107                         med = me->medge + mednum;
1108                         if (!(med->flag & ME_SEAM)) {
1109                                 allseams = 0;
1110                                 break;
1111                         }
1112                         mednum = prevedge[mednum];
1113                 } while (mednum != source);
1114
1115                 mednum = target;
1116                 do {
1117                         med = me->medge + mednum;
1118                         if (allseams)
1119                                 med->flag &= ~ME_SEAM;
1120                         else
1121                                 med->flag |= ME_SEAM;
1122                         mednum = prevedge[mednum];
1123                 } while (mednum != -1);
1124         }
1125
1126         MEM_freeN(prevedge);
1127         return 1;
1128 }
1129
1130 static void seam_select(Mesh *me, short *mval, short path)
1131 {
1132         unsigned int index = 0;
1133         MEdge *medge, *med;
1134         int a, lastindex = -1;
1135
1136         if (!facesel_edge_pick(me, mval, &index))
1137                 return;
1138
1139         for (a=0, med=me->medge; a<me->totedge; a++, med++) {
1140                 if (med->flag & ME_SEAM_LAST) {
1141                         lastindex = a;
1142                         med->flag &= ~ME_SEAM_LAST;
1143                         break;
1144                 }
1145         }
1146
1147         medge = me->medge + index;
1148         if (!path || (lastindex == -1) || (index == lastindex) ||
1149             !seam_shortest_path(me, lastindex, index))
1150                 medge->flag ^= ME_SEAM;
1151         medge->flag |= ME_SEAM_LAST;
1152
1153         G.f |= G_DRAWSEAMS;
1154
1155         if (G.rt == 8)
1156                 unwrap_lscm(1);
1157
1158         BIF_undo_push("Mark Seam");
1159
1160         object_tface_flags_changed(OBACT, 1);
1161 }
1162
1163 void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
1164 {
1165         BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
1166         BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
1167         if (mf->v4) {
1168                 BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
1169                 BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
1170         }
1171         else
1172                 BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
1173 }
1174
1175 void seam_mark_clear_tface(short mode)
1176 {
1177         Mesh *me;
1178         MFace *mf;
1179         MEdge *med;
1180         int a;
1181         
1182         me= get_mesh(OBACT);
1183         if(me==0 ||  me->totface==0) return;
1184
1185         if (mode == 0)
1186                 mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
1187
1188         if (mode != 1 && mode != 2)
1189                 return;
1190
1191         if (mode == 2) {
1192                 EdgeHash *ehash = BLI_edgehash_new();
1193
1194                 for (a=0, mf=me->mface; a<me->totface; a++, mf++)
1195                         if (!(mf->flag & ME_HIDE) && (mf->flag & ME_FACE_SEL))
1196                                 seam_edgehash_insert_face(ehash, mf);
1197
1198                 for (a=0, med=me->medge; a<me->totedge; a++, med++)
1199                         if (BLI_edgehash_haskey(ehash, med->v1, med->v2))
1200                                 med->flag &= ~ME_SEAM;
1201
1202                 BLI_edgehash_free(ehash, NULL);
1203         }
1204         else {
1205                 /* mark edges that are on both selected and deselected faces */
1206                 EdgeHash *ehash1 = BLI_edgehash_new();
1207                 EdgeHash *ehash2 = BLI_edgehash_new();
1208
1209                 for (a=0, mf=me->mface; a<me->totface; a++, mf++) {
1210                         if ((mf->flag & ME_HIDE) || !(mf->flag & ME_FACE_SEL))
1211                                 seam_edgehash_insert_face(ehash1, mf);
1212                         else
1213                                 seam_edgehash_insert_face(ehash2, mf);
1214                 }
1215
1216                 for (a=0, med=me->medge; a<me->totedge; a++, med++)
1217                         if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) &&
1218                             BLI_edgehash_haskey(ehash2, med->v1, med->v2))
1219                                 med->flag |= ME_SEAM;
1220
1221                 BLI_edgehash_free(ehash1, NULL);
1222                 BLI_edgehash_free(ehash2, NULL);
1223         }
1224
1225         if (G.rt == 8)
1226                 unwrap_lscm(1);
1227
1228         G.f |= G_DRAWSEAMS;
1229         BIF_undo_push("Mark Seam");
1230
1231         object_tface_flags_changed(OBACT, 1);
1232 }
1233
1234 void face_select()
1235 {
1236         Object *ob;
1237         Mesh *me;
1238         MTFace *tface, *tsel;
1239         MFace *mface, *msel;
1240         short mval[2];
1241         unsigned int a, index;
1242
1243         /* Get the face under the cursor */
1244         ob = OBACT;
1245         if (!(ob->lay & G.vd->lay)) {
1246                 error("The active object is not in this layer");
1247         }
1248         me = get_mesh(ob);
1249         getmouseco_areawin(mval);
1250
1251         if (G.qual & LR_ALTKEY) {
1252                 seam_select(me, mval, (G.qual & LR_SHIFTKEY) != 0);
1253                 return;
1254         }
1255
1256         if (!facesel_face_pick(me, mval, &index, 1)) return;
1257         
1258         tsel= (((MTFace*)me->mtface)+index); /* check me->mtface before using */
1259         msel= (((MFace*)me->mface)+index);
1260
1261         if (msel->flag & ME_HIDE) return;
1262         
1263         /* clear flags */
1264         tface = me->mtface;
1265         mface = me->mface;
1266         a = me->totface;
1267         while (a--) {
1268                 if (G.qual & LR_SHIFTKEY) {
1269                         if (me->mtface) {
1270                                 tface->flag &= ~TF_ACTIVE;
1271                         }
1272                 } else {
1273                         if (me->mtface) {
1274                                 tface->flag &= ~TF_ACTIVE;
1275                         }
1276                         mface->flag &= ~ME_FACE_SEL;
1277                 }
1278                 if (me->mtface) {
1279                         tface++;
1280                 }
1281                 mface++;
1282         }
1283         if (me->mtface)
1284                 tsel->flag |= TF_ACTIVE;
1285
1286         if (G.qual & LR_SHIFTKEY) {
1287                 if (msel->flag & ME_FACE_SEL)
1288                         msel->flag &= ~ME_FACE_SEL;
1289                 else
1290                         msel->flag |= ME_FACE_SEL;
1291         }
1292         else msel->flag |= ME_FACE_SEL;
1293         
1294         /* image window redraw */
1295         
1296         BIF_undo_push("Select UV face");
1297
1298         object_tface_flags_changed(OBACT, 1);
1299 }
1300
1301 void face_borderselect()
1302 {
1303         Mesh *me;
1304         MFace *mface;
1305         rcti rect;
1306         struct ImBuf *ibuf;
1307         unsigned int *rt;
1308         int a, sx, sy, index, val;
1309         char *selar;
1310         
1311         me= get_mesh(OBACT);
1312         if(me==0) return;
1313         if(me->totface==0) return;
1314         
1315         val= get_border(&rect, 3);
1316         
1317         /* why readbuffer here? shouldn't be necessary (maybe a flush or so) */
1318         glReadBuffer(GL_BACK);
1319 #ifdef __APPLE__
1320         glReadBuffer(GL_AUX0); /* apple only */
1321 #endif
1322         
1323         if(val) {
1324                 selar= MEM_callocN(me->totface+1, "selar");
1325                 
1326                 sx= (rect.xmax-rect.xmin+1);
1327                 sy= (rect.ymax-rect.ymin+1);
1328                 if(sx*sy<=0) return;
1329
1330                 ibuf = IMB_allocImBuf(sx,sy,32,IB_rect,0);
1331                 rt = ibuf->rect;
1332                 glReadPixels(rect.xmin+curarea->winrct.xmin,  rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
1333                 if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
1334
1335                 a= sx*sy;
1336                 while(a--) {
1337                         if(*rt) {
1338                                 index= framebuffer_to_index(*rt);
1339                                 if(index<=me->totface) selar[index]= 1;
1340                         }
1341                         rt++;
1342                 }
1343                 
1344                 mface= me->mface;
1345                 for(a=1; a<=me->totface; a++, mface++) {
1346                         if(selar[a]) {
1347                                 if(mface->flag & ME_HIDE);
1348                                 else {
1349                                         if(val==LEFTMOUSE) mface->flag |= ME_FACE_SEL;
1350                                         else mface->flag &= ~ME_FACE_SEL;
1351                                 }
1352                         }
1353                 }
1354                 
1355                 IMB_freeImBuf(ibuf);
1356                 MEM_freeN(selar);
1357
1358                 BIF_undo_push("Border Select UV face");
1359
1360                 object_tface_flags_changed(OBACT, 0);
1361         }
1362 #ifdef __APPLE__        
1363         glReadBuffer(GL_BACK);
1364 #endif
1365 }
1366
1367 void uv_autocalc_tface()
1368 {
1369         short mode, i=0, has_pymenu=0; /* pymenu must be bigger then UV_*_MAPPING */
1370         BPyMenu *pym;
1371         char menu_number[3];
1372         
1373         /* uvmenu, will add python items */
1374         char uvmenu[4096]=MENUTITLE("UV Calculation")
1375                                         MENUSTRING("Unwrap",                            UV_UNWRAP_MAPPING) "|%l|"
1376                                         
1377                                         MENUSTRING("Cube Projection",                   UV_CUBE_MAPPING) "|"
1378                                         MENUSTRING("Cylinder from View",                UV_CYL_MAPPING) "|"
1379                                         MENUSTRING("Sphere from View",                  UV_SPHERE_MAPPING) "|%l|"
1380
1381                                         MENUSTRING("Project From View",                 UV_WINDOW_MAPPING) "|"
1382                                         MENUSTRING("Project from View (Bounds)",UV_BOUNDS_MAPPING) "|%l|"
1383                                         
1384                                         MENUSTRING("Reset",                                             UV_RESET_MAPPING);
1385         
1386         /* note that we account for the 10 previous entries with i+10: */
1387         for (pym = BPyMenuTable[PYMENU_UVCALCULATION]; pym; pym = pym->next, i++) {
1388                 
1389                 if (!has_pymenu) {
1390                         strcat(uvmenu, "|%l");
1391                         has_pymenu = 1;
1392                 }
1393                 
1394                 strcat(uvmenu, "|");
1395                 strcat(uvmenu, pym->name);
1396                 strcat(uvmenu, " %x");
1397                 sprintf(menu_number, "%d", i+10);
1398                 strcat(uvmenu, menu_number);
1399         }
1400         
1401         mode= pupmenu(uvmenu);
1402         
1403         if (mode >= 10) {
1404                 BPY_menu_do_python(PYMENU_UVCALCULATION, mode - 10);
1405                 return;
1406         }
1407         
1408         switch(mode) {
1409         case UV_CUBE_MAPPING:
1410                 calculate_uv_map(B_UVAUTO_CUBE); break;
1411         case UV_CYL_MAPPING:
1412                 calculate_uv_map(B_UVAUTO_CYLINDER); break;
1413         case UV_SPHERE_MAPPING:
1414                 calculate_uv_map(B_UVAUTO_SPHERE); break;
1415         case UV_BOUNDS_MAPPING:
1416                 calculate_uv_map(B_UVAUTO_BOUNDS); break;
1417         case UV_RESET_MAPPING:
1418                 calculate_uv_map(B_UVAUTO_RESET); break;
1419         case UV_WINDOW_MAPPING:
1420                 calculate_uv_map(B_UVAUTO_WINDOW); break;
1421         case UV_UNWRAP_MAPPING:
1422                 unwrap_lscm(0); break;
1423         }
1424 }
1425
1426 /* Texture Paint */
1427
1428 void set_texturepaint() /* toggle */
1429 {
1430         Object *ob = OBACT;
1431         Mesh *me = 0;
1432         
1433         scrarea_queue_headredraw(curarea);
1434         if(ob==NULL) return;
1435         
1436         if (object_data_is_libdata(ob)) {
1437                 error_libdata();
1438                 return;
1439         }
1440
1441         me= get_mesh(ob);
1442         
1443         if(me)
1444                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1445
1446         if(G.f & G_TEXTUREPAINT) {
1447                 G.f &= ~G_TEXTUREPAINT;
1448                 texpaint_enable_mipmap();
1449         }
1450         else if (me) {
1451                 G.f |= G_TEXTUREPAINT;
1452
1453                 if(me->mtface==NULL)
1454                         make_tfaces(me);
1455
1456                 brush_check_exists(&G.scene->toolsettings->imapaint.brush);
1457                 texpaint_disable_mipmap();
1458         }
1459
1460         allqueue(REDRAWVIEW3D, 0);
1461         allqueue(REDRAWBUTSEDIT, 0);
1462 }
1463
1464 static void texpaint_project(Object *ob, float *model, float *proj, float *co, float *pco)
1465 {
1466         VECCOPY(pco, co);
1467         pco[3]= 1.0f;
1468
1469         Mat4MulVecfl(ob->obmat, pco);
1470         Mat4MulVecfl((float(*)[4])model, pco);
1471         Mat4MulVec4fl((float(*)[4])proj, pco);
1472 }
1473
1474 static void texpaint_tri_weights(Object *ob, float *v1, float *v2, float *v3, float *co, float *w)
1475 {
1476         float pv1[4], pv2[4], pv3[4], h[3], divw;
1477         float model[16], proj[16], wmat[3][3], invwmat[3][3];
1478         GLint view[4];
1479
1480         /* compute barycentric coordinates */
1481
1482         /* get the needed opengl matrices */
1483         glGetIntegerv(GL_VIEWPORT, view);
1484         glGetFloatv(GL_MODELVIEW_MATRIX, model);
1485         glGetFloatv(GL_PROJECTION_MATRIX, proj);
1486         view[0] = view[1] = 0;
1487
1488         /* project the verts */
1489         texpaint_project(ob, model, proj, v1, pv1);
1490         texpaint_project(ob, model, proj, v2, pv2);
1491         texpaint_project(ob, model, proj, v3, pv3);
1492
1493         /* do inverse view mapping, see gluProject man page */
1494         h[0]= (co[0] - view[0])*2.0f/view[2] - 1;
1495         h[1]= (co[1] - view[1])*2.0f/view[3] - 1;
1496         h[2]= 1.0f;
1497
1498         /* solve for (w1,w2,w3)/perspdiv in:
1499            h*perspdiv = Project*Model*(w1*v1 + w2*v2 + w3*v3) */
1500
1501         wmat[0][0]= pv1[0];  wmat[1][0]= pv2[0];  wmat[2][0]= pv3[0];
1502         wmat[0][1]= pv1[1];  wmat[1][1]= pv2[1];  wmat[2][1]= pv3[1];
1503         wmat[0][2]= pv1[3];  wmat[1][2]= pv2[3];  wmat[2][2]= pv3[3];
1504
1505         Mat3Inv(invwmat, wmat);
1506         Mat3MulVecfl(invwmat, h);
1507
1508         VECCOPY(w, h);
1509
1510         /* w is still divided by perspdiv, make it sum to one */
1511         divw= w[0] + w[1] + w[2];
1512         if(divw != 0.0f)
1513                 VecMulf(w, 1.0f/divw);
1514 }
1515
1516 /* compute uv coordinates of mouse in face */
1517 void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy, float *uv)
1518 {
1519         DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
1520         int *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1521         MTFace *tface = dm->getFaceDataArray(dm, CD_MTFACE), *tf;
1522         int numfaces = dm->getNumFaces(dm), a;
1523         float p[2], w[3], absw, minabsw;
1524         MFace mf;
1525         MVert mv[4];
1526
1527         minabsw = 1e10;
1528         uv[0] = uv[1] = 0.0;
1529
1530         persp(PERSP_VIEW);
1531
1532         /* test all faces in the derivedmesh with the original index of the picked face */
1533         for (a = 0; a < numfaces; a++) {
1534                 if (index[a] == faceindex) {
1535                         dm->getFace(dm, a, &mf);
1536
1537                         dm->getVert(dm, mf.v1, &mv[0]);
1538                         dm->getVert(dm, mf.v2, &mv[1]);
1539                         dm->getVert(dm, mf.v3, &mv[2]);
1540                         if (mf.v4)
1541                                 dm->getVert(dm, mf.v4, &mv[3]);
1542
1543                         tf= &tface[a];
1544
1545                         p[0]= xy[0];
1546                         p[1]= xy[1];
1547
1548                         if (mf.v4) {
1549                                 /* the triangle with the largest absolute values is the one
1550                                    with the most negative weights */
1551                                 texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w);
1552                                 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1553                                 if(absw < minabsw) {
1554                                         uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[3][0]*w[2];
1555                                         uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[3][1]*w[2];
1556                                         minabsw = absw;
1557                                 }
1558
1559                                 texpaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w);
1560                                 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1561                                 if (absw < minabsw) {
1562                                         uv[0]= tf->uv[1][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2];
1563                                         uv[1]= tf->uv[1][1]*w[0] + tf->uv[2][1]*w[1] + tf->uv[3][1]*w[2];
1564                                         minabsw = absw;
1565                                 }
1566                         }
1567                         else {
1568                                 texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w);
1569                                 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1570                                 if (absw < minabsw) {
1571                                         uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2];
1572                                         uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[2][1]*w[2];
1573                                         minabsw = absw;
1574                                 }
1575                         }
1576                 }
1577         }
1578
1579         dm->release(dm);
1580 }