int BRLFile::AddModel(char const *name) { if(dbip==DBI_NULL) return 1; struct directory *dp=db_lookup(dbip, name, 1); if(dp == NULL) return 1; rt_init_resource( &rt_uniresource, 0, NULL ); db_functree(dbip, dp, CsgCombine, CsgLeaf, &rt_uniresource, this); while(construction.size()>0) { Add(construction.front()); construction.pop_front(); } return 0; }
/* * The only reason for this to be broken out is that * 2 separate locations in db_functree() call it. */ void db_functree_subtree(struct db_i *dbip, union tree *tp, void (*comb_func) (struct db_i *, struct directory *, void *), void (*leaf_func) (struct db_i *, struct directory *, void *), struct resource *resp, void *client_data) { struct directory *dp; if (!tp) return; RT_CHECK_DBI(dbip); RT_CK_TREE(tp); if (resp) { RT_CK_RESOURCE(resp); } switch (tp->tr_op) { case OP_DB_LEAF: if ((dp=db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL) return; db_functree(dbip, dp, comb_func, leaf_func, resp, client_data); break; case OP_UNION: case OP_INTERSECT: case OP_SUBTRACT: case OP_XOR: db_functree_subtree(dbip, tp->tr_b.tb_left, comb_func, leaf_func, resp, client_data); db_functree_subtree(dbip, tp->tr_b.tb_right, comb_func, leaf_func, resp, client_data); break; default: bu_log("db_functree_subtree: unrecognized operator %d\n", tp->tr_op); bu_bomb("db_functree_subtree: unrecognized operator\n"); } }
int ged_keep(struct ged *gedp, int argc, const char *argv[]) { int i; struct keep_node_data knd; struct rt_wdb *keepfp; struct directory *dp; struct bu_vls title = BU_VLS_INIT_ZERO; struct db_i *new_dbip; const char *cmd = argv[0]; static const char *usage = "[-R] file object(s)"; int c; int flag_R = 0; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); return GED_HELP; } /* check for options */ bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, "R")) != -1) { switch (c) { case 'R': /* not recursively */ flag_R = 1; break; default: bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c); return GED_ERROR; } } /* skip options processed plus command name */ argc -= bu_optind; argv += bu_optind; if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "ERROR: missing file or object names\n"); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); return GED_ERROR; } /* First, clear any existing counts */ for (i = 0; i < RT_DBNHASH; i++) { for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) dp->d_nref = 0; } /* Alert user if named file already exists */ new_dbip = db_open(argv[0], DB_OPEN_READWRITE); if (new_dbip != DBI_NULL) { if (db_version(new_dbip) != db_version(gedp->ged_wdbp->dbip)) { bu_vls_printf(gedp->ged_result_str, "%s: File format mismatch between '%s' and '%s'\n", cmd, argv[0], gedp->ged_wdbp->dbip->dbi_filename); return GED_ERROR; } if ((keepfp = wdb_dbopen(new_dbip, RT_WDB_TYPE_DB_DISK)) == NULL) { bu_vls_printf(gedp->ged_result_str, "%s: Error opening '%s'\n", cmd, argv[0]); return GED_ERROR; } else { bu_vls_printf(gedp->ged_result_str, "%s: Appending to '%s'\n", cmd, argv[0]); /* --- Scan geometry database and build in-memory directory --- */ db_dirbuild(new_dbip); } } else { /* Create a new database */ keepfp = wdb_fopen_v(argv[0], db_version(gedp->ged_wdbp->dbip)); if (keepfp == NULL) { perror(argv[0]); return GED_ERROR; } } knd.wdbp = keepfp; knd.gedp = gedp; /* ident record */ if (bu_strncmp(gedp->ged_wdbp->dbip->dbi_title, "Parts of: ", 10) != 0) { bu_vls_strcat(&title, "Parts of: "); } bu_vls_strcat(&title, gedp->ged_wdbp->dbip->dbi_title); if (db_update_ident(keepfp->dbip, bu_vls_addr(&title), gedp->ged_wdbp->dbip->dbi_local2base) < 0) { perror("fwrite"); bu_vls_printf(gedp->ged_result_str, "db_update_ident() failed\n"); wdb_close(keepfp); bu_vls_free(&title); return GED_ERROR; } bu_vls_free(&title); for (i = 1; i < argc; i++) { if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) continue; if (!flag_R) { /* recursively keep objects */ db_functree(gedp->ged_wdbp->dbip, dp, node_write, node_write, &rt_uniresource, (void *)&knd); } else { /* keep just this object */ node_write(gedp->ged_wdbp->dbip, dp, (void *)&knd); } } wdb_close(keepfp); return GED_OK; }
int ged_killtree(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; int i; int c; struct killtree_data gktd; static const char *usage = "[-a|-f|-n] object(s)"; 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; } gktd.gedp = gedp; gktd.killrefs = 0; gktd.print = 0; gktd.force = 0; gktd.ac = 1; gktd.top = NULL; gktd.av = (char **)bu_calloc(1, sizeof(char *) * AV_STEP, "alloc av"); gktd.av_capacity = AV_STEP; BU_ASSERT(gktd.ac + argc + 2 < AV_STEP); /* potential -n opts */ gktd.av[0] = "killrefs"; gktd.av[1] = (char *)0; bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, "afn")) != -1) { switch (c) { case 'a': gktd.killrefs = 1; break; case 'n': gktd.print = 1; gktd.av[gktd.ac++] = bu_strdup("-n"); gktd.av[gktd.ac] = (char *)0; break; case 'f': gktd.force = 1; break; default: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); bu_free(gktd.av, "free av (error)"); gktd.av = NULL; return GED_ERROR; } } argc -= (bu_optind - 1); argv += (bu_optind - 1); /* Objects that would be killed are in the first sublist */ if (gktd.print) bu_vls_printf(gedp->ged_result_str, "{"); for (i = 1; i < argc; i++) { if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) continue; /* ignore phony objects */ if (dp->d_addr == RT_DIR_PHONY_ADDR) continue; /* stash the what's killed so we can find refs elsewhere */ gktd.top = argv[i]; db_functree(gedp->ged_wdbp->dbip, dp, killtree_callback, killtree_callback, gedp->ged_wdbp->wdb_resp, (void *)&gktd); } /* Close the sublist of would-be killed objects. Also open the * sublist of objects that reference the would-be killed objects. */ if (gktd.print) bu_vls_printf(gedp->ged_result_str, "} {"); if (gktd.killrefs && gktd.ac > 1) { gedp->ged_internal_call = 1; (void)ged_killrefs(gedp, gktd.ac, (const char **)gktd.av); gedp->ged_internal_call = 0; for (i = 1; i < gktd.ac; i++) { if (!gktd.print) bu_vls_printf(gedp->ged_result_str, "Freeing %s\n", gktd.av[i]); bu_free((void *)gktd.av[i], "killtree_data"); gktd.av[i] = NULL; } } if (gktd.print) bu_vls_printf(gedp->ged_result_str, "}"); bu_free(gktd.av, "free av"); gktd.av = NULL; return GED_OK; }
/** * recursively copy a tree of geometry */ static struct directory * copy_tree(struct db_i *_dbip, struct directory *dp, struct resource *resp, struct clone_state *state) { size_t i; union record *rp = (union record *)NULL; struct directory *mdp = (struct directory *)NULL; struct directory *copy = (struct directory *)NULL; struct bu_vls *copyname = NULL; struct bu_vls *nextname = NULL; /* get the name of what the object "should" get cloned to */ copyname = get_name(_dbip, dp, state, 0); /* copy the object */ if (dp->d_flags & RT_DIR_COMB) { if (db_version(_dbip) < 5) { /* A v4 method of peeking into a combination */ int errors = 0; /* get an in-memory record of this object */ if ((rp = db_getmrec(_dbip, dp)) == (union record *)0) { TCL_READ_ERR; goto done_copy_tree; } /* * if it is a combination/region, copy the objects that * make up the object. */ for (i = 1; i < dp->d_len; i++) { if ((mdp = db_lookup(_dbip, rp[i].M.m_instname, LOOKUP_NOISY)) == RT_DIR_NULL) { errors++; bu_log("WARNING: failed to locate \"%s\"\n", rp[i].M.m_instname); continue; } copy = copy_tree(_dbip, mdp, resp, state); if (!copy) { errors++; bu_log("WARNING: unable to fully clone \"%s\"\n", rp[i].M.m_instname); } } if (errors) { bu_log("WARNING: some elements of \"%s\" could not be cloned\n", dp->d_namep); } /* copy this combination itself */ copy_comb(_dbip, dp, (genptr_t)state); } else /* A v5 method of peeking into a combination */ db_functree(_dbip, dp, copy_comb, copy_solid, resp, (genptr_t)state); } else if (dp->d_flags & RT_DIR_SOLID) /* leaf node -- make a copy the object */ copy_solid(_dbip, dp, (genptr_t)state); else { Tcl_AppendResult(state->interp, "clone: ", dp->d_namep, " is neither a combination or a primitive?\n", (char *)NULL); goto done_copy_tree; } nextname = get_name(_dbip, dp, state, 0); if (bu_vls_strcmp(copyname, nextname) == 0) bu_log("ERROR: unable to successfully clone \"%s\" to \"%s\"\n", dp->d_namep, bu_vls_addr(copyname)); else copy = db_lookup(_dbip, bu_vls_addr(copyname), LOOKUP_QUIET); done_copy_tree: if (rp) bu_free((char *)rp, "copy_tree record[]"); if (copyname) bu_free((char *)copyname, "free get_name() copyname"); if (nextname) bu_free((char *)nextname, "free get_name() copyname"); return copy; }
int main(int argc, char *argv[]) { size_t i; int ret; int c; double percent; char copy_buffer[CP_BUF_SIZE] = {0}; struct directory *dp; bu_setprogname(argv[0]); bu_setlinebuf(stderr); bu_log("%s", brlcad_ident("BRL-CAD to IGES Translator")); bu_log("Please direct bug reports to <*****@*****.**>\n\n"); tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; tree_state.ts_m = &the_model; ttol.magic = RT_TESS_TOL_MAGIC; /* Defaults, updated by command line options. */ ttol.abs = 0.0; ttol.rel = 0.01; ttol.norm = 0.0; /* FIXME: These need to be improved */ tol.magic = BN_TOL_MAGIC; tol.dist = 0.0005; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1 - tol.perp; the_model = nmg_mm(); BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ rt_init_resource(&rt_uniresource, 0, NULL); prog_name = argv[0]; /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "ftsmd:a:n:o:p:r:vx:P:X:")) != -1) { switch (c) { case 'f': /* Select facetized output */ mode = FACET_MODE; multi_file = 0; break; case 't': mode = TRIMMED_SURF_MODE; multi_file = 0; break; case 'm': /* multi-file mode */ multi_file = 1; mode = TRIMMED_SURF_MODE; break; case 's': /* Select NURB output */ do_nurbs = 1; break; case 'v': verbose++; break; case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); break; case 'd': /* distance tolerance */ tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); NMG_debug = RTG.NMG_debug; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'P': ncpu = atoi(bu_optarg); break; default: usage(argv[0]); break; } } if (bu_optind+1 >= argc) { usage(argv[0]); } /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; db_name = argv[0]; if ((DBIP = db_open(db_name, DB_OPEN_READONLY)) == DBI_NULL) { perror("g-iges"); bu_exit(1, "ERROR: unable to open geometry database file (%s)\n", db_name); } /* Scan the database */ if (db_dirbuild(DBIP)) { bu_exit(1, "db_dirbuild failed\n"); } if (!multi_file) { /* let the IGES routines know the selected tolerances and the database pointer */ iges_init(&tol, &ttol, verbose, DBIP); /* Open the output file */ if (output_file == NULL) fp_dir = stdout; else { if ((fp_dir = fopen(output_file, "wb")) == NULL) { perror(output_file); bu_exit(1, "Cannot open output file: %s\n", output_file); } } /* Open the temporary file for the parameter section */ if ((fp_param = bu_temp_file(NULL, 0)) == NULL) { perror("g-iges"); bu_exit(1, "Cannot open temporary file\n"); } /* Write start and global sections of the IGES file */ w_start_global(fp_dir, fp_param, argv[0], prog_name, output_file, __DATE__, brlcad_version()); } else { if (!bu_file_directory(output_file)) { bu_exit(1, "-o option must provide a directory, %s is not a directory\n", output_file); } } /* Count object references */ /* for (i = 1; i < argc; i++) { dp = db_lookup(DBIP, argv[i], 1); db_functree(DBIP, dp, count_refs, 0, NULL); } */ /* tree tops must have independent status, so we need to remember them */ independent = (argv+1); no_of_indeps = (size_t)argc-1; if (mode == FACET_MODE) { /* Walk indicated tree(s). Each region will be output * as a single manifold solid BREP object */ ret = db_walk_tree(DBIP, argc-1, (const char **)(argv+1), ncpu, &tree_state, 0, /* take all regions */ do_nmg_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (ret) bu_exit(1, "g-iges: Could not facetize anything!"); if (!multi_file) { /* Now walk the same trees again, but only output groups */ for (i = 1; i < (size_t)argc; i++) { char *ptr; ptr = strrchr(argv[i], '/'); if (ptr != NULL) { ptr++; } else { ptr = argv[i]; } dp = db_lookup(DBIP, ptr, 1); if (!dp) { bu_log("WARNING: Unable to locate %s in %s\n, skipping\n", ptr, db_name); continue; } db_functree(DBIP, dp, csg_comb_func, 0, &rt_uniresource, NULL); } } } else if (mode == CSG_MODE) { /* Walk indicated tree(s). Each combination and solid will be output * as a CSG object, unless there is no IGES equivalent (then the * solid will be tessellated and output as a BREP object) */ for (i = 1; i < (size_t)argc; i++) { dp = db_lookup(DBIP, argv[i], 1); if (!dp) { bu_log("WARNING: Unable to locate %s in %s\n, skipping\n", argv[i], db_name); continue; } db_functree(DBIP, dp, csg_comb_func, csg_leaf_func, &rt_uniresource, NULL); } } else if (mode == TRIMMED_SURF_MODE) { /* Walk the indicated tree(s). Each region is output as a collection * of trimmed NURBS */ ret = db_walk_tree(DBIP, argc-1, (const char **)(argv+1), ncpu, &tree_state, 0, /* take all regions */ do_nmg_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (ret) bu_exit(1, "g-iges: Could not facetize anything!"); } if (!multi_file) { /* Copy the parameter section from the temporary file to the output file */ if ((bu_fseek(fp_param, 0, 0))) { perror("g-iges"); bu_exit(1, "Cannot seek to start of temporary file\n"); } while ((i = fread(copy_buffer, 1, CP_BUF_SIZE, fp_param))) if (fwrite(copy_buffer, 1, i, fp_dir) != i) { perror("g-iges"); bu_exit(1, "Error in copying parameter data to %s\n", output_file); } /* Write the terminate section */ w_terminate(fp_dir); } /* Print some statistics */ Print_stats(stdout); /* report on the success rate for facetizing regions */ if (mode == FACET_MODE || mode == TRIMMED_SURF_MODE) { percent = 0; if (regions_tried>0) percent = ((double)regions_done * 100) / regions_tried; bu_log("Tried %d regions, %d converted to nmg's successfully. %g%%\n", regions_tried, regions_done, percent); } /* re-iterate warnings */ if (scale_error || solid_error || comb_error) bu_log("WARNING: the IGES file produced has errors:\n"); if (scale_error) bu_log("\t%d scaled objects found, written to IGES file without being scaled\n", scale_error); if (solid_error) bu_log("\t%d solids were not converted to IGES format\n", solid_error); if (comb_error) bu_log("\t%d combinations were not converted to IGES format\n", comb_error); return 0; }
void db_functree(struct db_i *dbip, struct directory *dp, void (*comb_func) (struct db_i *, struct directory *, void *), void (*leaf_func) (struct db_i *, struct directory *, void *), struct resource *resp, void *client_data) { register size_t i; RT_CK_DBI(dbip); if (resp) { RT_CK_RESOURCE(resp); } if ((!dp) || (!comb_func && !leaf_func)) { return; /* nothing to do */ } if (RT_G_DEBUG&DEBUG_DB) { bu_log("db_functree(%s) %p, %p, comb=%lx, leaf=%lx, client_data=%p\n", dp->d_namep, (void *)dbip, (void *)dp, (long unsigned int)comb_func, (long unsigned int)leaf_func, client_data); } if (dp->d_flags & RT_DIR_COMB) { if (db_version(dbip) < 5) { register union record *rp; register struct directory *mdp; /* * Load the combination into local record buffer * This is in external v4 format. */ if ((rp = db_getmrec(dbip, dp)) == (union record *)0) return; /* recurse */ for (i=1; i < dp->d_len; i++) { if ((mdp = db_lookup(dbip, rp[i].M.m_instname, LOOKUP_NOISY)) == RT_DIR_NULL) continue; db_functree(dbip, mdp, comb_func, leaf_func, resp, client_data); } bu_free((char *)rp, "db_functree record[]"); } else { struct rt_db_internal in; struct rt_comb_internal *comb; if (rt_db_get_internal5(&in, dp, dbip, NULL, resp) < 0) return; comb = (struct rt_comb_internal *)in.idb_ptr; db_functree_subtree(dbip, comb->tree, comb_func, leaf_func, resp, client_data); rt_db_free_internal(&in); } /* Finally, the combination itself */ if (comb_func) comb_func(dbip, dp, client_data); } else if (dp->d_flags & RT_DIR_SOLID || dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK) { if (leaf_func) leaf_func(dbip, dp, client_data); } else { bu_log("db_functree: %s is neither COMB nor SOLID?\n", dp->d_namep); } }
int main(int argc, char *argv[]) { int c; struct directory* dp; struct db_i *dbip; /* setup BRL-CAD environment */ bu_setprogname(argv[0]); bu_setlinebuf(stderr); /* process command line arguments */ while ((c = bu_getopt(argc, argv, "vo:ys:fh?")) != -1) { switch (c) { case 'v': verbose++; break; case 'o': out_file = bu_optarg; break; case 'y': yup++; break; case 's': sscanf(bu_optarg, "%f", &scale); break; case 'f': flip_normals++; break; default: print_usage(argv[0]); } } /* param check */ if (bu_optind+1 >= argc) print_usage(argv[0]); /* get database filename and object */ db_file = argv[bu_optind++]; object = argv[bu_optind]; /* open BRL-CAD database */ if ((dbip = db_open(db_file, DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open geometry database file %s\n", db_file); } if (db_dirbuild(dbip)) bu_exit(1, "db_dirbuild() failed!\n"); if (verbose) fprintf(stderr, ">> opened db '%s'\n", dbip->dbi_title); /* setup output stream */ if (out_file == NULL) { fp_out = stdout; setmode(fileno(fp_out), O_BINARY); } else { if ((fp_out = fopen(out_file, "wb")) == NULL) { bu_log("Cannot open %s\n", out_file); perror(argv[0]); return 2; } } /* find requested object */ db_update_nref(dbip, &rt_uniresource); dp = db_lookup(dbip, object, 0); if (dp == RT_DIR_NULL) bu_exit(1, "Object %s not found in database!\n", object); /* generate mesh list */ db_functree(dbip, dp, NULL, mesh_tracker, &rt_uniresource, NULL); if (verbose) fprintf(stderr, ">> mesh count: %d\n", mesh_count); /* write out header */ write_header(dbip); /* write out meshes */ write_mesh_data(); /* finish */ dealloc_mesh_list(); db_close(dbip); return 0; }