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