4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
46 #include "MEM_guardedalloc.h"
48 #include "BLI_blenlib.h"
49 #include "BLI_arithb.h"
50 #include "BLI_editVert.h"
52 #include "IMB_imbuf_types.h"
53 #include "IMB_imbuf.h"
55 #include "DNA_image_types.h"
56 #include "DNA_mesh_types.h"
57 #include "DNA_meshdata_types.h"
58 #include "DNA_node_types.h"
59 #include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object)
60 #include "DNA_packedFile_types.h"
61 #include "DNA_scene_types.h"
62 #include "DNA_space_types.h"
63 #include "DNA_screen_types.h"
64 #include "DNA_texture_types.h"
65 #include "DNA_userdef_types.h"
66 #include "DNA_view3d_types.h"
68 #include "BKE_colortools.h"
69 #include "BKE_depsgraph.h"
70 #include "BKE_displist.h"
71 #include "BKE_image.h"
72 #include "BKE_global.h"
73 #include "BKE_library.h"
77 #include "BKE_object.h"
78 #include "BKE_packedFile.h"
79 #include "BKE_utildefines.h"
82 #include "BIF_glutil.h"
83 #include "BIF_imasel.h"
84 #include "BIF_interface.h"
85 #include "BIF_drawimage.h"
86 #include "BIF_editview.h"
87 #include "BIF_editsima.h"
88 #include "BIF_mywindow.h"
89 #include "BIF_previewrender.h"
90 #include "BIF_screen.h"
91 #include "BIF_space.h"
92 #include "BIF_toolbox.h"
93 #include "BIF_transform.h"
94 #include "BIF_writeimage.h"
95 #include "BIF_editmesh.h"
97 #include "BSE_drawipo.h"
99 #include "BSE_filesel.h"
100 #include "BSE_trans_types.h"
102 #include "BDR_editobject.h"
103 #include "BDR_unwrapper.h"
107 #include "RE_pipeline.h"
110 #include "multires.h"
111 #include "mydevice.h"
112 #include "editmesh.h"
114 /* local prototypes */
115 void sel_uvco_inside_radius(short , EditFace *efa, MTFace *, int , float *, float *, short);
116 void uvedit_selectionCB(short , Object *, short *, float ); /* used in edit.c*/
118 void object_uvs_changed(Object *ob)
120 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
122 allqueue(REDRAWVIEW3D, 0);
123 allqueue(REDRAWIMAGE, 0);
126 void object_tface_flags_changed(Object *ob, int updateButtons)
128 if (updateButtons) allqueue(REDRAWBUTSEDIT, 0);
129 allqueue(REDRAWVIEW3D, 0);
130 allqueue(REDRAWIMAGE, 0);
133 int is_uv_tface_editing_allowed_silent(void)
135 if(!EM_texFaceCheck()) return 0;
136 if(G.sima->mode!=SI_TEXTURE) return 0;
137 if(multires_level1_test()) return 0;
141 int is_uv_tface_editing_allowed(void)
143 if(!G.obedit) error("Enter Edit Mode to perform this action");
145 return is_uv_tface_editing_allowed_silent();
148 void get_connected_limit_tface_uv(float *limit)
150 ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
151 if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
152 limit[0]= 0.05/(float)ibuf->x;
153 limit[1]= 0.05/(float)ibuf->y;
156 limit[0]= limit[1]= 0.05/256.0;
159 void be_square_tface_uv(EditMesh *em)
163 /* if 1 vertex selected: doit (with the selected vertex) */
164 for (efa= em->faces.first; efa; efa= efa->next) {
166 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
167 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
168 if (SIMA_UVSEL_CHECK(efa, tface, 0)) {
169 if( tface->uv[1][0] == tface->uv[2][0] ) {
170 tface->uv[1][1]= tface->uv[0][1];
171 tface->uv[3][0]= tface->uv[0][0];
174 tface->uv[1][0]= tface->uv[0][0];
175 tface->uv[3][1]= tface->uv[0][1];
179 if (SIMA_UVSEL_CHECK(efa, tface, 1)) {
180 if( tface->uv[2][1] == tface->uv[3][1] ) {
181 tface->uv[2][0]= tface->uv[1][0];
182 tface->uv[0][1]= tface->uv[1][1];
185 tface->uv[2][1]= tface->uv[1][1];
186 tface->uv[0][0]= tface->uv[1][0];
190 if (SIMA_UVSEL_CHECK(efa, tface, 2)) {
191 if( tface->uv[3][0] == tface->uv[0][0] ) {
192 tface->uv[3][1]= tface->uv[2][1];
193 tface->uv[1][0]= tface->uv[2][0];
196 tface->uv[3][0]= tface->uv[2][0];
197 tface->uv[1][1]= tface->uv[2][1];
200 if (SIMA_UVSEL_CHECK(efa, tface, 3)) {
201 if( tface->uv[0][1] == tface->uv[1][1] ) {
202 tface->uv[0][0]= tface->uv[3][0];
203 tface->uv[2][1]= tface->uv[3][1];
206 tface->uv[0][1]= tface->uv[3][1];
207 tface->uv[2][0]= tface->uv[3][0];
216 void transform_aspect_ratio_tface_uv(float *aspx, float *aspy)
219 float xuser_asp, yuser_asp;
221 aspect_sima(G.sima, &xuser_asp, &yuser_asp);
223 transform_width_height_tface_uv(&w, &h);
224 *aspx= (float)w/256.0f * xuser_asp;
225 *aspy= (float)h/256.0f * yuser_asp;
228 void transform_width_height_tface_uv(int *width, int *height)
230 ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
242 void mirror_tface_uv(char mirroraxis)
244 if (mirroraxis == 'x')
245 Mirror(1); /* global x */
246 else if (mirroraxis == 'y')
247 Mirror(2); /* global y */
250 void mirrormenu_tface_uv(void)
254 if( is_uv_tface_editing_allowed()==0 ) return;
256 mode= pupmenu("Mirror%t|X Axis%x1|Y Axis%x2|");
260 if(mode==1) mirror_tface_uv('x');
261 else if(mode==2) mirror_tface_uv('y');
263 BIF_undo_push("Mirror UV");
266 void weld_align_tface_uv(char tool)
268 EditMesh *em = G.editMesh;
273 if( is_uv_tface_editing_allowed()==0 ) return;
274 cent_tface_uv(cent, 0);
276 if(tool == 'x' || tool == 'w') {
277 for (efa= em->faces.first; efa; efa= efa->next) {
278 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
279 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
280 if (SIMA_UVSEL_CHECK(efa, tface, 0))
281 tface->uv[0][0]= cent[0];
282 if (SIMA_UVSEL_CHECK(efa, tface, 1))
283 tface->uv[1][0]= cent[0];
284 if (SIMA_UVSEL_CHECK(efa, tface, 2))
285 tface->uv[2][0]= cent[0];
286 if (efa->v4 && SIMA_UVSEL_CHECK(efa, tface, 3))
287 tface->uv[3][0]= cent[0];
292 if(tool == 'y' || tool == 'w') {
293 for (efa= em->faces.first; efa; efa= efa->next) {
294 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
295 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
296 if (SIMA_UVSEL_CHECK(efa, tface, 0))
297 tface->uv[0][1]= cent[1];
298 if (SIMA_UVSEL_CHECK(efa, tface, 1))
299 tface->uv[1][1]= cent[1];
300 if (SIMA_UVSEL_CHECK(efa, tface, 2))
301 tface->uv[2][1]= cent[1];
302 if (efa->v4 && SIMA_UVSEL_CHECK(efa, tface, 3))
303 tface->uv[3][1]= cent[1];
308 object_uvs_changed(OBACT);
311 void weld_align_menu_tface_uv(void)
315 if( is_uv_tface_editing_allowed()==0 ) return;
317 mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3|");
321 if(mode==1) weld_align_tface_uv('w');
322 else if(mode==2) weld_align_tface_uv('x');
323 else if(mode==3) weld_align_tface_uv('y');
325 if(mode==1) BIF_undo_push("Weld UV");
326 else if(mode==2 || mode==3) BIF_undo_push("Align UV");
329 void select_invert_tface_uv(void)
331 EditMesh *em = G.editMesh;
335 if( is_uv_tface_editing_allowed()==0 ) return;
337 if (G.sima->flag & SI_SYNC_UVSEL) {
338 /* Warning, this is not that good (calling editmode stuff from UV),
339 TODO look into changing it */
343 for (efa= em->faces.first; efa; efa= efa->next) {
344 tface = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
345 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
346 tface->flag ^= TF_SEL1;
347 tface->flag ^= TF_SEL2;
348 tface->flag ^= TF_SEL3;
349 if(efa->v4) tface->flag ^= TF_SEL4;
353 BIF_undo_push("Select Inverse UV");
355 allqueue(REDRAWIMAGE, 0);
358 void select_swap_tface_uv(void)
360 EditMesh *em = G.editMesh;
365 if( is_uv_tface_editing_allowed()==0 ) return;
367 if (G.sima->flag & SI_SYNC_UVSEL) {
372 for (efa= em->faces.first; efa; efa= efa->next) {
373 tface = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
374 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
375 if(tface->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) {
382 for (efa= em->faces.first; efa; efa= efa->next) {
383 tface = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
384 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
386 if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
387 else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
390 if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
391 else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3);
396 BIF_undo_push("Select swap");
398 allqueue(REDRAWIMAGE, 0);
401 static int msel_hit(float *limit, unsigned int *hitarray, unsigned int vertexid, float **uv, float *uv2, int sticky)
404 for(i=0; i< 4; i++) {
405 if(hitarray[i] == vertexid) {
407 if(fabs(uv[i][0]-uv2[0]) < limit[0] &&
408 fabs(uv[i][1]-uv2[1]) < limit[1])
417 static void find_nearest_tface(MTFace **nearesttf, EditFace **nearestefa)
419 EditMesh *em= G.editMesh;
422 int i, nverts, mindist, dist, fcenter[2], uval[2];
425 getmouseco_areawin(mval);
431 for (efa= em->faces.first; efa; efa= efa->next) {
432 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
433 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
434 fcenter[0]= fcenter[1]= 0;
435 nverts= efa->v4? 4: 3;
436 for(i=0; i<nverts; i++) {
437 uvco_to_areaco_noclip(tf->uv[i], uval);
438 fcenter[0] += uval[0];
439 fcenter[1] += uval[1];
442 fcenter[0] /= nverts;
443 fcenter[1] /= nverts;
445 dist= abs(mval[0]- fcenter[0])+ abs(mval[1]- fcenter[1]);
446 if (dist < mindist) {
455 static int nearest_uv_between(MTFace *tf, int nverts, int id, short *mval, int *uval)
457 float m[3], v1[3], v2[3], c1, c2;
460 id1= (id+nverts-1)%nverts;
461 id2= (id+nverts+1)%nverts;
463 m[0] = (float)(mval[0]-uval[0]);
464 m[1] = (float)(mval[1]-uval[1]);
465 Vec2Subf(v1, tf->uv[id1], tf->uv[id]);
466 Vec2Subf(v2, tf->uv[id2], tf->uv[id]);
468 /* m and v2 on same side of v-v1? */
469 c1= v1[0]*m[1] - v1[1]*m[0];
470 c2= v1[0]*v2[1] - v1[1]*v2[0];
475 /* m and v1 on same side of v-v2? */
476 c1= v2[0]*m[1] - v2[1]*m[0];
477 c2= v2[0]*v1[1] - v2[1]*v1[0];
479 return (c1*c2 >= 0.0f);
482 static void find_nearest_uv(MTFace **nearesttf, EditFace **nearestefa, unsigned int *nearestv, int *nearestuv)
484 EditMesh *em= G.editMesh;
487 int i, nverts, mindist, dist, uval[2];
490 getmouseco_areawin(mval);
496 for (efa= em->faces.first; efa; efa= efa->next) {
497 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
498 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
499 nverts= efa->v4? 4: 3;
500 for(i=0; i<nverts; i++) {
501 uvco_to_areaco_noclip(tf->uv[i], uval);
502 dist= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
504 if (SIMA_UVSEL_CHECK(efa, tf, i))
509 if (!nearest_uv_between(tf, nverts, i, mval, uval))
518 if (i==0) *nearestv= efa->v1->tmp.l;
519 else if (i==1) *nearestv= efa->v2->tmp.l;
520 else if (i==2) *nearestv= efa->v3->tmp.l;
521 else *nearestv= efa->v4->tmp.l;
528 void mouse_select_sima(void) /* TODO - SYNCSEL */
530 EditMesh *em = G.editMesh;
532 MTFace *tf, *nearesttf;
533 EditFace *nearestefa=NULL;
534 int a, selectsticky, actface, nearestuv, i;
536 short flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
537 unsigned int hitv[4], nearestv;
538 float *hituv[4], limit[2];
540 if( is_uv_tface_editing_allowed()==0 ) return;
542 get_connected_limit_tface_uv(limit);
544 if (G.sima->flag & SI_SYNC_UVSEL) {
546 if (G.scene->selectmode == SCE_SELECT_FACE) {
550 actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
554 /* normal operation */
555 actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
557 switch(G.sima->sticky) {
565 if(G.qual & LR_CTRLKEY) {
575 find_nearest_tface(&nearesttf, &nearestefa);
579 nearesttf->flag |= TF_ACTIVE;
582 hituv[i]= nearesttf->uv[i];
584 hitv[0]= nearestefa->v1->tmp.l;
585 hitv[1]= nearestefa->v2->tmp.l;
586 hitv[2]= nearestefa->v3->tmp.l;
588 if (nearestefa->v4) hitv[3]= nearestefa->v4->tmp.l;
589 else hitv[3]= 0xFFFFFFFF;
592 find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
599 hitv[nearestuv]= nearestv;
600 hituv[nearestuv]= nearesttf->uv[nearestuv];
604 if(G.qual & LR_SHIFTKEY) {
605 /* (de)select face */
607 if(SIMA_FACESEL_CHECK(nearestefa, nearesttf)) {
608 SIMA_FACESEL_UNSET(nearestefa, nearesttf);
612 SIMA_FACESEL_SET(nearestefa, nearesttf);
617 /* (de)select uv node */
619 if (SIMA_UVSEL_CHECK(nearestefa, nearesttf, nearestuv)) {
620 SIMA_UVSEL_UNSET(nearestefa, nearesttf, nearestuv);
624 SIMA_UVSEL_SET(nearestefa, nearesttf, nearestuv);
630 /* (de)select sticky uv nodes */
631 if(sticky || actface) {
634 for (a=0, ev=em->verts.first; ev; ev = ev->next, a++)
638 if(selectsticky==0) {
639 for (efa= em->faces.first; efa; efa= efa->next) {
640 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
641 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
642 /*if(nearesttf && tf!=nearesttf) tf->flag &=~ TF_ACTIVE;*/ /* TODO - deal with editmesh active face */
643 if (!sticky) continue;
645 if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
646 SIMA_UVSEL_UNSET(efa, tf, 0);
647 if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
648 SIMA_UVSEL_UNSET(efa, tf, 1);
649 if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
650 SIMA_UVSEL_UNSET(efa, tf, 2);
652 if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
653 SIMA_UVSEL_UNSET(efa, tf, 3);
660 for (efa= em->faces.first; efa; efa= efa->next) {
661 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
662 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
663 if(nearesttf && tf!=nearesttf)
664 tf->flag &=~ TF_ACTIVE;
665 if (!sticky) continue;
667 if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
668 SIMA_UVSEL_SET(efa, tf, 0);
669 if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
670 SIMA_UVSEL_SET(efa, tf, 1);
671 if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
672 SIMA_UVSEL_SET(efa, tf, 2);
674 if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
675 SIMA_UVSEL_SET(efa, tf, 3);
683 /* select face and deselect other faces */
685 for (efa= em->faces.first; efa; efa= efa->next) {
686 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
687 SIMA_FACESEL_UNSET(efa, tf);
688 //if(nearesttf && tf!=nearesttf) /* TODO - deal with editmesh active face */
689 // tf->flag &= ~TF_ACTIVE;
692 SIMA_FACESEL_SET(nearestefa, nearesttf);
695 /* deselect uvs, and select sticky uvs */
696 for (efa= em->faces.first; efa; efa= efa->next) {
697 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
698 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
699 if(!actface) SIMA_FACESEL_UNSET(efa, tf);
700 if(!sticky) continue;
702 if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
703 SIMA_UVSEL_SET(efa, tf, 0);
704 if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
705 SIMA_UVSEL_SET(efa, tf, 1);
706 if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
707 SIMA_UVSEL_SET(efa, tf, 2);
709 if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
710 SIMA_UVSEL_SET(efa, tf, 3);
716 SIMA_UVSEL_SET(nearestefa, nearesttf, nearestuv);
723 if (G.sima->flag & SI_SYNC_UVSEL) {
724 /* flush for mesh selection */
725 if (G.scene->selectmode != SCE_SELECT_FACE) {
726 if (flush==1) EM_select_flush();
727 else if (flush==-1) EM_deselect_flush();
729 allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
732 BIF_undo_push("Select UV");
733 rightmouse_transform();
736 void borderselect_sima(short whichuvs)
738 EditMesh *em = G.editMesh;
746 if( is_uv_tface_editing_allowed()==0) return;
748 val= get_border(&rect, 3);
753 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
756 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
758 for (efa= em->faces.first; efa; efa= efa->next) {
759 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
760 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
761 if (whichuvs == UV_SELECT_ALL || (G.sima->flag & SI_SYNC_UVSEL) ) {
762 /* SI_SYNC_UVSEL - cant do pinned selection */
763 if(BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
764 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 0);
765 else SIMA_UVSEL_UNSET(efa, tface, 0);
767 if(BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
768 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 1);
769 else SIMA_UVSEL_UNSET(efa, tface, 1);
771 if(BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
772 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 2);
773 else SIMA_UVSEL_UNSET(efa, tface, 2);
775 if(efa->v4 && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
776 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 3);
777 else SIMA_UVSEL_UNSET(efa, tface, 3);
779 } else if (whichuvs == UV_SELECT_PINNED) {
780 if ((tface->unwrap & TF_PIN1) &&
781 BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
783 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 0);
784 else SIMA_UVSEL_UNSET(efa, tface, 0);
786 if ((tface->unwrap & TF_PIN2) &&
787 BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
789 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 1);
790 else SIMA_UVSEL_UNSET(efa, tface, 1);
792 if ((tface->unwrap & TF_PIN3) &&
793 BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
795 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 2);
796 else SIMA_UVSEL_UNSET(efa, tface, 2);
798 if ((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
799 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 3);
800 else SIMA_UVSEL_UNSET(efa, tface, 3);
806 /* make sure newly selected vert selection is updated*/
807 if (G.sima->flag & SI_SYNC_UVSEL) {
808 if (G.scene->selectmode != SCE_SELECT_FACE) {
809 if (val==LEFTMOUSE) EM_select_flush();
810 else EM_deselect_flush();
812 allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
815 BIF_undo_push("Border select UV");
816 scrarea_queue_winredraw(curarea);
820 int snap_uv_sel_to_curs(void)
822 EditMesh *em = G.editMesh;
827 for (efa= em->faces.first; efa; efa= efa->next) {
828 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
829 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
830 if (SIMA_UVSEL_CHECK(efa, tface, 0)) VECCOPY2D(tface->uv[0], G.v2d->cursor);
831 if (SIMA_UVSEL_CHECK(efa, tface, 1)) VECCOPY2D(tface->uv[1], G.v2d->cursor);
832 if (SIMA_UVSEL_CHECK(efa, tface, 2)) VECCOPY2D(tface->uv[2], G.v2d->cursor);
834 if (SIMA_UVSEL_CHECK(efa, tface, 3)) VECCOPY2D(tface->uv[3], G.v2d->cursor);
841 void snap_coord_to_pixel(float *uvco, float w, float h)
843 uvco[0] = ((float) ((int)((uvco[0]*w) + 0.5))) / w;
844 uvco[1] = ((float) ((int)((uvco[1]*h) + 0.5))) / h;
847 int snap_uv_sel_to_pixels(void) /* warning, sanity checks must alredy be done */
849 EditMesh *em = G.editMesh;
856 transform_width_height_tface_uv(&wi, &hi);
860 for (efa= em->faces.first; efa; efa= efa->next) {
861 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
862 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
863 if (SIMA_UVSEL_CHECK(efa, tface, 0)) snap_coord_to_pixel(tface->uv[0], w, h);
864 if (SIMA_UVSEL_CHECK(efa, tface, 1)) snap_coord_to_pixel(tface->uv[1], w, h);
865 if (SIMA_UVSEL_CHECK(efa, tface, 2)) snap_coord_to_pixel(tface->uv[2], w, h);
867 if (SIMA_UVSEL_CHECK(efa, tface, 3)) snap_coord_to_pixel(tface->uv[3], w, h);
874 void snap_uv_curs_to_pixels(void)
879 transform_width_height_tface_uv(&wi, &hi);
882 snap_coord_to_pixel(G.v2d->cursor, w, h);
885 int snap_uv_curs_to_sel(void)
887 if( is_uv_tface_editing_allowed()==0 ) return 0;
888 return cent_tface_uv(G.v2d->cursor, 0);
891 void snap_menu_sima(void)
894 if( is_uv_tface_editing_allowed()==0 || !G.v2d) return; /* !G.v2d should never happen */
896 event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Cursor-> Pixel%x3|Cursor-> Selection%x4");
899 if (snap_uv_sel_to_pixels()) {
900 BIF_undo_push("Snap UV Selection to Pixels");
901 object_uvs_changed(OBACT);
905 if (snap_uv_sel_to_curs()) {
906 BIF_undo_push("Snap UV Selection to Cursor");
907 object_uvs_changed(OBACT);
911 snap_uv_curs_to_pixels();
912 scrarea_queue_winredraw(curarea);
915 if (snap_uv_curs_to_sel())
916 allqueue(REDRAWIMAGE, 0);
922 /** This is an ugly function to set the Tface selection flags depending
923 * on whether its UV coordinates are inside the normalized
924 * area with radius rad and offset offset. These coordinates must be
926 * Just for readability...
929 void sel_uvco_inside_radius(short sel, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, short select_index)
931 // normalized ellipse: ell[0] = scaleX,
934 float *uv = tface->uv[index];
937 x = (uv[0] - offset[0]) * ell[0];
938 y = (uv[1] - offset[1]) * ell[1];
942 if (sel == LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, select_index);
943 else SIMA_UVSEL_UNSET(efa, tface, select_index);
948 /** gets image dimensions of the 2D view 'v' */
949 static void getSpaceImageDimension(SpaceImage *sima, float *xy)
951 ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
954 xy[0] = ibuf->x * sima->zoom;
955 xy[1] = ibuf->y * sima->zoom;
957 xy[0] = 256 * sima->zoom;
958 xy[1] = 256 * sima->zoom;
962 /** Callback function called by circle_selectCB to enable
963 * brush select in UV editor.
966 void uvedit_selectionCB(short selecting, Object *editobj, short *mval, float rad)
968 EditMesh *em = G.editMesh;
972 float ellipse[2]; // we need to deal with ellipses, as
973 // non square textures require for circle
974 // selection. this ellipse is normalized; r = 1.0
976 getSpaceImageDimension(curarea->spacedata.first, ellipse);
980 areamouseco_to_ipoco(G.v2d, mval, &offset[0], &offset[1]);
983 for (efa= em->faces.first; efa; efa= efa->next) {
984 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
985 sel_uvco_inside_radius(selecting, efa, tface, 0, offset, ellipse, 0);
986 sel_uvco_inside_radius(selecting, efa, tface, 1, offset, ellipse, 1);
987 sel_uvco_inside_radius(selecting, efa, tface, 2, offset, ellipse, 2);
989 sel_uvco_inside_radius(selecting, efa, tface, 3, offset, ellipse, 3);
992 if(G.f & G_DRAWFACES) { /* full redraw only if necessary */
993 draw_sel_circle(0, 0, 0, 0, 0); /* signal */
996 else { /* force_draw() is no good here... */
997 glDrawBuffer(GL_FRONT);
1000 glDrawBuffer(GL_BACK);
1004 if (selecting == LEFTMOUSE) EM_select_flush();
1005 else EM_deselect_flush();
1007 if (G.sima->lock && (G.sima->flag & SI_SYNC_UVSEL))
1008 force_draw_plus(SPACE_VIEW3D, 0);
1013 void mouseco_to_curtile(void)
1018 if( is_uv_tface_editing_allowed()==0) return;
1020 if(G.sima->image && G.sima->image->tpageflag & IMA_TILES) {
1022 G.sima->flag |= SI_EDITTILE;
1024 while(get_mbut()&L_MOUSE) {
1026 calc_image_view(G.sima, 'f');
1028 getmouseco_areawin(mval);
1029 areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
1031 if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
1033 fx= (fx)*G.sima->image->xrep;
1034 fy= (fy)*G.sima->image->yrep;
1039 G.sima->curtile= mval[1]*G.sima->image->xrep + mval[0];
1042 scrarea_do_windraw(curarea);
1043 screen_swapbuffers();
1046 G.sima->flag &= ~SI_EDITTILE;
1048 image_set_tile(G.sima, 2);
1050 allqueue(REDRAWVIEW3D, 0);
1051 scrarea_queue_winredraw(curarea);
1055 /* Could be used for other 2D views also */
1056 void mouseco_to_cursor_sima(void)
1059 getmouseco_areawin(mval);
1060 areamouseco_to_ipoco(G.v2d, mval, &G.v2d->cursor[0], &G.v2d->cursor[1]);
1061 scrarea_queue_winredraw(curarea);
1064 void stitch_uv_tface(int mode)
1068 float newuv[2], limit[2];
1069 UvMapVert *vlist, *iterv, *v;
1070 EditMesh *em = G.editMesh;
1074 struct UvVertMap *vmap;
1077 if(is_uv_tface_editing_allowed()==0)
1079 if(G.sima->flag & SI_SYNC_UVSEL) {
1080 error("Can't stitch when Sync Mesh Selection is enabled");
1084 limit[0]= limit[1]= 20.0;
1086 add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL);
1087 if (!do_clever_numbuts("Stitch UVs", 1, REDRAW))
1091 limit[0]= limit[1]= limit[0]/256.0;
1093 ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
1095 if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
1096 limit[1]= limit[0]/(float)ibuf->y;
1097 limit[0]= limit[0]/(float)ibuf->x;
1101 /*vmap= make_uv_vert_map(me->mface, tf, me->totface, me->totvert, 1, limit);*/
1102 EM_init_index_arrays(0, 0, 1);
1103 vmap= make_uv_vert_map_EM(1, 0, limit);
1108 for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
1109 v = get_uv_map_vert_EM(vmap, a);
1114 newuv[0]= 0; newuv[1]= 0;
1117 for(iterv=v; iterv; iterv=iterv->next) {
1118 efa = EM_get_face_for_index(iterv->f);
1119 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1120 if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
1121 newuv[0] += tf->uv[iterv->tfindex][0];
1122 newuv[1] += tf->uv[iterv->tfindex][1];
1128 newuv[0] /= vtot; newuv[1] /= vtot;
1130 for(iterv=v; iterv; iterv=iterv->next) {
1131 efa = EM_get_face_for_index(iterv->f);
1132 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1133 if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
1134 tf->uv[iterv->tfindex][0]= newuv[0];
1135 tf->uv[iterv->tfindex][1]= newuv[1];
1140 } else if(mode==1) {
1141 for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
1142 vlist= get_uv_map_vert_EM(vmap, a);
1145 newuv[0]= 0; newuv[1]= 0;
1148 for(iterv=vlist; iterv; iterv=iterv->next) {
1149 if((iterv != vlist) && iterv->separate)
1151 efa = EM_get_face_for_index(iterv->f);
1152 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1154 if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
1155 newuv[0] += tf->uv[iterv->tfindex][0];
1156 newuv[1] += tf->uv[iterv->tfindex][1];
1162 newuv[0] /= vtot; newuv[1] /= vtot;
1164 for(iterv=vlist; iterv; iterv=iterv->next) {
1165 if((iterv != vlist) && iterv->separate)
1167 efa = EM_get_face_for_index(iterv->f);
1168 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1169 if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
1170 tf->uv[iterv->tfindex][0]= newuv[0];
1171 tf->uv[iterv->tfindex][1]= newuv[1];
1180 free_uv_vert_map_EM(vmap);
1181 EM_free_index_arrays();
1183 if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(em);
1185 BIF_undo_push("Stitch UV");
1187 object_uvs_changed(OBACT);
1190 void select_linked_tface_uv(int mode) /* TODO */
1192 EditMesh *em= G.editMesh;
1193 EditFace *efa, *nearestefa=NULL;
1194 MTFace *tf, *nearesttf=NULL;
1196 UvMapVert *vlist, *iterv, *startv;
1197 unsigned int *stack, stacksize= 0, nearestv;
1199 int a, nearestuv, i, nverts, j;
1201 if(is_uv_tface_editing_allowed()==0)
1204 if(G.sima->flag & SI_SYNC_UVSEL) {
1205 error("Can't select linked when Sync Mesh Selection is enabled");
1214 find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
1219 get_connected_limit_tface_uv(limit);
1220 vmap= make_uv_vert_map_EM(1, 1, limit);
1224 stack= MEM_mallocN(sizeof(*stack)* BLI_countlist(&em->faces), "UvLinkStack");
1225 flag= MEM_callocN(sizeof(*flag)*BLI_countlist(&em->faces), "UvLinkFlag");
1228 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1229 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1230 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
1231 if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) {
1232 stack[stacksize]= a;
1239 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1240 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1241 if(tf == nearesttf) {
1242 stack[stacksize]= a;
1250 while(stacksize > 0) {
1252 a= stack[stacksize];
1254 for (j=0, efa= em->faces.first; efa; efa= efa->next, j++) {
1256 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1261 nverts= efa->v4? 4: 3;
1263 for(i=0; i<nverts; i++) {
1264 /* make_uv_vert_map_EM sets verts tmp.l to the indicies */
1265 vlist= get_uv_map_vert_EM(vmap, (*(&efa->v1 + i))->tmp.l);
1269 for(iterv=vlist; iterv; iterv=iterv->next) {
1276 for(iterv=startv; iterv; iterv=iterv->next) {
1277 if((startv != iterv) && (iterv->separate))
1279 else if(!flag[iterv->f]) {
1281 stack[stacksize]= iterv->f;;
1288 if(mode==0 || mode==2) {
1289 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1290 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1292 tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1294 tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1298 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1300 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1302 if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
1305 else if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
1311 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1313 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1314 tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1319 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1321 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1322 tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1330 free_uv_vert_map_EM(vmap);
1332 BIF_undo_push("Select linked UV");
1333 scrarea_queue_winredraw(curarea);
1336 void unlink_selection(void)
1338 EditMesh *em= G.editMesh;
1342 if( is_uv_tface_editing_allowed()==0 ) return;
1344 if(G.sima->flag & SI_SYNC_UVSEL) {
1345 error("Can't select unlinked when Sync Mesh Selection is enabled");
1349 for (efa= em->faces.first; efa; efa= efa->next) {
1350 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1351 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
1353 if(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))
1354 tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1356 if(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
1357 tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3);
1362 BIF_undo_push("Unlink UV selection");
1363 scrarea_queue_winredraw(curarea);
1367 void toggle_uv_select(int mode)
1371 G.sima->flag ^= SI_SELACTFACE;
1374 G.sima->flag &= ~SI_LOCALSTICKY;
1375 G.sima->flag |= SI_STICKYUVS;
1378 G.sima->flag &= ~SI_STICKYUVS;
1379 G.sima->flag &= ~SI_LOCALSTICKY;
1382 G.sima->flag &= ~SI_STICKYUVS;
1383 G.sima->flag |= SI_LOCALSTICKY;
1386 allqueue(REDRAWIMAGE, 0);
1390 void pin_tface_uv(int mode)
1392 EditMesh *em = G.editMesh;
1396 if( is_uv_tface_editing_allowed()==0 ) return;
1398 for (efa= em->faces.first; efa; efa= efa->next) {
1399 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1400 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
1402 if(SIMA_UVSEL_CHECK(efa, tface, 0)) tface->unwrap |= TF_PIN1;
1403 if(SIMA_UVSEL_CHECK(efa, tface, 1)) tface->unwrap |= TF_PIN2;
1404 if(SIMA_UVSEL_CHECK(efa, tface, 2)) tface->unwrap |= TF_PIN3;
1406 if(SIMA_UVSEL_CHECK(efa, tface, 3)) tface->unwrap |= TF_PIN4;
1408 else if (mode ==0) {
1409 if(SIMA_UVSEL_CHECK(efa, tface, 0)) tface->unwrap &= ~TF_PIN1;
1410 if(SIMA_UVSEL_CHECK(efa, tface, 1)) tface->unwrap &= ~TF_PIN2;
1411 if(SIMA_UVSEL_CHECK(efa, tface, 2)) tface->unwrap &= ~TF_PIN3;
1413 if(SIMA_UVSEL_CHECK(efa, tface, 3)) tface->unwrap &= ~TF_PIN4;
1418 BIF_undo_push("Pin UV");
1419 scrarea_queue_winredraw(curarea);
1422 void select_pinned_tface_uv(void)
1424 EditMesh *em= G.editMesh;
1428 if( is_uv_tface_editing_allowed()==0 ) return;
1430 for (efa= em->faces.first; efa; efa= efa->next) {
1431 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1432 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
1433 if (tface->unwrap & TF_PIN1) SIMA_UVSEL_SET(efa, tface, 0);
1434 if (tface->unwrap & TF_PIN2) SIMA_UVSEL_SET(efa, tface, 1);
1435 if (tface->unwrap & TF_PIN3) SIMA_UVSEL_SET(efa, tface, 2);
1437 if (tface->unwrap & TF_PIN4) SIMA_UVSEL_SET(efa, tface, 3);
1443 if (G.sima->flag & SI_SYNC_UVSEL) {
1444 allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
1447 BIF_undo_push("Select Pinned UVs");
1448 scrarea_queue_winredraw(curarea);
1451 int minmax_tface_uv(float *min, float *max)
1453 EditMesh *em= G.editMesh;
1458 if( is_uv_tface_editing_allowed()==0 ) return 0;
1460 INIT_MINMAX2(min, max);
1463 for (efa= em->faces.first; efa; efa= efa->next) {
1464 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1465 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
1466 if (SIMA_UVSEL_CHECK(efa, tf, 0)) DO_MINMAX2(tf->uv[0], min, max);
1467 if (SIMA_UVSEL_CHECK(efa, tf, 1)) DO_MINMAX2(tf->uv[1], min, max);
1468 if (SIMA_UVSEL_CHECK(efa, tf, 2)) DO_MINMAX2(tf->uv[2], min, max);
1469 if (efa->v4 && (SIMA_UVSEL_CHECK(efa, tf, 3))) DO_MINMAX2(tf->uv[3], min, max);
1476 int cent_tface_uv(float *cent, int mode)
1478 float min[2], max[2];
1482 if (minmax_tface_uv(min, max))
1485 } else if (mode==1) {
1488 INIT_MINMAX2(min, max);
1490 for (efa= G.editMesh->faces.first; efa; efa= efa->next) {
1491 tf = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
1492 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
1493 if (SIMA_UVSEL_CHECK(efa, tf, 0)) { DO_MINMAX2(tf->uv[0], min, max); change= 1;}
1494 if (SIMA_UVSEL_CHECK(efa, tf, 1)) { DO_MINMAX2(tf->uv[1], min, max); change= 1;}
1495 if (SIMA_UVSEL_CHECK(efa, tf, 2)) { DO_MINMAX2(tf->uv[2], min, max); change= 1;}
1496 if (efa->v4 && (SIMA_UVSEL_CHECK(efa, tf, 3))) { DO_MINMAX2(tf->uv[3], min, max); change= 1;}
1502 cent[0]= (min[0]+max[0])/2.0;
1503 cent[1]= (min[1]+max[1])/2.0;
1509 static void sima_show_info(int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
1514 ofs= sprintf(str, "X: %d Y: %d ", x, y);
1516 ofs+= sprintf(str+ofs, "| R: %d G: %d B: %d A: %d ", cp[0], cp[1], cp[2], cp[3]);
1519 ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
1520 else if(channels==1)
1521 ofs+= sprintf(str+ofs, "| Val: %.3f ", fp[0]);
1522 else if(channels==3)
1523 ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f ", fp[0], fp[1], fp[2]);
1526 ofs+= sprintf(str+ofs, "| Z: %.4f ", 0.5+0.5*( ((float)*zp)/(float)0x7fffffff));
1528 ofs+= sprintf(str+ofs, "| Z: %.3f ", *zpf);
1530 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1533 glColor4f(.0,.0,.0,.25);
1534 glRectf(0.0, 0.0, curarea->winx, 30.0);
1535 glDisable(GL_BLEND);
1537 glColor3ub(255, 255, 255);
1538 glRasterPos2i(10, 10);
1540 BMF_DrawString(G.fonts, str);
1544 void sima_sample_color(void)
1546 ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
1548 short mval[2], mvalo[2], firsttime=1;
1553 calc_image_view(G.sima, 'f');
1554 getmouseco_areawin(mvalo);
1556 while(get_mbut() & L_MOUSE) {
1558 getmouseco_areawin(mval);
1559 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) {
1561 areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
1563 if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
1564 float *fp= NULL, *zpf= NULL;
1568 int x= (int) (fx*ibuf->x);
1569 int y= (int) (fy*ibuf->y);
1571 if(x>=ibuf->x) x= ibuf->x-1;
1572 if(y>=ibuf->y) y= ibuf->y-1;
1575 cp= (char *)(ibuf->rect + y*ibuf->x + x);
1577 zp= ibuf->zbuf + y*ibuf->x + x;
1578 if(ibuf->zbuf_float)
1579 zpf= ibuf->zbuf_float + y*ibuf->x + x;
1580 if(ibuf->rect_float)
1581 fp= (ibuf->rect_float + (ibuf->channels)*(y*ibuf->x + x));
1587 vec[0]= (float)cp[0]/255.0f;
1588 vec[1]= (float)cp[1]/255.0f;
1589 vec[2]= (float)cp[2]/255.0f;
1592 if(ibuf->channels==4) {
1593 if(G.qual & LR_CTRLKEY) {
1594 curvemapping_set_black_white(G.sima->cumap, NULL, fp);
1595 curvemapping_do_ibuf(G.sima->cumap, ibuf);
1597 else if(G.qual & LR_SHIFTKEY) {
1598 curvemapping_set_black_white(G.sima->cumap, fp, NULL);
1599 curvemapping_do_ibuf(G.sima->cumap, ibuf);
1604 scrarea_do_windraw(curarea);
1605 myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
1607 sima_show_info(ibuf->channels, x, y, cp, fp, zp, zpf);
1608 screen_swapbuffers();
1612 BIF_wait_for_statechange();
1615 scrarea_queue_winredraw(curarea);
1618 /* Image functions */
1620 static void load_image_filesel(char *str) /* called from fileselect */
1624 ima= BKE_add_image_file(str);
1626 BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
1627 image_changed(G.sima, ima);
1629 BIF_undo_push("Load image UV");
1630 allqueue(REDRAWIMAGE, 0);
1633 static void replace_image_filesel(char *str) /* called from fileselect */
1638 strncpy(G.sima->image->name, str, sizeof(G.sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */
1639 BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
1640 BIF_undo_push("Replace image UV");
1641 allqueue(REDRAWIMAGE, 0);
1642 allqueue(REDRAWVIEW3D, 0);
1646 static void save_image_doit(char *name)
1648 Image *ima= G.sima->image;
1649 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1651 char str[FILE_MAXDIR+FILE_MAXFILE];
1654 BLI_strncpy(str, name, sizeof(str));
1656 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
1658 if(G.scene->r.scemode & R_EXTENSION)
1659 BKE_add_image_extension(str, G.sima->imtypenr);
1661 if (saveover(str)) {
1663 /* enforce user setting for RGB or RGBA, but skip BW */
1664 if(G.scene->r.planes==32)
1666 else if(G.scene->r.planes==24)
1670 if(G.sima->imtypenr==R_MULTILAYER) {
1671 RenderResult *rr= BKE_image_get_renderresult(ima);
1673 RE_WriteRenderResult(rr, str, G.scene->r.quality);
1675 BLI_strncpy(ima->name, name, sizeof(ima->name));
1676 BLI_strncpy(ibuf->name, str, sizeof(ibuf->name));
1678 /* should be function? nevertheless, saving only happens here */
1679 for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
1680 ibuf->userflags &= ~IB_BITMAPDIRTY;
1683 else error("Did not write, no Multilayer Image");
1685 else if (BKE_write_ibuf(ibuf, str, G.sima->imtypenr, G.scene->r.subimtype, G.scene->r.quality)) {
1686 BLI_strncpy(ima->name, name, sizeof(ima->name));
1687 BLI_strncpy(ibuf->name, str, sizeof(ibuf->name));
1689 ibuf->userflags &= ~IB_BITMAPDIRTY;
1692 if( ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) {
1693 ima->source= IMA_SRC_FILE;
1694 ima->type= IMA_TYPE_IMAGE;
1696 if(ima->type==IMA_TYPE_R_RESULT)
1697 ima->type= IMA_TYPE_IMAGE;
1699 /* name image as how we saved it */
1701 while (len > 0 && str[len - 1] != '/' && str[len - 1] != '\\') len--;
1702 rename_id(&ima->id, str+len);
1705 error("Couldn't write image: %s", str);
1708 allqueue(REDRAWHEADERS, 0);
1709 allqueue(REDRAWBUTSSHADING, 0);
1716 void open_image_sima(short imageselect)
1718 char name[FILE_MAXDIR+FILE_MAXFILE];
1721 strcpy(name, G.sima->image->name);
1723 strcpy(name, U.textudir);
1726 activate_imageselect(FILE_SPECIAL, "Open Image", name, load_image_filesel);
1728 activate_fileselect(FILE_SPECIAL, "Open Image", name, load_image_filesel);
1731 void replace_image_sima(short imageselect)
1733 char name[FILE_MAXDIR+FILE_MAXFILE];
1736 strcpy(name, G.sima->image->name);
1738 strcpy(name, U.textudir);
1741 activate_imageselect(FILE_SPECIAL, "Replace Image", name, replace_image_filesel);
1743 activate_fileselect(FILE_SPECIAL, "Replace Image", name, replace_image_filesel);
1747 static char *filesel_imagetype_string(Image *ima)
1749 char *strp, *str= MEM_callocN(14*32, "menu for filesel");
1752 str += sprintf(str, "Save Image as: %%t|");
1753 str += sprintf(str, "Targa %%x%d|", R_TARGA);
1754 str += sprintf(str, "Targa Raw %%x%d|", R_RAWTGA);
1755 str += sprintf(str, "PNG %%x%d|", R_PNG);
1756 str += sprintf(str, "BMP %%x%d|", R_BMP);
1757 str += sprintf(str, "Jpeg %%x%d|", R_JPEG90);
1758 str += sprintf(str, "Iris %%x%d|", R_IRIS);
1760 str += sprintf(str, "Tiff %%x%d|", R_TIFF);
1761 str += sprintf(str, "Radiance HDR %%x%d|", R_RADHDR);
1762 str += sprintf(str, "Cineon %%x%d|", R_CINEON);
1763 str += sprintf(str, "DPX %%x%d|", R_DPX);
1765 str += sprintf(str, "OpenEXR %%x%d|", R_OPENEXR);
1766 /* saving sequences of multilayer won't work, they copy buffers */
1767 if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
1768 else str += sprintf(str, "MultiLayer %%x%d|", R_MULTILAYER);
1773 /* always opens fileselect */
1774 void save_as_image_sima(void)
1776 Image *ima = G.sima->image;
1777 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1778 char name[FILE_MAXDIR+FILE_MAXFILE];
1781 strcpy(name, ima->name);
1786 strp= filesel_imagetype_string(ima);
1788 /* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
1789 if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
1790 G.sima->imtypenr= R_MULTILAYER;
1791 else if(ima->type==IMA_TYPE_R_RESULT)
1792 G.sima->imtypenr= G.scene->r.imtype;
1793 else G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
1795 activate_fileselect_menu(FILE_SPECIAL, "Save Image", name, strp, &G.sima->imtypenr, save_image_doit);
1800 /* if exists, saves over without fileselect */
1801 void save_image_sima(void)
1803 Image *ima = G.sima->image;
1804 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1805 char name[FILE_MAXDIR+FILE_MAXFILE];
1808 strcpy(name, ima->name);
1811 if (BLI_exists(ibuf->name)) {
1812 if(BKE_image_get_renderresult(ima))
1813 G.sima->imtypenr= R_MULTILAYER;
1815 G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
1817 save_image_doit(ibuf->name);
1820 save_as_image_sima();
1825 void save_image_sequence_sima(void)
1829 char di[FILE_MAX], fi[FILE_MAX];
1831 if(G.sima->image==NULL)
1833 if(G.sima->image->source!=IMA_SRC_SEQUENCE)
1835 if(G.sima->image->type==IMA_TYPE_MULTILAYER) {
1836 error("Cannot save Multilayer Sequences");
1841 for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next)
1842 if(ibuf->userflags & IB_BITMAPDIRTY)
1846 notice("No Images have been changed");
1849 /* get a filename for menu */
1850 for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next)
1851 if(ibuf->userflags & IB_BITMAPDIRTY)
1854 BLI_strncpy(di, ibuf->name, FILE_MAX);
1855 BLI_splitdirstring(di, fi);
1857 sprintf(fi, "%d Image(s) will be saved in %s", tot, di);
1860 for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next) {
1861 if(ibuf->userflags & IB_BITMAPDIRTY) {
1862 char name[FILE_MAX];
1863 BLI_strncpy(name, ibuf->name, sizeof(name));
1865 BLI_convertstringcode(name, G.sce, 0);
1867 if(0 == IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)) {
1868 error("Could not write image", name);
1871 printf("Saved: %s\n", ibuf->name);
1872 ibuf->userflags &= ~IB_BITMAPDIRTY;
1878 void reload_image_sima(void)
1881 BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
1882 /* image_changed(G.sima, 0); - do we really need this? */
1885 allqueue(REDRAWIMAGE, 0);
1886 allqueue(REDRAWVIEW3D, 0);
1887 BIF_preview_changed(ID_TE);
1890 void new_image_sima(void)
1892 static int width= 256, height= 256;
1893 static short uvtestgrid= 0;
1894 static float color[] = {0, 0, 0, 1};
1898 strcpy(name, "Untitled");
1900 add_numbut(0, TEX, "Name:", 0, 21, name, NULL);
1901 add_numbut(1, NUM|INT, "Width:", 1, 5000, &width, NULL);
1902 add_numbut(2, NUM|INT, "Height:", 1, 5000, &height, NULL);
1903 add_numbut(3, COL, "", 0, 0, &color, NULL);
1904 add_numbut(4, NUM|FLO, "Alpha:", 0.0, 1.0, &color[3], NULL);
1905 add_numbut(5, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL);
1906 if (!do_clever_numbuts("New Image", 6, REDRAW))
1909 ima = BKE_add_image_size(width, height, name, uvtestgrid, color);
1910 image_changed(G.sima, ima);
1911 BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
1912 BIF_undo_push("Add image");
1914 allqueue(REDRAWIMAGE, 0);
1915 allqueue(REDRAWVIEW3D, 0);
1918 void pack_image_sima()
1920 Image *ima = G.sima->image;
1923 if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) {
1924 if (ima->packedfile) {
1925 if (G.fileflags & G_AUTOPACK)
1926 if (okee("Disable AutoPack?"))
1927 G.fileflags &= ~G_AUTOPACK;
1929 if ((G.fileflags & G_AUTOPACK) == 0) {
1930 unpackImage(ima, PF_ASK);
1931 BIF_undo_push("Unpack image");
1935 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1936 if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
1937 if(okee("Can't pack painted image. Use Repack as PNG?"))
1938 BKE_image_memorypack(ima);
1941 ima->packedfile = newPackedFile(ima->name);
1942 BIF_undo_push("Pack image");
1946 allqueue(REDRAWBUTSSHADING, 0);
1947 allqueue(REDRAWHEADERS, 0);
1954 /* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */
1955 void BIF_image_update_frame(void)
1960 for(tex= G.main->tex.first; tex; tex= tex->id.next) {
1961 if(tex->type==TEX_IMAGE && tex->ima)
1962 if(ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
1963 if(tex->iuser.flag & IMA_ANIM_ALWAYS)
1964 BKE_image_user_calc_imanr(&tex->iuser, G.scene->r.cfra, 0);
1967 /* image window, compo node users */
1970 for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
1971 if(sa->spacetype==SPACE_VIEW3D) {
1972 View3D *v3d= sa->spacedata.first;
1974 if(v3d->bgpic->iuser.flag & IMA_ANIM_ALWAYS)
1975 BKE_image_user_calc_imanr(&v3d->bgpic->iuser, G.scene->r.cfra, 0);
1977 else if(sa->spacetype==SPACE_IMAGE) {
1978 SpaceImage *sima= sa->spacedata.first;
1979 if(sima->iuser.flag & IMA_ANIM_ALWAYS)
1980 BKE_image_user_calc_imanr(&sima->iuser, G.scene->r.cfra, 0);
1982 else if(sa->spacetype==SPACE_NODE) {
1983 SpaceNode *snode= sa->spacedata.first;
1984 if((snode->treetype==NTREE_COMPOSIT) && (snode->nodetree)) {
1986 for(node= snode->nodetree->nodes.first; node; node= node->next) {
1987 if(node->id && node->type==CMP_NODE_IMAGE) {
1988 Image *ima= (Image *)node->id;
1989 ImageUser *iuser= node->storage;
1990 if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
1991 if(iuser->flag & IMA_ANIM_ALWAYS)
1992 BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
2001 void aspect_sima(SpaceImage *sima, float *x, float *y)
2005 if( (sima->image == 0) ||
2006 (sima->image->type == IMA_TYPE_R_RESULT) ||
2007 (sima->image->type == IMA_TYPE_COMPOSITE) ||
2008 (sima->image->tpageflag & IMA_TILES) ||
2009 (sima->image->aspx==0.0 || sima->image->aspy==0.0)
2015 *y = sima->image->aspy / sima->image->aspx;