Esempio n. 1
0
/*
 *			M A I N
 */
int
main(int argc, char **argv) {

static struct rt_i *rtip;
fastf_t sizeVoxel[3], threshold;
int levelOfDetail;
genptr_t callBackData;

char title[1024] = {0};

    /* Check for command-line arguments.  Make sure we have at least a
     * geometry file and one geometry object on the command line.
     */
    if (argc < 3) {
	bu_exit(1, "Usage: %s model.g objects...\n", argv[0]);
    }


    /* Load the specified geometry database (i.e., a ".g" file).
     * rt_dirbuild() returns an "instance" pointer which describes the
     * database to be raytraced.  It also gives you back the title
     * string if you provide a buffer.  This builds a directory of the
     * geometry (i.e., a table of contents) in the file.
     */
    rtip = rt_dirbuild(argv[1], title, sizeof(title));
    if (rtip == RTI_NULL) {
	bu_exit(2, "Building the database directory for [%s] FAILED\n", argv[1]);
    }


    /* Walk the geometry trees.  Here you identify any objects in the
     * database that you want included in the ray trace by iterating
     * of the object names that were specified on the command-line.
     */
    while (argc > 2) {
	if (rt_gettree(rtip, argv[2]) < 0)
	    bu_log("Loading the geometry for [%s] FAILED\n", argv[2]);
	argc--;
	argv++;
    }


    /* user parameters are being given values directly here*/
    sizeVoxel[0] = 1.0;
    sizeVoxel[1] = 1.0;
    sizeVoxel[2] = 1.0;

    threshold = 0.5;
    levelOfDetail = 4;

    callBackData = (void *)(& threshold);

    /* voxelize function is called here with rtip(ray trace instance), userParameters and printToFile/printToScreen options */
    voxelize(rtip, sizeVoxel, levelOfDetail, printToFile, callBackData);

    rt_free_rti(rtip);

    return 0;
}
Esempio n. 2
0
/**
 * Add another top-level tree to the in-core geometry.
 */
void
BU_FORTRAN(frtree, FRTREE)(int *fail,
			   struct rt_i **rtip,
			   char *objname,
			   int *objlen)
{
    char *obj;

    RT_CHECK_RTI(*rtip);

    obj = fr_string_f2c(objname, *objlen);
    *fail = rt_gettree(*rtip, obj);
}
Esempio n. 3
0
BrlCadInterface::BrlCadInterface(QString file_name, QString object_name)
{
  m_Rtip = rt_dirbuild(qPrintable(file_name), m_IdBuf, sizeof(m_IdBuf));
  if (m_Rtip == RTI_NULL) {
    EG_ERR_RETURN("Unable to open BRL-CAD database!");
  }
  if (rt_gettree(m_Rtip, qPrintable(object_name)) < 0) {
    EG_ERR_RETURN("unable to access selected object");
  }
  rt_prep_parallel(m_Rtip, 1);
  application ap = {0};
  m_Ap = ap;
  m_Ap.a_rt_i   = m_Rtip;

  setName("BRL-CAD interface");
  m_ShootRayImplemented = true;

  //m_Ap.a_onehit = 1;
}
Esempio n. 4
0
/**
 * START HERE
 *
 * This is where it all begins.
 */
int
main(int argc, char **argv)
{
    /* Every application needs one of these.  The "application"
     * structure carries information about how the ray-casting should
     * be performed.  Defined in the raytrace.h header.
     */
    struct application	ap;

    /* The "raytrace instance" structure contains definitions for
     * librt which are specific to the particular model being
     * processed.  One copy exists for each model.  Defined in
     * the raytrace.h header and is returned by rt_dirbuild().
     */
    static struct rt_i *rtip;

    /* optional parameter to rt_dirbuild() what can be used to capture
     * a title if the geometry database has one set.
     */
    char title[1024] = {0};

    /* Check for command-line arguments.  Make sure we have at least a
     * geometry file and one geometry object on the command line.
     */
    if (argc < 3) {
	bu_exit(1, "Usage: %s model.g objects...\n", argv[0]);
    }

    /* Load the specified geometry database (i.e., a ".g" file).
     * rt_dirbuild() returns an "instance" pointer which describes the
     * database to be raytraced.  It also gives you back the title
     * string if you provide a buffer.  This builds a directory of the
     * geometry (i.e., a table of contents) in the file.
     */
    rtip = rt_dirbuild(argv[1], title, sizeof(title));
    if (rtip == RTI_NULL) {
	bu_exit(2, "Building the database directory for [%s] FAILED\n", argv[1]);
    }

    /* Display the geometry database title obtained during
     * rt_dirbuild if a title is set.
     */
    if (title[0]) {
	bu_log("Title:\n%s\n", title);
    }

    /* Walk the geometry trees.  Here you identify any objects in the
     * database that you want included in the ray trace by iterating
     * of the object names that were specified on the command-line.
     */
    while (argc > 2)  {
	if (rt_gettree(rtip, argv[2]) < 0)
	    bu_log("Loading the geometry for [%s] FAILED\n", argv[2]);
	argc--;
	argv++;
    }

    /* This next call gets the database ready for ray tracing.  This
     * causes some values to be precomputed, sets up space
     * partitioning, computes boudning volumes, etc.
     */
    rt_prep_parallel(rtip, 1);

    /* initialize all values in application structure to zero */
    RT_APPLICATION_INIT(&ap);

    /* your application uses the raytrace instance containing the
     * geometry we loaded.  this describes what we're shooting at.
     */
    ap.a_rt_i = rtip;

    /* stop at the first point of intersection or shoot all the way
     * through (defaults to 0 to shoot all the way through).
     */
    ap.a_onehit = 0;

    /* Set the ray start point and direction rt_shootray() uses these
     * two to determine what ray to fire.  In this case we simply
     * shoot down the z axis toward the origin from 10 meters away.
     *
     * It's worth nothing that librt assumes units of millimeters.
     * All geometry is stored as millimeters regardless of the units
     * set during editing.  There are libbu routines for performing
     * unit conversions if desired.
     */
    VSET(ap.a_ray.r_pt, 0.0, 0.0, 10000.0);
    VSET(ap.a_ray.r_dir, 0.0, 0.0, -1.0);

    /* Simple debug printing */
    VPRINT("Pnt", ap.a_ray.r_pt);
    VPRINT("Dir", ap.a_ray.r_dir);

    /* This is what callback to perform on a hit. */
    ap.a_hit = hit;

    /* This is what callback to perform on a miss. */
    ap.a_miss = miss;

    /* Shoot the ray. */
    (void)rt_shootray(&ap);

    /* A real application would probably set up another ray and fire
     * again or do something a lot more complex in the callbacks.
     */

    return 0;
}
Esempio n. 5
0
/*
 *			F _ H I D E L I N E
 */
int
f_hideline(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{
    FILE 	*plotfp;
    char 	visible;
    int 	i, numobjs;
    char 	*objname[MAXOBJECTS], title[1];
    fastf_t 	len, u, step;
    float 	ratio;
    vect_t	last_move;
    struct rt_i	*rtip;
    struct resource resource;
    struct application a;
    vect_t temp;
    vect_t last, dir;
    register struct bn_vlist	*vp;

    CHECK_DBI_NULL;

    if (argc < 2 || 4 < argc) {
	struct bu_vls vls;

	bu_vls_init(&vls);
	bu_vls_printf(&vls, "help H");
	Tcl_Eval(interp, bu_vls_addr(&vls));
	bu_vls_free(&vls);
	return TCL_ERROR;
    }

    if ((plotfp = fopen(argv[1], "w")) == NULL) {
	Tcl_AppendResult(interp, "f_hideline: unable to open \"", argv[1],
			 "\" for writing.\n", (char *)NULL);
	return TCL_ERROR;
    }
    pl_space(plotfp, (int)GED_MIN, (int)GED_MIN, (int)GED_MAX, (int)GED_MAX);

    /*  Build list of objects being viewed */
    numobjs = 0;
    FOR_ALL_SOLIDS(sp) {
	for (i = 0; i < numobjs; i++)  {
	    if ( objname[i] == FIRST_SOLID(sp)->d_namep )
		break;
	}
	if (i == numobjs)
	    objname[numobjs++] = FIRST_SOLID(sp)->d_namep;
    }

    Tcl_AppendResult(interp, "Generating hidden-line drawing of the following regions:\n",
		     (char *)NULL);
    for (i = 0; i < numobjs; i++)
	Tcl_AppendResult(interp, "\t", objname[i], "\n", (char *)NULL);

    /* Initialization for librt */
    if ((rtip = rt_dirbuild(dbip->dbi_filename, title, 0)) == RTI_NULL) {
	Tcl_AppendResult(interp, "f_hideline: unable to open model file \"",
			 dbip->dbi_filename, "\"\n", (char *)NULL);
	return TCL_ERROR;
    }
    a.a_hit = hit_headon;
    a.a_miss = hit_tangent;
    a.a_overlap = hit_overlap;
    a.a_rt_i = rtip;
    a.a_resource = &resource;
    a.a_level = 0;
    a.a_onehit = 1;
    a.a_diverge = 0;
    a.a_rbeam = 0;

    if (argc > 2) {
	sscanf(argv[2], "%f", &step);
	step = view_state->vs_Viewscale/step;
	sscanf(argv[3], "%f", &epsilon);
	epsilon *= view_state->vs_Viewscale/100;
    } else {
	step = view_state->vs_Viewscale/256;
	epsilon = 0.1*view_state->vs_Viewscale;
    }

    for (i = 0; i < numobjs; i++)
	if (rt_gettree(rtip, objname[i]) == -1)
	    Tcl_AppendResult(interp, "f_hideline: rt_gettree failed on \"",
			     objname[i], "\"\n", (char *)NULL);

    /* Crawl along the vectors raytracing as we go */
    VSET(temp, 0.0, 0.0, -1.0);				/* looking at model */
    MAT4X3VEC(a.a_ray.r_dir, view_state->vs_view2model, temp);
    VUNITIZE(a.a_ray.r_dir);

    FOR_ALL_SOLIDS(sp) {

	ratio = sp->s_size / VIEWSIZE;		/* ignore if small or big */
	if (ratio >= dmp->dmr_bound || ratio < 0.001)
	    continue;

	Tcl_AppendResult(interp, "Primitive\n", (char *)NULL);
	for ( BU_LIST_FOR( vp, bn_vlist, &(sp->s_vlist) ) )  {
	    register int	i;
	    register int	nused = vp->nused;
	    register int	*cmd = vp->cmd;
	    register point_t *pt = vp->pt;
	    for ( i = 0; i < nused; i++, cmd++, pt++ )  {
		Tcl_AppendResult(interp, "\tVector\n", (char *)NULL);
		switch ( *cmd )  {
		    case BN_VLIST_POLY_START:
		    case BN_VLIST_POLY_VERTNORM:
			break;
		    case BN_VLIST_POLY_MOVE:
		    case BN_VLIST_LINE_MOVE:
			/* move */
			VMOVE(last, *pt);
			MOVE(last);
			break;
		    case BN_VLIST_POLY_DRAW:
		    case BN_VLIST_POLY_END:
		    case BN_VLIST_LINE_DRAW:
			/* setup direction && length */
			VSUB2(dir, *pt, last);
			len = MAGNITUDE(dir);
			VUNITIZE(dir);
			visible = FALSE;
			{
			    struct bu_vls tmp_vls;

			    bu_vls_init(&tmp_vls);
			    bu_vls_printf(&tmp_vls, "\t\tDraw 0 -> %g, step %g\n", len, step);
			    Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
			    bu_vls_free(&tmp_vls);
			}
			for (u = 0; u <= len; u += step) {
			    VJOIN1(aim_point, last, u, dir);
			    MAT4X3PNT(temp, view_state->vs_model2view, aim_point);
			    temp[Z] = 100;			/* parallel project */
			    MAT4X3PNT(a.a_ray.r_pt, view_state->vs_view2model, temp);
			    if (rt_shootray(&a)) {
				if (!visible) {
				    visible = TRUE;
				    MOVE(aim_point);
				}
			    } else {
				if (visible) {
				    visible = FALSE;
				    DRAW(aim_point);
				}
			    }
			}
			if (visible)
			    DRAW(aim_point);
			VMOVE(last, *pt); /* new last vertex */
		}
	    }
	}
    }
    fclose(plotfp);
    return TCL_OK;
}
Esempio n. 6
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 */
}
Esempio n. 7
0
int
ged_voxelize(struct ged *gedp, int argc, const char *argv[])
{
    struct rt_i *rtip;
    static const char *usage = "[-s \"dx dy dz\"] [-d n] [-t f] new_obj old_obj [old_obj2 old_obj3 ...]";
    fastf_t sizeVoxel[3];
    int levelOfDetail;
    genptr_t callBackData;
    struct voxelizeData voxDat;
    int c;

    /* intentionally double for scan */
    double threshold;

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

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

    /* incorrect arguments */
    if (argc < 3) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    sizeVoxel[0]  = 1.0;
    sizeVoxel[1]  = 1.0;
    sizeVoxel[2]  = 1.0;
    levelOfDetail = 1;
    threshold = 0.5;

    bu_optind = 1;
    while ((c = bu_getopt(argc, (char * const *)argv, (const char *)"s:d:t:")) != -1) {
	double scan[3];

	switch (c) {
	    case 's':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scan[0],
			   &scan[1],
			   &scan[2]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		} else {
		    /* convert from double to fastf_t */
		    VMOVE(sizeVoxel, scan);

		    sizeVoxel[0] = sizeVoxel[0] * gedp->ged_wdbp->dbip->dbi_local2base;
		    sizeVoxel[1] = sizeVoxel[1] * gedp->ged_wdbp->dbip->dbi_local2base;
		    sizeVoxel[2] = sizeVoxel[2] * gedp->ged_wdbp->dbip->dbi_local2base;
		}
		break;

	    case 'd':
		if (sscanf(bu_optarg, "%d", &levelOfDetail) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;

	    case 't':
		if(sscanf(bu_optarg, "%lf", &threshold) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;

	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
	}
    }

    argc -= bu_optind;
    argv += bu_optind;

    if (argc < 2) {
	bu_vls_printf(gedp->ged_result_str, "error: missing argument(s)\n");
	return GED_ERROR;
    }

    voxDat.newname = (char *)argv[0];
    argc--;
    argv++;

    if (db_lookup(gedp->ged_wdbp->dbip, voxDat.newname, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", voxDat.newname);
	return GED_ERROR;
    }

    rtip = rt_new_rti(gedp->ged_wdbp->dbip);
    rtip->useair = 1;

    /* Walk trees.  Here we identify any object trees in the database
     * that the user wants included in the ray trace.
     */
    while(argc > 0) {
	if(rt_gettree(rtip,argv[0]) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "error: object '%s' does not exists, aborting\n", argv[1]);
	    return GED_ERROR;
	}

	argc--;
	argv++;
    }


    voxDat.sizeVoxel[0] = sizeVoxel[0];
    voxDat.sizeVoxel[1] = sizeVoxel[1];
    voxDat.sizeVoxel[2] = sizeVoxel[2];
    voxDat.threshold = threshold;
    voxDat.wdbp = gedp->ged_wdbp;
    voxDat.bbMin = rtip->mdl_min;
    BU_LIST_INIT(&voxDat.content.l);

    callBackData = (void*)(&voxDat);

   /* voxelize function is called here with rtip(ray trace instance), userParameter and create_boxes function */
    voxelize(rtip, sizeVoxel, levelOfDetail, create_boxes, callBackData);

    mk_comb(gedp->ged_wdbp, voxDat.newname, &voxDat.content.l, 1, "plastic", "sh=4 sp=0.5 di=0.5 re=0.1", 0, 1000, 0, 0, 100, 0, 0, 0);

    mk_freemembers(&voxDat.content.l);
    rt_free_rti(rtip);

    return GED_OK;
}
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 */
Esempio n. 9
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);


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

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

    struct bn_unif *msr = NULL;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	    /* Find vector in yz-plane.  */

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

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

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

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

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

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

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

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

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

		dump = dump + 1000000.0;
	    }

	}					/* END # 2 */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		}

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

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

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

    }						/* END # 1 */
    return 0;
}
Esempio n. 11
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  */
/* 0 = no difference within tolerance, 1 = difference >= tolerance */
int
analyze_raydiff(/* TODO - decide what to return.  Probably some sort of left, common, right segment sets.  See what rtcheck does... */
	struct db_i *dbip, const char *obj1, const char *obj2, struct bn_tol *tol)
{
    int ret;
    int count = 0;
    struct rt_i *rtip;
    int ncpus = bu_avail_cpus();
    point_t min, mid, max;
    struct rt_pattern_data *xdata, *ydata, *zdata;
    fastf_t *rays;
    struct raydiff_container *state;

    if (!dbip || !obj1 || !obj2 || !tol) return 0;

    rtip = rt_new_rti(dbip);
    if (rt_gettree(rtip, obj1) < 0) return -1;
    if (rt_gettree(rtip, obj2) < 0) return -1;
    rt_prep_parallel(rtip, 1);


    /* Now we've got the bounding box - set up the grids */
    VMOVE(min, rtip->mdl_min);
    VMOVE(max, rtip->mdl_max);
    VSET(mid, (max[0] - min[0])/2, (max[1] - min[1])/2, (max[2] - min[2])/2);

    BU_GET(xdata, struct rt_pattern_data);
    VSET(xdata->center_pt, min[0] - 0.1 * min[0], mid[1], mid[2]);
    VSET(xdata->center_dir, 1, 0, 0);
    xdata->vn = 2;
    xdata->pn = 2;
    xdata->n_vec = (vect_t *)bu_calloc(xdata->vn + 1, sizeof(vect_t), "vects array");
    xdata->n_p = (fastf_t *)bu_calloc(xdata->pn + 1, sizeof(fastf_t), "params array");
    xdata->n_p[0] = 50; /* TODO - get tolerances from caller */
    xdata->n_p[1] = 50;
    VSET(xdata->n_vec[0], 0, max[1], 0);
    VSET(xdata->n_vec[1], 0, 0, max[2]);
    ret = rt_pattern(xdata, RT_PATTERN_RECT_ORTHOGRID);
    bu_free(xdata->n_vec, "x vec inputs");
    bu_free(xdata->n_p, "x p inputs");
    if (ret < 0) return -1;


    BU_GET(ydata, struct rt_pattern_data);
    VSET(ydata->center_pt, mid[0], min[1] - 0.1 * min[1], mid[2]);
    VSET(ydata->center_dir, 0, 1, 0);
    ydata->vn = 2;
    ydata->pn = 2;
    ydata->n_vec = (vect_t *)bu_calloc(ydata->vn + 1, sizeof(vect_t), "vects array");
    ydata->n_p = (fastf_t *)bu_calloc(ydata->pn + 1, sizeof(fastf_t), "params array");
    ydata->n_p[0] = 50; /* TODO - get tolerances from caller */
    ydata->n_p[1] = 50;
    VSET(ydata->n_vec[0], max[0], 0, 0);
    VSET(ydata->n_vec[1], 0, 0, max[2]);
    ret = rt_pattern(ydata, RT_PATTERN_RECT_ORTHOGRID);
    bu_free(ydata->n_vec, "y vec inputs");
    bu_free(ydata->n_p, "y p inputs");
    if (ret < 0) return -1;

    BU_GET(zdata, struct rt_pattern_data);
    VSET(zdata->center_pt, mid[0], mid[1], min[2] - 0.1 * min[2]);
    VSET(zdata->center_dir, 0, 0, 1);
    zdata->vn = 2;
    zdata->pn = 2;
    zdata->n_vec = (vect_t *)bu_calloc(zdata->vn + 1, sizeof(vect_t), "vects array");
    zdata->n_p = (fastf_t *)bu_calloc(zdata->pn + 1, sizeof(fastf_t), "params array");
    zdata->n_p[0] = 50; /* TODO - get tolerances from caller */
    zdata->n_p[1] = 50;
    VSET(zdata->n_vec[0], max[0], 0, 0);
    VSET(zdata->n_vec[1], 0, max[1], 0);
    ret = rt_pattern(zdata, RT_PATTERN_RECT_ORTHOGRID);
    bu_free(zdata->n_vec, "x vec inputs");
    bu_free(zdata->n_p, "x p inputs");
    if (ret < 0) return -1;

    /* Consolidate the grids into a single ray array */
    {
	size_t i, j;
	rays = (fastf_t *)bu_calloc((xdata->ray_cnt + ydata->ray_cnt + zdata->ray_cnt + 1) * 6, sizeof(fastf_t), "rays");
	count = 0;
	for (i = 0; i < xdata->ray_cnt; i++) {
	    for (j = 0; j < 6; j++) {
		rays[6*count+j] = xdata->rays[6*i + j];
	    }
	    count++;
	}
	for (i = 0; i < ydata->ray_cnt; i++) {
	    for (j = 0; j < 6; j++) {
		rays[6*count+j] = ydata->rays[6*i + j];
	    }
	    count++;
	}
	for (i = 0; i < zdata->ray_cnt; i++) {
	    for (j = 0; j < 6; j++) {
		rays[6*count+j] = zdata->rays[6*i+j];
	    }
	    count++;
	}

    }
    bu_free(xdata->rays, "x rays");
    bu_free(ydata->rays, "y rays");
    bu_free(zdata->rays, "z rays");
    BU_PUT(xdata, struct rt_pattern_data);
    BU_PUT(ydata, struct rt_pattern_data);
    BU_PUT(zdata, struct rt_pattern_data);

    bu_log("ray cnt: %d\n", count);

    {
	int i, j;
	ncpus = 2;
	state = (struct raydiff_container *)bu_calloc(ncpus+1, sizeof(struct raydiff_container), "resources");
	for (i = 0; i < ncpus+1; i++) {
	    state[i].rtip = rtip;
	    state[i].tol = 0.5;
	    state[i].ncpus = ncpus;
	    state[i].left_name = bu_strdup(obj1);
	    state[i].right_name = bu_strdup(obj2);
	    BU_GET(state[i].resp, struct resource);
	    rt_init_resource(state[i].resp, i, state->rtip);
	    BU_GET(state[i].left, struct bu_ptbl);
	    bu_ptbl_init(state[i].left, 64, "left solid hits");
	    BU_GET(state[i].both, struct bu_ptbl);
	    bu_ptbl_init(state[i].both, 64, "hits on both solids");
	    BU_GET(state[i].right, struct bu_ptbl);
	    bu_ptbl_init(state[i].right, 64, "right solid hits");
	    state[i].rays_cnt = count;
	    state[i].rays = rays;
	}
	bu_parallel(raydiff_gen_worker, ncpus, (void *)state);

	/* Collect and print all of the results */
	for (i = 0; i < ncpus+1; i++) {
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].left, j);
		bu_log("Result: LEFT diff vol (%s): %g %g %g -> %g %g %g\n", obj1, V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt));
	    }
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].both, j);
		bu_log("Result: BOTH): %g %g %g -> %g %g %g\n", V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt));
	    }
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].right, j);
		bu_log("Result: RIGHT diff vol (%s): %g %g %g -> %g %g %g\n", obj2, V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt));
	    }
	}

	/* Free results */
	for (i = 0; i < ncpus+1; i++) {
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].left, j);
		BU_PUT(dseg, struct diff_seg);
	    }
	    bu_ptbl_free(state[i].left);
	    BU_PUT(state[i].left, struct diff_seg);
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].both, j);
		BU_PUT(dseg, struct diff_seg);
	    }
	    bu_ptbl_free(state[i].both);
	    BU_PUT(state[i].both, struct diff_seg);
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].right, j);
		BU_PUT(dseg, struct diff_seg);
	    }
	    bu_ptbl_free(state[i].right);
	    BU_PUT(state[i].right, struct diff_seg);

	    bu_free((void *)state[i].left_name, "left name");
	    bu_free((void *)state[i].right_name, "right name");
	    BU_PUT(state[i].resp, struct resource);
	}
	bu_free(state, "free state containers");
    }
    return 0;
}
Esempio n. 13
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  */
HIDDEN int
_rt_generate_points(int **faces, int *num_faces, point_t **points, int *num_pnts, struct bu_ptbl *hit_pnts, struct db_i *dbip, const char *obj, fastf_t delta)
{
    int i, dir1, j;
    point_t min, max;
    int ncpus = bu_avail_cpus();
    struct rt_parallel_container *state;
    struct bu_vls vlsstr;
    bu_vls_init(&vlsstr);

    if (!hit_pnts || !dbip || !obj) return -1;

    BU_GET(state, struct rt_parallel_container);

    state->rtip = rt_new_rti(dbip);
    state->delta = delta;

    if (rt_gettree(state->rtip, obj) < 0) return -1;
    rt_prep_parallel(state->rtip, 1);

    state->resp = (struct resource *)bu_calloc(ncpus+1, sizeof(struct resource), "resources");
    for (i = 0; i < ncpus+1; i++) {
	rt_init_resource(&(state->resp[i]), i, state->rtip);
    }

    state->npts = (struct rt_point_container *)bu_calloc(ncpus+1, sizeof(struct rt_point_container), "point container arrays");
    int n[3];
    VMOVE(min, state->rtip->mdl_min);
    VMOVE(max, state->rtip->mdl_max);
    for (i = 0; i < 3; i++) {
	n[i] = (int)((max[i] - min[i])/state->delta) + 2;
	if(n[i] < 12) n[i] = 12;
    }
    int total = 0;
    for (i = 0; i < 3; i++) total += n[i]*n[(i+1)%3];
    if (total > 1e6) total = 1e6;
    for (i = 0; i < ncpus+1; i++) {
	state->npts[i].pts = (struct npoints *)bu_calloc(total, sizeof(struct npoints), "npoints arrays");
	state->npts[i].pnt_cnt = 0;
	state->npts[i].capacity = total;
    }

    for (dir1 = 0; dir1 < 3; dir1++) {
	state->ray_dir = dir1;
	state->ncpus = ncpus;
	state->delta = delta;
	bu_parallel(_rt_gen_worker, ncpus, (void *)state);
    }

    int out_cnt = 0;
    for (i = 0; i < ncpus+1; i++) {
	bu_log("%d, pnt_cnt: %d\n", i, state->npts[i].pnt_cnt);
	for (j = 0; j < state->npts[i].pnt_cnt; j++) {
	    struct npoints *npt = &(state->npts[i].pts[j]);
	    if (npt->in.is_set) out_cnt++;
	    if (npt->out.is_set) out_cnt++;
	}
    }

    struct rt_vert **rt_verts = (struct rt_vert **)bu_calloc(out_cnt, sizeof(struct rt_vert *), "output array");
    int curr_ind = 0;
    for (i = 0; i < ncpus+1; i++) {
	for (j = 0; j < state->npts[i].pnt_cnt; j++) {
	    struct npoints *npt = &(state->npts[i].pts[j]);
	    if (npt->in.is_set) {
		rt_verts[curr_ind] = &(npt->in);
		curr_ind++;
	    }
	    if (npt->out.is_set) {
		rt_verts[curr_ind] = &(npt->out);
		curr_ind++;
	    }
	}
    }

    struct spr_options opts = SPR_OPTIONS_DEFAULT_INIT;
    (void)spr_surface_build(faces, num_faces, (double **)points, num_pnts, (const struct cvertex **)rt_verts, out_cnt, &opts);

    return 0;
}