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 _ v l s c a t z a p * * Concatenate a new vls string onto the end of an existing vls * string. The storage of the source string is released (zapped). */ void bu_vls_vlscatzap(register struct bu_vls *dest, register struct bu_vls *src) { BU_CK_VLS(src); BU_CK_VLS(dest); if ( src->vls_len <= 0 ) return; bu_vls_vlscat( dest, src ); bu_vls_trunc( src, 0 ); }
/** * H I S T O R Y _ R E C O R D * * Stores the given command with start and finish times in the * history vls'es. 'status' is either BRLCAD_OK or BRLCAD_ERROR. */ HIDDEN void cmdhist_record(struct bu_cmdhist_obj *chop, struct bu_vls *cmdp, struct timeval *start, struct timeval *finish, int status) { struct bu_cmdhist *new_hist; const char *eol = "\n"; if (UNLIKELY(BU_STR_EQUAL(bu_vls_addr(cmdp), eol))) return; BU_ALLOC(new_hist, struct bu_cmdhist); bu_vls_init(&new_hist->h_command); bu_vls_vlscat(&new_hist->h_command, cmdp); new_hist->h_start = *start; new_hist->h_finish = *finish; new_hist->h_status = status; BU_LIST_INSERT(&chop->cho_head.l, &new_hist->l); chop->cho_curr = &chop->cho_head; }
/** * 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; }
/* * H I S T O R Y _ R E C O R D * * Stores the given command with start and finish times in the * history vls'es. */ void history_record(struct bu_vls *cmdp, struct timeval *start, struct timeval *finish, int status) /* Either TCL_OK or TCL_ERROR */ { struct bu_cmdhist *new_hist; if (strcmp(bu_vls_addr(cmdp), "\n") == 0) return; new_hist = (struct bu_cmdhist *)bu_malloc(sizeof(struct bu_cmdhist), "mged history"); bu_vls_init(&(new_hist->h_command)); bu_vls_vlscat(&(new_hist->h_command), cmdp); new_hist->h_start = *start; new_hist->h_finish = *finish; new_hist->h_status = status; /* make sure the list is initialized before attempting to add this entry */ if (!historyInitialized) { historyInit(); } BU_LIST_INSERT(&(histHead.l), &(new_hist->l)); /* As long as this isn't our first command to record after setting up the journal (which would be "journal", which we don't want recorded!)... */ #if 0 if (journalfp != NULL && !firstjournal) history_journalize(new_hist); #endif currHist = &histHead; #if 0 firstjournal = 0; #endif }
/** *@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; }
/* * D O _ R E G I O N _ E N D * * Called from db_walk_tree(). * * This routine must be prepared to run in parallel. */ union tree *do_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data) { union tree *ret_tree; struct nmgregion *r; struct bu_list vhead; RT_CK_TESS_TOL(tsp->ts_ttol); BN_CK_TOL(tsp->ts_tol); NMG_CK_MODEL(*tsp->ts_m); BU_LIST_INIT(&vhead); if (RT_G_DEBUG&DEBUG_TREEWALK || verbose) { char *sofar = db_path_to_string(pathp); bu_log("\ndo_region_end(%d %d%%) %s\n", regions_tried, regions_tried>0 ? (regions_done * 100) / regions_tried : 0, sofar); bu_free(sofar, "path string"); } if (curtree->tr_op == OP_NOP) return curtree; regions_tried++; /* Begin bomb protection */ if ( ncpu == 1 ) { if ( BU_SETJUMP ) { /* Error, bail out */ BU_UNSETJUMP; /* Relinquish the protection */ /* Sometimes the NMG library adds debugging bits when * it detects an internal error, before bombing out. */ rt_g.NMG_debug = NMG_debug; /* restore mode */ /* Release the tree memory & input regions */ db_free_tree(curtree, &rt_uniresource); /* Does an nmg_kr() */ /* Get rid of (m)any other intermediate structures */ if ( (*tsp->ts_m)->magic != -1L ) nmg_km(*tsp->ts_m); /* Now, make a new, clean model structure for next pass. */ *tsp->ts_m = nmg_mm(); goto out; } } (void)nmg_model_fuse(*tsp->ts_m, tsp->ts_tol); ret_tree = nmg_booltree_evaluate(curtree, tsp->ts_tol, &rt_uniresource); /* librt/nmg_bool.c */ BU_UNSETJUMP; /* Relinquish the protection */ if ( ret_tree ) r = ret_tree->tr_d.td_r; else r = (struct nmgregion *)NULL; regions_done++; if (r != 0) { FILE *fp_psurf; int i; struct bu_vls file_base; struct bu_vls file; bu_vls_init(&file_base); bu_vls_init(&file); bu_vls_strcpy(&file_base, prefix); bu_vls_strcat(&file_base, DB_FULL_PATH_CUR_DIR(pathp)->d_namep); /* Dots confuse Jack's Peabody language. Change to '_'. */ for (i = 0; i < file_base.vls_len; i++) if (file_base.vls_str[i] == '.') file_base.vls_str[i] = '_'; /* Write color attribute to .fig figure file. */ if (tsp->ts_mater.ma_color_valid != 0) { fprintf(fp_fig, "\tattribute %s {\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\trgb = (%f, %f, %f);\n", V3ARGS(tsp->ts_mater.ma_color)); fprintf(fp_fig, "\t\tambient = 0.18;\n"); fprintf(fp_fig, "\t\tdiffuse = 0.72;\n"); fprintf(fp_fig, "\t}\n"); } /* Write segment attributes to .fig figure file. */ fprintf(fp_fig, "\tsegment %s_seg {\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\tpsurf=\"%s.pss\";\n", bu_vls_addr(&file_base)); if (tsp->ts_mater.ma_color_valid != 0) fprintf(fp_fig, "\t\tattribute=%s;\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\tsite base->location=trans(0, 0, 0);\n"); fprintf(fp_fig, "\t}\n"); if ( bu_vls_strlen(&base_seg) <= 0 ) { bu_vls_vlscat( &base_seg, &file_base ); } else { fprintf(fp_fig, "\tjoint %s_jt {\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\tconnect %s_seg.base to %s_seg.base;\n", bu_vls_addr(&file_base), bu_vls_addr(&base_seg) ); fprintf(fp_fig, "\t}\n"); } bu_vls_vlscat(&file, &file_base); bu_vls_strcat(&file, ".pss"); /* Required Jack suffix. */ /* Write psurf to .pss file. */ if ((fp_psurf = fopen(bu_vls_addr(&file), "wb")) == NULL) perror(bu_vls_addr(&file)); else { nmg_to_psurf(r, fp_psurf); fclose(fp_psurf); if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file)); } bu_vls_free(&file); /* Also write as UNIX-plot file, if desired */ if ( debug_plots ) { FILE *fp; bu_vls_vlscat(&file, &file_base); bu_vls_strcat(&file, ".pl"); if ((fp = fopen(bu_vls_addr(&file), "wb")) == NULL) perror(bu_vls_addr(&file)); else { struct bu_list vhead; pl_color( fp, (int)(tsp->ts_mater.ma_color[0] * 255), (int)(tsp->ts_mater.ma_color[1] * 255), (int)(tsp->ts_mater.ma_color[2] * 255) ); /* nmg_pl_r( fp, r ); */ BU_LIST_INIT( &vhead ); nmg_r_to_vlist( &vhead, r, 0 ); rt_vlist_to_uplot( fp, &vhead ); fclose(fp); if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file)); } bu_vls_free(&file); } /* NMG region is no longer necessary */ nmg_kr(r); } /* * Dispose of original tree, so that all associated dynamic * memory is released now, not at the end of all regions. * A return of TREE_NULL from this routine signals an error, * so we need to cons up an OP_NOP node to return. */ db_free_tree(curtree, &rt_uniresource); /* Does an nmg_kr() */ out: BU_GETUNION(curtree, tree); curtree->magic = RT_TREE_MAGIC; curtree->tr_op = OP_NOP; return(curtree); }
/** * Apply a transformation matrix to the specified 'ip' input revolve * object, storing the results in the specified 'op' out pointer or * creating a copy if NULL. */ int rt_revolve_xform( struct rt_db_internal *op, const mat_t mat, struct rt_db_internal *ip, int release, struct db_i *dbip, struct resource *resp) { struct rt_revolve_internal *rip, *rop; point_t tmp_vec; if (dbip) RT_CK_DBI(dbip); RT_CK_DB_INTERNAL(ip); RT_CK_RESOURCE(resp); rip = (struct rt_revolve_internal *)ip->idb_ptr; RT_REVOLVE_CK_MAGIC(rip); if (bu_debug&BU_DEBUG_MEM_CHECK) { bu_log("Barrier check at start of revolve_xform():\n"); bu_mem_barriercheck(); } if (op != ip) { RT_DB_INTERNAL_INIT(op); BU_ALLOC(rop, struct rt_revolve_internal); rop->magic = RT_REVOLVE_INTERNAL_MAGIC; bu_vls_init(&rop->sketch_name); bu_vls_vlscat(&rop->sketch_name, &rip->sketch_name); op->idb_ptr = (void *)rop; op->idb_meth = &OBJ[ID_REVOLVE]; op->idb_major_type = DB5_MAJORTYPE_BRLCAD; op->idb_type = ID_REVOLVE; if (ip->idb_avs.magic == BU_AVS_MAGIC) { bu_avs_init(&op->idb_avs, ip->idb_avs.count, "avs"); bu_avs_merge(&op->idb_avs, &ip->idb_avs); } } else { rop = (struct rt_revolve_internal *)ip->idb_ptr; } MAT4X3PNT(tmp_vec, mat, rip->v3d); VMOVE(rop->v3d, tmp_vec); MAT4X3VEC(tmp_vec, mat, rip->axis3d); VMOVE(rop->axis3d, tmp_vec); V2MOVE(rop->v2d, rip->v2d); V2MOVE(rop->axis2d, rip->axis2d); if (release && ip != op) { rop->skt = rip->skt; rip->skt = (struct rt_sketch_internal *)NULL; rt_db_free_internal(ip); } else if (rip->skt) { rop->skt = rt_copy_sketch(rip->skt); } else { rop->skt = (struct rt_sketch_internal *)NULL; } if (bu_debug&BU_DEBUG_MEM_CHECK) { bu_log("Barrier check at end of revolve_xform():\n"); bu_mem_barriercheck(); } return 0; }
int bu_cmdhist_history(void *data, int argc, const char *argv[]) { FILE *fp; int with_delays = 0; struct bu_cmdhist *hp, *hp_prev; struct bu_vls str = BU_VLS_INIT_ZERO; struct timeval tvdiff; struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)data; if (argc < 2 || 5 < argc) { bu_log("Usage: %s -delays\nList command history.\n", argv[0]); return BRLCAD_ERROR; } fp = NULL; while (argc >= 3) { const char *delays = "-delays"; const char *outfile = "-outfile"; if (BU_STR_EQUAL(argv[2], delays)) with_delays = 1; else if (BU_STR_EQUAL(argv[2], outfile)) { if (fp != NULL) { fclose(fp); bu_log("%s: -outfile option given more than once\n", argv[0]); return BRLCAD_ERROR; } else if (argc < 4 || BU_STR_EQUAL(argv[3], delays)) { bu_log("%s: I need a file name\n", argv[0]); return BRLCAD_ERROR; } else { fp = fopen(argv[3], "ab+"); if (UNLIKELY(fp == NULL)) { bu_log("%s: error opening file", argv[0]); return BRLCAD_ERROR; } --argc; ++argv; } } else { bu_log("Invalid option %s\n", argv[2]); } --argc; ++argv; } for (BU_LIST_FOR(hp, bu_cmdhist, &chop->cho_head.l)) { bu_vls_trunc(&str, 0); hp_prev = BU_LIST_PREV(bu_cmdhist, &hp->l); if (with_delays && BU_LIST_NOT_HEAD(hp_prev, &chop->cho_head.l)) { if (cmdhist_timediff(&tvdiff, &(hp_prev->h_finish), &(hp->h_start)) >= 0) bu_vls_printf(&str, "delay %ld %ld\n", (long)tvdiff.tv_sec, (long)tvdiff.tv_usec); } if (hp->h_status == BRLCAD_ERROR) bu_vls_printf(&str, "# "); bu_vls_vlscat(&str, &(hp->h_command)); if (fp != NULL) bu_vls_fwrite(fp, &str); else bu_log("%s\n", bu_vls_addr(&str)); } if (fp != NULL) fclose(fp); return BRLCAD_OK; }
/* * D O _ R E G I O N _ E N D * * Called from db_walk_tree(). * * This routine must be prepared to run in parallel. */ union tree *do_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, genptr_t UNUSED(client_data)) { union tree *ret_tree; struct nmgregion *r; RT_CK_TESS_TOL(tsp->ts_ttol); BN_CK_TOL(tsp->ts_tol); NMG_CK_MODEL(*tsp->ts_m); if (RT_G_DEBUG&DEBUG_TREEWALK || verbose) { char *sofar = db_path_to_string(pathp); bu_log("\ndo_region_end(%d %d%%) %s\n", regions_tried, regions_tried>0 ? (regions_done * 100) / regions_tried : 0, sofar); bu_free(sofar, "path string"); } if (curtree->tr_op == OP_NOP) return curtree; regions_tried++; ret_tree = process_boolean(curtree, tsp, pathp); if ( ret_tree ) r = ret_tree->tr_d.td_r; else r = (struct nmgregion *)NULL; regions_done++; if (r != 0) { FILE *fp_psurf; size_t i; struct bu_vls file_base = BU_VLS_INIT_ZERO; struct bu_vls file = BU_VLS_INIT_ZERO; bu_vls_strcpy(&file_base, prefix); bu_vls_strcat(&file_base, DB_FULL_PATH_CUR_DIR(pathp)->d_namep); /* Dots confuse Jack's Peabody language. Change to '_'. */ for (i = 0; i < file_base.vls_len; i++) if (file_base.vls_str[i] == '.') file_base.vls_str[i] = '_'; /* Write color attribute to .fig figure file. */ if (tsp->ts_mater.ma_color_valid != 0) { fprintf(fp_fig, "\tattribute %s {\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\trgb = (%f, %f, %f);\n", V3ARGS(tsp->ts_mater.ma_color)); fprintf(fp_fig, "\t\tambient = 0.18;\n"); fprintf(fp_fig, "\t\tdiffuse = 0.72;\n"); fprintf(fp_fig, "\t}\n"); } /* Write segment attributes to .fig figure file. */ fprintf(fp_fig, "\tsegment %s_seg {\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\tpsurf=\"%s.pss\";\n", bu_vls_addr(&file_base)); if (tsp->ts_mater.ma_color_valid != 0) fprintf(fp_fig, "\t\tattribute=%s;\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\tsite base->location=trans(0, 0, 0);\n"); fprintf(fp_fig, "\t}\n"); if ( bu_vls_strlen(&base_seg) <= 0 ) { bu_vls_vlscat( &base_seg, &file_base ); } else { fprintf(fp_fig, "\tjoint %s_jt {\n", bu_vls_addr(&file_base)); fprintf(fp_fig, "\t\tconnect %s_seg.base to %s_seg.base;\n", bu_vls_addr(&file_base), bu_vls_addr(&base_seg) ); fprintf(fp_fig, "\t}\n"); } bu_vls_vlscat(&file, &file_base); bu_vls_strcat(&file, ".pss"); /* Required Jack suffix. */ /* Write psurf to .pss file. */ if ((fp_psurf = fopen(bu_vls_addr(&file), "wb")) == NULL) perror(bu_vls_addr(&file)); else { nmg_to_psurf(r, fp_psurf); fclose(fp_psurf); if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file)); } bu_vls_free(&file); /* Also write as UNIX-plot file, if desired */ if ( debug_plots ) { FILE *fp; bu_vls_vlscat(&file, &file_base); bu_vls_strcat(&file, ".pl"); if ((fp = fopen(bu_vls_addr(&file), "wb")) == NULL) perror(bu_vls_addr(&file)); else { struct bu_list vhead; pl_color( fp, (int)(tsp->ts_mater.ma_color[0] * 255), (int)(tsp->ts_mater.ma_color[1] * 255), (int)(tsp->ts_mater.ma_color[2] * 255) ); /* nmg_pl_r( fp, r ); */ BU_LIST_INIT( &vhead ); nmg_r_to_vlist( &vhead, r, 0 ); rt_vlist_to_uplot( fp, &vhead ); fclose(fp); if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file)); } bu_vls_free(&file); } /* NMG region is no longer necessary */ nmg_kr(r); } /* * Dispose of original tree, so that all associated dynamic * memory is released now, not at the end of all regions. * A return of TREE_NULL from this routine signals an error, * so we need to cons up an OP_NOP node to return. */ db_free_tree(curtree, &rt_uniresource); /* Does an nmg_kr() */ BU_ALLOC(curtree, union tree); RT_TREE_INIT(curtree); curtree->tr_op = OP_NOP; return curtree; }
/** * This function parses the input shaders * Example: * shadername=color#Cin#point#0.0#0.0#1.0 * shadername=glass * shadername=checker#K#float#4.0 * join=color#Cout#shader#Cin1 * join=glass#Cout#shader#Cin1 **/ int osl_parse(const struct bu_vls *in_vls, ShaderGroupInfo &group_info) { struct bu_vls vls = BU_VLS_INIT_ZERO; register char *cp; char *name; char *value; int retval; BU_CK_VLS(in_vls); /* Duplicate the input string. This algorithm is destructive. */ bu_vls_vlscat(&vls, in_vls); cp = bu_vls_addr(&vls); while (*cp) { /* NAME = VALUE white-space-separator */ /* skip any leading whitespace */ while (*cp != '\0' && isspace(*cp)) cp++; /* Find equal sign */ name = cp; while (*cp != '\0' && *cp != '=') cp++; if (*cp == '\0') { if (name == cp) break; /* end of string in middle of arg */ bu_log("bu_structparse: input keyword '%s' is not followed by '=' in '%s'\nInput must be in keyword=value format.\n", name, bu_vls_addr(in_vls)); bu_vls_free(&vls); return -2; } *cp++ = '\0'; /* Find end of value. */ if (*cp == '"') { /* strings are double-quote (") delimited skip leading " & * find terminating " while skipping escaped quotes (\") */ for (value = ++cp; *cp != '\0'; ++cp) if (*cp == '"' && (cp == value || *(cp-1) != '\\')) break; if (*cp != '"') { bu_log("bu_structparse: keyword '%s'=\" without closing \"\n", name); bu_vls_free(&vls); return -3; } } else { /* non-strings are white-space delimited */ value = cp; while (*cp != '\0' && !isspace(*cp)) cp++; } if (*cp != '\0') *cp++ = '\0'; if (BU_STR_EQUAL(name, "shadername")) { ShaderInfo sh_info; osl_parse_shader(value, sh_info); group_info.shader_layers.push_back(sh_info); } else if (BU_STR_EQUAL(name, "join")) { ShaderEdge sh_edge; osl_parse_edge(value, sh_edge); group_info.shader_edges.push_back(sh_edge); } } bu_vls_free(&vls); return 0; }
/** * find a new unique name given a list of previously used names, and * the type of naming mode that described what type of affix to use. */ static char * get_new_name(const char *name, struct db_i *dbip, Tcl_HashTable *name_tbl, Tcl_HashTable *used_names_tbl, struct ged_concat_data *cc_data) { struct bu_vls new_name = BU_VLS_INIT_ZERO; Tcl_HashEntry *ptr = NULL; char *aname = NULL; char *ret_name = NULL; int int_new=0; long num=0; RT_CK_DBI(dbip); BU_ASSERT(name_tbl); BU_ASSERT(used_names_tbl); BU_ASSERT(cc_data); if (!name) { bu_log("WARNING: encountered NULL name, renaming to \"UNKNOWN\"\n"); name = "UNKNOWN"; } ptr = Tcl_CreateHashEntry(name_tbl, name, &int_new); if (!int_new) { return (char *)Tcl_GetHashValue(ptr); } do { /* iterate until we find an object name that is not in * use, trying to accommodate the user's requested affix * naming mode. */ bu_vls_trunc(&new_name, 0); if (cc_data->copy_mode & NO_AFFIX) { if (num > 0 && cc_data->copy_mode & CUSTOM_PREFIX) { /* auto-increment prefix */ bu_vls_printf(&new_name, "%ld_", num); } bu_vls_strcat(&new_name, name); if (num > 0 && cc_data->copy_mode & CUSTOM_SUFFIX) { /* auto-increment suffix */ bu_vls_printf(&new_name, "_%ld", num); } } else if (cc_data->copy_mode & CUSTOM_SUFFIX) { /* use custom suffix */ bu_vls_strcpy(&new_name, name); if (num > 0) { bu_vls_printf(&new_name, "_%ld_", num); } bu_vls_vlscat(&new_name, &cc_data->affix); } else if (cc_data->copy_mode & CUSTOM_PREFIX) { /* use custom prefix */ bu_vls_vlscat(&new_name, &cc_data->affix); if (num > 0) { bu_vls_printf(&new_name, "_%ld_", num); } bu_vls_strcat(&new_name, name); } else if (cc_data->copy_mode & AUTO_SUFFIX) { /* use auto-incrementing suffix */ bu_vls_strcat(&new_name, name); bu_vls_printf(&new_name, "_%ld", num); } else if (cc_data->copy_mode & AUTO_PREFIX) { /* use auto-incrementing prefix */ bu_vls_printf(&new_name, "%ld_", num); bu_vls_strcat(&new_name, name); } else { /* no custom suffix/prefix specified, use prefix */ if (num > 0) { bu_vls_printf(&new_name, "_%ld", num); } bu_vls_strcpy(&new_name, name); } /* make sure it fits for v4 */ if (db_version(cc_data->old_dbip) < 5) { if (bu_vls_strlen(&new_name) > _GED_V4_MAXNAME) { bu_log("ERROR: generated new name [%s] is too long (%zu > %d)\n", bu_vls_addr(&new_name), bu_vls_strlen(&new_name), _GED_V4_MAXNAME); } return NULL; } aname = bu_vls_addr(&new_name); num++; } while (db_lookup(dbip, aname, LOOKUP_QUIET) != RT_DIR_NULL || Tcl_FindHashEntry(used_names_tbl, aname) != NULL); /* if they didn't get what they asked for, warn them */ if (num > 1) { if (cc_data->copy_mode & NO_AFFIX) { bu_log("WARNING: unable to import [%s] without an affix, imported as [%s]\n", name, bu_vls_addr(&new_name)); } else if (cc_data->copy_mode & CUSTOM_SUFFIX) { bu_log("WARNING: unable to import [%s] as [%s%s], imported as [%s]\n", name, name, bu_vls_addr(&cc_data->affix), bu_vls_addr(&new_name)); } else if (cc_data->copy_mode & CUSTOM_PREFIX) { bu_log("WARNING: unable to import [%s] as [%s%s], imported as [%s]\n", name, bu_vls_addr(&cc_data->affix), name, bu_vls_addr(&new_name)); } } /* we should now have a unique name. store it in the hash */ ret_name = bu_vls_strgrab(&new_name); Tcl_SetHashValue(ptr, (ClientData)ret_name); (void)Tcl_CreateHashEntry(used_names_tbl, ret_name, &int_new); bu_vls_free(&new_name); return ret_name; }