/* Last edited on 2007-02-04 16:10:30 by stolfi */ /* ---------------------------------------------------------------------- */ /* Cube.c */ void PrintCubePlaces(Place_t p); /* Prints the 8 places with the same negative cell as {p}, assuming the cell is a cube. */ void PrintCubePlaces(Place_t p) { auto void PrintPnegsOfWall(Place_t s); void PrintPnegsOfWall(Place_t s) { Place_t t = s; do { PrtPnegNum(t); t = PrevE(t); } while (t != s); } PrintPnegsOfWall(p); Place_t t = p; do { PrintPnegsOfWall(Clock(PrevF(t))); t = PrevE(t); } while (t != p); t = PrevF(PrevE(PrevF(p))); PrintPnegsOfWall(t); } /* ---------------------------------------------------------------------- */ /* CubeMake */ pv.el[t + 3] = sq.el[2]; pv.el[t + 2] = Flip0(sq.el[3]); pv.el[t + 10] = sq.el[1]; pv.el[t + 11] = Flip0(sq.el[1]); pv.el[t + 9] = sq.el[3]; pv.el[t + 8] = Flip0(sq.el[3]); /* ---------------------------------------------------------------------- */ NodeOrCell_t Org(Place_t p); /* Returns the element record that is currently stored in the `origin node' slot of of {p}. */ /* ---------------------------------------------------------------------- */ typedef struct EdgeRec_t { ...; bool_t marks2[2]; /* Used by Numberedges, ex: marks2[SpinBit(a)] associated to edge */ } EdgeRec_t; typedef struct WallRec_t { ...; bool_t marks2[2]; /* Used by {RenumberWalls}, ex: marks2[DualBit(a)] associated to Wall */ } WallRec_t; /* ---------------------------------------------------------------------- */ struct WedgeRec_t { ...; bool_t marks1; /* [???]. */ bool_t marks2[2]; /* Used by {EnumNodes}, {EnumWedges}; indexed by {OrientationBit} [!!!] */ uint ind; /* Used by {RenumberEdges}, {RenumberWalls}, etc. */ ...; } WedgeRec_t; /* #default WedgeRec_t.ind 0 */ /* #default WedgeRec_t.marks1 FALSE */ Edge_vec_t RenumberEdges(Place_vec_t *pv); /* Collects and renumbers all (primal) edges reachable from {pv[0..pv.nel-1]}. */ Wall_vec_t RenumberWalls(Place_vec_t *pv); /* Collects and renumbers all (primal) walls reachable from {pv[0..pv.nel-1]}. */ Place_vec_t RenumberEdgesOutOfNodes(Place_vec_t *pv); /* Collects and renumbers all (primal) edges with the same origin nodes as the places {pv[0..pv.nel-1]}. */ #define INIT_STACK_SIZE 1024 Edge_vec_t RenumberEdges(Place_vec_t *pv) { /* [!!! ???] Note: I change the SpinBit by DualBit for purpouses of gluing octahedra. */ Edge_vec_t estack = Edge_vec_new(INIT_STACK_SIZE); Place_vec_t pstack = Place_vec_new(INIT_STACK_SIZE); uint top = 0; /* top for stack "estack" */ uint nstack = 0; /* top for stack "pstack" */ auto void VisitAndMark(Place_t t); /* If {t} is unmarked: visit, mark, and stack it. */ void VisitAndMark(Place_t t) { Wedge_t w = PWedge(t); if ((w->ind < nstack) && (PWedge(pstack.el[w->ind]) == w)) { /* Wedge of {t} is already marked, not do nothing */ } else { /* Wedge of {t} is not marked. */ Edge_t e = PWedge(t)->edge; if (! e->marks2[DualBit(t)]) { /* Edge {e} is not marked; mark it and all edges of places adjacents to {t} */ Place_t tn = t; do { Edge_t en = PWedge(tn)->edge; en->marks2[DualBit(tn)] = TRUE; tn = NextF(tn); } while (tn != t); /* Save the edge {e} in {estack}: */ Edge_vec_expand(&estack,top);; estack.el[top] = e; /* Make {t} its entry place: */ e->pa = t; e->num = top; top++; } Place_vec_expand(&pstack,nstack); w->ind = nstack; pstack.el[nstack] = t; nstack++; } } uint seen = 0; /* Number of wedges whose childeren were looked at */ /* Stack the root places: */ int i; for (i = 0; i < pv->nel; i++) { VisitAndMark (pv->el[i]); } /* Enumerate edges, number them, collect in {estack}: */ while (seen < nstack) { Place_t s = pstack.el[seen]; VisitAndMark(NextF(s)); VisitAndMark(NextF(PrevE(s))); VisitAndMark(NextE(s)); VisitAndMark(PrevF(s)); seen++; } /* Erase all marks */ while (nstack > 0) { nstack--; Place_t b = pstack.el[nstack]; Place_t atn = b; do { PWedge(atn)->edge->marks2[DualBit(atn)] = FALSE; atn= NextF(atn); } while (atn != b); } /* Reclaim {pstack}, trim {estack}, and return it: */ Place_vec_trim(&pstack,0); Edge_vec_trim(&estack,top); return estack; } Place_vec_t RenumberEdgesOutOfNodes(Place_vec_t *pv) { Place_vec_t estack = Place_vec_new(20); Place_vec_t pstack = Place_vec_new(20); uint top = 0; /* top for stack "estack" */ uint nstack = 0; /* top for stack "nstack" */ uint seen = 0; /* Wedges already seen. */ auto void VisitAndMark(Place_t t); /* If t is unmarked: visit, mark, and stack it. */ void VisitAndMark(Place_t t) { Wedge_t w = PWedge(t); if ((w->ind < nstack) && (PWedge(pstack.el[w->ind]) == w)) { /* wedge is already marked, do nothing */ } else { if (! w->marks2[DualBit(t)]) { /* mark PWedge(t)->edge and of all places with same edge as {t}. */ Place_t tn = t; do { PWedge(tn)->marks2[DualBit(tn)] = TRUE; tn = NextF(tn); } while (tn != t); /* Assign {w} a new serial number: */ w->edge->dg = top; /* Add {t} to the list {estack}: */ Place_vec_expand(&estack,top);; estack.el[top] = t; top++; } /* Add {t} to {pstack}: */ Place_vec_expand(&pstack,nstack); w->ind = nstack; pstack.el[nstack] = t; nstack++; } } /* Stack the root pointers: */ int i; for (i = 0; i < pv->nel; i++) { VisitAndMark(pv->el[i]); } /* Enumerate reachable places: */ while (seen < nstack) { Place_t s = pstack.el[seen]; if (DualBit(s) == 0) { VisitAndMark(ONext(s)); VisitAndMark(ONext(NextF(s))); } else { VisitAndMark(Clock(ONext(s))); VisitAndMark(Clock(ONext(NextF(s)))); } seen++; } /* Erase all marks */ while (nstack > 0) { nstack--; Place_t b = pstack.el[nstack]; Place_t atn = b; do { PWedge(atn)->marks2[DualBit(atn)] = FALSE; atn = NextF(atn); } while (atn != b); } /* Reclaim {pstack}, trim {estack} and return it: */ Place_vec_trim(&pstack,0); Place_vec_trim(&estack,top); return estack; } Wall_vec_t RenumberWalls(Place_vec_t *pv) { Wall_vec_t estack = Wall_vec_new(INIT_STACK_SIZE); Place_vec_t pstack = Place_vec_new(INIT_STACK_SIZE); uint top = 0; /* top for stack "estack" */ uint nstack = 0; /* top for stack "pstack" */ auto void VisitAndMark(Place_t t); /* If {t} is unmarked: visit, mark, and stack it. */ void VisitAndMark(Place_t t) { Wedge_t w = PWedge(t); if ((w->ind < nstack) && (PWedge(pstack.el[w->ind]) == w)) { /* Wedge of {t} is already marked, not do nothing */ } else { /* Wedge of {t} is not marked. */ Wall_t e = PWedge(t)->wall; /* if component wall of @place "t" not are marked, then */ if (! e->marks2[DualBit(t)]) { /* Wall {e} is not marked; mark it and all walls of places adjacents to {t} */ Place_t tn = t; do { Wall_t en = PWedge(tn)->wall; en->marks2[DualBit(tn)] = TRUE; tn = PrevE(tn); } while (tn != t); /* Save the wall {e} in {estack}: */ Wall_vec_expand(&estack,top); estack.el[top] = e; /* Make {t} its entry place: */ estack.el[top]->pa = t; e->num = top; top++; } Place_vec_expand(&pstack,nstack); w->ind = nstack; pstack.el[nstack] = t; nstack++; } } uint seen = 0; /* Number of wedges whose childeren were looked at */ int i; for (i = 0; i < pv->nel; i++) { VisitAndMark (pv->el[i]); } /* Enumerate walls, number them, collect in {estack}: */ while (seen < nstack) { Place_t s = pstack.el[seen]; VisitAndMark(NextF(s)); VisitAndMark(NextF(PrevE(s))); VisitAndMark(NextE(s)); VisitAndMark(PrevF(s)); seen++; } /* Erase all marks */ while (nstack > 0) { nstack--; Place_t b = pstack.el[nstack]; Place_t atn = b; do { PWedge(atn)->wall->marks2[DualBit(atn)] = FALSE; atn= PrevE(atn); } while (atn != b); } /* Reclaim {pstack}, trim {estack}, and return it: */ Place_vec_trim(&pstack,0); Wall_vec_trim(&estack,top); return estack; } /* ---------------------------------------------------------------------- */ uint m = digits(top.wedge.nel) + 1; fprintf(stderr, "\n"); fprintf(stderr, "nodes = %*d\n", m, top.node.nel); fprintf(stderr, "edges = %*d\n", m, top.edge.nel); fprintf(stderr, "walls = %*d\n", m, top.wall.nel); fprintf(stderr, "cells = %*d\n", m, top.cell.nel); fprintf(stderr, "\n"); fprintf(stderr, "wedges = %*d\n", m, top.wedge.nel); fprintf(stderr, "\n"); /* ---------------------------------------------------------------------- */ void WriteCoord(double x) { fprintf(st, Fmt.Pad(Fmt.LongReal(x, Fmt.Style.Sci, prec = 3), 7)); } WriteCoord; void WritePoint(*c: r4_t) { WriteCoord(c[0]); fprintf(st, " "); WriteCoord(c[1]); fprintf(st, " "); WriteCoord(c[2]); fprintf(st, " "); WriteCoord(c[3]); } WritePoint; {