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, sticky, actface, nearestuv, i;
535 short flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
536 unsigned int hitv[4], nearestv;
537 float *hituv[4], limit[2];
539 if( is_uv_tface_editing_allowed()==0 ) return;
541 get_connected_limit_tface_uv(limit);
543 if (G.sima->flag & SI_SYNC_UVSEL) {
545 if (G.scene->selectmode == SCE_SELECT_FACE) {
549 actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
553 /* normal operation */
554 actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
556 if(G.qual & LR_CTRLKEY) {
557 if(G.sima->flag & SI_STICKYUVS) sticky= 0;
561 if(G.sima->flag & SI_STICKYUVS) sticky= 1;
562 else if(G.sima->flag & SI_LOCALSTICKY) sticky= 2;
568 find_nearest_tface(&nearesttf, &nearestefa);
572 nearesttf->flag |= TF_ACTIVE;
575 hituv[i]= nearesttf->uv[i];
577 hitv[0]= nearestefa->v1->tmp.l;
578 hitv[1]= nearestefa->v2->tmp.l;
579 hitv[2]= nearestefa->v3->tmp.l;
581 if (nearestefa->v4) hitv[3]= nearestefa->v4->tmp.l;
582 else hitv[3]= 0xFFFFFFFF;
585 find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
592 hitv[nearestuv]= nearestv;
593 hituv[nearestuv]= nearesttf->uv[nearestuv];
597 if(G.qual & LR_SHIFTKEY) {
598 /* (de)select face */
600 if(SIMA_FACESEL_CHECK(nearestefa, nearesttf)) {
601 SIMA_FACESEL_UNSET(nearestefa, nearesttf);
605 SIMA_FACESEL_SET(nearestefa, nearesttf);
610 /* (de)select uv node */
612 if (SIMA_UVSEL_CHECK(nearestefa, nearesttf, nearestuv)) {
613 SIMA_UVSEL_UNSET(nearestefa, nearesttf, nearestuv);
617 SIMA_UVSEL_SET(nearestefa, nearesttf, nearestuv);
623 /* (de)select sticky uv nodes */
624 if(sticky || actface) {
627 for (a=0, ev=em->verts.first; ev; ev = ev->next, a++)
631 if(selectsticky==0) {
632 for (efa= em->faces.first; efa; efa= efa->next) {
633 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
634 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
635 /*if(nearesttf && tf!=nearesttf) tf->flag &=~ TF_ACTIVE;*/ /* TODO - deal with editmesh active face */
636 if (!sticky) continue;
638 if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
639 SIMA_UVSEL_UNSET(efa, tf, 0);
640 if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
641 SIMA_UVSEL_UNSET(efa, tf, 1);
642 if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
643 SIMA_UVSEL_UNSET(efa, tf, 2);
645 if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
646 SIMA_UVSEL_UNSET(efa, tf, 3);
653 for (efa= em->faces.first; efa; efa= efa->next) {
654 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
655 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
656 if(nearesttf && tf!=nearesttf)
657 tf->flag &=~ TF_ACTIVE;
658 if (!sticky) continue;
660 if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
661 SIMA_UVSEL_SET(efa, tf, 0);
662 if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
663 SIMA_UVSEL_SET(efa, tf, 1);
664 if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
665 SIMA_UVSEL_SET(efa, tf, 2);
667 if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
668 SIMA_UVSEL_SET(efa, tf, 3);
676 /* select face and deselect other faces */
678 for (efa= em->faces.first; efa; efa= efa->next) {
679 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
680 SIMA_FACESEL_UNSET(efa, tf);
681 //if(nearesttf && tf!=nearesttf) /* TODO - deal with editmesh active face */
682 // tf->flag &= ~TF_ACTIVE;
685 SIMA_FACESEL_SET(nearestefa, nearesttf);
688 /* deselect uvs, and select sticky uvs */
689 for (efa= em->faces.first; efa; efa= efa->next) {
690 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
691 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
692 if(!actface) SIMA_FACESEL_UNSET(efa, tf);
693 if(!sticky) continue;
695 if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
696 SIMA_UVSEL_SET(efa, tf, 0);
697 if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
698 SIMA_UVSEL_SET(efa, tf, 1);
699 if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
700 SIMA_UVSEL_SET(efa, tf, 2);
702 if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
703 SIMA_UVSEL_SET(efa, tf, 3);
709 SIMA_UVSEL_SET(nearestefa, nearesttf, nearestuv);
716 if (G.sima->flag & SI_SYNC_UVSEL) {
717 /* flush for mesh selection */
718 if (G.scene->selectmode != SCE_SELECT_FACE) {
719 if (flush==1) EM_select_flush();
720 else if (flush==-1) EM_deselect_flush();
722 allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
725 BIF_undo_push("Select UV");
726 rightmouse_transform();
729 void borderselect_sima(short whichuvs)
731 EditMesh *em = G.editMesh;
739 if( is_uv_tface_editing_allowed()==0) return;
741 val= get_border(&rect, 3);
746 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
749 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
751 for (efa= em->faces.first; efa; efa= efa->next) {
752 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
753 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
754 if (whichuvs == UV_SELECT_ALL || (G.sima->flag & SI_SYNC_UVSEL) ) {
755 /* SI_SYNC_UVSEL - cant do pinned selection */
756 if(BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
757 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 0);
758 else SIMA_UVSEL_UNSET(efa, tface, 0);
760 if(BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
761 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 1);
762 else SIMA_UVSEL_UNSET(efa, tface, 1);
764 if(BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
765 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 2);
766 else SIMA_UVSEL_UNSET(efa, tface, 2);
768 if(efa->v4 && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
769 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 3);
770 else SIMA_UVSEL_UNSET(efa, tface, 3);
772 } else if (whichuvs == UV_SELECT_PINNED) {
773 if ((tface->unwrap & TF_PIN1) &&
774 BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
776 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 0);
777 else SIMA_UVSEL_UNSET(efa, tface, 0);
779 if ((tface->unwrap & TF_PIN2) &&
780 BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
782 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 1);
783 else SIMA_UVSEL_UNSET(efa, tface, 1);
785 if ((tface->unwrap & TF_PIN3) &&
786 BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
788 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 2);
789 else SIMA_UVSEL_UNSET(efa, tface, 2);
791 if ((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
792 if(val==LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, 3);
793 else SIMA_UVSEL_UNSET(efa, tface, 3);
799 /* make sure newly selected vert selection is updated*/
800 if (G.sima->flag & SI_SYNC_UVSEL) {
801 if (G.scene->selectmode != SCE_SELECT_FACE) {
802 if (val==LEFTMOUSE) EM_select_flush();
803 else EM_deselect_flush();
805 allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
808 BIF_undo_push("Border select UV");
809 scrarea_queue_winredraw(curarea);
813 int snap_uv_sel_to_curs(void)
815 EditMesh *em = G.editMesh;
820 for (efa= em->faces.first; efa; efa= efa->next) {
821 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
822 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
823 if (SIMA_UVSEL_CHECK(efa, tface, 0)) VECCOPY2D(tface->uv[0], G.v2d->cursor);
824 if (SIMA_UVSEL_CHECK(efa, tface, 1)) VECCOPY2D(tface->uv[1], G.v2d->cursor);
825 if (SIMA_UVSEL_CHECK(efa, tface, 2)) VECCOPY2D(tface->uv[2], G.v2d->cursor);
827 if (SIMA_UVSEL_CHECK(efa, tface, 3)) VECCOPY2D(tface->uv[3], G.v2d->cursor);
834 void snap_coord_to_pixel(float *uvco, float w, float h)
836 uvco[0] = ((float) ((int)((uvco[0]*w) + 0.5))) / w;
837 uvco[1] = ((float) ((int)((uvco[1]*h) + 0.5))) / h;
840 int snap_uv_sel_to_pixels(void) /* warning, sanity checks must alredy be done */
842 EditMesh *em = G.editMesh;
849 transform_width_height_tface_uv(&wi, &hi);
853 for (efa= em->faces.first; efa; efa= efa->next) {
854 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
855 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
856 if (SIMA_UVSEL_CHECK(efa, tface, 0)) snap_coord_to_pixel(tface->uv[0], w, h);
857 if (SIMA_UVSEL_CHECK(efa, tface, 1)) snap_coord_to_pixel(tface->uv[1], w, h);
858 if (SIMA_UVSEL_CHECK(efa, tface, 2)) snap_coord_to_pixel(tface->uv[2], w, h);
860 if (SIMA_UVSEL_CHECK(efa, tface, 3)) snap_coord_to_pixel(tface->uv[3], w, h);
867 void snap_uv_curs_to_pixels(void)
872 transform_width_height_tface_uv(&wi, &hi);
875 snap_coord_to_pixel(G.v2d->cursor, w, h);
878 int snap_uv_curs_to_sel(void)
880 if( is_uv_tface_editing_allowed()==0 ) return 0;
881 return cent_tface_uv(G.v2d->cursor, 0);
884 void snap_menu_sima(void)
887 if( is_uv_tface_editing_allowed()==0 || !G.v2d) return; /* !G.v2d should never happen */
889 event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Cursor-> Pixel%x3|Cursor-> Selection%x4");
892 if (snap_uv_sel_to_pixels()) {
893 BIF_undo_push("Snap UV Selection to Pixels");
894 object_uvs_changed(OBACT);
898 if (snap_uv_sel_to_curs()) {
899 BIF_undo_push("Snap UV Selection to Cursor");
900 object_uvs_changed(OBACT);
904 snap_uv_curs_to_pixels();
905 scrarea_queue_winredraw(curarea);
908 if (snap_uv_curs_to_sel())
909 allqueue(REDRAWIMAGE, 0);
915 /** This is an ugly function to set the Tface selection flags depending
916 * on whether its UV coordinates are inside the normalized
917 * area with radius rad and offset offset. These coordinates must be
919 * Just for readability...
922 void sel_uvco_inside_radius(short sel, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, short select_index)
924 // normalized ellipse: ell[0] = scaleX,
927 float *uv = tface->uv[index];
930 x = (uv[0] - offset[0]) * ell[0];
931 y = (uv[1] - offset[1]) * ell[1];
935 if (sel == LEFTMOUSE) SIMA_UVSEL_SET(efa, tface, select_index);
936 else SIMA_UVSEL_UNSET(efa, tface, select_index);
941 /** gets image dimensions of the 2D view 'v' */
942 static void getSpaceImageDimension(SpaceImage *sima, float *xy)
944 ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
947 xy[0] = ibuf->x * sima->zoom;
948 xy[1] = ibuf->y * sima->zoom;
950 xy[0] = 256 * sima->zoom;
951 xy[1] = 256 * sima->zoom;
955 /** Callback function called by circle_selectCB to enable
956 * brush select in UV editor.
959 void uvedit_selectionCB(short selecting, Object *editobj, short *mval, float rad)
961 EditMesh *em = G.editMesh;
965 float ellipse[2]; // we need to deal with ellipses, as
966 // non square textures require for circle
967 // selection. this ellipse is normalized; r = 1.0
969 getSpaceImageDimension(curarea->spacedata.first, ellipse);
973 areamouseco_to_ipoco(G.v2d, mval, &offset[0], &offset[1]);
976 for (efa= em->faces.first; efa; efa= efa->next) {
977 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
978 sel_uvco_inside_radius(selecting, efa, tface, 0, offset, ellipse, 0);
979 sel_uvco_inside_radius(selecting, efa, tface, 1, offset, ellipse, 1);
980 sel_uvco_inside_radius(selecting, efa, tface, 2, offset, ellipse, 2);
982 sel_uvco_inside_radius(selecting, efa, tface, 3, offset, ellipse, 3);
985 if(G.f & G_DRAWFACES) { /* full redraw only if necessary */
986 draw_sel_circle(0, 0, 0, 0, 0); /* signal */
989 else { /* force_draw() is no good here... */
990 glDrawBuffer(GL_FRONT);
993 glDrawBuffer(GL_BACK);
997 if (selecting == LEFTMOUSE) EM_select_flush();
998 else EM_deselect_flush();
1000 if (G.sima->lock && (G.sima->flag & SI_SYNC_UVSEL))
1001 force_draw_plus(SPACE_VIEW3D, 0);
1006 void mouseco_to_curtile(void)
1011 if( is_uv_tface_editing_allowed()==0) return;
1013 if(G.sima->image && G.sima->image->tpageflag & IMA_TILES) {
1015 G.sima->flag |= SI_EDITTILE;
1017 while(get_mbut()&L_MOUSE) {
1019 calc_image_view(G.sima, 'f');
1021 getmouseco_areawin(mval);
1022 areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
1024 if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
1026 fx= (fx)*G.sima->image->xrep;
1027 fy= (fy)*G.sima->image->yrep;
1032 G.sima->curtile= mval[1]*G.sima->image->xrep + mval[0];
1035 scrarea_do_windraw(curarea);
1036 screen_swapbuffers();
1039 G.sima->flag &= ~SI_EDITTILE;
1041 image_set_tile(G.sima, 2);
1043 allqueue(REDRAWVIEW3D, 0);
1044 scrarea_queue_winredraw(curarea);
1048 /* Could be used for other 2D views also */
1049 void mouseco_to_cursor_sima(void)
1052 getmouseco_areawin(mval);
1053 areamouseco_to_ipoco(G.v2d, mval, &G.v2d->cursor[0], &G.v2d->cursor[1]);
1054 scrarea_queue_winredraw(curarea);
1057 void stitch_uv_tface(int mode)
1061 float newuv[2], limit[2];
1062 UvMapVert *vlist, *iterv, *v;
1063 EditMesh *em = G.editMesh;
1067 struct UvVertMap *vmap;
1070 if(is_uv_tface_editing_allowed()==0)
1072 if(G.sima->flag & SI_SYNC_UVSEL) {
1073 error("Can't stitch when Sync Mesh Selection is enabled");
1077 limit[0]= limit[1]= 20.0;
1079 add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL);
1080 if (!do_clever_numbuts("Stitch UVs", 1, REDRAW))
1084 limit[0]= limit[1]= limit[0]/256.0;
1086 ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
1088 if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
1089 limit[1]= limit[0]/(float)ibuf->y;
1090 limit[0]= limit[0]/(float)ibuf->x;
1094 /*vmap= make_uv_vert_map(me->mface, tf, me->totface, me->totvert, 1, limit);*/
1095 EM_init_index_arrays(0, 0, 1);
1096 vmap= make_uv_vert_map_EM(1, 0, limit);
1101 for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
1102 v = get_uv_map_vert_EM(vmap, a);
1107 newuv[0]= 0; newuv[1]= 0;
1110 for(iterv=v; iterv; iterv=iterv->next) {
1111 efa = EM_get_face_for_index(iterv->f);
1112 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1113 if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
1114 newuv[0] += tf->uv[iterv->tfindex][0];
1115 newuv[1] += tf->uv[iterv->tfindex][1];
1121 newuv[0] /= vtot; newuv[1] /= vtot;
1123 for(iterv=v; iterv; iterv=iterv->next) {
1124 efa = EM_get_face_for_index(iterv->f);
1125 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1126 if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
1127 tf->uv[iterv->tfindex][0]= newuv[0];
1128 tf->uv[iterv->tfindex][1]= newuv[1];
1133 } else if(mode==1) {
1134 for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
1135 vlist= get_uv_map_vert_EM(vmap, a);
1138 newuv[0]= 0; newuv[1]= 0;
1141 for(iterv=vlist; iterv; iterv=iterv->next) {
1142 if((iterv != vlist) && iterv->separate)
1144 efa = EM_get_face_for_index(iterv->f);
1145 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1147 if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
1148 newuv[0] += tf->uv[iterv->tfindex][0];
1149 newuv[1] += tf->uv[iterv->tfindex][1];
1155 newuv[0] /= vtot; newuv[1] /= vtot;
1157 for(iterv=vlist; iterv; iterv=iterv->next) {
1158 if((iterv != vlist) && iterv->separate)
1160 efa = EM_get_face_for_index(iterv->f);
1161 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1162 if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
1163 tf->uv[iterv->tfindex][0]= newuv[0];
1164 tf->uv[iterv->tfindex][1]= newuv[1];
1173 free_uv_vert_map_EM(vmap);
1174 EM_free_index_arrays();
1176 if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(em);
1178 BIF_undo_push("Stitch UV");
1180 object_uvs_changed(OBACT);
1183 void select_linked_tface_uv(int mode) /* TODO */
1185 EditMesh *em= G.editMesh;
1186 EditFace *efa, *nearestefa=NULL;
1187 MTFace *tf, *nearesttf=NULL;
1189 UvMapVert *vlist, *iterv, *startv;
1190 unsigned int *stack, stacksize= 0, nearestv;
1192 int a, nearestuv, i, nverts, j;
1194 if(is_uv_tface_editing_allowed()==0)
1197 if(G.sima->flag & SI_SYNC_UVSEL) {
1198 error("Can't select linked when Sync Mesh Selection is enabled");
1207 find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
1212 get_connected_limit_tface_uv(limit);
1213 vmap= make_uv_vert_map_EM(1, 1, limit);
1217 stack= MEM_mallocN(sizeof(*stack)* BLI_countlist(&em->faces), "UvLinkStack");
1218 flag= MEM_callocN(sizeof(*flag)*BLI_countlist(&em->faces), "UvLinkFlag");
1221 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1222 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1223 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
1224 if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) {
1225 stack[stacksize]= a;
1232 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1233 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1234 if(tf == nearesttf) {
1235 stack[stacksize]= a;
1243 while(stacksize > 0) {
1245 a= stack[stacksize];
1247 for (j=0, efa= em->faces.first; efa; efa= efa->next, j++) {
1249 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1254 nverts= efa->v4? 4: 3;
1256 for(i=0; i<nverts; i++) {
1257 /* make_uv_vert_map_EM sets verts tmp.l to the indicies */
1258 vlist= get_uv_map_vert_EM(vmap, (*(&efa->v1 + i))->tmp.l);
1262 for(iterv=vlist; iterv; iterv=iterv->next) {
1269 for(iterv=startv; iterv; iterv=iterv->next) {
1270 if((startv != iterv) && (iterv->separate))
1272 else if(!flag[iterv->f]) {
1274 stack[stacksize]= iterv->f;;
1281 if(mode==0 || mode==2) {
1282 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1283 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1285 tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1287 tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1291 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1293 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1295 if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
1298 else if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
1304 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1306 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1307 tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1312 for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
1314 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1315 tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1323 free_uv_vert_map_EM(vmap);
1325 BIF_undo_push("Select linked UV");
1326 scrarea_queue_winredraw(curarea);
1329 void unlink_selection(void)
1331 EditMesh *em= G.editMesh;
1335 if( is_uv_tface_editing_allowed()==0 ) return;
1337 if(G.sima->flag & SI_SYNC_UVSEL) {
1338 error("Can't select unlinked when Sync Mesh Selection is enabled");
1342 for (efa= em->faces.first; efa; efa= efa->next) {
1343 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1344 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
1346 if(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))
1347 tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
1349 if(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
1350 tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3);
1355 BIF_undo_push("Unlink UV selection");
1356 scrarea_queue_winredraw(curarea);
1359 void toggle_uv_select(int mode)
1363 G.sima->flag ^= SI_SELACTFACE;
1366 G.sima->flag ^= SI_STICKYUVS;
1367 if (G.sima->flag & SI_STICKYUVS) G.sima->flag &= ~SI_LOCALSTICKY;
1368 else G.sima->flag |= SI_LOCALSTICKY;
1371 G.sima->flag ^= SI_LOCALSTICKY;
1372 if (G.sima->flag & SI_LOCALSTICKY) G.sima->flag &= ~SI_STICKYUVS;
1375 G.sima->flag &= ~SI_STICKYUVS;
1376 G.sima->flag &= ~SI_LOCALSTICKY;
1379 allqueue(REDRAWIMAGE, 0);
1382 void pin_tface_uv(int mode)
1384 EditMesh *em = G.editMesh;
1388 if( is_uv_tface_editing_allowed()==0 ) return;
1390 for (efa= em->faces.first; efa; efa= efa->next) {
1391 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1392 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
1394 if(SIMA_UVSEL_CHECK(efa, tface, 0)) tface->unwrap |= TF_PIN1;
1395 if(SIMA_UVSEL_CHECK(efa, tface, 1)) tface->unwrap |= TF_PIN2;
1396 if(SIMA_UVSEL_CHECK(efa, tface, 2)) tface->unwrap |= TF_PIN3;
1398 if(SIMA_UVSEL_CHECK(efa, tface, 3)) tface->unwrap |= TF_PIN4;
1400 else if (mode ==0) {
1401 if(SIMA_UVSEL_CHECK(efa, tface, 0)) tface->unwrap &= ~TF_PIN1;
1402 if(SIMA_UVSEL_CHECK(efa, tface, 1)) tface->unwrap &= ~TF_PIN2;
1403 if(SIMA_UVSEL_CHECK(efa, tface, 2)) tface->unwrap &= ~TF_PIN3;
1405 if(SIMA_UVSEL_CHECK(efa, tface, 3)) tface->unwrap &= ~TF_PIN4;
1410 BIF_undo_push("Pin UV");
1411 scrarea_queue_winredraw(curarea);
1414 void select_pinned_tface_uv(void)
1416 EditMesh *em= G.editMesh;
1420 if( is_uv_tface_editing_allowed()==0 ) return;
1422 for (efa= em->faces.first; efa; efa= efa->next) {
1423 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1424 if (SIMA_FACEDRAW_CHECK(efa, tface)) {
1425 if (tface->unwrap & TF_PIN1) SIMA_UVSEL_SET(efa, tface, 0);
1426 if (tface->unwrap & TF_PIN2) SIMA_UVSEL_SET(efa, tface, 1);
1427 if (tface->unwrap & TF_PIN3) SIMA_UVSEL_SET(efa, tface, 2);
1429 if (tface->unwrap & TF_PIN4) SIMA_UVSEL_SET(efa, tface, 3);
1435 if (G.sima->flag & SI_SYNC_UVSEL) {
1436 allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
1439 BIF_undo_push("Select Pinned UVs");
1440 scrarea_queue_winredraw(curarea);
1443 int minmax_tface_uv(float *min, float *max)
1445 EditMesh *em= G.editMesh;
1450 if( is_uv_tface_editing_allowed()==0 ) return 0;
1452 INIT_MINMAX2(min, max);
1455 for (efa= em->faces.first; efa; efa= efa->next) {
1456 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1457 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
1458 if (SIMA_UVSEL_CHECK(efa, tf, 0)) DO_MINMAX2(tf->uv[0], min, max);
1459 if (SIMA_UVSEL_CHECK(efa, tf, 1)) DO_MINMAX2(tf->uv[1], min, max);
1460 if (SIMA_UVSEL_CHECK(efa, tf, 2)) DO_MINMAX2(tf->uv[2], min, max);
1461 if (efa->v4 && (SIMA_UVSEL_CHECK(efa, tf, 3))) DO_MINMAX2(tf->uv[3], min, max);
1468 int cent_tface_uv(float *cent, int mode)
1470 float min[2], max[2];
1474 if (minmax_tface_uv(min, max))
1477 } else if (mode==1) {
1480 INIT_MINMAX2(min, max);
1482 for (efa= G.editMesh->faces.first; efa; efa= efa->next) {
1483 tf = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
1484 if (SIMA_FACEDRAW_CHECK(efa, tf)) {
1485 if (SIMA_UVSEL_CHECK(efa, tf, 0)) { DO_MINMAX2(tf->uv[0], min, max); change= 1;}
1486 if (SIMA_UVSEL_CHECK(efa, tf, 1)) { DO_MINMAX2(tf->uv[1], min, max); change= 1;}
1487 if (SIMA_UVSEL_CHECK(efa, tf, 2)) { DO_MINMAX2(tf->uv[2], min, max); change= 1;}
1488 if (efa->v4 && (SIMA_UVSEL_CHECK(efa, tf, 3))) { DO_MINMAX2(tf->uv[3], min, max); change= 1;}
1494 cent[0]= (min[0]+max[0])/2.0;
1495 cent[1]= (min[1]+max[1])/2.0;
1501 static void sima_show_info(int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
1506 ofs= sprintf(str, "X: %d Y: %d ", x, y);
1508 ofs+= sprintf(str+ofs, "| R: %d G: %d B: %d A: %d ", cp[0], cp[1], cp[2], cp[3]);
1511 ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
1512 else if(channels==1)
1513 ofs+= sprintf(str+ofs, "| Val: %.3f ", fp[0]);
1514 else if(channels==3)
1515 ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f ", fp[0], fp[1], fp[2]);
1518 ofs+= sprintf(str+ofs, "| Z: %.4f ", 0.5+0.5*( ((float)*zp)/(float)0x7fffffff));
1520 ofs+= sprintf(str+ofs, "| Z: %.3f ", *zpf);
1522 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1525 glColor4f(.0,.0,.0,.25);
1526 glRectf(0.0, 0.0, curarea->winx, 30.0);
1527 glDisable(GL_BLEND);
1529 glColor3ub(255, 255, 255);
1530 glRasterPos2i(10, 10);
1532 BMF_DrawString(G.fonts, str);
1536 void sima_sample_color(void)
1538 ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
1540 short mval[2], mvalo[2], firsttime=1;
1545 calc_image_view(G.sima, 'f');
1546 getmouseco_areawin(mvalo);
1548 while(get_mbut() & L_MOUSE) {
1550 getmouseco_areawin(mval);
1551 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) {
1553 areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
1555 if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
1556 float *fp= NULL, *zpf= NULL;
1560 int x= (int) (fx*ibuf->x);
1561 int y= (int) (fy*ibuf->y);
1563 if(x>=ibuf->x) x= ibuf->x-1;
1564 if(y>=ibuf->y) y= ibuf->y-1;
1567 cp= (char *)(ibuf->rect + y*ibuf->x + x);
1569 zp= ibuf->zbuf + y*ibuf->x + x;
1570 if(ibuf->zbuf_float)
1571 zpf= ibuf->zbuf_float + y*ibuf->x + x;
1572 if(ibuf->rect_float)
1573 fp= (ibuf->rect_float + (ibuf->channels)*(y*ibuf->x + x));
1579 vec[0]= (float)cp[0]/255.0f;
1580 vec[1]= (float)cp[1]/255.0f;
1581 vec[2]= (float)cp[2]/255.0f;
1584 if(ibuf->channels==4) {
1585 if(G.qual & LR_CTRLKEY) {
1586 curvemapping_set_black_white(G.sima->cumap, NULL, fp);
1587 curvemapping_do_ibuf(G.sima->cumap, ibuf);
1589 else if(G.qual & LR_SHIFTKEY) {
1590 curvemapping_set_black_white(G.sima->cumap, fp, NULL);
1591 curvemapping_do_ibuf(G.sima->cumap, ibuf);
1596 scrarea_do_windraw(curarea);
1597 myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
1599 sima_show_info(ibuf->channels, x, y, cp, fp, zp, zpf);
1600 screen_swapbuffers();
1604 BIF_wait_for_statechange();
1607 scrarea_queue_winredraw(curarea);
1610 /* Image functions */
1612 static void load_image_filesel(char *str) /* called from fileselect */
1616 ima= BKE_add_image_file(str);
1618 BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
1619 image_changed(G.sima, ima);
1621 BIF_undo_push("Load image UV");
1622 allqueue(REDRAWIMAGE, 0);
1625 static void replace_image_filesel(char *str) /* called from fileselect */
1630 strncpy(G.sima->image->name, str, sizeof(G.sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */
1631 BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
1632 BIF_undo_push("Replace image UV");
1633 allqueue(REDRAWIMAGE, 0);
1634 allqueue(REDRAWVIEW3D, 0);
1638 static void save_image_doit(char *name)
1640 Image *ima= G.sima->image;
1641 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1643 char str[FILE_MAXDIR+FILE_MAXFILE];
1646 BLI_strncpy(str, name, sizeof(str));
1648 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
1650 if(G.scene->r.scemode & R_EXTENSION)
1651 BKE_add_image_extension(str, G.sima->imtypenr);
1653 if (saveover(str)) {
1655 /* enforce user setting for RGB or RGBA, but skip BW */
1656 if(G.scene->r.planes==32)
1658 else if(G.scene->r.planes==24)
1662 if(G.sima->imtypenr==R_MULTILAYER) {
1663 RenderResult *rr= BKE_image_get_renderresult(ima);
1665 RE_WriteRenderResult(rr, str, G.scene->r.quality);
1667 BLI_strncpy(ima->name, name, sizeof(ima->name));
1668 BLI_strncpy(ibuf->name, str, sizeof(ibuf->name));
1670 /* should be function? nevertheless, saving only happens here */
1671 for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
1672 ibuf->userflags &= ~IB_BITMAPDIRTY;
1675 else error("Did not write, no Multilayer Image");
1677 else if (BKE_write_ibuf(ibuf, str, G.sima->imtypenr, G.scene->r.subimtype, G.scene->r.quality)) {
1678 BLI_strncpy(ima->name, name, sizeof(ima->name));
1679 BLI_strncpy(ibuf->name, str, sizeof(ibuf->name));
1681 ibuf->userflags &= ~IB_BITMAPDIRTY;
1684 if( ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) {
1685 ima->source= IMA_SRC_FILE;
1686 ima->type= IMA_TYPE_IMAGE;
1688 if(ima->type==IMA_TYPE_R_RESULT)
1689 ima->type= IMA_TYPE_IMAGE;
1691 /* name image as how we saved it */
1693 while (len > 0 && str[len - 1] != '/' && str[len - 1] != '\\') len--;
1694 rename_id(&ima->id, str+len);
1697 error("Couldn't write image: %s", str);
1700 allqueue(REDRAWHEADERS, 0);
1701 allqueue(REDRAWBUTSSHADING, 0);
1708 void open_image_sima(short imageselect)
1710 char name[FILE_MAXDIR+FILE_MAXFILE];
1713 strcpy(name, G.sima->image->name);
1715 strcpy(name, U.textudir);
1718 activate_imageselect(FILE_SPECIAL, "Open Image", name, load_image_filesel);
1720 activate_fileselect(FILE_SPECIAL, "Open Image", name, load_image_filesel);
1723 void replace_image_sima(short imageselect)
1725 char name[FILE_MAXDIR+FILE_MAXFILE];
1728 strcpy(name, G.sima->image->name);
1730 strcpy(name, U.textudir);
1733 activate_imageselect(FILE_SPECIAL, "Replace Image", name, replace_image_filesel);
1735 activate_fileselect(FILE_SPECIAL, "Replace Image", name, replace_image_filesel);
1739 static char *filesel_imagetype_string(Image *ima)
1741 char *strp, *str= MEM_callocN(14*32, "menu for filesel");
1744 str += sprintf(str, "Save Image as: %%t|");
1745 str += sprintf(str, "Targa %%x%d|", R_TARGA);
1746 str += sprintf(str, "Targa Raw %%x%d|", R_RAWTGA);
1747 str += sprintf(str, "PNG %%x%d|", R_PNG);
1748 str += sprintf(str, "BMP %%x%d|", R_BMP);
1749 str += sprintf(str, "Jpeg %%x%d|", R_JPEG90);
1750 str += sprintf(str, "Iris %%x%d|", R_IRIS);
1752 str += sprintf(str, "Tiff %%x%d|", R_TIFF);
1753 str += sprintf(str, "Radiance HDR %%x%d|", R_RADHDR);
1754 str += sprintf(str, "Cineon %%x%d|", R_CINEON);
1755 str += sprintf(str, "DPX %%x%d|", R_DPX);
1757 str += sprintf(str, "OpenEXR %%x%d|", R_OPENEXR);
1758 /* saving sequences of multilayer won't work, they copy buffers */
1759 if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
1760 else str += sprintf(str, "MultiLayer %%x%d|", R_MULTILAYER);
1765 /* always opens fileselect */
1766 void save_as_image_sima(void)
1768 Image *ima = G.sima->image;
1769 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1770 char name[FILE_MAXDIR+FILE_MAXFILE];
1773 strcpy(name, ima->name);
1778 strp= filesel_imagetype_string(ima);
1780 /* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
1781 if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
1782 G.sima->imtypenr= R_MULTILAYER;
1783 else if(ima->type==IMA_TYPE_R_RESULT)
1784 G.sima->imtypenr= G.scene->r.imtype;
1785 else G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
1787 activate_fileselect_menu(FILE_SPECIAL, "Save Image", name, strp, &G.sima->imtypenr, save_image_doit);
1792 /* if exists, saves over without fileselect */
1793 void save_image_sima(void)
1795 Image *ima = G.sima->image;
1796 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1797 char name[FILE_MAXDIR+FILE_MAXFILE];
1800 strcpy(name, ima->name);
1803 if (BLI_exists(ibuf->name)) {
1804 if(BKE_image_get_renderresult(ima))
1805 G.sima->imtypenr= R_MULTILAYER;
1807 G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
1809 save_image_doit(ibuf->name);
1812 save_as_image_sima();
1817 void save_image_sequence_sima(void)
1821 char di[FILE_MAX], fi[FILE_MAX];
1823 if(G.sima->image==NULL)
1825 if(G.sima->image->source!=IMA_SRC_SEQUENCE)
1827 if(G.sima->image->type==IMA_TYPE_MULTILAYER) {
1828 error("Cannot save Multilayer Sequences");
1833 for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next)
1834 if(ibuf->userflags & IB_BITMAPDIRTY)
1838 notice("No Images have been changed");
1841 /* get a filename for menu */
1842 for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next)
1843 if(ibuf->userflags & IB_BITMAPDIRTY)
1846 BLI_strncpy(di, ibuf->name, FILE_MAX);
1847 BLI_splitdirstring(di, fi);
1849 sprintf(fi, "%d Image(s) will be saved in %s", tot, di);
1852 for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next) {
1853 if(ibuf->userflags & IB_BITMAPDIRTY) {
1854 char name[FILE_MAX];
1855 BLI_strncpy(name, ibuf->name, sizeof(name));
1857 BLI_convertstringcode(name, G.sce, 0);
1859 if(0 == IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)) {
1860 error("Could not write image", name);
1863 printf("Saved: %s\n", ibuf->name);
1864 ibuf->userflags &= ~IB_BITMAPDIRTY;
1870 void reload_image_sima(void)
1873 BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
1874 /* image_changed(G.sima, 0); - do we really need this? */
1877 allqueue(REDRAWIMAGE, 0);
1878 allqueue(REDRAWVIEW3D, 0);
1879 BIF_preview_changed(ID_TE);
1882 void new_image_sima(void)
1884 static int width= 256, height= 256;
1885 static short uvtestgrid= 0;
1886 static float color[] = {0, 0, 0, 1};
1890 strcpy(name, "Untitled");
1892 add_numbut(0, TEX, "Name:", 0, 21, name, NULL);
1893 add_numbut(1, NUM|INT, "Width:", 1, 5000, &width, NULL);
1894 add_numbut(2, NUM|INT, "Height:", 1, 5000, &height, NULL);
1895 add_numbut(3, COL, "", 0, 0, &color, NULL);
1896 add_numbut(4, NUM|FLO, "Alpha:", 0.0, 1.0, &color[3], NULL);
1897 add_numbut(5, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL);
1898 if (!do_clever_numbuts("New Image", 6, REDRAW))
1901 ima = BKE_add_image_size(width, height, name, uvtestgrid, color);
1902 image_changed(G.sima, ima);
1903 BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
1904 BIF_undo_push("Add image");
1906 allqueue(REDRAWIMAGE, 0);
1907 allqueue(REDRAWVIEW3D, 0);
1910 void pack_image_sima()
1912 Image *ima = G.sima->image;
1915 if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) {
1916 if (ima->packedfile) {
1917 if (G.fileflags & G_AUTOPACK)
1918 if (okee("Disable AutoPack?"))
1919 G.fileflags &= ~G_AUTOPACK;
1921 if ((G.fileflags & G_AUTOPACK) == 0) {
1922 unpackImage(ima, PF_ASK);
1923 BIF_undo_push("Unpack image");
1927 ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
1928 if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
1929 if(okee("Can't pack painted image. Use Repack as PNG?"))
1930 BKE_image_memorypack(ima);
1933 ima->packedfile = newPackedFile(ima->name);
1934 BIF_undo_push("Pack image");
1938 allqueue(REDRAWBUTSSHADING, 0);
1939 allqueue(REDRAWHEADERS, 0);
1946 /* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */
1947 void BIF_image_update_frame(void)
1952 for(tex= G.main->tex.first; tex; tex= tex->id.next) {
1953 if(tex->type==TEX_IMAGE && tex->ima)
1954 if(ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
1955 if(tex->iuser.flag & IMA_ANIM_ALWAYS)
1956 BKE_image_user_calc_imanr(&tex->iuser, G.scene->r.cfra, 0);
1959 /* image window, compo node users */
1962 for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
1963 if(sa->spacetype==SPACE_VIEW3D) {
1964 View3D *v3d= sa->spacedata.first;
1966 if(v3d->bgpic->iuser.flag & IMA_ANIM_ALWAYS)
1967 BKE_image_user_calc_imanr(&v3d->bgpic->iuser, G.scene->r.cfra, 0);
1969 else if(sa->spacetype==SPACE_IMAGE) {
1970 SpaceImage *sima= sa->spacedata.first;
1971 if(sima->iuser.flag & IMA_ANIM_ALWAYS)
1972 BKE_image_user_calc_imanr(&sima->iuser, G.scene->r.cfra, 0);
1974 else if(sa->spacetype==SPACE_NODE) {
1975 SpaceNode *snode= sa->spacedata.first;
1976 if((snode->treetype==NTREE_COMPOSIT) && (snode->nodetree)) {
1978 for(node= snode->nodetree->nodes.first; node; node= node->next) {
1979 if(node->id && node->type==CMP_NODE_IMAGE) {
1980 Image *ima= (Image *)node->id;
1981 ImageUser *iuser= node->storage;
1982 if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
1983 if(iuser->flag & IMA_ANIM_ALWAYS)
1984 BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
1993 void aspect_sima(SpaceImage *sima, float *x, float *y)
1997 if( (sima->image == 0) ||
1998 (sima->image->type == IMA_TYPE_R_RESULT) ||
1999 (sima->image->type == IMA_TYPE_COMPOSITE) ||
2000 (sima->image->tpageflag & IMA_TILES) ||
2001 (sima->image->aspx==0.0 || sima->image->aspy==0.0)
2007 *y = sima->image->aspy / sima->image->aspx;