/** * Make human-readable formatted presentation of this solid. * First line describes type of solid. * Additional lines are indented one tab, and give parameter values. */ int rt_arbn_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local) { struct rt_arbn_internal *aip = (struct rt_arbn_internal *)ip->idb_ptr; char buf[256]; size_t i; RT_ARBN_CK_MAGIC(aip); sprintf(buf, "arbn bounded by %lu planes\n", (long unsigned)aip->neqn); bu_vls_strcat(str, buf); if (!verbose) return 0; for (i = 0; i < aip->neqn; i++) { sprintf(buf, "\t%lu: (%g, %g, %g) %g\n", (long unsigned)i, INTCLAMP(aip->eqn[i][X]), /* should have unit length */ INTCLAMP(aip->eqn[i][Y]), INTCLAMP(aip->eqn[i][Z]), INTCLAMP(aip->eqn[i][W] * mm2local)); bu_vls_strcat(str, buf); } return 0; }
void rt_pr_partitions(const struct rt_i *rtip, register const struct partition *phead, const char *title) { register const struct partition *pp; struct bu_vls v = BU_VLS_INIT_ZERO; RT_CHECK_RTI(rtip); bu_log_indent_vls(&v); bu_vls_strcat(&v, "------"); bu_vls_strcat(&v, title); bu_vls_strcat(&v, "\n"); bu_log_indent_delta(2); for (pp = phead->pt_forw; pp != phead; pp = pp->pt_forw) { RT_CHECK_PT(pp); rt_pr_pt_vls(&v, rtip, pp); } bu_log_indent_delta(-2); bu_log_indent_vls(&v); bu_vls_strcat(&v, "------\n"); bu_log("%s", bu_vls_addr(&v)); bu_vls_free(&v); }
static void dup_dir_check5(struct db_i *input_dbip, const struct db5_raw_internal *rip, off_t addr, void *ptr) { char *name; struct directory *dupdp; struct bu_vls local = BU_VLS_INIT_ZERO; struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr; if (dcsp->main_dbip == DBI_NULL) return; RT_CK_DBI(input_dbip); RT_CK_RIP(rip); if (rip->h_dli == DB5HDR_HFLAGS_DLI_HEADER_OBJECT) return; if (rip->h_dli == DB5HDR_HFLAGS_DLI_FREE_STORAGE) return; name = (char *)rip->name.ext_buf; if (name == (char *)NULL) return; if (addr == 0) return; /* do not compare _GLOBAL */ if (rip->major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY && rip->minor_type == 0) return; /* Add the prefix, if any */ if (db_version(dcsp->main_dbip) < 5) { if (dcsp->wdbp->wdb_ncharadd > 0) { bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd); bu_vls_strcat(&local, name); } else { bu_vls_strncpy(&local, name, _GED_V4_MAXNAME); } bu_vls_trunc(&local, _GED_V4_MAXNAME); } else { if (dcsp->wdbp->wdb_ncharadd > 0) { (void)bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr); (void)bu_vls_strcat(&local, name); } else { (void)bu_vls_strcat(&local, name); } } /* Look up this new name in the existing (main) database */ if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) { /* Duplicate found, add it to the list */ dcsp->wdbp->wdb_num_dups++; *dcsp->dup_dirp++ = dupdp; } bu_vls_free(&local); return; }
/** * b u _ v l s _ f r o m _ a r g v * * Given and argc & argv pair, convert them into a vls string of * space-separated words. */ void bu_vls_from_argv(register struct bu_vls *vp, int argc, const char *argv[]) { BU_CK_VLS(vp); for (/* nada */; argc > 0; argc--, argv++) { bu_vls_strcat( vp, *argv ); if ( argc > 1 ) bu_vls_strcat( vp, " " ); } }
void rt_pr_pt_vls(struct bu_vls *v, const struct rt_i *rtip, register const struct partition *pp) { register const struct soltab *stp; register struct seg **segpp; RT_CHECK_RTI(rtip); RT_CHECK_PT(pp); BU_CK_VLS(v); bu_log_indent_vls(v); bu_vls_printf(v, "%p: PT ", (void *)pp); stp = pp->pt_inseg->seg_stp; bu_vls_printf(v, "%s (%s#%ld) ", stp->st_dp->d_namep, OBJ[stp->st_id].ft_name+3, stp->st_bit); stp = pp->pt_outseg->seg_stp; bu_vls_printf(v, "%s (%s#%ld) ", stp->st_dp->d_namep, OBJ[stp->st_id].ft_name+3, stp->st_bit); bu_vls_printf(v, "(%g, %g)", pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist); if (pp->pt_inflip) bu_vls_strcat(v, " Iflip"); if (pp->pt_outflip) bu_vls_strcat(v, " Oflip"); bu_vls_strcat(v, "\n"); rt_pr_hit_vls(v, " In", pp->pt_inhit); rt_pr_hit_vls(v, " Out", pp->pt_outhit); bu_log_indent_vls(v); bu_vls_strcat(v, " Primitives: "); for (BU_PTBL_FOR(segpp, (struct seg **), &pp->pt_seglist)) { stp = (*segpp)->seg_stp; RT_CK_SOLTAB(stp); bu_vls_strcat(v, stp->st_dp->d_namep); bu_vls_strcat(v, ", "); } bu_vls_strcat(v, "\n"); bu_log_indent_vls(v); bu_vls_strcat(v, " Untrimmed Segments spanning this interval:\n"); bu_log_indent_delta(4); for (BU_PTBL_FOR(segpp, (struct seg **), &pp->pt_seglist)) { RT_CK_SEG(*segpp); rt_pr_seg_vls(v, *segpp); } bu_log_indent_delta(-4); if (pp->pt_regionp) { RT_CK_REGION(pp->pt_regionp); bu_log_indent_vls(v); bu_vls_printf(v, " Region: %s\n", pp->pt_regionp->reg_name); } }
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**"); } }
/* * Validate points data file unit string and output conversion factor * to millimeters. If string is not a standard units identifier, the * function assumes a custom conversion factor was specified. A valid * null terminated string is expected as input. The function returns * GED_ERROR if the unit string is invalid or if null pointers were * passed to the function. */ int str2mm(const char *units_string, double *conv_factor, struct bu_vls *ged_result_str) { struct bu_vls str = BU_VLS_INIT_ZERO; double tmp_value = 0.0; char *endp = (char *)NULL; int ret = GED_OK; if ((units_string == (char *)NULL) || (conv_factor == (double *)NULL)) { bu_vls_printf(ged_result_str, "NULL pointer(s) passed to function 'str2mm'.\n"); ret = GED_ERROR; } else { bu_vls_strcat(&str, units_string); bu_vls_trimspace(&str); tmp_value = strtod(bu_vls_addr(&str), &endp); if ((endp != bu_vls_addr(&str)) && (*endp == '\0')) { /* convert to double success */ *conv_factor = tmp_value; } else if ((tmp_value = bu_mm_value(bu_vls_addr(&str))) > 0.0) { *conv_factor = tmp_value; } else { bu_vls_printf(ged_result_str, "Invalid units string '%s'\n", units_string); ret = GED_ERROR; } } bu_vls_free(&str); return ret; }
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; }
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); }
int read_point (FILE *fp, fastf_t *c_p, int c_len, int normalize, struct bu_vls *tail) { char *cp = NULL; fastf_t sum; int i; int return_code = 1; static int line_nm = 0; struct bu_vls *bp; for (bp = bu_vls_vlsinit();; bu_vls_trunc(bp, 0)) { if (bu_vls_gets(bp, fp) == -1) { return_code = EOF; goto wrap_up; } ++line_nm; cp = bu_vls_addr(bp); while ((*cp == ' ') || (*cp == '\t')) ++cp; if ((*cp == '#') || (*cp == '\0')) continue; for (i = 0; i < c_len; ++i) { char *endp; c_p[i] = strtod(cp, &endp); if (endp == cp) bu_exit (1, "Illegal input at line %d: '%s'\n", line_nm, bu_vls_addr(bp)); cp = endp; } if (normalize) { sum = 0.0; for (i = 0; i < c_len; ++i) sum += c_p[i]; for (i = 0; i < c_len; ++i) c_p[i] /= sum; } goto wrap_up; } wrap_up: if ((return_code == 1) && (tail != 0)) { bu_vls_trunc(tail, 0); bu_vls_strcat(tail, cp); } bu_vls_vlsfree(bp); return (return_code); }
void rt_pr_hit_vls(struct bu_vls *v, const char *str, register const struct hit *hitp) { BU_CK_VLS(v); RT_CK_HIT(hitp); bu_log_indent_vls(v); bu_vls_strcat(v, str); bu_vls_printf(v, "HIT dist=%g (surf %d)\n", hitp->hit_dist, hitp->hit_surfno); }
/** * Make human-readable formatted presentation of this solid. First * line describes type of solid. Additional lines are indented one * tab, and give parameter values. */ int rt_xxx_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local) { struct rt_xxx_internal *xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr; char buf[256]; RT_XXX_CK_MAGIC(xxx_ip); bu_vls_strcat(str, "truncated general xxx (XXX)\n"); if (!verbose) return 0; sprintf(buf, "\tV (%g, %g, %g)\n", INTCLAMP(xxx_ip->v[X] * mm2local), INTCLAMP(xxx_ip->v[Y] * mm2local), INTCLAMP(xxx_ip->v[Z] * mm2local)); bu_vls_strcat(str, buf); return 0; }
int db_regexp_match_all(struct bu_vls *dest, struct db_i *dbip, const char *pattern) { register int i, num; register struct directory *dp; for ( i = num = 0; i < RT_DBNHASH; i++ ) { for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw ) { if ( !db_regexp_match( pattern, dp->d_namep ) ) continue; if ( num == 0 ) bu_vls_strcat( dest, dp->d_namep ); else { bu_vls_strcat( dest, " " ); bu_vls_strcat( dest, dp->d_namep ); } ++num; } } return num; }
/* * Gets the output from bu_log and appends it to clientdata vls. */ static int output_catch(void *clientdata, void *str) { struct bu_vls *vp = (struct bu_vls *)clientdata; int len; BU_CK_VLS(vp); len = bu_vls_strlen(vp); bu_vls_strcat(vp, (const char *)str); len = bu_vls_strlen(vp) - len; return len; }
/** *@brief * Check a name against the global directory. */ static int dup_dir_check(struct db_i *input_dbip, const char *name, off_t UNUSED(laddr), size_t UNUSED(len), int UNUSED(flags), void *ptr) { struct directory *dupdp; struct bu_vls local = BU_VLS_INIT_ZERO; struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr; if (dcsp->main_dbip == DBI_NULL) return 0; RT_CK_DBI(input_dbip); /* Add the prefix, if any */ if (db_version(dcsp->main_dbip) < 5) { if (dcsp->wdbp->wdb_ncharadd > 0) { bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd); bu_vls_strcat(&local, name); } else { bu_vls_strncpy(&local, name, _GED_V4_MAXNAME); } bu_vls_trunc(&local, _GED_V4_MAXNAME); } else { if (dcsp->wdbp->wdb_ncharadd > 0) { bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr); bu_vls_strcat(&local, name); } else { bu_vls_strcat(&local, name); } } /* Look up this new name in the existing (main) database */ if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) { /* Duplicate found, add it to the list */ dcsp->wdbp->wdb_num_dups++; *dcsp->dup_dirp++ = dupdp; } bu_vls_free(&local); return 0; }
/** * Make human-readable formatted presentation of this solid. First * line describes type of solid. Additional lines are indented one * tab, and give parameter values. */ int rt_metaball_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double UNUSED(mm2local)) { int metaball_count = 0; char buf[BUFSIZ]; struct rt_metaball_internal *mb; struct wdb_metaballpt *mbpt; RT_CK_DB_INTERNAL(ip); mb = (struct rt_metaball_internal *)ip->idb_ptr; RT_METABALL_CK_MAGIC(mb); for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) metaball_count++; snprintf(buf, BUFSIZ, "Metaball with %d points and a threshold of %g (%s rendering)\n", metaball_count, mb->threshold, rt_metaball_lookup_type_name(mb->method)); bu_vls_strcat(str, buf); if (!verbose) return 0; metaball_count = 0; for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) { switch (mb->method) { case METABALL_ISOPOTENTIAL: snprintf(buf, BUFSIZ, "\t%d: %g field strength at (%g, %g, %g)\n", ++metaball_count, mbpt->fldstr, V3ARGS(mbpt->coord)); break; case METABALL_METABALL: case METABALL_BLOB: snprintf(buf, BUFSIZ, "\t%d: %g field strength at (%g, %g, %g) and blobbiness factor of %g\n", ++metaball_count, mbpt->fldstr, V3ARGS(mbpt->coord), mbpt->sweat); break; default: bu_bomb("Bad metaball method"); /* asplode */ } bu_vls_strcat(str, buf); } return 0; }
void rt_pr_hitarray_vls(struct bu_vls *v, const char *str, register const struct hit *hitp, int count) { int i; BU_CK_VLS(v); RT_CK_HIT(hitp); bu_log_indent_vls(v); bu_vls_strcat(v, str); for (i=0; i<count; i++, hitp++) { bu_vls_printf(v, "HIT%d dist=%g (surf %d)\n", i, hitp->hit_dist, hitp->hit_surfno); } }
int db_dircheck(struct db_i *dbip, struct bu_vls *ret_name, int noisy, struct directory ***headp) { struct directory *dp; char *cp = bu_vls_addr(ret_name); char n0 = cp[0]; char n1 = cp[1]; /* Compute hash only once (almost always the case) */ *headp = &(dbip->dbi_Head[db_dirhash(cp)]); for (dp = **headp; dp != RT_DIR_NULL; dp=dp->d_forw) { char *this_obj; if (n0 == *(this_obj=dp->d_namep) && /* speed */ n1 == this_obj[1] && /* speed */ BU_STR_EQUAL(cp, this_obj)) { /* Name exists in directory already */ int c; bu_vls_strcpy(ret_name, "A_"); bu_vls_strcat(ret_name, this_obj); cp = bu_vls_addr(ret_name); for (c = 'A'; c <= 'Z'; c++) { *cp = c; if (db_lookup(dbip, cp, noisy) == RT_DIR_NULL) break; } if (c > 'Z') { bu_log("db_dircheck: Duplicate of name '%s', ignored\n", cp); return -1; /* fail */ } bu_log("db_dircheck: Duplicate of '%s', given temporary name '%s'\n", cp+2, cp); /* no need to recurse, simply recompute the hash and break */ *headp = &(dbip->dbi_Head[db_dirhash(cp)]); break; } } return 0; /* success */ }
/** * Register all MGED commands. */ HIDDEN void cmd_setup(void) { struct cmdtab *ctp; struct bu_vls temp = BU_VLS_INIT_ZERO; const char *pathname; char buffer[1024]; /* from cmd.c */ extern int glob_compat_mode; extern int output_as_return; for (ctp = mged_cmdtab; ctp->name != NULL; ctp++) { bu_vls_strcpy(&temp, "_mged_"); bu_vls_strcat(&temp, ctp->name); (void)Tcl_CreateCommand(INTERP, ctp->name, ctp->tcl_func, (ClientData)ctp, (Tcl_CmdDeleteProc *)NULL); (void)Tcl_CreateCommand(INTERP, bu_vls_addr(&temp), ctp->tcl_func, (ClientData)ctp, (Tcl_CmdDeleteProc *)NULL); } /* overrides/wraps the built-in tree command */ /* Locate the BRL-CAD-specific Tcl scripts */ pathname = bu_brlcad_data("tclscripts", 1); snprintf(buffer, sizeof(buffer), "%s", pathname); /* link some tcl variables to these corresponding globals */ Tcl_LinkVar(INTERP, "glob_compat_mode", (char *)&glob_compat_mode, TCL_LINK_BOOLEAN); Tcl_LinkVar(INTERP, "output_as_return", (char *)&output_as_return, TCL_LINK_BOOLEAN); /* Provide Tcl interfaces to the fundamental BRL-CAD libraries */ if (Bu_Init(INTERP) == TCL_ERROR) { bu_log("Bu_Init ERROR:\n%s\n", Tcl_GetStringResult(INTERP)); } Bn_Init(INTERP); Rt_Init(INTERP); Go_Init(INTERP); Wdb_Init(INTERP); tkwin = NULL; bu_vls_free(&temp); }
/** * R T _ P G _ D E S C R I B E * * Make human-readable formatted presentation of this solid. * First line describes type of solid. * Additional lines are indented one tab, and give parameter values. */ int rt_pg_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local) { size_t i, j; struct rt_pg_internal *pgp = (struct rt_pg_internal *)ip->idb_ptr; char buf[256] = {0}; RT_PG_CK_MAGIC(pgp); bu_vls_strcat(str, "polygon solid with no topology (POLY)\n"); sprintf(buf, "\t%ld polygons (faces)\n", (long int)pgp->npoly); bu_vls_strcat(str, buf); sprintf(buf, "\tMost complex face has %lu vertices\n", (long unsigned)pgp->max_npts); bu_vls_strcat(str, buf); if (pgp->npoly) { sprintf(buf, "\tFirst vertex (%g, %g, %g)\n", INTCLAMP(pgp->poly[0].verts[X] * mm2local), INTCLAMP(pgp->poly[0].verts[Y] * mm2local), INTCLAMP(pgp->poly[0].verts[Z] * mm2local)); bu_vls_strcat(str, buf); } if (!verbose) return 0; /* Print out all the vertices of all the faces */ for (i=0; i < pgp->npoly; i++) { fastf_t *v = pgp->poly[i].verts; fastf_t *n = pgp->poly[i].norms; sprintf(buf, "\tPolygon %lu: (%lu pts)\n", (long unsigned)i, (long unsigned)pgp->poly[i].npts); bu_vls_strcat(str, buf); for (j=0; j < pgp->poly[i].npts; j++) { sprintf(buf, "\t\tV (%g, %g, %g)\n\t\t N (%g, %g, %g)\n", INTCLAMP(v[X] * mm2local), INTCLAMP(v[Y] * mm2local), INTCLAMP(v[Z] * mm2local), INTCLAMP(n[X] * mm2local), INTCLAMP(n[Y] * mm2local), INTCLAMP(n[Z] * mm2local)); bu_vls_strcat(str, buf); v += ELEMENTS_PER_VECT; n += ELEMENTS_PER_VECT; } } return 0; }
int mk_dsp(struct rt_wdb *fp, const char *name, const char *file, size_t xdim, size_t ydim, const matp_t mat) /* name of file containing elevation data */ /* X dimension of file (w cells) */ /* Y dimension of file (n cells) */ /* convert solid coords to model space */ { struct rt_dsp_internal *dsp; BU_ALLOC(dsp, struct rt_dsp_internal); dsp->magic = RT_DSP_INTERNAL_MAGIC; bu_vls_init(&dsp->dsp_name); bu_vls_strcat(&dsp->dsp_name, file); dsp->dsp_xcnt = xdim; dsp->dsp_ycnt = ydim; MAT_COPY(dsp->dsp_stom, mat); return wdb_export(fp, name, (void *)dsp, ID_DSP, mk_conv2mm); }
HIDDEN void create_boxes(genptr_t callBackData, int x, int y, int z, const char *UNUSED(a), fastf_t fill) { fastf_t min[3], max[3]; struct bu_vls *vp; char bufx[50], bufy[50], bufz[50]; char *nameDestination; struct voxelizeData *dataValues = (struct voxelizeData *)callBackData; sprintf(bufx, "%d", x); sprintf(bufy, "%d", y); sprintf(bufz, "%d", z); if(dataValues->threshold <= fill) { vp = bu_vls_vlsinit(); bu_vls_strcat(vp, dataValues->newname); bu_vls_strcat(vp, ".x"); bu_vls_strcat(vp, bufx); bu_vls_strcat(vp, "y"); bu_vls_strcat(vp, bufy); bu_vls_strcat(vp, "z"); bu_vls_strcat(vp, bufz); bu_vls_strcat(vp, ".s"); min[0] = (dataValues->bbMin)[0] + (x * (dataValues->sizeVoxel)[0]); min[1] = (dataValues->bbMin)[1] + (y * (dataValues->sizeVoxel)[1]); min[2] = (dataValues->bbMin)[2] + (z * (dataValues->sizeVoxel)[2]); max[0] = (dataValues->bbMin)[0] + ( (x + 1.0) * (dataValues->sizeVoxel)[0]); max[1] = (dataValues->bbMin)[1] + ( (y + 1.0) * (dataValues->sizeVoxel)[1]); max[2] = (dataValues->bbMin)[2] + ( (z + 1.0) * (dataValues->sizeVoxel)[2]); nameDestination = bu_vls_strgrab(vp); mk_rpp(dataValues->wdbp,nameDestination, min, max); mk_addmember(nameDestination, &dataValues->content.l, 0, WMOP_UNION); } }
/** * string is a literal or a file name */ static void enqueue_script(struct bu_list *qp, int type, char *string) { struct script_rec *srp; FILE *cfPtr; struct bu_vls str = BU_VLS_INIT_ZERO; BU_CK_LIST_HEAD(qp); BU_ALLOC(srp, struct script_rec); srp->sr_magic = SCRIPT_REC_MAGIC; srp->sr_type = type; bu_vls_init(&(srp->sr_script)); /*Check if supplied file name is local or in brlcad's nirt data dir*/ if (type == READING_FILE) { bu_vls_trunc(&str, 0); bu_vls_printf(&str, "%s", string); cfPtr = fopen(bu_vls_addr(&str), "rb"); if (cfPtr == NULL) { bu_vls_trunc(&str, 0); bu_vls_printf(&str, "%s/%s.nrt", bu_brlcad_data("nirt", 0), string); cfPtr = fopen(bu_vls_addr(&str), "rb"); if (cfPtr != NULL) { fclose(cfPtr); } else { bu_vls_trunc(&str, 0); bu_vls_printf(&str, "%s", string); } } else { fclose(cfPtr); } bu_vls_printf(&(srp->sr_script), "%s", bu_vls_addr(&str)); } else { bu_vls_strcat(&(srp->sr_script), string); } BU_LIST_INSERT(qp, &(srp->l)); bu_vls_free(&str); }
/** * Make human-readable formatted presentation of this solid. First * line describes type of solid. Additional lines are indented one * tab, and give parameter values. */ int rt_revolve_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local) { struct rt_revolve_internal *rip = (struct rt_revolve_internal *)ip->idb_ptr; char buf[256]; RT_REVOLVE_CK_MAGIC(rip); bu_vls_strcat(str, "truncated general revolve (REVOLVE)\n"); if (!verbose) return 0; sprintf(buf, "\tV (%g, %g, %g)\n", INTCLAMP(rip->v3d[X] * mm2local), INTCLAMP(rip->v3d[Y] * mm2local), INTCLAMP(rip->v3d[Z] * mm2local)); bu_vls_strcat(str, buf); sprintf(buf, "\tAxis (%g, %g, %g)\n", INTCLAMP(rip->axis3d[X] * mm2local), INTCLAMP(rip->axis3d[Y] * mm2local), INTCLAMP(rip->axis3d[Z] * mm2local)); bu_vls_strcat(str, buf); sprintf(buf, "\tR (%g, %g, %g)\n", INTCLAMP(rip->r[X] * mm2local), INTCLAMP(rip->r[Y] * mm2local), INTCLAMP(rip->r[Z] * mm2local)); bu_vls_strcat(str, buf); sprintf(buf, "\tAngle=%g\n", INTCLAMP(rip->ang * RAD2DEG)); bu_vls_strcat(str, buf); sprintf(buf, "\tsketch name: "); bu_vls_strcat(str, buf); bu_vls_vlscat(str, &rip->sketch_name); return 0; }
/** * b n _ p r _ p o l y * * Print out the polynomial. */ void bn_pr_poly(const char *title, register const struct bn_poly *eqn) { register int n; register int exp; struct bu_vls str; char buf[48]; bu_vls_init( &str ); bu_vls_extend( &str, 196 ); bu_vls_strcat( &str, title ); snprintf(buf, 48, " polynomial, degree = %d\n", eqn->dgr); bu_vls_strcat( &str, buf ); exp = eqn->dgr; for ( n=0; n<=eqn->dgr; n++, exp-- ) { register double coeff = eqn->cf[n]; if ( n > 0 ) { if ( coeff < 0 ) { bu_vls_strcat( &str, " - " ); coeff = -coeff; } else { bu_vls_strcat( &str, " + " ); } } bu_vls_printf( &str, "%g", coeff ); if ( exp > 1 ) { bu_vls_printf( &str, " *X^%d", exp ); } else if ( exp == 1 ) { bu_vls_strcat( &str, " *X" ); } else { /* For constant term, add nothing */ } } bu_vls_strcat( &str, "\n" ); bu_log( "%s", bu_vls_addr(&str) ); bu_vls_free( &str ); }
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; }
/* * 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); }
static struct name_conv_list * Add_new_name(char *name, unsigned int obj, int type) { struct name_conv_list *ptr; if ( debug ) bu_log( "Add_new_name( %s, x%x, %d )\n", name, obj, type ); if ( type != ASSEMBLY_TYPE && type != PART_TYPE && type != CUT_SOLID_TYPE ) { bu_exit(EXIT_FAILURE, "Bad type for name (%s) in Add_new_name\n", name ); } /* Add a new name */ ptr = (struct name_conv_list *)bu_calloc( 1, sizeof( struct name_conv_list ), "Add_new_name: prev->next" ); ptr->next = (struct name_conv_list *)NULL; ptr->brlcad_name = bu_strdup( name ); ptr->obj = obj; if ( do_regex && type != CUT_SOLID_TYPE ) { regmatch_t pmatch; if ( regexec( ®_cmp, ptr->brlcad_name, 1, &pmatch, 0 ) == 0 ) { /* got a match */ bu_strlcpy( &ptr->brlcad_name[pmatch.rm_so], &ptr->brlcad_name[pmatch.rm_eo], MAX_LINE_SIZE ); } if ( debug ) bu_log( "\tafter reg_ex, name is %s\n", ptr->brlcad_name ); } else if ( type == CUT_SOLID_TYPE ) { bu_free( (char *)ptr->brlcad_name, "brlcad_name" ); ptr->brlcad_name = NULL; } ptr->solid_use_no = 0; ptr->comb_use_no = 0; if ( type != CUT_SOLID_TYPE ) { /* make sure brlcad_name is unique */ char *tmp; tmp = ptr->brlcad_name; ptr->brlcad_name = bu_strdup( Build_unique_name( ptr->brlcad_name ) ); bu_free( (char *)tmp, "brlcad_name" ); } if ( type == ASSEMBLY_TYPE ) { ptr->solid_name = NULL; return( ptr ); } else if ( type == PART_TYPE ) { struct bu_vls vls; bu_vls_init( &vls ); bu_vls_strcpy( &vls, "s." ); bu_vls_strcat( &vls, ptr->brlcad_name ); ptr->solid_name = bu_vls_strgrab( &vls ); } else { struct bu_vls vls; bu_vls_init( &vls ); bu_vls_strcpy( &vls, "s." ); bu_vls_strcat( &vls, ptr->brlcad_name ); ptr->solid_name = bu_vls_strgrab( &vls ); } /* make sure solid name is unique */ ptr->solid_name = bu_strdup( Build_unique_name( ptr->solid_name ) ); return( ptr ); }
int ged_keep(struct ged *gedp, int argc, const char *argv[]) { int i; struct keep_node_data knd; struct rt_wdb *keepfp; struct directory *dp; struct bu_vls title = BU_VLS_INIT_ZERO; struct db_i *new_dbip; const char *cmd = argv[0]; static const char *usage = "[-R] file object(s)"; int c; int flag_R = 0; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); return GED_HELP; } /* check for options */ bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, "R")) != -1) { switch (c) { case 'R': /* not recursively */ flag_R = 1; break; default: bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c); return GED_ERROR; } } /* skip options processed plus command name */ argc -= bu_optind; argv += bu_optind; if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "ERROR: missing file or object names\n"); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); return GED_ERROR; } /* First, clear any existing counts */ for (i = 0; i < RT_DBNHASH; i++) { for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) dp->d_nref = 0; } /* Alert user if named file already exists */ new_dbip = db_open(argv[0], DB_OPEN_READWRITE); if (new_dbip != DBI_NULL) { if (db_version(new_dbip) != db_version(gedp->ged_wdbp->dbip)) { bu_vls_printf(gedp->ged_result_str, "%s: File format mismatch between '%s' and '%s'\n", cmd, argv[0], gedp->ged_wdbp->dbip->dbi_filename); return GED_ERROR; } if ((keepfp = wdb_dbopen(new_dbip, RT_WDB_TYPE_DB_DISK)) == NULL) { bu_vls_printf(gedp->ged_result_str, "%s: Error opening '%s'\n", cmd, argv[0]); return GED_ERROR; } else { bu_vls_printf(gedp->ged_result_str, "%s: Appending to '%s'\n", cmd, argv[0]); /* --- Scan geometry database and build in-memory directory --- */ db_dirbuild(new_dbip); } } else { /* Create a new database */ keepfp = wdb_fopen_v(argv[0], db_version(gedp->ged_wdbp->dbip)); if (keepfp == NULL) { perror(argv[0]); return GED_ERROR; } } knd.wdbp = keepfp; knd.gedp = gedp; /* ident record */ if (bu_strncmp(gedp->ged_wdbp->dbip->dbi_title, "Parts of: ", 10) != 0) { bu_vls_strcat(&title, "Parts of: "); } bu_vls_strcat(&title, gedp->ged_wdbp->dbip->dbi_title); if (db_update_ident(keepfp->dbip, bu_vls_addr(&title), gedp->ged_wdbp->dbip->dbi_local2base) < 0) { perror("fwrite"); bu_vls_printf(gedp->ged_result_str, "db_update_ident() failed\n"); wdb_close(keepfp); bu_vls_free(&title); return GED_ERROR; } bu_vls_free(&title); for (i = 1; i < argc; i++) { if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) continue; if (!flag_R) { /* recursively keep objects */ db_functree(gedp->ged_wdbp->dbip, dp, node_write, node_write, &rt_uniresource, (void *)&knd); } else { /* keep just this object */ node_write(gedp->ged_wdbp->dbip, dp, (void *)&knd); } } wdb_close(keepfp); return GED_OK; }
void Make_brlcad_names( struct obj_info *part ) { struct bu_vls vls = BU_VLS_INIT_ZERO; int count=0; char *tmp_name, *ptr; Tcl_HashEntry *hash_entry=NULL; if ( use_part_name_hash ) { hash_entry = Tcl_FindHashEntry( &htbl, part->obj_name ); if ( !hash_entry ) { /* try without any name extension */ if ( (ptr=strrchr( part->obj_name, '_' )) != NULL ) { bu_vls_strncpy( &vls, part->obj_name, (ptr - part->obj_name) ); hash_entry = Tcl_FindHashEntry( &htbl, bu_vls_addr( &vls ) ); } } if ( !hash_entry ) { /* try without any name extension */ if ( (ptr=strchr( part->obj_name, '_' )) != NULL ) { bu_vls_strncpy( &vls, part->obj_name, (ptr - part->obj_name) ); hash_entry = Tcl_FindHashEntry( &htbl, bu_vls_addr( &vls ) ); } } if ( !hash_entry ) { /* try adding "-011" */ if ( (ptr=strchr( part->obj_name, '-' )) != NULL ) { bu_vls_strncpy( &vls, part->obj_name, (ptr - part->obj_name) ); bu_vls_strcat( &vls, "-011" ); hash_entry = Tcl_FindHashEntry( &htbl, bu_vls_addr( &vls ) ); } } if ( !hash_entry ) { name_not_converted++; } } bu_vls_free( &vls ); if ( hash_entry ) { tmp_name = bu_strdup( (char *)Tcl_GetHashValue( hash_entry ) ); } else { if ( use_part_name_hash ) { bu_log( "\tWarning: no name found for part %s\n", part->obj_name ); } /* make a copy of object name, then make it a legal BRL-CAD name */ if ( strlen( part->obj_name ) < 1 ) { tmp_name = bu_strdup( "s.1" ); } else { tmp_name = bu_strdup( part->obj_name ); ptr = tmp_name; while ( *ptr != '\0' ) { if ( !(isalnum( (int)*ptr ) || *ptr == '-')) { *ptr = '_'; } ptr++; } } } if ( part->obj_type == PART_TYPE ) { /* find a unique solid name */ bu_vls_printf( &vls, "s.%s", tmp_name ); if ( max_name_len ) { bu_vls_trunc( &vls, max_name_len ); } while ( db_lookup( fd_out->dbip, bu_vls_addr( &vls ), LOOKUP_QUIET ) != RT_DIR_NULL) { count++; if ( max_name_len ) { int digits = 1; int val = 10; while ( count >= val ) { digits++; val *= 10; } bu_vls_trunc( &vls, 0 ); bu_vls_printf( &vls, "s.%s", tmp_name ); bu_vls_trunc( &vls, max_name_len - digits - 1 ); bu_vls_printf( &vls, ".%d", count ); } else { bu_vls_trunc( &vls, 0 ); bu_vls_printf( &vls, "s.%s.%d", tmp_name, count ); } } part->brlcad_solid = bu_vls_strgrab( &vls ); } else { part->brlcad_solid = NULL; } /* find a unique non-primitive name */ bu_vls_printf( &vls, "%s", tmp_name ); if ( max_name_len ) { bu_vls_trunc( &vls, max_name_len ); } while ( db_lookup( fd_out->dbip, bu_vls_addr( &vls ), LOOKUP_QUIET) != RT_DIR_NULL ) { count++; if ( max_name_len ) { int digits = 1; int val = 10; while ( count >= val ) { digits++; val *= 10; } bu_vls_trunc( &vls, 0 ); bu_vls_printf( &vls, "%s", tmp_name ); bu_vls_trunc( &vls, max_name_len - digits - 1 ); bu_vls_printf( &vls, ".%d", count ); } else { bu_vls_trunc( &vls, 0 ); bu_vls_printf( &vls, "%s.%d", tmp_name, count ); } } part->brlcad_comb = bu_vls_strgrab( &vls ); switch ( part->obj_type ) { case UNKNOWN_TYPE: bu_log( "ERROR: Unknown object type for %s\n", part->obj_name ); break; case PART_TYPE: if ( use_part_name_hash ) { DO_INDENT bu_log( "part %s changed name to (%s)\n", part->obj_name, part->brlcad_comb ); } else { DO_INDENT bu_log( "part %s\n", part->brlcad_comb ); } break; case ASSEMBLY_TYPE: if ( use_part_name_hash ) { DO_INDENT bu_log( "assembly %s changed name to (%s)\n", part->obj_name, part->brlcad_comb ); } else { DO_INDENT bu_log( "assembly %s\n", part->brlcad_comb ); } break; } bu_free( tmp_name, "tmp_name" ); }