612e068c6cade9f80c78fd6bbd26b56e7e642ddf
[blender-staging.git] / source / blender / src / unwrapper.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 #include <string.h>
31 #include <stdlib.h>
32 #include <math.h>
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_mesh_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45
46 #include "BKE_global.h"
47 #include "BKE_mesh.h"
48 #include "BKE_utildefines.h"
49 #include "BKE_customdata.h"
50
51 #include "BLI_arithb.h"
52 #include "BLI_edgehash.h"
53 #include "BLI_editVert.h"
54
55 #include "BIF_editsima.h"
56 #include "BIF_space.h"
57 #include "BIF_screen.h"
58 #include "BIF_editmesh.h"
59
60 #include "blendef.h"
61 #include "mydevice.h"
62
63 #include "BDR_unwrapper.h"
64
65 #include "PIL_time.h"
66
67 #include "parametrizer.h"
68
69 /* Set tface seams based on edge data, uses hash table to find seam edges. */
70
71 static void hash_add_face(EdgeHash *ehash, MFace *mf)
72 {
73         BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
74         BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
75         if(mf->v4) {
76                 BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
77                 BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
78         }
79         else
80                 BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
81 }
82
83 void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
84 {
85         MFace *mf;
86         int a, doit=1, mark=0;
87         char *linkflag;
88         EdgeHash *ehash, *seamhash;
89         MEdge *med;
90
91         ehash= BLI_edgehash_new();
92         seamhash = BLI_edgehash_new();
93         linkflag= MEM_callocN(sizeof(char)*me->totface, "linkflaguv");
94
95         for(med=me->medge, a=0; a < me->totedge; a++, med++)
96                 if(med->flag & ME_SEAM)
97                         BLI_edgehash_insert(seamhash, med->v1, med->v2, NULL);
98
99         if (mode==0 || mode==1) {
100                 /* only put face under cursor in array */
101                 mf= ((MFace*)me->mface) + index;
102                 hash_add_face(ehash, mf);
103                 linkflag[index]= 1;
104         }
105         else {
106                 /* fill array by selection */
107                 mf= me->mface;
108                 for(a=0; a<me->totface; a++, mf++) {
109                         if(mf->flag & ME_HIDE);
110                         else if(mf->flag & ME_FACE_SEL) {
111                                 hash_add_face(ehash, mf);
112                                 linkflag[a]= 1;
113                         }
114                 }
115         }
116         
117         while(doit) {
118                 doit= 0;
119                 
120                 /* expand selection */
121                 mf= me->mface;
122                 for(a=0; a<me->totface; a++, mf++) {
123                         if(mf->flag & ME_HIDE)
124                                 continue;
125
126                         if(!linkflag[a]) {
127                                 mark= 0;
128
129                                 if(!BLI_edgehash_haskey(seamhash, mf->v1, mf->v2))
130                                         if(BLI_edgehash_haskey(ehash, mf->v1, mf->v2))
131                                                 mark= 1;
132                                 if(!BLI_edgehash_haskey(seamhash, mf->v2, mf->v3))
133                                         if(BLI_edgehash_haskey(ehash, mf->v2, mf->v3))
134                                                 mark= 1;
135                                 if(mf->v4) {
136                                         if(!BLI_edgehash_haskey(seamhash, mf->v3, mf->v4))
137                                                 if(BLI_edgehash_haskey(ehash, mf->v3, mf->v4))
138                                                         mark= 1;
139                                         if(!BLI_edgehash_haskey(seamhash, mf->v4, mf->v1))
140                                                 if(BLI_edgehash_haskey(ehash, mf->v4, mf->v1))
141                                                         mark= 1;
142                                 }
143                                 else if(!BLI_edgehash_haskey(seamhash, mf->v3, mf->v1))
144                                         if(BLI_edgehash_haskey(ehash, mf->v3, mf->v1))
145                                                 mark = 1;
146
147                                 if(mark) {
148                                         linkflag[a]= 1;
149                                         hash_add_face(ehash, mf);
150                                         doit= 1;
151                                 }
152                         }
153                 }
154                 
155         }
156
157         BLI_edgehash_free(ehash, NULL);
158         BLI_edgehash_free(seamhash, NULL);
159
160         if(mode==0 || mode==2) {
161                 for(a=0, mf=me->mface; a<me->totface; a++, mf++)
162                         if(linkflag[a])
163                                 mf->flag |= ME_FACE_SEL;
164                         else
165                                 mf->flag &= ~ME_FACE_SEL;
166         }
167         else if(mode==1) {
168                 for(a=0, mf=me->mface; a<me->totface; a++, mf++)
169                         if(linkflag[a] && (mf->flag & ME_FACE_SEL))
170                                 break;
171
172                 if (a<me->totface) {
173                         for(a=0, mf=me->mface; a<me->totface; a++, mf++)
174                                 if(linkflag[a])
175                                         mf->flag &= ~ME_FACE_SEL;
176                 }
177                 else {
178                         for(a=0, mf=me->mface; a<me->totface; a++, mf++)
179                                 if(linkflag[a])
180                                         mf->flag |= ME_FACE_SEL;
181                 }
182         }
183         
184         MEM_freeN(linkflag);
185         
186         BIF_undo_push("Select linked UV face");
187         object_tface_flags_changed(OBACT, 0);
188 }
189
190 /* Parametrizer */
191 ParamHandle *construct_param_handle(EditMesh *em, short implicit, short fill, short sel)
192 {
193         int a;
194         MTFace *tf;
195         
196         EditFace *efa;
197         EditEdge *eed;
198         EditVert *ev;
199         
200         ParamHandle *handle;
201         
202         handle = param_construct_begin();
203
204         if ((G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) {
205                 efa = EM_get_actFace(1);
206                 if (efa) {
207                         float aspx, aspy;
208                         MTFace *tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
209                         image_final_aspect(tface->tpage, &aspx, &aspy);
210                 
211                         if (aspx!=aspy)
212                                 param_aspect_ratio(handle, aspx, aspy);
213                 }
214         }
215         
216         /* we need the vert indicies */
217         for (ev= em->verts.first, a=0; ev; ev= ev->next, a++)
218                 ev->tmp.l = a;
219         
220         for (efa= em->faces.first; efa; efa= efa->next) {
221                 ParamKey key, vkeys[4];
222                 ParamBool pin[4], select[4];
223                 float *co[4];
224                 float *uv[4];
225                 int nverts;
226                 
227                 if ((efa->h) || (sel && (efa->f & SELECT)==0)) 
228                         continue;
229
230                 tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
231                 
232                 if (implicit &&
233                         !(      simaUVSel_Check(efa, tf, 0) ||
234                                 simaUVSel_Check(efa, tf, 1) ||
235                                 simaUVSel_Check(efa, tf, 2) ||
236                                 (efa->v4 && simaUVSel_Check(efa, tf, 3)) )
237                 ) {
238                         continue;
239                 }
240
241                 key = (ParamKey)efa;
242                 vkeys[0] = (ParamKey)efa->v1->tmp.l;
243                 vkeys[1] = (ParamKey)efa->v2->tmp.l;
244                 vkeys[2] = (ParamKey)efa->v3->tmp.l;
245
246                 co[0] = efa->v1->co;
247                 co[1] = efa->v2->co;
248                 co[2] = efa->v3->co;
249
250                 uv[0] = tf->uv[0];
251                 uv[1] = tf->uv[1];
252                 uv[2] = tf->uv[2];
253
254                 pin[0] = ((tf->unwrap & TF_PIN1) != 0);
255                 pin[1] = ((tf->unwrap & TF_PIN2) != 0);
256                 pin[2] = ((tf->unwrap & TF_PIN3) != 0);
257
258                 select[0] = ((simaUVSel_Check(efa, tf, 0)) != 0);
259                 select[1] = ((simaUVSel_Check(efa, tf, 1)) != 0);
260                 select[2] = ((simaUVSel_Check(efa, tf, 2)) != 0);
261
262                 if (efa->v4) {
263                         vkeys[3] = (ParamKey)efa->v4->tmp.l;
264                         co[3] = efa->v4->co;
265                         uv[3] = tf->uv[3];
266                         pin[3] = ((tf->unwrap & TF_PIN4) != 0);
267                         select[3] = (simaUVSel_Check(efa, tf, 3) != 0);
268                         nverts = 4;
269                 }
270                 else
271                         nverts = 3;
272
273                 param_face_add(handle, key, nverts, vkeys, co, uv, pin, select);
274         }
275
276         if (!implicit) {
277                 for (eed= em->edges.first; eed; eed= eed->next) {
278                         if(eed->seam) {
279                                 ParamKey vkeys[2];
280                                 vkeys[0] = (ParamKey)eed->v1->tmp.l;
281                                 vkeys[1] = (ParamKey)eed->v2->tmp.l;
282                                 param_edge_set_seam(handle, vkeys);
283                         }
284                 }
285         }
286
287         param_construct_end(handle, fill, implicit);
288
289         return handle;
290 }
291
292
293 extern int EM_texFaceCheck(void);
294
295 void unwrap_lscm(short seamcut)
296 {
297         EditMesh *em = G.editMesh;
298         ParamHandle *handle;
299         short abf = G.scene->toolsettings->unwrapper == 1;
300         short fillholes = G.scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
301         
302         /* add uvs if there not here */
303         if (!EM_texFaceCheck()) {
304                 if (em && em->faces.first)
305                         EM_add_data_layer(&em->fdata, CD_MTFACE);
306                 
307                 if (!EM_texFaceCheck())
308                         return;
309                 
310                 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 */
311                         image_changed(G.sima, G.sima->image);
312                 
313                 /* select new UV's */
314                 if ((G.sima==0 || G.sima->flag & SI_SYNC_UVSEL)==0) {
315                         EditFace *efa;
316                         MTFace *tf;
317                         for(efa=em->faces.first; efa; efa=efa->next) {
318                                 tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
319                                 simaFaceSel_Set(efa, tf);
320                         }
321                 }
322         }
323
324         handle = construct_param_handle(em, 0, fillholes, seamcut == 0);
325
326         param_lscm_begin(handle, PARAM_FALSE, abf);
327         param_lscm_solve(handle);
328         param_lscm_end(handle);
329         
330         param_pack(handle);
331
332         param_flush(handle);
333
334         param_delete(handle);
335
336         if (!seamcut)
337                 BIF_undo_push("UV unwrap");
338
339         object_uvs_changed(OBACT);
340
341         allqueue(REDRAWVIEW3D, 0);
342         allqueue(REDRAWIMAGE, 0);
343 }
344
345 void minimize_stretch_tface_uv(void)
346 {
347         EditMesh *em = G.editMesh;
348         ParamHandle *handle;
349         double lasttime;
350         short doit = 1, escape = 0, val, blend = 0;
351         unsigned short event = 0;
352         short fillholes = G.scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
353         
354         if(!EM_texFaceCheck()) return;
355
356         handle = construct_param_handle(em, 1, fillholes, 1);
357
358         lasttime = PIL_check_seconds_timer();
359
360         param_stretch_begin(handle);
361
362         while (doit) {
363                 param_stretch_iter(handle);
364
365                 while (qtest()) {
366                         event= extern_qread(&val);
367
368                         if (val) {
369                                 switch (event) {
370                                         case ESCKEY:
371                                                 escape = 1;
372                                         case RETKEY:
373                                         case PADENTER:
374                                                 doit = 0;
375                                                 break;
376                                         case PADPLUSKEY:
377                                         case WHEELUPMOUSE:
378                                                 if (blend < 10) {
379                                                         blend++;
380                                                         param_stretch_blend(handle, blend*0.1f);
381                                                         param_flush(handle);
382                                                         lasttime = 0.0f;
383                                                 }
384                                                 break;
385                                         case PADMINUS:
386                                         case WHEELDOWNMOUSE:
387                                                 if (blend > 0) {
388                                                         blend--;
389                                                         param_stretch_blend(handle, blend*0.1f);
390                                                         param_flush(handle);
391                                                         lasttime = 0.0f;
392                                                 }
393                                                 break;
394                                 }
395                         }
396                         else if ((event == LEFTMOUSE) || (event == RIGHTMOUSE)) {
397                                         escape = (event == RIGHTMOUSE);
398                                         doit = 0;
399                         }
400                 }
401                 
402                 if (!doit)
403                         break;
404
405                 if (PIL_check_seconds_timer() - lasttime > 0.5) {
406                         char str[100];
407
408                         param_flush(handle);
409
410                         sprintf(str, "Stretch minimize. Blend %.2f.", blend*0.1f);
411                         headerprint(str);
412
413                         lasttime = PIL_check_seconds_timer();
414                         object_uvs_changed(OBACT);
415                         if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
416                         else force_draw(0);
417                 }
418         }
419
420         if (escape)
421                 param_flush_restore(handle);
422         else
423                 param_flush(handle);
424
425         param_stretch_end(handle);
426
427         param_delete(handle);
428
429         BIF_undo_push("UV stretch minimize");
430
431         object_uvs_changed(OBACT);
432
433         allqueue(REDRAWVIEW3D, 0);
434         allqueue(REDRAWIMAGE, 0);
435 }
436
437 void pack_charts_tface_uv(void)
438 {
439         EditMesh *em = G.editMesh;
440         ParamHandle *handle;
441         
442         if(!EM_texFaceCheck()) return;
443
444         handle = construct_param_handle(em, 1, 0, 1);
445         param_pack(handle);
446         param_flush(handle);
447         param_delete(handle);
448
449         BIF_undo_push("UV pack islands");
450
451         object_uvs_changed(OBACT);
452
453         allqueue(REDRAWVIEW3D, 0);
454         allqueue(REDRAWIMAGE, 0);
455 }
456
457
458 void average_charts_tface_uv(void)
459 {
460         EditMesh *em = G.editMesh;
461         ParamHandle *handle;
462         
463         if(!EM_texFaceCheck()) return;
464
465         handle = construct_param_handle(em, 1, 0, 1);
466         param_average(handle);
467         param_flush(handle);
468         param_delete(handle);
469
470         BIF_undo_push("UV average island scale");
471
472         object_uvs_changed(OBACT);
473
474         allqueue(REDRAWVIEW3D, 0);
475         allqueue(REDRAWIMAGE, 0);
476 }
477
478 /* LSCM live mode */
479
480 static ParamHandle *liveHandle = NULL;
481
482 void unwrap_lscm_live_begin(void)
483 {
484         EditMesh *em = G.editMesh;
485         short abf = G.scene->toolsettings->unwrapper == 1;
486         short fillholes = G.scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
487
488         if(!EM_texFaceCheck()) return;
489
490         liveHandle = construct_param_handle(em, 0, fillholes, 1);
491
492         param_lscm_begin(liveHandle, PARAM_TRUE, abf);
493 }
494
495 void unwrap_lscm_live_re_solve(void)
496 {
497         if (liveHandle) {
498                 param_lscm_solve(liveHandle);
499                 param_flush(liveHandle);
500         }
501 }
502         
503 void unwrap_lscm_live_end(short cancel)
504 {
505         if (liveHandle) {
506                 param_lscm_end(liveHandle);
507                 if (cancel)
508                         param_flush_restore(liveHandle);
509                 param_delete(liveHandle);
510                 liveHandle = NULL;
511         }
512 }
513