Skip to content

Commit

Permalink
Force-update BVHs when updating query engine (#271)
Browse files Browse the repository at this point in the history
* Force-update BVHs when updating query engine

* Do not invalidate trimesh

* Adding unit tests + fix BVH build
  • Loading branch information
doyubkim authored and utilForever committed Nov 21, 2019
1 parent 3d298e3 commit e46b019
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 88 deletions.
3 changes: 2 additions & 1 deletion include/jet/detail/bvh2-inl.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -56,6 +56,7 @@ void Bvh2<T>::build(const std::vector<T>& items,
}

_nodes.clear();
_bound = BoundingBox2D();

for (size_t i = 0; i < _items.size(); ++i) {
_bound.merge(_itemBounds[i]);
Expand Down
3 changes: 2 additions & 1 deletion include/jet/detail/bvh3-inl.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -56,6 +56,7 @@ void Bvh3<T>::build(const std::vector<T>& items,
}

_nodes.clear();
_bound = BoundingBox3D();

for (size_t i = 0; i < _items.size(); ++i) {
_bound.merge(_itemBounds[i]);
Expand Down
7 changes: 5 additions & 2 deletions src/jet/implicit_surface_set2.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions src/jet/implicit_surface_set3.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions src/jet/surface_set2.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions src/jet/surface_set3.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Expand Down
41 changes: 32 additions & 9 deletions src/tests/unit_tests/implicit_surface_set2_tests.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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);
}
47 changes: 38 additions & 9 deletions src/tests/unit_tests/implicit_surface_set3_tests.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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);
}
80 changes: 50 additions & 30 deletions src/tests/unit_tests/surface_set2_tests.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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());

Expand All @@ -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());

Expand All @@ -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);
}
Loading

0 comments on commit e46b019

Please sign in to comment.