Revision: 77035
          http://sourceforge.net/p/brlcad/code/77035
Author:   brlcad
Date:     2020-09-03 07:13:01 +0000 (Thu, 03 Sep 2020)
Log Message:
-----------
move gcv's only unit test into a subdir like our other libs.

Modified Paths:
--------------
    brlcad/trunk/src/libgcv/CMakeLists.txt

Added Paths:
-----------
    brlcad/trunk/src/libgcv/tests/
    brlcad/trunk/src/libgcv/tests/test_bottess.c

Removed Paths:
-------------
    brlcad/trunk/src/libgcv/test_bottess.c

Modified: brlcad/trunk/src/libgcv/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libgcv/CMakeLists.txt      2020-09-03 07:04:04 UTC (rev 
77034)
+++ brlcad/trunk/src/libgcv/CMakeLists.txt      2020-09-03 07:13:01 UTC (rev 
77035)
@@ -33,14 +33,8 @@
 set_property(SOURCE gcv.c APPEND PROPERTY COMPILE_DEFINITIONS 
"LIBGCV_PLUGINS_PATH=\"${LIBGCV_PLUGINS_PATH}\"")
 set_property(SOURCE gcv.c APPEND PROPERTY COMPILE_DEFINITIONS 
"LIBGCV_PLUGIN_SUFFIX=\"${CMAKE_SHARED_LIBRARY_SUFFIX}\"")
 
-enable_testing()
-BRLCAD_ADDEXEC(test_bottess test_bottess.c libgcv NO_INSTALL)
-if(HIDE_INTERNAL_SYMBOLS)
-  set_property(TARGET test_bottess APPEND PROPERTY COMPILE_DEFINITIONS 
"BOTTESS_DLL_IMPORTS")
-endif(HIDE_INTERNAL_SYMBOLS)
-add_test(NAME bottess_test COMMAND test_bottess)
+add_subdirectory(tests)
 
-
 set(GCV_IGNORE_FILES
   CMakeLists.txt
   NOTES

Deleted: brlcad/trunk/src/libgcv/test_bottess.c
===================================================================
--- brlcad/trunk/src/libgcv/test_bottess.c      2020-09-03 07:04:04 UTC (rev 
77034)
+++ brlcad/trunk/src/libgcv/test_bottess.c      2020-09-03 07:13:01 UTC (rev 
77035)
@@ -1,343 +0,0 @@
-/*                  T E S T _ B O T T E S S . C
- * BRL-CAD
- *
- * Copyright (c) 2011-2020 United States Government as represented by
- * the U.S. Army Research Laboratory.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this file; see the file named COPYING for more
- * information.
- */
-/** @file libgcv/bottess_tester.c
- *
- * Test things in the bottess routines...
- */
-
-#include "common.h"
-
-#include "vmath.h"
-#include "bu/app.h"
-#include "bn.h"
-#include "raytrace.h"
-#include "nmg.h"
-#include "gcv.h"
-
-#include "./soup.h"
-#include "./tri_intersect.h"
-
-int
-test_intersection(int should, point_t *t1, point_t *t2, point_t p1, point_t p2)
-{
-    int coplanar = 0;
-    point_t i[2] = {VINIT_ZERO, VINIT_ZERO};
-    vect_t tmp[2] = {VINIT_ZERO, VINIT_ZERO};
-    struct face_s f[2];
-    struct bn_tol tol;
-
-    BN_TOL_INIT(&tol);
-    tol.dist = 0.005;
-    tol.dist_sq = tol.dist*tol.dist;
-
-    VMOVE(f[0].vert[0], t1[0]);
-    VMOVE(f[0].vert[1], t1[1]);
-    VMOVE(f[0].vert[2], t1[2]);
-    VSUB2(tmp[0], t1[1], t1[0]);
-    VSUB2(tmp[1], t1[2], t1[0]);
-    VCROSS(f[0].plane, tmp[0], tmp[1]);
-    f[0].foo = 0;
-
-    VMOVE(f[1].vert[0], t2[0]);
-    VMOVE(f[1].vert[1], t2[1]);
-    VMOVE(f[1].vert[2], t2[2]);
-    VSUB2(tmp[0], t2[1], t2[0]);
-    VSUB2(tmp[1], t2[2], t2[0]);
-    VCROSS(f[1].plane, tmp[0], tmp[1]);
-    f[1].foo = 0;
-
-    if (gcv_tri_tri_intersect_with_isectline(NULL, NULL, f, f+1, &coplanar, i, 
&tol) == 0 && should == 0)
-       return 0;
-    return !(VNEAR_EQUAL(i[0], p1, tol.dist) && VNEAR_EQUAL(i[1], p2, 
tol.dist));
-}
-
-
-int
-test_tri_intersections()
-{
-    int count = 0;
-#define TRY(suc, t00x, t00y, t00z, t01x, t01y, t01z, t02x, t02y, t02z, t10x, 
t10y, t10z, t11x, t11y, t11z, t12x, t12y, t12z, p0x, p0y, p0z, p1x, p1y, p1z) { 
\
-       point_t t0[3], t1[3], p0, p1; \
-       VSET(t0[0], t00x, t00y, t00z); VSET(t0[1], t01x, t01y, t01z); 
VSET(t0[2], t02x, t02y, t02z); \
-       VSET(t1[0], t10x, t10y, t10z); VSET(t1[1], t11x, t11y, t11z); 
VSET(t1[2], t12x, t12y, t12z); \
-       VSET(p0, p0x, p0y, p0z); VSET(p1, p1x, p1y, p1z); \
-       count += test_intersection(suc, t0, t1, p0, p1); }
-
-    TRY(1, 0, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0, 0, 
.5, 0, .5, .5);  /* ep ef */
-    TRY(0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2, 0.5, 0, 3, 0.5, 1, 2, 0.5, 0, 0, 
.5, 0, .5, .5);  /* no intersect */
-
-#undef TRY
-    return count;
-}
-
-
-static int
-find_tri(struct soup_s *s, struct face_s *f, struct bn_tol *t) {
-    unsigned int i, j, k;
-    for (i=0;i<s->nfaces;i++) {
-       int found[3] = {0, 0, 0};
-       struct face_s *wf = s->faces+i;
-
-       for (j=0;j<3;j++) for (k=0;k<3;k++) if (VNEAR_EQUAL(wf->vert[j], 
f->vert[k], t->dist)) found[j] = 1;
-       if (found[0] == 1 && found[1] == 1 && found[2] == 1) return i;
-    }
-    return -1;
-}
-
-
-int
-test_face_split_single()
-{
-    unsigned long int i, tcount = 0, count = 0, nsplt;
-    struct soup_s s;
-    struct face_s f;
-    struct bn_tol t;
-
-    BN_TOL_INIT(&t);
-    t.dist = 0.005;
-    t.dist_sq = t.dist * t.dist;
-
-    /* evil macros to do a lot of scaffolding, setup, execution, etc... */
-    /* prep take: the triangle to split (9 fastf_t), the intersection line (6
-     * fastf_t), and the number of expected resulting triangles. */
-
-    /* NOTE THE "PREP" AND "POST" MACROS MUST BE USED IN PAIRS DUE TO THE 
SPLIT ENCLOSING CURLY BRACES */
-#define PREP(t00, t01, t02, t10, t11, t12, t20, t21, t22,                      
 \
-            ispt00, ispt01, ispt02, ispt10, ispt11, ispt12, _nsplt)          \
-    {                                                             \
-       point_t isectpt[2];                                         \
-       int urf[_nsplt+1];                                          \
-       unsigned long int failure = 0, numsplit = _nsplt;           \
-       for (i = 0; i < _nsplt + 1; ++i) urf[i] = 0;                \
-       tcount++;                                                   \
-       VSET(isectpt[0], ispt00, ispt01, ispt02);                      \
-       VSET(isectpt[1], ispt10, ispt11, ispt12);                      \
-       s.magic = SOUP_MAGIC;                                       \
-       s.faces = NULL;                                             \
-       s.maxfaces = 0;                                             \
-       s.nfaces = 0;                                               \
-       VSET(f.vert[0], t00, t01, t02);                                \
-       VSET(f.vert[1], t10, t11, t12);                                \
-       VSET(f.vert[2], t20, t21, t22);                                \
-       soup_add_face(&s, V3ARGS(f.vert), &t);                        \
-       VSET(f.plane, 0, 0, 1);                                        \
-       nsplt = split_face_single(&s, 0, isectpt, &f, &t);              \
-       if (nsplt != s.nfaces) {                                    \
-           printf("Error, nsplit %lu != s.nfaces %lu ?\n", numsplit, 
s.nfaces); \
-       }
-
-    /* the _splits is an array of expected triangles, as 9 fastf_t tuples */
-    /* fastf_t _splits[nsplt][9] = {{...}, {...}} */
-    /* post tests to see if the resulting triangles match and cleans up */
-#define POST(name)                                                      \
-    for (i = 0; i < numsplit; i++) {                                    \
-       VSET(f.vert[0], _splits[i][0], _splits[i][1], _splits[i][2]);        \
-       VSET(f.vert[1], _splits[i][3], _splits[i][4], _splits[i][5]);        \
-       VSET(f.vert[2], _splits[i][6], _splits[i][7], _splits[i][8]);        \
-       urf[i] = find_tri(&s, &f, &t);                                      \
-       if (urf[i] == -1) failure++;                                      \
-    }                                                                   \
-    if (nsplt != 2 && urf[0] == -1 && urf[1] == -1) {                   \
-       printf("\033[1;31mFAILURE "name"\033[m\n");                       \
-       printf("%lu faces now\n", s.nfaces);                               \
-       for (i = 0; i < s.nfaces; i++)                                    \
-           printf("%03lu: % 2g, % 2g, % 2g | % 2g, % 2g, % 2g | % 2g, % 2g, % 
2g\n", \
-                  i, V3ARGS(s.faces[i].vert[0]), V3ARGS(s.faces[i].vert[1]), 
V3ARGS(s.faces[i].vert[2])); \
-       count++;                                                          \
-    }                                                                   \
-    free(s.faces);                                                      \
-} /* NOTE THIS IS THE CLOSING BRACE FROM THE OPENING BRACE IN THE PREVIOUS 
MACRO!! */
-
-
-    /* VERT/VERT */
-    PREP(0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1); {fastf_t 
_splits[1][9] = {{0, 0, 0, 0, 1, 0, 1, 0, 0}}; POST("VERT/VERT");}
-
-    /* VERT/EDGE */
-    PREP(-1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2); {fastf_t 
_splits[2][9] = {{0, 0, 0, 0, 1, 0, -1, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0, 0}}; 
POST("VERT/EDGE");}
-
-#if 0 /* known to be broken right now.  */
-    /* EDGE/EDGE */
-    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 1, 1, 0, -1, 1, 0, 3); {fastf_t 
_splits[3][9] = { { 1, 1, 0,  0, 2, 0, -1, 1, 0}, { 1, 1, 0, -2, 0, 0,  2, 0, 
0}, {-1, 1, 0,  1, 1, 0, -2, 0, 0}}; POST("EDGE/EDGE");}
-#endif
-
-    /* VERT/FACE */
-    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0, 1, 0, 3); {fastf_t 
_splits[4][9]={ {-2, 0, 0, 2, 0, 0, 0, 1, 0}, {-2, 0, 0, 0, 2, 0, 0, 1, 0}, {2, 
0, 0, 0, 2, 0, 0, 1, 0}}; POST("VERT/FACE");}
-
-    /* EDGE/FACE */
-    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4); {fastf_t 
_splits[4][9]={{0, 0, 0, -2, 0, 0, 0, 1, 0}, {0, 0, 0, 2, 0, 0, 0, 1, 0}, {-2, 
0, 0, 0, 2, 0, 0, 1, 0}, {2, 0, 0, 0, 2, 0, 0, 1, 0}}; POST("EDGE/FACE");}
-
-#if 0 /* known to be broken right now */
-    /* FACE/FACE */
-    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4); fastf_t 
_splits[4][9]={{0, 0, 0, -2, 0, 0, 0, 1, 0}, {0, 0, 0, 2, 0, 0, 0, 1, 0}, {-2, 
0, 0, 0, 2, 0, 0, 1, 0}, {2, 0, 0, 0, 2, 0, 0, 1, 0}}; POST("EDGE/FACE");
-#endif
-
-#undef PREP
-#undef POST
-
-    return count;
-}
-
-
-int
-test_face_splits()
-{
-    int count = 0;
-
-    int rval;
-    struct soup_s l, r;
-    struct bn_tol t;
-    point_t p[3];
-
-
-    BN_TOL_INIT(&t);
-    t.dist = 0.005;
-    t.dist_sq = t.dist * t.dist;
-
-    l.magic = r.magic = SOUP_MAGIC;
-    l.faces = r.faces = NULL;
-    l.maxfaces = l.nfaces = r.maxfaces = r.nfaces = 0;
-    VSET(p[0], -1, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[2], 1, 0, 0); 
soup_add_face(&l, p[0], p[1], p[2], &t);
-    VSET(p[0], 0, 0, -1); VSET(p[1], 0, 1, 0); VSET(p[2], 0, 0, 1); 
soup_add_face(&r, p[0], p[1], p[2], &t);
-
-    rval = split_face(&l, 0, &r, 0, &t);
-    if (rval != 3 || l.nfaces != 2 || r.nfaces != 2) {
-       printf("\033[1;31mFAILURE\033[m\n");
-       count++;
-    }
-    {
-       struct face_s f;
-       int tri;
-#define ZORF(XVAL, ZVAL, LR, FU) VSET(f.vert[0], 0, 0, 0); VSET(f.vert[1], 0, 
1, 0); VSET(f.vert[2], XVAL, 0, ZVAL); tri = find_tri(&LR, &f, &t); if (tri==-1 
|| l.faces[tri].foo != FU) { count++; printf("\033[1;31mFAILURE\033[m\n"); }
-       ZORF(1, 0, l, INSIDE);
-       ZORF(-1, 0, l, OUTSIDE);
-       ZORF(0, -1, r, OUTSIDE);
-       ZORF(0, 1, r, INSIDE);
-#undef ZORF
-    }
-
-    /* TODO: add more cases */
-
-    return count;
-}
-
-
-int test_invert()
-{
-    return -1;
-}
-
-
-int test_compose()
-{
-    int rval = 0;
-    unsigned int i;
-    union tree l, *r;
-    struct soup_s ls, *rs;
-    struct model lm, rm;
-    struct nmgregion lnr, rnr;
-    struct bn_tol t;
-    point_t p[3];
-
-    BN_TOL_INIT(&t);
-    t.dist = 0.005;
-    t.dist_sq = t.dist * t.dist;
-
-    /* assembly tree linkages */
-#define PREP l.magic = RT_TREE_MAGIC; ls.magic = SOUP_MAGIC; lm.magic = 
NMG_MODEL_MAGIC; lnr.m_p = &lm; ls.faces = NULL; ls.nfaces = ls.maxfaces = 0; 
l.tr_d.td_r = &lnr; l.tr_d.td_r->m_p = (struct model *)&ls; BU_ALLOC(r, union 
tree); BU_ALLOC(rs, struct soup_s); r->magic = RT_TREE_MAGIC; rs->magic = 
SOUP_MAGIC; rm.magic = NMG_MODEL_MAGIC; rnr.m_p = &rm; rs->faces = NULL; 
rs->nfaces = rs->maxfaces = 0; r->tr_d.td_r = &rnr; r->tr_d.td_r->m_p = (struct 
model *)rs;
-
-    /* test empty tree */
-    PREP;
-    compose(&l, r, 0, 0, 0);   /* r is destroyed */
-    if (ls.nfaces != 0) { printf("Erm, 0+0=%lu?\n", ls.nfaces); rval++; }
-
-    /* test no moves, all deleted */
-    PREP;
-    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    for (i=0;i<rs->nfaces;i++) rs->faces[i].foo = OUTSIDE;
-    compose(&l, r, INSIDE, OUTSIDE, INSIDE);
-    if (ls.nfaces != 0) { rval++; printf("Missing faces\n"); }
-
-    /* test all moves, all kept */
-    PREP;
-    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    for (i=0;i<rs->nfaces;i++) rs->faces[i].foo = OUTSIDE;
-    compose(&l, r, INSIDE, OUTSIDE, OUTSIDE);
-    if (ls.nfaces != 3) { rval++; printf("Missing faces\n"); }
-
-    /* test partial moves */
-    PREP;
-    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    rs->faces[0].foo = OUTSIDE;
-    rs->faces[1].foo = INSIDE;
-    rs->faces[2].foo = OUTSIDE;
-    compose(&l, r, INSIDE, OUTSIDE, OUTSIDE);
-    if (ls.nfaces != 2) { rval++; printf("Missing faces\n"); }
-
-    PREP;
-    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
-    rs->faces[0].foo = OUTSIDE;
-    rs->faces[1].foo = INSIDE;
-    rs->faces[2].foo = OUTSIDE;
-    compose(&l, r, INSIDE, OUTSIDE, INSIDE);
-    if (ls.nfaces != 1) { rval++; printf("Missing faces\n"); }
-#undef PREP
-    return rval;
-}
-
-
-int test_evaluate()
-{
-    return -1;
-}
-
-
-int
-main(int UNUSED(argc), const char **argv)
-{
-    bu_setprogname(argv[0]);
-#define TRY(STR, FNC) { int rval = FNC(); printf("RESULT:%18s: \033[1;", STR); 
if (rval) printf("31m%d\033[m failures\n",  rval); else 
printf("32mOK\033[m\n"); }
-    TRY("tri intersection", test_tri_intersections);
-    TRY("single face split", test_face_split_single);
-    TRY("face splitting", test_face_splits);
-    TRY("invert", test_invert);
-    TRY("compose", test_compose);
-    TRY("evaluate", test_evaluate);
-#undef TRY
-    return 0;
-}
-
-
-/*
- * Local Variables:
- * tab-width: 8
- * mode: C
- * indent-tabs-mode: t
- * c-file-style: "stroustrup"
- * End:
- * ex: shiftwidth=4 tabstop=8
- */

Copied: brlcad/trunk/src/libgcv/tests/test_bottess.c (from rev 77034, 
brlcad/trunk/src/libgcv/test_bottess.c)
===================================================================
--- brlcad/trunk/src/libgcv/tests/test_bottess.c                                
(rev 0)
+++ brlcad/trunk/src/libgcv/tests/test_bottess.c        2020-09-03 07:13:01 UTC 
(rev 77035)
@@ -0,0 +1,343 @@
+/*                  T E S T _ B O T T E S S . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2011-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libgcv/bottess_tester.c
+ *
+ * Test things in the bottess routines...
+ */
+
+#include "common.h"
+
+#include "vmath.h"
+#include "bu/app.h"
+#include "bn.h"
+#include "raytrace.h"
+#include "nmg.h"
+#include "gcv.h"
+
+#include "../soup.h"
+#include "../tri_intersect.h"
+
+int
+test_intersection(int should, point_t *t1, point_t *t2, point_t p1, point_t p2)
+{
+    int coplanar = 0;
+    point_t i[2] = {VINIT_ZERO, VINIT_ZERO};
+    vect_t tmp[2] = {VINIT_ZERO, VINIT_ZERO};
+    struct face_s f[2];
+    struct bn_tol tol;
+
+    BN_TOL_INIT(&tol);
+    tol.dist = 0.005;
+    tol.dist_sq = tol.dist*tol.dist;
+
+    VMOVE(f[0].vert[0], t1[0]);
+    VMOVE(f[0].vert[1], t1[1]);
+    VMOVE(f[0].vert[2], t1[2]);
+    VSUB2(tmp[0], t1[1], t1[0]);
+    VSUB2(tmp[1], t1[2], t1[0]);
+    VCROSS(f[0].plane, tmp[0], tmp[1]);
+    f[0].foo = 0;
+
+    VMOVE(f[1].vert[0], t2[0]);
+    VMOVE(f[1].vert[1], t2[1]);
+    VMOVE(f[1].vert[2], t2[2]);
+    VSUB2(tmp[0], t2[1], t2[0]);
+    VSUB2(tmp[1], t2[2], t2[0]);
+    VCROSS(f[1].plane, tmp[0], tmp[1]);
+    f[1].foo = 0;
+
+    if (gcv_tri_tri_intersect_with_isectline(NULL, NULL, f, f+1, &coplanar, i, 
&tol) == 0 && should == 0)
+       return 0;
+    return !(VNEAR_EQUAL(i[0], p1, tol.dist) && VNEAR_EQUAL(i[1], p2, 
tol.dist));
+}
+
+
+int
+test_tri_intersections()
+{
+    int count = 0;
+#define TRY(suc, t00x, t00y, t00z, t01x, t01y, t01z, t02x, t02y, t02z, t10x, 
t10y, t10z, t11x, t11y, t11z, t12x, t12y, t12z, p0x, p0y, p0z, p1x, p1y, p1z) { 
\
+       point_t t0[3], t1[3], p0, p1; \
+       VSET(t0[0], t00x, t00y, t00z); VSET(t0[1], t01x, t01y, t01z); 
VSET(t0[2], t02x, t02y, t02z); \
+       VSET(t1[0], t10x, t10y, t10z); VSET(t1[1], t11x, t11y, t11z); 
VSET(t1[2], t12x, t12y, t12z); \
+       VSET(p0, p0x, p0y, p0z); VSET(p1, p1x, p1y, p1z); \
+       count += test_intersection(suc, t0, t1, p0, p1); }
+
+    TRY(1, 0, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0, 0, 
.5, 0, .5, .5);  /* ep ef */
+    TRY(0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2, 0.5, 0, 3, 0.5, 1, 2, 0.5, 0, 0, 
.5, 0, .5, .5);  /* no intersect */
+
+#undef TRY
+    return count;
+}
+
+
+static int
+find_tri(struct soup_s *s, struct face_s *f, struct bn_tol *t) {
+    unsigned int i, j, k;
+    for (i=0;i<s->nfaces;i++) {
+       int found[3] = {0, 0, 0};
+       struct face_s *wf = s->faces+i;
+
+       for (j=0;j<3;j++) for (k=0;k<3;k++) if (VNEAR_EQUAL(wf->vert[j], 
f->vert[k], t->dist)) found[j] = 1;
+       if (found[0] == 1 && found[1] == 1 && found[2] == 1) return i;
+    }
+    return -1;
+}
+
+
+int
+test_face_split_single()
+{
+    unsigned long int i, tcount = 0, count = 0, nsplt;
+    struct soup_s s;
+    struct face_s f;
+    struct bn_tol t;
+
+    BN_TOL_INIT(&t);
+    t.dist = 0.005;
+    t.dist_sq = t.dist * t.dist;
+
+    /* evil macros to do a lot of scaffolding, setup, execution, etc... */
+    /* prep take: the triangle to split (9 fastf_t), the intersection line (6
+     * fastf_t), and the number of expected resulting triangles. */
+
+    /* NOTE THE "PREP" AND "POST" MACROS MUST BE USED IN PAIRS DUE TO THE 
SPLIT ENCLOSING CURLY BRACES */
+#define PREP(t00, t01, t02, t10, t11, t12, t20, t21, t22,                      
 \
+            ispt00, ispt01, ispt02, ispt10, ispt11, ispt12, _nsplt)          \
+    {                                                             \
+       point_t isectpt[2];                                         \
+       int urf[_nsplt+1];                                          \
+       unsigned long int failure = 0, numsplit = _nsplt;           \
+       for (i = 0; i < _nsplt + 1; ++i) urf[i] = 0;                \
+       tcount++;                                                   \
+       VSET(isectpt[0], ispt00, ispt01, ispt02);                      \
+       VSET(isectpt[1], ispt10, ispt11, ispt12);                      \
+       s.magic = SOUP_MAGIC;                                       \
+       s.faces = NULL;                                             \
+       s.maxfaces = 0;                                             \
+       s.nfaces = 0;                                               \
+       VSET(f.vert[0], t00, t01, t02);                                \
+       VSET(f.vert[1], t10, t11, t12);                                \
+       VSET(f.vert[2], t20, t21, t22);                                \
+       soup_add_face(&s, V3ARGS(f.vert), &t);                        \
+       VSET(f.plane, 0, 0, 1);                                        \
+       nsplt = split_face_single(&s, 0, isectpt, &f, &t);              \
+       if (nsplt != s.nfaces) {                                    \
+           printf("Error, nsplit %lu != s.nfaces %lu ?\n", numsplit, 
s.nfaces); \
+       }
+
+    /* the _splits is an array of expected triangles, as 9 fastf_t tuples */
+    /* fastf_t _splits[nsplt][9] = {{...}, {...}} */
+    /* post tests to see if the resulting triangles match and cleans up */
+#define POST(name)                                                      \
+    for (i = 0; i < numsplit; i++) {                                    \
+       VSET(f.vert[0], _splits[i][0], _splits[i][1], _splits[i][2]);        \
+       VSET(f.vert[1], _splits[i][3], _splits[i][4], _splits[i][5]);        \
+       VSET(f.vert[2], _splits[i][6], _splits[i][7], _splits[i][8]);        \
+       urf[i] = find_tri(&s, &f, &t);                                      \
+       if (urf[i] == -1) failure++;                                      \
+    }                                                                   \
+    if (nsplt != 2 && urf[0] == -1 && urf[1] == -1) {                   \
+       printf("\033[1;31mFAILURE "name"\033[m\n");                       \
+       printf("%lu faces now\n", s.nfaces);                               \
+       for (i = 0; i < s.nfaces; i++)                                    \
+           printf("%03lu: % 2g, % 2g, % 2g | % 2g, % 2g, % 2g | % 2g, % 2g, % 
2g\n", \
+                  i, V3ARGS(s.faces[i].vert[0]), V3ARGS(s.faces[i].vert[1]), 
V3ARGS(s.faces[i].vert[2])); \
+       count++;                                                          \
+    }                                                                   \
+    free(s.faces);                                                      \
+} /* NOTE THIS IS THE CLOSING BRACE FROM THE OPENING BRACE IN THE PREVIOUS 
MACRO!! */
+
+
+    /* VERT/VERT */
+    PREP(0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1); {fastf_t 
_splits[1][9] = {{0, 0, 0, 0, 1, 0, 1, 0, 0}}; POST("VERT/VERT");}
+
+    /* VERT/EDGE */
+    PREP(-1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2); {fastf_t 
_splits[2][9] = {{0, 0, 0, 0, 1, 0, -1, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0, 0}}; 
POST("VERT/EDGE");}
+
+#if 0 /* known to be broken right now.  */
+    /* EDGE/EDGE */
+    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 1, 1, 0, -1, 1, 0, 3); {fastf_t 
_splits[3][9] = { { 1, 1, 0,  0, 2, 0, -1, 1, 0}, { 1, 1, 0, -2, 0, 0,  2, 0, 
0}, {-1, 1, 0,  1, 1, 0, -2, 0, 0}}; POST("EDGE/EDGE");}
+#endif
+
+    /* VERT/FACE */
+    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0, 1, 0, 3); {fastf_t 
_splits[4][9]={ {-2, 0, 0, 2, 0, 0, 0, 1, 0}, {-2, 0, 0, 0, 2, 0, 0, 1, 0}, {2, 
0, 0, 0, 2, 0, 0, 1, 0}}; POST("VERT/FACE");}
+
+    /* EDGE/FACE */
+    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4); {fastf_t 
_splits[4][9]={{0, 0, 0, -2, 0, 0, 0, 1, 0}, {0, 0, 0, 2, 0, 0, 0, 1, 0}, {-2, 
0, 0, 0, 2, 0, 0, 1, 0}, {2, 0, 0, 0, 2, 0, 0, 1, 0}}; POST("EDGE/FACE");}
+
+#if 0 /* known to be broken right now */
+    /* FACE/FACE */
+    PREP(-2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4); fastf_t 
_splits[4][9]={{0, 0, 0, -2, 0, 0, 0, 1, 0}, {0, 0, 0, 2, 0, 0, 0, 1, 0}, {-2, 
0, 0, 0, 2, 0, 0, 1, 0}, {2, 0, 0, 0, 2, 0, 0, 1, 0}}; POST("EDGE/FACE");
+#endif
+
+#undef PREP
+#undef POST
+
+    return count;
+}
+
+
+int
+test_face_splits()
+{
+    int count = 0;
+
+    int rval;
+    struct soup_s l, r;
+    struct bn_tol t;
+    point_t p[3];
+
+
+    BN_TOL_INIT(&t);
+    t.dist = 0.005;
+    t.dist_sq = t.dist * t.dist;
+
+    l.magic = r.magic = SOUP_MAGIC;
+    l.faces = r.faces = NULL;
+    l.maxfaces = l.nfaces = r.maxfaces = r.nfaces = 0;
+    VSET(p[0], -1, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[2], 1, 0, 0); 
soup_add_face(&l, p[0], p[1], p[2], &t);
+    VSET(p[0], 0, 0, -1); VSET(p[1], 0, 1, 0); VSET(p[2], 0, 0, 1); 
soup_add_face(&r, p[0], p[1], p[2], &t);
+
+    rval = split_face(&l, 0, &r, 0, &t);
+    if (rval != 3 || l.nfaces != 2 || r.nfaces != 2) {
+       printf("\033[1;31mFAILURE\033[m\n");
+       count++;
+    }
+    {
+       struct face_s f;
+       int tri;
+#define ZORF(XVAL, ZVAL, LR, FU) VSET(f.vert[0], 0, 0, 0); VSET(f.vert[1], 0, 
1, 0); VSET(f.vert[2], XVAL, 0, ZVAL); tri = find_tri(&LR, &f, &t); if (tri==-1 
|| l.faces[tri].foo != FU) { count++; printf("\033[1;31mFAILURE\033[m\n"); }
+       ZORF(1, 0, l, INSIDE);
+       ZORF(-1, 0, l, OUTSIDE);
+       ZORF(0, -1, r, OUTSIDE);
+       ZORF(0, 1, r, INSIDE);
+#undef ZORF
+    }
+
+    /* TODO: add more cases */
+
+    return count;
+}
+
+
+int test_invert()
+{
+    return -1;
+}
+
+
+int test_compose()
+{
+    int rval = 0;
+    unsigned int i;
+    union tree l, *r;
+    struct soup_s ls, *rs;
+    struct model lm, rm;
+    struct nmgregion lnr, rnr;
+    struct bn_tol t;
+    point_t p[3];
+
+    BN_TOL_INIT(&t);
+    t.dist = 0.005;
+    t.dist_sq = t.dist * t.dist;
+
+    /* assembly tree linkages */
+#define PREP l.magic = RT_TREE_MAGIC; ls.magic = SOUP_MAGIC; lm.magic = 
NMG_MODEL_MAGIC; lnr.m_p = &lm; ls.faces = NULL; ls.nfaces = ls.maxfaces = 0; 
l.tr_d.td_r = &lnr; l.tr_d.td_r->m_p = (struct model *)&ls; BU_ALLOC(r, union 
tree); BU_ALLOC(rs, struct soup_s); r->magic = RT_TREE_MAGIC; rs->magic = 
SOUP_MAGIC; rm.magic = NMG_MODEL_MAGIC; rnr.m_p = &rm; rs->faces = NULL; 
rs->nfaces = rs->maxfaces = 0; r->tr_d.td_r = &rnr; r->tr_d.td_r->m_p = (struct 
model *)rs;
+
+    /* test empty tree */
+    PREP;
+    compose(&l, r, 0, 0, 0);   /* r is destroyed */
+    if (ls.nfaces != 0) { printf("Erm, 0+0=%lu?\n", ls.nfaces); rval++; }
+
+    /* test no moves, all deleted */
+    PREP;
+    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    for (i=0;i<rs->nfaces;i++) rs->faces[i].foo = OUTSIDE;
+    compose(&l, r, INSIDE, OUTSIDE, INSIDE);
+    if (ls.nfaces != 0) { rval++; printf("Missing faces\n"); }
+
+    /* test all moves, all kept */
+    PREP;
+    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    for (i=0;i<rs->nfaces;i++) rs->faces[i].foo = OUTSIDE;
+    compose(&l, r, INSIDE, OUTSIDE, OUTSIDE);
+    if (ls.nfaces != 3) { rval++; printf("Missing faces\n"); }
+
+    /* test partial moves */
+    PREP;
+    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    rs->faces[0].foo = OUTSIDE;
+    rs->faces[1].foo = INSIDE;
+    rs->faces[2].foo = OUTSIDE;
+    compose(&l, r, INSIDE, OUTSIDE, OUTSIDE);
+    if (ls.nfaces != 2) { rval++; printf("Missing faces\n"); }
+
+    PREP;
+    VSET(p[0], 0, 0, 0); VSET(p[1], 0, 1, 0); VSET(p[0], 0, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 1, 0, 0); VSET(p[1], 1, 1, 0); VSET(p[0], 1, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    VSET(p[0], 2, 0, 0); VSET(p[1], 2, 1, 0); VSET(p[0], 2, 0, 1); 
soup_add_face(rs, V3ARGS(p), &t);
+    rs->faces[0].foo = OUTSIDE;
+    rs->faces[1].foo = INSIDE;
+    rs->faces[2].foo = OUTSIDE;
+    compose(&l, r, INSIDE, OUTSIDE, INSIDE);
+    if (ls.nfaces != 1) { rval++; printf("Missing faces\n"); }
+#undef PREP
+    return rval;
+}
+
+
+int test_evaluate()
+{
+    return -1;
+}
+
+
+int
+main(int UNUSED(argc), const char **argv)
+{
+    bu_setprogname(argv[0]);
+#define TRY(STR, FNC) { int rval = FNC(); printf("RESULT:%18s: \033[1;", STR); 
if (rval) printf("31m%d\033[m failures\n",  rval); else 
printf("32mOK\033[m\n"); }
+    TRY("tri intersection", test_tri_intersections);
+    TRY("single face split", test_face_split_single);
+    TRY("face splitting", test_face_splits);
+    TRY("invert", test_invert);
+    TRY("compose", test_compose);
+    TRY("evaluate", test_evaluate);
+#undef TRY
+    return 0;
+}
+
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

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