/** * M A I N * * Call parse_args to handle command line arguments first, then * process input. */ int main(int ac, char *av[]) { /** @struct rt_i * This structure contains some global state information for librt */ struct rt_i *rtip; struct db_tree_state init_state; /* state table for the hierarchy walker */ char idbuf[1024] = {0}; /* Database title */ int arg_count; char *tmp_basename; /** @struct user_data * This is an example structure. * It contains anything you want to have available in the region/leaf processing routines */ struct user_data { int stuff; } user_data; arg_count = parse_args(ac, av); if ((ac - arg_count) < 1) { tmp_basename = bu_basename(av[0]); usage(tmp_basename, "bad argument count"); bu_free(tmp_basename, "tmp_basename free"); } /* * Build an index of what's in the database. * rt_dirbuild() returns an "instance" pointer which describes * the database. It also gives you back the * title string in the header (ID) record. */ rtip = rt_dirbuild(av[arg_count], idbuf, sizeof(idbuf)); if (rtip == RTI_NULL) { bu_exit(2, "%s: rt_dirbuild failure\n", av[0]); } arg_count++; init_state = rt_initial_tree_state; db_walk_tree(rtip->rti_dbip, /* database instance */ ac-arg_count, /* number of trees to get from the database */ (const char **)&av[arg_count], 1, /* number of cpus to use */ &init_state, region_start, region_end, leaf_func, (genptr_t)&user_data); /* at this point you can do things with the geometry you have obtained */ return 0; }
union tree * gcv_bottess(int argc, const char **argv, struct db_i *dbip, struct rt_tess_tol *ttol) { struct db_tree_state tree_state = rt_initial_tree_state; tree_state.ts_ttol = ttol; if (db_walk_tree(dbip, argc, argv, 1, &tree_state, NULL, gcv_bottess_region_end, nmg_booltree_leaf_tess, NULL) < 0) bu_log("gcv_bottess: db_walk_tree failure\n"); return NULL; }
static int gcv_vrml_write(const char *path, struct db_i *vdbip, const struct gcv_opts *UNUSED(options)) { size_t i; struct plate_mode pm; size_t num_objects = 0; char **object_names = NULL; out_file = path; dbip = vdbip; bu_setlinebuf(stderr); the_model = nmg_mm(); 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; tol.magic = BN_TOL_MAGIC; tol.dist = 0.005; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1 - tol.perp; /* NOTE: For visualization purposes, in the debug plot files */ { /* WTF: This value is specific to the Bradley */ nmg_eue_dist = 2.0; } BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ if ((bot_dump == 1) && (eval_all == 1)) { bu_log("BOT Dump and Evaluate All are mutually exclusive\n"); return 0; } if (out_file == NULL) { fp_out = stdout; setmode(fileno(fp_out), O_BINARY); } else { if ((fp_out = fopen(out_file, "wb")) == NULL) { perror("g-vrml"); bu_log("Cannot open %s\n", out_file); return 0; } } fprintf(fp_out, "#VRML V2.0 utf8\n"); fprintf(fp_out, "#Units are %s\n", units); /* NOTE: We may want to inquire about bounding boxes for the * various groups and add Viewpoints nodes that point the camera * to the center and orient for Top, Side, etc. Views. We will add * some default Material Color definitions (for thousands groups) * before we start defining the geometry. */ fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_999 Material { diffuseColor 0.78 0.78 0.78 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_1999 Material { diffuseColor 0.88 0.29 0.29 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_2999 Material { diffuseColor 0.82 0.53 0.54 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_3999 Material { diffuseColor 0.39 0.89 0.00 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_4999 Material { diffuseColor 1.00 0.00 0.00 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_5999 Material { diffuseColor 0.82 0.00 0.82 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_6999 Material { diffuseColor 0.62 0.62 0.62 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_7999 Material { diffuseColor 0.49 0.49 0.49 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_8999 Material { diffuseColor 0.18 0.31 0.31 } } }\n"); fprintf(fp_out, "Shape { appearance Appearance { material DEF Material_9999 Material { diffuseColor 0.00 0.41 0.82 } } }\n"); /* I had hoped to create a separate sub-tree (using the Transform * node) for each group name argument however, it appears they are * all handled at the same time so I will only have one Transform * for the complete conversion. Later on switch nodes may be added * to turn on and off the groups (via ROUTE nodes). */ fprintf(fp_out, "Transform {\n"); fprintf(fp_out, "\tchildren [\n"); pm.num_bots = 0; pm.num_nonbots = 0; if (!eval_all) { pm.array_size = 5; pm.bots = (struct rt_bot_internal **)bu_calloc(pm.array_size, sizeof(struct rt_bot_internal *), "pm.bots"); } /* get toplevel objects */ { struct directory **results; db_update_nref(dbip, &rt_uniresource); num_objects = db_ls(dbip, DB_LS_TOPS, NULL, &results); object_names = db_dpv_to_argv(results); bu_free(results, "tops"); } if (eval_all) { (void)db_walk_tree(dbip, num_objects, (const char **)(object_names), 1, /* ncpu */ &tree_state, 0, nmg_region_end, nmg_booltree_leaf_tess, (void *)&pm); /* in librt/nmg_bool.c */ goto out; } if (bot_dump) { (void)db_walk_tree(dbip, num_objects, (const char **)(object_names), 1, /* ncpu */ &tree_state, 0, do_region_end2, leaf_tess2, (void *)&pm); /* in librt/nmg_bool.c */ goto out; } for (i = 0; i < num_objects; i++) { struct directory *dp; dp = db_lookup(dbip, object_names[i], LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_log("Cannot find %s\n", object_names[i]); continue; } /* light source must be a combination */ if (!(dp->d_flags & RT_DIR_COMB)) { continue; } fprintf(fp_out, "# Includes group %s\n", object_names[i]); /* walk trees selecting only light source regions */ (void)db_walk_tree(dbip, 1, (const char **)(&object_names[i]), 1, /* ncpu */ &tree_state, select_lights, do_region_end1, leaf_tess1, (void *)&pm); /* in librt/nmg_bool.c */ } /* Walk indicated tree(s). Each non-light-source region will be output separately */ (void)db_walk_tree(dbip, num_objects, (const char **)(object_names), 1, /* ncpu */ &tree_state, select_non_lights, do_region_end1, leaf_tess1, (void *)&pm); /* in librt/nmg_bool.c */ /* Release dynamic storage */ nmg_km(the_model); if (!eval_all) { bu_free(pm.bots, "pm.bots"); } out: bu_free(object_names, "object_names"); /* Now we need to close each group set */ fprintf(fp_out, "\t]\n}\n"); bu_log("\nTotal of %d regions converted of %d regions attempted.\n", regions_converted, regions_tried); if (regions_converted != regions_tried) { bu_log("Of the %d which failed conversion, %d of these failed due to conversion error.\n", regions_tried - regions_converted, bomb_cnt); } fclose(fp_out); bu_log("Done.\n"); return 1; }
/* * M A I N */ int main(int argc, char **argv) { char *dot, *fig_file; register int c; double percent; int size; bu_setlinebuf( stderr ); jack_tree_state = rt_initial_tree_state; /* struct copy */ jack_tree_state.ts_tol = &tol; jack_tree_state.ts_ttol = &ttol; jack_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; /* XXX These need to be improved */ tol.magic = BN_TOL_MAGIC; tol.dist = 0.005; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1 - tol.perp; rt_init_resource( &rt_uniresource, 0, NULL ); the_model = nmg_mm(); BU_LIST_INIT( &rt_g.rtg_vlfree ); /* for vlist macros */ /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "a:dn:p:r:vx:P:X:")) != EOF) { switch (c) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); break; case 'd': debug_plots = 1; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); break; case 'p': /* Prefix for Jack file names. */ prefix = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi( bu_optarg ); rt_g.debug = 1; /* XXX DEBUG_ALLRAYS -- to get core dumps */ break; case 'x': sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.debug ); break; case 'X': sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.NMG_debug ); NMG_debug = rt_g.NMG_debug; break; default: bu_exit(1, usage, argv[0]); break; } } if (bu_optind+1 >= argc) { bu_exit(1, usage, argv[0]); } /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; if ((dbip = db_open(argv[0], "r")) == DBI_NULL) { perror(argv[0]); bu_exit(1, "ERROR: Unable to open geometry database (%s)\n", argv[0]); } if ( db_dirbuild( dbip ) ) { bu_exit(1, "db_dirbuild failed\n" ); } /* Create .fig file name and open it. */ size = sizeof(prefix) + sizeof(argv[0] + 4); fig_file = bu_malloc(size, "st"); /* Ignore leading path name. */ if ((dot = strrchr(argv[0], '/')) != (char *)NULL) { if (prefix) { snprintf(fig_file, size, "%s%s", prefix, 1+dot); } else { snprintf(fig_file, size, "%s", 1+dot); } } else { if (prefix) snprintf(fig_file, size, "%s%s", prefix, argv[0]); else snprintf(fig_file, size, "%s", argv[0]); } /* Get rid of any file name extension (probably .g). */ if ((dot = strrchr(fig_file, '.')) != (char *)NULL) *dot = '\0'; bu_strlcat(fig_file, ".fig", size); /* Add required Jack suffix. */ if ((fp_fig = fopen(fig_file, "wb")) == NULL) perror(fig_file); fprintf(fp_fig, "figure {\n"); bu_vls_init(&base_seg); /* .fig figure file's main segment. */ /* Walk indicated tree(s). Each region will be output separately */ (void)db_walk_tree(dbip, argc-1, (const char **)(argv+1), 1, /* ncpu */ &jack_tree_state, 0, /* take all regions */ do_region_end, nmg_booltree_leaf_tess, (genptr_t)NULL); /* in librt/nmg_bool.c */ fprintf(fp_fig, "\troot=%s_seg.base;\n", bu_vls_addr(&base_seg)); fprintf(fp_fig, "}\n"); fclose(fp_fig); bu_free(fig_file, "st"); bu_vls_free(&base_seg); percent = 0; if (regions_tried>0) percent = ((double)regions_done * 100) / regions_tried; printf("Tried %d regions, %d converted successfully. %g%%\n", regions_tried, regions_done, percent); return 0; }
/* * M A I N */ int main(int argc, char **argv) { register int c; double percent; bu_setlinebuf( stderr ); #if MEMORY_LEAK_CHECKING rt_g.debug |= DEBUG_MEM_FULL; #endif 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; /* XXX These need to be improved */ tol.magic = BN_TOL_MAGIC; tol.dist = 0.005; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-5; tol.para = 1 - tol.perp; rt_init_resource( &rt_uniresource, 0, NULL ); the_model = nmg_mm(); BU_LIST_INIT( &rt_g.rtg_vlfree ); /* for vlist macros */ /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "mua:n:o:r:vx:D:P:X:e:i")) != EOF) { switch (c) { case 'm': /* include 'usemtl' statements */ usemtl = 1; break; case 'u': /* Include vertexuse normals */ do_normals = 1; break; case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi( bu_optarg ); rt_g.debug = 1; /* XXX DEBUG_ALLRAYS -- to get core dumps */ break; case 'x': sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.debug ); break; case 'D': tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; rt_pr_tol( &tol ); break; case 'X': sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.NMG_debug ); NMG_debug = rt_g.NMG_debug; break; case 'e': /* Error file name. */ error_file = bu_optarg; break; case 'i': inches = 1; break; default: bu_exit(1, usage, argv[0]); break; } } if (bu_optind+1 >= argc) { bu_exit(1, usage, argv[0]); } if ( !output_file ) fp = stdout; else { /* Open output file */ if ( (fp=fopen( output_file, "wb+" )) == NULL ) { perror( argv[0] ); bu_exit(1, "Cannot open output file (%s) for writing\n", output_file ); } } /* Open g-obj error log file */ if (!error_file) { fpe = stderr; #if defined(_WIN32) && !defined(__CYGWIN__) setmode(fileno(fpe), O_BINARY); #endif } else if ((fpe=fopen(error_file, "wb")) == NULL) { perror( argv[0] ); bu_exit(1, "Cannot open output file (%s) for writing\n", error_file ); } /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; if ((dbip = db_open(argv[0], "r")) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Unable to open geometry file (%s) for reading\n", argv[0]); } if ( db_dirbuild( dbip ) ) { bu_exit(1, "db_dirbuild failed\n"); } BN_CK_TOL(tree_state.ts_tol); RT_CK_TESS_TOL(tree_state.ts_ttol); /* Write out header */ if (inches) fprintf(fp, "# BRL-CAD generated Wavefront OBJ file (Units in)\n"); else fprintf(fp, "# BRL-CAD generated Wavefront OBJ file (Units mm)\n"); fprintf( fp, "# BRL-CAD model: %s\n# BRL_CAD objects:", argv[0] ); for ( c=1; c<argc; c++ ) fprintf( fp, " %s", argv[c] ); fprintf( fp, "\n" ); /* Walk indicated tree(s). Each region will be output separately */ (void) db_walk_tree(dbip, argc-1, (const char **)(argv+1), 1, /* ncpu */ &tree_state, 0, /* take all regions */ do_region_end, nmg_booltree_leaf_tess, (genptr_t)NULL); /* in librt/nmg_bool.c */ percent = 0; if (regions_tried>0) { percent = ((double)regions_converted * 100) / regions_tried; printf("Tried %d regions, %d converted to NMG's successfully. %g%%\n", regions_tried, regions_converted, percent); } percent = 0; if ( regions_tried > 0 ) { percent = ((double)regions_written * 100) / regions_tried; printf( " %d triangulated successfully. %g%%\n", regions_written, percent ); } fclose(fp); /* Release dynamic storage */ nmg_km(the_model); rt_vlist_cleanup(); db_close(dbip); #if MEMORY_LEAK_CHECKING bu_prmem("After complete G-ACAD conversion"); #endif return 0; }
int main(int argc, char **argv) { int i; int c; struct plate_mode pm; bu_setprogname(argv[0]); bu_setlinebuf( stderr ); the_model = nmg_mm(); 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 = BN_TOL_DIST; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1 - tol.perp; /* NOTE: For visualization purposes, in the debug plot files */ { /* WTF: This value is specific to the Bradley */ nmg_eue_dist = 2.0; } BU_LIST_INIT( &RTG.rtg_vlfree ); /* for vlist macros */ BARRIER_CHECK; /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "d:a:n:o:r:vx:P:X:u:h?")) != -1) { switch (c) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'd': /* calculational tolerance */ tol.dist = atof( bu_optarg ); tol.dist_sq = tol.dist * tol.dist; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg)*DEG2RAD; ttol.rel = 0.0; break; case 'o': /* Output file name */ out_file = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi(bu_optarg); 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 'u': units = bu_strdup( bu_optarg ); scale_factor = bu_units_conversion( units ); if ( ZERO(scale_factor) ) bu_exit(1, "Unrecognized units (%s)\n", units ); scale_factor = 1.0 / scale_factor; break; default: print_usage(argv[0]); } } if (bu_optind+1 >= argc) print_usage(argv[0]); /* Open BRL-CAD database */ if ((dbip = db_open( argv[bu_optind], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open geometry database file %s\n", argv[bu_optind] ); } if ( db_dirbuild( dbip ) ) bu_exit(1, "db_dirbuild() failed!\n" ); if (out_file == NULL) { outfp = stdout; setmode(fileno(outfp), O_BINARY); } else { if ((outfp = fopen( out_file, "wb")) == NULL) { perror( argv[0] ); bu_exit(2, "Cannot open %s\n", out_file ); } } writeX3dHeader(outfp, out_file); bu_optind++; BARRIER_CHECK; pm.num_bots = 0; pm.num_nonbots = 0; pm.array_size = 5; pm.bots = (struct rt_bot_internal **)bu_calloc( pm.array_size, sizeof( struct rt_bot_internal *), "pm.bots" ); for ( i=bu_optind; i<argc; i++ ) { struct directory *dp; dp = db_lookup( dbip, argv[i], LOOKUP_QUIET ); if ( dp == RT_DIR_NULL ) { bu_log( "Cannot find %s\n", argv[i] ); continue; } /* light source must be a combination */ if ( !(dp->d_flags & RT_DIR_COMB) ) continue; /* walk trees selecting only light source regions */ (void)db_walk_tree(dbip, 1, (const char **)(&argv[i]), ncpu, &tree_state, select_lights, do_region_end, leaf_tess, (void *)&pm); /* in librt/nmg_bool.c */ } BARRIER_CHECK; /* Walk indicated tree(s). Each non-light-source region will be output separately */ (void)db_walk_tree(dbip, argc-bu_optind, (const char **)(&argv[bu_optind]), ncpu, &tree_state, select_non_lights, do_region_end, leaf_tess, (void *)&pm); /* in librt/nmg_bool.c */ BARRIER_CHECK; /* Release dynamic storage */ nmg_km(the_model); db_close(dbip); /* Now we need to close each group set */ writeX3dEnd(outfp); if ( verbose ) bu_log( "Total of %d regions converted of %d regions attempted\n", regions_converted, regions_tried ); return 0; }
int main(int argc, char **argv) { int i, j; int c; double percent; bu_setprogname(argv[0]); bu_setlinebuf(stderr); RTG.debug = 0; 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 = (struct model *)NULL; tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_m = &the_model; tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; rt_init_resource(&rt_uniresource, 0, NULL); /* For visualization purposes, in the debug plot files */ { /* WTF: This value is specific to the Bradley */ nmg_eue_dist = 2.0; } BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "a:n:o:r:vx:P:X:h?")) != -1) { switch (c) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name */ out_file = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi(bu_optarg); 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; default: usage(argv[0]); } } if (bu_optind+1 >= argc) usage(argv[0]); /* Open BRL-CAD database */ if ((dbip = db_open(argv[bu_optind], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open geometry database file %s\n", argv[bu_optind]); } if (db_dirbuild(dbip)) { bu_exit(1, "db_dirbuild failed\n"); } 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; } } bu_optind++; fprintf(fp_out, "$03"); /* First produce an unordered list of region ident codes */ (void)db_walk_tree(dbip, argc-bu_optind, (const char **)(&argv[bu_optind]), 1, /* ncpu */ &tree_state, get_reg_id, /* put id in table */ region_stub, leaf_stub, (void *)NULL); /* Process regions in ident order */ curr_id = 0; for (i = 0; i < ident_length; i++) { int next_id = 99999999; for (j = 0; j < ident_length; j++) { int test_id; test_id = idents[j]; if (test_id > curr_id && test_id < next_id) next_id = test_id; } curr_id = next_id; face_count = 0; bu_log("Processing id %d\n", curr_id); /* Walk indicated tree(s). Each region will be output separately */ tree_state = rt_initial_tree_state; /* struct copy */ the_model = nmg_mm(); tree_state.ts_m = &the_model; tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; (void)db_walk_tree(dbip, argc-bu_optind, (const char **)(&argv[bu_optind]), ncpu, &tree_state, select_region, do_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ nmg_km(the_model); } percent = 0; if (regions_tried > 0) percent = ((double)regions_converted * 100) / regions_tried; printf("Tried %d regions, %d converted successfully. %g%%\n", regions_tried, regions_converted, percent); percent = 0; if (regions_tried > 0) percent = ((double)regions_written * 100) / regions_tried; printf(" %d written successfully. %g%%\n", regions_written, percent); /* Release dynamic storage */ rt_vlist_cleanup(); db_close(dbip); return 0; }
int main(int argc, char *argv[]) { int verbose = 0; int ncpu = 1; /* Number of processors */ char *output_file = NULL; /* output filename */ struct db_i *dbip; struct model *the_model; struct rt_tess_tol ttol; /* tessellation tolerance in mm */ struct db_tree_state tree_state; /* includes tol & model */ int i, use_mc = 0, use_bottess = 0; struct egg_conv_data conv_data; struct gcv_region_end_data gcvwriter = {nmg_to_egg, NULL}; gcvwriter.client_data = (void *)&conv_data; bu_setprogname(argv[0]); bu_setlinebuf(stderr); tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &conv_data.tol; tree_state.ts_ttol = &ttol; tree_state.ts_m = &the_model; /* Set up tessellation tolerance defaults */ ttol.magic = RT_TESS_TOL_MAGIC; /* Defaults, updated by command line options. */ ttol.abs = 0.0; ttol.rel = 0.01; ttol.norm = 0.0; /* Set up calculation tolerance defaults */ /* FIXME: These need to be improved */ conv_data.tol.magic = BN_TOL_MAGIC; conv_data.tol.dist = BN_TOL_DIST; conv_data.tol.dist_sq = conv_data.tol.dist * conv_data.tol.dist; conv_data.tol.perp = 1e-6; conv_data.tol.para = 1 - conv_data.tol.perp; conv_data.tot_polygons = 0; /* make empty NMG model */ the_model = nmg_mm(); BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ /* Get command line arguments. */ while ((i = bu_getopt(argc, argv, "a:89n:o:r:vx:D:P:X:h?")) != -1) { switch (i) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi(bu_optarg); break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'D': conv_data.tol.dist = atof(bu_optarg); conv_data.tol.dist_sq = conv_data.tol.dist * conv_data.tol.dist; rt_pr_tol(&conv_data.tol); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); break; case '8': use_mc = 1; break; case '9': use_bottess = 1; break; default: usage(argv[0]); } } if (bu_optind+1 >= argc) usage(argv[0]); conv_data.fp = stdout; if (output_file) { if ((conv_data.fp=fopen(output_file, "wb+")) == NULL) { perror(argv[0]); bu_exit(1, "Cannot open ASCII output file (%s) for writing\n", output_file); } } /* Open brl-cad database */ argc -= bu_optind; argv += bu_optind; if (argc < 2 || argv[0] == NULL || argv[1] == NULL) usage(argv[0]); gcvwriter.write_region = nmg_to_egg; if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Unable to open geometry database file (%s)\n", argv[0]); } if (db_dirbuild(dbip)) { bu_exit(1, "ERROR: db_dirbuild failed\n"); } BN_CK_TOL(tree_state.ts_tol); RT_CK_TESS_TOL(tree_state.ts_ttol); if (verbose) { bu_log("Model: %s\n", argv[0]); bu_log("Objects:"); for (i=1; i<argc; i++) bu_log(" %s", argv[i]); bu_log("\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n", tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm); bu_log("Calculational tolerances:\n\tdist = %g mm perp = %g\n", tree_state.ts_tol->dist, tree_state.ts_tol->perp); } /* print the egg header stuff, including the command line to execute it */ fprintf(conv_data.fp, "<CoordinateSystem> { Z-Up }\n\n"); fprintf(conv_data.fp, "<Comment> {\n \"%s", *argv); for (i=1; i<argc; i++) fprintf(conv_data.fp, " %s", argv[i]); fprintf(conv_data.fp, "\"\n}\n"); /* Walk indicated tree(s). Each region will be output separately */ while (--argc) { fprintf(conv_data.fp, "<Group> %s {\n", *(argv+1)); (void) db_walk_tree(dbip, /* db_i */ 1, /* argc */ (const char **)(++argv), /* argv */ ncpu, /* ncpu */ &tree_state, /* state */ NULL, /* start func */ use_mc?gcv_region_end_mc:use_bottess?gcv_bottess_region_end:gcv_region_end, /* end func */ use_mc?NULL:nmg_booltree_leaf_tess, /* leaf func */ (void *)&gcvwriter); /* client_data */ fprintf(conv_data.fp, "}\n"); } bu_log("%ld triangles written\n", conv_data.tot_polygons); if (output_file) fclose(conv_data.fp); /* Release dynamic storage */ nmg_km(the_model); rt_vlist_cleanup(); db_close(dbip); return 0; }
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; }
int main(int argc, char *argv[]) { struct user_data your_data = {0, BN_TOL_INIT_ZERO}; int i; int c; char idbuf[132] = {0}; struct rt_i *rtip; struct db_tree_state init_state; bu_setprogname(argv[0]); bu_setlinebuf(stderr); /* calculational tolerances * mostly used by NMG routines */ your_data.tol.magic = BN_TOL_MAGIC; your_data.tol.dist = BN_TOL_DIST; your_data.tol.dist_sq = your_data.tol.dist * your_data.tol.dist; your_data.tol.perp = 1e-6; your_data.tol.para = 1 - your_data.tol.perp; /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "t:a:n:o:r:x:X:")) != -1) { switch (c) { case 't': /* calculational tolerance */ your_data.tol.dist = atof(bu_optarg); your_data.tol.dist_sq = your_data.tol.dist * your_data.tol.dist; case 'o': /* Output file name */ /* grab output file name */ break; case 'x': /* librt debug flag */ sscanf(bu_optarg, "%x", &RTG.debug); bu_printb("librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT); bu_log("\n"); break; case 'X': /* NMG debug flag */ sscanf(bu_optarg, "%x", &RTG.NMG_debug); bu_printb("librt RTG.NMG_debug", RTG.NMG_debug, NMG_DEBUG_FORMAT); bu_log("\n"); break; default: print_usage(argv[0]); break; } } if (bu_optind+1 >= argc) { print_usage(argv[0]); } /* Open BRL-CAD database */ /* Scan all the records in the database and build a directory */ rtip=rt_dirbuild(argv[bu_optind], idbuf, sizeof(idbuf)); if (rtip == RTI_NULL) { bu_exit(1, "g-xxx: rt_dirbuild failure\n"); } init_state = rt_initial_tree_state; bu_optind++; /* Walk the trees named on the command line * outputting combinations and primitives */ for (i=bu_optind; i<argc; i++) { db_walk_tree(rtip->rti_dbip, argc - i, (const char **)&argv[i], 1 /* bu_avail_cpus() */, &init_state, region_start, region_end, primitive_func, (void *) &your_data); } return 0; }
/* * This routine is the drawable geometry object's analog of rt_gettrees(). * Add a set of tree hierarchies to the active set. * Note that argv[0] should be ignored, it has the command name in it. * * Returns - * 0 Ordinarily * -1 On major error */ int _ged_drawtrees(struct ged *gedp, int argc, const char *argv[], int kind, struct _ged_client_data *_dgcdp) { int ret = 0; int c; int ncpu = 1; int nmg_use_tnurbs = 0; int enable_fastpath = 0; struct model *nmg_model; struct _ged_client_data dgcdp; int i; int ac = 1; char *av[3]; RT_CHECK_DBI(gedp->ged_wdbp->dbip); if (argc <= 0) return -1; /* FAIL */ ++drawtrees_depth; av[1] = (char *)0; /* options are already parsed into _dgcdp */ if (_dgcdp != (struct _ged_client_data *)0) { dgcdp = *_dgcdp; /* struct copy */ } else { struct bview *gvp; memset(&dgcdp, 0, sizeof(struct _ged_client_data)); dgcdp.gedp = gedp; gvp = gedp->ged_gvp; if (gvp && gvp->gv_adaptive_plot) dgcdp.autoview = 1; else dgcdp.autoview = 0; /* Initial values for options, must be reset each time */ dgcdp.draw_nmg_only = 0; /* no booleans */ dgcdp.nmg_triangulate = 1; dgcdp.draw_wireframes = 0; dgcdp.draw_normals = 0; dgcdp.draw_solid_lines_only = 0; dgcdp.draw_no_surfaces = 0; dgcdp.shade_per_vertex_normals = 0; dgcdp.draw_edge_uses = 0; dgcdp.wireframe_color_override = 0; dgcdp.fastpath_count = 0; dgcdp.shaded_mode_override = _GED_SHADED_MODE_UNSET; /* default color - red */ dgcdp.wireframe_color[0] = 255; dgcdp.wireframe_color[1] = 0; dgcdp.wireframe_color[2] = 0; /* default transparency - opaque */ dgcdp.transparency = 1.0; /* freesolid */ dgcdp.freesolid = gedp->freesolid; enable_fastpath = 0; /* Parse options. */ bu_optind = 0; /* re-init bu_getopt() */ while ((c = bu_getopt(argc, (char * const *)argv, "dfhm:nqstuvwx:C:STP:A:oR")) != -1) { switch (c) { case 'u': dgcdp.draw_edge_uses = 1; break; case 's': dgcdp.draw_solid_lines_only = 1; break; case 't': nmg_use_tnurbs = 1; break; case 'v': dgcdp.shade_per_vertex_normals = 1; break; case 'w': dgcdp.draw_wireframes = 1; break; case 'S': dgcdp.draw_no_surfaces = 1; break; case 'T': dgcdp.nmg_triangulate = 0; break; case 'n': dgcdp.draw_normals = 1; break; case 'P': ncpu = atoi(bu_optarg); break; case 'q': dgcdp.do_not_draw_nmg_solids_during_debugging = 1; break; case 'd': dgcdp.draw_nmg_only = 1; break; case 'f': enable_fastpath = 1; break; case 'C': { int r, g, b; char *cp = bu_optarg; r = atoi(cp); while ((*cp >= '0' && *cp <= '9')) cp++; while (*cp && (*cp < '0' || *cp > '9')) cp++; g = atoi(cp); while ((*cp >= '0' && *cp <= '9')) cp++; while (*cp && (*cp < '0' || *cp > '9')) cp++; b = atoi(cp); if (r < 0 || r > 255) r = 255; if (g < 0 || g > 255) g = 255; if (b < 0 || b > 255) b = 255; dgcdp.wireframe_color_override = 1; dgcdp.wireframe_color[0] = r; dgcdp.wireframe_color[1] = g; dgcdp.wireframe_color[2] = b; } break; case 'h': dgcdp.hiddenLine = 1; dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; break; case 'm': dgcdp.shaded_mode_override = atoi(bu_optarg); switch (dgcdp.shaded_mode_override) { case 0: dgcdp.shaded_mode_override = _GED_WIREFRAME; break; case 1: dgcdp.shaded_mode_override = _GED_SHADED_MODE_BOTS; break; case 2: dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; break; case 3: dgcdp.shaded_mode_override = _GED_SHADED_MODE_EVAL; break; default: if (dgcdp.shaded_mode_override < 0) { dgcdp.shaded_mode_override = _GED_SHADED_MODE_UNSET; } else { dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; } } break; case 'x': dgcdp.transparency = atof(bu_optarg); /* clamp it to [0, 1] */ if (dgcdp.transparency < 0.0) dgcdp.transparency = 0.0; if (1.0 < dgcdp.transparency) dgcdp.transparency = 1.0; break; case 'R': dgcdp.autoview = 0; break; case 'A': case 'o': /* nothing to do, handled by edit_com wrapper on the front-end */ break; default: { bu_vls_printf(gedp->ged_result_str, "unrecognized option - %c\n", c); --drawtrees_depth; return GED_ERROR; } } } argc -= bu_optind; argv += bu_optind; switch (kind) { case _GED_DRAW_WIREFRAME: dgcdp.dmode = _GED_WIREFRAME; if (dgcdp.shaded_mode_override != _GED_SHADED_MODE_UNSET) { dgcdp.dmode = dgcdp.shaded_mode_override; } else if (gedp->ged_gdp->gd_shaded_mode) { dgcdp.dmode = gedp->ged_gdp->gd_shaded_mode; } break; case _GED_DRAW_NMG_POLY: dgcdp.dmode = _GED_BOOL_EVAL; break; } } if (!argc) { bu_vls_printf(gedp->ged_result_str, "Please specify one or more objects to be drawn.\n"); --drawtrees_depth; return -1; } switch (kind) { default: bu_vls_printf(gedp->ged_result_str, "ERROR, bad kind\n"); --drawtrees_depth; return -1; case _GED_DRAW_WIREFRAME: /* * If asking for wireframe and in shaded_mode and no shaded mode override, * or asking for wireframe and shaded mode is being overridden with a value * greater than 0, then draw shaded polygons for each object's primitives if possible. * * Note - * If shaded_mode is _GED_SHADED_MODE_BOTS, only BOTS and polysolids * will be shaded. The rest is drawn as wireframe. * If shaded_mode is _GED_SHADED_MODE_ALL, everything except pipe solids * are drawn as shaded polygons. */ if (dgcdp.dmode == _GED_SHADED_MODE_BOTS || dgcdp.dmode == _GED_SHADED_MODE_ALL || dgcdp.dmode == _GED_SHADED_MODE_EVAL) { struct _ged_client_data dgcdp_save; for (i = 0; i < argc; ++i) { if (drawtrees_depth == 1) dgcdp.gdlp = dl_addToDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, argv[i]); if (dgcdp.gdlp == GED_DISPLAY_LIST_NULL) continue; dgcdp_save = dgcdp; if (dgcdp.dmode == _GED_SHADED_MODE_EVAL) { ret = plot_shaded_eval(gedp, argv[i], &dgcdp); if (ret == GED_OK) { continue; } /* if evaluated shading failed, fall back to "all" mode */ dgcdp.gedp->ged_gdp->gd_shaded_mode = 0; dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; dgcdp.dmode = _GED_SHADED_MODE_ALL; } av[0] = (char *)argv[i]; ret = db_walk_tree(gedp->ged_wdbp->dbip, ac, (const char **)av, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, NULL, draw_check_region_end, draw_check_leaf, (void *)&dgcdp); dgcdp = dgcdp_save; } } else { struct display_list **paths_to_draw; struct display_list *gdlp; paths_to_draw = (struct display_list **) bu_malloc(sizeof(struct display_list *) * argc, "redraw paths"); /* create solids */ for (i = 0; i < argc; ++i) { struct bview_client_data bview_data; bview_data.draw_solid_lines_only = dgcdp.draw_solid_lines_only; bview_data.wireframe_color_override = dgcdp.wireframe_color_override; bview_data.wireframe_color[0]= dgcdp.wireframe_color[0]; bview_data.wireframe_color[1]= dgcdp.wireframe_color[1]; bview_data.wireframe_color[2]= dgcdp.wireframe_color[2]; bview_data.transparency= dgcdp.transparency; bview_data.dmode = dgcdp.dmode; bview_data.hiddenLine = dgcdp.hiddenLine; bview_data.freesolid = (void *)gedp->freesolid; dgcdp.gdlp = dl_addToDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, argv[i]); bview_data.gdlp = dgcdp.gdlp; /* store draw path */ paths_to_draw[i] = dgcdp.gdlp; if (dgcdp.gdlp == GED_DISPLAY_LIST_NULL) { continue; } av[0] = (char *)argv[i]; ret = db_walk_tree(gedp->ged_wdbp->dbip, ac, (const char **)av, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, NULL, wireframe_region_end, append_solid_to_display_list, (void *)&bview_data); } /* We need to know the view size in order to choose * appropriate input values for the adaptive plot * routines. Unless we're keeping the current view, * we need to autoview now so we have the correct * view size for plotting. */ if (dgcdp.autoview) { const char *autoview_args[2] = {"autoview", NULL}; ged_autoview(gedp, 1, autoview_args); } /* calculate plot vlists for solids of each draw path */ for (i = 0; i < argc; ++i) { gdlp = paths_to_draw[i]; if (gdlp == GED_DISPLAY_LIST_NULL) { continue; } ret = dl_redraw(gdlp, gedp->ged_wdbp->dbip, &gedp->ged_wdbp->wdb_initial_tree_state, gedp->ged_gvp, gedp->ged_create_vlist_callback); if (ret < 0) { bu_vls_printf(gedp->ged_result_str, "%s: %s redraw failure\n", argv[0], argv[i]); return GED_ERROR; } } bu_free(paths_to_draw, "draw paths"); } break; case _GED_DRAW_NMG_POLY: { nmg_model = nmg_mm(); gedp->ged_wdbp->wdb_initial_tree_state.ts_m = &nmg_model; if (dgcdp.draw_edge_uses) { bu_vls_printf(gedp->ged_result_str, "Doing the edgeuse thang (-u)\n"); dgcdp.draw_edge_uses_vbp = rt_vlblock_init(); } for (i = 0; i < argc; ++i) { if (drawtrees_depth == 1) dgcdp.gdlp = dl_addToDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, argv[i]); if (dgcdp.gdlp == GED_DISPLAY_LIST_NULL) continue; av[0] = (char *)argv[i]; ret = db_walk_tree(gedp->ged_wdbp->dbip, ac, (const char **)av, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, enable_fastpath ? draw_nmg_region_start : 0, draw_nmg_region_end, nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : nmg_booltree_leaf_tess, (void *)&dgcdp); } if (dgcdp.draw_edge_uses) { _ged_cvt_vlblock_to_solids(gedp, dgcdp.draw_edge_uses_vbp, "_EDGEUSES_", 0); bn_vlblock_free(dgcdp.draw_edge_uses_vbp); dgcdp.draw_edge_uses_vbp = (struct bn_vlblock *)NULL; } /* Destroy NMG */ nmg_km(nmg_model); break; } } --drawtrees_depth; if (dgcdp.fastpath_count) { bu_log("%d region%s rendered through polygon fastpath\n", dgcdp.fastpath_count, dgcdp.fastpath_count == 1 ? "" : "s"); } if (ret < 0) return -1; return 0; /* OK */ }
int main(int argc, char **argv) { int c; double percent; int i; bu_setprogname(argv[0]); bu_setlinebuf(stderr); RTG.debug = 0; 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 = BN_TOL_DIST; 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 */ /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "a:n:o:r:vx:D:P:X:e:ih?")) != -1) { switch (c) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi(bu_optarg); break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'D': tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; rt_pr_tol(&tol); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); NMG_debug = RTG.NMG_debug; break; case 'e': /* Error file name. */ error_file = bu_optarg; break; case 'i': inches = 1; break; default: usage(argv[0]); } } if (bu_optind+1 >= argc) usage(argv[0]); if (!output_file) { fp = stdout; setmode(fileno(fp), O_BINARY); } else { /* Open output file */ if ((fp=fopen(output_file, "wb+")) == NULL) { perror(argv[0]); bu_exit(1, "Cannot open output file (%s) for writing\n", output_file); } } /* Open g-acad error log file */ if (!error_file) { fpe = stderr; setmode(fileno(fpe), O_BINARY); } else if ((fpe=fopen(error_file, "wb")) == NULL) { perror(argv[0]); bu_exit(1, "Cannot open output file (%s) for writing\n", error_file); } /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open geometry database file (%s)\n", argv[0]); } if (db_dirbuild(dbip)) { bu_exit(1, "db_dirbuild failed\n"); } BN_CK_TOL(tree_state.ts_tol); RT_CK_TESS_TOL(tree_state.ts_ttol); fprintf(fpe, "Model: %s\n", argv[0]); fprintf(fpe, "Objects:"); for (i=1; i<argc; i++) fprintf(fpe, " %s", argv[i]); fprintf(fpe, "\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n", tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm); fprintf(fpe, "Calculational tolerances:\n\tdist = %g mm perp = %g\n", tree_state.ts_tol->dist, tree_state.ts_tol->perp); bu_log("Model: %s\n", argv[0]); bu_log("Objects:"); for (i=1; i<argc; i++) bu_log(" %s", argv[i]); bu_log("\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n", tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm); bu_log("Calculational tolerances:\n\tdist = %g mm perp = %g\n", tree_state.ts_tol->dist, tree_state.ts_tol->perp); /* Write out ACAD facet header */ if (inches) fprintf(fp, "BRL-CAD generated ACAD FACET FILE (Units in)\n"); else fprintf(fp, "BRL-CAD generated ACAD FACET FILE (Units mm)\n"); /* Generate space for number of facet entities, will write over later */ fprintf(fp, " "); /* Walk indicated tree(s). Each region will be output separately */ (void) db_walk_tree(dbip, argc-1, (const char **)(argv+1), 1, /* ncpu */ &tree_state, 0, /* take all regions */ do_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ percent = 0; if (regions_tried>0) { percent = ((double)regions_converted * 100) / regions_tried; printf("Tried %d regions, %d converted to NMG's successfully. %g%%\n", regions_tried, regions_converted, percent); } percent = 0; if (regions_tried > 0) { percent = ((double)regions_written * 100) / regions_tried; printf(" %d triangulated successfully. %g%%\n", regions_written, percent); } bu_log("%ld triangles written\n", tot_polygons); fprintf(fpe, "%ld triangles written\n", tot_polygons); /* Write out number of facet entities to .facet file */ rewind(fp); bu_fseek(fp, 46, 0); /* Re-position pointer to 2nd line */ fprintf(fp, "%d\n", regions_written); /* Write out number of regions */ fclose(fp); /* Release dynamic storage */ nmg_km(the_model); rt_vlist_cleanup(); db_close(dbip); return 0; }
/** * This is the gist for what is going on (not verified): * * 1. initialize tree_state (db_tree_state) * 2. Deal with command line arguments. Strip off everything but regions for processing. * 3. Open geometry (.g) file and build directory db_dirbuild * 4. db_walk_tree (get_layer) for layer names only * 5. Initialize tree_state * 6. Initialize model (nmg)\ * 7. db_walk_tree (gcv_region_end) * 8. Cleanup */ int main(int argc, char *argv[]) { int c; double percent; bu_setlinebuf(stderr); tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; tree_state.ts_m = &the_model; /* Set up tessellation tolerance defaults */ ttol.magic = RT_TESS_TOL_MAGIC; /* Defaults, updated by command line options. */ ttol.abs = 0.0; ttol.rel = 0.01; ttol.norm = 0.0; /* Set up calculation tolerance defaults */ /* 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; /* init resources we might need */ rt_init_resource(&rt_uniresource, 0, NULL); BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "a:n:o:pr:vx:D:P:X:ih?")) != -1) { switch (c) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'p': polyface_mesh = 1; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi(bu_optarg); break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'D': tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; rt_pr_tol(&tol); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); NMG_debug = RTG.NMG_debug; break; case 'i': inches = 1; break; default: usage(argv[0]); bu_exit(1, "%s\n", brlcad_ident("BRL-CAD to DXF Exporter")); break; } } if (bu_optind+1 >= argc) { usage(argv[0]); bu_exit(1, "%s\n", brlcad_ident("BRL-CAD to DXF Exporter")); } if (!output_file) { fp = stdout; setmode(fileno(fp), O_BINARY); } else { /* Open output file */ if ((fp=fopen(output_file, "w+b")) == NULL) { perror(argv[0]); bu_exit(1, " Cannot open output file (%s) for writing\n", output_file); } } /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Unable to open geometry database file (%s)\n", argv[0]); } if (db_dirbuild(dbip)) { bu_exit(1, "db_dirbuild failed\n"); } BN_CK_TOL(tree_state.ts_tol); RT_CK_TESS_TOL(tree_state.ts_ttol); if (verbose) { int i; bu_log("Model: %s\n", argv[0]); bu_log("Objects:"); for (i = 1; i < argc; i++) bu_log(" %s", argv[i]); bu_log("\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n", tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm); bu_log("Calculational tolerances:\n\tdist = %g mm perp = %g\n", tree_state.ts_tol->dist, tree_state.ts_tol->perp); } /* output DXF header and start of TABLES section */ fprintf(fp, "0\nSECTION\n2\nHEADER\n999\n%s\n0\nENDSEC\n0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n", argv[argc-1]); /* Walk indicated tree(s) just for layer names to put in TABLES section */ (void)db_walk_tree(dbip, argc-1, (const char **)(argv+1), 1, /* ncpu */ &tree_state, 0, /* take all regions */ get_layer, NULL, (void *)NULL); /* in librt/nmg_bool.c */ /* end of layers section, start of ENTITIES SECTION */ fprintf(fp, "0\nENDTAB\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n"); /* Walk indicated tree(s). Each region will be output separately */ tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; /* make empty NMG model */ the_model = nmg_mm(); tree_state.ts_m = &the_model; (void) db_walk_tree(dbip, argc-1, (const char **)(argv+1), 1, /* ncpu */ &tree_state, 0, /* take all regions */ gcv_region_end, nmg_booltree_leaf_tess, (void *)&gcvwriter); /* callback for gcv_region_end */ percent = 0; if (regions_tried>0) { percent = ((double)regions_converted * 100) / regions_tried; if (verbose) bu_log("Tried %d regions, %d converted to NMG's successfully. %g%%\n", regions_tried, regions_converted, percent); } percent = 0; if (regions_tried > 0) { percent = ((double)regions_written * 100) / regions_tried; if (verbose) bu_log(" %d triangulated successfully. %g%%\n", regions_written, percent); } bu_log("%ld triangles written\n", (long int)tot_polygons); fprintf(fp, "0\nENDSEC\n0\nEOF\n"); if (output_file) { fclose(fp); } /* Release dynamic storage */ nmg_km(the_model); rt_vlist_cleanup(); db_close(dbip); return 0; }
int ged_bev(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "[P|t] new_obj obj1 op obj2 op obj3 ..."; int i; int c; int ncpu; char *cmdname; char *newname; struct rt_db_internal intern; struct directory *dp; char op; int failed; /* static due to longjmp */ static int triangulate = 0; static union tree *tmp_tree = NULL; 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; } cmdname = (char *)argv[0]; /* Establish tolerances */ gedp->ged_wdbp->wdb_initial_tree_state.ts_ttol = &gedp->ged_wdbp->wdb_ttol; gedp->ged_wdbp->wdb_initial_tree_state.ts_tol = &gedp->ged_wdbp->wdb_tol; gedp->ged_wdbp->wdb_ttol.magic = RT_TESS_TOL_MAGIC; /* Initial values for options, must be reset each time */ ncpu = 1; triangulate = 0; /* Parse options. */ bu_optind = 1; /* re-init bu_getopt() */ while ((c=bu_getopt(argc, (char * const *)argv, "tP:")) != -1) { switch (c) { case 'P': #if 0 /* not yet supported */ ncpu = atoi(bu_optarg); #endif break; case 't': triangulate = 1; break; default: { bu_vls_printf(gedp->ged_result_str, "%s: option '%c' unknown\n", cmdname, c); } break; } } argc -= bu_optind; argv += bu_optind; newname = (char *)argv[0]; argv++; argc--; if (argc < 1) { bu_vls_printf(gedp->ged_result_str, "%s: Nothing to evaluate!!!\n", cmdname); return GED_ERROR; } GED_CHECK_EXISTS(gedp, newname, LOOKUP_QUIET, GED_ERROR); bu_vls_printf(gedp->ged_result_str, "%s: tessellating primitives with tolerances a=%g, r=%g, n=%g\n", argv[0], gedp->ged_wdbp->wdb_ttol.abs, gedp->ged_wdbp->wdb_ttol.rel, gedp->ged_wdbp->wdb_ttol.norm); bev_facetize_tree = (union tree *)0; bev_nmg_model = nmg_mm(); gedp->ged_wdbp->wdb_initial_tree_state.ts_m = &bev_nmg_model; op = ' '; tmp_tree = (union tree *)NULL; while (argc) { i = db_walk_tree(gedp->ged_wdbp->dbip, 1, (const char **)argv, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, 0, /* take all regions */ bev_facetize_region_end, nmg_booltree_leaf_tess, (genptr_t)gedp); if (i < 0) { bu_vls_printf(gedp->ged_result_str, "%s: error in db_walk_tree()\n", cmdname); /* Destroy NMG */ nmg_km(bev_nmg_model); return GED_ERROR; } argc--; argv++; if (tmp_tree && op != ' ') { union tree *new_tree; BU_ALLOC(new_tree, union tree); RT_TREE_INIT(new_tree); new_tree->tr_b.tb_regionp = REGION_NULL; new_tree->tr_b.tb_left = tmp_tree; new_tree->tr_b.tb_right = bev_facetize_tree; switch (op) { case 'u': case 'U': new_tree->tr_op = OP_UNION; break; case '-': new_tree->tr_op = OP_SUBTRACT; break; case '+': new_tree->tr_op = OP_INTERSECT; break; default: { bu_vls_printf(gedp->ged_result_str, "%s: Unrecognized operator: (%c)\nAborting\n", argv[0], op); db_free_tree(bev_facetize_tree, &rt_uniresource); nmg_km(bev_nmg_model); return GED_ERROR; } } tmp_tree = new_tree; bev_facetize_tree = (union tree *)NULL; } else if (!tmp_tree && op == ' ') { /* just starting out */ tmp_tree = bev_facetize_tree; bev_facetize_tree = (union tree *)NULL; } if (argc) { op = *argv[0]; argc--; argv++; } else op = ' '; } if (tmp_tree) { /* Now, evaluate the boolean tree into ONE region */ bu_vls_printf(gedp->ged_result_str, "%s: evaluating boolean expressions\n", cmdname); if (BU_SETJUMP) { BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Boolean evaluation failed!!!\n", cmdname); if (tmp_tree) db_free_tree(tmp_tree, &rt_uniresource); tmp_tree = (union tree *)NULL; nmg_km(bev_nmg_model); bev_nmg_model = (struct model *)NULL; return GED_ERROR; } failed = nmg_boolean(tmp_tree, bev_nmg_model, &gedp->ged_wdbp->wdb_tol, &rt_uniresource); BU_UNSETJUMP; } else failed = 1; if (failed) { bu_vls_printf(gedp->ged_result_str, "%s: no resulting region, aborting\n", cmdname); if (tmp_tree) db_free_tree(tmp_tree, &rt_uniresource); tmp_tree = (union tree *)NULL; nmg_km(bev_nmg_model); bev_nmg_model = (struct model *)NULL; return GED_ERROR; } /* New region remains part of this nmg "model" */ NMG_CK_REGION(tmp_tree->tr_d.td_r); bu_vls_printf(gedp->ged_result_str, "%s: facetize %s\n", cmdname, tmp_tree->tr_d.td_name); nmg_vmodel(bev_nmg_model); /* Triangulate model, if requested */ if (triangulate) { bu_vls_printf(gedp->ged_result_str, "%s: triangulating resulting object\n", cmdname); if (BU_SETJUMP) { BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Triangulation failed!!!\n", cmdname); if (tmp_tree) db_free_tree(tmp_tree, &rt_uniresource); tmp_tree = (union tree *)NULL; nmg_km(bev_nmg_model); bev_nmg_model = (struct model *)NULL; return GED_ERROR; } nmg_triangulate_model(bev_nmg_model, &gedp->ged_wdbp->wdb_tol); BU_UNSETJUMP; } bu_vls_printf(gedp->ged_result_str, "%s: converting NMG to database format\n", cmdname); /* 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 = &rt_functab[ID_NMG]; intern.idb_ptr = (genptr_t)bev_nmg_model; bev_nmg_model = (struct model *)NULL; GED_DB_DIRADD(gedp, dp, newname, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (genptr_t)&intern.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); tmp_tree->tr_d.td_r = (struct nmgregion *)NULL; /* Free boolean tree, and the regions in it. */ db_free_tree(tmp_tree, &rt_uniresource); return GED_OK; }
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; }
int main(int argc, char **argv) { int c; double percent; bu_setprogname(argv[0]); bu_setlinebuf(stderr); tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; tree_state.ts_m = &the_model; /* Set up tessellation tolerance defaults */ ttol.magic = RT_TESS_TOL_MAGIC; /* Defaults, updated by command line options. */ ttol.abs = 0.0; ttol.rel = 0.01; ttol.norm = 0.0; /* Set up calculation tolerance defaults */ /* 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; /* init resources we might need */ rt_init_resource(&rt_uniresource, 0, NULL); /* make empty NMG model */ the_model = nmg_mm(); /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "r:a:n:o:vx:D:X:h?")) != -1) { switch (c) { case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name. */ /* grab output file name */ break; case 'v': verbose++; break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'D': tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; rt_pr_tol(&tol); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); NMG_debug = RTG.NMG_debug; break; default: bu_exit(1, usage, argv[0]); } } if (bu_optind+1 >= argc) bu_exit(1, usage, argv[0]); /* Open output file */ /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "ERROR: Unable to open geometry database file (%s)\n", argv[0]); } if (db_dirbuild(dbip)) bu_exit(1, "db_dirbuild failed\n"); BN_CK_TOL(tree_state.ts_tol); RT_CK_TESS_TOL(tree_state.ts_ttol); if (verbose) { int i; bu_log("Model: %s\n", argv[0]); bu_log("Objects:"); for (i = 1; i < argc; i++) bu_log(" %s", argv[i]); bu_log("\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n", tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm); bu_log("Calculational tolerances:\n\tdist = %g mm perp = %g\n", tree_state.ts_tol->dist, tree_state.ts_tol->perp); } /* Walk indicated tree(s). Each region will be output separately */ (void) db_walk_tree(dbip, argc-1, (const char **)(argv+1), 1, /* ncpu */ &tree_state, 0, /* take all regions */ do_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ percent = 0; if (regions_tried>0) { percent = ((double)regions_converted * 100) / regions_tried; bu_log("Tried %d regions, %d converted to NMG's successfully. %g%%\n", regions_tried, regions_converted, percent); } percent = 0; if (regions_tried > 0) { percent = ((double)regions_written * 100) / regions_tried; bu_log(" %d triangulated successfully. %g%%\n", regions_written, percent); } bu_log("%zd triangles written\n", tot_polygons); bu_log("Tessellation parameters used:\n"); bu_log(" abs [-a] %g\n", ttol.abs); bu_log(" rel [-r] %g\n", ttol.rel); bu_log(" norm [-n] %g\n", ttol.norm); bu_log(" dist [-D] %g\n", tol.dist); /* Release dynamic storage */ nmg_km(the_model); rt_vlist_cleanup(); db_close(dbip); return 0; }
/** * R T _ G E T T R E E S _ M U V E S * * User-called function to add a set of tree hierarchies to the active * set. Includes getting the indicated list of attributes and a * Tcl_HashTable for use with the ORCA man regions. (stashed in the * rt_i structure). * * This function may run in parallel, but is not multiply re-entrant * itself, because db_walk_tree() isn't multiply re-entrant. * * Semaphores used for critical sections in parallel mode: * RT_SEM_TREE* protects rti_solidheads[] lists, d_uses(solids) * RT_SEM_RESULTS protects HeadRegion, mdl_min/max, d_uses(reg), nregions * RT_SEM_WORKER (db_walk_dispatcher, from db_walk_tree) * RT_SEM_STATS nsolids * * INPUTS * rtip - RT instance pointer * attrs - array of pointers (NULL terminated) to strings (attribute names). A corresponding * array of "bu_mro" objects containing the attribute values will be attached to region * structures ("attr_values") * argc - number of trees to get * argv - array of char pointers to the names of the tree tops * ncpus - number of cpus to use * * Returns - * 0 Ordinarily * -1 On major error */ int rt_gettrees_muves(struct rt_i *rtip, const char **attrs, int argc, const char **argv, int ncpus) { register struct soltab *stp; register struct region *regp; Tcl_HashTable *tbl; int prev_sol_count; int i; int num_attrs=0; point_t region_min, region_max; RT_CHECK_RTI(rtip); RT_CK_DBI(rtip->rti_dbip); if (!rtip->needprep) { bu_log("ERROR: rt_gettree() called again after rt_prep!\n"); return(-1); /* FAIL */ } if ( argc <= 0 ) return(-1); /* FAIL */ tbl = (Tcl_HashTable *)bu_malloc( sizeof( Tcl_HashTable ), "rtip->Orca_hash_tbl" ); Tcl_InitHashTable( tbl, TCL_ONE_WORD_KEYS ); rtip->Orca_hash_tbl = (genptr_t)tbl; prev_sol_count = rtip->nsolids; { struct db_tree_state tree_state; tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_dbip = rtip->rti_dbip; tree_state.ts_rtip = rtip; tree_state.ts_resp = NULL; /* sanity. Needs to be updated */ if ( attrs ) { if ( rtip->rti_dbip->dbi_version < 5 ) { bu_log( "WARNING: requesting attributes from an old database version (ignored)\n" ); bu_avs_init_empty( &tree_state.ts_attrs ); } else { while ( attrs[num_attrs] ) { num_attrs++; } if ( num_attrs ) { bu_avs_init( &tree_state.ts_attrs, num_attrs, "avs in tree_state" ); num_attrs = 0; while ( attrs[num_attrs] ) { bu_avs_add( &tree_state.ts_attrs, attrs[num_attrs], NULL ); num_attrs++; } } else { bu_avs_init_empty( &tree_state.ts_attrs ); } } } else { bu_avs_init_empty( &tree_state.ts_attrs ); } /* ifdef this out for now, it is only using memory. perhaps a * better way of initiating ORCA stuff can be found. */ #if 0 bu_avs_add( &tree_state.ts_attrs, "ORCA_Comp", (char *)NULL ); #endif i = db_walk_tree( rtip->rti_dbip, argc, argv, ncpus, &tree_state, rt_gettree_region_start, rt_gettree_region_end, rt_gettree_leaf, (genptr_t)tbl ); bu_avs_free( &tree_state.ts_attrs ); } /* DEBUG: Ensure that all region trees are valid */ for ( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) ) { RT_CK_REGION(regp); db_ck_tree(regp->reg_treetop); } /* * Eliminate any "dead" solids that parallel code couldn't change. * First remove any references from the region tree, then remove * actual soltab structs from the soltab list. */ for ( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) ) { RT_CK_REGION(regp); rt_tree_kill_dead_solid_refs( regp->reg_treetop ); (void)rt_tree_elim_nops( regp->reg_treetop, &rt_uniresource ); } again: RT_VISIT_ALL_SOLTABS_START( stp, rtip ) { RT_CK_SOLTAB(stp); if ( stp->st_aradius <= 0 ) { bu_log("rt_gettrees() cleaning up dead solid '%s'\n", stp->st_dp->d_namep ); rt_free_soltab(stp); /* Can't do rtip->nsolids--, that doubles as max bit number! */ /* The macro makes it hard to regain place, punt */ goto again; } } RT_VISIT_ALL_SOLTABS_END