void
do_rt_gettrees(struct rt_i *my_rtip, char **object_name, int nm_objects, int *prep)
{
    static char **prev_names = 0;
    static int prev_nm = 0;
    int i;

    if (object_name == NULL) {
	if ((object_name = prev_names) == 0)
	    bu_exit (1, "%s:%d: This shouldn't happen\n", __FILE__, __LINE__);
	nm_objects = prev_nm;
    }

    if (prev_names == 0) {
	prev_names = object_name;
	prev_nm = nm_objects;
    }

    if (silent_flag != SILENT_YES) {
	printf("\nGet trees...");
	fflush(stdout);
    }

    i = rt_gettrees_and_attrs(my_rtip, (const char **)a_tab.attrib, nm_objects, (const char **) object_name, 1);
    if (i) {
	fflush(stdout);
	bu_exit (1, "rt_gettrees() failed\n");
    }

    if (*prep) {
	if (silent_flag != SILENT_YES) {
	    printf("\nPrepping the geometry...");
	    fflush(stdout);
	}
	rt_prep(my_rtip);
	*prep = 0;
    }

    if (silent_flag != SILENT_YES) {
	printf("\n%s", (nm_objects == 1) ? "Object" : "Objects");
	for (i = 0; i < nm_objects; ++i)
	    printf(" '%s'", object_name[i]);
	printf(" processed\n");
    }
}
Example #2
0
/**
 * Given a ray, shoot it at all the relevant parts of the model,
 * (building the HeadSeg chain), and then call rt_boolregions() to
 * build and evaluate the partition chain.  If the ray actually hit
 * anything, call the application's a_hit() routine with a pointer to
 * the partition chain, otherwise, call the application's a_miss()
 * routine.
 *
 * It is important to note that rays extend infinitely only in the
 * positive direction.  The ray is composed of all points P, where
 *
 * P = r_pt + K * r_dir
 *
 * for K ranging from 0 to +infinity.  There is no looking backwards.
 *
 * It is also important to note that the direction vector r_dir must
 * have unit length; this is mandatory, and is not ordinarily checked,
 * in the name of efficiency.
 *
 * Input:  Pointer to an application structure, with these mandatory fields:
 * a_ray.r_pt Starting point of ray to be fired
 * a_ray.r_dir UNIT VECTOR with direction to fire in (dir cosines)
 * a_hit Routine to call when something is hit
 * a_miss Routine to call when ray misses everything
 *
 * Calls user's a_miss() or a_hit() routine as appropriate.  Passes
 * a_hit() routine list of partitions, with only hit_dist fields
 * valid.  Normal computation deferred to user code, to avoid needless
 * computation here.
 *
 * Returns: whatever the application function returns (an int).
 *
 * NOTE: The application functions may call rt_shootray() recursively.
 * Thus, none of the local variables may be static.
 *
 * An open issue for execution in a PARALLEL environment is locking of
 * the statistics variables.
 */
int
rt_vshootray(struct application *ap)
{
    struct seg *HeadSeg;
    int ret;
    vect_t inv_dir;	/* inverses of ap->a_ray.r_dir */
    struct bu_bitv *solidbits;	/* bits for all solids shot so far */
    struct bu_ptbl *regionbits;	/* bits for all involved regions */
    char *status;
    struct partition InitialPart;	/* Head of Initial Partitions */
    struct partition FinalPart;	/* Head of Final Partitions */
    int nrays = 1;			/* for now */
    int vlen;
    int id;
    int i;
    struct soltab **ary_stp;	/* array of pointers */
    struct xray **ary_rp;	/* array of pointers */
    struct seg *ary_seg;	/* array of structures */
    struct rt_i *rtip;
    int done;

#define BACKING_DIST (-2.0)		/* mm to look behind start point */
    rtip = ap->a_rt_i;
    RT_AP_CHECK(ap);
    if (!ap->a_resource) {
	ap->a_resource = &rt_uniresource;
    }
    RT_CK_RESOURCE(ap->a_resource);

    if (RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) {
	bu_log("\n**********mshootray cpu=%d  %d, %d lvl=%d (%s)\n",
	       ap->a_resource->re_cpu,
	       ap->a_x, ap->a_y,
	       ap->a_level,
	       ap->a_purpose != (char *)0 ? ap->a_purpose : "?");
	VPRINT("Pnt", ap->a_ray.r_pt);
	VPRINT("Dir", ap->a_ray.r_dir);
    }

    rtip->rti_nrays++;
    if (rtip->needprep)
	rt_prep(rtip);

    /* Allocate dynamic memory */
    vlen = nrays * rtip->rti_maxsol_by_type;
    ary_stp = (struct soltab **)bu_calloc(vlen, sizeof(struct soltab *),
					  "*ary_stp[]");
    ary_rp = (struct xray **)bu_calloc(vlen, sizeof(struct xray *),
				       "*ary_rp[]");
    ary_seg = (struct seg *)bu_calloc(vlen, sizeof(struct seg),
				      "ary_seg[]");

    /**** for each ray, do this ****/

    InitialPart.pt_forw = InitialPart.pt_back = &InitialPart;
    FinalPart.pt_forw = FinalPart.pt_back = &FinalPart;

    HeadSeg = RT_SEG_NULL;

    solidbits = rt_get_solidbitv(rtip->nsolids, ap->a_resource);

    if (BU_LIST_IS_EMPTY(&ap->a_resource->re_region_ptbl)) {
	BU_ALLOC(regionbits, struct bu_ptbl);
	bu_ptbl_init(regionbits, 7, "rt_shootray() regionbits ptbl");
    } else {
	regionbits = BU_LIST_FIRST(bu_ptbl, &ap->a_resource->re_region_ptbl);
	BU_LIST_DEQUEUE(&regionbits->l);
	BU_CK_PTBL(regionbits);
    }

    /* Compute the inverse of the direction cosines */
    if (!ZERO(ap->a_ray.r_dir[X])) {
	inv_dir[X]=1.0/ap->a_ray.r_dir[X];
    } else {
	inv_dir[X] = INFINITY;
	ap->a_ray.r_dir[X] = 0.0;
    }
    if (!ZERO(ap->a_ray.r_dir[Y])) {
	inv_dir[Y]=1.0/ap->a_ray.r_dir[Y];
    } else {
	inv_dir[Y] = INFINITY;
	ap->a_ray.r_dir[Y] = 0.0;
    }
    if (!ZERO(ap->a_ray.r_dir[Z])) {
	inv_dir[Z]=1.0/ap->a_ray.r_dir[Z];
    } else {
	inv_dir[Z] = INFINITY;
	ap->a_ray.r_dir[Z] = 0.0;
    }

    /*
     * XXX handle infinite solids here, later.
     */

    /*
     * If ray does not enter the model RPP, skip on.
     * If ray ends exactly at the model RPP, trace it.
     */
    if (!rt_in_rpp(&ap->a_ray, inv_dir, rtip->mdl_min, rtip->mdl_max)  ||
	ap->a_ray.r_max < 0.0) {
	rtip->nmiss_model++;
	if (ap->a_miss)
	    ret = ap->a_miss(ap);
	else
	    ret = 0;
	status = "MISS model";
	goto out;
    }

    /* For each type of solid to be shot at, assemble the vectors */
    for (id = 1; id <= ID_MAX_SOLID; id++) {
	register int nsol;

	if ((nsol = rtip->rti_nsol_by_type[id]) <= 0) continue;

	/* For each instance of this solid type */
	for (i = nsol-1; i >= 0; i--) {
	    ary_stp[i] = rtip->rti_sol_by_type[id][i];
	    ary_rp[i] = &(ap->a_ray);	/* XXX, sb [ray] */
	    ary_seg[i].seg_stp = SOLTAB_NULL;
	    BU_LIST_INIT(&ary_seg[i].l);
	}
	/* bounding box check */
	/* bit vector per ray check */
	/* mark elements to be skipped with ary_stp[] = SOLTAB_NULL */
	ap->a_rt_i->nshots += nsol;	/* later: skipped ones */
	if (OBJ[id].ft_vshot) {
	    OBJ[id].ft_vshot(ary_stp, ary_rp, ary_seg, nsol, ap);
	} else {
	    vshot_stub(ary_stp, ary_rp, ary_seg, nsol, ap);
	}


	/* set bits for all solids shot at for each ray */

	/* append resulting seg list to input for boolweave */
	for (i = nsol-1; i >= 0; i--) {
	    register struct seg *seg2;

	    if (ary_seg[i].seg_stp == SOLTAB_NULL) {
		/* MISS */
		ap->a_rt_i->nmiss++;
		continue;
	    }
	    ap->a_rt_i->nhits++;

	    /* For now, do it the slow way.  sb [ray] */
	    /* MUST dup it -- all segs have to live till after a_hit() */
	    RT_GET_SEG(seg2, ap->a_resource);
	    *seg2 = ary_seg[i];	/* struct copy */
	    /* rt_boolweave(seg2, &InitialPart, ap); */
	    bu_bomb("FIXME: need to call boolweave here");

	    /* Add seg chain to list of used segs awaiting reclaim */

#if 0
	    /* FIXME: need to use waiting_segs/finished_segs here in
	     * conjunction with rt_boolweave()
	     {
	     register struct seg *seg3 = seg2;
	     while (seg3->seg_next != RT_SEG_NULL)
	     seg3 = seg3->seg_next;
	     seg3->seg_next = HeadSeg;
	     HeadSeg = seg2;
	     }
	    */
#endif
	}
    }

    /*
     * Ray has finally left known space.
     */
    if (InitialPart.pt_forw == &InitialPart) {
	if (ap->a_miss)
	    ret = ap->a_miss(ap);
	else
	    ret = 0;
	status = "MISSed all primitives";
	goto freeup;
    }

    /*
     * All intersections of the ray with the model have been computed.
     * Evaluate the boolean trees over each partition.
     */
    done = rt_boolfinal(&InitialPart, &FinalPart, BACKING_DIST, INFINITY, regionbits, ap, solidbits);

    if (done > 0) goto hitit;

    if (FinalPart.pt_forw == &FinalPart) {
	if (ap->a_miss)
	    ret = ap->a_miss(ap);
	else
	    ret = 0;
	status = "MISS bool";
	goto freeup;
    }

    /*
     * Ray/model intersections exist.  Pass the list to the user's
     * a_hit() routine.  Note that only the hit_dist elements of
     * pt_inhit and pt_outhit have been computed yet.  To compute both
     * hit_point and hit_normal, use the
     *
     * RT_HIT_NORMAL(NULL, hitp, stp, rayp, 0);
     *
     * macro.  To compute just hit_point, use
     *
     * VJOIN1(hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir);
     */
hitit:
    if (RT_G_DEBUG&DEBUG_SHOOT) rt_pr_partitions(rtip, &FinalPart, "a_hit()");

    if (ap->a_hit)
	ret = ap->a_hit(ap, &FinalPart, HeadSeg/* &finished_segs */);
    else
	ret = 0;
    status = "HIT";

    /*
     * Processing of this ray is complete.  Free dynamic resources.
     */
freeup:
    {
	register struct partition *pp;

	/* Free up initial partition list */
	for (pp = InitialPart.pt_forw; pp != &InitialPart;) {
	    register struct partition *newpp;
	    newpp = pp;
	    pp = pp->pt_forw;
	    FREE_PT(newpp, ap->a_resource);
	}
	/* Free up final partition list */
	for (pp = FinalPart.pt_forw; pp != &FinalPart;) {
	    register struct partition *newpp;
	    newpp = pp;
	    pp = pp->pt_forw;
	    FREE_PT(newpp, ap->a_resource);
	}
    }

    /* Segs can't be freed until after a_hit() has returned */
#if 0
    /* FIXME: depends on commented out code above */
    if (HeadSeg)
	RT_FREE_SEG_LIST(HeadSeg, ap->a_resource);
#endif

out:
    bu_free((char *)ary_stp, "*ary_stp[]");
    bu_free((char *)ary_rp, "*ary_rp[]");
    bu_free((char *)ary_seg, "ary_seg[]");

    if (solidbits != NULL) {
	bu_bitv_free(solidbits);
    }
    if (RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) {
	bu_log("----------mshootray cpu=%d  %d, %d lvl=%d (%s) %s ret=%d\n",
	       ap->a_resource->re_cpu,
	       ap->a_x, ap->a_y,
	       ap->a_level,
	       ap->a_purpose != (char *)0 ? ap->a_purpose : "?",
	       status, ret);
    }
    return ret;
}
Example #3
0
void
BU_FORTRAN(frprep, FRPREP)(struct rt_i **rtip)
{
    RT_CHECK_RTI(*rtip);
    rt_prep(*rtip);
}
Example #4
0
/**
 * Called at the start of a run.
 *
 * Returns 1 if framebuffer should be opened, else 0.
 */
int
view_init(struct application *ap, char *file, char *UNUSED(obj), int minus_o, int minus_F)
{
    /*
     * Allocate a scanline for each processor.
     */
    ap->a_hit = rayhit;
    ap->a_miss = raymiss;
    ap->a_onehit = 1;

    /*
     * Does the user want occlusion checking?
     *
     * If so, load and prep.
     */
    if (bu_vls_strlen(&occlusion_objects) != 0) {
	struct db_i *dbip;
	int nObjs;
	const char **objs;
	int i;

	bu_log("rtedge: loading occlusion geometry from %s.\n", file);

	if (Tcl_SplitList(NULL, bu_vls_addr(&occlusion_objects), &nObjs,
			  &objs) == TCL_ERROR) {
	    bu_log("rtedge: occlusion list = %s\n",
		   bu_vls_addr(&occlusion_objects));
	    bu_exit(EXIT_FAILURE, "rtedge: could not parse occlusion objects list.\n");
	}

	for (i=0; i<nObjs; ++i) {
	    bu_log("rtedge: occlusion object %d = %s\n", i, objs[i]);
	}


	if ((dbip = db_open(file, DB_OPEN_READONLY)) == DBI_NULL)
	    bu_exit(EXIT_FAILURE, "rtedge: could not open geometry database file %s.\n", file);
	RT_CK_DBI(dbip);

#if 0
	/* FIXME: calling this when db_open()'s mapped file doesn't
	 * fail will cause duplicate directory entries.  need to make
	 * sure db_dirbuild rebuilds from scratch or only updates
	 * existing entries when they exist.
	 */
	if (db_dirbuild(dbip) < 0)
	    bu_exit(EXIT_FAILURE, "rtedge: could not read database.\n");
#endif

	occlusion_rtip = rt_new_rti(dbip); /* clones dbip */

	for (i=0; i < MAX_PSW; i++) {
	    rt_init_resource(&occlusion_resources[i], i, occlusion_rtip);
	    bn_rand_init(occlusion_resources[i].re_randptr, i);
	}

	db_close(dbip);			 /* releases original dbip */

	for (i=0; i<nObjs; ++i)
	    if (rt_gettree(occlusion_rtip, objs[i]) < 0)
		bu_log("rtedge: gettree failed for %s\n", objs[i]);
	    else
		bu_log("rtedge: got tree for object %d = %s\n", i, objs[i]);

	bu_log("rtedge: occlusion rt_gettrees done.\n");

	rt_prep(occlusion_rtip);

	bu_log("rtedge: occlusion prep done.\n");

	/*
	 * Create a set of application structures for the occlusion
	 * geometry. Need one per cpu, the upper half does the per-
	 * thread allocation in worker, but that's off limits.
	 */
	occlusion_apps = (struct application **)bu_calloc(npsw, sizeof(struct application *),
							  "occlusion application structure array");
	for (i=0; i<npsw; ++i) {
	    BU_ALLOC(occlusion_apps[i], struct application);
	    RT_APPLICATION_INIT(occlusion_apps[i]);

	    occlusion_apps[i]->a_rt_i = occlusion_rtip;
	    occlusion_apps[i]->a_resource = (struct resource *)BU_PTBL_GET(&occlusion_rtip->rti_resources, i);
	    occlusion_apps[i]->a_onehit = 1;
	    occlusion_apps[i]->a_hit = occlusion_hit;
	    occlusion_apps[i]->a_miss = occlusion_miss;
	    if (rpt_overlap)
		occlusion_apps[i]->a_logoverlap = (void (*)(struct application *, const struct partition *, const struct bu_ptbl *, const struct partition *))NULL;
	    else
		occlusion_apps[i]->a_logoverlap = rt_silent_logoverlap;

	}
	bu_log("rtedge: will perform occlusion testing.\n");

	/*
	 * If an inclusion mode has not been specified, use the default.
	 */
	if (occlusion_mode == OCCLUSION_MODE_NONE) {
	    occlusion_mode = OCCLUSION_MODE_DEFAULT;
	    bu_log("rtedge: occlusion mode = %d\n", occlusion_mode);
	}

	if ((occlusion_mode != OCCLUSION_MODE_NONE) &&
	    (overlay == OVERLAY_MODE_UNSET)) {
	    bu_log("rtedge: automagically activating overlay mode.\n");
	    overlay = OVERLAY_MODE_DOIT;
	}

    }

    if (occlusion_mode != OCCLUSION_MODE_NONE &&
	bu_vls_strlen(&occlusion_objects) == 0) {
	bu_exit(EXIT_FAILURE, "rtedge: occlusion mode set, but no objects were specified.\n");
    }

    /* if non-default/inverted background was requested, swap the
     * foreground and background colors.
     */
    if (!default_background) {
	color tmp;
	tmp[RED] = fgcolor[RED];
	tmp[GRN] = fgcolor[GRN];
	tmp[BLU] = fgcolor[BLU];
	fgcolor[RED] = bgcolor[RED];
	fgcolor[GRN] = bgcolor[GRN];
	fgcolor[BLU] = bgcolor[BLU];
	bgcolor[RED] = tmp[RED];
	bgcolor[GRN] = tmp[GRN];
	bgcolor[BLU] = tmp[BLU];
    }

    if (minus_o && (overlay || blend)) {
	/*
	 * Output is to a file stream.  Do not allow parallel
	 * processing since we can't seek to the rows.
	 */
	RTG.rtg_parallel = 0;
	bu_log("view_init: deactivating parallelism due to -o option.\n");
	/*
	 * The overlay and blend cannot be used in -o mode.  Note that
	 * the overlay directive takes precedence, they can't be used
	 * together.
	 */
	overlay = 0;
	blend = 0;
	bu_log("view_init: deactivating overlay and blending due to -o option.\n");
    }

    if (overlay)
	bu_log("view_init: will perform simple overlay.\n");
    else if (blend)
	bu_log("view_init: will perform blending.\n");

    return minus_F || (!minus_o && !minus_F); /* we need a framebuffer */
}
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 */
Example #6
0
/**
 * raytrace an object optionally storing the rays
 */
void
fit_rt(char *obj, struct db_i *db, struct fitness_state *fstate)
{
    int i;
    fastf_t diff[3], tmp;
    fastf_t min[3], max[3];


    /*
     * uncomment to calculate # of nodes
     * and use in fitness calculation
     *
     struct directory *dp
     struct rt_db_internal in;
     int n_leaves;
     if (!rt_db_lookup_internal(db, obj, &dp, &in, LOOKUP_NOISY, &rt_uniresource))
     bu_exit(EXIT_FAILURE, "Failed to read object to raytrace");
     n_leaves = db_count_tree_nodes(((struct rt_comb_internal *)in.idb_ptr)->tree, 0);
     rt_db_free_internal(&in);
    */

    fstate->rtip = rt_new_rti(db);
    fstate->row = 0;

    if (rt_gettree(fstate->rtip, obj) < 0)
	bu_exit(EXIT_FAILURE, "rt_gettree failed");

    /*
      for (i = 0; i < fstate->max_cpus; i++) {
      rt_init_resource(&fstate->resource[i], i, fstate->rtip);
      bn_rand_init(fstate->resource[i].re_randptr, i);
      }
    */

    /* stash bounding box and if comparing to source
     * calculate the difference between the bounding boxes */
    if (fstate->capture) {
	VMOVE(fstate->min, fstate->rtip->mdl_min);
	VMOVE(fstate->max, fstate->rtip->mdl_max);
/*	z_max = fstate->rtip->mdl_max[Z];*/
    }
    /*else {
     * instead of storing min and max, just compute
     * what we're going to need later
     for (i = 0; i < 3; i++) {
     diff[i] = 0;
     if (fstate->min[i] > fstate->rtip->mdl_min[i])
     diff[i] += fstate->min[i] - fstate->rtip->mdl_min[i];
     if (fstate->max[i] < fstate->rtip->mdl_max[i])
     diff[i] += fstate->rtip->mdl_max[i] - fstate->max[i];
     if (fstate->min[i]  < fstate->rtip->mdl_min[i])
     min[i] = fstate->min[i];
     else
     min[i] = fstate->rtip->mdl_min[i];
     if (fstate->max[i] > fstate->rtip->mdl_max[i])
     max[i] = fstate->max[i];
     else
     max[i] = fstate->rtip->mdl_max[i];
     diff[i] = max[i] - min[i];
     }
     fastf_t tmp = (diff[X]/fstate->gridSpacing[X]-1) * (diff[Y]/fstate->gridSpacing[Y] - 1);
     fstate->volume = (fstate->a_len + (max[Z] - fstate->max[Z])) * tmp;
     }
    */


    /*rt_prep_parallel(fstate->rtip, fstate->ncpu)o;*/

    rt_prep(fstate->rtip);
    if (fstate->capture) {
	/* Store bounding box of voxel data -- fixed bounding box for fitness */
	fstate->gridSpacing[X] = (fstate->rtip->mdl_max[X] - fstate->rtip->mdl_min[X]) / (fstate->res[X] + 1);
	fstate->gridSpacing[Y] = (fstate->rtip->mdl_max[Y] - fstate->rtip->mdl_min[Y]) / (fstate->res[Y] + 1);
	fstate->a_len = fstate->max[Z]-fstate->rtip->mdl_min[Z]; /* maximum ray length (z-dist of bounding box) */
	fstate->volume = fstate->a_len * fstate->res[X] * fstate->res[Y]; /* volume of bounding box */

	/* allocate storage for saved rays */
	fstate->ray = (struct part **)bu_malloc(sizeof(struct part *) * fstate->res[X] * fstate->res[Y], "ray");
	VMOVE(fstate->min, fstate->rtip->mdl_min);
	VMOVE(fstate->max, fstate->rtip->mdl_max);


    } else {
	/* instead of storing min and max, just compute
	 * what we're going to need later */
	for (i = 0; i < 3; i++) {
	    diff[i] = 0;
	    if (fstate->min[i]  < fstate->rtip->mdl_min[i])
		min[i] = fstate->min[i];
	    else
		min[i] = fstate->rtip->mdl_min[i];
	    if (fstate->max[i] > fstate->rtip->mdl_max[i])
		max[i] = fstate->max[i];
	    else
		max[i] = fstate->rtip->mdl_max[i];
	    diff[i] = max[i] - min[i];
	}
	tmp = (diff[X]/fstate->gridSpacing[X]-1) * (diff[Y]/fstate->gridSpacing[Y] - 1);
	fstate->volume = (fstate->a_len + (max[Z] - fstate->max[Z])) * tmp;
	/* scale fitness to the unon of the sources and individual's bounding boxes */
	/* FIXME: sloppy
	   fastf_t tmp = (diff[X]/fstate->gridSpacing[X]-1) * (diff[Y]/fstate->gridSpacing[Y] * diff[Z] - 1);
	   if (tmp < 0) tmp = 0;*/
    }


    rt_worker(0, (void *)fstate);
    /*bu_parallel(rt_worker, fstate->ncpu, (void *)fstate);*/

    /* normalize fitness if we aren't just saving the source */
    if (!fstate->capture) {
	fstate->fitness = fstate->same / (fstate->volume );
	/* reset counters for future comparisons */
	fstate->diff = fstate->same = 0.0;
    }

    /* clean up resources and rtip */
    /*
      for (i = 0; i < fstate->max_cpus; i++)
      rt_clean_resource(fstate->rtip, &fstate->resource[i]);
    */
    rt_free_rti(fstate->rtip);


}
Example #7
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;
}
Example #8
0
/*
 *			M A I N
 */
int
main(int argc, char **argv)
{
    struct application	ap;

    static struct rt_i *rtip;
    char *title_file;
    char idbuf[RT_BUFSIZE] = {0};		/* First ID record info */
    char *ptr;
    int attr_count=0, i;
    char **attrs = (char **)NULL;

    if ( argc < 3 )  {
	bu_exit(1, usage);
    }

    RT_APPLICATION_INIT(&ap);

    argc--;
    argv++;
    while ( argv[0][0] == '-' ) switch ( argv[0][1] )  {
	case 'R':
	    bundle_radius = atof( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'n':
	    num_rings = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'c':
	    rays_per_ring = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'v':
	    /* count the number of attribute names provided */
	    ptr = argv[1];
	    while ( *ptr ) {
		while ( *ptr && isspace( *ptr ) )
		    ptr++;
		if ( *ptr )
		    attr_count++;
		while ( *ptr && !isspace( *ptr ) )
		    ptr++;
	    }

	    if ( attr_count == 0 ) {
		bu_log( "missing list of attribute names!\n" );
		bu_exit( 1, usage );
	    }

	    /* allocate enough for a null terminated list */
	    attrs = (char **)bu_calloc( attr_count + 1, sizeof( char *), "attrs" );

	    /* use strtok to actually grab the names */
	    i = 0;
	    ptr = strtok( argv[1], "\t " );
	    while ( ptr && i < attr_count ) {
		attrs[i] = bu_strdup( ptr );
		ptr = strtok( (char *)NULL, "\t " );
		i++;
	    }
	    argc -= 2;
	    argv += 2;
	    break;
	case 't':
	    rt_bot_tri_per_piece = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'b':
	    rt_bot_minpieces = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'o':
	    sscanf( argv[1], "%d", &set_onehit );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'r':
	{
	    float ray_len;

	    sscanf( argv[1], "%f", &ray_len );
	    set_ray_length = ray_len;
	}
	argc -= 2;
	argv += 2;
	break;
	case 'U':
	    sscanf( argv[1], "%d", &use_air );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'u':
	    sscanf( argv[1], "%x", (unsigned int *)&bu_debug );
	    fprintf(stderr, "librt bu_debug=x%x\n", bu_debug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'x':
	    sscanf( argv[1], "%x", (unsigned int *)&rt_g.debug );
	    fprintf(stderr, "librt rt_g.debug=x%x\n", rt_g.debug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'X':
	    sscanf( argv[1], "%x", (unsigned int *)&rdebug );
	    fprintf(stderr, "rdebug=x%x\n", rdebug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'N':
	    sscanf( argv[1], "%x", (unsigned int *)&rt_g.NMG_debug);
	    fprintf(stderr, "librt rt_g.NMG_debug=x%x\n", rt_g.NMG_debug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'd':
	    if ( argc < 4 )  goto err;
	    ap.a_ray.r_dir[X] = atof( argv[1] );
	    ap.a_ray.r_dir[Y] = atof( argv[2] );
	    ap.a_ray.r_dir[Z] = atof( argv[3] );
	    set_dir = 1;
	    argc -= 4;
	    argv += 4;
	    continue;

	case 'p':
	    if ( argc < 4 )  goto err;
	    ap.a_ray.r_pt[X] = atof( argv[1] );
	    ap.a_ray.r_pt[Y] = atof( argv[2] );
	    ap.a_ray.r_pt[Z] = atof( argv[3] );
	    set_pt = 1;
	    argc -= 4;
	    argv += 4;
	    continue;

	case 'a':
	    if ( argc < 4 )  goto err;
	    at_vect[X] = atof( argv[1] );
	    at_vect[Y] = atof( argv[2] );
	    at_vect[Z] = atof( argv[3] );
	    set_at = 1;
	    argc -= 4;
	    argv += 4;
	    continue;

	case 'O':
	{
	    if ( !strcmp( argv[1], "resolve" ) || !strcmp( argv[1], "0") )
		overlap_claimant_handling = 0;
	    else if ( !strcmp( argv[1], "rebuild_fastgen" ) || !strcmp( argv[1], "1") )
		overlap_claimant_handling = 1;
	    else if ( !strcmp( argv[1], "rebuild_all" ) || !strcmp( argv[1], "2") )
		overlap_claimant_handling = 2;
	    else if ( !strcmp( argv[1], "retain" ) || !strcmp( argv[1], "3") )
		overlap_claimant_handling = 3;
	    else
	    {
		bu_log( "Illegal argument (%s) to '-O' option.  Must be:\n", argv[1] );
		bu_log( "\t'resolve' or '0'\n");
		bu_log( "\t'rebuild_fastgen' or '1'\n");
		bu_log( "\t'rebuild_all' or '2'\n");
		bu_log( "\t'retain' or '3'\n");
		bu_exit(1, NULL);
	    }
	    argc -= 2;
	    argv += 2;
	}
	continue;

	default:
    err:
	    bu_exit(1, usage);
    }
    if ( argc < 2 )  {
	(void)fputs(usage, stderr);
	bu_exit(1, "rtshot: MGED database not specified\n");
    }

    if ( set_dir + set_pt + set_at != 2 )  goto err;

    if ( num_rings != 0 || rays_per_ring != 0 || bundle_radius != 0.0 ) {
	if ( num_rings <= 0 || rays_per_ring <= 0 || bundle_radius <= 0.0 ) {
	    fprintf( stderr, "Must have all of \"-R\", \"-n\", and \"-c\" set\n" );
	    goto err;
	}
    }

    /* Load database */
    title_file = argv[0];
    argv++;
    argc--;
    if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) {
	bu_exit(2, "rtshot:  rt_dirbuild failure\n");
    }

    if ( overlap_claimant_handling )
	rtip->rti_save_overlaps = 1;

    ap.a_rt_i = rtip;
    fprintf(stderr, "db title:  %s\n", idbuf);
    rtip->useair = use_air;

    /* Walk trees */
    if ( rt_gettrees_and_attrs( rtip, (const char **)attrs, argc, (const char **)argv, 1 ) ) {
	bu_exit(1, "rt_gettrees FAILED\n");
    }
    ap.attrs = attrs;

    rt_prep(rtip);

    if ( R_DEBUG&RDEBUG_RAYPLOT )  {
	if ( (plotfp = fopen("rtshot.plot", "w")) == NULL )  {
	    perror("rtshot.plot");
	    bu_exit(1, NULL);
	}
	pdv_3space( plotfp, rtip->rti_pmin, rtip->rti_pmax );
    }

    /* Compute r_dir and r_pt from the inputs */
    if ( set_at )  {
	if ( set_dir ) {
	    vect_t	diag;
	    fastf_t	viewsize;
	    VSUB2( diag, rtip->mdl_max, rtip->mdl_min );
	    viewsize = MAGNITUDE( diag );
	    VJOIN1( ap.a_ray.r_pt, at_vect,
		    -viewsize/2.0, ap.a_ray.r_dir );
	} else {
	    /* set_pt */
	    VSUB2( ap.a_ray.r_dir, at_vect, ap.a_ray.r_pt );
	}
    }
    VUNITIZE( ap.a_ray.r_dir );

    if ( rays_per_ring ) {
	bu_log( "Central Ray:\n" );
    }
    VPRINT( "Pnt", ap.a_ray.r_pt );
    VPRINT( "Dir", ap.a_ray.r_dir );

    if ( set_onehit )
	ap.a_onehit = set_onehit;
    else
	ap.a_onehit = 0;

    if ( set_ray_length > 0.0 )
	ap.a_ray_length = set_ray_length;
    else
	ap.a_ray_length = 0.0;

    /* Shoot Ray */
    ap.a_purpose = "main ray";
    ap.a_hit = hit;
    ap.a_miss = miss;

    if ( rays_per_ring ) {
	vect_t avec, bvec;
	struct xray *rp;

	/* create orthogonal rays for basis of bundle */
	bn_vec_ortho( avec, ap.a_ray.r_dir );
	VCROSS( bvec, ap.a_ray.r_dir, avec );
	VUNITIZE( bvec );

	rp = (struct xray *)bu_calloc( sizeof( struct xray ),
				       (rays_per_ring * num_rings) + 1,
				       "ray bundle" );
	rp[0] = ap.a_ray;	/* struct copy */
	rp[0].magic = RT_RAY_MAGIC;
	rt_raybundle_maker( rp, bundle_radius, avec, bvec, rays_per_ring, num_rings );
	(void)rt_shootray_bundle( &ap, rp, (rays_per_ring * num_rings) + 1 );
    } else {
	(void)rt_shootray( &ap );
    }

    return(0);
}
Example #9
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  */
Example #10
0
int main(int argc, char **argv)
{
    /*  START # 1  */
    struct application ap;	/*  Structure passed between functions.  */

    static struct rt_i *rtip;	/*  *rtip pointer to structure of  */
				/*  type rt_i  */
    char idbuf[132];	/*  first ID record info, used in  */
			/*  rt_dirbuild  */
    int index;		/*  index for rt_dirbuild & rt_gettree  */

    FILE *fp;		/*  used in opening file for second pass  */
    char spfile[16];	/*  second pass file name  */
    FILE *fp1=NULL;		/*  conductivity file  */
    char confile[16];	/*  conductivity file  */
    FILE *fp2;		/*  conductivity table file  */
    char tblfile[16];	/*  conductivity table file  */

    int i, j;		/*  integers used in loops  */
    int numreg;		/*  number of regions  */
    int nmged;		/*  number of regions in mged file  */
    double gridspace;	/*  spacing between fired rays  */
    int iwrite;		/*  0 => write to standard out, 1 => write  */
			/*  to file  */
    int typeout;		/*  Type of file to be written, 0 => PRISM file,  */
    /*  1 => generic file.  */
    FILE *fp6;		/*  Used in writing generic file.  */
    char genfile[16];	/*  Generic file name.  */
    FILE *fp3=NULL;		/*  used for writing output to file  */
    char filename[16];	/*  output file name  */

    FILE *fp5;		/*  material file  */
    char filemat[16];	/*  material file  */
    char line[150];	/*  used for reading a line from a file  */
    double k[41];	/*  thermal conductivity  */
    int itype;		/*  type of length measurement to use for  */
			/*  rk calculations  */
    double rki, rkj;	/*  used in finding rk  */
    double ki, kj;	/*  thermal conductivity of region  */
    double leni, lenj;	/*  lengths used in finding rk  */
    double areai;	/*  areas used in finding rk  */
    double a1;		/*  area used in writing conductivity table  */
    double l1, l2, l3, l4;	/*  lengths used in writing conductivity table  */
    FILE *fp4;		/*  error file  */
    char fileerr[16];	/*  error file  */

    double angle[3];	/*  Angles of rotation.  angle[0]-rotation about  */
			/*  x-axis, angle[1]-rotation about y-axis, &  */
			/*  angle[2]-rotation about z-axis.  */
    double strtpt[3];	/*  Starting point of fired ray.  */
    double strtdir[3];	/*  Starting direction of fired ray.  */
    double r[3], t[3];	/*  Used in computing rotations.  */
    double center[3];	/*  Center point of bounding rpp.  */
    double diagonal;	/*  Length of diagonal of bounding rpp.  */
    double xmin, xmax;	/*  Maximum & minimum x of grid.  */
    double ymin, ymax;	/*  Maximum & minimum y of grid.  */
    double zmin, zmax;	/*  Maximum & minimum z of grid.  */
    int nadjreg;		/*  Number of adjacent regions.  */
    int prmrel;		/*  PRISM release number, 2=>2.0, 3=>3.0.  */
    int ifire;		/*  Number of sets of rays to be fired, 0=>  */
			/*  fire from 3 orthogonal postions, 1=>fire  */
			/*  from 1 position.  */

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

    else
    {
    	/*  START # 2  */

	/*  Ask if output goes to standard out or to a file.  */
	(void)fprintf(stdout, "Write output to standard out (0) or a file(1) ");
	(void)fprintf(stdout, "not at all (2)?  ");
	(void)fflush(stdout);
	(void)scanf("%d", &iwrite);
	if ((iwrite != 0) && (iwrite != 1)) iwrite=2;
	if (iwrite == 1)
	{
	    (void)fprintf(stdout, "Enter name of output file (15 char max).  ");
	    (void)fflush(stdout);
	    (void)scanf("%15s", filename);
	    fp3 = fopen(filename, "wb");
	}

	/*  Which file that has second pass information in it?  */
	(void)fprintf(stdout, "Enter name of file that has second pass ");
	(void)fprintf(stdout, "information\nin it (15 char max).  ");
	(void)fflush(stdout);
	(void)scanf("%15s", spfile);

	/*  Ask for type of output file to be generated.  */
	(void)printf("Enter type of output file to be generated.\n");
	(void)printf("\t 0 - PRISM File\n");
	(void)printf("\t 1 - Generic File\n");
	(void)fflush(stdout);
	(void)scanf("%d", &typeout);

	/*  Read name of file to write conductivity information  */
	/*  to for use in PRISM.  */
	if (typeout == 0)
	{
	    (void)fprintf(stdout, "Enter name of file to be created for PRISM ");
	    (void)fprintf(stdout, "conductivity\ninformation (15 char max).  ");
	    (void)fflush(stdout);
	    (void)scanf("%15s", confile);

	    /*  Find which release of PRISM is being used.  The format  */
	    /*  for writing region numbers is I3 for PRISM 2.0 & I6 for  */
	    /*  PRISM 3.0.  */
	    prmrel = 2;
	    (void)printf("Which release of PRISM is being used, 2.0 (2) ");
	    (void)printf("or 3.0 (3)?  ");
	    (void)fflush(stdout);
	    (void)scanf("%d", &prmrel);
	    if (prmrel != 3) prmrel = 2;
	}

	/*  Read generic file name if necessary.  */
	if (typeout == 1)
	{
	    (void)printf("Enter name of generic file to be created (15 char ");
	    (void)printf("max).  ");
	    (void)fflush(stdout);
	    (void)scanf("%15s", genfile);
	}

	/*  Which calculated length should be used when writing to  */
	/*  this file:  1 -> average length, 2 -> rms length, 3 ->  */
	/*  minimum length, and 4 -> maximum length.  */
	(void)fprintf(stdout, "Which length calculation should be used when\n");
	(void)fprintf(stdout, "computing conduction\nbetween regions?\n");
	(void)fprintf(stdout, "\t1 - average length\n");
	(void)fprintf(stdout, "\t2 - rms length\n");
	(void)fprintf(stdout, "\t3 - minimum length\n");
	(void)fprintf(stdout, "\t4 - maximum length\n");
	(void)fflush(stdout);
	(void)scanf("%d", &itype);

	/*  Read name of file to write conductivity information to  */
	/*  in table format.  */
	(void)fprintf(stdout, "Enter name of file to be created for ");
	(void)fprintf(stdout, "conductivity\ntable (15 char max).  ");
	(void)fflush(stdout);
	(void)scanf("%15s", tblfile);

	/*  Read name of material file that contains thermal  */
	/*  conductivity information.  */
	(void)fprintf(stdout, "Enter name of material file (15 char max).  ");
	(void)fflush(stdout);
	(void)scanf("%15s", filemat);

	/*  Read name of error file.  */
	(void)fprintf(stdout, "Enter name of error file to be created ");
	(void)fprintf(stdout, "(15 char max).  ");
	(void)fflush(stdout);
	(void)scanf("%15s", fileerr);

	/*  Choose whether 3 orthogonal sets of rays are to be fired  */
	/*  or 1 set of rays is to be fired.  */
	(void)printf("Should there be 3 sets of orhogonal rays fired ");
	(void)printf("(0) or 1 set (1)?\n\t");
	(void)fflush(stdout);
	(void)scanf("%d", &ifire);
	if (ifire != 0) ifire = 1;
	if (ifire == 0)
	{
	    (void)printf("3 sets of orthogonal rays will be fired.\n");
	}
	if (ifire == 1)
	{
	    (void)printf("1 set of rays will be fired.\n");
	}
	(void)fflush(stdout);

	/*  Write out file information.  */
	if (iwrite ==1)
	{
	    (void)fprintf(fp3, "\nsecond pass file:  %s\n", spfile);
	    (void)fprintf(fp3, "material file:  %s\n", filemat);
	    if (typeout == 0)
	    {
		(void)fprintf(fp3, "conductivity file for use ");
		(void)fprintf(fp3, "with PRISM:  %s\n", confile);
		(void)fprintf(fp3, "  (format is PRISM %d.0)\n", prmrel);
	    }
	    if (typeout == 1) (void)fprintf(fp3, "generic file:  %s\n", genfile);
	    (void)fflush(fp3);
	    if (itype == 1) (void)fprintf(fp3, "\taverage length being used\n");
	    if (itype == 2) (void)fprintf(fp3, "\trms length being used\n");
	    if (itype == 3) (void)fprintf(fp3, "\tminimum length being used\n");
	    if (itype == 4) (void)fprintf(fp3, "\tmaximum length being used\n");
	    (void)fprintf(fp3, "conductivity table file:  %s\n", tblfile);
	    (void)fprintf(fp3, "error file:  %s\n\n", fileerr);
	    (void)fflush(fp3);
	}

	/*  Read thermal conductivity file.  */
	fp5 = fopen(filemat, "rb");
	for (i=0; i<41; i++)
	{
	    (void)bu_fgets(line, 151, fp5);
	    (void)sscanf(line, "%*d%*f%*f%*f%*f%lf", &k[i]);
	}

	/*  Print out the thermal conductivity.  */
	/*
	 *	for (i=0; i<41; i++)
	 *	{
	 *	   (void)fprintf(stdout, "  thermal conductivity %d = %f\n", i, k[i]);
	 *	   (void)fflush(stdout);
	 *	}
	 */

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

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

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

	/*  Find total number of regions in mged file.  */
	nmged = (int)rtip->nregions;

	(void)fprintf(stdout, "Number of regions in mged file:  %d\n", nmged);
	(void)fflush(stdout);

	if (iwrite == 1)
	{
	    (void)fprintf(fp3, "Number of regions in mged file:  %d\n", nmged);
	    (void)fflush(fp3);
	}

	/*  Number of regions known, everything can be malloced.  */
	(void)fprintf(stdout, "Mallocing arrays.\n");
	(void)fflush(stdout);

	cond = (struct table *)bu_malloc( nmged * sizeof(struct table), "cond" );
	(void)fprintf(stdout, "cond malloced\n");
	(void)fflush(stdout);
	for (i=0; i<nmged; i++)
	{
	    cond[i].shrarea = (double *)bu_malloc( nmged * sizeof(double), "cond[i].shrarea" );
	    cond[i].avglen = (double *)bu_malloc( nmged * sizeof(double), "cond[i].avglen" );
	    cond[i].rmslen = (double *)bu_malloc( nmged * sizeof(double), "cond[i].rmslen" );
	    cond[i].minlen = (double *)bu_malloc( nmged * sizeof(double), "cond[i].minlen" );
	    cond[i].maxlen = (double *)bu_malloc( nmged * sizeof(double), "cond[i].maxlen" );
	    cond[i].numcal = (double *)bu_malloc( nmged * sizeof(double), "cond[i].numcal" );
	    cond[i].rkavg = (double *)bu_malloc( nmged * sizeof(double), "cond[i].rkavg" );
	    cond[i].rkrms = (double *)bu_malloc( nmged * sizeof(double), "cond[i].rkrms" );
	    cond[i].rkmin = (double *)bu_malloc( nmged * sizeof(double), "cond[i].rkmin" );
	    cond[i].rkmax = (double *)bu_malloc( nmged * sizeof(double), "cond[i].rkmax" );
	}
	(void)fprintf(stdout, "loop malloced\n");
	(void)fflush(stdout);

	/*  All variables 'dimensioned', now zero all variables.  */
	for (i=0; i<nmged; i++)
	{
	    cond[i].centroid[0] = (double)0.;
	    cond[i].centroid[1] = (double)0.;
	    cond[i].centroid[2] = (double)0.;
	    cond[i].mat = (int)0;
	    for (j=0; j<nmged; j++)
	    {
		cond[i].shrarea[j] = (double)0.;
		cond[i].avglen[j] = (double)0.;
		cond[i].rmslen[j] = (double)0.;
		cond[i].minlen[j] = (double)0.;
		cond[i].maxlen[j] = (double)0.;
		cond[i].numcal[j] = (double)0.;
		cond[i].rkavg[j] = (double)0.;
		cond[i].rkrms[j] = (double)0.;
		cond[i].rkmin[j] = (double)0.;
		cond[i].rkmax[j] = (double)0.;
	    }
	}
	(void)fprintf(stdout, "All variables zeroed.\n");
	(void)fflush(stdout);

	/*  Now open file with second pass information in it.  */
	fp = fopen(spfile, "rb");
	(void)fprintf(stdout, "second pass file opened\n");
	(void)fflush(stdout);

	/*  Read number of regions in file.  */
	(void)fscanf(fp, "%d\n", &numreg);
	(void)fprintf(stdout, "The number of regions read was %d\n", numreg);
	(void)fflush(stdout);

	if (iwrite == 1)
	{
	    (void)fprintf(fp3, "number of regions read from second ");
	    (void)fprintf(fp3, "pass file:  %d\n", numreg);
	    (void)fflush(fp3);
	}

	/*  Read all information in file.  */
	for (i=0; i<numreg; i++)
	{
	    (void)fscanf(fp, "%*d%le%le%le%d\n", &cond[i].centroid[0],
			 &cond[i].centroid[1],
			 &cond[i].centroid[2], &cond[i].mat);
	    /*
	     *	   (void)fprintf(stdout, "reg=%8d, centroid:  %10.0f, %10.0f, %10.0f\n",
	     *		i, cond[i].centroid[0], cond[i].centroid[1], cond[i].centroid[2]);
	     *	   (void)fflush(stdout);
	     */

	    for (j=0; j<numreg; j++)
	    {
		(void)fscanf(fp, "%*d%le\n", &cond[i].shrarea[j]);
		/*
		 *		(void)fprintf(stdout, "\treg=%8d, area=%10.0f\n",
		 *		   j, cond[i].shrarea[j]);
		 *		(void)fflush(stdout);
		 */
	    }
	}

	(void)fclose(fp);

	/*  Check that the number of regions in the mged file  */
	/*  and the second pass file are equal.  */
	if (nmged != numreg)
	{
	    (void)fprintf(stdout, "ERROR -- The number of regions in the mged\n");
	    (void)fprintf(stdout, "file (%d) does not equal the number of\n",
			  nmged);
	    (void)fprintf(stdout, "regions in the second pass file (%d).\n",
			  numreg);
	    (void)fprintf(stdout, "Watch for unexplained errors.\n");
	    (void)fflush(stdout);

	    if (iwrite == 1)
	    {
		(void)fprintf(fp3, "ERROR -- The number of regions in the mged\n");
		(void)fprintf(fp3, "file (%d) does not equal the number of\n",
			      nmged);
		(void)fprintf(fp3, "regions in the second pass file (%d).\n",
			      numreg);
		(void)fprintf(fp3, "Watch for unexplained errors.\n");
		(void)fflush(fp3);
	    }
	}

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

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

	/*  Find length of diagonal.  */
	diagonal = (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]);
	diagonal = sqrt(diagonal) / 2. + .5;

	/*  Find minimum & maximum of grid.  */
	xmin = center[X] - diagonal;
	xmax = center[X] + diagonal;
	ymin = center[Y] - diagonal;
	ymax = center[Y] + diagonal;
	zmin = center[Z] - diagonal;
	zmax = center[Z] + diagonal;

	/*  Print center of bounding rpp, diagonal, & maximum  */
	/*  & minimum of grid.  */
	(void)fprintf(stdout, "Center of bounding rpp ( %f, %f, %f )\n",
		      center[X], center[Y], center[Z]);
	(void)fprintf(stdout, "Length of diagonal of bounding rpp:  %f\n",
		      diagonal);
	(void)fprintf(stdout, "Minimums & maximums of grid:\n");
	(void)fprintf(stdout, "  %f - %f\n", xmin, xmax);
	(void)fprintf(stdout, "  %f - %f\n", ymin, ymax);
	(void)fprintf(stdout, "  %f - %f\n\n", zmin, zmax);
	(void)fflush(stdout);

	/*  Write model minimum & maximum.  */
	(void)fprintf(stdout, "Model minimum & maximum.\n");
	(void)fprintf(stdout, "\tX:  %f to %f\n\tY:  %f to %f\n\tZ:  %f to %f\n\n",
		      rtip->mdl_min[X], rtip->mdl_max[X],
		      rtip->mdl_min[Y], rtip->mdl_max[Y],
		      rtip->mdl_min[Z], rtip->mdl_max[Z]);
	(void)fflush(stdout);

	if (iwrite == 1)
	{
	    (void)fprintf(fp3, "Model minimum & maximum.\n");
	    (void)fprintf(fp3, "\tX:  %f to %f\n\tY:  %f kto %f\n",
			  rtip->mdl_min[X], rtip->mdl_max[X],
			  rtip->mdl_min[Y], rtip->mdl_max[Y]);
	    (void)fprintf(fp3, "\tZ:  %f to %f\n\n",
			  rtip->mdl_min[Z], rtip->mdl_max[Z]);
	    (void)fflush(fp3);
	}

	/*  User enters grid spacing.  All units are in mm.  */
	(void)fprintf(stdout, "Enter spacing (mm) between fired rays.  ");
	(void)fflush(stdout);
	(void)scanf("%lf", &gridspace);

	(void)fprintf(stdout, "\ngrid spacing:  %f\n", gridspace);
	(void)fflush(stdout);

	if (iwrite == 1)
	{
	    (void)fprintf(fp3, "gridspacing:  %f\n\n", gridspace);
	    (void)fflush(fp3);
	}

	/*  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 = ovrlap;	/*  user supplied overlap function.  */
	ap.a_rt_i = rtip;	/*  Pointer from rt_dirbuild.  */
	ap.a_onehit = 0;	/*  Hit flag (returns all hits).  */
	ap.a_level = 0;		/*  Recursion level for diagnostics.  */
	ap.a_resource = 0;	/*  Address of resource structure (NULL).  */

	/*  Put angles for rotation into radians.  */
	angle[X] = radians((double)GAMMA);
	angle[Y] = radians((double)BETA);
	angle[Z] = radians((double)ALPHA);

	/*  Set up and shoot down the 1st axis, positive to negative  */
	/*  (x-axis).  */

	(void)fprintf(stdout, "\nShooting down 1st axis.\n");
	(void)fflush(stdout);

	strtpt[X] = xmax;
	strtpt[Y] = ymin + gridspace / 2.;
	strtpt[Z] = zmin + gridspace / 2.;
	strtdir[X] = (-1);
	strtdir[Y] = 0;
	strtdir[Z] = 0;

	/*  Rotate starting point.  (new pt = C + R[P -C])  */
	t[X] = strtpt[X] - center[X];
	t[Y] = strtpt[Y] - center[Y];
	t[Z] = strtpt[Z] - center[Z];

	(void)rotate(t, angle, r);

	ap.a_ray.r_pt[X] = center[X] + r[X];
	ap.a_ray.r_pt[Y] = center[Y] + r[Y];
	ap.a_ray.r_pt[Z] = center[Z] + r[Z];

	/*  Rotate firing direction.  (new dir = R[D])  */
	(void)rotate(strtdir, angle, r);
	ap.a_ray.r_dir[X] = r[X];
	ap.a_ray.r_dir[Y] = r[Y];
	ap.a_ray.r_dir[Z] = r[Z];

	while (strtpt[Z] <= zmax)
	{
	    /*  START # 3  */

	    iprev = (-1);	/*  No previous shots.  */

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

	    strtpt[Y] += gridspace;
	    if (strtpt[Y] > ymax)
	    {
		strtpt[Y] = ymin + gridspace / 2.;
		strtpt[Z] += gridspace;
	    }

	    t[X] = strtpt[X] - center[X];
	    t[Y] = strtpt[Y] - center[Y];
	    t[Z] = strtpt[Z] - center[Z];

	    (void)rotate(t, angle, r);

	    ap.a_ray.r_pt[X] = center[X] + r[X];
	    ap.a_ray.r_pt[Y] = center[Y] + r[Y];
	    ap.a_ray.r_pt[Z] = center[Z] + r[Z];

	}	/*  END # 3  */

	/*  Shoot down 2nd & 3rd axes if necessary.  */
	if (ifire == 0)
	{
	    /*  START # 1000  */
	    /*  Set up & shoot down the 2nd axis (y-axis).  */
	    (void)printf("\nShooting down the 2nd axis.\n");
	    (void)fflush(stdout);

	    strtpt[X] = xmin + gridspace / 2.;
	    strtpt[Y] = ymax;
	    strtpt[Z] = zmin + gridspace / 2.;
	    strtdir[X] = 0.;
	    strtdir[Y] = (-1.);
	    strtdir[X] = 0.;

	    /*  Rotate starting point (new pt = C + R[P - C]).  */
	    t[X] = strtpt[X] - center [X];
	    t[Y] = strtpt[Y] - center [Y];
	    t[Z] = strtpt[Z] - center [Z];

	    (void)rotate(t, angle, r);

	    ap.a_ray.r_pt[X] = center[X] + r[X];
	    ap.a_ray.r_pt[Y] = center[Y] + r[Y];
	    ap.a_ray.r_pt[Z] = center[Z] + r[Z];

	    /*  Rotate firing direction (new dir = R[D])  */
	    (void)rotate(strtdir, angle, r);

	    ap.a_ray.r_dir[X] = r[X];
	    ap.a_ray.r_dir[Y] = r[Y];
	    ap.a_ray.r_dir[Z] = r[Z];

	    while (strtpt[Z] <= zmax)
	    {
		/*  START # 1010  */
		iprev = (-1);		/*  No previous shots.  */

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

		strtpt[X] += gridspace;
		if (strtpt[X] > xmax)
		{
		    strtpt[X] = xmin + gridspace / 2.;
		    strtpt[Z] += gridspace;
		}

		t[X] = strtpt[X] - center[X];
		t[Y] = strtpt[Y] - center[Y];
		t[Z] = strtpt[Z] - center[Z];

		(void)rotate(t, angle, r);

		ap.a_ray.r_pt[X] = center[X] + r[X];
		ap.a_ray.r_pt[Y] = center[Y] + r[Y];
		ap.a_ray.r_pt[Z] = center[Z] + r[Z];
	    }						/*  END # 1010  */

	    /*  Set up & shoot down the 3rd axis (z-axis).  */
	    (void)printf("\nShooting down the 3rd axis.\n");
	    (void)fflush(stdout);

	    strtpt[X] = xmin + gridspace / 2.;
	    strtpt[Y] = ymin + gridspace / 2.;
	    strtpt[Z] = zmax;
	    strtdir[X] = 0.;
	    strtdir[Y] = 0.;
	    strtdir[Z] = (-1.);

	    /*  Rotate starting points (new pt = C + R[P - C]).  */
	    t[X] = strtpt[X] - center[X];
	    t[Y] = strtpt[Y] - center[Y];
	    t[Z] = strtpt[Z] - center[Z];

	    (void)rotate(t, angle, r);

	    ap.a_ray.r_pt[X] = r[X];
	    ap.a_ray.r_pt[Y] = r[Y];
	    ap.a_ray.r_pt[Z] = r[Z];

	    while (strtpt[Y] <= ymax)
	    {
		/*  START # 1020  */
		iprev = (-1);		/*  No previous shots.  */

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

		strtpt[X] += gridspace;
		if (strtpt[X] > xmax)
		{
		    strtpt[X] = xmin + gridspace / 2.;
		    strtpt[Y] += gridspace;
		}

		t[X] = strtpt[X] - center[X];
		t[Y] = strtpt[Y] - center[Y];
		t[Z] = strtpt[Z] - center[Z];

		(void)rotate(t, angle, r);

		ap.a_ray.r_pt[X] = center[X] + r[X];
		ap.a_ray.r_pt[Y] = center[Y] + r[Y];
		ap.a_ray.r_pt[Z] = center[Z] + r[Z];
	    }						/*  END # 1020  */
	}						/*  END # 1000  */

	/*  Calculate final length between centroid & shared surface area.  */
	if (iwrite == 0)
	{
	    (void)fprintf(stdout, "\n\nFinal numbers.\n");
	    (void)fflush(stdout);
	}

	for (i=0; i<numreg; i++)
	{

	    if (iwrite == 0)
	    {
		(void)fprintf(stdout, "reg#=%d, matid=%d\n", (i+1), cond[i].mat);
		(void)fflush(stdout);
	    }

	    if (iwrite == 1)
	    {
		(void)fprintf(fp3, "reg#=%d, matid=%d\n", (i+1), cond[i].mat);
		(void)fflush(fp3);
	    }

	    for (j=0; j<numreg; j++)
	    {
		if (cond[i].numcal[j] > ZEROTOL)
		{
		    cond[i].avglen[j] /= cond[i].numcal[j];
		    cond[i].rmslen[j] /= cond[i].numcal[j];
		    cond[i].rmslen[j] = sqrt(cond[i].rmslen[j]);

		    if (iwrite == 0)
		    {
			(void)fprintf(stdout, "\tadjreg=%d, numcal=%f, shrarea=%f, ",
				      (j+1), cond[i].numcal[j], cond[i].shrarea[j]);
			(void)fprintf(stdout, "avglen=%f\n", cond[i].avglen[j]);
			(void)fprintf(stdout, "\t\trmslen=%f, ", cond[i].rmslen[j]);
			(void)fprintf(stdout, "minlen=%f, maxlen=%f\n",
				      cond[i].minlen[j], cond[i].maxlen[j]);
			(void)fflush(stdout);
		    }

		    if (iwrite == 1)
		    {
			(void)fprintf(fp3, "\tadjreg=%d, numcal=%f, shrarea=%f, ",
				      (j+1), cond[i].numcal[j], cond[i].shrarea[j]);
			(void)fprintf(fp3, "avglen=%f\n", cond[i].avglen[j]);
			(void)fprintf(fp3, "\t\trmslen=%f, ", cond[i].rmslen[j]);
			(void)fprintf(fp3, "minlen=%f, maxlen=%f\n",
				      cond[i].minlen[j], cond[i].maxlen[j]);
			(void)fflush(fp3);
		    }

		}
		else
		{
		    cond[i].avglen[j] = 0.;
		    cond[i].rmslen[j] = 0.;
		}
	    }
	}

	if (iwrite == 1)
	{
	    /*  Print summary of all files used.  */
	    (void)fprintf(fp3, "\n\nSUMMARY OF FILES USED & CREATED\n");
	    (void)fprintf(fp3, "\t.g file used:  %s\n", argv[1]);
	    (void)fprintf(fp3, "\tregions used:\n");
	    (void)fflush(fp3);
	    i=2;
	    while (argv[i] != NULL)
	    {
		(void)fprintf(fp3, "\t\t%s\n", argv[i]);
		(void)fflush(fp3);
		i++;
	    }
	    (void)fprintf(fp3, "\tfile containing second pass information:  %s\n",
			  spfile);
	    (void)fprintf(fp3, "\tmaterial file used:  %s\n", filemat);
	    (void)fprintf(fp3, "\toutput file created:  %s\n", filename);
	    if (typeout == 0)
	    {
		(void)fprintf(fp3, "\tconductivity file created:  %s\n", confile);
		(void)fprintf(fp3, "\t  (format is PRISM %d.0)\n", prmrel);
	    }
	    if (typeout == 1) (void)fprintf(fp3, "\tgeneric file created:  %s\n"
					    , genfile);
	    (void)fprintf(fp3, "\tconductivity table file created:  %s\n",
			  tblfile);
	    (void)fprintf(fp3, "\terror file created:  %s\n\n\n", fileerr);
	    (void)fflush(fp3);

	    (void)fclose(fp3);
	}

	/*------------------------------------------------------------------*/

	/*  Open conductivity file to be used with PRISM if needed.  */
	if (typeout == 0)
	{
	    fp1=fopen(confile, "wb");
	    (void)fprintf(fp1, "Conductivity file for use with PRISM.\n");
	    (void)fflush(fp1);
	}

	/*  Make calculations & write to conductivity file.  */
	for (i=0; i<numreg; i++)
	{
	    /*  START # 6  */

	    /*  Make conductivity file triangular.  This program still  */
	    /*  computes the ENTIRE matrix.  */

	    for (j=(i+1); j<numreg; j++)
	    {
	    	/*  START # 7  */

		if ( (cond[i].avglen[j] != 0) )
		{
		    /*  START # 8  */
		    /*  Find correct thermal conductivity.  */
		    /*  If ki or kj = 0 => rk = 0.  */
		    ki = k[cond[i].mat];
		    kj = k[cond[j].mat];

		    /*  All calculations will be in meters &  */
		    /*  square meters.  */

		    areai = cond[i].shrarea[j] * 1.e-6;

		    /*  average length  */
		    leni = cond[i].avglen[j] * 1.e-3;
		    lenj = cond[j].avglen[i] * 1.e-3;
		    if (((-ZEROTOL < ki) && (ki < ZEROTOL)) ||
			((-ZEROTOL < kj) && (kj < ZEROTOL)))
			cond[i].rkavg[j] = 0.;
		    else
		    {
			rki = leni / (ki * areai);
			rkj = lenj / (kj * areai);
			cond[i].rkavg[j] = 1. / (rki + rkj);
		    }

		    /*  rms length  */
		    leni = cond[i].rmslen[j] * 1.e-3;
		    lenj = cond[j].rmslen[i] * 1.e-3;
		    if (((-ZEROTOL < ki) && (ki < ZEROTOL)) ||
			((-ZEROTOL < kj) && (kj < ZEROTOL)))
			cond[i].rkrms[j] = 0.;
		    else
		    {
			rki = leni / (ki * areai);
			rkj = lenj / (kj * areai);
			cond[i].rkrms[j] = 1. / (rki + rkj);
		    }

		    /*  minimum length  */
		    leni = cond[i].minlen[j] * 1.e-3;
		    lenj = cond[j].minlen[i] * 1.e-3;
		    if (((-ZEROTOL < ki) && (ki < ZEROTOL)) ||
			((-ZEROTOL < kj) && (kj < ZEROTOL)))
			cond[i].rkmin[j] = 0.;
		    else
		    {
			rki = leni / (ki * areai);
			rkj = lenj / (kj * areai);
			cond[i].rkmin[j] = 1. / (rki + rkj);
		    }

		    /*  maximum length  */
		    leni = cond[i].maxlen[j] * 1.e-3;
		    lenj = cond[j].maxlen[i] * 1.e-3;
		    if (((-ZEROTOL < ki) && (ki < ZEROTOL)) ||
			((-ZEROTOL < kj) && (kj < ZEROTOL)))
			cond[i].rkmax[j] = 0.;
		    else
		    {
			rki = leni / (ki * areai);
			rkj = lenj / (kj * areai);
			cond[i].rkmax[j] = 1. / (rki + rkj);
		    }

		    /*  Print if had adjacent regions, conductivity  */
		    /*  may be zero.  */

		    /*  Print only if PRISM file is to be created.  */
		    if (typeout == 0) {
			/*  START # 8A  */
			if ( (itype == 1) && (cond[i].shrarea[j] > ZEROTOL) )
			{
			    if (prmrel == 2)
				(void)fprintf(fp1, "%3d %3d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkavg[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			    if (prmrel == 3)
				(void)fprintf(fp1, "%6d %6d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkavg[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			}

			if ( (itype == 2) && (cond[i].shrarea[j] > ZEROTOL) )
			{
			    if (prmrel == 2)
				(void)fprintf(fp1, "%3d %3d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkrms[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			    if (prmrel == 3)
				(void)fprintf(fp1, "%6d %6d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkrms[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			}

			if ( (itype == 3) && (cond[i].shrarea[j] > ZEROTOL) )
			{
			    if (prmrel == 2)
				(void)fprintf(fp1, "%3d %3d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkmin[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			    if (prmrel == 3)
				(void)fprintf(fp1, "%6d %6d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkmin[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			}

			if ( (itype == 4) && (cond[i].shrarea[j] > ZEROTOL) )
			{
			    if (prmrel == 2)
				(void)fprintf(fp1, "%3d %3d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkmax[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			    if (prmrel == 3)
				(void)fprintf(fp1, "%6d %6d %7.3f %.3e\n",
					      (j+1), (i+1), cond[i].rkmax[j],
					      (cond[i].shrarea[j] * 1.0e-6));
			}

			(void)fflush(fp1);
		    }				/*  END of # 8A  */
		}	/*  END # 8  */
	    }	/*  END # 7  */
	}	/*  END # 6  */

	if (typeout == 0) (void)fclose(fp1);

	/*------------------------------------------------------------------*/

	/*  Open and write to generic file if necessary. */
	/*  The format follows.  */
	/*  4  region number  number of adjacent regions  */
	/*     adjacent region  shared area  conduction distance  */

	if (typeout == 1)
	{
	    /*  Open file.  */
	    fp6 = fopen(genfile, "wb");
	    (void)printf("Opened generic file.\n");
	    (void)fflush(stdout);

	    for (i=0; i<numreg; i++)
	    {
		/*  Find number of adjacent regions.  */
		/*
		 *		(void)printf("Ready to find number of adjacent areas.\n");
		 *		(void)fflush(stdout);
		 */
		nadjreg = 0;
		/*
		 *		(void)printf("nadjreg = %d\n", nadjreg);
		 *		(void)fflush(stdout);
		 */
		for (j=0; j<numreg; j++)
		{
		    /*
		     *		   (void)printf("%d, %d, %f\n", i, j, cond[i].shrarea[j]);
		     *		   (void)fflush(stdout);
		     */
		    if (cond[i].shrarea[j] > ZEROTOL) nadjreg += 1;
		}
		/*
		 *		(void)printf("Found number of adjacent areas.\n");
		 *		(void)fflush(stdout);
		 */

		(void)fprintf(fp6, "4  %5d  %5d\n", (i+1), nadjreg);
		(void)fflush(fp6);

		for (j=0; j<numreg; j++)
		{
		    if (cond[i].shrarea[j] > ZEROTOL)
		    {
			(void)fprintf(fp6, "   %5d  %.3e  ", (j+1),
				      (cond[i].shrarea[j] * 1.e-6));
			if (itype == 1) (void)fprintf(fp6, "%.3e\n",
						      (cond[i].avglen[j] * 1.e-3));
			if (itype == 2) (void)fprintf(fp6, "%.3e\n",
						      (cond[i].rmslen[j] * 1.e-3));
			if (itype == 3) (void)fprintf(fp6, "%.3e\n",
						      (cond[i].minlen[j] * 1.e-3));
			if (itype == 4) (void)fprintf(fp6, "%.3e\n",
						      (cond[i].maxlen[j] * 1.e-3));
		    }
		    (void)fflush(fp6);
		}
	    }
	    (void)fclose(fp6);
	}

	/*------------------------------------------------------------------*/

	/*  Open conductivity table file and write information to  */
	/*  it.  All units will be in meters or square meters.  */
	fp2=fopen(tblfile, "wb");
	(void)fprintf(fp2, "Conductivity table.  Units are in meters or ");
	(void)fprintf(fp2, "square meters.\n");

	(void)fprintf(fp2, " reg, mat, adj,   shrarea,");
	(void)fprintf(fp2, "    avglen,     rkavg,");
	(void)fprintf(fp2, "    rmslen,     rkrms,");
	(void)fprintf(fp2, "    minlen,     rkmin,");
	(void)fprintf(fp2, "    maxlen,     rkmax\n");

	(void)fflush(fp2);

	for (i=0; i<numreg; i++)
	{
	    /*  START # 9  */
	    for (j=0; j<numreg; j++)
	    {
	    	/*  START # 10  */
		if (cond[i].shrarea[j] != 0)
		{
		    /*  START # 11  */
		    a1 = cond[i].shrarea[j] * 1.e-6;
		    l1 = cond[i].avglen[j] * 1.e-3;
		    l2 = cond[i].rmslen[j] * 1.e-3;
		    l3 = cond[i].minlen[j] * 1.e-3;
		    l4 = cond[i].maxlen[j] * 1.e-3;

		    (void)fprintf(fp2, "%4d,%4d,%4d, %.3e,",
				  (i+1), cond[i].mat, (j+1), a1);
		    if (j > i)
		    {
			(void)fprintf(fp2, " %.3e, %.3e,", l1, cond[i].rkavg[j]);
			(void)fprintf(fp2, " %.3e, %.3e,", l2, cond[i].rkrms[j]);
			(void)fprintf(fp2, " %.3e, %.3e,", l3, cond[i].rkmin[j]);
			(void)fprintf(fp2, " %.3e, %.3e\n", l4, cond[i].rkmax[j]);
		    }
		    else
		    {
			(void)fprintf(fp2, " %.3e, %.3e,", l1, cond[j].rkavg[i]);
			(void)fprintf(fp2, " %.3e, %.3e,", l2, cond[j].rkrms[i]);
			(void)fprintf(fp2, " %.3e, %.3e,", l3, cond[j].rkmin[i]);
			(void)fprintf(fp2, " %.3e, %.3e\n", l4, cond[j].rkmax[i]);
		    }

		    (void)fflush(fp2);
		}	/*  END # 11  */
	    }	/*  END # 10  */
	}	/*  END # 9  */

	(void)fclose(fp2);

	/*------------------------------------------------------------------*/

	/*  Print summary of all files used.  */
	(void)fprintf(stdout, "\n\nSUMMARY OF FILES USED & CREATED\n");
	(void)fprintf(stdout, "\t.g file used:  %s\n", argv[1]);
	(void)fprintf(stdout, "\tregions used:\n");
	(void)fflush(stdout);
	i=2;
	while (argv[i] != NULL)
	{
	    (void)fprintf(stdout, "\t\t%s\n", argv[i]);
	    (void)fflush(stdout);
	    i++;
	}
	(void)fprintf(stdout, "\tfile containing second pass information:  %s\n",
		      spfile);
	(void)fprintf(stdout, "\tmaterial file used:  %s\n", filemat);
	if (iwrite == 1)
	{
	    (void)fprintf(stdout, "\toutput file created:  %s\n", filename);
	}
	if (typeout == 0)
	{
	    (void)fprintf(stdout, "\tconductivity file created:  %s\n", confile);
	    (void)fprintf(stdout, "\t  (format is PRISM %d.0)\n", prmrel);
	}
	if (typeout == 1) (void)printf("\tgeneric file created:  %s\n", genfile);
	(void)fprintf(stdout, "\tconductivity table file created:  %s\n", tblfile);
	(void)fprintf(stdout, "\terror file created:  %s\n\n\n", fileerr);
	(void)fflush(stdout);

	/*------------------------------------------------------------------*/

	/*  Open error file.  */
	fp4 = fopen(fileerr, "wb");

	/*  Write errors to error file.  */
	(void)fprintf(fp4, "\nERRORS from secpass\n\n");
	/*  Write type of file created to error file.  */
	if (typeout == 0)
	{
	    (void)fprintf(fp4, "PRISM %d.0 conductivity file, %s, created.\n\n",
			  prmrel, confile);
	}
	if (typeout == 1) (void)fprintf(fp4, "Generic file, %s, created.\n\n",
					genfile);
	(void)fflush(fp4);
	for (i=0; i<numreg; i++)
	{
	    for (j=0; j<numreg;  j++)
	    {
		if ( (cond[i].numcal[j] > ZEROTOL) &&
		     ( cond[i].numcal[j] < MINCAL ) )
		{
		    (void)fprintf(fp4, "region %d, adjacent region %d:\n",
				  (i+1), (j+1));
		    (void)fprintf(fp4, "\tnumber of length calculations ");
		    (void)fprintf(fp4, "below minimum of %d\n", MINCAL);
		    (void)fflush(fp4);
		}
	    }
	}
	(void)fclose(fp4);

	/*------------------------------------------------------------------*/

	/*  Everything completed, free memory.  */
	(void)fprintf(stdout, "Freeing memory.\n");
	(void)fflush(stdout);
	for (i=0; i<nmged; i++)
	{
	    bu_free(cond[i].shrarea, "cond[i].shrarea");
	    bu_free(cond[i].avglen, "cond[i].avglen");
	    bu_free(cond[i].rmslen, "cond[i].rmslen");
	    bu_free(cond[i].minlen, "cond[i].minlen");
	    bu_free(cond[i].maxlen, "cond[i].maxlen");
	    bu_free(cond[i].numcal, "cond[i].numcal");
	    bu_free(cond[i].rkavg, "cond[i].rkavg");
	    bu_free(cond[i].rkrms, "cond[i].rkrms");
	    bu_free(cond[i].rkmin, "cond[i].rkmin");
	    bu_free(cond[i].rkmax, "cond[i].rkmax");
	}
	bu_free(cond, "cond");

    }	/*  END # 2  */
    return(0);
}	/*  END # 1  */