test: cover testSelection
This commit is contained in:
1 parent
b6fe9d78eb
commit
83f9ea128d
1 file changed
+165
@@ -155,3 +155,168 @@ VF_TEST(dilationGrowsOneCellIntoASixNeighbourCrossAndKeepsGoing) {
|
|||||||
CHECK(!once.contains({1, 1, 0}));
|
CHECK(!once.contains({1, 1, 0}));
|
||||||
CHECK(once.min() == Vec3i(-1, -1, -1));
|
CHECK(once.min() == Vec3i(-1, -1, -1));
|
||||||
|
|
||||||
|
// Manhattan ball of radius two: 1 + 6 + 18 cells.
|
||||||
|
Selection twice = seed.expanded(2);
|
||||||
|
CHECK_EQ(twice.count(), 25u);
|
||||||
|
CHECK(twice.contains({1, 1, 0}));
|
||||||
|
CHECK(twice.contains({2, 0, 0}));
|
||||||
|
CHECK(!twice.contains({1, 1, 1}));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(erosionPeelsExactlyOneShellOffASolidBoxPerStep) {
|
||||||
|
Selection box = Selection::box({0, 0, 0}, {4, 4, 4});
|
||||||
|
CHECK_EQ(box.count(), 125u);
|
||||||
|
|
||||||
|
Selection once = box.contracted(1);
|
||||||
|
CHECK_EQ(once.count(), 27u);
|
||||||
|
CHECK(once.contains({2, 2, 2}));
|
||||||
|
CHECK(!once.contains({0, 2, 2}));
|
||||||
|
|
||||||
|
Selection twice = box.contracted(2);
|
||||||
|
CHECK_EQ(twice.count(), 1u);
|
||||||
|
CHECK(twice.contains({2, 2, 2}));
|
||||||
|
|
||||||
|
Selection gone = box.contracted(3);
|
||||||
|
CHECK(gone.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(expandingThenContractingASolidBoxReturnsTheSameCells) {
|
||||||
|
Selection box = Selection::box({-2, 7, 3}, {5, 9, 8});
|
||||||
|
Selection roundTrip = box.expanded(2).contracted(2);
|
||||||
|
CHECK_EQ(roundTrip.count(), box.count());
|
||||||
|
CHECK(roundTrip.mask().sameCells(box.mask()));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(outlineKeepsOnlyCellsWithANeighbourOutsideTheSelection) {
|
||||||
|
Selection box = Selection::box({0, 0, 0}, {4, 4, 4});
|
||||||
|
Selection shell = box.outline();
|
||||||
|
CHECK_EQ(shell.count(), 125u - 27u);
|
||||||
|
CHECK(shell.contains({0, 0, 0}));
|
||||||
|
CHECK(shell.contains({2, 4, 2}));
|
||||||
|
CHECK(!shell.contains({2, 2, 2}));
|
||||||
|
|
||||||
|
Selection single = Selection::box({9, 9, 9}, {9, 9, 9});
|
||||||
|
CHECK_EQ(single.outline().count(), 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(shiftingASelectionMovesEveryCellAndKeepsItsShape) {
|
||||||
|
Selection sphere = Selection::sphere({0, 0, 0}, 3);
|
||||||
|
Selection moved = sphere.shifted({100, -50, 7});
|
||||||
|
CHECK_EQ(moved.count(), sphere.count());
|
||||||
|
CHECK(moved.min() == Vec3i(97, -53, 4));
|
||||||
|
sphere.forEach([&](const Vec3i& cell) {
|
||||||
|
CHECK(moved.contains({cell.x + 100, cell.y - 50, cell.z + 7}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(magicWandFollowsConnectedCellsOfTheSameBlockOnly) {
|
||||||
|
World world;
|
||||||
|
for (int z = 0; z < 3; ++z)
|
||||||
|
for (int x = 0; x < 3; ++x) world.setBlock(x, 0, z, Block::Stone);
|
||||||
|
world.setBlock(1, 0, 1, Block::Dirt);
|
||||||
|
world.setBlock(10, 0, 10, Block::Stone);
|
||||||
|
|
||||||
|
Selection wand = Selection::magicWand(world, {0, 0, 0}, 1000u);
|
||||||
|
CHECK(wand.shape() == SelectionShape::Wand);
|
||||||
|
CHECK_EQ(wand.count(), 8u);
|
||||||
|
CHECK(!wand.truncated());
|
||||||
|
CHECK(!wand.contains({1, 0, 1}));
|
||||||
|
CHECK(!wand.contains({10, 0, 10}));
|
||||||
|
CHECK(wand.contains({2, 0, 2}));
|
||||||
|
|
||||||
|
Selection islandWand = Selection::magicWand(world, {10, 0, 10}, 1000u);
|
||||||
|
CHECK_EQ(islandWand.count(), 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(magicWandStopsAtTheCellLimitAndSaysSo) {
|
||||||
|
World world = slabWorld(40, 40, 0, Block::Stone);
|
||||||
|
Selection capped = Selection::magicWand(world, {0, 0, 0}, 50u);
|
||||||
|
CHECK_EQ(capped.count(), 50u);
|
||||||
|
CHECK(capped.truncated());
|
||||||
|
|
||||||
|
Selection whole = Selection::magicWand(world, {0, 0, 0}, 40u * 40u);
|
||||||
|
CHECK_EQ(whole.count(), 1600u);
|
||||||
|
CHECK(!whole.truncated());
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(magicWandStaysInsideTheBoundingLimitItWasGiven) {
|
||||||
|
World world = slabWorld(20, 20, 0, Block::Stone);
|
||||||
|
Selection boxed =
|
||||||
|
Selection::magicWandWithin(world, {5, 0, 5}, 10000u, {2, 0, 2}, {6, 0, 6});
|
||||||
|
CHECK_EQ(boxed.count(), 25u);
|
||||||
|
CHECK(boxed.min() == Vec3i(2, 0, 2));
|
||||||
|
CHECK(boxed.max() == Vec3i(6, 0, 6));
|
||||||
|
CHECK(!boxed.contains({7, 0, 5}));
|
||||||
|
CHECK_EQ(cellsInsideBox(boxed, {2, 0, 2}, {6, 0, 6}), boxed.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(selectionStatsReportCountsDimensionsAndABlockHistogram) {
|
||||||
|
World world;
|
||||||
|
for (int z = 0; z < 4; ++z)
|
||||||
|
for (int x = 0; x < 4; ++x) {
|
||||||
|
world.setBlock(x, 0, z, Block::Stone);
|
||||||
|
world.setBlock(x, 1, z, Block::Dirt);
|
||||||
|
}
|
||||||
|
world.setBlock(0, 1, 0, Block::Grass);
|
||||||
|
|
||||||
|
Selection region = Selection::box({0, 0, 0}, {3, 2, 3});
|
||||||
|
SelectionStats summary = region.stats(world);
|
||||||
|
CHECK_EQ(summary.blockCount, 48u);
|
||||||
|
CHECK(summary.dims == Vec3i(4, 3, 4));
|
||||||
|
CHECK_EQ(summary.boundingVolume, 48);
|
||||||
|
CHECK_EQ(summary.countOf(Block::Stone), 16u);
|
||||||
|
CHECK_EQ(summary.countOf(Block::Dirt), 15u);
|
||||||
|
CHECK_EQ(summary.countOf(Block::Grass), 1u);
|
||||||
|
CHECK_EQ(summary.countOf(Block::Air), 16u);
|
||||||
|
CHECK_EQ(summary.solidCount, 32u);
|
||||||
|
CHECK_EQ(summary.airCount, 16u);
|
||||||
|
CHECK(summary.dominantBlock() == Block::Stone);
|
||||||
|
CHECK_EQ(summary.distinctBlocks(), 4u);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(anEmptySelectionHasNoCellsAndNoStatistics) {
|
||||||
|
Selection nothing;
|
||||||
|
CHECK(nothing.empty());
|
||||||
|
CHECK_EQ(nothing.count(), 0u);
|
||||||
|
CHECK_EQ(nothing.blocks().size(), 0u);
|
||||||
|
|
||||||
|
World world;
|
||||||
|
SelectionStats summary = nothing.stats(world);
|
||||||
|
CHECK_EQ(summary.blockCount, 0u);
|
||||||
|
CHECK_EQ(summary.boundingVolume, 0);
|
||||||
|
CHECK_EQ(summary.distinctBlocks(), 0u);
|
||||||
|
CHECK(summary.dominantBlock() == Block::Air);
|
||||||
|
|
||||||
|
CHECK_EQ(nothing.expanded(3).count(), 0u);
|
||||||
|
CHECK_EQ(nothing.outline().count(), 0u);
|
||||||
|
CHECK(nothing.unionWith(Selection::box({0, 0, 0}, {1, 1, 1})).count() == 8u);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(setOperationsComposeIntoARingShapedSelection) {
|
||||||
|
Selection outer = Selection::sphere({0, 0, 0}, 5);
|
||||||
|
Selection inner = Selection::sphere({0, 0, 0}, 3);
|
||||||
|
Selection ring = outer.differenceWith(inner);
|
||||||
|
CHECK_EQ(ring.count(), outer.count() - inner.count());
|
||||||
|
CHECK(ring.contains({5, 0, 0}));
|
||||||
|
CHECK(!ring.contains({0, 0, 0}));
|
||||||
|
|
||||||
|
Selection cut = Selection::box({-10, 1, -10}, {10, 10, 10});
|
||||||
|
Selection lowerRing = ring.differenceWith(cut);
|
||||||
|
lowerRing.forEach([&](const Vec3i& cell) { CHECK(cell.y <= 0); });
|
||||||
|
CHECK(lowerRing.count() < ring.count());
|
||||||
|
CHECK(lowerRing.count() > 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(trimmingAMaskShrinksTheBoundingBoxWithoutLosingCells) {
|
||||||
|
SelectionMask sparse(Vec3i{0, 0, 0}, Vec3i{16, 16, 16});
|
||||||
|
sparse.add({4, 5, 6});
|
||||||
|
sparse.add({7, 5, 6});
|
||||||
|
CHECK_EQ(sparse.cellCount(), 4096u);
|
||||||
|
|
||||||
|
SelectionMask tight = sparse.trimmed();
|
||||||
|
CHECK_EQ(tight.count(), 2u);
|
||||||
|
CHECK(tight.min() == Vec3i(4, 5, 6));
|
||||||
|
CHECK(tight.max() == Vec3i(7, 5, 6));
|
||||||
|
CHECK_EQ(tight.cellCount(), 4u);
|
||||||
|
CHECK(tight.sameCells(sparse));
|
||||||
|
}
|
||||||
Reference in new issue
Block a user