static void nmg_conv(struct rt_db_internal *intern, const char *name) { struct model *m; struct nmgregion *r; struct shell *s; RT_CK_DB_INTERNAL(intern); m = (struct model *)intern->idb_ptr; NMG_CK_MODEL(m); r = BU_LIST_FIRST(nmgregion, &m->r_hd); if (r && BU_LIST_NEXT(nmgregion, &r->l) != (struct nmgregion *)&m->r_hd) bu_exit(1, "ERROR: this code works only for NMG models with one region!\n"); s = BU_LIST_FIRST(shell, &r->s_hd); if (s && BU_LIST_NEXT(shell, &s->l) != (struct shell *)&r->s_hd) bu_exit(1, "ERROR: this code works only for NMG models with one shell!\n"); if (!s) { bu_log("WARNING: NMG has no shells\n"); return; } if (!BU_SETJUMP) { /* try */ mk_bot_from_nmg(fdout, name, s); } else { /* catch */ BU_UNSETJUMP; bu_log("Failed to convert %s\n", name); return; } BU_UNSETJUMP; if (verbose) bu_log("Converted %s to a Bot solid\n", name); }
HIDDEN void cho_deleteProc(ClientData clientData) { struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData; struct bu_cmdhist *curr, *next; /* free list of commands */ curr = BU_LIST_NEXT(bu_cmdhist, &chop->cho_head.l); while (BU_LIST_NOT_HEAD(curr, &chop->cho_head.l)) { curr = BU_LIST_NEXT(bu_cmdhist, &chop->cho_head.l); next = BU_LIST_PNEXT(bu_cmdhist, curr); bu_vls_free(&curr->h_command); BU_LIST_DEQUEUE(&curr->l); bu_free((genptr_t)curr, "cho_deleteProc: curr"); curr = next; } bu_vls_free(&chop->cho_name); bu_vls_free(&chop->cho_head.h_command); BU_LIST_DEQUEUE(&chop->l); BU_PUT(chop, struct bu_cmdhist_obj); }
HIDDEN int wdb_do_paren(struct bu_list *hp) { struct tokens *tok; for (BU_LIST_FOR(tok, tokens, hp)) { struct tokens *prev, *next; if (tok->type != WDB_TOK_TREE) continue; prev = BU_LIST_PREV(tokens, &tok->l); next = BU_LIST_NEXT(tokens, &tok->l); if (prev->type !=WDB_TOK_LPAREN || next->type != WDB_TOK_RPAREN) continue; /* this is an eligible operand surrounded by parens */ BU_LIST_DEQUEUE(&next->l); bu_free((char *)next, "next"); BU_LIST_DEQUEUE(&prev->l); bu_free((char *)prev, "prev"); } if (hp->forw == hp->back && hp->forw != hp) return 1; /* done */ else if (BU_LIST_IS_EMPTY(hp)) return -1; /* empty tree!!!! */ else return 0; /* more to do */ }
HIDDEN void wdb_do_inter(struct bu_list *hp) { struct tokens *tok; for (BU_LIST_FOR(tok, tokens, hp)) { struct tokens *prev, *next; union tree *tp; if (tok->type != WDB_TOK_INTER) continue; prev = BU_LIST_PREV(tokens, &tok->l); next = BU_LIST_NEXT(tokens, &tok->l); if (prev->type !=WDB_TOK_TREE || next->type != WDB_TOK_TREE) continue; /* this is an eligible intersection operation */ BU_ALLOC(tp, union tree); RT_TREE_INIT(tp); tp->tr_b.tb_op = OP_INTERSECT; tp->tr_b.tb_regionp = (struct region *)NULL; tp->tr_b.tb_left = prev->tp; tp->tr_b.tb_right = next->tp; BU_LIST_DEQUEUE(&tok->l); bu_free((char *)tok, "tok"); BU_LIST_DEQUEUE(&prev->l); bu_free((char *)prev, "prev"); next->tp = tp; tok = next; } }
/* * Illuminate/highlight database object * * Usage: * illum [-n] obj * */ int ged_illum(struct ged *gedp, int argc, const char *argv[]) { struct display_list *gdlp; struct display_list *next_gdlp; int found = 0; int illum = 1; static const char *usage = "[-n] obj"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_DRAWABLE(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc == 3) { if (argv[1][0] == '-' && argv[1][1] == 'n') illum = 0; else goto bad; --argc; ++argv; } if (argc != 2) goto bad; gdlp = BU_LIST_NEXT(display_list, gedp->ged_gdp->gd_headDisplay); while (BU_LIST_NOT_HEAD(gdlp, gedp->ged_gdp->gd_headDisplay)) { next_gdlp = BU_LIST_PNEXT(display_list, gdlp); found += dl_set_illum(gdlp, argv[1], illum); gdlp = next_gdlp; } if (!found) { bu_vls_printf(gedp->ged_result_str, "illum: %s not found", argv[1]); return GED_ERROR; } return GED_OK; bad: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; }
void bu_free_mapped_files(int verbose) { struct bu_mapped_file *mp, *next; if (UNLIKELY(bu_debug&BU_DEBUG_MAPPED_FILE)) bu_log("bu_free_mapped_files(verbose=%d)\n", verbose); bu_semaphore_acquire(BU_SEM_MAPPEDFILE); next = BU_LIST_FIRST(bu_mapped_file, &bu_mapped_file_list); while (BU_LIST_NOT_HEAD(next, &bu_mapped_file_list)) { BU_CK_MAPPED_FILE(next); mp = next; next = BU_LIST_NEXT(bu_mapped_file, &mp->l); if (mp->uses > 0) continue; /* Found one that needs to have storage released */ if (UNLIKELY(verbose || (bu_debug&BU_DEBUG_MAPPED_FILE))) bu_pr_mapped_file("freeing", mp); BU_LIST_DEQUEUE(&mp->l); /* If application pointed mp->apbuf at mp->buf, break that * association so we don't double-free the buffer. */ if (mp->apbuf == mp->buf) mp->apbuf = (void *)NULL; #ifdef HAVE_SYS_MMAN_H if (mp->is_mapped) { int ret; bu_semaphore_acquire(BU_SEM_SYSCALL); ret = munmap(mp->buf, (size_t)mp->buflen); bu_semaphore_release(BU_SEM_SYSCALL); if (UNLIKELY(ret < 0)) perror("munmap"); /* XXX How to get this chunk of address space back to malloc()? */ } else #endif { bu_free(mp->buf, "bu_mapped_file.buf[]"); } mp->buf = (void *)NULL; /* sanity */ bu_free((void *)mp->name, "bu_mapped_file.name"); if (mp->appl) bu_free((void *)mp->appl, "bu_mapped_file.appl"); bu_free((void *)mp, "struct bu_mapped_file"); } bu_semaphore_release(BU_SEM_MAPPEDFILE); }
HIDDEN union tree * wdb_eval_bool(struct bu_list *hp) { int done=0; union tree *final_tree; struct tokens *tok; while (done != 1) { wdb_do_inter(hp); wdb_do_union_subtr(hp); done = wdb_do_paren(hp); } tok = BU_LIST_NEXT(tokens, hp); final_tree = tok->tp; BU_LIST_DEQUEUE(&tok->l); bu_free((char *)tok, "tok"); return final_tree; }
void merge(void) { struct frame *cur, *next; for (BU_LIST_FOR(cur, frame, &head)) { next = BU_LIST_NEXT(frame, &cur->l); if (BU_LIST_IS_HEAD(next, &head)) break; if (cur->number == next->number) { if (next->text) addtext(cur, next->text); cur->flags |= next->flags; BU_LIST_DEQUEUE(&next->l); if (next->text) bu_free(next->text, "text area"); next->text = NULL; next->l.magic = -1; bu_free(next, "struct frame"); cur = BU_LIST_PREV(frame, &cur->l); } } }
HIDDEN void wdb_do_union_subtr(struct bu_list *hp) { struct tokens *tok; for (BU_LIST_FOR(tok, tokens, hp)) { struct tokens *prev, *next; union tree *tp; if (tok->type != WDB_TOK_UNION && tok->type != WDB_TOK_SUBTR) continue; prev = BU_LIST_PREV( tokens, &tok->l ); next = BU_LIST_NEXT( tokens, &tok->l ); if (prev->type !=WDB_TOK_TREE || next->type != WDB_TOK_TREE) continue; /* this is an eligible operation */ tp = (union tree *)bu_malloc( sizeof( union tree ), "tp" ); tp->magic = RT_TREE_MAGIC; if (tok->type == WDB_TOK_UNION) tp->tr_b.tb_op = OP_UNION; else tp->tr_b.tb_op = OP_SUBTRACT; tp->tr_b.tb_regionp = (struct region *)NULL; tp->tr_b.tb_left = prev->tp; tp->tr_b.tb_right = next->tp; BU_LIST_DEQUEUE(&tok->l); bu_free((char *)tok, "tok"); BU_LIST_DEQUEUE(&prev->l); bu_free((char *)prev, "prev"); next->tp = tp; tok = next; } }
HIDDEN void do_union_subtr(struct bu_list *hp) { struct tokens *tok; for (BU_LIST_FOR(tok, tokens, hp)) { struct tokens *prev, *next; union tree *tp; if (tok->type != TOK_UNION && tok->type != TOK_SUBTR) continue; prev = BU_LIST_PREV(tokens, &tok->l); next = BU_LIST_NEXT(tokens, &tok->l); if (prev->type !=TOK_TREE || next->type != TOK_TREE) continue; /* this is an eligible operation */ BU_ALLOC(tp, union tree); RT_TREE_INIT(tp); if (tok->type == TOK_UNION) tp->tr_b.tb_op = OP_UNION; else tp->tr_b.tb_op = OP_SUBTRACT; tp->tr_b.tb_regionp = (struct region *)NULL; tp->tr_b.tb_left = prev->tp; tp->tr_b.tb_right = next->tp; BU_LIST_DEQUEUE(&tok->l); bu_free((char *)tok, "tok"); BU_LIST_DEQUEUE(&prev->l); bu_free((char *)prev, "prev"); next->tp = tp; tok = next; } }
int ged_saveview(struct ged *gedp, int argc, const char *argv[]) { struct ged_display_list *gdlp; struct ged_display_list *next_gdlp; int i; FILE *fp; char *base; int c; char rtcmd[255] = {'r', 't', 0}; char outlog[255] = {0}; char outpix[255] = {0}; char inputg[255] = {0}; static const char *usage = "[-e] [-i] [-l] [-o] filename [args]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, "e:i:l:o:")) != -1) { switch (c) { case 'e': snprintf(rtcmd, 255, "%s", bu_optarg); break; case 'l': snprintf(outlog, 255, "%s", bu_optarg); break; case 'o': snprintf(outpix, 255, "%s", bu_optarg); break; case 'i': snprintf(inputg, 255, "%s", bu_optarg); break; default: { bu_vls_printf(gedp->ged_result_str, "Option '%c' unknown\n", c); bu_vls_printf(gedp->ged_result_str, "help saveview"); return GED_ERROR; } } } argc -= bu_optind-1; argv += bu_optind-1; if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((fp = fopen(argv[1], "a")) == NULL) { perror(argv[1]); return GED_ERROR; } (void)bu_fchmod(fileno(fp), 0755); /* executable */ if (!gedp->ged_wdbp->dbip->dbi_filename) { bu_log("Error: geometry file is not specified\n"); fclose(fp); return GED_ERROR; } if (!bu_file_exists(gedp->ged_wdbp->dbip->dbi_filename, NULL)) { bu_log("Error: %s does not exist\n", gedp->ged_wdbp->dbip->dbi_filename); fclose(fp); return GED_ERROR; } base = basename_without_suffix(argv[1], ".sh"); if (outpix[0] == '\0') { snprintf(outpix, 255, "%s.pix", base); } if (outlog[0] == '\0') { snprintf(outlog, 255, "%s.log", base); } /* Do not specify -v option to rt; batch jobs must print everything. -Mike */ fprintf(fp, "#!/bin/sh\n%s -M ", rtcmd); if (gedp->ged_gvp->gv_perspective > 0) fprintf(fp, "-p%g ", gedp->ged_gvp->gv_perspective); for (i = 2; i < argc; i++) fprintf(fp, "%s ", argv[i]); if (bu_strncmp(rtcmd, "nirt", 4) != 0) fprintf(fp, "\\\n -o %s\\\n $*\\\n", outpix); if (inputg[0] == '\0') { snprintf(inputg, 255, "%s", gedp->ged_wdbp->dbip->dbi_filename); } fprintf(fp, " '%s'\\\n ", inputg); gdlp = BU_LIST_NEXT(ged_display_list, gedp->ged_gdp->gd_headDisplay); while (BU_LIST_NOT_HEAD(gdlp, gedp->ged_gdp->gd_headDisplay)) { next_gdlp = BU_LIST_PNEXT(ged_display_list, gdlp); fprintf(fp, "'%s' ", bu_vls_addr(&gdlp->gdl_path)); gdlp = next_gdlp; } fprintf(fp, "\\\n 2>> %s\\\n", outlog); fprintf(fp, " <<EOF\n"); { vect_t eye_model; _ged_rt_set_eye_model(gedp, eye_model); _ged_rt_write(gedp, fp, eye_model); } fprintf(fp, "\nEOF\n"); (void)fclose(fp); return GED_OK; }
int ged_facetize(struct ged *gedp, int argc, const char *argv[]) { int i; int c; char *newname; struct rt_db_internal intern; struct directory *dp; int failed; int nmg_use_tnurbs = 0; struct db_tree_state init_state; struct db_i *dbip; union tree *facetize_tree; struct model *nmg_model; static const char *usage = "[ [-P] | [-n] [-t] [-T] ] new_obj old_obj [old_obj2 old_obj3 ...]"; /* static due to jumping */ static int triangulate; static int make_bot; static int marching_cube; static int screened_poisson; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } dbip = gedp->ged_wdbp->dbip; RT_CHECK_DBI(dbip); db_init_db_tree_state(&init_state, dbip, gedp->ged_wdbp->wdb_resp); /* Establish tolerances */ init_state.ts_ttol = &gedp->ged_wdbp->wdb_ttol; init_state.ts_tol = &gedp->ged_wdbp->wdb_tol; /* Initial values for options, must be reset each time */ marching_cube = 0; screened_poisson = 0; triangulate = 0; make_bot = 1; /* Parse options. */ bu_optind = 1; /* re-init bu_getopt() */ while ((c=bu_getopt(argc, (char * const *)argv, "mntTP")) != -1) { switch (c) { case 'm': marching_cube = triangulate = 1; /* no break, marching cubes assumes nmg for now */ case 'n': make_bot = 0; break; case 'P': screened_poisson = 1; triangulate = 1; make_bot = 1; break; case 'T': triangulate = 1; break; case 't': nmg_use_tnurbs = 1; break; default: { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } } argc -= bu_optind; argv += bu_optind; if (argc < 0) { bu_vls_printf(gedp->ged_result_str, "facetize: missing argument\n"); return GED_ERROR; } if (screened_poisson && (marching_cube || !make_bot || nmg_use_tnurbs)) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } newname = (char *)argv[0]; argv++; argc--; if (argc < 0) { bu_vls_printf(gedp->ged_result_str, "facetize: missing argument\n"); return GED_ERROR; } if (db_lookup(dbip, newname, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", newname); return GED_ERROR; } if (screened_poisson) { struct rt_bot_internal *bot; BU_ALLOC(bot, struct rt_bot_internal); bot->magic = RT_BOT_INTERNAL_MAGIC; bot->mode = RT_BOT_SOLID; bot->orientation = RT_BOT_UNORIENTED; bot->thickness = (fastf_t *)NULL; bot->face_mode = (struct bu_bitv *)NULL; /* TODO - generate point cloud, then mesh - need to see the input points for debugging */ (void)rt_generate_mesh(&(bot->faces), (int *)&(bot->num_faces), (point_t **)&(bot->vertices), (int *)&(bot->num_vertices), dbip, argv[0], 15); /* Export BOT as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_BOT; intern.idb_meth = &OBJ[ID_BOT]; intern.idb_ptr = (void *) bot; } else { bu_vls_printf(gedp->ged_result_str, "facetize: tessellating primitives with tolerances a=%g, r=%g, n=%g\n", gedp->ged_wdbp->wdb_ttol.abs, gedp->ged_wdbp->wdb_ttol.rel, gedp->ged_wdbp->wdb_ttol.norm); facetize_tree = (union tree *)0; nmg_model = nmg_mm(); init_state.ts_m = &nmg_model; i = db_walk_tree(dbip, argc, (const char **)argv, 1, &init_state, 0, /* take all regions */ facetize_region_end, nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : nmg_booltree_leaf_tess, (void *)&facetize_tree ); if (i < 0) { bu_vls_printf(gedp->ged_result_str, "facetize: error in db_walk_tree()\n"); /* Destroy NMG */ nmg_km(nmg_model); return GED_ERROR; } if (facetize_tree) { /* Now, evaluate the boolean tree into ONE region */ bu_vls_printf(gedp->ged_result_str, "facetize: evaluating boolean expressions\n"); if (!BU_SETJUMP) { /* try */ failed = nmg_boolean(facetize_tree, nmg_model, &gedp->ged_wdbp->wdb_tol, &rt_uniresource); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "WARNING: facetization failed!!!\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } BU_UNSETJUMP; } else failed = 1; if (failed) { bu_vls_printf(gedp->ged_result_str, "facetize: no resulting region, aborting\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } /* New region remains part of this nmg "model" */ NMG_CK_REGION(facetize_tree->tr_d.td_r); bu_vls_printf(gedp->ged_result_str, "facetize: %s\n", facetize_tree->tr_d.td_name); /* Triangulate model, if requested */ if (triangulate && !make_bot) { bu_vls_printf(gedp->ged_result_str, "facetize: triangulating resulting object\n"); if (!BU_SETJUMP) { /* try */ if (marching_cube == 1) nmg_triangulate_model_mc(nmg_model, &gedp->ged_wdbp->wdb_tol); else nmg_triangulate_model(nmg_model, &gedp->ged_wdbp->wdb_tol); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "WARNING: triangulation failed!!!\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } BU_UNSETJUMP; } if (make_bot) { struct rt_bot_internal *bot; struct nmgregion *r; struct shell *s; bu_vls_printf(gedp->ged_result_str, "facetize: converting to BOT format\n"); /* WTF, FIXME: this is only dumping the first shell of the first region */ r = BU_LIST_FIRST(nmgregion, &nmg_model->r_hd); if (r && BU_LIST_NEXT(nmgregion, &r->l) != (struct nmgregion *)&nmg_model->r_hd) bu_vls_printf(gedp->ged_result_str, "WARNING: model has more than one region, only facetizing the first\n"); s = BU_LIST_FIRST(shell, &r->s_hd); if (s && BU_LIST_NEXT(shell, &s->l) != (struct shell *)&r->s_hd) bu_vls_printf(gedp->ged_result_str, "WARNING: model has more than one shell, only facetizing the first\n"); if (!BU_SETJUMP) { /* try */ bot = (struct rt_bot_internal *)nmg_bot(s, &gedp->ged_wdbp->wdb_tol); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "WARNING: conversion to BOT failed!\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } BU_UNSETJUMP; nmg_km(nmg_model); nmg_model = (struct model *)NULL; /* Export BOT as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_BOT; intern.idb_meth = &OBJ[ID_BOT]; intern.idb_ptr = (void *) bot; } else { bu_vls_printf(gedp->ged_result_str, "facetize: converting NMG to database format\n"); /* Export NMG as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_NMG; intern.idb_meth = &OBJ[ID_NMG]; intern.idb_ptr = (void *)nmg_model; nmg_model = (struct model *)NULL; } } dp=db_diradd(dbip, newname, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Cannot add %s to directory\n", newname); return GED_ERROR; } if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Failed to write %s to database\n", newname); rt_db_free_internal(&intern); return GED_ERROR; } if (!screened_poisson) { facetize_tree->tr_d.td_r = (struct nmgregion *)NULL; /* Free boolean tree, and the regions in it */ db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; } return GED_OK; }