Blender  V3.3
uvedit_buttons.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "DNA_meshdata_types.h"
14 #include "DNA_object_types.h"
15 #include "DNA_scene_types.h"
16 #include "DNA_screen_types.h"
17 #include "DNA_space_types.h"
18 
19 #include "BLI_blenlib.h"
20 #include "BLI_math.h"
21 #include "BLI_utildefines.h"
22 
23 #include "BLT_translation.h"
24 
25 #include "BKE_context.h"
26 #include "BKE_customdata.h"
27 #include "BKE_editmesh.h"
28 #include "BKE_layer.h"
29 #include "BKE_screen.h"
30 
31 #include "DEG_depsgraph.h"
32 
33 #include "ED_image.h"
34 #include "ED_uvedit.h"
35 
36 #include "UI_interface.h"
37 
38 #include "WM_api.h"
39 #include "WM_types.h"
40 
41 #define B_UVEDIT_VERTEX 3
42 
43 /* UV Utilities */
44 
45 static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float center[2])
46 {
47  BMFace *f;
48  BMLoop *l;
49  BMIter iter, liter;
50  MLoopUV *luv;
51  int tot = 0;
52 
53  zero_v2(center);
54 
55  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
56  Object *obedit = objects[ob_index];
58  const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
59 
60  BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
62  continue;
63  }
64 
65  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
66  if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
67  luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
68  add_v2_v2(center, luv->uv);
69  tot++;
70  }
71  }
72  }
73  }
74 
75  if (tot > 0) {
76  center[0] /= tot;
77  center[1] /= tot;
78  }
79 
80  return tot;
81 }
82 
84  Object **objects,
85  uint objects_len,
86  const float delta[2])
87 {
88  BMFace *f;
89  BMLoop *l;
90  BMIter iter, liter;
91  MLoopUV *luv;
92 
93  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
94  Object *obedit = objects[ob_index];
96 
97  const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
98 
99  BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
100  if (!uvedit_face_visible_test(scene, f)) {
101  continue;
102  }
103 
104  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
105  if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
106  luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
107  add_v2_v2(luv->uv, delta);
108  }
109  }
110  }
111  }
112 }
113 
114 /* Button Functions, using an evil static variable */
115 
116 static float uvedit_old_center[2];
117 
118 static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
119 {
122  float center[2];
123  int imx, imy, step, digits;
124  uint objects_len = 0;
126  CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
127 
128  ED_space_image_get_size(sima, &imx, &imy);
129 
130  if (uvedit_center(scene, objects, objects_len, center)) {
131  float range_xy[2][2] = {
132  {-10.0f, 10.0f},
133  {-10.0f, 10.0f},
134  };
135 
137 
138  /* expand UI range by center */
139  CLAMP_MAX(range_xy[0][0], uvedit_old_center[0]);
140  CLAMP_MIN(range_xy[0][1], uvedit_old_center[0]);
141  CLAMP_MAX(range_xy[1][0], uvedit_old_center[1]);
142  CLAMP_MIN(range_xy[1][1], uvedit_old_center[1]);
143 
144  if (!(sima->flag & SI_COORDFLOATS)) {
145  uvedit_old_center[0] *= imx;
146  uvedit_old_center[1] *= imy;
147 
148  mul_v2_fl(range_xy[0], imx);
149  mul_v2_fl(range_xy[1], imy);
150  }
151 
152  if (sima->flag & SI_COORDFLOATS) {
153  step = 1;
154  digits = 3;
155  }
156  else {
157  step = 100;
158  digits = 2;
159  }
160 
161  uiBut *but;
162 
163  int y = 0;
164  UI_block_align_begin(block);
165  but = uiDefButF(block,
166  UI_BTYPE_NUM,
168  IFACE_("X:"),
169  0,
170  y -= UI_UNIT_Y,
171  200,
172  UI_UNIT_Y,
173  &uvedit_old_center[0],
174  UNPACK2(range_xy[0]),
175  0,
176  0,
177  "");
178  UI_but_number_step_size_set(but, step);
179  UI_but_number_precision_set(but, digits);
180  but = uiDefButF(block,
181  UI_BTYPE_NUM,
183  IFACE_("Y:"),
184  0,
185  y -= UI_UNIT_Y,
186  200,
187  UI_UNIT_Y,
188  &uvedit_old_center[1],
189  UNPACK2(range_xy[1]),
190  0,
191  0,
192  "");
193  UI_but_number_step_size_set(but, step);
194  UI_but_number_precision_set(but, digits);
195  UI_block_align_end(block);
196  }
197 
198  MEM_freeN(objects);
199 }
200 
201 static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
202 {
205  float center[2], delta[2];
206  int imx, imy;
207 
208  if (event != B_UVEDIT_VERTEX) {
209  return;
210  }
211 
212  uint objects_len = 0;
214  CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
215 
216  ED_space_image_get_size(sima, &imx, &imy);
217  uvedit_center(scene, objects, objects_len, center);
218 
219  if (sima->flag & SI_COORDFLOATS) {
220  delta[0] = uvedit_old_center[0] - center[0];
221  delta[1] = uvedit_old_center[1] - center[1];
222  }
223  else {
224  delta[0] = uvedit_old_center[0] / imx - center[0];
225  delta[1] = uvedit_old_center[1] / imy - center[1];
226  }
227 
228  uvedit_translate(scene, objects, objects_len, delta);
229 
231  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
232  Object *obedit = objects[ob_index];
234  }
235 
236  MEM_freeN(objects);
237 }
238 
239 /* Panels */
240 
241 static bool image_panel_uv_poll(const bContext *C, PanelType *UNUSED(pt))
242 {
244  if (sima->mode != SI_MODE_UV) {
245  return false;
246  }
247  Object *obedit = CTX_data_edit_object(C);
248  return ED_uvedit_test(obedit);
249 }
250 
251 static void image_panel_uv(const bContext *C, Panel *panel)
252 {
253  uiBlock *block;
254 
255  block = uiLayoutAbsoluteBlock(panel->layout);
257 
258  uvedit_vertex_buttons(C, block);
259 }
260 
262 {
263  PanelType *pt;
264 
265  pt = MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
266  strcpy(pt->idname, "IMAGE_PT_uv");
267  strcpy(pt->label, N_("UV Vertex")); /* XXX C panels unavailable through RNA bpy.types! */
268  /* Could be 'Item' matching 3D view, avoid new tab for two buttons. */
269  strcpy(pt->category, "Image");
270  pt->draw = image_panel_uv;
272  BLI_addtail(&art->paneltypes, pt);
273 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1370
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct SpaceImage * CTX_wm_space_image(const bContext *C)
Definition: context.c:824
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:58
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, v3d, r_len)
Definition: BKE_layer.h:550
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
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:67
#define UNPACK2(a)
#define CLAMP_MAX(a, c)
#define UNUSED(x)
#define CLAMP_MIN(a, b)
#define IFACE_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ 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:201
bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset)
bool ED_uvedit_test(struct Object *obedit)
Definition: uvedit_ops.c:64
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:25
#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.cc:5042
uiBlock * uiLayoutAbsoluteBlock(uiLayout *layout)
void UI_but_number_step_size_set(uiBut *but, float step_size)
Definition: interface.cc:6455
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
Definition: interface.cc:5953
void UI_block_align_begin(uiBlock *block)
Definition: interface.cc:3910
void UI_but_number_precision_set(uiBut *but, float precision)
Definition: interface.cc:6464
@ UI_BTYPE_NUM
Definition: UI_interface.h:337
void UI_block_align_end(uiBlock *block)
Definition: interface.cc:3923
#define NC_IMAGE
Definition: WM_types.h:334
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:541
#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:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ListBase paneltypes
Definition: BKE_screen.h:198
struct BMesh * bm
Definition: BKE_editmesh.h:40
CustomData ldata
Definition: bmesh_class.h:337
Definition: DNA_ID.h:368
void * data
void(* draw)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:248
bool(* poll)(const struct bContext *C, struct PanelType *pt)
Definition: BKE_screen.h:242
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:223
char category[BKE_ST_MAXNAME]
Definition: BKE_screen.h:228
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:224
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
#define N_(msgid)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)