home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / gprim / discgrp / dgstream.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-07  |  11.7 KB  |  452 lines

  1. /* Copyright (c) 1992 The Geometry Center; University of Minnesota
  2.    1300 South Second Street;  Minneapolis, MN  55454, USA;
  3.    
  4. This file is part of geomview/OOGL. geomview/OOGL is free software;
  5. you can redistribute it and/or modify it only under the terms given in
  6. the file COPYING, which you should have received along with this file.
  7. This and other related software may be obtained via anonymous ftp from
  8. geom.umn.edu; email: software@geom.umn.edu. */
  9.  
  10. /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
  11.  
  12. #include <ctype.h>
  13. #include "sl2c.h"        /* in case file has elements of SL(2,C) */
  14. #include "discgrpP.h"
  15. #include <string.h>
  16. #include "mgP.h"
  17. #include "streampool.h"
  18. #include "transobj.h"
  19. #include "handleP.h"
  20.  
  21. #define DG_GROUPNAME    1
  22. #define DG_COMMENT    2
  23. #define DG_ATTRIBUTE    3
  24. #define DG_MODEL    4
  25. #define DG_NGENS    5
  26. #define DG_NELS        6
  27. #define DG_GENS        7
  28. #define DG_ELS        8
  29. #define    DG_DIMN        9
  30. #define    DG_CAMGEOM    10
  31. #define    DG_GEOM        11
  32. #define    DG_CAMGEOMFILE    12
  33. #define    DG_GEOMFILE    13
  34. #define    DG_WAFILE    14
  35. #define    DG_MATRIXGROUP    15
  36. #define    DG_CPOINT    16
  37. #define    DG_ENUMDEPTH    17
  38. #define    DG_ENUMDIST    18
  39. #define    DG_DSPYATTR    19
  40. #define DG_SCALE    20
  41. #define DG_C2M        21
  42. #define DG_NUMKEYWORDS    23    /* 2 redundant keywords */
  43.  
  44. keytokenpair keytokenlist[] = {
  45.         "group",     DG_GROUPNAME,
  46.         "comment",     DG_COMMENT,
  47.         "attribute",     DG_ATTRIBUTE,
  48.         "model",     DG_MODEL,
  49.         "ngens",     DG_NGENS,
  50.         "nels",     DG_NELS,
  51.         "gens",     DG_GENS,
  52.         "els",         DG_ELS,
  53.         "dimn",        DG_DIMN,
  54.         "dimension",    DG_DIMN,
  55.         "camgeom",    DG_CAMGEOM,
  56.         "geom",        DG_GEOM,
  57.         "camgeomfile",    DG_CAMGEOMFILE,
  58.         "geomfile",    DG_GEOMFILE,
  59.         "wafile",    DG_WAFILE,
  60.         "matrixgroup",    DG_MATRIXGROUP,
  61.         "mgroup",    DG_MATRIXGROUP,
  62.         "cpoint",    DG_CPOINT,
  63.         "enumdepth",    DG_ENUMDEPTH,
  64.         "enumdist",    DG_ENUMDIST,
  65.         "display",    DG_DSPYATTR,
  66.         "scale",    DG_SCALE,
  67.         "cam2model",    DG_C2M
  68.         };
  69.  
  70. keytokenpair attr_list[DG_NUM_ATTR] = {
  71.         "hyperbolic",     DG_HYPERBOLIC,    
  72.         "euclidean",     DG_EUCLIDEAN,
  73.         "spherical",     DG_SPHERICAL,
  74.         "finite",     DG_FINITE,
  75.         "transposed",     DG_TRANSPOSED,
  76.         "conformalball", DG_CONFORMALBALL,
  77.         "upperhalfspace", DG_UPPERHALFSPACE,
  78.         "projective",     DG_PROJECTIVEMODEL
  79.         };
  80.  
  81. keytokenpair dspyattr_list[DG_NUM_DSPYATTR] = {
  82.         "centercam",    DG_CENTERCAM,
  83.         "zcull",    DG_ZCULL,
  84.         "drawcam",    DG_DRAWCAM,
  85.         "drawdirdom",    DG_DRAWDIRDOM,
  86.         "drawgeom",    DG_DRAWGEOM
  87.         };
  88.  
  89. /* Name can be {GL | SL | SO } ( {n},{k},{R | C} ) */
  90.     matrixgroup cgroup = { DG_GENERAL | DG_REAL, 4, 0};
  91.  
  92. static char delims[] = "%{}();";
  93. static char errfmt[] = "Reading discrete group from \"%s\": %s";
  94.  
  95. static int
  96. token_from_string(char *s, keytokenpair *kl, int n)
  97. {
  98.     int i;
  99.     for (i=0; i<n; ++i)    {
  100.     if (strcasecmp(s, kl[i].key) == 0) 
  101.          return (kl[i].token);
  102.     }
  103.     return (0);
  104. }
  105.  
  106.  
  107. /* following gets the next %keyword from file.
  108.    returns 0 if EOF, otherwise 1 */
  109. static int
  110. get_keyword(fp, keyword, fname)
  111. FILE *fp;
  112. char keyword[];
  113. char *fname;
  114. {
  115.     char t;
  116.  
  117.     t = fnextc(fp, 0);
  118.     if (t == '\377')  { /* EOF */
  119.         getc(fp);
  120.         return(0);
  121.         }
  122.  
  123.     else if (t == '}')    { /* end of discgrp description? */
  124.         return(0);
  125.         }
  126.  
  127.     if (t != '(')    {
  128.         OOGLSyntax(fp,"Reading discrete group from \"%s\": expected (", fname);
  129.         return(0);
  130.         }
  131.     /* discard 't': it's OK */
  132.     getc(fp);
  133.     sprintf(keyword, "%.31s", fdelimtok(delims, fp, 0));
  134.     return 1;
  135. }
  136.  
  137. static int
  138. get_matching_parenthesis(FILE *fp, char *fname)
  139. {
  140.     char t;
  141.     t = fnextc(fp, 0);
  142.     if (t == EOF) return(0);
  143.     if (t != ')')    {
  144.             OOGLSyntax(fp,"Reading discrete group from \"%s\": expected matching )", fname);
  145.             return(0);
  146.         }
  147.     getc(fp);
  148.     return(1);
  149. }
  150.  
  151. static FILE *
  152. included_file(fp)
  153. FILE *fp;
  154. {
  155.     char *name;
  156.     
  157.     if (fnextc(fp, 0) == '<') /* read from file */
  158.         {
  159.         name = fdelimtok(delims, fp, 0);
  160.         OOGLError(1,"Discrete groups: including files not implemented");
  161.         return(NULL);
  162.         }
  163.     return(NULL);
  164. }
  165.  
  166. static int
  167. parse_group_name(char *gname)
  168. {
  169.     char *gptr = gname;
  170.  
  171.     cgroup.attributes = DG_GENERAL | DG_REAL;    /* type of entry */
  172.     cgroup.dimn = 4;        /* dimension of matrices */
  173.     cgroup.sig = 0;        /* signature of quadratic form */
  174.      
  175. }
  176.  
  177.     static ColorA white = {1,1,1,.75};
  178.  
  179. static void
  180. get_el_list( DiscGrp *discgrp, DiscGrpElList *dgellist, FILE *fp, char *fname)
  181. {
  182.     int i;
  183.     char *name, c;
  184.  
  185.         if (included_file(fp))    /* read from file */
  186.             {
  187.             }
  188.         
  189.         for (i=0; i<dgellist->num_el; ++i)    {
  190.         dgellist->el_list[i].attributes = 0;
  191.         dgellist->el_list[i].color = white;
  192.         dgellist->el_list[i].inverse = NULL;
  193.             c = fnextc(fp, 0);
  194.             /* get the name if it's alphabetic */
  195.             if ( c >= 'A' && c <= 'z' )
  196.             {
  197.                         name = fdelimtok(delims, fp, 0);
  198.                 if (strlen(name) > DG_WORDLENGTH) {
  199.                 OOGLSyntax(fp,"Reading discrete group from \"%s\": Words limited to length %d", fname, DG_WORDLENGTH);
  200.                  return;
  201.                 }
  202.                         strcpy(dgellist->el_list[i].word, name);
  203.               }
  204.         else  {    /* make up a name for this gen */
  205.         dgellist->el_list[i].word[0] = 'a' + i;
  206.         dgellist->el_list[i].word[1] = 0;
  207.         }
  208.         
  209.     
  210.             switch(discgrp->attributes & DG_MODEL_BITS){
  211.                 case DG_CONFORMALBALL:
  212.                 OOGLSyntax(fp,errfmt,fname,"Unimplemented conformal model");
  213.                     break;
  214.  
  215.                 case DG_UPPERHALFSPACE:
  216.             {
  217.             lin_frac mylf; 
  218.             proj_matrix mypm;
  219.             int k,m;
  220.              for (k=0; k<2; ++k) for (m=0; m<2; ++m)
  221.                 fscanf(fp,"%lf%lf",&mylf[k][m].real, &mylf[k][m].imag);
  222.             sl2c_to_proj(mylf, mypm); 
  223.              for (k=0; k<4; ++k) for (m=0; m<4; ++m)
  224.             dgellist->el_list[i].tform[k][m] = mypm[k][m];
  225.             }
  226.                     break;
  227.  
  228.                 default:
  229.                     if (fgettransform(fp,1,(float *)dgellist->el_list[i].tform,0) != 1) {
  230.                     OOGLSyntax(fp,errfmt,fname,"Error reading generator");
  231.                     return;
  232.                 }
  233.                     if (discgrp->attributes & DG_TRANSPOSED) 
  234.                         TmTranspose(dgellist->el_list[i].tform, discgrp->big_list->el_list[i].tform);
  235.             break;
  236.             }
  237.             }
  238. }
  239.  
  240. Geom *
  241. DiscGrpImport(Pool *p)
  242. {
  243.     char *name, *fname, t;
  244.     char keyword[DG_KEYWORDSIZE];
  245.     DiscGrp *discgrp;
  246.     int i;
  247.     FILE *wafp, *fp;
  248.     char *expect;
  249.  
  250.         if(p == NULL || (fp = p->inf) == NULL)
  251.             return 0;
  252.  
  253.     /* check for 'DISCGRP' at head of file */
  254.     if(fexpectstr(fp, "DISCGRP"))
  255.         return(NULL);
  256.  
  257.     /* now the parentheses begin */
  258.     if ((t = fnextc(fp, 0)) != '(')
  259.         return(NULL);
  260.  
  261.     discgrp = (DiscGrp*)GeomCreate("discgrp",CR_END);
  262.  
  263.     while (get_keyword(fp, keyword,p->poolname))    {
  264.  
  265.         switch ( token_from_string(keyword, keytokenlist,sizeof(keytokenlist)/sizeof(keytokenpair) ))    {
  266.         
  267.         case DG_WAFILE:
  268.             name = fdelimtok(delims, fp, 0);
  269.             fname = findfile(PoolName(p), name);
  270.             if(fname == NULL || (wafp = fopen(fname, "r")) == NULL) {
  271.             OOGLSyntax(fp,
  272.             "Reading discrete group from \"%s\": can't open wafile \"%s\"",
  273.                 p->poolname, name);
  274.             return(NULL);
  275.             }
  276.             discgrp->fsa = OOGLNew(wa);
  277.             fsaparse(wafp, discgrp->fsa);
  278.             fclose(wafp);
  279.             break;
  280.         
  281.         case DG_DSPYATTR:
  282.             name = fdelimtok(delims, fp, 0);
  283.             discgrp->flag |= token_from_string(name, dspyattr_list,sizeof(dspyattr_list)/sizeof(keytokenpair));
  284.             break;
  285.             
  286.         case DG_ATTRIBUTE:
  287.         case DG_MODEL:
  288.             name = fdelimtok(delims, fp, 0);
  289.             discgrp->attributes |= token_from_string(name, attr_list,sizeof(attr_list)/sizeof(keytokenpair));
  290.             break;
  291.             
  292.         case DG_COMMENT:
  293.             discgrp->comment = strdup(fdelimtok(delims, fp, 0));
  294.             break;
  295.  
  296.         case DG_MATRIXGROUP:
  297.             parse_group_name(fdelimtok(delims, fp, 0));
  298.             break;
  299.  
  300.         case DG_SCALE:
  301.             if(fgetnf(fp, 1, &discgrp->scale, 0) <= 0) {
  302.             OOGLSyntax(fp,errfmt, p->poolname, "Invalid scale");    
  303.             return(NULL);
  304.             }
  305.             break;
  306.  
  307.         
  308.          case DG_C2M:
  309.             discgrp->c2m = (float (*)[4])OOGLNewNE(float, 16, "Transform");
  310.                     if (fgettransform(fp,1,(float *)discgrp->c2m,0) != 1) {
  311.                     OOGLSyntax(fp,errfmt,p->poolname,"Error reading cam2model");
  312.                     return(NULL);
  313.             }
  314.             break;
  315.         
  316.         case DG_ENUMDEPTH:
  317.             if(fgetni(fp, 1, &discgrp->enumdepth, 0) <= 0) {
  318.             OOGLSyntax(fp,errfmt, p->poolname, "Invalid enumdepth");    
  319.             return(NULL);
  320.             }
  321.             break;
  322.  
  323.         case DG_ENUMDIST:
  324.             if(fgetnf(fp, 1, &discgrp->enumdist, 0) <= 0) {
  325.             OOGLSyntax(fp,errfmt, p->poolname, "Invalid enumdist");    
  326.             return(NULL);
  327.             }
  328.             break;
  329.  
  330.         case DG_CPOINT:
  331.             if(fgetnf(fp, 4, (float *)&discgrp->cpoint, 0) <= 0) {
  332.             OOGLSyntax(fp,errfmt, p->poolname, "Invalid Cpoint");    
  333.             return(NULL);
  334.             }
  335.             break;
  336.  
  337.         case DG_CAMGEOM:
  338.             expect = "camgeometry";
  339.                     if(!GeomStreamIn(p, &discgrp->camgeomhandle, &discgrp->camgeom))
  340.                         goto failed;
  341.                     if(discgrp->camgeomhandle)
  342.                         HandleRegister(&discgrp->camgeomhandle, (Ref *)discgrp,
  343.                                 &discgrp->camgeom, HandleUpdRef);
  344.             
  345.             break;
  346.  
  347.         case DG_ELS:
  348.             discgrp->big_list->mgroup = cgroup;
  349.             get_el_list(discgrp, discgrp->big_list, fp, p->poolname);
  350.             discgrp->flag |= DG_SAVEBIGLIST;
  351.                  break;
  352.  
  353.         case DG_GROUPNAME:
  354.             discgrp->name = strdup(fdelimtok(delims, fp, 0));
  355.             break;
  356.  
  357.         case DG_GENS:
  358.             {
  359.             int i;
  360.             static char name[2] = "a";
  361.             discgrp->gens->mgroup = cgroup;
  362.             get_el_list(discgrp, discgrp->gens, fp, p->poolname);
  363.             /* make up names for the generators if not given */
  364.             if (strcmp(discgrp->gens->el_list[0].word, "") == 0) {
  365.             for (i=0; i<discgrp->gens->num_el; ++i)    {
  366.                 strcpy(discgrp->gens->el_list[i].word,name);
  367.                 name[0]++;
  368.                 }
  369.             }
  370.             }
  371.      
  372.             break;
  373.  
  374.         case DG_GEOM:
  375.              expect = "geometry";
  376.                     if(!GeomStreamIn(p, &discgrp->geomhandle, &discgrp->geom))
  377.                         goto failed;
  378.                     if(discgrp->geomhandle)
  379.                         HandleRegister(&discgrp->geomhandle, (Ref *)discgrp,
  380.                                 &discgrp->geom, HandleUpdRef);
  381.             
  382.             break;
  383.  
  384.         case DG_DIMN:
  385.             if(fgetni(fp, 1, &discgrp->dimn, 0) <= 0 ||
  386.                             discgrp->dimn > 4)     {
  387.             OOGLSyntax(fp,errfmt, p->poolname, "Invalid Dimension");    
  388.             return(NULL);
  389.             }
  390.             cgroup.dimn = discgrp->dimn+1;  /* default matrix group */
  391.             break;
  392.  
  393.         case DG_NGENS:
  394.             {
  395.             int ngens;
  396.             if(fgetni(fp, 1, &ngens, 0) <= 0 || ngens <= 0) {
  397.             OOGLSyntax(fp,errfmt,p->poolname, "Invalid generator count");
  398.             return(NULL);
  399.             }
  400.             discgrp->gens = OOGLNewE(DiscGrpElList, "DiscGrp gens"); 
  401.             discgrp->gens->num_el = ngens;
  402.             discgrp->gens->el_list = OOGLNewNE(DiscGrpEl,
  403.                 discgrp->gens->num_el, "DiscGrp gens elem list"); 
  404.             }
  405.             break;
  406.  
  407.         case DG_NELS:
  408.             {
  409.             int nels;
  410.             if(fgetni(fp, 1, &nels, 0) <= 0 || nels <= 0) {
  411.             OOGLSyntax(fp,errfmt,p->poolname, "Invalid generator count");
  412.             return(NULL);
  413.             }
  414.             discgrp->big_list = OOGLNewE(DiscGrpElList, "DiscGrp el_list"); 
  415.             discgrp->big_list->num_el = nels;
  416.             discgrp->big_list->el_list = OOGLNewNE(DiscGrpEl,
  417.                 discgrp->big_list->num_el, "DiscGrp elem list"); 
  418.             }
  419.             break;
  420.         failed:
  421.           OOGLSyntax(fp, "Couldn't read DISCGRP in \"%s\": expected %s",
  422.                         PoolName(p), expect);
  423.       break;
  424.  
  425.         default:
  426.             OOGLError(1,"Bad keyword DiscGrpFLoad %s",keyword);
  427.             break;
  428.             }
  429.         if ( !(get_matching_parenthesis(fp,p->poolname))) break;
  430.         }
  431.  
  432.     /* make sure the generator list includes all inverses */
  433.     DiscGrpAddInverses(discgrp);
  434.  
  435. /*
  436.     if (discgrp->geom == NULL)    
  437.         {
  438.         discgrp->flag |= DG_DRAWDIRDOM;
  439.         DiscGrpSetupDirdom(discgrp);
  440.               discgrp->ddgeom = DiscGrpDirDom(discgrp);
  441.         }
  442. */
  443.  
  444.     if (discgrp->big_list == NULL)
  445.         {
  446.         DiscGrpInitStandardConstraint(discgrp->enumdepth, discgrp->enumdist, discgrp->enumdist);
  447.         discgrp->big_list = DiscGrpEnum(discgrp, DiscGrpStandardConstraint);
  448.         }
  449.     
  450.     return(( Geom *) discgrp);
  451. }
  452.