Revision: 69075
          http://sourceforge.net/p/brlcad/code/69075
Author:   starseeker
Date:     2016-10-16 14:28:31 +0000 (Sun, 16 Oct 2016)
Log Message:
-----------
I doubt this whole re_nmgfree list will survive long term, but in the short 
term it's coupling nmg to the RTG global.  Make it an nmg.h global.  Also start 
roughing out the nessary bits to get the ray intersection test needed by 
nmg_class to be self contained.

Modified Paths:
--------------
    brlcad/trunk/include/nmg.h
    brlcad/trunk/include/rt/nmg.h
    brlcad/trunk/src/conv/g-shell-rect.c
    brlcad/trunk/src/librt/prep.c
    brlcad/trunk/src/librt/primitives/nmg/nmg.c
    brlcad/trunk/src/librt/primitives/nmg/nmg_inter.c
    brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c
    brlcad/trunk/src/librt/primitives/nmg/nmg_rt_isect.c

Modified: brlcad/trunk/include/nmg.h
===================================================================
--- brlcad/trunk/include/nmg.h  2016-10-16 13:27:29 UTC (rev 69074)
+++ brlcad/trunk/include/nmg.h  2016-10-16 14:28:31 UTC (rev 69075)
@@ -825,7 +825,137 @@
 };
 #define NMG_CK_INTER_STRUCT(_p) NMG_CKMAG(_p, NMG_INTER_STRUCT_MAGIC, 
"nmg_inter_struct")
 
+/* TODO - these structs and ray_in_rpp are versions of librt functionality,
+ * and we need to think about how/where to merge them into a common function
+ * and struct that are available to both libraries without introducing a
+ * coupling dependency. */
+
+RT_EXPORT extern struct bu_list re_nmgfree;     /**< @brief  head of NMG 
hitmiss freelist */
+#define NMG_GET_HITMISS(_p) { \
+            (_p) = BU_LIST_FIRST(hitmiss, &(re_nmgfree)); \
+            if (BU_LIST_IS_HEAD((_p), &(re_nmgfree))) \
+                BU_ALLOC((_p), struct hitmiss); \
+            else \
+                BU_LIST_DEQUEUE(&((_p)->l)); \
+        }
+
+
+#define NMG_FREE_HITLIST(_p) { \
+            BU_CK_LIST_HEAD((_p)); \
+            BU_LIST_APPEND_LIST(&(re_nmgfree), (_p)); \
+        }
+#define HIT 1   /**< @brief  a hit on a face */
+#define MISS 0  /**< @brief  a miss on the face */
+
+
+struct nmg_ray {
+    point_t             r_pt;           /**< @brief Point at which ray starts 
*/
+    vect_t              r_dir;          /**< @brief Direction of ray (UNIT 
Length) */
+    fastf_t             r_min;          /**< @brief entry dist to bounding 
sphere */
+    fastf_t             r_max;          /**< @brief exit dist from bounding 
sphere */
+};
+
+struct nmg_hit {
+    uint32_t           hit_magic;
+    fastf_t             hit_dist;       /**< @brief dist from r_pt to 
hit_point */
+    point_t             hit_point;      /**< @brief DEPRECATED: Intersection 
point, use VJOIN1 hit_dist */
+    vect_t              hit_normal;     /**< @brief DEPRECATED: Surface Normal 
at hit_point, use RT_HIT_NORMAL */
+    void *              hit_private;    /**< @brief PRIVATE handle for 
xxx_shot() */ 
+    int                 hit_surfno;     /**< @brief solid-specific surface 
indicator */
+    struct nmg_ray *    hit_rayp;       /**< @brief pointer to defining ray */
+};
+
+struct nmg_seg {
+    struct bu_list      l;
+    struct nmg_hit      seg_in;         /**< @brief IN information */
+    struct nmg_hit      seg_out;        /**< @brief OUT information */
+};
+
+struct nmg_hitmiss {
+    struct bu_list      l;
+    struct nmg_hit      hit;
+    fastf_t             dist_in_plane;  /**< @brief  distance from plane 
intersect */
+    int                 in_out;         /**< @brief  status of ray as it 
transitions
+                                         * this hit point.
+                                         */
+    long                *inbound_use;
+    vect_t              inbound_norm;
+    long                *outbound_use;
+    vect_t              outbound_norm;
+    int                 start_stop;     /**< @brief  is this a seg_in or 
seg_out */
+    struct nmg_hitmiss  *other;         /**< @brief  for keeping track of the 
other
+                                         * end of the segment when we know
+                                         * it
+                                         */
+};
+
 /**
+ * Ray Data structure
+ *
+ * A) the hitmiss table has one element for each nmg structure in the
+ * nmgmodel.  The table keeps track of which elements have been
+ * processed before and which haven't.  Elements in this table will
+ * either be: (NULL) item not previously processed hitmiss ptr item
+ * previously processed
+ *
+ * the 0th item in the array is a pointer to the head of the "hit"
+ * list.  The 1th item in the array is a pointer to the head of the
+ * "miss" list.
+ *
+ * B) If plane_pt is non-null then we are currently processing a face
+ * intersection.  The plane_dist and ray_dist_to_plane are valid.  The
+ * ray/edge intersector should check the distance from the plane
+ * intercept to the edge and update "plane_closest" if the current
+ * edge is closer to the intercept than the previous closest object.
+ */
+struct nmg_ray_data {
+    uint32_t            magic;
+    struct model        *rd_m;
+    char                *manifolds; /**< @brief   structure 1-3manifold table 
*/
+    vect_t              rd_invdir;
+    struct nmg_ray      *rp;
+    struct seg          *seghead;
+    const struct bn_tol *tol;
+    struct nmg_hitmiss  **hitmiss;      /**< @brief  1 struct hitmiss ptr per 
elem. */
+    struct bu_list      rd_hit;         /**< @brief  list of hit elements */
+    struct bu_list      rd_miss;        /**< @brief  list of missed/sub-hit 
elements */
+
+/* The following are to support isect_ray_face() */
+
+    /**
+     * plane_pt is the intercept point of the ray with the plane of
+     * the face.
+     */
+    point_t             plane_pt;       /**< @brief  ray/plane(face) intercept 
point */
+
+    /**
+     * ray_dist_to_plane is the parametric distance along the ray from
+     * the ray origin (rd->rp->r_pt) to the ray/plane intercept point
+     */
+    fastf_t             ray_dist_to_plane; /**< @brief  ray parametric dist to 
plane */
+
+    /**
+     * the "face_subhit" element is a boolean used by isect_ray_face
+     * and [e|v]u_touch_func to record the fact that the
+     * ray/(plane/face) intercept point was within tolerance of an
+     * edge/vertex of the face.  In such instances, isect_ray_face
+     * does NOT need to generate a hit point for the face, as the hit
+     * point for the edge/vertex will suffice.
+     */
+    int                 face_subhit;
+
+    /**
+     * the "classifying_ray" flag indicates that this ray is being
+     * used to classify a point, so that the "eu_touch" and "vu_touch"
+     * functions should not be called.
+     */
+    int                 classifying_ray;
+};
+
+
+
+
+/**
  * global nmg animation vblock callback
  */
 RT_EXPORT extern void (*nmg_vlblock_anim_upcall)(void);
@@ -2276,8 +2406,21 @@
                                        struct model *m2);
 RT_EXPORT extern long nmg_find_max_index(const struct model *m);
 
+#if 0
+/* From nmg_rt_isect.c */
+RT_EXPORT extern void nmg_rt_print_hitlist(struct bu_list *hd);
 
+RT_EXPORT extern void nmg_rt_print_hitmiss(struct nmg_hitmiss *a_hit);
 
+RT_EXPORT extern int nmg_class_ray_vs_shell(struct nmg_ray *rp,
+                                            const struct shell *s,
+                                            const int in_or_out_only,
+                                           struct bu_list *vlfree,
+                                            const struct bn_tol *tol);
+
+RT_EXPORT extern void nmg_isect_ray_model(struct nmg_ray_data *rd, struct 
bu_list *vlfree);
+#endif
+
 __END_DECLS
 
 #endif /* NMG_H */

Modified: brlcad/trunk/include/rt/nmg.h
===================================================================
--- brlcad/trunk/include/rt/nmg.h       2016-10-16 13:27:29 UTC (rev 69074)
+++ brlcad/trunk/include/rt/nmg.h       2016-10-16 14:28:31 UTC (rev 69075)
@@ -37,12 +37,6 @@
 
 __BEGIN_DECLS
 
-/*********************************************************************************
- *      The following section is an exact copy of what was previously 
"nmg_rt.h" *
- *      (with minor changes to NMG_GET_HITMISS and NMG_FREE_HITLIST            
  *
- *      moved here to use RTG.rtg_nmgfree freelist for hitmiss structs.        
 *
- 
******************************************************************************* 
*/
-
 struct rt_db_internal; /*forward declaration*/
 
 #define NMG_HIT_LIST    0
@@ -208,25 +202,6 @@
 #define NMG_CK_RD(_rd) NMG_CKMAG(_rd, NMG_RAY_DATA_MAGIC, "ray data");
 
 
-#define NMG_GET_HITMISS(_p, _ap) { \
-        (_p) = BU_LIST_FIRST(hitmiss, &((_ap)->a_resource->re_nmgfree)); \
-        if (BU_LIST_IS_HEAD((_p), &((_ap)->a_resource->re_nmgfree))) \
-            BU_ALLOC((_p), struct hitmiss); \
-        else \
-            BU_LIST_DEQUEUE(&((_p)->l)); \
-    }
-
-
-#define NMG_FREE_HITLIST(_p, _ap) { \
-        BU_CK_LIST_HEAD((_p)); \
-        BU_LIST_APPEND_LIST(&((_ap)->a_resource->re_nmgfree), (_p)); \
-    }
-
-
-#define HIT 1   /**< @brief  a hit on a face */
-#define MISS 0  /**< @brief  a miss on the face */
-
-
 #ifdef NO_BOMBING_MACROS
 #  define nmg_bu_bomb(rd, vlfree, str) (void)(rd)
 #else

Modified: brlcad/trunk/src/conv/g-shell-rect.c
===================================================================
--- brlcad/trunk/src/conv/g-shell-rect.c        2016-10-16 13:27:29 UTC (rev 
69074)
+++ brlcad/trunk/src/conv/g-shell-rect.c        2016-10-16 14:28:31 UTC (rev 
69075)
@@ -459,12 +459,12 @@
        a_hit = BU_LIST_LAST(hitmiss, &rd.rd_hit);
        VMOVE(hit2, a_hit->hit.hit_point);
 
-       NMG_FREE_HITLIST(&rd.rd_hit, ap);
+       NMG_FREE_HITLIST(&rd.rd_hit);
 
        ret = 1;
     }
 
-    NMG_FREE_HITLIST(&rd.rd_miss, ap);
+    NMG_FREE_HITLIST(&rd.rd_miss);
 
     return ret;
 }

Modified: brlcad/trunk/src/librt/prep.c
===================================================================
--- brlcad/trunk/src/librt/prep.c       2016-10-16 13:27:29 UTC (rev 69074)
+++ brlcad/trunk/src/librt/prep.c       2016-10-16 14:28:31 UTC (rev 69075)
@@ -708,8 +708,10 @@
     if (!BU_LIST_IS_INITIALIZED(&resp->re_region_ptbl))
        BU_LIST_INIT(&resp->re_region_ptbl);
 
-    if (!BU_LIST_IS_INITIALIZED(&resp->re_nmgfree))
-       BU_LIST_INIT(&resp->re_nmgfree);
+    /* transitioning to using a global independent of the librt
+     * structures as an intermediate step during lib refactoring */
+    if (!BU_LIST_IS_INITIALIZED(&re_nmgfree))
+       BU_LIST_INIT(&re_nmgfree);
 
     resp->re_boolstack = NULL;
     resp->re_boolslen = 0;
@@ -763,14 +765,14 @@
     }
 
     /* The "struct hitmiss' guys are individually malloc()ed */
-    if (BU_LIST_IS_INITIALIZED(&resp->re_nmgfree)) {
+    if (BU_LIST_IS_INITIALIZED(&re_nmgfree)) {
        struct hitmiss *hitp;
-       while (BU_LIST_WHILE(hitp, hitmiss, &resp->re_nmgfree)) {
+       while (BU_LIST_WHILE(hitp, hitmiss, &re_nmgfree)) {
            NMG_CK_HITMISS(hitp);
            BU_LIST_DEQUEUE((struct bu_list *)hitp);
            bu_free((void *)hitp, "struct hitmiss");
        }
-       resp->re_nmgfree.forw = BU_LIST_NULL;
+       re_nmgfree.forw = BU_LIST_NULL;
     }
 
     /* The 'struct partition' guys are individually malloc()ed */

Modified: brlcad/trunk/src/librt/primitives/nmg/nmg.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg.c 2016-10-16 13:27:29 UTC (rev 
69074)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg.c 2016-10-16 14:28:31 UTC (rev 
69075)
@@ -1259,7 +1259,7 @@
 
     if (BU_LIST_IS_EMPTY(&rd->rd_hit)) {
 
-       NMG_FREE_HITLIST(&rd->rd_miss, rd->ap);
+       NMG_FREE_HITLIST(&rd->rd_miss);
 
        if (nmg_debug & DEBUG_RT_SEGS) {
            if (last_miss) bu_log(".");
@@ -1281,8 +1281,8 @@
     last_miss = 0;
 
     if (check_hitstate(&rd->rd_hit, rd, vlfree)) {
-       NMG_FREE_HITLIST(&rd->rd_hit, rd->ap);
-       NMG_FREE_HITLIST(&rd->rd_miss, rd->ap);
+       NMG_FREE_HITLIST(&rd->rd_hit);
+       NMG_FREE_HITLIST(&rd->rd_miss);
        return 0;
     }
 
@@ -1298,8 +1298,8 @@
        int seg_count = nmg_bsegs(rd, rd->ap, rd->seghead, rd->stp);
 
 
-       NMG_FREE_HITLIST(&rd->rd_hit, rd->ap);
-       NMG_FREE_HITLIST(&rd->rd_miss, rd->ap);
+       NMG_FREE_HITLIST(&rd->rd_hit);
+       NMG_FREE_HITLIST(&rd->rd_miss);
 
 
        if (nmg_debug & DEBUG_RT_SEGS) {

Modified: brlcad/trunk/src/librt/primitives/nmg/nmg_inter.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg_inter.c   2016-10-16 13:27:29 UTC 
(rev 69074)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg_inter.c   2016-10-16 14:28:31 UTC 
(rev 69075)
@@ -2000,19 +2000,6 @@
     return discards;
 }
 
-
-/* TODO - this struct and ray_in_rpp are versions of librt functionality,
- * and we need to think about how/where to merge them into a common function
- * and struct that are available to both libraries without introducing a
- * coupling dependency. */
-struct nmg_ray {
-    point_t             r_pt;           /**< @brief Point at which ray starts 
*/
-    vect_t              r_dir;          /**< @brief Direction of ray (UNIT 
Length) */
-    fastf_t             r_min;          /**< @brief entry dist to bounding 
sphere */
-    fastf_t             r_max;          /**< @brief exit dist from bounding 
sphere */
-};
-
-
 HIDDEN int
 ray_in_rpp(struct nmg_ray *rp,
           register const fastf_t *invdir,       /* inverses of rp->r_dir[] */

Modified: brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c    2016-10-16 13:27:29 UTC 
(rev 69074)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c    2016-10-16 14:28:31 UTC 
(rev 69075)
@@ -41,6 +41,7 @@
 
 /* externed */
 uint32_t nmg_debug;
+struct bu_list re_nmgfree;     /**< @brief  head of NMG hitmiss freelist */
 
 int
 nmg_snurb_calc_lu_uv_orient(const struct loopuse *lu)

Modified: brlcad/trunk/src/librt/primitives/nmg/nmg_rt_isect.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg_rt_isect.c        2016-10-16 
13:27:29 UTC (rev 69074)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg_rt_isect.c        2016-10-16 
14:28:31 UTC (rev 69075)
@@ -324,7 +324,7 @@
        return myhit;
     }
 
-    NMG_GET_HITMISS(myhit, rd->ap);
+    NMG_GET_HITMISS(myhit);
     NMG_INDEX_ASSIGN(rd->hitmiss, vu_p->v_p, myhit);
     myhit->outbound_use = (long *)vu_p;
     myhit->inbound_use = (long *)vu_p;
@@ -977,7 +977,7 @@
        /* oops, we have to change a MISS into a HIT */
        BU_LIST_DEQUEUE(&myhit->l);
     } else {
-       NMG_GET_HITMISS(myhit, rd->ap);
+       NMG_GET_HITMISS(myhit);
        NMG_INDEX_ASSIGN(rd->hitmiss, vu_p->v_p, myhit);
        myhit->outbound_use = (long *)vu_p;
        myhit->inbound_use = (long *)vu_p;
@@ -1114,7 +1114,7 @@
     vhit1->other = vhit2;
     vhit2->other = vhit1;
 
-    NMG_GET_HITMISS(myhit, rd->ap);
+    NMG_GET_HITMISS(myhit);
     NMG_INDEX_ASSIGN(rd->hitmiss, eu_p->e_p, myhit);
     myhit->hit.hit_private = (void *)eu_p->e_p;
 
@@ -1138,7 +1138,7 @@
            ray_hit_vertex(rd, vu_p, NMG_VERT_ENTER_LEAVE); \
        else \
            ray_hit_vertex(rd, vu_p, NMG_VERT_UNKNOWN); \
-       NMG_GET_HITMISS(myhit, rd->ap); \
+       NMG_GET_HITMISS(myhit); \
        NMG_INDEX_ASSIGN(rd->hitmiss, eu_p->e_p, myhit); \
        myhit->hit.hit_private = (void *)eu_p->e_p; \
        \
@@ -1386,7 +1386,7 @@
                break;
        }
     } else {
-       NMG_GET_HITMISS(myhit, rd->ap);
+       NMG_GET_HITMISS(myhit);
     }
 
     /* create hit structure for this edge */
@@ -1447,7 +1447,7 @@
            vhit1 = isect_ray_vertexuse(rd, eu_p->vu_p);
            vhit2 = isect_ray_vertexuse(rd, eu_p->eumate_p->vu_p);
 
-           NMG_GET_HITMISS(myhit, rd->ap);
+           NMG_GET_HITMISS(myhit);
            NMG_INDEX_ASSIGN(rd->hitmiss, eu_p->e_p, myhit);
 
            myhit->hit.hit_private = (void *)eu_p->e_p;
@@ -1476,7 +1476,7 @@
            (void)ray_miss_vertex(rd, eu_p->eumate_p->vu_p);
 
            /* record the fact that we missed the edge */
-           NMG_GET_HITMISS(myhit, rd->ap);
+           NMG_GET_HITMISS(myhit);
            NMG_INDEX_ASSIGN(rd->hitmiss, eu_p->e_p, myhit);
            myhit->hit.hit_private = (void *)eu_p->e_p;
 
@@ -1491,7 +1491,7 @@
            ray_miss_vertex(rd, eu_p->vu_p);
            ray_miss_vertex(rd, eu_p->eumate_p->vu_p);
 
-           NMG_GET_HITMISS(myhit, rd->ap);
+           NMG_GET_HITMISS(myhit);
            NMG_INDEX_ASSIGN(rd->hitmiss, eu_p->e_p, myhit);
            myhit->hit.hit_private = (void *)eu_p->e_p;
 
@@ -1958,7 +1958,7 @@
                continue;
            }
 
-           NMG_GET_HITMISS(myhit, rd->ap);
+           NMG_GET_HITMISS(myhit);
            NMG_INDEX_ASSIGN(rd->hitmiss, fu->f_p, myhit);
            myhit->hit.hit_private = (void *)fu->f_p;
            myhit->inbound_use = myhit->outbound_use = (long *)&fu->l.magic;
@@ -2139,7 +2139,7 @@
                                          rd->tol);
 
 
-    NMG_GET_HITMISS(myhit, rd->ap);
+    NMG_GET_HITMISS(myhit);
     NMG_INDEX_ASSIGN(rd->hitmiss, fu_p->f_p, myhit);
     myhit->hit.hit_private = (void *)fu_p->f_p;
     myhit->hit.hit_surfno = fu_p->f_p->index;
@@ -2256,7 +2256,7 @@
 
        code = bn_isect_line3_plane(&dist, rd->rp->r_pt, rd->rp->r_dir, fgp->N, 
rd->tol);
        if (code < 1) {
-           NMG_GET_HITMISS(myhit, rd->ap);
+           NMG_GET_HITMISS(myhit);
            NMG_INDEX_ASSIGN(rd->hitmiss, fu_p->f_p, myhit);
            myhit->hit.hit_private = (void *)fu_p->f_p;
            myhit->hit.hit_surfno = fu_p->f_p->index;
@@ -2270,7 +2270,7 @@
        dist *= MAGNITUDE(rd->rp->r_dir);
        VJOIN1(hit_pt, rd->rp->r_pt, dist, r_dir_unit);
        if (V3PT_OUT_RPP_TOL(hit_pt, fp->min_pt, fp->max_pt, rd->tol->dist)) {
-           NMG_GET_HITMISS(myhit, rd->ap);
+           NMG_GET_HITMISS(myhit);
            NMG_INDEX_ASSIGN(rd->hitmiss, fu_p->f_p, myhit);
            myhit->hit.hit_private = (void *)fu_p->f_p;
            myhit->hit.hit_surfno = fu_p->f_p->index;
@@ -2286,7 +2286,7 @@
        rd->ray_dist_to_plane = dist;
     } else if (!rt_in_rpp(rd->rp, rd->rd_invdir,
                          fu_p->f_p->min_pt, fu_p->f_p->max_pt)) {
-       NMG_GET_HITMISS(myhit, rd->ap);
+       NMG_GET_HITMISS(myhit);
        NMG_INDEX_ASSIGN(rd->hitmiss, fu_p->f_p, myhit);
        myhit->hit.hit_private = (void *)fu_p->f_p;
        myhit->hit.hit_surfno = fu_p->f_p->index;
@@ -2670,8 +2670,8 @@
     RT_APPLICATION_INIT(&ap);
     ap.a_resource = &rt_uniresource;
 
-    if (!BU_LIST_IS_INITIALIZED(&rt_uniresource.re_nmgfree))
-       BU_LIST_INIT(&rt_uniresource.re_nmgfree);
+    if (!BU_LIST_IS_INITIALIZED(&re_nmgfree))
+       BU_LIST_INIT(&re_nmgfree);
 
     rd.rd_m = nmg_find_model(&s->l.magic);
 
@@ -2732,7 +2732,7 @@
     BU_LIST_INIT(&rd.rd_miss);
 
     nmg_isect_ray_shell(&rd, s, vlfree);
-    NMG_FREE_HITLIST(&rd.rd_miss, &ap);
+    NMG_FREE_HITLIST(&rd.rd_miss);
 
     /* count the number of hits */
     if (nmg_debug & (DEBUG_CLASSIFY|DEBUG_RT_ISECT)) {
@@ -2772,12 +2772,12 @@
        plus_class = NMG_CLASS_Unknown;
     }
 
-    NMG_FREE_HITLIST(&rd.rd_hit, &ap);
+    NMG_FREE_HITLIST(&rd.rd_hit);
 
     /* free the hitmiss freelist, filled during NMG_FREE_HITLIST */
-    if (BU_LIST_IS_INITIALIZED(&rt_uniresource.re_nmgfree)) {
+    if (BU_LIST_IS_INITIALIZED(&re_nmgfree)) {
        struct hitmiss *hitp;
-       while (BU_LIST_WHILE(hitp, hitmiss, &rt_uniresource.re_nmgfree)) {
+       while (BU_LIST_WHILE(hitp, hitmiss, &re_nmgfree)) {
            NMG_CK_HITMISS(hitp);
            BU_LIST_DEQUEUE((struct bu_list *)hitp);
            bu_free((void *)hitp, "struct hitmiss");

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

Reply via email to