This is dgstream.c in view mode; [Download] [Up]
/* Copyright (c) 1992 The Geometry Center; University of Minnesota 1300 South Second Street; Minneapolis, MN 55454, USA; This file is part of geomview/OOGL. geomview/OOGL is free software; you can redistribute it and/or modify it only under the terms given in the file COPYING, which you should have received along with this file. This and other related software may be obtained via anonymous ftp from geom.umn.edu; email: software@geom.umn.edu. */ /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */ #include <ctype.h> #include "sl2c.h" /* in case file has elements of SL(2,C) */ #include "discgrpP.h" #include <string.h> #include "mgP.h" #include "streampool.h" #include "transobj.h" #include "handleP.h" #define DG_GROUPNAME 1 #define DG_COMMENT 2 #define DG_ATTRIBUTE 3 #define DG_MODEL 4 #define DG_NGENS 5 #define DG_NELS 6 #define DG_GENS 7 #define DG_ELS 8 #define DG_DIMN 9 #define DG_CAMGEOM 10 #define DG_GEOM 11 #define DG_CAMGEOMFILE 12 #define DG_GEOMFILE 13 #define DG_WAFILE 14 #define DG_MATRIXGROUP 15 #define DG_CPOINT 16 #define DG_ENUMDEPTH 17 #define DG_ENUMDIST 18 #define DG_DSPYATTR 19 #define DG_SCALE 20 #define DG_C2M 21 #define DG_NUMKEYWORDS 23 /* 2 redundant keywords */ keytokenpair keytokenlist[] = { "group", DG_GROUPNAME, "comment", DG_COMMENT, "attribute", DG_ATTRIBUTE, "model", DG_MODEL, "ngens", DG_NGENS, "nels", DG_NELS, "gens", DG_GENS, "els", DG_ELS, "dimn", DG_DIMN, "dimension", DG_DIMN, "camgeom", DG_CAMGEOM, "geom", DG_GEOM, "camgeomfile", DG_CAMGEOMFILE, "geomfile", DG_GEOMFILE, "wafile", DG_WAFILE, "matrixgroup", DG_MATRIXGROUP, "mgroup", DG_MATRIXGROUP, "cpoint", DG_CPOINT, "enumdepth", DG_ENUMDEPTH, "enumdist", DG_ENUMDIST, "display", DG_DSPYATTR, "scale", DG_SCALE, "cam2model", DG_C2M }; keytokenpair attr_list[DG_NUM_ATTR] = { "hyperbolic", DG_HYPERBOLIC, "euclidean", DG_EUCLIDEAN, "spherical", DG_SPHERICAL, "finite", DG_FINITE, "transposed", DG_TRANSPOSED, "conformalball", DG_CONFORMALBALL, "upperhalfspace", DG_UPPERHALFSPACE, "projective", DG_PROJECTIVEMODEL }; keytokenpair dspyattr_list[DG_NUM_DSPYATTR] = { "centercam", DG_CENTERCAM, "zcull", DG_ZCULL, "drawcam", DG_DRAWCAM, "drawdirdom", DG_DRAWDIRDOM, "drawgeom", DG_DRAWGEOM }; /* Name can be {GL | SL | SO } ( {n},{k},{R | C} ) */ matrixgroup cgroup = { DG_GENERAL | DG_REAL, 4, 0}; static char delims[] = "%{}();"; static char errfmt[] = "Reading discrete group from \"%s\": %s"; static int token_from_string(char *s, keytokenpair *kl, int n) { int i; for (i=0; i<n; ++i) { if (strcasecmp(s, kl[i].key) == 0) return (kl[i].token); } return (0); } /* following gets the next %keyword from file. returns 0 if EOF, otherwise 1 */ static int get_keyword(fp, keyword, fname) FILE *fp; char keyword[]; char *fname; { char t; t = fnextc(fp, 0); if (t == '\377') { /* EOF */ getc(fp); return(0); } else if (t == '}') { /* end of discgrp description? */ return(0); } if (t != '(') { OOGLSyntax(fp,"Reading discrete group from \"%s\": expected (", fname); return(0); } /* discard 't': it's OK */ getc(fp); sprintf(keyword, "%.31s", fdelimtok(delims, fp, 0)); return 1; } static int get_matching_parenthesis(FILE *fp, char *fname) { char t; t = fnextc(fp, 0); if (t == EOF) return(0); if (t != ')') { OOGLSyntax(fp,"Reading discrete group from \"%s\": expected matching )", fname); return(0); } getc(fp); return(1); } static FILE * included_file(fp) FILE *fp; { char *name; if (fnextc(fp, 0) == '<') /* read from file */ { name = fdelimtok(delims, fp, 0); OOGLError(1,"Discrete groups: including files not implemented"); return(NULL); } return(NULL); } static int parse_group_name(char *gname) { char *gptr = gname; cgroup.attributes = DG_GENERAL | DG_REAL; /* type of entry */ cgroup.dimn = 4; /* dimension of matrices */ cgroup.sig = 0; /* signature of quadratic form */ } static ColorA white = {1,1,1,.75}; static void get_el_list( DiscGrp *discgrp, DiscGrpElList *dgellist, FILE *fp, char *fname) { int i; char *name, c; if (included_file(fp)) /* read from file */ { } for (i=0; i<dgellist->num_el; ++i) { dgellist->el_list[i].attributes = 0; dgellist->el_list[i].color = white; dgellist->el_list[i].inverse = NULL; c = fnextc(fp, 0); /* get the name if it's alphabetic */ if ( c >= 'A' && c <= 'z' ) { name = fdelimtok(delims, fp, 0); if (strlen(name) > DG_WORDLENGTH) { OOGLSyntax(fp,"Reading discrete group from \"%s\": Words limited to length %d", fname, DG_WORDLENGTH); return; } strcpy(dgellist->el_list[i].word, name); } else { /* make up a name for this gen */ dgellist->el_list[i].word[0] = 'a' + i; dgellist->el_list[i].word[1] = 0; } switch(discgrp->attributes & DG_MODEL_BITS){ case DG_CONFORMALBALL: OOGLSyntax(fp,errfmt,fname,"Unimplemented conformal model"); break; case DG_UPPERHALFSPACE: { lin_frac mylf; proj_matrix mypm; int k,m; for (k=0; k<2; ++k) for (m=0; m<2; ++m) fscanf(fp,"%lf%lf",&mylf[k][m].real, &mylf[k][m].imag); sl2c_to_proj(mylf, mypm); for (k=0; k<4; ++k) for (m=0; m<4; ++m) dgellist->el_list[i].tform[k][m] = mypm[k][m]; } break; default: if (fgettransform(fp,1,(float *)dgellist->el_list[i].tform,0) != 1) { OOGLSyntax(fp,errfmt,fname,"Error reading generator"); return; } if (discgrp->attributes & DG_TRANSPOSED) TmTranspose(dgellist->el_list[i].tform, discgrp->big_list->el_list[i].tform); break; } } } Geom * DiscGrpImport(Pool *p) { char *name, *fname, t; char keyword[DG_KEYWORDSIZE]; DiscGrp *discgrp; int i; FILE *wafp, *fp; char *expect; if(p == NULL || (fp = p->inf) == NULL) return 0; /* check for 'DISCGRP' at head of file */ if(fexpectstr(fp, "DISCGRP")) return(NULL); /* now the parentheses begin */ if ((t = fnextc(fp, 0)) != '(') return(NULL); discgrp = (DiscGrp*)GeomCreate("discgrp",CR_END); while (get_keyword(fp, keyword,p->poolname)) { switch ( token_from_string(keyword, keytokenlist,sizeof(keytokenlist)/sizeof(keytokenpair) )) { case DG_WAFILE: name = fdelimtok(delims, fp, 0); fname = findfile(PoolName(p), name); if(fname == NULL || (wafp = fopen(fname, "r")) == NULL) { OOGLSyntax(fp, "Reading discrete group from \"%s\": can't open wafile \"%s\"", p->poolname, name); return(NULL); } discgrp->fsa = OOGLNew(wa); fsaparse(wafp, discgrp->fsa); fclose(wafp); break; case DG_DSPYATTR: name = fdelimtok(delims, fp, 0); discgrp->flag |= token_from_string(name, dspyattr_list,sizeof(dspyattr_list)/sizeof(keytokenpair)); break; case DG_ATTRIBUTE: case DG_MODEL: name = fdelimtok(delims, fp, 0); discgrp->attributes |= token_from_string(name, attr_list,sizeof(attr_list)/sizeof(keytokenpair)); break; case DG_COMMENT: discgrp->comment = strdup(fdelimtok(delims, fp, 0)); break; case DG_MATRIXGROUP: parse_group_name(fdelimtok(delims, fp, 0)); break; case DG_SCALE: if(fgetnf(fp, 1, &discgrp->scale, 0) <= 0) { OOGLSyntax(fp,errfmt, p->poolname, "Invalid scale"); return(NULL); } break; case DG_C2M: discgrp->c2m = (float (*)[4])OOGLNewNE(float, 16, "Transform"); if (fgettransform(fp,1,(float *)discgrp->c2m,0) != 1) { OOGLSyntax(fp,errfmt,p->poolname,"Error reading cam2model"); return(NULL); } break; case DG_ENUMDEPTH: if(fgetni(fp, 1, &discgrp->enumdepth, 0) <= 0) { OOGLSyntax(fp,errfmt, p->poolname, "Invalid enumdepth"); return(NULL); } break; case DG_ENUMDIST: if(fgetnf(fp, 1, &discgrp->enumdist, 0) <= 0) { OOGLSyntax(fp,errfmt, p->poolname, "Invalid enumdist"); return(NULL); } break; case DG_CPOINT: if(fgetnf(fp, 4, (float *)&discgrp->cpoint, 0) <= 0) { OOGLSyntax(fp,errfmt, p->poolname, "Invalid Cpoint"); return(NULL); } break; case DG_CAMGEOM: expect = "camgeometry"; if(!GeomStreamIn(p, &discgrp->camgeomhandle, &discgrp->camgeom)) goto failed; if(discgrp->camgeomhandle) HandleRegister(&discgrp->camgeomhandle, (Ref *)discgrp, &discgrp->camgeom, HandleUpdRef); break; case DG_ELS: discgrp->big_list->mgroup = cgroup; get_el_list(discgrp, discgrp->big_list, fp, p->poolname); discgrp->flag |= DG_SAVEBIGLIST; break; case DG_GROUPNAME: discgrp->name = strdup(fdelimtok(delims, fp, 0)); break; case DG_GENS: { int i; static char name[2] = "a"; discgrp->gens->mgroup = cgroup; get_el_list(discgrp, discgrp->gens, fp, p->poolname); /* make up names for the generators if not given */ if (strcmp(discgrp->gens->el_list[0].word, "") == 0) { for (i=0; i<discgrp->gens->num_el; ++i) { strcpy(discgrp->gens->el_list[i].word,name); name[0]++; } } } break; case DG_GEOM: expect = "geometry"; if(!GeomStreamIn(p, &discgrp->geomhandle, &discgrp->geom)) goto failed; if(discgrp->geomhandle) HandleRegister(&discgrp->geomhandle, (Ref *)discgrp, &discgrp->geom, HandleUpdRef); break; case DG_DIMN: if(fgetni(fp, 1, &discgrp->dimn, 0) <= 0 || discgrp->dimn > 4) { OOGLSyntax(fp,errfmt, p->poolname, "Invalid Dimension"); return(NULL); } cgroup.dimn = discgrp->dimn+1; /* default matrix group */ break; case DG_NGENS: { int ngens; if(fgetni(fp, 1, &ngens, 0) <= 0 || ngens <= 0) { OOGLSyntax(fp,errfmt,p->poolname, "Invalid generator count"); return(NULL); } discgrp->gens = OOGLNewE(DiscGrpElList, "DiscGrp gens"); discgrp->gens->num_el = ngens; discgrp->gens->el_list = OOGLNewNE(DiscGrpEl, discgrp->gens->num_el, "DiscGrp gens elem list"); } break; case DG_NELS: { int nels; if(fgetni(fp, 1, &nels, 0) <= 0 || nels <= 0) { OOGLSyntax(fp,errfmt,p->poolname, "Invalid generator count"); return(NULL); } discgrp->big_list = OOGLNewE(DiscGrpElList, "DiscGrp el_list"); discgrp->big_list->num_el = nels; discgrp->big_list->el_list = OOGLNewNE(DiscGrpEl, discgrp->big_list->num_el, "DiscGrp elem list"); } break; failed: OOGLSyntax(fp, "Couldn't read DISCGRP in \"%s\": expected %s", PoolName(p), expect); break; default: OOGLError(1,"Bad keyword DiscGrpFLoad %s",keyword); break; } if ( !(get_matching_parenthesis(fp,p->poolname))) break; } /* make sure the generator list includes all inverses */ DiscGrpAddInverses(discgrp); /* if (discgrp->geom == NULL) { discgrp->flag |= DG_DRAWDIRDOM; DiscGrpSetupDirdom(discgrp); discgrp->ddgeom = DiscGrpDirDom(discgrp); } */ if (discgrp->big_list == NULL) { DiscGrpInitStandardConstraint(discgrp->enumdepth, discgrp->enumdist, discgrp->enumdist); discgrp->big_list = DiscGrpEnum(discgrp, DiscGrpStandardConstraint); } return(( Geom *) discgrp); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.