Revision: 65338
http://sourceforge.net/p/brlcad/code/65338
Author: starseeker
Date: 2015-06-16 21:27:07 +0000 (Tue, 16 Jun 2015)
Log Message:
-----------
Add the ability to report only left/right rays that appear to be part of a
volume difference, rather than being some sort of grazing or edge case.
Preserve the full reporting with a -G option if we want to see the grazing
differences.
Modified Paths:
--------------
brlcad/trunk/include/analyze.h
brlcad/trunk/src/libanalyze/raydiff.c
brlcad/trunk/src/libanalyze/tests/raydiff.c
brlcad/trunk/src/libged/gdiff.c
Modified: brlcad/trunk/include/analyze.h
===================================================================
--- brlcad/trunk/include/analyze.h 2015-06-16 21:15:55 UTC (rev 65337)
+++ brlcad/trunk/include/analyze.h 2015-06-16 21:27:07 UTC (rev 65338)
@@ -135,11 +135,13 @@
struct diff_seg {
point_t in_pt;
point_t out_pt;
+ struct xray ray;
+ int valid;
};
ANALYZE_EXPORT int
analyze_raydiff(struct analyze_raydiff_results **results, struct db_i *dbip,
- const char *left, const char *right, struct bn_tol *tol);
+ const char *left, const char *right, struct bn_tol *tol, int
solidcheck);
ANALYZE_EXPORT void
analyze_raydiff_results_free(struct analyze_raydiff_results *results);
Modified: brlcad/trunk/src/libanalyze/raydiff.c
===================================================================
--- brlcad/trunk/src/libanalyze/raydiff.c 2015-06-16 21:15:55 UTC (rev
65337)
+++ brlcad/trunk/src/libanalyze/raydiff.c 2015-06-16 21:27:07 UTC (rev
65338)
@@ -29,6 +29,7 @@
#include "vmath.h"
#include "bu/log.h"
#include "bu/ptbl.h"
+#include "bn/mat.h"
#include "raytrace.h"
#include "analyze.h"
@@ -91,6 +92,8 @@
struct bu_ptbl *right;
fastf_t *rays;
int rays_cnt;
+ int cnt;
+ struct bu_ptbl *test;
};
#define RDIFF_ADD_DSEG(_ptbl, p1, p2) {\
@@ -98,6 +101,9 @@
BU_GET(dseg, struct diff_seg); \
VMOVE(dseg->in_pt, p1); \
VMOVE(dseg->out_pt, p2); \
+ VMOVE(dseg->ray.r_pt, ap->a_ray.r_pt); \
+ VMOVE(dseg->ray.r_dir, ap->a_ray.r_dir); \
+ dseg->valid = 0; \
bu_ptbl_ins(_ptbl, (long *)dseg); \
}
@@ -212,10 +218,121 @@
}
+/* TODO - do we care if it's a left or right hit? */
+HIDDEN int
+raycheck_hit(struct application *ap, struct partition *PartHeadp, struct seg
*UNUSED(segs))
+{
+ point_t in_pt, out_pt;
+ struct partition *part;
+ fastf_t part_len = 0.0;
+ struct raydiff_container *state = (struct raydiff_container *)(ap->a_uptr);
+
+ for (part = PartHeadp->pt_forw; part != PartHeadp; part = part->pt_forw) {
+ VJOIN1(in_pt, ap->a_ray.r_pt, part->pt_inhit->hit_dist,
ap->a_ray.r_dir);
+ VJOIN1(out_pt, ap->a_ray.r_pt, part->pt_outhit->hit_dist,
ap->a_ray.r_dir);
+ part_len = DIST_PT_PT(in_pt, out_pt);
+ if (part_len > state->tol) {
+ state->cnt++;
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+
+HIDDEN int
+raycheck_overlap(struct application *ap,
+ struct partition *UNUSED(pp),
+ struct region *UNUSED(reg1),
+ struct region *UNUSED(reg2),
+ struct partition *UNUSED(hp))
+{
+ RT_CK_APPLICATION(ap);
+ return 0;
+}
+
+
+
+HIDDEN void
+raycheck_gen_worker(int cpu, void *ptr)
+{
+ struct application ap;
+ struct raydiff_container *state = &(((struct raydiff_container
*)ptr)[cpu]);
+ fastf_t si, ei;
+ int start_ind, end_ind, i;
+ if (cpu == 0) {
+ /* If we're serial, start at the beginning */
+ start_ind = 0;
+ end_ind = BU_PTBL_LEN(state->test) - 1;
+ } else {
+ si = (fastf_t)(cpu - 1)/(fastf_t)state->ncpus * (fastf_t)
BU_PTBL_LEN(state->test);
+ ei = (fastf_t)cpu/(fastf_t)state->ncpus * (fastf_t)
BU_PTBL_LEN(state->test) - 1;
+ start_ind = (int)si;
+ end_ind = (int)ei;
+ if (BU_PTBL_LEN(state->test) - end_ind < 3) end_ind =
BU_PTBL_LEN(state->test) - 1;
+ /*
+ bu_log("start_ind (%d): %d\n", cpu, start_ind);
+ bu_log("end_ind (%d): %d\n", cpu, end_ind);
+ */
+ }
+
+ RT_APPLICATION_INIT(&ap);
+ ap.a_rt_i = state->rtip;
+ ap.a_hit = raycheck_hit;
+ ap.a_miss = raydiff_miss;
+ ap.a_overlap = raycheck_overlap;
+ ap.a_onehit = 0;
+ ap.a_logoverlap = rt_silent_logoverlap;
+ ap.a_resource = state->resp;
+ ap.a_uptr = (void *)state;
+
+ for (i = start_ind; i <= end_ind; i++) {
+ point_t r_pt;
+ vect_t v1, v2;
+ int valid = 0;
+ struct diff_seg *d = (struct diff_seg *)BU_PTBL_GET(state->test, i);
+ VMOVE(ap.a_ray.r_dir, d->ray.r_dir);
+ /* Construct 4 rays and test around the original hit.*/
+ bn_vec_perp(v1, d->ray.r_dir);
+ VCROSS(v2, v1, d->ray.r_dir);
+ VUNITIZE(v1);
+ VUNITIZE(v2);
+
+ valid = 0;
+ VJOIN2(r_pt, d->ray.r_pt, 0.5 * state->tol, v1, 0.5 * state->tol, v2);
+ state->cnt = 0;
+ VMOVE(ap.a_ray.r_pt, r_pt);
+ rt_shootray(&ap);
+ if (state->cnt) valid++;
+ state->cnt = 0;
+ VJOIN2(r_pt, d->ray.r_pt, -0.5 * state->tol, v1, -0.5 * state->tol, v2);
+ state->cnt = 0;
+ VMOVE(ap.a_ray.r_pt, r_pt);
+ rt_shootray(&ap);
+ if (state->cnt) valid++;
+ VJOIN2(r_pt, d->ray.r_pt, -0.5 * state->tol, v1, 0.5 * state->tol, v2);
+ state->cnt = 0;
+ VMOVE(ap.a_ray.r_pt, r_pt);
+ rt_shootray(&ap);
+ if (state->cnt) valid++;
+ state->cnt = 0;
+ VJOIN2(r_pt, d->ray.r_pt, 0.5 * state->tol, v1, -0.5 * state->tol, v2);
+ state->cnt = 0;
+ VMOVE(ap.a_ray.r_pt, r_pt);
+ rt_shootray(&ap);
+ if (state->cnt) valid++;
+
+ if (valid == 4) {
+ d->valid = 1;
+ }
+ }
+}
+
/* 0 = no difference within tolerance, 1 = difference >= tolerance */
int
analyze_raydiff(struct analyze_raydiff_results **results, struct db_i *dbip,
- const char *left, const char *right, struct bn_tol *tol)
+ const char *left, const char *right, struct bn_tol *tol, int solidcheck)
{
int ret;
int count = 0;
@@ -341,6 +458,7 @@
*/
{
int i, j;
+ struct bu_ptbl test_tbl = BU_PTBL_INIT_ZERO;
/*ncpus = 2;*/
state = (struct raydiff_container *)bu_calloc(ncpus+1, sizeof(struct
raydiff_container), "resources");
for (i = 0; i < ncpus+1; i++) {
@@ -362,20 +480,49 @@
}
bu_parallel(raydiff_gen_worker, ncpus, (void *)state);
+ /* If we want to do a solidity check, do it here. */
+ if (solidcheck) {
+ for (i = 0; i < ncpus+1; i++) {
+ for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) {
+ bu_ptbl_ins(&test_tbl, BU_PTBL_GET(state[i].left, j));
+ }
+ for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
+ bu_ptbl_ins(&test_tbl, BU_PTBL_GET(state[i].right, j));
+ }
+ }
+ for (i = 0; i < ncpus+1; i++) {
+ state[i].test = &test_tbl;
+ }
+ bu_parallel(raycheck_gen_worker, ncpus, (void *)state);
+ } else {
+ /* Not restricting to solids, all are valid */
+ for (i = 0; i < ncpus+1; i++) {
+ for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) {
+ struct diff_seg *d = (struct diff_seg
*)BU_PTBL_GET(state[i].left, j);
+ d->valid = 1;
+ }
+ for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
+ struct diff_seg *d = (struct diff_seg
*)BU_PTBL_GET(state[i].right, j);
+ d->valid = 1;
+ }
+ }
+ }
- /* Now we should have results */
+ /* Collect and print all of the results */
analyze_raydiff_results_init(results);
-
- /* 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++) {
- bu_ptbl_ins((*results)->left, BU_PTBL_GET(state[i].left, j));
+ struct diff_seg *d = (struct diff_seg
*)BU_PTBL_GET(state[i].left, j);
+ if (d->valid)
+ bu_ptbl_ins((*results)->left, (long *)d);
}
for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) {
bu_ptbl_ins((*results)->both, BU_PTBL_GET(state[i].both, j));
}
for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
- bu_ptbl_ins((*results)->right, BU_PTBL_GET(state[i].right, j));
+ struct diff_seg *d = (struct diff_seg
*)BU_PTBL_GET(state[i].right, j);
+ if (d->valid)
+ bu_ptbl_ins((*results)->right, (long *)d);
}
}
Modified: brlcad/trunk/src/libanalyze/tests/raydiff.c
===================================================================
--- brlcad/trunk/src/libanalyze/tests/raydiff.c 2015-06-16 21:15:55 UTC (rev
65337)
+++ brlcad/trunk/src/libanalyze/tests/raydiff.c 2015-06-16 21:27:07 UTC (rev
65338)
@@ -61,7 +61,7 @@
if (dp1 == RT_DIR_NULL || dp2 == RT_DIR_NULL) return 1;
- analyze_raydiff(&results, dbip, dp1->d_namep, dp2->d_namep, &tol);
+ analyze_raydiff(&results, dbip, dp1->d_namep, dp2->d_namep, &tol, 1);
/* Print results */
for (i = 0; i < BU_PTBL_LEN(results->left); i++) {
Modified: brlcad/trunk/src/libged/gdiff.c
===================================================================
--- brlcad/trunk/src/libged/gdiff.c 2015-06-16 21:15:55 UTC (rev 65337)
+++ brlcad/trunk/src/libged/gdiff.c 2015-06-16 21:27:07 UTC (rev 65338)
@@ -53,6 +53,7 @@
int view_left = 0;
int view_right = 0;
int view_overlap = 0;
+ int grazereport = 0;
const char *left_obj;
const char *right_obj;
fastf_t len_tol = BN_TOL_DIST;
@@ -61,13 +62,14 @@
int ac = argc - 1;
const char **av = argv+1;
- struct bu_opt_desc d[6];
+ struct bu_opt_desc d[7];
BU_OPT(d[0], "t", "tol", "#", &bu_opt_fastf_t, (void *)&len_tol,
"Tolerance")
BU_OPT(d[1], "R", "ray-diff", "", NULL, (void *)&do_diff_raytrace, "Test
for differences with raytracing")
BU_OPT(d[2], "l", "view-left", "", NULL, (void *)&view_left, "Visualize
volumes added only by left object")
BU_OPT(d[3], "b", "view-both", "", NULL, (void *)&view_overlap, "Visualize
volumes common to both objects")
BU_OPT(d[4], "r", "view-right", "", NULL, (void *)&view_right, "Visualize
volumes added only by right object")
- BU_OPT_NULL(d[5]);
+ BU_OPT(d[5], "G", "grazing", "", NULL, (void *)&grazereport, "Report
differences in grazing hits (raytracing mode)")
+ BU_OPT_NULL(d[6]);
GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
@@ -147,7 +149,7 @@
if (db_lookup(gedp->ged_wdbp->dbip, right_obj, LOOKUP_NOISY) ==
RT_DIR_NULL) {
return GED_ERROR;
}
- analyze_raydiff(&results, gedp->ged_wdbp->dbip, left_obj, right_obj,
&tol);
+ analyze_raydiff(&results, gedp->ged_wdbp->dbip, left_obj, right_obj,
&tol, !grazereport);
/* TODO - may want to integrate with a "regular" diff and report
intelligently. Needs
* some thought. */
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits