=bmesh= merge from trunk at r36529
[blender.git] / source / blender / editors / uvedit / uvedit_buttons.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, 2002-2009
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/uvedit/uvedit_buttons.c
29  *  \ingroup eduv
30  */
31
32 #include <string.h>
33 #include <stdio.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_meshdata_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_screen_types.h"
41 #include "DNA_space_types.h"
42
43 #include "BLI_blenlib.h"
44 #include "BLI_math.h"
45 #include "BLI_editVert.h"
46 #include "BLI_utildefines.h"
47
48 #include "BKE_context.h"
49 #include "BKE_customdata.h"
50 #include "BKE_mesh.h"
51 #include "BKE_screen.h"
52 #include "BKE_tessmesh.h"
53
54 #include "ED_image.h"
55 #include "ED_uvedit.h"
56
57 #include "UI_interface.h"
58 #include "UI_resources.h"
59
60 #include "WM_api.h"
61 #include "WM_types.h"
62
63 #define B_UVEDIT_VERTEX         3
64
65 /* UV Utilities */
66
67 static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[2])
68 {
69         BMFace *f;
70         BMLoop *l;
71         BMIter iter, liter;
72         MLoopUV *luv;
73         int tot = 0.0;
74         
75         zero_v2(center);
76         BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
77                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
78                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
79                         if (uvedit_uv_selected(em, scene, l)) {
80                                 add_v2_v2(center, luv->uv);
81                                 tot++;
82                         }
83                 }
84         }
85
86         if(tot > 0) {
87                 center[0] /= tot;
88                 center[1] /= tot;
89         }
90
91         return tot;
92 }
93
94 static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float delta[2])
95 {
96         BMFace *f;
97         BMLoop *l;
98         BMIter iter, liter;
99         MLoopUV *luv;
100         
101         BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
102                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
103                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
104                         if (uvedit_uv_selected(em, scene, l)) {
105                                 add_v2_v2(luv->uv, delta);
106                         }
107                 }
108         }
109 }
110
111 /* Button Functions, using an evil static variable */
112
113 static float uvedit_old_center[2];
114
115 static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
116 {
117         SpaceImage *sima= CTX_wm_space_image(C);
118         Scene *scene= CTX_data_scene(C);
119         Object *obedit= CTX_data_edit_object(C);
120         Image *ima= sima->image;
121         BMEditMesh *em;
122         float center[2];
123         int imx, imy, step, digits;
124
125         ED_space_image_size(sima, &imx, &imy);
126         
127         em= ((Mesh *)obedit->data)->edit_btmesh;
128
129         if(uvedit_center(scene, em, ima, center)) {
130                 copy_v2_v2(uvedit_old_center, center);
131
132                 if(!(sima->flag & SI_COORDFLOATS)) {
133                         uvedit_old_center[0] *= imx;
134                         uvedit_old_center[1] *= imy;
135                 }
136
137                 if(sima->flag & SI_COORDFLOATS) {
138                         step= 1;
139                         digits= 3;
140                 }
141                 else {
142                         step= 100;
143                         digits= 2;
144                 }
145                 
146                 uiBlockBeginAlign(block);
147                 uiDefButF(block, NUM, B_UVEDIT_VERTEX, "X:",    10, 10, 145, 19, &uvedit_old_center[0], -10*imx, 10.0*imx, step, digits, "");
148                 uiDefButF(block, NUM, B_UVEDIT_VERTEX, "Y:",    165, 10, 145, 19, &uvedit_old_center[1], -10*imy, 10.0*imy, step, digits, "");
149                 uiBlockEndAlign(block);
150         }
151 }
152
153 static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
154 {
155         SpaceImage *sima= CTX_wm_space_image(C);
156         Scene *scene= CTX_data_scene(C);
157         Object *obedit= CTX_data_edit_object(C);
158         Image *ima= sima->image;
159         BMEditMesh *em;
160         float center[2], delta[2];
161         int imx, imy;
162
163         if(event != B_UVEDIT_VERTEX)
164                 return;
165
166         em= ((Mesh *)obedit->data)->edit_btmesh;
167
168         ED_space_image_size(sima, &imx, &imy);
169         uvedit_center(scene, em, ima, center);
170
171         if(sima->flag & SI_COORDFLOATS) {
172                 delta[0]= uvedit_old_center[0] - center[0];
173                 delta[1]= uvedit_old_center[1] - center[1];
174         }
175         else {
176                 delta[0]= uvedit_old_center[0]/imx - center[0];
177                 delta[1]= uvedit_old_center[1]/imy - center[1];
178         }
179
180         uvedit_translate(scene, em, ima, delta);
181
182         WM_event_add_notifier(C, NC_IMAGE, sima->image);
183 }
184
185 /* Panels */
186
187 static int image_panel_uv_poll(const bContext *C, PanelType *UNUSED(pt))
188 {
189         Object *obedit= CTX_data_edit_object(C);
190         return ED_uvedit_test(obedit);
191 }
192
193 static void image_panel_uv(const bContext *C, Panel *pa)
194 {
195         uiBlock *block;
196         
197         block= uiLayoutAbsoluteBlock(pa->layout);
198         uiBlockSetHandleFunc(block, do_uvedit_vertex, NULL);
199
200         uvedit_vertex_buttons(C, block);
201 }       
202
203 void ED_uvedit_buttons_register(ARegionType *art)
204 {
205         PanelType *pt;
206
207         pt= MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
208         strcpy(pt->idname, "IMAGE_PT_uv");
209         strcpy(pt->label, "UV Vertex");
210         pt->draw= image_panel_uv;
211         pt->poll= image_panel_uv_poll;
212         BLI_addtail(&art->paneltypes, pt);
213 }
214