diff --git a/extern/glow-extras b/extern/glow-extras index f53a709b1a5926ce12dd00d3514d7d730c859748..2c3cb630bfe74e262535123015a444cb0247278e 160000 --- a/extern/glow-extras +++ b/extern/glow-extras @@ -1 +1 @@ -Subproject commit f53a709b1a5926ce12dd00d3514d7d730c859748 +Subproject commit 2c3cb630bfe74e262535123015a444cb0247278e diff --git a/extern/typed-geometry b/extern/typed-geometry index 0dad6e4b42f81513e75fd264394ec45461cbccc1..a6c6371f1bac47f0f269032549adb1873d1f32e4 160000 --- a/extern/typed-geometry +++ b/extern/typed-geometry @@ -1 +1 @@ -Subproject commit 0dad6e4b42f81513e75fd264394ec45461cbccc1 +Subproject commit a6c6371f1bac47f0f269032549adb1873d1f32e4 diff --git a/tests/feature/intersections/intersection.cc b/tests/feature/intersections/intersection.cc index 07e1e82cbf29b52e457ac28a68c9820e631629a3..8cdff59ab73199c391f78d7bb02f8507e8cba9d8 100644 --- a/tests/feature/intersections/intersection.cc +++ b/tests/feature/intersections/intersection.cc @@ -7,7 +7,7 @@ TG_FUZZ_TEST(TypedGeometry, IntersectionRay3Sphere3) auto box1 = tg::aabb1(tg::pos1(-1.0f), tg::pos1(1.0f)); auto box3 = tg::aabb3(tg::pos3(-1.0f), tg::pos3(1.0f)); // random sphere - auto s = tg::sphere3(uniform(rng, box3) * 10.0f, tg::abs(uniform(rng, box1).x)); + auto s = tg::sphere_boundary<3, float>(uniform(rng, box3) * 10.0f, tg::abs(uniform(rng, box1).x)); { // ray from sphere origin to random direction @@ -357,19 +357,19 @@ TG_FUZZ_TEST(Triangle, Intersection) auto ip4 = tg::intersection(ray, t4); auto ip5 = tg::intersection(ray, t5); - CHECK(ip0.has_value()); - CHECK(ip1.has_value()); - CHECK(ip2.has_value()); - CHECK(ip3.has_value()); - CHECK(ip4.has_value()); - CHECK(ip5.has_value()); - - CHECK(ip0.value() == approx(p, 0.01f)); - CHECK(ip1.value() == approx(p, 0.01f)); - CHECK(ip2.value() == approx(p, 0.01f)); - CHECK(ip3.value() == approx(p, 0.01f)); - CHECK(ip4.value() == approx(p, 0.01f)); - CHECK(ip5.value() == approx(p, 0.01f)); + CHECK(ip0.any()); + CHECK(ip1.any()); + CHECK(ip2.any()); + CHECK(ip3.any()); + CHECK(ip4.any()); + CHECK(ip5.any()); + + CHECK(ip0.first() == approx(p, 0.01f)); + CHECK(ip1.first() == approx(p, 0.01f)); + CHECK(ip2.first() == approx(p, 0.01f)); + CHECK(ip3.first() == approx(p, 0.01f)); + CHECK(ip4.first() == approx(p, 0.01f)); + CHECK(ip5.first() == approx(p, 0.01f)); auto a = uniform(rng, -2.f, 2.f); auto b = uniform(rng, -2.f, 2.f); diff --git a/tests/feature/intersections/ray-intersect.cc b/tests/feature/intersections/ray-intersect.cc index df4316f7e1065043825287b569987e98c21a3c80..9cab42e5a5d9e519c45c5c0994405634d2e8a51a 100644 --- a/tests/feature/intersections/ray-intersect.cc +++ b/tests/feature/intersections/ray-intersect.cc @@ -1,67 +1,223 @@ #include <test.hh> -TG_FUZZ_TEST(Ray, Intersect) +TG_FUZZ_TEST(TypedGeometry, Intersections) { - auto bounds = tg::aabb3(-10, 10); - - // ray - plane - { - auto const r = tg::ray3(uniform(rng, bounds), tg::uniform<tg::dir3>(rng)); - auto const p = tg::plane(tg::uniform<tg::dir3>(rng), uniform(rng, bounds)); - - auto t = intersection_parameter(r, p); - + auto const tolerance = 0.002f; + auto const test_obj = [tolerance](auto const& ray, auto const& obj) { + auto const ts = tg::intersection_parameter(ray, obj); + for (auto const& t : ts) + { + auto const ip = ray[t]; + CHECK(contains(obj, ip, tolerance * tg::sqrt(t))); + } + auto const t = tg::closest_intersection_parameter(ray, obj); if (t.has_value()) { - auto const ip = r[t.value()]; - - CHECK(distance(ip, p) == approx(0).epsilon(1e-2f)); + CHECK(t.value() == ts.first()); + CHECK(closest_intersection(ray, obj) == ray[t.value()]); + CHECK(intersects(ray, obj)); } - } - - // ray - tube - { - auto const r = tg::ray3(uniform(rng, bounds), tg::uniform<tg::dir3>(rng)); - auto const t = tg::cylinder_boundary_no_caps<3, float>(uniform(rng, bounds), uniform(rng, bounds), uniform(rng, 0.5f, 10.0f)); - - auto is = intersection_parameter(r, t); - for (auto i : is) + else + CHECK(!intersects(ray, obj)); + + auto const tsLine = tg::intersection_parameter(inf_of(ray), obj); + auto iRay = 0; + for (auto iLine = 0; iLine < tsLine.size(); ++iLine) + if (tsLine[iLine] >= 0) + CHECK(tsLine[iLine] == ts[iRay++]); + CHECK(iRay == ts.size()); + }; + + auto const test_solid_obj = [tolerance, &rng](auto const& ray, auto const& obj) { + auto const ts = tg::intersection_parameter(ray, obj); + if (ts.has_value()) { - auto ip = r[i]; - - CHECK(distance(ip, t) == approx(0).epsilon(1e-2f)); + auto const interval = ts.value(); + auto const ip1 = ray[interval.start]; + auto const ip2 = ray[uniform(rng, interval.start, interval.end)]; + auto const ip3 = ray[interval.end]; + CHECK(contains(obj, ip1, tolerance)); + CHECK(contains(obj, ip2, tolerance)); + CHECK(contains(obj, ip3, tolerance * tg::sqrt(interval.end))); + + auto const t = tg::closest_intersection_parameter(ray, obj); + CHECK(t.has_value()); + CHECK(t.value() == ts.value().start); + CHECK(closest_intersection(ray, obj) == ip1); + CHECK(intersects(ray, obj)); + + auto const tsLine = tg::intersection_parameter(inf_of(ray), obj); + CHECK(tsLine.has_value()); + auto const interLine = tsLine.value(); + CHECK(interLine.end == interval.end); + if (interLine.start < 0) + CHECK(interval.start == 0); + else + CHECK(interLine.start == interval.start); } - } - - // ray - disk - { - auto const r = tg::ray3(uniform(rng, bounds), tg::uniform<tg::dir3>(rng)); - auto const d = tg::sphere2in3(uniform(rng, bounds), uniform(rng, 0.5f, 10.0f), tg::uniform<tg::dir3>(rng)); - - auto ip = intersection(r, d); - - if (ip.has_value()) - CHECK(distance(ip.value(), d) == approx(0).epsilon(1e-2f)); - } - - // ray - cylinder - { - auto const r = tg::ray3(uniform(rng, bounds), tg::uniform<tg::dir3>(rng)); - auto const c = tg::cylinder3(uniform(rng, bounds), uniform(rng, bounds), uniform(rng, 0.5f, 10.0f)); - auto const t = tg::cylinder_boundary_no_caps<3, float>(c.axis, c.radius); - - auto it = closest_intersection(r, t); - if (it.has_value()) + else + CHECK(!intersects(ray, obj)); + }; + + auto const test_obj_and_boundary = [&](auto const& ray, auto const& obj) { + auto const bounds = boundary_of(obj); + test_solid_obj(ray, obj); + test_obj(ray, bounds); + + auto const iObj = tg::closest_intersection_parameter(ray, obj); + auto const iBounds = tg::closest_intersection_parameter(ray, bounds); + if (iBounds.has_value()) { - CHECK(distance(it.value(), t) == approx(0).epsilon(1e-2f)); - CHECK(distance(it.value(), c) == approx(0).epsilon(1e-2f)); + CHECK(iObj.has_value()); + CHECK(iBounds.value() >= iObj.value()); + CHECK(contains(obj, ray[iBounds.value()], tolerance)); } - - auto ip = closest_intersection(r, c); - - if (ip.has_value()) - CHECK(distance(ip.value(), c) == approx(0).epsilon(1e-2f)); - } + }; + + auto const test_obj_and_boundary_no_caps = [&](auto const& ray, auto const& obj) { + auto const bounds = boundary_of(obj); + auto const boundsNoCaps = boundary_no_caps_of(obj); + test_solid_obj(ray, obj); + test_obj(ray, bounds); + test_obj(ray, boundsNoCaps); + + auto const iObj = tg::closest_intersection_parameter(ray, obj); + auto const iBounds = tg::closest_intersection_parameter(ray, bounds); + auto const iBoundsNoCaps = tg::closest_intersection_parameter(ray, boundsNoCaps); + if (iBoundsNoCaps.has_value()) + { + CHECK(iBounds.has_value()); + CHECK(iBoundsNoCaps.value() >= iBounds.value()); + CHECK(contains(bounds, ray[iBoundsNoCaps.value()], tolerance)); + } + if (iBounds.has_value()) + { + CHECK(iObj.has_value()); + CHECK(iBounds.value() >= iObj.value()); + CHECK(contains(obj, ray[iBounds.value()], tolerance)); + } + }; + + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const a = uniform(rng, 5_deg, 180_deg); // sensible range for a convex inf_cone + auto const n1 = tg::uniform<tg::dir1>(rng); + auto const n2 = tg::uniform<tg::dir2>(rng); + auto const n3 = tg::uniform<tg::dir3>(rng); + auto const n4 = tg::uniform<tg::dir4>(rng); + + auto const range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); + auto const range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); + auto const range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); + auto const range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); + + auto const pos10 = uniform(rng, range1); + auto const pos11 = uniform(rng, range1); + + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); + + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); + + auto const pos40 = uniform(rng, range4); + auto const pos41 = uniform(rng, range4); + + auto const axis0 = tg::segment3(pos30, pos31); + auto const disk0 = tg::sphere2in3(pos30, r, n3); + + auto const d1 = tg::uniform<tg::dir1>(rng); + auto m1 = tg::mat1(); + m1[0] = d1 * uniform(rng, 1.0f, 3.0f); + + auto const d20 = tg::uniform<tg::dir2>(rng); + auto const d21 = perpendicular(d20); + auto m2 = tg::mat2(); + m2[0] = d20 * uniform(rng, 1.0f, 3.0f); + m2[1] = d21 * uniform(rng, 1.0f, 3.0f); + + auto const d30 = tg::uniform<tg::dir3>(rng); + auto const d31 = any_normal(d30); + auto const d32 = normalize(cross(d30, d31)); + auto m3 = tg::mat3(); + m3[0] = d30 * uniform(rng, 1.0f, 3.0f); + m3[1] = d31 * uniform(rng, 1.0f, 3.0f); + m3[2] = d32 * uniform(rng, 1.0f, 3.0f); + + auto m23 = tg::mat2x3(); + m23[0] = d30 * uniform(rng, 1.0f, 3.0f); + m23[1] = d31 * uniform(rng, 1.0f, 3.0f); + + + auto const ray1 = tg::ray1(uniform(rng, range1), tg::uniform<tg::dir1>(rng)); + auto const ray2 = tg::ray2(uniform(rng, range2), tg::uniform<tg::dir2>(rng)); + auto const ray3 = tg::ray3(uniform(rng, range3), tg::uniform<tg::dir3>(rng)); + auto const ray4 = tg::ray4(uniform(rng, range4), tg::uniform<tg::dir4>(rng)); + + // aabb + test_obj_and_boundary(ray1, aabb_of(pos10, pos11)); + test_obj_and_boundary(ray2, aabb_of(pos20, pos21)); + test_obj_and_boundary(ray3, aabb_of(pos30, pos31)); + test_obj_and_boundary(ray4, aabb_of(pos40, pos41)); + // box + test_obj_and_boundary(ray1, tg::box1(pos10, m1)); + test_obj_and_boundary(ray2, tg::box2(pos20, m2)); + test_obj_and_boundary(ray3, tg::box3(pos30, m3)); + test_obj(ray3, tg::box2in3(pos30, m23)); + // capsule + test_obj_and_boundary(ray3, tg::capsule3(axis0, r)); + // cylinder + test_obj_and_boundary_no_caps(ray3, tg::cylinder<3, float>(axis0, r)); + // ellipse + test_obj_and_boundary(ray1, tg::ellipse1(pos10, m1)); + test_obj_and_boundary(ray2, tg::ellipse2(pos20, m2)); + test_obj_and_boundary(ray3, tg::ellipse3(pos30, m3)); + // TODO: ellipse4 + test_obj(ray3, tg::ellipse2in3(pos30, m23)); + // halfspace + test_solid_obj(ray1, tg::halfspace1(n1, h)); + test_solid_obj(ray2, tg::halfspace2(n2, h)); + test_solid_obj(ray3, tg::halfspace3(n3, h)); + test_solid_obj(ray4, tg::halfspace4(n4, h)); + // hemisphere + test_obj_and_boundary_no_caps(ray1, tg::hemisphere1(pos10, r, n1)); + test_obj_and_boundary_no_caps(ray2, tg::hemisphere2(pos20, r, n2)); + test_obj_and_boundary_no_caps(ray3, tg::hemisphere3(pos30, r, n3)); + // test_obj_and_boundary_no_caps(ray4, tg::hemisphere4(pos40, r, n4)); + // inf_cone + test_obj_and_boundary(ray2, tg::inf_cone2(pos20, n2, a)); + test_obj_and_boundary(ray3, tg::inf_cone3(pos30, n3, a)); + // inf_cylinder + test_obj_and_boundary(ray2, tg::inf_cylinder2(tg::line2(pos20, n2), r)); + test_obj_and_boundary(ray3, tg::inf_cylinder3(tg::line3(pos30, n3), r)); + // line + test_obj(ray2, tg::line2(pos20, n2)); + // plane + test_obj(ray1, tg::plane1(n1, h)); + test_obj(ray2, tg::plane2(n2, h)); + test_obj(ray3, tg::plane3(n3, h)); + test_obj(ray4, tg::plane4(n4, h)); + // pyramid + test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h)); + test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone + test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h)); + test_obj(ray3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); + // test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); + // ray + test_obj(ray2, tg::ray2(pos20, n2)); + // segment + test_obj(ray2, tg::segment2(pos20, pos21)); + // sphere + test_obj_and_boundary(ray1, tg::sphere1(pos10, r)); + test_obj_and_boundary(ray2, tg::sphere2(pos20, r)); + test_obj_and_boundary(ray3, tg::sphere3(pos30, r)); + test_obj_and_boundary(ray4, tg::sphere4(pos40, r)); + test_obj(ray3, tg::sphere2in3(pos30, r, n3)); + // triangle + test_solid_obj(ray2, tg::triangle2(pos20, pos21, pos22)); + test_obj(ray3, tg::triangle3(pos30, pos31, pos32)); } TG_FUZZ_TEST(Intersect, LineLine2) diff --git a/tests/feature/objects/aabb.cc b/tests/feature/objects/aabb.cc index ab7152f560550f943407528936d459bd48b341a3..5836bd6c97da079b804a55ade7071449e13d20a5 100644 --- a/tests/feature/objects/aabb.cc +++ b/tests/feature/objects/aabb.cc @@ -24,40 +24,40 @@ TG_FUZZ_TEST(TypedGeometry, AABB) TG_FUZZ_TEST(TypedGeometry, ObjectAABB) {; - auto test_obj = [&](auto obj) { + auto const test_obj = [&](auto const& obj) { auto bb = aabb_of(obj); auto p = uniform(rng, obj); CHECK(contains(bb, p)); }; - const auto r = uniform(rng, 0.0f, 10.0f); - const auto h = uniform(rng, 0.0f, 10.0f); - const auto n1 = tg::dir(uniform(rng, tg::sphere_boundary<1, float>::unit)); - const auto n2 = tg::dir(uniform(rng, tg::sphere_boundary<2, float>::unit)); - const auto n3 = tg::dir(uniform(rng, tg::sphere_boundary<3, float>::unit)); + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const n1 = tg::dir(uniform(rng, tg::sphere_boundary<1, float>::unit)); + auto const n2 = tg::dir(uniform(rng, tg::sphere_boundary<2, float>::unit)); + auto const n3 = tg::dir(uniform(rng, tg::sphere_boundary<3, float>::unit)); - const auto range1 = tg::aabb1(-10,10); - const auto range2 = tg::aabb2(-10,10); - const auto range3 = tg::aabb3(-10,10); - const auto range4 = tg::aabb4(-10,10); + auto const range1 = tg::aabb1(-10,10); + auto const range2 = tg::aabb2(-10,10); + auto const range3 = tg::aabb3(-10,10); + auto const range4 = tg::aabb4(-10,10); - const auto pos10 = uniform(rng, range1); - const auto pos11 = uniform(rng, range1); + auto const pos10 = uniform(rng, range1); + auto const pos11 = uniform(rng, range1); - const auto pos20 = uniform(rng, range2); - const auto pos21 = uniform(rng, range2); - const auto pos22 = uniform(rng, range2); + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); - const auto pos30 = uniform(rng, range3); - const auto pos31 = uniform(rng, range3); - const auto pos32 = uniform(rng, range3); + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); - const auto pos40 = uniform(rng, range4); - const auto pos41 = uniform(rng, range4); - const auto pos42 = uniform(rng, range4); + auto const pos40 = uniform(rng, range4); + auto const pos41 = uniform(rng, range4); + auto const pos42 = uniform(rng, range4); - const auto axis0 = tg::segment3(pos30, pos31); + auto const axis0 = tg::segment3(pos30, pos31); auto d1 = tg::uniform<tg::dir1>(rng); auto m1 = tg::mat1(); @@ -111,7 +111,7 @@ TG_FUZZ_TEST(TypedGeometry, ObjectAABB) // test_obj(p4, tg::hemisphere4(pos40, r, n4)); // pyramid test_obj(tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h)); - //test_obj(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: uniform(quad) missing + //test_obj(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: uniform(quad) missing test_obj(tg::pyramid<tg::sphere2in3>(tg::sphere2in3(pos30, r, n3), h)); // == cone test_obj(tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h)); // TODO: test for quad require uniform(quad) diff --git a/tests/feature/objects/any_point.cc b/tests/feature/objects/any_point.cc index dbe7da1a92d38bd9d580a4036724061fef0fa221..ab9c7e387ff6650f27509d5e2b12ad5a88e06593 100644 --- a/tests/feature/objects/any_point.cc +++ b/tests/feature/objects/any_point.cc @@ -2,66 +2,66 @@ TG_FUZZ_TEST(TypedGeometry, AnyPoint) { - const auto tolerance = 0.001f; - auto const test_obj = [tolerance](const auto& o) { + auto const tolerance = 0.001f; + auto const test_obj = [tolerance](auto const& o) { auto p = any_point(o); CHECK(contains(o, p, tolerance)); }; - auto const test_obj_and_boundary = [&test_obj](const auto& o) { + auto const test_obj_and_boundary = [&test_obj](auto const& o) { test_obj(o); test_obj(boundary_of(o)); }; - auto const test_obj_and_boundary_no_caps = [&test_obj](const auto& o) { + auto const test_obj_and_boundary_no_caps = [&test_obj](auto const& o) { test_obj(o); test_obj(boundary_of(o)); test_obj(boundary_no_caps_of(o)); }; - const auto r = uniform(rng, 0.0f, 10.0f); - const auto h = uniform(rng, 0.0f, 10.0f); - const auto a = tg::uniform<tg::angle>(rng); - const auto n1 = tg::uniform<tg::dir1>(rng); - const auto n2 = tg::uniform<tg::dir2>(rng); - const auto n3 = tg::uniform<tg::dir3>(rng); - const auto n4 = tg::uniform<tg::dir4>(rng); + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const a = tg::uniform<tg::angle>(rng); + auto const n1 = tg::uniform<tg::dir1>(rng); + auto const n2 = tg::uniform<tg::dir2>(rng); + auto const n3 = tg::uniform<tg::dir3>(rng); + auto const n4 = tg::uniform<tg::dir4>(rng); - const auto range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); - const auto range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); - const auto range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); - const auto range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); + auto const range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); + auto const range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); + auto const range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); + auto const range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); - const auto pos10 = uniform(rng, range1); - const auto pos11 = uniform(rng, range1); + auto const pos10 = uniform(rng, range1); + auto const pos11 = uniform(rng, range1); - const auto pos20 = uniform(rng, range2); - const auto pos21 = uniform(rng, range2); - const auto pos22 = uniform(rng, range2); + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); - const auto pos30 = uniform(rng, range3); - const auto pos31 = uniform(rng, range3); - const auto pos32 = uniform(rng, range3); + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); - const auto pos40 = uniform(rng, range4); - const auto pos41 = uniform(rng, range4); + auto const pos40 = uniform(rng, range4); + auto const pos41 = uniform(rng, range4); - const auto axis0 = tg::segment3(pos30, pos31); - const auto disk0 = tg::sphere2in3(pos30, r, n3); + auto const axis0 = tg::segment3(pos30, pos31); + auto const disk0 = tg::sphere2in3(pos30, r, n3); - const auto d1 = tg::uniform<tg::dir1>(rng); + auto const d1 = tg::uniform<tg::dir1>(rng); auto m1 = tg::mat1(); m1[0] = d1 * uniform(rng, 1.0f, 3.0f); - const auto d20 = tg::uniform<tg::dir2>(rng); - const auto d21 = perpendicular(d20); + auto const d20 = tg::uniform<tg::dir2>(rng); + auto const d21 = perpendicular(d20); auto m2 = tg::mat2(); m2[0] = d20 * uniform(rng, 1.0f, 3.0f); m2[1] = d21 * uniform(rng, 1.0f, 3.0f); - const auto d30 = tg::uniform<tg::dir3>(rng); - const auto d31 = any_normal(d30); - const auto d32 = normalize(cross(d30, d31)); + auto const d30 = tg::uniform<tg::dir3>(rng); + auto const d31 = any_normal(d30); + auto const d32 = normalize(cross(d30, d31)); auto m3 = tg::mat3(); m3[0] = d30 * uniform(rng, 1.0f, 3.0f); m3[1] = d31 * uniform(rng, 1.0f, 3.0f); @@ -103,8 +103,10 @@ TG_FUZZ_TEST(TypedGeometry, AnyPoint) test_obj_and_boundary_no_caps(tg::hemisphere3(pos30, r, n3)); // test_obj_and_boundary_no_caps(tg::hemisphere4(pos40, r, n4)); // inf_cone + test_obj_and_boundary(tg::inf_cone2(pos20, n2, a)); test_obj_and_boundary(tg::inf_cone3(pos30, n3, a)); // inf_cylinder + test_obj_and_boundary(tg::inf_cylinder2(tg::line2(pos20, n2), r)); test_obj_and_boundary(tg::inf_cylinder3(tg::line3(pos30, n3), r)); // line test_obj(tg::line1(pos10, n1)); @@ -120,8 +122,8 @@ TG_FUZZ_TEST(TypedGeometry, AnyPoint) test_obj_and_boundary_no_caps(tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h)); test_obj_and_boundary_no_caps(tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone test_obj_and_boundary_no_caps(tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h)); - test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); - // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); + test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); + // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: quad // test_obj(tg::quad2(pos20, pos21, pos22, pos23)); // test_obj(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30))); diff --git a/tests/feature/objects/centroid.cc b/tests/feature/objects/centroid.cc index 290c219921e0689e50f636fd2338180d517c7e8f..09360733ab0b46a81b4beddd133ab8ed5db5b071 100644 --- a/tests/feature/objects/centroid.cc +++ b/tests/feature/objects/centroid.cc @@ -16,9 +16,9 @@ TG_FUZZ_TEST(TypedGeometry, Centroid) } { auto t = tg::triangle2(uniform(rng, range2), uniform(rng, range2), uniform(rng, range2)); - const auto center = centroid_of(t); + auto const center = centroid_of(t); CHECK(contains(t, center)); - const auto transl = uniform_vec(rng, range2); + auto const transl = uniform_vec(rng, range2); t.pos0.x += transl.x; t.pos0.y += transl.y; @@ -27,7 +27,7 @@ TG_FUZZ_TEST(TypedGeometry, Centroid) t.pos2.x += transl.x; t.pos2.y += transl.y; - const auto newCenter = center + transl; + auto const newCenter = center + transl; CHECK(contains(t, newCenter)); CHECK(centroid_of(t) == approx(newCenter)); @@ -56,29 +56,29 @@ TG_FUZZ_TEST(TypedGeometry, Centroid) { // tetrahedron - const auto pyTri = tg::pyramid<tg::triangle3>(tg::triangle3(uniform(rng, range3), uniform(rng, range3), uniform(rng, range3)), uniform(rng, 0.1f, 10.f)); + auto const pyTri = tg::pyramid<tg::triangle3>(tg::triangle3(uniform(rng, range3), uniform(rng, range3), uniform(rng, range3)), uniform(rng, 0.1f, 10.f)); auto center = apex_of(pyTri); - for (const auto& vertex : vertices_of(pyTri.base)) + for (auto const& vertex : vertices_of(pyTri.base)) center += vertex; center /= 4.f; - const auto centroid = centroid_of(pyTri); + auto const centroid = centroid_of(pyTri); CHECK(centroid == approx(center)); } } TG_FUZZ_TEST(TypedGeometry, CentroidByUniform) { - const auto tolerance = 0.25f; - const auto numSamples = 100000; + auto const tolerance = 0.25f; + auto const numSamples = 100000; auto const test_obj = [&rng, numSamples, tolerance](auto const& o) { auto center = uniform(rng, o); for (auto i = 1; i < numSamples; ++i) center += uniform(rng, o); center /= numSamples; - const auto centroid = centroid_of(o); - const auto relError = tg::distance_sqr(center, centroid) / tg::distance_sqr_to_origin(centroid); - const auto approxEqual = centroid == approx(center, tolerance) || relError <= tg::pow2(tolerance); + auto const centroid = centroid_of(o); + auto const relError = tg::distance_sqr(center, centroid) / tg::distance_sqr_to_origin(centroid); + auto const approxEqual = centroid == approx(center, tolerance) || relError <= tg::pow2(tolerance); CHECK(approxEqual); }; @@ -93,47 +93,47 @@ TG_FUZZ_TEST(TypedGeometry, CentroidByUniform) test_obj(boundary_no_caps_of(o)); }; - const auto r = uniform(rng, 0.0f, 10.0f); - const auto h = uniform(rng, 0.0f, 10.0f); - const auto n2 = tg::uniform<tg::dir2>(rng); - const auto n3 = tg::uniform<tg::dir3>(rng); + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const n2 = tg::uniform<tg::dir2>(rng); + auto const n3 = tg::uniform<tg::dir3>(rng); - const auto range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); - const auto range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); - const auto range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); - const auto range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); + auto const range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); + auto const range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); + auto const range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); + auto const range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); - const auto pos10 = uniform(rng, range1); - const auto pos11 = uniform(rng, range1); + auto const pos10 = uniform(rng, range1); + auto const pos11 = uniform(rng, range1); - const auto pos20 = uniform(rng, range2); - const auto pos21 = uniform(rng, range2); - const auto pos22 = uniform(rng, range2); + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); - const auto pos30 = uniform(rng, range3); - const auto pos31 = uniform(rng, range3); - const auto pos32 = uniform(rng, range3); + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); - const auto pos40 = uniform(rng, range4); - const auto pos41 = uniform(rng, range4); - const auto pos42 = uniform(rng, range4); + auto const pos40 = uniform(rng, range4); + auto const pos41 = uniform(rng, range4); + auto const pos42 = uniform(rng, range4); - const auto axis0 = tg::segment3(pos30, pos31); - const auto disk0 = tg::sphere2in3(pos30, r, n3); + auto const axis0 = tg::segment3(pos30, pos31); + auto const disk0 = tg::sphere2in3(pos30, r, n3); - const auto d1 = tg::uniform<tg::dir1>(rng); + auto const d1 = tg::uniform<tg::dir1>(rng); auto m1 = tg::mat1(); m1[0] = d1 * uniform(rng, 1.0f, 3.0f); - const auto d20 = tg::uniform<tg::dir2>(rng); - const auto d21 = perpendicular(d20); + auto const d20 = tg::uniform<tg::dir2>(rng); + auto const d21 = perpendicular(d20); auto m2 = tg::mat2(); m2[0] = d20 * uniform(rng, 1.0f, 3.0f); m2[1] = d21 * uniform(rng, 1.0f, 3.0f); - const auto d30 = tg::uniform<tg::dir3>(rng); - const auto d31 = any_normal(d30); - const auto d32 = normalize(cross(d30, d31)); + auto const d30 = tg::uniform<tg::dir3>(rng); + auto const d31 = any_normal(d30); + auto const d32 = normalize(cross(d30, d31)); auto m3 = tg::mat3(); m3[0] = d30 * uniform(rng, 1.0f, 3.0f); m3[1] = d31 * uniform(rng, 1.0f, 3.0f); @@ -173,8 +173,8 @@ TG_FUZZ_TEST(TypedGeometry, CentroidByUniform) test_obj_and_boundary_no_caps(tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h)); test_obj_and_boundary_no_caps(tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone test_obj_and_boundary_no_caps(tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h)); - // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: area(quad) missing - test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); + // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: area(quad) missing + test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: quad // segment test_obj(tg::segment1(pos10, pos11)); diff --git a/tests/feature/objects/project.cc b/tests/feature/objects/project.cc index e496d308afeca40933f100210788f87ee90cf804..c157b192eec81ba382b0cc6298a8a71ae35231bf 100644 --- a/tests/feature/objects/project.cc +++ b/tests/feature/objects/project.cc @@ -4,7 +4,7 @@ TG_FUZZ_TEST_MAX_ITS_MAX_CYCLES(TypedGeometry, Project, 25, 100'000'000'000) { - auto const test_obj = [&rng](auto p, auto o) { + auto const test_obj = [&rng](auto const& p, auto const& o) { auto proj = project(p, o); // Projected point lies in the object @@ -29,63 +29,63 @@ TG_FUZZ_TEST_MAX_ITS_MAX_CYCLES(TypedGeometry, Project, 25, 100'000'000'000) CHECK(dist == approx(0.0f)); }; - auto const test_obj_and_boundary = [&test_obj](auto p, auto o) { + auto const test_obj_and_boundary = [&test_obj](auto const& p, auto const& o) { test_obj(p, o); test_obj(p, boundary_of(o)); }; - auto const test_obj_and_boundary_no_caps = [&test_obj](auto p, auto o) { + auto const test_obj_and_boundary_no_caps = [&test_obj](auto const& p, auto const& o) { test_obj(p, o); test_obj(p, boundary_of(o)); test_obj(p, boundary_no_caps_of(o)); }; - const auto r = uniform(rng, 0.0f, 10.0f); - const auto h = uniform(rng, 0.0f, 10.0f); - const auto n2 = tg::uniform<tg::dir2>(rng); - const auto n3 = tg::uniform<tg::dir3>(rng); + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const n2 = tg::uniform<tg::dir2>(rng); + auto const n3 = tg::uniform<tg::dir3>(rng); - const auto range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); - const auto range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); - const auto range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); - const auto range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); + auto const range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); + auto const range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); + auto const range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); + auto const range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); - const auto p1 = uniform(rng, range1); - const auto p2 = uniform(rng, range2); - const auto p3 = uniform(rng, range3); - const auto p4 = uniform(rng, range4); + auto const p1 = uniform(rng, range1); + auto const p2 = uniform(rng, range2); + auto const p3 = uniform(rng, range3); + auto const p4 = uniform(rng, range4); - const auto pos10 = uniform(rng, range1); - const auto pos11 = uniform(rng, range1); + auto const pos10 = uniform(rng, range1); + auto const pos11 = uniform(rng, range1); - const auto pos20 = uniform(rng, range2); - const auto pos21 = uniform(rng, range2); - const auto pos22 = uniform(rng, range2); + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); - const auto pos30 = uniform(rng, range3); - const auto pos31 = uniform(rng, range3); - const auto pos32 = uniform(rng, range3); + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); - const auto pos40 = uniform(rng, range4); - const auto pos41 = uniform(rng, range4); + auto const pos40 = uniform(rng, range4); + auto const pos41 = uniform(rng, range4); - const auto axis0 = tg::segment3(pos30, pos31); - const auto disk0 = tg::sphere2in3(pos30, r, n3); + auto const axis0 = tg::segment3(pos30, pos31); + auto const disk0 = tg::sphere2in3(pos30, r, n3); - const auto d1 = tg::uniform<tg::dir1>(rng); + auto const d1 = tg::uniform<tg::dir1>(rng); auto m1 = tg::mat1(); m1[0] = d1 * uniform(rng, 1.0f, 3.0f); - const auto d20 = tg::uniform<tg::dir2>(rng); - const auto d21 = perpendicular(d20); + auto const d20 = tg::uniform<tg::dir2>(rng); + auto const d21 = perpendicular(d20); auto m2 = tg::mat2(); m2[0] = d20 * uniform(rng, 1.0f, 3.0f); m2[1] = d21 * uniform(rng, 1.0f, 3.0f); - const auto d30 = tg::uniform<tg::dir3>(rng); - const auto d31 = any_normal(d30); - const auto d32 = normalize(cross(d30, d31)); + auto const d30 = tg::uniform<tg::dir3>(rng); + auto const d31 = any_normal(d30); + auto const d32 = normalize(cross(d30, d31)); auto m3 = tg::mat3(); m3[0] = d30 * uniform(rng, 1.0f, 3.0f); m3[1] = d31 * uniform(rng, 1.0f, 3.0f); @@ -121,8 +121,8 @@ TG_FUZZ_TEST_MAX_ITS_MAX_CYCLES(TypedGeometry, Project, 25, 100'000'000'000) test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h)); test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h)); - // test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: project(quad) missing - test_obj(p3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); + // test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: project(quad) missing + test_obj(p3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: quad // segment test_obj(p1, tg::segment1(pos10, pos11)); diff --git a/tests/feature/random/uniform.cc b/tests/feature/random/uniform.cc index 26413c5adc2b57380450c9d95d179915e0f85d22..7bcf2431578c9399d570e7515c366a62b3a27867 100644 --- a/tests/feature/random/uniform.cc +++ b/tests/feature/random/uniform.cc @@ -39,10 +39,10 @@ TG_FUZZ_TEST(TypedGeometry, Uniform) TG_FUZZ_TEST_MAX_ITS(TypedGeometry, UniformGeneralProperties, 100) { - const auto tolerance = 0.01f; - const tg::u64 sampleSize = 32; + auto const tolerance = 0.01f; + tg::u64 const sampleSize = 32; - auto const test_obj = [&rng, tolerance](auto samples, auto o) { + auto const test_obj = [&rng, tolerance](auto samples, auto const& o) { for (tg::u64 i = 0; i < samples.size(); ++i) { auto p = uniform(rng, o); @@ -54,12 +54,12 @@ TG_FUZZ_TEST_MAX_ITS(TypedGeometry, UniformGeneralProperties, 100) } }; - auto const test_obj_and_boundary = [&test_obj](auto p, auto o) { + auto const test_obj_and_boundary = [&test_obj](auto const& p, auto const& o) { test_obj(p, o); test_obj(p, boundary_of(o)); }; - auto const test_obj_and_boundary_no_caps = [&test_obj](auto p, auto o) { + auto const test_obj_and_boundary_no_caps = [&test_obj](auto const& p, auto const& o) { test_obj(p, o); test_obj(p, boundary_of(o)); test_obj(p, boundary_no_caps_of(o)); @@ -71,46 +71,46 @@ TG_FUZZ_TEST_MAX_ITS(TypedGeometry, UniformGeneralProperties, 100) auto samples3 = tg::array<tg::pos3, sampleSize>(); auto samples4 = tg::array<tg::pos4, sampleSize>(); - const auto r = uniform(rng, 0.0f, 10.0f); - const auto h = uniform(rng, 0.0f, 10.0f); - const auto n2 = tg::uniform<tg::dir2>(rng); - const auto n3 = tg::uniform<tg::dir3>(rng); + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const n2 = tg::uniform<tg::dir2>(rng); + auto const n3 = tg::uniform<tg::dir3>(rng); - const auto range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); - const auto range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); - const auto range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); - const auto range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); + auto const range1 = tg::aabb1(tg::pos1(-10), tg::pos1(10)); + auto const range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); + auto const range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); + auto const range4 = tg::aabb4(tg::pos4(-10), tg::pos4(10)); - const auto pos10 = uniform(rng, range1); - const auto pos11 = uniform(rng, range1); + auto const pos10 = uniform(rng, range1); + auto const pos11 = uniform(rng, range1); - const auto pos20 = uniform(rng, range2); - const auto pos21 = uniform(rng, range2); - const auto pos22 = uniform(rng, range2); + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); - const auto pos30 = uniform(rng, range3); - const auto pos31 = uniform(rng, range3); - const auto pos32 = uniform(rng, range3); + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); - const auto pos40 = uniform(rng, range4); - const auto pos41 = uniform(rng, range4); + auto const pos40 = uniform(rng, range4); + auto const pos41 = uniform(rng, range4); - const auto axis0 = tg::segment3(pos30, pos31); - const auto disk0 = tg::sphere2in3(pos30, r, n3); + auto const axis0 = tg::segment3(pos30, pos31); + auto const disk0 = tg::sphere2in3(pos30, r, n3); - const auto d1 = tg::uniform<tg::dir1>(rng); + auto const d1 = tg::uniform<tg::dir1>(rng); auto m1 = tg::mat1(); m1[0] = d1 * uniform(rng, 1.0f, 3.0f); - const auto d20 = tg::uniform<tg::dir2>(rng); - const auto d21 = perpendicular(d20); + auto const d20 = tg::uniform<tg::dir2>(rng); + auto const d21 = perpendicular(d20); auto m2 = tg::mat2(); m2[0] = d20 * uniform(rng, 1.0f, 3.0f); m2[1] = d21 * uniform(rng, 1.0f, 3.0f); - const auto d30 = tg::uniform<tg::dir3>(rng); - const auto d31 = any_normal(d30); - const auto d32 = normalize(cross(d30, d31)); + auto const d30 = tg::uniform<tg::dir3>(rng); + auto const d31 = any_normal(d30); + auto const d32 = normalize(cross(d30, d31)); auto m3 = tg::mat3(); m3[0] = d30 * uniform(rng, 1.0f, 3.0f); m3[1] = d31 * uniform(rng, 1.0f, 3.0f); @@ -152,8 +152,8 @@ TG_FUZZ_TEST_MAX_ITS(TypedGeometry, UniformGeneralProperties, 100) test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h)); test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h)); - // test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: uniform(quad) missing - test_obj(samples3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); + // test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: uniform(quad) missing + test_obj(samples3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: quad // segment test_obj(samples1, tg::segment1(pos10, pos11)); diff --git a/tests/impl-report.cc b/tests/impl-report.cc index ee0a1fd17884b5e788bd27c85c1cfd65da467ad7..06ef44a1f020c0a09e46ca6b5528e7aa635c3779 100644 --- a/tests/impl-report.cc +++ b/tests/impl-report.cc @@ -11,21 +11,6 @@ namespace { -// see https://stackoverflow.com/questions/44395169/why-is-sfinae-on-if-constexpr-not-allowed -namespace detail -{ -template <template <class...> class, class, class...> -struct can_apply : std::false_type -{ -}; -template <template <class...> class Z, class... Ts> -struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...> : std::true_type -{ -}; -[[maybe_unused]] tg::rng rng; -} -template <template <class...> class Z, class... Ts> -constexpr bool can_apply = detail::can_apply<Z, void, Ts...>::value; template <class T> using try_print = decltype(std::declval<std::ostream&>() << std::declval<T>()); @@ -55,7 +40,7 @@ template <class T> using try_contains_pos3 = decltype(contains(std::declval<T const&>(), tg::pos3())); template <class T> -using try_uniform = decltype(uniform(detail::rng, std::declval<T const&>())); +using try_uniform = decltype(uniform(std::declval<tg::rng>(), std::declval<T const&>())); template <class T> using try_aabb_of = decltype(aabb_of(std::declval<T const&>())); @@ -96,7 +81,7 @@ void test_single_object_type(std::string name) static auto constexpr domainD = tg::object_traits<ObjT>::domain_dimension; static auto constexpr objectD = tg::object_traits<ObjT>::object_dimension; static auto constexpr solidD = [] { - if constexpr (can_apply<try_solid_of, ObjT>) + if constexpr (tg::can_apply<try_solid_of, ObjT>) return tg::object_traits<try_solid_of<ObjT>>::object_dimension; return objectD; }(); // ternary constexpr of solid domain with fallback to object domain @@ -104,7 +89,7 @@ void test_single_object_type(std::string name) if constexpr (!std::is_default_constructible_v<ObjT>) std::cerr << "cannot default construct tg::" << name << std::endl; - if constexpr (can_apply<try_print, ObjT>) + if constexpr (tg::can_apply<try_print, ObjT>) { std::stringstream ss; ss << ObjT{}; @@ -118,39 +103,39 @@ void test_single_object_type(std::string name) else std::cerr << "cannot print tg::" << name << std::endl; - if constexpr (!can_apply<try_equal, ObjT>) + if constexpr (!tg::can_apply<try_equal, ObjT>) std::cerr << "equality not implemented for tg::" << name << std::endl; // TODO: somehow doesnt work? - if constexpr (!can_apply<try_less, ObjT>) + if constexpr (!tg::can_apply<try_less, ObjT>) std::cerr << "std::less not specialized for tg::" << name << std::endl; - if constexpr (!can_apply<try_hash, ObjT>) + if constexpr (!tg::can_apply<try_hash, ObjT>) std::cerr << "std::hash not specialized for tg::" << name << std::endl; - if constexpr (!can_apply<try_any_point, ObjT>) + if constexpr (!tg::can_apply<try_any_point, ObjT>) std::cerr << "no any_point(tg::" << name << ")" << std::endl; if constexpr (domainD == 2) { - if constexpr (!can_apply<try_project_pos2, ObjT>) + if constexpr (!tg::can_apply<try_project_pos2, ObjT>) { if (!(name.size() >= 7 && std::string_view(name).substr(0, 7) == "ellipse")) // project(ellipse) is not planned std::cerr << "no project(tg::pos2, tg::" << name << ")" << std::endl; } - if constexpr (!can_apply<try_contains_pos2, ObjT>) + if constexpr (!tg::can_apply<try_contains_pos2, ObjT>) std::cerr << "no contains(tg::" << name << ", tg::pos2)" << std::endl; } else if constexpr (domainD == 3) { - if constexpr (!can_apply<try_project_pos3, ObjT>) + if constexpr (!tg::can_apply<try_project_pos3, ObjT>) { if (!(name.size() >= 7 && std::string_view(name).substr(0, 7) == "ellipse")) // project(ellipse) is not planned std::cerr << "no project(tg::pos3, tg::" << name << ")" << std::endl; } - if constexpr (!can_apply<try_contains_pos3, ObjT>) + if constexpr (!tg::can_apply<try_contains_pos3, ObjT>) std::cerr << "no contains(tg::" << name << ", tg::pos3)" << std::endl; } else @@ -159,37 +144,37 @@ void test_single_object_type(std::string name) // operations for finite objects if constexpr (tg::object_traits<ObjT>::is_finite) { - if constexpr (!can_apply<try_uniform, ObjT>) + if constexpr (!tg::can_apply<try_uniform, ObjT>) std::cerr << "no uniform(tg::rng, tg::" << name << ")" << std::endl; - if constexpr (!can_apply<try_aabb_of, ObjT>) + if constexpr (!tg::can_apply<try_aabb_of, ObjT>) std::cerr << "no aabb_of(tg::" << name << ")" << std::endl; - if constexpr (!can_apply<try_centroid_of, ObjT>) + if constexpr (!tg::can_apply<try_centroid_of, ObjT>) std::cerr << "no centroid_of(tg::" << name << ")" << std::endl; if constexpr (objectD == 1) { - if constexpr (solidD == 1 && !can_apply<try_length_of, ObjT>) + if constexpr (solidD == 1 && !tg::can_apply<try_length_of, ObjT>) std::cerr << "no length(tg::" << name << ")" << std::endl; - if constexpr (solidD != 1 && !can_apply<try_perimeter_of, ObjT>) + if constexpr (solidD != 1 && !tg::can_apply<try_perimeter_of, ObjT>) std::cerr << "no perimeter_of(tg::" << name << ")" << std::endl; } else if constexpr (objectD == 2) { - if constexpr (!can_apply<try_area_of, ObjT>) + if constexpr (!tg::can_apply<try_area_of, ObjT>) std::cerr << "no area_of(tg::" << name << ")" << std::endl; - if constexpr (solidD == 2 && !can_apply<try_perimeter_of, ObjT>) + if constexpr (solidD == 2 && !tg::can_apply<try_perimeter_of, ObjT>) std::cerr << "no perimeter_of(tg::" << name << ")" << std::endl; } else if constexpr (objectD == 3) { - if constexpr (!can_apply<try_volume_of, ObjT>) + if constexpr (!tg::can_apply<try_volume_of, ObjT>) std::cerr << "no volume_of(tg::" << name << ")" << std::endl; - if constexpr (solidD == 3 && !can_apply<try_area_of, ObjT>) + if constexpr (solidD == 3 && !tg::can_apply<try_area_of, ObjT>) std::cerr << "no area_of(tg::" << name << ")" << std::endl; } else @@ -199,14 +184,14 @@ void test_single_object_type(std::string name) // ray intersections if constexpr (objectD >= domainD - 1) { - if constexpr (domainD == 2 && !can_apply<try_closest_ray2_intersect_of, ObjT>) + if constexpr (domainD == 2 && !tg::can_apply<try_closest_ray2_intersect_of, ObjT>) std::cerr << "no closest_intersection_parameter(tg::ray2, tg::" << name << ")" << std::endl; - if constexpr (domainD == 3 && !can_apply<try_closest_ray3_intersect_of, ObjT>) + if constexpr (domainD == 3 && !tg::can_apply<try_closest_ray3_intersect_of, ObjT>) std::cerr << "no closest_intersection_parameter(tg::ray3, tg::" << name << ")" << std::endl; - if constexpr (domainD == 2 && !can_apply<try_intersects_aabb2_of, ObjT>) + if constexpr (domainD == 2 && !tg::can_apply<try_intersects_aabb2_of, ObjT>) std::cerr << "no intersects(tg::" << name << ", tg::aabb2)" << std::endl; - if constexpr (domainD == 3 && !can_apply<try_intersects_aabb3_of, ObjT>) + if constexpr (domainD == 3 && !tg::can_apply<try_intersects_aabb3_of, ObjT>) std::cerr << "no intersects(tg::" << name << ", tg::aabb3)" << std::endl; // TODO: more