示例#1
0
文件: off-g.c 项目: kanzure/brlcad
int off2nmg(FILE *fpin, struct rt_wdb *fpout)
{
    char title[64], geom_fname[64];
    char rname[67], sname[67];
    char buf[200], buf2[200];

    FILE *fgeom;
    struct model *m;

    title[0] = geom_fname[0] = '\0';

    bu_fgets(buf, sizeof(buf), fpin);
    while (!feof(fpin)) {
	/* Retrieve the important data */
	if (sscanf(buf, "name %[^\n]s", buf2) > 0)
	    bu_strlcpy(title, buf2, sizeof(title));
	if (sscanf(buf, "geometry %200[^\n]s", buf2) > 0) {
	    char dtype[40], format[40];
	    if (sscanf(buf2, "%40s %40s %64s", dtype, format, geom_fname) != 3)
		bu_exit(1, "Incomplete geometry field in input file.");
	    if (!BU_STR_EQUAL(dtype, "indexed_poly"))
		bu_exit(1, "Unknown geometry data type. Must be \"indexed_poly\".");
	}
	bu_fgets(buf, sizeof(buf), fpin);
    }

    if (strlen(title) < (unsigned)1)
	fprintf(stderr, "Warning: no title\n");

    if (strlen(geom_fname) < (unsigned)1)
	bu_exit(1, "ERROR: no geometry filename given");

    if ((fgeom = fopen(geom_fname, "rb")) == NULL) {
	bu_exit(1, "off2nmg: cannot open %s (geometry description) for reading\n",
		geom_fname);
    }

    m = nmg_mm();
    read_faces(m, fgeom);
    fclose(fgeom);

    snprintf(sname, 67, "s.%s", title);
    snprintf(rname, 67, "r.%s", title);

    mk_id(fpout, title);
    mk_nmg(fpout, sname, m);
    mk_comb1(fpout, rname, sname, 1);

    nmg_km(m);
    return 0;
}
示例#2
0
文件: lgt_db.c 项目: cogitokat/brlcad
static int
get_Lgt_Entry(Lgt_Source *entry, FILE *fp)
{
    char	*ptr;
    int		red, grn, blu;
    if ( bu_fgets( entry->name, MAX_LGT_NM, fp ) == NULL )
	return	0;
    ptr = &entry->name[strlen(entry->name) - 1];
    if ( *ptr == '\n' )
	/* Read entire line.					*/
	*ptr = '\0';
    else	/* Skip rest of line.					*/
	while ( getc( fp ) != '\n' )
	    ;
    if ( fscanf( fp, "%d %d", &entry->beam, &entry->over ) != 2 )
	return	0;
    if ( fscanf( fp, "%d %d %d", &red, &grn, &blu ) != 3 )
	return	0;
    entry->rgb[0] = red;
    entry->rgb[1] = grn;
    entry->rgb[2] = blu;
    if (	fscanf(	fp,
			"%lf %lf %lf %lf %lf",
			&entry->azim,
			&entry->elev,
			&entry->dist,
			&entry->energy,
			&entry->radius
		    ) != 5
	)
	return	0;
    while ( getc( fp ) != '\n' )
	; /* Gobble rest of line.				*/
    return	1;
}
示例#3
0
int
main(int argc, char *argv)
{
    double	xyz[3];
    int	i;
    int	first = 1;

    for (;;)  {
        xyz[0] = xyz[1] = xyz[2] = 0.0;

        buf[0] = '\0';
        bu_fgets( buf, sizeof(buf), stdin );
        if ( feof(stdin) )  break;
        i = sscanf( buf, "%lf %lf %lf",
                    &xyz[0], &xyz[1], &xyz[2] );
        if (debug)  {
            fprintf(stderr, "buf=%s", buf);
            fprintf(stderr, "%d: %f\t%f\t%f\n",
                    i, xyz[0], xyz[1], xyz[2] );
        }
        if ( i <= 0 )
            break;
        if ( first )  {
            first = 0;
            pdv_3move( stdout, xyz );
        } else {
            pdv_3cont( stdout, xyz );
        }
    }

    return 0;
}
示例#4
0
/**
 * b u _ i p w d
 *
 * set/return the path to the initial working directory.
 * bu_setprogname() must be called on app startup for the correct pwd to
 * be acquired/set.
 */
static const char *
bu_ipwd()
{
    /* private stash */
    static const char *ipwd = NULL;
    static char buffer[MAXPATHLEN] = {0};

    if (ipwd) {
	return ipwd;
    }

    ipwd = getenv("PWD"); /* not our memory to free */

    if (!ipwd && (ipwd = bu_which("pwd"))) {
	FILE *fp;

	fp = popen(ipwd, "r");
	if (fp) {
	    if (bu_fgets(buffer, MAXPATHLEN, fp)) {
		ipwd = buffer;
	    } else {
		ipwd = ".";
	    }
	} else {
	    ipwd = ".";
	}
    } else {
	ipwd = ".";
    }

    return ipwd;
}
示例#5
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ g e t s
 *
 * Append a newline-terminated string from the file pointed to by "fp"
 * to the end of the vls pointed to by "vp".  The newline from the
 * file is read, but not stored into the vls.
 *
 * The most common error is to forget to bu_vls_trunc(vp, 0) before
 * reading the next line into the vls.
 *
 * Returns -
 *	>=0	the length of the resulting vls
 *	 -1	on EOF where no characters were added to the vls.
 */
int
bu_vls_gets(register struct bu_vls *vp, register FILE *fp)
{
    int	startlen;
    int endlen;
    char buffer[BUFSIZ*10] = {0};
    char *bufp;

    BU_CK_VLS(vp);

    startlen = bu_vls_strlen(vp);

    bufp = bu_fgets(buffer, BUFSIZ*10, fp);

    if (!bufp)
	return -1;

    /* strip the trailing EOL (or at least part of it) */
    if ((bufp[strlen(bufp)-1] == '\n') ||
	(bufp[strlen(bufp)-1] == '\r'))
	bufp[strlen(bufp)-1] = '\0';

    /* handle \r\n lines */
    if (bufp[strlen(bufp)-1] == '\r')
	bufp[strlen(bufp)-1] = '\0';

    bu_vls_printf(vp, "%s", bufp);

    /* sanity check */
    endlen = bu_vls_strlen(vp);
    if (endlen < startlen )
	return -1;

    return endlen;
}
示例#6
0
文件: move_all.c 项目: kanzure/brlcad
HIDDEN int
move_all_file(struct ged *gedp, int nflag, const char *file)
{
    FILE *fp;
    char line[512];

    if ((fp=fopen(file, "r")) == NULL) {
	bu_vls_printf(gedp->ged_result_str, "cannot open %s\n", file);
	return GED_ERROR;
    }

    while (bu_fgets(line, sizeof(line), fp) != NULL) {
	char *cp;
	char *new_av[3];

	/* Skip comments */
	if ((cp = strchr(line, '#')) != NULL)
	    *cp = '\0';

	if (bu_argv_from_string(new_av, 2, line) != 2)
	    continue;

	move_all_func(gedp, nflag, (const char *)new_av[0], (const char *)new_av[1]);
    }

    fclose(fp);

    return GED_OK;
}
int readMaterials(FILE *fp)
{
   char title[LINELEN];
   char name[20];
   int mat;

   if (bu_fgets(title, LINELEN, fp) == NULL)
      return 1;

   char descr[LINELEN];
   while (fscanf(fp, "%s%d%[^\n]", name, &mat, descr) != EOF)
   {
      if (name[0] == '-')
	 continue;

      Region *regionp;

      regionp = new Region(atoi(name), descr);
      regionp->addMaterial(mat);

      std::string key = name;
      regionTable[key] = regionp;

      fgetc(fp);     // newline lezen
   }
   return 0;
}
示例#8
0
文件: enf-g.c 项目: kanzure/brlcad
void
create_name_hash( FILE *fd )
{
    char line[MAX_LINE_SIZE];
    Tcl_HashEntry *hash_entry=NULL;
    int new_entry=0;

    Tcl_InitHashTable( &htbl, TCL_STRING_KEYS );

    while ( bu_fgets( line, MAX_LINE_SIZE, fd ) ) {
	char *part_no, *desc, *ptr;

	ptr = strtok( line, " \t\n" );
	if ( !ptr )
	    bu_exit( 1, "%s: *****Error processing part name file at line:\n\t%s\n", progname,line );
	part_no = bu_strdup( ptr );
	lower_case( part_no );
	ptr = strtok( (char *)NULL, " \t\n" );
	if ( !ptr )
	    bu_exit( 1, "%s: *****Error processing part name file at line:\n\t%s\n", progname,line );
	desc = bu_strdup( ptr );
	lower_case( desc );

	hash_entry = Tcl_CreateHashEntry( &htbl, part_no, &new_entry );
	if ( new_entry ) {
	    Tcl_SetHashValue( hash_entry, desc );
	} else {
	    bu_free( (char *)part_no, "part_no" );
	    bu_free( (char *)desc, "desc" );
	}
    }
}
示例#9
0
文件: trie.c 项目: kanzure/brlcad
int
readTrie(FILE *fp, Trie **triepp)
{
    static char name_buf[MAX_TRIE_LEVEL+1];
    while (bu_fgets(name_buf, MAX_TRIE_LEVEL, fp) != NULL) {
        name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line. */
        (void) addTrie(name_buf, triepp);
    }
    return 1;
}
示例#10
0
HIDDEN void
reset_input(void)
{
    int i;
    char *tmp;

    for (i=0; i < 20; i++)
	prev_rec[i][0] = '\0';

    bu_fseek(fpin, start_off, SEEK_SET);
    line_count = bulk_data_start_line;

    tmp = bu_fgets(next_line, MAX_LINE_SIZE, fpin);
    while (tmp && *tmp == '$')
	tmp = bu_fgets(next_line, MAX_LINE_SIZE, fpin);

    if (tmp != (char *)NULL)
	input_status = INPUT_OK;
    else
	input_status = INPUT_NULL;
}
示例#11
0
int main(int argc, char **argv)
{
    double	d;
    int	i;

    if ( isatty(fileno(stdout)) ) {
	bu_exit(1, "Usage: a-d [values] < ascii > doubles\n");
    }

    if ( argc > 1 ) {
	/* get them from the command line */
	for ( i = 1; i < argc; i++ ) {
	    d = atof( argv[i] );
	    fwrite( &d, sizeof(d), 1, stdout );
	}
    } else {
	/* get them from stdin */
#if 0
	char	s[80];
	while ( bu_fgets(s, 80, stdin) != NULL ) {
	    d = atof( s );
#else
	    /* XXX This one is slower but allows more than 1 per line */
	    while (1) {
		int	ch;

		while (isspace(ch = getchar()))
		    ;
		if (ch == COMMENT_CHAR) {
		    while (((ch = getchar()) != '\n') && (ch != EOF))
			;
		}
		if (ch == EOF)
		    bu_exit(0, NULL);
		else
		    ungetc(ch, stdin);

		if ( scanf("%lf", &d) == 1 ) {
#endif
		    fwrite( &d, sizeof(d), 1, stdout );
		}
		else if (feof(stdin))
		    bu_exit(0, NULL);
		else {
		    bu_exit(1, "Error in input stream\n");
		}
	    }
	}
	return 0;
    }
示例#12
0
static int
Input(point *coop)				/* input a coordinate record */
    /* -> input coordinates */
{
    char inbuf[82];	/* input record buffer */

    while (bu_fgets(inbuf, (int)sizeof inbuf, stdin) != NULL) {
	/* scan input record */
	int cvt;	/* # converted fields */

	cvt = sscanf(inbuf, " %le %le", &coop->x, &coop->y);

	if (cvt == 0)
	    continue;	/* skip color, comment, etc. */

	if (cvt == 2)
	    return 1;	/* successfully converted */

	printf("cad_parea: bad input:\n%s\n", inbuf);
	bu_exit(2, NULL);		/* return false insufficient */
    }

    return 0;			/* EOF */
}
示例#13
0
void
do_lines(FILE *fp, char *buffer)
{
#define TOKLEN	128
    char	token[TOKLEN];
    int	ntokenwords;
    register char	*cp;
    register char	*tp;
    int	i;

    for ( line=0; /*NIL*/; line++ )  {
	linebuf[0] = '\0';
	(void)bu_fgets( linebuf, sizeof(linebuf), fp );
	if ( feof(fp) )
	    break;

	/* Skip blank or commented out lines */
	if ( linebuf[0] == '\0' ||
	     linebuf[0] == '#' ||
	     linebuf[0] == '\n' )
	    continue;

	if (debug)  {
	    fprintf(stderr, "Prototype=\n%s", buffer);
	    fprintf(stderr, "Line %d='%s'\n", line, linebuf);
	}

	/* Here, there is no way to check for too many words */
	nwords = bu_argv_from_string( chanwords, NCHANS, linebuf );

	for ( cp=buffer; *cp != '\0'; )  {
	    if (debug) fputc( *cp, stderr );
	    /* Copy all plain text, verbatim */
	    if ( *cp != '@' )  {
		putc( *cp++, stdout );
		continue;
	    }

	    /* An '@' sign has been seen, slurp up a token */
	    cp++;			/* skip '@' */
	    if ( *cp == '@' )  {
		/* Double '@' is escape for single one
		 * (just like ARPANET TACs)
		 */
		putc( '@', stdout );
		cp++;		/* skip '@' */
		continue;
	    }
	    if ( *cp == '(' )  {
		cp++;		/* skip '(' */
		tp = token;
		while ( *cp && *cp != ')' && tp<&token[TOKLEN-1])  {
		    *tp++ = *cp++;
		}
		*tp++ = '\0';
		cp++;		/* skip ')' */
	    } else if ( isdigit( *cp ) )  {
		tp = token;
		while ( isdigit( *cp ) && tp<&token[TOKLEN-1] )  {
		    *tp++ = *cp++;
		}
		*tp++ = '\0';
	    } else {
		fprintf( stderr, "Line %d:  Bad sequence '@%c'\n", line, *cp);
		fprintf( stdout, "@%c", *cp++ );
		continue;
	    }
	    if (debug) fprintf(stderr, "token='%s'\n", token);

	    if ( isdigit( token[0] ) )  {
		fputs( chanwords[str2chan_index(token)],
		       stdout );
		continue;
	    }
	    if ( strcmp( token, "line" ) == 0 )  {
		fprintf(stdout, "%d", line );
		continue;
	    }
	    if ( strcmp( token, "time" ) == 0 )  {
		fputs( chanwords[0], stdout );
		continue;
	    }

	    /* Check here for multi-word tokens */
	    ntokenwords = bu_argv_from_string( tokenwords, NTOKENWORDS, token );

	    /*  If first character of a word is '@' or '%', that
	     *  signifies substituting the value of the
	     *  indicated channel.  Otherwise the word is literal.
	     */
	    for ( i=1; i<ntokenwords; i++ )  {
		char	c;
		int	chan;
		c = tokenwords[i][0];
		if ( c != '@' && c != '%' )  continue;
		chan = str2chan_index( &tokenwords[i][1] );
		tokenwords[i] = chanwords[chan];
	    }

	    if ( (i=multi_words( tokenwords, ntokenwords )) >= 0 )
		continue;

	    if ( i == -1 )  {
		fprintf(stderr,
			"Line %d: keyword @(%s) encountered error\n",
			line, token);
		fprintf(stdout,
			"@(%s)", token );
	    } else {
		fprintf(stderr,
			"Line %d: keyword @(%s) unknown\n",
			line, token);
		fprintf(stdout,
			"@(%s)", token );
	    }
	    for ( i=0; i<ntokenwords; i++ )  {
		fprintf( stderr,
			 "word[%2d] = '%s'\n",
			 i, tokenwords[i] );
	    }
	}
    }
}
int main(int argc, char **argv)
{
    /* START # 1 */
    struct application ap;	/* Application struct, passed between functions.  */

    int idx;		/* Index for rt_dirbuild & rt_gettree.  */
    static struct rt_i *rtip;/* Used for building directory, etc.  */
    char idbuf[132];	/* First id record in .g file.  */

    int i, j, k;		/* Loop variables.  */
    double vec[3];		/* Temporary vector.  */
    double r[8];		/* Temporary variable.  */
    int c;			/* Variable to read a character.  */
    char tmpstrng[150];	/* Temporary string variable.  */
    FILE *fpr=NULL;	/* Used to read a file.  */
    FILE *fpw;		/* Used to write a file.  */
    char filetmp[MAXFIL];	/* Temperature file name.  */
    char filernn[MAXFIL];	/* Region # & name file.  */
    char fileout[MAXFIL];	/* Output file name.  */
    char line[151];	/* Used to read one line of a file.  */
    int mon, day, yr;	/* Month, day, and year read from PRISM file.  */
    float hr, min;		/* Hour & minute read from PRISM file.  */
    int itype;		/* Type of temperature file, 0=>PRISM, 1=>other.  */
    int numreg;		/* Number of regions (includes background).  */
			/* User enters when using a PRISM file or read */
			/* from generic file.  */
    int numreg_read;	/* Number of regions read from region # & name */
			/* file (includes background).  */
    int numreg_g;		/* Number of regions read from .g file plus one */
    /* for the background.  */
    double eltim;		/* Elapsed time.  */
    double eltim_read;	/* Elapsed time read from temperature file.  */
    int frst_line;		/* Number of regions to be read in first line */
    /* of PRISM file.  */
    int last_line;		/* Number of regions to be read in last line */
    /* of PRISM file.  */
    int full_line;		/* Number of full lines of PRISM file to read.  */

    double center[3];	/* Center of bounding sphere or rpp.  */
    double radius;		/* Radius of bounding sphere.  */
    double rppmax[3];	/* Maximum of bounding rpp.  */
    double rppmin[3];	/* Minimum of bounding rpp.  */
    double multi;		/* Multiplication factor for radius.  */

    int region_hit;	/* Region number hit by ray.  */
    int wide, high;		/* Width & height of picture.  */
    double deltaw, deltah;	/* Spacing between rays.  */

    double denom;		/* Denominator for use in equations.  */
    double az, el;		/* Viewing azimuth & elevation.  */
    double alpha, beta;	/* Angles for rotation (rad).  */
    double calpha, salpha;	/* Cosine & sine of alpha.  */
    double cbeta, sbeta;	/* Cosine & sine of beta.  */
    int ret;

    /* Check to see if arguments implemented correctly.  */
    if (argc < 3 || argv[1]==NULL || argv[2]==NULL) {
	fprintf(stderr, "\nUsage:  showtherm file.g objects\n\n");
    } else {
	/* START # 4 */
	/* Get beginning info such as name of temperature file,  */
	/* name of region # & name file, type of temperature file */
	/* using.  */

	/* Ask type of temperature file to be used.  */
	fprintf(stderr, "Type of output file to be read 0=>PRISM, ");
	fprintf(stderr, "1=>generic.\n\t");
	ret = scanf("%d", &itype);
	if (ret == 0)
	    perror("scanf");
	if (itype != 1) itype = 0;

	if (itype == 0) {
	    /* Read info about (name & # regions) PRISM file.  */
	    fprintf(stderr, "Enter name of the PRISM output ");
	    fprintf(stderr, "file to be read (%d char max).\n\t", MAXFIL);
	    ret = scanf("%25s", filetmp); /* MAXFIL */
	    if (ret == 0)
		perror("scanf");

	    /* Ask for number of regions.  */
	    fprintf(stderr, "Enter the number of regions in the PRISM ");
	    fprintf(stderr, "file, must be more\n");
	    fprintf(stderr, "than eight (not including the background).\n\t");
	    ret = scanf("%d", &numreg);
	    if (ret == 0)
		perror("scanf");
	} else {
	    /* Read info about (name) generic file.  */
	    fprintf(stderr, "Enter name of the generic output file to be ");
	    fprintf(stderr, "read (%d char max).\n\t", MAXFIL);
	    ret = scanf("%25s", filetmp); /* MAXFIL */
	    if (ret == 0)
		perror("scanf");
	}

	/* Find name of region # & name file.  */
	fprintf(stderr, "Enter name of region # & name file to be read ");
	fprintf(stderr, "(%d char max).\n\t", MAXFIL);
	ret = scanf("%25s", filernn); /* MAXFIL */
	if (ret == 0)
	    perror("scanf");

	/* Find name of output file.  */
	fprintf(stderr, "Enter name of output file (%d char max).\n\t", MAXFIL);
	ret = scanf("%25s", fileout); /*MAXFIL */
	if (ret == 0)
	    perror("scanf");

	/* Find elapsed time to create graphical representation of.  */
	fprintf(stderr, "Enter the elapsed time to create graphical ");
	fprintf(stderr, "representation of.\n\t");
	ret = scanf("%lf", &eltim);
	if (ret == 0)
	    perror("scanf");

	/* Open generic file and read number of regions if necessary.  */
	if (itype == 1) {
	    fpr = fopen(filetmp, "rb");
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%d", &numreg);
	}

	/* Add one to number of regions to include background.  */
	numreg ++;
	printf("Number of regions (including ");
	(void)fflush(stdout);
	printf("the background):  %d\n", numreg);
	(void)fflush(stdout);

	/* Malloc arrays.  */
	info = (struct table *)bu_malloc(numreg * sizeof (struct table), "info");

	/* Zero all arrays.  */
	for (i=0; i<numreg; i++) {
	    info[i].temp = 0.0;
	    for (j=0; j<150; j++) {
		info[i].regname[j] = ' ';
	    }
	}

	/* Now read the temperature file.  */
	if (itype == 0) {
	    /* PRISM file.  */
	    /* START # 2 */
	    fpr = fopen(filetmp, "rb");

	    /* Read date and print out.  */
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%d %d %d %f %f", &mon, &day, &yr, &hr, &min);
	    printf("%d/%d/%d ", mon, day, yr);
	    printf(" %f:%f\n", hr, min);
	    (void)fflush(stdout);

	    /* Find number of lines to read.  */
	    frst_line = 7;
	    full_line = (numreg - frst_line) / (frst_line + 1);
	    last_line = numreg - frst_line -(full_line * (frst_line + 1));

	    /* Read first line & check if correct elapsed time.  */
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &eltim_read,
		   &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]);

	    /*
	     * while (eltim_read != eltim)
	     */
	    while ((eltim_read < (eltim - VUNITIZE_TOL)) || ((eltim + VUNITIZE_TOL) < eltim_read)) {
		/* Page through to end of data.  */
		for (i=0; i<(full_line + 1); i++) {
		    (void)bu_fgets(line, 150, fpr);
		}
		/* Read next elapsed time.  */
		(void)bu_fgets(line, 150, fpr);
		sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &eltim_read,
		       &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]);
	    }

	    /* When correct elapsed time is found, read data.  */
	    /* Read first line of data.  */
	    for (i=0; i<frst_line; i++) {
		info[i].temp = r[i];
	    }
	    k = frst_line;	/* Next region number of temperature to be read.  */
	    /* Read full lines of data.  */
	    for (i=0; i<full_line; i++) {
		(void)bu_fgets(line, 150, fpr);
		sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf",
		       &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7]);
		for (j=0; j<(frst_line + 1); j++) {
		    info[k].temp = r[j];
		    k++;
		}
	    }
	    /* Read last line of data.  */
	    (void)bu_fgets(line, 150, fpr);
	    if (last_line == 1) sscanf(line, "%lf", &r[0]);
	    if (last_line == 2) sscanf(line, "%lf %lf", &r[0], &r[1]);
	    if (last_line == 3) sscanf(line, "%lf %lf %lf", &r[0], &r[1], &r[2]);
	    if (last_line == 4) sscanf(line, "%lf %lf %lf %lf", &r[0], &r[1], &r[2],
				       &r[3]);
	    if (last_line == 5) sscanf(line, "%lf %lf %lf %lf %lf",
				       &r[0], &r[1], &r[2], &r[3], &r[4]);
	    if (last_line == 6) sscanf(line, "%lf %lf %lf %lf %lf %lf",
				       &r[0], &r[1], &r[2], &r[3], &r[4], &r[5]);
	    if (last_line == 7) sscanf(line, "%lf %lf %lf %lf %lf %lf %lf",
				       &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]);
	    if (last_line == 8) sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf",
				       &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7]);
	    if (last_line != 0) {
		for (j=0; j<last_line; j++) {
		    info[k].temp = r[j];
		    k++;
		}
	    }
	    printf("Prism out file read.\n");
	    (void)fflush(stdout);
	    /* END # 2 */
	} else {
	    /* Read generic file.  */
	    /* START # 3 */
	    /* File is already open.  */
	    /* Read elapsed time.  */
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%lf", &eltim_read);

	    while (!EQUAL(eltim_read, eltim)) {
		/* Page through to end of data.  */
		for (i=0; i<numreg; i++) {
		    (void)bu_fgets(line, 150, fpr);
		}
		(void)bu_fgets(line, 150, fpr);
		sscanf(line, "%lf", &eltim_read);
	    }

	    /* When correct elapsed time is found, read data.  */
	    for (i=0; i<numreg; i++) {
		(void)bu_fgets(line, 150, fpr);
		sscanf(line, "%lf", &r[0]);
		info[i].temp = r[0];
	    }
	}							/* END # 3 */

	/* Close file.  */
	(void)fclose(fpr);

	/* Read the region # & name file.  */
	fpr = fopen(filernn, "rb");
	printf("Region # & name file opened.\n");
	(void)fflush(stdout);
	numreg_read = 1;
	c = getc(fpr);
	while ((c != EOF) && (numreg_read < numreg)) {
	    (void)ungetc(c, fpr);
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%*d%149s", tmpstrng);
	    for (i=0; i<150; i++) {
		info[numreg_read].regname[i] = tmpstrng[i];
	    }
	    numreg_read++;
	    c = getc(fpr);
	}
	/* Close file.  */
	(void)fclose(fpr);

	/* Check if the number of regions read from the output file is */
	/* the same as the number of regions read from the region # &  */
	/* name file.  */
	if (numreg_read == numreg) {
	    printf("The number of regions read from the output file ");
	    printf("and the region # & name\n");
	    printf("file was the same, %d (does not ", (numreg-1));
	    printf("include background in number).\n");
	    (void)fflush(stdout);
	}
	if (numreg_read != numreg) {
	    printf("The number of regions read from the output file ");
	    printf("and the region # & name\n");
	    printf("file was not the same, %d vs %d.\n", (numreg-1),
		   (numreg_read-1));
	    printf("This is an ERROR.\n\n");
	    (void)fflush(stdout);
	}

	/* Build the directory.  */
	printf("Building directory.\n");
	(void)fflush(stdout);
	idx = 1;		/* Set index for rt_dirbuild.  */
	rtip = rt_dirbuild(argv[idx], idbuf, sizeof(idbuf));
	printf("File:  %s\n", argv[idx]);
	(void)fflush(stdout);
	printf("Database Title:  %s\n", idbuf);
	(void)fflush(stdout);

	/* Set useair to 1, to show hits of air.  Must show hits of air */
	/* since other irprep programs do.  */
	rtip->useair = 1;

	/* Load desired objects.  */
	idx = 2;		/* Set index for rt_gettree.  */
	while (argv[idx] != NULL) {
	    rt_gettree(rtip, argv[idx]);
	    printf("\t%s loaded.\n", argv[idx]);
	    (void)fflush(stdout);
	    idx++;
	}

	/* Find the total number of regions in the .g file & add one */
	/* for background.  */
	numreg_g = (int)rtip->nregions + 1;

	if ((numreg == numreg_read) && (numreg_read == numreg_g)) {
	    printf("The number of regions read from the output\n");
	    printf("file, the region # & name file, and the .g\n");
	    printf("file are all equal.  The number of regions\n");
	    printf("read, including the background is %d\n", numreg_g);
	    (void)fflush(stdout);
	} else {
	    printf("The number of regions read from the output\n");
	    printf("file, the region # & name file, and the .g\n");
	    printf("file are not all equal.\n");
	    printf("\toutput file:  %d\n", numreg);
	    printf("\tregion # & name file:  %d\n", numreg_read);
	    printf("\t.g file:  %d\n", numreg_g);
	    (void)fflush(stdout);
	}

	/* Start preparation.  */
	printf("Preparation started.\n");
	(void)fflush(stdout);
	rt_prep(rtip);

	/* Maximums & minimums of bounding rpp.  */
	rppmin[X] = rtip->mdl_min[X];
	rppmin[Y] = rtip->mdl_min[Y];
	rppmin[Z] = rtip->mdl_min[Z];
	rppmax[X] = rtip->mdl_max[X];
	rppmax[Y] = rtip->mdl_max[Y];
	rppmax[Z] = rtip->mdl_max[Z];

	/* Find the center of the bounding sphere or rpp.  */
	center[X] = rppmin[X] + (rppmax[X] - rppmin[X]) / 2.0;
	center[Y] = rppmin[Y] + (rppmax[Y] - rppmin[Y]) / 2.0;
	center[Z] = rppmin[Z] + (rppmax[Z] - rppmin[Z]) / 2.0;

	/* Find the length of the radius of the bounding sphere.  */
	radius = (rppmax[X] - rppmin[X]) * (rppmax[X] - rppmin[X]) +
	    (rppmax[Y] - rppmin[Y]) * (rppmax[Y] - rppmin[Y]) +
	    (rppmax[Z] - rppmin[Z]) * (rppmax[Z] - rppmin[Z]);
	radius = sqrt(radius) / 2.0 + 1.0;	/* Make radius a bit longer.  */

	printf("\nMinimum & maximum X:  %f - %f\n", rppmin[X], rppmax[X]);
	printf("Minimum & maximum Y:  %f - %f\n", rppmin[Y], rppmax[Y]);
	printf("Minimum & maximum Z:  %f - %f\n", rppmin[Z], rppmax[Z]);
	printf("Center of bounding sphere:  %f, %f, %f\n",
	       center[X], center[Y], center[Z]);
	printf("Radius of bounding sphere:  %f\n", radius);
	printf("Enter multiplication factor for radius.\n\t");
	(void)fflush(stdout);
	ret = scanf("%lf", &multi);
	if (ret == 0)
	    perror("scanf");
	/* Multiply radius by multiplication factor.  */
	radius = radius * multi;

	/* Set up parameters for rt_shootray.  */
	RT_APPLICATION_INIT(&ap);
	ap.a_hit = hit;		/* User supplied hit function.  */
	ap.a_miss = miss;		/* User supplied miss function.  */
	ap.a_overlap = overlap;	/* User supplied overlap function.  */
	ap.a_rt_i = rtip;		/* Pointer from rt_dirbuild.  */
	ap.a_onehit = 1;		/* Hit flag, stop after first hit.  */
	ap.a_level = 0;		/* Recursion level for diagnostics.  */
	ap.a_resource = 0;		/* Address of resource struct.  */

	/* Open output file.  */
	fpw = fopen(fileout, "wb");

	/* User enters grid size.  */
	fprintf(stderr, "Enter grid size.\n\t");
	ret = scanf("%d", &wide);
	if (ret == 0)
	    perror("scanf");
	high = wide;

	/* User enters azimuth & elevation for viewing.  */
	fprintf(stderr, "Enter azimuth & elevation.\n\t");
	ret = scanf("%lf %lf", &az, &el);
	if (ret == 0)
	    perror("scanf");
	alpha = az * DEG2RAD;
	beta = (-el) * DEG2RAD;
	calpha = cos(alpha);
	salpha = sin(alpha);
	cbeta = cos(beta);
	sbeta = sin(beta);

	/* Find spacing between rays.  */
	deltaw = 2. * radius / (float)wide;
	deltah = 2. * radius / (float)high;

	/* Print grid size, azimuth, and elevation.  */
	printf("gridsize:  %d x %d\n", wide, high);
	printf("azimuth:  %f degrees\n", az);
	printf("elevation:  %f degrees\n", el);
	(void)fflush(stdout);

	/* Write size of grid to output file.  */
	fprintf(fpw, "%d\t%d\n", wide, high);
	(void)fflush(stdout);

	/* Set firing direction.  Rotate (-1, 0, 0) to proper position.  */
	vec[X] = (-1.0) * cbeta * calpha;
	vec[Y] = (-1.0) * cbeta * salpha;
	vec[Z] = (-1.0) * (-1.0) * sbeta;
	/* Normalize.  */
	denom = vec[X] * vec[X] + vec[Y] * vec[Y] + vec[Z] * vec[Z];
	denom = sqrt(denom);
	vec[X] /= denom;
	vec[Y] /= denom;
	vec[Z] /= denom;
	ap.a_ray.r_dir[X] = vec[X];
	ap.a_ray.r_dir[Y] = vec[Y];
	ap.a_ray.r_dir[Z] = vec[Z];

	/* Set starting point.  */
	vec[X] = center[X] + radius;

	for (i=0; i<high; i++) {
	    vec[Z] = center[Z] + radius - (float)i * deltah;

	    for (j=0; j<wide; j++) {
		vec[Y] = center[Y] - radius + (float)j * deltaw;
		/* Rotate starting point.  */
		ap.a_ray.r_pt[X] = vec[X] * cbeta * calpha +
		    vec[Z] * sbeta * calpha - vec[Y] * salpha;
		ap.a_ray.r_pt[Y] = vec[X] * cbeta * salpha +
		    vec[Z] * sbeta * salpha + vec[Y] * calpha;
		ap.a_ray.r_pt[Z] = (-vec[X]) * sbeta + vec[Z] * cbeta;

		/* Call rt_shootray.  */
		region_hit = rt_shootray(&ap);

		/* Write temperature of region to output file.  */
		fprintf(fpw, "%f\n", info[region_hit].temp);
		(void)fflush(fpw);
	    }
	}

    }							/* END # 4 */
    return 0;
}							/* END # 1 */
示例#15
0
int main(int argc, char **argv)
{
    struct application ap;	/* Structure passed between functions.  */
    struct rt_i *rtip;
    int idx;		/* Index for rt_dirbuild & rt_gettree.  */
    char idbuf[32];	/* Contains database name.  */
    struct region *pr;	/* Used in finding region names.  */
    double rho, phi, theta;/* Spherical coordinates for starting point.  */
    double areabs=0.0;	/* Area of bounding sphere (mm**2).  */
    int ians;		/* Answer of question.  */
    double strtpt[3];	/* Starting point of ray.  */
    double strtdir[3];	/* Starting direction.  */
    size_t loops;	/* Number of rays fired.  */
    size_t r;		/* Variable in loops.  */
    int i, j, k;		/* Variable in loops.  */
    long seed;		/* Initial seed for random number generator.  */
    double denom;	/* Denominator.  */
    double elev;		/* Elevation, used to find point on yz-plane.  */
    double az;		/* Azimuth, used to find point on yz-plane.  */
    double rad;		/* Radius, used to find point on yz-plane.  */
    double s[3], t[3];	/* Temporary variables used to find points.  */
    double q;		/* Temporary variable used to find points.  */
    int numreg;		/* Number of regions.  */
    double center[3];	/* Center of the bounding rpp.  */
    double sf;		/* Used to print shape factor.  */
    double dump;		/* How often a dump is to occur.  */
    int idump;		/* 1=>dump to occur.  */

    FILE *fp;		/* Used to open files.  */
    char outfile[16];	/* Output file.  */
    FILE *fp1;		/* Used to read region # & name file.  */
    char rnnfile[16];	/* Region # & name file.  */
    FILE *fp2;		/* Used to write the error file.  */
    char errfile[16];	/* Error file.  */
    double totalsf;	/* Sum of shape factors.  */
    double totalnh;	/* Sum of number of hits.  */
    int itype;		/* Type of file to be created, 0=>regular,  */
			/* 1=>generic.  */
    char line[500];	/* Buffer to read a line of data into.  */
    int c;		/* Reads one character of information.  */
    int icnt;		/* Counter for shape factor.  */
    char tmpname[150];	/* Temporary name.  */
    int tmpreg;		/* Temporary region number.  */
    char rnnname[800][150];  /* Region name from region # & name file.  */
    int rnnnum;		/* Number of regions in region # & name file.  */
    int rnnchar[800];	/* Number of characters in name.  */
    int rnnreg[800];	/* Region number from region # & name file.  */
    int jcnt;		/* Counter.  */
    int equal;		/* 0=>equal, 1=>not equal.  */
    double rcpi, rcpj;	/* Used to check reciprocity.  */
    double rcp_diff;	/* Difference in reciprocity.  */
    double rcp_pdiff;	/* Percent difference in reciprocity.  */
    int ret;

    struct bn_unif *msr = NULL;

    /* Check to see if arguments are implemented correctly.  */
    if ((argc < 3 || argv[1] == NULL) || (argv[2] == NULL)) {
	fprintf(stderr, "\nUsage:  %s file.g objects\n\n", *argv);
    } else {
	/* START # 1 */

	/* Ask what type of file is to be created - regular */
	/* or generic.  */
	printf("Enter type of file to be written (0=>regular or ");
	printf("1=>generic).  ");
	(void)fflush(stdout);
	ret = scanf("%1d", &itype);
	if (ret == 0)
	    bu_exit(-1, "scanf failure when reading file type");
	if (itype != 1) itype = 0;

	/* Enter names of files to be used.  */
	fprintf(stderr, "Enter name of output file (15 char max).\n\t");
	(void)fflush(stderr);
	ret = scanf("%15s", outfile);
	if (ret == 0)
	    bu_exit(-1, "scanf failure when reading output file name");

	/* Read name of the error file to be written.  */
	printf("Enter the name of the error file (15 char max).\n\t");
	(void)fflush(stdout);
	ret = scanf("%15s", errfile);
	if (ret == 0)
	    bu_exit(-1, "scanf failure when reading error file name");

	{
	    /* Enter name of region # & name file to be read.  */
	    printf("Enter region # & name file to be read ");
	    printf("(15 char max).\n\t");
	    (void)fflush(stdout);
	    ret = scanf("%15s", rnnfile);
	    if (ret == 0)
		bu_exit(-1, "scanf failure when reading region # + name file");
	}

	/* Check if dump is to occur.  */
	idump = 0;
	printf("Do you want to dump intermediate shape factors to ");
	printf("screen (0-no, 1-yes)?  ");
	(void)fflush(stdout);
	ret = scanf("%1d", &idump);
	if (ret == 0)
	    bu_exit(-1, "scanf failure - intermediate shape factors setting");

	/* Find number of rays to be fired.  */
	fprintf(stderr, "Enter number of rays to be fired.  ");
	(void)fflush(stderr);
	ret = scanf("%llu", (unsigned long long *)&loops);
	if (ret == 0)
	    bu_exit(-1, "scanf failure - number of rays to be fired");

	/* clamp loops */
	if (loops > UINT32_MAX)
	    loops = UINT32_MAX;

	/* Set seed for random number generator.  */
	seed = 1;
	fprintf(stderr, "Do you wish to enter your own seed (0) or ");
	fprintf(stderr, "use the default of 1 (1)?  ");
	(void)fflush(stderr);
	ret = scanf("%1d", &ians);
	if (ret == 0)
	    bu_exit(-1, "scanf failure - seed use setting");
	if (ians == 0) {
	    fprintf(stderr, "Enter unsigned integer seed.  ");
	    (void)fflush(stderr);
	    ret = scanf("%ld", &seed);
	    if (ret == 0)
		bu_exit(-1, "scanf failure - seed");
	}
	msr = bn_unif_init(seed, 0);
	bu_log("seed initialized\n");

	/* Read region # & name file.  */
	rnnnum = 0;
	fp1 = fopen(rnnfile, "rb");
	c = getc(fp1);
	while (c != EOF) {
	    (void)ungetc(c, fp1);
	    (void)bu_fgets(line, 200, fp1);
	    sscanf(line, "%d%149s", &tmpreg, tmpname);
	    for (i=0; i<150; i++) {
		rnnname[rnnnum][i] = tmpname[i];
	    }
	    rnnreg[rnnnum] = tmpreg;
	    rnnnum++;
	    c = getc(fp1);
	}
	(void)fclose(fp1);

	printf("Number of regions read from region # & name file:  %d\n",		rnnnum);
	(void)fflush(stdout);

	/* Find number of characters in each region name.  */
	for (i=0; i<rnnnum; i++) {
	    jcnt = 0;
	    while (rnnname[i][jcnt] != '\0') {
		jcnt++;
	    }
	    rnnchar[i] = jcnt;
	}

	/* Build directory.  */
	idx = 1;	/* Set index for rt_dirbuild.  */
	rtip = rt_dirbuild(argv[idx], idbuf, sizeof(idbuf));
	printf("Database Title:  %s\n", idbuf);
	(void)fflush(stdout);

	/* Set useair to 1 to show hits of air.  */
	rtip->useair = 1;

	/* Load desired objects.  */
	idx = 2;	/* Set index.  */
	while (argv[idx] != NULL) {
	    rt_gettree(rtip, argv[idx]);
	    idx += 1;
	}

	/* Find number of regions.  */
	numreg = (int)rtip->nregions;

	fprintf(stderr, "Number of regions:  %d\n", numreg);
	(void)fflush(stderr);

	/* Zero all arrays.  */
	for (i=0; i<numreg; i++) {
	    info[i].name = "\0";
	    info[i].regnum = (-1);
	    info[i].numchar = 0;
	    info[i].lvrays = 0.0;
	    info[i].engarea = 0.0;
	    for (j=0; j<numreg; j++) {
		info[i].intrays[j] = 0.0;
	    }
	}
	nummiss = 0.0;

	/* Get database ready by starting prep.  */
	rt_prep(rtip);

	/* Find the center of the bounding rpp.  */
	center[X] = rtip->mdl_min[X] +
	    (rtip->mdl_max[X] - rtip->mdl_min[X]) / 2.0;
	center[Y] = rtip->mdl_min[Y] +
	    (rtip->mdl_max[Y] - rtip->mdl_min[Y]) / 2.0;
	center[Z] = rtip->mdl_min[Z] +
	    (rtip->mdl_max[Z] - rtip->mdl_min[Z]) / 2.0;

	/* Put region names into structure.  */
	pr = BU_LIST_FIRST(region, &rtip->HeadRegion);
	for (i=0; i<numreg; i++) {
	    info[(int)(pr->reg_bit)].name = pr->reg_name;
	    pr = BU_LIST_FORW(region, &(pr->l));
	}

	/* Set up parameters for rt_shootray.  */
	RT_APPLICATION_INIT(&ap);
	ap.a_hit = hit;		/* User supplied hit function.  */
	ap.a_miss = miss;	/* User supplied miss function.  */
	ap.a_overlap = overlap;	/* User supplied overlap function.  */
	ap.a_rt_i = rtip;	/* Pointer from rt_dirbuild.  */
	ap.a_onehit = 0;	/* Look at all hits.  */
	ap.a_level = 0;		/* Recursion level for diagnostics.  */
	ap.a_resource = 0;	/* Address for resource structure.  */

	dump = 1000000.0;	/* Used for dumping info.  */

	for (r=0; r<loops; r++) {
	    /* Number of rays fired.  */
	    /* START # 2 */

	    /* Find length of 'diagonal' (rho).  (In reality rho is */
	    /* the radius of bounding sphere).  */
	    rho = (rtip->mdl_max[X] - rtip->mdl_min[X])
		* (rtip->mdl_max[X] - rtip->mdl_min[X])
		+(rtip->mdl_max[Y] - rtip->mdl_min[Y])
		* (rtip->mdl_max[Y] - rtip->mdl_min[Y])
		+(rtip->mdl_max[Z] - rtip->mdl_min[Z])
		* (rtip->mdl_max[Z] - rtip->mdl_min[Z]);
	    rho = sqrt(rho) / 2.0 + .5;

	    /* find surface area of bounding sphere.  */
	    areabs = 4.0 * M_PI * rho * rho;

	    /* Second way to find starting point and direction.  */
	    /* This approach finds the starting point and direction */
	    /* by using parallel rays.  */

	    /* Find point on the bounding sphere.  (The negative */
	    /* of the unit vector of this point will eventually be */
	    /* the firing direction.  */
	    q = BN_UNIF_DOUBLE(msr) + 0.5;
	    theta = q * M_2PI;
	    q = BN_UNIF_DOUBLE(msr) + 0.5;
	    phi = (q * 2.0) - 1.0;
	    phi = acos(phi);
	    strtdir[X] = rho * sin(phi) * cos(theta);
	    strtdir[Y] = rho * sin(phi) * sin(theta);
	    strtdir[Z] = rho * cos(phi);

	    /* Elevation and azimuth for finding a vector in a plane.  */
	    elev = M_PI_2 - phi;
	    az = theta;

	    /* Find vector in yz-plane.  */

	    q = BN_UNIF_DOUBLE(msr) + 0.5;
	    theta = q * M_2PI;
	    q = BN_UNIF_DOUBLE(msr) + 0.5;
	    rad = rho * sqrt(q);
	    s[X] = 0.0;
	    s[Y] = rad * cos(theta);
	    s[Z] = rad * sin(theta);

	    /* Rotate vector.  */
	    t[X] = s[X] * cos(elev) * cos(az) - s[Z] * sin(elev) * cos(az)
		- s[Y] * sin(az);
	    t[Y] = s[X] * cos(elev) * sin(az) - s[Z] * sin(elev) * sin(az)
		+ s[Y] * cos(az);
	    t[Z] = s[X] * sin(elev) + s[Z] * cos(elev);

	    /* Translate the point.  This is starting point.  */
	    strtpt[X] = t[X] + strtdir[X];
	    strtpt[Y] = t[Y] + strtdir[Y];
	    strtpt[Z] = t[Z] + strtdir[Z];

	    /* Now transfer starting point so that it is in */
	    /* the absolute coordinates not the origin's.  */
	    strtpt[X] += center[X];
	    strtpt[Y] += center[Y];
	    strtpt[Z] += center[Z];

	    /* Normalize starting direction and make negative.  */
	    denom = strtdir[X] * strtdir[X] +
		strtdir[Y] * strtdir[Y] +
		strtdir[Z] * strtdir[Z];
	    denom = sqrt(denom);
	    strtdir[X] /= (-denom);
	    strtdir[Y] /= (-denom);
	    strtdir[Z] /= (-denom);

	    /* Set up firing point and direction.  */
	    ap.a_ray.r_pt[X] = strtpt[X];
	    ap.a_ray.r_pt[Y] = strtpt[Y];
	    ap.a_ray.r_pt[Z] = strtpt[Z];
	    ap.a_ray.r_dir[X] = strtdir[X];
	    ap.a_ray.r_dir[Y] = strtdir[Y];
	    ap.a_ray.r_dir[Z] = strtdir[Z];

	    /* Call rt_shootray for "forward ray".  */
	    (void)rt_shootray(&ap);

	    if (EQUAL(r, (dump - 1.0))) {
		printf("%llu rays have been fired in forward direction.\n",
		       (unsigned long long)(r+1));
		(void)fflush(stdout);
		if (idump == 1) {
		    /* START # 3 */
		    printf("\n****************************************");
		    printf("****************************************\n");
		    (void)fflush(stdout);
		    /* Dump info to file.  */
		    for (i=0; i<numreg; i++) {
			for (j=0; j<numreg; j++) {
			    sf = 0.0;
			    if ((info[i].lvrays < -ZEROTOL) || (ZEROTOL <
								info[i].lvrays))
				sf = info[i].intrays[j] / info[i].lvrays;

			    printf("%d\t%d\t%f\n", i, j, sf);
			    (void)fflush(stdout);
			}
		    }
		}						/* START # 3 */

		dump = dump + 1000000.0;
	    }

	}					/* END # 2 */

	/* Find area bounded by engine air using Monte Carlo method.  */
	for (i=0; i<numreg; i++) {
	    /* Old way, only incrementing info[i].allvrays for forward */
	    /* ray therefore do not divide by 2.  Division by 2 is to */
	    /* include the backwards ray also.  */
	    /*
	     * info[i].engarea = info[i].allvrays * areabs / loops / 2.0;
	     */
	    info[i].engarea = info[i].allvrays * areabs / (double)loops;

	    /* Put area into square meters.  */
	    info[i].engarea *= 1.e-6;
	}

	/* Find number of characters in each region name.  */
	for (i=0; i<numreg; i++) {
	    jcnt = 0;
	    while (info[i].name[jcnt] != '\0') {
		jcnt++;
	    }
	    info[i].numchar = jcnt;
	}

	/* Find correct region number.  */
	printf("Finding correct region numbers.\n");
	(void)fflush(stdout);
	for (i=0; i<numreg; i++) {
	    for (j=0; j<rnnnum; j++) {
		equal = 0;	/* 1=>not equal.  */
		jcnt = rnnchar[j];
		for (k=info[i].numchar; k>=0; k--) {
		    if (jcnt<0) equal = 1;
		    else if (info[i].name[k] != rnnname[j][jcnt])
			equal = 1;
		    jcnt--;
		}
		if (equal == 0) info[i].regnum = rnnreg[j];
	    }
	}
	printf("Finished finding correct region numbers.\n");
	(void)fflush(stdout);

	/******************************************************************/

	/* Check for reciprocity.  */
	/* Open error file.  */
	fp2 = fopen(errfile, "wb");
	fprintf(fp2, "\nError file for shapefact.\n");
	fprintf(fp2, "Shape factor file created:  %s\n\n", outfile);
	fprintf(fp2, "Regions with reciprocity errors greater ");
	fprintf(fp2, "than 10%%.\n\n");
	(void)fflush(fp2);

	for (i=0; i<numreg; i++) {
	    for (j=0; j<numreg; j++) {
		rcpi = 0.0;
		rcpj = 0.0;
		if ((info[i].lvrays < -ZEROTOL) || (ZEROTOL < info[i].lvrays))
		    rcpi = info[i].intrays[j] * info[i].engarea /info[i].lvrays;
		if ((info[j].lvrays < -ZEROTOL) || (ZEROTOL < info[j].lvrays))
		    rcpj = info[j].intrays[i] * info[j].engarea /info[j].lvrays;
		rcp_diff = rcpi - rcpj;
		if (rcp_diff < 0.0) rcp_diff = (-rcp_diff);
		if ((rcpi < -ZEROTOL) || (ZEROTOL < rcpi))
		    rcp_pdiff = rcp_diff / rcpi;
		else rcp_pdiff = 0.0;	/* Don't divide by 0.  */
		/* Print reciprocity errors greater than 10%.  */
		if (rcp_pdiff > 0.1) {
		    fprintf(fp2, "%d   %d   %f   %f   %f   %f\n",
			    info[i].regnum, info[j].regnum, rcpi, rcpj, rcp_diff,
			    (rcp_pdiff * 100.0));
		    (void)fflush(fp2);
		}
	    }
	}
	/* Close error file.  */
	(void)fclose(fp2);

	/******************************************************************/

	/* Print out shape factor to regular output file.  */
	if (itype == 0) {
	    fp = fopen(outfile, "wb");
	    fprintf(fp, "Number of forward rays fired:  %llu\n\n", (unsigned long long)loops);
	    (void)fflush(fp);

	    /* Print out structure.  */
	    for (i=0; i<numreg; i++) {
		/* Print region number, region name, & engine area.  */
		fprintf(fp, "%d\t%s\t%e\n",
			info[i].regnum, info[i].name, info[i].engarea);
		(void)fflush(fp);

		/* Zero sums for shape factors & rays hit.  */
		totalsf = 0.0;
		totalnh = 0.0;

		for (j=0; j<numreg; j++) {
		    sf = 0.0;
		    if ((info[i].lvrays < -ZEROTOL) || (ZEROTOL <
							info[i].lvrays))
			sf = info[i].intrays[j] / info[i].lvrays;

		    /* Print region number & shape factor.  */
		    fprintf(fp, "   %d\t%e\n",
			    info[j].regnum, sf);
		    (void)fflush(fp);

		    /* Add to sum of shape factors & number of hits.  */
		    totalsf += sf;
		    totalnh += info[i].intrays[j];

		}

		/* Print sum of hits & sum of shape factors.  */
		fprintf(fp, " sum of hits:  %f\n", totalnh);
		fprintf(fp, " sum of shape factors:  %f\n\n", totalsf);
		(void)fflush(fp);
	    }
	    (void)fclose(fp);
	}

	/******************************************************************/

	/* Create and write to generic shape factor file.  */
	if (itype == 1) {
	    fp = fopen(outfile, "wb");
	    for (i=0; i<numreg; i++) {
		/* Count the number of shape factors.  */
		icnt = 0;
		for (j=0; j<numreg; j++) {
		    if (info[i].intrays[j] > ZEROTOL) icnt++;
		}
		/* Print the # 5, region number (matches firpass &  */
		/* secpass), engine area, & number of shape factors.  */
		fprintf(fp, " 5  %d  %e  %d\n",
			info[i].regnum, info[i].engarea, icnt);
		(void)fflush(fp);
		for (j=0; j<numreg; j++) {
		    if (info[i].intrays[j] > ZEROTOL) {
			sf = info[i].intrays[j] / info[i].lvrays;
			/* Print each region # & shape factor.  */
			fprintf(fp, "    %d  %e\n", info[j].regnum, sf);
			(void)fflush(fp);
		    }
		}
	    }
	    (void)fclose(fp);
	}

    }						/* END # 1 */
    return 0;
}
示例#16
0
文件: enf-g.c 项目: kanzure/brlcad
struct obj_info *
Assembly_import( int id_start )
{
    char line[MAX_LINE_SIZE];
    struct obj_info *this_assem, *member;
    struct wmember assem_head;
    int id_end, member_id;
    size_t i;

    BU_ALLOC(this_assem, struct obj_info);

    this_assem->obj_type = ASSEMBLY_TYPE;
    this_assem->obj_id = id_start;
    this_assem->part_count = 0;
    this_assem->members = NULL;
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "AssemblyName", 12 ) ) {
	    line[strlen( line ) - 1] = '\0';
	    this_assem->obj_name = bu_strdup( &line[13] );
	    lower_case( this_assem->obj_name );
	    DO_INDENT;
	    bu_log( "Start of assembly %s (id = %d)\n", this_assem->obj_name, id_start );
	    indent_level += indent_delta;
	} else if ( !bu_strncmp( line, "PartId", 6 ) ) {
	    /* found a member part */
	    member_id = atoi( &line[7] );
	    member = Part_import( member_id );
	    if ( !member )
		continue;
	    this_assem->part_count++;
	    this_assem->members = (struct obj_info **)bu_realloc(
		this_assem->members,
		this_assem->part_count * sizeof( struct obj_info *),
		"this_assem->members" );
	    this_assem->members[this_assem->part_count-1] = member;
	} else if ( !bu_strncmp( line, "AssemblyId", 10 ) ) {
	    /* found a member assembly */
	    member_id = atoi( &line[11] );
	    member = Assembly_import( member_id );
	    this_assem->part_count++;
	    this_assem->members = (struct obj_info **)bu_realloc(
		this_assem->members,
		this_assem->part_count * sizeof( struct obj_info *),
		"this_assem->members" );
	    this_assem->members[this_assem->part_count-1] = member;
	} else if ( !bu_strncmp( line, "EndAssemblyId", 13 ) ) {
	    /* found end of assembly, make sure it is this one */
	    id_end = atoi( &line[14] );
	    if ( id_end != id_start )
		bu_exit( 1, "%s: ERROR: found end of assembly id %d while processing id %d\n", progname,id_end, id_start );
	    indent_level -= indent_delta;
	    DO_INDENT;
	    bu_log( "Found end of assembly %s (id = %d)\n",  this_assem->obj_name, id_start );
	    break;
	} else {
	    bu_log( "%s: Unrecognized line encountered while processing assembly id %d:\n", progname,id_start );
	    bu_exit( 1, "%s\n", line );
	}
    }

    Make_brlcad_names( this_assem );

    /* write this assembly to the database */
    BU_LIST_INIT( &assem_head.l );

    for ( i=0; i<this_assem->part_count; i++ )
	if ( mk_addmember( this_assem->members[i]->brlcad_comb,
			   &assem_head.l, NULL, WMOP_UNION ) == WMEMBER_NULL )
	    bu_exit( 1, "%s: ERROR: Failed to add region %s to assembly %s\n",
			progname,this_assem->members[i]->brlcad_comb, this_assem->brlcad_comb );

    if ( mk_comb( fd_out, this_assem->brlcad_comb, &assem_head.l, 0, NULL, NULL, NULL,
		  0, 0, 0, 0, 0, 0, 0 ) )
	bu_exit( 1, "%s: ERROR: Failed to write combination (%s) to database\n", progname,this_assem->brlcad_comb );
    if ( use_part_name_hash ) {
	if ( db5_update_attribute( this_assem->brlcad_comb, "Part_No",
				   this_assem->obj_name, fd_out->dbip ) ) {
	    bu_log( "Failed to assign Part_no attribute to %s\n",
		    this_assem->brlcad_comb );
	}
    }

    return this_assem;
}
void
use_air(char *buffer, com_table *ctp, struct rt_i *UNUSED(rtip))
{
    int new_use = 0;      /* current position on the *buffer */
    char response[128];
    char *rp = response;
    char db_title[TITLE_LEN+1];	/* title from MGED database */
    struct rt_i *my_rtip;

    extern char *db_name;		/* Name of MGED database file */

    while (isspace((int)*buffer))
	++buffer;
    if (*buffer == '\0') {
	/* display current value of use_of_air */
	bu_log("use_air = %d\n", ap.a_rt_i->useair);
	return;
    }
    if (!isdigit((int)*buffer)) {
	com_usage(ctp);
	return;
    }
    while (isdigit((int)*buffer)) {
	new_use *= 10;
	new_use += *buffer++ - '0';
    }
    if (new_use && (new_use != 1)) {
	bu_log("Warning: useair=%d specified, will set to 1\n",
	       new_use);
	new_use = 1;
    }
    if (rti_tab[new_use] == RTI_NULL) {
	bu_log(" Air %s in the current directory of database objects.\n",
	       new_use ? "is not included" : "is included");
	bu_log(
	    " To set useair=%d requires building/prepping another directory.\n",
	    new_use);
	bu_log(" Do you want to do that now (y|n)[n]? ");
	bu_fgets(response, sizeof(response), stdin);
	while ((*rp == ' ') || (*rp == '\t'))
	    ++rp;
	if ((*rp != 'y') && (*rp != 'Y')) {
	    bu_log("useair remains %d\n", ap.a_rt_i->useair);
	    return;
	}
	bu_log("Building the directory...");
	if ((my_rtip = rt_dirbuild(db_name, db_title, TITLE_LEN)) == RTI_NULL) {
	    bu_log("Could not load file %s\n", db_name);
	    printusage();
	    bu_exit(1, NULL);
	}
	rti_tab[new_use] = my_rtip;
	my_rtip->useair = new_use;
	my_rtip->rti_save_overlaps = (overlap_claims > 0);

	bu_log("Prepping the geometry...");
	do_rt_gettrees(my_rtip, NULL, 0, &need_prep);
    }
    ap.a_rt_i = rti_tab[new_use];
    ap.a_resource = &res_tab[new_use];
    set_diameter(ap.a_rt_i);
}
示例#18
0
文件: pack.c 项目: cciechad/brlcad
void common_pack_texture(void** app_data, int* app_ind, const char* filename) {
    FILE *fh;
    char line[256], *token;
    unsigned char c;
    unsigned int marker, size;
    short s;

    marker = *app_ind;
    *app_ind += sizeof(unsigned int);

    fh = fopen(filename, "r");
    if (!fh) {
	fprintf(stderr, "error: Textures file %s doesn't exist, exiting.\n", filename);
	exit(1);
    }


    while (bu_fgets(line, 256, fh)) {
	token = strtok(line, ",");
	if (!strcmp("texture", token)) {
	    token = strtok(NULL, ",");
	    if (!strcmp("stack", token)) {
		s = TEXTURE_STACK;
		common_pack_write(app_data, app_ind, &s, sizeof(short));

		/* name */
		token = strtok(NULL, ",");
		if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;

		c = strlen(token) + 1;
		common_pack_write(app_data, app_ind, &c, sizeof(char));
		common_pack_write(app_data, app_ind, token, c);
	    } else if (!strcmp("mix", token)) {
		tfloat coef;

		s = TEXTURE_MIX;
		common_pack_write(app_data, app_ind, &s, sizeof(short));

		/* name */
		token = strtok(NULL, ",");
		c = strlen(token) + 1;
		common_pack_write(app_data, app_ind, &c, sizeof(char));
		common_pack_write(app_data, app_ind, token, c);

		/* texture 1 */
		token = strtok(NULL, ",");
		c = strlen(token) + 1;
		common_pack_write(app_data, app_ind, &c, sizeof(char));
		common_pack_write(app_data, app_ind, token, c);

		/* texture 2 */
		token = strtok(NULL, ",");
		c = strlen(token) + 1;
		common_pack_write(app_data, app_ind, &c, sizeof(char));
		common_pack_write(app_data, app_ind, token, c);
/*
  sscanf(strstr(tag, "mode"), "mode=\"%[^\"]", ident);
  c = strlen(ident);
  common_pack_write(app_data, app_ind, &c, sizeof(char));
  common_pack_write(app_data, app_ind, ident, c);
*/

		/* coefficient */
		token = strtok(NULL, ",");
		if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
		coef = atof(token);
		common_pack_write(app_data, app_ind, &coef, sizeof(tfloat));
	    }
	} else if (!strcmp("blend", token)) {
	    TIE_3 color1, color2;

	    s = TEXTURE_BLEND;
	    common_pack_write(app_data, app_ind, &s, sizeof(short));

	    /* color 1 */
	    token = strtok(NULL, ",");
	    color1.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    color1.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    color1.v[2] = atof(token);

	    /* color 2 */
	    token = strtok(NULL, ",");
	    color2.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    color2.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    color2.v[2] = atof(token);

	    common_pack_write(app_data, app_ind, &color1, sizeof(TIE_3));
	    common_pack_write(app_data, app_ind, &color2, sizeof(TIE_3));
	} else if (!strcmp("bump", token)) {
	    TIE_3 coef;

	    s = TEXTURE_BUMP;
	    common_pack_write(app_data, app_ind, &s, sizeof(short));

	    /* coefficient */
	    token = strtok(NULL, ",");
	    coef.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    coef.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    coef.v[2] = atof(token);

	    common_pack_write(app_data, app_ind, &coef, sizeof(TIE_3));
	} else if (!strcmp("checker", token)) {
	    int tile;

	    s = TEXTURE_CHECKER;
	    common_pack_write(app_data, app_ind, &s, sizeof(short));

	    /* tile */
	    token = strtok(NULL, ",");
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    tile = atoi(token);

	    common_pack_write(app_data, app_ind, &tile, sizeof(unsigned int));
	} else if (!strcmp("camo", token)) {
	    tfloat toksize;
	    int octaves, absolute;
	    TIE_3 color1, color2, color3;

	    s = TEXTURE_CAMO;
	    common_pack_write(app_data, app_ind, &s, sizeof(short));

	    /* size */
	    token = strtok(NULL, ",");
	    toksize = atof(token);

	    /* octaves */
	    token = strtok(NULL, ",");
	    octaves = atoi(token);

	    /* absolute */
	    token = strtok(NULL, ",");
	    absolute = atoi(token);

	    /* color 1 */
	    token = strtok(NULL, ",");
	    color1.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    color1.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    color1.v[2] = atof(token);

	    /* color 2 */
	    token = strtok(NULL, ",");
	    color2.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    color2.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    color2.v[2] = atof(token);

	    /* color 3 */
	    token = strtok(NULL, ",");
	    color3.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    color3.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    color3.v[2] = atof(token);

	    common_pack_write(app_data, app_ind, &toksize, sizeof(tfloat));
	    common_pack_write(app_data, app_ind, &octaves, sizeof(int));
	    common_pack_write(app_data, app_ind, &absolute, sizeof(int));
	    common_pack_write(app_data, app_ind, &color1, sizeof(TIE_3));
	    common_pack_write(app_data, app_ind, &color2, sizeof(TIE_3));
	    common_pack_write(app_data, app_ind, &color3, sizeof(TIE_3));
	} else if (!strcmp("clouds", token)) {
	    tfloat toksize;
	    int octaves, absolute;
	    TIE_3 scale, translate;

	    s = TEXTURE_CLOUDS;
	    common_pack_write(app_data, app_ind, &s, sizeof(short));

	    /* size */
	    token = strtok(NULL, ",");
	    toksize = atof(token);

	    /* octaves */
	    token = strtok(NULL, ",");
	    octaves = atoi(token);

	    /* absolute */
	    token = strtok(NULL, ",");
	    absolute = atoi(token);

	    /* scale */
	    token = strtok(NULL, ",");
	    scale.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    scale.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    scale.v[2] = atof(token);

	    /* translate */
	    token = strtok(NULL, ",");
	    translate.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    translate.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    translate.v[2] = atof(token);

	    common_pack_write(app_data, app_ind, &toksize, sizeof(tfloat));
	    common_pack_write(app_data, app_ind, &octaves, sizeof(int));
	    common_pack_write(app_data, app_ind, &absolute, sizeof(int));
	    common_pack_write(app_data, app_ind, &scale, sizeof(TIE_3));
	    common_pack_write(app_data, app_ind, &translate, sizeof(TIE_3));
	} else if (!strcmp("image", token)) {
/*
  char file[64];
  image = SDL_LoadBMP(file);
  if (image) {
  s = TEXTURE_IMAGE;
  common_pack_write(app_data, app_ind, &s, sizeof(short));
  common_pack_write(app_data, app_ind, &(image->w), sizeof(short));
  common_pack_write(app_data, app_ind, &(image->h), sizeof(short));
  common_pack_write(app_data, app_ind, image->pixels, 3*image->w*image->h);
  }
*/
	} else if (!strcmp("gradient", token)) {
	    int axis;

	    s = TEXTURE_GRADIENT;
	    common_pack_write(app_data, app_ind, &s, sizeof(short));

	    /* axis */
	    token = strtok(NULL, ",");
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    axis = atoi(token);

	    common_pack_write(app_data, app_ind, &axis, sizeof(int));
	}
    }

    fclose(fh);


    size = *app_ind - marker - sizeof(unsigned int);
    common_pack_write(app_data, &marker, &size, sizeof(unsigned int));
    *app_ind = marker + size;
}
示例#19
0
文件: pack.c 项目: cciechad/brlcad
void common_pack_prop(void** app_data, int* app_ind, const char* filename) {
    FILE *fh;
    common_prop_t def_prop;
    char line[ADRT_NAME_SIZE], name[ADRT_NAME_SIZE], *token;
    unsigned char c;
    unsigned int marker, size, prop_num;

    marker = *app_ind;
    *app_ind += sizeof(unsigned int);

    fh = fopen(filename, "r");
    if (!fh) {
	fprintf(stderr, "error: Properties file %s doesn't exist, exiting.\n", filename);
	exit(1);
    }

    prop_num = 0;
    while (bu_fgets(line, ADRT_NAME_SIZE, fh)) {
	token = strtok(line, ",");
	if (!strcmp("properties", token)) {

	    if (prop_num) {
		/* pack name */
		c = strlen(name) + 1;
		common_pack_write(app_data, app_ind, &c, sizeof(char));
		common_pack_write(app_data, app_ind, name, c);
		/* pack properties data */
		common_pack_write(app_data, app_ind, &def_prop, sizeof(common_prop_t));
	    }

	    token = strtok(NULL, ",");
	    /* strip off newline */
	    if (token[strlen(token)-1] == '\n') token[strlen(token)-1] = 0;
	    strncpy(name, token, sizeof(name));

	    /* set defaults */
	    def_prop.color.v[0] = 0.8;
	    def_prop.color.v[1] = 0.8;
	    def_prop.color.v[2] = 0.8;
	    def_prop.density = 0.5;
	    def_prop.gloss = 0.5;
	    def_prop.emission = 0.0;
	    def_prop.ior = 1.0;

	    prop_num++;

	} else if (!strcmp("color", token)) {

	    token = strtok(NULL, ",");
	    def_prop.color.v[0] = atof(token);
	    token = strtok(NULL, ",");
	    def_prop.color.v[1] = atof(token);
	    token = strtok(NULL, ",");
	    def_prop.color.v[2] = atof(token);

	} else if (!strcmp("density", token)) {

	    token = strtok(NULL, ",");
	    def_prop.density = atof(token);

	} else if (!strcmp("gloss", token)) {

	    token = strtok(NULL, ",");
	    def_prop.gloss = atof(token);

	} else if (!strcmp("emission", token)) {

	    token = strtok(NULL, ",");
	    def_prop.emission = atof(token);

	} else if (!strcmp("ior", token)) {

	    token = strtok(NULL, ",");
	    def_prop.ior = atof(token);

	}
    }

    if (prop_num) {
	/* pack name */
	c = strlen(name) + 1;
	common_pack_write(app_data, app_ind, &c, sizeof(char));
	common_pack_write(app_data, app_ind, name, c);
	/* pack properties data */
	common_pack_write(app_data, app_ind, &def_prop, sizeof(common_prop_t));
    }


    size = *app_ind - marker - sizeof(unsigned int);
    common_pack_write(app_data, &marker, &size, sizeof(unsigned int));
    *app_ind = marker + size;
}
示例#20
0
文件: trie.c 项目: cogitokat/brlcad
int
read_Trie(FILE *fp)
{
    static char	name_buf[MAX_TRIE_LEVEL+1];
    Trie	*triep;
    F_Hdr_Ptlist	hdr_ptlist;
    int		min, max;
    /* Read temperature range information.				*/
    if (	fread( (char *) &min, (int) sizeof(int), 1, fp ) != 1
		||	fread( (char *) &max, (int) sizeof(int), 1, fp ) != 1
	)
    {
	bu_log( "Could not read min/max info.\n" );
	rewind( fp );
    }
    else
    {
	bu_log( "IR data base temperature range is %d to %d\n",
		min, max
	    );
	if ( ir_min == ABSOLUTE_ZERO )
	{
	    /* Temperature range not set.			*/
	    ir_min = min;
	    ir_max = max;
	}
	else
	{
	    /* Merge with existing range.			*/
	    V_MIN( ir_min, min );
	    V_MAX( ir_max, max );
	    bu_log(	"Global temperature range is %d to %d\n",
			ir_min, ir_max
		);
	    (void) fflush( stdout );
	}
    }
    if ( ! init_Temp_To_RGB() )
    {
	return	0;
    }
    while ( bu_fgets( name_buf, MAX_TRIE_LEVEL, fp ) != NULL )
    {
	name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line.*/
	triep = add_Trie( name_buf, &reg_triep );
	if ( fread( (char *) &hdr_ptlist, (int) sizeof(F_Hdr_Ptlist), 1, fp )
	     != 1
	    )
	{
	    bu_log( "\"%s\"(%d) Read failed!\n", __FILE__, __LINE__ );
	    return	0;
	}
	for (; hdr_ptlist.f_length > 0; hdr_ptlist.f_length-- )
	{
	    fastf_t		point[3];
	    float		c_point[3];
	    Octree		*octreep;
	    if ( fread( (char *) c_point, (int) sizeof(c_point), 1, fp ) != 1 )
	    {
		bu_log(	"\"%s\"(%d) Read failed.\n",
			__FILE__, __LINE__ );
		return	0;
	    }
	    VMOVE( point, c_point );
	    if ( (octreep = add_Region_Octree(	&ir_octree,
						point,
						triep,
						hdr_ptlist.f_temp,
						0
		      )
		     ) != OCTREE_NULL
		)
		append_Octp( triep, octreep );
	}
    }
    return	1;
}
示例#21
0
文件: enf-g.c 项目: kanzure/brlcad
struct obj_info *
Part_import( int id_start )
{
    char line[MAX_LINE_SIZE];
    struct obj_info *part;
    struct wmember reg_head;
    unsigned char rgb[3];
    int surf_count=0;
    int id_end;
    int last_surf=0;
    int i;
    int tri[3];
    int corner_index=-1;

    clean_vert_tree( tree_root );

    VSETALL( rgb, 128 );

    BU_ALLOC(part, struct obj_info);
    part->obj_type = PART_TYPE;
    part->obj_id = id_start;
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "PartName", 8 ) ) {
	    line[strlen( line ) - 1] = '\0';
	    part->obj_name = bu_strdup( &line[9] );
	    lower_case( part->obj_name );
	    Make_brlcad_names( part );
	} else if ( !bu_strncmp( line, "FaceCount", 9 ) ) {
	    surf_count = atoi( &line[10] );
	    if ( surf_count == 0 ) {
		last_surf = 1;
	    }
	} else if ( !bu_strncmp( line, "EndPartId", 9 ) ) {
	    /* found end of part, check id */
	    id_end = atoi( &line[10] );
	    if ( id_end != id_start )
		bu_exit( 1, "%s: ERROR: found end of part id %d while processing part %d\n", progname,id_end, id_start );
	    if ( last_surf ) {
		break;
	    }
	} else if ( !bu_strncmp( line, "FaceRGB", 7 ) ) {
	    /* get face color */
	    char *ptr;

	    i = 8;
	    ptr = strtok( &line[i], " \t" );
	    for ( i=0; i<3 && ptr; i++ ) {
		rgb[i] = atof( ptr );
		ptr = strtok( (char *)NULL, " \t" );
	    }
	} else if ( !bu_strncmp( line, "Facet", 5 ) ) {
	    /* read a triangle */
	    VSETALL( tri, -1 );
	    corner_index = -1;
	} else if ( !bu_strncmp( line, "Face", 4 ) ) {
	    /* start of a surface */
	    int surf_no;

	    surf_no = atoi( &line[5] );
	    if ( surf_no == surf_count ) {
		last_surf = 1;
	    }
	} else if ( !bu_strncmp( line, "TriangleCount", 13 ) ) {
	    /* get number of triangles for this surface */
	} else if ( !bu_strncmp( line, "Vertices", 9 ) ) {
	    /* get vertex list for this triangle */
	} else if ( !bu_strncmp( line, "Vertex", 6 ) ) {
	    /* get a vertex */
	    char *ptr = NULL;
	    vect_t v = VINIT_ZERO;

	    i = 7;
	    while ( !isspace( (int)line[i] ) && line[i] != '\0' )
		i++;
	    ptr = strtok( &line[i], " \t" );
	    for ( i=0; i<3 && ptr; i++ ) {
		v[i] = atof( ptr );
		ptr = strtok( (char *)NULL, " \t" );
	    }
	    tri[++corner_index] = Add_vert( V3ARGS( v ), tree_root, local_tol_sq );
	    if ( corner_index == 2 ) {
		if ( !bad_triangle( tri, tree_root->the_array ) ) {
		    add_triangle( tri );
		}
	    }
	} else if ( !bu_strncmp( line, "Normal", 6 ) ) {
	    /* get a vertex normal */
	} else if ( !bu_strncmp( line, "PointCount", 10 ) ) {
	    /* get number of vertices for this surface */
	} else
	    bu_exit( 1, "%s: ERROR: unrecognized line encountered while processing part id %d:\n%s\n", progname,id_start, line );
    }

    if ( curr_tri == 0 ) {
	/* no facets in this part, so ignore it */
	bu_free( (char *)part, "part" );
	part = (struct obj_info *)NULL;
    } else {

	/* write this part to database, first make a primitive solid */
	if ( mk_bot( fd_out, part->brlcad_solid, RT_BOT_SOLID, RT_BOT_UNORIENTED, 0,
		     tree_root->curr_vert, curr_tri, tree_root->the_array, part_tris, NULL, NULL ) )
	    bu_exit( 1, "%s: Failed to write primitive %s (%s) to database\n", progname,part->brlcad_solid, part->obj_name );
	if ( verbose ) {
	    DO_INDENT;
	    bu_log( "Wrote BOT %s\n", part->brlcad_solid );
	}

	/* then a region */
	BU_LIST_INIT( &reg_head.l );
	if ( mk_addmember( part->brlcad_solid, &reg_head.l, NULL, WMOP_UNION ) == WMEMBER_NULL )
	    bu_exit( 1, "%s: ERROR: Failed to add solid (%s), to region (%s)\n", progname,part->brlcad_solid, part->brlcad_comb );
	if ( mk_comb( fd_out, part->brlcad_comb, &reg_head.l, 1, NULL, NULL, rgb, ident++,
		      0, 1, 100, 0, 0, 0 ) )
	    bu_exit( 1, "%s: Failed to write region %s (%s) to database\n", progname,part->brlcad_comb, part->obj_name );
	if ( verbose ) {
	    DO_INDENT;
	    bu_log( "Wrote region %s\n", part->brlcad_comb );
	}

	if ( use_part_name_hash ) {
	    if ( db5_update_attribute( part->brlcad_comb, "Part_No",
				       part->obj_name, fd_out->dbip ) ) {
		bu_log( "Failed to assign Part_no attribute to %s\n",
			part->brlcad_comb );
	    }
	}
    }

    /* free some memory */
    if ( part_tris ) {
	bu_free( (char *)part_tris, "part_tris" );
    }
    max_tri = 0;
    curr_tri = 0;
    part_tris = NULL;

    return part;
}
示例#22
0
文件: clone.c 项目: cogitokat/brlcad
/**
 * master hook function for the 'tracker' command used to create
 * copies of objects along a spline path.
 */
int
f_tracker(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, const char *argv[])
{
    size_t ret;
    struct spline s;
    vect_t *verts  = (vect_t *)NULL;
    struct link *links = (struct link *)NULL;
    int opt;
    size_t i, j, k, inc;
    size_t n_verts, n_links;
    int arg = 1;
    FILE *points = (FILE *)NULL;
    char tok[81] = {0}, line[81] = {0};
    char ch;
    fastf_t totlen = 0.0;
    fastf_t len, olen;
    fastf_t dist_to_next;
    fastf_t min, max, mid;
    fastf_t pt[3] = {0};
    int no_draw = 0;

    /* allow interrupts */
    if (setjmp(jmp_env) == 0)
	(void)signal(SIGINT, sig3);
    else
	return TCL_OK;

    bu_optind = 1;

    while ((opt = bu_getopt(argc, (char * const *)argv, "fh")) != EOF) {
	switch (opt) {
	    case 'f':
		no_draw = 1;
		arg++;
		break;
	    case 'h':
		Tcl_AppendResult(interp, "tracker [-fh] [# links] [increment] [spline.iges] [link...]\n\n", (char *)NULL);
		Tcl_AppendResult(interp, "-f:\tDo not draw the links as they are made.\n", (char *)NULL);
		Tcl_AppendResult(interp, "-h:\tPrint this message.\n\n", (char *)NULL);
		Tcl_AppendResult(interp, "\tThe prototype link(s) should be placed so that one\n", (char *)NULL);
		Tcl_AppendResult(interp, "\tpin's vertex lies on the origin and points along the\n", (char *)NULL);
		Tcl_AppendResult(interp, "\ty-axis, and the link should lie along the positive x-axis.\n\n", (char *)NULL);
		Tcl_AppendResult(interp, "\tIf two or more sublinks comprise the link, they are specified in this manner:\n", (char *)NULL);
		Tcl_AppendResult(interp, "\t<link1> <%% of total link> <link2> <%% of total link> ....\n", (char *)NULL);
		return TCL_OK;
	}
    }

    if (argc < arg+1) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter number of links: ", (char *)NULL);
	return TCL_ERROR;
    }
    n_verts = atoi(argv[arg++])+1;

    if (argc < arg+1) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter amount to increment parts by: ", (char *)NULL);
	return TCL_ERROR;
    }
    inc = atoi(argv[arg++]);

    if (argc < arg+1) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter spline file name: ", (char *)NULL);
	return TCL_ERROR;
    }
    if ((points = fopen(argv[arg++], "r")) == NULL) {
	fprintf(stdout, "tracker:  couldn't open points file %s.\n", argv[arg-1]);
	return TCL_ERROR;
    }

    if (argc < arg+1) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter prototype link name: ", (char *)NULL);
	fclose(points);
	return TCL_ERROR;
    }


    /* Prepare vert list *****************************/
    n_links = ((argc-3)/2)>1?((argc-3)/2):1;
    verts = (vect_t *)malloc(sizeof(vect_t) * n_verts * (n_links+2));

    /* Read in links names and link lengths **********/
    links = (struct link *)malloc(sizeof(struct link)*n_links);
    for (i = arg; i < (size_t)argc; i+=2) {
	double scan;

	bu_vls_strcpy(&links[(i-arg)/2].name, argv[i]);
	if (argc > arg+1) {
	    sscanf(argv[i+1], "%lf", &scan);
	    /* double to fastf_t */
	    links[(i-arg)/2].pct = scan;
	} else {
	    links[(i-arg)/2].pct = 1.0;
	}
	totlen += links[(i-arg)/2].pct;
    }
    if (!ZERO(totlen - 1.0))
	fprintf(stdout, "ERROR\n");

    /* Read in knots from specified file *************/
    do
	bu_fgets(line, 81, points);
    while (!BU_STR_EQUAL(strtok(line, ","), "112"));

    bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok));
    bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok));
    bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok));
    bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok));
    s.n_segs = atoi(tok);
    s.t = (fastf_t *)bu_malloc(sizeof(fastf_t) * (s.n_segs+1), "t");
    s.k = (struct knot *)bu_malloc(sizeof(struct knot) * (s.n_segs+1), "k");
    for (i = 0; i <= s.n_segs; i++) {
	bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok));
	if (strstr(tok, "P") != NULL) {
	    bu_fgets(line, 81, points);
	    bu_fgets(line, 81, points);
	    bu_strlcpy(tok, strtok(line, ","), sizeof(tok));
	}
	s.t[i] = atof(tok);
    }
    for (i = 0; i <= s.n_segs; i++)
	for (j = 0; j < 3; j++) {
	    for (k = 0; k < 4; k++) {
		bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok));
		if (strstr(tok, "P") != NULL) {
		    bu_fgets(line, 81, points);
		    bu_fgets(line, 81, points);
		    bu_strlcpy(tok, strtok(line, ","), sizeof(tok));
		}
		s.k[i].c[j][k] = atof(tok);
	    }
	    s.k[i].pt[j] = s.k[i].c[j][0];
	}
    fclose(points);

    /* Interpolate link vertices *********************/
    for (i = 0; i < s.n_segs; i++) /* determine initial track length */
	totlen += DIST_PT_PT(s.k[i].pt, s.k[i+1].pt);
    len = totlen/(n_verts-1);
    VMOVE(verts[0], s.k[0].pt);
    olen = 2*len;

    for (i = 0; (fabs(olen-len) >= VUNITIZE_TOL) && (i < 250); i++) {
	/* number of track iterations */
	fprintf(stdout, ".");
	fflush(stdout);
	for (j = 0; j < n_links; j++) /* set length of each link based on current track length */
	    links[j].len = len * links[j].pct;
	min = 0;
	max = s.t[s.n_segs];
	mid = 0;

	for (j = 0; j < n_verts+1; j++) /* around the track once */
	    for (k = 0; k < n_links; k++) {
		/* for each sub-link */
		if ((k == 0) && (j == 0)) {continue;} /* the first sub-link of the first link is already in position */
		min = mid;
		max = s.t[s.n_segs];
		mid = (min+max)/2;
		interp_spl(mid, s, pt);
		dist_to_next = (k > 0) ? links[k-1].len : links[n_links-1].len; /* links[k].len;*/
		while (fabs(DIST_PT_PT(verts[n_links*j+k-1], pt) - dist_to_next) >= VUNITIZE_TOL) {
		    if (DIST_PT_PT(verts[n_links*j+k-1], pt) > dist_to_next) {
			max = mid;
			mid = (min+max)/2;
		    } else {
			min = mid;
			mid = (min+max)/2;
		    }
		    interp_spl(mid, s, pt);
		    if (fabs(min-max) <= VUNITIZE_TOL) {break;}
		}
		interp_spl(mid, s, verts[n_links*j+k]);
	    }

	interp_spl(s.t[s.n_segs], s, verts[n_verts*n_links-1]);
	totlen = 0.0;
	for (j = 0; j < n_verts*n_links-1; j++)
	    totlen += DIST_PT_PT(verts[j], verts[j+1]);
	olen = len;
	len = totlen/(n_verts-1);
    }
    fprintf(stdout, "\n");

    /* Write out interpolation info ******************/
    fprintf(stdout, "%ld Iterations; Final link lengths:\n", (unsigned long)i);
    for (i = 0; i < n_links; i++)
	fprintf(stdout, "  %s\t%.15f\n", bu_vls_addr(&links[i].name), links[i].len);
    fflush(stdin);
    /* Place links on vertices ***********************/
    fprintf(stdout, "Continue? [y/n]  ");
    ret = fscanf(stdin, "%c", &ch);
    if (ret != 1)
	perror("fscanf");

    if (ch == 'y') {
	struct clone_state state;
	struct directory **dps = (struct directory **)NULL;
	char *vargs[3];

	for (i = 0; i < 2; i++)
	    vargs[i] = (char *)bu_calloc(CLONE_BUFSIZE, sizeof(char), "alloc vargs[i]");
	vargs[0][0] = 'e';

	state.interp = interp;
	state.incr = inc;
	state.n_copies = 1;
	state.draw_obj = 0;
	state.miraxis = W;

	dps = (struct directory **)bu_calloc(n_links, sizeof(struct directory *), "alloc dps array");
	/* rots = (vect_t *)bu_malloc(sizeof(vect_t)*n_links, "alloc rots");*/
	for (i = 0; i < n_links; i++) {
	    /* global dbip */
	    dps[i] = db_lookup(dbip, bu_vls_addr(&links[i].name), LOOKUP_QUIET);
	    /* VSET(rots[i], 0, 0, 0);*/
	}

	for (i = 0; i < n_verts-1; i++) {
	    for (j = 0; j < n_links; j++) {
		if (i == 0) {
		    VSCALE(state.trans, verts[n_links*i+j], local2base);
		} else
		    VSUB2SCALE(state.trans, verts[n_links*(i-1)+j], verts[n_links*i+j], local2base);
		VSCALE(state.rpnt, verts[n_links*i+j], local2base);

		VSUB2(pt, verts[n_links*i+j], verts[n_links*i+j+1]);
		VSET(state.rot, 0, (M_PI - atan2(pt[Z], pt[X])),
		     -atan2(pt[Y], sqrt(pt[X]*pt[X]+pt[Z]*pt[Z])));
		VSCALE(state.rot, state.rot, RAD2DEG);
		/*
		  VSUB2(state.rot, state.rot, rots[j]);
		  VADD2(rots[j], state.rot, rots[j]);
		*/

		state.src = dps[j];
		/* global dbip */
		dps[j] = copy_object(dbip, &rt_uniresource, &state);
		bu_strlcpy(vargs[1], dps[j]->d_namep, CLONE_BUFSIZE);

		if (!no_draw || !is_dm_null()) {
		    drawtrees(2, (const char **)vargs, 1);
		    size_reset();
		    new_mats();
		    color_soltab();
		    refresh();
		}
		fprintf(stdout, ".");
		fflush(stdout);
	    }
	}
	fprintf(stdout, "\n");
	bu_free(dps, "free dps array");

	for (i = 0; i < 2; i++)
	    bu_free(vargs[i], "free vargs[i]");
    }

    free(s.t);
    free(s.k);
    free(links);
    free(verts);
    (void)signal(SIGINT, SIG_IGN);
    return TCL_OK;
}
示例#23
0
文件: enf-g.c 项目: kanzure/brlcad
int
main( int argc, char *argv[] )
{
    char line[MAX_LINE_SIZE];
    char *input_file, *output_file;
    FILE *fd_parts;
    struct obj_info **top_level_assems = NULL;
    int top_level_assem_count = 0;
    int curr_top_level = -1;
    fastf_t tmp;
    int id;
    int c;

    bu_setprogname(argv[0]);

    local_tol = 0.0005;
    local_tol_sq = local_tol * local_tol;
    ident = 1000;

    while ( (c=bu_getopt( argc, argv, "vi:t:n:l:h?" ) ) != -1 ) {
	switch ( c ) {
	    case 'v':	/* verbose */
		verbose = 1;
		break;
	    case 'i':	/* starting ident number */
		ident = atoi( bu_optarg );
		break;
	    case 't':	/* tolerance */
		tmp = atof( bu_optarg );
		if ( tmp <= 0.0 )
		    bu_exit( 1, "%s: Illegal tolerance (%g), must be > 0.0\n", progname,tmp );
		break;
	    case 'n':	/* part name list */
		part_name_file = bu_optarg;
		use_part_name_hash = 1;
		break;
	    case 'l':	/* max name length */
		max_name_len = atoi( bu_optarg );
		if ( max_name_len < 5 )
		    bu_exit( 1, "%s: Unreasonable name length limitation\n",progname );
		break;
	    default:
		Usage();
		bu_exit( 1, NULL );
	}
    }

    if ( argc - bu_optind != 2 ) {
	bu_log( "Not enough arguments!! (need at least input & output file names)\n" );
	Usage();
	bu_exit( 1, NULL );
    }

    input_file = bu_strdup( argv[bu_optind] );

    if ((fd_in=fopen(input_file, "rb")) == NULL) {
	bu_log( "%s: Cannot open %s for reading\n", progname,input_file );
	perror( argv[0] );
	bu_exit( 1, NULL );
    }

    output_file = bu_strdup( argv[bu_optind+1] );

    if ( (fd_out=wdb_fopen( output_file )) == NULL ) {
	bu_log( "%s: Cannot open %s for writing\n", progname,output_file );
	perror( argv[0] );
	bu_exit( 1, NULL );
    }

    if ( use_part_name_hash ) {
	if ( (fd_parts=fopen( part_name_file, "rb" )) == NULL ) {
	    bu_log( "%s,Cannot open part name file (%s)\n", progname,part_name_file );
	    perror( argv[0] );
	    bu_exit( 1, NULL );
	}

	create_name_hash( fd_parts );
    }

    tree_root = create_vert_tree();

    /* finally, start processing the input */
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "FileName", 8 ) ) {
	    bu_log( "Converting facets originally from %s",
		    &line[9] );
	} else if ( !bu_strncmp( line, "TopAssemblies", 13 ) ) {
	    bu_log( "Top level assemblies: %s", &line[14] );
	    top_level_assem_count = atoi( &line[14] );
	    if ( top_level_assem_count < 1 ) {
		top_level_assems = (struct obj_info **)NULL;
	    } else {
		top_level_assems = (struct obj_info **)bu_calloc( top_level_assem_count,
								  sizeof( struct obj_info * ),
								  "top_level_assems" );
	    }
	} else if ( !bu_strncmp( line, "PartCount", 9 ) ) {
	    bu_log( "Part count: %s", &line[10] );
	} else if ( !bu_strncmp( line, "AssemblyId", 10 ) ) {
	    id = atoi( &line[11] );
	    curr_top_level++;
	    if ( curr_top_level >= top_level_assem_count ) {
		bu_log( "Warning: too many top level assemblies\n" );
		bu_log( "\texpected %d, this os number %d\n",
			top_level_assem_count, curr_top_level+1 );
		top_level_assem_count = curr_top_level+1;
		top_level_assems = (struct obj_info **)bu_realloc( top_level_assems,
								   top_level_assem_count *
								   sizeof( struct obj_info * ),
								   "top_level_assems" );
	    }
	    top_level_assems[curr_top_level] = Assembly_import( id );
	} else if ( !bu_strncmp( line, "PartId", 6 ) ) {
	    /* found a top-level part */
	    id = atoi( &line[7] );
	    (void)Part_import( id );
	}
    }

    if ( name_not_converted ) {
	bu_log( "Warning %d objects were not found in the part number to name mapping,\n",
		name_not_converted );
	bu_log( "\ttheir names remain as part numbers.\n" );
    }

    return 0;
}
示例#24
0
文件: color.c 项目: kanzure/brlcad
/*
 * used by the 'color' command when provided the -e option
 */
static int
edcolor(struct ged *gedp, int argc, const char *argv[])
{
    struct mater *mp;
    struct mater *zot;
    FILE *fp;
    int c;
    char line[128];
    static char hdr[] = "LOW\tHIGH\tRed\tGreen\tBlue\n";
    char tmpfil[MAXPATHLEN];
    char *editstring = NULL;

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    bu_optind = 1;
    /* First, grab the editstring off of the argv list */
    while ((c = bu_getopt(argc, (char * const *)argv, "E:")) != -1) {
	switch (c) {
	    case 'E' :
		editstring = bu_optarg;
		break;
	    default :
		break;
	}
    }

    argc -= bu_optind - 1;
    argv += bu_optind - 1;

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    fp = bu_temp_file(tmpfil, MAXPATHLEN);
    if (fp == NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: could not create tmp file", argv[0]);
	return GED_ERROR;
    }

    fprintf(fp, "%s", hdr);
    for (mp = rt_material_head(); mp != MATER_NULL; mp = mp->mt_forw) {
	fprintf(fp, "%d\t%d\t%3d\t%3d\t%3d",
		      mp->mt_low, mp->mt_high,
		      mp->mt_r, mp->mt_g, mp->mt_b);
	fprintf(fp, "\n");
    }
    (void)fclose(fp);

    if (!_ged_editit(editstring, (const char *)tmpfil)) {
	bu_vls_printf(gedp->ged_result_str, "%s: editor returned bad status. Aborted\n", argv[0]);
	return GED_ERROR;
    }

    /* Read file and process it */
    if ((fp = fopen(tmpfil, "r")) == NULL) {
	perror(tmpfil);
	return GED_ERROR;
    }

    if (bu_fgets(line, sizeof (line), fp) == NULL ||
	line[0] != hdr[0]) {
	bu_vls_printf(gedp->ged_result_str, "%s: Header line damaged, aborting\n", argv[0]);
	(void)fclose(fp);
	return GED_ERROR;
    }

    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	/* Zap all the current records, both in core and on disk */
	while (rt_material_head() != MATER_NULL) {
	    zot = rt_material_head();
	    rt_new_material_head(zot->mt_forw);
	    color_zaprec(gedp, zot);
	    bu_free((void *)zot, "mater rec");
	}

	while (bu_fgets(line, sizeof (line), fp) != NULL) {
	    int cnt;
	    int low, hi, r, g, b;

	    /* character-separated numbers (ideally a space) */
	    cnt = sscanf(line, "%d%*c%d%*c%d%*c%d%*c%d",
			 &low, &hi, &r, &g, &b);
	    if (cnt != 9) {
		bu_vls_printf(gedp->ged_result_str, "%s: Discarding %s\n", argv[0], line);
		continue;
	    }
	    BU_ALLOC(mp, struct mater);
	    mp->mt_low = low;
	    mp->mt_high = hi;
	    mp->mt_r = r;
	    mp->mt_g = g;
	    mp->mt_b = b;
	    mp->mt_daddr = MATER_NO_ADDR;
	    rt_insert_color(mp);
	    color_putrec(gedp, mp);
	}
    } else {
	struct bu_vls vls = BU_VLS_INIT_ZERO;

	/* free colors in rt_material_head */
	rt_color_free();

	while (bu_fgets(line, sizeof (line), fp) != NULL) {
	    int cnt;
	    int low, hi, r, g, b;

	    /* character-separated numbers (ideally a space) */
	    cnt = sscanf(line, "%d%*c%d%*c%d%*c%d%*c%d",
			 &low, &hi, &r, &g, &b);

	    /* check to see if line is reasonable */
	    if (cnt != 5) {
		bu_vls_printf(gedp->ged_result_str, "%s: Discarding %s\n", argv[0], line);
		continue;
	    }
	    bu_vls_printf(&vls, "{%d %d %d %d %d} ", low, hi, r, g, b);
	}

	db5_update_attribute("_GLOBAL", "regionid_colortable", bu_vls_addr(&vls), gedp->ged_wdbp->dbip);
	db5_import_color_table(bu_vls_addr(&vls));
	bu_vls_free(&vls);
    }

    (void)fclose(fp);
    bu_file_delete(tmpfil);

    /* if there are drawables, update their colors */
    if (gedp->ged_gdp)
	ged_color_soltab(gedp->ged_gdp->gd_headDisplay);

    return GED_OK;
}
static long
read_Cell_Data(void)
{
    static char linebuf[MAX_LINE];
    static char *lbp = NULL;
    static char format[MAX_LINE];
    int state = STATE_VIEW_TOP;
    int i;
    Cell *gp = grid;
    int view_ct = 1;

    /*
     * First time through...
     * 1) initialize line-buffer pointer and try to fill the line buffer
     * 2) build the format for sscanf()
     */
    if (lbp == NULL) {
	lbp = linebuf;
	bu_fgets(lbp, MAX_LINE, filep);
	bu_strlcpy(format, "%lf %lf", sizeof(format));
	if (color_flag)
	    bu_strlcat(format, " %d %d %d", sizeof(format));
	else {
	    /* Skip to field of interest */
	    for (i = 1; i < field; i++)
		bu_strlcat(format, " %*lf", sizeof(format));
	    bu_strlcat(format, " %lf", sizeof(format));
	}
    }
    /* EOF encountered before we found the desired view? */
    if (feof(filep))
	return 0;

    /* Read the data */
    do {
	double x, y;
	int r, g, b;
	cell_val value;

	if (lbp[strlen(lbp) - 1] != '\n')
	    bu_exit (1, "Overlong line\n");

	/* Have we run out of room for the cells?  If so reallocate memory */
	if (gp - grid >= maxcells) {
	    long ncells = gp - grid;

	    maxcells *= 2;
	    grid = (Cell *) bu_realloc((char *) grid,
				       sizeof(Cell) * maxcells, "grid");
	    if (debug_flag & CFB_DBG_MEM)
		bu_log("cell-fb: maxcells increased to %ld\n", maxcells);
	    gp = grid + ncells;
	}
	/* Process any non-data (i.e. view-header) lines */
	while ((state != STATE_BEYOND_DATA) &&
	       ((color_flag &&
		 (sscanf(lbp, format, &x, &y, &r, &g, &b) != 5))
		|| (! color_flag &&
		    (sscanf(lbp, format, &x, &y, &value.v_scalar) != 3))))
	{
	    if (state == STATE_VIEW_TOP)
		state = STATE_IN_HEADER;
	    else if (state == STATE_IN_DATA)
		state = STATE_BEYOND_DATA;
	    if (feof(filep) || bu_fgets(lbp, MAX_LINE, filep) == NULL)
		return gp - grid;
	}
	/*
	 * At this point we know we have a line of cell data,
	 * though it might be the first line of the next view.
	 */
	if (state == STATE_BEYOND_DATA) {
	    state = STATE_VIEW_TOP;
	    if ((view_flag == 0) || (view_flag == view_ct++))
		return gp - grid;
	    else	/* Not the selected view, read the next one. */
		continue;
	} else
	    state = STATE_IN_DATA;

	/* If user has selected a view, only store values for that view. */
	if ((view_flag == 0) || (view_flag == view_ct)) {
	    MinMax(xmin, xmax, x);
	    MinMax(ymin, ymax, y);
	    if (debug_flag & CFB_DBG_MINMAX)
		bu_log("x=%g, y=%g, xmin=%g, xmax=%g, ymin=%g, ymax=%g\n",
		       x, y, xmin, xmax, ymin, ymax);
	    gp->c_x = x;
	    gp->c_y = y;
	    if (color_flag) {
		gp->c_val.v_color[RED] = r;
		gp->c_val.v_color[GRN] = g;
		gp->c_val.v_color[BLU] = b;
	    } else
		gp->c_val.v_scalar = value.v_scalar;
	    gp++;
	}
    } while (bu_fgets(lbp, MAX_LINE, filep) != NULL);
    return gp - grid;
}
int
main(int argc, char **argv)
{
    /* static to prevent longjmp clobber warning */
    static FILE *stream = NULL;
    static unsigned long line_num = 0;
    static unsigned long failed_cnt = 0;
    static unsigned long bomb_cnt = 0;
    static unsigned long success_cnt = 0;
    static int ret = 0;

    char buf[BUFSIZ];
    FILE *fp_in = NULL;
    char *endp = NULL;
    size_t string_length;
    int argv_idx;
    int c;
    char dt_fmt[50];  /* data type format string */
    char *buf_p1;
    char *buf_p;
    struct bn_tol tol;

    /* command line parameters */
    static unsigned long test_case_line_num = 0; /* static due to longjmp */
    static unsigned long function_num = 0; /* static due to longjmp */
    struct bu_vls input_file_name = BU_VLS_INIT_ZERO;
    struct bu_vls output_file_name = BU_VLS_INIT_ZERO;

    /* function parameter arrays */
    int i[50] = {0};
    long l[50] = {0};
    fastf_t d[50] = {0.0};
    unsigned long u[50] = {0};

    /* boolean variables */
    static int output_file_name_defined = 0; /* static due to longjmp */
    static int process_single_test_case = 0; /* static due to longjmp */
    static int process_single_function = 0; /* static due to longjmp */
    int input_file_name_defined = 0;
    int valid_function_number = 0;
    int process_test_case = 0;
    int early_exit = 0;
    static int found_eof = 0; /* static due to longjmp */

    /* set initial values in tol structure */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = BN_TOL_DIST;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1.0 - tol.perp;


    if (argc < 2) {
	bu_log("Too few parameters, %d specified, at least 1 required\n", argc - 1);
	bu_exit(EXIT_FAILURE, USAGE);
    }

    while ((c = bu_getopt(argc, argv, "l:f:i:o:")) != -1) {
	switch (c) {
	    case 'l': /* test case line number */
		errno = 0;
		test_case_line_num = strtoul(bu_optarg, &endp, 10);
		if (errno) {
		    bu_log("Invalid test case line number '%s' '%s'\n", bu_optarg, strerror(errno));
		    bu_exit(EXIT_FAILURE, USAGE);
		}
		if ((*endp != '\0') || (bu_optarg == endp) || (strchr(bu_optarg, '-') != '\0')) {
		    bu_log("Invalid test case line number '%s'\n", bu_optarg);
		    bu_exit(EXIT_FAILURE, USAGE);
		}
		process_single_test_case = 1;
		break;
	    case 'f': /* function number */
		errno = 0;
		function_num = strtoul(bu_optarg, &endp, 10);
		if (errno) {
		    bu_log("Invalid function number '%s' '%s'\n", bu_optarg, strerror(errno));
		    bu_exit(EXIT_FAILURE, USAGE);
		}
		if ((*endp != '\0') || (bu_optarg == endp) || (strchr(bu_optarg, '-') != '\0')) {
		    bu_log("Invalid function number '%s'\n", bu_optarg);
		    bu_exit(EXIT_FAILURE, USAGE);
		}
		process_single_function = 1;
		break;
	    case 'i': /* input file name */
		string_length = strlen(bu_optarg);
		if (string_length >= BUFSIZ) {
		    bu_log("Input file name too long, length was %d but must be less than %d\n",
			   string_length, BUFSIZ);
		    bu_exit(EXIT_FAILURE, USAGE);
		}
		bu_vls_strcpy(&input_file_name, bu_optarg);
		input_file_name_defined = 1;
		break;
	    case 'o': /* output file name */
		string_length = strlen(bu_optarg);
		if (string_length >= BUFSIZ) {
		    bu_log("Output file name too long, length was %d but must be less than %d\n",
			   string_length, BUFSIZ);
		    bu_exit(EXIT_FAILURE, USAGE);
		}
		bu_vls_strcpy(&output_file_name, bu_optarg);
		output_file_name_defined = 1;
		break;
	    default:
		bu_log("Invalid option '%c'.\n", c);
		bu_exit(EXIT_FAILURE, USAGE);
		break;
	}
    }

    if (process_single_test_case && process_single_function) {
	bu_log("Can not specify both test case line number and function number.\n");
	early_exit = 1;
    }

    if (!input_file_name_defined) {
	bu_log("Input file name is required but was not specified.\n");
	early_exit = 1;
    }

    if (early_exit) {
	bu_vls_free(&input_file_name);
	bu_vls_free(&output_file_name);
	bu_exit(EXIT_FAILURE, USAGE);
    }

    if ((fp_in = fopen(bu_vls_addr(&input_file_name), "r")) == NULL) {
	bu_log("Cannot open input file (%s)\n", bu_vls_addr(&input_file_name));
	bu_vls_free(&input_file_name);
	bu_vls_free(&output_file_name);
	return EXIT_FAILURE;
    }


    if (output_file_name_defined) {
	if ((stream = fopen(bu_vls_addr(&output_file_name), "w")) == NULL) {
	    bu_log("Cannot create output file (%s)\n", bu_vls_addr(&output_file_name));
	    if (fclose(fp_in) != 0) {
		bu_log("Unable to close input file.\n");
	    }
	    bu_vls_free(&input_file_name);
	    bu_vls_free(&output_file_name);
	    return EXIT_FAILURE;
	}
    } else {
	stream = stderr;
    }

    /* all output after this point is sent to stream */

    fprintf(stream, "Command line parameters: bntester ");
    for (argv_idx = 1 ; argv_idx < argc ; argv_idx++) {
	fprintf(stream, "%s ", argv[argv_idx]);
    }
    fprintf(stream, "\n");

    if (process_single_test_case) {
	fprintf(stream, "Processing only test case on line number: %lu\n", test_case_line_num);
    }

    if (process_single_function) {
	fprintf(stream, "Processing all test cases for function number: %lu\n", function_num);
    }

    if (!process_single_test_case && !process_single_function) {
	fprintf(stream, "Processing all test cases.\n");
    }


    while (!found_eof) {
	if (line_num == ULONG_MAX) {
	    fprintf(stream, "ERROR: Input data file exceeded max %lu number of lines.\n", ULONG_MAX);
	    if (fclose(fp_in) != 0) {
		fprintf(stream, "Unable to close input file.\n");
	    }
	    if (output_file_name_defined) {
		if (fclose(stream) != 0) {
		    bu_log("Unable to close output file.\n");
		}
	    }
	    bu_vls_free(&input_file_name);
	    bu_vls_free(&output_file_name);
	    return EXIT_FAILURE;
	}
	line_num++;
	if (bu_fgets(buf, BUFSIZ, fp_in) == NULL) {
	    if (feof(fp_in)) {
		found_eof = 1;
		continue;
	    }
	    if (ferror(fp_in)) {
		perror("ERROR: Problem reading file, system error message");
		if (fclose(fp_in) != 0) {
		    fprintf(stream, "Unable to close input file.\n");
		}
	    } else {
		perror("Oddness reading input file");
	    }
	    bu_vls_free(&input_file_name);
	    bu_vls_free(&output_file_name);
	    return EXIT_FAILURE;
	} else {
	    /* Skip input data file lines which start with a '#' character
	     * or a new line character.
	     */
	    if ((buf[0] != '#') && (buf[0] != '\n')) {
		buf_p1 = strtok(buf, "\n");
		buf_p = strtok(buf_p1, ", ");

		/* The 1st parameter of the test case is always an unsigned
		 * long int which represents the function number. This logic
		 * validates the test case function number to ensure it is
		 * an unsigned long int.
		 */
		valid_function_number = 1;
		errno = 0;
		u[0] = strtoul(buf_p, &endp, 10);
		if (errno) {
		    fprintf(stream, "Read function number failed, line %lu error msg: '%s' string '%s'\n",
				  line_num, strerror(errno), buf_p);
		    valid_function_number = 0;
		} else if ((*endp != '\0') || (buf_p == endp) || (strchr(buf_p, '-') != '\0')) {
		    fprintf(stream, "Read function number failed, line %lu string '%s'\n", line_num, buf_p);
		    valid_function_number = 0;
		}

		/* This logic restricts processing of the test case(s) to
		 * only those specified by the bntester input parameters.
		 */
		process_test_case = 0;
		if (valid_function_number && process_single_test_case && (test_case_line_num == line_num)) {
		    process_test_case = 1;
		} else if (valid_function_number && process_single_function && (function_num == u[0])) {
		    process_test_case = 1;
		} else if (valid_function_number && !process_single_test_case && !process_single_function) {
		    process_test_case = 1;
		}

		if (process_test_case) {
		    /* Each case within this switch corresponds to each
		     * function to be tested.
		     */
		    switch (u[0]) {
			case 1: /* function 'bn_distsq_line3_pt3' */
			    bu_strlcpy(dt_fmt, "dddddddddd", sizeof(dt_fmt)); /* defines parameter data types */
			    if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) {
				/* Parse failed, skipping test case */
				ret = 1;
			    } else {
				double result;
				if (!BU_SETJUMP) {
				    /* try */
				    result = bn_distsq_line3_pt3(&d[0], &d[3], &d[6]);
				    if (!NEAR_EQUAL(result, d[9], VUNITIZE_TOL)) {
					ret = 1;
					failed_cnt++;
					fprintf(stream, "Failed function %lu test case on line %lu expected = %.15f result = %.15f\n",
						      u[0], line_num, d[9], result);
				    } else {
					success_cnt++;
				    }
				} else {
				    /* catch */
				    BU_UNSETJUMP;
				    ret = 1;
				    bomb_cnt++;
				    fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num);
				} BU_UNSETJUMP;
			    }
			    break;
			case 2: /* function 'bn_2line3_colinear' */
			    bu_strlcpy(dt_fmt, "ddddddddddddduddddi", sizeof(dt_fmt));
			    if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) {
				/* Parse failed, skipping test case */
				ret = 1;
			    } else {
				int result;
				if (!BU_SETJUMP) {
				    /* try */
				    tol.magic = u[1];
				    tol.dist = d[13];
				    tol.dist_sq = d[14];
				    tol.perp = d[15];
				    tol.para = d[16];
				    result = bn_2line3_colinear(&d[0], &d[3], &d[6], &d[9], d[12], &tol);
				    if (result != i[0]) {
					ret = 1;
					failed_cnt++;
					fprintf(stream, "Failed function %lu test case on line %lu expected = %d result = %d\n",
						      u[0], line_num, i[0], result);
				    } else {
					success_cnt++;
				    }
				} else {
				    /* catch */
				    BU_UNSETJUMP;
				    ret = 1;
				    bomb_cnt++;
				    fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num);
				} BU_UNSETJUMP;
			    }
			    break;
			case 3: /* function 'bn_isect_line3_line3' */
			    bu_strlcpy(dt_fmt, "dddddddddddddduddddi", sizeof(dt_fmt));
			    if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) {
				/* Parse failed, skipping test case */
				ret = 1;
			    } else {
				int result;
				fastf_t t_out = 0.0;
				fastf_t u_out = 0.0;
				int t_fail = 0;
				int u_fail = 0;

				if (!BU_SETJUMP) {
				    /* try */
				    tol.magic = u[1];
				    tol.dist = d[14];
				    tol.dist_sq = d[15];
				    tol.perp = d[16];
				    tol.para = d[17];
				    result = bn_isect_line3_line3(&t_out, &u_out, &d[2], &d[5], &d[8], &d[11], &tol);
				    if (result != i[0]) {
					ret = 1;
					failed_cnt++;
					fprintf(stream, "Failed function %lu test case on line %lu expected = %d result = %d\n",
						      u[0], line_num, i[0], result);
				    } else if (result == 0) {
					if (!NEAR_EQUAL(t_out, d[0], tol.dist)) {
					    ret = 1;
					    failed_cnt++;
					    fprintf(stream, "Failed function %lu test case on line %lu result = %d expected t = %.15f result t = %.15f\n",
							  u[0], line_num, result, d[0], t_out);
					} else {
					    success_cnt++;
					}
				    } else if (result == 1) {
					t_fail = !NEAR_EQUAL(t_out, d[0], tol.dist);
					u_fail = !NEAR_EQUAL(u_out, d[1], tol.dist);
					if (t_fail) {
					    fprintf(stream, "Failed function %lu test case on line %lu result = %d expected t = %.15f result t = %.15f\n",
							  u[0], line_num, result, d[0], t_out);
					}
					if (u_fail) {
					    fprintf(stream, "Failed function %lu test case on line %lu result = %d expected u = %.15f result u = %.15f\n",
							  u[0], line_num, result, d[1], u_out);
					}
					if (t_fail || u_fail) {
					    ret = 1;
					    failed_cnt++;
					} else {
					    /* No other output to validate when result matches expected and
					     * result is not 0 and not 1.
					     */
					    success_cnt++;
					}
				    } else {
					success_cnt++;
				    }
				} else {
				    /* catch */
				    BU_UNSETJUMP;
				    ret = 1;
				    bomb_cnt++;
				    fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num);
				} BU_UNSETJUMP;
			    }
			    break;
			case 4: /* function 'bn_isect_lseg3_lseg3' */
			    bu_strlcpy(dt_fmt, "dddddddddddddduddddi", sizeof(dt_fmt));
			    if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) {
				/* Parse failed, skipping test case */
				ret = 1;
			    } else {
				int result;
				fastf_t dist[2] = {0.0, 0.0};
				int d0_fail = 0;
				int d1_fail = 0;

				if (!BU_SETJUMP) {
				    /* try */
				    tol.magic = u[1];
				    tol.dist = d[14];
				    tol.dist_sq = d[15];
				    tol.perp = d[16];
				    tol.para = d[17];
				    result = bn_isect_lseg3_lseg3(&dist[0], &d[2], &d[5], &d[8], &d[11], &tol);
				    if (result != i[0]) {
					ret = 1;
					failed_cnt++;
					fprintf(stream, "Failed function %lu test case on line %lu expected = %d result = %d\n",
						      u[0], line_num, i[0], result);
				    } else if (result == 0 || result == 1) {
					d0_fail = !NEAR_EQUAL(dist[0], d[0], VUNITIZE_TOL);
					d1_fail = !NEAR_EQUAL(dist[1], d[1], VUNITIZE_TOL);
					if (d0_fail) {
					    fprintf(stream, "Failed function %lu test case on line %lu result = %d expected dist[0] = %.15f result dist[0] = %.15f\n",
							  u[0], line_num, result, d[0], dist[0]);
					}
					if (d1_fail) {
					    fprintf(stream, "Failed function %lu test case on line %lu result = %d expected dist[1] = %.15f result dist[1] = %.15f\n",
							  u[0], line_num, result, d[1], dist[1]);
					}
					if (d0_fail || d1_fail) {
					    ret = 1;
					    failed_cnt++;
					} else {
					    /* No other output to validate when result matches expected and
					     * result is not 0 and not 1.
					     */
					    success_cnt++;
					}
				    } else {
					success_cnt++;
				    }
				} else {
				    /* catch */
				    BU_UNSETJUMP;
				    ret = 1;
				    bomb_cnt++;
				    fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num);
				} BU_UNSETJUMP;
			    }
			    break;
			default:
			    fprintf(stream, "ERROR: Unknown function number %lu test case on line %lu, skipping test case.\n", u[0], line_num);
			    bu_vls_free(&input_file_name);
			    bu_vls_free(&output_file_name);
			    return EXIT_FAILURE;
			    break;
		    } /* End of function number switch */
		}
	    } /* End of if statement skipping lines starting with '#' or new line */
	}
    } /* End of while loop reading lines from data file */

    fprintf(stream, "Summary: %lu total test cases success.\n", success_cnt);
    fprintf(stream, "Summary: %lu total test cases failed.\n", failed_cnt);
    fprintf(stream, "Summary: %lu total test cases bomb.\n", bomb_cnt);

    if (output_file_name_defined) {
	bu_log("Summary: %lu total test cases success.\n", success_cnt);
	bu_log("Summary: %lu total test cases failed.\n", failed_cnt);
	bu_log("Summary: %lu total test cases bomb.\n", bomb_cnt);
    }

    fprintf(stream, "Done.\n");

    if (output_file_name_defined) {
	bu_log("Done.\n");
    }

    if (fclose(fp_in) != 0) {
	fprintf(stream, "Unable to close input file.\n");
    }

    if (output_file_name_defined) {
	if (fclose(stream) != 0) {
	    bu_log("Unable to close output file.\n");
	}
    }

    bu_vls_free(&input_file_name);
    bu_vls_free(&output_file_name);

    return ret;
}
示例#27
0
文件: proe-g.c 项目: cciechad/brlcad
static void
Convert_assy(char *line)
{
    struct wmember head;
    struct wmember *wmem = NULL;
    char line1[MAX_LINE_SIZE];
    char name[MAX_LINE_SIZE];
    unsigned int obj;
    char memb_name[MAX_LINE_SIZE];
    unsigned int memb_obj;
    char *brlcad_name = NULL;
    float mat_col[4];
    float junk;
    int start;
    int i;

    if ( RT_G_DEBUG & DEBUG_MEM_FULL )
    {
	bu_log( "Barrier check at start of Convert_assy:\n" );
	if ( bu_mem_barriercheck() )
	    bu_exit(EXIT_FAILURE,  "Barrier check failed!!!\n" );
    }

    BU_LIST_INIT( &head.l );

    start = (-1);
    /* skip leading blanks */
    while ( isspace( line[++start] ) && line[start] != '\0' );
    if ( strncmp( &line[start], "assembly", 8 ) && strncmp( &line[start], "ASSEMBLY", 8 ) )
    {
	bu_log( "PROE-G: Convert_assy called for non-assembly:\n%s\n", line );
	return;
    }

    /* skip blanks before name */
    start += 7;
    while ( isspace( line[++start] ) && line[start] != '\0' );

    /* get name */
    i = (-1);
    start--;
    while ( !isspace( line[++start] ) && line[start] != '\0' && line[start] != '\n' )
	name[++i] = line[start];
    name[++i] = '\0';

    /* get object pointer */
    sscanf( &line[start], "%x %f", &obj, &junk );

    bu_log( "Converting Assembly: %s\n", name );

    if ( debug )
	bu_log( "Convert_assy: %s x%x\n", name, obj );

    while ( bu_fgets( line1, MAX_LINE_SIZE, fd_in ) )
    {
	/* skip leading blanks */
	start = (-1);
	while ( isspace( line1[++start] ) && line[start] != '\0' );

	if ( !strncmp( &line1[start], "endassembly", 11 ) || !strncmp( &line1[start], "ENDASSEMBLY", 11 ) )
	{

	    brlcad_name = Get_unique_name( name, obj, ASSEMBLY_TYPE );
	    if ( debug )
	    {
		struct wmember *wp;

		bu_log( "\tmake assembly ( %s)\n", brlcad_name );
		for ( BU_LIST_FOR( wp, wmember, &head.l ) )
		    bu_log( "\t%c %s\n", wp->wm_op, wp->wm_name );
	    }
	    else
		bu_log( "\tUsing name: %s\n", brlcad_name );

	    mk_lcomb( fd_out, brlcad_name, &head, 0 ,
		      (char *)NULL, (char *)NULL, (unsigned char *)NULL, 0 );
	    break;
	}
示例#28
0
int
main(int argc, char **argv)
{
    int done;
    char units[16], fname[80];
    int optc;

    while ( (optc = bu_getopt( argc, argv, "tsmnc" )) != -1)
    {
	switch ( optc )	/* Set joint type and cable option */
	{
	    case 't':
		torus = 1;
		break;
	    case 's':
		sphere = 1;
		break;
	    case 'm':
		mitre = 1;
		break;
	    case 'n':
		nothing = 1;
		break;
	    case 'c':
		cable = 1;
		break;
	    case '?':
		fprintf( stderr, "Illegal option %c\n", optc );
		Usage();
		return 1;
		break;

	}
    }

    if ( (torus + sphere + mitre + nothing) > 1 ) /* Too many joint options */
    {
	Usage();
	fprintf( stderr, "Options t, s, m, n are mutually exclusive\n" );
	return 1;
    }
    else if ( (torus + sphere + mitre + nothing) == 0 ) {
	torus = 1;		/* default */
    }

    if ( (argc - bu_optind) != 2 ) {
	Usage();
	return 1;
    }

    bu_strlcpy( name, argv[bu_optind++], sizeof(name) ); /* Base name for objects */

    fdout = wdb_fopen( argv[bu_optind] );
    if ( fdout == NULL )
    {
	fprintf( stderr, "Cannot open %s\n", argv[bu_optind] );
	perror( "Pipe" );
	Usage();
	return 1;
    }

    MAT_IDN(identity);	/* Identity matrix for all objects */
    pi = atan2( 0.0, -1.0 );	/* PI */

    printf( "FLUID & PIPING V%d.%d 10 Mar 89\n\n", VERSION, RELEASE );
    printf( "append %s to your target description using 'concat' in mged\n", argv[bu_optind] );

    k = 0.0;
    while ( k == 0.0 )
    {
	printf( "UNITS? (ft, in, m, cm, default is millimeters) ");
	bu_fgets(units, sizeof(units), stdin);
	switch (units[0])
	{

	    case '\0':
		k = 1.0;
		break;

	    case 'f':
		k = 12*25.4;
		break;

	    case 'i':
		k=25.4;
		break;

	    case 'm':
		if ( units[1] == '\0') k=1000.0;
		else k=1.0;
		break;

	    case 'c':
		k=10.0;
		break;

	    default:
		k=0.0;
		printf( "\n\t%s is not a legal choice for units\n", units );
		printf( "\tTry again\n" );
		break;
	}
    }

    done = 0;
    while ( !done )
    {
	if ( !cable ) {
	    printf( "radius and wall thickness: ");
	    if (scanf("%lf %lf", &radius, &wall) == EOF )
		return 1;
	    if (radius > wall)
		done = 1;
	    else
	    {
		printf( " *** bad input!\n\n");
		printf( "\tradius must be larger than wall thickness\n" );
		printf( "\tTry again\n" );
	    }
	}
	else {
	    printf( "radius: ");
	    if ( scanf("%lf", &radius ) == EOF )
		return 1;
	    done=1;
	}
    }
    radius=k*radius;
    wall=k*wall;

    Readpoints();	/* Read data points */

    Names();	/* Construct names for all solids */

    Normals();	/* Calculate normals and other vectors */

    Adjust();       /* Adjust points to allow for elbows */

/*	Generate Title */

    bu_strlcpy(fname, name, sizeof(fname));

    if ( !cable )
	bu_strlcat(fname, " pipe and fluid", sizeof(fname));
    else
	bu_strlcat(fname, " cable", sizeof(fname));

/*	Create ident record	*/

    mk_id(fdout, fname);

    Pipes();	/* Construct the piping */

    Elbows();	/* Construct the elbow sections */

    Groups();	/* Make some groups */

    return 0;
}
int
bu_crashreport(const char *filename)
{
    if (UNLIKELY(!filename || strlen(filename) == 0)) {
	return 0;
    }

    /* vat time ist? */
    (void)time(&now);

    path = bu_argv0_full_path();

    /* do our own expansion to avoid heap allocation */
    snprintf(buffer, CR_BUFSIZE, "******************************************\n\n"
	     "%s\n"		/* version info */
	     "Command: %s\n"	/* program name */
	     "Process: %d\n"	/* pid */
	     "Path: %s\n"	/* which binary */
	     "Date: %s\n",	/* date/time */
	     brlcad_ident("Crash Report"),
	     bu_getprogname(),
	     bu_process_id(),
	     path ? path : "Unknown",
	     ctime(&now));

    fp = fopen(filename, "ab");
    if (UNLIKELY(!fp || ferror(fp))) {
	perror("unable to open crash report file");
	bu_log("ERROR: Unable to open crash report file [%s]\n", filename);
	return 0;
    }

    /* make the file stream unbuffered */
    if (setvbuf(fp, (char *)NULL, _IONBF, 0) != 0) {
	perror("unable to make stream unbuffered");
    }

    /* print the report header */
    if (fwrite(buffer, 1, strlen(buffer), fp) != strlen(buffer)) {
	/* cannot bomb */
	bu_log("ERROR: Unable to write to crash report file [%s]\n", filename);
	(void)fclose(fp);
	fp = NULL;
	return 0;
    }

    /* write out the backtrace */
    fprintf(fp, "Call stack backtrace (thread %d):\n", bu_parallel_id());
    fflush(fp);
    if (bu_backtrace(fp) == 0) {
	bu_log("WARNING: Unable to obtain a call stack backtrace\n");
    }

    /* write out operating system information */
    path = bu_which("uname");
    if (path) {
	snprintf(buffer, CR_BUFSIZE, "%s -a 2>&1", path);
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	popenfp = popen(buffer, "r");
	if (!popenfp) {
	    perror("unable to popen uname");
	    bu_log("WARNING: Unable to obtain uname information\n");
	}
#endif
	if (popenfp) {
	    fprintf(fp, "\nSystem characteristics:\n");
	    fflush(fp);
	    while (bu_fgets(buffer, CR_BUFSIZE, popenfp)) {
		size_t ret;
		size_t len;

		len = strlen(buffer);
		ret = fwrite(buffer, 1, len, fp);
		if (ret != len)
		    perror("fwrite failed");
	    }
	}
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	(void)pclose(popenfp);
#endif
	popenfp = NULL;
	path = NULL;
    }

    /* write out kernel and hardware information */
    path = bu_which("sysctl");
    if (path) {
	/* need 2>&1 to capture stderr junk from sysctl on Mac OS X for kern.exec */
	snprintf(buffer, CR_BUFSIZE, "%s -a 2>&1", path);
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	popenfp = popen(buffer, "r");
	if (popenfp == (FILE *)NULL) {
	    perror("unable to popen sysctl");
	    bu_log("WARNING: Unable to obtain sysctl information\n");
	}
#endif
	if (popenfp != (FILE *)NULL) {
	    fprintf(fp, "\nSystem information:\n");
	    fflush(fp);
	    while (bu_fgets(buffer, CR_BUFSIZE, popenfp)) {
		size_t ret;
		size_t len;

		len = strlen(buffer);
		if ((len == 0)
		    || ((len == 1) && (buffer[0] == '\n')))
		{
		    continue;
		}

		ret = fwrite(buffer, 1, len, fp);
		if (ret != len)
		    perror("fwrite failed");
	    }
	}
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	(void)pclose(popenfp);
#endif
	popenfp = NULL;
	path = NULL;
    }

    memset(buffer, 0, CR_BUFSIZE);
    fprintf(fp, "\n");
    fflush(fp);
    (void)fclose(fp);
    fp = NULL;

    /* success */
    return 1;
}
int
main (int argc, char **argv)
{
    /* Variables used for XWindow.  */
    Display *my_display;		/* Display unit.  */
    Window root_id;		/* Root window.  */
    Window my_window;		/* First window opened.  */
    Window wind_pic;		/* Window with picture.  */
    Window wind_exit;		/* Exit window.  */
    Window wind_scale;		/* Color scale window.  */
    GC my_gc;			/* Gc for my_window.  */
    XSizeHints window_hints;	/* Hints for 1st window.  */
    XEvent event_received;	/* Events.  */
    long input_event_mask;	/* Input event mask that are to
				 * be responded to.  */
    unsigned long black;		/* Black pixel value.  */
    unsigned long white;		/* White pixel value.  */
    int screen=0;		/* Used for getting colors.  */
    XColor colval[MAXCOL];	/* Color values.  */
    XRectangle rect[MAXARR];	/* Array for drawing rectangles.  */
    char **a=(char **)NULL;	/* Place holder for XSetStandard Properties.  */
    const char winttl[] = "SEE";	/* Window title.  */
    const char quit[] = "QUIT";		/* Exit label.  */
    Font font;			/* Structure for setting font.  */

    /* Other variables.  */
    FILE *fpr;			/* Used to read a file.  */
    FILE *fpw;			/* Used to write a file.  */
    char file[MAXFIL];		/* File to be read.  */
    char line[151];		/* Used to read one line of a file.  */
    size_t main_w, main_h;	/* Width & height of main window.  */
    size_t wide, high;	/* Width and height of picture window.  */
    double pixval[MAXPIX][MAXPIX];/* Pixel value (width, height).  */
    double min=0.0, max=0.0;	/* Minimum & maximum pixel values.  */
    int i, j, k, m;			/* Loop counters.  */
    double r;			/* Temporary variable.  */
    double dcol;			/* Color step.  */
    double pixbin[MAXCOL + 1];	/* Pixel bins.  */
    double dpix;			/* Delta between pixel bins.  */
    int color[MAXPIX][MAXPIX];	/* Indicates color.  */
    int icol;			/* Indicates color shading.  */
    double check;		/* Used for finding colors.  */
    char string[11];		/* Used to write a label.  */
    int flag=0;			/* Color flag.  */
    int lstarr;			/* Last color array.  */
    int flag_pix;		/* 0=>no pix file written, 1=>pix file written.  */
    char file_pix[MAXFIL];	/* Pix file name.  */
    unsigned char c;		/* Used to write pix file.  */
    int ret;
    int ch;

    struct colstr *array = NULL;	/* Array for color information.  */

    bu_opterr = 0;
    while ((ch = bu_getopt(argc, argv, "h?")) != -1)
    {	if (bu_optopt == '?') ch = 'h';
	switch (ch) {
	    case 'h':
		fprintf(stderr,"ir-X is interactive; sample session in 'man' page\n");
		bu_exit(1,NULL);
	    default:
		break;
	}
    }

    fprintf(stderr,"   Program continues running:\n");

    array = (struct colstr *)bu_calloc(MAXCOL + EXTRA, sizeof(struct colstr), "allocate colstr array");

    /* Get file name to be read.  */
    printf("Enter name of file to be read (%d char max).\n\t", MAXFIL);
    (void)fflush(stdout);
    ret = scanf("%25s", file);
    if (ret == 0)
	perror("scanf");

    /* Find what color shading to use.  */
    printf("Indicate type of color shading to use.\n");
    printf("\t0 - gray\n");
    printf("\t1 - red\n");
    printf("\t2 - black-blue-cyan-green-yellow-white\n");
    printf("\t3 - black-blue-magenta-red-yellow-white\n");
    (void)fflush(stdout);
    ret = scanf("%d", &icol);
    if (ret == 0)
	perror("scanf");
    if ((icol != 1) && (icol != 2) && (icol != 3)) icol = 0;

    /* Determine if a pix file is to be written.  */
    flag_pix = 0;
    printf("Do you wish to create a pix file (0-no, 1-yes)?\n\t");
    (void)fflush(stdout);
    ret = scanf("%d", &flag_pix);
    if (ret == 0)
	perror("scanf");
    if (flag_pix != 1)
	 flag_pix = 0;
    else {
	printf("Enter name of the pix file to be created ");
	printf("(%d char max).\n\t", MAXFIL);
	(void)fflush(stdout);
	ret = scanf("%25s", file_pix);
	if (ret == 0)
	    perror("scanf");
    }

    printf("Zeroing color info array ");
    (void)fflush(stdout);

    /* Zero color info array.  */
    for (i=0; i<(MAXCOL + EXTRA); i++) {
	array[i].cnt = 0;
	array[i].more = 0;
    }
    lstarr = MAXCOL;

    printf("- finished zeroing\n");
    (void)fflush(stdout);

    printf("Setting up color scale ");
    (void)fflush(stdout);

    /* Set up color scale.  */
    dcol = (65535.0 + 1.0) / MAXCOL;
    if (icol == 0) {
	/* Shades of gray.  */
	printf("-shades of gray ");
	(void)fflush(stdout);
	for (i=0; i<MAXCOL; i++) {
	    colval[i].red = (unsigned short)((double)i * dcol);
	    colval[i].green = (unsigned short)((double)i * dcol);
	    colval[i].blue = (unsigned short)((double)i * dcol);
	}
    }

    else if (icol == 1) {
	/* Shades of red.  */
	printf("- shades of red ");
	(void)fflush(stdout);
	for (i=0; i<MAXCOL; i++) {
	    colval[i].red = (unsigned short)((double)i * dcol);
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)0;
	}
    }

    else if (icol == 2) {
	/* Black-blue-cyan-green-yellow-white.  */
	printf("- black-blue-cyan-green-yellow-white ");
	(void)fflush(stdout);
	if (MAXCOL > 1280.0) {
	    printf("Maximum number of colors, %d, is ", MAXCOL);
	    printf("greater than 1280.\n");
	    printf("This may create problems.\n");
	}
	/* Color step.  */
	dcol = 1280. / MAXCOL;
	i = 0;
	/* Colors (0, 0, 0) to (0, 0, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
	/* Colors (0, 0, 255) to (0, 255, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)(check * 256.0);
	    colval[i].blue = (unsigned short)(255 * 256);
	    check += dcol;
	    i++;
	}
	/* Colors (0, 255, 255) to (0, 255, 0).  */
	check = 255.0;
	while ((check >= 0.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check -= dcol;
	    i++;
	}
	/* Colors (0, 255, 0) to (255, 255, 0).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(check * 256.0);
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)0;
	    check += dcol;
	    i++;
	}
	/* Colors (255, 255, 0) to (255, 255, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
    }

    else if (icol == 3) {
	/* Black-blue-magenta-red-yellow-white.  */
	printf("- black-blue-magenta-red-yellow-white ");
	(void)fflush(stdout);
	if (MAXCOL > 1280.0) {
	    printf("Maximum number of colors, %d, is ", MAXCOL);
	    printf("greater than 1280.\n");
	    printf("This may create problems.\n");
	}
	/* Color step.  */
	dcol = 1280. / MAXCOL;
	i = 0;
	/* Colors (0, 0, 0) to (0, 0, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
	/* Colors (0, 0, 255) to (255, 0, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(check * 256.0);
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(255 * 256);
	    check += dcol;
	    i++;
	}
	/* Colors (255, 0, 255) to (255, 0, 0).  */
	check = 255.0;
	while ((check >= 0.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check -= dcol;
	    i++;
	}
	/* Colors (255, 0, 0) to (255, 255, 0).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)(check * 256.0);
	    colval[i].blue = (unsigned short)0;
	    check += dcol;
	    i++;
	}
	/* Colors (255, 255, 0) to (255, 255, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
    }

    printf("- finished.\n");
    (void)fflush(stdout);

    printf("Reading file ");
    (void)fflush(stdout);

    /* Open file for reading.  */
    fpr = fopen(file, "rb");

    /* Check for non-existent file.  */
    while (fpr == NULL) {
	printf("\nThis file does not exist, please try again.\n");
	(void)fflush(stdout);
	ret = scanf("%25s", file);
	if (ret == 0) {
	    bu_exit(EXIT_FAILURE, "ir-X - scanf failure - no file to work with!!\n");
	}
	fpr = fopen(file, "rb");
    }

    /* Read width and height of window.  */
    (void)bu_fgets(line, 150, fpr);
    {
	unsigned long w, h;
	sscanf(line, "%lu %lu", &w, &h);
	wide = w;
	high = h;
    }

    /* Check that width and height are not too big.  */
    if (wide > (size_t)MAXPIX) {
	printf("The width of the window, %lu, is greater\n", (unsigned long)wide);
	printf("than the maximum for width, %lu.  Press\n", (unsigned long)MAXPIX);
	printf("delete to end program.\n");
	(void)fflush(stdout);
    }
    if (high > MAXPIX) {
	printf("The height of the window, %lu, is greater\n", (unsigned long)wide);
	printf("than the maximum for height, %lu.  Press\n", (unsigned long)MAXPIX);
	printf("delete to end program.\n");
	(void)fflush(stdout);
    }

    /* Read pixel values.  */
    for (i=0; i<(int)high; i++) {
	for (j=0; j<(int)wide; j++) {
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%lf", &pixval[j][i]);
	}
    }

    /* Close file.  */
    (void)fclose(fpr);

    printf("- file read.\n");
    (void)fflush(stdout);

    /* Print out width and height of window.  */
    printf("Width:  %lu\n", (unsigned long)wide);
    printf("Height:  %lu\n", (unsigned long)high);
    (void)fflush(stdout);

    printf("Finding min & max.\n");
    (void)fflush(stdout);

    /* Find minimum and maximum of pixel values.  */
    for (i=0; (size_t)i<high; i++) {
	for (j=0; (size_t)j<wide; j++) {
	    if ((j==0) && (i==0)) {
		min = pixval[j][i];
		max = pixval[j][i];
	    }
	    V_MIN(min, pixval[j][i]);
	    V_MAX(max, pixval[j][i]);
	}
    }

    /* Write minimum and maximum pixel values.  */
    printf("Minimum:  %f\n", min);
    printf("Maximum:  %f\n", max);
    (void)fflush(stdout);

    printf("Finding pixel bins ");
    (void)fflush(stdout);

    /* Find pixel bins.  */
    dpix = (max - min) / MAXCOL;
    pixbin[0] = min;
    for (i=1; i<MAXCOL; i++) {
	pixbin[i] = pixbin[i-1] + dpix;
    }
    pixbin[MAXCOL] = max;

    /* Find the color for each pixel.  */
    for (i=0; (size_t)i<high; i++) {
	for (j=0; (size_t)j<wide; j++) {
	    /* Determine the color associated with pixval[j][i].  */
	    m = 0;
	    k = 0;
	    color[j][i] = 0;
	    while ((m == 0) && (k < MAXCOL)) {
		if ((pixval[j][i] > pixbin[k]) &&
		    (pixval[j][i] <= pixbin[k + 1]))
		{
		    color[j][i] = k;
		    m = 1;
		}
		k++;
	    }
	}
    }

    printf("- found pixel bins.\n");
    (void)fflush(stdout);

    printf("Putting color info in arrays ");
    (void)fflush(stdout);

    /* Put color info in arrays.  */
    for (i=0; (size_t)i<high; i++) {
	for (j=0; (size_t)j<wide; j++) {
	    if (array[color[j][i]].cnt < MAXARR) {
		array[color[j][i]].x1[array[color[j][i]].cnt] = j;
		array[color[j][i]].y1[array[color[j][i]].cnt] = i;
		array[color[j][i]].cnt++;
	    } else {
		if (array[color[j][i]].more == 0) {
		    if (lstarr < (MAXCOL + EXTRA)) {
			array[color[j][i]].more = lstarr;
			k = lstarr;
			lstarr++;
			array[k].x1[array[k].cnt] = j;
			array[k].y1[array[k].cnt] = i;
			array[k].cnt++;
		    } else {
			flag = 1;
		    }
		} else {
		    k = array[color[j][i]].more;
		    if (array[k].cnt < MAXARR) {
			array[k].x1[array[k].cnt] = j;
			array[k].y1[array[k].cnt] = i;
			array[k].cnt++;
		    } else {
			flag = 1;
		    }
		}
	    }
	}
    }

    printf("- color info in arrays.\n");
    (void)fflush(stdout);

    if (flag != 0) {
	printf("There too many pixels of one color.  Note that\n");
	printf("this means there is something wrong with the\n");
	printf("picture!\n");
	(void)fflush(stdout);
    }

    /* Set up window to be the size that was read.  */
    /* Open display.  */
    my_display = XOpenDisplay(NULL);

    /* Get id of parent (root is parent).  */
    root_id = DefaultRootWindow(my_display);

    /* Find value for black & white.  */
    black = BlackPixel(my_display, DefaultScreen(my_display));
    white = WhitePixel(my_display, DefaultScreen(my_display));

    /* Create a window & find its id.  */
    main_w = wide + (unsigned int)150;
    main_h = high + (unsigned int)150;
    my_window = XCreateSimpleWindow(my_display, root_id, 0, 0,
				    main_w, main_h, 50, white, black);

    /* Set appropriate fields in window hits structure.  */
    /* This is only done for the first window created.  */
    window_hints.width = (int)main_w;
    window_hints.height = (int)main_h;
    window_hints.flags = PSize;

    /* Inform window manager of hints.  */
    /* Set XSetStandarProperties instead of XSetNormalHints.  */
    XSetStandardProperties(my_display, my_window, winttl, winttl, None, a, 0,
			   &window_hints);

    /* Create picture window & find its id.  */
    wind_pic = XCreateSimpleWindow(my_display, my_window, 20, 20, wide, high,
				   5, white, black);

    /* Create exit window & find its id.  */
    wind_exit = XCreateSimpleWindow(my_display, my_window, (wide + 30),
				    (high + 65), 80, 30, 5, white, black);

    /* Create color scale window & find its id.  */
    wind_scale = XCreateSimpleWindow(my_display, my_window, 10, (high + 50),
				     (2 * MAXCOL), 60, 5, white, black);

    /* Select input event masks that are to be responded to (exposure).  */
    input_event_mask = ExposureMask | ButtonPressMask;

    /* Notify server about input event masks.  */
    XSelectInput(my_display, my_window, ExposureMask);
    XSelectInput(my_display, wind_pic, ExposureMask);
    XSelectInput(my_display, wind_exit, input_event_mask);
    XSelectInput(my_display, wind_scale, input_event_mask);

    /* Map window to display so that it will show up.  */
    XMapWindow(my_display, my_window);

    /* Map picture window, exit window, & color scale window to display */
    /* so that they will show up.  */
    XMapWindow(my_display, wind_pic);
    XMapWindow(my_display, wind_exit);
    XMapWindow(my_display, wind_scale);

    /* Create graphics context (gc) for my window.  */
    my_gc = XCreateGC(my_display, my_window, None, NULL);

    /* Create a loop so that events will occur.  */
    for (;;) {
	XNextEvent(my_display, &event_received);
	switch (event_received.type) {
	    /* Do the following when an expose occurs.  */
	    case Expose:		/* Code for expose event.  */
		/* Draw the picture if the picture window is exposed.  */
		if (event_received.xexpose.window == wind_pic) {
		    /* START # 1 */
		    /* Send groups of color to screen.  */
		    for (k=0; k<MAXCOL; k++) {
			if (array[k].cnt > 0) {
			    for (i=0; i<array[k].cnt; i++) {
				rect[i].x = array[k].x1[i];
				rect[i].y = array[k].y1[i];
				rect[i].width = 1;
				rect[i].height = 1;
			    }
			    m = array[k].cnt;
			    XAllocColor(my_display, DefaultColormap(my_display, screen),
					&colval[k]);
			    XSetForeground(my_display, my_gc, colval[k].pixel);
			    XFillRectangles(my_display, wind_pic, my_gc, rect, m);

			    /* Send extra array if there is a lot of that color.  */
			    if (array[k].more > 0) {
				j = array[k].more;
				for (i=0; i<array[j].cnt; i++) {
				    rect[i].x = array[j].x1[i];
				    rect[i].y = array[j].y1[i];
				    rect[i].width = 1;
				    rect[i].height = 1;
				}
				m = array[j].cnt;
				XAllocColor(my_display, DefaultColormap(my_display,
									screen), &colval[k]);
				XSetForeground(my_display, my_gc, colval[k].pixel);
				XFillRectangles(my_display, wind_pic, my_gc, rect, m);
			    }
			}
		    }
		}						/* END # 1 */

		/* If exit window is exposed write label.  */
		else if (event_received.xexpose.window == wind_exit) {
		    /* START # 2 */
		    XSetForeground(my_display, my_gc, white);
		    font = XLoadFont(my_display, "8x13bold");
		    XSetFont(my_display, my_gc, font);
		    XDrawString(my_display, wind_exit, my_gc, 25, 20, quit,
				strlen(quit));
		}						/* END # 2 */

		/* If color scale window is exposed put up color scale.  */
		else if (event_received.xexpose.window == wind_scale) {
		    for (i=0; i<MAXCOL; i++) {
			XAllocColor(my_display, DefaultColormap(my_display,
								screen), &colval[i]);
			XSetForeground(my_display, my_gc, colval[i].pixel);
			XFillRectangle(my_display, wind_scale, my_gc,
				       (i * 2), 0, 2, 30);
		    }
		    /* Write label.  */
		    XSetForeground(my_display, my_gc, white);
		    font = XLoadFont(my_display, "8x13bold");
		    XSetFont(my_display, my_gc, font);
		    (void)sprintf(string, "%.0f", min);
		    XDrawString(my_display, wind_scale, my_gc,
				2, 45, string, strlen(string));
		    r = min + (max - min) / 4.0;
		    (void)sprintf(string, "%.0f", r);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 / 4 - 8), 45, string, strlen(string));
		    r = min + (max - min) / 2.0;
		    (void)sprintf(string, "%.0f", r);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 / 2 - 8), 45, string, strlen(string));
		    r = min + (max - min) * 3. / 4.0;
		    (void)sprintf(string, "%.0f", r);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 * 3 / 4 - 8), 45, string, strlen(string));
		    (void)sprintf(string, "%.0f", max);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 - 16), 45, string, strlen(string));
		}
		break;

		/* Do the following if a mouse press occurs.  */
	    case ButtonPress:
		if (event_received.xbutton.window == wind_exit) {
		    XCloseDisplay(my_display);

		    /* Create pix file if necessary.  */
		    if (flag_pix == 1) {
			/* START # 1.  */
			/* Open pix file to be written to.  */
			fpw = fopen(file_pix, "wb");

			/* Write colors to file.  */
			for (i=high; i>0; i--) {
			    /* START # 2.  */
			    for (j=0; (size_t)j<wide; j++) {
				/* START # 3.  */
				c = (unsigned char)((int)(colval[color[j][i-1]].red
							  / 256));
				putc(c, fpw);
				c = (unsigned char)((int)
						    (colval[color[j][i-1]].green / 256));
				putc(c, fpw);
				c = (unsigned char)((int)(colval[color[j][i-1]].blue
							  / 256));
				putc(c, fpw);
			    }				/* END # 3.  */
			}					/* END # 2.  */

			/* Close file.  */
			(void)fclose(fpw);

			printf("Pix file, %s, has been written.\n", file_pix);
			(void)fflush(stdout);
		    }					/* END # 1.  */

		    bu_free(array, "free colstr array");
		    return 0;
		}
		break;
	}
    }

    bu_free(array, "free colstr array");
    return 0;
}