/* * 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; }
/** * 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); }
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; }
/** * 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; }
/* * 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; }
/** * Called at the start of a run. * * Returns 1 if framebuffer should be opened, else 0. */ int view_init(struct application *ap, char *file, char *UNUSED(obj), int minus_o, int minus_F) { /* * Allocate a scanline for each processor. */ ap->a_hit = rayhit; ap->a_miss = raymiss; ap->a_onehit = 1; /* * Does the user want occlusion checking? * * If so, load and prep. */ if (bu_vls_strlen(&occlusion_objects) != 0) { struct db_i *dbip; int nObjs; const char **objs; int i; bu_log("rtedge: loading occlusion geometry from %s.\n", file); if (Tcl_SplitList(NULL, bu_vls_addr(&occlusion_objects), &nObjs, &objs) == TCL_ERROR) { bu_log("rtedge: occlusion list = %s\n", bu_vls_addr(&occlusion_objects)); bu_exit(EXIT_FAILURE, "rtedge: could not parse occlusion objects list.\n"); } for (i=0; i<nObjs; ++i) { bu_log("rtedge: occlusion object %d = %s\n", i, objs[i]); } if ((dbip = db_open(file, DB_OPEN_READONLY)) == DBI_NULL) bu_exit(EXIT_FAILURE, "rtedge: could not open geometry database file %s.\n", file); RT_CK_DBI(dbip); #if 0 /* FIXME: calling this when db_open()'s mapped file doesn't * fail will cause duplicate directory entries. need to make * sure db_dirbuild rebuilds from scratch or only updates * existing entries when they exist. */ if (db_dirbuild(dbip) < 0) bu_exit(EXIT_FAILURE, "rtedge: could not read database.\n"); #endif occlusion_rtip = rt_new_rti(dbip); /* clones dbip */ for (i=0; i < MAX_PSW; i++) { rt_init_resource(&occlusion_resources[i], i, occlusion_rtip); bn_rand_init(occlusion_resources[i].re_randptr, i); } db_close(dbip); /* releases original dbip */ for (i=0; i<nObjs; ++i) if (rt_gettree(occlusion_rtip, objs[i]) < 0) bu_log("rtedge: gettree failed for %s\n", objs[i]); else bu_log("rtedge: got tree for object %d = %s\n", i, objs[i]); bu_log("rtedge: occlusion rt_gettrees done.\n"); rt_prep(occlusion_rtip); bu_log("rtedge: occlusion prep done.\n"); /* * Create a set of application structures for the occlusion * geometry. Need one per cpu, the upper half does the per- * thread allocation in worker, but that's off limits. */ occlusion_apps = (struct application **)bu_calloc(npsw, sizeof(struct application *), "occlusion application structure array"); for (i=0; i<npsw; ++i) { BU_ALLOC(occlusion_apps[i], struct application); RT_APPLICATION_INIT(occlusion_apps[i]); occlusion_apps[i]->a_rt_i = occlusion_rtip; occlusion_apps[i]->a_resource = (struct resource *)BU_PTBL_GET(&occlusion_rtip->rti_resources, i); occlusion_apps[i]->a_onehit = 1; occlusion_apps[i]->a_hit = occlusion_hit; occlusion_apps[i]->a_miss = occlusion_miss; if (rpt_overlap) occlusion_apps[i]->a_logoverlap = (void (*)(struct application *, const struct partition *, const struct bu_ptbl *, const struct partition *))NULL; else occlusion_apps[i]->a_logoverlap = rt_silent_logoverlap; } bu_log("rtedge: will perform occlusion testing.\n"); /* * If an inclusion mode has not been specified, use the default. */ if (occlusion_mode == OCCLUSION_MODE_NONE) { occlusion_mode = OCCLUSION_MODE_DEFAULT; bu_log("rtedge: occlusion mode = %d\n", occlusion_mode); } if ((occlusion_mode != OCCLUSION_MODE_NONE) && (overlay == OVERLAY_MODE_UNSET)) { bu_log("rtedge: automagically activating overlay mode.\n"); overlay = OVERLAY_MODE_DOIT; } } if (occlusion_mode != OCCLUSION_MODE_NONE && bu_vls_strlen(&occlusion_objects) == 0) { bu_exit(EXIT_FAILURE, "rtedge: occlusion mode set, but no objects were specified.\n"); } /* if non-default/inverted background was requested, swap the * foreground and background colors. */ if (!default_background) { color tmp; tmp[RED] = fgcolor[RED]; tmp[GRN] = fgcolor[GRN]; tmp[BLU] = fgcolor[BLU]; fgcolor[RED] = bgcolor[RED]; fgcolor[GRN] = bgcolor[GRN]; fgcolor[BLU] = bgcolor[BLU]; bgcolor[RED] = tmp[RED]; bgcolor[GRN] = tmp[GRN]; bgcolor[BLU] = tmp[BLU]; } if (minus_o && (overlay || blend)) { /* * Output is to a file stream. Do not allow parallel * processing since we can't seek to the rows. */ RTG.rtg_parallel = 0; bu_log("view_init: deactivating parallelism due to -o option.\n"); /* * The overlay and blend cannot be used in -o mode. Note that * the overlay directive takes precedence, they can't be used * together. */ overlay = 0; blend = 0; bu_log("view_init: deactivating overlay and blending due to -o option.\n"); } if (overlay) bu_log("view_init: will perform simple overlay.\n"); else if (blend) bu_log("view_init: will perform blending.\n"); return minus_F || (!minus_o && !minus_F); /* we need a framebuffer */ }
int 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 */
/** * 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); }
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; }
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; }
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; }