HIDDEN int
raydiff_hit(struct application *ap, struct partition *PartHeadp, struct seg *UNUSED(segs))
{
    point_t in_pt, out_pt;
    struct partition *part;
    fastf_t part_len = 0.0;
    struct raydiff_container *state = (struct raydiff_container *)(ap->a_uptr);
    /*rt_pr_seg(segs);*/
    /*rt_pr_partitions(ap->a_rt_i, PartHeadp, "hits");*/

    for (part = PartHeadp->pt_forw; part != PartHeadp; part = part->pt_forw) {
	VJOIN1(in_pt, ap->a_ray.r_pt, part->pt_inhit->hit_dist, ap->a_ray.r_dir);
	VJOIN1(out_pt, ap->a_ray.r_pt, part->pt_outhit->hit_dist, ap->a_ray.r_dir);
	part_len = DIST_PT_PT(in_pt, out_pt);
	if (part_len > state->tol) {
	    state->have_diffs = 1;
	    if (state->left && !bu_strncmp(part->pt_regionp->reg_name+1, state->left_name, strlen(state->left_name))) {
		RDIFF_ADD_DSEG(state->left, in_pt, out_pt);
		bu_log("LEFT diff vol (%s) (len: %f): %g %g %g -> %g %g %g\n", part->pt_regionp->reg_name, part_len, V3ARGS(in_pt), V3ARGS(out_pt));
		continue;
	    }
	    if (state->right && !bu_strncmp(part->pt_regionp->reg_name+1, state->right_name, strlen(state->right_name))) {
		RDIFF_ADD_DSEG(state->right, in_pt, out_pt);
		bu_log("RIGHT diff vol (%s) (len: %f): %g %g %g -> %g %g %g\n", part->pt_regionp->reg_name, part_len, V3ARGS(in_pt), V3ARGS(out_pt));
		continue;
	    }
	    /* If we aren't collecting segments, we already have our final answer */
	    if (!state->left && !state->right) return 0;
	}
    }

    return 0;
}
/* add all hit point info to info list */
HIDDEN int
add_hit_pnts(struct application *app, struct partition *partH, struct seg *UNUSED(segs))
{

    struct partition *pp;
    struct soltab *stp;
    /*point_t hit_pnt;
    vect_t hit_normal;*/
    struct rt_point_container *c = (struct rt_point_container *)(app->a_uptr);
    struct npoints *npt;

    if (c->pnt_cnt > c->capacity-1) {
	c->capacity *= 4;
	c->pts = (struct npoints *)bu_realloc((char *)c->pts, c->capacity * sizeof(struct npoints), "enlarge results array");
    }

    RT_CK_APPLICATION(app);
    /*struct bu_vls *fp = (struct bu_vls *)(app->a_uptr);*/

    /* add all hit points */
    for (pp = partH->pt_forw; pp != partH; pp = pp->pt_forw) {

	npt = &(c->pts[c->pnt_cnt]);

	/* add "in" hit point info */
	stp = pp->pt_inseg->seg_stp;

	/* hack fix for bad tgc surfaces */
	if (bu_strncmp("rec", stp->st_meth->ft_label, 3) == 0 || bu_strncmp("tgc", stp->st_meth->ft_label, 3) == 0) {

	    /* correct invalid surface number */
	    if (pp->pt_inhit->hit_surfno < 1 || pp->pt_inhit->hit_surfno > 3) {
		pp->pt_inhit->hit_surfno = 2;
	    }
	    if (pp->pt_outhit->hit_surfno < 1 || pp->pt_outhit->hit_surfno > 3) {
		pp->pt_outhit->hit_surfno = 2;
	    }
	}


	VJOIN1(npt->in.p, app->a_ray.r_pt, pp->pt_inhit->hit_dist, app->a_ray.r_dir);
	RT_HIT_NORMAL(npt->in.n, pp->pt_inhit, stp, &(app->a_ray), pp->pt_inflip);
	npt->in.is_set = 1;
	//bu_vls_printf(fp, "%f %f %f %f %f %f\n", hit_pnt[0], hit_pnt[1], hit_pnt[2], hit_normal[0], hit_normal[1], hit_normal[2]);
	/* add "out" hit point info (unless half-space) */
	stp = pp->pt_inseg->seg_stp;
	if (bu_strncmp("half", stp->st_meth->ft_label, 4) != 0) {
	    VJOIN1(npt->out.p, app->a_ray.r_pt, pp->pt_outhit->hit_dist, app->a_ray.r_dir);
	    RT_HIT_NORMAL(npt->out.n, pp->pt_outhit, stp, &(app->a_ray), pp->pt_outflip);
	    npt->out.is_set = 1;
	    //bu_vls_printf(fp, "%f %f %f %f %f %f\n", hit_pnt[0], hit_pnt[1], hit_pnt[2], hit_normal[0], hit_normal[1], hit_normal[2]);
	}
	c->pnt_cnt++;
    }
    return 1;
}
Esempio n. 3
0
/* txt_datasource_hook() is used to automatically try to load a default texture
 * datasource.  The type gets set to auto and the datasource is detected.  First
 * the database is searched for a matching object, then a file on disk is
 * looked up.  If neither is found, object name is left null so txt_setup() will
 * fail.
 */
HIDDEN void
txt_source_hook(const struct bu_structparse *UNUSED(sdp),
		const char *name,
		void *base,
		const char *UNUSED(value))
{
    struct txt_specific *textureSpecific = (struct txt_specific *)base;
    if (bu_strncmp(name, "file", 4) == 0) {
	textureSpecific->tx_datasrc=TXT_SRC_FILE;
    } else if (bu_strncmp(name, "obj", 3) == 0) {
	textureSpecific->tx_datasrc = TXT_SRC_OBJECT;
    } else {
	textureSpecific->tx_datasrc = TXT_SRC_AUTO;
    }
}
Esempio n. 4
0
    /* now look for objects in the other database that aren't here */
    FOR_ALL_DIRECTORY_START(dp2, dbip2) {
	/* skip the _GLOBAL object */
	if (dp2->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY)
	    continue;

	/* check if this object exists in the other database */
	if (db_lookup(dbip1, dp2->d_namep, 0) == RT_DIR_NULL) {
	    /* need to add this object */
	    has_diff += 1;
	    argv[2] = dp2->d_namep;

	    /* FIXME: use libtclcad's get interface or libged or librt
	     * directly, just not wdb_obj
	     */
	    if (wdb_get_tcl((void *)dbip2->dbi_wdbp, 3, (const char **)argv) == TCL_ERROR ||
		!bu_strncmp(Tcl_GetStringResult(interp), "invalid", 7)) {
		/* could not get TCL version */
		if (mode == HUMAN)
		    printf("Import %s from %s\n",
			   dp2->d_namep, dbip2->dbi_filename);
		else
		    printf("# IMPORT %s from %s\n",
			   dp2->d_namep, dbip2->dbi_filename);
	    } else {
		if (mode == HUMAN)
		    printf("%s does not exist in %s\n",
			   dp2->d_namep, dbip1->dbi_filename);
		else
		    printf("db put %s %s\n",
			   dp2->d_namep, Tcl_GetStringResult(interp));
	    }
	    Tcl_ResetResult(interp);
	}
    } FOR_ALL_DIRECTORY_END;
int rt_metaball_lookup_type_id(const char *name)
{
    int i = 0;
    while (metaballnames[i++])
	if (!bu_strncmp(metaballnames[i], name, 4))
	    return i;
    return -1;
}
Esempio n. 6
0
int
render_shader_unload_plugin(render_t *r, const char *name)
{
#ifdef HAVE_DLFCN_H
    struct render_shader_s *t, *s = shaders, *meh;
    if (!bu_strncmp(s->name, name, 8)) {
	t = s->next;
	if (r && r->shader && !bu_strncmp(r->shader, name, 8)) {
	    meh = s->next;
	    while (meh) {
		if (render_shader_init(r, meh->name, NULL) != -1)
		    goto LOADED;
		meh = meh->next;
	    }
	    bu_exit(-1, "Unable to find suitable shader\n");
	}
LOADED:

	if (s->dlh)
	    bu_dlclose(s->dlh);
	bu_free(s, "unload first shader");
	shaders = t;
	return 0;
    }

    while (s->next) {
	if (!bu_strncmp(s->next->name, name, 8)) {
	    if (r)
		render_shader_init(r, s->name, NULL);
	    if (s->next->dlh)
		bu_dlclose(s->next->dlh);
	    t = s->next;
	    s->next = s->next->next;
	    bu_free(t, "unload shader");
	    return 0;
	}
    }

    bu_log("Could not find shader \"%s\"\n", name);
#else
    bu_log("No plugin support.\n");
#endif
    return -1;
}
HIDDEN void
reassemble_argstr(struct bu_vls *instr, struct bu_vls *outstr, option::Option *unknowns)
{
    for (option::Option* opt = unknowns; opt; opt = opt->next()) {
	int input_only = 0;
	int output_only = 0;
	char *inputcpy = NULL;
	if (!instr || !outstr) return;
	inputcpy = bu_strdup(opt->name);
	if (!bu_strncmp(inputcpy, "--in-", 5)) input_only = 1;
	if (!bu_strncmp(inputcpy, "--out-", 5)) output_only = 1;
	char *equal_pos = strchr(inputcpy, '=');
	if (equal_pos) {
	    struct bu_vls vopt = BU_VLS_INIT_ZERO;
	    struct bu_vls varg = BU_VLS_INIT_ZERO;
	    bu_vls_sprintf(&vopt, "%s", inputcpy);
	    bu_vls_trunc(&vopt, -1 * strlen(equal_pos));
	    bu_vls_sprintf(&varg, "%s", inputcpy);
	    bu_vls_nibble(&varg, strlen(inputcpy) - strlen(equal_pos) + 1);
	    if (!output_only) {
		(bu_vls_strlen(&vopt) == 1) ? bu_vls_printf(instr, "-%s ", bu_vls_addr(&vopt)) : bu_vls_printf(instr, "%s ", bu_vls_addr(&vopt));
		if (bu_vls_strlen(&varg)) bu_vls_printf(instr, "%s ", bu_vls_addr(&varg));
	    }
	    if (!input_only) {
		(bu_vls_strlen(&vopt) == 1) ? bu_vls_printf(outstr, "-%s ", bu_vls_addr(&vopt)) : bu_vls_printf(outstr, "%s ", bu_vls_addr(&vopt));
		if (bu_vls_strlen(&varg)) bu_vls_printf(outstr, "%s ", bu_vls_addr(&varg));
	    }
	    bu_vls_free(&vopt);
	    bu_vls_free(&varg);
	} else {
	    if (!output_only) {
		(strlen(opt->name) == 1) ? bu_vls_printf(instr, "-%s ", opt->name) : bu_vls_printf(instr, "%s ", opt->name);
		if (opt->arg) bu_vls_printf(instr, "%s ", opt->arg);
	    }
	    if (!input_only) {
		(strlen(opt->name) == 1) ? bu_vls_printf(outstr, "-%s ", opt->name) : bu_vls_printf(outstr, "%s ", opt->name);
		if (opt->arg) bu_vls_printf(outstr, "%s ", opt->arg);
	    }
	}
	bu_free(inputcpy, "input cpy");
    }
}
Esempio n. 8
0
com_table *
get_comtab_ent(char *pattern, int pat_len)
{
    com_table *ctp;
    int len;

    for (ctp = ComTab; ctp->com_name; ++ctp) {
	len = FMAX(pat_len, (int)strlen(ctp->com_name));
	if ((bu_strncmp (pattern, ctp->com_name, len)) == 0)
	    break;
    }
    return (ctp->com_name) ? ctp : CT_NULL;
}
void
cm_attr(char *buffer, com_table *ctp, struct rt_i *UNUSED(rtip))
{
    while (isascii(*buffer) && isspace((int)*buffer)) buffer++;

    if (strlen(buffer) == 0) {
	com_usage(ctp);
	return;
    }

    if (! bu_strncmp(buffer, "-p", 2)) {
	attrib_print();
	return;
    }

    if (! bu_strncmp(buffer, "-f", 2)) {
	attrib_flush();
	return;
    }

    attrib_add(buffer, &need_prep);
}
Esempio n. 10
0
int
render_shader_init(render_t *r, const char *name, const char *buf)
{
    struct render_shader_s *s = shaders;
    while (s) {
	if (!bu_strncmp(s->name, name, 8)) {
	    s->init(r, buf);
	    r->shader = s->name;
	    return 0;
	}
	s = s->next;
    }
    bu_log("Shader \"%s\" not found\n", name);
    return -1;
}
Esempio n. 11
0
/**
 * List formats installed in global nirt data directory
 */
void
listformats(void)
{
    size_t files, i;
    char **filearray = NULL;
    char suffix[6]="*.nrt";
    FILE *cfPtr = NULL;
    int fnddesc;

    struct bu_vls nirtfilespath = BU_VLS_INIT_ZERO;
    struct bu_vls nirtpathtofile = BU_VLS_INIT_ZERO;
    struct bu_vls vlsfileline = BU_VLS_INIT_ZERO;

    /* get a nirt directory listing */
    bu_vls_printf(&nirtfilespath, "%s", bu_brlcad_data("nirt", 0));
    files = bu_dir_list(bu_vls_addr(&nirtfilespath), suffix, &filearray);

    /* open every nirt file we find and extract the description */
    for (i = 0; i < files; i++) {
	bu_vls_trunc(&nirtpathtofile, 0);
	bu_vls_trunc(&vlsfileline, 0);
	bu_vls_printf(&nirtpathtofile, "%s/%s", bu_vls_addr(&nirtfilespath), filearray[i]);
	cfPtr = fopen(bu_vls_addr(&nirtpathtofile), "rb");
	fnddesc = 0;
	while (bu_vls_gets(&vlsfileline, cfPtr) && fnddesc == 0) {
	    if (bu_strncmp(bu_vls_addr(&vlsfileline), "# Description: ", 15) == 0) {
		fnddesc = 1;
		bu_log("%s\n", bu_vls_addr(&vlsfileline)+15);
	    }
	    bu_vls_trunc(&vlsfileline, 0);
	}
	fclose(cfPtr);
    }

    /* release resources */
    bu_free_argv(files, filearray);
    bu_vls_free(&vlsfileline);
    bu_vls_free(&nirtfilespath);
    bu_vls_free(&nirtpathtofile);
}
Esempio n. 12
0
void
remove_region_attrs(Tcl_Obj *obj)
{
    int len = 0;
    Tcl_Obj **objs;
    char *key;
    int i, j;
    int found_material = 0;

    if (Tcl_ListObjGetElements(INTERP, obj, &len, &objs) != TCL_OK) {
	fprintf(stderr, "Cannot get length of attributes for %s\n",
		Tcl_GetStringFromObj(obj, NULL));
	bu_exit(1, NULL);
    }

    if (len == 0)
	return;

    for (i=len-1; i>0; i -= 2) {

	key = Tcl_GetStringFromObj(objs[i-1], NULL);
	j = 0;
	while (region_attrs[j]) {
	    if (BU_STR_EQUAL(key, region_attrs[j])) {
		Tcl_ListObjReplace(INTERP, obj, i-1, 2, 0, NULL);
		break;
	    }
	    j++;
	}
	if (!found_material && BU_STR_EQUAL(key, "material")) {
	    found_material = 1;
	    if (!bu_strncmp(Tcl_GetStringFromObj(objs[i], NULL), "gift", 4)) {
		Tcl_ListObjReplace(INTERP, obj, i-1, 2, 0, NULL);
	    }
	}
    }
}
Esempio n. 13
0
int
ged_keep(struct ged *gedp, int argc, const char *argv[])
{
    int i;
    struct keep_node_data knd;
    struct rt_wdb *keepfp;
    struct directory *dp;
    struct bu_vls title = BU_VLS_INIT_ZERO;
    struct db_i *new_dbip;
    const char *cmd = argv[0];
    static const char *usage = "[-R] file object(s)";

    int c;
    int flag_R = 0;

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

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

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage);
	return GED_HELP;
    }

    /* check for options */
    bu_optind = 1;
    while ((c = bu_getopt(argc, (char * const *)argv, "R")) != -1) {
	switch (c) {
	    case 'R':
		/* not recursively */
		flag_R = 1;
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c);
		return GED_ERROR;
	}
    }
    /* skip options processed plus command name */
    argc -= bu_optind;
    argv += bu_optind;

    if (argc < 2) {
	bu_vls_printf(gedp->ged_result_str, "ERROR: missing file or object names\n");
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage);
	return GED_ERROR;
    }

    /* First, clear any existing counts */
    for (i = 0; i < RT_DBNHASH; i++) {
	for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw)
	    dp->d_nref = 0;
    }

    /* Alert user if named file already exists */

    new_dbip = db_open(argv[0], DB_OPEN_READWRITE);

    if (new_dbip != DBI_NULL) {
	if (db_version(new_dbip) != db_version(gedp->ged_wdbp->dbip)) {
	    bu_vls_printf(gedp->ged_result_str, "%s: File format mismatch between '%s' and '%s'\n",
			  cmd, argv[0], gedp->ged_wdbp->dbip->dbi_filename);
	    return GED_ERROR;
	}

	if ((keepfp = wdb_dbopen(new_dbip, RT_WDB_TYPE_DB_DISK)) == NULL) {
	    bu_vls_printf(gedp->ged_result_str, "%s:  Error opening '%s'\n", cmd, argv[0]);
	    return GED_ERROR;
	} else {
	    bu_vls_printf(gedp->ged_result_str, "%s:  Appending to '%s'\n", cmd, argv[0]);

	    /* --- Scan geometry database and build in-memory directory --- */
	    db_dirbuild(new_dbip);
	}
    } else {
	/* Create a new database */
	keepfp = wdb_fopen_v(argv[0], db_version(gedp->ged_wdbp->dbip));

	if (keepfp == NULL) {
	    perror(argv[0]);
	    return GED_ERROR;
	}
    }

    knd.wdbp = keepfp;
    knd.gedp = gedp;

    /* ident record */
    if (bu_strncmp(gedp->ged_wdbp->dbip->dbi_title, "Parts of: ", 10) != 0) {
	bu_vls_strcat(&title, "Parts of: ");
    }
    bu_vls_strcat(&title, gedp->ged_wdbp->dbip->dbi_title);

    if (db_update_ident(keepfp->dbip, bu_vls_addr(&title), gedp->ged_wdbp->dbip->dbi_local2base) < 0) {
	perror("fwrite");
	bu_vls_printf(gedp->ged_result_str, "db_update_ident() failed\n");
	wdb_close(keepfp);
	bu_vls_free(&title);
	return GED_ERROR;
    }
    bu_vls_free(&title);

    for (i = 1; i < argc; i++) {
	if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL)
	    continue;

	if (!flag_R) {
	    /* recursively keep objects */
	    db_functree(gedp->ged_wdbp->dbip, dp, node_write, node_write, &rt_uniresource, (void *)&knd);
	} else {
	    /* keep just this object */
	    node_write(gedp->ged_wdbp->dbip, dp, (void *)&knd);
	}
    }

    wdb_close(keepfp);
    return GED_OK;
}
Esempio n. 14
0
int
ged_bot(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *bot_dp;
    struct rt_db_internal intern;
    struct rt_bot_internal *bot;
    const char *cmd = argv[0];
    const char *sub = NULL;
    const char *arg = NULL;
    const char *primitive = NULL;
    size_t len;
    fastf_t tmp;
    fastf_t propVal;
    static const char *usage = "get (faces|minEdge|maxEdge|orientation|type|vertices) bot\nchull bot_in bot_out\n";

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

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

    /* must be wanting help */
    if (argc < 3) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage);
	return GED_ERROR;
    }

    /* determine subcommand */
    sub = argv[1];
    len = strlen(sub);
    if (bu_strncmp(sub, "get", len) == 0) {
	primitive = argv[argc - 1];
    }
    if (bu_strncmp(sub, "chull", len) == 0) {
	primitive = argv[2];
    }
    if (primitive == NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: %s is not a known subcommand!", cmd, sub);
	return GED_ERROR;
    }

    /* get bot */
    GED_DB_LOOKUP(gedp, bot_dp, primitive, LOOKUP_NOISY, GED_ERROR & GED_QUIET);
    GED_DB_GET_INTERNAL(gedp, &intern, bot_dp, bn_mat_identity, &rt_uniresource, GED_ERROR);

    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!", cmd, primitive);
	return GED_ERROR;
    }

    bot = (struct rt_bot_internal *)intern.idb_ptr;
    RT_BOT_CK_MAGIC(bot);

    if (bu_strncmp(sub, "get", len) == 0) {

	arg = argv[2];
	propVal = rt_bot_propget(bot, arg);

	/* print result string */
	if (!EQUAL(propVal, -1.0)) {

	    tmp = (int) propVal;

	    /* int result */
	    if (EQUAL(propVal, tmp)) {
		bu_vls_printf(gedp->ged_result_str, "%d", (int) propVal);
	    }

	    /* float result */
	    else {
		bu_vls_printf(gedp->ged_result_str, "%f", propVal);
	    }
	} else {
	    bu_vls_printf(gedp->ged_result_str, "%s: %s is not a valid argument!", sub, arg);
	    return GED_ERROR;
	}
    }
    if (bu_strncmp(sub, "chull", len) == 0) {
	int retval = 0;
	int fc = 0;
	int vc = 0;
	point_t *vert_array;
	int *faces;
	unsigned char err = 0;

	/* must be wanting help */
	if (argc < 4) {
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage);
	    return GED_ERROR;
	}

	retval = bg_3d_chull(&faces, &fc, &vert_array, &vc, (const point_t *)bot->vertices, (int)bot->num_vertices);

	if (retval != 3) return GED_ERROR;

	retval = mk_bot(gedp->ged_wdbp, argv[3], RT_BOT_SOLID, RT_BOT_CCW, err, vc, fc, (fastf_t *)vert_array, faces, NULL, NULL);

	if (retval) return GED_ERROR;
    }

    return GED_OK;
}
Esempio n. 15
0
int
main( int argc, char *argv[] )
{
    char line[MAX_LINE_SIZE];
    char *input_file, *output_file;
    FILE *fd_parts;
    struct obj_info **top_level_assems = NULL;
    int top_level_assem_count = 0;
    int curr_top_level = -1;
    fastf_t tmp;
    int id;
    int c;

    bu_setprogname(argv[0]);

    local_tol = 0.0005;
    local_tol_sq = local_tol * local_tol;
    ident = 1000;

    while ( (c=bu_getopt( argc, argv, "vi:t:n:l:h?" ) ) != -1 ) {
	switch ( c ) {
	    case 'v':	/* verbose */
		verbose = 1;
		break;
	    case 'i':	/* starting ident number */
		ident = atoi( bu_optarg );
		break;
	    case 't':	/* tolerance */
		tmp = atof( bu_optarg );
		if ( tmp <= 0.0 )
		    bu_exit( 1, "%s: Illegal tolerance (%g), must be > 0.0\n", progname,tmp );
		break;
	    case 'n':	/* part name list */
		part_name_file = bu_optarg;
		use_part_name_hash = 1;
		break;
	    case 'l':	/* max name length */
		max_name_len = atoi( bu_optarg );
		if ( max_name_len < 5 )
		    bu_exit( 1, "%s: Unreasonable name length limitation\n",progname );
		break;
	    default:
		Usage();
		bu_exit( 1, NULL );
	}
    }

    if ( argc - bu_optind != 2 ) {
	bu_log( "Not enough arguments!! (need at least input & output file names)\n" );
	Usage();
	bu_exit( 1, NULL );
    }

    input_file = bu_strdup( argv[bu_optind] );

    if ((fd_in=fopen(input_file, "rb")) == NULL) {
	bu_log( "%s: Cannot open %s for reading\n", progname,input_file );
	perror( argv[0] );
	bu_exit( 1, NULL );
    }

    output_file = bu_strdup( argv[bu_optind+1] );

    if ( (fd_out=wdb_fopen( output_file )) == NULL ) {
	bu_log( "%s: Cannot open %s for writing\n", progname,output_file );
	perror( argv[0] );
	bu_exit( 1, NULL );
    }

    if ( use_part_name_hash ) {
	if ( (fd_parts=fopen( part_name_file, "rb" )) == NULL ) {
	    bu_log( "%s,Cannot open part name file (%s)\n", progname,part_name_file );
	    perror( argv[0] );
	    bu_exit( 1, NULL );
	}

	create_name_hash( fd_parts );
    }

    tree_root = create_vert_tree();

    /* finally, start processing the input */
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "FileName", 8 ) ) {
	    bu_log( "Converting facets originally from %s",
		    &line[9] );
	} else if ( !bu_strncmp( line, "TopAssemblies", 13 ) ) {
	    bu_log( "Top level assemblies: %s", &line[14] );
	    top_level_assem_count = atoi( &line[14] );
	    if ( top_level_assem_count < 1 ) {
		top_level_assems = (struct obj_info **)NULL;
	    } else {
		top_level_assems = (struct obj_info **)bu_calloc( top_level_assem_count,
								  sizeof( struct obj_info * ),
								  "top_level_assems" );
	    }
	} else if ( !bu_strncmp( line, "PartCount", 9 ) ) {
	    bu_log( "Part count: %s", &line[10] );
	} else if ( !bu_strncmp( line, "AssemblyId", 10 ) ) {
	    id = atoi( &line[11] );
	    curr_top_level++;
	    if ( curr_top_level >= top_level_assem_count ) {
		bu_log( "Warning: too many top level assemblies\n" );
		bu_log( "\texpected %d, this os number %d\n",
			top_level_assem_count, curr_top_level+1 );
		top_level_assem_count = curr_top_level+1;
		top_level_assems = (struct obj_info **)bu_realloc( top_level_assems,
								   top_level_assem_count *
								   sizeof( struct obj_info * ),
								   "top_level_assems" );
	    }
	    top_level_assems[curr_top_level] = Assembly_import( id );
	} else if ( !bu_strncmp( line, "PartId", 6 ) ) {
	    /* found a top-level part */
	    id = atoi( &line[7] );
	    (void)Part_import( id );
	}
    }

    if ( name_not_converted ) {
	bu_log( "Warning %d objects were not found in the part number to name mapping,\n",
		name_not_converted );
	bu_log( "\ttheir names remain as part numbers.\n" );
    }

    return 0;
}
Esempio n. 16
0
struct obj_info *
Assembly_import( int id_start )
{
    char line[MAX_LINE_SIZE];
    struct obj_info *this_assem, *member;
    struct wmember assem_head;
    int id_end, member_id;
    size_t i;

    BU_ALLOC(this_assem, struct obj_info);

    this_assem->obj_type = ASSEMBLY_TYPE;
    this_assem->obj_id = id_start;
    this_assem->part_count = 0;
    this_assem->members = NULL;
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "AssemblyName", 12 ) ) {
	    line[strlen( line ) - 1] = '\0';
	    this_assem->obj_name = bu_strdup( &line[13] );
	    lower_case( this_assem->obj_name );
	    DO_INDENT;
	    bu_log( "Start of assembly %s (id = %d)\n", this_assem->obj_name, id_start );
	    indent_level += indent_delta;
	} else if ( !bu_strncmp( line, "PartId", 6 ) ) {
	    /* found a member part */
	    member_id = atoi( &line[7] );
	    member = Part_import( member_id );
	    if ( !member )
		continue;
	    this_assem->part_count++;
	    this_assem->members = (struct obj_info **)bu_realloc(
		this_assem->members,
		this_assem->part_count * sizeof( struct obj_info *),
		"this_assem->members" );
	    this_assem->members[this_assem->part_count-1] = member;
	} else if ( !bu_strncmp( line, "AssemblyId", 10 ) ) {
	    /* found a member assembly */
	    member_id = atoi( &line[11] );
	    member = Assembly_import( member_id );
	    this_assem->part_count++;
	    this_assem->members = (struct obj_info **)bu_realloc(
		this_assem->members,
		this_assem->part_count * sizeof( struct obj_info *),
		"this_assem->members" );
	    this_assem->members[this_assem->part_count-1] = member;
	} else if ( !bu_strncmp( line, "EndAssemblyId", 13 ) ) {
	    /* found end of assembly, make sure it is this one */
	    id_end = atoi( &line[14] );
	    if ( id_end != id_start )
		bu_exit( 1, "%s: ERROR: found end of assembly id %d while processing id %d\n", progname,id_end, id_start );
	    indent_level -= indent_delta;
	    DO_INDENT;
	    bu_log( "Found end of assembly %s (id = %d)\n",  this_assem->obj_name, id_start );
	    break;
	} else {
	    bu_log( "%s: Unrecognized line encountered while processing assembly id %d:\n", progname,id_start );
	    bu_exit( 1, "%s\n", line );
	}
    }

    Make_brlcad_names( this_assem );

    /* write this assembly to the database */
    BU_LIST_INIT( &assem_head.l );

    for ( i=0; i<this_assem->part_count; i++ )
	if ( mk_addmember( this_assem->members[i]->brlcad_comb,
			   &assem_head.l, NULL, WMOP_UNION ) == WMEMBER_NULL )
	    bu_exit( 1, "%s: ERROR: Failed to add region %s to assembly %s\n",
			progname,this_assem->members[i]->brlcad_comb, this_assem->brlcad_comb );

    if ( mk_comb( fd_out, this_assem->brlcad_comb, &assem_head.l, 0, NULL, NULL, NULL,
		  0, 0, 0, 0, 0, 0, 0 ) )
	bu_exit( 1, "%s: ERROR: Failed to write combination (%s) to database\n", progname,this_assem->brlcad_comb );
    if ( use_part_name_hash ) {
	if ( db5_update_attribute( this_assem->brlcad_comb, "Part_No",
				   this_assem->obj_name, fd_out->dbip ) ) {
	    bu_log( "Failed to assign Part_no attribute to %s\n",
		    this_assem->brlcad_comb );
	}
    }

    return this_assem;
}
Esempio n. 17
0
struct obj_info *
Part_import( int id_start )
{
    char line[MAX_LINE_SIZE];
    struct obj_info *part;
    struct wmember reg_head;
    unsigned char rgb[3];
    int surf_count=0;
    int id_end;
    int last_surf=0;
    int i;
    int tri[3];
    int corner_index=-1;

    clean_vert_tree( tree_root );

    VSETALL( rgb, 128 );

    BU_ALLOC(part, struct obj_info);
    part->obj_type = PART_TYPE;
    part->obj_id = id_start;
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "PartName", 8 ) ) {
	    line[strlen( line ) - 1] = '\0';
	    part->obj_name = bu_strdup( &line[9] );
	    lower_case( part->obj_name );
	    Make_brlcad_names( part );
	} else if ( !bu_strncmp( line, "FaceCount", 9 ) ) {
	    surf_count = atoi( &line[10] );
	    if ( surf_count == 0 ) {
		last_surf = 1;
	    }
	} else if ( !bu_strncmp( line, "EndPartId", 9 ) ) {
	    /* found end of part, check id */
	    id_end = atoi( &line[10] );
	    if ( id_end != id_start )
		bu_exit( 1, "%s: ERROR: found end of part id %d while processing part %d\n", progname,id_end, id_start );
	    if ( last_surf ) {
		break;
	    }
	} else if ( !bu_strncmp( line, "FaceRGB", 7 ) ) {
	    /* get face color */
	    char *ptr;

	    i = 8;
	    ptr = strtok( &line[i], " \t" );
	    for ( i=0; i<3 && ptr; i++ ) {
		rgb[i] = atof( ptr );
		ptr = strtok( (char *)NULL, " \t" );
	    }
	} else if ( !bu_strncmp( line, "Facet", 5 ) ) {
	    /* read a triangle */
	    VSETALL( tri, -1 );
	    corner_index = -1;
	} else if ( !bu_strncmp( line, "Face", 4 ) ) {
	    /* start of a surface */
	    int surf_no;

	    surf_no = atoi( &line[5] );
	    if ( surf_no == surf_count ) {
		last_surf = 1;
	    }
	} else if ( !bu_strncmp( line, "TriangleCount", 13 ) ) {
	    /* get number of triangles for this surface */
	} else if ( !bu_strncmp( line, "Vertices", 9 ) ) {
	    /* get vertex list for this triangle */
	} else if ( !bu_strncmp( line, "Vertex", 6 ) ) {
	    /* get a vertex */
	    char *ptr = NULL;
	    vect_t v = VINIT_ZERO;

	    i = 7;
	    while ( !isspace( (int)line[i] ) && line[i] != '\0' )
		i++;
	    ptr = strtok( &line[i], " \t" );
	    for ( i=0; i<3 && ptr; i++ ) {
		v[i] = atof( ptr );
		ptr = strtok( (char *)NULL, " \t" );
	    }
	    tri[++corner_index] = Add_vert( V3ARGS( v ), tree_root, local_tol_sq );
	    if ( corner_index == 2 ) {
		if ( !bad_triangle( tri, tree_root->the_array ) ) {
		    add_triangle( tri );
		}
	    }
	} else if ( !bu_strncmp( line, "Normal", 6 ) ) {
	    /* get a vertex normal */
	} else if ( !bu_strncmp( line, "PointCount", 10 ) ) {
	    /* get number of vertices for this surface */
	} else
	    bu_exit( 1, "%s: ERROR: unrecognized line encountered while processing part id %d:\n%s\n", progname,id_start, line );
    }

    if ( curr_tri == 0 ) {
	/* no facets in this part, so ignore it */
	bu_free( (char *)part, "part" );
	part = (struct obj_info *)NULL;
    } else {

	/* write this part to database, first make a primitive solid */
	if ( mk_bot( fd_out, part->brlcad_solid, RT_BOT_SOLID, RT_BOT_UNORIENTED, 0,
		     tree_root->curr_vert, curr_tri, tree_root->the_array, part_tris, NULL, NULL ) )
	    bu_exit( 1, "%s: Failed to write primitive %s (%s) to database\n", progname,part->brlcad_solid, part->obj_name );
	if ( verbose ) {
	    DO_INDENT;
	    bu_log( "Wrote BOT %s\n", part->brlcad_solid );
	}

	/* then a region */
	BU_LIST_INIT( &reg_head.l );
	if ( mk_addmember( part->brlcad_solid, &reg_head.l, NULL, WMOP_UNION ) == WMEMBER_NULL )
	    bu_exit( 1, "%s: ERROR: Failed to add solid (%s), to region (%s)\n", progname,part->brlcad_solid, part->brlcad_comb );
	if ( mk_comb( fd_out, part->brlcad_comb, &reg_head.l, 1, NULL, NULL, rgb, ident++,
		      0, 1, 100, 0, 0, 0 ) )
	    bu_exit( 1, "%s: Failed to write region %s (%s) to database\n", progname,part->brlcad_comb, part->obj_name );
	if ( verbose ) {
	    DO_INDENT;
	    bu_log( "Wrote region %s\n", part->brlcad_comb );
	}

	if ( use_part_name_hash ) {
	    if ( db5_update_attribute( part->brlcad_comb, "Part_No",
				       part->obj_name, fd_out->dbip ) ) {
		bu_log( "Failed to assign Part_no attribute to %s\n",
			part->brlcad_comb );
	    }
	}
    }

    /* free some memory */
    if ( part_tris ) {
	bu_free( (char *)part_tris, "part_tris" );
    }
    max_tri = 0;
    curr_tri = 0;
    part_tris = NULL;

    return part;
}
Esempio n. 18
0
HIDDEN int
mem_open(FBIO *ifp, const char *file, int width, int height)
{
    int mode;
    const char *cp;
    FBIO *fbp;
    char modebuf[80];
    char *mp;
    int alpha;
    struct modeflags *mfp;

    FB_CK_FBIO(ifp);

    /* This function doesn't look like it will work if file
     * is NULL - stop before we start, if that's the case.*/
    if (file == NULL) return -1;

    /*
     * First, attempt to determine operating mode for this open,
     * based upon the "unit number" or flags.
     * file = "/dev/mem###"
     * The default mode is zero.
     */
    mode = 0;

	if (bu_strncmp(file, "/dev/mem", 8)) {
	    /* How did this happen?? */
	    mode = 0;
	} else {
	    /* Parse the options */
	    alpha = 0;
	    mp = &modebuf[0];
	    cp = &file[8];
	    while (*cp != '\0' && !isspace((int)*cp)) {
		*mp++ = *cp;	/* copy it to buffer */
		if (isdigit((int)*cp)) {
		    cp++;
		    continue;
		}
		alpha++;
		for (mfp = modeflags; mfp->c != '\0'; mfp++) {
		    if (mfp->c == *cp) {
			mode = (mode&~mfp->mask)|mfp->value;
			break;
		    }
		}
		if (mfp->c == '\0' && *cp != '-') {
		    fb_log("if_mem: unknown option '%c' ignored\n", *cp);
		}
		cp++;
	    }
	    *mp = '\0';
	    if (!alpha)
		mode = atoi(modebuf);
	}

    /* build a local static info struct */
    if ((MIL(ifp) = (char *)calloc(1, sizeof(struct mem_info))) == NULL) {
	fb_log("mem_open:  mem_info malloc failed\n");
	return -1;
    }
    cp = &file[strlen("/dev/mem")];
    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
	cp++;	/* skip suffix */
    while (*cp != '\0' && (*cp == ' ' || *cp == '\t' || *cp == ';'))
	cp++;	/* skip blanks and separators */

    if (*cp) {
	/* frame buffer device specified */
	if ((fbp = fb_open(cp, width, height)) == FBIO_NULL) {
	    free(MIL(ifp));
	    return -1;
	}
	MI(ifp)->fbp = fbp;
	ifp->if_width = fbp->if_width;
	ifp->if_height = fbp->if_height;
	ifp->if_selfd = fbp->if_selfd;
	if ((mode & MODE_1MASK) == MODE_1IMMEDIATE)
	    MI(ifp)->write_thru = 1;
    } else {
	/* no frame buffer specified */
	if (width > 0)
	    ifp->if_width = width;
	if (height > 0)
	    ifp->if_height = height;
    }
    if ((MI(ifp)->mem = (unsigned char *)calloc(ifp->if_width*ifp->if_height, 3)) == NULL) {
	fb_log("mem_open:  memory buffer malloc failed\n");
	(void)free(MIL(ifp));
	return -1;
    }
    if ((MI(ifp)->fbp != FBIO_NULL)
	&& (mode & MODE_2MASK) == MODE_2PREREAD) {
	/* Pre read all of the image data and cmap */
	int got;
	got = fb_readrect(MI(ifp)->fbp, 0, 0,
			  ifp->if_width, ifp->if_height,
			  (unsigned char *)MI(ifp)->mem);
	if (got != ifp->if_width * ifp->if_height) {
	    fb_log("if_mem:  WARNING: pre-read of %d only got %d, your image is truncated.\n",
		   ifp->if_width * ifp->if_height, got);
	}
	if (fb_rmap(MI(ifp)->fbp, &(MI(ifp)->cmap)) < 0)
	    fb_make_linear_cmap(&(MI(ifp)->cmap));
    } else {
	/* Image data begins black, colormap linear */
	fb_make_linear_cmap(&(MI(ifp)->cmap));
    }

    return 0;
}
Esempio n. 19
0
/*
 * Called from db_walk_tree().
 *
 * This routine must be prepared to run in parallel.
 */
union tree *
do_nmg_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *UNUSED(client_data))
{
    union tree *result;
    struct nmgregion *r;
    struct bu_list vhead;
    struct directory *dp;
    int dependent;
    size_t i;

    RT_CK_TESS_TOL(tsp->ts_ttol);
    BN_CK_TOL(tsp->ts_tol);
    NMG_CK_MODEL(*tsp->ts_m);

    BU_LIST_INIT(&vhead);

    if (RT_G_DEBUG&DEBUG_TREEWALK || verbose) {
	char *sofar = db_path_to_string(pathp);
	bu_log("\ndo_nmg_region_end(%d %d%%) %s\n",
	       regions_tried,
	       regions_tried>0 ? (regions_done * 100) / regions_tried : 0,
	       sofar);
	bu_free(sofar, "path string");
    }

    if (curtree->tr_op == OP_NOP)
	return curtree;

    regions_tried++;

    if (verbose)
	bu_log("\ndoing boolean tree evaluate...\n");

    /* evaluate the boolean */
    result = process_boolean(tsp, curtree, pathp);

    if (result)
	r = result->tr_d.td_r;
    else
	r = (struct nmgregion *)NULL;

    if (verbose)
	bu_log("\nfinished boolean tree evaluate...\n");

    regions_done++;
    if (r != NULL) {

	dp = DB_FULL_PATH_CUR_DIR(pathp);

	if (multi_file) {
	    /* Open the output file */
	    if (output_file == NULL)
		fp_dir = stdout;
	    else {
		char *multi_name;
		size_t len;
		int unique = 0;
		char suffix[SUFFIX_LEN+1];

		/* construct a unique file name */
		len = strlen(output_file) + strlen(dp->d_namep) + 6 + SUFFIX_LEN;
		multi_name = (char *)bu_malloc(sizeof(char)*len, "multi_name");
		snprintf(multi_name, len, "%s/%s.igs", output_file, dp->d_namep);
		bu_strlcpy(suffix, "a", sizeof(suffix));
		suffix[0]--;
		while (!unique) {
		    if (bu_file_readable(multi_name)) {
			unique = 1;
			break;
		    }

		    /* not unique, try adding a suffix */
		    len = strlen(suffix);
		    i = len - 1;
		    suffix[i]++;
		    while (suffix[i] > 'z' && i > 0) {
			suffix[i] = 'a';
			i--;
			suffix[i]++;
		    }

		    if (suffix[0] > 'z' && len < SUFFIX_LEN) {
			for (i = 0; i <= len; i++)
			    suffix[i] = 'a';
		    } else if (suffix[0] > 'z' && len >= SUFFIX_LEN) {
			bu_log("too many files with the same name (%s)\n", dp->d_namep);
			bu_exit(1, "Cannot create a unique filename, \n");
		    }
		    snprintf(multi_name, len, "%s/%s%s.igs", output_file, dp->d_namep, suffix);
		}
		if ((fp_dir = fopen(multi_name, "wb")) == NULL) {
		    perror("g-iges");
		    bu_exit(1, "Cannot open output file: %s\n", multi_name);
		}
	    }

	    /* Open the temporary file for the parameter section */
	    if ((fp_param = bu_temp_file(NULL, 0)) == NULL) {
		perror("g-iges");
		bu_exit(1, "Cannot open temporary file\n");
	    }

	    /* let the IGES routines know the selected tolerances and the database pointer */
	    iges_init(&tol, &ttol, verbose, DBIP);

	    /* Write start and global sections of the IGES file */
	    w_start_global(fp_dir, fp_param, db_name, prog_name, output_file, __DATE__, brlcad_version());
	}

	if (mode == FACET_MODE) {
	    dependent = 1;
	    for (i = 0; i < no_of_indeps; i++) {
		if (!bu_strncmp(dp->d_namep, independent[i], NAMESIZE+1)) {
		    dependent = 0;
		    break;
		}
	    }

	    dp->d_uses = (-nmgregion_to_iges(dp->d_namep, r, dependent, fp_dir, fp_param));
	} else if (mode == TRIMMED_SURF_MODE)
	    dp->d_uses = (-nmgregion_to_tsurf(dp->d_namep, r, fp_dir, fp_param));

	/* NMG region is no longer necessary */
	nmg_kr(r);

	if (multi_file) {
	    char copy_buffer[CP_BUF_SIZE] = {0};

	    /* Copy the parameter section from the temporary file to the output file */
	    if ((bu_fseek(fp_param, 0, 0))) {
		perror("g-iges");
		bu_exit(1, "Cannot seek to start of temporary file\n");
	    }

	    while ((i = fread(copy_buffer, 1, CP_BUF_SIZE, fp_param)))
		if (fwrite(copy_buffer, 1, i, fp_dir) != i) {
		    perror("g-iges");
		    bu_exit(1, "Error in copying parameter data to %s\n", output_file);
		}

	    /* Write the terminate section */
	    w_terminate(fp_dir);
	    fclose(fp_dir);
	    fclose(fp_param);
	}
    }

    /*
     * Dispose of original tree, so that all associated dynamic
     * memory is released now, not at the end of all regions.
     * A return of TREE_NULL from this routine signals an error,
     * so we need to cons up an OP_NOP node to return.
     */
    db_free_tree(curtree, &rt_uniresource);		/* Does an nmg_kr() */

    BU_ALLOC(curtree, union tree);
    RT_TREE_INIT(curtree);
    curtree->tr_op = OP_NOP;
    return curtree;
}
Esempio n. 20
0
void
verify_region_attrs(struct directory *dp, struct db_i *dbip, Tcl_Obj *obj)
{
    Tcl_Obj **objs;
    int len = 0;
    int i;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;

    if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) {
	fprintf(stderr, "Cannot import %s\n", dp->d_namep);
	bu_exit(1, NULL);
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CHECK_COMB(comb);

    if (Tcl_ListObjGetElements(INTERP, obj, &len, &objs) != TCL_OK) {
	fprintf(stderr, "Cannot get length of attributes for %s\n", dp->d_namep);
	bu_exit(1, NULL);
    }

    for (i=1; i<len; i += 2) {
	char *key, *value;

	key = Tcl_GetStringFromObj(objs[i-1], NULL);
	value = Tcl_GetStringFromObj(objs[i], NULL);
	if (BU_STR_EQUAL(key, "region_id")) {
	    long id;

	    id = strtol(value, NULL, 0);
	    if (id != comb->region_id) {
		fprintf(stderr, "WARNING: %s in %s: \"region_id\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, id, comb->region_id);
	    }
	} else if (BU_STR_EQUAL(key, "giftmater")) {
	    long GIFTmater;

	    GIFTmater = strtol(value, NULL, 0);
	    if (GIFTmater != comb->GIFTmater) {
		fprintf(stderr, "WARNING: %s in %s: \"giftmater\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, GIFTmater, comb->GIFTmater);
	    }
	} else if (BU_STR_EQUAL(key, "los")) {
	    long los;

	    los = strtol(value, NULL, 0);
	    if (los != comb->los) {
		fprintf(stderr, "WARNING: %s in %s: \"los\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, los, comb->los);
	    }
	} else if (BU_STR_EQUAL(key, "material")) {
	    if (!bu_strncmp(value, "gift", 4)) {
		long GIFTmater;

		GIFTmater = strtol(&value[4], NULL, 0);
		if (GIFTmater != comb->GIFTmater) {
		    fprintf(stderr, "WARNING: %s in %s: \"material\" attribute says %s, while region says %ld\n",
			    dp->d_namep, dbip->dbi_filename, value, comb->GIFTmater);
		}
	    }
	} else if (BU_STR_EQUAL(key, "aircode")) {
	    long aircode;

	    aircode = strtol(value, NULL, 0);
	    if (aircode != comb->aircode) {
		fprintf(stderr, "WARNING: %s in %s: \"aircode\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, aircode, comb->aircode);
	    }
	}
    }
    rt_db_free_internal(&intern);
}
void
nmg_2_vrml(struct db_tree_state *tsp, const struct db_full_path *pathp, struct model *m)
{
    struct mater_info *mater = &tsp->ts_mater;
    const struct bn_tol *tol2 = tsp->ts_tol;
    struct nmgregion *reg;
    struct bu_ptbl verts;
    struct vrml_mat mat;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    char *tok;
    int i;
    int first = 1;
    int is_light = 0;
    point_t ave_pt = VINIT_ZERO;
    struct bu_vls shape_name = BU_VLS_INIT_ZERO;
    char *full_path;
    /* There may be a better way to capture the region_id, than
     * getting the rt_comb_internal structure, (and may be a better
     * way to capture the rt_comb_internal struct), but for now I just
     * copied the method used in select_lights/select_non_lights above,
     * could have used a global variable but I noticed none other were
     * used, so I didn't want to be the first
     */
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    /* static due to libbu exception handling */
    static float r, g, b;

    NMG_CK_MODEL(m);

    full_path = db_path_to_string(pathp);

    RT_CK_FULL_PATH(pathp);
    dp = DB_FULL_PATH_CUR_DIR(pathp);

    if (!(dp->d_flags & RT_DIR_COMB)) {
	return;
    }

    id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource);
    if (id < 0) {
	bu_log("Cannot internal form of %s\n", dp->d_namep);
	return;
    }

    if (id != ID_COMBINATION) {
	bu_log("Directory/database mismatch!\n\t is '%s' a combination or not?\n",
		dp->d_namep);
	return;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    if (mater->ma_color_valid) {
	r = mater->ma_color[0];
	g = mater->ma_color[1];
	b = mater->ma_color[2];
    } else {
	r = g = b = 0.5;
    }

    if (mater->ma_shader) {
	tok = strtok(mater->ma_shader, tok_sep);
	bu_strlcpy(mat.shader, tok, TXT_NAME_SIZE);
    } else {
	mat.shader[0] = '\0';
    }

    mat.shininess = -1;
    mat.transparency = -1.0;
    mat.lt_fraction = -1.0;
    VSETALL(mat.lt_dir, 0.0);
    mat.lt_angle = -1.0;
    mat.tx_file[0] = '\0';
    mat.tx_w = -1;
    mat.tx_n = -1;
    bu_vls_strcpy(&vls, &mater->ma_shader[strlen(mat.shader)]);
    (void)bu_struct_parse(&vls, vrml_mat_parse, (char *)&mat, NULL);

    if (bu_strncmp("light", mat.shader, 5) == 0) {
	/* this is a light source */
	is_light = 1;
    } else {
	path_2_vrml_id(&shape_name, full_path);
	fprintf(fp_out, "\t\tDEF %s Shape {\n", bu_vls_addr(&shape_name));

	fprintf(fp_out, "\t\t\t# Component_ID: %ld   %s\n", comb->region_id, full_path);
	fprintf(fp_out, "\t\t\tappearance Appearance {\n");

	if (bu_strncmp("plastic", mat.shader, 7) == 0) {
	    if (mat.shininess < 0) {
		mat.shininess = 10;
	    }
	    if (mat.transparency < SMALL_FASTF) {
		mat.transparency = 0.0;
	    }

	    fprintf(fp_out, "\t\t\t\tmaterial Material {\n");
	    fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b);
	    fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0));
	    if (mat.transparency > SMALL_FASTF) {
		fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency);
	    }
	    fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0);
	} else if (bu_strncmp("glass", mat.shader, 5) == 0) {
	    if (mat.shininess < 0) {
		mat.shininess = 4;
	    }
	    if (mat.transparency < SMALL_FASTF) {
		mat.transparency = 0.8;
	    }

	    fprintf(fp_out, "\t\t\t\tmaterial Material {\n");
	    fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b);
	    fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0));
	    if (mat.transparency > SMALL_FASTF) {
		fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency);
	    }
	    fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0);
	} else if (bu_strncmp("texture", mat.shader, 7) == 0) {
	    if (mat.tx_w < 0) {
		mat.tx_w = 512;
	    }
	    if (mat.tx_n < 0) {
		mat.tx_n = 512;
	    }
	    if (strlen(mat.tx_file)) {
		int tex_fd;
		unsigned char tex_buf[TXT_BUF_LEN * 3];

		if ((tex_fd = open(mat.tx_file, O_RDONLY | O_BINARY)) == (-1)) {
		    bu_log("Cannot open texture file (%s)\n", mat.tx_file);
		    perror("g-vrml: ");
		} else {
		    long tex_len;
		    long bytes_read = 0;
		    long bytes_to_go = 0;

		    /* Johns note - need to check (test) the texture stuff */
		    fprintf(fp_out, "\t\t\t\ttextureTransform TextureTransform {\n");
		    fprintf(fp_out, "\t\t\t\t\tscale 1.33333 1.33333\n\t\t\t\t}\n");
		    fprintf(fp_out, "\t\t\t\ttexture PixelTexture {\n");
		    fprintf(fp_out, "\t\t\t\t\trepeatS TRUE\n");
		    fprintf(fp_out, "\t\t\t\t\trepeatT TRUE\n");
		    fprintf(fp_out, "\t\t\t\t\timage %d %d %d\n", mat.tx_w, mat.tx_n, 3);
		    tex_len = mat.tx_w*mat.tx_n * 3;
		    while (bytes_read < tex_len) {
			int nbytes;
			long readval;

			bytes_to_go = tex_len - bytes_read;
			CLAMP(bytes_to_go, 0, TXT_BUF_LEN * 3);

			nbytes = 0;
			while (nbytes < bytes_to_go) {
			    readval = read(tex_fd, &tex_buf[nbytes], bytes_to_go-nbytes);
			    if (readval < 0) {
				perror("READ ERROR");
				break;
			    } else {
				nbytes += readval;
			    }
			}
			bytes_read += nbytes;
			for (i = 0; i < nbytes; i += 3) {
			    fprintf(fp_out, "\t\t\t0x%02x%02x%02x\n",
				    tex_buf[i], tex_buf[i+1], tex_buf[i+2]);
			}
		    }
		    fprintf(fp_out, "\t\t\t\t}\n");

		    close(tex_fd);
		}
	    }
	} else if (mater->ma_color_valid) {
	    /* no shader specified, but a color is assigned */
	    fprintf(fp_out, "\t\t\t\tmaterial Material {\n");
	    fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g }\n", r, g, b);
	} else {
	    /* If no color was defined set the colors according to the thousands groups */
	    int thou = comb->region_id / 1000;
	    thou == 0 ? fprintf(fp_out, "\t\t\tmaterial USE Material_999\n")
		: thou == 1 ? fprintf(fp_out, "\t\t\tmaterial USE Material_1999\n")
		: thou == 2 ? fprintf(fp_out, "\t\t\tmaterial USE Material_2999\n")
		: thou == 3 ? fprintf(fp_out, "\t\t\tmaterial USE Material_3999\n")
		: thou == 4 ? fprintf(fp_out, "\t\t\tmaterial USE Material_4999\n")
		: thou == 5 ? fprintf(fp_out, "\t\t\tmaterial USE Material_5999\n")
		: thou == 6 ? fprintf(fp_out, "\t\t\tmaterial USE Material_6999\n")
		: thou == 7 ? fprintf(fp_out, "\t\t\tmaterial USE Material_7999\n")
		: thou == 8 ? fprintf(fp_out, "\t\t\tmaterial USE Material_8999\n")
		: fprintf(fp_out, "\t\t\tmaterial USE Material_9999\n");
	}
    }

    if (!is_light) {
	nmg_triangulate_model(m, tol2);
	fprintf(fp_out, "\t\t\t}\n");
	fprintf(fp_out, "\t\t\tgeometry IndexedFaceSet {\n");
	fprintf(fp_out, "\t\t\t\tcoord Coordinate {\n");
    }

    /* get list of vertices */
    nmg_vertex_tabulate(&verts, &m->magic);
    if (!is_light) {
	fprintf(fp_out, "\t\t\t\t\tpoint [");
    } else {
	VSETALL(ave_pt, 0.0);
    }

    for (i = 0; i < BU_PTBL_END(&verts); i++) {
	struct vertex *v;
	struct vertex_g *vg;
	point_t pt_meters;

	v = (struct vertex *)BU_PTBL_GET(&verts, i);
	NMG_CK_VERTEX(v);
	vg = v->vg_p;
	NMG_CK_VERTEX_G(vg);

	/* convert to desired units */
	VSCALE(pt_meters, vg->coord, scale_factor);

	if (is_light) {
	    VADD2(ave_pt, ave_pt, pt_meters);
	}

	if (first) {
	    if (!is_light) {
		fprintf(fp_out, " %10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i);
	    }
	    first = 0;
	} else if (!is_light) {
	    fprintf(fp_out, "\t\t\t\t\t%10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i);
	}
    }

    if (!is_light) {
	fprintf(fp_out, "\t\t\t\t\t]\n\t\t\t\t}\n");
    } else {
	fastf_t one_over_count;
	one_over_count = 1.0/(fastf_t)BU_PTBL_END(&verts);
	VSCALE(ave_pt, ave_pt, one_over_count);
    }

    first = 1;
    if (!is_light) {
	fprintf(fp_out, "\t\t\t\tcoordIndex [\n");
	for (BU_LIST_FOR(reg, nmgregion, &m->r_hd)) {
	    struct shell *s;

	    NMG_CK_REGION(reg);
	    for (BU_LIST_FOR(s, shell, &reg->s_hd)) {
		struct faceuse *fu;

		NMG_CK_SHELL(s);
		for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
		    struct loopuse *lu;

		    NMG_CK_FACEUSE(fu);

		    if (fu->orientation != OT_SAME) {
			continue;
		    }

		    for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
			struct edgeuse *eu;

			NMG_CK_LOOPUSE(lu);
			if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) {
			    continue;
			}

			if (!first) {
			    fprintf(fp_out, ",\n");
			} else {
			    first = 0;
			}

			fprintf(fp_out, "\t\t\t\t\t");
			for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
			    struct vertex *v;

			    NMG_CK_EDGEUSE(eu);
			    v = eu->vu_p->v_p;
			    NMG_CK_VERTEX(v);
			    fprintf(fp_out, " %d,", bu_ptbl_locate(&verts, (long *)v));
			}
			fprintf(fp_out, "-1");
		    }
		}
	    }
	}
	fprintf(fp_out, "\n\t\t\t\t]\n\t\t\t\tnormalPerVertex FALSE\n");
	fprintf(fp_out, "\t\t\t\tconvex FALSE\n");
	fprintf(fp_out, "\t\t\t\tcreaseAngle 0.5\n");
	fprintf(fp_out, "\t\t\t}\n\t\t}\n");
    } else {
Esempio n. 22
0
/**
 * R E A D _ M A T
 */
void read_mat (struct rt_i *rtip)
{
    double scan[16] = MAT_INIT_ZERO;
    char	*buf;
    int		status = 0x0;
    mat_t	m;
    mat_t       q;

    while ((buf = rt_read_cmd(stdin)) != (char *) 0) {
	if (bu_strncmp(buf, "eye_pt", 6) == 0) {
	    if (sscanf(buf + 6, "%lf%lf%lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
		bu_exit(1, "nirt: read_mat(): Failed to read eye_pt\n");
	    }
	    target(X) = scan[X];
	    target(Y) = scan[Y];
	    target(Z) = scan[Z];
	    status |= RMAT_SAW_EYE;
	} else if (bu_strncmp(buf, "orientation", 11) == 0) {
	    if (sscanf(buf + 11,
		       "%lf%lf%lf%lf",
		       &scan[X], &scan[Y], &scan[Z], &scan[W]) != 4) {
		bu_exit(1, "nirt: read_mat(): Failed to read orientation\n");
	    }
	    MAT_COPY(q, scan);
	    quat_quat2mat(m, q);
	    if (nirt_debug & DEBUG_MAT)
		bn_mat_print("view matrix", m);
	    azimuth() = atan2(-m[0], m[1]) / DEG2RAD;
	    elevation() = atan2(m[10], m[6]) / DEG2RAD;
	    status |= RMAT_SAW_ORI;
	} else if (bu_strncmp(buf, "viewrot", 7) == 0) {
	    if (sscanf(buf + 7,
		       "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
		       &scan[0], &scan[1], &scan[2], &scan[3],
		       &scan[4], &scan[5], &scan[6], &scan[7],
		       &scan[8], &scan[9], &scan[10], &scan[11],
		       &scan[12], &scan[13], &scan[14], &scan[15]) != 16) {
		bu_exit(1, "nirt: read_mat(): Failed to read viewrot\n");
	    }
	    MAT_COPY(m, scan);
	    if (nirt_debug & DEBUG_MAT)
		bn_mat_print("view matrix", m);
	    azimuth() = atan2(-m[0], m[1]) / DEG2RAD;
	    elevation() = atan2(m[10], m[6]) / DEG2RAD;
	    status |= RMAT_SAW_VR;
	}
    }

    if ((status & RMAT_SAW_EYE) == 0) {
	bu_exit(1, "nirt: read_mat(): Was given no eye_pt\n");
    }
    if ((status & (RMAT_SAW_ORI | RMAT_SAW_VR)) == 0) {
	bu_exit(1, "nirt: read_mat(): Was given no orientation or viewrot\n");
    }

    direct(X) = -m[8];
    direct(Y) = -m[9];
    direct(Z) = -m[10];

    dir2ae();

    targ2grid();
    shoot("", 0, rtip);
}
Esempio n. 23
0
int
ged_importFg4Section(struct ged *gedp, int argc, const char *argv[])
{
    char *cp;
    char *line;
    char *lines;
    int eosFlag = 0;
    static const char *usage = "obj section";

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

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

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    if (argc != 3) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    grid_size = GRID_BLOCK;
    grid_pts = (point_t *)bu_malloc(grid_size * sizeof(point_t) ,
				    "importFg4Section: grid_pts");

    lines = strdup(argv[2]);
    cp = line = lines;

    FIND_NEWLINE(cp, eosFlag);

    bu_strlcpy(field, line+8, sizeof(field));
    group_id = atoi(field);

    bu_strlcpy(field, line+16, sizeof(field));
    comp_id = atoi(field);

    region_id = group_id * 1000 + comp_id;

    if (comp_id > 999) {
	bu_log("Illegal component id number %d, changed to 999\n", comp_id);
	comp_id = 999;
    }

    bu_strlcpy(field, line+24, sizeof(field));
    mode = atoi(field);
    if (mode != 1 && mode != 2) {
	bu_log("Illegal mode (%d) for group %d component %d, using volume mode\n",
	       mode, group_id, comp_id);
	mode = 2;
    }

    while (!eosFlag) {
	++cp;
	line = cp;
	FIND_NEWLINE(cp, eosFlag);

	if (!bu_strncmp(line, "GRID", 4))
	    do_grid(line);
	else if (!bu_strncmp(line, "CTRI", 4))
	    do_tri(line);
	else if (!bu_strncmp(line, "CQUAD", 4))
	    do_quad(line);
    }

    make_bot_object(argv[1], gedp->ged_wdbp);
    free((void *)lines);
    bu_free((void *)grid_pts, "importFg4Section: grid_pts");

    /* free memory associated with globals */
    bu_free((void *)faces, "importFg4Section: faces");
    bu_free((void *)thickness, "importFg4Section: thickness");
    bu_free((void *)facemode, "importFg4Section: facemode");

    faces = NULL;
    thickness = NULL;
    facemode = NULL;

    return TCL_OK;
}
Esempio n. 24
0
int
main(int argc, char *argv[])
{
    int length, frame_number, number, success, maxnum;
    int first_frame, spread, reserve;
    off_t last_pos;
    char line[MAXLEN];
    char pbuffer[MAXLEN*MAXLINES];


    if (!get_args(argc, argv))
	fprintf(stderr, "Get_args error\n");

    /* copy any lines preceding the first "start" command */
    last_pos = bu_ftell(stdin);
    while (bu_fgets(line, MAXLEN, stdin)!=NULL) {
	if (bu_strncmp(line, "start", 5)) {
	    printf("%s", line);
	    last_pos = bu_ftell(stdin);
	} else
	    break;
    }

    /* read the frame number of the first "start" command */
    sscanf(strpbrk(line, "0123456789"), "%d", &frame_number);

    /* find the highest frame number in the file */
    maxnum = 0;
    while (bu_fgets(line, MAXLEN, stdin)!=NULL) {
	if (!bu_strncmp(line, "start", 5)) {
	    sscanf(strpbrk(line, "0123456789"), "%d", &number);
	    maxnum = (maxnum>number)?maxnum:number;
	}
    }

    length = maxnum - frame_number + 1;
    /* spread should initially be the smallest power of two larger than
     * or equal to length */
    spread = 2;
    while (spread < length)
	spread = spread<<1;

    first_frame = frame_number;
    success = 1;
    while (length--) {
	number = -1;
	success = 0; /* tells whether or not any frames have been found which have the current frame number*/
	if (incremental) {
	    bu_fseek(stdin, 0, 0);
	} else {
	    bu_fseek(stdin, last_pos, 0);
	}

	reserve = MAXLEN*MAXLINES;
	pbuffer[0] = '\0'; /* delete old pbuffer */

	/* inner loop: search through the entire file for frames */
	/* which have the current frame number */
	while (!feof(stdin)) {

	    /*read to next "start" command*/
	    while (bu_fgets(line, MAXLEN, stdin)!=NULL) {
		if (!bu_strncmp(line, "start", 5)) {
		    sscanf(strpbrk(line, "0123456789"), "%d", &number);
		    break;
		}
	    }
	    if (number==frame_number) {
		if (!success) {
		    /*first successful match*/
		    printf("%s", line);
		    if (!suppressed) printf("clean;\n");
		    success = 1;
		    last_pos = bu_ftell(stdin);
		}
		/* print contents until next "end" */
		while (bu_fgets(line, MAXLEN, stdin)!=NULL) {
		    if (!bu_strncmp(line, "end;", 4))
			break;
		    else if (bu_strncmp(line, "clean", 5))
			printf("%s", line);
		}
		/* save contents until next "start" */
		while (bu_fgets(line, MAXLEN, stdin)!=NULL) {
		    if (!bu_strncmp(line, "start", 5))
			break;
		    else {
			reserve -= strlen(line);
			reserve -= 1;
			if (reserve > 0) {
			    bu_strlcat(pbuffer, line, reserve + strlen(line) + 1);
			} else {
			    printf("ERROR: ran out of buffer space (%d characters)\n", MAXLEN*MAXLINES);
			}
		    }
		}
	    }
	}
	if (success)
	    printf("end;\n");
	/* print saved-up post-raytracing commands, if any */
	printf("%s", pbuffer);

	/* get next frame number */
	if (incremental) {
	    frame_number = frame_number + 2*spread;
	    while (frame_number > maxnum) {
		spread = spread>>1;
		frame_number = first_frame + spread;
	    }
	} else {
	    frame_number += 1;
	}
    }
Esempio n. 25
0
void
csg_comb_func(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr))
{
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    struct iges_properties props;
    int comb_len;
    size_t i;
    int dependent = 1;
    int *de_pointers;
    int id;

    /* when this is called in facet mode, we only want groups */
    if (mode == FACET_MODE && (dp->d_flags & RT_DIR_REGION))
	return;

    /* check if already written */
    if (dp->d_uses < 0)
	return;

    for (i = 0; i < no_of_indeps; i++) {
	if (!bu_strncmp(dp->d_namep, independent[i], NAMESIZE+1)) {
	    dependent = 0;
	    break;
	}
    }

    id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource);
    if (id < 0)
	return;
    if (id != ID_COMBINATION) {
	bu_log("Directory/Database mismatch! is %s a combination or not?\n", dp->d_namep);
	return;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    if (verbose)
	bu_log("Combination - %s\n", dp->d_namep);

    if (!comb->tree) {
	bu_log("Warning: empty combination (%s)\n", dp->d_namep);
	dp->d_uses = 0;
	return;
    }
    comb_len = db_tree_nleaves(comb->tree);
    de_pointers = (int *)bu_calloc(comb_len, sizeof(int), "csg_comb_func");

    comb_form = 0;

    de_pointer_number = 0;
    if (get_de_pointers(comb->tree, dp, comb_len, de_pointers)) {
	bu_log("Error in combination %s\n", dp->d_namep);
	bu_free((char *)de_pointers, "csg_comb_func de_pointers");
	rt_db_free_internal(&intern);
	return;
    }

    bu_strlcpy(props.name, dp->d_namep, NAMESIZE+1);
    props.material_name[0] = '\0';
    props.material_params[0] = '\0';
    props.region_flag = ' ';
    props.ident = 0;
    props.air_code = 0;
    props.material_code = 0;
    props.los_density = 0;
    props.color[0] = 0;
    props.color[1] = 0;
    props.color[2] = 0;
    get_props(&props, comb);

    dp->d_uses = (-comb_to_iges(comb, comb_len, dependent, &props, de_pointers, fp_dir, fp_param));

    if (!dp->d_uses) {
	comb_error++;
	bu_log("g-iges: combination (%s) not written to iges file\n", dp->d_namep);
    }

    rt_db_free_internal(&intern);
    bu_free((char *)de_pointers, "csg_comb_func de_pointers");

}
Esempio n. 26
0
void
format_output (const char* buffer, com_table* ctp, struct rt_i *UNUSED(rtip))
{
    const char* bp = buffer;	/* was + 1; */
    int fmt_type = FMT_NONE;
    int i;
    int use_defaults = 0;

    void parse_fmt(const char* uoutspec, int outcom_type);
    void show_ospec(outitem *oil);

    /* Handle no args, arg=='?', and obvious bad arg */
    if (*bp != '\0')
	++bp;
    while (isspace((int)*bp))
	++bp;
    switch (*bp) {
	case 'r':
	    fmt_type = FMT_RAY;
	    break;
	case 'h':
	    fmt_type = FMT_HEAD;
	    break;
	case 'p':
	    fmt_type = FMT_PART;
	    break;
	case 'f':
	    fmt_type = FMT_FOOT;
	    break;
	case 'm':
	    fmt_type = FMT_MISS;
	    break;
	case 'o':
	    fmt_type = FMT_OVLP;
	    break;
	case 'g':
	    fmt_type = FMT_GAP;
	    break;
	default:
	    --bp;
	    break;
    }
    while (isspace((int)*++bp))
	;

    switch (*bp) {
	case '\0':     /* display current output specs */
	    if (fmt_type == FMT_NONE)
		fprintf(stderr, "Error: No output-statement type specified\n");
	    else
		show_ospec(oi_list[fmt_type]);
	    return;
	case '"':
	    if (fmt_type == FMT_NONE) {
		fprintf(stderr, "Error: No output-statement type specified\n");
		return;
	    }
	    break;
	default:
	    if (bu_strncmp(bp, "default", 7) == 0) {
		use_defaults = 1;
		break;
	    }
	    fprintf(stderr, "Error: Illegal format specification: '%s'\n", buffer);
	    /* fall through here */
	case '?':
	    com_usage(ctp);
	    return;
    }

    if (use_defaults) {
	if (fmt_type == FMT_NONE) {
	    for (i = 0; i < FMT_NONE; ++i) {
		parse_fmt(def_fmt[i], i);
	    }
	} else {
	    parse_fmt(def_fmt[fmt_type], fmt_type);
	}
    } else {
	parse_fmt(bp, fmt_type);
    }
}
size_t
bu_avail_cpus(void)
{
    int ncpu = -1;

#ifdef PARALLEL

#  if defined(__sp3__)
    if (ncpu < 0) {
	int status;
	int cmd;
	int parmlen;
	struct var p;

	cmd = SYS_GETPARMS;
	parmlen = sizeof(struct var);
	if (sysconfig(cmd, &p, parmlen) != 0) {
	    bu_bomb("bu_parallel(): sysconfig error for sp3");
	}
	ncpu = p.v_ncpus;
    }
#  endif	/* __sp3__ */


#  ifdef __FreeBSD__
    if (ncpu < 0) {
	int maxproc;
	size_t len;
	len = 4;
	if (sysctlbyname("hw.ncpu", &maxproc, &len, NULL, 0) == -1) {
	    perror("sysctlbyname");
	} else {
	    ncpu = maxproc;
	}
    }
#  endif


#  if defined(__APPLE__)
    if (ncpu < 0) {
	size_t len;
	int maxproc;
	int mib[] = {CTL_HW, HW_AVAILCPU};

	len = sizeof(maxproc);
	if (sysctl(mib, 2, &maxproc, &len, NULL, 0) == -1) {
	    perror("sysctl");
	} else {
	    ncpu = maxproc; /* should be able to get sysctl to return maxproc */
	}
    }
#  endif /* __ppc__ */


#  if defined(HAVE_GET_NPROCS)
    if (ncpu < 0) {
	ncpu = get_nprocs(); /* GNU extension from sys/sysinfo.h */
    }
#  endif


    /*
     * multithreading support for SunOS 5.X / Solaris 2.x
     */
#  if defined(_SC_NPROCESSORS_ONLN)
    /* SUNOS and linux (and now Mac 10.6+) */
    if (ncpu < 0) {
	ncpu = sysconf(_SC_NPROCESSORS_ONLN);
	if (ncpu < 0) {
	    perror("Unable to get the number of available CPUs");
	}
    }
#endif


#if defined(_SC_NPROC_ONLN)
    if (ncpu < 0) {
	ncpu = sysconf(_SC_NPROC_ONLN);
	if (ncpu < 0) {
	    perror("Unable to get the number of available CPUs");
	}
    }
#endif


#  if defined(linux)
    if (ncpu < 0) {
	/* old linux method */
	/*
	 * Ultra-kludgey way to determine the number of cpus in a
	 * linux box--count the number of processor entries in
	 * /proc/cpuinfo!
	 */

#    define CPUINFO_FILE "/proc/cpuinfo"
	FILE *fp;
	char buf[128];

	fp = fopen (CPUINFO_FILE, "r");

	if (fp == NULL) {
	    perror (CPUINFO_FILE);
	} else {
	    ncpu = 0;
	    while (bu_fgets(buf, 80, fp) != NULL) {
		if (bu_strncmp (buf, "processor", 9) == 0) {
		    ncpu++;
		}
	    }
	    fclose (fp);
	}
    }
#  endif


#  if defined(_WIN32)
    /* Windows */
    if (ncpu < 0) {
	SYSTEM_INFO sysinfo;

	GetSystemInfo(&sysinfo);
	ncpu = (int)sysinfo.dwNumberOfProcessors;
    }
#  endif


#endif /* PARALLEL */

    if (UNLIKELY(bu_debug & BU_DEBUG_PARALLEL)) {
	/* do not use bu_log() here, this can get called before semaphores are initialized */
	fprintf(stderr, "bu_avail_cpus: counted %d cpus.\n", ncpu);
    }

    if (LIKELY(ncpu > 0)) {
	return ncpu;
    }

    /* non-PARALLEL */
    return 1;
}
Esempio n. 28
0
int
main(int argc, char **argv)
{
    int c;
    int i;
    struct pshell *psh;
    struct pbar *pbp;
    struct wmember head;
    struct wmember all_head;
    char *nastran_file = "Converted from NASTRAN file (stdin)";

    bu_setprogname(argv[0]);

    fpin = stdin;

    units = INCHES;

    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    while ((c=bu_getopt(argc, argv, "x:X:t:ni:o:mh?")) != -1) {
	switch (c) {
	    case 'x':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug);
		bu_printb("librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT);
		bu_log("\n");
		break;
	    case 'X':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug);
		bu_printb("librt RTG.NMG_debug", RTG.NMG_debug, NMG_DEBUG_FORMAT);
		bu_log("\n");
		break;
	    case 't':		/* calculational tolerance */
		tol.dist = atof(bu_optarg);
		tol.dist_sq = tol.dist * tol.dist;
		break;
	    case 'n':
		polysolids = 0;
		break;
	    case 'm':
		units = MM;
		break;
	    case 'i':
		fpin = fopen(bu_optarg, "rb");
		if (fpin == (FILE *)NULL) {
		    bu_log("Cannot open NASTRAN file (%s) for reading!\n", bu_optarg);
		    bu_exit(1, Usage, argv[0]);
		}
		nastran_file = bu_optarg;
		break;
	    case 'o':
		output_file = bu_optarg;
		break;
	    default:
		bu_exit(1, Usage, argv[0]);
	}
    }

    fpout = wdb_fopen(output_file);
    if (fpout == NULL) {
	bu_log("Cannot open BRL-CAD file (%s) for writing!\n", output_file);
	bu_exit(1, Usage, argv[0]);
    }

    if (!fpin || !fpout) {
	bu_exit(1, Usage, argv[0]);
    }

    line = (char *)bu_malloc(MAX_LINE_SIZE, "line");
    next_line = (char *)bu_malloc(MAX_LINE_SIZE, "next_line");
    prev_line = (char *)bu_malloc(MAX_LINE_SIZE, "prev_line");
    curr_rec = (char **)bu_calloc(NO_OF_FIELDS, sizeof(char *), "curr_rec");
    for (i=0; i<NO_OF_FIELDS; i++)
	curr_rec[i] = (char *)bu_malloc(sizeof(char)*FIELD_LENGTH, "curr_rec[i]");
    prev_rec = (char **)bu_calloc(NO_OF_FIELDS, sizeof(char *), "prev_rec");
    for (i=0; i<NO_OF_FIELDS; i++)
	prev_rec[i] = (char *)bu_malloc(sizeof(char)*FIELD_LENGTH, "prev_rec[i]");

    /* first pass, find start of NASTRAN "bulk data" */
    start_off = (-1);
    bulk_data_start_line = 0;
    while (bu_fgets(line, MAX_LINE_SIZE, fpin)) {
	bulk_data_start_line++;
	if (bu_strncmp(line, "BEGIN BULK", 10))
	    continue;

	start_off = bu_ftell(fpin);
	break;
    }

    if (start_off < 0) {
	bu_log("Cannot find start of bulk data in NASTRAN file!\n");
	bu_exit(1, Usage, argv[0]);
    }

    /* convert BULK data deck into something reasonable */
    fptmp = bu_temp_file(NULL, 0);
    if (fptmp == NULL) {
	perror(argv[0]);
	bu_exit(1, "Cannot open temporary file\n");
    }
    convert_input();

    /* initialize some lists */
    BU_LIST_INIT(&coord_head.l);
    BU_LIST_INIT(&pbar_head.l);
    BU_LIST_INIT(&pshell_head.l);
    BU_LIST_INIT(&all_head.l);

    nmg_model = (struct model *)NULL;

    /* count grid points */
    bu_fseek(fptmp, 0, SEEK_SET);
    while (bu_fgets(line, MAX_LINE_SIZE, fptmp)) {
	if (!bu_strncmp(line, "GRID", 4))
	    grid_count++;
    }
    if (!grid_count) {
	bu_exit(1, "No geometry in this NASTRAN file!\n");
    }

    /* get default values and properties */
    bu_fseek(fptmp, 0, SEEK_SET);
    while (get_next_record(fptmp, 1, 0)) {
	if (!bu_strncmp(curr_rec[0], "BAROR", 5)) {
	    /* get BAR defaults */
	    bar_def_pid = atoi(curr_rec[2]);
	} else if (!bu_strncmp(curr_rec[0], "PBAR", 4)) {
	    struct pbar *pb;

	    BU_ALLOC(pb, struct pbar);

	    pb->pid = atoi(curr_rec[1]);
	    pb->mid = atoi(curr_rec[2]);
	    pb->area = atof(curr_rec[3]);

	    BU_LIST_INIT(&pb->head.l);

	    BU_LIST_INSERT(&pbar_head.l, &pb->l);
	} else if (!bu_strncmp(curr_rec[0], "PSHELL", 6)) {
	    BU_ALLOC(psh, struct pshell);

	    psh->s = (struct shell *)NULL;
	    psh->pid = atoi(curr_rec[1]);
	    psh->mid = atoi(curr_rec[2]);
	    psh->thick = atof(curr_rec[3]);
	    BU_LIST_INSERT(&pshell_head.l, &psh->l);
	    pshell_count++;
	}
    }

    /* allocate storage for grid points */
    g_pts = (struct grid_point *)bu_calloc(grid_count, sizeof(struct grid_point), "grid points");

    /* get all grid points */
    bu_fseek(fptmp, 0, SEEK_SET);
    while (get_next_record(fptmp, 1, 0)) {
	int gid;
	int cid;
	double tmp[3];

	if (bu_strncmp(curr_rec[0], "GRID", 4))
	    continue;

	gid = atoi(curr_rec[1]);
	cid = atoi(curr_rec[2]);

	for (i=0; i<3; i++) {
	    tmp[i] = atof(curr_rec[i+3]);
	}

	g_pts[grid_used].gid = gid;
	g_pts[grid_used].cid = cid;
	g_pts[grid_used].v = (struct vertex **)bu_calloc(pshell_count + 1, sizeof(struct vertex *), "g_pts vertex array");
	VMOVE(g_pts[grid_used].pt, tmp);
	grid_used++;
    }


    /* find coordinate systems */
    bu_fseek(fptmp, 0, SEEK_SET);
    while (get_next_record(fptmp, 1, 0)) {
	if (bu_strncmp(curr_rec[0], "CORD", 4))
	    continue;

	get_coord_sys();
    }
    /* convert everything to BRL-CAD coordinate system */
    i = 0;
    while (convert_all_cs() || convert_all_pts()) {
	i++;
	if (i > 10) {
	    bu_exit(1, "Cannot convert to default coordinate system, check for circular definition\n");
	}
    }

    mk_id(fpout, nastran_file);

    /* get elements */
    bu_fseek(fptmp, 0, SEEK_SET);
    while (get_next_record(fptmp, 1, 0)) {
	if (!bu_strncmp(curr_rec[0], "CBAR", 4))
	    get_cbar();
	else if (!bu_strncmp(curr_rec[0], "CROD", 4))
	    get_cbar();
	else if (!bu_strncmp(curr_rec[0], "CTRIA3", 6))
	    get_ctria3();
	else if (!bu_strncmp(curr_rec[0], "CQUAD4", 6))
	    get_cquad4();
    }

    if (nmg_model) {
	nmg_rebound(nmg_model, &tol);
	if (polysolids)
	    mk_bot_from_nmg(fpout, "pshell.0", nmg_shell);
	else
	    mk_nmg(fpout, "pshell.0", nmg_model);
    }

    BU_LIST_INIT(&head.l);
    for (BU_LIST_FOR(psh, pshell, &pshell_head.l)) {
	struct model *m;
	char name[NAMESIZE+1];

	if (!psh->s)
	    continue;

	m = nmg_find_model(&psh->s->l.magic);
	nmg_rebound(m, &tol);
	nmg_fix_normals(psh->s, &tol);
	if (psh->thick > tol.dist) {
	    nmg_model_face_fuse(m, &tol);
	    nmg_hollow_shell(psh->s, psh->thick*conv[units], 1, &tol);
	}
	sprintf(name, "pshell.%d", psh->pid);
	if (polysolids)
	    mk_bot_from_nmg(fpout, name, psh->s);
	else
	    mk_nmg(fpout, name, m);

	mk_addmember(name, &head.l, NULL, WMOP_UNION);
    }
    if (BU_LIST_NON_EMPTY(&head.l)) {
	mk_lfcomb(fpout, "shells", &head, 0);
	mk_addmember("shells", &all_head.l, NULL, WMOP_UNION);
    }

    BU_LIST_INIT(&head.l);
    for (BU_LIST_FOR(pbp, pbar, &pbar_head.l)) {
	char name[NAMESIZE+1];

	if (BU_LIST_IS_EMPTY(&pbp->head.l))
	    continue;

	sprintf(name, "pbar_group.%d", pbp->pid);
	mk_lfcomb(fpout, name, &pbp->head, 0);

	mk_addmember(name, &head.l, NULL, WMOP_UNION);
    }
    if (BU_LIST_NON_EMPTY(&head.l)) {
	mk_lfcomb(fpout, "pbars", &head, 0);
	mk_addmember("pbars", &all_head.l, NULL, WMOP_UNION);
    }

    if (BU_LIST_NON_EMPTY(&all_head.l)) {
	mk_lfcomb(fpout, "all", &all_head, 0);
    }
    wdb_close(fpout);
    return 0;
}
void
nmg_2_vrml(FILE *fp, const struct db_full_path *pathp, struct model *m, struct mater_info *mater)
{
    struct nmgregion *reg;
    struct bu_ptbl verts;
    struct vrml_mat mat;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    char *tok;
    int i;
    int first=1;
    int is_light=0;
    float r, g, b;
    point_t ave_pt;
    char *full_path;
    /*There may be a better way to capture the region_id, than getting the rt_comb_internal structure,
     * (and may be a better way to capture the rt_comb_internal struct), but for now I just copied the
     * method used in select_lights/select_non_lights above, could have used a global variable but I noticed
     * none other were used, so I didn't want to be the first
     */
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    NMG_CK_MODEL( m );

    BARRIER_CHECK;

    full_path = db_path_to_string( pathp );

    /* replace all occurrences of '.' with '_' */
    char_replace(full_path, '.', '_');

    RT_CK_FULL_PATH( pathp );
    dp = DB_FULL_PATH_CUR_DIR( pathp );

    if ( !(dp->d_flags & RT_DIR_COMB) )
	return;

    id = rt_db_get_internal( &intern, dp, dbip, (matp_t)NULL, &rt_uniresource );
    if ( id < 0 )
    {
	bu_log( "Cannot internal form of %s\n", dp->d_namep );
	return;
    }

    if ( id != ID_COMBINATION )
    {
	bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n",
		dp->d_namep );
	return;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB( comb );

    if ( mater->ma_color_valid )
    {
	r = mater->ma_color[0];
	g = mater->ma_color[1];
	b = mater->ma_color[2];
    }
    else
    {
	r = g = b = 0.5;
    }

    if ( mater->ma_shader )
    {
	tok = strtok( mater->ma_shader, tok_sep );
	bu_strlcpy( mat.shader, tok, TXT_NAME_SIZE );
    }
    else
	mat.shader[0] = '\0';
    mat.shininess = -1;
    mat.transparency = -1.0;
    mat.lt_fraction = -1.0;
    VSETALL( mat.lt_dir, 0.0 );
    mat.lt_angle = -1.0;
    mat.tx_file[0] = '\0';
    mat.tx_w = -1;
    mat.tx_n = -1;

    bu_vls_strcpy( &vls, &mater->ma_shader[strlen(mat.shader)] );
    (void)bu_struct_parse( &vls, vrml_mat_parse, (char *)&mat, NULL);

    if ( bu_strncmp( "light", mat.shader, 5 ) == 0 )
    {
	/* this is a light source */
	is_light = 1;
    }
    else
    {
	fprintf( fp, "\t<Shape DEF=\"%s\">\n", full_path);
	fprintf( fp, "\t\t<Appearance>\n");

	if ( bu_strncmp( "plastic", mat.shader, 7 ) == 0 )
	{
	    if ( mat.shininess < 0 )
		mat.shininess = 10;
	    V_MAX(mat.transparency, 0.0);

	    fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0);
	}
	else if ( bu_strncmp( "glass", mat.shader, 5 ) == 0 )
	{
	    if ( mat.shininess < 0 )
		mat.shininess = 4;
	    if ( mat.transparency < 0.0 )
		mat.transparency = 0.8;

	    fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0);
	}
	else if ( mater->ma_color_valid )
	{
	    fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\"/>\n", r, g, b);
	}
	else
	{
	    /* If no color was defined set the colors according to the thousands groups */
	    int thou = comb->region_id/1000;
	    thou == 0 ? fprintf( fp, "\t\t\t<Material USE=\"Material_999\"/>\n")
		: thou == 1 ? fprintf( fp, "\t\t\t<Material USE=\"Material_1999\"/>\n")
		: thou == 2 ? fprintf( fp, "\t\t\t<Material USE=\"Material_2999\"/>\n")
		: thou == 3 ? fprintf( fp, "\t\t\t<Material USE=\"Material_3999\"/>\n")
		: thou == 4 ? fprintf( fp, "\t\t\t<Material USE=\"Material_4999\"/>\n")
		: thou == 5 ? fprintf( fp, "\t\t\t<Material USE=\"Material_5999\"/>\n")
		: thou == 6 ? fprintf( fp, "\t\t\t<Material USE=\"Material_6999\"/>\n")
		: thou == 7 ? fprintf( fp, "\t\t\t<Material USE=\"Material_7999\"/>\n")
		: thou == 8 ? fprintf( fp, "\t\t\t<Material USE=\"Material_8999\"/>\n")
		: fprintf( fp, "\t\t\t<Material USE=\"Material_9999\"/>\n");
	}
    }

    if ( !is_light )
    {
	process_non_light(m);
	fprintf( fp, "\t\t</Appearance>\n");
    }

    /* FIXME: need code to handle light */

    /* get list of vertices */
    nmg_vertex_tabulate( &verts, &m->magic );

    fprintf( fp, "\t\t<IndexedFaceSet coordIndex=\"\n");
    first = 1;
    if ( !is_light )
    {
	for ( BU_LIST_FOR( reg, nmgregion, &m->r_hd ) )
	{
	    struct shell *s;

	    NMG_CK_REGION( reg );
	    for ( BU_LIST_FOR( s, shell, &reg->s_hd ) )
	    {
		struct faceuse *fu;

		NMG_CK_SHELL( s );
		for ( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) )
		{
		    struct loopuse *lu;

		    NMG_CK_FACEUSE( fu );

		    if ( fu->orientation != OT_SAME )
			continue;

		    for ( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) )
		    {
			struct edgeuse *eu;

			NMG_CK_LOOPUSE( lu );

			if ( BU_LIST_FIRST_MAGIC( &lu->down_hd ) != NMG_EDGEUSE_MAGIC )
			    continue;

			if ( !first )
			    fprintf( fp, ",\n" );
			else
			    first = 0;

			fprintf( fp, "\t\t\t\t" );
			for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) )
			{
			    struct vertex *v;

			    NMG_CK_EDGEUSE( eu );

			    v = eu->vu_p->v_p;
			    NMG_CK_VERTEX( v );
			    fprintf( fp, " %d,", bu_ptbl_locate( &verts, (long *)v ) );
			}
			fprintf( fp, "-1" );
		    }
		}
	    }
	}
	/* close coordIndex */
	fprintf( fp, "\" ");
	fprintf( fp, "normalPerVertex=\"false\" ");
	fprintf( fp, "convex=\"false\" ");
	fprintf( fp, "creaseAngle=\"0.5\" ");
	/* close IndexedFaceSet open tag */
	fprintf( fp, ">\n");
    }

    fprintf( fp, "\t\t\t<Coordinate point=\"");

    for ( i=0; i<BU_PTBL_END( &verts ); i++ )
    {
	struct vertex *v;
	struct vertex_g *vg;
	point_t pt_meters;

	v = (struct vertex *)BU_PTBL_GET( &verts, i );
	NMG_CK_VERTEX( v );
	vg = v->vg_p;
	NMG_CK_VERTEX_G( vg );

	/* convert to desired units */
	VSCALE( pt_meters, vg->coord, scale_factor );

	if ( is_light )
	    VADD2( ave_pt, ave_pt, pt_meters );
	if ( first )
	{
	    if ( !is_light )
		fprintf( fp, " %10.10e %10.10e %10.10e, ", V3ARGS(pt_meters));
	    first = 0;
	}
	else
	    if ( !is_light )
		fprintf( fp, "%10.10e %10.10e %10.10e, ", V3ARGS( pt_meters ));
    }

    /* close point */
    fprintf(fp, "\"");
    /* close Coordinate */
    fprintf(fp, "/>\n");
    /* IndexedFaceSet end tag */
    fprintf( fp, "\t\t</IndexedFaceSet>\n");
    /* Shape end tag */
    fprintf( fp, "\t</Shape>\n");

    BARRIER_CHECK;
}
Esempio n. 30
0
int
ged_saveview(struct ged *gedp, int argc, const char *argv[])
{
    struct ged_display_list *gdlp;
    struct ged_display_list *next_gdlp;
    int i;
    FILE *fp;
    char *base;
    int c;
    char rtcmd[255] = {'r', 't', 0};
    char outlog[255] = {0};
    char outpix[255] = {0};
    char inputg[255] = {0};
    static const char *usage = "[-e] [-i] [-l] [-o] filename [args]";

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

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

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    bu_optind = 1;
    while ((c = bu_getopt(argc, (char * const *)argv, "e:i:l:o:")) != -1) {
	switch (c) {
	    case 'e':
		snprintf(rtcmd, 255, "%s", bu_optarg);
		break;
	    case 'l':
		snprintf(outlog, 255, "%s", bu_optarg);
		break;
	    case 'o':
		snprintf(outpix, 255, "%s", bu_optarg);
		break;
	    case 'i':
		snprintf(inputg, 255, "%s", bu_optarg);
		break;
	    default: {
		bu_vls_printf(gedp->ged_result_str, "Option '%c' unknown\n", c);
		bu_vls_printf(gedp->ged_result_str, "help saveview");
		return GED_ERROR;
	    }
	}
    }
    argc -= bu_optind-1;
    argv += bu_optind-1;

    if (argc < 2) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    if ((fp = fopen(argv[1], "a")) == NULL) {
	perror(argv[1]);
	return GED_ERROR;
    }
    (void)bu_fchmod(fileno(fp), 0755);	/* executable */

    if (!gedp->ged_wdbp->dbip->dbi_filename) {
	bu_log("Error: geometry file is not specified\n");
	fclose(fp);
	return GED_ERROR;
    }

    if (!bu_file_exists(gedp->ged_wdbp->dbip->dbi_filename, NULL)) {
	bu_log("Error: %s does not exist\n", gedp->ged_wdbp->dbip->dbi_filename);
	fclose(fp);
	return GED_ERROR;
    }

    base = basename_without_suffix(argv[1], ".sh");
    if (outpix[0] == '\0') {
	snprintf(outpix, 255, "%s.pix", base);
    }
    if (outlog[0] == '\0') {
	snprintf(outlog, 255, "%s.log", base);
    }

    /* Do not specify -v option to rt; batch jobs must print everything. -Mike */
    fprintf(fp, "#!/bin/sh\n%s -M ", rtcmd);
    if (gedp->ged_gvp->gv_perspective > 0)
	fprintf(fp, "-p%g ", gedp->ged_gvp->gv_perspective);
    for (i = 2; i < argc; i++)
	fprintf(fp, "%s ", argv[i]);

    if (bu_strncmp(rtcmd, "nirt", 4) != 0)
	fprintf(fp, "\\\n -o %s\\\n $*\\\n", outpix);

    if (inputg[0] == '\0') {
	snprintf(inputg, 255, "%s", gedp->ged_wdbp->dbip->dbi_filename);
    }
    fprintf(fp, " '%s'\\\n ", inputg);

    gdlp = BU_LIST_NEXT(ged_display_list, gedp->ged_gdp->gd_headDisplay);
    while (BU_LIST_NOT_HEAD(gdlp, gedp->ged_gdp->gd_headDisplay)) {
	next_gdlp = BU_LIST_PNEXT(ged_display_list, gdlp);
	fprintf(fp, "'%s' ", bu_vls_addr(&gdlp->gdl_path));
	gdlp = next_gdlp;
    }

    fprintf(fp, "\\\n 2>> %s\\\n", outlog);
    fprintf(fp, " <<EOF\n");

    {
	vect_t eye_model;

	_ged_rt_set_eye_model(gedp, eye_model);
	_ged_rt_write(gedp, fp, eye_model);
    }

    fprintf(fp, "\nEOF\n");
    (void)fclose(fp);

    return GED_OK;
}