示例#1
0
std::string
BRLCADWrapper::GetBRLCADName(std::string &name)
{
    std::ostringstream str;
    std::string strcnt;
    struct bu_vls obj_name = BU_VLS_INIT_ZERO;
    int len = 0;
    char *cp,*tp;
    static int start = 1;

    for (cp = (char *)name.c_str(), len = 0; *cp != '\0'; ++cp, ++len) {
	if (*cp == '@') {
	    if (*(cp + 1) == '@')
		++cp;
	    else
		break;
	}
	bu_vls_putc(&obj_name, *cp);
    }
    bu_vls_putc(&obj_name, '\0');
    tp = (char *)((*cp == '\0') ? "" : cp + 1);

    do {
	bu_vls_trunc(&obj_name, len);
	bu_vls_printf(&obj_name, "%d", start++);
	bu_vls_strcat(&obj_name, tp);
    }
    while (db_lookup(outfp->dbip, bu_vls_addr(&obj_name), LOOKUP_QUIET) != RT_DIR_NULL);

    return bu_vls_addr(&obj_name);
}
/**
 * compares an input units string to a reference units name and
 * returns truthfully if they match.  the comparison ignores any
 * embedded whitespace and is case insensitive.
 */
static int
units_name_matches(const char *input, const char *name)
{
    const char *cp;
    int match;
    struct bu_vls normalized_input = BU_VLS_INIT_ZERO;
    struct bu_vls normalized_name = BU_VLS_INIT_ZERO;

    /* convert NULL */
    if (!input)
	input = "";
    if (!name)
	name = "";

    /* skip spaces */
    while (isspace((unsigned char)*input))
	input++;
    while (isspace((unsigned char)*name))
	name++;

    /* quick exit */
    if (tolower((unsigned char)input[0]) != tolower((unsigned char)name[0]))
	return 0;

    cp = input;
    /* skip spaces, convert to lowercase */
    while (*cp != '\0') {
	if (!isspace((unsigned char)*cp))
	    bu_vls_putc(&normalized_input, tolower((unsigned char)*cp));
	cp++;
    }

    cp = name;
    /* skip spaces, convert to lowercase */
    while (*cp != '\0') {
	if (!isspace((unsigned char)*cp))
	    bu_vls_putc(&normalized_name, tolower((unsigned char)*cp));
	cp++;
    }

    /* trim any trailing 's' for plurality */
    if (bu_vls_addr(&normalized_input)[bu_vls_strlen(&normalized_input)-1] == 's') {
	bu_vls_trunc(&normalized_input, -1);
    }
    if (bu_vls_addr(&normalized_name)[bu_vls_strlen(&normalized_name)-1] == 's') {
	bu_vls_trunc(&normalized_name, -1);
    }

    /* compare */
    match = BU_STR_EQUAL(bu_vls_addr(&normalized_input), bu_vls_addr(&normalized_name));

    bu_vls_free(&normalized_input);
    bu_vls_free(&normalized_name);

    return match;
}
示例#3
0
int
bu_cmdhist_add(void *clientData, int argc, const char **argv)
{
    struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    struct timeval zero;

    if (argc != 3) {
	bu_log("ERROR: expecting only three arguments\n");
	return BRLCAD_ERROR;
    }

    if (UNLIKELY(argv[2][0] == '\n' || argv[2][0] == '\0'))
	return BRLCAD_OK;

    bu_vls_strcpy(&vls, argv[2]);
    if (argv[2][strlen(argv[2])-1] != '\n')
	bu_vls_putc(&vls, '\n');

    zero.tv_sec = zero.tv_usec = 0L;
    cmdhist_record(chop, &vls, &zero, &zero, BRLCAD_OK);

    bu_vls_free(&vls);

    /* newly added command is in chop->cho_curr */
    return BRLCAD_OK;
}
示例#4
0
文件: dm-X.c 项目: cciechad/brlcad
static int
X_dm(int	argc,
     char	*argv[])
{
    if (!strcmp(argv[0], "set")) {
	struct bu_vls	vls;

	bu_vls_init(&vls);

	if (argc < 2) {
	    /* Bare set command, print out current settings */
	    bu_vls_struct_print2(&vls, "dm_X internal variables", X_vparse, (const char *)dmp );
	} else if (argc == 2) {
	    bu_vls_struct_item_named(&vls, X_vparse, argv[1], (const char *)dmp, ',');
	} else {
	    struct bu_vls tmp_vls;

	    bu_vls_init(&tmp_vls);
	    bu_vls_printf(&tmp_vls, "%s=\"", argv[1]);
	    bu_vls_from_argv(&tmp_vls, argc-2, (const char **)argv+2);
	    bu_vls_putc(&tmp_vls, '\"');
	    bu_struct_parse(&tmp_vls, X_vparse, (char *)dmp);
	    bu_vls_free(&tmp_vls);
	}

	Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
	bu_vls_free(&vls);

	return TCL_OK;
    }

    return common_dm(argc, argv);
}
示例#5
0
struct bu_mapped_file *
bu_open_mapped_file_with_path(char *const *path, const char *name, const char *appl)

/* file name */
/* non-null only when app. will use 'apbuf' */
{
    char * const *pathp = path;
    struct bu_vls str = BU_VLS_INIT_ZERO;
    struct bu_mapped_file *ret;

    BU_ASSERT_PTR(name, !=, NULL);
    BU_ASSERT_PTR(pathp, !=, NULL);

    /* Do not resort to path for a rooted filename */
    if (name[0] == '/')
	return bu_open_mapped_file(name, appl);

    /* Try each path prefix in sequence */
    for (; *pathp != NULL; pathp++) {
	bu_vls_strcpy(&str, *pathp);
	bu_vls_putc(&str, '/');
	bu_vls_strcat(&str, name);

	ret = bu_open_mapped_file(bu_vls_addr(&str), appl);
	if (ret) {
	    bu_vls_free(&str);
	    return ret;
	}
    }

    /* Failure, none of the opens succeeded */
    bu_vls_free(&str);
    return (struct bu_mapped_file *)NULL;
}
void
random_hex_or_binary_string(struct bu_vls *v, const hex_bin_enum_t typ, const int nbytes)
{
    const char hex_chars[] = "0123456789abcdef";
    const char bin_chars[] = "01";
    const int nstrchars = (typ & HEX) ? nbytes * HEXCHARS_PER_BYTE : nbytes * BITS_PER_BYTE;
    const char *chars = (typ & HEX) ? hex_chars : bin_chars;
    const int nchars = (typ & HEX) ? sizeof(hex_chars)/sizeof(char) : sizeof(bin_chars)/sizeof(char);
    int i;
    long int seed;

    /* get a random seed from system entropy to seed "random()" */
    seed = bu_get_urandom_number();
    srand(seed);

    bu_vls_trunc(v, 0);
    bu_vls_extend(v, nchars);
    for (i = 0; i < nstrchars; ++i) {
	long int r = rand();
	int n = r ? (int)(r % (nchars - 1)) : 0;
	char c = chars[n];
	bu_vls_putc(v, c);
    }

    if (typ == HEX) {
	bu_vls_prepend(v, "0x");
    } else if (typ == BINARY) {
	bu_vls_prepend(v, "0b");
    }

}
示例#7
0
文件: bn_tcl.c 项目: cciechad/brlcad
void
bn_encode_mat(struct bu_vls *vp, const mat_t m)
{
    if ( m == NULL )  {
	bu_vls_putc(vp, 'I');
	return;
    }

    bu_vls_printf(vp, "%g %g %g %g  %g %g %g %g  %g %g %g %g  %g %g %g %g",
		  m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7],
		  m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]);
}
示例#8
0
/*
 * Validate 'point file data format string', determine and output the
 * point-cloud type. A valid null terminated string is expected as
 * input.  The function returns GED_ERROR if the format string is
 * invalid or if null pointers were passed to the function.
 */
int
str2type(const char *format_string, rt_pnt_type *pnt_type, struct bu_vls *ged_result_str)
{
    struct bu_vls str = BU_VLS_INIT_ZERO;
    char *temp_string = (char *)NULL;
    size_t idx = 0;
    size_t format_string_length = 0;
    int ret = GED_OK;

    if ((format_string == (char *)NULL) || (pnt_type == (rt_pnt_type *)NULL)) {
        bu_vls_printf(ged_result_str, "NULL pointer(s) passed to function 'str2type'.\n");
        ret = GED_ERROR;
    } else {
        format_string_length = strlen(format_string);

        /* remove any '?' from format string before testing for point-cloud type */
        for (idx = 0 ; idx < format_string_length ; idx++) {
            if (format_string[idx] != '?') {
                bu_vls_putc(&str, format_string[idx]);
            }
        }

        bu_vls_trimspace(&str);

        temp_string = bu_vls_addr(&str);
        bu_sort(temp_string, strlen(temp_string), sizeof(char), (int (*)(const void *a, const void *b, void *arg))compare_char, NULL);

        if (BU_STR_EQUAL(temp_string, "xyz")) {
            *pnt_type = RT_PNT_TYPE_PNT;
        } else if (BU_STR_EQUAL(temp_string, "bgrxyz")) {
            *pnt_type = RT_PNT_TYPE_COL;
        } else if (BU_STR_EQUAL(temp_string, "sxyz")) {
            *pnt_type = RT_PNT_TYPE_SCA;
        } else if (BU_STR_EQUAL(temp_string, "ijkxyz")) {
            *pnt_type = RT_PNT_TYPE_NRM;
        } else if (BU_STR_EQUAL(temp_string, "bgrsxyz")) {
            *pnt_type = RT_PNT_TYPE_COL_SCA;
        } else if (BU_STR_EQUAL(temp_string, "bgijkrxyz")) {
            *pnt_type = RT_PNT_TYPE_COL_NRM;
        } else if (BU_STR_EQUAL(temp_string, "ijksxyz")) {
            *pnt_type = RT_PNT_TYPE_SCA_NRM;
        } else if (BU_STR_EQUAL(temp_string, "bgijkrsxyz")) {
            *pnt_type = RT_PNT_TYPE_COL_SCA_NRM;
        } else {
            bu_vls_printf(ged_result_str, "Invalid format string '%s'", format_string);
            ret = GED_ERROR;
        }
    }

    bu_vls_free(&str);

    return ret;
}
示例#9
0
void
db_path_to_vls(struct bu_vls *str, const struct db_full_path *pp)
{
    size_t i;

    BU_CK_VLS(str);
    RT_CK_FULL_PATH(pp);

    for (i = 0; i < pp->fp_len; i++) {
	bu_vls_putc(str, '/');
	if (pp->fp_names[i])
	    bu_vls_strcat(str, pp->fp_names[i]->d_namep);
	else
	    bu_vls_strcat(str, "**NULL**");
    }
}
示例#10
0
文件: dm-ogl.c 项目: cogitokat/brlcad
/*
 * O G L _ D M
 *
 * Implement display-manager specific commands, from MGED "dm" command.
 */
static int
Ogl_dm(int argc,
       const char *argv[])
{
    if (BU_STR_EQUAL(argv[0], "set")) {
	struct bu_vls vls = BU_VLS_INIT_ZERO;

	if (argc < 2) {
	    /* Bare set command, print out current settings */
	    bu_vls_struct_print2(&vls,
				 "dm_ogl internal variables",
				 Ogl_vparse,
				 (const char *)&((struct ogl_vars *)dmp->dm_vars.priv_vars)->mvars);
	} else if (argc == 2) {
	    bu_vls_struct_item_named(&vls,
				     Ogl_vparse,
				     argv[1],
				     (const char *)&((struct ogl_vars *)dmp->dm_vars.priv_vars)->mvars,
				     COMMA);
	} else {
	    struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
	    int ret;

	    bu_vls_printf(&tmp_vls, "%s=\"", argv[1]);
	    bu_vls_from_argv(&tmp_vls, argc-2, (const char **)argv+2);
	    bu_vls_putc(&tmp_vls, '\"');
	    ret = bu_struct_parse(&tmp_vls,
			    Ogl_vparse,
			    (char *)&((struct ogl_vars *)dmp->dm_vars.priv_vars)->mvars);
	    bu_vls_free(&tmp_vls);
	    if (ret < 0) {
	      bu_vls_free(&vls);
	      return TCL_ERROR;
	    }
	}

	Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL);
	bu_vls_free(&vls);

	return TCL_OK;
    }

    return common_dm(argc, argv);
}
示例#11
0
文件: vparse.c 项目: cogitokat/brlcad
void
mged_vls_struct_parse(struct bu_vls *vls,
		      const char *title,
		      struct bu_structparse *how_to_parse,
		      const char *structp,
		      int argc,
		      const char *argv[])
{
    if (argc < 2) {
	/* Bare set command, print out current settings */
	bu_vls_struct_print2(vls, title, how_to_parse, structp);
    } else if (argc == 2) {
	bu_vls_struct_item_named(vls, how_to_parse, argv[1], structp, ' ');
    } else {
	struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;

	bu_vls_printf(&tmp_vls, "%s=\"", argv[1]);
	bu_vls_from_argv(&tmp_vls, argc-2, (const char **)argv+2);
	bu_vls_putc(&tmp_vls, '\"');
	if (bu_struct_parse(&tmp_vls, how_to_parse, structp) < 0) bu_log("Warning - bu_struct_parse failure, mged_vls_struct_parse.\n");
	bu_vls_free(&tmp_vls);
    }
}
示例#12
0
/*
 *			R A Y H I T
 *
 *  Rayhit() is called by rt_shootray() when the ray hits one or more objects.
 *  A per-shotline header record is written, followed by information about
 *  each object hit.
 *
 *  Note that the GIFT-3 format uses a different convention for the "zero"
 *  distance along the ray.  RT has zero at the ray origin (emanation plain),
 *  while GIFT has zero at the screen plain translated so that it contains
 *  the model origin.  This difference is compensated for by adding the
 *  'dcorrection' distance correction factor.
 *
 *  Also note that the GIFT-3 format requires information about the start
 *  point of the ray in two formats.  First, the h, v coordinates of the
 *  grid cell CENTERS (in screen space coordinates) are needed.
 *  Second, the ACTUAL h, v coordinates fired from are needed.
 *
 *  An optional rtg3.pl UnixPlot file is written, permitting a
 *  color vector display of ray-model intersections.
 */
int
rayhit(struct application *ap, register struct partition *PartHeadp, struct seg *segp)
{
    register struct partition *pp = PartHeadp->pt_forw;
    int 			comp_count;	/* component count */
    fastf_t			dfirst, dlast;	/* ray distances */
    static fastf_t		dcorrection = 0; /* RT to GIFT dist corr */
    int			card_count;	/* # comp. on this card */
    const char		*fmt;		/* printf() format string */
    struct bu_vls		str;
    char			buf[128];	/* temp. sprintf() buffer */
    point_t			hv;		/* GIFT h, v coords, in inches */
    point_t			hvcen;
    int			prev_id=-1;
    point_t			first_hit;
    int			first;

    if ( pp == PartHeadp )
	return(0);		/* nothing was actually hit?? */

    if ( ap->a_rt_i->rti_save_overlaps )
	rt_rebuild_overlaps( PartHeadp, ap, 1 );

    part_compact(ap, PartHeadp, TOL);

    /* count components in partitions */
    comp_count = 0;
    for ( pp=PartHeadp->pt_forw; pp!=PartHeadp; pp=pp->pt_forw )  {
	if ( pp->pt_regionp->reg_regionid > 0 ) {
	    prev_id = pp->pt_regionp->reg_regionid;
	    comp_count++;
	} else if ( prev_id <= 0 ) {
	    /* normally air would be output along with a solid partition, but this will require a '111' partition */
	    prev_id = pp->pt_regionp->reg_regionid;
	    comp_count++;
	} else
	    prev_id = pp->pt_regionp->reg_regionid;
    }
    pp = PartHeadp->pt_back;
    if ( pp!=PartHeadp && pp->pt_regionp->reg_regionid <= 0 )
	comp_count++;  /* a trailing '111' ident */
    if ( comp_count == 0 )
	return( 0 );

    /* Set up variable length string, to buffer this shotline in.
     * Note that there is one component per card, and that each card
     * (line) is 80 characters long.  Hence the parameters given to
     * rt-vls-extend().
     */

    bu_vls_init( &str );
    bu_vls_extend( &str, 80 * (comp_count+1) );

    /*
     *  Find the H, V coordinates of the grid cell center.
     *  RT uses the lower left corner of each cell.
     */
    {
	point_t		center;
	fastf_t		dx;
	fastf_t		dy;

	dx = ap->a_x + 0.5;
	dy = ap->a_y + 0.5;
	VJOIN2( center, viewbase_model, dx, dx_model, dy, dy_model );
	MAT4X3PNT( hvcen, model2hv, center );
    }

    /*
     *  Find exact h, v coordinates of actual ray start by
     *  projecting start point into GIFT h, v coordinates.
     */
    MAT4X3PNT( hv, model2hv, ap->a_ray.r_pt );

    /*
     *  In RT, rays are launched from the plane of the screen,
     *  and ray distances are relative to the start point.
     *  In GIFT-3 output files, ray distances are relative to
     *  the (H, V) plane translated so that it contains the origin.
     *  A distance correction is required to convert between the two.
     *  Since this really should be computed only once, not every time,
     *  the trip_count flag was added.
     */
    {

	static int  trip_count;
	vect_t	tmp;
	vect_t	viewZdir;

	if ( trip_count == 0) {

	    VSET( tmp, 0, 0, -1 );		/* viewing direction */
	    MAT4X3VEC( viewZdir, view2model, tmp );
	    VUNITIZE( viewZdir );
	    /* dcorrection will typically be negative */
	    dcorrection = VDOT( ap->a_ray.r_pt, viewZdir );
	    trip_count = 1;
	}
    }

    /* This code is for diagnostics.
     * bu_log("dcorrection=%g\n", dcorrection);
     */

    /* dfirst and dlast have been made negative to account for GIFT looking
     * in the opposite direction of RT.
     */

    dfirst = -(PartHeadp->pt_forw->pt_inhit->hit_dist + dcorrection);
    dlast = -(PartHeadp->pt_back->pt_outhit->hit_dist + dcorrection);
#if 0
    /* This code is to note any occurances of negative distances. */
    if ( PartHeadp->pt_forw->pt_inhit->hit_dist < 0)  {
	bu_log("ERROR: dfirst=%g at partition x%x\n", dfirst, PartHeadp->pt_forw );
	bu_log("\tdcorrection = %f\n", dcorrection );
	bu_log("\tray start point is ( %f %f %f ) in direction ( %f %f %f )\n", V3ARGS( ap->a_ray.r_pt ), V3ARGS( ap->a_ray.r_dir ) );
	VJOIN1( PartHeadp->pt_forw->pt_inhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_inhit->hit_dist, ap->a_ray.r_dir );
	VJOIN1( PartHeadp->pt_back->pt_outhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_outhit->hit_dist, ap->a_ray.r_dir );
	rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
    }
    /* End of bug trap. */
#endif
    /*
     *  Output the ray header.  The GIFT statements that
     *  would have generated this are:
     *  410	write(1, 411) hcen, vcen, h, v, ncomp, dfirst, dlast, a, e
     *  411	format(2f7.1, 2f9.3, i3, 2f8.2,' A', f6.1,' E', f6.1)
     */

#define	SHOT_FMT	"%7.1f%7.1f%9.3f%9.3f%3d%8.2f%8.2f A%6.1f E%6.1f"

    if ( rt_perspective > 0 )  {
	bn_ae_vec( &azimuth, &elevation, ap->a_ray.r_dir );
    }

    bu_vls_printf( &str, SHOT_FMT,
		   hvcen[0], hvcen[1],
		   hv[0], hv[1],
		   comp_count,
		   dfirst * MM2IN, dlast * MM2IN,
		   azimuth, elevation );

    /*
     *  As an aid to debugging, take advantage of the fact that
     *  there are more than 80 columns on UNIX "cards", and
     *  add debugging information to the end of the line to
     *  allow this shotline to be reproduced offline.
     *   -b gives the shotline x, y coordinates when re-running RTG3,
     *   -p and -d are used with RTSHOT
     *  The easy way to activate this is with the harmless -!1 option
     *  when running RTG3.
     */
    if ( R_DEBUG || bu_debug || RT_G_DEBUG )  {
	bu_vls_printf( &str, "   -b%d,%d -p %26.20e %26.20e %26.20e -d %26.20e %26.20e %26.20e\n",
		       ap->a_x, ap->a_y,
		       V3ARGS(ap->a_ray.r_pt),
		       V3ARGS(ap->a_ray.r_dir) );
    } else {
	bu_vls_putc( &str, '\n' );
    }

    /* loop here to deal with individual components */
    card_count = 0;
    prev_id = -1;
    first = 1;
    for ( pp=PartHeadp->pt_forw; pp!=PartHeadp; pp=pp->pt_forw )  {
	/*
	 *  The GIFT statements that would have produced
	 *  this output are:
	 *	do 632 i=icomp, iend
	 *	if (clos(icomp).gt.999.99.or.slos(i).gt.999.9) goto 635
	 * 632	continue
	 * 	write(1, 633)(item(i), clos(i), cangi(i), cango(i),
	 * &			kspac(i), slos(i), i=icomp, iend)
	 * 633	format(1x, 3(i4, f6.2, 2f5.1, i1, f5.1))
	 *	goto 670
	 * 635	write(1, 636)(item(i), clos(i), cangi(i), cango(i),
	 * &			kspac(i), slos(i), i=icomp, iend)
	 * 636	format(1x, 3(i4, f6.1, 2f5.1, i1, f5.0))
	 */
	fastf_t	comp_thickness;	/* component line of sight thickness */
	fastf_t	in_obliq;	/* in obliquity angle */
	fastf_t	out_obliq;	/* out obliquity angle */
	int	region_id;	/* solid region's id */
	int	air_id;		/* air id */
	fastf_t	dot_prod;	/* dot product of normal and ray dir */
	fastf_t	air_thickness;	/* air line of sight thickness */
	vect_t	normal;		/* surface normal */
	register struct partition	*nextpp = pp->pt_forw;

	region_id = pp->pt_regionp->reg_regionid;

	if ( region_id <= 0 && prev_id > 0 )
	{
	    /* air region output with previous partition */
	    prev_id = region_id;
	    continue;
	}
	comp_thickness = pp->pt_outhit->hit_dist -
	    pp->pt_inhit->hit_dist;

	/* The below code is meant to catch components with zero or
	 * negative thicknesses.  This is not supposed to be possible,
	 * but the condition has been seen.
	 */
#if 0
	if ( comp_thickness <= 0 )  {
	    VJOIN1( pp->pt_inhit->hit_point, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir );
	    VJOIN1( pp->pt_outhit->hit_point, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir );
	    bu_log("ERROR: comp_thickness=%g for region id = %d at h=%g, v=%g (x=%d, y=%d), partition at x%x\n",
		   comp_thickness, region_id, hv[0], hv[1], ap->a_x, ap->a_y, pp );
	    rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
	    bu_log("Send this output to the BRL-CAD Developers ([email protected])\n");
	    if ( ! (RT_G_DEBUG & DEBUG_ARB8)) {
		rt_g.debug |= DEBUG_ARB8;
		rt_shootray(ap);
		rt_g.debug &= ~DEBUG_ARB8;
	    }
	}
#endif

	if ( nextpp == PartHeadp )  {
	    if ( region_id <= 0 ) {
		/* last partition is air, need a 111 'phantom armor' before AND after */
		bu_log( "WARNING: adding 'phantom armor' (id=111) with zero thickness before and after air region %s\n",
			pp->pt_regionp->reg_name );
		region_id = 111;
		air_id = pp->pt_regionp->reg_aircode;
		air_thickness = comp_thickness;
		comp_thickness = 0.0;
	    } else {
		/* Last partition, no air follows, use code 9 */
		air_id = 9;
		air_thickness = 0.0;
	    }
	} else if ( region_id <= 0 ) {
	    /* air region, need a 111 'phantom armor' */
	    bu_log( "WARNING: adding 'phantom armor' (id=111) with zero thickness before air region %s\n",
		    pp->pt_regionp->reg_name );
	    prev_id = region_id;
	    region_id = 111;
	    air_id = pp->pt_regionp->reg_aircode;
	    air_thickness = comp_thickness;
	    comp_thickness = 0.0;
	} else if ( nextpp->pt_regionp->reg_regionid <= 0 &&
		    nextpp->pt_regionp->reg_aircode != 0 )  {
	    /* Next partition is air region */
	    air_id = nextpp->pt_regionp->reg_aircode;
	    air_thickness = nextpp->pt_outhit->hit_dist -
		nextpp->pt_inhit->hit_dist;
	    prev_id = air_id;
	} else {
	    /* 2 solid regions, maybe with gap */
	    air_id = 0;
	    air_thickness = nextpp->pt_inhit->hit_dist -
		pp->pt_outhit->hit_dist;
	    if ( air_thickness < 0.0 )
		air_thickness = 0.0;
	    if ( !NEAR_ZERO( air_thickness, 0.1 ) )  {
		air_id = 1;	/* air gap */
		if ( R_DEBUG & RDEBUG_HITS )
		    bu_log("air gap added\n");
	    } else {
		air_thickness = 0.0;
	    }
	    prev_id = region_id;
	}

	/*
	 *  Compute the obliquity angles in degrees, ie,
	 *  the "declension" angle down off the normal vector.
	 *  RT normals always point outwards;
	 *  the "inhit" normal points opposite the ray direction,
	 *  the "outhit" normal points along the ray direction.
	 *  Hence the one sign change.
	 *  XXX this should probably be done with atan2()
	 */

	if ( first ) {
	    first = 0;
	    VJOIN1( first_hit, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir );
	}
    out:
	RT_HIT_NORMAL( normal, pp->pt_inhit, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip );
	dot_prod = VDOT( ap->a_ray.r_dir, normal );
	if ( dot_prod > 1.0 )
	    dot_prod = 1.0;
	if ( dot_prod < -1.0 )
	    dot_prod = (-1.0);

	in_obliq = acos( -dot_prod ) *
	    bn_radtodeg;
	RT_HIT_NORMAL( normal, pp->pt_outhit, pp->pt_outseg->seg_stp, &(ap->a_ray), pp->pt_outflip );
	dot_prod = VDOT( ap->a_ray.r_dir, normal );
	if ( dot_prod > 1.0 )
	    dot_prod = 1.0;
	if ( dot_prod < -1.0 )
	    dot_prod = (-1.0);

	out_obliq = acos( dot_prod ) *
	    bn_radtodeg;

	/* Check for exit obliquties greater than 90 degrees. */
#if 0
	if ( in_obliq > 90 || in_obliq < 0 )  {
	    bu_log("ERROR: in_obliquity=%g\n", in_obliq);
	    rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
	}
	if ( out_obliq > 90 || out_obliq < 0 )  {
	    bu_log("ERROR: out_obliquity=%g\n", out_obliq);
	    VPRINT(" r_dir", ap->a_ray.r_dir);
	    VPRINT("normal", normal);
	    bu_log("dot=%g, acos(dot)=%g\n",
		   VDOT( ap->a_ray.r_dir, normal ),
		   acos( VDOT( ap->a_ray.r_dir, normal ) ) );
	    /* Print the defective one */
	    rt_pr_pt( ap->a_rt_i, pp );
	    /* Print the whole ray's partition list */
	    rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
	}
#endif

	if ( in_obliq > 90.0 )
	    in_obliq = 90.0;
	if ( in_obliq < 0.0 )
	    in_obliq = 0.0;
	if ( out_obliq > 90.0 )
	    out_obliq = 90.0;
	if ( out_obliq < 0.0 )
	    out_obliq = 0.0;

	/*
	 *  Handle 3-components per card output format, with
	 *  a leading space in front of the first component.
	 */
	if ( card_count == 0 )  {
	    bu_vls_strcat( &str, " " );
	}
	comp_thickness *= MM2IN;
	/* Check thickness fields for format overflow */
	if ( comp_thickness > 999.99 || air_thickness*MM2IN > 999.9 )
	    fmt = "%4d%6.1f%5.1f%5.1f%1d%5.0f";
	else
	    fmt = "%4d%6.2f%5.1f%5.1f%1d%5.1f";
#ifdef SPRINTF_NOT_PARALLEL
	bu_semaphore_acquire( BU_SEM_SYSCALL );
#endif
	snprintf(buf, 128, fmt,
		 region_id,
		 comp_thickness,
		 in_obliq, out_obliq,
		 air_id, air_thickness*MM2IN );
#ifdef SPRINTF_NOT_PARALLEL
	bu_semaphore_release( BU_SEM_SYSCALL );
#endif
	bu_vls_strcat( &str, buf );
	card_count++;
	if ( card_count >= 3 )  {
	    bu_vls_strcat( &str, "\n" );
	    card_count = 0;
	}

	/* A color rtg3.pl UnixPlot file of output commands
	 * is generated.  This is processed by plot(1)
	 * plotting filters such as pl-fb or pl-sgi.
	 * Portions of a ray passing through air within the
	 * model are represented in blue, while portions
	 * passing through a solid are assigned green.
	 * This will always be done single CPU,
	 * to prevent output garbling.  (See view_init).
	 */
	if (R_DEBUG & RDEBUG_RAYPLOT) {
	    vect_t     inpt;
	    vect_t     outpt;
	    VJOIN1(inpt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist,
		   ap->a_ray.r_dir);
	    VJOIN1(outpt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist,
		   ap->a_ray.r_dir);
	    pl_color(plotfp, 0, 255, 0);	/* green */
	    pdv_3line(plotfp, inpt, outpt);

	    if (air_thickness > 0) {
		vect_t     air_end;
		VJOIN1(air_end, ap->a_ray.r_pt,
		       pp->pt_outhit->hit_dist + air_thickness,
		       ap->a_ray.r_dir);
		pl_color(plotfp, 0, 0, 255);	/* blue */
		pdv_3cont(plotfp, air_end);
	    }
	}
	if ( nextpp == PartHeadp && air_id != 9 ) {
	    /* need to output a 111 'phantom armor' at end of shotline */
	    air_id = 9;
	    air_thickness = 0.0;
	    region_id = 111;
	    comp_thickness = 0.0;
	    goto out;
	}
    }

    /* If partway through building the line, add a newline */
    if ( card_count > 0 )  {
	/*
	 *  Note that GIFT zero-fills the unused component slots,
	 *  but neither COVART II nor COVART III require it,
	 *  so just end the line here.
	 */
	bu_vls_strcat( &str, "\n" );
    }

    /* Single-thread through file output.
     * COVART will accept non-sequential ray data provided the
     * ray header and its associated data are not separated.  CAVEAT:
     * COVART will not accept headers out of sequence.
     */
    bu_semaphore_acquire( BU_SEM_SYSCALL );

    fputs( bu_vls_addr( &str ), outfp );

    if ( shot_fp )
    {
	fprintf( shot_fp, "%.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f %ld %.5f %.5f %.5f\n",
		 azimuth, elevation, V3ARGS( ap->a_ray.r_pt ), V3ARGS( ap->a_ray.r_dir ),
		 line_num, V3ARGS( first_hit) );

	line_num +=  1 + (comp_count / 3 );
	if ( comp_count % 3 )
	    line_num++;
    }

    /* End of single-thread region */
    bu_semaphore_release( BU_SEM_SYSCALL );

    /* Release vls storage */
    bu_vls_free( &str );

    return(0);
}
示例#13
0
int
ged_make_name(struct rt_wdb *wdbp, int argc, char *argv[])
{
    int status = GED_OK;
    struct bu_vls obj_name;
    char *cp, *tp;
    static int i = 0;
    int	len;
    static const char *usage = "template | -s [num]";

    GED_CHECK_DATABASE_OPEN(wdbp, GED_ERROR);
    GED_CHECK_READ_ONLY(wdbp, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(&wdbp->wdb_result_str, 0);
    wdbp->wdb_result = GED_RESULT_NULL;
    wdbp->wdb_result_flags = 0;

    /* must be wanting help */
    if (argc == 1) {
        wdbp->wdb_result_flags |= GED_RESULT_FLAGS_HELP_BIT;
        bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage);
        return GED_OK;
    }

    switch (argc) {
    case 2:
        if (strcmp(argv[1], "-s") != 0)
            break;
        else {
            i = 0;
            return GED_OK;
        }
    case 3:
    {
        int	new_i;

        if ((strcmp(argv[1], "-s") == 0)
                && (sscanf(argv[2], "%d", &new_i) == 1)) {
            i = new_i;
            return GED_OK;
        }
    }
    default:
        bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage);
        return GED_ERROR;
    }

    bu_vls_init(&obj_name);
    for (cp = argv[1], len = 0; *cp != '\0'; ++cp, ++len) {
        if (*cp == '@') {
            if (*(cp + 1) == '@')
                ++cp;
            else
                break;
        }
        bu_vls_putc(&obj_name, *cp);
    }
    bu_vls_putc(&obj_name, '\0');
    tp = (*cp == '\0') ? "" : cp + 1;

    do {
        bu_vls_trunc(&obj_name, len);
        bu_vls_printf(&obj_name, "%d", i++);
        bu_vls_strcat(&obj_name, tp);
    }
    while (db_lookup(wdbp->dbip, bu_vls_addr(&obj_name), LOOKUP_QUIET) != DIR_NULL);

    bu_vls_printf(&wdbp->wdb_result_str, bu_vls_addr(&obj_name));
    bu_vls_free(&obj_name);

    return GED_OK;
}
示例#14
0
文件: gdiff.c 项目: kanzure/brlcad
int
do_compare(int type, struct bu_vls *vls, Tcl_Obj *obj1, Tcl_Obj *obj2, char *obj_name)
{
    Tcl_Obj *key1, *val1, *key2, *val2;
    int len1, len2, found, junk;
    int i, j;
    int start_index;
    int found_diffs = 0;
    int ev = 0;

    if (Tcl_ListObjLength(INTERP, obj1, &len1) == TCL_ERROR) {
	fprintf(stderr, "Error getting length of TCL object!!!\n");
	fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
	bu_exit (1, NULL);
    }
    if (Tcl_ListObjLength(INTERP, obj2, &len2) == TCL_ERROR) {
	fprintf(stderr, "Error getting length of TCL object!!!\n");
	fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
	bu_exit (1, NULL);
    }

    if (!len1 && !len2)
	return 0;

    if (type == ATTRS) {
	start_index = 0;
    } else {
	start_index = 1;
    }

    /* check for changed values from object 1 to object2 */
    for (i=start_index; i<len1; i+=2) {
	if (Tcl_ListObjIndex(INTERP, obj1, i, &key1) == TCL_ERROR) {
	    fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", i, Tcl_GetStringFromObj(obj1, &junk));
	    fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
	    bu_exit (1, NULL);
	}

	if (Tcl_ListObjIndex(INTERP, obj1, i+1, &val1) == TCL_ERROR) {
	    fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", i+1, Tcl_GetStringFromObj(obj1, &junk));
	    fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
	    bu_exit (1, NULL);
	}

	found = 0;
	for (j=start_index; j<len2; j += 2) {
	    if (Tcl_ListObjIndex(INTERP, obj2, j, &key2) == TCL_ERROR) {
		fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", j, Tcl_GetStringFromObj(obj2, &junk));
		fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
		bu_exit (1, NULL);
	    }
	    if (BU_STR_EQUAL(Tcl_GetStringFromObj(key1, &junk), Tcl_GetStringFromObj(key2, &junk))) {

		found = 1;
		if (Tcl_ListObjIndex(INTERP, obj2, j+1, &val2) == TCL_ERROR) {
		    fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", j+1, Tcl_GetStringFromObj(obj2, &junk));
		    fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
		    bu_exit (1, NULL);
		}

		/* check if this value has changed */
		ev = compare_values(type, val1, val2);
		if (ev) {
		    if (!found_diffs++) {
			if (mode == HUMAN) {
			    printf("%s has changed:\n", obj_name);
			}
		    }
		    if (mode == HUMAN) {
			if (type == PARAMS) {
			    printf("\tparameter %s has changed from:\n\t\t%s\n\tto:\n\t\t%s\n",
				   Tcl_GetStringFromObj(key1, &junk),
				   Tcl_GetStringFromObj(val1, &junk),
				   Tcl_GetStringFromObj(val2, &junk));
			} else {
			    printf("\t%s attribute \"%s\" has changed from:\n\t\t%s\n\tto:\n\t\t%s\n",
				   obj_name,
				   Tcl_GetStringFromObj(key1, &junk),
				   Tcl_GetStringFromObj(val1, &junk),
				   Tcl_GetStringFromObj(val2, &junk));
			}
		    } else {
			int val_len;

			if (type == ATTRS) {
			    bu_vls_printf(vls, "attr set %s ", obj_name);
			} else {
			    bu_vls_strcat(vls, " ");
			}
			bu_vls_strcat(vls, Tcl_GetStringFromObj(key1, &junk));
			bu_vls_strcat(vls, " ");
			if (Tcl_ListObjLength(INTERP, val2, &val_len) == TCL_ERROR) {
			    fprintf(stderr, "Error getting length of TCL object!!\n");
			    fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
			    bu_exit(1, NULL);
			}
			if (val_len > 1)
			    bu_vls_putc(vls, '{');
			bu_vls_strcat(vls, Tcl_GetStringFromObj(val2, &junk));
			if (val_len > 1)
			    bu_vls_putc(vls, '}');
			if (type == ATTRS) {
			    bu_vls_putc(vls, '\n');
			}
		    }
		}
		break;
	    }
	}
	if (!found) {
	    /* this keyword value pair has been eliminated */
	    if (!found_diffs++) {
		if (mode == HUMAN) {
		    printf("%s has changed:\n", obj_name);
		}
	    }
	    if (mode == HUMAN) {
		if (type == PARAMS) {
		    printf("\tparameter %s has been eliminated\n",
			   Tcl_GetStringFromObj(key1, &junk));
		} else {
		    printf("\tattribute \"%s\" has been eliminated from %s\n",
			   Tcl_GetStringFromObj(key1, &junk), obj_name);
		}
	    } else {
		if (type == ATTRS) {
		    bu_vls_printf(vls, "attr rm %s %s\n", obj_name,
				  Tcl_GetStringFromObj(key1, &junk));
		} else {
		    bu_vls_strcat(vls, " ");
		    bu_vls_strcat(vls, Tcl_GetStringFromObj(key1, &junk));
		    bu_vls_strcat(vls, " none");
		}
	    }
	}
    }

    /* check for keyword value pairs in object 2 that don't appear in object 1 */
    for (i=start_index; i<len2; i+= 2) {
	/* get keyword/value pairs from object 2 */
	if (Tcl_ListObjIndex(INTERP, obj2, i, &key2) == TCL_ERROR) {
	    fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", i, Tcl_GetStringFromObj(obj2, &junk));
	    fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
	    bu_exit (1, NULL);
	}

	if (Tcl_ListObjIndex(INTERP, obj2, i+1, &val2) == TCL_ERROR) {
	    fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", i+1, Tcl_GetStringFromObj(obj2, &junk));
	    fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
	    bu_exit (1, NULL);
	}

	found = 0;
	/* look for this keyword in object 1 */
	for (j=start_index; j<len1; j += 2) {
	    if (Tcl_ListObjIndex(INTERP, obj1, j, &key1) == TCL_ERROR) {
		fprintf(stderr, "Error getting word #%d in TCL object!!! (%s)\n", i, Tcl_GetStringFromObj(obj1, &junk));
		fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
		bu_exit (1, NULL);
	    }
	    if (BU_STR_EQUAL(Tcl_GetStringFromObj(key1, &junk), Tcl_GetStringFromObj(key2, &junk))) {
		found = 1;
		break;
	    }
	}
	if (found)
	    continue;

	/* This keyword/value pair in object 2 is not in object 1 */
	if (!found_diffs++) {
	    if (mode == HUMAN) {
		printf("%s has changed:\n", obj_name);
	    }
	}
	if (mode == HUMAN) {
	    if (type == PARAMS) {
		printf("\t%s has new parameter \"%s\" with value %s\n",
		       obj_name,
		       Tcl_GetStringFromObj(key2, &junk),
		       Tcl_GetStringFromObj(val2, &junk));
	    } else {
		printf("\t%s has new attribute \"%s\" with value {%s}\n",
		       obj_name,
		       Tcl_GetStringFromObj(key2, &junk),
		       Tcl_GetStringFromObj(val2, &junk));
	    }
	} else {
	    int val_len;

	    if (type == ATTRS) {
		bu_vls_printf(vls, "attr set %s ", obj_name);
	    } else {
		bu_vls_strcat(vls, " ");
	    }
	    bu_vls_strcat(vls, Tcl_GetStringFromObj(key2, &junk));
	    bu_vls_strcat(vls, " ");
	    if (Tcl_ListObjLength(INTERP, val2, &val_len) == TCL_ERROR) {
		fprintf(stderr, "Error getting length of TCL object!!\n");
		fprintf(stderr, "%s\n", Tcl_GetStringResult(INTERP));
		bu_exit(1, NULL);
	    }
	    if (val_len > 1)
		bu_vls_putc(vls, '{');
	    bu_vls_strcat(vls, Tcl_GetStringFromObj(val2, &junk));
	    if (val_len > 1)
		bu_vls_putc(vls, '}');
	    if (type == ATTRS)
		bu_vls_putc(vls, '\n');
	}
    }

    if (evolutionary && found_diffs)
	bu_vls_strcat(vls, ev == 2 ? " (Evolutionary)" : " (Reworked)");

    return found_diffs;
}
示例#15
0
/*
 *			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( &times );
    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( &times, 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(&times) );
    bu_vls_free( &times );
    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);
}
/* converts a geometry path to a vrml-compliant id.  a buffer is
 * allocated for use, it's the responsibility of the caller to free
 * it.
 *
 * fortunately '/' is valid, so the paths should convert mostly
 * untouched.  it is probably technically possible to name something
 * in mged such that two conversions will result in the same name, but
 * it should be an extremely rare situation.
 */
static void path_2_vrml_id(struct bu_vls *id, const char *path) {
    static int counter = 0;
    unsigned int i;
    char c;

    /* poof go the previous contents just in case */
    bu_vls_trunc(id, 0);

    if (path == NULL) {
	bu_vls_printf(id, "NO_PATH_%d", counter++);
	return;
    }

    /* disallow any character from the
     * ISO-IEC-14772-IS-VRML97WithAmendment1 spec that's not
     * allowed for the first char.
     */
    c = *path;
    switch (c) {
	/* numbers */
	case 0x30:
	    bu_vls_strcat(id, "_ZERO");
	    break;
	case 0x31:
	    bu_vls_strcat(id, "_ONE");
	    break;
	case 0x32:
	    bu_vls_strcat(id, "_TWO");
	    break;
	case 0x33:
	    bu_vls_strcat(id, "_THREE");
	    break;
	case 0x34:
	    bu_vls_strcat(id, "_FOUR");
	    break;
	case 0x35:
	    bu_vls_strcat(id, "_FIVE");
	    break;
	case 0x36:
	    bu_vls_strcat(id, "_SIX");
	    break;
	case 0x37:
	    bu_vls_strcat(id, "_SEVEN");
	    break;
	case 0x38:
	    bu_vls_strcat(id, "_EIGHT");
	    break;
	case 0x39:
	    bu_vls_strcat(id, "_NINE");
	    break;
	case 0x0:
	case 0x1:
	case 0x2:
	case 0x3:
	case 0x4:
	case 0x5:
	case 0x6:
	case 0x7:
	case 0x8:
	case 0x9:
	case 0x10:
	case 0x11:
	case 0x12:
	case 0x13:
	case 0x14:
	case 0x15:
	case 0x16:
	case 0x17:
	case 0x18:
	case 0x19:
	case 0x20:
	    /* control codes */
	    bu_vls_strcat(id, "_CTRL_");
	    break;
	case 0x22:
	    /* " */
	    bu_vls_strcat(id, "_QUOT_");
	    break;
	case 0x23:
	    /* # */
	    bu_vls_strcat(id, "_NUM_");
	    break;
	case 0x27:
	    /* ' */
	    bu_vls_strcat(id, "_APOS_");
	    break;
	case 0x2b:
	    /* + */
	    bu_vls_strcat(id, "_PLUS_");
	    break;
	case 0x2c:
	    /*, */
	    bu_vls_strcat(id, "_COMMA_");
	    break;
	case 0x2d:
	    /* - */
	    bu_vls_strcat(id, "_MINUS_");
	    break;
	case 0x2e:
	    /* . */
	    bu_vls_strcat(id, "_DOT_");
	    break;
	case 0x5b:
	    /* [ */
	    bu_vls_strcat(id, "_LBRK_");
	    break;
	case 0x5c:
	    /* \ */
	    bu_vls_strcat(id, "_BACK_");
	    break;
	case 0x5d:
	    /* ] */
	    bu_vls_strcat(id, "_RBRK_");
	    break;
	case 0x7b:
	    /* { */
	    bu_vls_strcat(id, "_LBRC_");
	    break;
	case 0x7d:
	    /* } */
	    bu_vls_strcat(id, "_RBRC_");
	    break;
	case 0x7f:
	    /* DEL */
	    bu_vls_strcat(id, "_DEL_");
	    break;
	default:
	    bu_vls_putc(id, c);
	    break;
    }

    /* convert the invalid path characters to something valid */
    for (i = 1; i < strlen(path); i++) {
	c = *(path+i);

	/* disallow any character from the
	 * ISO-IEC-14772-IS-VRML97WithAmendment1 spec that's not
	 * allowed for subsequent characters.  only difference is that
	 * #'s and numbers are allowed.
	 */
	switch (c) {
	    case 0x0:
	    case 0x1:
	    case 0x2:
	    case 0x3:
	    case 0x4:
	    case 0x5:
	    case 0x6:
	    case 0x7:
	    case 0x8:
	    case 0x9:
	    case 0x10:
	    case 0x11:
	    case 0x12:
	    case 0x13:
	    case 0x14:
	    case 0x15:
	    case 0x16:
	    case 0x17:
	    case 0x18:
	    case 0x19:
	    case 0x20:
		/* control codes */
		bu_vls_strcat(id, "_CTRL_");
		break;
	    case 0x22:
		/* " */
		bu_vls_strcat(id, "_QUOT_");
		break;
	    case 0x27:
		/* ' */
		bu_vls_strcat(id, "_APOS_");
		break;
	    case 0x2b:
		/* + */
		bu_vls_strcat(id, "_PLUS_");
		break;
	    case 0x2c:
		/*, */
		bu_vls_strcat(id, "_COMMA_");
		break;
	    case 0x2d:
		/* - */
		bu_vls_strcat(id, "_MINUS_");
		break;
	    case 0x2e:
		/* . */
		bu_vls_strcat(id, "_DOT_");
		break;
	    case 0x5b:
		/* [ */
		bu_vls_strcat(id, "_LBRK_");
		break;
	    case 0x5c:
		/* \ */
		bu_vls_strcat(id, "_BACK_");
		break;
	    case 0x5d:
		/* ] */
		bu_vls_strcat(id, "_RBRK_");
		break;
	    case 0x7b:
		/* { */
		bu_vls_strcat(id, "_LBRC_");
		break;
	    case 0x7d:
		/* } */
		bu_vls_strcat(id, "_RBRC_");
		break;
	    case 0x7f:
		/* DEL */
		bu_vls_strcat(id, "_DEL_");
		break;
	    default:
		bu_vls_putc(id, c);
		break;
	}  /* switch c */
    }  /* loop over chars */
}
void
Convtree()
{

    int conv = 0;
    int tottrees = 0;
    union tree *ptr;
    struct rt_comb_internal *comb;
    int no_of_assoc = 0;
    int no_of_props = 0;
    int att_de = 0;
    struct brlcad_att brl_att;
    int i, j, k;

    if (bu_debug & BU_DEBUG_MEM_CHECK)
	bu_log("Doing memory checking in Convtree()\n");
    MEMCHECK;

    bu_log("\nConverting boolean tree entities:\n");

    for (i = 0; i < totentities; i++) {
	/* loop through all entities */
	if (dir[i]->type != 180)	/* This is not a tree */
	    continue;

	att_de = 0;			/* For default if there is no attribute entity */

	tottrees++;

	if (dir[i]->param <= pstart) {
	    /* Illegal parameter address */
	    bu_log("Entity number %d (Boolean Tree) does not have a legal parameter pointer\n", i);
	    continue;
	}

	Readrec(dir[i]->param); /* read first record into buffer */

	MEMCHECK;

	ptr = Readtree(dir[i]->rot); /* construct the tree */

	MEMCHECK;

	if (!ptr) {
	    /* failure */
	    bu_log("\tFailed to convert Boolean tree at D%07d\n", dir[i]->direct);
	    continue;
	}

	/* skip over the associativities */
	Readint(&no_of_assoc, "");
	for (k = 0; k < no_of_assoc; k++)
	    Readint(&j, "");

	/* get property entity DE's */
	Readint(&no_of_props, "");
	for (k = 0; k < no_of_props; k++) {
	    Readint(&j, "");
	    if (dir[(j-1)/2]->type == 422 &&
		dir[(j-1)/2]->referenced == brlcad_att_de) {
		/* this is one of our attribute instances */
		att_de = j;
	    }
	}

	Read_att(att_de, &brl_att);
	/* Read_att will supply defaults if att_de is 0 */
	if (att_de == 0)
	    brl_att.region_flag = 1;

	BU_ALLOC(comb, struct rt_comb_internal);
	RT_COMB_INTERNAL_INIT(comb);

	comb->tree = ptr;

	if (brl_att.region_flag) {
	    comb->region_flag = 1;
	    comb->region_id = brl_att.ident;
	    comb->aircode = brl_att.air_code;
	    comb->GIFTmater = brl_att.material_code;
	    comb->los = brl_att.los_density;
	}
	if (dir[i]->colorp != 0) {
	    comb->rgb_valid = 1;
	    comb->rgb[0] = dir[i]->rgb[0];
	    comb->rgb[1] = dir[i]->rgb[1];
	    comb->rgb[2] = dir[i]->rgb[2];
	}
	comb->inherit = brl_att.inherit;
	bu_vls_init(&comb->shader);
	if (brl_att.material_name) {
	    bu_vls_strcpy(&comb->shader, brl_att.material_name);
	    if (brl_att.material_params) {
		bu_vls_putc(&comb->shader, ' ');
		bu_vls_strcat(&comb->shader, brl_att.material_params);
	    }
	}
	bu_vls_init(&comb->material);

	MEMCHECK;
	if (wdb_export(fdout, dir[i]->name, (void *)comb, ID_COMBINATION, mk_conv2mm))
	    bu_exit(1, "mk_export_fwrite() failed for combination (%s)\n", dir[i]->name);

	conv++;

	MEMCHECK;
    }

    bu_log("Converted %d trees successfully out of %d total trees\n", conv, tottrees);
    MEMCHECK;
}
示例#18
0
void
db_fullpath_to_vls(struct bu_vls *vls, const struct db_full_path *full_path, const struct db_i *dbip, int fp_flags)
{
    size_t i;
    int type;
    const struct bn_tol tol = {BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST * BN_TOL_DIST, 1e-6, 1.0 - 1e-6 };
    BU_CK_VLS(vls);
    RT_CK_FULL_PATH(full_path);

    if (!full_path->fp_names[0]) {
	bu_vls_strcat(vls, "**NULL**");
	return;
    }

    if ((fp_flags & DB_FP_PRINT_TYPE) && !dbip) {
	bu_log("Warning - requested object type printing, but dbip is NULL - object types will not be printed!");
    }

    for (i = 0; i < full_path->fp_len; i++) {
	bu_vls_putc(vls, '/');
	if (fp_flags & DB_FP_PRINT_BOOL) {
	    switch (full_path->fp_bool[i]) {
		case 2:
		    bu_vls_strcat(vls, "u ");
		    break;
		case 3:
		    bu_vls_strcat(vls, "+ ");
		    break;
		case 4:
		    bu_vls_strcat(vls, "- ");
		    break;
	    }
	}
	if (fp_flags & DB_FP_PRINT_MATRIX) {
	    if (full_path->fp_mat[i]) {
		bu_vls_strcat(vls, "(M)");
	    }
	}

	bu_vls_strcat(vls, full_path->fp_names[i]->d_namep);
	if ((fp_flags & DB_FP_PRINT_TYPE) && dbip) {
	    struct rt_db_internal intern;
	    if (!(rt_db_get_internal(&intern, full_path->fp_names[i], dbip, NULL, &rt_uniresource) < 0)) {
		if (intern.idb_meth->ft_label) {
		    bu_vls_putc(vls, '(');
		    switch (intern.idb_minor_type) {
			case DB5_MINORTYPE_BRLCAD_ARB8:
			    type = rt_arb_std_type(&intern, &tol);
			    switch (type) {
				case 4:
				    bu_vls_strcat(vls, "arb4");
				    break;
				case 5:
				    bu_vls_strcat(vls, "arb5");
				    break;
				case 6:
				    bu_vls_strcat(vls, "arb6");
				    break;
				case 7:
				    bu_vls_strcat(vls, "arb7");
				    break;
				case 8:
				    bu_vls_strcat(vls, "arb8");
				    break;
				default:
				    break;
			    }
			    break;
			case DB5_MINORTYPE_BRLCAD_COMBINATION:
			    if (full_path->fp_names[i]->d_flags & RT_DIR_REGION) {
				bu_vls_putc(vls, 'r');
			    } else {
				bu_vls_putc(vls, 'c');
			    }
			    break;
			default:
			    bu_vls_strcat(vls, intern.idb_meth->ft_label);
			    break;
		    }

		}
		bu_vls_putc(vls, ')');
		rt_db_free_internal(&intern);
	    }
	}

    }
}
int
ged_draw_guts(struct ged *gedp, int argc, const char *argv[], int kind)
{
    size_t i;
    int drawtrees_retval;
    int flag_A_attr=0;
    int flag_o_nonunique=1;
    int last_opt=0;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    static const char *usage = "<[-R -C#/#/# -s] objects> | <-o -A attribute name/value pairs>";

/* #define DEBUG_TIMING 1 */

#ifdef DEBUG_TIMING
    int64_t elapsedtime;
#endif

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_DRAWABLE(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;
    }

#ifdef DEBUG_TIMING
    elapsedtime = bu_gettime();
#endif

    /* skip past cmd */
    --argc;
    ++argv;

    /* check args for "-A" (attributes) and "-o" */
    for (i = 0; i < (size_t)argc; i++) {
	char *ptr_A=NULL;
	char *ptr_o=NULL;
	char *c;

	if (*argv[i] != '-') {
	    /* Done checking options. If our display is non-empty,
	     * add -R to keep current view.
	     */
	    if (BU_LIST_NON_EMPTY(gedp->ged_gdp->gd_headDisplay)) {
		bu_vls_strcat(&vls, " -R");
	    }
	    break;
	}

	ptr_A=strchr(argv[i], 'A');
	if (ptr_A)
	    flag_A_attr = 1;

	ptr_o=strchr(argv[i], 'o');
	if (ptr_o)
	    flag_o_nonunique = 2;

	last_opt = i;

	if (!ptr_A && !ptr_o) {
	    bu_vls_putc(&vls, ' ');
	    bu_vls_strcat(&vls, argv[i]);
	    continue;
	}

	if (strlen(argv[i]) == ((size_t)1 + (ptr_A != NULL) + (ptr_o != NULL))) {
	    /* argv[i] is just a "-A" or "-o" */
	    continue;
	}

	/* copy args other than "-A" or "-o" */
	bu_vls_putc(&vls, ' ');
	c = (char *)argv[i];
	while (*c != '\0') {
	    if (*c != 'A' && *c != 'o') {
		bu_vls_putc(&vls, *c);
	    }
	    c++;
	}
    }

    if (flag_A_attr) {
	/* args are attribute name/value pairs */
	struct bu_attribute_value_set avs;
	int max_count=0;
	int remaining_args=0;
	int new_argc=0;
	char **new_argv=NULL;
	struct bu_ptbl *tbl;

	remaining_args = argc - last_opt - 1;
	if (remaining_args < 2 || remaining_args%2) {
	    bu_vls_printf(gedp->ged_result_str, "Error: must have even number of arguments (name/value pairs)\n");
	    bu_vls_free(&vls);
	    return GED_ERROR;
	}

	bu_avs_init(&avs, (argc - last_opt)/2, "ged_draw_guts avs");
	i = 0;
	while (i < (size_t)argc) {
	    if (*argv[i] == '-') {
		i++;
		continue;
	    }

	    /* this is a name/value pair */
	    if (flag_o_nonunique == 2) {
		bu_avs_add_nonunique(&avs, argv[i], argv[i+1]);
	    } else {
		bu_avs_add(&avs, argv[i], argv[i+1]);
	    }
	    i += 2;
	}

	tbl = db_lookup_by_attr(gedp->ged_wdbp->dbip, RT_DIR_REGION | RT_DIR_SOLID | RT_DIR_COMB, &avs, flag_o_nonunique);
	bu_avs_free(&avs);
	if (!tbl) {
	    bu_log("Error: db_lookup_by_attr() failed!!\n");
	    bu_vls_free(&vls);
	    return TCL_ERROR;
	}
	if (BU_PTBL_LEN(tbl) < 1) {
	    /* nothing matched, just return */
	    bu_vls_free(&vls);
	    return TCL_OK;
	}
	for (i = 0; i < BU_PTBL_LEN(tbl); i++) {
	    struct directory *dp;

	    dp = (struct directory *)BU_PTBL_GET(tbl, i);
	    bu_vls_putc(&vls, ' ');
	    bu_vls_strcat(&vls, dp->d_namep);
	}

	max_count = BU_PTBL_LEN(tbl) + last_opt + 1;
	bu_ptbl_free(tbl);
	bu_free((char *)tbl, "ged_draw_guts ptbl");
	new_argv = (char **)bu_calloc(max_count+1, sizeof(char *), "ged_draw_guts new_argv");
	new_argc = bu_argv_from_string(new_argv, max_count, bu_vls_addr(&vls));

	/* First, delete any mention of these objects.
	 * Silently skip any leading options (which start with minus signs).
	 */
	for (i = 0; i < (size_t)new_argc; ++i) {
	    /* Skip any options */
	    if (new_argv[i][0] == '-') {
		/* If this option requires an argument which was
		 * provided separately (e.g. '-C 0/255/0' instead of
		 * '-C0/255/0'), skip the argument too.
		 */
		if (strlen(argv[i]) == 2 && strchr("mxCP", argv[i][1])) {
		    i++;
		}
		continue;
	    }

	    dl_erasePathFromDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_free_vlist_callback, new_argv[i], 0, gedp->freesolid);
	}

	drawtrees_retval = _ged_drawtrees(gedp, new_argc, (const char **)new_argv, kind, (struct _ged_client_data *)0);
	bu_vls_free(&vls);
	bu_free((char *)new_argv, "ged_draw_guts new_argv");
	if (drawtrees_retval) {
	    return GED_ERROR;
	}
    } else {
	int empty_display;
	bu_vls_free(&vls);

	empty_display = 1;
	if (BU_LIST_NON_EMPTY(gedp->ged_gdp->gd_headDisplay)) {
	    empty_display = 0;
	}

	/* First, delete any mention of these objects.
	 * Silently skip any leading options (which start with minus signs).
	 */
	for (i = 0; i < (size_t)argc; ++i) {
	    /* Skip any options */
	    if (argv[i][0] == '-') {
		/* If this option requires an argument which was
		 * provided separately (e.g. '-C 0/255/0' instead of
		 * '-C0/255/0'), skip the argument too.
		 */
		if (strlen(argv[i]) == 2 && strchr("mxCP", argv[i][1])) {
		    i++;
		}
		continue;
	    }

	    dl_erasePathFromDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_free_vlist_callback, argv[i], 0, gedp->freesolid);
	}

	/* if our display is non-empty add -R to keep current view */
	if (!empty_display) {
	    int new_argc;
	    char **new_argv;

	    new_argc = argc + 1;
	    new_argv = (char **)bu_malloc(new_argc * sizeof(char *), "ged_draw_guts new_argv");

	    new_argv[0] = bu_strdup("-R");
	    for (i = 0; i < (size_t)argc; ++i) {
		new_argv[i + 1] = bu_strdup(argv[i]);
	    }

	    drawtrees_retval = _ged_drawtrees(gedp, new_argc, (const char **)new_argv, kind, (struct _ged_client_data *)0);

	    for (i = 0; i < (size_t)new_argc; ++i) {
		bu_free(new_argv[i], "ged_draw_guts new_argv[i] - bu_strdup(argv[i])");
	    }
	    bu_free(new_argv, "ged_draw_guts new_argv");
	} else {
	    drawtrees_retval = _ged_drawtrees(gedp, argc, argv, kind, (struct _ged_client_data *)0);
	}
	if (drawtrees_retval) {
	    return GED_ERROR;
	}
    }

#ifdef DEBUG_TIMING
    elapsedtime = bu_gettime() - elapsedtime;
    {
	int seconds = elapsedtime / 1000000;
	int minutes = seconds / 60;
	int hours = minutes / 60;

	minutes = minutes % 60;
	seconds = seconds %60;

	bu_vls_printf(gedp->ged_result_str, "Elapsed time: %02d:%02d:%02d\n", hours, minutes, seconds);
    }
#endif

    return GED_OK;
}
/* This routine just produces an ascii description of the Boolean tree.
 * In a real converter, this would output the tree in the desired format.
 */
void
describe_tree(union tree *tree,
	      struct bu_vls *str)
{
    struct bu_vls left = BU_VLS_INIT_ZERO;
    struct bu_vls right = BU_VLS_INIT_ZERO;
    const char op_xor='^';
    char op='\0';

    BU_CK_VLS(str);

    if (!tree) {
	/* this tree has no members */
	bu_vls_strcat(str, "-empty-");
	return;
    }

    RT_CK_TREE(tree);

    /* Handle all the possible node types.
     * the first four are the most common types, and are typically
     * the only ones found in a BRL-CAD database.
     */
    switch (tree->tr_op) {
	case OP_DB_LEAF:	/* leaf node, this is a member */
	    /* Note: tree->tr_l.tl_mat is a pointer to a
	     * transformation matrix to apply to this member
	     */
	    bu_vls_strcat(str,  tree->tr_l.tl_name);
	    break;
	case OP_UNION:		/* union operator node */
	    op = DB_OP_UNION;
	    goto binary;
	case OP_INTERSECT:	/* intersection operator node */
	    op = DB_OP_INTERSECT;
	    goto binary;
	case OP_SUBTRACT:	/* subtraction operator node */
	    op = DB_OP_SUBTRACT;
	    goto binary;
	case OP_XOR:		/* exclusive "or" operator node */
	    op = op_xor;
	binary:				/* common for all binary nodes */
	    describe_tree(tree->tr_b.tb_left, &left);
	    describe_tree(tree->tr_b.tb_right, &right);
	    bu_vls_putc(str, '(');
	    bu_vls_vlscatzap(str, &left);
	    bu_vls_printf(str, " %c ", op);
	    bu_vls_vlscatzap(str, &right);
	    bu_vls_putc(str, ')');
	    break;
	case OP_NOT:
	    bu_vls_strcat(str, "(!");
	    describe_tree(tree->tr_b.tb_left, str);
	    bu_vls_putc(str, ')');
	    break;
	case OP_GUARD:
	    bu_vls_strcat(str, "(G");
	    describe_tree(tree->tr_b.tb_left, str);
	    bu_vls_putc(str, ')');
	    break;
	case OP_XNOP:
	    bu_vls_strcat(str, "(X");
	    describe_tree(tree->tr_b.tb_left, str);
	    bu_vls_putc(str, ')');
	    break;
	case OP_NOP:
	    bu_vls_strcat(str, "NOP");
	    break;
	default:
	    bu_exit(1, "ERROR: describe_tree() got unrecognized op (%d)\n", tree->tr_op);
    }
}