# To unbundle, sh this file echo README 1>&2 sed 's/.//' >README <<'//GO.SYSIN DD README' -this is some source to help you read polyhedra files. -i am disinclined to put all of the 9th edition clibrary in -here so i just include getfields. the only problem you might -have is fio (F* routines). just change - Fprint fprintf - sprint sprintf - fprint fprintf (unbuffered) - Fgetc getc - Fflush flush -(its not hard). -let me know of any comments and i will update this readme //GO.SYSIN DD README echo getfields.c 1>&2 sed 's/.//' >getfields.c <<'//GO.SYSIN DD getfields.c' -#include - -static char is_sep[256], is_field[256]; -static init = 0; - -void -setfields(arg) - char *arg; -{ - register unsigned char *s = (unsigned char *)arg; - - memset(is_sep, 0, sizeof is_sep); - memset(is_field, 1, sizeof is_field); - while(*s){ - is_sep[*s] = 1; - is_field[*s++] = 0; - } - is_field[0] = 0; - init = 1; -} - -getfields(ss, sp, nptrs) - char *ss; - char **sp; -{ - register unsigned char *s = (unsigned char *)ss; - register unsigned char **p = (unsigned char **)sp; - register unsigned c; - - if(init == 0) - setfields(" \t"); - for(;;){ - if(*s == 0) break; - if(--nptrs < 0) break; - *p++ = s; - while(is_field[c = *s++]); - if(c == 0) break; - s[-1] = 0; - } - if(nptrs > 0) - *p = 0; - else if(--s >= (unsigned char *)ss) - *s = c; - return(p - (unsigned char **)sp); -} - -getmfields(ss, sp, nptrs) - char *ss; - char **sp; -{ - register unsigned char *s = (unsigned char *)ss; - register unsigned char **p = (unsigned char **)sp; - register unsigned c; - unsigned char *goo; - - if(init == 0) - setfields(" \t"); - if(*s){ - while(nptrs-- > 0){ - *p++ = s; - while(is_field[*s++]); - goo = s-1; - if((c = *goo) == 0) - break; - *goo = 0; - while(is_sep[*s]) s++; - if(*s == 0) break; - } - } - if(nptrs > 0) /* plenty of room */ - *p = 0; - else if(*s) /* no room and we found a trailing non-is_seper */ - *goo = c; - return(p - (unsigned char **)sp); -} - -#ifdef MAIN -#include - -main() -{ - char *fields[256]; - char *s; - int n, i; - - print("go:\n"); - while(s = Frdline(0)){ - n = getmfields(s, fields, 3); - for(i = 0; i < n; i++) - Fprint(1, ">%s< ", fields[i]); - Fputc(1, '\n'); - Fflush(1); - } - exit(0); -} -#endif //GO.SYSIN DD getfields.c echo poly.h 1>&2 sed 's/.//' >poly.h <<'//GO.SYSIN DD poly.h' -#define POLYDB "../poly" -#define MAXPOLY 4096 - -typedef struct Value -{ - double v; - char *code; -} Value; - -typedef struct Vertex -{ - Value x, y, z; -} Vertex; - -typedef struct Dihedral -{ - Value d; - short sc; /* if nonzero s, c are set */ - short count; - short *fe; /* f,e * count */ - Value s, c; -} Dihedral; - -typedef struct Hinge -{ - short f1, s1, f2, s2; - Value d; /* dihedral angle (>PI is reverse fold) */ -} Hinge; - -typedef struct Polyhedron -{ - short number; - char *name; - char *comment; - char *dual; - char *symbol; - char *sfaces; - char *svertices; - short nvertices, nnet; - Vertex *vertices; - short nface; - short maxface; /* max number of sides in a face */ - short **net; - short **solid; - short ndih; - Dihedral *dih; - short nhinges; - Hinge *hinges; - short ndgoo; - Hinge *dgoo; -} Polyhedron; - -extern char *poly_field(); //GO.SYSIN DD poly.h echo poly_field.c 1>&2 sed 's/.//' >poly_field.c <<'//GO.SYSIN DD poly_field.c' -#include "libc.h" -#include "fio.h" -#include "poly.h" -#include -#include - -static char *buf; -static long size; -typedef struct Field -{ - char *field; - char *start; -} Field; -Field poly_ffields[100]; -static nfields; - -static -cmp(a, b) - Field *a, *b; -{ - return(strcmp(a->field, b->field)); -} - -poly_ifield(s) - char *s; -{ - int fd; - struct stat sbuf; - - if((fd = open(s, 0)) < 0){ - perror(s); - return(1); - } - if(fstat(fd, &sbuf) < 0){ - perror(s); - return(1); - } - if(sbuf.st_size >= size){ - if(buf == 0) - buf = malloc((unsigned)(size = sbuf.st_size+1)); - else - buf = realloc(buf, (unsigned)(size = sbuf.st_size+1)); - } - if(read(fd, buf, (int)sbuf.st_size) != sbuf.st_size){ - perror("read"); - return(1); - } - close(fd); - buf[sbuf.st_size] = 0; - for(s = buf; *s; s++) - if(*s == '\n') *s = 0; - for(s = buf, nfields = 0; *s;){ - if(*s == ':'){ - *s++ = 0; - if(strcmp(s, "EOF") == 0) - break; - poly_ffields[nfields].field = s; - while(*s++); - poly_ffields[nfields++].start = s; - } - while(*s++); - } - qsort((char *)poly_ffields, nfields, sizeof(Field), cmp); - poly_ffields[nfields].field = 0; - return(0); -} - -char * -poly_field(s) - char *s; -{ /* body duplicated in rfield */ - register l, m, h; - - if(strcmp(s, poly_ffields[0].field) < 0) - return((char *)0); - for(l = 0, h = nfields; l != h-1;){ - m = (l+h)/2; - if(strcmp(s, poly_ffields[m].field) < 0) - h = m; - else - l = m; - } - return(strcmp(s, poly_ffields[l].field)? (char *)0 : poly_ffields[l].start); -} - -poly_rfield(f, s) - char *f, *s; -{ /* body duplicated in field */ - register l, m, h; - - if(strcmp(s, poly_ffields[0].field) < 0) - l = nfields; - else { - for(l = 0, h = nfields; l != h-1;){ - m = (l+h)/2; - if(strcmp(s, poly_ffields[m].field) < 0) - h = m; - else - l = m; - } - if(strcmp(s, poly_ffields[l].field)) - l = nfields; - } - if(l == nfields){ - nfields++; - poly_ffields[l].field = f; - } - poly_ffields[l].start = s; -} //GO.SYSIN DD poly_field.c echo poly_lk.c 1>&2 sed 's/.//' >poly_lk.c <<'//GO.SYSIN DD poly_lk.c' -#include "libc.h" -#include "fio.h" -#include "poly.h" - -static char names[MAXPOLY][128]; -static int ns; - -poly_lk(s) - char *s; -{ - register i; - register char *ss; - char buf[128]; - int n = strlen(s); - static doread = 1; - - for(ss = s; *ss; ss++) - if((*ss < '0') || (*ss > '9')) break; - if(*ss == 0) - { - n = atoi(s); - sprint(buf, "%s/%d", POLYDB, n); - if(access(buf, 4) == 0) - return(n); - fprint(2, "number %d out of range\n", n); - return(-1); - } - if(doread){ - readnames(); - doread = 0; - } - for(i = 0; i < ns; i++) - if(strncmp(&names[i][0], s, n) == 0) return(i); - fprint(2, "no solid '%s'\n", s); - return(-1); -} - -readnames() -{ - register i, fd; - register char *s; - char buf[128]; - - sprint(buf, "%s/index", POLYDB); - if((fd = open(buf, 0)) < 0){ - perror(buf); - exit(1); - } - ns = 0; - while(s = Frdline(fd)){ - i = atoi(s); - s = strchr(s, '\t'); - strcpy(&names[i][0], s+1); - if(i >= ns) - ns = i+1; - } - close(fd); -} //GO.SYSIN DD poly_lk.c echo poly_read.c 1>&2 sed 's/.//' >poly_read.c <<'//GO.SYSIN DD poly_read.c' -#include "libc.h" -#include "string.h" -#include "fio.h" -#include "poly.h" - -static short **facelist(); -#define SPLIT(s) getmfields(s, ptr, sizeof ptr/sizeof ptr[0]) - -poly_read(p, dir, n) - register Polyhedron *p; - char *dir; -{ - char buf[128]; - char *s, *nexts; - int i, j, k; - short *sp; - char *ptr[10]; - - sprint(buf, "%s/%d", dir? dir:POLYDB, n); - if(poly_ifield(buf)) - return(1); - p->number = atoi(poly_field("number")); - p->name = strdup(poly_field("name")); - p->comment = strdup(poly_field("comment")); - p->symbol = strdup(poly_field("symbol")); - p->dual = strdup(poly_field("dual")); - p->sfaces = strdup(poly_field("sfaces")); - p->svertices = strdup(poly_field("svertices")); - s = poly_field("vertices"); - if(p->nvertices = atoi(s)){ - p->vertices = (Vertex *)malloc(p->nvertices*sizeof(Vertex)); - for(nexts = s; *nexts++;); - if(SPLIT(s) == 2) - p->nnet = atoi(ptr[1]); - else - p->nnet = p->nvertices; - for(i = 0, s = nexts; *s; s = nexts, i++){ - for(nexts = s; *nexts++;); - if(SPLIT(s) != 3){ - fprint(2, "bad vertex in file %s (next line is %s)\n", buf, nexts); - return(1); - } - rdvalue(&p->vertices[i].x, ptr[0]); - rdvalue(&p->vertices[i].y, ptr[1]); - rdvalue(&p->vertices[i].z, ptr[2]); - } - if(i != p->nvertices){ - fprint(2, "%s: expected %d vertices, read %d\n", buf, - p->nvertices, i); - return(1); - } - } - p->maxface = 0; - p->nface = 0; - p->net = facelist(p, "net", buf); - p->solid = facelist(p, "solid", buf); - s = poly_field("hinges"); - if(p->nhinges = atoi(s)){ - p->hinges = (Hinge *)malloc(p->nhinges*sizeof(Hinge)); - while(*s++); - for(i = 0; *s; s = nexts, i++){ - for(nexts = s; *nexts++;); - if(SPLIT(s) != 5){ - fprint(2, "%s: bad hinge line\n", buf); - return(1); - } - p->hinges[i].f1 = atoi(ptr[0]); - p->hinges[i].s1 = atoi(ptr[1]); - p->hinges[i].f2 = atoi(ptr[2]); - p->hinges[i].s2 = atoi(ptr[3]); - rdvalue(&p->hinges[i].d, ptr[4]); - } - if(i != p->nhinges){ - fprint(2, "%s: expected %d hinges, read %d\n", buf, - p->nhinges, i); - return(1); - } - } - s = poly_field("dihedral"); - if(p->ndih = atoi(s)){ - p->dih = (Dihedral *)malloc(p->ndih*sizeof(Dihedral)); - while(*s++); - for(i = 0; i < p->ndih; s = nexts, i++){ - for(nexts = s; *nexts++;); - k = SPLIT(s); - if(k == 4){ - rdvalue(&p->dih[i].s, ptr[2]); - rdvalue(&p->dih[i].c, ptr[3]); - p->dih[i].sc = 1; - k -= 2; - } else - p->dih[i].sc = 0; - if(k != 2){ - fprint(2, "%s: bad dihedral count\n", buf); - return(1); - } - k = p->dih[i].count = atoi(ptr[0]); - rdvalue(&p->dih[i].d, ptr[1]); - s = nexts; - if(k){ - sp = p->dih[i].fe = (short *)malloc(2*k*sizeof(short)); - for(j = 0; j < k; s = nexts, j++){ - for(nexts = s; *nexts++;); - if(SPLIT(s) != 2){ - fprint(2, "%s: bad face-edge\n", buf); - return(1); - } - *sp++ = atoi(ptr[0]); - *sp++ = atoi(ptr[1]); - } - } else - p->dih[i].fe = 0; - } - if(i != p->ndih){ - fprint(2, "%s: expected %d dihedrals, read %d\n", buf, - p->ndih, i); - return(1); - } - } - s = poly_field("dih"); - if(p->ndgoo = atoi(s)){ - p->dgoo = (Hinge *)malloc(p->ndgoo*sizeof(Hinge)); - while(*s++); - for(i = 0; *s; s = nexts, i++){ - for(nexts = s; *nexts++;); - if(SPLIT(s) != 4){ - fprint(2, "%s: bad dgoo line\n", buf); - return(1); - } - p->dgoo[i].f1 = atoi(ptr[0]); - p->dgoo[i].s1 = atoi(ptr[1]); - p->dgoo[i].f2 = atoi(ptr[2]); - rdvalue(&p->dgoo[i].d, ptr[3]); - } - if(i != p->ndgoo){ - fprint(2, "%s: expected %d dgoo, read %d\n", buf, - p->ndgoo, i); - return(1); - } - } - return(0); -} - -rdvalue(v, s) - Value *v; - register char *s; -{ - v->v = atof(s); - while(*s && (*s != '[')) - s++; - if(*s == '['){ - char *ss = ++s; - - while(*s && (*s != ']')) - s++; - *s = 0; - v->code = strdup(ss); - } else - v->code = 0; -} - -static short ** -facelist(p, ss, file) - Polyhedron *p; - char *ss, *file; -{ - char *s, *nexts; - char *ptr[100]; - int i, j, k, n; - short **ret; - - s = poly_field(ss); - if(atoi(s) == 0) - return((short **)0); - nexts = strchr(s, 0)+1; - if(SPLIT(s) != 2){ - fprint(2, "%s: bad count line for '%s'\n", file, ss); - return((short **)0); - } - n = atoi(ptr[0]); - p->maxface = atoi(ptr[1]); - if(p->nface){ - if(p->nface != n){ - fprint(2, "%s: nface disagreement: %d vs %d\n", file, - p->nface, n); - return((short **)0); - } - } else - p->nface = n; - ret = (short **)malloc(p->nface*sizeof(short *)); - s = nexts; - for(i = 0; *s && (i < p->nface); i++, s = nexts){ - nexts = strchr(s, 0)+1; - SPLIT(s); - k = atoi(ptr[0]); - ret[i] = (short *)malloc((k+1)*sizeof(short)); - for(j = 0; j <= k; j++) - ret[i][j] = atoi(ptr[j]); - } - return(ret); -} //GO.SYSIN DD poly_read.c echo poly_write.c 1>&2 sed 's/.//' >poly_write.c <<'//GO.SYSIN DD poly_write.c' -#include "libc.h" -#include "fio.h" -#include "poly.h" - -typedef struct Field -{ - char *field; - char *start; -} Field; -extern Field poly_ffields[]; - -poly_write(p, fd) - register Polyhedron *p; -{ - int i, j, k; - short *sp; - - Fprint(fd, ":name\n%s\n", p->name); - Fprint(fd, ":number\n%d\n", p->number); - Fprint(fd, ":comment\n%d\n", p->comment); - if(*p->symbol) - Fprint(fd, ":symbol\n%s\n", p->symbol); - if(*p->dual) - Fprint(fd, ":dual\n%s\n", p->dual); - if(*p->sfaces) - Fprint(fd, ":sfaces\n%s\n", p->sfaces); - if(*p->svertices) - Fprint(fd, ":svertices\n%s\n", p->svertices); - if(p->net) - wrlist(p->net, p->nface, p->maxface, "net", fd); - if(p->solid) - wrlist(p->solid, p->nface, p->maxface, "solid", fd); - if(p->nhinges){ - Fprint(fd, ":hinges\n%d\n", p->nhinges); - for(i = 0; i < p->nhinges; i++){ - Fprint(fd, "%d %d %d %d ", p->hinges[i].f1, - p->hinges[i].s1, p->hinges[i].f2, p->hinges[i].s2); - wrvalue(&p->hinges[i].d, fd); - Fputc(fd, '\n'); - } - } - if(p->ndih){ - Fprint(fd, ":dihedral\n%d\n", p->ndih); - for(i = 0; i < p->ndih; i++){ - Fprint(fd, "%d ", k = p->dih[i].count); - wrvalue(&p->dih[i].d, fd); - if(p->dih[i].sc){ - wrvalue(&p->dih[i].s, fd); - Fputc(fd, ' '); - wrvalue(&p->dih[i].c, fd); - } - Fputc(fd, '\n'); - if(k){ - sp = p->dih[i].fe; - for(j = 0; j < k; j++){ - Fprint(fd, "%d %d\n", sp[0], sp[1]); - sp += 2; - } - } - } - } - if(p->ndgoo){ - Fprint(fd, ":dih\n%d\n", p->ndgoo); - for(i = 0; i < p->ndgoo; i++){ - Fprint(fd, "%d %d %d ", p->dgoo[i].f1, p->dgoo[i].s1, - p->dgoo[i].f2); - wrvalue(&p->dgoo[i].d, fd); - Fputc(fd, '\n'); - } - } - if(p->nvertices){ - Fprint(fd, ":vertices\n%d %d\n", p->nvertices, p->nnet); - for(i = 0; i < p->nvertices; i++){ - wrvalue(&p->vertices[i].x, fd); - Fputc(fd, ' '); - wrvalue(&p->vertices[i].y, fd); - Fputc(fd, ' '); - wrvalue(&p->vertices[i].z, fd); - Fputc(fd, '\n'); - } - } - Fprint(fd, ":EOF\n"); - Fflush(fd); - return(0); -} - -wrvalue(v, fd) - Value *v; -{ - Fprint(fd, "%.17g", v->v); - if(v->code) - Fprint(fd, "[%s]", v->code); -} - -wrlist(list, n, max, str, fd) - register short **list; - char *str; -{ - register short *p; - register i, k; - - Fprint(fd, ":%s\n%d %d\n", str, n, max); - for(i = 0; i < n; i++){ - p = list[i]; - Fprint(fd, "%d", k = *p++); - while(k--) - Fprint(fd, " %d", *p++); - Fputc(fd, '\n'); - } -} //GO.SYSIN DD poly_write.c .