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