/* * The only argument is the name of the database file. */ void ph_dirbuild(struct pkg_conn *UNUSED(pc), char *buf) { long max_argc = 0; char **argv = NULL; struct rt_i *rtip = NULL; size_t n = 0; if (debug) fprintf(stderr, "ph_dirbuild: %s\n", buf); for (n = 0; n < strlen(buf); n++) { if (isspace((int)buf[n])) max_argc++; } argv = (char **)bu_calloc(max_argc+1, sizeof(char *), "alloc argv"); if ((bu_argv_from_string(argv, max_argc, buf)) <= 0) { /* No words in input */ (void)free(buf); bu_free(argv, "free argv"); return; } if (seen_dirbuild) { bu_log("ph_dirbuild: MSG_DIRBUILD already seen, ignored\n"); (void)free(buf); bu_free(argv, "free argv"); return; } title_file = bu_strdup(argv[0]); bu_free(argv, "free argv"); /* Build directory of GED database */ if ((rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL) bu_exit(2, "ph_dirbuild: rt_dirbuild(%s) failure\n", title_file); APP.a_rt_i = rtip; seen_dirbuild = 1; /* * Initialize all the per-CPU memory resources. * Go for the max, as TCL interface may change npsw as we run. */ for (n=0; n < MAX_PSW; n++) { rt_init_resource(&resource[n], n, rtip); bn_rand_init(resource[n].re_randptr, n); } if (pkg_send(MSG_DIRBUILD_REPLY, idbuf, strlen(idbuf)+1, pcsrv) < 0) fprintf(stderr, "MSG_DIRBUILD_REPLY error\n"); }
/** * load database and prepare for raytracing */ void fit_prep(struct fitness_state *fstate, int rows, int cols) { fstate->max_cpus = fstate->ncpu = 1;/*bu_avail_cpus();*/ fstate->capture = 0; fstate->res[X] = rows; fstate->res[Y] = cols; fstate->ray = NULL; bu_semaphore_init(TOTAL_SEMAPHORES); rt_init_resource(&rt_uniresource, fstate->max_cpus, NULL); bn_rand_init(rt_uniresource.re_randptr, 0); }
/** * P O P _ I N I T --- initialize a population of a given size */ void pop_init (struct population *p, int size) { p->parent = bu_malloc(sizeof(struct individual) * size, "parent"); p->child = bu_malloc(sizeof(struct individual) * size, "child"); p->size = size; p->db_c = p->db_p = DBI_NULL; p->name = bu_malloc(sizeof(char *) * size, "names"); #define SEED 33 /* init in main() bn_rand_init(randomer, SEED);*/ bn_rand_init(randomer, SEED); }
/** * Creates one metaball object with 'count' random points using * LIBWDB's mk_metaball() interface. */ static void make_meatballs(struct rt_wdb *fp, const char *name, long count) { static float *ctx; /* random context */ static const int method = 1; /* 1==ISO */ static const fastf_t threshold = 1.0; static const fastf_t SZ = 1000.0; long i; fastf_t **pts; RT_CK_WDB(fp); bn_rand_init(ctx, rand()); bu_log("Creating [%s] object with %ld random point%s\n", name, count, count > 1 ? "s" : ""); /* allocate a dynamic array of pointers to points. this may be * subject to change but is presently the format mk_metaball() * wants. */ pts = (fastf_t **)bu_calloc(count, sizeof(fastf_t*), "alloc metaball pts array"); for (i=0; i < count; i++) { pts[i] = (fastf_t *)bu_malloc(sizeof(fastf_t)*5, "alloc metaball point"); } /* create random metaball point values positioned randomly within * a cube with random field strengths. */ for (i=0; i < count; i++) { /* just for explicit clarity */ fastf_t x = bn_rand_half(ctx) * SZ; fastf_t y = bn_rand_half(ctx) * SZ; fastf_t z = bn_rand_half(ctx) * SZ; fastf_t field_strength = bn_rand0to1(ctx) * SZ / (2.0 * sqrt(count)); VSET(pts[i], x, y, z); pts[i][3] = field_strength; /* something blobbly random */ pts[i][4] = 0.0; /* sweat/goo field is unused with iso method */ } /* pack the meat, create the metaball */ mk_metaball(fp, name, count, method, threshold, (const fastf_t **)pts); /* free up our junk */ for (i=0; i < count; i++) { bu_free(pts[i], "dealloc metaball point"); } bu_free(pts, "dealloc metaball pts array"); }
int main(int argc, char **argv) { register float *randp; struct color_rec { unsigned char red, green, blue; } cur_color; bn_rand_init( randp, 0); if ( !get_args( argc, argv ) ) { (void)fputs(usage, stderr); bu_exit ( 1, NULL ); } /* fprintf(stderr, "pixfade: max = %d, multiplier = %f\n", max, multiplier); */ for (;;) { register double t; if ( fread(&cur_color, 1, 3, inp) != 3 ) break; if ( feof(inp) ) break; t = cur_color.red * multiplier + bn_rand_half(randp); if (t > max) cur_color.red = max; else cur_color.red = t; t = cur_color.green * multiplier + bn_rand_half(randp); if (t > max) cur_color.green = max; else cur_color.green = t; t = cur_color.blue * multiplier + bn_rand_half(randp); if (t > max) cur_color.blue = max; else cur_color.blue = t; fwrite(&cur_color, 1, 3, stdout); } return 0; }
int main(int argc, char **argv) { int n; if (argc < 2) { fprintf(stderr, "%s", srv_usage); return 1; } while (argv[1][0] == '-') { if (BU_STR_EQUAL(argv[1], "-d")) { debug++; } else if (BU_STR_EQUAL(argv[1], "-x")) { sscanf(argv[2], "%x", (unsigned int *)&RTG.debug); argc--; argv++; } else if (BU_STR_EQUAL(argv[1], "-X")) { sscanf(argv[2], "%x", (unsigned int *)&rdebug); argc--; argv++; } else { fprintf(stderr, "%s", srv_usage); return 3; } argc--; argv++; } if (argc != 3 && argc != 4) { fprintf(stderr, "%s", srv_usage); return 2; } control_host = argv[1]; tcp_port = argv[2]; /* Note that the LIBPKG error logger can not be * "bu_log", as that can cause bu_log to be entered recursively. * Given the special version of bu_log in use here, * that will result in a deadlock in bu_semaphore_acquire(res_syscall)! * libpkg will default to stderr via pkg_errlog(), which is fine. */ pcsrv = pkg_open(control_host, tcp_port, "tcp", "", "", pkgswitch, NULL); if (pcsrv == PKC_ERROR) { fprintf(stderr, "rtsrv: unable to contact %s, port %s\n", control_host, tcp_port); return 1; } if (argc == 4) { /* Slip one command to dispatcher */ (void)pkg_send(MSG_CMD, argv[3], strlen(argv[3])+1, pcsrv); /* Prevent chasing the package with an immediate TCP close */ sleep(1); pkg_close(pcsrv); return 0; } #ifdef SO_SNDBUF /* increase the default send buffer size to 32k since we're * sending pixels more than likely. */ { int val = 32767; n = setsockopt(pcsrv->pkc_fd, SOL_SOCKET, SO_SNDBUF, (const void *)&val, sizeof(val)); if (n < 0) perror("setsockopt: SO_SNDBUF"); } #endif if (!debug) { /* A fresh process */ if (fork()) return 0; /* Go into our own process group */ n = bu_process_id(); #ifdef HAVE_SETPGID if (setpgid(n, n) < 0) perror("setpgid"); #else /* SysV uses setpgrp with no args and it can't fail, * obsoleted by setpgid. */ setpgrp(); #endif /* * Unless controller process has specifically said * that this is an interactive session, e.g., for a demo, * drop to the lowest sensible priority. */ if (!interactive) { bu_nice_set(19); /* lowest priority */ } /* Close off the world */ fclose(stdin); fclose(stdout); fclose(stderr); (void)close(0); (void)close(1); (void)close(2); /* For stdio & perror safety, reopen 0, 1, 2 */ (void)open("/dev/null", 0); /* to fd 0 */ n = dup(0); /* to fd 1 */ if (n == -1) perror("dup"); n = dup(0); /* to fd 2 */ if (n == -1) perror("dup"); #if defined(HAVE_SYS_IOCTL_H) && defined(TIOCNOTTY) n = open("/dev/tty", 2); if (n >= 0) { (void)ioctl(n, TIOCNOTTY, 0); (void)close(n); } #endif } /* Send our version string */ if (pkg_send(MSG_VERSION, PROTOCOL_VERSION, strlen(PROTOCOL_VERSION)+1, pcsrv) < 0) { fprintf(stderr, "pkg_send MSG_VERSION error\n"); return 1; } if (debug) fprintf(stderr, "PROTOCOL_VERSION='%s'\n", PROTOCOL_VERSION); /* * Now that the fork() has been done, it is safe to initialize * the parallel processing support. */ avail_cpus = bu_avail_cpus(); /* Need to set rtg_parallel non_zero here for RES_INIT to work */ npsw = avail_cpus; if (npsw > 1) { RTG.rtg_parallel = 1; } else RTG.rtg_parallel = 0; bu_semaphore_init(RT_SEM_LAST); bu_log("using %d of %d cpus\n", npsw, avail_cpus); /* * Initialize the non-parallel memory resource. * The parallel guys are initialized after the rt_dirbuild(). */ rt_init_resource(&rt_uniresource, MAX_PSW, NULL); bn_rand_init(rt_uniresource.re_randptr, MAX_PSW); BU_LIST_INIT(&WorkHead); for (;;) { struct pkg_queue *lp; fd_set ifds; struct timeval tv; /* First, process any packages in library buffers */ if (pkg_process(pcsrv) < 0) { bu_log("pkg_get error\n"); break; } /* Second, see if any input to read */ FD_ZERO(&ifds); FD_SET(pcsrv->pkc_fd, &ifds); tv.tv_sec = BU_LIST_NON_EMPTY(&WorkHead) ? 0L : 9999L; tv.tv_usec = 0L; if (select(pcsrv->pkc_fd+1, &ifds, (fd_set *)0, (fd_set *)0, &tv) != 0) { n = pkg_suckin(pcsrv); if (n < 0) { bu_log("pkg_suckin error\n"); break; } else if (n == 0) { /* EOF detected */ break; } else { /* All is well */ } } /* Third, process any new packages in library buffers */ if (pkg_process(pcsrv) < 0) { bu_log("pkg_get error\n"); break; } /* Finally, more work may have just arrived, check our list */ if (BU_LIST_NON_EMPTY(&WorkHead)) { lp = BU_LIST_FIRST(pkg_queue, &WorkHead); BU_LIST_DEQUEUE(&lp->l); switch (lp->type) { case MSG_MATRIX: ph_matrix((struct pkg_conn *)0, lp->buf); break; case MSG_LINES: ph_lines((struct pkg_conn *)0, lp->buf); break; case MSG_OPTIONS: ph_options((struct pkg_conn *)0, lp->buf); break; case MSG_GETTREES: ph_gettrees((struct pkg_conn *)0, lp->buf); break; default: bu_log("bad list element, type=%d\n", lp->type); return 33; } BU_PUT(lp, struct pkg_queue); } } return 0; /* bu_exit(0, NULL) */ }
/** * 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 */ }
/* * M A I N */ int main(int argc, char **argv) { struct rt_i *rtip = NULL; char *title_file = NULL, *title_obj = NULL; /* name of file and first object */ char idbuf[RT_BUFSIZE] = {0}; /* First ID record info */ void application_init(); struct bu_vls times; int i; #if defined(_WIN32) && !defined(__CYGWIN__) setmode(fileno(stdin), O_BINARY); setmode(fileno(stdout), O_BINARY); setmode(fileno(stderr), O_BINARY); #else bu_setlinebuf( stdout ); bu_setlinebuf( stderr ); #endif #ifdef HAVE_SBRK beginptr = (char *) sbrk(0); #endif azimuth = 35.0; /* GIFT defaults */ elevation = 25.0; AmbientIntensity=0.4; background[0] = background[1] = 0.0; background[2] = 1.0/255.0; /* slightly non-black */ /* Before option processing, get default number of processors */ npsw = bu_avail_cpus(); /* Use all that are present */ if ( npsw > MAX_PSW ) npsw = MAX_PSW; /* Before option processing, do application-specific initialization */ RT_APPLICATION_INIT( &ap ); application_init(); /* Process command line options */ if ( !get_args( argc, argv ) ) { (void)fputs(usage, stderr); return 1; } /* Identify the versions of the libraries we are using. */ if (rt_verbosity & VERBOSE_LIBVERSIONS) { (void)fprintf(stderr, "%s%s%s%s\n", brlcad_ident(title), rt_version(), bn_version(), bu_version() ); } #if defined(DEBUG) (void)fprintf(stderr, "Compile-time debug symbols are available\n"); #endif #if defined(NO_BOMBING_MACROS) || defined(NO_MAGIC_CHECKING) || defined(NO_BADRAY_CECHKING) || defined(NO_DEBUG_CHECKING) (void)fprintf(stderr, "WARNING: Run-time debugging is disabled and may enhance performance\n"); #endif /* Identify what host we're running on */ if (rt_verbosity & VERBOSE_LIBVERSIONS) { char hostname[512] = {0}; #ifndef _WIN32 if ( gethostname( hostname, sizeof(hostname) ) >= 0 && hostname[0] != '\0' ) (void)fprintf(stderr, "Running on %s\n", hostname); #else sprintf(hostname, "Microsoft Windows"); (void)fprintf(stderr, "Running on %s\n", hostname); #endif } if ( bu_optind >= argc ) { fprintf(stderr, "%s: MGED database not specified\n", argv[0]); (void)fputs(usage, stderr); return 1; } if (rpt_overlap) ap.a_logoverlap = ((void (*)())0); else ap.a_logoverlap = rt_silent_logoverlap; /* If user gave no sizing info at all, use 512 as default */ if ( width <= 0 && cell_width <= 0 ) width = 512; if ( height <= 0 && cell_height <= 0 ) height = 512; /* If user didn't provide an aspect ratio, use the image * dimensions ratio as a default. */ if (aspect <= 0.0) { aspect = (fastf_t)width / (fastf_t)height; } if ( sub_grid_mode ) { /* check that we have a legal subgrid */ if ( sub_xmax >= width || sub_ymax >= height ) { fprintf( stderr, "rt: illegal values for subgrid %d,%d,%d,%d\n", sub_xmin, sub_ymin, sub_xmax, sub_ymax ); fprintf( stderr, "\tFor a %d X %d image, the subgrid must be within 0, 0,%d,%d\n", width, height, width-1, height-1 ); return 1; } } if ( incr_mode ) { int x = height; if ( x < width ) x = width; incr_nlevel = 1; while ( (1<<incr_nlevel) < x ) incr_nlevel++; height = width = 1<<incr_nlevel; if (rt_verbosity & VERBOSE_INCREMENTAL) fprintf(stderr, "incremental resolution, nlevels = %d, width=%d\n", incr_nlevel, width); } /* * Handle parallel initialization, if applicable. */ #ifndef PARALLEL npsw = 1; /* force serial */ #endif if ( npsw < 0 ) { /* Negative number means "all but" npsw */ npsw = bu_avail_cpus() + npsw; } /* allow debug builds to go higher than the max */ if (!(bu_debug & BU_DEBUG_PARALLEL)) { if ( npsw > MAX_PSW ) { npsw = MAX_PSW; } } if (npsw > 1) { rt_g.rtg_parallel = 1; if (rt_verbosity & VERBOSE_MULTICPU) fprintf(stderr, "Planning to run with %d processors\n", npsw ); } else { rt_g.rtg_parallel = 0; } /* Initialize parallel processor support */ bu_semaphore_init( RT_SEM_LAST ); /* * Do not use bu_log() or bu_malloc() before this point! */ if ( bu_debug ) { bu_printb( "libbu bu_debug", bu_debug, BU_DEBUG_FORMAT ); bu_log("\n"); } if ( RT_G_DEBUG ) { bu_printb( "librt rt_g.debug", rt_g.debug, DEBUG_FORMAT ); bu_log("\n"); } if ( rdebug ) { bu_printb( "rt rdebug", rdebug, RDEBUG_FORMAT ); bu_log("\n"); } /* We need this to run rt_dirbuild */ rt_init_resource( &rt_uniresource, MAX_PSW, NULL ); bn_rand_init( rt_uniresource.re_randptr, 0 ); title_file = argv[bu_optind]; title_obj = argv[bu_optind+1]; nobjs = argc - bu_optind - 1; objtab = &(argv[bu_optind+1]); if ( nobjs <= 0 ) { bu_log("%s: no objects specified -- raytrace aborted\n", argv[0]); return 1; } /* Echo back the command line arugments as given, in 3 Tcl commands */ if (rt_verbosity & VERBOSE_MODELTITLE) { struct bu_vls str; bu_vls_init(&str); bu_vls_from_argv( &str, bu_optind, (const char **)argv ); bu_vls_strcat( &str, "\nopendb " ); bu_vls_strcat( &str, title_file ); bu_vls_strcat( &str, ";\ntree " ); bu_vls_from_argv( &str, nobjs <= 16 ? nobjs : 16, (const char **)argv+bu_optind+1 ); if ( nobjs > 16 ) bu_vls_strcat( &str, " ..."); else bu_vls_putc( &str, ';' ); bu_log("%s\n", bu_vls_addr(&str) ); bu_vls_free(&str); } /* Build directory of GED database */ bu_vls_init( × ); rt_prep_timer(); if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) { bu_log("rt: rt_dirbuild(%s) failure\n", title_file); return 2; } ap.a_rt_i = rtip; (void)rt_get_timer( ×, NULL ); if (rt_verbosity & VERBOSE_MODELTITLE) bu_log("db title: %s\n", idbuf); if (rt_verbosity & VERBOSE_STATS) bu_log("DIRBUILD: %s\n", bu_vls_addr(×) ); bu_vls_free( × ); memory_summary(); /* Copy values from command line options into rtip */ rtip->rti_space_partition = space_partition; rtip->rti_nugrid_dimlimit = nugrid_dimlimit; rtip->rti_nu_gfactor = nu_gfactor; rtip->useair = use_air; rtip->rti_save_overlaps = save_overlaps; if ( rt_dist_tol > 0 ) { rtip->rti_tol.dist = rt_dist_tol; rtip->rti_tol.dist_sq = rt_dist_tol * rt_dist_tol; } if ( rt_perp_tol > 0 ) { rtip->rti_tol.perp = rt_perp_tol; rtip->rti_tol.para = 1 - rt_perp_tol; } if (rt_verbosity & VERBOSE_TOLERANCE) rt_pr_tol( &rtip->rti_tol ); /* before view_init */ if ( outputfile && strcmp( outputfile, "-") == 0 ) outputfile = (char *)0; /* * Initialize application. * Note that width & height may not have been set yet, * since they may change from frame to frame. */ if ( view_init( &ap, title_file, title_obj, outputfile!=(char *)0, framebuffer!=(char *)0 ) != 0 ) { /* Framebuffer is desired */ register int xx, yy; int zoom; /* Ask for a fb big enough to hold the image, at least 512. */ /* This is so MGED-invoked "postage stamps" get zoomed up big enough to see */ xx = yy = 512; if ( width > xx || height > yy ) { xx = width; yy = height; } bu_semaphore_acquire( BU_SEM_SYSCALL ); fbp = fb_open( framebuffer, xx, yy ); bu_semaphore_release( BU_SEM_SYSCALL ); if ( fbp == FBIO_NULL ) { fprintf(stderr, "rt: can't open frame buffer\n"); return 12; } bu_semaphore_acquire( BU_SEM_SYSCALL ); /* If fb came out smaller than requested, do less work */ if ( fb_getwidth(fbp) < width ) width = fb_getwidth(fbp); if ( fb_getheight(fbp) < height ) height = fb_getheight(fbp); /* If the fb is lots bigger (>= 2X), zoom up & center */ if ( width > 0 && height > 0 ) { zoom = fb_getwidth(fbp)/width; if ( fb_getheight(fbp)/height < zoom ) zoom = fb_getheight(fbp)/height; } else { zoom = 1; } (void)fb_view( fbp, width/2, height/2, zoom, zoom ); bu_semaphore_release( BU_SEM_SYSCALL ); } if ( (outputfile == (char *)0) && (fbp == FBIO_NULL) ) { /* If not going to framebuffer, or to a file, then use stdout */ if ( outfp == NULL ) outfp = stdout; /* output_is_binary is changed by view_init, as appropriate */ if ( output_is_binary && isatty(fileno(outfp)) ) { fprintf(stderr, "rt: attempting to send binary output to terminal, aborting\n"); return 14; } } /* * Initialize all the per-CPU memory resources. * The number of processors can change at runtime, init them all. */ for ( i=0; i < MAX_PSW; i++ ) { rt_init_resource( &resource[i], i, rtip ); bn_rand_init( resource[i].re_randptr, i ); } memory_summary(); #ifdef SIGUSR1 (void)signal( SIGUSR1, siginfo_handler ); #endif #ifdef SIGINFO (void)signal( SIGINFO, siginfo_handler ); #endif if ( !matflag ) { int frame_retval; def_tree( rtip ); /* Load the default trees */ do_ae( azimuth, elevation ); frame_retval = do_frame( curframe ); if (frame_retval != 0) { /* Release the framebuffer, if any */ if ( fbp != FBIO_NULL ) { fb_close(fbp); } return 1; } } else if ( !isatty(fileno(stdin)) && old_way( stdin ) ) { ; /* All is done */ } else { register char *buf; register int ret; /* * New way - command driven. * Process sequence of input commands. * All the work happens in the functions * called by rt_do_cmd(). */ while ( (buf = rt_read_cmd( stdin )) != (char *)0 ) { if ( R_DEBUG&RDEBUG_PARSE ) fprintf(stderr, "cmd: %s\n", buf ); ret = rt_do_cmd( rtip, buf, rt_cmdtab ); bu_free( buf, "rt_read_cmd command buffer" ); if ( ret < 0 ) break; } if ( curframe < desiredframe ) { fprintf(stderr, "rt: Desired frame %d not reached, last was %d\n", desiredframe, curframe); } } /* Release the framebuffer, if any */ if (fbp != FBIO_NULL) { fb_close(fbp); } return(0); }