void do_rt_gettrees(struct rt_i *my_rtip, char **object_name, int nm_objects, int *prep) { static char **prev_names = 0; static int prev_nm = 0; int i; if (object_name == NULL) { if ((object_name = prev_names) == 0) bu_exit (1, "%s:%d: This shouldn't happen\n", __FILE__, __LINE__); nm_objects = prev_nm; } if (prev_names == 0) { prev_names = object_name; prev_nm = nm_objects; } if (silent_flag != SILENT_YES) { printf("\nGet trees..."); fflush(stdout); } i = rt_gettrees_and_attrs(my_rtip, (const char **)a_tab.attrib, nm_objects, (const char **) object_name, 1); if (i) { fflush(stdout); bu_exit (1, "rt_gettrees() failed\n"); } if (*prep) { if (silent_flag != SILENT_YES) { printf("\nPrepping the geometry..."); fflush(stdout); } rt_prep(my_rtip); *prep = 0; } if (silent_flag != SILENT_YES) { printf("\n%s", (nm_objects == 1) ? "Object" : "Objects"); for (i = 0; i < nm_objects; ++i) printf(" '%s'", object_name[i]); printf(" processed\n"); } }
/** * Given a ray, shoot it at all the relevant parts of the model, * (building the HeadSeg chain), and then call rt_boolregions() to * build and evaluate the partition chain. If the ray actually hit * anything, call the application's a_hit() routine with a pointer to * the partition chain, otherwise, call the application's a_miss() * routine. * * It is important to note that rays extend infinitely only in the * positive direction. The ray is composed of all points P, where * * P = r_pt + K * r_dir * * for K ranging from 0 to +infinity. There is no looking backwards. * * It is also important to note that the direction vector r_dir must * have unit length; this is mandatory, and is not ordinarily checked, * in the name of efficiency. * * Input: Pointer to an application structure, with these mandatory fields: * a_ray.r_pt Starting point of ray to be fired * a_ray.r_dir UNIT VECTOR with direction to fire in (dir cosines) * a_hit Routine to call when something is hit * a_miss Routine to call when ray misses everything * * Calls user's a_miss() or a_hit() routine as appropriate. Passes * a_hit() routine list of partitions, with only hit_dist fields * valid. Normal computation deferred to user code, to avoid needless * computation here. * * Returns: whatever the application function returns (an int). * * NOTE: The application functions may call rt_shootray() recursively. * Thus, none of the local variables may be static. * * An open issue for execution in a PARALLEL environment is locking of * the statistics variables. */ int rt_vshootray(struct application *ap) { struct seg *HeadSeg; int ret; vect_t inv_dir; /* inverses of ap->a_ray.r_dir */ struct bu_bitv *solidbits; /* bits for all solids shot so far */ struct bu_ptbl *regionbits; /* bits for all involved regions */ char *status; struct partition InitialPart; /* Head of Initial Partitions */ struct partition FinalPart; /* Head of Final Partitions */ int nrays = 1; /* for now */ int vlen; int id; int i; struct soltab **ary_stp; /* array of pointers */ struct xray **ary_rp; /* array of pointers */ struct seg *ary_seg; /* array of structures */ struct rt_i *rtip; int done; #define BACKING_DIST (-2.0) /* mm to look behind start point */ rtip = ap->a_rt_i; RT_AP_CHECK(ap); if (!ap->a_resource) { ap->a_resource = &rt_uniresource; } RT_CK_RESOURCE(ap->a_resource); if (RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) { bu_log("\n**********mshootray cpu=%d %d, %d lvl=%d (%s)\n", ap->a_resource->re_cpu, ap->a_x, ap->a_y, ap->a_level, ap->a_purpose != (char *)0 ? ap->a_purpose : "?"); VPRINT("Pnt", ap->a_ray.r_pt); VPRINT("Dir", ap->a_ray.r_dir); } rtip->rti_nrays++; if (rtip->needprep) rt_prep(rtip); /* Allocate dynamic memory */ vlen = nrays * rtip->rti_maxsol_by_type; ary_stp = (struct soltab **)bu_calloc(vlen, sizeof(struct soltab *), "*ary_stp[]"); ary_rp = (struct xray **)bu_calloc(vlen, sizeof(struct xray *), "*ary_rp[]"); ary_seg = (struct seg *)bu_calloc(vlen, sizeof(struct seg), "ary_seg[]"); /**** for each ray, do this ****/ InitialPart.pt_forw = InitialPart.pt_back = &InitialPart; FinalPart.pt_forw = FinalPart.pt_back = &FinalPart; HeadSeg = RT_SEG_NULL; solidbits = rt_get_solidbitv(rtip->nsolids, ap->a_resource); if (BU_LIST_IS_EMPTY(&ap->a_resource->re_region_ptbl)) { BU_ALLOC(regionbits, struct bu_ptbl); bu_ptbl_init(regionbits, 7, "rt_shootray() regionbits ptbl"); } else { regionbits = BU_LIST_FIRST(bu_ptbl, &ap->a_resource->re_region_ptbl); BU_LIST_DEQUEUE(®ionbits->l); BU_CK_PTBL(regionbits); } /* Compute the inverse of the direction cosines */ if (!ZERO(ap->a_ray.r_dir[X])) { inv_dir[X]=1.0/ap->a_ray.r_dir[X]; } else { inv_dir[X] = INFINITY; ap->a_ray.r_dir[X] = 0.0; } if (!ZERO(ap->a_ray.r_dir[Y])) { inv_dir[Y]=1.0/ap->a_ray.r_dir[Y]; } else { inv_dir[Y] = INFINITY; ap->a_ray.r_dir[Y] = 0.0; } if (!ZERO(ap->a_ray.r_dir[Z])) { inv_dir[Z]=1.0/ap->a_ray.r_dir[Z]; } else { inv_dir[Z] = INFINITY; ap->a_ray.r_dir[Z] = 0.0; } /* * XXX handle infinite solids here, later. */ /* * If ray does not enter the model RPP, skip on. * If ray ends exactly at the model RPP, trace it. */ if (!rt_in_rpp(&ap->a_ray, inv_dir, rtip->mdl_min, rtip->mdl_max) || ap->a_ray.r_max < 0.0) { rtip->nmiss_model++; if (ap->a_miss) ret = ap->a_miss(ap); else ret = 0; status = "MISS model"; goto out; } /* For each type of solid to be shot at, assemble the vectors */ for (id = 1; id <= ID_MAX_SOLID; id++) { register int nsol; if ((nsol = rtip->rti_nsol_by_type[id]) <= 0) continue; /* For each instance of this solid type */ for (i = nsol-1; i >= 0; i--) { ary_stp[i] = rtip->rti_sol_by_type[id][i]; ary_rp[i] = &(ap->a_ray); /* XXX, sb [ray] */ ary_seg[i].seg_stp = SOLTAB_NULL; BU_LIST_INIT(&ary_seg[i].l); } /* bounding box check */ /* bit vector per ray check */ /* mark elements to be skipped with ary_stp[] = SOLTAB_NULL */ ap->a_rt_i->nshots += nsol; /* later: skipped ones */ if (OBJ[id].ft_vshot) { OBJ[id].ft_vshot(ary_stp, ary_rp, ary_seg, nsol, ap); } else { vshot_stub(ary_stp, ary_rp, ary_seg, nsol, ap); } /* set bits for all solids shot at for each ray */ /* append resulting seg list to input for boolweave */ for (i = nsol-1; i >= 0; i--) { register struct seg *seg2; if (ary_seg[i].seg_stp == SOLTAB_NULL) { /* MISS */ ap->a_rt_i->nmiss++; continue; } ap->a_rt_i->nhits++; /* For now, do it the slow way. sb [ray] */ /* MUST dup it -- all segs have to live till after a_hit() */ RT_GET_SEG(seg2, ap->a_resource); *seg2 = ary_seg[i]; /* struct copy */ /* rt_boolweave(seg2, &InitialPart, ap); */ bu_bomb("FIXME: need to call boolweave here"); /* Add seg chain to list of used segs awaiting reclaim */ #if 0 /* FIXME: need to use waiting_segs/finished_segs here in * conjunction with rt_boolweave() { register struct seg *seg3 = seg2; while (seg3->seg_next != RT_SEG_NULL) seg3 = seg3->seg_next; seg3->seg_next = HeadSeg; HeadSeg = seg2; } */ #endif } } /* * Ray has finally left known space. */ if (InitialPart.pt_forw == &InitialPart) { if (ap->a_miss) ret = ap->a_miss(ap); else ret = 0; status = "MISSed all primitives"; goto freeup; } /* * All intersections of the ray with the model have been computed. * Evaluate the boolean trees over each partition. */ done = rt_boolfinal(&InitialPart, &FinalPart, BACKING_DIST, INFINITY, regionbits, ap, solidbits); if (done > 0) goto hitit; if (FinalPart.pt_forw == &FinalPart) { if (ap->a_miss) ret = ap->a_miss(ap); else ret = 0; status = "MISS bool"; goto freeup; } /* * Ray/model intersections exist. Pass the list to the user's * a_hit() routine. Note that only the hit_dist elements of * pt_inhit and pt_outhit have been computed yet. To compute both * hit_point and hit_normal, use the * * RT_HIT_NORMAL(NULL, hitp, stp, rayp, 0); * * macro. To compute just hit_point, use * * VJOIN1(hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir); */ hitit: if (RT_G_DEBUG&DEBUG_SHOOT) rt_pr_partitions(rtip, &FinalPart, "a_hit()"); if (ap->a_hit) ret = ap->a_hit(ap, &FinalPart, HeadSeg/* &finished_segs */); else ret = 0; status = "HIT"; /* * Processing of this ray is complete. Free dynamic resources. */ freeup: { register struct partition *pp; /* Free up initial partition list */ for (pp = InitialPart.pt_forw; pp != &InitialPart;) { register struct partition *newpp; newpp = pp; pp = pp->pt_forw; FREE_PT(newpp, ap->a_resource); } /* Free up final partition list */ for (pp = FinalPart.pt_forw; pp != &FinalPart;) { register struct partition *newpp; newpp = pp; pp = pp->pt_forw; FREE_PT(newpp, ap->a_resource); } } /* Segs can't be freed until after a_hit() has returned */ #if 0 /* FIXME: depends on commented out code above */ if (HeadSeg) RT_FREE_SEG_LIST(HeadSeg, ap->a_resource); #endif out: bu_free((char *)ary_stp, "*ary_stp[]"); bu_free((char *)ary_rp, "*ary_rp[]"); bu_free((char *)ary_seg, "ary_seg[]"); if (solidbits != NULL) { bu_bitv_free(solidbits); } if (RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) { bu_log("----------mshootray cpu=%d %d, %d lvl=%d (%s) %s ret=%d\n", ap->a_resource->re_cpu, ap->a_x, ap->a_y, ap->a_level, ap->a_purpose != (char *)0 ? ap->a_purpose : "?", status, ret); } return ret; }
void BU_FORTRAN(frprep, FRPREP)(struct rt_i **rtip) { RT_CHECK_RTI(*rtip); rt_prep(*rtip); }
/** * Called at the start of a run. * * Returns 1 if framebuffer should be opened, else 0. */ int view_init(struct application *ap, char *file, char *UNUSED(obj), int minus_o, int minus_F) { /* * Allocate a scanline for each processor. */ ap->a_hit = rayhit; ap->a_miss = raymiss; ap->a_onehit = 1; /* * Does the user want occlusion checking? * * If so, load and prep. */ if (bu_vls_strlen(&occlusion_objects) != 0) { struct db_i *dbip; int nObjs; const char **objs; int i; bu_log("rtedge: loading occlusion geometry from %s.\n", file); if (Tcl_SplitList(NULL, bu_vls_addr(&occlusion_objects), &nObjs, &objs) == TCL_ERROR) { bu_log("rtedge: occlusion list = %s\n", bu_vls_addr(&occlusion_objects)); bu_exit(EXIT_FAILURE, "rtedge: could not parse occlusion objects list.\n"); } for (i=0; i<nObjs; ++i) { bu_log("rtedge: occlusion object %d = %s\n", i, objs[i]); } if ((dbip = db_open(file, DB_OPEN_READONLY)) == DBI_NULL) bu_exit(EXIT_FAILURE, "rtedge: could not open geometry database file %s.\n", file); RT_CK_DBI(dbip); #if 0 /* FIXME: calling this when db_open()'s mapped file doesn't * fail will cause duplicate directory entries. need to make * sure db_dirbuild rebuilds from scratch or only updates * existing entries when they exist. */ if (db_dirbuild(dbip) < 0) bu_exit(EXIT_FAILURE, "rtedge: could not read database.\n"); #endif occlusion_rtip = rt_new_rti(dbip); /* clones dbip */ for (i=0; i < MAX_PSW; i++) { rt_init_resource(&occlusion_resources[i], i, occlusion_rtip); bn_rand_init(occlusion_resources[i].re_randptr, i); } db_close(dbip); /* releases original dbip */ for (i=0; i<nObjs; ++i) if (rt_gettree(occlusion_rtip, objs[i]) < 0) bu_log("rtedge: gettree failed for %s\n", objs[i]); else bu_log("rtedge: got tree for object %d = %s\n", i, objs[i]); bu_log("rtedge: occlusion rt_gettrees done.\n"); rt_prep(occlusion_rtip); bu_log("rtedge: occlusion prep done.\n"); /* * Create a set of application structures for the occlusion * geometry. Need one per cpu, the upper half does the per- * thread allocation in worker, but that's off limits. */ occlusion_apps = (struct application **)bu_calloc(npsw, sizeof(struct application *), "occlusion application structure array"); for (i=0; i<npsw; ++i) { BU_ALLOC(occlusion_apps[i], struct application); RT_APPLICATION_INIT(occlusion_apps[i]); occlusion_apps[i]->a_rt_i = occlusion_rtip; occlusion_apps[i]->a_resource = (struct resource *)BU_PTBL_GET(&occlusion_rtip->rti_resources, i); occlusion_apps[i]->a_onehit = 1; occlusion_apps[i]->a_hit = occlusion_hit; occlusion_apps[i]->a_miss = occlusion_miss; if (rpt_overlap) occlusion_apps[i]->a_logoverlap = (void (*)(struct application *, const struct partition *, const struct bu_ptbl *, const struct partition *))NULL; else occlusion_apps[i]->a_logoverlap = rt_silent_logoverlap; } bu_log("rtedge: will perform occlusion testing.\n"); /* * If an inclusion mode has not been specified, use the default. */ if (occlusion_mode == OCCLUSION_MODE_NONE) { occlusion_mode = OCCLUSION_MODE_DEFAULT; bu_log("rtedge: occlusion mode = %d\n", occlusion_mode); } if ((occlusion_mode != OCCLUSION_MODE_NONE) && (overlay == OVERLAY_MODE_UNSET)) { bu_log("rtedge: automagically activating overlay mode.\n"); overlay = OVERLAY_MODE_DOIT; } } if (occlusion_mode != OCCLUSION_MODE_NONE && bu_vls_strlen(&occlusion_objects) == 0) { bu_exit(EXIT_FAILURE, "rtedge: occlusion mode set, but no objects were specified.\n"); } /* if non-default/inverted background was requested, swap the * foreground and background colors. */ if (!default_background) { color tmp; tmp[RED] = fgcolor[RED]; tmp[GRN] = fgcolor[GRN]; tmp[BLU] = fgcolor[BLU]; fgcolor[RED] = bgcolor[RED]; fgcolor[GRN] = bgcolor[GRN]; fgcolor[BLU] = bgcolor[BLU]; bgcolor[RED] = tmp[RED]; bgcolor[GRN] = tmp[GRN]; bgcolor[BLU] = tmp[BLU]; } if (minus_o && (overlay || blend)) { /* * Output is to a file stream. Do not allow parallel * processing since we can't seek to the rows. */ RTG.rtg_parallel = 0; bu_log("view_init: deactivating parallelism due to -o option.\n"); /* * The overlay and blend cannot be used in -o mode. Note that * the overlay directive takes precedence, they can't be used * together. */ overlay = 0; blend = 0; bu_log("view_init: deactivating overlay and blending due to -o option.\n"); } if (overlay) bu_log("view_init: will perform simple overlay.\n"); else if (blend) bu_log("view_init: will perform blending.\n"); return minus_F || (!minus_o && !minus_F); /* we need a framebuffer */ }
int main(int argc, char **argv) { /* START # 1 */ struct application ap; /* Application struct, passed between functions. */ int idx; /* Index for rt_dirbuild & rt_gettree. */ static struct rt_i *rtip;/* Used for building directory, etc. */ char idbuf[132]; /* First id record in .g file. */ int i, j, k; /* Loop variables. */ double vec[3]; /* Temporary vector. */ double r[8]; /* Temporary variable. */ int c; /* Variable to read a character. */ char tmpstrng[150]; /* Temporary string variable. */ FILE *fpr=NULL; /* Used to read a file. */ FILE *fpw; /* Used to write a file. */ char filetmp[MAXFIL]; /* Temperature file name. */ char filernn[MAXFIL]; /* Region # & name file. */ char fileout[MAXFIL]; /* Output file name. */ char line[151]; /* Used to read one line of a file. */ int mon, day, yr; /* Month, day, and year read from PRISM file. */ float hr, min; /* Hour & minute read from PRISM file. */ int itype; /* Type of temperature file, 0=>PRISM, 1=>other. */ int numreg; /* Number of regions (includes background). */ /* User enters when using a PRISM file or read */ /* from generic file. */ int numreg_read; /* Number of regions read from region # & name */ /* file (includes background). */ int numreg_g; /* Number of regions read from .g file plus one */ /* for the background. */ double eltim; /* Elapsed time. */ double eltim_read; /* Elapsed time read from temperature file. */ int frst_line; /* Number of regions to be read in first line */ /* of PRISM file. */ int last_line; /* Number of regions to be read in last line */ /* of PRISM file. */ int full_line; /* Number of full lines of PRISM file to read. */ double center[3]; /* Center of bounding sphere or rpp. */ double radius; /* Radius of bounding sphere. */ double rppmax[3]; /* Maximum of bounding rpp. */ double rppmin[3]; /* Minimum of bounding rpp. */ double multi; /* Multiplication factor for radius. */ int region_hit; /* Region number hit by ray. */ int wide, high; /* Width & height of picture. */ double deltaw, deltah; /* Spacing between rays. */ double denom; /* Denominator for use in equations. */ double az, el; /* Viewing azimuth & elevation. */ double alpha, beta; /* Angles for rotation (rad). */ double calpha, salpha; /* Cosine & sine of alpha. */ double cbeta, sbeta; /* Cosine & sine of beta. */ int ret; /* Check to see if arguments implemented correctly. */ if (argc < 3 || argv[1]==NULL || argv[2]==NULL) { fprintf(stderr, "\nUsage: showtherm file.g objects\n\n"); } else { /* START # 4 */ /* Get beginning info such as name of temperature file, */ /* name of region # & name file, type of temperature file */ /* using. */ /* Ask type of temperature file to be used. */ fprintf(stderr, "Type of output file to be read 0=>PRISM, "); fprintf(stderr, "1=>generic.\n\t"); ret = scanf("%d", &itype); if (ret == 0) perror("scanf"); if (itype != 1) itype = 0; if (itype == 0) { /* Read info about (name & # regions) PRISM file. */ fprintf(stderr, "Enter name of the PRISM output "); fprintf(stderr, "file to be read (%d char max).\n\t", MAXFIL); ret = scanf("%25s", filetmp); /* MAXFIL */ if (ret == 0) perror("scanf"); /* Ask for number of regions. */ fprintf(stderr, "Enter the number of regions in the PRISM "); fprintf(stderr, "file, must be more\n"); fprintf(stderr, "than eight (not including the background).\n\t"); ret = scanf("%d", &numreg); if (ret == 0) perror("scanf"); } else { /* Read info about (name) generic file. */ fprintf(stderr, "Enter name of the generic output file to be "); fprintf(stderr, "read (%d char max).\n\t", MAXFIL); ret = scanf("%25s", filetmp); /* MAXFIL */ if (ret == 0) perror("scanf"); } /* Find name of region # & name file. */ fprintf(stderr, "Enter name of region # & name file to be read "); fprintf(stderr, "(%d char max).\n\t", MAXFIL); ret = scanf("%25s", filernn); /* MAXFIL */ if (ret == 0) perror("scanf"); /* Find name of output file. */ fprintf(stderr, "Enter name of output file (%d char max).\n\t", MAXFIL); ret = scanf("%25s", fileout); /*MAXFIL */ if (ret == 0) perror("scanf"); /* Find elapsed time to create graphical representation of. */ fprintf(stderr, "Enter the elapsed time to create graphical "); fprintf(stderr, "representation of.\n\t"); ret = scanf("%lf", &eltim); if (ret == 0) perror("scanf"); /* Open generic file and read number of regions if necessary. */ if (itype == 1) { fpr = fopen(filetmp, "rb"); (void)bu_fgets(line, 150, fpr); sscanf(line, "%d", &numreg); } /* Add one to number of regions to include background. */ numreg ++; printf("Number of regions (including "); (void)fflush(stdout); printf("the background): %d\n", numreg); (void)fflush(stdout); /* Malloc arrays. */ info = (struct table *)bu_malloc(numreg * sizeof (struct table), "info"); /* Zero all arrays. */ for (i=0; i<numreg; i++) { info[i].temp = 0.0; for (j=0; j<150; j++) { info[i].regname[j] = ' '; } } /* Now read the temperature file. */ if (itype == 0) { /* PRISM file. */ /* START # 2 */ fpr = fopen(filetmp, "rb"); /* Read date and print out. */ (void)bu_fgets(line, 150, fpr); sscanf(line, "%d %d %d %f %f", &mon, &day, &yr, &hr, &min); printf("%d/%d/%d ", mon, day, yr); printf(" %f:%f\n", hr, min); (void)fflush(stdout); /* Find number of lines to read. */ frst_line = 7; full_line = (numreg - frst_line) / (frst_line + 1); last_line = numreg - frst_line -(full_line * (frst_line + 1)); /* Read first line & check if correct elapsed time. */ (void)bu_fgets(line, 150, fpr); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &eltim_read, &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]); /* * while (eltim_read != eltim) */ while ((eltim_read < (eltim - VUNITIZE_TOL)) || ((eltim + VUNITIZE_TOL) < eltim_read)) { /* Page through to end of data. */ for (i=0; i<(full_line + 1); i++) { (void)bu_fgets(line, 150, fpr); } /* Read next elapsed time. */ (void)bu_fgets(line, 150, fpr); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &eltim_read, &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]); } /* When correct elapsed time is found, read data. */ /* Read first line of data. */ for (i=0; i<frst_line; i++) { info[i].temp = r[i]; } k = frst_line; /* Next region number of temperature to be read. */ /* Read full lines of data. */ for (i=0; i<full_line; i++) { (void)bu_fgets(line, 150, fpr); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7]); for (j=0; j<(frst_line + 1); j++) { info[k].temp = r[j]; k++; } } /* Read last line of data. */ (void)bu_fgets(line, 150, fpr); if (last_line == 1) sscanf(line, "%lf", &r[0]); if (last_line == 2) sscanf(line, "%lf %lf", &r[0], &r[1]); if (last_line == 3) sscanf(line, "%lf %lf %lf", &r[0], &r[1], &r[2]); if (last_line == 4) sscanf(line, "%lf %lf %lf %lf", &r[0], &r[1], &r[2], &r[3]); if (last_line == 5) sscanf(line, "%lf %lf %lf %lf %lf", &r[0], &r[1], &r[2], &r[3], &r[4]); if (last_line == 6) sscanf(line, "%lf %lf %lf %lf %lf %lf", &r[0], &r[1], &r[2], &r[3], &r[4], &r[5]); if (last_line == 7) sscanf(line, "%lf %lf %lf %lf %lf %lf %lf", &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]); if (last_line == 8) sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7]); if (last_line != 0) { for (j=0; j<last_line; j++) { info[k].temp = r[j]; k++; } } printf("Prism out file read.\n"); (void)fflush(stdout); /* END # 2 */ } else { /* Read generic file. */ /* START # 3 */ /* File is already open. */ /* Read elapsed time. */ (void)bu_fgets(line, 150, fpr); sscanf(line, "%lf", &eltim_read); while (!EQUAL(eltim_read, eltim)) { /* Page through to end of data. */ for (i=0; i<numreg; i++) { (void)bu_fgets(line, 150, fpr); } (void)bu_fgets(line, 150, fpr); sscanf(line, "%lf", &eltim_read); } /* When correct elapsed time is found, read data. */ for (i=0; i<numreg; i++) { (void)bu_fgets(line, 150, fpr); sscanf(line, "%lf", &r[0]); info[i].temp = r[0]; } } /* END # 3 */ /* Close file. */ (void)fclose(fpr); /* Read the region # & name file. */ fpr = fopen(filernn, "rb"); printf("Region # & name file opened.\n"); (void)fflush(stdout); numreg_read = 1; c = getc(fpr); while ((c != EOF) && (numreg_read < numreg)) { (void)ungetc(c, fpr); (void)bu_fgets(line, 150, fpr); sscanf(line, "%*d%149s", tmpstrng); for (i=0; i<150; i++) { info[numreg_read].regname[i] = tmpstrng[i]; } numreg_read++; c = getc(fpr); } /* Close file. */ (void)fclose(fpr); /* Check if the number of regions read from the output file is */ /* the same as the number of regions read from the region # & */ /* name file. */ if (numreg_read == numreg) { printf("The number of regions read from the output file "); printf("and the region # & name\n"); printf("file was the same, %d (does not ", (numreg-1)); printf("include background in number).\n"); (void)fflush(stdout); } if (numreg_read != numreg) { printf("The number of regions read from the output file "); printf("and the region # & name\n"); printf("file was not the same, %d vs %d.\n", (numreg-1), (numreg_read-1)); printf("This is an ERROR.\n\n"); (void)fflush(stdout); } /* Build the directory. */ printf("Building directory.\n"); (void)fflush(stdout); idx = 1; /* Set index for rt_dirbuild. */ rtip = rt_dirbuild(argv[idx], idbuf, sizeof(idbuf)); printf("File: %s\n", argv[idx]); (void)fflush(stdout); printf("Database Title: %s\n", idbuf); (void)fflush(stdout); /* Set useair to 1, to show hits of air. Must show hits of air */ /* since other irprep programs do. */ rtip->useair = 1; /* Load desired objects. */ idx = 2; /* Set index for rt_gettree. */ while (argv[idx] != NULL) { rt_gettree(rtip, argv[idx]); printf("\t%s loaded.\n", argv[idx]); (void)fflush(stdout); idx++; } /* Find the total number of regions in the .g file & add one */ /* for background. */ numreg_g = (int)rtip->nregions + 1; if ((numreg == numreg_read) && (numreg_read == numreg_g)) { printf("The number of regions read from the output\n"); printf("file, the region # & name file, and the .g\n"); printf("file are all equal. The number of regions\n"); printf("read, including the background is %d\n", numreg_g); (void)fflush(stdout); } else { printf("The number of regions read from the output\n"); printf("file, the region # & name file, and the .g\n"); printf("file are not all equal.\n"); printf("\toutput file: %d\n", numreg); printf("\tregion # & name file: %d\n", numreg_read); printf("\t.g file: %d\n", numreg_g); (void)fflush(stdout); } /* Start preparation. */ printf("Preparation started.\n"); (void)fflush(stdout); rt_prep(rtip); /* Maximums & minimums of bounding rpp. */ rppmin[X] = rtip->mdl_min[X]; rppmin[Y] = rtip->mdl_min[Y]; rppmin[Z] = rtip->mdl_min[Z]; rppmax[X] = rtip->mdl_max[X]; rppmax[Y] = rtip->mdl_max[Y]; rppmax[Z] = rtip->mdl_max[Z]; /* Find the center of the bounding sphere or rpp. */ center[X] = rppmin[X] + (rppmax[X] - rppmin[X]) / 2.0; center[Y] = rppmin[Y] + (rppmax[Y] - rppmin[Y]) / 2.0; center[Z] = rppmin[Z] + (rppmax[Z] - rppmin[Z]) / 2.0; /* Find the length of the radius of the bounding sphere. */ radius = (rppmax[X] - rppmin[X]) * (rppmax[X] - rppmin[X]) + (rppmax[Y] - rppmin[Y]) * (rppmax[Y] - rppmin[Y]) + (rppmax[Z] - rppmin[Z]) * (rppmax[Z] - rppmin[Z]); radius = sqrt(radius) / 2.0 + 1.0; /* Make radius a bit longer. */ printf("\nMinimum & maximum X: %f - %f\n", rppmin[X], rppmax[X]); printf("Minimum & maximum Y: %f - %f\n", rppmin[Y], rppmax[Y]); printf("Minimum & maximum Z: %f - %f\n", rppmin[Z], rppmax[Z]); printf("Center of bounding sphere: %f, %f, %f\n", center[X], center[Y], center[Z]); printf("Radius of bounding sphere: %f\n", radius); printf("Enter multiplication factor for radius.\n\t"); (void)fflush(stdout); ret = scanf("%lf", &multi); if (ret == 0) perror("scanf"); /* Multiply radius by multiplication factor. */ radius = radius * multi; /* Set up parameters for rt_shootray. */ RT_APPLICATION_INIT(&ap); ap.a_hit = hit; /* User supplied hit function. */ ap.a_miss = miss; /* User supplied miss function. */ ap.a_overlap = overlap; /* User supplied overlap function. */ ap.a_rt_i = rtip; /* Pointer from rt_dirbuild. */ ap.a_onehit = 1; /* Hit flag, stop after first hit. */ ap.a_level = 0; /* Recursion level for diagnostics. */ ap.a_resource = 0; /* Address of resource struct. */ /* Open output file. */ fpw = fopen(fileout, "wb"); /* User enters grid size. */ fprintf(stderr, "Enter grid size.\n\t"); ret = scanf("%d", &wide); if (ret == 0) perror("scanf"); high = wide; /* User enters azimuth & elevation for viewing. */ fprintf(stderr, "Enter azimuth & elevation.\n\t"); ret = scanf("%lf %lf", &az, &el); if (ret == 0) perror("scanf"); alpha = az * DEG2RAD; beta = (-el) * DEG2RAD; calpha = cos(alpha); salpha = sin(alpha); cbeta = cos(beta); sbeta = sin(beta); /* Find spacing between rays. */ deltaw = 2. * radius / (float)wide; deltah = 2. * radius / (float)high; /* Print grid size, azimuth, and elevation. */ printf("gridsize: %d x %d\n", wide, high); printf("azimuth: %f degrees\n", az); printf("elevation: %f degrees\n", el); (void)fflush(stdout); /* Write size of grid to output file. */ fprintf(fpw, "%d\t%d\n", wide, high); (void)fflush(stdout); /* Set firing direction. Rotate (-1, 0, 0) to proper position. */ vec[X] = (-1.0) * cbeta * calpha; vec[Y] = (-1.0) * cbeta * salpha; vec[Z] = (-1.0) * (-1.0) * sbeta; /* Normalize. */ denom = vec[X] * vec[X] + vec[Y] * vec[Y] + vec[Z] * vec[Z]; denom = sqrt(denom); vec[X] /= denom; vec[Y] /= denom; vec[Z] /= denom; ap.a_ray.r_dir[X] = vec[X]; ap.a_ray.r_dir[Y] = vec[Y]; ap.a_ray.r_dir[Z] = vec[Z]; /* Set starting point. */ vec[X] = center[X] + radius; for (i=0; i<high; i++) { vec[Z] = center[Z] + radius - (float)i * deltah; for (j=0; j<wide; j++) { vec[Y] = center[Y] - radius + (float)j * deltaw; /* Rotate starting point. */ ap.a_ray.r_pt[X] = vec[X] * cbeta * calpha + vec[Z] * sbeta * calpha - vec[Y] * salpha; ap.a_ray.r_pt[Y] = vec[X] * cbeta * salpha + vec[Z] * sbeta * salpha + vec[Y] * calpha; ap.a_ray.r_pt[Z] = (-vec[X]) * sbeta + vec[Z] * cbeta; /* Call rt_shootray. */ region_hit = rt_shootray(&ap); /* Write temperature of region to output file. */ fprintf(fpw, "%f\n", info[region_hit].temp); (void)fflush(fpw); } } } /* END # 4 */ return 0; } /* END # 1 */
/** * 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; }
/* * M A I N */ int main(int argc, char **argv) { struct application ap; static struct rt_i *rtip; char *title_file; char idbuf[RT_BUFSIZE] = {0}; /* First ID record info */ char *ptr; int attr_count=0, i; char **attrs = (char **)NULL; if ( argc < 3 ) { bu_exit(1, usage); } RT_APPLICATION_INIT(&ap); argc--; argv++; while ( argv[0][0] == '-' ) switch ( argv[0][1] ) { case 'R': bundle_radius = atof( argv[1] ); argc -= 2; argv += 2; break; case 'n': num_rings = atoi( argv[1] ); argc -= 2; argv += 2; break; case 'c': rays_per_ring = atoi( argv[1] ); argc -= 2; argv += 2; break; case 'v': /* count the number of attribute names provided */ ptr = argv[1]; while ( *ptr ) { while ( *ptr && isspace( *ptr ) ) ptr++; if ( *ptr ) attr_count++; while ( *ptr && !isspace( *ptr ) ) ptr++; } if ( attr_count == 0 ) { bu_log( "missing list of attribute names!\n" ); bu_exit( 1, usage ); } /* allocate enough for a null terminated list */ attrs = (char **)bu_calloc( attr_count + 1, sizeof( char *), "attrs" ); /* use strtok to actually grab the names */ i = 0; ptr = strtok( argv[1], "\t " ); while ( ptr && i < attr_count ) { attrs[i] = bu_strdup( ptr ); ptr = strtok( (char *)NULL, "\t " ); i++; } argc -= 2; argv += 2; break; case 't': rt_bot_tri_per_piece = atoi( argv[1] ); argc -= 2; argv += 2; break; case 'b': rt_bot_minpieces = atoi( argv[1] ); argc -= 2; argv += 2; break; case 'o': sscanf( argv[1], "%d", &set_onehit ); argc -= 2; argv += 2; break; case 'r': { float ray_len; sscanf( argv[1], "%f", &ray_len ); set_ray_length = ray_len; } argc -= 2; argv += 2; break; case 'U': sscanf( argv[1], "%d", &use_air ); argc -= 2; argv += 2; break; case 'u': sscanf( argv[1], "%x", (unsigned int *)&bu_debug ); fprintf(stderr, "librt bu_debug=x%x\n", bu_debug); argc -= 2; argv += 2; break; case 'x': sscanf( argv[1], "%x", (unsigned int *)&rt_g.debug ); fprintf(stderr, "librt rt_g.debug=x%x\n", rt_g.debug); argc -= 2; argv += 2; break; case 'X': sscanf( argv[1], "%x", (unsigned int *)&rdebug ); fprintf(stderr, "rdebug=x%x\n", rdebug); argc -= 2; argv += 2; break; case 'N': sscanf( argv[1], "%x", (unsigned int *)&rt_g.NMG_debug); fprintf(stderr, "librt rt_g.NMG_debug=x%x\n", rt_g.NMG_debug); argc -= 2; argv += 2; break; case 'd': if ( argc < 4 ) goto err; ap.a_ray.r_dir[X] = atof( argv[1] ); ap.a_ray.r_dir[Y] = atof( argv[2] ); ap.a_ray.r_dir[Z] = atof( argv[3] ); set_dir = 1; argc -= 4; argv += 4; continue; case 'p': if ( argc < 4 ) goto err; ap.a_ray.r_pt[X] = atof( argv[1] ); ap.a_ray.r_pt[Y] = atof( argv[2] ); ap.a_ray.r_pt[Z] = atof( argv[3] ); set_pt = 1; argc -= 4; argv += 4; continue; case 'a': if ( argc < 4 ) goto err; at_vect[X] = atof( argv[1] ); at_vect[Y] = atof( argv[2] ); at_vect[Z] = atof( argv[3] ); set_at = 1; argc -= 4; argv += 4; continue; case 'O': { if ( !strcmp( argv[1], "resolve" ) || !strcmp( argv[1], "0") ) overlap_claimant_handling = 0; else if ( !strcmp( argv[1], "rebuild_fastgen" ) || !strcmp( argv[1], "1") ) overlap_claimant_handling = 1; else if ( !strcmp( argv[1], "rebuild_all" ) || !strcmp( argv[1], "2") ) overlap_claimant_handling = 2; else if ( !strcmp( argv[1], "retain" ) || !strcmp( argv[1], "3") ) overlap_claimant_handling = 3; else { bu_log( "Illegal argument (%s) to '-O' option. Must be:\n", argv[1] ); bu_log( "\t'resolve' or '0'\n"); bu_log( "\t'rebuild_fastgen' or '1'\n"); bu_log( "\t'rebuild_all' or '2'\n"); bu_log( "\t'retain' or '3'\n"); bu_exit(1, NULL); } argc -= 2; argv += 2; } continue; default: err: bu_exit(1, usage); } if ( argc < 2 ) { (void)fputs(usage, stderr); bu_exit(1, "rtshot: MGED database not specified\n"); } if ( set_dir + set_pt + set_at != 2 ) goto err; if ( num_rings != 0 || rays_per_ring != 0 || bundle_radius != 0.0 ) { if ( num_rings <= 0 || rays_per_ring <= 0 || bundle_radius <= 0.0 ) { fprintf( stderr, "Must have all of \"-R\", \"-n\", and \"-c\" set\n" ); goto err; } } /* Load database */ title_file = argv[0]; argv++; argc--; if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) { bu_exit(2, "rtshot: rt_dirbuild failure\n"); } if ( overlap_claimant_handling ) rtip->rti_save_overlaps = 1; ap.a_rt_i = rtip; fprintf(stderr, "db title: %s\n", idbuf); rtip->useair = use_air; /* Walk trees */ if ( rt_gettrees_and_attrs( rtip, (const char **)attrs, argc, (const char **)argv, 1 ) ) { bu_exit(1, "rt_gettrees FAILED\n"); } ap.attrs = attrs; rt_prep(rtip); if ( R_DEBUG&RDEBUG_RAYPLOT ) { if ( (plotfp = fopen("rtshot.plot", "w")) == NULL ) { perror("rtshot.plot"); bu_exit(1, NULL); } pdv_3space( plotfp, rtip->rti_pmin, rtip->rti_pmax ); } /* Compute r_dir and r_pt from the inputs */ if ( set_at ) { if ( set_dir ) { vect_t diag; fastf_t viewsize; VSUB2( diag, rtip->mdl_max, rtip->mdl_min ); viewsize = MAGNITUDE( diag ); VJOIN1( ap.a_ray.r_pt, at_vect, -viewsize/2.0, ap.a_ray.r_dir ); } else { /* set_pt */ VSUB2( ap.a_ray.r_dir, at_vect, ap.a_ray.r_pt ); } } VUNITIZE( ap.a_ray.r_dir ); if ( rays_per_ring ) { bu_log( "Central Ray:\n" ); } VPRINT( "Pnt", ap.a_ray.r_pt ); VPRINT( "Dir", ap.a_ray.r_dir ); if ( set_onehit ) ap.a_onehit = set_onehit; else ap.a_onehit = 0; if ( set_ray_length > 0.0 ) ap.a_ray_length = set_ray_length; else ap.a_ray_length = 0.0; /* Shoot Ray */ ap.a_purpose = "main ray"; ap.a_hit = hit; ap.a_miss = miss; if ( rays_per_ring ) { vect_t avec, bvec; struct xray *rp; /* create orthogonal rays for basis of bundle */ bn_vec_ortho( avec, ap.a_ray.r_dir ); VCROSS( bvec, ap.a_ray.r_dir, avec ); VUNITIZE( bvec ); rp = (struct xray *)bu_calloc( sizeof( struct xray ), (rays_per_ring * num_rings) + 1, "ray bundle" ); rp[0] = ap.a_ray; /* struct copy */ rp[0].magic = RT_RAY_MAGIC; rt_raybundle_maker( rp, bundle_radius, avec, bvec, rays_per_ring, num_rings ); (void)rt_shootray_bundle( &ap, rp, (rays_per_ring * num_rings) + 1 ); } else { (void)rt_shootray( &ap ); } return(0); }
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 */
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 */