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