diff --git a/include/jet/detail/bvh2-inl.h b/include/jet/detail/bvh2-inl.h index 3b3764111..884d8cf45 100644 --- a/include/jet/detail/bvh2-inl.h +++ b/include/jet/detail/bvh2-inl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -56,6 +56,7 @@ void Bvh2::build(const std::vector& items, } _nodes.clear(); + _bound = BoundingBox2D(); for (size_t i = 0; i < _items.size(); ++i) { _bound.merge(_itemBounds[i]); diff --git a/include/jet/detail/bvh3-inl.h b/include/jet/detail/bvh3-inl.h index 01306589a..c1050dbed 100644 --- a/include/jet/detail/bvh3-inl.h +++ b/include/jet/detail/bvh3-inl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -56,6 +56,7 @@ void Bvh3::build(const std::vector& items, } _nodes.clear(); + _bound = BoundingBox3D(); for (size_t i = 0; i < _items.size(); ++i) { _bound.merge(_itemBounds[i]); diff --git a/src/jet/implicit_surface_set2.cpp b/src/jet/implicit_surface_set2.cpp index 3c5258ac5..92f58d4f0 100644 --- a/src/jet/implicit_surface_set2.cpp +++ b/src/jet/implicit_surface_set2.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -39,7 +39,10 @@ ImplicitSurfaceSet2::ImplicitSurfaceSet2(const ImplicitSurfaceSet2& other) _surfaces(other._surfaces), _unboundedSurfaces(other._unboundedSurfaces) {} -void ImplicitSurfaceSet2::updateQueryEngine() { buildBvh(); } +void ImplicitSurfaceSet2::updateQueryEngine() { + invalidateBvh(); + buildBvh(); +} bool ImplicitSurfaceSet2::isBounded() const { // All surfaces should be bounded. diff --git a/src/jet/implicit_surface_set3.cpp b/src/jet/implicit_surface_set3.cpp index 9a82f5ed3..3f7cb2e0b 100644 --- a/src/jet/implicit_surface_set3.cpp +++ b/src/jet/implicit_surface_set3.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -39,7 +39,10 @@ ImplicitSurfaceSet3::ImplicitSurfaceSet3(const ImplicitSurfaceSet3& other) _surfaces(other._surfaces), _unboundedSurfaces(other._unboundedSurfaces) {} -void ImplicitSurfaceSet3::updateQueryEngine() { buildBvh(); } +void ImplicitSurfaceSet3::updateQueryEngine() { + invalidateBvh(); + buildBvh(); +} bool ImplicitSurfaceSet3::isBounded() const { // All surfaces should be bounded. diff --git a/src/jet/surface_set2.cpp b/src/jet/surface_set2.cpp index 51a468665..028d1cb91 100644 --- a/src/jet/surface_set2.cpp +++ b/src/jet/surface_set2.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -30,7 +30,10 @@ SurfaceSet2::SurfaceSet2(const SurfaceSet2& other) invalidateBvh(); } -void SurfaceSet2::updateQueryEngine() { buildBvh(); } +void SurfaceSet2::updateQueryEngine() { + invalidateBvh(); + buildBvh(); +} bool SurfaceSet2::isBounded() const { // All surfaces should be bounded. diff --git a/src/jet/surface_set3.cpp b/src/jet/surface_set3.cpp index d034c936d..ef7b34137 100644 --- a/src/jet/surface_set3.cpp +++ b/src/jet/surface_set3.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -30,7 +30,10 @@ SurfaceSet3::SurfaceSet3(const SurfaceSet3& other) invalidateBvh(); } -void SurfaceSet3::updateQueryEngine() { buildBvh(); } +void SurfaceSet3::updateQueryEngine() { + invalidateBvh(); + buildBvh(); +} bool SurfaceSet3::isBounded() const { // All surfaces should be bounded. diff --git a/src/tests/unit_tests/implicit_surface_set2_tests.cpp b/src/tests/unit_tests/implicit_surface_set2_tests.cpp index 33337d8c8..f5b9e37bc 100644 --- a/src/tests/unit_tests/implicit_surface_set2_tests.cpp +++ b/src/tests/unit_tests/implicit_surface_set2_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -211,18 +211,18 @@ TEST(ImplicitSurfaceSet2, MixedBoundTypes) { BoundingBox2D domain(Vector2D(), Vector2D(1, 2)); auto plane = Plane2::builder() - .withNormal({0, 1}) - .withPoint({0.0, 0.25 * domain.height()}) - .makeShared(); + .withNormal({0, 1}) + .withPoint({0.0, 0.25 * domain.height()}) + .makeShared(); auto sphere = Sphere2::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); auto surfaceSet = ImplicitSurfaceSet2::builder() - .withExplicitSurfaces({plane, sphere}) - .makeShared(); + .withExplicitSurfaces({plane, sphere}) + .makeShared(); EXPECT_FALSE(surfaceSet->isBounded()); @@ -271,3 +271,26 @@ TEST(ImplicitSurfaceSet2, IsInside) { EXPECT_TRUE(surfaceSet->isInside(Vector2D(0.5, 1.0) + offset)); EXPECT_FALSE(surfaceSet->isInside(Vector2D(0.5, 1.5) + offset)); } + +TEST(ImplicitSurfaceSet2, UpdateQueryEngine) { + auto sphere = + Sphere2::builder().withCenter({-1.0, 1.0}).withRadius(0.5).makeShared(); + + auto surfaceSet = ImplicitSurfaceSet2::builder() + .withExplicitSurfaces({sphere}) + .withTransform(Transform2({1.0, 2.0}, 0.0)) + .makeShared(); + + auto bbox1 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox2D({-0.5, 2.5}, {0.5, 3.5}), bbox1); + + surfaceSet->transform = Transform2({3.0, -4.0}, 0.0); + surfaceSet->updateQueryEngine(); + auto bbox2 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox2D({1.5, -3.5}, {2.5, -2.5}), bbox2); + + sphere->transform = Transform2({-6.0, 9.0}, 0.0); + surfaceSet->updateQueryEngine(); + auto bbox3 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox2D({-4.5, 5.5}, {-3.5, 6.5}), bbox3); +} diff --git a/src/tests/unit_tests/implicit_surface_set3_tests.cpp b/src/tests/unit_tests/implicit_surface_set3_tests.cpp index 1e738f026..d266c0b24 100644 --- a/src/tests/unit_tests/implicit_surface_set3_tests.cpp +++ b/src/tests/unit_tests/implicit_surface_set3_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -215,18 +215,18 @@ TEST(ImplicitSurfaceSet3, MixedBoundTypes) { BoundingBox3D domain(Vector3D(), Vector3D(1, 2, 1)); auto plane = Plane3::builder() - .withNormal({0, 1, 0}) - .withPoint({0, 0.25 * domain.height(), 0}) - .makeShared(); + .withNormal({0, 1, 0}) + .withPoint({0, 0.25 * domain.height(), 0}) + .makeShared(); auto sphere = Sphere3::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); auto surfaceSet = ImplicitSurfaceSet3::builder() - .withExplicitSurfaces({plane, sphere}) - .makeShared(); + .withExplicitSurfaces({plane, sphere}) + .makeShared(); EXPECT_FALSE(surfaceSet->isBounded()); @@ -275,3 +275,32 @@ TEST(ImplicitSurfaceSet3, IsInside) { EXPECT_TRUE(surfaceSet->isInside(Vector3D(0.5, 1.0, 0.5) + offset)); EXPECT_FALSE(surfaceSet->isInside(Vector3D(0.5, 1.5, 0.5) + offset)); } + +TEST(ImplicitSurfaceSet3, UpdateQueryEngine) { + auto sphere = Sphere3::builder() + .withCenter({-1.0, 1.0, 2.0}) + .withRadius(0.5) + .makeShared(); + + auto surfaceSet = + ImplicitSurfaceSet3::builder() + .withExplicitSurfaces({sphere}) + .withTransform(Transform3({1.0, 2.0, -1.0}, QuaternionD())) + .makeShared(); + + auto bbox1 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox3D({-0.5, 2.5, 0.5}, {0.5, 3.5, 1.5}), + bbox1); + + surfaceSet->transform = Transform3({3.0, -4.0, 7.0}, QuaternionD()); + surfaceSet->updateQueryEngine(); + auto bbox2 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox3D({1.5, -3.5, 4.5}, {2.5, -2.5, 5.5}), + bbox2); + + sphere->transform = Transform3({-6.0, 9.0, 2.0}, QuaternionD()); + surfaceSet->updateQueryEngine(); + auto bbox3 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox3D({-4.5, 5.5, 10.5}, {-3.5, 6.5, 11.5}), + bbox3); +} diff --git a/src/tests/unit_tests/surface_set2_tests.cpp b/src/tests/unit_tests/surface_set2_tests.cpp index 03e291220..17bfdc682 100644 --- a/src/tests/unit_tests/surface_set2_tests.cpp +++ b/src/tests/unit_tests/surface_set2_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -387,18 +387,17 @@ TEST(SurfaceSet2, MixedBoundTypes) { BoundingBox2D domain(Vector2D(), Vector2D(1, 2)); auto plane = Plane2::builder() - .withNormal({0, 1}) - .withPoint({0.0, 0.25 * domain.height()}) - .makeShared(); + .withNormal({0, 1}) + .withPoint({0.0, 0.25 * domain.height()}) + .makeShared(); auto sphere = Sphere2::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); - auto surfaceSet = SurfaceSet2::builder() - .withSurfaces({plane, sphere}) - .makeShared(); + auto surfaceSet = + SurfaceSet2::builder().withSurfaces({plane, sphere}).makeShared(); EXPECT_FALSE(surfaceSet->isBounded()); @@ -409,26 +408,24 @@ TEST(SurfaceSet2, MixedBoundTypes) { } TEST(SurfaceSet2, IsValidGeometry) { - auto surfaceSet = SurfaceSet2::builder() - .makeShared(); + auto surfaceSet = SurfaceSet2::builder().makeShared(); EXPECT_FALSE(surfaceSet->isValidGeometry()); BoundingBox2D domain(Vector2D(), Vector2D(1, 2)); auto plane = Plane2::builder() - .withNormal({0, 1}) - .withPoint({0, 0.25 * domain.height()}) - .makeShared(); + .withNormal({0, 1}) + .withPoint({0, 0.25 * domain.height()}) + .makeShared(); auto sphere = Sphere2::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); - auto surfaceSet2 = SurfaceSet2::builder() - .withSurfaces({plane, sphere}) - .makeShared(); + auto surfaceSet2 = + SurfaceSet2::builder().withSurfaces({plane, sphere}).makeShared(); EXPECT_TRUE(surfaceSet2->isValidGeometry()); @@ -442,21 +439,44 @@ TEST(SurfaceSet2, IsInside) { Vector2D offset(1, 2); auto plane = Plane2::builder() - .withNormal({0, 1}) - .withPoint({0, 0.25 * domain.height()}) - .makeShared(); + .withNormal({0, 1}) + .withPoint({0, 0.25 * domain.height()}) + .makeShared(); auto sphere = Sphere2::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); auto surfaceSet = SurfaceSet2::builder() - .withSurfaces({plane, sphere}) - .withTransform(Transform2(offset, 0.0)) - .makeShared(); + .withSurfaces({plane, sphere}) + .withTransform(Transform2(offset, 0.0)) + .makeShared(); EXPECT_TRUE(surfaceSet->isInside(Vector2D(0.5, 0.25) + offset)); EXPECT_TRUE(surfaceSet->isInside(Vector2D(0.5, 1.0) + offset)); EXPECT_FALSE(surfaceSet->isInside(Vector2D(0.5, 1.5) + offset)); } + +TEST(SurfaceSet2, UpdateQueryEngine) { + auto sphere = + Sphere2::builder().withCenter({-1.0, 1.0}).withRadius(0.5).makeShared(); + + auto surfaceSet = SurfaceSet2::builder() + .withSurfaces({sphere}) + .withTransform(Transform2({1.0, 2.0}, 0.0)) + .makeShared(); + + auto bbox1 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox2D({-0.5, 2.5}, {0.5, 3.5}), bbox1); + + surfaceSet->transform = Transform2({3.0, -4.0}, 0.0); + surfaceSet->updateQueryEngine(); + auto bbox2 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox2D({1.5, -3.5}, {2.5, -2.5}), bbox2); + + sphere->transform = Transform2({-6.0, 9.0}, 0.0); + surfaceSet->updateQueryEngine(); + auto bbox3 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox2D({-4.5, 5.5}, {-3.5, 6.5}), bbox3); +} diff --git a/src/tests/unit_tests/surface_set3_tests.cpp b/src/tests/unit_tests/surface_set3_tests.cpp index 02e2ba547..270b5868c 100644 --- a/src/tests/unit_tests/surface_set3_tests.cpp +++ b/src/tests/unit_tests/surface_set3_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Doyub Kim +// Copyright (c) Doyub Kim // // I am making my contributions/submissions to this project solely in my // personal capacity and am not conveying any rights to any intellectual @@ -389,18 +389,17 @@ TEST(SurfaceSet3, MixedBoundTypes) { BoundingBox3D domain(Vector3D(), Vector3D(1, 2, 1)); auto plane = Plane3::builder() - .withNormal({0, 1, 0}) - .withPoint({0, 0.25 * domain.height(), 0}) - .makeShared(); + .withNormal({0, 1, 0}) + .withPoint({0, 0.25 * domain.height(), 0}) + .makeShared(); auto sphere = Sphere3::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); - auto surfaceSet = SurfaceSet3::builder() - .withSurfaces({plane, sphere}) - .makeShared(); + auto surfaceSet = + SurfaceSet3::builder().withSurfaces({plane, sphere}).makeShared(); EXPECT_FALSE(surfaceSet->isBounded()); @@ -411,26 +410,24 @@ TEST(SurfaceSet3, MixedBoundTypes) { } TEST(SurfaceSet3, IsValidGeometry) { - auto surfaceSet = SurfaceSet3::builder() - .makeShared(); + auto surfaceSet = SurfaceSet3::builder().makeShared(); EXPECT_FALSE(surfaceSet->isValidGeometry()); BoundingBox3D domain(Vector3D(), Vector3D(1, 2, 1)); auto plane = Plane3::builder() - .withNormal({0, 1, 0}) - .withPoint({0, 0.25 * domain.height(), 0}) - .makeShared(); + .withNormal({0, 1, 0}) + .withPoint({0, 0.25 * domain.height(), 0}) + .makeShared(); auto sphere = Sphere3::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); - auto surfaceSet2 = SurfaceSet3::builder() - .withSurfaces({plane, sphere}) - .makeShared(); + auto surfaceSet2 = + SurfaceSet3::builder().withSurfaces({plane, sphere}).makeShared(); EXPECT_TRUE(surfaceSet2->isValidGeometry()); @@ -444,21 +441,50 @@ TEST(SurfaceSet3, IsInside) { Vector3D offset(1, 2, 3); auto plane = Plane3::builder() - .withNormal({0, 1, 0}) - .withPoint({0, 0.25 * domain.height(), 0}) - .makeShared(); + .withNormal({0, 1, 0}) + .withPoint({0, 0.25 * domain.height(), 0}) + .makeShared(); auto sphere = Sphere3::builder() - .withCenter(domain.midPoint()) - .withRadius(0.15 * domain.width()) - .makeShared(); + .withCenter(domain.midPoint()) + .withRadius(0.15 * domain.width()) + .makeShared(); auto surfaceSet = SurfaceSet3::builder() - .withSurfaces({plane, sphere}) - .withTransform(Transform3(offset, QuaternionD())) - .makeShared(); + .withSurfaces({plane, sphere}) + .withTransform(Transform3(offset, QuaternionD())) + .makeShared(); EXPECT_TRUE(surfaceSet->isInside(Vector3D(0.5, 0.25, 0.5) + offset)); EXPECT_TRUE(surfaceSet->isInside(Vector3D(0.5, 1.0, 0.5) + offset)); EXPECT_FALSE(surfaceSet->isInside(Vector3D(0.5, 1.5, 0.5) + offset)); } + +TEST(SurfaceSet3, UpdateQueryEngine) { + auto sphere = Sphere3::builder() + .withCenter({-1.0, 1.0, 2.0}) + .withRadius(0.5) + .makeShared(); + + auto surfaceSet = + SurfaceSet3::builder() + .withSurfaces({sphere}) + .withTransform(Transform3({1.0, 2.0, -1.0}, QuaternionD())) + .makeShared(); + + auto bbox1 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox3D({-0.5, 2.5, 0.5}, {0.5, 3.5, 1.5}), + bbox1); + + surfaceSet->transform = Transform3({3.0, -4.0, 7.0}, QuaternionD()); + surfaceSet->updateQueryEngine(); + auto bbox2 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox3D({1.5, -3.5, 4.5}, {2.5, -2.5, 5.5}), + bbox2); + + sphere->transform = Transform3({-6.0, 9.0, 2.0}, QuaternionD()); + surfaceSet->updateQueryEngine(); + auto bbox3 = surfaceSet->boundingBox(); + EXPECT_BOUNDING_BOX2_EQ(BoundingBox3D({-4.5, 5.5, 10.5}, {-3.5, 6.5, 11.5}), + bbox3); +}