void printrecords (void) { vertex_t *vp; edge_t *ep; poly_t *pp; int ei; SUmessage (1, "printrecords", "printing data structures"); for ( vp = (vertex_t *) dtflatten (vertexdict); vp; vp = (vertex_t *) dtlink (vertexdict, vp) ) { sfprintf (sfstdout, "vertex: %x %d %d\n", vp, vp->xy.x, vp->xy.y); for (ei = 0; ei < vp->edgepl; ei++) sfprintf (sfstdout, "\tedge %d\n", vp->edgeps[ei]->tlid); } for ( ep = (edge_t *) dtflatten (edgedict); ep; ep = (edge_t *) dtlink (edgedict, ep) ) { sfprintf ( sfstdout, "edge: %d %s %s\n", ep->tlid, ep->sp->str, cfccid2str (ep->cfccid) ); sfprintf (sfstdout, "\tzip %d %d\n", ep->zipl, ep->zipr); sfprintf ( sfstdout, "\tnpanxxloc %d %d\n", ep->npanxxlocl, ep->npanxxlocr ); sfprintf (sfstdout, "\tstate %d %d\n", ep->statel, ep->stater); sfprintf (sfstdout, "\tcounty %d %d\n", ep->countyl, ep->countyr); sfprintf (sfstdout, "\tctbna %d %d\n", ep->ctbnal, ep->ctbnar); sfprintf (sfstdout, "\tblk %d %d\n", ep->blkl, ep->blkr); sfprintf (sfstdout, "\tblks %d %d\n", ep->blksl, ep->blksr); sfprintf ( sfstdout, "\tvertices %x/%d %x/%d\n", ep->v0p, ep->v0i, ep->v1p, ep->v1i ); if (ep->p0p) sfprintf ( sfstdout, "\tl poly %d-%d/%d\n", ep->p0p->cenid, ep->p0p->polyid, ep->p0i ); if (ep->p1p) sfprintf ( sfstdout, "\tr poly %d-%d/%d\n", ep->p1p->cenid, ep->p1p->polyid, ep->p1i ); } for ( pp = (poly_t *) dtflatten (polydict); pp; pp = (poly_t *) dtlink (polydict, pp) ) { sfprintf (sfstdout, "poly: %d-%d\n", pp->cenid, pp->polyid); for (ei = 0; ei < pp->edgepl; ei++) sfprintf (sfstdout, "\tedge %d\n", pp->edgeps[ei]->tlid); } }
/* processTbl: * Convert parser representation of cells into final form. * Find column and row positions of cells. * Recursively size cells. * Return 1 if problem sizing a cell. */ static int processTbl(graph_t *g, htmltbl_t * tbl, htmlenv_t * env) { pitem *rp; pitem *cp; Dt_t *cdict; int r, c, cnt; htmlcell_t *cellp; htmlcell_t **cells; Dt_t *rows = tbl->u.p.rows; int rv = 0; int n_rows = 0; int n_cols = 0; PointSet *ps = newPS(); rp = (pitem *) dtflatten(rows); cnt = 0; while (rp) { cdict = rp->u.rp; cp = (pitem *) dtflatten(cdict); while (cp) { cellp = cp->u.cp; cnt++; cp = (pitem *) dtlink(cdict, (Dtlink_t *) cp); } rp = (pitem *) dtlink(rows, (Dtlink_t *) rp); } cells = tbl->u.n.cells = N_NEW(cnt + 1, htmlcell_t *); rp = (pitem *) dtflatten(rows); r = 0; while (rp) { cdict = rp->u.rp; cp = (pitem *) dtflatten(cdict); c = 0; while (cp) { cellp = cp->u.cp; *cells++ = cellp; rv |= size_html_cell(g, cellp, tbl, env); c = findCol(ps, r, c, cellp); cellp->row = r; cellp->col = c; c += cellp->cspan; n_cols = MAX(c, n_cols); n_rows = MAX(r + cellp->rspan, n_rows); cp = (pitem *) dtlink(cdict, (Dtlink_t *) cp); } rp = (pitem *) dtlink(rows, (Dtlink_t *) rp); r++; } tbl->rc = n_rows; tbl->cc = n_cols; dtclose(rows); freePS(ps); return rv; }
tmain() { Dt_t* dt; Obj_t *o, proto; long i, k, count, n; for(i = 0; i < N_OBJ; i = k) { for(k = i; k < i+R_OBJ && k < N_OBJ; ++k) { Obj[k].key = i; Obj[k].ord = k; } } for(k = 0; k < 2; ++k) { if(!(dt = dtopen(&Disc, k == 0 ? Dtrhbag : Dtobag)) ) terror("Opening dictionary"); dtcustomize(dt, DT_SHARE, 1); /* turn on sharing */ for(i = 0; i < N_OBJ; ++i) { if(dtinsert(dt, Obj+i) != Obj+i) terror("Insert %d,%d", Obj[i].key, Obj[i].ord); if(i > 0 && (i%N_CHK) == 0) if((count = dtsize(dt)) != i+1) terror("Bad size %d (need %d)", count, i+1); } count = n = 0; /* count the group of elements with key == 0 */ for(o = (Obj_t*)dtflatten(dt); o; o = (Obj_t*)dtlink(dt,o), count += 1) if(o->key == 0) n += 1; if(count != N_OBJ || n != R_OBJ) terror("flatten %s: count=%d(need=%d) n=%d(need=%d)", k == 0 ? "bag" : "obag", count, N_OBJ, n, R_OBJ); /* delete a bunch of objects */ for(n = 0, i = 0; i < N_OBJ; i += R_OBJ, n += 1) if(!dtdelete(dt, Obj+i)) terror("delete %s: i=%d", k == 0 ? "bag" : "obag", i); count = 0; /* count the left over */ for(o = (Obj_t*)dtflatten(dt); o; o = (Obj_t*)dtlink(dt,o)) count += 1; if(count != N_OBJ-n) terror("%s wrong count %d", k == 0 ? "bag" : "obag", count); dtclose(dt); } texit(0); }
static void add_p_edges (Dt_t* chans, maze* mp) { Dt_t* lp; Dtlink_t* l1; Dtlink_t* l2; for (l1 = dtflatten (chans); l1; l1 = dtlink(chans,l1)) { lp = ((chanItem*)l1)->chans; for (l2 = dtflatten (lp); l2; l2 = dtlink(lp,l2)) { addPEdges ((channel*)l2, mp); } } }
static void create_graphs(Dt_t* chans) { Dt_t* lp; Dtlink_t* l1; Dtlink_t* l2; channel* cp; for (l1 = dtflatten (chans); l1; l1 = dtlink(chans,l1)) { lp = ((chanItem*)l1)->chans; for (l2 = dtflatten (lp); l2; l2 = dtlink(lp,l2)) { cp = (channel*)l2; cp->G = make_graph (cp->cnt); } } }
static void add_np_edges (Dt_t* chans) { Dt_t* lp; Dtlink_t* l1; Dtlink_t* l2; channel* cp; for (l1 = dtflatten (chans); l1; l1 = dtlink(chans,l1)) { lp = ((chanItem*)l1)->chans; for (l2 = dtflatten (lp); l2; l2 = dtlink(lp,l2)) { cp = (channel*)l2; if (cp->cnt) add_edges_in_G(cp); } } }
void print_edge(edgelist * list) { edgelistitem *temp; Agedge_t *ep; for (temp = (edgelistitem *) dtflatten(list); temp; temp = (edgelistitem *) dtlink(list, (Dtlink_t *) temp)) { ep = temp->edge; fprintf(stderr, "%s--%s \n", ep->tail->name, ep->head->name); } fputs("\n", stderr); }
void print_edge(edgelist * list) { edgelistitem *temp; Agedge_t *ep; for (temp = (edgelistitem *) dtflatten(list); temp; temp = (edgelistitem *) dtlink(list, (Dtlink_t *) temp)) { ep = temp->edge; fprintf(stderr, "%s--", agnameof(agtail(ep))); fprintf(stderr, "%s \n", agnameof(aghead(ep))); } fputs("\n", stderr); }
point *pointsOf(PointSet * ps) { int n = dtsize(ps); point *pts = N_NEW(n, point); pair *p; point *pp = pts; for (p = (pair *) dtflatten(ps); p; p = (pair *) dtlink(ps, (Dtlink_t *) p)) { *pp++ = p->id; } return pts; }
static void assignTrackNo (Dt_t* chans) { Dt_t* lp; Dtlink_t* l1; Dtlink_t* l2; channel* cp; int k; for (l1 = dtflatten (chans); l1; l1 = dtlink(chans,l1)) { lp = ((chanItem*)l1)->chans; for (l2 = dtflatten (lp); l2; l2 = dtlink(lp,l2)) { cp = (channel*)l2; if (cp->cnt) { #ifdef DEBUG if (odb_flags & ODB_CHANG) dumpChanG (cp, ((chanItem*)l1)->v); #endif top_sort (cp->G); for (k=0;k<cp->cnt;k++) cp->seg_list[k]->track_no = cp->G->vertices[k].topsort_order+1; } } } }
tmain() { Dt_t *dt; Dtstat_t stat; Obj_t *p, *o, *obj, proto; char *name; long i, k, mid, n_mid, n_obj, meth; /* construct repetitive objects */ for(i = 0; i < N_OBJ; i += R_OBJ) { for(k = 0; k < R_OBJ; ++k) { Obj[i+k].key = i; Obj[i+k].ord = k; } } for(meth = 0; meth < 4; ++meth) { switch(meth) { case 0: name = "Dtobag"; if(!(dt = dtopen(&Disc, Dtobag)) ) terror("%s: Can't open dictionary", name); break; case 1: name = "Dtbag"; if(!(dt = dtopen(&Disc, Dtbag)) ) terror("%s: Can't open dictionary", name); break; case 2: name = "Dtrhbag"; if(!(dt = dtopen(&Disc, Dtrhbag)) ) terror("%s: Can't open dictionary", name); break; case 3: name = "Dtlist"; if(!(dt = dtopen(&Disc, Dtlist)) ) terror("%s: Can't open dictionary", name); break; default: terror("Unknown storage method"); break; } tinfo("Testing method %s:", name); dtcustomize(dt, DT_SHARE, 1); /* make it more interesting */ /* add all objects into dictionary */ for(k = 0; k < R_OBJ; ++k) for(i = 0; i < N_OBJ/R_OBJ; ++i) { obj = Obj + i*R_OBJ + k; o = (meth == 3 || i%2 == 0) ? dtappend(dt,obj) : dtinsert(dt,obj); if(o != obj) terror("%s: dtappend (key=%d,ord=%d) failed", name, obj->key, obj->ord); } mid = ((N_OBJ/R_OBJ)/2) * R_OBJ; /* key for middle group */ proto.key = mid; proto.ord = -1; if(meth == 3) /* testing ATMOST/ATLEAST for Dtlist */ { /* note that dtappend() was used to keep objects in order of insertion */ if(!(o = dtatmost(dt, &proto)) ) terror("%s: dtatmost (key=%d) failed", name, mid); if(o->ord != 0) terror("%s: dtatmost (key=%d) but ord=%d > 0", name, o->key, o->ord); if(!(o = dtatleast(dt, &proto)) ) terror("%s: dtatleast (key=%d) failed", name, mid); if(o->ord != R_OBJ-1) terror("%s: dtatleast (key=%d) but ord=%d > 0", name, o->key, o->ord); n_obj = 0; /* test ordering */ for(p = NIL(Obj_t*), o = dtfirst(dt); o; p = o, o = dtnext(dt,o) ) { n_obj += 1; if(p && p->ord > o->ord) terror("%s: objects not ordered correctly p=%d > o=%d", name, p->ord, o->ord); } if(n_obj != N_OBJ) terror("%s: Bad object count %d != %d", n_obj, N_OBJ); } if(meth == 0) /* testing ordering properties of Dtobag */ { n_obj = 0; /* test atmost/next */ for(o = dtatmost(dt, &proto); o; o = dtnext(dt,o) ) { if(o->key == mid) n_obj += 1; else break; } if(n_obj != R_OBJ) terror("%s: dtatmost/dtnext count n_obj=%d != %d", name, n_obj, R_OBJ); n_obj = 0; /* test atleast/prev */ for(o = dtatleast(dt, &proto); o; o = dtprev(dt,o) ) { if(o->key == mid) n_obj += 1; else break; } if(n_obj != R_OBJ) terror("%s: dtatleast/dtprev count n_obj=%d != %d", name, n_obj, R_OBJ); n_obj = 0; /* test linear order */ for(p = NIL(Obj_t*), o = dtfirst(dt); o; p = o, o = dtnext(dt,o) ) { n_obj += 1; if(p && p->key > o->key) terror("%s: objects not ordered correctly p=%d > o=%d", name, p->key, o->key); } if(n_obj != N_OBJ) terror("%s: Bad object count %d != %d", n_obj, N_OBJ); } n_mid = n_obj = 0; /* walk forward and count objects */ for(o = dtfirst(dt); o; o = dtnext(dt,o)) { n_obj += 1; if(o->key == mid) n_mid += 1; } if(n_obj != N_OBJ) terror("%s: Walk forward n_obj=%d != %d", name, n_obj, N_OBJ); if(n_mid != R_OBJ) terror("%s: Walk forward n_mid=%d != %d", name, n_mid, R_OBJ); n_mid = n_obj = 0; /* walk backward and count objects */ for(o = dtlast(dt); o; o = dtprev(dt,o)) { n_obj += 1; if(o->key == mid) n_mid += 1; } if(n_obj != N_OBJ) terror("%s: Walk backward n_obj=%d != %d", name, n_obj, N_OBJ); if(n_mid != R_OBJ) terror("%s: Walk backward n_mid=%d != %d", name, n_mid, R_OBJ); n_mid = n_obj = 0; /* walk flattened list and count objects */ for(o = (Obj_t*)dtflatten(dt); o; o = (Obj_t*)dtlink(dt,o) ) { n_obj += 1; if(o->key == mid) n_mid += 1; } if(n_obj != N_OBJ) terror("%s: Walk flattened list n_obj=%d != %d", name, n_obj, N_OBJ); if(n_mid != R_OBJ) terror("%s: Walk flattened list n_mid=%d != %d", name, n_mid, R_OBJ); n_mid = 0; /* delete a bunch of objects */ for(i = 0; i < N_OBJ-1; i += R_OBJ) { obj = Obj + i + R_OBJ/2; /* use the one in the middle of group */ if((o = dtremove(dt, obj)) == obj ) n_mid += 1; else terror("%s: dtremove (key=%d,ord=%d) wrongly yielded (key=%d,ord=%d)", name, obj->key, obj->ord, o->key, o->ord); if((o = dtremove(dt, obj)) != NIL(Obj_t*) ) terror("%s: dtremove (key=%d,ord=%d) wrongly yielded (key=%d,ord=%d)", name, obj->key, obj->ord, o->key, o->ord); if((o = dtdelete(dt, obj)) != NIL(Obj_t*) ) n_mid += 1; else terror("%s: dtdelete matching object to (key=%d,ord=%d) failed", name, obj->key, obj->ord); }
static int genpoints (int attr) { poly_t *pp; int zip, npanxxloc, ctbna; short county, blk; char state, blks; char *s; item_t *itemmem, *itemp; int itemi; int *indp; edge_t *e1p, *e2p; int edgepi; vertex_t *v1p, *v2p, *v3p; int xyi; for ( pp = (poly_t *) dtflatten (polydict); pp; pp = (poly_t *) dtlink (polydict, pp) ) { if (pp->edgepl == 0) continue; e1p = pp->edgeps[0]; if (e1p->p0p == pp) { blks = e1p->blksl; blk = e1p->blkl; ctbna = e1p->ctbnal; county = e1p->countyl; state = e1p->statel; zip = e1p->zipl; npanxxloc = e1p->npanxxlocl; } else { blks = e1p->blksr; blk = e1p->blkr; ctbna = e1p->ctbnar; county = e1p->countyr; state = e1p->stater; zip = e1p->zipr; npanxxloc = e1p->npanxxlocr; } s = NULL; switch (attr) { case T_EATTR_BLKS: if ((state > 0) && (county > 0) && (ctbna > 0) && (blk > 0)) s = sfprints ( "%02d%03d%06d%03d%c", state, county, ctbna, blk, blks ); break; case T_EATTR_BLK: if ((state > 0) && (county > 0) && (ctbna > 0) && (blk > 0)) s = sfprints ("%02d%03d%06d%03d", state, county, ctbna, blk); break; case T_EATTR_BLKG: if ((state > 0) && (county > 0) && (ctbna > 0) && (blk > 0)) s = sfprints ( "%02d%03d%06d%d", state, county, ctbna, blk / 100 ); break; case T_EATTR_CTBNA: if ((state > 0) && (county > 0) && (ctbna > 0)) s = sfprints ("%02d%03d%06d", state, county, ctbna); break; case T_EATTR_COUNTY: if ((state > 0) && (county > 0)) s = sfprints ("%02d%03d", state, county); break; case T_EATTR_STATE: if ((state > 0)) s = sfprints ("%02d", state); break; case T_EATTR_ZIP: if ((zip > 0)) s = sfprints ("%05d", zip); break; case T_EATTR_NPANXXLOC: if ((npanxxloc > -1)) s = sfprints ("%d", npanxxloc); break; case T_EATTR_COUNTRY: s = "USA"; break; } if (!s) continue; if (!(itemmem = malloc (sizeof (item_t)))) { SUwarning (1, "genpoints", "malloc failed for itemmem"); return -1; } itemmem->name = strdup (s); if (!(itemp = dtinsert (itemdict, itemmem))) { SUwarning (1, "genpoints", "dtinsert failed for itemp"); return -1; } if (itemp == itemmem) { itemp->pointn = 0, itemp->pointm = POINTINCR; if (!(itemp->points = malloc (sizeof (point_t) * itemp->pointm))) { SUwarning (1, "genpoints", "malloc failed for points"); return -1; } itemp->indn = 0, itemp->indm = INDINCR; if (!(itemp->inds = malloc (sizeof (int) * itemp->indm))) { SUwarning (1, "genpoints", "malloc failed for inds"); return -1; } itemp->trin = 0, itemp->trim = TRIINCR; if (!(itemp->tris = malloc (sizeof (tri_t) * itemp->trim))) { SUwarning (1, "genpoints", "malloc failed for tris"); return -1; } } orderedges (pp); for (v1p = NULL, edgepi = 0; edgepi < pp->edgepl; edgepi++) { e1p = pp->edgeps[edgepi]; if (!v1p) { if (!(indp = getind (itemp, 0))) { SUwarning (1, "genpoints", "getind failed"); return -1; } if (e1p->p0p == pp) v1p = e1p->v0p, v2p = e1p->v1p; else v1p = e1p->v1p, v2p = e1p->v0p; v3p = v1p; } (*indp)++; if (!getpoint (itemp, v1p->xy)) { SUwarning (1, "genpoints", "getpoint failed (1)"); return -1; } if (v1p == e1p->v0p) { for (xyi = 0; xyi < e1p->xyn; xyi++) { (*indp)++; if (!getpoint (itemp, e1p->xys[xyi])) { SUwarning (1, "genpoints", "getpoint failed (2)"); return -1; } } } else { for (xyi = e1p->xyn - 1; xyi >= 0; xyi--) { (*indp)++; if (!getpoint (itemp, e1p->xys[xyi])) { SUwarning (1, "genpoints", "getpoint failed (3)"); return -1; } } } v1p = NULL; if (edgepi + 1 < pp->edgepl) { e2p = pp->edgeps[edgepi + 1]; if (e2p->v0p == v2p) v1p = e2p->v0p, v2p = e2p->v1p; else if (e2p->v1p == v2p) v1p = e2p->v1p, v2p = e2p->v0p; } if (!v1p) { (*indp)++; if (!getpoint (itemp, v2p->xy)) { SUwarning (1, "genpoints", "getpoint failed (4)"); return -1; } if (savemask & 8) { if (v2p->xy.x != v3p->xy.x || v2p->xy.y != v3p->xy.y) { (*indp)++; if (!getpoint (itemp, v3p->xy)) { SUwarning (1, "genpoints", "getpoint failed (5)"); return -1; } } } } } } itempn = dtsize (itemdict); if (!(itemps = malloc (sizeof (item_t *) * itempn))) { SUwarning (1, "genpoints", "malloc failed for itemps"); return -1; } for ( itemi = 0, itemp = (item_t *) dtflatten (itemdict); itemp; itemp = (item_t *) dtlink (itemdict, itemp) ) itemps[itemi++] = itemp; return 0; }
int checkrecords (void) { vertex_t *vp; edge_t *ep; poly_t *pp; int edgepi; SUmessage (0, "checkrecords", "checking data structure consistency"); for ( vp = (vertex_t *) dtflatten (vertexdict); vp; vp = (vertex_t *) dtlink (vertexdict, vp) ) { for (edgepi = 0; edgepi < vp->edgepl; edgepi++) { ep = vp->edgeps[edgepi]; if (ep->v0p != vp && ep->v1p != vp) SUerror ( "checkrecords", "bad vertex list pointer: %x, %x - %x", ep->v0p, ep->v1p, vp ); if (ep->v0i != edgepi && ep->v1i != edgepi) SUerror ( "checkrecords", "bad vertex list index: %d, %d - %d", ep->v0i, ep->v1i, edgepi ); } } for ( ep = (edge_t *) dtflatten (edgedict); ep; ep = (edge_t *) dtlink (edgedict, ep) ) { if ( !((ep->v0p && ep->v0p->edgeps[ep->v0i] == ep) || (!ep->v0p && ep->v0i == -1)) ) SUerror ( "checkrecords", "vertex error: %d, %d", ep->tlid, ep->v0i ); if ( !((ep->v1p && ep->v1p->edgeps[ep->v1i] == ep) || (!ep->v1p && ep->v1i == -1)) ) SUerror ( "checkrecords", "vertex error: %d, %d", ep->tlid, ep->v1i ); if ( !((ep->p0p && ep->p0p->edgeps[ep->p0i] == ep) || (!ep->p0p && ep->p0i == -1)) ) SUerror ( "checkrecords", "poly error: %d, %d", ep->tlid, ep->p0i ); if ( !((ep->p1p && ep->p1p->edgeps[ep->p1i] == ep) || (!ep->p1p && ep->p1i == -1)) ) SUerror ( "checkrecords", "poly error: %d, %d", ep->tlid, ep->p1i ); } for ( pp = (poly_t *) dtflatten (polydict); pp; pp = (poly_t *) dtlink (polydict, pp) ) { for (edgepi = 0; edgepi < pp->edgepl; edgepi++) { ep = pp->edgeps[edgepi]; if (ep->p0p != pp && ep->p1p != pp) SUerror ( "checkrecords", "bad poly list pointer: %x, %x - %x", ep->p0p, ep->p1p, pp ); if (ep->p0i != edgepi && ep->p1i != edgepi) SUerror ( "checkrecords", "bad poly list pointer: %d, %d - %d", ep->p0i, ep->p1i, edgepi ); } } return 0; }
/* mkConstraintG: */ static graph_t *mkConstraintG(graph_t * g, Dt_t * list, intersectfn intersect, distfn dist) { nitem *p; nitem *nxt = NULL; nitem *nxp; graph_t *vg; node_t *prev = NULL; node_t *root = NULL; node_t *n = NULL; edge_t *e; int lcnt, cnt; int oldval = -INT_MAX; #ifdef OLD double root_val; #endif node_t *lastn = NULL; #ifndef WITH_CGRAPH graph_t *cg = agopen("cg", AGDIGRAPHSTRICT); #else graph_t *cg = agopen("cg", Agstrictdirected, NIL(Agdisc_t *)); agbindrec(cg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); // graph custom data #endif /* count distinct nodes */ cnt = 0; for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { if (oldval != p->val) { oldval = p->val; cnt++; } } /* construct basic chain to enforce left to right order */ oldval = -INT_MAX; lcnt = 0; for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { if (oldval != p->val) { oldval = p->val; /* n = newNode (cg); */ #ifndef WITH_CGRAPH n = agnode(cg, agnameof(p->np)); /* FIX */ #else n = agnode(cg, agnameof(p->np), 1); /* FIX */ agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data #endif ND_alg(n) = p; if (root) { ND_next(lastn) = n; lastn = n; } else { root = n; #ifdef OLD root_val = p->val; #endif lastn = GD_nlist(cg) = n; } alloc_elist(lcnt, ND_in(n)); if (prev) { if (prev == root) alloc_elist(2 * (cnt - 1), ND_out(prev)); else alloc_elist(cnt - lcnt - 1, ND_out(prev)); #ifndef WITH_CGRAPH e = agedge(cg, prev, n); #else e = agedge(cg, prev, n, NULL, 1); agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); // edge custom data #endif ED_minlen(e) = SCALE; ED_weight(e) = 1; elist_append(e, ND_out(prev)); elist_append(e, ND_in(n)); } lcnt++; prev = n; } p->cnode = n; } alloc_elist(0, ND_out(prev)); /* add immediate right neighbor constraints * Construct visibility graph, then perform transitive reduction. * Remaining outedges are immediate right neighbors. * FIX: Incremental algorithm to construct trans. reduction? */ #ifndef WITH_CGRAPH vg = agopen("vg", AGDIGRAPHSTRICT); #else vg = agopen("vg", Agstrictdirected, NIL(Agdisc_t *)); #endif for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { #ifndef WITH_CGRAPH n = agnode(vg, agnameof(p->np)); /* FIX */ #else n = agnode(vg, agnameof(p->np), 1); /* FIX */ agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data #endif p->vnode = n; ND_alg(n) = p; } oldval = -INT_MAX; for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { if (oldval != p->val) { /* new pos: reset nxt */ oldval = p->val; for (nxt = (nitem *) dtlink(link, (Dtlink_t *) p); nxt; nxt = (nitem *) dtlink(list, (Dtlink_t *) nxt)) { if (nxt->val != oldval) break; } if (!nxt) break; } for (nxp = nxt; nxp; nxp = (nitem *) dtlink(list, (Dtlink_t *) nxp)) { if (intersect(p, nxp)) #ifndef WITH_CGRAPH agedge(vg, p->vnode, nxp->vnode); #else agedge(vg, p->vnode, nxp->vnode, NULL, 1); #endif } } /* Remove redundant constraints here. However, the cost of doing this * may be a good deal more than the time saved in network simplex. Also, * if the graph is changed, the ND_in and ND_out data has to be updated. */ mapGraphs(vg, cg, dist); agclose(vg); /* add dummy constraints for absolute values and initial positions */ #ifdef OLD for (n = agfstnode(cg); n; n = agnxtnode(cg, n)) { node_t *vn; /* slack node for absolute value */ node_t *an; /* node representing original position */ p = (nitem *) ND_alg(n); if ((n == root) || (!p)) continue; vn = newNode(cg); ND_next(lastn) = vn; lastn = vn; alloc_elist(0, ND_out(vn)); alloc_elist(2, ND_in(vn)); an = newNode(cg); ND_next(lastn) = an; lastn = an; alloc_elist(1, ND_in(an)); alloc_elist(1, ND_out(an)); #ifndef WITH_CGRAPH e = agedge(cg, root, an); #else e = agedge(cg, root, an, 1); #endif ED_minlen(e) = p->val - root_val; elist_append(e, ND_out(root)); elist_append(e, ND_in(an)); #ifndef WITH_CGRAPH e = agedge(cg, an, vn); #else e = agedge(cg, an, vn, 1); #endif elist_append(e, ND_out(an)); elist_append(e, ND_in(vn)); #ifndef WITH_CGRAPH e = agedge(cg, n, vn); #else e = agedge(cg, n, vn, 1); #endif elist_append(e, ND_out(n)); elist_append(e, ND_in(vn)); } #endif /* OLD */ return cg; }
/* mkNConstraintG: * Similar to mkConstraintG, except it doesn't enforce orthogonal * ordering. If there is overlap, as defined by intersect, the * nodes will kept/pushed apart in the current order. If not, no * constraint is enforced. If a constraint edge is added, and it * corresponds to a real edge, we increase the weight in an attempt * to keep the resulting shift short. */ static graph_t *mkNConstraintG(graph_t * g, Dt_t * list, intersectfn intersect, distfn dist) { nitem *p; nitem *nxp; node_t *n; edge_t *e; node_t *lastn = NULL; #ifndef WITH_CGRAPH graph_t *cg = agopen("cg", AGDIGRAPHSTRICT); #else graph_t *cg = agopen("cg", Agstrictdirected, NIL(Agdisc_t *)); agbindrec(cg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); // graph custom data #endif for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { #ifndef WITH_CGRAPH n = agnode(cg, agnameof(p->np)); /* FIX */ #else n = agnode(cg, agnameof(p->np), 1); /* FIX */ agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data #endif ND_alg(n) = p; p->cnode = n; alloc_elist(0, ND_in(n)); alloc_elist(0, ND_out(n)); if (lastn) { ND_next(lastn) = n; lastn = n; } else { lastn = GD_nlist(cg) = n; } } for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { for (nxp = (nitem *) dtlink(link, (Dtlink_t *) p); nxp; nxp = (nitem *) dtlink(list, (Dtlink_t *) nxp)) { e = NULL; if (intersect(p, nxp)) { double delta = dist(&p->bb, &nxp->bb); #ifndef WITH_CGRAPH e = agedge(cg, p->cnode, nxp->cnode); #else e = agedge(cg, p->cnode, nxp->cnode, NULL, 1); agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); // edge custom data #endif assert (delta <= 0xFFFF); ED_minlen(e) = delta; ED_weight(e) = 1; } if (e && agfindedge(g,p->np, nxp->np)) { ED_weight(e) = 100; } #if 0 if (agfindedge(g,p->np, nxp->np)) { if (e == NULL) e = agedge(cg, p->cnode, nxp->cnode); ED_weight(e) = 100; /* If minlen < SCALE, the nodes can't conflict or there's * an overlap but it will be removed in the orthogonal pass. * So we just keep the node's basically where they are. */ if (SCALE > ED_minlen(e)) ED_minlen(e) = SCALE; } #endif } } for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { n = p->cnode; for (e = agfstout(cg,n); e; e = agnxtout(cg,e)) { elist_append(e, ND_out(n)); elist_append(e, ND_in(aghead(e))); } } /* We could remove redundant constraints here. However, the cost of doing * this may be a good deal more than the time saved in network simplex. * Also, if the graph is changed, the ND_in and ND_out data has to be * updated. */ return cg; }