/* * M A I N */ int main(int argc, char **argv) { static struct rt_i *rtip; fastf_t sizeVoxel[3], threshold; int levelOfDetail; genptr_t callBackData; char title[1024] = {0}; /* Check for command-line arguments. Make sure we have at least a * geometry file and one geometry object on the command line. */ if (argc < 3) { bu_exit(1, "Usage: %s model.g objects...\n", argv[0]); } /* Load the specified geometry database (i.e., a ".g" file). * rt_dirbuild() returns an "instance" pointer which describes the * database to be raytraced. It also gives you back the title * string if you provide a buffer. This builds a directory of the * geometry (i.e., a table of contents) in the file. */ rtip = rt_dirbuild(argv[1], title, sizeof(title)); if (rtip == RTI_NULL) { bu_exit(2, "Building the database directory for [%s] FAILED\n", argv[1]); } /* Walk the geometry trees. Here you identify any objects in the * database that you want included in the ray trace by iterating * of the object names that were specified on the command-line. */ while (argc > 2) { if (rt_gettree(rtip, argv[2]) < 0) bu_log("Loading the geometry for [%s] FAILED\n", argv[2]); argc--; argv++; } /* user parameters are being given values directly here*/ sizeVoxel[0] = 1.0; sizeVoxel[1] = 1.0; sizeVoxel[2] = 1.0; threshold = 0.5; levelOfDetail = 4; callBackData = (void *)(& threshold); /* voxelize function is called here with rtip(ray trace instance), userParameters and printToFile/printToScreen options */ voxelize(rtip, sizeVoxel, levelOfDetail, printToFile, callBackData); rt_free_rti(rtip); return 0; }
int ged_voxelize(struct ged *gedp, int argc, const char *argv[]) { struct rt_i *rtip; static const char *usage = "[-s \"dx dy dz\"] [-d n] [-t f] new_obj old_obj [old_obj2 old_obj3 ...]"; fastf_t sizeVoxel[3]; int levelOfDetail; genptr_t callBackData; struct voxelizeData voxDat; int c; /* intentionally double for scan */ double threshold; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialization */ bu_vls_trunc(gedp->ged_result_str, 0); /* incorrect arguments */ if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } sizeVoxel[0] = 1.0; sizeVoxel[1] = 1.0; sizeVoxel[2] = 1.0; levelOfDetail = 1; threshold = 0.5; bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, (const char *)"s:d:t:")) != -1) { double scan[3]; switch (c) { case 's': if (sscanf(bu_optarg, "%lf %lf %lf", &scan[0], &scan[1], &scan[2]) != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } else { /* convert from double to fastf_t */ VMOVE(sizeVoxel, scan); sizeVoxel[0] = sizeVoxel[0] * gedp->ged_wdbp->dbip->dbi_local2base; sizeVoxel[1] = sizeVoxel[1] * gedp->ged_wdbp->dbip->dbi_local2base; sizeVoxel[2] = sizeVoxel[2] * gedp->ged_wdbp->dbip->dbi_local2base; } break; case 'd': if (sscanf(bu_optarg, "%d", &levelOfDetail) != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } break; case 't': if(sscanf(bu_optarg, "%lf", &threshold) != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } 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 < 2) { bu_vls_printf(gedp->ged_result_str, "error: missing argument(s)\n"); return GED_ERROR; } voxDat.newname = (char *)argv[0]; argc--; argv++; if (db_lookup(gedp->ged_wdbp->dbip, voxDat.newname, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", voxDat.newname); return GED_ERROR; } rtip = rt_new_rti(gedp->ged_wdbp->dbip); rtip->useair = 1; /* Walk trees. Here we identify any object trees in the database * that the user wants included in the ray trace. */ while(argc > 0) { if(rt_gettree(rtip,argv[0]) < 0) { bu_vls_printf(gedp->ged_result_str, "error: object '%s' does not exists, aborting\n", argv[1]); return GED_ERROR; } argc--; argv++; } voxDat.sizeVoxel[0] = sizeVoxel[0]; voxDat.sizeVoxel[1] = sizeVoxel[1]; voxDat.sizeVoxel[2] = sizeVoxel[2]; voxDat.threshold = threshold; voxDat.wdbp = gedp->ged_wdbp; voxDat.bbMin = rtip->mdl_min; BU_LIST_INIT(&voxDat.content.l); callBackData = (void*)(&voxDat); /* voxelize function is called here with rtip(ray trace instance), userParameter and create_boxes function */ voxelize(rtip, sizeVoxel, levelOfDetail, create_boxes, callBackData); mk_comb(gedp->ged_wdbp, voxDat.newname, &voxDat.content.l, 1, "plastic", "sh=4 sp=0.5 di=0.5 re=0.1", 0, 1000, 0, 0, 100, 0, 0, 0); mk_freemembers(&voxDat.content.l); rt_free_rti(rtip); return GED_OK; }
/** * raytrace an object optionally storing the rays */ void fit_rt(char *obj, struct db_i *db, struct fitness_state *fstate) { int i; fastf_t diff[3], tmp; fastf_t min[3], max[3]; /* * uncomment to calculate # of nodes * and use in fitness calculation * struct directory *dp struct rt_db_internal in; int n_leaves; if (!rt_db_lookup_internal(db, obj, &dp, &in, LOOKUP_NOISY, &rt_uniresource)) bu_exit(EXIT_FAILURE, "Failed to read object to raytrace"); n_leaves = db_count_tree_nodes(((struct rt_comb_internal *)in.idb_ptr)->tree, 0); rt_db_free_internal(&in); */ fstate->rtip = rt_new_rti(db); fstate->row = 0; if (rt_gettree(fstate->rtip, obj) < 0) bu_exit(EXIT_FAILURE, "rt_gettree failed"); /* for (i = 0; i < fstate->max_cpus; i++) { rt_init_resource(&fstate->resource[i], i, fstate->rtip); bn_rand_init(fstate->resource[i].re_randptr, i); } */ /* stash bounding box and if comparing to source * calculate the difference between the bounding boxes */ if (fstate->capture) { VMOVE(fstate->min, fstate->rtip->mdl_min); VMOVE(fstate->max, fstate->rtip->mdl_max); /* z_max = fstate->rtip->mdl_max[Z];*/ } /*else { * instead of storing min and max, just compute * what we're going to need later for (i = 0; i < 3; i++) { diff[i] = 0; if (fstate->min[i] > fstate->rtip->mdl_min[i]) diff[i] += fstate->min[i] - fstate->rtip->mdl_min[i]; if (fstate->max[i] < fstate->rtip->mdl_max[i]) diff[i] += fstate->rtip->mdl_max[i] - fstate->max[i]; if (fstate->min[i] < fstate->rtip->mdl_min[i]) min[i] = fstate->min[i]; else min[i] = fstate->rtip->mdl_min[i]; if (fstate->max[i] > fstate->rtip->mdl_max[i]) max[i] = fstate->max[i]; else max[i] = fstate->rtip->mdl_max[i]; diff[i] = max[i] - min[i]; } fastf_t tmp = (diff[X]/fstate->gridSpacing[X]-1) * (diff[Y]/fstate->gridSpacing[Y] - 1); fstate->volume = (fstate->a_len + (max[Z] - fstate->max[Z])) * tmp; } */ /*rt_prep_parallel(fstate->rtip, fstate->ncpu)o;*/ rt_prep(fstate->rtip); if (fstate->capture) { /* Store bounding box of voxel data -- fixed bounding box for fitness */ fstate->gridSpacing[X] = (fstate->rtip->mdl_max[X] - fstate->rtip->mdl_min[X]) / (fstate->res[X] + 1); fstate->gridSpacing[Y] = (fstate->rtip->mdl_max[Y] - fstate->rtip->mdl_min[Y]) / (fstate->res[Y] + 1); fstate->a_len = fstate->max[Z]-fstate->rtip->mdl_min[Z]; /* maximum ray length (z-dist of bounding box) */ fstate->volume = fstate->a_len * fstate->res[X] * fstate->res[Y]; /* volume of bounding box */ /* allocate storage for saved rays */ fstate->ray = (struct part **)bu_malloc(sizeof(struct part *) * fstate->res[X] * fstate->res[Y], "ray"); VMOVE(fstate->min, fstate->rtip->mdl_min); VMOVE(fstate->max, fstate->rtip->mdl_max); } else { /* instead of storing min and max, just compute * what we're going to need later */ for (i = 0; i < 3; i++) { diff[i] = 0; if (fstate->min[i] < fstate->rtip->mdl_min[i]) min[i] = fstate->min[i]; else min[i] = fstate->rtip->mdl_min[i]; if (fstate->max[i] > fstate->rtip->mdl_max[i]) max[i] = fstate->max[i]; else max[i] = fstate->rtip->mdl_max[i]; diff[i] = max[i] - min[i]; } tmp = (diff[X]/fstate->gridSpacing[X]-1) * (diff[Y]/fstate->gridSpacing[Y] - 1); fstate->volume = (fstate->a_len + (max[Z] - fstate->max[Z])) * tmp; /* scale fitness to the unon of the sources and individual's bounding boxes */ /* FIXME: sloppy fastf_t tmp = (diff[X]/fstate->gridSpacing[X]-1) * (diff[Y]/fstate->gridSpacing[Y] * diff[Z] - 1); if (tmp < 0) tmp = 0;*/ } rt_worker(0, (void *)fstate); /*bu_parallel(rt_worker, fstate->ncpu, (void *)fstate);*/ /* normalize fitness if we aren't just saving the source */ if (!fstate->capture) { fstate->fitness = fstate->same / (fstate->volume ); /* reset counters for future comparisons */ fstate->diff = fstate->same = 0.0; } /* clean up resources and rtip */ /* for (i = 0; i < fstate->max_cpus; i++) rt_clean_resource(fstate->rtip, &fstate->resource[i]); */ rt_free_rti(fstate->rtip); }