ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/lib/gprim/discgrp/dgstream.c

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.