Blender  V3.3
bitmap_draw_2d.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 
10 #include <limits.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_bitmap_draw_2d.h"
15 
16 #include "BLI_math_base.h"
17 #include "BLI_sort.h"
18 #include "BLI_utildefines.h"
19 
20 #include "BLI_strict_flags.h"
21 
22 /* -------------------------------------------------------------------- */
26 void BLI_bitmap_draw_2d_line_v2v2i(const int p1[2],
27  const int p2[2],
28  bool (*callback)(int, int, void *),
29  void *user_data)
30 {
31  /* Bresenham's line algorithm. */
32  int x1 = p1[0];
33  int y1 = p1[1];
34  int x2 = p2[0];
35  int y2 = p2[1];
36 
37  if (callback(x1, y1, user_data) == 0) {
38  return;
39  }
40 
41  /* if x1 == x2 or y1 == y2, then it does not matter what we set here */
42  const int sign_x = (x2 > x1) ? 1 : -1;
43  const int sign_y = (y2 > y1) ? 1 : -1;
44 
45  const int delta_x = (sign_x == 1) ? (x2 - x1) : (x1 - x2);
46  const int delta_y = (sign_y == 1) ? (y2 - y1) : (y1 - y2);
47 
48  const int delta_x_step = delta_x * 2;
49  const int delta_y_step = delta_y * 2;
50 
51  if (delta_x >= delta_y) {
52  /* error may go below zero */
53  int error = delta_y_step - delta_x;
54 
55  while (x1 != x2) {
56  if (error >= 0) {
57  if (error || (sign_x == 1)) {
58  y1 += sign_y;
59  error -= delta_x_step;
60  }
61  /* else do nothing */
62  }
63  /* else do nothing */
64 
65  x1 += sign_x;
66  error += delta_y_step;
67 
68  if (callback(x1, y1, user_data) == 0) {
69  return;
70  }
71  }
72  }
73  else {
74  /* error may go below zero */
75  int error = delta_x_step - delta_y;
76 
77  while (y1 != y2) {
78  if (error >= 0) {
79  if (error || (sign_y == 1)) {
80  x1 += sign_x;
81  error -= delta_y_step;
82  }
83  /* else do nothing */
84  }
85  /* else do nothing */
86 
87  y1 += sign_y;
88  error += delta_x_step;
89 
90  if (callback(x1, y1, user_data) == 0) {
91  return;
92  }
93  }
94  }
95 }
96 
99 /* -------------------------------------------------------------------- */
119 /* Macros could be moved to a shared location. */
120 #define ORDERED_SWAP(ty, a, b) \
121  if (a > b) { \
122  SWAP(ty, a, b); \
123  } \
124  ((void)0)
125 
126 #define ORDERED_SWAP_BY(ty, a, b, by) \
127  if ((a by) > (b by)) { \
128  SWAP(ty, a, b); \
129  } \
130  ((void)0)
131 
132 #define ORDER_VARS2(ty, a, b) \
133  { \
134  ORDERED_SWAP(ty, a, b); \
135  } \
136  ((void)0)
137 
138 #define ORDER_VARS3_BY(ty, a, b, c, by) \
139  { \
140  ORDERED_SWAP_BY(ty, b, c, by); \
141  ORDERED_SWAP_BY(ty, a, c, by); \
142  ORDERED_SWAP_BY(ty, a, b, by); \
143  } \
144  ((void)0)
145 
146 static float inv_slope(const int a[2], const int b[2])
147 {
148  return ((float)(a[0] - b[0]) / (float)(a[1] - b[1]));
149 }
150 
158 static void draw_tri_flat_max(const int p[2],
159  const int max_y,
160  const float inv_slope1,
161  const float inv_slope2,
162  void (*callback)(int x, int x_end, int y, void *),
163  void *user_data)
164 {
165  float cur_x1 = (float)p[0];
166  float cur_x2 = cur_x1;
167  /* start-end inclusive */
168  const int min_y = p[1];
169  const int max_y_end = max_y + 1;
170  for (int scanline_y = min_y; scanline_y != max_y_end; scanline_y += 1) {
171  callback((int)cur_x1, 1 + (int)cur_x2, scanline_y, user_data);
172  cur_x1 += inv_slope1;
173  cur_x2 += inv_slope2;
174  }
175 }
176 
184 static void draw_tri_flat_min(const int p[2],
185  const int min_y,
186  const float inv_slope1,
187  const float inv_slope2,
188  void (*callback)(int x, int x_end, int y, void *),
189  void *user_data)
190 {
191  float cur_x1 = (float)p[0];
192  float cur_x2 = cur_x1;
193  /* start-end inclusive */
194  const int max_y = p[1];
195  const int min_y_end = min_y - 1;
196  for (int scanline_y = max_y; scanline_y != min_y_end; scanline_y -= 1) {
197  callback((int)cur_x1, 1 + (int)cur_x2, scanline_y, user_data);
198  cur_x1 -= inv_slope1;
199  cur_x2 -= inv_slope2;
200  }
201 }
202 
204  /* all 2d */
205  const int p1[2],
206  const int p2[2],
207  const int p3[2],
208  void (*callback)(int x, int x_end, int y, void *),
209  void *user_data)
210 {
211  /* At first sort the three vertices by y-coordinate ascending so p1 is the top-most vertex */
212  ORDER_VARS3_BY(const int *, p1, p2, p3, [1]);
213 
214  BLI_assert(p1[1] <= p2[1] && p2[1] <= p3[1]);
215 
216  /* Check for trivial case of bottom-flat triangle. */
217  if (p2[1] == p3[1]) {
218  float inv_slope1 = inv_slope(p2, p1);
219  float inv_slope2 = inv_slope(p3, p1);
220  ORDER_VARS2(float, inv_slope1, inv_slope2);
221  BLI_assert(!(inv_slope1 > inv_slope2));
222  draw_tri_flat_max(p1, p2[1], inv_slope1, inv_slope2, callback, user_data);
223  }
224  else if (p1[1] == p2[1]) {
225  /* Check for trivial case of top-flat triangle. */
226  float inv_slope1 = inv_slope(p3, p1);
227  float inv_slope2 = inv_slope(p3, p2);
228  ORDER_VARS2(float, inv_slope2, inv_slope1);
229  BLI_assert(!(inv_slope1 < inv_slope2));
231  p2[1] + 1, /* avoid overlap */
232  inv_slope1,
233  inv_slope2,
234  callback,
235  user_data);
236  }
237  else {
238  /* General case - split the triangle in a top-flat and bottom-flat one. */
239  const float inv_slope_p21 = inv_slope(p2, p1);
240  const float inv_slope_p31 = inv_slope(p3, p1);
241  const float inv_slope_p32 = inv_slope(p3, p2);
242 
243  float inv_slope1_max, inv_slope2_max;
244  float inv_slope2_min, inv_slope1_min;
245 
246  if (inv_slope_p21 < inv_slope_p31) {
247  inv_slope1_max = inv_slope_p21;
248  inv_slope2_max = inv_slope_p31;
249  inv_slope2_min = inv_slope_p31;
250  inv_slope1_min = inv_slope_p32;
251  }
252  else {
253  inv_slope1_max = inv_slope_p31;
254  inv_slope2_max = inv_slope_p21;
255  inv_slope2_min = inv_slope_p32;
256  inv_slope1_min = inv_slope_p31;
257  }
258 
259  draw_tri_flat_max(p1, p2[1], inv_slope1_max, inv_slope2_max, callback, user_data);
261  p2[1] + 1, /* avoid overlap */
262  inv_slope1_min,
263  inv_slope2_min,
264  callback,
265  user_data);
266  }
267 }
268 
269 #undef ORDERED_SWAP
270 #undef ORDERED_SWAP_BY
271 #undef ORDER_VARS2
272 #undef ORDER_VARS3_BY
273 
276 /* -------------------------------------------------------------------- */
280 /* sort edge-segments on y, then x axis */
281 static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void *verts_p)
282 {
283  const int(*verts)[2] = verts_p;
284  const int *a = a_p;
285  const int *b = b_p;
286  const int *co_a = verts[a[0]];
287  const int *co_b = verts[b[0]];
288 
289  if (co_a[1] < co_b[1]) {
290  return -1;
291  }
292  if (co_a[1] > co_b[1]) {
293  return 1;
294  }
295  if (co_a[0] < co_b[0]) {
296  return -1;
297  }
298  if (co_a[0] > co_b[0]) {
299  return 1;
300  }
301  /* co_a & co_b are identical, use the line closest to the x-min */
302  const int *co = co_a;
303  co_a = verts[a[1]];
304  co_b = verts[b[1]];
305  int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1])));
306  if (ord > 0) {
307  return -1;
308  }
309  if (ord < 0) {
310  return 1;
311  }
312  return 0;
313 }
314 
315 void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin,
316  const int ymin,
317  const int xmax,
318  const int ymax,
319  const int verts[][2],
320  const int verts_len,
321  void (*callback)(int x, int x_end, int y, void *),
322  void *user_data)
323 {
324  /* Originally by Darel Rex Finley, 2007.
325  * Optimized by Campbell Barton, 2016 to track sorted intersections. */
326 
327  int(*span_y)[2] = MEM_mallocN(sizeof(*span_y) * (size_t)verts_len, __func__);
328  int span_y_len = 0;
329 
330  for (int i_curr = 0, i_prev = verts_len - 1; i_curr < verts_len; i_prev = i_curr++) {
331  const int *co_prev = verts[i_prev];
332  const int *co_curr = verts[i_curr];
333 
334  if (co_prev[1] != co_curr[1]) {
335  /* Any segments entirely above or below the area of interest can be skipped. */
336  if ((min_ii(co_prev[1], co_curr[1]) >= ymax) || (max_ii(co_prev[1], co_curr[1]) < ymin)) {
337  continue;
338  }
339 
340  int *s = span_y[span_y_len++];
341  if (co_prev[1] < co_curr[1]) {
342  s[0] = i_prev;
343  s[1] = i_curr;
344  }
345  else {
346  s[0] = i_curr;
347  s[1] = i_prev;
348  }
349  }
350  }
351 
352  BLI_qsort_r(
353  span_y, (size_t)span_y_len, sizeof(*span_y), draw_poly_v2i_n__span_y_sort, (void *)verts);
354 
355  struct NodeX {
356  int span_y_index;
357  int x;
358  } *node_x = MEM_mallocN(sizeof(*node_x) * (size_t)(verts_len + 1), __func__);
359  int node_x_len = 0;
360 
361  int span_y_index = 0;
362  if (span_y_len != 0 && verts[span_y[0][0]][1] < ymin) {
363  while ((span_y_index < span_y_len) && (verts[span_y[span_y_index][0]][1] < ymin)) {
364  BLI_assert(verts[span_y[span_y_index][0]][1] < verts[span_y[span_y_index][1]][1]);
365  if (verts[span_y[span_y_index][1]][1] >= ymin) {
366  struct NodeX *n = &node_x[node_x_len++];
367  n->span_y_index = span_y_index;
368  }
369  span_y_index += 1;
370  }
371  }
372 
373  /* Loop through the rows of the image. */
374  for (int pixel_y = ymin; pixel_y < ymax; pixel_y++) {
375  bool is_sorted = true;
376  bool do_remove = false;
377 
378  for (int i = 0, x_ix_prev = INT_MIN; i < node_x_len; i++) {
379  struct NodeX *n = &node_x[i];
380  const int *s = span_y[n->span_y_index];
381  const int *co_prev = verts[s[0]];
382  const int *co_curr = verts[s[1]];
383 
384  BLI_assert(co_prev[1] < pixel_y && co_curr[1] >= pixel_y);
385 
386  const double x = (co_prev[0] - co_curr[0]);
387  const double y = (co_prev[1] - co_curr[1]);
388  const double y_px = (pixel_y - co_curr[1]);
389  const int x_ix = (int)((double)co_curr[0] + ((y_px / y) * x));
390  n->x = x_ix;
391 
392  if (is_sorted && (x_ix_prev > x_ix)) {
393  is_sorted = false;
394  }
395  if (do_remove == false && co_curr[1] == pixel_y) {
396  do_remove = true;
397  }
398  x_ix_prev = x_ix;
399  }
400 
401  /* Sort the nodes, via a simple "Bubble" sort. */
402  if (is_sorted == false) {
403  int i = 0;
404  const int node_x_end = node_x_len - 1;
405  while (i < node_x_end) {
406  if (node_x[i].x > node_x[i + 1].x) {
407  SWAP(struct NodeX, node_x[i], node_x[i + 1]);
408  if (i != 0) {
409  i -= 1;
410  }
411  }
412  else {
413  i += 1;
414  }
415  }
416  }
417 
418  /* Fill the pixels between node pairs. */
419  for (int i = 0; i < node_x_len; i += 2) {
420  int x_src = node_x[i].x;
421  int x_dst = node_x[i + 1].x;
422 
423  if (x_src >= xmax) {
424  break;
425  }
426 
427  if (x_dst > xmin) {
428  if (x_src < xmin) {
429  x_src = xmin;
430  }
431  if (x_dst > xmax) {
432  x_dst = xmax;
433  }
434  /* for single call per x-span */
435  if (x_src < x_dst) {
436  callback(x_src - xmin, x_dst - xmin, pixel_y - ymin, user_data);
437  }
438  }
439  }
440 
441  /* Clear finalized nodes in one pass, only when needed
442  * (avoids excessive array-resizing). */
443  if (do_remove == true) {
444  int i_dst = 0;
445  for (int i_src = 0; i_src < node_x_len; i_src += 1) {
446  const int *s = span_y[node_x[i_src].span_y_index];
447  const int *co = verts[s[1]];
448  if (co[1] != pixel_y) {
449  if (i_dst != i_src) {
450  /* x is initialized for the next pixel_y (no need to adjust here) */
451  node_x[i_dst].span_y_index = node_x[i_src].span_y_index;
452  }
453  i_dst += 1;
454  }
455  }
456  node_x_len = i_dst;
457  }
458 
459  /* Scan for new x-nodes */
460  while ((span_y_index < span_y_len) && (verts[span_y[span_y_index][0]][1] == pixel_y)) {
461  /* NOTE: node_x these are just added at the end,
462  * not ideal but sorting once will resolve. */
463 
464  /* x is initialized for the next pixel_y */
465  struct NodeX *n = &node_x[node_x_len++];
466  n->span_y_index = span_y_index;
467  span_y_index += 1;
468  }
469  }
470 
471  MEM_freeN(span_y);
472  MEM_freeN(node_x);
473 }
474 
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
Definition: sort.c:79
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
#define SWAP(type, a, b)
_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 y1
_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
_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 x2
Read Guarded memory(de)allocation.
void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin, const int ymin, const int xmax, const int ymax, const int verts[][2], const int verts_len, void(*callback)(int x, int x_end, int y, void *), void *user_data)
static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void *verts_p)
static float inv_slope(const int a[2], const int b[2])
void BLI_bitmap_draw_2d_line_v2v2i(const int p1[2], const int p2[2], bool(*callback)(int, int, void *), void *user_data)
void BLI_bitmap_draw_2d_tri_v2i(const int p1[2], const int p2[2], const int p3[2], void(*callback)(int x, int x_end, int y, void *), void *user_data)
static void draw_tri_flat_max(const int p[2], const int max_y, const float inv_slope1, const float inv_slope2, void(*callback)(int x, int x_end, int y, void *), void *user_data)
static void draw_tri_flat_min(const int p[2], const int min_y, const float inv_slope1, const float inv_slope2, void(*callback)(int x, int x_end, int y, void *), void *user_data)
#define ORDER_VARS3_BY(ty, a, b, c, by)
#define ORDER_VARS2(ty, a, b)
void * user_data
DEGForeachIDComponentCallback callback
static float verts[][3]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static void error(const char *str)
Definition: meshlaplacian.c:51
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)