Blender  V2.93
scanfill.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  * (uit traces) maart 95
19  */
20 
34 #include <limits.h>
35 #include <math.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include "MEM_guardedalloc.h"
41 
42 #include "BLI_listbase.h"
43 #include "BLI_math.h"
44 #include "BLI_memarena.h"
45 #include "BLI_utildefines.h"
46 
47 #include "BLI_scanfill.h" /* own include */
48 
49 #include "BLI_strict_flags.h"
50 
51 /* local types */
52 typedef struct PolyFill {
53  unsigned int edges, verts;
54  float min_xy[2], max_xy[2];
55  unsigned short nr;
56  bool f;
58 
59 typedef struct ScanFillVertLink {
63 
64 /* local funcs */
65 
66 #define SF_EPSILON 0.00003f
67 #define SF_EPSILON_SQ (SF_EPSILON * SF_EPSILON)
68 
69 /* ScanFillVert.status */
70 #define SF_VERT_NEW 0 /* all new verts have this flag set */
71 #define SF_VERT_AVAILABLE 1 /* available - in an edge */
72 #define SF_VERT_ZERO_LEN 2
73 
74 /* ScanFillEdge.status */
75 /* Optionally set ScanFillEdge f to this to mark original boundary edges.
76  * Only needed if there are internal diagonal edges passed to BLI_scanfill_calc. */
77 #define SF_EDGE_NEW 0 /* all new edges have this flag set */
78 // #define SF_EDGE_BOUNDARY 1 /* UNUSED */
79 #define SF_EDGE_INTERNAL 2 /* edge is created while scan-filling */
80 
81 /* PolyFill.status */
82 #define SF_POLY_NEW 0 /* all polys initialized to this */
83 #define SF_POLY_VALID 1 /* has at least 3 verts */
84 
85 /* **** FUNCTIONS FOR QSORT *************************** */
86 
87 static int vergscdata(const void *a1, const void *a2)
88 {
89  const ScanFillVertLink *x1 = a1, *x2 = a2;
90 
91  if (x1->vert->xy[1] < x2->vert->xy[1]) {
92  return 1;
93  }
94  if (x1->vert->xy[1] > x2->vert->xy[1]) {
95  return -1;
96  }
97  if (x1->vert->xy[0] > x2->vert->xy[0]) {
98  return 1;
99  }
100  if (x1->vert->xy[0] < x2->vert->xy[0]) {
101  return -1;
102  }
103 
104  return 0;
105 }
106 
107 static int vergpoly(const void *a1, const void *a2)
108 {
109  const PolyFill *x1 = a1, *x2 = a2;
110 
111  if (x1->min_xy[0] > x2->min_xy[0]) {
112  return 1;
113  }
114  if (x1->min_xy[0] < x2->min_xy[0]) {
115  return -1;
116  }
117  if (x1->min_xy[1] > x2->min_xy[1]) {
118  return 1;
119  }
120  if (x1->min_xy[1] < x2->min_xy[1]) {
121  return -1;
122  }
123 
124  return 0;
125 }
126 
127 /* **** FILL ROUTINES *************************** */
128 
130 {
131  ScanFillVert *sf_v;
132 
133  sf_v = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillVert));
134 
135  BLI_addtail(&sf_ctx->fillvertbase, sf_v);
136 
137  sf_v->tmp.p = NULL;
138  copy_v3_v3(sf_v->co, vec);
139 
140  /* just zero out the rest */
141  zero_v2(sf_v->xy);
142  sf_v->keyindex = 0;
143  sf_v->poly_nr = sf_ctx->poly_nr;
144  sf_v->edge_tot = 0;
145  sf_v->f = SF_VERT_NEW;
146  sf_v->user_flag = 0;
147 
148  return sf_v;
149 }
150 
152 {
153  ScanFillEdge *sf_ed;
154 
155  sf_ed = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillEdge));
156  BLI_addtail(&sf_ctx->filledgebase, sf_ed);
157 
158  sf_ed->v1 = v1;
159  sf_ed->v2 = v2;
160 
161  /* just zero out the rest */
162  sf_ed->poly_nr = sf_ctx->poly_nr;
163  sf_ed->f = SF_EDGE_NEW;
164  sf_ed->user_flag = 0;
165  sf_ed->tmp.c = 0;
166 
167  return sf_ed;
168 }
169 
170 static void addfillface(ScanFillContext *sf_ctx,
171  ScanFillVert *v1,
172  ScanFillVert *v2,
173  ScanFillVert *v3)
174 {
175  /* does not make edges */
176  ScanFillFace *sf_tri;
177 
178  sf_tri = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillFace));
179  BLI_addtail(&sf_ctx->fillfacebase, sf_tri);
180 
181  sf_tri->v1 = v1;
182  sf_tri->v2 = v2;
183  sf_tri->v3 = v3;
184 }
185 
186 static bool boundisect(PolyFill *pf2, PolyFill *pf1)
187 {
188  /* has pf2 been touched (intersected) by pf1 ? with bounding box */
189  /* test first if polys exist */
190 
191  if (pf1->edges == 0 || pf2->edges == 0) {
192  return false;
193  }
194 
195  if (pf2->max_xy[0] < pf1->min_xy[0]) {
196  return false;
197  }
198  if (pf2->max_xy[1] < pf1->min_xy[1]) {
199  return false;
200  }
201 
202  if (pf2->min_xy[0] > pf1->max_xy[0]) {
203  return false;
204  }
205  if (pf2->min_xy[1] > pf1->max_xy[1]) {
206  return false;
207  }
208 
209  /* join */
210  if (pf2->max_xy[0] < pf1->max_xy[0]) {
211  pf2->max_xy[0] = pf1->max_xy[0];
212  }
213  if (pf2->max_xy[1] < pf1->max_xy[1]) {
214  pf2->max_xy[1] = pf1->max_xy[1];
215  }
216 
217  if (pf2->min_xy[0] > pf1->min_xy[0]) {
218  pf2->min_xy[0] = pf1->min_xy[0];
219  }
220  if (pf2->min_xy[1] > pf1->min_xy[1]) {
221  pf2->min_xy[1] = pf1->min_xy[1];
222  }
223 
224  return true;
225 }
226 
227 /* add pf2 to pf1 */
228 static void mergepolysSimp(ScanFillContext *sf_ctx, PolyFill *pf1, PolyFill *pf2)
229 {
230  ScanFillVert *eve;
231  ScanFillEdge *eed;
232 
233  /* replace old poly numbers */
234  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
235  if (eve->poly_nr == pf2->nr) {
236  eve->poly_nr = pf1->nr;
237  }
238  }
239 
240  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
241  if (eed->poly_nr == pf2->nr) {
242  eed->poly_nr = pf1->nr;
243  }
244  }
245 
246  pf1->verts += pf2->verts;
247  pf1->edges += pf2->edges;
248  pf2->verts = pf2->edges = 0;
249  pf1->f = (pf1->f | pf2->f);
250 }
251 
252 static bool testedgeside(const float v1[2], const float v2[2], const float v3[2])
253 /* is v3 to the right of v1-v2 ? With exception: v3 == v1 || v3 == v2 */
254 {
255  float inp;
256 
257  inp = (v2[0] - v1[0]) * (v1[1] - v3[1]) + (v1[1] - v2[1]) * (v1[0] - v3[0]);
258 
259  if (inp < 0.0f) {
260  return false;
261  }
262  if (inp == 0.0f) {
263  if (v1[0] == v3[0] && v1[1] == v3[1]) {
264  return false;
265  }
266  if (v2[0] == v3[0] && v2[1] == v3[1]) {
267  return false;
268  }
269  }
270  return true;
271 }
272 
274 {
275  /* find first edge to the right of eed, and insert eed before that */
276  ScanFillEdge *ed;
277  float fac, fac1, x, y;
278 
279  if (sc->edge_first == NULL) {
280  sc->edge_first = sc->edge_last = eed;
281  eed->prev = eed->next = NULL;
282  return 1;
283  }
284 
285  x = eed->v1->xy[0];
286  y = eed->v1->xy[1];
287 
288  fac1 = eed->v2->xy[1] - y;
289  if (fac1 == 0.0f) {
290  fac1 = 1.0e10f * (eed->v2->xy[0] - x);
291  }
292  else {
293  fac1 = (x - eed->v2->xy[0]) / fac1;
294  }
295 
296  for (ed = sc->edge_first; ed; ed = ed->next) {
297 
298  if (ed->v2 == eed->v2) {
299  return false;
300  }
301 
302  fac = ed->v2->xy[1] - y;
303  if (fac == 0.0f) {
304  fac = 1.0e10f * (ed->v2->xy[0] - x);
305  }
306  else {
307  fac = (x - ed->v2->xy[0]) / fac;
308  }
309 
310  if (fac > fac1) {
311  break;
312  }
313  }
314  if (ed) {
315  BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed);
316  }
317  else {
318  BLI_addtail((ListBase *)&(sc->edge_first), eed);
319  }
320 
321  return true;
322 }
323 
325  ScanFillEdge *eed,
326  unsigned int len)
327 {
328  /* inserts edge at correct location in ScanFillVertLink list */
329  /* returns sc when edge already exists */
330  ScanFillVertLink *sc, scsearch;
331  ScanFillVert *eve;
332 
333  /* which vert is left-top? */
334  if (eed->v1->xy[1] == eed->v2->xy[1]) {
335  if (eed->v1->xy[0] > eed->v2->xy[0]) {
336  eve = eed->v1;
337  eed->v1 = eed->v2;
338  eed->v2 = eve;
339  }
340  }
341  else if (eed->v1->xy[1] < eed->v2->xy[1]) {
342  eve = eed->v1;
343  eed->v1 = eed->v2;
344  eed->v2 = eve;
345  }
346  /* find location in list */
347  scsearch.vert = eed->v1;
348  sc = (ScanFillVertLink *)bsearch(&scsearch, scdata, len, sizeof(ScanFillVertLink), vergscdata);
349 
350  if (UNLIKELY(sc == NULL)) {
351  printf("Error in search edge: %p\n", (void *)eed);
352  }
353  else if (addedgetoscanvert(sc, eed) == false) {
354  return sc;
355  }
356 
357  return NULL;
358 }
359 
360 static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
361 /* is eve inside boundbox eed */
362 {
363  float minx, maxx, miny, maxy;
364 
365  if (eed->v1->xy[0] < eed->v2->xy[0]) {
366  minx = eed->v1->xy[0];
367  maxx = eed->v2->xy[0];
368  }
369  else {
370  minx = eed->v2->xy[0];
371  maxx = eed->v1->xy[0];
372  }
373  if (eve->xy[0] >= minx && eve->xy[0] <= maxx) {
374  if (eed->v1->xy[1] < eed->v2->xy[1]) {
375  miny = eed->v1->xy[1];
376  maxy = eed->v2->xy[1];
377  }
378  else {
379  miny = eed->v2->xy[1];
380  maxy = eed->v1->xy[1];
381  }
382  if (eve->xy[1] >= miny && eve->xy[1] <= maxy) {
383  return true;
384  }
385  }
386  return false;
387 }
388 
390 {
391  /* only vertices with (->edge_tot == 1) are being tested for
392  * being close to an edge, if true insert */
393 
394  ScanFillVert *eve;
395  ScanFillEdge *eed, *ed1;
396 
397  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
398  if (eve->edge_tot == 1) {
399  /* find the edge which has vertex eve,
400  * note: we _know_ this will crash if 'ed1' becomes NULL
401  * but this will never happen. */
402  for (ed1 = sf_ctx->filledgebase.first; !(ed1->v1 == eve || ed1->v2 == eve);
403  ed1 = ed1->next) {
404  /* do nothing */
405  }
406 
407  if (ed1->v1 == eve) {
408  ed1->v1 = ed1->v2;
409  ed1->v2 = eve;
410  }
411 
412  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
413  if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) {
414  if (compare_v2v2(eve->xy, eed->v1->xy, SF_EPSILON)) {
415  ed1->v2 = eed->v1;
416  eed->v1->edge_tot++;
417  eve->edge_tot = 0;
418  break;
419  }
420  if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
421  ed1->v2 = eed->v2;
422  eed->v2->edge_tot++;
423  eve->edge_tot = 0;
424  break;
425  }
426 
427  if (boundinsideEV(eed, eve)) {
428  const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
429  if (dist < SF_EPSILON_SQ) {
430  /* new edge */
431  ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
432 
433  /* printf("fill: vertex near edge %x\n", eve); */
434  ed1->poly_nr = eed->poly_nr;
435  eed->v1 = eve;
436  eve->edge_tot = 3;
437  break;
438  }
439  }
440  }
441  }
442  }
443  }
444 }
445 
446 static void splitlist(ScanFillContext *sf_ctx,
447  ListBase *tempve,
448  ListBase *temped,
449  unsigned short nr)
450 {
451  /* everything is in templist, write only poly nr to fillist */
452  ScanFillVert *eve, *eve_next;
453  ScanFillEdge *eed, *eed_next;
454 
455  BLI_movelisttolist(tempve, &sf_ctx->fillvertbase);
456  BLI_movelisttolist(temped, &sf_ctx->filledgebase);
457 
458  for (eve = tempve->first; eve; eve = eve_next) {
459  eve_next = eve->next;
460  if (eve->poly_nr == nr) {
461  BLI_remlink(tempve, eve);
462  BLI_addtail(&sf_ctx->fillvertbase, eve);
463  }
464  }
465 
466  for (eed = temped->first; eed; eed = eed_next) {
467  eed_next = eed->next;
468  if (eed->poly_nr == nr) {
469  BLI_remlink(temped, eed);
470  BLI_addtail(&sf_ctx->filledgebase, eed);
471  }
472  }
473 }
474 
475 static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
476 {
477  ScanFillVertLink *scdata;
478  ScanFillVertLink *sc = NULL, *sc1;
479  ScanFillVert *eve, *v1, *v2, *v3;
480  ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3;
481  unsigned int a, b, verts, maxface, totface;
482  const unsigned short nr = pf->nr;
483  bool twoconnected = false;
484 
485  /* PRINTS */
486 #if 0
487  verts = pf->verts;
488  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
489  printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]);
490  }
491 
492  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
493  printf("edge: %x verts: %x %x\n", eed, eed->v1, eed->v2);
494  }
495 #endif
496 
497  /* STEP 0: remove zero sized edges */
499  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
500  if (equals_v2v2(eed->v1->xy, eed->v2->xy)) {
501  if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) {
502  eed->v2->f = SF_VERT_ZERO_LEN;
503  eed->v2->tmp.v = eed->v1->tmp.v;
504  }
505  else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) {
506  eed->v1->f = SF_VERT_ZERO_LEN;
507  eed->v1->tmp.v = eed->v2->tmp.v;
508  }
509  else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) {
510  eed->v1->tmp.v = eed->v2->tmp.v;
511  }
512  else {
513  eed->v2->f = SF_VERT_ZERO_LEN;
514  eed->v2->tmp.v = eed->v1;
515  }
516  }
517  }
518  }
519 
520  /* STEP 1: make using FillVert and FillEdge lists a sorted
521  * ScanFillVertLink list
522  */
523  sc = scdata = MEM_mallocN(sizeof(*scdata) * pf->verts, "Scanfill1");
524  verts = 0;
525  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
526  if (eve->poly_nr == nr) {
527  if (eve->f != SF_VERT_ZERO_LEN) {
528  verts++;
529  eve->f = SF_VERT_NEW; /* Flag for connect edges later on. */
530  sc->vert = eve;
531  sc->edge_first = sc->edge_last = NULL;
532  /* Note, debug print only will work for curve poly-fill, union is in use for mesh. */
533  /* if (even->tmp.v == NULL) eve->tmp.u = verts; */
534  sc++;
535  }
536  }
537  }
538 
539  qsort(scdata, verts, sizeof(ScanFillVertLink), vergscdata);
540 
542  for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
543  eed_next = eed->next;
544  BLI_remlink(&sf_ctx->filledgebase, eed);
545  /* This code is for handling zero-length edges that get
546  * collapsed in step 0. It was removed for some time to
547  * fix trunk bug T4544, so if that comes back, this code
548  * may need some work, or there will have to be a better
549  * fix to T4544.
550  *
551  * warning, this can hang on un-ordered edges, see: T33281.
552  * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons.
553  */
554  if (eed->v1->f == SF_VERT_ZERO_LEN) {
555  v1 = eed->v1;
556  while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) &&
557  (eed->v1 != eed->v1->tmp.v)) {
558  eed->v1 = eed->v1->tmp.v;
559  }
560  }
561  if (eed->v2->f == SF_VERT_ZERO_LEN) {
562  v2 = eed->v2;
563  while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) &&
564  (eed->v2 != eed->v2->tmp.v)) {
565  eed->v2 = eed->v2->tmp.v;
566  }
567  }
568  if (eed->v1 != eed->v2) {
569  addedgetoscanlist(scdata, eed, verts);
570  }
571  }
572  }
573  else {
574  for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
575  eed_next = eed->next;
576  BLI_remlink(&sf_ctx->filledgebase, eed);
577  if (eed->v1 != eed->v2) {
578  addedgetoscanlist(scdata, eed, verts);
579  }
580  }
581  }
582 #if 0
583  sc = sf_ctx->_scdata;
584  for (a = 0; a < verts; a++) {
585  printf("\nscvert: %x\n", sc->vert);
586  for (eed = sc->edge_first; eed; eed = eed->next) {
587  printf(" ed %x %x %x\n", eed, eed->v1, eed->v2);
588  }
589  sc++;
590  }
591 #endif
592 
593  /* STEP 2: FILL LOOP */
594 
595  if (pf->f == SF_POLY_NEW) {
596  twoconnected = true;
597  }
598 
599  /* (temporal) security: never much more faces than vertices */
600  totface = 0;
601  if (flag & BLI_SCANFILL_CALC_HOLES) {
602  maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
603  }
604  else {
605  /* when we don't calc any holes, we assume face is a non overlapping loop */
606  maxface = verts - 2;
607  }
608 
609  sc = scdata;
610  for (a = 0; a < verts; a++) {
611  /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */
612  /* Set connect-flags. */
613  for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
614  eed_next = ed1->next;
615  if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) {
616  BLI_remlink((ListBase *)&(sc->edge_first), ed1);
617  BLI_addtail(&sf_ctx->filledgebase, ed1);
618  if (ed1->v1->edge_tot > 1) {
619  ed1->v1->edge_tot--;
620  }
621  if (ed1->v2->edge_tot > 1) {
622  ed1->v2->edge_tot--;
623  }
624  }
625  else {
626  ed1->v2->f = SF_VERT_AVAILABLE;
627  }
628  }
629  while (sc->edge_first) { /* for as long there are edges */
630  ed1 = sc->edge_first;
631  ed2 = ed1->next;
632 
633  /* commented out... the ESC here delivers corrupted memory
634  * (and doesn't work during grab). */
635  /* if (callLocalInterruptCallBack()) break; */
636  if (totface >= maxface) {
637  /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */
638  a = verts;
639  break;
640  }
641  if (ed2 == NULL) {
642  sc->edge_first = sc->edge_last = NULL;
643  /* printf("just 1 edge to vert\n"); */
644  BLI_addtail(&sf_ctx->filledgebase, ed1);
645  ed1->v2->f = SF_VERT_NEW;
646  ed1->v1->edge_tot--;
647  ed1->v2->edge_tot--;
648  }
649  else {
650  /* test rest of vertices */
651  ScanFillVertLink *best_sc = NULL;
652  float angle_best_cos = -1.0f;
653  float miny;
654  bool firsttime = false;
655 
656  v1 = ed1->v2;
657  v2 = ed1->v1;
658  v3 = ed2->v2;
659 
660  /* this happens with a serial of overlapping edges */
661  if (v1 == v2 || v2 == v3) {
662  break;
663  }
664 
665  /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
666  miny = min_ff(v1->xy[1], v3->xy[1]);
667  sc1 = sc + 1;
668 
669  for (b = a + 1; b < verts; b++, sc1++) {
670  if (sc1->vert->f == SF_VERT_NEW) {
671  if (sc1->vert->xy[1] <= miny) {
672  break;
673  }
674  if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) {
675  if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) {
676  if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) {
677  /* point is in triangle */
678 
679  /* Because multiple points can be inside triangle
680  * (concave holes) we continue searching and pick the
681  * one with sharpest corner. */
682  if (best_sc == NULL) {
683  /* even without holes we need to keep checking T35861. */
684  best_sc = sc1;
685  }
686  else {
687  /* Prevent angle calc for the simple cases
688  * only 1 vertex is found. */
689  if (firsttime == false) {
690  angle_best_cos = cos_v2v2v2(v2->xy, v1->xy, best_sc->vert->xy);
691  firsttime = true;
692  }
693 
694  const float angle_test_cos = cos_v2v2v2(v2->xy, v1->xy, sc1->vert->xy);
695  if (angle_test_cos > angle_best_cos) {
696  best_sc = sc1;
697  angle_best_cos = angle_test_cos;
698  }
699  }
700  }
701  }
702  }
703  }
704  }
705 
706  if (best_sc) {
707  /* make new edge, and start over */
708  /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */
709 
710  ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert);
711  BLI_remlink(&sf_ctx->filledgebase, ed3);
712  BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed2, ed3);
713  ed3->v2->f = SF_VERT_AVAILABLE;
714  ed3->f = SF_EDGE_INTERNAL;
715  ed3->v1->edge_tot++;
716  ed3->v2->edge_tot++;
717  }
718  else {
719  /* new triangle */
720  /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
721  addfillface(sf_ctx, v1, v2, v3);
722  totface++;
723  BLI_remlink((ListBase *)&(sc->edge_first), ed1);
724  BLI_addtail(&sf_ctx->filledgebase, ed1);
725  ed1->v2->f = SF_VERT_NEW;
726  ed1->v1->edge_tot--;
727  ed1->v2->edge_tot--;
728  /* ed2 can be removed when it's a boundary edge */
729  if (((ed2->f == SF_EDGE_NEW) && twoconnected) /* || (ed2->f == SF_EDGE_BOUNDARY) */) {
730  BLI_remlink((ListBase *)&(sc->edge_first), ed2);
731  BLI_addtail(&sf_ctx->filledgebase, ed2);
732  ed2->v2->f = SF_VERT_NEW;
733  ed2->v1->edge_tot--;
734  ed2->v2->edge_tot--;
735  }
736 
737  /* new edge */
738  ed3 = BLI_scanfill_edge_add(sf_ctx, v1, v3);
739  BLI_remlink(&sf_ctx->filledgebase, ed3);
740  ed3->f = SF_EDGE_INTERNAL;
741  ed3->v1->edge_tot++;
742  ed3->v2->edge_tot++;
743 
744  /* printf("add new edge %x %x\n", v1, v3); */
745  sc1 = addedgetoscanlist(scdata, ed3, verts);
746 
747  if (sc1) { /* ed3 already exists: remove if a boundary */
748  /* printf("Edge exists\n"); */
749  ed3->v1->edge_tot--;
750  ed3->v2->edge_tot--;
751 
752  for (ed3 = sc1->edge_first; ed3; ed3 = ed3->next) {
753  if ((ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1)) {
754  if (twoconnected /* || (ed3->f == SF_EDGE_BOUNDARY) */) {
755  BLI_remlink((ListBase *)&(sc1->edge_first), ed3);
756  BLI_addtail(&sf_ctx->filledgebase, ed3);
757  ed3->v1->edge_tot--;
758  ed3->v2->edge_tot--;
759  }
760  break;
761  }
762  }
763  }
764  }
765  }
766 
767  /* test for loose edges */
768  for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
769  eed_next = ed1->next;
770  if (ed1->v1->edge_tot < 2 || ed1->v2->edge_tot < 2) {
771  BLI_remlink((ListBase *)&(sc->edge_first), ed1);
772  BLI_addtail(&sf_ctx->filledgebase, ed1);
773  if (ed1->v1->edge_tot > 1) {
774  ed1->v1->edge_tot--;
775  }
776  if (ed1->v2->edge_tot > 1) {
777  ed1->v2->edge_tot--;
778  }
779  }
780  }
781  /* done with loose edges */
782  }
783 
784  sc++;
785  }
786 
787  MEM_freeN(scdata);
788 
789  BLI_assert(totface <= maxface);
790 
791  return totface;
792 }
793 
795 {
796  memset(sf_ctx, 0, sizeof(*sf_ctx));
797  sf_ctx->poly_nr = SF_POLY_UNSET;
798  sf_ctx->arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
799 }
800 
802 {
803  memset(sf_ctx, 0, sizeof(*sf_ctx));
804  sf_ctx->poly_nr = SF_POLY_UNSET;
805  sf_ctx->arena = arena;
806 }
807 
809 {
810  BLI_memarena_free(sf_ctx->arena);
811  sf_ctx->arena = NULL;
812 
816 }
817 
819 {
820  BLI_memarena_clear(arena);
821  BLI_assert(sf_ctx->arena == arena);
822 
826 }
827 
828 unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
829 {
830  /*
831  * - fill works with its own lists, so create that first (no faces!)
832  * - for vertices, put in ->tmp.v the old pointer
833  * - struct elements xs en ys are not used here: don't hide stuff in it
834  * - edge flag ->f becomes 2 when it's a new edge
835  * - mode: & 1 is check for crossings, then create edges (TO DO )
836  * - returns number of triangle faces added.
837  */
838  ListBase tempve, temped;
839  ScanFillVert *eve;
840  ScanFillEdge *eed, *eed_next;
841  PolyFill *pflist, *pf;
842  float *min_xy_p, *max_xy_p;
843  unsigned int totfaces = 0; /* total faces added */
844  unsigned short a, c, poly = 0;
845  bool ok;
846  float mat_2d[3][3];
847 
848  BLI_assert(!nor_proj || len_squared_v3(nor_proj) > FLT_EPSILON);
849 
850 #ifdef DEBUG
851  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
852  /* these values used to be set,
853  * however they should always be zero'd so check instead */
854  BLI_assert(eve->f == 0);
855  BLI_assert(sf_ctx->poly_nr || eve->poly_nr == 0);
856  BLI_assert(eve->edge_tot == 0);
857  }
858 #endif
859 
860  /* first test vertices if they are in edges */
861  /* including resetting of flags */
862  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
863  BLI_assert(sf_ctx->poly_nr != SF_POLY_UNSET || eed->poly_nr == SF_POLY_UNSET);
864  eed->v1->f = SF_VERT_AVAILABLE;
865  eed->v2->f = SF_VERT_AVAILABLE;
866  }
867 
868  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
869  if (eve->f == SF_VERT_AVAILABLE) {
870  break;
871  }
872  }
873 
874  if (UNLIKELY(eve == NULL)) {
875  return 0;
876  }
877 
878  float n[3];
879 
880  if (nor_proj) {
881  copy_v3_v3(n, nor_proj);
882  }
883  else {
884  /* define projection: with 'best' normal */
885  /* Newell's Method */
886  /* Similar code used elsewhere, but this checks for double ups
887  * which historically this function supports so better not change */
888 
889  /* warning: this only gives stable direction with single polygons,
890  * ideally we'd calculate connectivity and each polys normal, see T41047 */
891  const float *v_prev;
892 
893  zero_v3(n);
894  eve = sf_ctx->fillvertbase.last;
895  v_prev = eve->co;
896 
897  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
898  if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
899  add_newell_cross_v3_v3v3(n, v_prev, eve->co);
900  v_prev = eve->co;
901  }
902  }
903  }
904 
905  if (UNLIKELY(normalize_v3(n) == 0.0f)) {
906  return 0;
907  }
908 
910 
911  /* STEP 1: COUNT POLYS */
912  if (sf_ctx->poly_nr != SF_POLY_UNSET) {
913  poly = (unsigned short)(sf_ctx->poly_nr + 1);
914  sf_ctx->poly_nr = SF_POLY_UNSET;
915  }
916 
917  if (flag & BLI_SCANFILL_CALC_POLYS && (poly == 0)) {
918  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
919  mul_v2_m3v3(eve->xy, mat_2d, eve->co);
920 
921  /* get first vertex with no poly number */
922  if (eve->poly_nr == SF_POLY_UNSET) {
923  unsigned int toggle = 0;
924  /* now a sort of select connected */
925  ok = true;
926  eve->poly_nr = poly;
927 
928  while (ok) {
929 
930  ok = false;
931 
932  toggle++;
933  for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last; eed;
934  eed = (toggle & 1) ? eed->next : eed->prev) {
935  if (eed->v1->poly_nr == SF_POLY_UNSET && eed->v2->poly_nr == poly) {
936  eed->v1->poly_nr = poly;
937  eed->poly_nr = poly;
938  ok = true;
939  }
940  else if (eed->v2->poly_nr == SF_POLY_UNSET && eed->v1->poly_nr == poly) {
941  eed->v2->poly_nr = poly;
942  eed->poly_nr = poly;
943  ok = true;
944  }
945  else if (eed->poly_nr == SF_POLY_UNSET) {
946  if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
947  eed->poly_nr = poly;
948  ok = true;
949  }
950  }
951  }
952  }
953 
954  poly++;
955  }
956  }
957  /* printf("amount of poly's: %d\n", poly); */
958  }
959  else if (poly) {
960  /* we pre-calculated poly_nr */
961  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
962  mul_v2_m3v3(eve->xy, mat_2d, eve->co);
963  }
964  }
965  else {
966  poly = 1;
967 
968  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
969  mul_v2_m3v3(eve->xy, mat_2d, eve->co);
970  eve->poly_nr = 0;
971  }
972 
973  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
974  eed->poly_nr = 0;
975  }
976  }
977 
978  /* STEP 2: remove loose edges and strings of edges */
979  if (flag & BLI_SCANFILL_CALC_LOOSE) {
980  unsigned int toggle = 0;
981  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
982  if (eed->v1->edge_tot++ > 250) {
983  break;
984  }
985  if (eed->v2->edge_tot++ > 250) {
986  break;
987  }
988  }
989  if (eed) {
990  /* otherwise it's impossible to be sure you can clear vertices */
991 #ifdef DEBUG
992  printf("No vertices with 250 edges allowed!\n");
993 #endif
994  return 0;
995  }
996 
997  /* does it only for vertices with (->edge_tot == 1) */
998  testvertexnearedge(sf_ctx);
999 
1000  ok = true;
1001  while (ok) {
1002  ok = false;
1003 
1004  toggle++;
1005  for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last; eed;
1006  eed = eed_next) {
1007  eed_next = (toggle & 1) ? eed->next : eed->prev;
1008  if (eed->v1->edge_tot == 1) {
1009  eed->v2->edge_tot--;
1010  BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
1011  BLI_remlink(&sf_ctx->filledgebase, eed);
1012  ok = true;
1013  }
1014  else if (eed->v2->edge_tot == 1) {
1015  eed->v1->edge_tot--;
1016  BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
1017  BLI_remlink(&sf_ctx->filledgebase, eed);
1018  ok = true;
1019  }
1020  }
1021  }
1022  if (BLI_listbase_is_empty(&sf_ctx->filledgebase)) {
1023  /* printf("All edges removed\n"); */
1024  return 0;
1025  }
1026  }
1027  else {
1028  /* skip checks for loose edges */
1029  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
1030  eed->v1->edge_tot++;
1031  eed->v2->edge_tot++;
1032  }
1033 #ifdef DEBUG
1034  /* ensure we're right! */
1035  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
1036  BLI_assert(eed->v1->edge_tot != 1);
1037  BLI_assert(eed->v2->edge_tot != 1);
1038  }
1039 #endif
1040  }
1041 
1042  /* CURRENT STATUS:
1043  * - eve->f :1 = available in edges
1044  * - eve->poly_nr :polynumber
1045  * - eve->edge_tot :amount of edges connected to vertex
1046  * - eve->tmp.v :store! original vertex number
1047  *
1048  * - eed->f :1 = boundary edge (optionally set by caller)
1049  * - eed->poly_nr :poly number
1050  */
1051 
1052  /* STEP 3: MAKE POLYFILL STRUCT */
1053  pflist = MEM_mallocN(sizeof(*pflist) * (size_t)poly, "edgefill");
1054  pf = pflist;
1055  for (a = 0; a < poly; a++) {
1056  pf->edges = pf->verts = 0;
1057  pf->min_xy[0] = pf->min_xy[1] = 1.0e20f;
1058  pf->max_xy[0] = pf->max_xy[1] = -1.0e20f;
1059  pf->f = SF_POLY_NEW;
1060  pf->nr = a;
1061  pf++;
1062  }
1063  for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
1064  pflist[eed->poly_nr].edges++;
1065  }
1066 
1067  for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
1068  pflist[eve->poly_nr].verts++;
1069  min_xy_p = pflist[eve->poly_nr].min_xy;
1070  max_xy_p = pflist[eve->poly_nr].max_xy;
1071 
1072  min_xy_p[0] = (min_xy_p[0]) < (eve->xy[0]) ? (min_xy_p[0]) : (eve->xy[0]);
1073  min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]);
1074  max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]);
1075  max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]);
1076  if (eve->edge_tot > 2) {
1077  pflist[eve->poly_nr].f = SF_POLY_VALID;
1078  }
1079  }
1080 
1081  /* STEP 4: FIND HOLES OR BOUNDS, JOIN THEM
1082  * ( bounds just to divide it in pieces for optimization,
1083  * the edgefill itself has good auto-hole detection)
1084  * WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */
1085 
1086  if ((flag & BLI_SCANFILL_CALC_HOLES) && (poly > 1)) {
1087  unsigned short *polycache, *pc;
1088 
1089  /* so, sort first */
1090  qsort(pflist, (size_t)poly, sizeof(PolyFill), vergpoly);
1091 
1092 #if 0
1093  pf = pflist;
1094  for (a = 0; a < poly; a++) {
1095  printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f);
1096  PRINT2(f, f, pf->min[0], pf->min[1]);
1097  pf++;
1098  }
1099 #endif
1100 
1101  polycache = pc = MEM_callocN(sizeof(*polycache) * (size_t)poly, "polycache");
1102  pf = pflist;
1103  for (a = 0; a < poly; a++, pf++) {
1104  for (c = (unsigned short)(a + 1); c < poly; c++) {
1105 
1106  /* if 'a' inside 'c': join (bbox too)
1107  * Careful: 'a' can also be inside another poly.
1108  */
1109  if (boundisect(pf, pflist + c)) {
1110  *pc = c;
1111  pc++;
1112  }
1113  /* only for optimize! */
1114  /* else if (pf->max_xy[0] < (pflist+c)->min[cox]) break; */
1115  }
1116  while (pc != polycache) {
1117  pc--;
1118  mergepolysSimp(sf_ctx, pf, pflist + *pc);
1119  }
1120  }
1121  MEM_freeN(polycache);
1122  }
1123 
1124 #if 0
1125  printf("after merge\n");
1126  pf = pflist;
1127  for (a = 0; a < poly; a++) {
1128  printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f);
1129  pf++;
1130  }
1131 #endif
1132 
1133  /* STEP 5: MAKE TRIANGLES */
1134 
1135  tempve.first = sf_ctx->fillvertbase.first;
1136  tempve.last = sf_ctx->fillvertbase.last;
1137  temped.first = sf_ctx->filledgebase.first;
1138  temped.last = sf_ctx->filledgebase.last;
1139  BLI_listbase_clear(&sf_ctx->fillvertbase);
1140  BLI_listbase_clear(&sf_ctx->filledgebase);
1141 
1142  pf = pflist;
1143  for (a = 0; a < poly; a++) {
1144  if (pf->edges > 1) {
1145  splitlist(sf_ctx, &tempve, &temped, pf->nr);
1146  totfaces += scanfill(sf_ctx, pf, flag);
1147  }
1148  pf++;
1149  }
1150  BLI_movelisttolist(&sf_ctx->fillvertbase, &tempve);
1151  BLI_movelisttolist(&sf_ctx->filledgebase, &temped);
1152 
1153  /* FREE */
1154 
1155  MEM_freeN(pflist);
1156 
1157  return totfaces;
1158 }
1159 
1160 unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
1161 {
1162  return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
1163 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
MINLINE float min_ff(float a, float b)
void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3])
Definition: math_geom.c:3772
float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2])
Definition: math_geom.c:324
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
Definition: math_matrix.c:921
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE bool compare_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
MINLINE bool compare_v2v2(const float a[2], const float b[2], const float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:470
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
MINLINE void zero_v3(float r[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:109
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:131
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:185
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:79
@ BLI_SCANFILL_CALC_LOOSE
Definition: BLI_scanfill.h:113
@ BLI_SCANFILL_CALC_POLYS
Definition: BLI_scanfill.h:106
@ BLI_SCANFILL_CALC_HOLES
Definition: BLI_scanfill.h:110
@ BLI_SCANFILL_CALC_REMOVE_DOUBLES
Definition: BLI_scanfill.h:103
#define SF_POLY_UNSET
Definition: BLI_scanfill.h:52
#define BLI_SCANFILL_ARENA_SIZE
Definition: BLI_scanfill.h:45
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
#define UNLIKELY(x)
#define LIKELY(x)
_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
_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 v1
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static float verts[][3]
#define pf2(_x, _i)
Prefetch 128.
Definition: gim_memory.h:50
#define pf(_x, _i)
Prefetch 64.
Definition: gim_memory.h:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2, ScanFillVert *v3)
Definition: scanfill.c:170
#define SF_POLY_VALID
Definition: scanfill.c:83
static bool testedgeside(const float v1[2], const float v2[2], const float v3[2])
Definition: scanfill.c:252
void BLI_scanfill_begin(ScanFillContext *sf_ctx)
Definition: scanfill.c:794
#define SF_VERT_NEW
Definition: scanfill.c:70
struct ScanFillVertLink ScanFillVertLink
void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena)
Definition: scanfill.c:818
#define SF_EPSILON
Definition: scanfill.c:66
ScanFillVert * BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3])
Definition: scanfill.c:129
static int vergpoly(const void *a1, const void *a2)
Definition: scanfill.c:107
static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
Definition: scanfill.c:475
void BLI_scanfill_end(ScanFillContext *sf_ctx)
Definition: scanfill.c:808
#define SF_EDGE_NEW
Definition: scanfill.c:77
struct PolyFill PolyFill
static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
Definition: scanfill.c:360
static void mergepolysSimp(ScanFillContext *sf_ctx, PolyFill *pf1, PolyFill *pf2)
Definition: scanfill.c:228
unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
Definition: scanfill.c:1160
static bool boundisect(PolyFill *pf2, PolyFill *pf1)
Definition: scanfill.c:186
#define SF_VERT_ZERO_LEN
Definition: scanfill.c:72
static int vergscdata(const void *a1, const void *a2)
Definition: scanfill.c:87
ScanFillEdge * BLI_scanfill_edge_add(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2)
Definition: scanfill.c:151
#define SF_EDGE_INTERNAL
Definition: scanfill.c:79
void BLI_scanfill_begin_arena(ScanFillContext *sf_ctx, MemArena *arena)
Definition: scanfill.c:801
#define SF_EPSILON_SQ
Definition: scanfill.c:67
#define SF_POLY_NEW
Definition: scanfill.c:82
unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
Definition: scanfill.c:828
static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
Definition: scanfill.c:273
static ScanFillVertLink * addedgetoscanlist(ScanFillVertLink *scdata, ScanFillEdge *eed, unsigned int len)
Definition: scanfill.c:324
static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, unsigned short nr)
Definition: scanfill.c:446
#define SF_VERT_AVAILABLE
Definition: scanfill.c:71
static void testvertexnearedge(ScanFillContext *sf_ctx)
Definition: scanfill.c:389
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
unsigned int verts
Definition: scanfill.c:53
bool f
Definition: scanfill.c:56
float max_xy[2]
Definition: scanfill.c:54
unsigned int edges
Definition: scanfill.c:53
float min_xy[2]
Definition: scanfill.c:54
unsigned short nr
Definition: scanfill.c:55
struct MemArena * arena
Definition: BLI_scanfill.h:42
ListBase fillvertbase
Definition: BLI_scanfill.h:33
ListBase filledgebase
Definition: BLI_scanfill.h:34
unsigned short poly_nr
Definition: BLI_scanfill.h:39
ListBase fillfacebase
Definition: BLI_scanfill.h:35
struct ScanFillEdge * prev
Definition: BLI_scanfill.h:78
unsigned short poly_nr
Definition: BLI_scanfill.h:80
union ScanFillEdge::@120 tmp
struct ScanFillVert * v1
Definition: BLI_scanfill.h:79
struct ScanFillVert * v2
Definition: BLI_scanfill.h:79
unsigned char c
Definition: BLI_scanfill.h:84
unsigned int f
Definition: BLI_scanfill.h:81
struct ScanFillEdge * next
Definition: BLI_scanfill.h:78
unsigned int user_flag
Definition: BLI_scanfill.h:82
struct ScanFillVert * v2
Definition: BLI_scanfill.h:90
struct ScanFillVert * v3
Definition: BLI_scanfill.h:90
struct ScanFillVert * v1
Definition: BLI_scanfill.h:90
float xy[2]
Definition: BLI_scanfill.h:65
unsigned short poly_nr
Definition: BLI_scanfill.h:68
unsigned int f
Definition: BLI_scanfill.h:72
struct ScanFillVert * next
Definition: BLI_scanfill.h:55
float co[3]
Definition: BLI_scanfill.h:63
struct ScanFillVert * v
Definition: BLI_scanfill.h:57
unsigned char edge_tot
Definition: BLI_scanfill.h:70
union ScanFillVert::@119 tmp
unsigned int user_flag
Definition: BLI_scanfill.h:74
unsigned int keyindex
Definition: BLI_scanfill.h:67
uint len