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