ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/bin/trigrp/main.c

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

/*  todo:   add menu with choice of groups: now icosa,octa, tetra 
 */
#include <stdio.h>
#include <geom.h>
#include "vec4.h"
#include "trigrp.h"
#include <mg.h>
#include <window.h>
#include <appearance.h>
#include <color.h>

#include <gl/gl.h>
#include <gl/device.h>

extern char *getenv();

/*	Barycentric:	convert from 236 triangle coordinate system
		to barycentric coordinate system:
		(1,0,0,0):	pi/2
		(0,1,0,0):	pi/3
		(0,0,1,0):	pi/6
 	Input:		a point in the same coordinate system as
		the global variable reftri
 */
	
#define Barycentric(src,dst) PtTransform(ireftri[G_236],&src,&dst);	\
	fprintf(stderr,"Barycentric: %f %f %f %f\n",dst.x,dst.y,dst.z,dst.w);
#define PI	3.1415926

char *progname;
FILE *toviewer = stdout;
char cmapfile[128] = "";
extern char *grpnames[];
extern Geom *plist;
extern Geom *eucplist;
extern char *group_path;
static Geom *fd;
extern Geom *Make2nmFD();

int dbg = 0, batch = 0, stop = 1,active_group = 0, which = 0,
	    automatic = 0, newgroup = 1;
int menu;
WnPosition wp;

HPoint3 ppoint = {0.15, 0.4, 0.0, 1.0}, bary;
static HPoint3 vel = {.005, .008, 0, 0};
static Transform LineTri;
extern Transform reftri[], ireftri[], gens[][3]; 
extern float t236[][4];

static int initmenu();

double
MyDot(p0,p1)
float *p0, *p1;
{
    return(p0[0]*p1[0] + p0[1]*p1[1] + p0[2]*p1[2] + p0[3]*p1[3]);
}
void
init_Lines()
{
    int i;
    LineTri[0][0] = reftri[G_236][1][1] - reftri[G_236][2][1];
    LineTri[0][1] = -reftri[G_236][1][0] + reftri[G_236][2][0];
    LineTri[0][3] = reftri[G_236][1][0]*reftri[G_236][2][1] -
			reftri[G_236][2][0]*reftri[G_236][1][1];
    LineTri[1][0] = reftri[G_236][2][1] - reftri[G_236][0][1];
    LineTri[1][1] = -reftri[G_236][2][0] + reftri[G_236][0][0];
    LineTri[1][3] = reftri[G_236][2][0]*reftri[G_236][0][1] -
			reftri[G_236][0][0]*reftri[G_236][2][1];
    LineTri[2][0] = reftri[G_236][0][1] - reftri[G_236][1][1];
    LineTri[2][1] = -reftri[G_236][0][0] + reftri[G_236][1][0];
    LineTri[2][3] = reftri[G_236][0][0]*reftri[G_236][1][1] -
			reftri[G_236][1][0]*reftri[G_236][0][1];
    LineTri[0][2] = LineTri[1][2] = LineTri[2][2] = 0.0;
}
	
int
GetOrigin(pt)
register HPoint3 *pt;
{
    /* simple solution now */
    int x,y;
    float px, py, winsize;
    int xsize, ysize;
    int xmid, ymid;
    int reverse = 0;

    xsize = (wp.xmax - wp.xmin + 1);
    ysize = (wp.ymax - wp.ymin + 1);
    winsize = xsize < ysize ? xsize : ysize;

    xmid = (wp.xmin + wp.xmax) / 2;
    ymid = (wp.ymin + wp.ymax) / 2;

    /* only look when the left mouse button's down */
    x = getvaluator(MOUSEX);
    if (x > wp.xmax  || x < wp.xmin) return(0);
    px = (XMAX - XMIN) * ((x - xmid)/winsize) + (XMIN+XMAX)/2;
    y = getvaluator(MOUSEY);
    if (y > wp.ymax  || y < wp.ymin) return(0);
    py = (YMAX - YMIN) * ((y - ymid)/winsize) + (YMIN+YMAX)/2;
    if(px == pt->x && py == pt->y)
	return 0;
    pt->x = px;
    pt->y = py;
    return(1);
}

static
SendBegin() {
    fprintf(toviewer, "(progn");
}

static
SendEnd() {
    fprintf(toviewer, ")");
    fflush(toviewer);
}

static
SendFD()
{
    fprintf(toviewer, "(read geometry { define fd ");
      GeomFSave(plist, toviewer, "stdout");
    fprintf(toviewer, "} )\n");
    fflush(toviewer);
}

static
SendGroup()
{
    static int washyp = 0;
    int needhyp;
    static char *space[2] = {
	"(space euclidean) (normalization trigrp on)",
	"(space hyperbolic)"
    };

    fprintf(toviewer,
		"(geometry trigrp { = INST tlist < %s/%s.prj unit : fd })",
		group_path, grpnames[active_group]);
    needhyp = (active_group == 4);
    if(washyp != needhyp)
	fprintf(toviewer, "%s\n", space[needhyp]);
    washyp = needhyp;
    fflush(toviewer);
}

main(argc, argv)
char **argv;
{
 	int  i, n,m, count = 1;
        short val, dev;
	char *term = getenv("TERM");

	progname = argv[0];
	active_group = G_236;

	if (!batch)
	  if(term == NULL || strcmp(term, "iris-ansi") != 0) {
	    fprintf(stderr,"Not on an iris-ansi terminal, unsafe to use windows\n");
	    batch = 1;
	}
	init_groups();
	readcmap(cmapfile);
	/* and initialize polylist structure */
	init_plist(active_group);
	init_Lines();

    /* in interactive mode, init graphics for inputting distinguished point */
    if (!batch)	{
	static Color gray = {.8,.8,.8};

        foreground();
	mgdevice_GL();
        mgctxcreate(MG_WnSet, WN_NAME, "trigrp", WN_END,
		    MG_CamSet, CAM_PERSPECTIVE, 0,
				CAM_FOCUS, 1.,
				CAM_HALFYFIELD, .5, CAM_END,
		    MG_ApSet, AP_DO, APF_FACEDRAW|APF_EDGEDRAW,
				AP_SHADING, APF_CONSTANT, AP_END,
		    MG_BACKGROUND, &gray,
		    MG_END);

	mgreshapeviewport();
        initmouse();
	menu = initmenu();
	PtTransform(ireftri[G_236],&ppoint,&bary);
        drawframe();
	fprintf(stderr,"Trigrp: use left button to drag meeting point, right button for menu.\n");
	}
	
	i = 0;
	if (!batch) {
	  while (1) {	/* if interactive, continue forever */
	    if(newgroup) {
		drawframe();
		fd = Make2nmFD(bary, active_group, plist);
		SendBegin();
		    SendFD();
		    SendGroup();
		SendEnd();
		newgroup = 0;
	    }
    	    if (automatic) {
		ppoint.x += vel.x;
		ppoint.y += vel.y;
		for (i=0; i<3; ++i) {
		    /* is bouncing point outside triangle ? */
	    	    if (MyDot(&ppoint, LineTri[i]) < 0) 	{
	        	PtTransform(gens[G_236][i], &ppoint, &ppoint); 
	        	PtTransform(gens[G_236][i], &vel, &vel); 
			i = 3;
		    }
		}
		drawframe();
		PtTransform(ireftri[G_236],&ppoint,&bary);
	        fd = Make2nmFD(bary, active_group, plist);
	    	SendFD();
	  	sginap(20);
	    }
	    if (!automatic || qtest()) {
	    	  dev = qread(&val);
		  switch(dev)	{
		    case LEFTMOUSE:
		    case MIDDLEMOUSE:
			automatic = 0;
			do {
			    if(GetOrigin(&ppoint)) {
				PtTransform(ireftri[G_236],&ppoint,&bary);
				fd = Make2nmFD(bary, active_group, plist);
				SendFD();
				drawframe();
			    }
			    sginap(20);
			} while(getbutton(dev));
			break;
	    	    case KEYBD:	
		      switch(val)	{
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			    active_group = val - '3';
			    newgroup = 2;
			    break;
			case 'a':
			    automatic = 1 - automatic;
			    break;
			case 'p':
			    fprintf(stderr,"Barycentric: %f %f %f %f\n",bary.x,bary.y,bary.z,bary.w);
			    break;

			case '\033':
			case 'Q':
				gexit(); exit(1);	/* Quit */
			}
			break;
	   	    case MENUBUTTON:
		    if( val ) {
		      switch(val = dopup(menu)) {
			case 0: 
			case 1: 
			case 2: 
			case 3: 
			case 4: 
			    active_group = val;
			    newgroup = 2;
			    break;
			case 5:
			fprintf(stderr,"Barycentric: %f %f %f %f\n",bary.x,bary.y,bary.z,bary.w);
			    break;
			case 6: 
			    automatic = 1 - automatic;
			    break;
			case 7: exit(1); break;	/* Quit */
		      }
		    }
		    break;
		    case REDRAW:
			mgreshapeviewport();
			initmouse();
			drawframe();
			break;
		    }
		}
	    }
	} else {
	    fd = Make2nmFD(bary, active_group, plist);
	    GeomFSave(fd, stdout, "stdout");
	}
}

initmouse()
{
    WnWindow *w;

    qdevice(LEFTMOUSE);
    qdevice(MIDDLEMOUSE);
    qdevice(MENUBUTTON);
    qdevice(KEYBD);

    mgctxget(MG_WINDOW, &w);
    WnGet(w, WN_CURPOS, &wp);
}

#ifdef sgi
#include <fmclient.h>
labelframe()
{
    static int fminitted = 0;
    static fmfonthandle font = NULL;
    int i;
    static struct label {
	float x, y;  char str[4];
    } lab[3] = {
	{-.05,-.05, "p/2" },
	{ .505, -.05, "p/3" },
	{ .05, .85, "p/N" }
    };

    if(!fminitted) {
	fminit();
	font = fmfindfont("Symbol");
	if(font) fmsetfont(fmscalefont(font, 12));
    }
    if(font) {
	pushattributes();
	cpack(0);
	pushmatrix();
	lab[2].str[2] = active_group + '3';
	for(i=0; i<3; i++) {
	    cmov2(lab[i].x, lab[i].y);
	    fmprstr(lab[i].str);
	}
	popmatrix();
	popattributes();
    }
}
#endif /*sgi*/

drawframe()
{
    Transform T;

    mgworldbegin();
    TmTranslate(T, -.25, -.4, 0.);
    mgtransform(T);
    Make2nmFD(bary, G_236, eucplist);
    GeomDraw(eucplist);
#ifdef sgi
    labelframe();
#endif
    mgworldend();
}

static int
initmenu()
{
    int pup;
    long groupmenu;


    pup = defpup("Trigrp %t");
    addtopup(pup, "233 [3]%x0|234 [4]%x1|235 [5]%x2|236 [6]%x3|237 [7]%x4|PrintBary [p]%x5|Autopilot [a]%x6|Quit [Q]%x7");

    return pup;
}

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