#include "testcases.h" #include "MeshTriangle.h" #include "Utils.h" #include using namespace std; //----------------------- // TEST SUITE //----------------------- //--------------------------------- // This reveals a bug where if an edge is axis-aligned, then my minDistTri function would mess up //--------------------------------- void testMeshTriangleShouldGetEdgePOT() { //----------------------- // Setup //----------------------- MeshTriangle tri( Point(-8.1021398727898486e-006, 185.35530090332031, -45.355339050292969), Point(-8.1021389632951468e-006, 185.35530090332031, 35.355339050292969), Point(160.52239990234375, -92.67767333984375, 35.355339050292969)); Point testpt(-20.065299987792969, 206.86122131347656, -25.065299987792969); //----------------------- // Run //----------------------- PointOnTriangle pot(tri.closest_point_from(testpt)); //----------------------- // Check //----------------------- Point expectedCp(-1.0490417e-005, 185.35530, -25.06530); assert(pot.getType() == PointOnTriangle::POT_EDGE); assert(pot.getPoint().EpsEq(expectedCp, 1e-4)); } void testMeshTriangleEdgePOT() { //----------------------- // Setup //----------------------- MeshTriangle *tri = MeshTriangle::create_test_tri( 100.00000, 100.00000, 0.00000000, 100.00000, -200.00000, 0.00000000, 100.00000, -200.00000, 100.00000); Point testpt(-200.0f, -200.0f, 50.0f); //----------------------- // Run //----------------------- PointOnTriangle pot(tri->closest_point_from(testpt)); //----------------------- // Check //----------------------- Point expectedCp( 100.0f, -200.0f, 50.0f ); assert(pot.getType() == PointOnTriangle::POT_EDGE); assert(pot.getPoint() == expectedCp); } void testMeshTriangleVertexPOT() { //----------------------- // Setup //----------------------- MeshTriangle *tri = MeshTriangle::create_test_tri( 100.00000, 100.00000, 100.00000, 200.00000, 200.00000, 100.00000, -200.00000, 100.00000, 100.00000); Point testpt(-200.00000, 0.00000000, -150.00000); //----------------------- // Run //----------------------- PointOnTriangle pot(tri->closest_point_from(testpt)); //----------------------- // Check //----------------------- Point expectedCp( -200, 100, 100 ); assert(pot.getType() == PointOnTriangle::POT_VERTEX); assert(pot.getPoint() == expectedCp); } //----------------------- // This tests for a subtle bug in the closest pt on tri logic. //----------------------- void testMeshTriangleVertexBug() { //----------------------- // Setup //----------------------- MeshTriangle *tri = new MeshTriangle( Point(200, -200, 0.005), Point(-50, 0, 0.005), Point(200, 200, 0.005)); Point testpt(160.522, 86.4694, -45.1306); //----------------------- // Run //----------------------- PointOnTriangle pot(tri->closest_point_from(testpt)); //----------------------- // Check //----------------------- __DBa("test case: " << pot.getPoint()); Point expPc(160.522, 86.4694, 0.00500107); Vector expNorm(0, 0, -1); assert(tri->norm == expNorm); assert(pot.getPoint().EpsEq(expPc, 1e-6)); assert(pot.getType() == PointOnTriangle::POT_FACE); } //----------------------- //----------------------- void testMeshTriangleFaceBug() { { //----------------------- // Setup //----------------------- MeshTriangle *tri = new MeshTriangle( Point(-50, 0, 500.005), Point(-300, -200, 0.005), Point(200, -200, 0.005)); Point testpt(-268.75, -125, 218.755); //----------------------- // Run //----------------------- PointOnTriangle pot(tri->closest_point_from(testpt)); //----------------------- // Check //----------------------- __DBa("test case: " << pot.getPoint()); Point expPc(-206.25, -125, 187.505); Vector expNorm(0, -0.928477, 0.371391); assert(tri->norm == expNorm); assert(pot.getPoint().EpsEq(expPc, 1e-6)); assert(pot.getType() == PointOnTriangle::POT_EDGE); } //----------------------- // This really pushes the floating point precision to its limits // This may become POT_FACE or POT_EDGE..depending on the FPU internals. // For now, the test case assumes FACE (AMD Athlon XP 2500) //----------------------- { //----------------------- // Setup //----------------------- MeshTriangle *tri = new MeshTriangle( Point(-50, 0, 500.005), Point(-300, 200, 0.005), Point(-300, -200, 0.005)); Point testpt(-268.75, -125, 218.755); //----------------------- // Run //----------------------- PointOnTriangle pot(tri->closest_point_from(testpt)); //----------------------- // Check //----------------------- __DBa("test case: " << pot.getPoint()); Point expPc(-206.25, -125, 187.505); Vector expNorm(-0.894427, 0, 0.447214); assert(tri->norm == expNorm); assert(pot.getPoint().EpsEq(expPc, 1e-6)); assert(pot.getType() == PointOnTriangle::POT_FACE); } } //--------------------------------- // This tests for a bug that Greg's original minDistTri // had. //--------------------------------- void testMeshTriangleClosestPoint() { MeshTriangle tri( Point(0, 0, 0), Point(10, 0, 0), Point(20, 10, 0)); Point testpt0(15, -1, 0); PointOnTriangle pot0( tri.closest_point_from(testpt0) ); assert(pot0.getType() == PointOnTriangle::POT_EDGE); Point testpt1(15, -20, 0); PointOnTriangle pot1( tri.closest_point_from(testpt1) ); assert(pot1.getType() == PointOnTriangle::POT_VERTEX); } void debug_just_one_point() { //octreeVtx *returned_vtx = NULL; //double returned_dist = -1; ////-------------------------------- //// Set the point //// Once u set a point, you should keep it in the comments //// along with the test STL file, run time args, and expected result //// (INSIDE or OUTSIDE). //// TODO eventually i should make these regression tests to auto-run them. ////-------------------------------- ////----------------------- //// ////----------------------- //// for test_pt_cross 1 3 //// should be ON the triangle //// Point poison1(0.000000, 0.000000, 200.005005); ////----------------------- //// ////----------------------- //// for test_pt_cross 1 3 //// should be ON the triangle - but make sure it accumulates 16 tris //// this is basically where all the pts meet //// Point poison1(0.000000, 0.000000, 0.005005); ////----------------------- //// -none testcases/L.stl 50 3 //// should not crash ////----------------------- //Point poison1(-200.0f, -200.0f, 50.0f); ////----------------------- //// ////----------------------- ///* Use this code to debug octree corners */ //// for trigon 0 5 - should be OUTSIDE ///* //Point poison1 = // Utils::octnode_corner_pt( // // 0 0 0 pt // Point(-160.522400, -114.183586, 55.195900), // // edge len // 37.5, // // the corner we want // 0, 0, 0); // */ // // ////-------------------------------- //// ask the STL model for the closest point ////-------------------------------- // //GlobalSTLFile stl_model; //Point cp; //double sdf = stl_model.calc_sdf_from_pt(poison1, cp); } // TODO make this test case automatically load up trigon.. void testTrigonFlatFoldBug(ISDF *trigonStl) { //----------------------- // Setup //----------------------- Point testpt(-160.52239990234375, -114.18358612060547, -85.261199951171875); //-------------------------------- // Run //-------------------------------- SDF::SdfValue sdf = trigonStl->calc_sdf_from_pt(testpt); assert(sdf.dist_class == SDF::EXTERIOR); assert(sdf.getSignedDistance() < 0.0f); // Should be exterior assert(sdf.closest_point.EpsEq( Point(-160.52240, -92.677658, -45.355339), 1e-5)); } void testWedgeBigBug(const ISDF &wedge) { Point testpt(-100, 100, 0); SDF::SdfValue sdf = wedge.calc_sdf_from_pt(testpt); assert(sdf.getSignedDistance() == 0.0f); assert(sdf.closest_point == testpt); } void testWedgeEdgeBumpiness(const ISDF &wedge) { Point testpt(-75, 75, 125); SDF::SdfValue sdf = wedge.calc_sdf_from_pt(testpt); assert(sdf.getSignedDistance() == 17.677670); assert(sdf.dist_class == SDF::INTERIOR); } void testTrigonStaller(const ISDF &trigon) { Point testpt(-20.065299987792969, 206.86122131347656, -25.065299987792969); SDF::SdfValue sdf = trigon.calc_sdf_from_pt(testpt); //assert(sdf.getSignedDistance() == 17.677670); //assert(sdf.dist_class == SDF::INTERIOR); } void testCrossStaller(const ISDF &cross) { //--------------------------------- // Turns out cross.stl had a T-junction, screwing us up! // We should keep the test case tho..in the future, we may be able to deal with T-junctions. //--------------------------------- /* Point staller(200, -200, -99.9949951171875); SDF::SdfValue sdf = cross.calc_sdf_from_pt(staller); */ } void testFoldLeak(const ISDF &fold00) { Point leaker( Utils::octnode_corner_pt( Point(25.000000, 0.000000, 125.002495), 18.750000, 1, 0, 1)); SDF::SdfValue sdf = fold00.calc_sdf_from_pt(leaker); assert(sdf.dist_class == SDF::EXTERIOR); } void testBoxTubeErrors(const ISDF &bt) { Point tp(-330, 0, -23.75); SDF::SdfValue sdf = bt.calc_sdf_from_pt(tp); // assert no errors } void testSTR(const ISDF &model) { Point tp(-389.115478515625, -203.51130676269531, -102.07484436035156); SDF::SdfValue sdf = model.calc_sdf_from_pt(tp); cout << "for test point " << tp << " we got SDF: " << sdf.getSignedDistance(); // assert no errors }