Revision: 70795 http://sourceforge.net/p/brlcad/code/70795 Author: starseeker Date: 2018-03-04 22:06:02 +0000 (Sun, 04 Mar 2018) Log Message: ----------- slew of nirt diffing related changes.
Modified Paths: -------------- brlcad/trunk/src/libanalyze/nirt.cxx brlcad/trunk/src/nirt/CMakeLists.txt brlcad/trunk/src/nirt/main.cxx Added Paths: ----------- brlcad/trunk/src/nirt/sfiles/diff.nrt Modified: brlcad/trunk/src/libanalyze/nirt.cxx =================================================================== --- brlcad/trunk/src/libanalyze/nirt.cxx 2018-03-04 21:58:22 UTC (rev 70794) +++ brlcad/trunk/src/libanalyze/nirt.cxx 2018-03-04 22:06:02 UTC (rev 70795) @@ -43,6 +43,13 @@ #include <vector> #include <limits> +//#define NIRT_USE_UNICODE 1 +#ifdef NIRT_USE_UNICODE +# define delta_str "Δ" +#else +# define delta_str "Delta" +#endif + extern "C" { #include "bu/color.h" #include "bu/cmd.h" @@ -164,7 +171,6 @@ struct nirt_seg { int type; - int id; point_t in; fastf_t d_in; point_t out; @@ -342,7 +348,8 @@ struct nirt_diff { point_t orig; vect_t dir; - std::vector<struct nirt_seg *> segs; + std::vector<struct nirt_seg *> old_segs; + std::vector<struct nirt_seg *> new_segs; std::vector<struct nirt_seg_diff *> diffs; }; @@ -410,9 +417,12 @@ std::set<std::string> attrs; // active attributes std::vector<std::string> active_paths; // active paths for raytracer struct nirt_output_record *vals; - struct nirt_diff *diff; + struct bu_vls *diff_file; + struct nirt_diff *cdiff; std::vector<struct nirt_diff *> diffs; struct nirt_diff_settings *diff_settings; + int diff_run; + int diff_ready; /* state alteration flags */ bool b_state; // updated for any state change @@ -770,15 +780,20 @@ **********************/ #define SD_INIT(sd, l, r) \ - do {BU_GET(sd, struct nirt_seg_diff); sd->left = left; sd->right = _nirt_seg_cpy(right);} \ + do {BU_GET(sd, struct nirt_seg_diff); sd->left = left; sd->right = right;} \ while (0) +#define SD_FREE(sd) \ + do {BU_PUT(sd, struct nirt_seg_diff);} \ + while (0) + + HIDDEN struct nirt_seg_diff * _nirt_partition_diff(struct nirt_state *nss, struct nirt_seg *left, struct nirt_seg *right) { int have_diff = 0; struct nirt_seg_diff *sd; - if (!nss || !nss->i->diff || !nss->i->diff_settings) return NULL; + if (!nss || !nss->i->diff_settings) return NULL; fastf_t in_delta = DIST_PT_PT(left->in, right->in); fastf_t out_delta = DIST_PT_PT(left->in, right->in); fastf_t los_delta = fabs(left->los - right->los); @@ -812,7 +827,7 @@ { int have_diff = 0; struct nirt_seg_diff *sd; - if (!nss || !nss->i->diff || !nss->i->diff_settings) return NULL; + if (!nss || !nss->i->diff_settings) return NULL; fastf_t ov_in_delta = DIST_PT_PT(left->ov_in, right->ov_in); fastf_t ov_out_delta = DIST_PT_PT(left->ov_out, right->ov_out); fastf_t ov_los_delta = fabs(left->ov_los - right->ov_los); @@ -838,7 +853,7 @@ { int have_diff = 0; struct nirt_seg_diff *sd; - if (!nss || !nss->i->diff || !nss->i->diff_settings) return NULL; + if (!nss || !nss->i->diff_settings) return NULL; fastf_t gap_in_delta = DIST_PT_PT(left->gap_in, right->gap_in); fastf_t gap_los_delta = fabs(left->gap_los - right->gap_los); if (gap_in_delta > nss->i->diff_settings->dist_delta_tol) have_diff = 1; @@ -856,7 +871,7 @@ _nirt_segs_diff(struct nirt_state *nss, struct nirt_seg *left, struct nirt_seg *right) { struct nirt_seg_diff *sd; - if (!nss || !nss->i->diff) return NULL; + if (!nss) return NULL; if (!left || !right || left->type != right->type) { /* Fundamental segment difference - no point going further, they're different */ SD_INIT(sd, left, right); @@ -903,13 +918,27 @@ _nirt_diff_report(struct nirt_state *nss) { int reporting_diff = 0; + int did_header = 0; struct bu_vls dreport = BU_VLS_INIT_ZERO; + if (!nss || nss->i->diffs.size() == 0) return 0; std::vector<struct nirt_diff *> *dfs = &(nss->i->diffs); - for (size_t i = 0; i < dfs->size(); i++) { struct nirt_diff *d = (*dfs)[i]; - bu_vls_printf(&dreport, "Found differences along Ray:\n xyz %.17f %.17f %.17f\n dir %.17f %.17f %.17f\n \n", V3ARGS(d->orig), V3ARGS(d->dir)); + // Calculate diffs according to settings. TODO - need to be more sophisticated about this - if a + // segment is "missing" but the rays otherwise match, don't propagate the "offset" and report all + // of the subsequent segments as different... + size_t seg_max = (d->old_segs.size() > d->new_segs.size()) ? d->new_segs.size() : d->old_segs.size(); + for (size_t j = 0; j < seg_max; j++) { + struct nirt_seg_diff *sd = _nirt_segs_diff(nss, d->old_segs[j], d->new_segs[j]); + if (sd) d->diffs.push_back(sd); + } + if (d->diffs.size() > 0 && !did_header) { + bu_vls_printf(&dreport, "Diff Results (%s):\n", bu_vls_addr(nss->i->diff_file)); + did_header = 1; + } + + if (d->diffs.size() > 0) bu_vls_printf(&dreport, "Found differences along Ray:\n xyz %.17f %.17f %.17f\n dir %.17f %.17f %.17f\n \n", V3ARGS(d->orig), V3ARGS(d->dir)); for (size_t j = 0; j < d->diffs.size(); j++) { struct nirt_seg_diff *sd = d->diffs[j]; struct nirt_seg *left = sd->left; @@ -919,8 +948,6 @@ nout(nss, "%s", bu_vls_addr(&dreport)); bu_vls_free(&dreport); return 1; - } else { - bu_vls_printf(&dreport, " %s %d:\n", _nirt_seg_string(sd->left->type), left->id); } switch (sd->left->type) { case NIRT_MISS_SEG: @@ -929,88 +956,96 @@ break; case NIRT_PARTITION_SEG: if (!nss->i->diff_settings->report_partitions) continue; + bu_vls_printf(&dreport, " Segment difference(%s):\n", _nirt_seg_string(sd->left->type), j); if (bu_vls_strcmp(left->reg_name, right->reg_name) && nss->i->diff_settings->report_partition_reg_names) { - bu_vls_printf(&dreport, " Region Name(Original): %s, Region Name(Current): %s\n", bu_vls_addr(left->reg_name), bu_vls_addr(right->reg_name)); + bu_vls_printf(&dreport, " Region Name: '%s' -> '%s'\n", bu_vls_addr(left->reg_name), bu_vls_addr(right->reg_name)); reporting_diff = 1; } if (bu_vls_strcmp(left->path_name, right->path_name) && nss->i->diff_settings->report_partition_path_names) { - bu_vls_printf(&dreport, " Path Name(Original): %s, Path Name(Current): %s\n", bu_vls_addr(left->path_name), bu_vls_addr(right->path_name)); + bu_vls_printf(&dreport, " Path Name: '%s' -> '%s'\n", bu_vls_addr(left->path_name), bu_vls_addr(right->path_name)); reporting_diff = 1; } if (left->reg_id != right->reg_id && nss->i->diff_settings->report_partition_reg_ids) { - bu_vls_printf(&dreport, " Region ID(Original): %d, Region ID(Current): %d\n", left->reg_id, right->reg_id); + bu_vls_printf(&dreport, " Region ID: %d -> %d\n", left->reg_id, right->reg_id); reporting_diff = 1; } if (sd->in_delta > nss->i->diff_settings->dist_delta_tol && nss->i->diff_settings->report_partition_dists) { std::string oval = _nirt_dbl_to_str(sd->in_delta, _nirt_digits(nss->i->diff_settings->dist_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Input Points: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " DIST_PT_PT(in_old,in_new): %s\n", oval.c_str()); reporting_diff = 1; } if (sd->out_delta > nss->i->diff_settings->dist_delta_tol && nss->i->diff_settings->report_partition_dists) { std::string oval = _nirt_dbl_to_str(sd->out_delta, _nirt_digits(nss->i->diff_settings->dist_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Output Points: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " DIST_PT_PT(out_old,out_new): %s\n", oval.c_str()); reporting_diff = 1; } if (sd->los_delta > nss->i->diff_settings->los_delta_tol && nss->i->diff_settings->report_partition_dists) { std::string oval = _nirt_dbl_to_str(sd->los_delta, _nirt_digits(nss->i->diff_settings->los_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Line-Of-Sight (LOS): %s\n", oval.c_str()); + bu_vls_printf(&dreport, " Line-Of-Sight(LOS) %s: %s\n", delta_str, oval.c_str()); reporting_diff = 1; } if (sd->scaled_los_delta > nss->i->diff_settings->scaled_los_delta_tol && nss->i->diff_settings->report_partition_dists) { std::string oval = _nirt_dbl_to_str(sd->scaled_los_delta, _nirt_digits(nss->i->diff_settings->los_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Scaled Line-Of-Sight: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " Scaled Line-Of-Sight %s: %s\n", delta_str, oval.c_str()); reporting_diff = 1; } if (sd->obliq_in_delta > nss->i->diff_settings->obliq_delta_tol && nss->i->diff_settings->report_partition_obliq) { std::string oval = _nirt_dbl_to_str(sd->obliq_in_delta, _nirt_digits(nss->i->diff_settings->obliq_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Input Normal Obliquity: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " Input Normal Obliquity %s: %s\n", delta_str, oval.c_str()); reporting_diff = 1; } if (sd->obliq_out_delta > nss->i->diff_settings->obliq_delta_tol && nss->i->diff_settings->report_partition_obliq) { std::string oval = _nirt_dbl_to_str(sd->obliq_out_delta, _nirt_digits(nss->i->diff_settings->obliq_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Output Normal Obliquity: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " Output Normal Obliquity %s: %s\n", delta_str, oval.c_str()); reporting_diff = 1; } break; case NIRT_GAP_SEG: if (!nss->i->diff_settings->report_gaps) continue; + bu_vls_printf(&dreport, " Segment difference(%s):\n", _nirt_seg_string(sd->left->type), j); if (sd->gap_in_delta > nss->i->diff_settings->dist_delta_tol && nss->i->diff_settings->report_gap_dists) { std::string oval = _nirt_dbl_to_str(sd->gap_in_delta, _nirt_digits(nss->i->diff_settings->dist_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Input Points: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " DIST_PT_PT(gap_in_old,gap_in_new): %s\n", oval.c_str()); reporting_diff = 1; } if (sd->gap_los_delta > nss->i->diff_settings->los_delta_tol && nss->i->diff_settings->report_gap_dists) { std::string oval = _nirt_dbl_to_str(sd->gap_los_delta, _nirt_digits(nss->i->diff_settings->los_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Line-Of-Sight (LOS): %s\n", oval.c_str()); + bu_vls_printf(&dreport, " Gap Line-Of-Sight (LOS) %s: %s\n", delta_str, oval.c_str()); reporting_diff = 1; } break; case NIRT_OVERLAP_SEG: if (!nss->i->diff_settings->report_overlaps) continue; + bu_vls_printf(&dreport, " Segment difference(%s):\n", _nirt_seg_string(sd->left->type), j); if (bu_vls_strcmp(left->ov_reg1_name, right->ov_reg1_name) && nss->i->diff_settings->report_overlap_reg_names) { - bu_vls_printf(&dreport, " Region 1 Name(Original): %s, Region 1 Name(Current): %s\n", bu_vls_addr(left->ov_reg1_name), bu_vls_addr(right->ov_reg1_name)); + bu_vls_printf(&dreport, " Region 1 Name: '%s' -> '%s'\n", bu_vls_addr(left->ov_reg1_name), bu_vls_addr(right->ov_reg1_name)); reporting_diff = 1; } if (bu_vls_strcmp(left->ov_reg2_name, right->ov_reg2_name) && nss->i->diff_settings->report_overlap_reg_names) { - bu_vls_printf(&dreport, " Region 2 Name(Original): %s, Region 2 Name(Current): %s\n", bu_vls_addr(left->ov_reg2_name), bu_vls_addr(right->ov_reg2_name)); + bu_vls_printf(&dreport, " Region 2 Name: '%s' -> '%s'\n", bu_vls_addr(left->ov_reg2_name), bu_vls_addr(right->ov_reg2_name)); reporting_diff = 1; } if (left->ov_reg1_id != right->ov_reg1_id && nss->i->diff_settings->report_overlap_reg_ids) { - bu_vls_printf(&dreport, " Region 1 ID(Original): %d, Region 1 ID(Current): %d\n", left->ov_reg1_id, right->ov_reg1_id); + bu_vls_printf(&dreport, " Region 1 ID: %d -> %d\n", left->ov_reg1_id, right->ov_reg1_id); reporting_diff = 1; } if (left->ov_reg2_id != right->ov_reg2_id && nss->i->diff_settings->report_overlap_reg_ids) { - bu_vls_printf(&dreport, " Region 2 ID(Original): %d, Region 2 ID(Current): %d\n", left->ov_reg2_id, right->ov_reg2_id); + bu_vls_printf(&dreport, " Region 2 ID: %d -> %d\n", left->ov_reg2_id, right->ov_reg2_id); reporting_diff = 1; } if (sd->ov_in_delta > nss->i->diff_settings->dist_delta_tol && nss->i->diff_settings->report_overlap_dists) { std::string oval = _nirt_dbl_to_str(sd->ov_in_delta, _nirt_digits(nss->i->diff_settings->dist_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Input Points: %s\n", oval.c_str()); + bu_vls_printf(&dreport, " DIST_PT_PT(ov_in_old, ov_in_new): %s\n", oval.c_str()); reporting_diff = 1; } + if (sd->ov_out_delta > nss->i->diff_settings->dist_delta_tol && nss->i->diff_settings->report_overlap_dists) { + std::string oval = _nirt_dbl_to_str(sd->ov_out_delta, _nirt_digits(nss->i->diff_settings->dist_delta_tol)); + bu_vls_printf(&dreport, " DIST_PT_PT(ov_out_old, ov_out_new): %s\n", oval.c_str()); + reporting_diff = 1; + } if (sd->ov_los_delta > nss->i->diff_settings->los_delta_tol && nss->i->diff_settings->report_overlap_dists) { std::string oval = _nirt_dbl_to_str(sd->ov_los_delta, _nirt_digits(nss->i->diff_settings->los_delta_tol)); - bu_vls_printf(&dreport, " Distance between Original and Current Line-Of-Sight (LOS): %s\n", oval.c_str()); + bu_vls_printf(&dreport, " Overlap Line-Of-Sight (LOS) %s: %s\n", delta_str, oval.c_str()); reporting_diff = 1; } break; @@ -1018,12 +1053,17 @@ nerr(nss, "NIRT diff error: unknown segment type: %d\n", left->type); return 0; } + } + for (size_t j = 0; j < d->diffs.size(); j++) { + SD_FREE(d->diffs[j]); } - + d->diffs.clear(); } if (reporting_diff) { nout(nss, "%s", bu_vls_addr(&dreport)); + } else { + nout(nss, "No differences found\n"); } bu_vls_free(&dreport); @@ -1586,6 +1626,10 @@ } if (r->seg->type == NIRT_GAP_SEG || r->seg->type == NIRT_ALL_SEG) { + nirt_print_key("x_in", r->seg->in[X] * base2local); + nirt_print_key("y_in", r->seg->in[Y] * base2local); + nirt_print_key("z_in", r->seg->in[Z] * base2local); + nirt_print_key("x_gap_in", r->seg->gap_in[X] * base2local); nirt_print_key("y_gap_in", r->seg->gap_in[Y] * base2local); nirt_print_key("z_gap_in", r->seg->gap_in[Z] * base2local); @@ -1700,7 +1744,6 @@ struct nirt_overlap *ovp; struct partition *part; int ev_odd = 1; /* first partition is colored as "odd" */ - int cnt = 0; point_t out_old = VINIT_ZERO; double d_out_old = 0.0; struct nirt_seg *s; @@ -1711,8 +1754,8 @@ } vals->seg = s; - _nirt_report(nss, 'r', vals); - _nirt_report(nss, 'h', vals); + if (!nss->i->diff_run) _nirt_report(nss, 'r', vals); + if (!nss->i->diff_run) _nirt_report(nss, 'h', vals); if (nss->i->overlap_claims == NIRT_OVLP_REBUILD_FASTGEN) { rt_rebuild_overlaps(part_head, ap, 1); @@ -1722,8 +1765,6 @@ for (part = part_head->pt_forw; part != part_head; part = part->pt_forw) { s->type = NIRT_PARTITION_SEG; - cnt++; - s->id = cnt; ++part_nm; @@ -1758,14 +1799,9 @@ if (s->gap_los > 0) { s->type = NIRT_GAP_SEG; - _nirt_report(nss, 'g', vals); - if (nss->i->diff) { - struct nirt_seg_diff *sd = _nirt_segs_diff(nss, nss->i->diff->segs[cnt-1], s); - if (sd) { - nss->i->diff->diffs.push_back(sd); - } else { - _nirt_seg_free(nss->i->diff->segs[cnt-1]); // matched - we don't need this one anymore - } + if (!nss->i->diff_run) _nirt_report(nss, 'g', vals); + if (nss->i->cdiff) { + nss->i->cdiff->new_segs.push_back(_nirt_seg_cpy(s)); } /* vlist segment for gap */ vhead = bn_vlblock_find(nss->i->segs, nss->i->void_color->buc_rgb[RED], nss->i->void_color->buc_rgb[GRN], nss->i->void_color->buc_rgb[BLU]); @@ -1773,8 +1809,6 @@ BN_ADD_VLIST(nss->i->segs->free_vlist_hd, vhead, s->in, BN_VLIST_LINE_DRAW); nss->i->b_segs = true; s->type = NIRT_PARTITION_SEG; - cnt++; // bump the partition out to the next index to account for gap - s->id = cnt; } } VMOVE(out_old, s->out); // Stash the out value for gap_los calculation in the next partition @@ -1830,7 +1864,7 @@ } } - _nirt_report(nss, 'p', vals); + if (!nss->i->diff_run) _nirt_report(nss, 'p', vals); /* vlist segment for hit */ if (ev_odd % 2) { @@ -1843,20 +1877,13 @@ nss->i->b_segs = true; /* done with hit portion - if diff, stash */ - if (nss->i->diff) { - struct nirt_seg_diff *sd = _nirt_segs_diff(nss, nss->i->diff->segs[cnt-1], s); - if (sd) { - nss->i->diff->diffs.push_back(sd); - } else { - _nirt_seg_free(nss->i->diff->segs[cnt-1]); // matched - we don't need this one anymore - } + if (nss->i->cdiff && nss->i->diff_run) { + nss->i->cdiff->new_segs.push_back(_nirt_seg_cpy(s)); } while ((ovp = _nirt_find_ovlp(nss, part)) != NIRT_OVERLAP_NULL) { s->type = NIRT_OVERLAP_SEG; - cnt++; // bump the partition out to the next index - ovlp is its own seg - s->id = cnt; // TODO - do this more cleanly char *copy_ovlp_reg1 = bu_strdup(ovp->reg1->reg_name); @@ -1884,7 +1911,7 @@ s->ov_d_out = vals->d_orig - ovp->out_dist; // TODO looks sketchy in NIRT - did they really mean target(D) ?? -> (VTI_XORIG + 3 -> VTI_H) s->ov_los = s->ov_d_in - s->ov_d_out; - _nirt_report(nss, 'o', vals); + if (!nss->i->diff_run) _nirt_report(nss, 'o', vals); /* vlist segment for overlap */ if (nss->i->plot_overlaps) { @@ -1895,13 +1922,8 @@ } /* Diff */ - if (nss->i->diff) { - struct nirt_seg_diff *sd = _nirt_segs_diff(nss, nss->i->diff->segs[cnt-1], s); - if (sd) { - nss->i->diff->diffs.push_back(sd); - } else { - _nirt_seg_free(nss->i->diff->segs[cnt-1]); // matched - we don't need this one anymore - } + if (nss->i->cdiff && nss->i->diff_run) { + nss->i->cdiff->new_segs.push_back(_nirt_seg_cpy(s)); } _nirt_del_ovlp(ovp); @@ -1910,7 +1932,7 @@ } - _nirt_report(nss, 'f', vals); + if (!nss->i->diff_run) _nirt_report(nss, 'f', vals); if (vals->ovlp_list.forw != &(vals->ovlp_list)) { nerr(nss, "Previously unreported overlaps. Shouldn't happen\n"); @@ -1920,7 +1942,7 @@ ovp = ovp->forw; } } - + /* We're done reporting - let print get at everything */ vals->seg->type = NIRT_ALL_SEG; @@ -1931,8 +1953,8 @@ _nirt_if_miss(struct application *ap) { struct nirt_state *nss = (struct nirt_state *)ap->a_uptr; - _nirt_report(nss, 'r', nss->i->vals); - _nirt_report(nss, 'm', nss->i->vals); + if (!nss->i->diff_run) _nirt_report(nss, 'r', nss->i->vals); + if (!nss->i->diff_run) _nirt_report(nss, 'm', nss->i->vals); // TODO - handle miss diffing... @@ -2128,6 +2150,7 @@ return ret; } +//#define NIRT_DIFF_DEBUG 1 extern "C" int _nirt_cmd_diff(void *ns, int argc, const char *argv[]) @@ -2139,7 +2162,6 @@ double tol = 0; int have_ray = 0; size_t cmt = std::string::npos; - int cnt = 0; struct bu_vls optparse_msg = BU_VLS_INIT_ZERO; struct bu_opt_desc d[3]; // TODO - add reporting options for enabling/disabling region/path, partition length, normal, and overlap ordering diffs. @@ -2162,220 +2184,368 @@ } bu_vls_free(&optparse_msg); - if (print_help || (ac != 1) || !argv[0]) { + if (print_help || !argv[0]) { nerr(nss, "%s\n%s", ustr, help); if (help) bu_free((char *)help, "help str"); return -1; } - std::string line; - std::ifstream ifs; - ifs.open(argv[0]); - if (!ifs.is_open()) { - nerr(nss, "Error: could not open file %s\n", argv[0]); - return -1; - } + if (BU_STR_EQUAL(argv[0], "load")) { + ac--; argv++; + if (ac != 1) { + nerr(nss, "Please specify a NIRT diff file to load.\n"); + return -1; + } - if (nss->i->need_reprep) { - /* If we need to (re)prep, do it now. Failure is an error. */ - if (_nirt_raytrace_prep(nss)) { - nerr(nss, "Error: raytrace prep failed!\n"); + if (nss->i->diff_ready) { + nerr(nss, "Diff file already loaded. To reset, run \"diff clear\"\n"); return -1; } - } else { - /* Based on current settings, tell the ap which rtip to use */ - nss->i->ap->a_rt_i = _nirt_get_rtip(nss); - nss->i->ap->a_resource = _nirt_get_resource(nss); - } - have_ray = 0; - while (std::getline(ifs, line)) { - struct nirt_diff *df; + std::string line; + std::ifstream ifs; + ifs.open(argv[0]); + if (!ifs.is_open()) { + nerr(nss, "Error: could not open file %s\n", argv[0]); + return -1; + } - /* If part of the line is commented, skip that part */ - cmt = _nirt_find_first_unescaped(line, "#", 0); - if (cmt != std::string::npos) { - line.erase(cmt); + if (nss->i->need_reprep) { + /* If we need to (re)prep, do it now. Failure is an error. */ + if (_nirt_raytrace_prep(nss)) { + nerr(nss, "Error: raytrace prep failed!\n"); + return -1; + } + } else { + /* Based on current settings, tell the ap which rtip to use */ + nss->i->ap->a_rt_i = _nirt_get_rtip(nss); + nss->i->ap->a_resource = _nirt_get_resource(nss); } - _nirt_trim_whitespace(line); - if (!line.length()) continue; - if (!line.compare(0, 5, "Ray: ")) { - if (have_ray) { - bu_log("\n\nanother ray!\n\n\n"); - // Have ray already - execute current ray, store results in - // diff database (if any diffs were found), then clear expected - // results and old ray - for (int i = 0; i < 3; ++i) { - nss->i->ap->a_ray.r_pt[i] = nss->i->vals->orig[i]; - nss->i->ap->a_ray.r_dir[i] = nss->i->vals->dir[i]; + bu_vls_sprintf(nss->i->diff_file, "%s", argv[0]); + nss->i->diff_run = 1; + have_ray = 0; + while (std::getline(ifs, line)) { + struct nirt_diff *df; + + /* If part of the line is commented, skip that part */ + cmt = _nirt_find_first_unescaped(line, "#", 0); + if (cmt != std::string::npos) { + line.erase(cmt); + } + _nirt_trim_whitespace(line); + if (!line.length()) continue; + + if (!line.compare(0, 4, "RAY ")) { + if (have_ray) { +#ifdef NIRT_DIFF_DEBUG + bu_log("\n\nanother ray!\n\n\n"); +#endif + // Have ray already - execute current ray, store results in + // diff database (if any diffs were found), then clear expected + // results and old ray + for (int i = 0; i < 3; ++i) { + nss->i->ap->a_ray.r_pt[i] = nss->i->vals->orig[i]; + nss->i->ap->a_ray.r_dir[i] = nss->i->vals->dir[i]; + } + // TODO - rethink this container... + _nirt_init_ovlp(nss); + (void)rt_shootray(nss->i->ap); + nss->i->diffs.push_back(nss->i->cdiff); } - // TODO - rethink this container... - _nirt_init_ovlp(nss); - (void)rt_shootray(nss->i->ap); - if (nss->i->diff->diffs.size() > 0) { - nss->i->diffs.push_back(nss->i->diff); - } else { - delete nss->i->diff; + // Read ray + df = new struct nirt_diff; + // TODO - once we go to C++11, used std::regex_search and std::smatch to more flexibly get a substring + std::string rstr = line.substr(7); + have_ray = 1; + std::vector<std::string> substrs = _nirt_string_split(rstr); + if (substrs.size() != 6) { + nerr(nss, "Error processing ray line \"%s\"!\nExpected 6 elements, found %d\n", line.c_str(), substrs.size()); + return -1; } + VSET(df->orig, _nirt_str_to_dbl(substrs[0], 0), _nirt_str_to_dbl(substrs[1], 0), _nirt_str_to_dbl(substrs[2], 0)); + VSET(df->dir, _nirt_str_to_dbl(substrs[3], 0), _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0)); + VMOVE(nss->i->vals->dir, df->dir); + VMOVE(nss->i->vals->orig, df->orig); +#ifdef NIRT_DIFF_DEBUG + bu_log("Found RAY:\n"); + bu_log("origin : %0.17f, %0.17f, %0.17f\n", V3ARGS(df->orig)); + bu_log("direction: %0.17f, %0.17f, %0.17f\n", V3ARGS(df->dir)); +#endif + _nirt_targ2grid(nss); + _nirt_dir2ae(nss); + nss->i->cdiff = df; + continue; + } else { + if (!line.compare(0, 4, "HIT ") || !line.compare(0, 4, "GAP ") || + !line.compare(0, 5, "MISS ") || !line.compare(0, 8, "OVERLAP ")) { + if (!have_ray) { + nerr(nss, "Error: Result line found but no ray set.\n"); + return -1; + } + } } - // Read ray - df = new struct nirt_diff; - std::string rstr = line.substr(5); - have_ray = 1; - std::vector<std::string> substrs = _nirt_string_split(rstr); - if (substrs.size() != 6) { - nerr(nss, "Error processing ray line \"%s\"!\nExpected 6 elements, found %d\n", line.c_str(), substrs.size()); - return -1; + if (!line.compare(0, 4, "HIT ")) { + // TODO - once we go to C++11, used std::regex_search and std::smatch to more flexibly get a substring + std::string hstr = line.substr(7); + std::vector<std::string> substrs = _nirt_string_split(hstr); + if (substrs.size() != 15) { + nerr(nss, "Error processing hit line \"%s\"!\nExpected 15 elements, found %d\n", hstr.c_str(), substrs.size()); + return -1; + } + struct nirt_seg *seg; + _nirt_seg_init(&seg); + seg->type = NIRT_PARTITION_SEG; + bu_vls_decode(seg->reg_name, substrs[0].c_str()); + //bu_vls_printf(seg->reg_name, "%s", substrs[0].c_str()); + bu_vls_decode(seg->path_name, substrs[1].c_str()); + seg->reg_id = _nirt_str_to_int(substrs[2]); + VSET(seg->in, _nirt_str_to_dbl(substrs[3], 0), _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0)); + seg->d_in = _nirt_str_to_dbl(substrs[6], 0); + VSET(seg->out, _nirt_str_to_dbl(substrs[7], 0), _nirt_str_to_dbl(substrs[8], 0), _nirt_str_to_dbl(substrs[9], 0)); + seg->d_out = _nirt_str_to_dbl(substrs[10], 0); + seg->los = _nirt_str_to_dbl(substrs[11], 0); + seg->scaled_los = _nirt_str_to_dbl(substrs[12], 0); + seg->obliq_in = _nirt_str_to_dbl(substrs[13], 0); + seg->obliq_out = _nirt_str_to_dbl(substrs[14], 0); +#ifdef NIRT_DIFF_DEBUG + bu_log("Found %s:\n", line.c_str()); + bu_log(" reg_name: %s\n", bu_vls_addr(seg->reg_name)); + bu_log(" path_name: %s\n", bu_vls_addr(seg->path_name)); + bu_log(" reg_id: %d\n", seg->reg_id); + bu_log(" in: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->in)); + bu_log(" out: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->out)); + bu_log(" d_in: %0.17f d_out: %0.17f\n", seg->d_in, seg->d_out); + bu_log(" los: %0.17f scaled_los: %0.17f\n", seg->los, seg->scaled_los); + bu_log(" obliq_in: %0.17f obliq_out: %0.17f\n", seg->obliq_in, seg->obliq_out); +#endif + nss->i->cdiff->old_segs.push_back(seg); + continue; } - bu_log("Found Ray:\n"); - VSET(df->orig, _nirt_str_to_dbl(substrs[0], 0), _nirt_str_to_dbl(substrs[1], 0), _nirt_str_to_dbl(substrs[2], 0)); - VSET(df->dir, _nirt_str_to_dbl(substrs[3], 0), _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0)); - VMOVE(nss->i->vals->dir, df->dir); - VMOVE(nss->i->vals->orig, df->orig); - bu_log("origin : %0.17f, %0.17f, %0.17f\n", V3ARGS(df->orig)); - bu_log("direction: %0.17f, %0.17f, %0.17f\n", V3ARGS(df->dir)); - _nirt_targ2grid(nss); - _nirt_dir2ae(nss); - nss->i->diff = df; - cnt = 0; - continue; - } else { - if (!line.compare(0, 5, "HIT: ") || !line.compare(0, 5, "GAP: ") || - !line.compare("MISS") || !line.compare(0, 9, "OVERLAP: ")) { - if (!have_ray) { - nerr(nss, "Error: Result line found but no ray set.\n"); + if (!line.compare(0, 4, "GAP ")) { + // TODO - once we go to C++11, used std::regex_search and std::smatch to more flexibly get a substring + std::string gstr = line.substr(7); + std::vector<std::string> substrs = _nirt_string_split(gstr); + if (substrs.size() != 7) { + nerr(nss, "Error processing gap line \"%s\"!\nExpected 7 elements, found %d\n", gstr.c_str(), substrs.size()); return -1; } + struct nirt_seg *seg; + _nirt_seg_init(&seg); + seg->type = NIRT_GAP_SEG; + VSET(seg->gap_in, _nirt_str_to_dbl(substrs[0], 0), _nirt_str_to_dbl(substrs[1], 0), _nirt_str_to_dbl(substrs[2], 0)); + VSET(seg->in, _nirt_str_to_dbl(substrs[3], 0), _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0)); + seg->gap_los = _nirt_str_to_dbl(substrs[6], 0); +#ifdef NIRT_DIFF_DEBUG + bu_log("Found %s:\n", line.c_str()); + bu_log(" in: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->gap_in)); + bu_log(" out: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->in)); + bu_log(" gap_los: %0.17f\n", seg->gap_los); +#endif + nss->i->cdiff->old_segs.push_back(seg); + continue; } - } - if (!line.compare(0, 5, "HIT: ")) { - std::string hstr = line.substr(5); - std::vector<std::string> substrs = _nirt_string_split(hstr); - if (substrs.size() != 15) { - nerr(nss, "Error processing hit line \"%s\"!\nExpected 15 elements, found %d\n", hstr.c_str(), substrs.size()); - return -1; + if (!line.compare(0, 5, "MISS ")) { + struct nirt_seg *seg; + _nirt_seg_init(&seg); + seg->type = NIRT_MISS_SEG; +#ifdef NIRT_DIFF_DEBUG + bu_log("Found MISS\n"); +#endif + have_ray = 0; + nss->i->cdiff->old_segs.push_back(seg); + continue; } - bu_log("Found %s:\n", line.c_str()); - cnt++; - struct nirt_seg *seg; - _nirt_seg_init(&seg); - seg->type = NIRT_PARTITION_SEG; - seg->id = cnt; - bu_vls_decode(seg->reg_name, substrs[0].c_str()); - bu_vls_decode(seg->path_name, substrs[1].c_str()); - seg->reg_id = _nirt_str_to_int(substrs[2]); - VSET(seg->in, _nirt_str_to_dbl(substrs[3], 0), _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0)); - seg->d_in = _nirt_str_to_dbl(substrs[6], 0); - VSET(seg->out, _nirt_str_to_dbl(substrs[7], 0), _nirt_str_to_dbl(substrs[8], 0), _nirt_str_to_dbl(substrs[9], 0)); - seg->d_out = _nirt_str_to_dbl(substrs[10], 0); - seg->los = _nirt_str_to_dbl(substrs[11], 0); - seg->scaled_los = _nirt_str_to_dbl(substrs[12], 0); - seg->obliq_in = _nirt_str_to_dbl(substrs[13], 0); - seg->obliq_out = _nirt_str_to_dbl(substrs[14], 0); - bu_log("reg_name: %s\n", bu_vls_addr(seg->reg_name)); - bu_log("path_name: %s\n", bu_vls_addr(seg->path_name)); - bu_log("reg_id: %d\n", seg->reg_id); - bu_log("in: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->in)); - bu_log("out: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->out)); - bu_log("d_in: %0.17f d_out: %0.17f\n", seg->d_in, seg->d_out); - bu_log("los: %0.17f scaled_los: %0.17f\n", seg->los, seg->scaled_los); - bu_log("obliq_in: %0.17f obliq_out: %0.17f\n", seg->obliq_in, seg->obliq_out); - nss->i->diff->segs.push_back(seg); - continue; - } - if (!line.compare(0, 5, "GAP: ")) { - std::string gstr = line.substr(5); - std::vector<std::string> substrs = _nirt_string_split(gstr); - if (substrs.size() != 7) { - nerr(nss, "Error processing gap line \"%s\"!\nExpected 7 elements, found %d\n", gstr.c_str(), substrs.size()); - return -1; + if (!line.compare(0, 8, "OVERLAP ")) { + // TODO - once we go to C++11, used std::regex_search and std::smatch to more flexibly get a substring + std::string ostr = line.substr(11); + std::vector<std::string> substrs = _nirt_string_split(ostr); + if (substrs.size() != 11) { + nerr(nss, "Error processing overlap line \"%s\"!\nExpected 11 elements, found %d\n", ostr.c_str(), substrs.size()); + return -1; + } + struct nirt_seg *seg; + _nirt_seg_init(&seg); + seg->type = NIRT_OVERLAP_SEG; + bu_vls_decode(seg->ov_reg1_name, substrs[0].c_str()); + bu_vls_decode(seg->ov_reg2_name, substrs[1].c_str()); + seg->ov_reg1_id = _nirt_str_to_int(substrs[2]); + seg->ov_reg2_id = _nirt_str_to_int(substrs[3]); + VSET(seg->ov_in, _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0), _nirt_str_to_dbl(substrs[6], 0)); + VSET(seg->ov_out, _nirt_str_to_dbl(substrs[7], 0), _nirt_str_to_dbl(substrs[8], 0), _nirt_str_to_dbl(substrs[9], 0)); + seg->ov_los = _nirt_str_to_dbl(substrs[10], 0); +#ifdef NIRT_DIFF_DEBUG + bu_log("Found %s:\n", line.c_str()); + bu_log(" ov_reg1_name: %s\n", bu_vls_addr(seg->ov_reg1_name)); + bu_log(" ov_reg2_name: %s\n", bu_vls_addr(seg->ov_reg2_name)); + bu_log(" ov_reg1_id: %d\n", seg->ov_reg1_id); + bu_log(" ov_reg2_id: %d\n", seg->ov_reg2_id); + bu_log(" ov_in: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->ov_in)); + bu_log(" ov_out: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->ov_out)); + bu_log(" ov_los: %0.17f\n", seg->ov_los); +#endif + nss->i->cdiff->old_segs.push_back(seg); + continue; } - bu_log("Found %s:\n", line.c_str()); - cnt++; - struct nirt_seg *seg; - _nirt_seg_init(&seg); - seg->type = NIRT_GAP_SEG; - seg->id = cnt; - VSET(seg->gap_in, _nirt_str_to_dbl(substrs[0], 0), _nirt_str_to_dbl(substrs[1], 0), _nirt_str_to_dbl(substrs[2], 0)); - VSET(seg->in, _nirt_str_to_dbl(substrs[3], 0), _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0)); - seg->gap_los = _nirt_str_to_dbl(substrs[6], 0); - bu_log("in: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->gap_in)); - bu_log("out: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->in)); - bu_log("gap_los: %0.17f\n", seg->gap_los); - nss->i->diff->segs.push_back(seg); - continue; +#ifdef NIRT_DIFF_DEBUG + nerr(nss, "Warning - unknown line type, skipping: %s\n", line.c_str()); +#endif } - if (!line.compare("MISS")) { - struct nirt_seg *seg; - _nirt_seg_init(&seg); - cnt++; - seg->type = NIRT_MISS_SEG; - seg->id = cnt; - bu_log("Found MISS\n"); - have_ray = 0; - nss->i->diff->segs.push_back(seg); - continue; - } - if (!line.compare(0, 9, "OVERLAP: ")) { - std::string ostr = line.substr(9); - std::vector<std::string> substrs = _nirt_string_split(ostr); - if (substrs.size() != 8) { - nerr(nss, "Error processing overlap line \"%s\"!\nExpected 8 elements, found %d\n", ostr.c_str(), substrs.size()); - return -1; + + if (have_ray) { + // Execute work. + for (int i = 0; i < 3; ++i) { + nss->i->ap->a_ray.r_pt[i] = nss->i->vals->orig[i]; + nss->i->ap->a_ray.r_dir[i] = nss->i->vals->dir[i]; } - bu_log("Found %s:\n", line.c_str()); - cnt++; - struct nirt_seg *seg; - _nirt_seg_init(&seg); - seg->type = NIRT_OVERLAP_SEG; - seg->id = cnt; - bu_vls_decode(seg->ov_reg1_name, substrs[0].c_str()); - bu_vls_decode(seg->ov_reg2_name, substrs[1].c_str()); - seg->ov_reg1_id = _nirt_str_to_int(substrs[2]); - seg->ov_reg2_id = _nirt_str_to_int(substrs[3]); + // TODO - rethink this container... + _nirt_init_ovlp(nss); + (void)rt_shootray(nss->i->ap); + nss->i->diffs.push_back(nss->i->cdiff); - VSET(seg->ov_in, _nirt_str_to_dbl(substrs[4], 0), _nirt_str_to_dbl(substrs[5], 0), _nirt_str_to_dbl(substrs[6], 0)); - seg->ov_los = _nirt_str_to_dbl(substrs[7], 0); - bu_log("ov_reg1_name: %s\n", bu_vls_addr(seg->ov_reg1_name)); - bu_log("ov_reg2_name: %s\n", bu_vls_addr(seg->ov_reg2_name)); - bu_log("ov_reg1_id: %d\n", seg->ov_reg1_id); - bu_log("ov_reg2_id: %d\n", seg->ov_reg2_id); - bu_log("ov_in: %0.17f, %0.17f, %0.17f\n", V3ARGS(seg->ov_in)); - bu_log("ov_los: %0.17f\n", seg->ov_los); - nss->i->diff->segs.push_back(seg); - continue; + // Thought - if we have rays but no pre-defined output, write out the + // expected output to stdout - in this mode diff will generate a diff + // input file from a supplied list of rays. } - nerr(nss, "Warning - unknown line type, skipping: %s\n", line.c_str()); + + ifs.close(); + + // Done with if_hit and friends + nss->i->cdiff = NULL; + nss->i->diff_run = 0; + nss->i->diff_ready = 1; + return 0; } - if (have_ray) { - // Execute work. - for (int i = 0; i < 3; ++i) { - nss->i->ap->a_ray.r_pt[i] = nss->i->vals->orig[i]; - nss->i->ap->a_ray.r_dir[i] = nss->i->vals->dir[i]; - } - // TODO - rethink this container... - _nirt_init_ovlp(nss); - (void)rt_shootray(nss->i->ap); - if (nss->i->diff->diffs.size() > 0) { - nss->i->diffs.push_back(nss->i->diff); + if (BU_STR_EQUAL(argv[0], "report")) { + // Report diff results according to the NIRT diff settings. + if (!nss->i->diff_ready) { + nerr(nss, "No diff file loaded - please load a diff file with \"diff load <filename>\"\n"); + return -1; } else { - delete nss->i->diff; + return (_nirt_diff_report(nss) >= 0) ? 0 : -1; } + } - // Thought - if we have rays but no pre-defined output, write out the - // expected output to stdout - in this mode diff will generate a diff - // input file from a supplied list of rays. + if (BU_STR_EQUAL(argv[0], "clear")) { + // need clear command to scrub old nss->i->diffs + for (size_t i = 0; i < nss->i->diffs.size(); i++) { + struct nirt_diff *df = nss->i->diffs[i]; + for (size_t j = 0; j < df->old_segs.size(); j++) { + _nirt_seg_free(df->old_segs[j]); + } + for (size_t j = 0; j < df->new_segs.size(); j++) { + _nirt_seg_free(df->new_segs[j]); + } + delete nss->i->diffs[i]; + } + nss->i->diffs.clear(); + nss->i->diff_ready = 0; + return 0; } + if (BU_STR_EQUAL(argv[0], "settings")) { + ac--; argv++; + if (!ac) { + //print current settings + nout(nss, "report_partitions: %d\n", nss->i->diff_settings->report_partitions); + nout(nss, "report_misses: %d\n", nss->i->diff_settings->report_misses); + nout(nss, "report_gaps: %d\n", nss->i->diff_settings->report_gaps); + nout(nss, "report_overlaps: %d\n", nss->i->diff_settings->report_overlaps); + nout(nss, "report_partition_reg_ids: %d\n", nss->i->diff_settings->report_partition_reg_ids); + nout(nss, "report_partition_reg_names: %d\n", nss->i->diff_settings->report_partition_reg_names); + nout(nss, "report_partition_path_names: %d\n", nss->i->diff_settings->report_partition_path_names); + nout(nss, "report_partition_dists: %d\n", nss->i->diff_settings->report_partition_dists); + nout(nss, "report_partition_obliq: %d\n", nss->i->diff_settings->report_partition_obliq); + nout(nss, "report_overlap_reg_names: %d\n", nss->i->diff_settings->report_overlap_reg_names); + nout(nss, "report_overlap_reg_ids: %d\n", nss->i->diff_settings->report_overlap_reg_ids); + nout(nss, "report_overlap_dists: %d\n", nss->i->diff_settings->report_overlap_dists); + nout(nss, "report_overlap_obliq: %d\n", nss->i->diff_settings->report_overlap_obliq); + nout(nss, "report_gap_dists: %d\n", nss->i->diff_settings->report_gap_dists); + nout(nss, "dist_delta_tol: %g\n", nss->i->diff_settings->dist_delta_tol); + nout(nss, "obliq_delta_tol: %g\n", nss->i->diff_settings->obliq_delta_tol); + nout(nss, "los_delta_tol: %g\n", nss->i->diff_settings->los_delta_tol); + nout(nss, "scaled_los_delta_tol: %g\n", nss->i->diff_settings->scaled_los_delta_tol); + return 0; + } + if (ac == 1) { + //print specific setting + if (BU_STR_EQUAL(argv[0], "report_partitions")) nout(nss, "%d\n", nss->i->diff_settings->report_partitions); + if (BU_STR_EQUAL(argv[0], "report_misses")) nout(nss, "%d\n", nss->i->diff_settings->report_misses); + if (BU_STR_EQUAL(argv[0], "report_gaps")) nout(nss, "%d\n", nss->i->diff_settings->report_gaps); + if (BU_STR_EQUAL(argv[0], "report_overlaps")) nout(nss, "%d\n", nss->i->diff_settings->report_overlaps); + if (BU_STR_EQUAL(argv[0], "report_partition_reg_ids")) nout(nss, "%d\n", nss->i->diff_settings->report_partition_reg_ids); + if (BU_STR_EQUAL(argv[0], "report_partition_reg_names")) nout(nss, "%d\n", nss->i->diff_settings->report_partition_reg_names); + if (BU_STR_EQUAL(argv[0], "report_partition_path_names")) nout(nss, "%d\n", nss->i->diff_settings->report_partition_path_names); + if (BU_STR_EQUAL(argv[0], "report_partition_dists")) nout(nss, "%d\n", nss->i->diff_settings->report_partition_dists); + if (BU_STR_EQUAL(argv[0], "report_partition_obliq")) nout(nss, "%d\n", nss->i->diff_settings->report_partition_obliq); + if (BU_STR_EQUAL(argv[0], "report_overlap_reg_names")) nout(nss, "%d\n", nss->i->diff_settings->report_overlap_reg_names); + if (BU_STR_EQUAL(argv[0], "report_overlap_reg_ids")) nout(nss, "%d\n", nss->i->diff_settings->report_overlap_reg_ids); + if (BU_STR_EQUAL(argv[0], "report_overlap_dists")) nout(nss, "%d\n", nss->i->diff_settings->report_overlap_dists); + if (BU_STR_EQUAL(argv[0], "report_overlap_obliq")) nout(nss, "%d\n", nss->i->diff_settings->report_overlap_obliq); + if (BU_STR_EQUAL(argv[0], "report_gap_dists")) nout(nss, "%d\n", nss->i->diff_settings->report_gap_dists); + if (BU_STR_EQUAL(argv[0], "dist_delta_tol")) nout(nss, "%g\n", nss->i->diff_settings->dist_delta_tol); + if (BU_STR_EQUAL(argv[0], "obliq_delta_tol")) nout(nss, "%g\n", nss->i->diff_settings->obliq_delta_tol); + if (BU_STR_EQUAL(argv[0], "los_delta_tol")) nout(nss, "%g\n", nss->i->diff_settings->los_delta_tol); + if (BU_STR_EQUAL(argv[0], "scaled_los_delta_tol")) nout(nss, "%g\n", nss->i->diff_settings->scaled_los_delta_tol); + return 0; + } + if (ac == 2) { + //set setting + struct bu_vls opt_msg = BU_VLS_INIT_ZERO; + int *setting_int = NULL; + fastf_t *setting_fastf_t = NULL; + if (BU_STR_EQUAL(argv[0], "report_partitions")) setting_int = &(nss->i->diff_settings->report_partitions); + if (BU_STR_EQUAL(argv[0], "report_misses")) setting_int = &(nss->i->diff_settings->report_misses); + if (BU_STR_EQUAL(argv[0], "report_gaps")) setting_int = &(nss->i->diff_settings->report_gaps); + if (BU_STR_EQUAL(argv[0], "report_overlaps")) setting_int = &(nss->i->diff_settings->report_overlaps); + if (BU_STR_EQUAL(argv[0], "report_partition_reg_ids")) setting_int = &(nss->i->diff_settings->report_partition_reg_ids); + if (BU_STR_EQUAL(argv[0], "report_partition_reg_names")) setting_int = &(nss->i->diff_settings->report_partition_reg_names); + if (BU_STR_EQUAL(argv[0], "report_partition_path_names")) setting_int = &(nss->i->diff_settings->report_partition_path_names); + if (BU_STR_EQUAL(argv[0], "report_partition_dists")) setting_int = &(nss->i->diff_settings->report_partition_dists); + if (BU_STR_EQUAL(argv[0], "report_partition_obliq")) setting_int = &(nss->i->diff_settings->report_partition_obliq); + if (BU_STR_EQUAL(argv[0], "report_overlap_reg_names")) setting_int = &(nss->i->diff_settings->report_overlap_reg_names); + if (BU_STR_EQUAL(argv[0], "report_overlap_reg_ids")) setting_int = &(nss->i->diff_settings->report_overlap_reg_ids); + if (BU_STR_EQUAL(argv[0], "report_overlap_dists")) setting_int = &(nss->i->diff_settings->report_overlap_dists); + if (BU_STR_EQUAL(argv[0], "report_overlap_obliq")) setting_int = &(nss->i->diff_settings->report_overlap_obliq); + if (BU_STR_EQUAL(argv[0], "report_gap_dists")) setting_int = &(nss->i->diff_settings->report_gap_dists); + if (BU_STR_EQUAL(argv[0], "dist_delta_tol")) setting_fastf_t = &(nss->i->diff_settings->dist_delta_tol); + if (BU_STR_EQUAL(argv[0], "obliq_delta_tol")) setting_fastf_t = &(nss->i->diff_settings->obliq_delta_tol); + if (BU_STR_EQUAL(argv[0], "los_delta_tol")) setting_fastf_t = &(nss->i->diff_settings->los_delta_tol); + if (BU_STR_EQUAL(argv[0], "scaled_los_delta_tol")) setting_fastf_t = &(nss->i->diff_settings->scaled_los_delta_tol); - ifs.close(); + if (setting_int) { + if (bu_opt_int(&opt_msg, 1, (const char **)&argv[1], (void *)setting_int) == -1) { + nerr(nss, "Error: bu_opt value read failure: %s\n", bu_vls_addr(&opt_msg)); + bu_vls_free(&opt_msg); + return -1; + } else { + return 0; + } + } + if (setting_fastf_t) { + if (BU_STR_EQUAL(argv[1], "BN_TOL_DIST")) { + *setting_fastf_t = BN_TOL_DIST; + return 0; + } else { + if (bu_opt_fastf_t(&opt_msg, 1, (const char **)&argv[1], (void *)setting_fastf_t) == -1) { + nerr(nss, "Error: bu_opt value read failure: %s\n", bu_vls_addr(&opt_msg)); + bu_vls_free(&opt_msg); + return -1; + } else { + return 0; + } + } + } - // Report diff results according to the supplied options. - (void)_nirt_diff_report(nss); + // anything else is an error + return -1; + } + } - return 0; + nerr(nss, "Unknown diff subcommand: \"%s\"\n", argv[0]); + + return -1; } @@ -3458,6 +3628,7 @@ /* Get memory */ n = new nirt_state_impl; ns->i = n; + n->overlap_claims = NIRT_OVLP_RESOLVE; BU_GET(n->hit_odd_color, struct bu_color); BU_GET(n->hit_even_color, struct bu_color); BU_GET(n->void_color, struct bu_color); @@ -3523,6 +3694,11 @@ bu_avs_init_empty(n->val_types); bu_avs_init_empty(n->val_docs); + BU_GET(n->diff_file, struct bu_vls); + bu_vls_init(n->diff_file); + n->cdiff = NULL; + n->diff_run = 0; + n->diff_ready = 0; BU_GET(n->diff_settings, struct nirt_diff_settings); n->diff_settings->report_partitions = 1; n->diff_settings->report_misses = 1; @@ -3671,6 +3847,7 @@ bu_vls_free(ns->i->err); bu_vls_free(ns->i->msg); bu_vls_free(ns->i->out); + bu_vls_free(ns->i->diff_file); bn_vlist_cleanup(&(ns->i->s_vlist)); bn_vlblock_free(ns->i->segs); @@ -3687,6 +3864,7 @@ BU_PUT(ns->i->err, struct bu_vls); BU_PUT(ns->i->msg, struct bu_vls); BU_PUT(ns->i->out, struct bu_vls); + BU_PUT(ns->i->diff_file, struct bu_vls); BU_PUT(ns->i->ap, struct application); BU_PUT(ns->i->hit_odd_color, struct bu_color); BU_PUT(ns->i->hit_even_color, struct bu_color); Modified: brlcad/trunk/src/nirt/CMakeLists.txt =================================================================== --- brlcad/trunk/src/nirt/CMakeLists.txt 2018-03-04 21:58:22 UTC (rev 70794) +++ brlcad/trunk/src/nirt/CMakeLists.txt 2018-03-04 22:06:02 UTC (rev 70795) @@ -35,6 +35,7 @@ sfiles/csv.nrt sfiles/csv-gap.nrt sfiles/default.nrt + sfiles/diff.nrt sfiles/entryexit.nrt sfiles/gap1.nrt sfiles/gap2.nrt Modified: brlcad/trunk/src/nirt/main.cxx =================================================================== --- brlcad/trunk/src/nirt/main.cxx 2018-03-04 21:58:22 UTC (rev 70794) +++ brlcad/trunk/src/nirt/main.cxx 2018-03-04 22:06:02 UTC (rev 70795) @@ -30,9 +30,12 @@ #include <string> #include <iostream> #include <limits> +#include <cstdio> +#include <cstring> /* needed on mac in c90 mode */ #ifndef HAVE_DECL_FSEEKO +#include <sys/types.h> /* for off_t */ extern "C" int fseeko(FILE *, off_t, int); extern "C" off_t ftello(FILE *); #endif Added: brlcad/trunk/src/nirt/sfiles/diff.nrt =================================================================== --- brlcad/trunk/src/nirt/sfiles/diff.nrt (rev 0) +++ brlcad/trunk/src/nirt/sfiles/diff.nrt 2018-03-04 22:06:02 UTC (rev 70795) @@ -0,0 +1,12 @@ +# diff.nrt +# Description: Output formatted for processing by the NIRT diff command. The +# numbers after each label (RAY, HIT, etc.) are for versioning purposes, to allow +# new variations on this format to be processed while allowing for backwards +# compatibility. +fmt r "RAY 01: %.17f,%.17f,%.17f,%.17f,%.17f,%.17f\n" x_orig y_orig z_orig x_dir y_dir z_dir +fmt h "" +fmt p "HIT 01: \"%s\",\"%s\",%d,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f\n" reg_name path_name reg_id x_in y_in z_in d_in x_out y_out z_out d_out los scaled_los obliq_in obliq_out +fmt f "" +fmt m "MISS 01\n" +fmt o "OVERLAP 01: \"%s\",\"%s\",%d,%d,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f\n" ov_reg1_name ov_reg2_name ov_reg1_id ov_reg2_id ov_x_in ov_y_in ov_z_in ov_x_out ov_y_out ov_z_out ov_los +fmt g "GAP 01: %.17f,%.17f,%.17f,%.17f,%.17f,%.17f,%.17f\n" x_gap_in y_gap_in z_gap_in x_in y_in z_in gap_los Property changes on: brlcad/trunk/src/nirt/sfiles/diff.nrt ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits