Blender  V2.93
uvedit_buttons.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "DNA_meshdata_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_space_types.h"
34 
35 #include "BLI_blenlib.h"
36 #include "BLI_math.h"
37 #include "BLI_utildefines.h"
38 
39 #include "BLT_translation.h"
40 
41 #include "BKE_context.h"
42 #include "BKE_customdata.h"
43 #include "BKE_editmesh.h"
44 #include "BKE_layer.h"
45 #include "BKE_screen.h"
46 
47 #include "DEG_depsgraph.h"
48 
49 #include "ED_image.h"
50 #include "ED_uvedit.h"
51 
52 #include "UI_interface.h"
53 
54 #include "WM_api.h"
55 #include "WM_types.h"
56 
57 #define B_UVEDIT_VERTEX 3
58 
59 /* UV Utilities */
60 
61 static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float center[2])
62 {
63  BMFace *f;
64  BMLoop *l;
65  BMIter iter, liter;
66  MLoopUV *luv;
67  int tot = 0;
68 
69  zero_v2(center);
70 
71  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
72  Object *obedit = objects[ob_index];
74  const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
75 
76  BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
78  continue;
79  }
80 
81  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
82  if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
83  luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
84  add_v2_v2(center, luv->uv);
85  tot++;
86  }
87  }
88  }
89  }
90 
91  if (tot > 0) {
92  center[0] /= tot;
93  center[1] /= tot;
94  }
95 
96  return tot;
97 }
98 
100  Object **objects,
101  uint objects_len,
102  const float delta[2])
103 {
104  BMFace *f;
105  BMLoop *l;
106  BMIter iter, liter;
107  MLoopUV *luv;
108 
109  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
110  Object *obedit = objects[ob_index];
111  BMEditMesh *em = BKE_editmesh_from_object(obedit);
112 
113  const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
114 
115  BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
116  if (!uvedit_face_visible_test(scene, f)) {
117  continue;
118  }
119 
120  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
121  if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
122  luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
123  add_v2_v2(luv->uv, delta);
124  }
125  }
126  }
127  }
128 }
129 
130 /* Button Functions, using an evil static variable */
131 
132 static float uvedit_old_center[2];
133 
134 static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
135 {
138  float center[2];
139  int imx, imy, step, digits;
140  uint objects_len = 0;
142  CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
143 
144  ED_space_image_get_size(sima, &imx, &imy);
145 
146  if (uvedit_center(scene, objects, objects_len, center)) {
147  float range_xy[2][2] = {
148  {-10.0f, 10.0f},
149  {-10.0f, 10.0f},
150  };
151 
153 
154  /* expand UI range by center */
155  CLAMP_MAX(range_xy[0][0], uvedit_old_center[0]);
156  CLAMP_MIN(range_xy[0][1], uvedit_old_center[0]);
157  CLAMP_MAX(range_xy[1][0], uvedit_old_center[1]);
158  CLAMP_MIN(range_xy[1][1], uvedit_old_center[1]);
159 
160  if (!(sima->flag & SI_COORDFLOATS)) {
161  uvedit_old_center[0] *= imx;
162  uvedit_old_center[1] *= imy;
163 
164  mul_v2_fl(range_xy[0], imx);
165  mul_v2_fl(range_xy[1], imy);
166  }
167 
168  if (sima->flag & SI_COORDFLOATS) {
169  step = 1;
170  digits = 3;
171  }
172  else {
173  step = 100;
174  digits = 2;
175  }
176 
177  uiBut *but;
178 
179  int y = 0;
180  UI_block_align_begin(block);
181  but = uiDefButF(block,
182  UI_BTYPE_NUM,
184  IFACE_("X:"),
185  0,
186  y -= UI_UNIT_Y,
187  200,
188  UI_UNIT_Y,
189  &uvedit_old_center[0],
190  UNPACK2(range_xy[0]),
191  0,
192  0,
193  "");
194  UI_but_number_step_size_set(but, step);
195  UI_but_number_precision_set(but, digits);
196  but = uiDefButF(block,
197  UI_BTYPE_NUM,
199  IFACE_("Y:"),
200  0,
201  y -= UI_UNIT_Y,
202  200,
203  UI_UNIT_Y,
204  &uvedit_old_center[1],
205  UNPACK2(range_xy[1]),
206  0,
207  0,
208  "");
209  UI_but_number_step_size_set(but, step);
210  UI_but_number_precision_set(but, digits);
211  UI_block_align_end(block);
212  }
213 
214  MEM_freeN(objects);
215 }
216 
217 static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
218 {
221  float center[2], delta[2];
222  int imx, imy;
223 
224  if (event != B_UVEDIT_VERTEX) {
225  return;
226  }
227 
228  uint objects_len = 0;
230  CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
231 
232  ED_space_image_get_size(sima, &imx, &imy);
233  uvedit_center(scene, objects, objects_len, center);
234 
235  if (sima->flag & SI_COORDFLOATS) {
236  delta[0] = uvedit_old_center[0] - center[0];
237  delta[1] = uvedit_old_center[1] - center[1];
238  }
239  else {
240  delta[0] = uvedit_old_center[0] / imx - center[0];
241  delta[1] = uvedit_old_center[1] / imy - center[1];
242  }
243 
244  uvedit_translate(scene, objects, objects_len, delta);
245 
247  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
248  Object *obedit = objects[ob_index];
250  }
251 
252  MEM_freeN(objects);
253 }
254 
255 /* Panels */
256 
257 static bool image_panel_uv_poll(const bContext *C, PanelType *UNUSED(pt))
258 {
260  if (sima->mode != SI_MODE_UV) {
261  return false;
262  }
263  Object *obedit = CTX_data_edit_object(C);
264  return ED_uvedit_test(obedit);
265 }
266 
267 static void image_panel_uv(const bContext *C, Panel *panel)
268 {
269  uiBlock *block;
270 
271  block = uiLayoutAbsoluteBlock(panel->layout);
273 
274  uvedit_vertex_buttons(C, block);
275 }
276 
278 {
279  PanelType *pt;
280 
281  pt = MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
282  strcpy(pt->idname, "IMAGE_PT_uv");
283  strcpy(pt->label, N_("UV Vertex")); /* XXX C panels unavailable through RNA bpy.types! */
284  /* Could be 'Item' matching 3D view, avoid new tab for two buttons. */
285  strcpy(pt->category, "Image");
286  pt->draw = image_panel_uv;
288  BLI_addtail(&art->paneltypes, pt);
289 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1296
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct SpaceImage * CTX_wm_space_image(const bContext *C)
Definition: context.c:800
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const struct CustomData *data, int type)
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, v3d, r_len)
Definition: BKE_layer.h:434
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void zero_v2(float r[2])
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK2(a)
#define CLAMP_MAX(a, c)
#define UNUSED(x)
#define CLAMP_MIN(a, b)
#define IFACE_(msgid)
#define N_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ CD_MLOOPUV
Object is a sort of wrapper for general info.
@ SI_COORDFLOATS
@ SI_MODE_UV
void ED_space_image_get_size(struct SpaceImage *sima, int *r_width, int *r_height)
Definition: image_edit.c:215
bool ED_uvedit_test(struct Object *obedit)
Definition: uvedit_ops.c:80
bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, const int cd_loop_uv_offset)
bool uvedit_face_visible_test(const struct Scene *scene, struct BMFace *efa)
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
#define UI_UNIT_Y
uiBut * uiDefButF(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4896
uiBlock * uiLayoutAbsoluteBlock(uiLayout *layout)
void UI_but_number_step_size_set(uiBut *but, float step_size)
Definition: interface.c:6827
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
Definition: interface.c:6247
void UI_block_align_begin(uiBlock *block)
Definition: interface.c:3821
void UI_but_number_precision_set(uiBut *but, float precision)
Definition: interface.c:6836
@ UI_BTYPE_NUM
Definition: UI_interface.h:341
void UI_block_align_end(uiBlock *block)
Definition: interface.c:3834
#define NC_IMAGE
Definition: WM_types.h:285
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:530
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_FACE
ATTR_WARN_UNUSED_RESULT const BMLoop * l
Scene scene
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
ListBase paneltypes
Definition: BKE_screen.h:216
struct BMesh * bm
Definition: BKE_editmesh.h:52
CustomData ldata
Definition: bmesh_class.h:337
Definition: DNA_ID.h:273
void * data
void(* draw)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:266
bool(* poll)(const struct bContext *C, struct PanelType *pt)
Definition: BKE_screen.h:260
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:241
char category[BKE_ST_MAXNAME]
Definition: BKE_screen.h:246
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:242
struct uiLayout * layout
struct Image * image
static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float center[2])
void ED_uvedit_buttons_register(ARegionType *art)
static void uvedit_translate(Scene *scene, Object **objects, uint objects_len, const float delta[2])
static bool image_panel_uv_poll(const bContext *C, PanelType *UNUSED(pt))
static float uvedit_old_center[2]
static void image_panel_uv(const bContext *C, Panel *panel)
static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
#define B_UVEDIT_VERTEX
void WM_event_add_notifier(const bContext *C, uint type, void *reference)