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; }
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; }
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); }
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"); } }
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]); }
/* * 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; }
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**"); } }
/* * 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); }
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); } }
/* * 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); }
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; }
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; }
/* * M A I N */ int main(int argc, char **argv) { struct rt_i *rtip = NULL; char *title_file = NULL, *title_obj = NULL; /* name of file and first object */ char idbuf[RT_BUFSIZE] = {0}; /* First ID record info */ void application_init(); struct bu_vls times; int i; #if defined(_WIN32) && !defined(__CYGWIN__) setmode(fileno(stdin), O_BINARY); setmode(fileno(stdout), O_BINARY); setmode(fileno(stderr), O_BINARY); #else bu_setlinebuf( stdout ); bu_setlinebuf( stderr ); #endif #ifdef HAVE_SBRK beginptr = (char *) sbrk(0); #endif azimuth = 35.0; /* GIFT defaults */ elevation = 25.0; AmbientIntensity=0.4; background[0] = background[1] = 0.0; background[2] = 1.0/255.0; /* slightly non-black */ /* Before option processing, get default number of processors */ npsw = bu_avail_cpus(); /* Use all that are present */ if ( npsw > MAX_PSW ) npsw = MAX_PSW; /* Before option processing, do application-specific initialization */ RT_APPLICATION_INIT( &ap ); application_init(); /* Process command line options */ if ( !get_args( argc, argv ) ) { (void)fputs(usage, stderr); return 1; } /* Identify the versions of the libraries we are using. */ if (rt_verbosity & VERBOSE_LIBVERSIONS) { (void)fprintf(stderr, "%s%s%s%s\n", brlcad_ident(title), rt_version(), bn_version(), bu_version() ); } #if defined(DEBUG) (void)fprintf(stderr, "Compile-time debug symbols are available\n"); #endif #if defined(NO_BOMBING_MACROS) || defined(NO_MAGIC_CHECKING) || defined(NO_BADRAY_CECHKING) || defined(NO_DEBUG_CHECKING) (void)fprintf(stderr, "WARNING: Run-time debugging is disabled and may enhance performance\n"); #endif /* Identify what host we're running on */ if (rt_verbosity & VERBOSE_LIBVERSIONS) { char hostname[512] = {0}; #ifndef _WIN32 if ( gethostname( hostname, sizeof(hostname) ) >= 0 && hostname[0] != '\0' ) (void)fprintf(stderr, "Running on %s\n", hostname); #else sprintf(hostname, "Microsoft Windows"); (void)fprintf(stderr, "Running on %s\n", hostname); #endif } if ( bu_optind >= argc ) { fprintf(stderr, "%s: MGED database not specified\n", argv[0]); (void)fputs(usage, stderr); return 1; } if (rpt_overlap) ap.a_logoverlap = ((void (*)())0); else ap.a_logoverlap = rt_silent_logoverlap; /* If user gave no sizing info at all, use 512 as default */ if ( width <= 0 && cell_width <= 0 ) width = 512; if ( height <= 0 && cell_height <= 0 ) height = 512; /* If user didn't provide an aspect ratio, use the image * dimensions ratio as a default. */ if (aspect <= 0.0) { aspect = (fastf_t)width / (fastf_t)height; } if ( sub_grid_mode ) { /* check that we have a legal subgrid */ if ( sub_xmax >= width || sub_ymax >= height ) { fprintf( stderr, "rt: illegal values for subgrid %d,%d,%d,%d\n", sub_xmin, sub_ymin, sub_xmax, sub_ymax ); fprintf( stderr, "\tFor a %d X %d image, the subgrid must be within 0, 0,%d,%d\n", width, height, width-1, height-1 ); return 1; } } if ( incr_mode ) { int x = height; if ( x < width ) x = width; incr_nlevel = 1; while ( (1<<incr_nlevel) < x ) incr_nlevel++; height = width = 1<<incr_nlevel; if (rt_verbosity & VERBOSE_INCREMENTAL) fprintf(stderr, "incremental resolution, nlevels = %d, width=%d\n", incr_nlevel, width); } /* * Handle parallel initialization, if applicable. */ #ifndef PARALLEL npsw = 1; /* force serial */ #endif if ( npsw < 0 ) { /* Negative number means "all but" npsw */ npsw = bu_avail_cpus() + npsw; } /* allow debug builds to go higher than the max */ if (!(bu_debug & BU_DEBUG_PARALLEL)) { if ( npsw > MAX_PSW ) { npsw = MAX_PSW; } } if (npsw > 1) { rt_g.rtg_parallel = 1; if (rt_verbosity & VERBOSE_MULTICPU) fprintf(stderr, "Planning to run with %d processors\n", npsw ); } else { rt_g.rtg_parallel = 0; } /* Initialize parallel processor support */ bu_semaphore_init( RT_SEM_LAST ); /* * Do not use bu_log() or bu_malloc() before this point! */ if ( bu_debug ) { bu_printb( "libbu bu_debug", bu_debug, BU_DEBUG_FORMAT ); bu_log("\n"); } if ( RT_G_DEBUG ) { bu_printb( "librt rt_g.debug", rt_g.debug, DEBUG_FORMAT ); bu_log("\n"); } if ( rdebug ) { bu_printb( "rt rdebug", rdebug, RDEBUG_FORMAT ); bu_log("\n"); } /* We need this to run rt_dirbuild */ rt_init_resource( &rt_uniresource, MAX_PSW, NULL ); bn_rand_init( rt_uniresource.re_randptr, 0 ); title_file = argv[bu_optind]; title_obj = argv[bu_optind+1]; nobjs = argc - bu_optind - 1; objtab = &(argv[bu_optind+1]); if ( nobjs <= 0 ) { bu_log("%s: no objects specified -- raytrace aborted\n", argv[0]); return 1; } /* Echo back the command line arugments as given, in 3 Tcl commands */ if (rt_verbosity & VERBOSE_MODELTITLE) { struct bu_vls str; bu_vls_init(&str); bu_vls_from_argv( &str, bu_optind, (const char **)argv ); bu_vls_strcat( &str, "\nopendb " ); bu_vls_strcat( &str, title_file ); bu_vls_strcat( &str, ";\ntree " ); bu_vls_from_argv( &str, nobjs <= 16 ? nobjs : 16, (const char **)argv+bu_optind+1 ); if ( nobjs > 16 ) bu_vls_strcat( &str, " ..."); else bu_vls_putc( &str, ';' ); bu_log("%s\n", bu_vls_addr(&str) ); bu_vls_free(&str); } /* Build directory of GED database */ bu_vls_init( × ); rt_prep_timer(); if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) { bu_log("rt: rt_dirbuild(%s) failure\n", title_file); return 2; } ap.a_rt_i = rtip; (void)rt_get_timer( ×, NULL ); if (rt_verbosity & VERBOSE_MODELTITLE) bu_log("db title: %s\n", idbuf); if (rt_verbosity & VERBOSE_STATS) bu_log("DIRBUILD: %s\n", bu_vls_addr(×) ); bu_vls_free( × ); memory_summary(); /* Copy values from command line options into rtip */ rtip->rti_space_partition = space_partition; rtip->rti_nugrid_dimlimit = nugrid_dimlimit; rtip->rti_nu_gfactor = nu_gfactor; rtip->useair = use_air; rtip->rti_save_overlaps = save_overlaps; if ( rt_dist_tol > 0 ) { rtip->rti_tol.dist = rt_dist_tol; rtip->rti_tol.dist_sq = rt_dist_tol * rt_dist_tol; } if ( rt_perp_tol > 0 ) { rtip->rti_tol.perp = rt_perp_tol; rtip->rti_tol.para = 1 - rt_perp_tol; } if (rt_verbosity & VERBOSE_TOLERANCE) rt_pr_tol( &rtip->rti_tol ); /* before view_init */ if ( outputfile && strcmp( outputfile, "-") == 0 ) outputfile = (char *)0; /* * Initialize application. * Note that width & height may not have been set yet, * since they may change from frame to frame. */ if ( view_init( &ap, title_file, title_obj, outputfile!=(char *)0, framebuffer!=(char *)0 ) != 0 ) { /* Framebuffer is desired */ register int xx, yy; int zoom; /* Ask for a fb big enough to hold the image, at least 512. */ /* This is so MGED-invoked "postage stamps" get zoomed up big enough to see */ xx = yy = 512; if ( width > xx || height > yy ) { xx = width; yy = height; } bu_semaphore_acquire( BU_SEM_SYSCALL ); fbp = fb_open( framebuffer, xx, yy ); bu_semaphore_release( BU_SEM_SYSCALL ); if ( fbp == FBIO_NULL ) { fprintf(stderr, "rt: can't open frame buffer\n"); return 12; } bu_semaphore_acquire( BU_SEM_SYSCALL ); /* If fb came out smaller than requested, do less work */ if ( fb_getwidth(fbp) < width ) width = fb_getwidth(fbp); if ( fb_getheight(fbp) < height ) height = fb_getheight(fbp); /* If the fb is lots bigger (>= 2X), zoom up & center */ if ( width > 0 && height > 0 ) { zoom = fb_getwidth(fbp)/width; if ( fb_getheight(fbp)/height < zoom ) zoom = fb_getheight(fbp)/height; } else { zoom = 1; } (void)fb_view( fbp, width/2, height/2, zoom, zoom ); bu_semaphore_release( BU_SEM_SYSCALL ); } if ( (outputfile == (char *)0) && (fbp == FBIO_NULL) ) { /* If not going to framebuffer, or to a file, then use stdout */ if ( outfp == NULL ) outfp = stdout; /* output_is_binary is changed by view_init, as appropriate */ if ( output_is_binary && isatty(fileno(outfp)) ) { fprintf(stderr, "rt: attempting to send binary output to terminal, aborting\n"); return 14; } } /* * Initialize all the per-CPU memory resources. * The number of processors can change at runtime, init them all. */ for ( i=0; i < MAX_PSW; i++ ) { rt_init_resource( &resource[i], i, rtip ); bn_rand_init( resource[i].re_randptr, i ); } memory_summary(); #ifdef SIGUSR1 (void)signal( SIGUSR1, siginfo_handler ); #endif #ifdef SIGINFO (void)signal( SIGINFO, siginfo_handler ); #endif if ( !matflag ) { int frame_retval; def_tree( rtip ); /* Load the default trees */ do_ae( azimuth, elevation ); frame_retval = do_frame( curframe ); if (frame_retval != 0) { /* Release the framebuffer, if any */ if ( fbp != FBIO_NULL ) { fb_close(fbp); } return 1; } } else if ( !isatty(fileno(stdin)) && old_way( stdin ) ) { ; /* All is done */ } else { register char *buf; register int ret; /* * New way - command driven. * Process sequence of input commands. * All the work happens in the functions * called by rt_do_cmd(). */ while ( (buf = rt_read_cmd( stdin )) != (char *)0 ) { if ( R_DEBUG&RDEBUG_PARSE ) fprintf(stderr, "cmd: %s\n", buf ); ret = rt_do_cmd( rtip, buf, rt_cmdtab ); bu_free( buf, "rt_read_cmd command buffer" ); if ( ret < 0 ) break; } if ( curframe < desiredframe ) { fprintf(stderr, "rt: Desired frame %d not reached, last was %d\n", desiredframe, curframe); } } /* Release the framebuffer, if any */ if (fbp != FBIO_NULL) { fb_close(fbp); } return(0); }
/* 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; }
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); } }