int main(int argc, char **argv) { struct directory *dp; if (argc != 3 && argc != 4) { bu_exit(1, "Usage:\n\t%s [-v] input.g output.g\n", argv[0]); } if (argc == 4) { if (BU_STR_EQUAL(argv[1], "-v")) verbose = 1; else { bu_log("Illegal option: %s\n", argv[1]); bu_exit(1, "Usage:\n\t%s [-v] input.g output.g\n", argv[0]); } } rt_init_resource(&rt_uniresource, 0, NULL); dbip = db_open(argv[argc-2], DB_OPEN_READONLY); if (dbip == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open geometry database file (%s)\n", argv[argc-2]); } if ((fdout=wdb_fopen(argv[argc-1])) == NULL) { perror(argv[0]); bu_exit(1, "Cannot open file (%s)\n", argv[argc-1]); } if (db_dirbuild(dbip)) { bu_exit(1, "db_dirbuild failed\n"); } /* Visit all records in input database, and spew them out, * modifying NMG objects into BoTs. */ FOR_ALL_DIRECTORY_START(dp, dbip) { struct rt_db_internal intern; int id; int ret; id = rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource); if (id < 0) { fprintf(stderr, "%s: rt_db_get_internal(%s) failure, skipping\n", argv[0], dp->d_namep); continue; } if (id == ID_NMG) { nmg_conv(&intern, dp->d_namep); } else { ret = wdb_put_internal(fdout, dp->d_namep, &intern, 1.0); if (ret < 0) { fprintf(stderr, "%s: wdb_put_internal(%s) failure, skipping\n", argv[0], dp->d_namep); rt_db_free_internal(&intern); continue; } } rt_db_free_internal(&intern); } FOR_ALL_DIRECTORY_END wdb_close(fdout); return 0; }
/* * M A I N */ 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 = 0.0005; 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; } rt_init_resource( &rt_uniresource, 0, NULL ); BU_LIST_INIT( &rt_g.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:")) != -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)*bn_pi/180.0; 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': rt_g.debug = 1; 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; 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: bu_exit(1, usage, argv[0]); break; } } if (bu_optind+1 >= argc) { bu_exit(1, usage, argv[0]); } if ( !units ) units = "mm"; /* Open BRL-CAD database */ if ((dbip = db_open( argv[bu_optind], "r")) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open %s\n", argv[bu_optind] ); } if ( db_dirbuild( dbip ) ) { bu_exit(1, "db_dirbuild() failed!\n" ); } if (out_file == NULL) { outfp = stdout; #if defined(_WIN32) && !defined(__CYGWIN__) setmode(fileno(outfp), O_BINARY); #endif } 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]), 1, /* ncpu */ &tree_state, select_lights, do_region_end, leaf_tess, (genptr_t)&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]), 1, /* ncpu */ &tree_state, select_non_lights, do_region_end, leaf_tess, (genptr_t)&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 opt; size_t i; const char *argv0 = argv[0]; struct rt_wdb *fd_out; struct bu_vls vls_in = BU_VLS_INIT_ZERO; struct bu_vls vls_out = BU_VLS_INIT_ZERO; int opt_debug = 0; int opt_verbose = 0; /* shapelib vars */ SHPHandle shapefile; size_t shp_num_invalid = 0; int shp_num_entities = 0; int shp_type = 0; /* intentionally double for scan */ double shp_min[4] = HINIT_ZERO; double shp_max[4] = HINIT_ZERO; /* geometry */ point2d_t *verts = NULL; size_t num_verts = 0; if (argc < 2) { usage(argv0); bu_exit(1, NULL); } while ((opt = bu_getopt(argc, argv, "dxv")) != -1) { switch (opt) { case 'd': opt_debug = 1; break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *) &RTG.debug); bu_printb("librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT); bu_log("\n"); break; case 'v': opt_verbose++; break; default: usage(argv0); bu_exit(1, NULL); break; } } argv += bu_optind; argc -= bu_optind; if (opt_verbose) bu_log("Verbose output enabled.\n"); if (opt_debug) bu_log("Debugging output enabled.\n"); /* validate input/output file specifiers */ if (argc < 1) { usage(argv0); bu_exit(1, "ERROR: Missing input and output file names\n"); } bu_vls_strcat(&vls_in, argv[0]); if (argc < 2) { bu_vls_printf(&vls_out, "%s.g", argv[0]); } else { bu_vls_strcat(&vls_out, argv[1]); } if (opt_verbose) { bu_log("Reading from [%s]\n", bu_vls_addr(&vls_in)); bu_log("Writing to [%s]\n\n", bu_vls_addr(&vls_out)); } /* initialize single threaded resource */ rt_init_resource(&rt_uniresource, 0, NULL); /* open the input */ shapefile = SHPOpen(bu_vls_addr(&vls_in), "rb"); if (!shapefile) { bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_in)); bu_vls_free(&vls_in); bu_vls_free(&vls_out); bu_exit(4, NULL); } /* print shapefile details */ if (opt_verbose) { SHPGetInfo(shapefile, &shp_num_entities, &shp_type, shp_min, shp_max); bu_log("Shapefile Type: %s\n", SHPTypeName(shp_type)); bu_log("# of Shapes: %d\n\n", shp_num_entities); bu_log("File Bounds: (%12.3f,%12.3f, %.3g, %.3g)\n" " to (%12.3f,%12.3f, %.3g, %.3g)\n", shp_min[0], shp_min[1], shp_min[2], shp_min[3], shp_max[0], shp_max[1], shp_max[2], shp_max[3]); } /* open the .g for writing */ if ((fd_out = wdb_fopen(bu_vls_addr(&vls_out))) == NULL) { bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_out)); bu_vls_free(&vls_in); bu_vls_free(&vls_out); perror(argv0); bu_exit(5, NULL); } /* iterate over all entities */ for (i=0; i < (size_t)shp_num_entities; i++) { SHPObject *object; int shp_part; size_t j; object = SHPReadObject(shapefile, i); if (!object) { if (opt_debug) bu_log("Shape %zu of %zu is missing, skipping.\n", i+1, (size_t)shp_num_entities); continue; } /* validate the object */ if (opt_debug) { int shp_altered = SHPRewindObject(shapefile, object); if (shp_altered > 0) { bu_log("WARNING: Shape %zu of %zu has [%d] bad loop orientations.\n", i+1, (size_t)shp_num_entities, shp_altered); shp_num_invalid++; } } /* print detail header */ if (opt_verbose) { if (object->bMeasureIsUsed) { bu_log("\nShape:%zu (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g, %g)\n" " to (%12.3f,%12.3f, %g, %g)\n", i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts, object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin, object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax); } else { bu_log("\nShape:%zu (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g)\n" " to (%12.3f,%12.3f, %g)\n", i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts, object->dfXMin, object->dfYMin, object->dfZMin, object->dfXMax, object->dfYMax, object->dfZMax); } if (object->nParts > 0 && object->panPartStart[0] != 0) { if (opt_debug) bu_log("Shape %zu of %zu: panPartStart[0] = %d, not zero as expected.\n", i+1, (size_t)shp_num_entities, object->panPartStart[0]); continue; } } num_verts = 0; verts = (point2d_t *)bu_calloc((size_t)object->nVertices, sizeof(point2d_t), "alloc point array"); for (j = 0, shp_part = 1; j < (size_t)object->nVertices; j++) { if (shp_part < object->nParts && j == (size_t)object->panPartStart[shp_part]) { shp_part++; bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities); make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts); /* reset for next loop */ memset(verts, 0, sizeof(point2d_t) * object->nVertices); num_verts = 0; } bu_log("%zu/%zu:%zu/%zu\t\t", i+1, (size_t)shp_num_entities, j+1, (size_t)object->nVertices); bu_log("(%12.4f, %12.4f, %12.4f, %g)\n", object->padfX[j], object->padfY[j], object->padfZ[j], object->padfM[j]); V2SET(verts[num_verts], object->padfX[j], object->padfY[j]); num_verts++; } bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities); make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts); bu_free(verts, "free point array"); verts = NULL; num_verts = 0; SHPDestroyObject(object); object = NULL; } if (opt_verbose) { if (shp_num_invalid > 0) { bu_log("WARNING: %zu of %zu shape(s) had bad loop orientations.\n", shp_num_invalid, (size_t)shp_num_entities); } bu_log("\nDone.\n"); } /* close up our files */ SHPClose(shapefile); wdb_close(fd_out); /* free up allocated resources */ bu_vls_free(&vls_in); bu_vls_free(&vls_out); return 0; }
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; }
/* 0 = no difference within tolerance, 1 = difference >= tolerance */ int analyze_raydiff(/* TODO - decide what to return. Probably some sort of left, common, right segment sets. See what rtcheck does... */ struct db_i *dbip, const char *obj1, const char *obj2, struct bn_tol *tol) { int ret; int count = 0; struct rt_i *rtip; int ncpus = bu_avail_cpus(); point_t min, mid, max; struct rt_pattern_data *xdata, *ydata, *zdata; fastf_t *rays; struct raydiff_container *state; if (!dbip || !obj1 || !obj2 || !tol) return 0; rtip = rt_new_rti(dbip); if (rt_gettree(rtip, obj1) < 0) return -1; if (rt_gettree(rtip, obj2) < 0) return -1; rt_prep_parallel(rtip, 1); /* Now we've got the bounding box - set up the grids */ VMOVE(min, rtip->mdl_min); VMOVE(max, rtip->mdl_max); VSET(mid, (max[0] - min[0])/2, (max[1] - min[1])/2, (max[2] - min[2])/2); BU_GET(xdata, struct rt_pattern_data); VSET(xdata->center_pt, min[0] - 0.1 * min[0], mid[1], mid[2]); VSET(xdata->center_dir, 1, 0, 0); xdata->vn = 2; xdata->pn = 2; xdata->n_vec = (vect_t *)bu_calloc(xdata->vn + 1, sizeof(vect_t), "vects array"); xdata->n_p = (fastf_t *)bu_calloc(xdata->pn + 1, sizeof(fastf_t), "params array"); xdata->n_p[0] = 50; /* TODO - get tolerances from caller */ xdata->n_p[1] = 50; VSET(xdata->n_vec[0], 0, max[1], 0); VSET(xdata->n_vec[1], 0, 0, max[2]); ret = rt_pattern(xdata, RT_PATTERN_RECT_ORTHOGRID); bu_free(xdata->n_vec, "x vec inputs"); bu_free(xdata->n_p, "x p inputs"); if (ret < 0) return -1; BU_GET(ydata, struct rt_pattern_data); VSET(ydata->center_pt, mid[0], min[1] - 0.1 * min[1], mid[2]); VSET(ydata->center_dir, 0, 1, 0); ydata->vn = 2; ydata->pn = 2; ydata->n_vec = (vect_t *)bu_calloc(ydata->vn + 1, sizeof(vect_t), "vects array"); ydata->n_p = (fastf_t *)bu_calloc(ydata->pn + 1, sizeof(fastf_t), "params array"); ydata->n_p[0] = 50; /* TODO - get tolerances from caller */ ydata->n_p[1] = 50; VSET(ydata->n_vec[0], max[0], 0, 0); VSET(ydata->n_vec[1], 0, 0, max[2]); ret = rt_pattern(ydata, RT_PATTERN_RECT_ORTHOGRID); bu_free(ydata->n_vec, "y vec inputs"); bu_free(ydata->n_p, "y p inputs"); if (ret < 0) return -1; BU_GET(zdata, struct rt_pattern_data); VSET(zdata->center_pt, mid[0], mid[1], min[2] - 0.1 * min[2]); VSET(zdata->center_dir, 0, 0, 1); zdata->vn = 2; zdata->pn = 2; zdata->n_vec = (vect_t *)bu_calloc(zdata->vn + 1, sizeof(vect_t), "vects array"); zdata->n_p = (fastf_t *)bu_calloc(zdata->pn + 1, sizeof(fastf_t), "params array"); zdata->n_p[0] = 50; /* TODO - get tolerances from caller */ zdata->n_p[1] = 50; VSET(zdata->n_vec[0], max[0], 0, 0); VSET(zdata->n_vec[1], 0, max[1], 0); ret = rt_pattern(zdata, RT_PATTERN_RECT_ORTHOGRID); bu_free(zdata->n_vec, "x vec inputs"); bu_free(zdata->n_p, "x p inputs"); if (ret < 0) return -1; /* Consolidate the grids into a single ray array */ { size_t i, j; rays = (fastf_t *)bu_calloc((xdata->ray_cnt + ydata->ray_cnt + zdata->ray_cnt + 1) * 6, sizeof(fastf_t), "rays"); count = 0; for (i = 0; i < xdata->ray_cnt; i++) { for (j = 0; j < 6; j++) { rays[6*count+j] = xdata->rays[6*i + j]; } count++; } for (i = 0; i < ydata->ray_cnt; i++) { for (j = 0; j < 6; j++) { rays[6*count+j] = ydata->rays[6*i + j]; } count++; } for (i = 0; i < zdata->ray_cnt; i++) { for (j = 0; j < 6; j++) { rays[6*count+j] = zdata->rays[6*i+j]; } count++; } } bu_free(xdata->rays, "x rays"); bu_free(ydata->rays, "y rays"); bu_free(zdata->rays, "z rays"); BU_PUT(xdata, struct rt_pattern_data); BU_PUT(ydata, struct rt_pattern_data); BU_PUT(zdata, struct rt_pattern_data); bu_log("ray cnt: %d\n", count); { int i, j; ncpus = 2; state = (struct raydiff_container *)bu_calloc(ncpus+1, sizeof(struct raydiff_container), "resources"); for (i = 0; i < ncpus+1; i++) { state[i].rtip = rtip; state[i].tol = 0.5; state[i].ncpus = ncpus; state[i].left_name = bu_strdup(obj1); state[i].right_name = bu_strdup(obj2); BU_GET(state[i].resp, struct resource); rt_init_resource(state[i].resp, i, state->rtip); BU_GET(state[i].left, struct bu_ptbl); bu_ptbl_init(state[i].left, 64, "left solid hits"); BU_GET(state[i].both, struct bu_ptbl); bu_ptbl_init(state[i].both, 64, "hits on both solids"); BU_GET(state[i].right, struct bu_ptbl); bu_ptbl_init(state[i].right, 64, "right solid hits"); state[i].rays_cnt = count; state[i].rays = rays; } bu_parallel(raydiff_gen_worker, ncpus, (void *)state); /* Collect and print all of the results */ for (i = 0; i < ncpus+1; i++) { for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) { struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].left, j); bu_log("Result: LEFT diff vol (%s): %g %g %g -> %g %g %g\n", obj1, V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt)); } for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) { struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].both, j); bu_log("Result: BOTH): %g %g %g -> %g %g %g\n", V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt)); } for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) { struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].right, j); bu_log("Result: RIGHT diff vol (%s): %g %g %g -> %g %g %g\n", obj2, V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt)); } } /* Free results */ for (i = 0; i < ncpus+1; i++) { for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) { struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].left, j); BU_PUT(dseg, struct diff_seg); } bu_ptbl_free(state[i].left); BU_PUT(state[i].left, struct diff_seg); for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) { struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].both, j); BU_PUT(dseg, struct diff_seg); } bu_ptbl_free(state[i].both); BU_PUT(state[i].both, struct diff_seg); for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) { struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].right, j); BU_PUT(dseg, struct diff_seg); } bu_ptbl_free(state[i].right); BU_PUT(state[i].right, struct diff_seg); bu_free((void *)state[i].left_name, "left name"); bu_free((void *)state[i].right_name, "right name"); BU_PUT(state[i].resp, struct resource); } bu_free(state, "free state containers"); } return 0; }
/* * M A I N */ int main(int argc, char **argv) { struct rt_i *rtip = NULL; char *title_file = NULL, *title_obj = NULL; /* name of file and first object */ char idbuf[RT_BUFSIZE] = {0}; /* First ID record info */ void application_init(); struct bu_vls times; int i; #if defined(_WIN32) && !defined(__CYGWIN__) setmode(fileno(stdin), O_BINARY); setmode(fileno(stdout), O_BINARY); setmode(fileno(stderr), O_BINARY); #else bu_setlinebuf( stdout ); bu_setlinebuf( stderr ); #endif #ifdef HAVE_SBRK beginptr = (char *) sbrk(0); #endif azimuth = 35.0; /* GIFT defaults */ elevation = 25.0; AmbientIntensity=0.4; background[0] = background[1] = 0.0; background[2] = 1.0/255.0; /* slightly non-black */ /* Before option processing, get default number of processors */ npsw = bu_avail_cpus(); /* Use all that are present */ if ( npsw > MAX_PSW ) npsw = MAX_PSW; /* Before option processing, do application-specific initialization */ RT_APPLICATION_INIT( &ap ); application_init(); /* Process command line options */ if ( !get_args( argc, argv ) ) { (void)fputs(usage, stderr); return 1; } /* Identify the versions of the libraries we are using. */ if (rt_verbosity & VERBOSE_LIBVERSIONS) { (void)fprintf(stderr, "%s%s%s%s\n", brlcad_ident(title), rt_version(), bn_version(), bu_version() ); } #if defined(DEBUG) (void)fprintf(stderr, "Compile-time debug symbols are available\n"); #endif #if defined(NO_BOMBING_MACROS) || defined(NO_MAGIC_CHECKING) || defined(NO_BADRAY_CECHKING) || defined(NO_DEBUG_CHECKING) (void)fprintf(stderr, "WARNING: Run-time debugging is disabled and may enhance performance\n"); #endif /* Identify what host we're running on */ if (rt_verbosity & VERBOSE_LIBVERSIONS) { char hostname[512] = {0}; #ifndef _WIN32 if ( gethostname( hostname, sizeof(hostname) ) >= 0 && hostname[0] != '\0' ) (void)fprintf(stderr, "Running on %s\n", hostname); #else sprintf(hostname, "Microsoft Windows"); (void)fprintf(stderr, "Running on %s\n", hostname); #endif } if ( bu_optind >= argc ) { fprintf(stderr, "%s: MGED database not specified\n", argv[0]); (void)fputs(usage, stderr); return 1; } if (rpt_overlap) ap.a_logoverlap = ((void (*)())0); else ap.a_logoverlap = rt_silent_logoverlap; /* If user gave no sizing info at all, use 512 as default */ if ( width <= 0 && cell_width <= 0 ) width = 512; if ( height <= 0 && cell_height <= 0 ) height = 512; /* If user didn't provide an aspect ratio, use the image * dimensions ratio as a default. */ if (aspect <= 0.0) { aspect = (fastf_t)width / (fastf_t)height; } if ( sub_grid_mode ) { /* check that we have a legal subgrid */ if ( sub_xmax >= width || sub_ymax >= height ) { fprintf( stderr, "rt: illegal values for subgrid %d,%d,%d,%d\n", sub_xmin, sub_ymin, sub_xmax, sub_ymax ); fprintf( stderr, "\tFor a %d X %d image, the subgrid must be within 0, 0,%d,%d\n", width, height, width-1, height-1 ); return 1; } } if ( incr_mode ) { int x = height; if ( x < width ) x = width; incr_nlevel = 1; while ( (1<<incr_nlevel) < x ) incr_nlevel++; height = width = 1<<incr_nlevel; if (rt_verbosity & VERBOSE_INCREMENTAL) fprintf(stderr, "incremental resolution, nlevels = %d, width=%d\n", incr_nlevel, width); } /* * Handle parallel initialization, if applicable. */ #ifndef PARALLEL npsw = 1; /* force serial */ #endif if ( npsw < 0 ) { /* Negative number means "all but" npsw */ npsw = bu_avail_cpus() + npsw; } /* allow debug builds to go higher than the max */ if (!(bu_debug & BU_DEBUG_PARALLEL)) { if ( npsw > MAX_PSW ) { npsw = MAX_PSW; } } if (npsw > 1) { rt_g.rtg_parallel = 1; if (rt_verbosity & VERBOSE_MULTICPU) fprintf(stderr, "Planning to run with %d processors\n", npsw ); } else { rt_g.rtg_parallel = 0; } /* Initialize parallel processor support */ bu_semaphore_init( RT_SEM_LAST ); /* * Do not use bu_log() or bu_malloc() before this point! */ if ( bu_debug ) { bu_printb( "libbu bu_debug", bu_debug, BU_DEBUG_FORMAT ); bu_log("\n"); } if ( RT_G_DEBUG ) { bu_printb( "librt rt_g.debug", rt_g.debug, DEBUG_FORMAT ); bu_log("\n"); } if ( rdebug ) { bu_printb( "rt rdebug", rdebug, RDEBUG_FORMAT ); bu_log("\n"); } /* We need this to run rt_dirbuild */ rt_init_resource( &rt_uniresource, MAX_PSW, NULL ); bn_rand_init( rt_uniresource.re_randptr, 0 ); title_file = argv[bu_optind]; title_obj = argv[bu_optind+1]; nobjs = argc - bu_optind - 1; objtab = &(argv[bu_optind+1]); if ( nobjs <= 0 ) { bu_log("%s: no objects specified -- raytrace aborted\n", argv[0]); return 1; } /* Echo back the command line arugments as given, in 3 Tcl commands */ if (rt_verbosity & VERBOSE_MODELTITLE) { struct bu_vls str; bu_vls_init(&str); bu_vls_from_argv( &str, bu_optind, (const char **)argv ); bu_vls_strcat( &str, "\nopendb " ); bu_vls_strcat( &str, title_file ); bu_vls_strcat( &str, ";\ntree " ); bu_vls_from_argv( &str, nobjs <= 16 ? nobjs : 16, (const char **)argv+bu_optind+1 ); if ( nobjs > 16 ) bu_vls_strcat( &str, " ..."); else bu_vls_putc( &str, ';' ); bu_log("%s\n", bu_vls_addr(&str) ); bu_vls_free(&str); } /* Build directory of GED database */ bu_vls_init( × ); rt_prep_timer(); if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) { bu_log("rt: rt_dirbuild(%s) failure\n", title_file); return 2; } ap.a_rt_i = rtip; (void)rt_get_timer( ×, NULL ); if (rt_verbosity & VERBOSE_MODELTITLE) bu_log("db title: %s\n", idbuf); if (rt_verbosity & VERBOSE_STATS) bu_log("DIRBUILD: %s\n", bu_vls_addr(×) ); bu_vls_free( × ); memory_summary(); /* Copy values from command line options into rtip */ rtip->rti_space_partition = space_partition; rtip->rti_nugrid_dimlimit = nugrid_dimlimit; rtip->rti_nu_gfactor = nu_gfactor; rtip->useair = use_air; rtip->rti_save_overlaps = save_overlaps; if ( rt_dist_tol > 0 ) { rtip->rti_tol.dist = rt_dist_tol; rtip->rti_tol.dist_sq = rt_dist_tol * rt_dist_tol; } if ( rt_perp_tol > 0 ) { rtip->rti_tol.perp = rt_perp_tol; rtip->rti_tol.para = 1 - rt_perp_tol; } if (rt_verbosity & VERBOSE_TOLERANCE) rt_pr_tol( &rtip->rti_tol ); /* before view_init */ if ( outputfile && strcmp( outputfile, "-") == 0 ) outputfile = (char *)0; /* * Initialize application. * Note that width & height may not have been set yet, * since they may change from frame to frame. */ if ( view_init( &ap, title_file, title_obj, outputfile!=(char *)0, framebuffer!=(char *)0 ) != 0 ) { /* Framebuffer is desired */ register int xx, yy; int zoom; /* Ask for a fb big enough to hold the image, at least 512. */ /* This is so MGED-invoked "postage stamps" get zoomed up big enough to see */ xx = yy = 512; if ( width > xx || height > yy ) { xx = width; yy = height; } bu_semaphore_acquire( BU_SEM_SYSCALL ); fbp = fb_open( framebuffer, xx, yy ); bu_semaphore_release( BU_SEM_SYSCALL ); if ( fbp == FBIO_NULL ) { fprintf(stderr, "rt: can't open frame buffer\n"); return 12; } bu_semaphore_acquire( BU_SEM_SYSCALL ); /* If fb came out smaller than requested, do less work */ if ( fb_getwidth(fbp) < width ) width = fb_getwidth(fbp); if ( fb_getheight(fbp) < height ) height = fb_getheight(fbp); /* If the fb is lots bigger (>= 2X), zoom up & center */ if ( width > 0 && height > 0 ) { zoom = fb_getwidth(fbp)/width; if ( fb_getheight(fbp)/height < zoom ) zoom = fb_getheight(fbp)/height; } else { zoom = 1; } (void)fb_view( fbp, width/2, height/2, zoom, zoom ); bu_semaphore_release( BU_SEM_SYSCALL ); } if ( (outputfile == (char *)0) && (fbp == FBIO_NULL) ) { /* If not going to framebuffer, or to a file, then use stdout */ if ( outfp == NULL ) outfp = stdout; /* output_is_binary is changed by view_init, as appropriate */ if ( output_is_binary && isatty(fileno(outfp)) ) { fprintf(stderr, "rt: attempting to send binary output to terminal, aborting\n"); return 14; } } /* * Initialize all the per-CPU memory resources. * The number of processors can change at runtime, init them all. */ for ( i=0; i < MAX_PSW; i++ ) { rt_init_resource( &resource[i], i, rtip ); bn_rand_init( resource[i].re_randptr, i ); } memory_summary(); #ifdef SIGUSR1 (void)signal( SIGUSR1, siginfo_handler ); #endif #ifdef SIGINFO (void)signal( SIGINFO, siginfo_handler ); #endif if ( !matflag ) { int frame_retval; def_tree( rtip ); /* Load the default trees */ do_ae( azimuth, elevation ); frame_retval = do_frame( curframe ); if (frame_retval != 0) { /* Release the framebuffer, if any */ if ( fbp != FBIO_NULL ) { fb_close(fbp); } return 1; } } else if ( !isatty(fileno(stdin)) && old_way( stdin ) ) { ; /* All is done */ } else { register char *buf; register int ret; /* * New way - command driven. * Process sequence of input commands. * All the work happens in the functions * called by rt_do_cmd(). */ while ( (buf = rt_read_cmd( stdin )) != (char *)0 ) { if ( R_DEBUG&RDEBUG_PARSE ) fprintf(stderr, "cmd: %s\n", buf ); ret = rt_do_cmd( rtip, buf, rt_cmdtab ); bu_free( buf, "rt_read_cmd command buffer" ); if ( ret < 0 ) break; } if ( curframe < desiredframe ) { fprintf(stderr, "rt: Desired frame %d not reached, last was %d\n", desiredframe, curframe); } } /* Release the framebuffer, if any */ if (fbp != FBIO_NULL) { fb_close(fbp); } return(0); }
int main(int argc, char *argv[]) { struct rt_i *rtip = NULL; char db_title[TITLE_LEN+1];/* title from MGED file */ const char *tmp_str; extern char local_u_name[65]; extern double base2local; extern double local2base; FILE *fPtr; int Ch; /* Option name */ int mat_flag = 0; /* Read matrix from stdin? */ int use_of_air = 0; int print_ident_flag = 1; char ocastring[1024] = {0}; struct bu_list script_list; /* For -e and -f options */ struct script_rec *srp; extern outval ValTab[]; /* from if.c, callback functions for overlap, hit, and miss shots */ int if_overlap(struct application *, struct partition *, struct region *, struct region *, struct partition *); int if_hit(struct application *, struct partition *, struct seg *); int if_miss(struct application *); BU_LIST_INIT(&script_list); bu_setprogname(argv[0]); ocname[OVLP_RESOLVE] = "resolve"; ocname[OVLP_REBUILD_FASTGEN] = "rebuild_fastgen"; ocname[OVLP_REBUILD_ALL] = "rebuild_all"; ocname[OVLP_RETAIN] = "retain"; *ocastring = '\0'; bu_optind = 1; /* restart */ /* Handle command-line options */ while ((Ch = bu_getopt(argc, argv, OPT_STRING)) != -1) { if (bu_optopt == '?') Ch='h'; switch (Ch) { case 'A': attrib_add(bu_optarg, &need_prep); break; case 'B': rt_bot_minpieces = atoi(bu_optarg); break; case 'T': setenv("LIBRT_BOT_MINTIE", bu_optarg, 1); break; case 'b': do_backout = 1; break; case 'E': if (nirt_debug & DEBUG_SCRIPTS) show_scripts(&script_list, "before erasure"); while (BU_LIST_WHILE(srp, script_rec, &script_list)) { BU_LIST_DEQUEUE(&(srp->l)); free_script(srp); } if (nirt_debug & DEBUG_SCRIPTS) show_scripts(&script_list, "after erasure"); break; case 'e': enqueue_script(&script_list, READING_STRING, bu_optarg); if (nirt_debug & DEBUG_SCRIPTS) show_scripts(&script_list, "after enqueueing a literal"); break; case 'f': enqueue_script(&script_list, READING_FILE, bu_optarg); if (nirt_debug & DEBUG_SCRIPTS) show_scripts(&script_list, "after enqueueing a file name"); break; case 'L': listformats(); bu_exit(EXIT_SUCCESS, NULL); case 'M': mat_flag = 1; break; case 'O': sscanf(bu_optarg, "%1024s", ocastring); break; case 's': silent_flag = SILENT_YES; /* Positively yes */ break; case 'v': silent_flag = SILENT_NO; /* Positively no */ break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&nirt_debug); break; case 'u': if (sscanf(bu_optarg, "%d", &use_of_air) != 1) { (void) fprintf(stderr, "Illegal use-air specification: '%s'\n", bu_optarg); return 1; } break; case 'H': if (sscanf(bu_optarg, "%d", &print_ident_flag) != 1) { (void) fprintf(stderr, "Illegal header output option specified: '%s'\n", bu_optarg); return 1; } break; default: printusage(); bu_exit (Ch != 'h', NULL); } } /* end while getopt */ if (argc - bu_optind < 2) { printusage(); return 1; } if (isatty(0)) { if (silent_flag != SILENT_YES) silent_flag = SILENT_NO; } else { /* stdin is not a TTY */ if (silent_flag != SILENT_NO) silent_flag = SILENT_YES; } if (silent_flag != SILENT_YES && print_ident_flag) (void) fputs(brlcad_ident("Natalie's Interactive Ray Tracer"), stdout); if (use_of_air && (use_of_air != 1)) { fprintf(stderr, "Warning: useair=%d specified, will set to 1\n", use_of_air); use_of_air = 1; } switch (*ocastring) { case '\0': overlap_claims = OVLP_RESOLVE; break; case '0': case '1': case '2': case '3': if (ocastring[1] == '\0') { sscanf(ocastring, "%d", &overlap_claims); } else { fprintf(stderr, "Illegal overlap_claims specification: '%s'\n", ocastring); return 1; } break; case 'r': if (BU_STR_EQUAL(ocastring, "resolve")) overlap_claims = OVLP_RESOLVE; else if (BU_STR_EQUAL(ocastring, "rebuild_fastgen")) overlap_claims = OVLP_REBUILD_FASTGEN; else if (BU_STR_EQUAL(ocastring, "rebuild_all")) overlap_claims = OVLP_REBUILD_ALL; else if (BU_STR_EQUAL(ocastring, "retain")) overlap_claims = OVLP_RETAIN; else { fprintf(stderr, "Illegal overlap_claims specification: '%s'\n", ocastring); return 1; } break; default: fprintf(stderr, "Illegal overlap_claims specification: '%s'\n", ocastring); return 1; } db_name = argv[bu_optind]; /* build directory for target object */ if (silent_flag != SILENT_YES) { printf("Database file: '%s'\n", db_name); printf("Building the directory..."); } if ((rtip = rt_dirbuild(db_name, db_title, TITLE_LEN)) == RTI_NULL) { fflush(stdout); fprintf(stderr, "Could not load file %s\n", db_name); return 1; } rti_tab[use_of_air] = rtip; rti_tab[1 - use_of_air] = RTI_NULL; rtip->useair = use_of_air; rtip->rti_save_overlaps = (overlap_claims > 0); ++bu_optind; do_rt_gettrees(rtip, argv + bu_optind, argc - bu_optind, &need_prep); /* Initialize the table of resource structures */ rt_init_resource(&res_tab, 0, rtip); /* initialization of the application structure */ RT_APPLICATION_INIT(&ap); ap.a_hit = if_hit; /* branch to if_hit routine */ ap.a_miss = if_miss; /* branch to if_miss routine */ ap.a_overlap = if_overlap;/* branch to if_overlap routine */ ap.a_logoverlap = rt_silent_logoverlap; ap.a_onehit = 0; /* continue through shotline after hit */ ap.a_resource = &res_tab; ap.a_purpose = "NIRT ray"; ap.a_rt_i = rtip; /* rt_i pointer */ ap.a_zero1 = 0; /* sanity check, sayth raytrace.h */ ap.a_zero2 = 0; /* sanity check, sayth raytrace.h */ ap.a_uptr = (void *)a_tab.attrib; /* initialize variables */ azimuth() = 0.0; elevation() = 0.0; direct(X) = -1.0; direct(Y) = 0.0; direct(Z) = 0.0; grid(HORZ) = 0.0; grid(VERT) = 0.0; grid(DIST) = 0.0; grid2targ(); set_diameter(rtip); /* initialize the output specification */ default_ospec(); /* initialize NIRT's local units */ base2local = rtip->rti_dbip->dbi_base2local; local2base = rtip->rti_dbip->dbi_local2base; tmp_str = bu_units_string(local2base); if (tmp_str) { bu_strlcpy(local_u_name, tmp_str, sizeof(local_u_name)); } else { bu_strlcpy(local_u_name, "Unknown units", sizeof(local_u_name)); } if (silent_flag != SILENT_YES) { printf("Database title: '%s'\n", db_title); printf("Database units: '%s'\n", local_u_name); printf("model_min = (%g, %g, %g) model_max = (%g, %g, %g)\n", rtip->mdl_min[X] * base2local, rtip->mdl_min[Y] * base2local, rtip->mdl_min[Z] * base2local, rtip->mdl_max[X] * base2local, rtip->mdl_max[Y] * base2local, rtip->mdl_max[Z] * base2local); } /* Run the run-time configuration file, if it exists */ if ((fPtr = fopenrc()) != NULL) { interact(READING_FILE, fPtr, rtip); fclose(fPtr); } /* Run all scripts specified on the command line */ run_scripts(&script_list, rtip); /* Perform the user interface */ if (mat_flag) { read_mat(rtip); return 0; } else { interact(READING_FILE, stdin, rtip); } return 0; }
HIDDEN int _rt_generate_points(int **faces, int *num_faces, point_t **points, int *num_pnts, struct bu_ptbl *hit_pnts, struct db_i *dbip, const char *obj, fastf_t delta) { int i, dir1, j; point_t min, max; int ncpus = bu_avail_cpus(); struct rt_parallel_container *state; struct bu_vls vlsstr; bu_vls_init(&vlsstr); if (!hit_pnts || !dbip || !obj) return -1; BU_GET(state, struct rt_parallel_container); state->rtip = rt_new_rti(dbip); state->delta = delta; if (rt_gettree(state->rtip, obj) < 0) return -1; rt_prep_parallel(state->rtip, 1); state->resp = (struct resource *)bu_calloc(ncpus+1, sizeof(struct resource), "resources"); for (i = 0; i < ncpus+1; i++) { rt_init_resource(&(state->resp[i]), i, state->rtip); } state->npts = (struct rt_point_container *)bu_calloc(ncpus+1, sizeof(struct rt_point_container), "point container arrays"); int n[3]; VMOVE(min, state->rtip->mdl_min); VMOVE(max, state->rtip->mdl_max); for (i = 0; i < 3; i++) { n[i] = (int)((max[i] - min[i])/state->delta) + 2; if(n[i] < 12) n[i] = 12; } int total = 0; for (i = 0; i < 3; i++) total += n[i]*n[(i+1)%3]; if (total > 1e6) total = 1e6; for (i = 0; i < ncpus+1; i++) { state->npts[i].pts = (struct npoints *)bu_calloc(total, sizeof(struct npoints), "npoints arrays"); state->npts[i].pnt_cnt = 0; state->npts[i].capacity = total; } for (dir1 = 0; dir1 < 3; dir1++) { state->ray_dir = dir1; state->ncpus = ncpus; state->delta = delta; bu_parallel(_rt_gen_worker, ncpus, (void *)state); } int out_cnt = 0; for (i = 0; i < ncpus+1; i++) { bu_log("%d, pnt_cnt: %d\n", i, state->npts[i].pnt_cnt); for (j = 0; j < state->npts[i].pnt_cnt; j++) { struct npoints *npt = &(state->npts[i].pts[j]); if (npt->in.is_set) out_cnt++; if (npt->out.is_set) out_cnt++; } } struct rt_vert **rt_verts = (struct rt_vert **)bu_calloc(out_cnt, sizeof(struct rt_vert *), "output array"); int curr_ind = 0; for (i = 0; i < ncpus+1; i++) { for (j = 0; j < state->npts[i].pnt_cnt; j++) { struct npoints *npt = &(state->npts[i].pts[j]); if (npt->in.is_set) { rt_verts[curr_ind] = &(npt->in); curr_ind++; } if (npt->out.is_set) { rt_verts[curr_ind] = &(npt->out); curr_ind++; } } } struct spr_options opts = SPR_OPTIONS_DEFAULT_INIT; (void)spr_surface_build(faces, num_faces, (double **)points, num_pnts, (const struct cvertex **)rt_verts, out_cnt, &opts); 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; }