d89af858f2123f1ccf17251c64314066c774787a
[blender.git] / source / blender / src / editface.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30
31 #include <math.h>
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_arithb.h"
38 #include "BLI_heap.h"
39 #include "BLI_edgehash.h"
40 #include "BLI_editVert.h"
41
42 #include "MTC_matrixops.h"
43
44 #include "IMB_imbuf_types.h"
45 #include "IMB_imbuf.h"
46
47 #include "DNA_image_types.h"
48 #include "DNA_mesh_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_space_types.h"
52 #include "DNA_screen_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_view3d_types.h"
55
56 #include "BKE_brush.h"
57 #include "BKE_customdata.h"
58 #include "BKE_depsgraph.h"
59 #include "BKE_DerivedMesh.h"
60 #include "BKE_displist.h"
61 #include "BKE_global.h"
62 #include "BKE_mesh.h"
63 #include "BKE_multires.h"
64 #include "BKE_object.h"
65 #include "BKE_texture.h"
66 #include "BKE_utildefines.h"
67 #include "BKE_customdata.h"
68
69 #include "BSE_view.h"
70 #include "BSE_edit.h"
71 #include "BSE_drawview.h"       /* for backdrawview3d */
72
73 #include "BIF_editsima.h"
74 #include "BIF_editmesh.h"
75 #include "BIF_interface.h"
76 #include "BIF_mywindow.h"
77 #include "BIF_toolbox.h"
78 #include "BIF_resources.h"
79 #include "BIF_screen.h"
80 #include "BIF_gl.h"
81 #include "BIF_graphics.h"
82 #include "BIF_space.h"  /* for allqueue */
83 #include "BIF_drawimage.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
96 #include "BSE_trans_types.h"
97
98 #include "BDR_unwrapper.h"
99 #include "BDR_editobject.h"
100
101 #include "BPY_extern.h"
102 #include "BPY_menus.h"
103
104 /* Pupmenu codes: */
105 #define UV_CUBE_MAPPING 2
106 #define UV_CYL_MAPPING 3
107 #define UV_SPHERE_MAPPING 4
108 #define UV_BOUNDS_MAPPING 5
109 #define UV_RESET_MAPPING 6
110 #define UV_WINDOW_MAPPING 7
111 #define UV_UNWRAP_MAPPING 8
112 #define UV_CYL_EX 32
113 #define UV_SPHERE_EX 34
114
115 /* Some macro tricks to make pupmenu construction look nicer :-)
116    Sorry, just did it for fun. */
117
118 #define _STR(x) " " #x
119 #define STRING(x) _STR(x)
120
121 #define MENUSTRING(string, code) string " %x" STRING(code)
122 #define MENUTITLE(string) string " %t|" 
123
124
125 /* returns 0 if not found, otherwise 1 */
126 int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
127 {
128         if (!me || me->totface==0)
129                 return 0;
130
131         if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
132                 check_backbuf();
133                 persp(PERSP_VIEW);
134         }
135
136         if (rect) {
137                 /* sample rect to increase changes of selecting, so that when clicking
138                    on an edge in the backbuf, we can still select a face */
139                 int dist;
140                 *index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist,0,NULL);
141         }
142         else
143                 /* sample only on the exact position */
144                 *index = sample_backbuf(mval[0], mval[1]);
145
146         if ((*index)<=0 || (*index)>(unsigned int)me->totface)
147                 return 0;
148
149         (*index)--;
150         
151         return 1;
152 }
153
154 #if 0 // not used
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 #endif
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 correct_uv_aspect( void )
342 {
343         float aspx=1, aspy=1;
344         EditMesh *em = G.editMesh;
345         EditFace *efa = EM_get_actFace(1);
346         MTFace *tface;
347         
348         if (efa) {
349                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
350                 image_final_aspect(tface->tpage, &aspx, &aspy);
351         }
352         
353         if (aspx != aspy) {
354                 
355                 EditMesh *em = G.editMesh;
356                 float scale;
357                 
358                 if (aspx > aspy) {
359                         scale = aspy/aspx;
360                         for (efa= em->faces.first; efa; efa= efa->next) {
361                                 if (efa->f & SELECT) {
362                                         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
363                                         tface->uv[0][0] = ((tface->uv[0][0]-0.5)*scale)+0.5;
364                                         tface->uv[1][0] = ((tface->uv[1][0]-0.5)*scale)+0.5;
365                                         tface->uv[2][0] = ((tface->uv[2][0]-0.5)*scale)+0.5;
366                                         if(efa->v4) {
367                                                 tface->uv[3][0] = ((tface->uv[3][0]-0.5)*scale)+0.5;
368                                         }
369                                 }
370                         }
371                 } else {
372                         scale = aspx/aspy;
373                         for (efa= em->faces.first; efa; efa= efa->next) {
374                                 if (efa->f & SELECT) {
375                                         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
376                                         tface->uv[0][1] = ((tface->uv[0][1]-0.5)*scale)+0.5;
377                                         tface->uv[1][1] = ((tface->uv[1][1]-0.5)*scale)+0.5;
378                                         tface->uv[2][1] = ((tface->uv[2][1]-0.5)*scale)+0.5;
379                                         if(efa->v4) {
380                                                 tface->uv[3][1] = ((tface->uv[3][1]-0.5)*scale)+0.5;
381                                         }
382                                 }
383                         }
384                 }
385         }
386 }
387
388 void calculate_uv_map(unsigned short mapmode)
389 {
390         MTFace *tface;
391         Object *ob;
392         float dx, dy, rotatematrix[4][4], radius= 1.0, min[3], cent[3], max[3];
393         float fac= 1.0, upangledeg= 0.0, sideangledeg= 90.0;
394         int i, b, mi, n;
395
396         EditMesh *em = G.editMesh;
397         EditFace *efa;
398         
399         if(G.scene->toolsettings->uvcalc_mapdir==1)  {
400                 upangledeg= 90.0;
401                 sideangledeg= 0.0;
402         } else {
403                 upangledeg= 0.0;
404                 if(G.scene->toolsettings->uvcalc_mapalign==1) sideangledeg= 0.0;
405                 else sideangledeg= 90.0;
406         }
407         
408         /* add uvs if there not here */
409         if (!EM_texFaceCheck()) {
410                 if (em && em->faces.first)
411                         EM_add_data_layer(&em->fdata, CD_MTFACE);
412                 
413                 if (G.sima && G.sima->image) /* this is a bit of a kludge, but assume they want the image on their mesh when UVs are added */
414                         image_changed(G.sima, G.sima->image);
415                 
416                 if (!EM_texFaceCheck())
417                         return;
418                 
419                 /* select new UV's */
420                 if ((G.sima && G.sima->flag & SI_SYNC_UVSEL)==0) {
421                         for(efa=em->faces.first; efa; efa=efa->next) {
422                                 MTFace *tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
423                                 simaFaceSel_Set(efa, tf);
424                         }
425                 }
426         }
427         
428         ob=OBACT;
429         
430         switch(mapmode) {
431         case B_UVAUTO_BOUNDS:
432                 min[0]= min[1]= 10000000.0;
433                 max[0]= max[1]= -10000000.0;
434
435                 cent[0] = cent[1] = cent[2] = 0.0; 
436                 uv_calc_map_matrix(rotatematrix, ob, upangledeg, sideangledeg, 1.0f);
437                 
438                 for (efa= em->faces.first; efa; efa= efa->next) {
439                         if (efa->f & SELECT) {
440                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
441                                 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,3, efa->v1->co, min,max);
442                                 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,3, efa->v2->co, min,max);
443                                 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,3, efa->v3->co,min,max);
444                                 if(efa->v4)
445                                         uv_calc_shift_project(tface->uv[3],cent,rotatematrix,3, efa->v4->co,min,max);
446                         }
447                 }
448                 
449                 /* rescale UV to be in 1/1 */
450                 dx= (max[0]-min[0]);
451                 dy= (max[1]-min[1]);
452
453                 for (efa= em->faces.first; efa; efa= efa->next) {
454                         if (efa->f & SELECT) {
455                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
456                                 if(efa->v4) b= 3; else b= 2;
457                                 for(; b>=0; b--) {
458                                         tface->uv[b][0]= ((tface->uv[b][0]-min[0])*fac)/dx;
459                                         tface->uv[b][1]= 1.0-fac+((tface->uv[b][1]-min[1])/* *fac */)/dy;
460                                 }
461                         }
462                 }
463                 break;
464
465         case B_UVAUTO_WINDOW:           
466                 cent[0] = cent[1] = cent[2] = 0.0; 
467                 Mat4CpyMat4(rotatematrix,ob->obmat);
468                 for (efa= em->faces.first; efa; efa= efa->next) {
469                         if (efa->f & SELECT) {
470                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
471                                 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,4, efa->v1->co, NULL,NULL);
472                                 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,4, efa->v2->co, NULL,NULL);
473                                 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,4, efa->v3->co, NULL,NULL);
474                                 if(efa->v4)
475                                         uv_calc_shift_project(tface->uv[3],cent,rotatematrix,4, efa->v4->co, NULL,NULL);
476                         }
477                 }
478                 break;
479
480         case B_UVAUTO_RESET:
481                 for (efa= em->faces.first; efa; efa= efa->next) {
482                         if (efa->f & SELECT) {
483                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
484                                 default_uv(tface->uv, 1.0);
485                         }
486                 }
487                 break;
488
489         case B_UVAUTO_CYLINDER:
490         case B_UVAUTO_SPHERE:
491                 uv_calc_center_vector(cent, ob, em);
492                         
493                 if(mapmode==B_UVAUTO_CYLINDER) radius = G.scene->toolsettings->uvcalc_radius;
494
495                 /* be compatible to the "old" sphere/cylinder mode */
496                 if (G.scene->toolsettings->uvcalc_mapdir== 2)
497                         Mat4One(rotatematrix);
498                 else 
499                         uv_calc_map_matrix(rotatematrix,ob,upangledeg,sideangledeg,radius);
500                 for (efa= em->faces.first; efa; efa= efa->next) {
501                         if (efa->f & SELECT) {
502                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
503                                 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,mapmode, efa->v1->co, NULL,NULL);
504                                 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,mapmode, efa->v2->co, NULL,NULL);
505                                 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,mapmode, efa->v3->co, NULL,NULL);
506                                 n = 3;       
507                                 if(efa->v4) {
508                                         uv_calc_shift_project(tface->uv[3],cent,rotatematrix,mapmode, efa->v4->co, NULL,NULL);
509                                         n=4;
510                                 }
511
512                                 mi = 0;
513                                 for (i = 1; i < n; i++)
514                                         if (tface->uv[i][0] > tface->uv[mi][0]) mi = i;
515
516                                 for (i = 0; i < n; i++) {
517                                         if (i != mi) {
518                                                 dx = tface->uv[mi][0] - tface->uv[i][0];
519                                                 if (dx > 0.5) tface->uv[i][0] += 1.0;
520                                         } 
521                                 } 
522                         }
523                 }
524
525                 break;
526
527         case B_UVAUTO_CUBE:
528                 {
529                 /* choose x,y,z axis for projetion depending on the largest normal */
530                 /* component, but clusters all together around the center of map */
531                 float no[3];
532                 short cox, coy;
533                 float *loc= ob->obmat[3];
534                 /*MVert *mv= me->mvert;*/
535                 float cubesize = G.scene->toolsettings->uvcalc_cubesize;
536
537                 for (efa= em->faces.first; efa; efa= efa->next) {
538                         if (efa->f & SELECT) {
539                                 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
540                                 CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, no);
541                                 
542                                 no[0]= fabs(no[0]);
543                                 no[1]= fabs(no[1]);
544                                 no[2]= fabs(no[2]);
545                                 
546                                 cox=0; coy= 1;
547                                 if(no[2]>=no[0] && no[2]>=no[1]);
548                                 else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2;
549                                 else { cox= 1; coy= 2; }
550                                 
551                                 tface->uv[0][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v1->co[cox]);
552                                 tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v1->co[coy]);
553                                 dx = floor(tface->uv[0][0]);
554                                 dy = floor(tface->uv[0][1]);
555                                 tface->uv[0][0] -= dx;
556                                 tface->uv[0][1] -= dy;
557                                 tface->uv[1][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v2->co[cox]);
558                                 tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v2->co[coy]);
559                                 tface->uv[1][0] -= dx;
560                                 tface->uv[1][1] -= dy;
561                                 tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v3->co[cox]);
562                                 tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v3->co[coy]);
563                                 tface->uv[2][0] -= dx;
564                                 tface->uv[2][1] -= dy;
565                                 if(efa->v4) {
566                                         tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v4->co[cox]);
567                                         tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v4->co[coy]);
568                                         tface->uv[3][0] -= dx;
569                                         tface->uv[3][1] -= dy;
570                                 }
571                         }
572                 }
573                 break;
574                 }
575         default:
576                 if ((G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0)
577                         correct_uv_aspect();
578                 return;
579         } /* end switch mapmode */
580
581         /* clipping and wrapping */
582         if(G.sima && G.sima->flag & SI_CLIP_UV) {
583                 for (efa= em->faces.first; efa; efa= efa->next) {
584                         if (!(efa->f & SELECT)) continue;
585                         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
586                 
587                         dx= dy= 0;
588                         if(efa->v4) b= 3; else b= 2;
589                         for(; b>=0; b--) {
590                                 while(tface->uv[b][0] + dx < 0.0) dx+= 0.5;
591                                 while(tface->uv[b][0] + dx > 1.0) dx-= 0.5;
592                                 while(tface->uv[b][1] + dy < 0.0) dy+= 0.5;
593                                 while(tface->uv[b][1] + dy > 1.0) dy-= 0.5;
594                         }
595         
596                         if(efa->v4) b= 3; else b= 2;
597                         for(; b>=0; b--) {
598                                 tface->uv[b][0]+= dx;
599                                 CLAMP(tface->uv[b][0], 0.0, 1.0);
600                                 
601                                 tface->uv[b][1]+= dy;
602                                 CLAMP(tface->uv[b][1], 0.0, 1.0);
603                         }
604                 }
605         }
606
607         if (    (mapmode!=B_UVAUTO_BOUNDS) &&
608                         (mapmode!=B_UVAUTO_RESET) &&
609                         (G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0
610                 ) {
611                 correct_uv_aspect();
612         }
613         
614         BIF_undo_push("UV calculation");
615
616         object_uvs_changed(OBACT);
617
618         allqueue(REDRAWVIEW3D, 0);
619         allqueue(REDRAWIMAGE, 0);
620 }
621
622 /* last_sel, use em->act_face otherwise get the last selected face in the editselections
623  * at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */
624 MTFace *get_active_mtface(EditFace **act_efa, MCol **mcol, int sloppy)
625 {
626         EditMesh *em = G.editMesh;
627         EditFace *efa = NULL;
628         
629         if(!EM_texFaceCheck())
630                 return NULL;
631         
632         efa = EM_get_actFace(sloppy);
633         
634         if (efa) {
635                 if (mcol) {
636                         if (CustomData_has_layer(&em->fdata, CD_MCOL))
637                                 *mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
638                         else
639                                 *mcol = NULL;
640                 }
641                 if (act_efa) *act_efa = efa; 
642                 return CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
643         }
644         if (act_efa) *act_efa= NULL;
645         if(mcol) *mcol = NULL;
646         return NULL;
647 }
648
649 void default_uv(float uv[][2], float size)
650 {
651         int dy;
652         
653         if(size>1.0) size= 1.0;
654
655         dy= 1.0-size;
656         
657         uv[0][0]= 0;
658         uv[0][1]= size+dy;
659         
660         uv[1][0]= 0;
661         uv[1][1]= dy;
662         
663         uv[2][0]= size;
664         uv[2][1]= dy;
665         
666         uv[3][0]= size;
667         uv[3][1]= size+dy;
668 }
669
670 void make_tfaces(Mesh *me) 
671 {
672         if(!me->mtface) {
673                 if(me->mr) {
674                         multires_add_layer(me, &me->mr->fdata, CD_MTFACE,
675                                            CustomData_number_of_layers(&me->fdata, CD_MTFACE));
676                 }
677                 else {
678                         me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT,
679                                 NULL, me->totface);
680                 }
681         }
682 }
683
684 void reveal_tface()
685 {
686         Mesh *me;
687         MFace *mface;
688         int a;
689         
690         me= get_mesh(OBACT);
691         if(me==0 || me->totface==0) return;
692         
693         mface= me->mface;
694         a= me->totface;
695         while(a--) {
696                 if(mface->flag & ME_HIDE) {
697                         mface->flag |= ME_FACE_SEL;
698                         mface->flag -= ME_HIDE;
699                 }
700                 mface++;
701         }
702
703         BIF_undo_push("Reveal face");
704
705         object_tface_flags_changed(OBACT, 0);
706 }
707
708 void hide_tface()
709 {
710         Mesh *me;
711         MFace *mface;
712         int a;
713         
714         me= get_mesh(OBACT);
715         if(me==0 || me->totface==0) return;
716         
717         if(G.qual & LR_ALTKEY) {
718                 reveal_tface();
719                 return;
720         }
721         
722         mface= me->mface;
723         a= me->totface;
724         while(a--) {
725                 if(mface->flag & ME_HIDE);
726                 else {
727                         if(G.qual & LR_SHIFTKEY) {
728                                 if( (mface->flag & ME_FACE_SEL)==0) mface->flag |= ME_HIDE;
729                         }
730                         else {
731                                 if( (mface->flag & ME_FACE_SEL)) mface->flag |= ME_HIDE;
732                         }
733                 }
734                 if(mface->flag & ME_HIDE) mface->flag &= ~ME_FACE_SEL;
735                 
736                 mface++;
737         }
738
739         BIF_undo_push("Hide face");
740
741         object_tface_flags_changed(OBACT, 0);
742 }
743
744 void select_linked_tfaces(int mode)
745 {
746         Object *ob;
747         Mesh *me;
748         short mval[2];
749         unsigned int index=0;
750
751         ob = OBACT;
752         me = get_mesh(ob);
753         if(me==0 || me->totface==0) return;
754
755         if (mode==0 || mode==1) {
756                 if (!(ob->lay & G.vd->lay))
757                         error("The active object is not in this layer");
758                         
759                 getmouseco_areawin(mval);
760                 if (!facesel_face_pick(me, mval, &index, 1)) return;
761         }
762
763         select_linked_tfaces_with_seams(mode, me, index);
764 }
765
766 void deselectall_tface()
767 {
768         Mesh *me;
769         MFace *mface;
770         int a, sel;
771                 
772         me= get_mesh(OBACT);
773         if(me==0) return;
774         
775         mface= me->mface;
776         a= me->totface;
777         sel= 0;
778         while(a--) {
779                 if(mface->flag & ME_HIDE);
780                 else if(mface->flag & ME_FACE_SEL) sel= 1;
781                 mface++;
782         }
783         
784         mface= me->mface;
785         a= me->totface;
786         while(a--) {
787                 if(mface->flag & ME_HIDE);
788                 else {
789                         if(sel) mface->flag &= ~ME_FACE_SEL;
790                         else mface->flag |= ME_FACE_SEL;
791                 }
792                 mface++;
793         }
794
795         BIF_undo_push("(De)select all faces");
796
797         object_tface_flags_changed(OBACT, 0);
798 }
799
800 void selectswap_tface(void)
801 {
802         Mesh *me;
803         MFace *mface;
804         int a;
805                 
806         me= get_mesh(OBACT);
807         if(me==0) return;
808         
809         mface= me->mface;
810         a= me->totface;
811         while(a--) {
812                 if(mface->flag & ME_HIDE);
813                 else {
814                         if(mface->flag & ME_FACE_SEL) mface->flag &= ~ME_FACE_SEL;
815                         else mface->flag |= ME_FACE_SEL;
816                 }
817                 mface++;
818         }
819
820         BIF_undo_push("Select inverse face");
821
822         object_tface_flags_changed(OBACT, 0);
823 }
824
825 int minmax_tface(float *min, float *max)
826 {
827         Object *ob;
828         Mesh *me;
829         MFace *mf;
830         MTFace *tf;
831         MVert *mv;
832         int a, ok=0;
833         float vec[3], bmat[3][3];
834         
835         ob = OBACT;
836         if (ob==0) return ok;
837         me= get_mesh(ob);
838         if(me==0 || me->mtface==0) return ok;
839         
840         Mat3CpyMat4(bmat, ob->obmat);
841
842         mv= me->mvert;
843         mf= me->mface;
844         tf= me->mtface;
845         for (a=me->totface; a>0; a--, mf++, tf++) {
846                 if (mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL))
847                         continue;
848
849                 VECCOPY(vec, (mv+mf->v1)->co);
850                 Mat3MulVecfl(bmat, vec);
851                 VecAddf(vec, vec, ob->obmat[3]);
852                 DO_MINMAX(vec, min, max);               
853
854                 VECCOPY(vec, (mv+mf->v2)->co);
855                 Mat3MulVecfl(bmat, vec);
856                 VecAddf(vec, vec, ob->obmat[3]);
857                 DO_MINMAX(vec, min, max);               
858
859                 VECCOPY(vec, (mv+mf->v3)->co);
860                 Mat3MulVecfl(bmat, vec);
861                 VecAddf(vec, vec, ob->obmat[3]);
862                 DO_MINMAX(vec, min, max);               
863
864                 if (mf->v4) {
865                         VECCOPY(vec, (mv+mf->v4)->co);
866                         Mat3MulVecfl(bmat, vec);
867                         VecAddf(vec, vec, ob->obmat[3]);
868                         DO_MINMAX(vec, min, max);
869                 }
870                 ok= 1;
871         }
872         return ok;
873 }
874
875 #define ME_SEAM_DONE 2          /* reuse this flag */
876
877 static float edgetag_cut_cost(EditMesh *em, int e1, int e2, int vert)
878 {
879         EditVert *v = EM_get_vert_for_index(vert);
880         EditEdge *eed1 = EM_get_edge_for_index(e1), *eed2 = EM_get_edge_for_index(e2);
881         EditVert *v1 = EM_get_vert_for_index( (eed1->v1->tmp.l == vert)? eed1->v2->tmp.l: eed1->v1->tmp.l );
882         EditVert *v2 = EM_get_vert_for_index( (eed2->v1->tmp.l == vert)? eed2->v2->tmp.l: eed2->v1->tmp.l );
883         float cost, d1[3], d2[3];
884
885         cost = VecLenf(v1->co, v->co);
886         cost += VecLenf(v->co, v2->co);
887
888         VecSubf(d1, v->co, v1->co);
889         VecSubf(d2, v2->co, v->co);
890
891         cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
892
893         return cost;
894 }
895
896 static void edgetag_add_adjacent(EditMesh *em, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
897 {
898         int startadj, endadj = nedges[vertnum+1];
899
900         for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
901                 int adjnum = edges[startadj];
902                 EditEdge *eedadj = EM_get_edge_for_index(adjnum);
903                 float newcost;
904
905                 if (eedadj->f2 & ME_SEAM_DONE)
906                         continue;
907
908                 newcost = cost[mednum] + edgetag_cut_cost(em, mednum, adjnum, vertnum);
909
910                 if (cost[adjnum] > newcost) {
911                         cost[adjnum] = newcost;
912                         prevedge[adjnum] = mednum;
913                         BLI_heap_insert(heap, newcost, SET_INT_IN_POINTER(adjnum));
914                 }
915         }
916 }
917
918 void edgetag_context_set(EditEdge *eed, int val)
919 {
920         switch (G.scene->toolsettings->edge_mode) {
921         case EDGE_MODE_TAG_SEAM:
922                 if (val)                {eed->seam = 255;}
923                 else                    {eed->seam = 0;}
924                 break;
925         case EDGE_MODE_TAG_SHARP:
926                 if (val)                {eed->sharp = 1;}
927                 else                    {eed->sharp = 0;}
928                 break;                          
929         case EDGE_MODE_TAG_CREASE:      
930                 if (val)                {eed->crease = 1.0f;}
931                 else                    {eed->crease = 0.0f;}
932                 break;
933         case EDGE_MODE_TAG_BEVEL:
934                 if (val)                {eed->bweight = 1.0f;}
935                 else                    {eed->bweight = 0.0f;}
936                 break;
937         }
938 }
939
940 int edgetag_context_check(EditEdge *eed)
941 {
942         switch (G.scene->toolsettings->edge_mode) {
943         case EDGE_MODE_TAG_SEAM:
944                 return eed->seam ? 1 : 0;
945         case EDGE_MODE_TAG_SHARP:
946                 return eed->sharp ? 1 : 0;
947         case EDGE_MODE_TAG_CREASE:      
948                 return eed->crease ? 1 : 0;
949         case EDGE_MODE_TAG_BEVEL:
950                 return eed->bweight ? 1 : 0;
951         }
952         return 0;
953 }
954
955
956 int edgetag_shortest_path(EditEdge *source, EditEdge *target)
957 {
958         EditMesh *em = G.editMesh;
959         EditEdge *eed;
960         EditVert *ev;
961         
962         Heap *heap;
963         float *cost;
964         int a, totvert=0, totedge=0, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
965
966
967         /* we need the vert */
968         for (ev= em->verts.first, totvert=0; ev; ev= ev->next) {
969                 ev->tmp.l = totvert;
970                 totvert++;
971         }
972
973         for (eed= em->edges.first; eed; eed = eed->next) {
974                 eed->f2 = 0;
975                 if (eed->h) {
976                         eed->f2 |= ME_SEAM_DONE;
977                 }
978                 eed->tmp.l = totedge;
979                 totedge++;
980         }
981
982         /* alloc */
983         nedges = MEM_callocN(sizeof(*nedges)*totvert+1, "SeamPathNEdges");
984         edges = MEM_mallocN(sizeof(*edges)*totedge*2, "SeamPathEdges");
985         prevedge = MEM_mallocN(sizeof(*prevedge)*totedge, "SeamPathPrevious");
986         cost = MEM_mallocN(sizeof(*cost)*totedge, "SeamPathCost");
987
988         /* count edges, compute adjacent edges offsets and fill adjacent edges */
989         for (eed= em->edges.first; eed; eed = eed->next) {
990                 nedges[eed->v1->tmp.l+1]++;
991                 nedges[eed->v2->tmp.l+1]++;
992         }
993
994         for (a=1; a<totvert; a++) {
995                 int newswap = nedges[a+1];
996                 nedges[a+1] = nedgeswap + nedges[a];
997                 nedgeswap = newswap;
998         }
999         nedges[0] = nedges[1] = 0;
1000
1001         for (a=0, eed= em->edges.first; eed; a++, eed = eed->next) {
1002                 edges[nedges[eed->v1->tmp.l+1]++] = a;
1003                 edges[nedges[eed->v2->tmp.l+1]++] = a;
1004
1005                 cost[a] = 1e20f;
1006                 prevedge[a] = -1;
1007         }
1008
1009         /* regular dijkstra shortest path, but over edges instead of vertices */
1010         heap = BLI_heap_new();
1011         BLI_heap_insert(heap, 0.0f, SET_INT_IN_POINTER(source->tmp.l));
1012         cost[source->tmp.l] = 0.0f;
1013
1014         EM_init_index_arrays(1, 1, 0);
1015
1016
1017         while (!BLI_heap_empty(heap)) {
1018                 mednum = GET_INT_FROM_POINTER(BLI_heap_popmin(heap));
1019                 eed = EM_get_edge_for_index( mednum );
1020
1021                 if (mednum == target->tmp.l)
1022                         break;
1023
1024                 if (eed->f2 & ME_SEAM_DONE)
1025                         continue;
1026
1027                 eed->f2 |= ME_SEAM_DONE;
1028
1029                 edgetag_add_adjacent(em, heap, mednum, eed->v1->tmp.l, nedges, edges, prevedge, cost);
1030                 edgetag_add_adjacent(em, heap, mednum, eed->v2->tmp.l, nedges, edges, prevedge, cost);
1031         }
1032         
1033         
1034         MEM_freeN(nedges);
1035         MEM_freeN(edges);
1036         MEM_freeN(cost);
1037         BLI_heap_free(heap, NULL);
1038
1039         for (eed= em->edges.first; eed; eed = eed->next) {
1040                 eed->f2 &= ~ME_SEAM_DONE;
1041         }
1042
1043         if (mednum != target->tmp.l) {
1044                 MEM_freeN(prevedge);
1045                 EM_free_index_arrays();
1046                 return 0;
1047         }
1048
1049         /* follow path back to source and mark as seam */
1050         if (mednum == target->tmp.l) {
1051                 short allseams = 1;
1052
1053                 mednum = target->tmp.l;
1054                 do {
1055                         eed = EM_get_edge_for_index( mednum );
1056                         if (!edgetag_context_check(eed)) {
1057                                 allseams = 0;
1058                                 break;
1059                         }
1060                         mednum = prevedge[mednum];
1061                 } while (mednum != source->tmp.l);
1062
1063                 mednum = target->tmp.l;
1064                 do {
1065                         eed = EM_get_edge_for_index( mednum );
1066                         if (allseams)
1067                                 edgetag_context_set(eed, 0);
1068                         else
1069                                 edgetag_context_set(eed, 1);
1070                         mednum = prevedge[mednum];
1071                 } while (mednum != -1);
1072         }
1073
1074         MEM_freeN(prevedge);
1075         EM_free_index_arrays();
1076         return 1;
1077 }
1078
1079 void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
1080 {
1081         BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
1082         BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
1083         if (mf->v4) {
1084                 BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
1085                 BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
1086         }
1087         else
1088                 BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
1089 }
1090
1091 void seam_mark_clear_tface(short mode)
1092 {
1093         Mesh *me;
1094         MFace *mf;
1095         MEdge *med;
1096         int a;
1097         
1098         me= get_mesh(OBACT);
1099         if(me==0 ||  me->totface==0) return;
1100
1101         if (mode == 0)
1102                 mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
1103
1104         if (mode != 1 && mode != 2)
1105                 return;
1106
1107         if (mode == 2) {
1108                 EdgeHash *ehash = BLI_edgehash_new();
1109
1110                 for (a=0, mf=me->mface; a<me->totface; a++, mf++)
1111                         if (!(mf->flag & ME_HIDE) && (mf->flag & ME_FACE_SEL))
1112                                 seam_edgehash_insert_face(ehash, mf);
1113
1114                 for (a=0, med=me->medge; a<me->totedge; a++, med++)
1115                         if (BLI_edgehash_haskey(ehash, med->v1, med->v2))
1116                                 med->flag &= ~ME_SEAM;
1117
1118                 BLI_edgehash_free(ehash, NULL);
1119         }
1120         else {
1121                 /* mark edges that are on both selected and deselected faces */
1122                 EdgeHash *ehash1 = BLI_edgehash_new();
1123                 EdgeHash *ehash2 = BLI_edgehash_new();
1124
1125                 for (a=0, mf=me->mface; a<me->totface; a++, mf++) {
1126                         if ((mf->flag & ME_HIDE) || !(mf->flag & ME_FACE_SEL))
1127                                 seam_edgehash_insert_face(ehash1, mf);
1128                         else
1129                                 seam_edgehash_insert_face(ehash2, mf);
1130                 }
1131
1132                 for (a=0, med=me->medge; a<me->totedge; a++, med++)
1133                         if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) &&
1134                             BLI_edgehash_haskey(ehash2, med->v1, med->v2))
1135                                 med->flag |= ME_SEAM;
1136
1137                 BLI_edgehash_free(ehash1, NULL);
1138                 BLI_edgehash_free(ehash2, NULL);
1139         }
1140
1141         if (G.rt == 8)
1142                 unwrap_lscm(1);
1143
1144         G.f |= G_DRAWSEAMS;
1145         BIF_undo_push("Mark Seam");
1146
1147         object_tface_flags_changed(OBACT, 1);
1148 }
1149
1150 void face_select()
1151 {
1152         Object *ob;
1153         Mesh *me;
1154         MFace *mface, *msel;
1155         short mval[2];
1156         unsigned int a, index;
1157
1158         /* Get the face under the cursor */
1159         ob = OBACT;
1160         if (!(ob->lay & G.vd->lay)) {
1161                 error("The active object is not in this layer");
1162         }
1163         me = get_mesh(ob);
1164         getmouseco_areawin(mval);
1165
1166         if (!facesel_face_pick(me, mval, &index, 1)) return;
1167         
1168         msel= (((MFace*)me->mface)+index);
1169         if (msel->flag & ME_HIDE) return;
1170         
1171         /* clear flags */
1172         mface = me->mface;
1173         a = me->totface;
1174         if ((G.qual & LR_SHIFTKEY)==0) {
1175                 while (a--) {
1176                         mface->flag &= ~ME_FACE_SEL;
1177                         mface++;
1178                 }
1179         }
1180         
1181         me->act_face = (int)index;
1182
1183         if (G.qual & LR_SHIFTKEY) {
1184                 if (msel->flag & ME_FACE_SEL)
1185                         msel->flag &= ~ME_FACE_SEL;
1186                 else
1187                         msel->flag |= ME_FACE_SEL;
1188         }
1189         else msel->flag |= ME_FACE_SEL;
1190         
1191         /* image window redraw */
1192         
1193         BIF_undo_push("Select UV face");
1194
1195         object_tface_flags_changed(OBACT, 1);
1196 }
1197
1198 void face_borderselect()
1199 {
1200         Mesh *me;
1201         MFace *mface;
1202         rcti rect;
1203         struct ImBuf *ibuf;
1204         unsigned int *rt;
1205         int a, sx, sy, index, val;
1206         char *selar;
1207         
1208         me= get_mesh(OBACT);
1209         if(me==0) return;
1210         if(me->totface==0) return;
1211         
1212         val= get_border(&rect, 3);
1213         
1214         /* why readbuffer here? shouldn't be necessary (maybe a flush or so) */
1215         glReadBuffer(GL_BACK);
1216 #ifdef __APPLE__
1217         glReadBuffer(GL_AUX0); /* apple only */
1218 #endif
1219         
1220         if(val) {
1221                 selar= MEM_callocN(me->totface+1, "selar");
1222                 
1223                 sx= (rect.xmax-rect.xmin+1);
1224                 sy= (rect.ymax-rect.ymin+1);
1225                 if(sx*sy<=0) return;
1226
1227                 ibuf = IMB_allocImBuf(sx,sy,32,IB_rect,0);
1228                 rt = ibuf->rect;
1229                 glReadPixels(rect.xmin+curarea->winrct.xmin,  rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
1230                 if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
1231
1232                 a= sx*sy;
1233                 while(a--) {
1234                         if(*rt) {
1235                                 index= framebuffer_to_index(*rt);
1236                                 if(index<=me->totface) selar[index]= 1;
1237                         }
1238                         rt++;
1239                 }
1240                 
1241                 mface= me->mface;
1242                 for(a=1; a<=me->totface; a++, mface++) {
1243                         if(selar[a]) {
1244                                 if(mface->flag & ME_HIDE);
1245                                 else {
1246                                         if(val==LEFTMOUSE) mface->flag |= ME_FACE_SEL;
1247                                         else mface->flag &= ~ME_FACE_SEL;
1248                                 }
1249                         }
1250                 }
1251                 
1252                 IMB_freeImBuf(ibuf);
1253                 MEM_freeN(selar);
1254
1255                 BIF_undo_push("Border Select UV face");
1256
1257                 object_tface_flags_changed(OBACT, 0);
1258         }
1259 #ifdef __APPLE__        
1260         glReadBuffer(GL_BACK);
1261 #endif
1262 }
1263
1264 void uv_autocalc_tface()
1265 {
1266         short mode, i=0, has_pymenu=0; /* pymenu must be bigger then UV_*_MAPPING */
1267         BPyMenu *pym;
1268         char menu_number[3];
1269         
1270         /* uvmenu, will add python items */
1271         char uvmenu[4096]=MENUTITLE("UV Calculation")
1272                                         MENUSTRING("Unwrap",                            UV_UNWRAP_MAPPING) "|%l|"
1273                                         
1274                                         MENUSTRING("Cube Projection",                   UV_CUBE_MAPPING) "|"
1275                                         MENUSTRING("Cylinder from View",                UV_CYL_MAPPING) "|"
1276                                         MENUSTRING("Sphere from View",                  UV_SPHERE_MAPPING) "|%l|"
1277
1278                                         MENUSTRING("Project From View",                 UV_WINDOW_MAPPING) "|"
1279                                         MENUSTRING("Project from View (Bounds)",UV_BOUNDS_MAPPING) "|%l|"
1280                                         
1281                                         MENUSTRING("Reset",                                             UV_RESET_MAPPING);
1282         
1283         /* note that we account for the 10 previous entries with i+10: */
1284         for (pym = BPyMenuTable[PYMENU_UVCALCULATION]; pym; pym = pym->next, i++) {
1285                 
1286                 if (!has_pymenu) {
1287                         strcat(uvmenu, "|%l");
1288                         has_pymenu = 1;
1289                 }
1290                 
1291                 strcat(uvmenu, "|");
1292                 strcat(uvmenu, pym->name);
1293                 strcat(uvmenu, " %x");
1294                 sprintf(menu_number, "%d", i+10);
1295                 strcat(uvmenu, menu_number);
1296         }
1297         
1298         mode= pupmenu(uvmenu);
1299         
1300         if (mode >= 10) {
1301                 BPY_menu_do_python(PYMENU_UVCALCULATION, mode - 10);
1302                 return;
1303         }
1304         
1305         switch(mode) {
1306         case UV_CUBE_MAPPING:
1307                 calculate_uv_map(B_UVAUTO_CUBE); break;
1308         case UV_CYL_MAPPING:
1309                 calculate_uv_map(B_UVAUTO_CYLINDER); break;
1310         case UV_SPHERE_MAPPING:
1311                 calculate_uv_map(B_UVAUTO_SPHERE); break;
1312         case UV_BOUNDS_MAPPING:
1313                 calculate_uv_map(B_UVAUTO_BOUNDS); break;
1314         case UV_RESET_MAPPING:
1315                 calculate_uv_map(B_UVAUTO_RESET); break;
1316         case UV_WINDOW_MAPPING:
1317                 calculate_uv_map(B_UVAUTO_WINDOW); break;
1318         case UV_UNWRAP_MAPPING:
1319                 unwrap_lscm(0); break;
1320         }
1321 }
1322
1323 /* Texture Paint */
1324
1325 void set_texturepaint() /* toggle */
1326 {
1327         Object *ob = OBACT;
1328         Mesh *me = 0;
1329         
1330         scrarea_queue_headredraw(curarea);
1331         if(ob==NULL) return;
1332         
1333         if (object_data_is_libdata(ob)) {
1334                 error_libdata();
1335                 return;
1336         }
1337
1338         me= get_mesh(ob);
1339         
1340         if(me)
1341                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1342
1343         if(G.f & G_TEXTUREPAINT) {
1344                 G.f &= ~G_TEXTUREPAINT;
1345                 texpaint_enable_mipmap();
1346         }
1347         else if (me) {
1348                 G.f |= G_TEXTUREPAINT;
1349
1350                 if(me->mtface==NULL)
1351                         make_tfaces(me);
1352
1353                 brush_check_exists(&G.scene->toolsettings->imapaint.brush);
1354                 texpaint_disable_mipmap();
1355         }
1356
1357         allqueue(REDRAWVIEW3D, 0);
1358         allqueue(REDRAWBUTSEDIT, 0);
1359 }
1360
1361 static void texpaint_project(Object *ob, float *model, float *proj, float *co, float *pco)
1362 {
1363         VECCOPY(pco, co);
1364         pco[3]= 1.0f;
1365
1366         Mat4MulVecfl(ob->obmat, pco);
1367         Mat4MulVecfl((float(*)[4])model, pco);
1368         Mat4MulVec4fl((float(*)[4])proj, pco);
1369 }
1370
1371 static void texpaint_tri_weights(Object *ob, float *v1, float *v2, float *v3, float *co, float *w)
1372 {
1373         float pv1[4], pv2[4], pv3[4], h[3], divw;
1374         float model[16], proj[16], wmat[3][3], invwmat[3][3];
1375         GLint view[4];
1376
1377         /* compute barycentric coordinates */
1378
1379         /* get the needed opengl matrices */
1380         glGetIntegerv(GL_VIEWPORT, view);
1381         glGetFloatv(GL_MODELVIEW_MATRIX, model);
1382         glGetFloatv(GL_PROJECTION_MATRIX, proj);
1383         view[0] = view[1] = 0;
1384
1385         /* project the verts */
1386         texpaint_project(ob, model, proj, v1, pv1);
1387         texpaint_project(ob, model, proj, v2, pv2);
1388         texpaint_project(ob, model, proj, v3, pv3);
1389
1390         /* do inverse view mapping, see gluProject man page */
1391         h[0]= (co[0] - view[0])*2.0f/view[2] - 1;
1392         h[1]= (co[1] - view[1])*2.0f/view[3] - 1;
1393         h[2]= 1.0f;
1394
1395         /* solve for (w1,w2,w3)/perspdiv in:
1396            h*perspdiv = Project*Model*(w1*v1 + w2*v2 + w3*v3) */
1397
1398         wmat[0][0]= pv1[0];  wmat[1][0]= pv2[0];  wmat[2][0]= pv3[0];
1399         wmat[0][1]= pv1[1];  wmat[1][1]= pv2[1];  wmat[2][1]= pv3[1];
1400         wmat[0][2]= pv1[3];  wmat[1][2]= pv2[3];  wmat[2][2]= pv3[3];
1401
1402         Mat3Inv(invwmat, wmat);
1403         Mat3MulVecfl(invwmat, h);
1404
1405         VECCOPY(w, h);
1406
1407         /* w is still divided by perspdiv, make it sum to one */
1408         divw= w[0] + w[1] + w[2];
1409         if(divw != 0.0f)
1410                 VecMulf(w, 1.0f/divw);
1411 }
1412
1413 /* compute uv coordinates of mouse in face */
1414 void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy, float *uv)
1415 {
1416         DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
1417         int *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1418         MTFace *tface = dm->getFaceDataArray(dm, CD_MTFACE), *tf;
1419         int numfaces = dm->getNumFaces(dm), a;
1420         float p[2], w[3], absw, minabsw;
1421         MFace mf;
1422         MVert mv[4];
1423
1424         minabsw = 1e10;
1425         uv[0] = uv[1] = 0.0;
1426
1427         persp(PERSP_VIEW);
1428
1429         /* test all faces in the derivedmesh with the original index of the picked face */
1430         for (a = 0; a < numfaces; a++) {
1431                 if (index[a] == faceindex) {
1432                         dm->getFace(dm, a, &mf);
1433
1434                         dm->getVert(dm, mf.v1, &mv[0]);
1435                         dm->getVert(dm, mf.v2, &mv[1]);
1436                         dm->getVert(dm, mf.v3, &mv[2]);
1437                         if (mf.v4)
1438                                 dm->getVert(dm, mf.v4, &mv[3]);
1439
1440                         tf= &tface[a];
1441
1442                         p[0]= xy[0];
1443                         p[1]= xy[1];
1444
1445                         if (mf.v4) {
1446                                 /* the triangle with the largest absolute values is the one
1447                                    with the most negative weights */
1448                                 texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w);
1449                                 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1450                                 if(absw < minabsw) {
1451                                         uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[3][0]*w[2];
1452                                         uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[3][1]*w[2];
1453                                         minabsw = absw;
1454                                 }
1455
1456                                 texpaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w);
1457                                 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1458                                 if (absw < minabsw) {
1459                                         uv[0]= tf->uv[1][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2];
1460                                         uv[1]= tf->uv[1][1]*w[0] + tf->uv[2][1]*w[1] + tf->uv[3][1]*w[2];
1461                                         minabsw = absw;
1462                                 }
1463                         }
1464                         else {
1465                                 texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w);
1466                                 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1467                                 if (absw < minabsw) {
1468                                         uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2];
1469                                         uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[2][1]*w[2];
1470                                         minabsw = absw;
1471                                 }
1472                         }
1473                 }
1474         }
1475
1476         dm->release(dm);
1477 }