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

Reply via email to