static void _bu_add_to_list(const char *fn, int fd) { struct _bu_tf_list *newtf; _bu_temp_files++; if (_bu_temp_files == 1) { /* schedule files for closure on exit */ atexit(_bu_close_files); BU_GETSTRUCT(_bu_tf, _bu_tf_list); BU_LIST_INIT(&(_bu_tf->l)); bu_vls_init(&_bu_tf->fn); bu_vls_strcpy(&_bu_tf->fn, fn); _bu_tf->fd = fd; return; } BU_GETSTRUCT(newtf, _bu_tf_list); bu_vls_init(&_bu_tf->fn); bu_vls_strcpy(&_bu_tf->fn, fn); newtf->fd = fd; BU_LIST_PUSH(&(_bu_tf->l), &(newtf->l)); return; }
char * Build_unique_name(char *name) { struct name_conv_list *ptr; int name_len; int tries=0; name_len = strlen( name ); bu_vls_strcpy( &ret_name, name ); ptr = name_root; while ( ptr ) { if ( !strcmp( bu_vls_addr( &ret_name ), ptr->brlcad_name ) || (ptr->solid_name && !strcmp( bu_vls_addr( &ret_name ), ptr->solid_name ) ) ) { /* this name already exists, build a new one */ ++tries; bu_vls_trunc( &ret_name, name_len ); bu_vls_printf( &ret_name, "_%d", tries ); ptr = name_root; } ptr = ptr->next; } return( bu_vls_addr( &ret_name ) ); }
HIDDEN struct bu_cmdhist_obj * cho_open(ClientData UNUSED(clientData), Tcl_Interp *interp, const char *name) { struct bu_cmdhist_obj *chop; /* check to see if command history object exists */ for (BU_LIST_FOR(chop, bu_cmdhist_obj, &HeadCmdHistObj.l)) { if (BU_STR_EQUAL(name, bu_vls_addr(&chop->cho_name))) { Tcl_AppendResult(interp, "ch_open: ", name, " exists.\n", (char *)NULL); return BU_CMDHIST_OBJ_NULL; } } BU_GET(chop, struct bu_cmdhist_obj); bu_vls_init(&chop->cho_name); bu_vls_strcpy(&chop->cho_name, name); BU_LIST_INIT(&chop->cho_head.l); bu_vls_init(&chop->cho_head.h_command); chop->cho_head.h_start.tv_sec = chop->cho_head.h_start.tv_usec = chop->cho_head.h_finish.tv_sec = chop->cho_head.h_finish.tv_usec = 0L; chop->cho_head.h_status = TCL_OK; chop->cho_curr = &chop->cho_head; BU_LIST_APPEND(&HeadCmdHistObj.l, &chop->l); return chop; }
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; }
int Dm_Init(void *interpreter) { Tcl_Interp *interp = (Tcl_Interp *)interpreter; static struct bu_cmdtab cmdtab[] = { {"dm_validXType", dm_validXType_tcl}, {"dm_bestXType", dm_bestXType_tcl}, {(const char *)NULL, BU_CMD_NULL} }; struct bu_vls vls = BU_VLS_INIT_ZERO; /* register commands */ register_cmds(interp, cmdtab); bu_vls_strcpy(&vls, "vectorThreshold"); Tcl_LinkVar(interp, bu_vls_addr(&vls), (char *)&vectorThreshold, TCL_LINK_INT); bu_vls_free(&vls); /* initialize display manager object code */ Dmo_Init(interp); Tcl_PkgProvide(interp, "Dm", brlcad_version()); return TCL_OK; }
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; }
int dm_processOptions(dm *dmp, struct bu_vls *init_proc_vls, int argc, char **argv) { int c; bu_optind = 0; /* re-init bu_getopt */ bu_opterr = 0; while ((c = bu_getopt(argc, argv, "N:S:W:s:d:i:n:t:")) != -1) { switch (c) { case 'N': dmp->dm_height = atoi(bu_optarg); break; case 'S': case 's': dmp->dm_width = dmp->dm_height = atoi(bu_optarg); break; case 'W': dmp->dm_width = atoi(bu_optarg); break; case 'd': bu_vls_strcpy(&dmp->dm_dName, bu_optarg); break; case 'i': bu_vls_strcpy(init_proc_vls, bu_optarg); break; case 'n': if (*bu_optarg != '.') bu_vls_printf(&dmp->dm_pathName, ".%s", bu_optarg); else bu_vls_strcpy(&dmp->dm_pathName, bu_optarg); break; case 't': dmp->dm_top = atoi(bu_optarg); break; default: bu_log("dm_processOptions: option '%c' unknown\n", bu_optopt); break; } } return bu_optind; }
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); }
/** * returns the next available/unused name, using a consistent naming * convention specific to combinations/regions and solids. * state->incr is used for each number level increase. */ static struct bu_vls * get_name(struct db_i *_dbip, struct directory *dp, struct clone_state *state, int iter) { struct bu_vls *newname; char prefix[CLONE_BUFSIZE] = {0}, suffix[CLONE_BUFSIZE] = {0}, buf[CLONE_BUFSIZE] = {0}, suffix2[CLONE_BUFSIZE] = {0}; int num = 0, i = 1, j = 0; newname = bu_vls_vlsinit(); /* Ugh. This needs much repair/cleanup. */ if (state->updpos == 0) { sscanf(dp->d_namep, "%[!-/,:-~]%d%[!-/,:-~]%512s", prefix, &num, suffix, suffix2); /* CLONE_BUFSIZE */ snprintf(suffix, CLONE_BUFSIZE, "%s", suffix2); } else if (state->updpos == 1) { int num2 = 0; sscanf(dp->d_namep, "%[!-/,:-~]%d%[!-/,:-~]%d%[!-/,:-~]", prefix, &num2, suffix2, &num, suffix); snprintf(prefix, CLONE_BUFSIZE, "%s%d%s", prefix, num2, suffix2); } else bu_exit(EXIT_FAILURE, "multiple -c options not supported yet."); do { /* choke the name back to the prefix */ bu_vls_trunc(newname, 0); bu_vls_strcpy(newname, prefix); if ((dp->d_flags & RT_DIR_SOLID) || (dp->d_flags & RT_DIR_REGION)) { /* primitives and regions */ if (suffix[0] != 0) if ((i == 1) && is_in_list(obj_list, buf)) { j = index_in_list(obj_list, buf); snprintf(buf, CLONE_BUFSIZE, "%s%d", prefix, num); /* save the name for the next pass */ /* clear and set the name */ bu_vls_trunc(newname, 0); bu_vls_printf(newname, "%V%s", obj_list.names[j].dest[iter], suffix); } else bu_vls_printf(newname, "%zu%s", num+i*state->incr, suffix); else bu_vls_printf(newname, "%zu", num + i*state->incr); } else /* non-region combinations */ bu_vls_printf(newname, "%d", (num==0)?i+1:i+num); i++; } while (db_lookup(_dbip, bu_vls_addr(newname), LOOKUP_QUIET) != NULL); return newname; }
/** * Routine to format the parameters of an ARBN primitive for "db get" * * Legal requested parameters include: * "N" - number of equations * "P" - list of all the planes * "P#" - the specified plane number (0 based) * no arguments returns everything */ int rt_arbn_get(struct bu_vls *logstr, const struct rt_db_internal *intern, const char *attr) { struct rt_arbn_internal *arbn=(struct rt_arbn_internal *)intern->idb_ptr; size_t i; long val; RT_ARBN_CK_MAGIC(arbn); if (attr == (char *)NULL) { bu_vls_strcpy(logstr, "arbn"); bu_vls_printf(logstr, " N %zu", arbn->neqn); for (i = 0; i < arbn->neqn; i++) { bu_vls_printf(logstr, " P%zu {%.25g %.25g %.25g %.25g}", i, V4ARGS(arbn->eqn[i])); } } else if (BU_STR_EQUAL(attr, "N")) { bu_vls_printf(logstr, "%zu", arbn->neqn); } else if (BU_STR_EQUAL(attr, "P")) { for (i = 0; i < arbn->neqn; i++) { bu_vls_printf(logstr, " P%zu {%.25g %.25g %.25g %.25g}", i, V4ARGS(arbn->eqn[i])); } } else if (attr[0] == 'P') { if (isdigit((int)attr[1]) == 0) { bu_vls_printf(logstr, "ERROR: Illegal plane number\n"); return BRLCAD_ERROR; } val = atol(&attr[1]); if (val < 0 || (size_t)val >= arbn->neqn) { bu_vls_printf(logstr, "ERROR: Illegal plane number [%ld]\n", val); return BRLCAD_ERROR; } i = (size_t)val; bu_vls_printf(logstr, "%.25g %.25g %.25g %.25g", V4ARGS(arbn->eqn[i])); } else { bu_vls_printf(logstr, "ERROR: Unknown attribute, choices are N, P, or P#\n"); return BRLCAD_ERROR; } return BRLCAD_OK; }
void mged_vls_struct_parse_old( struct bu_vls *vls, const char *title, struct bu_structparse *how_to_parse, 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) { struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; bu_vls_strcpy(&tmp_vls, argv[1]); if (bu_struct_parse(&tmp_vls, how_to_parse, structp) < 0) bu_log("Warning - bu_struct_parse failure, mged_vls_struct_parse_old.\n"); bu_vls_free(&tmp_vls); } }
/** * add a new name to the name list */ static int add_to_list(struct nametbl *l, char *name) { size_t i, j; /* * add more slots if adding 1 more new name will fill up all the * available slots. */ if (l->names_len == (l->names_used+1)) { l->names_len += 10; l->names = (struct name *)bu_realloc(l->names, sizeof(struct name)*(l->names_len+1), "realloc l->names"); for (i = l->names_used; i < l->names_len; i++) { bu_vls_init(&l->names[i].src); l->names[i].dest = (struct bu_vls *)bu_calloc(l->name_size, sizeof(struct bu_vls), "alloc l->names.dest"); for (j = 0; j < l->name_size; j++) bu_vls_init(&l->names[i].dest[j]); } } bu_vls_strcpy(&l->names[l->names_used++].src, name); return l->names_used-1; /* return number of available slots */ }
/** * make a copy of a v4 solid by adding it to our book-keeping list, * adding it to the db directory, and writing it out to disk. */ static void copy_v4_solid(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; union record *rp = (union record *)NULL; size_t i, j; /* make n copies */ for (i = 0; i < state->n_copies; i++) { struct bu_vls *name; if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } /* XXX: this can probably be optimized. */ bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); bu_vls_free(name); /* add the object to the directory */ dp = db_diradd(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i]), RT_DIR_PHONY_ADDR, proto->d_len, proto->d_flags, &proto->d_minor_type); if ((dp == RT_DIR_NULL) || (db_alloc(_dbip, dp, proto->d_len) < 0)) { TCL_ALLOC_ERR; return; } /* get an in-memory reference to the object being copied */ if ((rp = db_getmrec(_dbip, proto)) == (union record *)0) { TCL_READ_ERR; return; } if (rp->u_id == ID_SOLID) { bu_strlcpy(rp->s.s_name, dp->d_namep, NAMESIZE); /* mirror */ if (state->miraxis != W) { /* XXX er, this seems rather wrong .. but it's v4 so punt */ rp->s.s_values[state->miraxis] += 2 * (state->mirpos - rp->s.s_values[state->miraxis]); for (j = 3+state->miraxis; j < 24; j++) rp->s.s_values[j] = -rp->s.s_values[j]; } /* translate */ if (state->trans[W] > SMALL_FASTF) /* assumes primitive's first parameter is its position */ VADD2(rp->s.s_values, rp->s.s_values, state->trans); /* rotate */ if (state->rot[W] > SMALL_FASTF) { mat_t r; vect_t vec, ovec; if (state->rpnt[W] > SMALL_FASTF) VSUB2(rp->s.s_values, rp->s.s_values, state->rpnt); MAT_IDN(r); bn_mat_angles(r, state->rot[X], state->rot[Y], state->rot[Z]); for (j = 0; j < 24; j+=3) { VMOVE(vec, rp->s.s_values+j); MAT4X3VEC(ovec, r, vec); VMOVE(rp->s.s_values+j, ovec); } if (state->rpnt[W] > SMALL_FASTF) VADD2(rp->s.s_values, rp->s.s_values, state->rpnt); } } else bu_log("mods not available on %s\n", proto->d_namep); /* write the object to disk */ if (db_put(_dbip, dp, rp, 0, dp->d_len) < 0) { bu_log("ERROR: clone internal error writing to the database\n"); return; } } if (rp) bu_free((char *)rp, "copy_solid record[]"); return; }
/* * 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; }
/** * 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; }
int main(int argc, char **argv) { /* static to prevent longjmp clobber warning */ static FILE *stream = NULL; static unsigned long line_num = 0; static unsigned long failed_cnt = 0; static unsigned long bomb_cnt = 0; static unsigned long success_cnt = 0; static int ret = 0; char buf[BUFSIZ]; FILE *fp_in = NULL; char *endp = NULL; size_t string_length; int argv_idx; int c; char dt_fmt[50]; /* data type format string */ char *buf_p1; char *buf_p; struct bn_tol tol; /* command line parameters */ static unsigned long test_case_line_num = 0; /* static due to longjmp */ static unsigned long function_num = 0; /* static due to longjmp */ struct bu_vls input_file_name = BU_VLS_INIT_ZERO; struct bu_vls output_file_name = BU_VLS_INIT_ZERO; /* function parameter arrays */ int i[50] = {0}; long l[50] = {0}; fastf_t d[50] = {0.0}; unsigned long u[50] = {0}; /* boolean variables */ static int output_file_name_defined = 0; /* static due to longjmp */ static int process_single_test_case = 0; /* static due to longjmp */ static int process_single_function = 0; /* static due to longjmp */ int input_file_name_defined = 0; int valid_function_number = 0; int process_test_case = 0; int early_exit = 0; static int found_eof = 0; /* static due to longjmp */ /* set initial values in tol structure */ tol.magic = BN_TOL_MAGIC; tol.dist = BN_TOL_DIST; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1.0 - tol.perp; if (argc < 2) { bu_log("Too few parameters, %d specified, at least 1 required\n", argc - 1); bu_exit(EXIT_FAILURE, USAGE); } while ((c = bu_getopt(argc, argv, "l:f:i:o:")) != -1) { switch (c) { case 'l': /* test case line number */ errno = 0; test_case_line_num = strtoul(bu_optarg, &endp, 10); if (errno) { bu_log("Invalid test case line number '%s' '%s'\n", bu_optarg, strerror(errno)); bu_exit(EXIT_FAILURE, USAGE); } if ((*endp != '\0') || (bu_optarg == endp) || (strchr(bu_optarg, '-') != '\0')) { bu_log("Invalid test case line number '%s'\n", bu_optarg); bu_exit(EXIT_FAILURE, USAGE); } process_single_test_case = 1; break; case 'f': /* function number */ errno = 0; function_num = strtoul(bu_optarg, &endp, 10); if (errno) { bu_log("Invalid function number '%s' '%s'\n", bu_optarg, strerror(errno)); bu_exit(EXIT_FAILURE, USAGE); } if ((*endp != '\0') || (bu_optarg == endp) || (strchr(bu_optarg, '-') != '\0')) { bu_log("Invalid function number '%s'\n", bu_optarg); bu_exit(EXIT_FAILURE, USAGE); } process_single_function = 1; break; case 'i': /* input file name */ string_length = strlen(bu_optarg); if (string_length >= BUFSIZ) { bu_log("Input file name too long, length was %d but must be less than %d\n", string_length, BUFSIZ); bu_exit(EXIT_FAILURE, USAGE); } bu_vls_strcpy(&input_file_name, bu_optarg); input_file_name_defined = 1; break; case 'o': /* output file name */ string_length = strlen(bu_optarg); if (string_length >= BUFSIZ) { bu_log("Output file name too long, length was %d but must be less than %d\n", string_length, BUFSIZ); bu_exit(EXIT_FAILURE, USAGE); } bu_vls_strcpy(&output_file_name, bu_optarg); output_file_name_defined = 1; break; default: bu_log("Invalid option '%c'.\n", c); bu_exit(EXIT_FAILURE, USAGE); break; } } if (process_single_test_case && process_single_function) { bu_log("Can not specify both test case line number and function number.\n"); early_exit = 1; } if (!input_file_name_defined) { bu_log("Input file name is required but was not specified.\n"); early_exit = 1; } if (early_exit) { bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); bu_exit(EXIT_FAILURE, USAGE); } if ((fp_in = fopen(bu_vls_addr(&input_file_name), "r")) == NULL) { bu_log("Cannot open input file (%s)\n", bu_vls_addr(&input_file_name)); bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); return EXIT_FAILURE; } if (output_file_name_defined) { if ((stream = fopen(bu_vls_addr(&output_file_name), "w")) == NULL) { bu_log("Cannot create output file (%s)\n", bu_vls_addr(&output_file_name)); if (fclose(fp_in) != 0) { bu_log("Unable to close input file.\n"); } bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); return EXIT_FAILURE; } } else { stream = stderr; } /* all output after this point is sent to stream */ fprintf(stream, "Command line parameters: bntester "); for (argv_idx = 1 ; argv_idx < argc ; argv_idx++) { fprintf(stream, "%s ", argv[argv_idx]); } fprintf(stream, "\n"); if (process_single_test_case) { fprintf(stream, "Processing only test case on line number: %lu\n", test_case_line_num); } if (process_single_function) { fprintf(stream, "Processing all test cases for function number: %lu\n", function_num); } if (!process_single_test_case && !process_single_function) { fprintf(stream, "Processing all test cases.\n"); } while (!found_eof) { if (line_num == ULONG_MAX) { fprintf(stream, "ERROR: Input data file exceeded max %lu number of lines.\n", ULONG_MAX); if (fclose(fp_in) != 0) { fprintf(stream, "Unable to close input file.\n"); } if (output_file_name_defined) { if (fclose(stream) != 0) { bu_log("Unable to close output file.\n"); } } bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); return EXIT_FAILURE; } line_num++; if (bu_fgets(buf, BUFSIZ, fp_in) == NULL) { if (feof(fp_in)) { found_eof = 1; continue; } if (ferror(fp_in)) { perror("ERROR: Problem reading file, system error message"); if (fclose(fp_in) != 0) { fprintf(stream, "Unable to close input file.\n"); } } else { perror("Oddness reading input file"); } bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); return EXIT_FAILURE; } else { /* Skip input data file lines which start with a '#' character * or a new line character. */ if ((buf[0] != '#') && (buf[0] != '\n')) { buf_p1 = strtok(buf, "\n"); buf_p = strtok(buf_p1, ", "); /* The 1st parameter of the test case is always an unsigned * long int which represents the function number. This logic * validates the test case function number to ensure it is * an unsigned long int. */ valid_function_number = 1; errno = 0; u[0] = strtoul(buf_p, &endp, 10); if (errno) { fprintf(stream, "Read function number failed, line %lu error msg: '%s' string '%s'\n", line_num, strerror(errno), buf_p); valid_function_number = 0; } else if ((*endp != '\0') || (buf_p == endp) || (strchr(buf_p, '-') != '\0')) { fprintf(stream, "Read function number failed, line %lu string '%s'\n", line_num, buf_p); valid_function_number = 0; } /* This logic restricts processing of the test case(s) to * only those specified by the bntester input parameters. */ process_test_case = 0; if (valid_function_number && process_single_test_case && (test_case_line_num == line_num)) { process_test_case = 1; } else if (valid_function_number && process_single_function && (function_num == u[0])) { process_test_case = 1; } else if (valid_function_number && !process_single_test_case && !process_single_function) { process_test_case = 1; } if (process_test_case) { /* Each case within this switch corresponds to each * function to be tested. */ switch (u[0]) { case 1: /* function 'bn_distsq_line3_pt3' */ bu_strlcpy(dt_fmt, "dddddddddd", sizeof(dt_fmt)); /* defines parameter data types */ if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) { /* Parse failed, skipping test case */ ret = 1; } else { double result; if (!BU_SETJUMP) { /* try */ result = bn_distsq_line3_pt3(&d[0], &d[3], &d[6]); if (!NEAR_EQUAL(result, d[9], VUNITIZE_TOL)) { ret = 1; failed_cnt++; fprintf(stream, "Failed function %lu test case on line %lu expected = %.15f result = %.15f\n", u[0], line_num, d[9], result); } else { success_cnt++; } } else { /* catch */ BU_UNSETJUMP; ret = 1; bomb_cnt++; fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num); } BU_UNSETJUMP; } break; case 2: /* function 'bn_2line3_colinear' */ bu_strlcpy(dt_fmt, "ddddddddddddduddddi", sizeof(dt_fmt)); if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) { /* Parse failed, skipping test case */ ret = 1; } else { int result; if (!BU_SETJUMP) { /* try */ tol.magic = u[1]; tol.dist = d[13]; tol.dist_sq = d[14]; tol.perp = d[15]; tol.para = d[16]; result = bn_2line3_colinear(&d[0], &d[3], &d[6], &d[9], d[12], &tol); if (result != i[0]) { ret = 1; failed_cnt++; fprintf(stream, "Failed function %lu test case on line %lu expected = %d result = %d\n", u[0], line_num, i[0], result); } else { success_cnt++; } } else { /* catch */ BU_UNSETJUMP; ret = 1; bomb_cnt++; fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num); } BU_UNSETJUMP; } break; case 3: /* function 'bn_isect_line3_line3' */ bu_strlcpy(dt_fmt, "dddddddddddddduddddi", sizeof(dt_fmt)); if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) { /* Parse failed, skipping test case */ ret = 1; } else { int result; fastf_t t_out = 0.0; fastf_t u_out = 0.0; int t_fail = 0; int u_fail = 0; if (!BU_SETJUMP) { /* try */ tol.magic = u[1]; tol.dist = d[14]; tol.dist_sq = d[15]; tol.perp = d[16]; tol.para = d[17]; result = bn_isect_line3_line3(&t_out, &u_out, &d[2], &d[5], &d[8], &d[11], &tol); if (result != i[0]) { ret = 1; failed_cnt++; fprintf(stream, "Failed function %lu test case on line %lu expected = %d result = %d\n", u[0], line_num, i[0], result); } else if (result == 0) { if (!NEAR_EQUAL(t_out, d[0], tol.dist)) { ret = 1; failed_cnt++; fprintf(stream, "Failed function %lu test case on line %lu result = %d expected t = %.15f result t = %.15f\n", u[0], line_num, result, d[0], t_out); } else { success_cnt++; } } else if (result == 1) { t_fail = !NEAR_EQUAL(t_out, d[0], tol.dist); u_fail = !NEAR_EQUAL(u_out, d[1], tol.dist); if (t_fail) { fprintf(stream, "Failed function %lu test case on line %lu result = %d expected t = %.15f result t = %.15f\n", u[0], line_num, result, d[0], t_out); } if (u_fail) { fprintf(stream, "Failed function %lu test case on line %lu result = %d expected u = %.15f result u = %.15f\n", u[0], line_num, result, d[1], u_out); } if (t_fail || u_fail) { ret = 1; failed_cnt++; } else { /* No other output to validate when result matches expected and * result is not 0 and not 1. */ success_cnt++; } } else { success_cnt++; } } else { /* catch */ BU_UNSETJUMP; ret = 1; bomb_cnt++; fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num); } BU_UNSETJUMP; } break; case 4: /* function 'bn_isect_lseg3_lseg3' */ bu_strlcpy(dt_fmt, "dddddddddddddduddddi", sizeof(dt_fmt)); if (parse_case(buf_p, i, l, d, u, dt_fmt, line_num, stream)) { /* Parse failed, skipping test case */ ret = 1; } else { int result; fastf_t dist[2] = {0.0, 0.0}; int d0_fail = 0; int d1_fail = 0; if (!BU_SETJUMP) { /* try */ tol.magic = u[1]; tol.dist = d[14]; tol.dist_sq = d[15]; tol.perp = d[16]; tol.para = d[17]; result = bn_isect_lseg3_lseg3(&dist[0], &d[2], &d[5], &d[8], &d[11], &tol); if (result != i[0]) { ret = 1; failed_cnt++; fprintf(stream, "Failed function %lu test case on line %lu expected = %d result = %d\n", u[0], line_num, i[0], result); } else if (result == 0 || result == 1) { d0_fail = !NEAR_EQUAL(dist[0], d[0], VUNITIZE_TOL); d1_fail = !NEAR_EQUAL(dist[1], d[1], VUNITIZE_TOL); if (d0_fail) { fprintf(stream, "Failed function %lu test case on line %lu result = %d expected dist[0] = %.15f result dist[0] = %.15f\n", u[0], line_num, result, d[0], dist[0]); } if (d1_fail) { fprintf(stream, "Failed function %lu test case on line %lu result = %d expected dist[1] = %.15f result dist[1] = %.15f\n", u[0], line_num, result, d[1], dist[1]); } if (d0_fail || d1_fail) { ret = 1; failed_cnt++; } else { /* No other output to validate when result matches expected and * result is not 0 and not 1. */ success_cnt++; } } else { success_cnt++; } } else { /* catch */ BU_UNSETJUMP; ret = 1; bomb_cnt++; fprintf(stream, "Failed function %lu test case on line %lu bu_bomb encountered.\n", u[0], line_num); } BU_UNSETJUMP; } break; default: fprintf(stream, "ERROR: Unknown function number %lu test case on line %lu, skipping test case.\n", u[0], line_num); bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); return EXIT_FAILURE; break; } /* End of function number switch */ } } /* End of if statement skipping lines starting with '#' or new line */ } } /* End of while loop reading lines from data file */ fprintf(stream, "Summary: %lu total test cases success.\n", success_cnt); fprintf(stream, "Summary: %lu total test cases failed.\n", failed_cnt); fprintf(stream, "Summary: %lu total test cases bomb.\n", bomb_cnt); if (output_file_name_defined) { bu_log("Summary: %lu total test cases success.\n", success_cnt); bu_log("Summary: %lu total test cases failed.\n", failed_cnt); bu_log("Summary: %lu total test cases bomb.\n", bomb_cnt); } fprintf(stream, "Done.\n"); if (output_file_name_defined) { bu_log("Done.\n"); } if (fclose(fp_in) != 0) { fprintf(stream, "Unable to close input file.\n"); } if (output_file_name_defined) { if (fclose(stream) != 0) { bu_log("Unable to close output file.\n"); } } bu_vls_free(&input_file_name); bu_vls_free(&output_file_name); return ret; }
/** * Import an REVOLVE from the database format to the internal format. * Note that the data read will be in network order. This means * Big-Endian integers and IEEE doubles for floating point. * * Apply modeling transformations as well. */ int rt_revolve_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip, struct resource *resp) { struct rt_revolve_internal *rip; /* must be double for import and export */ double vv[ELEMENTS_PER_VECT*3 + 1]; char *sketch_name; unsigned char *ptr; struct directory *dp; struct rt_db_internal tmp_ip; if (dbip) RT_CK_DBI(dbip); RT_CK_DB_INTERNAL(ip); BU_CK_EXTERNAL(ep); /* set up the internal structure */ ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_REVOLVE; ip->idb_meth = &OBJ[ID_REVOLVE]; BU_ALLOC(ip->idb_ptr, struct rt_revolve_internal); rip = (struct rt_revolve_internal *)ip->idb_ptr; rip->magic = RT_REVOLVE_INTERNAL_MAGIC; /* Convert the data in ep->ext_buf into internal format. Note the * conversion from network data (Big Endian ints, IEEE double * floating point) to host local data representations. */ ptr = (unsigned char *)ep->ext_buf; sketch_name = (char *)ptr + (ELEMENTS_PER_VECT*3 + 1)*SIZEOF_NETWORK_DOUBLE; if (!dbip) rip->skt = (struct rt_sketch_internal *)NULL; else if ((dp=db_lookup(dbip, sketch_name, LOOKUP_NOISY)) == RT_DIR_NULL) { bu_log("ERROR: Cannot find sketch (%s) for extrusion\n", sketch_name); rip->skt = (struct rt_sketch_internal *)NULL; } else { if (rt_db_get_internal(&tmp_ip, dp, dbip, bn_mat_identity, resp) != ID_SKETCH) { bu_log("ERROR: Cannot import sketch (%s) for extrusion\n", sketch_name); bu_free(ip->idb_ptr, "extrusion"); return -1; } else rip->skt = (struct rt_sketch_internal *)tmp_ip.idb_ptr; } bu_cv_ntohd((unsigned char *)&vv, (unsigned char *)ep->ext_buf, ELEMENTS_PER_VECT*3 + 1); /* Apply the modeling transformation */ if (mat == NULL) mat = bn_mat_identity; MAT4X3PNT(rip->v3d, mat, &vv[0*3]); MAT4X3PNT(rip->axis3d, mat, &vv[1*3]); MAT4X3PNT(rip->r, mat, &vv[2*3]); rip->ang = vv[9]; /* convert name of data location */ bu_vls_init(&rip->sketch_name); bu_vls_strcpy(&rip->sketch_name, (char *)ep->ext_buf + (ELEMENTS_PER_VECT * 3 + 1) * SIZEOF_NETWORK_DOUBLE); return 0; /* OK */ }
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 nmg_2_vrml(struct db_tree_state *tsp, const struct db_full_path *pathp, struct model *m) { struct mater_info *mater = &tsp->ts_mater; const struct bn_tol *tol2 = tsp->ts_tol; struct nmgregion *reg; struct bu_ptbl verts; struct vrml_mat mat; struct bu_vls vls = BU_VLS_INIT_ZERO; char *tok; int i; int first = 1; int is_light = 0; point_t ave_pt = VINIT_ZERO; struct bu_vls shape_name = BU_VLS_INIT_ZERO; char *full_path; /* There may be a better way to capture the region_id, than * getting the rt_comb_internal structure, (and may be a better * way to capture the rt_comb_internal struct), but for now I just * copied the method used in select_lights/select_non_lights above, * could have used a global variable but I noticed none other were * used, so I didn't want to be the first */ struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; /* static due to libbu exception handling */ static float r, g, b; NMG_CK_MODEL(m); full_path = db_path_to_string(pathp); RT_CK_FULL_PATH(pathp); dp = DB_FULL_PATH_CUR_DIR(pathp); if (!(dp->d_flags & RT_DIR_COMB)) { return; } id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource); if (id < 0) { bu_log("Cannot internal form of %s\n", dp->d_namep); return; } if (id != ID_COMBINATION) { bu_log("Directory/database mismatch!\n\t is '%s' a combination or not?\n", dp->d_namep); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (mater->ma_color_valid) { r = mater->ma_color[0]; g = mater->ma_color[1]; b = mater->ma_color[2]; } else { r = g = b = 0.5; } if (mater->ma_shader) { tok = strtok(mater->ma_shader, tok_sep); bu_strlcpy(mat.shader, tok, TXT_NAME_SIZE); } else { mat.shader[0] = '\0'; } mat.shininess = -1; mat.transparency = -1.0; mat.lt_fraction = -1.0; VSETALL(mat.lt_dir, 0.0); mat.lt_angle = -1.0; mat.tx_file[0] = '\0'; mat.tx_w = -1; mat.tx_n = -1; bu_vls_strcpy(&vls, &mater->ma_shader[strlen(mat.shader)]); (void)bu_struct_parse(&vls, vrml_mat_parse, (char *)&mat, NULL); if (bu_strncmp("light", mat.shader, 5) == 0) { /* this is a light source */ is_light = 1; } else { path_2_vrml_id(&shape_name, full_path); fprintf(fp_out, "\t\tDEF %s Shape {\n", bu_vls_addr(&shape_name)); fprintf(fp_out, "\t\t\t# Component_ID: %ld %s\n", comb->region_id, full_path); fprintf(fp_out, "\t\t\tappearance Appearance {\n"); if (bu_strncmp("plastic", mat.shader, 7) == 0) { if (mat.shininess < 0) { mat.shininess = 10; } if (mat.transparency < SMALL_FASTF) { mat.transparency = 0.0; } fprintf(fp_out, "\t\t\t\tmaterial Material {\n"); fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b); fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0)); if (mat.transparency > SMALL_FASTF) { fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency); } fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0); } else if (bu_strncmp("glass", mat.shader, 5) == 0) { if (mat.shininess < 0) { mat.shininess = 4; } if (mat.transparency < SMALL_FASTF) { mat.transparency = 0.8; } fprintf(fp_out, "\t\t\t\tmaterial Material {\n"); fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b); fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0)); if (mat.transparency > SMALL_FASTF) { fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency); } fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0); } else if (bu_strncmp("texture", mat.shader, 7) == 0) { if (mat.tx_w < 0) { mat.tx_w = 512; } if (mat.tx_n < 0) { mat.tx_n = 512; } if (strlen(mat.tx_file)) { int tex_fd; unsigned char tex_buf[TXT_BUF_LEN * 3]; if ((tex_fd = open(mat.tx_file, O_RDONLY | O_BINARY)) == (-1)) { bu_log("Cannot open texture file (%s)\n", mat.tx_file); perror("g-vrml: "); } else { long tex_len; long bytes_read = 0; long bytes_to_go = 0; /* Johns note - need to check (test) the texture stuff */ fprintf(fp_out, "\t\t\t\ttextureTransform TextureTransform {\n"); fprintf(fp_out, "\t\t\t\t\tscale 1.33333 1.33333\n\t\t\t\t}\n"); fprintf(fp_out, "\t\t\t\ttexture PixelTexture {\n"); fprintf(fp_out, "\t\t\t\t\trepeatS TRUE\n"); fprintf(fp_out, "\t\t\t\t\trepeatT TRUE\n"); fprintf(fp_out, "\t\t\t\t\timage %d %d %d\n", mat.tx_w, mat.tx_n, 3); tex_len = mat.tx_w*mat.tx_n * 3; while (bytes_read < tex_len) { int nbytes; long readval; bytes_to_go = tex_len - bytes_read; CLAMP(bytes_to_go, 0, TXT_BUF_LEN * 3); nbytes = 0; while (nbytes < bytes_to_go) { readval = read(tex_fd, &tex_buf[nbytes], bytes_to_go-nbytes); if (readval < 0) { perror("READ ERROR"); break; } else { nbytes += readval; } } bytes_read += nbytes; for (i = 0; i < nbytes; i += 3) { fprintf(fp_out, "\t\t\t0x%02x%02x%02x\n", tex_buf[i], tex_buf[i+1], tex_buf[i+2]); } } fprintf(fp_out, "\t\t\t\t}\n"); close(tex_fd); } } } else if (mater->ma_color_valid) { /* no shader specified, but a color is assigned */ fprintf(fp_out, "\t\t\t\tmaterial Material {\n"); fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g }\n", r, g, b); } else { /* If no color was defined set the colors according to the thousands groups */ int thou = comb->region_id / 1000; thou == 0 ? fprintf(fp_out, "\t\t\tmaterial USE Material_999\n") : thou == 1 ? fprintf(fp_out, "\t\t\tmaterial USE Material_1999\n") : thou == 2 ? fprintf(fp_out, "\t\t\tmaterial USE Material_2999\n") : thou == 3 ? fprintf(fp_out, "\t\t\tmaterial USE Material_3999\n") : thou == 4 ? fprintf(fp_out, "\t\t\tmaterial USE Material_4999\n") : thou == 5 ? fprintf(fp_out, "\t\t\tmaterial USE Material_5999\n") : thou == 6 ? fprintf(fp_out, "\t\t\tmaterial USE Material_6999\n") : thou == 7 ? fprintf(fp_out, "\t\t\tmaterial USE Material_7999\n") : thou == 8 ? fprintf(fp_out, "\t\t\tmaterial USE Material_8999\n") : fprintf(fp_out, "\t\t\tmaterial USE Material_9999\n"); } } if (!is_light) { nmg_triangulate_model(m, tol2); fprintf(fp_out, "\t\t\t}\n"); fprintf(fp_out, "\t\t\tgeometry IndexedFaceSet {\n"); fprintf(fp_out, "\t\t\t\tcoord Coordinate {\n"); } /* get list of vertices */ nmg_vertex_tabulate(&verts, &m->magic); if (!is_light) { fprintf(fp_out, "\t\t\t\t\tpoint ["); } else { VSETALL(ave_pt, 0.0); } for (i = 0; i < BU_PTBL_END(&verts); i++) { struct vertex *v; struct vertex_g *vg; point_t pt_meters; v = (struct vertex *)BU_PTBL_GET(&verts, i); NMG_CK_VERTEX(v); vg = v->vg_p; NMG_CK_VERTEX_G(vg); /* convert to desired units */ VSCALE(pt_meters, vg->coord, scale_factor); if (is_light) { VADD2(ave_pt, ave_pt, pt_meters); } if (first) { if (!is_light) { fprintf(fp_out, " %10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i); } first = 0; } else if (!is_light) { fprintf(fp_out, "\t\t\t\t\t%10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i); } } if (!is_light) { fprintf(fp_out, "\t\t\t\t\t]\n\t\t\t\t}\n"); } else { fastf_t one_over_count; one_over_count = 1.0/(fastf_t)BU_PTBL_END(&verts); VSCALE(ave_pt, ave_pt, one_over_count); } first = 1; if (!is_light) { fprintf(fp_out, "\t\t\t\tcoordIndex [\n"); for (BU_LIST_FOR(reg, nmgregion, &m->r_hd)) { struct shell *s; NMG_CK_REGION(reg); for (BU_LIST_FOR(s, shell, ®->s_hd)) { struct faceuse *fu; NMG_CK_SHELL(s); for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) { struct loopuse *lu; NMG_CK_FACEUSE(fu); if (fu->orientation != OT_SAME) { continue; } for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { struct edgeuse *eu; NMG_CK_LOOPUSE(lu); if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) { continue; } if (!first) { fprintf(fp_out, ",\n"); } else { first = 0; } fprintf(fp_out, "\t\t\t\t\t"); for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) { struct vertex *v; NMG_CK_EDGEUSE(eu); v = eu->vu_p->v_p; NMG_CK_VERTEX(v); fprintf(fp_out, " %d,", bu_ptbl_locate(&verts, (long *)v)); } fprintf(fp_out, "-1"); } } } } fprintf(fp_out, "\n\t\t\t\t]\n\t\t\t\tnormalPerVertex FALSE\n"); fprintf(fp_out, "\t\t\t\tconvex FALSE\n"); fprintf(fp_out, "\t\t\t\tcreaseAngle 0.5\n"); fprintf(fp_out, "\t\t\t}\n\t\t}\n"); } else {
/* * P L O T _ O P E N * * Fire up the display manager, and the display processor. * */ struct dm * plot_open(Tcl_Interp *interp, int argc, const char *argv[]) { static int count = 0; struct dm *dmp; Tcl_Obj *obj; BU_ALLOC(dmp, struct dm); *dmp = dm_plot; /* struct copy */ dmp->dm_interp = interp; BU_ALLOC(dmp->dm_vars.priv_vars, struct plot_vars); obj = Tcl_GetObjResult(interp); if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); bu_vls_init(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls); bu_vls_init(&dmp->dm_pathName); bu_vls_init(&dmp->dm_tkName); bu_vls_printf(&dmp->dm_pathName, ".dm_plot%d", count++); bu_vls_printf(&dmp->dm_tkName, "dm_plot%d", count++); /* skip first argument */ --argc; ++argv; /* Process any options */ ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D = 1; /* 3-D w/color, by default */ while (argv[0] != (char *)0 && argv[0][0] == '-') { switch (argv[0][1]) { case '3': break; case '2': ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D = 0; /* 2-D, for portability */ break; case 'g': ((struct plot_vars *)dmp->dm_vars.priv_vars)->grid = 1; break; case 'f': ((struct plot_vars *)dmp->dm_vars.priv_vars)->floating = 1; break; case 'z': case 'Z': /* Enable Z clipping */ Tcl_AppendStringsToObj(obj, "Clipped in Z to viewing cube\n", (char *)NULL); dmp->dm_zclip = 1; break; default: Tcl_AppendStringsToObj(obj, "bad PLOT option ", argv[0], "\n", (char *)NULL); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } argv++; } if (argv[0] == (char *)0) { Tcl_AppendStringsToObj(obj, "no filename or filter specified\n", (char *)NULL); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } if (argv[0][0] == '|') { bu_vls_strcpy(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, &argv[0][1]); while ((++argv)[0] != (char *)0) { bu_vls_strcat(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, " "); bu_vls_strcat(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, argv[0]); } ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_pipe = 1; } else { bu_vls_strcpy(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, argv[0]); } if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_pipe) { if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp = popen(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "w")) == NULL) { perror(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls)); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } Tcl_AppendStringsToObj(obj, "piped to ", bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "\n", (char *)NULL); } else { if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp = fopen(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "wb")) == NULL) { perror(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls)); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } Tcl_AppendStringsToObj(obj, "plot stored in ", bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "\n", (char *)NULL); } setbuf(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, ((struct plot_vars *)dmp->dm_vars.priv_vars)->ttybuf); if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D) pl_3space(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, -2048, -2048, -2048, 2048, 2048, 2048); else pl_space(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, -2048, -2048, 2048, 2048); MAT_IDN(plotmat); Tcl_SetObjResult(interp, obj); return dmp; }
/** * make a copy of a v5 solid by adding it to our book-keeping list, * adding it to the db directory, and writing it out to disk. */ static void copy_v5_solid(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { size_t i; mat_t matrix; MAT_IDN(matrix); /* mirror */ if (state->miraxis != W) { matrix[state->miraxis*5] = -1.0; matrix[3 + state->miraxis*4] -= 2 * (matrix[3 + state->miraxis*4] - state->mirpos); } /* translate */ if (state->trans[W] > SMALL_FASTF) MAT_DELTAS_ADD_VEC(matrix, state->trans); /* rotation */ if (state->rot[W] > SMALL_FASTF) { mat_t m2, t; bn_mat_angles(m2, state->rot[X], state->rot[Y], state->rot[Z]); if (state->rpnt[W] > SMALL_FASTF) { mat_t m3; bn_mat_xform_about_pt(m3, m2, state->rpnt); bn_mat_mul(t, matrix, m3); } else bn_mat_mul(t, matrix, m2); MAT_COPY(matrix, t); } /* make n copies */ for (i = 0; i < state->n_copies; i++) { char *argv[6] = {"wdb_copy", (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL}; struct bu_vls *name; int ret; struct directory *dp = (struct directory *)NULL; struct rt_db_internal intern; if (i==0) dp = proto; else dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); /* get new name */ bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); /* actually copy the primitive to the new name */ argv[1] = proto->d_namep; argv[2] = bu_vls_addr(name); ret = wdb_copy_cmd(_dbip->dbi_wdbp, 3, (const char **)argv); if (ret != TCL_OK) bu_log("WARNING: failure cloning \"%s\" to \"%s\"\n", proto->d_namep, bu_vls_addr(name)); /* get the original objects matrix */ if (rt_db_get_internal(&intern, dp, _dbip, matrix, &rt_uniresource) < 0) { bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); bu_vls_free(name); return; } RT_CK_DB_INTERNAL(&intern); /* pull the new name */ dp = db_lookup(_dbip, bu_vls_addr(name), LOOKUP_QUIET); bu_vls_free(name); if (!dp) { bu_vls_free(name); continue; } /* write the new matrix to the new object */ if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); rt_db_free_internal(&intern); } /* end iteration over each copy */ return; }
/* * 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); }
/** * make n copies of a v4 combination. */ static struct directory * copy_v4_comb(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; union record *rp = (union record *)NULL; size_t i; size_t j; /* make n copies */ for (i = 0; i < state->n_copies; i++) { /* get a v4 in-memory reference to the object being copied */ if ((rp = db_getmrec(_dbip, proto)) == (union record *)0) { TCL_READ_ERR; return NULL; } if (proto->d_flags & RT_DIR_REGION) { if (!is_in_list(obj_list, rp[1].M.m_instname)) { bu_log("ERROR: clone internal error looking up %s\n", rp[1].M.m_instname); return NULL; } bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(&obj_list.names[index_in_list(obj_list, rp[1].M.m_instname)].dest[i])); /* bleh, odd convention going on here.. prefix regions with an 'r' */ *bu_vls_addr(&obj_list.names[idx].dest[i]) = 'r'; } else { struct bu_vls *name; if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); bu_vls_free(name); } bu_strlcpy(rp[0].c.c_name, bu_vls_addr(&obj_list.names[idx].dest[i]), NAMESIZE); /* add the object to the directory */ dp = db_diradd(_dbip, rp->c.c_name, RT_DIR_PHONY_ADDR, proto->d_len, proto->d_flags, &proto->d_minor_type); if ((dp == NULL) || (db_alloc(_dbip, dp, proto->d_len) < 0)) { TCL_ALLOC_ERR; return NULL; } for (j = 1; j < proto->d_len; j++) { if (!is_in_list(obj_list, rp[j].M.m_instname)) { bu_log("ERROR: clone internal error looking up %s\n", rp[j].M.m_instname); return NULL; } snprintf(rp[j].M.m_instname, NAMESIZE, "%s", bu_vls_addr(&obj_list.names[index_in_list(obj_list, rp[j].M.m_instname)].dest[i])); } /* write the object to disk */ if (db_put(_dbip, dp, rp, 0, dp->d_len) < 0) { bu_log("ERROR: clone internal error writing to the database\n"); return NULL; } /* our responsibility to free the record */ bu_free((char *)rp, "deallocate copy_v4_comb() db_getmrec() record"); } return dp; }
int diff_objs(Tcl_Interp *interp, const char *db1, const char *db2) { struct directory *dp1, *dp2; char *argv[4] = {NULL, NULL, NULL, NULL}; struct bu_vls s1_tcl = BU_VLS_INIT_ZERO; struct bu_vls s2_tcl = BU_VLS_INIT_ZERO; struct bu_vls vls = BU_VLS_INIT_ZERO; int has_diff = 0; /* look at all objects in this database */ FOR_ALL_DIRECTORY_START(dp1, dbip1) { char *str1, *str2; Tcl_Obj *obj1, *obj2; /* check if this object exists in the other database */ if ((dp2 = db_lookup(dbip2, dp1->d_namep, 0)) == RT_DIR_NULL) { kill_obj(dp1->d_namep); continue; } /* skip the _GLOBAL object */ if (dp1->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) continue; /* try to get the TCL version of this object */ bu_vls_trunc(&vls, 0); bu_vls_printf(&vls, "%s get %s", db1, dp1->d_namep); if (Tcl_Eval(interp, bu_vls_addr(&vls)) != TCL_OK) { /* cannot get TCL version, use bu_external */ Tcl_ResetResult(interp); has_diff += compare_external(dp1, dp2); continue; } obj1 = Tcl_NewListObj(0, NULL); Tcl_AppendObjToObj(obj1, Tcl_GetObjResult(interp)); bu_vls_trunc(&s1_tcl, 0); bu_vls_trunc(&s2_tcl, 0); bu_vls_strcpy(&s1_tcl, Tcl_GetStringResult(interp)); str1 = bu_vls_addr(&s1_tcl); Tcl_ResetResult(interp); /* try to get TCL version of object from the other database */ bu_vls_trunc(&vls, 0); bu_vls_printf(&vls, "%s get %s", db2, dp1->d_namep); if (Tcl_Eval(interp, bu_vls_addr(&vls)) != TCL_OK) { Tcl_ResetResult(interp); /* cannot get it, they MUST be different */ if (mode == HUMAN) printf("Replace %s with the same object from %s\n", dp1->d_namep, dbip2->dbi_filename); else printf("kill %s\n# IMPORT %s from %s\n", dp1->d_namep, dp2->d_namep, dbip2->dbi_filename); continue; } obj2 = Tcl_NewListObj(0, NULL); Tcl_AppendObjToObj(obj2, Tcl_GetObjResult(interp)); bu_vls_strcpy(&s2_tcl, Tcl_GetStringResult(interp)); str2 = bu_vls_addr(&s2_tcl); Tcl_ResetResult(interp); /* got TCL versions of both */ if ((dp1->d_flags & RT_DIR_SOLID) && (dp2->d_flags & RT_DIR_SOLID)) { /* both are solids */ has_diff += compare_tcl_solids(str1, obj1, dp1, str2, obj2); if (pre_5_vers != 2) { has_diff += compare_attrs(dp1, dp2); } continue; } if ((dp1->d_flags & RT_DIR_COMB) && (dp2->d_flags & RT_DIR_COMB)) { /* both are combinations */ has_diff += compare_tcl_combs(obj1, dp1, obj2); if (pre_5_vers != 2) { has_diff += compare_attrs(dp1, dp2); } continue; } /* the two objects are different types */ if (!BU_STR_EQUAL(str1, str2)) { has_diff += 1; if (mode == HUMAN) printf("%s:\n\twas: %s\n\tis now: %s\n\n", dp1->d_namep, str1, str2); else printf("kill %s\ndb put %s %s\n", dp1->d_namep, dp2->d_namep, str2); } } FOR_ALL_DIRECTORY_END;
/** * make n copies of a v5 combination. */ static struct directory * copy_v5_comb(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; struct bu_vls *name; size_t i; /* sanity */ if (!proto) { bu_log("ERROR: clone internal consistency error\n"); return (struct directory *)NULL; } /* make n copies */ for (i = 0; i < state->n_copies; i++) { if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); /* we have a before and an after, do the copy */ if (proto->d_namep && bu_vls_addr(name)) { struct rt_db_internal dbintern; struct rt_comb_internal *comb; dp = db_lookup(_dbip, proto->d_namep, LOOKUP_QUIET); if (!dp) { bu_vls_free(name); continue; } if (rt_db_get_internal(&dbintern, dp, _dbip, bn_mat_identity, &rt_uniresource) < 0) { bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); return NULL; } if ((dp=db_diradd(wdbp->dbip, bu_vls_addr(name), -1, 0, proto->d_flags, (genptr_t)&proto->d_minor_type)) == RT_DIR_NULL) { bu_log("An error has occurred while adding a new object to the database."); return NULL; } RT_CK_DB_INTERNAL(&dbintern); comb = (struct rt_comb_internal *)dbintern.idb_ptr; RT_CK_COMB(comb); RT_CK_TREE(comb->tree); /* recursively update the tree */ copy_v5_comb_tree(comb->tree, i); if (rt_db_put_internal(dp, wdbp->dbip, &dbintern, &rt_uniresource) < 0) { bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); bu_vls_free(name); return NULL; } bu_vls_free(name); rt_db_free_internal(&dbintern); } /* done with this name */ bu_vls_free(name); } return dp; }
/* * Open/create a framebuffer object. * * Usage: * fb_open [name device [args]] */ HIDDEN int fbo_open_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { struct fb_obj *fbop; FBIO *ifp; int width = 512; int height = 512; register int c; struct bu_vls vls; if (argc == 1) { /* get list of framebuffer objects */ for (BU_LIST_FOR(fbop, fb_obj, &HeadFBObj.l)) Tcl_AppendResult(interp, bu_vls_addr(&fbop->fbo_name), " ", (char *)NULL); return TCL_OK; } if (argc < 3) { bu_vls_init(&vls); bu_vls_printf(&vls, "helplib fb_open"); Tcl_Eval(interp, bu_vls_addr(&vls)); bu_vls_free(&vls); return TCL_ERROR; } /* process args */ bu_optind = 3; bu_opterr = 0; while ((c = bu_getopt(argc, argv, "w:W:s:S:n:N:")) != EOF) { switch (c) { case 'W': case 'w': width = atoi(bu_optarg); break; case 'N': case 'n': height = atoi(bu_optarg); break; case 'S': case 's': width = atoi(bu_optarg); height = width; break; case '?': default: Tcl_AppendResult(interp, "fb_open: bad option - ", bu_optarg, (char *)NULL); return TCL_ERROR; } } if ((ifp = fb_open(argv[2], width, height)) == FBIO_NULL) { Tcl_AppendResult(interp, "fb_open: bad device - ", argv[2], (char *)NULL); } if (fb_ioinit(ifp) != 0) { Tcl_AppendResult(interp, "fb_open: fb_ioinit() failed.", (char *) NULL); return TCL_ERROR; } BU_GETSTRUCT(fbop, fb_obj); bu_vls_init(&fbop->fbo_name); bu_vls_strcpy(&fbop->fbo_name, argv[1]); fbop->fbo_fbs.fbs_fbp = ifp; fbop->fbo_fbs.fbs_listener.fbsl_fbsp = &fbop->fbo_fbs; fbop->fbo_fbs.fbs_listener.fbsl_fd = -1; fbop->fbo_fbs.fbs_listener.fbsl_port = -1; /* append to list of fb_obj's */ BU_LIST_APPEND(&HeadFBObj.l, &fbop->l); (void)Tcl_CreateCommand(interp, bu_vls_addr(&fbop->fbo_name), (Tcl_CmdProc *)fbo_cmd, (ClientData)fbop, fbo_deleteProc); /* Return new function name as result */ Tcl_ResetResult(interp); Tcl_AppendResult(interp, bu_vls_addr(&fbop->fbo_name), (char *)NULL); return TCL_OK; }
/** * master hook function for the 'tracker' command used to create * copies of objects along a spline path. */ int f_tracker(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, const char *argv[]) { size_t ret; struct spline s; vect_t *verts = (vect_t *)NULL; struct link *links = (struct link *)NULL; int opt; size_t i, j, k, inc; size_t n_verts, n_links; int arg = 1; FILE *points = (FILE *)NULL; char tok[81] = {0}, line[81] = {0}; char ch; fastf_t totlen = 0.0; fastf_t len, olen; fastf_t dist_to_next; fastf_t min, max, mid; fastf_t pt[3] = {0}; int no_draw = 0; /* allow interrupts */ if (setjmp(jmp_env) == 0) (void)signal(SIGINT, sig3); else return TCL_OK; bu_optind = 1; while ((opt = bu_getopt(argc, (char * const *)argv, "fh")) != EOF) { switch (opt) { case 'f': no_draw = 1; arg++; break; case 'h': Tcl_AppendResult(interp, "tracker [-fh] [# links] [increment] [spline.iges] [link...]\n\n", (char *)NULL); Tcl_AppendResult(interp, "-f:\tDo not draw the links as they are made.\n", (char *)NULL); Tcl_AppendResult(interp, "-h:\tPrint this message.\n\n", (char *)NULL); Tcl_AppendResult(interp, "\tThe prototype link(s) should be placed so that one\n", (char *)NULL); Tcl_AppendResult(interp, "\tpin's vertex lies on the origin and points along the\n", (char *)NULL); Tcl_AppendResult(interp, "\ty-axis, and the link should lie along the positive x-axis.\n\n", (char *)NULL); Tcl_AppendResult(interp, "\tIf two or more sublinks comprise the link, they are specified in this manner:\n", (char *)NULL); Tcl_AppendResult(interp, "\t<link1> <%% of total link> <link2> <%% of total link> ....\n", (char *)NULL); return TCL_OK; } } if (argc < arg+1) { Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter number of links: ", (char *)NULL); return TCL_ERROR; } n_verts = atoi(argv[arg++])+1; if (argc < arg+1) { Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter amount to increment parts by: ", (char *)NULL); return TCL_ERROR; } inc = atoi(argv[arg++]); if (argc < arg+1) { Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter spline file name: ", (char *)NULL); return TCL_ERROR; } if ((points = fopen(argv[arg++], "r")) == NULL) { fprintf(stdout, "tracker: couldn't open points file %s.\n", argv[arg-1]); return TCL_ERROR; } if (argc < arg+1) { Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter prototype link name: ", (char *)NULL); fclose(points); return TCL_ERROR; } /* Prepare vert list *****************************/ n_links = ((argc-3)/2)>1?((argc-3)/2):1; verts = (vect_t *)malloc(sizeof(vect_t) * n_verts * (n_links+2)); /* Read in links names and link lengths **********/ links = (struct link *)malloc(sizeof(struct link)*n_links); for (i = arg; i < (size_t)argc; i+=2) { double scan; bu_vls_strcpy(&links[(i-arg)/2].name, argv[i]); if (argc > arg+1) { sscanf(argv[i+1], "%lf", &scan); /* double to fastf_t */ links[(i-arg)/2].pct = scan; } else { links[(i-arg)/2].pct = 1.0; } totlen += links[(i-arg)/2].pct; } if (!ZERO(totlen - 1.0)) fprintf(stdout, "ERROR\n"); /* Read in knots from specified file *************/ do bu_fgets(line, 81, points); while (!BU_STR_EQUAL(strtok(line, ","), "112")); bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok)); bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok)); bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok)); bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok)); s.n_segs = atoi(tok); s.t = (fastf_t *)bu_malloc(sizeof(fastf_t) * (s.n_segs+1), "t"); s.k = (struct knot *)bu_malloc(sizeof(struct knot) * (s.n_segs+1), "k"); for (i = 0; i <= s.n_segs; i++) { bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok)); if (strstr(tok, "P") != NULL) { bu_fgets(line, 81, points); bu_fgets(line, 81, points); bu_strlcpy(tok, strtok(line, ","), sizeof(tok)); } s.t[i] = atof(tok); } for (i = 0; i <= s.n_segs; i++) for (j = 0; j < 3; j++) { for (k = 0; k < 4; k++) { bu_strlcpy(tok, strtok(NULL, ","), sizeof(tok)); if (strstr(tok, "P") != NULL) { bu_fgets(line, 81, points); bu_fgets(line, 81, points); bu_strlcpy(tok, strtok(line, ","), sizeof(tok)); } s.k[i].c[j][k] = atof(tok); } s.k[i].pt[j] = s.k[i].c[j][0]; } fclose(points); /* Interpolate link vertices *********************/ for (i = 0; i < s.n_segs; i++) /* determine initial track length */ totlen += DIST_PT_PT(s.k[i].pt, s.k[i+1].pt); len = totlen/(n_verts-1); VMOVE(verts[0], s.k[0].pt); olen = 2*len; for (i = 0; (fabs(olen-len) >= VUNITIZE_TOL) && (i < 250); i++) { /* number of track iterations */ fprintf(stdout, "."); fflush(stdout); for (j = 0; j < n_links; j++) /* set length of each link based on current track length */ links[j].len = len * links[j].pct; min = 0; max = s.t[s.n_segs]; mid = 0; for (j = 0; j < n_verts+1; j++) /* around the track once */ for (k = 0; k < n_links; k++) { /* for each sub-link */ if ((k == 0) && (j == 0)) {continue;} /* the first sub-link of the first link is already in position */ min = mid; max = s.t[s.n_segs]; mid = (min+max)/2; interp_spl(mid, s, pt); dist_to_next = (k > 0) ? links[k-1].len : links[n_links-1].len; /* links[k].len;*/ while (fabs(DIST_PT_PT(verts[n_links*j+k-1], pt) - dist_to_next) >= VUNITIZE_TOL) { if (DIST_PT_PT(verts[n_links*j+k-1], pt) > dist_to_next) { max = mid; mid = (min+max)/2; } else { min = mid; mid = (min+max)/2; } interp_spl(mid, s, pt); if (fabs(min-max) <= VUNITIZE_TOL) {break;} } interp_spl(mid, s, verts[n_links*j+k]); } interp_spl(s.t[s.n_segs], s, verts[n_verts*n_links-1]); totlen = 0.0; for (j = 0; j < n_verts*n_links-1; j++) totlen += DIST_PT_PT(verts[j], verts[j+1]); olen = len; len = totlen/(n_verts-1); } fprintf(stdout, "\n"); /* Write out interpolation info ******************/ fprintf(stdout, "%ld Iterations; Final link lengths:\n", (unsigned long)i); for (i = 0; i < n_links; i++) fprintf(stdout, " %s\t%.15f\n", bu_vls_addr(&links[i].name), links[i].len); fflush(stdin); /* Place links on vertices ***********************/ fprintf(stdout, "Continue? [y/n] "); ret = fscanf(stdin, "%c", &ch); if (ret != 1) perror("fscanf"); if (ch == 'y') { struct clone_state state; struct directory **dps = (struct directory **)NULL; char *vargs[3]; for (i = 0; i < 2; i++) vargs[i] = (char *)bu_calloc(CLONE_BUFSIZE, sizeof(char), "alloc vargs[i]"); vargs[0][0] = 'e'; state.interp = interp; state.incr = inc; state.n_copies = 1; state.draw_obj = 0; state.miraxis = W; dps = (struct directory **)bu_calloc(n_links, sizeof(struct directory *), "alloc dps array"); /* rots = (vect_t *)bu_malloc(sizeof(vect_t)*n_links, "alloc rots");*/ for (i = 0; i < n_links; i++) { /* global dbip */ dps[i] = db_lookup(dbip, bu_vls_addr(&links[i].name), LOOKUP_QUIET); /* VSET(rots[i], 0, 0, 0);*/ } for (i = 0; i < n_verts-1; i++) { for (j = 0; j < n_links; j++) { if (i == 0) { VSCALE(state.trans, verts[n_links*i+j], local2base); } else VSUB2SCALE(state.trans, verts[n_links*(i-1)+j], verts[n_links*i+j], local2base); VSCALE(state.rpnt, verts[n_links*i+j], local2base); VSUB2(pt, verts[n_links*i+j], verts[n_links*i+j+1]); VSET(state.rot, 0, (M_PI - atan2(pt[Z], pt[X])), -atan2(pt[Y], sqrt(pt[X]*pt[X]+pt[Z]*pt[Z]))); VSCALE(state.rot, state.rot, RAD2DEG); /* VSUB2(state.rot, state.rot, rots[j]); VADD2(rots[j], state.rot, rots[j]); */ state.src = dps[j]; /* global dbip */ dps[j] = copy_object(dbip, &rt_uniresource, &state); bu_strlcpy(vargs[1], dps[j]->d_namep, CLONE_BUFSIZE); if (!no_draw || !is_dm_null()) { drawtrees(2, (const char **)vargs, 1); size_reset(); new_mats(); color_soltab(); refresh(); } fprintf(stdout, "."); fflush(stdout); } } fprintf(stdout, "\n"); bu_free(dps, "free dps array"); for (i = 0; i < 2; i++) bu_free(vargs[i], "free vargs[i]"); } free(s.t); free(s.k); free(links); free(verts); (void)signal(SIGINT, SIG_IGN); return TCL_OK; }
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 ); }
void nmg_2_vrml(FILE *fp, const struct db_full_path *pathp, struct model *m, struct mater_info *mater) { struct nmgregion *reg; struct bu_ptbl verts; struct vrml_mat mat; struct bu_vls vls = BU_VLS_INIT_ZERO; char *tok; int i; int first=1; int is_light=0; float r, g, b; point_t ave_pt; char *full_path; /*There may be a better way to capture the region_id, than getting the rt_comb_internal structure, * (and may be a better way to capture the rt_comb_internal struct), but for now I just copied the * method used in select_lights/select_non_lights above, could have used a global variable but I noticed * none other were used, so I didn't want to be the first */ struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; NMG_CK_MODEL( m ); BARRIER_CHECK; full_path = db_path_to_string( pathp ); /* replace all occurrences of '.' with '_' */ char_replace(full_path, '.', '_'); RT_CK_FULL_PATH( pathp ); dp = DB_FULL_PATH_CUR_DIR( pathp ); if ( !(dp->d_flags & RT_DIR_COMB) ) return; id = rt_db_get_internal( &intern, dp, dbip, (matp_t)NULL, &rt_uniresource ); if ( id < 0 ) { bu_log( "Cannot internal form of %s\n", dp->d_namep ); return; } if ( id != ID_COMBINATION ) { bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n", dp->d_namep ); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB( comb ); if ( mater->ma_color_valid ) { r = mater->ma_color[0]; g = mater->ma_color[1]; b = mater->ma_color[2]; } else { r = g = b = 0.5; } if ( mater->ma_shader ) { tok = strtok( mater->ma_shader, tok_sep ); bu_strlcpy( mat.shader, tok, TXT_NAME_SIZE ); } else mat.shader[0] = '\0'; mat.shininess = -1; mat.transparency = -1.0; mat.lt_fraction = -1.0; VSETALL( mat.lt_dir, 0.0 ); mat.lt_angle = -1.0; mat.tx_file[0] = '\0'; mat.tx_w = -1; mat.tx_n = -1; bu_vls_strcpy( &vls, &mater->ma_shader[strlen(mat.shader)] ); (void)bu_struct_parse( &vls, vrml_mat_parse, (char *)&mat, NULL); if ( bu_strncmp( "light", mat.shader, 5 ) == 0 ) { /* this is a light source */ is_light = 1; } else { fprintf( fp, "\t<Shape DEF=\"%s\">\n", full_path); fprintf( fp, "\t\t<Appearance>\n"); if ( bu_strncmp( "plastic", mat.shader, 7 ) == 0 ) { if ( mat.shininess < 0 ) mat.shininess = 10; V_MAX(mat.transparency, 0.0); fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0); } else if ( bu_strncmp( "glass", mat.shader, 5 ) == 0 ) { if ( mat.shininess < 0 ) mat.shininess = 4; if ( mat.transparency < 0.0 ) mat.transparency = 0.8; fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0); } else if ( mater->ma_color_valid ) { fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\"/>\n", r, g, b); } else { /* If no color was defined set the colors according to the thousands groups */ int thou = comb->region_id/1000; thou == 0 ? fprintf( fp, "\t\t\t<Material USE=\"Material_999\"/>\n") : thou == 1 ? fprintf( fp, "\t\t\t<Material USE=\"Material_1999\"/>\n") : thou == 2 ? fprintf( fp, "\t\t\t<Material USE=\"Material_2999\"/>\n") : thou == 3 ? fprintf( fp, "\t\t\t<Material USE=\"Material_3999\"/>\n") : thou == 4 ? fprintf( fp, "\t\t\t<Material USE=\"Material_4999\"/>\n") : thou == 5 ? fprintf( fp, "\t\t\t<Material USE=\"Material_5999\"/>\n") : thou == 6 ? fprintf( fp, "\t\t\t<Material USE=\"Material_6999\"/>\n") : thou == 7 ? fprintf( fp, "\t\t\t<Material USE=\"Material_7999\"/>\n") : thou == 8 ? fprintf( fp, "\t\t\t<Material USE=\"Material_8999\"/>\n") : fprintf( fp, "\t\t\t<Material USE=\"Material_9999\"/>\n"); } } if ( !is_light ) { process_non_light(m); fprintf( fp, "\t\t</Appearance>\n"); } /* FIXME: need code to handle light */ /* get list of vertices */ nmg_vertex_tabulate( &verts, &m->magic ); fprintf( fp, "\t\t<IndexedFaceSet coordIndex=\"\n"); first = 1; if ( !is_light ) { for ( BU_LIST_FOR( reg, nmgregion, &m->r_hd ) ) { struct shell *s; NMG_CK_REGION( reg ); for ( BU_LIST_FOR( s, shell, ®->s_hd ) ) { struct faceuse *fu; NMG_CK_SHELL( s ); for ( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) { struct loopuse *lu; NMG_CK_FACEUSE( fu ); if ( fu->orientation != OT_SAME ) continue; for ( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) { struct edgeuse *eu; NMG_CK_LOOPUSE( lu ); if ( BU_LIST_FIRST_MAGIC( &lu->down_hd ) != NMG_EDGEUSE_MAGIC ) continue; if ( !first ) fprintf( fp, ",\n" ); else first = 0; fprintf( fp, "\t\t\t\t" ); for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) { struct vertex *v; NMG_CK_EDGEUSE( eu ); v = eu->vu_p->v_p; NMG_CK_VERTEX( v ); fprintf( fp, " %d,", bu_ptbl_locate( &verts, (long *)v ) ); } fprintf( fp, "-1" ); } } } } /* close coordIndex */ fprintf( fp, "\" "); fprintf( fp, "normalPerVertex=\"false\" "); fprintf( fp, "convex=\"false\" "); fprintf( fp, "creaseAngle=\"0.5\" "); /* close IndexedFaceSet open tag */ fprintf( fp, ">\n"); } fprintf( fp, "\t\t\t<Coordinate point=\""); for ( i=0; i<BU_PTBL_END( &verts ); i++ ) { struct vertex *v; struct vertex_g *vg; point_t pt_meters; v = (struct vertex *)BU_PTBL_GET( &verts, i ); NMG_CK_VERTEX( v ); vg = v->vg_p; NMG_CK_VERTEX_G( vg ); /* convert to desired units */ VSCALE( pt_meters, vg->coord, scale_factor ); if ( is_light ) VADD2( ave_pt, ave_pt, pt_meters ); if ( first ) { if ( !is_light ) fprintf( fp, " %10.10e %10.10e %10.10e, ", V3ARGS(pt_meters)); first = 0; } else if ( !is_light ) fprintf( fp, "%10.10e %10.10e %10.10e, ", V3ARGS( pt_meters )); } /* close point */ fprintf(fp, "\""); /* close Coordinate */ fprintf(fp, "/>\n"); /* IndexedFaceSet end tag */ fprintf( fp, "\t\t</IndexedFaceSet>\n"); /* Shape end tag */ fprintf( fp, "\t</Shape>\n"); BARRIER_CHECK; }