Blender  V3.3
transform_convert_mesh_uv.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 "DNA_meshdata_types.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_bitmap.h"
13 #include "BLI_linklist_stack.h"
14 #include "BLI_math.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_customdata.h"
18 #include "BKE_editmesh.h"
19 #include "BKE_mesh_mapping.h"
20 
21 #include "ED_image.h"
22 #include "ED_mesh.h"
23 #include "ED_uvedit.h"
24 
25 #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
26 
27 #include "transform.h"
28 #include "transform_convert.h"
29 
30 /* -------------------------------------------------------------------- */
34 static void UVsToTransData(const float aspect[2],
35  TransData *td,
36  TransData2D *td2d,
37  float *uv,
38  const float *center,
39  float calc_dist,
40  bool selected)
41 {
42  /* UV coords are scaled by aspects. this is needed for rotations and
43  * proportional editing to be consistent with the stretched UV coords
44  * that are displayed. this also means that for display and number-input,
45  * and when the UV coords are flushed, these are converted each time. */
46  td2d->loc[0] = uv[0] * aspect[0];
47  td2d->loc[1] = uv[1] * aspect[1];
48  td2d->loc[2] = 0.0f;
49  td2d->loc2d = uv;
50 
51  td->flag = 0;
52  td->loc = td2d->loc;
53  copy_v2_v2(td->center, center ? center : td->loc);
54  td->center[2] = 0.0f;
55  copy_v3_v3(td->iloc, td->loc);
56 
57  memset(td->axismtx, 0, sizeof(td->axismtx));
58  td->axismtx[2][2] = 1.0f;
59 
60  td->ext = NULL;
61  td->val = NULL;
62 
63  if (selected) {
64  td->flag |= TD_SELECTED;
65  td->dist = 0.0;
66  }
67  else {
68  td->dist = calc_dist;
69  }
70  unit_m3(td->mtx);
71  unit_m3(td->smtx);
72 }
73 
78  BMesh *bm,
79  float *dists,
80  const float aspect[2])
81 {
82 #define TMP_LOOP_SELECT_TAG BM_ELEM_TAG_ALT
83  /* Mostly copied from #transform_convert_mesh_connectivity_distance. */
85 
86  /* Any BM_ELEM_TAG'd loop is added to 'queue_next', this makes sure that we don't add things
87  * twice. */
88  BLI_LINKSTACK_DECLARE(queue_next, BMLoop *);
89 
91  BLI_LINKSTACK_INIT(queue_next);
92 
93  const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
94  BMIter fiter, liter;
95  BMVert *f;
96  BMLoop *l;
97 
99 
100  BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
101  /* Visible faces was tagged in #createTransUVs. */
102  if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
103  continue;
104  }
105 
106  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
107  float dist;
108  MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
109 
110  bool uv_vert_sel = uvedit_uv_select_test_ex(ts, l, cd_loop_uv_offset);
111 
112  if (uv_vert_sel) {
115  dist = 0.0f;
116  }
117  else {
119  dist = FLT_MAX;
120  }
121 
122  /* Make sure all loops are in a clean tag state. */
124 
125  int loop_idx = BM_elem_index_get(l);
126 
127  dists[loop_idx] = dist;
128  }
129  }
130 
131  /* Need to be very careful of feedback loops here, store previous dist's to avoid feedback. */
132  float *dists_prev = MEM_dupallocN(dists);
133 
134  do {
135  while ((l = BLI_LINKSTACK_POP(queue))) {
136  BLI_assert(dists[BM_elem_index_get(l)] != FLT_MAX);
137 
138  BMLoop *l_other, *l_connected;
139  BMIter l_connected_iter;
140 
141  MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
142  float l_uv[2];
143 
144  copy_v2_v2(l_uv, luv->uv);
145  mul_v2_v2(l_uv, aspect);
146 
147  BM_ITER_ELEM (l_other, &liter, l->f, BM_LOOPS_OF_FACE) {
148  if (l_other == l) {
149  continue;
150  }
151  float other_uv[2], edge_vec[2];
152  MLoopUV *luv_other = BM_ELEM_CD_GET_VOID_P(l_other, cd_loop_uv_offset);
153 
154  copy_v2_v2(other_uv, luv_other->uv);
155  mul_v2_v2(other_uv, aspect);
156 
157  sub_v2_v2v2(edge_vec, l_uv, other_uv);
158 
159  const int i = BM_elem_index_get(l);
160  const int i_other = BM_elem_index_get(l_other);
161  float dist = len_v2(edge_vec) + dists_prev[i];
162 
163  if (dist < dists[i_other]) {
164  dists[i_other] = dist;
165  }
166  else {
167  /* The face loop already has a shorter path to it. */
168  continue;
169  }
170 
171  bool other_vert_sel, connected_vert_sel;
172 
173  other_vert_sel = BM_elem_flag_test_bool(l_other, TMP_LOOP_SELECT_TAG);
174 
175  BM_ITER_ELEM (l_connected, &l_connected_iter, l_other->v, BM_LOOPS_OF_VERT) {
176  if (l_connected == l_other) {
177  continue;
178  }
179  /* Visible faces was tagged in #createTransUVs. */
180  if (!BM_elem_flag_test(l_connected->f, BM_ELEM_TAG)) {
181  continue;
182  }
183 
184  MLoopUV *luv_connected = BM_ELEM_CD_GET_VOID_P(l_connected, cd_loop_uv_offset);
185  connected_vert_sel = BM_elem_flag_test_bool(l_connected, TMP_LOOP_SELECT_TAG);
186 
187  /* Check if this loop is connected in UV space.
188  * If the uv loops share the same selection state (if not, they are not connected as
189  * they have been ripped or other edit commands have separated them). */
190  bool connected = other_vert_sel == connected_vert_sel &&
191  equals_v2v2(luv_other->uv, luv_connected->uv);
192  if (!connected) {
193  continue;
194  }
195 
196  /* The loop vert is occupying the same space, so it has the same distance. */
197  const int i_connected = BM_elem_index_get(l_connected);
198  dists[i_connected] = dist;
199 
200  if (BM_elem_flag_test(l_connected, BM_ELEM_TAG) == 0) {
201  BM_elem_flag_enable(l_connected, BM_ELEM_TAG);
202  BLI_LINKSTACK_PUSH(queue_next, l_connected);
203  }
204  }
205  }
206  }
207 
208  /* Clear elem flags for the next loop. */
209  for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
210  BMLoop *l_link = lnk->link;
211  const int i = BM_elem_index_get(l_link);
212 
214 
215  /* Store all new dist values. */
216  dists_prev[i] = dists[i];
217  }
218 
219  BLI_LINKSTACK_SWAP(queue, queue_next);
220 
221  } while (BLI_LINKSTACK_SIZE(queue));
222 
223 #ifndef NDEBUG
224  /* Check that we didn't leave any loops tagged */
225  BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
226  /* Visible faces was tagged in #createTransUVs. */
227  if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
228  continue;
229  }
230 
231  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
233  }
234  }
235 #endif
236 
238  BLI_LINKSTACK_FREE(queue_next);
239 
240  MEM_freeN(dists_prev);
241 #undef TMP_LOOP_SELECT_TAG
242 }
243 
245 {
247  Scene *scene = t->scene;
248 
249  const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
250  const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
251  const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
252 
254 
255  TransData *td = NULL;
256  TransData2D *td2d = NULL;
257  BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
258  BMFace *efa;
259  BMIter iter, liter;
260  UvElementMap *elementmap = NULL;
261  struct {
262  float co[2];
263  int co_num;
264  } *island_center = NULL;
265  int count = 0, countsel = 0;
266  const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
267 
268  if (!ED_space_image_show_uvedit(sima, tc->obedit)) {
269  continue;
270  }
271 
272  /* count */
273  if (is_island_center) {
274  /* create element map with island information */
275  elementmap = BM_uv_element_map_create(em->bm, scene, true, false, true);
276  if (elementmap == NULL) {
277  continue;
278  }
279 
280  island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__);
281  }
282 
283  BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
284  BMLoop *l;
285 
286  if (!uvedit_face_visible_test(scene, efa)) {
288  continue;
289  }
290 
292  BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
293  /* Make sure that the loop element flag is cleared for when we use it in
294  * uv_set_connectivity_distance later. */
296  if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
297  countsel++;
298 
299  if (island_center) {
300  UvElement *element = BM_uv_element_get(elementmap, efa, l);
301 
302  if (element->flag == false) {
303  MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
304  add_v2_v2(island_center[element->island].co, luv->uv);
305  island_center[element->island].co_num++;
306  element->flag = true;
307  }
308  }
309  }
310 
311  if (is_prop_edit) {
312  count++;
313  }
314  }
315  }
316 
317  float *prop_dists = NULL;
318 
319  /* Support other objects using PET to adjust these, unless connected is enabled. */
320  if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) {
321  goto finally;
322  }
323 
324  if (is_island_center) {
325  int i;
326 
327  for (i = 0; i < elementmap->totalIslands; i++) {
328  mul_v2_fl(island_center[i].co, 1.0f / island_center[i].co_num);
329  mul_v2_v2(island_center[i].co, t->aspect);
330  }
331  }
332 
333  tc->data_len = (is_prop_edit) ? count : countsel;
334  tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(UV Editing)");
335  /* for each 2d uv coord a 3d vector is allocated, so that they can be
336  * treated just as if they were 3d verts */
337  tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(UV Editing)");
338 
339  if (sima->flag & SI_CLIP_UV) {
340  t->flag |= T_CLIP_UV;
341  }
342 
343  td = tc->data;
344  td2d = tc->data_2d;
345 
346  if (is_prop_connected) {
347  prop_dists = MEM_callocN(em->bm->totloop * sizeof(float), "TransObPropDists(UV Editing)");
348 
349  uv_set_connectivity_distance(t->settings, em->bm, prop_dists, t->aspect);
350  }
351 
352  BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
353  BMLoop *l;
354 
355  if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) {
356  continue;
357  }
358 
359  BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
360  const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
361  MLoopUV *luv;
362  const float *center = NULL;
363  float prop_distance = FLT_MAX;
364 
365  if (!is_prop_edit && !selected) {
366  continue;
367  }
368 
369  if (is_prop_connected) {
370  const int idx = BM_elem_index_get(l);
371  prop_distance = prop_dists[idx];
372  }
373 
374  if (is_island_center) {
375  UvElement *element = BM_uv_element_get(elementmap, efa, l);
376  if (element) {
377  center = island_center[element->island].co;
378  }
379  }
380 
381  luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
382  UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, prop_distance, selected);
383  }
384  }
385 
386  if (sima->flag & SI_LIVE_UNWRAP) {
387  ED_uvedit_live_unwrap_begin(t->scene, tc->obedit);
388  }
389 
390  finally:
391  if (is_prop_connected) {
392  MEM_SAFE_FREE(prop_dists);
393  }
394  if (is_island_center) {
395  BM_uv_element_map_free(elementmap);
396 
397  MEM_freeN(island_center);
398  }
399  }
400 }
401 
404 /* -------------------------------------------------------------------- */
408 static void flushTransUVs(TransInfo *t)
409 {
410  SpaceImage *sima = t->area->spacedata.first;
411  const bool use_pixel_snap = ((sima->pixel_snap_mode != SI_PIXEL_SNAP_DISABLED) &&
412  (t->state != TRANS_CANCEL));
413 
415  TransData2D *td;
416  int a;
417  float aspect_inv[2], size[2];
418 
419  aspect_inv[0] = 1.0f / t->aspect[0];
420  aspect_inv[1] = 1.0f / t->aspect[1];
421 
422  if (use_pixel_snap) {
423  int size_i[2];
424  ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
425  size[0] = size_i[0];
426  size[1] = size_i[1];
427  }
428 
429  /* flush to 2d vector from internally used 3d vector */
430  for (a = 0, td = tc->data_2d; a < tc->data_len; a++, td++) {
431  td->loc2d[0] = td->loc[0] * aspect_inv[0];
432  td->loc2d[1] = td->loc[1] * aspect_inv[1];
433 
434  if (use_pixel_snap) {
435  td->loc2d[0] *= size[0];
436  td->loc2d[1] *= size[1];
437 
438  switch (sima->pixel_snap_mode) {
440  td->loc2d[0] = roundf(td->loc2d[0] - 0.5f) + 0.5f;
441  td->loc2d[1] = roundf(td->loc2d[1] - 0.5f) + 0.5f;
442  break;
444  td->loc2d[0] = roundf(td->loc2d[0]);
445  td->loc2d[1] = roundf(td->loc2d[1]);
446  break;
447  }
448 
449  td->loc2d[0] /= size[0];
450  td->loc2d[1] /= size[1];
451  }
452  }
453  }
454 }
455 
456 static void recalcData_uv(TransInfo *t)
457 {
458  SpaceImage *sima = t->area->spacedata.first;
459 
460  flushTransUVs(t);
461  if (sima->flag & SI_LIVE_UNWRAP) {
463  }
464 
466  if (tc->data_len) {
467  DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
468  }
469  }
470 }
471 
475  /* flags */ (T_EDIT | T_POINTS | T_2D_EDIT),
476  /* createTransData */ createTransUVs,
477  /* recalcData */ recalcData_uv,
478  /* special_aftertrans_update */ NULL,
479 };
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 BLI_assert(a)
Definition: BLI_assert.h:46
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
MINLINE void mul_v2_v2(float r[2], const float a[2])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ CD_MLOOPUV
@ SI_CLIP_UV
@ SI_LIVE_UNWRAP
@ SI_PIXEL_SNAP_CORNER
@ SI_PIXEL_SNAP_CENTER
@ SI_PIXEL_SNAP_DISABLED
@ V3D_AROUND_LOCAL_ORIGINS
bool ED_space_image_show_uvedit(const struct SpaceImage *sima, struct Object *obedit)
void ED_space_image_get_size(struct SpaceImage *sima, int *r_width, int *r_height)
Definition: image_edit.c:201
struct UvElementMap * BM_uv_element_map_create(struct BMesh *bm, const struct Scene *scene, bool uv_selected, bool use_winding, bool do_islands)
struct UvElement * BM_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l)
void BM_uv_element_map_free(struct UvElementMap *element_map)
void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit)
bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset)
void ED_uvedit_live_unwrap_re_solve(void)
bool uvedit_uv_select_test_ex(const struct ToolSettings *ts, struct BMLoop *l, 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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:541
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
#define BM_elem_flag_disable(ele, hflag)
Definition: bmesh_inline.h:15
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_elem_flag_test_bool(ele, hflag)
Definition: bmesh_inline.h:13
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:14
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_VERT
@ BM_LOOPS_OF_FACE
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.cc:446
ATTR_WARN_UNUSED_RESULT const void * element
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
SyclQueue * queue
int count
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static unsigned a[3]
Definition: RandGen.cpp:78
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
struct BMesh * bm
Definition: BKE_editmesh.h:40
struct BMVert * v
Definition: bmesh_class.h:153
struct BMFace * f
Definition: bmesh_class.h:171
int totloop
Definition: bmesh_class.h:297
CustomData ldata
Definition: bmesh_class.h:337
struct LinkNode * next
Definition: BLI_linklist.h:23
float * loc2d
float loc[3]
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
conversion and adaptation of different datablocks to a common struct.
static void uv_set_connectivity_distance(const ToolSettings *ts, BMesh *bm, float *dists, const float aspect[2])
#define TMP_LOOP_SELECT_TAG
static void flushTransUVs(TransInfo *t)
TransConvertTypeInfo TransConvertType_MeshUV
static void createTransUVs(bContext *C, TransInfo *t)
static void recalcData_uv(TransInfo *t)
static void UVsToTransData(const float aspect[2], TransData *td, TransData2D *td2d, float *uv, const float *center, float calc_dist, bool selected)
@ TD_SELECTED