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

This is dgenum.c in view mode; [Download] [Up]

#include <stdio.h>
#include <math.h>
#include "wa.h"
#include "vec4.h"
#include "dgflag.h"
#include "enum.h"
#include "color.h"
#include "3d.h"
#include "ooglutil.h"
#include "discgrpP.h"


        static DiscGrp *mydg;
    	static ColorA white = {1,1,1,.75};
    	static DiscGrpEl grpel;
	static Transform mlist[128];
	static int (*constraintfn)();
	int check_big = 1, 	/* this is currently never non-zero */
		check_new = 1, 	/* ditto */
		have_matrices = 1,
		metric = DG_HYPERBOLIC,
		stringent = 0;
	int 
		long_cnt = 0,
		same_cnt = 0,
		far_cnt = 0, 
		print_cnt = 0, 
		store_cnt = 0;
	static int numchunks = 1;
	static int ngens = 0;
	int debug = 0;
	static char symbollist[64];
    static void get_matrices();

int
getindex(c)
char c;
{
    int i;
    for (i=0; i<ngens; ++i)
	if (symbollist[i] == c) return(i);
    return(-1);
}

static
word_to_mat(word, mat1)
char *word;
Transform mat1;
{
    int length, i, index;
    /*printf("# %s\n",word); */
    TmIdentity(mat1);

    for (i=0; word[i] != 0; ++i)
	{
	index = getindex(word[i]);
	if (index < 0)	{
		printf("Bad symbol\n");
		return;
		}
	TmConcat(mat1, mlist[index], mat1);
	}
}

static int 
is_big_and_new(DiscGrpEl *dgel)
{
    int is_big=0, is_n = DG_CONSTRAINT_NEW;
    if (check_new)	is_n = is_new(dgel->tform);
    if (is_n) {
	is_big = constraintfn(dgel);
	if (is_big & DG_CONSTRAINT_LONG) long_cnt++;
	if (is_big & DG_CONSTRAINT_PRINT) print_cnt++;
	if (is_big & DG_CONSTRAINT_STORE) store_cnt++;
	if (is_big & DG_CONSTRAINT_TOOFAR) far_cnt++;
	}
    else same_cnt++;
    return(is_big | is_n );
}	


static int
process(DiscGrpEl *dgel, int stacking)
{
	Transform mat;
	register int is_ok;

    	if (have_matrices)    	{
            is_ok = is_big_and_new(dgel);
	    /* remember that only NEW and PRINT are required to be here */
            if (is_ok & DG_CONSTRAINT_NEW )	{
	     if (!(is_ok & DG_CONSTRAINT_LONG))	{
	      if (is_ok & (DG_CONSTRAINT_STORE | DG_CONSTRAINT_PRINT)) 	{
          	if (check_new)	{
        	    insert_mat(dgel->tform);
          	    /* and put it on the stack */
          	    if (stacking) push_new_stack(dgel->word);
        	    }
              	if (is_ok & DG_CONSTRAINT_PRINT)   enumpush(dgel);
          	}
	      }
	     }
            }
     	return(is_ok);
}

static int
enumerate(int state, int depth, DiscGrpEl *dgel)
{
	register int i, newstate, pval;
	Transform mat;
	char wword[64];

	if ( ! ((pval = process(dgel, 0)) & DG_CONSTRAINT_STORE)) return 0;
	if (pval & DG_CONSTRAINT_MAXLEN)	return 0;
	if (depth > MAXDEPTH) return 0;

	for (i=1; i<mydg->fsa->ngens; ++i)
	    {
	    newstate = mydg->fsa->action[state][i];
	    if ( newstate != mydg->fsa->fail)
		{
	        dgel->word[depth] = mydg->fsa->genlist[i-1][0];
	    	dgel->word[depth+1] = 0;	/* null-terminate */
		word_to_mat(dgel->word, dgel->tform);
	        enumerate(newstate, depth+1, dgel);
	   	}
	    }
}

static int
dumb_enumerate(int depth, DiscGrpEl *dgel)
{
	register int i, j, l, stacking;
	Transform mat;
	char *word, wword[64];
	extern char  *pop_old_stack();

	init_stack();
	process(dgel, 1);
	for (j = 0; j < MAXDEPTH ; ++j)
	    {
	    make_new_old();
	    /* are we interested in his descendents ? */
	    while ( (word = pop_old_stack()) != NULL)	{
		/* these words have length j */
		strcpy(dgel->word, word);
	    	for (i=0; i<ngens; ++i)
	    	    {
	    	    dgel->word[j] = symbollist[i];
	    	    dgel->word[j+1] = 0;	/* null-terminate */
		    word_to_mat(dgel->word, dgel->tform);
		    process(dgel, 1);
	    	    }
		}
	    }
}	
 
	static char emptyword[64] = "";
/* 
 * hack together an enumerate routine
 */

DiscGrpElList *
DiscGrpEnum(DiscGrp *discgrp, int (* constraint)(void) )
{
    DiscGrpElList *enum_list = OOGLNewE(DiscGrpElList, "DiscGrpEnum");
    extern DiscGrpEl *enumgetstack();
    DiscGrpEl dgel;

    /* initialize the local variables */
    constraintfn = constraint;
    have_matrices = 1;
    same_cnt = 0;
    far_cnt = 0;
    print_cnt = 0;
    store_cnt = 0;
    long_cnt = 0;
    ngens = discgrp->gens->num_el;
    metric = discgrp->attributes & DG_METRIC_BITS;
    bzero(dgel.word, sizeof(dgel.word));
    dgel.attributes = discgrp->attributes;
    TmIdentity(dgel.tform);
    dgel.color = white;
    mydg = discgrp;

    init_out_stack();
    get_matrices();
    if (mydg->fsa) enumerate(mydg->fsa->start, 0, &dgel);
    else dumb_enumerate(0,&dgel);

    /* clean up the mess */
    delete_list();

    enum_list->num_el = enumgetsize();
    enum_list->el_list = enumgetstack();

    if (mydg->flag & DG_DEBUG)	{
	fprintf(stderr,"%d elements printed \n",print_cnt);
	fprintf(stderr,"%d elements stored \n",store_cnt);
	fprintf(stderr,"%d elements move too far \n",far_cnt);
	fprintf(stderr,"%d elements too long \n",long_cnt);
	fprintf(stderr,"%d elements duplicates \n",same_cnt);
	}
    return(enum_list);
}


static void
get_matrices()
{
	int i;
	
	for (i=0; i<mydg->gens->num_el; ++i)
		{
		symbollist[i] = mydg->gens->el_list[i].word[0];
		TmCopy(mydg->gens->el_list[i].tform, mlist[i]);
		}
	fprintf(stderr,"%d generators read\n",i);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.