Esempio n. 1
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;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
    /*  START # 99  */
    struct application ap;  /*  Structure passed between functions.  */
    struct rt_i *rtip;	/*  Used to build directory.  */
    int index;		/*  Index for rt_dirbuild & rt_gettree.  */
    char idbuf[32];	/*  Contains data base info.  */
    struct region *pr;   /*  Used in finding region names.  */

    int numreg;		/*  Number of regions.  */
    double centall[3];	/*  Center of entire model.  */
    double minall[3];	/*  Minimum of entire model.  */
    double maxall[3];	/*  Maximum of entire model.  */
    double areaall;	/*  Surface area of bounding sphere.  */
    double radall;	/*  Radius of bounding sphere.  */
    long seed;		/*  Seed for random number generator.  */
    double rayfir;	/*  Number of rays to be fired.  */
    double rho, phi, theta;/*  Spherical coordinates for starting point.  */
    double elev, az, rds;	/*  Elevation, azimuth, & radius for finding vector  */
    /*  in yz-plane.  */
    double strtpt[3];	/*  Starting point.  */
    double strtdir[3];	/*  Starting direction.  */
    double denom;	/*  Denominator.  */

    int ians;		/*  Answer to question.  */
    int i, j, k, m;		/*  Loop counters.  */
    double r;		/*  Loop counter.  */
    double q;		/*  Temporary variable.  */
    double s[3], t[3];	/*  Temporary variables.  */

    FILE *fpw;		/*  Allows a file to be written.  */
    char outfile[26];	/*  Output file name.  */
    char errfile[26];	/*  Error file name.  */
    FILE *fpw2;		/*  Allows a file to be written.  */
    char lwxfile[26];	/*  Longwave radiation exchange file for PRISM  */
    /*  (not quite PRISM ready).  */

    struct bn_unif *msr = NULL;

    /*  Check to see if arguments are implimented correctly.  */
    if ( (argv[1] == NULL) || (argv[2] == NULL) )
    {
        (void)fprintf(stderr, "\nusage:  %s file.g objects\n\n", *argv);
    }

    else
    {
        /*  START # 100  */

        /*  Find name of output file.  */
        (void)printf("Enter name of output file (25 char max).\n\t");
        (void)fflush(stdout);
        (void)scanf("%25s", outfile);

        /*  Find name of longwave radiation exchange (lwx) file  */
        /*  for use with PRISM (not quite PRISM ready).  */
        (void)printf("Enter name of longwave radiation exchange");
        (void)printf(" file (25 char max).\n\t");
        (void)fflush(stdout);
        (void)scanf("%25s", lwxfile);

        /*  Find name of error file.  */
        (void)printf("Enter name of error file (25 char max).\n\t");
        (void)fflush(stdout);
        (void)scanf("%25s", errfile);

        /*  Open files.  */
        fpw = fopen(outfile, "w");
        fpw1 = fopen(errfile, "w");
        fpw2 = fopen(lwxfile, "w");

        /*  Write info to output & error file.  */
        (void)fprintf(fpw, "\n.g file used:  %s\n", argv[1]);
        (void)fprintf(fpw, "regions used:\n");
        (void)fprintf(fpw1, "\n.g file used:  %s\n", argv[1]);
        (void)fprintf(fpw1, "regions used:\n");
        i = 2;
        while (argv[i] != NULL)
        {
            (void)fprintf(fpw, "\t%s\n", argv[i]);
            (void)fprintf(fpw1, "\t%s\n", argv[i]);
            i++;
        }
        (void)fprintf(fpw, "output file created:  %s\n", outfile);
        (void)fprintf(fpw, "error file created:  %s\n", errfile);
        (void)fprintf(fpw, "lwx file created:  %s\n", errfile);
        (void)fflush(fpw);
        (void)fprintf(fpw1, "output file created:  %s\n", outfile);
        (void)fprintf(fpw1, "error file created:  %s\n", errfile);
        (void)fprintf(fpw1, "lwx file created:  %s\n", errfile);
        (void)fflush(fpw1);

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

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

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

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

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

        /*  Malloc everything now that the number of regions is known.  */
        info = (struct table *)bu_malloc(numreg * sizeof(*info), "info");
        for (i=0; i<numreg; i++)
        {
            info[i].intrays = (double *)bu_malloc(numreg * sizeof(double), "info[i].intrays");
            info[i].sf = (double *)bu_malloc(numreg * sizeof(double), "info[i].sf");
        }

        /*  Zero all arrays.  */
        for (i=0; i<numreg; i++)
        {
            /*  START # 110  */
            info[i].name = "\0";
            info[i].lvrays = 0.;
            for (j=0; j<numreg; j++)
            {
                info[i].intrays[j] = 0.;
                info[i].sf[j] = 0.;
            }
            info[i].regarea = 0.;
        }						/*  END # 110  */

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

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

        /*  Find minimum and maximum of entire model.  */
        minall[X] = rtip->mdl_min[X];
        minall[Y] = rtip->mdl_min[Y];
        minall[Z] = rtip->mdl_min[Z];
        maxall[X] = rtip->mdl_max[X];
        maxall[Y] = rtip->mdl_max[Y];
        maxall[Z] = rtip->mdl_max[Z];

        /*  Find radius of bounding sphere.  */
        radall = (maxall[X] - minall[X]) * (maxall[X] - minall[X])
                 + (maxall[Y] - minall[Y]) * (maxall[Y] - minall[Y])
                 + (maxall[Z] - minall[Z]) * (maxall[Z] - minall[Z]);
        /*  Add .5 to make sure completely outside the rpp.  */
        radall = sqrt(radall) / 2. + .5;

        /*  Find surface area of bounding sphere.  */
        areaall = 4 * M_PI * radall * radall;

        /*  Print info on min, max, center, radius, & surface area  */
        /*  of entire model.  */
        (void)printf("Min & max for entire model.\n");
        (void)printf("\tX:  %f - %f\n", minall[X], maxall[X]);
        (void)printf("\tY:  %f - %f\n", minall[Y], maxall[Y]);
        (void)printf("\tZ:  %f - %f\n", minall[Z], maxall[Z]);
        (void)printf("Center:  %f, %f, %f\n\n", centall[X], centall[Y],
                     centall[Z]);
        (void)printf("Radius:  %f\n", radall);
        (void)printf("Surface Area:  %f\n\n", areaall);
        (void)fflush(stdout);

        /*  Find number of rays to fire.  */
        (void)printf("Enter the number of rays to be fired.\n\t");
        (void)fflush(stdout);
        (void)scanf("%lf", &rayfir);

        /*  Write info to files.  */
        (void)fprintf(fpw, "Min & max for entire region:\n");
        (void)fprintf(fpw, "\tX:  %f - %f\n", minall[X], maxall[X]);
        (void)fprintf(fpw, "\tY:  %f - %f\n", minall[Y], maxall[Y]);
        (void)fprintf(fpw, "\tZ:  %f - %f\n", minall[Z], maxall[Z]);
        (void)fprintf(fpw, "Center:  %f, %f, %f\n", centall[X],
                      centall[Y], centall[Z]);
        (void)fprintf(fpw, "Radius:  %f\n", radall);
        (void)fprintf(fpw, "Surface area:  %f\n", areaall);
        (void)fprintf(fpw, "Number of rays fired:  %f\n\n", rayfir);
        (void)fflush(fpw);

        (void)fprintf(fpw1, "Min & max for entire region:\n");
        (void)fprintf(fpw1, "\tX:  %f - %f\n", minall[X], maxall[X]);
        (void)fprintf(fpw1, "\tY:  %f - %f\n", minall[Y], maxall[Y]);
        (void)fprintf(fpw1, "\tZ:  %f - %f\n", minall[Z], maxall[Z]);
        (void)fprintf(fpw1, "Center:  %f, %f, %f\n", centall[X],
                      centall[Y], centall[Z]);
        (void)fprintf(fpw1, "Radius:  %f\n", radall);
        (void)fprintf(fpw1, "Surface area:  %f\n", areaall);
        (void)fprintf(fpw1, "Number of rays fired:  %f\n\n", rayfir);
        (void)fflush(fpw1);

        /*  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) );
        }

        (void)printf("Region names in structure.\n");
        (void)fflush(stdout);

        /*  Write region names to error file.  */
        for (i=0; i<numreg; i++)
        {
            (void)fprintf(fpw1, "region %d:  %s\n", (i + 1), info[i].name);
            (void)fflush(fpw1);
        }
        (void)fprintf(fpw1, "\n");
        (void)fflush(fpw1);

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

        (void)printf("Seed initialized\n");
        (void)fflush(stdout);

        /*  Set up parameters for rt_shootray.  */
        RT_APPLICATION_INIT(&ap);
        ap.a_hit = hit;			/*  User supplied hit func.  */
        ap.a_miss = miss;		/*  User supplied miss func.  */
        ap.a_overlap = overlap;		/*  User supplied overlap func.  */
        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 struct.  */
        /*
         *	(void)printf("Parameters for rt_shootray set.\n");
         *	(void)fflush(stdout);
         */

        /*  Loop through for each ray fired.  */
        for (r=0; r<rayfir; r++)
        {
            /*  START # 150  */
            /*
             *		(void)printf("In loop - %f\n", r);
             *		(void)fflush(stdout);
             */

            /*  Find point on the bounding sphere.  The negative  */
            /*  of the unit vector of this point will be the  */
            /*  firing direction.  */
            q = BN_UNIF_DOUBLE(msr) + 0.5;
            theta = q * 2. * M_PI;

            q = BN_UNIF_DOUBLE(msr) + 0.5;
            phi = (q * 2.) - 1.;
            phi = acos(phi);

            rho = radall;

            strtdir[X] = rho * sin(phi) * cos(theta);
            strtdir[Y] = rho * sin(phi) * sin(theta);
            strtdir[Z] = rho * cos(phi);

            /*  Elevation & 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 * 2. * M_PI;

            q = BN_UNIF_DOUBLE(msr) + 0.5;
            rds = rho * sqrt(q);
            s[X] = 0.;
            s[Y] = rds * cos(theta);
            s[Z] = rds * 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 the starting point.  */
            strtpt[X] = t[X] + strtdir[X];
            strtpt[Y] = t[Y] + strtdir[Y];
            strtpt[Z] = t[Z] + strtdir[Z];

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

            /*  Normalize starting direction & 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 & 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];

            /*
             *		(void)printf("Calling rt_shootray.\n");
             *		(void)fflush(stdout);
             */

            /*  Call rt_shootray.  */
            (void)rt_shootray(&ap);

            /*
             *		(void)printf("Rt_shootray finished.\n");
             *		(void)fflush(stdout);
             */

        }						/*  END # 150  */

        /*
         *	   (void)printf("Finished loop.\n");
         *	   (void)fflush(stdout);
         */

        for (i=0; i<numreg; i++)
        {
            /*  START # 160  */
            /*  Write region names to output file.  */
            (void)fprintf(fpw, "Region %d:  %s\n", (i+1), info[i].name);
            (void)fflush(fpw);

            /*  Find shape factors & print.  */
            if (info[i].lvrays == 0)
            {
                /*  START # 1060  */
                (void)fprintf(fpw1, "**  ERROR - # or rays hitting region ");
                (void)fprintf(fpw1, "%d is 0.  **\n", i);
                (void)fflush(fpw1);
            }						/*  END # 1060  */

            else
            {
                /*  START # 1070  */
                /*  Must divide by 2. since looking forwards & backwards.  */
                info[i].regarea = info[i].lvrays / rayfir * areaall / 2.;
                for (j=0; j<numreg; j++)
                {
                    /*  START # 1080  */
                    info[i].sf[j] = info[i].intrays[j] / info[i].lvrays;
                    (void)fprintf(fpw, "\t%d   %d   %f\n",
                                  (i + 1), (j + 1), info[i].sf[j]);
                    (void)fflush(fpw);

                    (void)fprintf(fpw1, "reg %d - reg %d - rays leave ",
                                  (i + 1), (j + 1));
                    (void)fprintf(fpw1, "& int %f - rays leave %f ",
                                  info[i].intrays[j], info[i].lvrays);
                    (void)fprintf(fpw1, "- sf %f - area %f\n",
                                  info[i].sf[j], info[i].regarea);
                    (void)fflush(fpw1);
                }					/*  END # 1080  */
            }						/*  END # 1070  */
        }						/*  END # 160  */

        /*  Write lwx file.  */
        (void)fprintf(fpw2, "Longwave Radiation Exchange Factors ");
        (void)fprintf(fpw2, "for %s\n", argv[1]);
        (void)fprintf(fpw2, "Number of Regions = %4d\n", numreg);
        (void)fprintf(fpw2, "TEMIS\n\n");

        for (i=0; i<numreg; i++)
        {
            /*  START # 1090  */
            (void)fprintf(fpw2, "Region\tArea\tEmissivity\n");
            /*  Area is put into square meters.  */
            (void)fprintf(fpw2, "%d\t%f\n", (i + 1),
                          (info[i].regarea / 1000. / 1000.));

            /*  Count the number of shape factors.  */
            k = 0;
            for (j=0; j<numreg; j++)
            {
                if (info[i].sf[j] != 0.) k++;
            }
            (void)fprintf(fpw2, "Bij\t%d\n", k);

            /*  Print shape factors.  */
            m = 0;
            for (j=0; j<numreg; j++)
            {
                /*  START # 1100  */
                if (info[i].sf[j] != 0.)
                {
                    /*  START # 1110  */
                    (void)fprintf(fpw2, "%4d   %.4f   ", (j + 1),
                                  info[i].sf[j]);
                    m++;
                    if (m == 5)
                    {
                        /*  START # 1120  */
                        m = 0;
                        (void)fprintf(fpw2, "\n");
                    }				/*  END # 1120  */
                }					/*  END # 1110  */
            }					/*  END # 1100  */
            if (m != 0) (void)fprintf(fpw2, "\n");
            (void)fprintf(fpw2, " Gnd         Sky\n\n");
            (void)fflush(fpw2);
        }						/*  END # 1090  */


        /* free memory */
        for (i=0; i<numreg; i++)
        {
            bu_free(info[i].intrays, "info[i].intrays");
            bu_free(info[i].sf, "info[i].sf");
        }
        bu_free(info, "info");

        /*  Close files.  */
        (void)fclose(fpw);
        (void)fclose(fpw1);
        (void)fclose(fpw2);
    }							/*  END # 100  */
    return 0;
}							/*  END # 99  */