55#define CELL(n) ((cell*)ND_alg(n))
57static double MID(
double a,
double b) {
68 if (cp == q->
cells[0] || cp == q->
cells[1])
return cp;
84 if (cp == ptr->
cells[1]) {
113setSeg (
segment* sp,
bool dir,
double fix,
double b1,
double b2,
int l1,
int l2)
151 pointf bp1, bp2, prevbp = {0.0,0.0};
154 for (ptr = fst; ptr; ptr =
N_DAD(ptr)) sz++;
179 else if (prevbp.
y > bp1.
y) l1 =
B_UP;
204 rte.
segs[rte.
n++] = seg;
212 if (prevbp.
y > bp1.
y) l1 =
B_UP;
226 rte.
segs[rte.
n++] = seg;
235 for (
size_t i=0; i<rte.
n; i++) {
274 const paird *key1 = k1;
275 const paird *key2 = k2;
276 if (key1->
p1 > key2->
p1) {
277 if (key1->
p2 <= key2->
p2)
return 0;
280 if (key1->
p1 < key2->
p1) {
281 if (key1->
p2 >= key2->
p2)
return 0;
288 const double *key1 = k1;
289 const double *key2 = k2;
290 return fcmp(*key1, *key2);
333 for (
size_t i = 0; i < mp->
ncells; i++) {
369 for (
size_t i = 0; i < mp->
ncells; i++) {
422 for (
size_t i=0;i<nrtes;i++) {
423 route rte = route_list[i];
424 for (
size_t j=0;j<rte.
n;j++) {
442 for (
size_t i = 0; i < cp->
nsides; i++) {
445 if (onp->
isVert)
continue;
446 const bool onTop = onp->
cells[0] == cp;
462 for (
size_t i = 0; i < cp->
nsides; i++) {
500 fprintf (fp,
"((%f,%f),(%f,%f)) %s %s", seg->
comm_coord, seg->
p.
p1,
503 fprintf (fp,
"((%f,%f),(%f,%f)) %s %s", seg->
p.
p1,seg->
comm_coord,
509 fprintf (stderr,
"channel %.0f (%f,%f)\n", v, cp->
p.
p1, cp->
p.
p2);
514 fputs (
" ->\n", stderr);
515 for (
size_t i = 0; i <
LIST_SIZE(&adj); ++i) {
518 fputs (
"\n", stderr);
567 if ((S1l2==T2 && S2l2!=T2) || (S1l2==
B_NODE && S2l2==T1))
577 if (S1->
l2 == T1 && S2->
l1 == T2)
return -1;
578 if (S1->
l2 == T2 && S2->
l1 == T1)
return 1;
581 if (S1->
p.
p2 > S2->
p.
p2) {
582 if (S2->
l1 == T2 && S2->
l2 == T2)
return -1;
583 if (S2->
l1 == T1 && S2->
l2 == T1)
return 1;
594 if (S1l2==
T)
return -1;
604 if (S1->
p.
p2 < S2->
p.
p1 || S1->
p.
p1 > S2->
p.
p2)
return 0;
611 if (S1->
p.
p1 == S2->
p.
p1) {
612 if (S1->
p.
p2 < S2->
p.
p2) {
617 if (S1->
p.
p2 > S2->
p.
p2) {
622 if (S1->
l1 == S2->
l1 && S1->
l2 == S2->
l2)
624 if (S2->
l1 == S2->
l2) {
625 if (S2->
l1 == T1)
return 1;
626 if (S2->
l1 == T2)
return -1;
627 if (S1->
l1 != T1 && S1->
l2 != T1)
return 1;
628 if (S1->
l1 != T2 && S1->
l2 != T2)
return -1;
631 if (S2->
l1 == T1 && S2->
l2 == T2) {
632 if (S1->
l1 != T1 && S1->
l2 == T2)
return 1;
633 if (S1->
l1 == T1 && S1->
l2 != T2)
return -1;
636 if (S2->
l2 == T1 && S2->
l1 == T2) {
637 if (S1->
l2 != T1 && S1->
l1 == T2)
return 1;
638 if (S1->
l2 == T1 && S1->
l1 != T2)
return -1;
653 if (S1->
p.
p2 == S2->
p.
p1) {
654 if (S1->
l2 == S2->
l1)
return 0;
655 if (S1->
l2 == T2)
return 1;
659 if (S1->
l1 == S2->
l2)
return 0;
660 if (S1->
l1 == T2)
return 1;
683 agerrorf(
"incomparable segments !! -- Aborting\n");
695 seg_list_t *seg_list = &cp->
seg_list;
699 for (
size_t x = 0; x + 1 < size; ++x) {
700 for (
size_t y = x + 1; y < size; ++y) {
704 }
else if (
cmp > 0) {
706 }
else if (
cmp == -1) {
754 for(x=1;x<=hops;x++) {
758 if(current->
l1==
B_UP) ans *= -1;
781 return s1->p.p1 == s2->
p.
p1 &&
782 s1->p.p2 == s2->
p.
p2 &&
795 int prec = 0, ans = 0, temp;
842 for (x=1;x<=hops;x++) {
963 else if (
LIST_GET(segs, j)->prev == 0) {
967 if (
LIST_GET(segs, i)->prev->comm_coord ==
968 LIST_GET(segs, j)->prev->comm_coord)
994 }
else if (prec1 == 0) {
1000 }
else if (prec2 == 0) {
1004 1 - dir, hops.
b, mp);
1005 }
else if (prec2 == 1) {
1009 1 - dir, hops.
b, mp);
1011 }
else if (prec1 == 1) {
1086 return round(lo + f * (hi - lo));
1094 for (
size_t irte = 0; irte < n_edges; irte++) {
1099 route rte = route_list[irte];
1100 size_t npts = 1 + 3*rte.
n;
1117 for (
size_t i = 1;i<rte.
n;i++) {
1152 return (
int)
DIST2(p,q);
1158 if (e0->
d > e1->
d) {
1161 if (e0->
d < e1->
d) {
1196 char*
s =
agget(g,
"odb");
1199 if (
s && *
s !=
'\0') {
1200 while ((c = *
s++)) {
1225 agwarningf(
"Orthogonal edges do not currently handle edge labels. Try using xlabels.\n");
1261 const int gstart = sg->
nnodes;
1265 for (
size_t i = 0; i < n_edges; i++) {
1282 if (
shortPath (sg, dn, sn))
goto orthofinish;
1304 for (
size_t i=0; i < n_edges; i++)
1305 free (route_list[i].segs);
1316%%%%BoundingBox: (atend)\n\
1321 X Y 3 0 360 arc fill\n\
1340 newpath l d moveto\n\
1341 r d lineto r u lineto l u lineto\n\
1349%%%%BoundingBox: %.f %.f %.f %.f\n";
1364 agerrorf(
"Node not adjacent to cell -- Aborting\n");
1382 bb.
LL.
x = fmin(bb.
LL.
x, x);
1383 bb.
LL.
y = fmin(bb.
LL.
y, y);
1384 bb.
UR.
x = fmax(bb.
UR.
x, x);
1385 bb.
UR.
y = fmax(bb.
UR.
y, y);
1386 fprintf(fp,
"newpath %.0f %.0f moveto\n", x, y);
1388 for (
size_t i = 1;i<rte.
n;i++) {
1396 bb.
LL.
x = fmin(bb.
LL.
x, x);
1397 bb.
LL.
y = fmin(bb.
LL.
y, y);
1398 bb.
UR.
x = fmax(bb.
UR.
x, x);
1399 bb.
UR.
y = fmax(bb.
UR.
y, y);
1400 fprintf(fp,
"%.0f %.0f lineto\n", x, y);
1412 bb.
LL.
x = fmin(bb.
LL.
x, x);
1413 bb.
LL.
y = fmin(bb.
LL.
y, y);
1414 bb.
UR.
x = fmax(bb.
UR.
x, x);
1415 bb.
UR.
y = fmax(bb.
UR.
y, y);
1416 fprintf(fp,
"%.0f %.0f lineto stroke\n", x, y);
1433 fputs (
"graph G {\n", fp);
1434 fputs (
" node[shape=point]\n", fp);
1435 fputs (
" layout=neato\n", fp);
1436 for (
int i = 0; i < sg->
nnodes; i++) {
1439 if (cp == np->
cells[1]) {
1446 fprintf (fp,
" %d [pos=\"%.0f,%.0f!\"]\n", i, p.
x, p.
y);
1448 for (
int i = 0; i < sg->
nedges; i++) {
1450 fprintf (fp,
" %d -- %d[label=\"%f\"]\n", ep->
v1, ep->
v2, ep->
weight);
1457 boxf absbb = {.
LL = {.
x = DBL_MAX, .y = DBL_MAX},
1458 .UR = {.x = -DBL_MAX, .y = -DBL_MAX}};
1461 fprintf (fp,
"%d %d translate\n",
TRANS,
TRANS);
1463 fputs (
"0 0 1 setrgbcolor\n", fp);
1464 for (
size_t i = 0; i < mp->
ngcells; i++) {
1466 fprintf (fp,
"%f %f %f %f node\n", bb.
LL.
x, bb.
LL.
y, bb.
UR.
x, bb.
UR.
y);
1469 for (
size_t i = 0; i < n_edges; i++) {
1470 absbb =
emitEdge (fp, es[i].e, route_list[i], mp, absbb);
1473 fputs (
"0.8 0.8 0.8 setrgbcolor\n", fp);
1474 for (
size_t i = 0; i < mp->
ncells; i++) {
1476 fprintf (fp,
"%f %f %f %f cell\n", bb.
LL.
x, bb.
LL.
y, bb.
UR.
x, bb.
UR.
y);
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
CDT_API Dtlink_t * dtflatten(Dt_t *)
CDT_API int dtclose(Dt_t *)
CDT_API Dtmethod_t * Dtoset
ordered set (self-adjusting tree)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
static NORETURN void graphviz_exit(int status)
static int cmp(const void *key, const void *candidate)
geometric functions (e.g. on points and boxes)
static pointf mid_pointf(pointf p, pointf q)
static pointf add_pointf(pointf p, pointf q)
static pointf interpolate_pointf(double t, pointf p, pointf q)
static void free_graph(gmlgraph *p)
int agnedges(Agraph_t *g)
char * agget(void *obj, char *name)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
void agwarningf(const char *fmt,...)
void agerrorf(const char *fmt,...)
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
char * agnameof(void *)
returns a string descriptor for the object.
Arithmetic helper functions.
static int fcmp(double a, double b)
comparator for doubles
type-generic dynamically expanding list
#define LIST_APPEND(list, item)
#define LIST_RESERVE(list, capacity)
#define LIST_IS_EMPTY(list)
#define LIST_GET(list, index)
maze * mkMaze(graph_t *g)
creates maze and fills maze::gcells and maze::cells. A subroutine of orthoEdges.
void updateWts(sgraph *g, cell *cp, sedge *ep)
updates sedge::weight of cell edges
makes maze with mkMaze for routing orthogonal edges
#define IsHScan(cp)
cell already inserted in horizontal channel
#define IsVScan(cp)
cell already inserted in vertical channel
#define IsNode(cp)
cell corresponds to node
static boxf bbox(Ppoly_t **obsp, int npoly, int *np)
NEATOPROCS_API void s1(graph_t *, node_t *)
snode priority queue for shortPath in sgraph
static char * bendToStr(bend b)
static int seg_cmp(segment *S1, segment *S2)
static route convertSPtoRoute(sgraph *g, snode *fst, snode *lst)
static Dt_t * extractVChans(maze *mp)
static int add_edges_in_G(channel *cp)
static int decide_point(pair *ret, segment *si, segment *sj, int dir1, int dir2)
static int add_p_edges(Dt_t *chans, maze *mp)
static int edgeLen(Agedge_t *e)
static void removeEdge(segment *seg1, segment *seg2, int dir, maze *mp)
static void setSeg(segment *sp, bool dir, double fix, double b1, double b2, int l1, int l2)
static int eqEndSeg(bend S1l2, bend S2l2, bend T1, bend T2)
static double htrack(segment *seg, maze *m)
static pointf coordOf(cell *cp, snode *np)
static UNUSED void emitGraph(FILE *fp, maze *mp, size_t n_edges, route *route_list, epair_t[])
static void putSeg(FILE *fp, segment *seg)
static UNUSED void emitSearchGraph(FILE *fp, sgraph *sg)
dumps in dot format snode::cells and edges of sgraph for debugging
static int segCmp(segment *S1, segment *S2, bend T1, bend T2)
static bool swap_ends_p(edge_t *e)
static segment * next_seg(segment *seg, int dir)
static void set_parallel_edges(segment *seg1, segment *seg2, int dir1, int dir2, int hops, maze *mp)
static bool spline_merge(node_t *n)
static pointf sidePt(snode *ptr, cell *cp)
static int addPEdges(channel *cp, maze *mp)
static double MID(double a, double b)
static UNUSED void dumpChanG(channel *cp, double v)
static void assignSegs(size_t nrtes, route *route_list, maze *mp)
static cell * cellOf(snode *p, snode *q)
static void create_graphs(Dt_t *chans)
static void addChan(Dt_t *chdict, channel *cp, double j)
static pointf midPt(const cell *cp)
static int add_np_edges(Dt_t *chans)
static void insertChan(channel *chan, segment *seg)
static double vtrack(segment *seg, maze *m)
static Dt_t * extractHChans(maze *mp)
static int overlapSeg(segment *S1, segment *S2, bend T1, bend T2)
static void freeChannel(void *chan)
static void assignTrackNo(Dt_t *chans)
static void attachOrthoEdges(maze *mp, size_t n_edges, route *route_list, splineInfo *sinfo, epair_t es[], bool doLbls)
void orthoEdges(Agraph_t *g, bool useLbls)
static int dcmpid(void *k1, void *k2)
static int ellSeg(bend S1l1, bend S1l2, bend T)
static void freeChanItem(void *item)
static int chancmpid(void *k1, void *k2)
static void addNodeEdges(sgraph *sg, cell *cp, snode *np)
static int assignTracks(maze *mp)
static int propagate_prec(segment *seg, int prec, int hops, int dir)
static channel * chanSearch(Dt_t *chans, segment *seg)
static void addLoop(sgraph *sg, cell *cp, snode *dp, snode *sp)
static int edgecmp(const void *x, const void *y)
static boxf emitEdge(FILE *fp, Agedge_t *e, route rte, maze *m, boxf bb)
static bool is_parallel(segment *s1, segment *s2)
static Dtdisc_t chanItemDisc
void addPS(PointSet *ps, double x, double y)
void freePS(PointSet *ps)
int isInPS(PointSet *ps, double x, double y)
point containers PointSet and PointMap
rawgraph * make_graph(size_t n)
makes a graph with n vertices, 0 edges
void insert_edge(rawgraph *g, size_t v1, size_t v2)
inserts edge FROM v1 to v2
void remove_redge(rawgraph *g, size_t v1, size_t v2)
removes any edge between v1 to v2 – irrespective of direction
void top_sort(rawgraph *g)
bool edge_exists(rawgraph *g, size_t v1, size_t v2)
tests if there is an edge FROM v1 TO v2
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, size_t pn, splineInfo *info)
void addEdgeLabels(edge_t *e)
sedge * createSEdge(sgraph *g, snode *v1, snode *v2, double wt)
int shortPath(sgraph *g, snode *from, snode *to)
result of partitioning available space, part of maze
snode ** sides
up to four sides: M_RIGHT, M_TOP, M_LEFT, M_BOTTOM
seg_list_t seg_list
segment pointers
available channels for orthogonal edges around nodes of graph_t
cell * cells
cells not corresponding to graph nodes
cell * gcells
cells corresponding to graph nodes
Dt_t * vchans
set of vertical channels, created by extractVChans
Dt_t * hchans
set of horizontal channels, created by extractHChans.
size_t ind_no
index number of this segment in its channel
a node of search graph sgraph, is created as a border segment between two adjusted cells of type cell...
struct cell * cells[2]
[0] - left or botom, [1] - top or right adjusted cell
adj_list_t adj_list
adjacency list
abstraction for squashing compiler warnings for unused symbols