112 #define INVERT_TRISTRIPS FALSE
121 #define EQ(a, b) (fabs((a) - (b)) <= GPC_EPSILON)
123 #define PREV_INDEX(i, n) ((i - 1 + n) % n)
124 #define NEXT_INDEX(i, n) ((i + 1 ) % n)
126 #define OPTIMAL(v, i, n) ((v[PREV_INDEX(i, n)].y != v[i].y) || \
127 (v[NEXT_INDEX(i, n)].y != v[i].y))
129 #define FWD_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y >= v[i].vertex.y) \
130 && (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y))
132 #define NOT_FMAX(v, i, n) (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y)
134 #define REV_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) \
135 && (v[NEXT_INDEX(i, n)].vertex.y >= v[i].vertex.y))
137 #define NOT_RMAX(v, i, n) (v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y)
139 #define VERTEX(e,p,s,x,y) {add_vertex(&((e)->outp[(p)]->v[(s)]), x, y); \
140 (e)->outp[(p)]->active++;}
142 #define P_EDGE(d,e,p,i,j) {(d)= (e); \
143 do {(d)= (d)->prev;} while (!(d)->outp[(p)]); \
144 (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);}
146 #define N_EDGE(d,e,p,i,j) {(d)= (e); \
147 do {(d)= (d)->next;} while (!(d)->outp[(p)]); \
148 (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);}
150 #define MALLOC(p, b, s, t) {if ((b) > 0) { \
151 p= (t*)malloc(b); if (!(p)) { \
152 fprintf(stderr, "gpc malloc failure: %s\n", s); \
153 exit(0);}} else p= NULL;}
155 #define FREE(p) {if (p) {free(p); (p)= NULL;}}
221 : prev(0),next(0),pred(0),succ(0),next_bound(0)
235 bundle_state bstate[2];
247 lmt_node() : first_bound(0),next(0) {}
292 const h_state next_h_state[3][6]=
296 {BH, TH, TH, BH, NH, NH},
297 {NH, NH, NH, NH, TH, TH},
298 {NH, NH, NH, NH, BH, BH}
308 static void reset_it(
it_node **it)
321 static void reset_lmt(
lmt_node **lmt)
346 if (e[0].bot.x < (*b)[0].bot.x)
351 (*b)->next_bound= existing_bound;
355 if (e[0].bot.x == (*b)[0].bot.x)
358 if (e[0].dx < (*b)[0].dx)
363 (*b)->next_bound= existing_bound;
368 insert_bound(&((*b)->next_bound), e);
374 insert_bound(&((*b)->next_bound), e);
390 (*lmt)->first_bound= NULL;
392 return &((*lmt)->first_bound);
401 (*lmt)->first_bound= NULL;
402 (*lmt)->next= existing_node;
403 return &((*lmt)->first_bound);
408 return bound_list(&((*lmt)->next), y);
411 return &((*lmt)->first_bound);
415 static void add_to_sbtree(
int *entries,
sb_tree **sbtree,
double y)
420 MALLOC(*sbtree,
sizeof(
sb_tree),
"scanbeam tree insertion",
sb_tree);
422 (*sbtree)->less= NULL;
423 (*sbtree)->more= NULL;
428 if ((*sbtree)->y > y)
431 add_to_sbtree(entries, &((*sbtree)->less), y);
435 if ((*sbtree)->y < y)
438 add_to_sbtree(entries, &((*sbtree)->more), y);
445 static void build_sbt(
int *entries,
double *sbt,
sb_tree *sbtree)
448 build_sbt(entries, sbt, sbtree->less);
449 sbt[*entries]= sbtree->y;
452 build_sbt(entries, sbt, sbtree->more);
456 static void free_sbtree(
sb_tree **sbtree)
460 free_sbtree(&((*sbtree)->less));
461 free_sbtree(&((*sbtree)->more));
472 if (c.num_vertices > 0)
474 for (i= 0; i < c.num_vertices; i++)
476 if (OPTIMAL(c.vertex, i, c.num_vertices))
487 int c, i,
min,
max, num_edges, v, num_vertices;
488 int total_vertices= 0, e_index=0;
491 for (c= 0; c < p->num_contours; c++)
492 total_vertices+= count_optimal_vertices(p->contour[c]);
495 MALLOC(edge_table, total_vertices *
sizeof(
edge_node),
"edge table creation",
edge_node);
496 for(
int k=0;k<total_vertices;++k)
499 for (c= 0; c < p->num_contours; c++)
501 if (p->contour[c].num_vertices < 0)
504 p->contour[c].num_vertices= -p->contour[c].num_vertices;
510 for (i= 0; i < p->contour[c].num_vertices; i++)
511 if (OPTIMAL(p->contour[c].vertex, i, p->contour[c].num_vertices))
513 edge_table[num_vertices].vertex.x= p->contour[c].vertex[i].x;
514 edge_table[num_vertices].vertex.y= p->contour[c].vertex[i].y;
517 add_to_sbtree(sbt_entries, sbtree,
518 edge_table[num_vertices].vertex.y);
524 for (min= 0; min < num_vertices; min++)
527 if (FWD_MIN(edge_table, min, num_vertices))
531 max= NEXT_INDEX(min, num_vertices);
532 while (NOT_FMAX(edge_table, max, num_vertices))
535 max= NEXT_INDEX(max, num_vertices);
539 e= &edge_table[e_index];
542 e[0].bstate[BELOW]= UNBUNDLED;
543 e[0].bundle[BELOW][CLIP]= FALSE;
544 e[0].bundle[BELOW][SUBJ]= FALSE;
545 for (i= 0; i < num_edges; i++)
547 e[i].xb= edge_table[v].vertex.x;
548 e[i].bot.x= edge_table[v].vertex.x;
549 e[i].bot.y= edge_table[v].vertex.y;
551 v= NEXT_INDEX(v, num_vertices);
553 e[i].top.x= edge_table[v].vertex.x;
554 e[i].top.y= edge_table[v].vertex.y;
555 e[i].dx= (edge_table[v].vertex.x - e[i].bot.x) /
556 (e[i].top.y - e[i].bot.y);
558 e[i].outp[ABOVE]= NULL;
559 e[i].outp[BELOW]= NULL;
562 e[i].succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
564 e[i].pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
565 e[i].next_bound= NULL;
566 e[i].bside[CLIP]= (op == GPC_DIFF) ? RIGHT : LEFT;
567 e[i].bside[SUBJ]= LEFT;
569 insert_bound(bound_list(lmt, edge_table[min].vertex.y), e);
574 for (min= 0; min < num_vertices; min++)
577 if (REV_MIN(edge_table, min, num_vertices))
581 max= PREV_INDEX(min, num_vertices);
582 while (NOT_RMAX(edge_table, max, num_vertices))
585 max= PREV_INDEX(max, num_vertices);
589 e= &edge_table[e_index];
592 e[0].bstate[BELOW]= UNBUNDLED;
593 e[0].bundle[BELOW][CLIP]= FALSE;
594 e[0].bundle[BELOW][SUBJ]= FALSE;
595 for (i= 0; i < num_edges; i++)
597 e[i].xb= edge_table[v].vertex.x;
598 e[i].bot.x= edge_table[v].vertex.x;
599 e[i].bot.y= edge_table[v].vertex.y;
601 v= PREV_INDEX(v, num_vertices);
603 e[i].top.x= edge_table[v].vertex.x;
604 e[i].top.y= edge_table[v].vertex.y;
605 e[i].dx= (edge_table[v].vertex.x - e[i].bot.x) /
606 (e[i].top.y - e[i].bot.y);
608 e[i].outp[ABOVE]= NULL;
609 e[i].outp[BELOW]= NULL;
612 e[i].succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
614 e[i].pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
615 e[i].next_bound= NULL;
616 e[i].bside[CLIP]= (op == GPC_DIFF) ? RIGHT : LEFT;
617 e[i].bside[SUBJ]= LEFT;
619 insert_bound(bound_list(lmt, edge_table[min].vertex.y), e);
640 if (edge->xb < (*aet)->xb)
650 if (edge->xb == (*aet)->xb)
653 if (edge->dx < (*aet)->dx)
664 add_edge_to_aet(&((*aet)->next), edge, *aet);
670 add_edge_to_aet(&((*aet)->next), edge, *aet);
694 if ((*it)->point.y > y)
703 (*it)->next= existing_node;
707 add_intersection(&((*it)->next), edge0, edge1, x, y);
730 den= ((*st)->xt - (*st)->xb) - (edge->xt - edge->xb);
733 if ((edge->xt >= (*st)->xt) || (edge->dx == (*st)->dx) ||
734 (fabs(den) <= DBL_EPSILON))
743 (*st)->prev= existing_node;
748 r= (edge->xb - (*st)->xb) / den;
749 x= (*st)->xb + r * ((*st)->xt - (*st)->xb);
753 add_intersection(it, (*st)->edge, edge, x, y);
756 add_st_edge(&((*st)->prev), it, edge, dy);
762 static void build_intersection_table(
it_node **it,
edge_node *aet,
double dy)
772 for (edge= aet; edge; edge= edge->next)
774 if ((edge->bstate[ABOVE] == BUNDLE_HEAD) ||
775 edge->bundle[ABOVE][CLIP] || edge->bundle[ABOVE][SUBJ])
776 add_st_edge(&st, it, edge, dy);
793 for (nc= 0; polygon; polygon= polygon->next)
798 for (v= polygon->proxy->v[LEFT]; v; v= v->next)
810 for (v= polygon->proxy->v[LEFT]; v; v= nextv)
822 static void add_left(
polygon_node *p,
double x,
double y)
826 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
834 nv->next= p->proxy->v[LEFT];
837 p->proxy->v[LEFT]= nv;
845 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
846 if(q == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
849 q->proxy->hole= TRUE;
851 if (p->proxy != q->proxy)
854 p->proxy->v[RIGHT]->next= q->proxy->v[LEFT];
855 q->proxy->v[LEFT]= p->proxy->v[LEFT];
859 for (target= p->proxy; list; list= list->next)
861 if (list->proxy == target)
864 list->proxy= q->proxy;
871 static void add_right(
polygon_node *p,
double x,
double y)
875 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
884 p->proxy->v[RIGHT]->next= nv;
887 p->proxy->v[RIGHT]= nv;
895 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
896 if(q == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
900 q->proxy->hole= FALSE;
902 if (p->proxy != q->proxy)
905 q->proxy->v[RIGHT]->next= p->proxy->v[LEFT];
906 q->proxy->v[RIGHT]= p->proxy->v[RIGHT];
909 for (target= p->proxy; list; list= list->next)
911 if (list->proxy == target)
914 list->proxy= q->proxy;
943 (*p)->next= existing_min;
950 edge->outp[ABOVE]= *p;
958 for (total= 0; tn; tn= tn->next)
965 static void add_vertex(
vertex_node **t,
double x,
double y)
976 add_vertex(&((*t)->next), x, y);
989 (*tn)->v[LEFT]= NULL;
990 (*tn)->v[RIGHT]= NULL;
992 add_vertex(&((*tn)->v[LEFT]), x, y);
993 edge->outp[ABOVE]= *tn;
997 new_tristrip(&((*tn)->next), edge, x, y);
1006 MALLOC(box, p->num_contours *
sizeof(
bbox),
"Bounding box creation",
bbox);
1009 for (c= 0; c < p->num_contours; c++)
1012 box[c].xmin= DBL_MAX;
1013 box[c].ymin= DBL_MAX;
1014 box[c].xmax= -DBL_MAX;
1015 box[c].ymax= -DBL_MAX;
1017 for (v= 0; v < p->contour[c].num_vertices; v++)
1020 if (p->contour[c].vertex[v].x < box[c].xmin)
1021 box[c].xmin= p->contour[c].vertex[v].x;
1022 if (p->contour[c].vertex[v].y < box[c].ymin)
1023 box[c].ymin= p->contour[c].vertex[v].y;
1024 if (p->contour[c].vertex[v].x > box[c].xmax)
1025 box[c].xmax= p->contour[c].vertex[v].x;
1026 if (p->contour[c].vertex[v].y > box[c].ymax)
1027 box[c].ymax= p->contour[c].vertex[v].y;
1036 bbox *s_bbox, *c_bbox;
1037 int s, c, *o_table, overlap;
1039 s_bbox= create_contour_bboxes(subj);
1040 c_bbox= create_contour_bboxes(clip);
1042 MALLOC(o_table, subj->num_contours * clip->num_contours *
sizeof(
int),
1043 "overlap table creation",
int);
1046 for (s= 0; s < subj->num_contours; s++)
1047 for (c= 0; c < clip->num_contours; c++)
1048 o_table[c * subj->num_contours + s]=
1049 (!((s_bbox[s].xmax < c_bbox[c].xmin) ||
1050 (s_bbox[s].xmin > c_bbox[c].xmax))) &&
1051 (!((s_bbox[s].ymax < c_bbox[c].ymin) ||
1052 (s_bbox[s].ymin > c_bbox[c].ymax)));
1055 for (c= 0; c < clip->num_contours; c++)
1058 for (s= 0; (!overlap) && (s < subj->num_contours); s++)
1059 overlap= o_table[c * subj->num_contours + s];
1063 clip->contour[c].num_vertices = -clip->contour[c].num_vertices;
1069 for (s= 0; s < subj->num_contours; s++)
1072 for (c= 0; (!overlap) && (c < clip->num_contours); c++)
1073 overlap= o_table[c * subj->num_contours + s];
1077 subj->contour[s].num_vertices = -subj->contour[s].num_vertices;
1097 for (c= 0; c < p->num_contours; c++)
1098 FREE(p->contour[c].vertex);
1132 void gpc_write_polygon(FILE *fp,
int write_hole_flags,
gpc_polygon *p)
1136 fprintf(fp,
"%d\n", p->num_contours);
1137 for (c= 0; c < p->num_contours; c++)
1139 fprintf(fp,
"%d\n", p->contour[c].num_vertices);
1141 if (write_hole_flags)
1142 fprintf(fp,
"%d\n", p->hole[c]);
1144 for (v= 0; v < p->contour[c].num_vertices; v++)
1145 fprintf(fp,
"% .*lf % .*lf\n",
1146 DBL_DIG, p->contour[c].vertex[v].x,
1147 DBL_DIG, p->contour[c].vertex[v].y);
1154 int *extended_hole, c, v;
1158 MALLOC(extended_hole, (p->num_contours + 1)
1159 *
sizeof(
int),
"contour hole addition",
int);
1162 MALLOC(extended_contour, (p->num_contours + 1)
1166 for (c= 0; c < p->num_contours; c++)
1168 extended_hole[c]= p->hole[c];
1169 extended_contour[c]= p->contour[c];
1174 extended_hole[c]= hole;
1175 extended_contour[c].num_vertices= new_contour->num_vertices;
1176 MALLOC(extended_contour[c].vertex, new_contour->num_vertices
1178 for (v= 0; v < new_contour->num_vertices; v++)
1179 extended_contour[c].vertex[v]= new_contour->vertex[v];
1187 p->hole= extended_hole;
1188 p->contour= extended_contour;
1196 it_node *it= NULL, *intersect=0;
1197 edge_node *edge=0, *prev_edge=0, *next_edge=0, *succ_edge=0, *e0=0, *e1=0;
1198 edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL;
1200 polygon_node *out_poly= NULL, *p=0, *q=0, *poly=0, *npoly=0, *cf= NULL;
1203 int in[2], exists[2], parity[2]= {LEFT, LEFT};
1204 int c, v, contributing=0, search, scanbeam= 0, sbt_entries= 0;
1205 int vclass=0, bl=0, br=0, tl=0, tr=0;
1206 double *sbt= NULL, xb, px, yb, yt=0.0, dy=0.0, ix, iy;
1209 if (((subj->num_contours == 0) && (clip->num_contours == 0))
1210 || ((subj->num_contours == 0) && ((op == GPC_INT) || (op == GPC_DIFF)))
1211 || ((clip->num_contours == 0) && (op == GPC_INT)))
1213 result->num_contours= 0;
1215 result->contour= NULL;
1220 if (((op == GPC_INT) || (op == GPC_DIFF))
1221 && (subj->num_contours > 0) && (clip->num_contours > 0))
1222 minimax_test(subj, clip, op);
1225 if (subj->num_contours > 0)
1226 s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj, SUBJ, op);
1227 if (clip->num_contours > 0)
1228 c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip, CLIP, op);
1233 result->num_contours= 0;
1235 result->contour= NULL;
1243 MALLOC(sbt, sbt_entries *
sizeof(
double),
"sbt creation",
double);
1244 build_sbt(&scanbeam, sbt, sbtree);
1246 free_sbtree(&sbtree);
1250 gpc_free_polygon(subj);
1252 gpc_free_polygon(clip);
1256 parity[CLIP]= RIGHT;
1261 while (scanbeam < sbt_entries)
1264 yb= sbt[scanbeam++];
1265 if (scanbeam < sbt_entries)
1276 if (local_min->y == yb)
1279 for (edge= local_min->first_bound; edge; edge= edge->next_bound)
1280 add_edge_to_aet(&aet, edge, NULL);
1282 local_min= local_min->next;
1294 aet->bundle[ABOVE][ aet->type]= (aet->top.y != yb);
1295 aet->bundle[ABOVE][!aet->type]= FALSE;
1296 aet->bstate[ABOVE]= UNBUNDLED;
1298 for (next_edge= aet->next; next_edge; next_edge= next_edge->next)
1301 next_edge->bundle[ABOVE][ next_edge->type]= (next_edge->top.y != yb);
1302 next_edge->bundle[ABOVE][!next_edge->type]= FALSE;
1303 next_edge->bstate[ABOVE]= UNBUNDLED;
1306 if (next_edge->bundle[ABOVE][next_edge->type])
1308 if (EQ(e0->xb, next_edge->xb) && EQ(e0->dx, next_edge->dx)
1309 && (e0->top.y != yb))
1311 next_edge->bundle[ABOVE][ next_edge->type]^=
1312 e0->bundle[ABOVE][ next_edge->type];
1313 next_edge->bundle[ABOVE][!next_edge->type]=
1314 e0->bundle[ABOVE][!next_edge->type];
1315 next_edge->bstate[ABOVE]= BUNDLE_HEAD;
1316 e0->bundle[ABOVE][CLIP]= FALSE;
1317 e0->bundle[ABOVE][SUBJ]= FALSE;
1318 e0->bstate[ABOVE]= BUNDLE_TAIL;
1328 for (edge= aet; edge; edge= edge->next)
1330 exists[CLIP]= edge->bundle[ABOVE][CLIP] +
1331 (edge->bundle[BELOW][CLIP] << 1);
1332 exists[SUBJ]= edge->bundle[ABOVE][SUBJ] +
1333 (edge->bundle[BELOW][SUBJ] << 1);
1335 if (exists[CLIP] || exists[SUBJ])
1338 edge->bside[CLIP]= parity[CLIP];
1339 edge->bside[SUBJ]= parity[SUBJ];
1346 contributing= (exists[CLIP] && (parity[SUBJ] || horiz[SUBJ]))
1347 || (exists[SUBJ] && (parity[CLIP] || horiz[CLIP]))
1348 || (exists[CLIP] && exists[SUBJ]
1349 && (parity[CLIP] == parity[SUBJ]));
1352 bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
1353 && (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
1354 tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
1355 && (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
1356 tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
1357 && (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
1360 contributing= exists[CLIP] || exists[SUBJ];
1363 bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
1364 ^ (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
1365 tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
1366 ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
1367 tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
1368 ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
1371 contributing= (exists[CLIP] && (!parity[SUBJ] || horiz[SUBJ]))
1372 || (exists[SUBJ] && (!parity[CLIP] || horiz[CLIP]))
1373 || (exists[CLIP] && exists[SUBJ]
1374 && (parity[CLIP] == parity[SUBJ]));
1377 bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
1378 || (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
1379 tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
1380 || (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
1381 tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
1382 || (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
1387 parity[CLIP]^= edge->bundle[ABOVE][CLIP];
1388 parity[SUBJ]^= edge->bundle[ABOVE][SUBJ];
1393 next_h_state[horiz[CLIP]]
1394 [((exists[CLIP] - 1) << 1) + parity[CLIP]];
1397 next_h_state[horiz[SUBJ]]
1398 [((exists[SUBJ] - 1) << 1) + parity[SUBJ]];
1400 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1410 add_local_min(&out_poly, edge, xb, yb);
1412 cf= edge->outp[ABOVE];
1417 add_right(cf, xb, yb);
1420 edge->outp[ABOVE]= cf;
1424 add_left(edge->outp[BELOW], xb, yb);
1426 cf= edge->outp[BELOW];
1431 add_left(cf, xb, yb);
1434 merge_right(cf, edge->outp[BELOW], out_poly);
1440 add_left(cf, xb, yb);
1443 edge->outp[ABOVE]= cf;
1447 add_right(edge->outp[BELOW], xb, yb);
1449 cf= edge->outp[BELOW];
1450 edge->outp[BELOW]= NULL;
1455 add_right(cf, xb, yb);
1458 merge_left(cf, edge->outp[BELOW], out_poly);
1460 edge->outp[BELOW]= NULL;
1465 add_right(cf, xb, yb);
1468 merge_left(cf, edge->outp[BELOW], out_poly);
1469 edge->outp[BELOW]= NULL;
1470 add_local_min(&out_poly, edge, xb, yb);
1471 cf= edge->outp[ABOVE];
1476 add_left(cf, xb, yb);
1479 merge_right(cf, edge->outp[BELOW], out_poly);
1480 edge->outp[BELOW]= NULL;
1481 add_local_min(&out_poly, edge, xb, yb);
1482 cf= edge->outp[ABOVE];
1485 if (edge->bot.y == yb)
1486 add_left(edge->outp[BELOW], xb, yb);
1487 edge->outp[ABOVE]= edge->outp[BELOW];
1491 if (edge->bot.y == yb)
1492 add_right(edge->outp[BELOW], xb, yb);
1493 edge->outp[ABOVE]= edge->outp[BELOW];
1504 for (edge= aet; edge; edge= edge->next)
1506 if (edge->top.y == yb)
1508 prev_edge= edge->prev;
1509 next_edge= edge->next;
1511 prev_edge->next= next_edge;
1515 next_edge->prev= prev_edge;
1518 if ((edge->bstate[BELOW] == BUNDLE_HEAD) && prev_edge)
1520 if (prev_edge->bstate[BELOW] == BUNDLE_TAIL)
1522 prev_edge->outp[BELOW]= edge->outp[BELOW];
1523 prev_edge->bstate[BELOW]= UNBUNDLED;
1524 if (prev_edge->prev)
1525 if (prev_edge->prev->bstate[BELOW] == BUNDLE_TAIL)
1526 prev_edge->bstate[BELOW]= BUNDLE_HEAD;
1532 if (edge->top.y == yt)
1533 edge->xt= edge->top.x;
1535 edge->xt= edge->bot.x + edge->dx * (yt - edge->bot.y);
1539 if (scanbeam < sbt_entries)
1543 build_intersection_table(&it, aet, dy);
1546 for (intersect= it; intersect; intersect= intersect->next)
1548 e0= intersect->ie[0];
1549 e1= intersect->ie[1];
1552 if ((e0->bundle[ABOVE][CLIP] || e0->bundle[ABOVE][SUBJ])
1553 && (e1->bundle[ABOVE][CLIP] || e1->bundle[ABOVE][SUBJ]))
1557 ix= intersect->point.x;
1558 iy= intersect->point.y + yb;
1560 in[CLIP]= ( e0->bundle[ABOVE][CLIP] && !e0->bside[CLIP])
1561 || ( e1->bundle[ABOVE][CLIP] && e1->bside[CLIP])
1562 || (!e0->bundle[ABOVE][CLIP] && !e1->bundle[ABOVE][CLIP]
1563 && e0->bside[CLIP] && e1->bside[CLIP]);
1564 in[SUBJ]= ( e0->bundle[ABOVE][SUBJ] && !e0->bside[SUBJ])
1565 || ( e1->bundle[ABOVE][SUBJ] && e1->bside[SUBJ])
1566 || (!e0->bundle[ABOVE][SUBJ] && !e1->bundle[ABOVE][SUBJ]
1567 && e0->bside[SUBJ] && e1->bside[SUBJ]);
1576 tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
1577 && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
1578 br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
1579 && (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
1580 bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
1581 && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
1586 tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
1587 ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
1588 br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
1589 ^ (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
1590 bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
1591 ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
1596 tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
1597 || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
1598 br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
1599 || (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
1600 bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
1601 || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
1605 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1610 add_local_min(&out_poly, e0, ix, iy);
1611 e1->outp[ABOVE]= e0->outp[ABOVE];
1616 add_right(p, ix, iy);
1618 e0->outp[ABOVE]= NULL;
1624 add_left(q, ix, iy);
1626 e1->outp[ABOVE]= NULL;
1632 add_left(p, ix, iy);
1633 merge_right(p, q, out_poly);
1634 e0->outp[ABOVE]= NULL;
1635 e1->outp[ABOVE]= NULL;
1639 add_local_min(&out_poly, e0, ix, iy);
1640 e1->outp[ABOVE]= e0->outp[ABOVE];
1645 add_left(p, ix, iy);
1647 e0->outp[ABOVE]= NULL;
1653 add_right(q, ix, iy);
1655 e1->outp[ABOVE]= NULL;
1661 add_right(p, ix, iy);
1662 merge_left(p, q, out_poly);
1663 e0->outp[ABOVE]= NULL;
1664 e1->outp[ABOVE]= NULL;
1670 add_right(p, ix, iy);
1671 merge_left(p, q, out_poly);
1672 add_local_min(&out_poly, e0, ix, iy);
1673 e1->outp[ABOVE]= e0->outp[ABOVE];
1679 add_left(p, ix, iy);
1680 merge_right(p, q, out_poly);
1681 add_local_min(&out_poly, e0, ix, iy);
1682 e1->outp[ABOVE]= e0->outp[ABOVE];
1691 if (e0->bundle[ABOVE][CLIP])
1692 e1->bside[CLIP]= !e1->bside[CLIP];
1693 if (e1->bundle[ABOVE][CLIP])
1694 e0->bside[CLIP]= !e0->bside[CLIP];
1695 if (e0->bundle[ABOVE][SUBJ])
1696 e1->bside[SUBJ]= !e1->bside[SUBJ];
1697 if (e1->bundle[ABOVE][SUBJ])
1698 e0->bside[SUBJ]= !e0->bside[SUBJ];
1701 prev_edge= e0->prev;
1702 next_edge= e1->next;
1704 next_edge->prev= e0;
1706 if (e0->bstate[ABOVE] == BUNDLE_HEAD)
1711 prev_edge= prev_edge->prev;
1714 if (prev_edge->bstate[ABOVE] != BUNDLE_TAIL)
1729 prev_edge->next->prev= e1;
1730 e1->next= prev_edge->next;
1731 prev_edge->next= e0->next;
1733 if(e0->next == NULL)
throw runtime_error(
"GPC internal error.") ;
1734 if(e1->next == NULL)
throw runtime_error(
"GPC internal error.") ;
1735 e0->next->prev= prev_edge;
1737 e0->next= next_edge;
1741 for (edge= aet; edge; edge= next_edge)
1743 next_edge= edge->next;
1744 succ_edge= edge->succ;
1746 if ((edge->top.y == yt) && succ_edge)
1749 succ_edge->outp[BELOW]= edge->outp[ABOVE];
1750 succ_edge->bstate[BELOW]= edge->bstate[ABOVE];
1751 succ_edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
1752 succ_edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
1753 prev_edge= edge->prev;
1755 prev_edge->next= succ_edge;
1759 next_edge->prev= succ_edge;
1760 succ_edge->prev= prev_edge;
1761 succ_edge->next= next_edge;
1766 edge->outp[BELOW]= edge->outp[ABOVE];
1767 edge->bstate[BELOW]= edge->bstate[ABOVE];
1768 edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
1769 edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
1772 edge->outp[ABOVE]= NULL;
1778 result->contour= NULL;
1780 result->num_contours= count_contours(out_poly);
1781 if (result->num_contours > 0)
1783 MALLOC(result->hole, result->num_contours
1784 *
sizeof(
int),
"hole flag table creation",
int);
1785 MALLOC(result->contour, result->num_contours
1789 for (poly= out_poly; poly; poly= npoly)
1794 result->hole[c]= poly->proxy->hole;
1795 result->contour[c].num_vertices= poly->active;
1796 MALLOC(result->contour[c].vertex,
1797 result->contour[c].num_vertices *
sizeof(
gpc_vertex),
1800 v= result->contour[c].num_vertices - 1;
1801 for (vtx= poly->proxy->v[LEFT]; vtx; vtx= nv)
1804 result->contour[c].vertex[v].x= vtx->x;
1805 result->contour[c].vertex[v].y= vtx->y;
1816 for (poly= out_poly; poly; poly= npoly)
1836 for (s= 0; s < t->num_strips; s++)
1837 FREE(t->strip[s].vertex);
1850 gpc_tristrip_clip(GPC_DIFF, s, &c, t);
1858 it_node *it= NULL, *intersect;
1859 edge_node *edge=0, *prev_edge=0, *next_edge=0, *succ_edge=0, *e0=0, *e1=0;
1860 edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL, *cf=0;
1865 vertex_type cft = NUL;
1866 int in[2], exists[2], parity[2]= {LEFT, LEFT};
1867 int s, v, contributing=0, search, scanbeam= 0, sbt_entries= 0;
1868 int vclass=0, bl=0, br=0, tl=0, tr=0;
1869 double *sbt= NULL, xb, px, nx, yb, yt=0.0, dy=0.0, ix, iy;
1872 if (((subj->num_contours == 0) && (clip->num_contours == 0))
1873 || ((subj->num_contours == 0) && ((op == GPC_INT) || (op == GPC_DIFF)))
1874 || ((clip->num_contours == 0) && (op == GPC_INT)))
1876 result->num_strips= 0;
1877 result->strip= NULL;
1882 if (((op == GPC_INT) || (op == GPC_DIFF))
1883 && (subj->num_contours > 0) && (clip->num_contours > 0))
1884 minimax_test(subj, clip, op);
1887 if (subj->num_contours > 0)
1888 s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj, SUBJ, op);
1889 if (clip->num_contours > 0)
1890 c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip, CLIP, op);
1895 result->num_strips= 0;
1896 result->strip= NULL;
1904 MALLOC(sbt, sbt_entries *
sizeof(
double),
"sbt creation",
double);
1905 build_sbt(&scanbeam, sbt, sbtree);
1907 free_sbtree(&sbtree);
1911 parity[CLIP]= RIGHT;
1916 while (scanbeam < sbt_entries)
1919 yb= sbt[scanbeam++];
1920 if (scanbeam < sbt_entries)
1931 if (local_min->y == yb)
1934 for (edge= local_min->first_bound; edge; edge= edge->next_bound)
1935 add_edge_to_aet(&aet, edge, NULL);
1937 local_min= local_min->next;
1949 aet->bundle[ABOVE][ aet->type]= (aet->top.y != yb);
1950 aet->bundle[ABOVE][!aet->type]= FALSE;
1951 aet->bstate[ABOVE]= UNBUNDLED;
1953 for (next_edge= aet->next; next_edge; next_edge= next_edge->next)
1956 next_edge->bundle[ABOVE][ next_edge->type]= (next_edge->top.y != yb);
1957 next_edge->bundle[ABOVE][!next_edge->type]= FALSE;
1958 next_edge->bstate[ABOVE]= UNBUNDLED;
1961 if (next_edge->bundle[ABOVE][next_edge->type])
1963 if (EQ(e0->xb, next_edge->xb) && EQ(e0->dx, next_edge->dx)
1964 && (e0->top.y != yb))
1966 next_edge->bundle[ABOVE][ next_edge->type]^=
1967 e0->bundle[ABOVE][ next_edge->type];
1968 next_edge->bundle[ABOVE][!next_edge->type]=
1969 e0->bundle[ABOVE][!next_edge->type];
1970 next_edge->bstate[ABOVE]= BUNDLE_HEAD;
1971 e0->bundle[ABOVE][CLIP]= FALSE;
1972 e0->bundle[ABOVE][SUBJ]= FALSE;
1973 e0->bstate[ABOVE]= BUNDLE_TAIL;
1983 for (edge= aet; edge; edge= edge->next)
1985 exists[CLIP]= edge->bundle[ABOVE][CLIP] +
1986 (edge->bundle[BELOW][CLIP] << 1);
1987 exists[SUBJ]= edge->bundle[ABOVE][SUBJ] +
1988 (edge->bundle[BELOW][SUBJ] << 1);
1990 if (exists[CLIP] || exists[SUBJ])
1993 edge->bside[CLIP]= parity[CLIP];
1994 edge->bside[SUBJ]= parity[SUBJ];
2001 contributing= (exists[CLIP] && (parity[SUBJ] || horiz[SUBJ]))
2002 || (exists[SUBJ] && (parity[CLIP] || horiz[CLIP]))
2003 || (exists[CLIP] && exists[SUBJ]
2004 && (parity[CLIP] == parity[SUBJ]));
2007 bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
2008 && (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
2009 tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
2010 && (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
2011 tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
2012 && (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
2015 contributing= exists[CLIP] || exists[SUBJ];
2018 bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
2019 ^ (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
2020 tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
2021 ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
2022 tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
2023 ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
2026 contributing= (exists[CLIP] && (!parity[SUBJ] || horiz[SUBJ]))
2027 || (exists[SUBJ] && (!parity[CLIP] || horiz[CLIP]))
2028 || (exists[CLIP] && exists[SUBJ]
2029 && (parity[CLIP] == parity[SUBJ]));
2032 bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
2033 || (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
2034 tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
2035 || (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
2036 tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
2037 || (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
2042 parity[CLIP]^= edge->bundle[ABOVE][CLIP];
2043 parity[SUBJ]^= edge->bundle[ABOVE][SUBJ];
2048 next_h_state[horiz[CLIP]]
2049 [((exists[CLIP] - 1) << 1) + parity[CLIP]];
2052 next_h_state[horiz[SUBJ]]
2053 [((exists[SUBJ] - 1) << 1) + parity[SUBJ]];
2055 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
2064 new_tristrip(&tlist, edge, xb, yb);
2068 edge->outp[ABOVE]= cf->outp[ABOVE];
2070 VERTEX(edge, ABOVE, RIGHT, xb, yb);
2074 VERTEX(edge, BELOW, LEFT, xb, yb);
2075 edge->outp[ABOVE]= NULL;
2080 VERTEX(edge, BELOW, RIGHT, xb, yb);
2081 edge->outp[ABOVE]= NULL;
2087 if (cf->bot.y != yb)
2088 VERTEX(cf, BELOW, LEFT, cf->xb, yb);
2089 new_tristrip(&tlist, cf, cf->xb, yb);
2091 edge->outp[ABOVE]= cf->outp[ABOVE];
2092 VERTEX(edge, ABOVE, RIGHT, xb, yb);
2095 new_tristrip(&tlist, edge, xb, yb);
2102 if (cf->bot.y != yb)
2103 VERTEX(cf, BELOW, LEFT, cf->xb, yb);
2104 new_tristrip(&tlist, cf, cf->xb, yb);
2106 VERTEX(edge, BELOW, RIGHT, xb, yb);
2107 edge->outp[ABOVE]= NULL;
2110 VERTEX(edge, BELOW, LEFT, xb, yb);
2111 edge->outp[ABOVE]= NULL;
2115 VERTEX(edge, BELOW, LEFT, xb, yb);
2116 edge->outp[ABOVE]= cf->outp[ABOVE];
2118 VERTEX(cf, ABOVE, RIGHT, xb, yb);
2122 VERTEX(edge, BELOW, RIGHT, xb, yb);
2123 edge->outp[ABOVE]= NULL;
2124 new_tristrip(&tlist, edge, xb, yb);
2128 if (edge->bot.y == yb)
2129 VERTEX(edge, BELOW, LEFT, xb, yb);
2130 edge->outp[ABOVE]= edge->outp[BELOW];
2135 edge->outp[ABOVE]= cf->outp[ABOVE];
2138 if (cf->bot.y == yb)
2140 VERTEX(edge, BELOW, RIGHT, xb, yb);
2144 if (edge->bot.y == yb)
2146 VERTEX(cf, BELOW, LEFT, cf->xb, yb);
2147 VERTEX(edge, BELOW, RIGHT, xb, yb);
2153 VERTEX(edge, BELOW, RIGHT, xb, yb);
2154 VERTEX(edge, ABOVE, RIGHT, xb, yb);
2166 for (edge= aet; edge; edge= edge->next)
2168 if (edge->top.y == yb)
2170 prev_edge= edge->prev;
2171 next_edge= edge->next;
2173 prev_edge->next= next_edge;
2177 next_edge->prev= prev_edge;
2180 if ((edge->bstate[BELOW] == BUNDLE_HEAD) && prev_edge)
2182 if (prev_edge->bstate[BELOW] == BUNDLE_TAIL)
2184 prev_edge->outp[BELOW]= edge->outp[BELOW];
2185 prev_edge->bstate[BELOW]= UNBUNDLED;
2186 if (prev_edge->prev)
2187 if (prev_edge->prev->bstate[BELOW] == BUNDLE_TAIL)
2188 prev_edge->bstate[BELOW]= BUNDLE_HEAD;
2194 if (edge->top.y == yt)
2195 edge->xt= edge->top.x;
2197 edge->xt= edge->bot.x + edge->dx * (yt - edge->bot.y);
2201 if (scanbeam < sbt_entries)
2205 build_intersection_table(&it, aet, dy);
2208 for (intersect= it; intersect; intersect= intersect->next)
2210 e0= intersect->ie[0];
2211 e1= intersect->ie[1];
2214 if ((e0->bundle[ABOVE][CLIP] || e0->bundle[ABOVE][SUBJ])
2215 && (e1->bundle[ABOVE][CLIP] || e1->bundle[ABOVE][SUBJ]))
2219 ix= intersect->point.x;
2220 iy= intersect->point.y + yb;
2222 in[CLIP]= ( e0->bundle[ABOVE][CLIP] && !e0->bside[CLIP])
2223 || ( e1->bundle[ABOVE][CLIP] && e1->bside[CLIP])
2224 || (!e0->bundle[ABOVE][CLIP] && !e1->bundle[ABOVE][CLIP]
2225 && e0->bside[CLIP] && e1->bside[CLIP]);
2226 in[SUBJ]= ( e0->bundle[ABOVE][SUBJ] && !e0->bside[SUBJ])
2227 || ( e1->bundle[ABOVE][SUBJ] && e1->bside[SUBJ])
2228 || (!e0->bundle[ABOVE][SUBJ] && !e1->bundle[ABOVE][SUBJ]
2229 && e0->bside[SUBJ] && e1->bside[SUBJ]);
2238 tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
2239 && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
2240 br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
2241 && (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
2242 bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
2243 && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
2248 tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
2249 ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
2250 br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
2251 ^ (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
2252 bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
2253 ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
2258 tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
2259 || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
2260 br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
2261 || (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
2262 bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
2263 || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
2267 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
2272 new_tristrip(&tlist, e1, ix, iy);
2273 e0->outp[ABOVE]= e1->outp[ABOVE];
2278 P_EDGE(prev_edge, e0, ABOVE, px, iy);
2279 VERTEX(prev_edge, ABOVE, LEFT, px, iy);
2280 VERTEX(e0, ABOVE, RIGHT, ix, iy);
2281 e1->outp[ABOVE]= e0->outp[ABOVE];
2282 e0->outp[ABOVE]= NULL;
2288 N_EDGE(next_edge, e1, ABOVE, nx, iy);
2289 VERTEX(e1, ABOVE, LEFT, ix, iy);
2290 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2291 e0->outp[ABOVE]= e1->outp[ABOVE];
2292 e1->outp[ABOVE]= NULL;
2298 VERTEX(e0, ABOVE, LEFT, ix, iy);
2299 e0->outp[ABOVE]= NULL;
2300 e1->outp[ABOVE]= NULL;
2304 P_EDGE(prev_edge, e0, ABOVE, px, iy);
2305 VERTEX(prev_edge, ABOVE, LEFT, px, iy);
2306 N_EDGE(next_edge, e1, ABOVE, nx, iy);
2307 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2308 new_tristrip(&tlist, prev_edge, px, iy);
2309 e1->outp[ABOVE]= prev_edge->outp[ABOVE];
2310 VERTEX(e1, ABOVE, RIGHT, ix, iy);
2311 new_tristrip(&tlist, e0, ix, iy);
2312 next_edge->outp[ABOVE]= e0->outp[ABOVE];
2313 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2318 VERTEX(e0, ABOVE, LEFT, ix, iy);
2319 N_EDGE(next_edge, e1, ABOVE, nx, iy);
2320 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2321 e1->outp[ABOVE]= e0->outp[ABOVE];
2322 e0->outp[ABOVE]= NULL;
2328 VERTEX(e1, ABOVE, RIGHT, ix, iy);
2329 P_EDGE(prev_edge, e0, ABOVE, px, iy);
2330 VERTEX(prev_edge, ABOVE, LEFT, px, iy);
2331 e0->outp[ABOVE]= e1->outp[ABOVE];
2332 e1->outp[ABOVE]= NULL;
2338 VERTEX(e0, ABOVE, RIGHT, ix, iy);
2339 VERTEX(e1, ABOVE, LEFT, ix, iy);
2340 e0->outp[ABOVE]= NULL;
2341 e1->outp[ABOVE]= NULL;
2342 P_EDGE(prev_edge, e0, ABOVE, px, iy);
2343 VERTEX(prev_edge, ABOVE, LEFT, px, iy);
2344 new_tristrip(&tlist, prev_edge, px, iy);
2345 N_EDGE(next_edge, e1, ABOVE, nx, iy);
2346 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2347 next_edge->outp[ABOVE]= prev_edge->outp[ABOVE];
2348 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2354 VERTEX(e0, ABOVE, RIGHT, ix, iy);
2355 VERTEX(e1, ABOVE, LEFT, ix, iy);
2356 P_EDGE(prev_edge, e0, ABOVE, px, iy);
2357 VERTEX(prev_edge, ABOVE, LEFT, px, iy);
2358 new_tristrip(&tlist, prev_edge, px, iy);
2359 N_EDGE(next_edge, e1, ABOVE, nx, iy);
2360 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2361 e1->outp[ABOVE]= prev_edge->outp[ABOVE];
2362 VERTEX(e1, ABOVE, RIGHT, ix, iy);
2363 new_tristrip(&tlist, e0, ix, iy);
2364 next_edge->outp[ABOVE]= e0->outp[ABOVE];
2365 VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
2371 VERTEX(e0, ABOVE, LEFT, ix, iy);
2372 new_tristrip(&tlist, e1, ix, iy);
2373 e0->outp[ABOVE]= e1->outp[ABOVE];
2382 if (e0->bundle[ABOVE][CLIP])
2383 e1->bside[CLIP]= !e1->bside[CLIP];
2384 if (e1->bundle[ABOVE][CLIP])
2385 e0->bside[CLIP]= !e0->bside[CLIP];
2386 if (e0->bundle[ABOVE][SUBJ])
2387 e1->bside[SUBJ]= !e1->bside[SUBJ];
2388 if (e1->bundle[ABOVE][SUBJ])
2389 e0->bside[SUBJ]= !e0->bside[SUBJ];
2392 prev_edge= e0->prev;
2393 next_edge= e1->next;
2397 if (e0->bstate[ABOVE] == BUNDLE_HEAD)
2402 prev_edge= prev_edge->prev;
2405 if (prev_edge->bundle[ABOVE][CLIP]
2406 || prev_edge->bundle[ABOVE][SUBJ]
2407 || (prev_edge->bstate[ABOVE] == BUNDLE_HEAD))
2421 e1->next= prev_edge->next;
2422 prev_edge->next= e0->next;
2424 e0->next->prev= prev_edge;
2426 e0->next= next_edge;
2430 for (edge= aet; edge; edge= next_edge)
2432 next_edge= edge->next;
2433 succ_edge= edge->succ;
2435 if ((edge->top.y == yt) && succ_edge)
2438 succ_edge->outp[BELOW]= edge->outp[ABOVE];
2439 succ_edge->bstate[BELOW]= edge->bstate[ABOVE];
2440 succ_edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
2441 succ_edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
2442 prev_edge= edge->prev;
2444 prev_edge->next= succ_edge;
2448 next_edge->prev= succ_edge;
2449 succ_edge->prev= prev_edge;
2450 succ_edge->next= next_edge;
2455 edge->outp[BELOW]= edge->outp[ABOVE];
2456 edge->bstate[BELOW]= edge->bstate[ABOVE];
2457 edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
2458 edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
2461 edge->outp[ABOVE]= NULL;
2467 result->strip= NULL;
2468 result->num_strips= count_tristrips(tlist);
2469 if (result->num_strips > 0)
2475 for (tn= tlist; tn; tn= tnn)
2482 result->strip[s].num_vertices= tn->active;
2483 MALLOC(result->strip[s].vertex, tn->active *
sizeof(
gpc_vertex),
2486 if (INVERT_TRISTRIPS)
2501 result->strip[s].vertex[v].x= lt->x;
2502 result->strip[s].vertex[v].y= lt->y;
2510 result->strip[s].vertex[v].x= rt->x;
2511 result->strip[s].vertex[v].y= rt->y;
2522 for (lt= tn->v[LEFT]; lt; lt= ltn)
2527 for (rt= tn->v[RIGHT]; rt; rt=rtn)
FARSA_UTIL_TEMPLATE const T max(const T &t1, const U &t2)
FARSA_UTIL_TEMPLATE const T min(const T &t1, const U &t2)