update working

This commit is contained in:
2025-01-05 13:41:36 +00:00
parent 595259b2cc
commit ef55ec5ab4
5 changed files with 307 additions and 290 deletions

View File

@@ -220,10 +220,11 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
Space space = empty_voxel_space; Space space = empty_voxel_space;
space.space = reprs_in[0]; space.space = reprs_in[0];
cullEmptySpace(&space); cullEmptySpace(&space);
positions = getAllPositionsInPrism(arena, &space, dims); positions = getAllPositionsInPrism(permsArena, &space, dims);
uint64 *insertion = PushArray(arena, uint64, positions.length);
polycubes.length += positions.length; polycubes.length += positions.length;
polycubes.head += positions.head; polycubes.head += positions.head;
memcpy(polycubes.data, positions.data, positions.length / sizeof(uint64)); memcpy(insertion, positions.data, positions.length * sizeof(uint64));
}; };
for (size_t i = 1; i < reprs_in_count; i++) { for (size_t i = 1; i < reprs_in_count; i++) {
@@ -232,9 +233,10 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
space.space = reprs_in[i]; space.space = reprs_in[i];
cullEmptySpace(&space); cullEmptySpace(&space);
list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims); list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims);
polycubes.length += positions.length; uint64 *insertion = PushArray(arena, uint64, perms.length);
polycubes.head += positions.head; polycubes.length += perms.length;
memcpy(polycubes.data + polycubes.length, perms.data, perms.length / sizeof(uint64)); polycubes.head += perms.head;
memcpy(insertion, perms.data, perms.length * sizeof(uint64));
} }
appendList(&offsets, polycubes.length); appendList(&offsets, polycubes.length);

View File

@@ -212,7 +212,7 @@ list<Space> getUniqueRotations(Arena *arena, Space *space) {
rotate90Z(&refSpace); rotate90Z(&refSpace);
rotate90Z(&refSpace); rotate90Z(&refSpace);
pushNewUniqueSpins(&rotations, &refSpace); pushNewUniqueSpins(&rotations, &refSpace);
rotations.head = rotations.length; rotations.length = rotations.head;
arenaPopTo(arena, rotations.data + rotations.head); arenaPopTo(arena, rotations.data + rotations.head);
return rotations; return rotations;
} }
@@ -239,8 +239,8 @@ list<uint64> getAllPositionsInPrism(Arena *arena, Space *space, int prism_dims[3
if (space->dim_x > prism_dims[0] || space->dim_y > prism_dims[1] || space->dim_z > prism_dims[2]) { if (space->dim_x > prism_dims[0] || space->dim_y > prism_dims[1] || space->dim_z > prism_dims[2]) {
return list<uint64>{0}; return list<uint64>{0};
} }
list<uint64> result = PushList(arena, uint64, 0);
int count = 0; int count = 0;
void *startList = 0;
int xPositionCount = prism_dims[0] - space->dim_x + 1; int xPositionCount = prism_dims[0] - space->dim_x + 1;
int yPositionCount = prism_dims[1] - space->dim_y + 1; int yPositionCount = prism_dims[1] - space->dim_y + 1;
int zPositionCount = prism_dims[2] - space->dim_z + 1; int zPositionCount = prism_dims[2] - space->dim_z + 1;
@@ -248,6 +248,9 @@ list<uint64> getAllPositionsInPrism(Arena *arena, Space *space, int prism_dims[3
for (int y = 0; y < yPositionCount; y++) { for (int y = 0; y < yPositionCount; y++) {
for (int z = 0; z < zPositionCount; z++) { for (int z = 0; z < zPositionCount; z++) {
uint64 *new_space = PushStruct(arena, uint64); uint64 *new_space = PushStruct(arena, uint64);
if (!startList) {
startList = new_space;
}
*new_space = 0; *new_space = 0;
count++; count++;
for (int posX = 0; posX < space->dim_x; posX++) { for (int posX = 0; posX < space->dim_x; posX++) {
@@ -262,6 +265,8 @@ list<uint64> getAllPositionsInPrism(Arena *arena, Space *space, int prism_dims[3
} }
} }
} }
list<uint64> result = {};
result.data = (uint64 *)startList;
result.length = count; result.length = count;
result.head = count; result.head = count;
return result; return result;
@@ -275,7 +280,7 @@ list<uint64> getAllPermutationsInPrism(Arena *arena, Space *space, int prism_dim
for (EachIn(rotations, i)) { for (EachIn(rotations, i)) {
list<uint64> positions = getAllPositionsInPrism(temp.arena, &rotations.data[i], prism_dims); list<uint64> positions = getAllPositionsInPrism(temp.arena, &rotations.data[i], prism_dims);
uint64 *listAppend = PushArray(arena, uint64, positions.length); uint64 *listAppend = PushArray(arena, uint64, positions.length);
memcpy(listAppend, positions.data, positions.length / sizeof(uint64)); memcpy(listAppend, positions.data, positions.length * sizeof(uint64));
result.length += positions.length; result.length += positions.length;
result.head += positions.head; result.head += positions.head;
} }

View File

@@ -210,8 +210,8 @@ void log(const char *fmt, ...);
void logError(const char *fmt, ...); void logError(const char *fmt, ...);
// ### Loops ### // ### Loops ###
#define EachIn(list, it) size_t it = 0; it < (list).length; it++ #define EachIn(list, it) size_t it = 0; it < (list).head; it++
#define EachInReversed(list, it) size_t it = (list).length - 1; it >= 0 && it < (list).length; it-- #define EachInReversed(list, it) size_t it = (list).head - 1; it >= 0 && it < (list).head; it--
#define EachInArray(arr, it) size_t it = 0; it < ArrayCount(arr); ++it #define EachInArray(arr, it) size_t it = 0; it < ArrayCount(arr); ++it
// ### Misc ### // ### Misc ###

View File

@@ -20,6 +20,8 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "lib/loaders/stb_image.h" #include "lib/loaders/stb_image.h"
#include "./tests.cpp"
struct Entity; struct Entity;
struct Polycube; struct Polycube;
struct SceneGraphNode; struct SceneGraphNode;
@@ -395,6 +397,6 @@ int main_gfx() {
int main() { int main() {
initialiseCore(); initialiseCore();
return main_gfx(); return main_cmd();
} }

View File

@@ -1,312 +1,320 @@
#include <gtest/gtest.h> #include <iostream>
#include <istream> #include <vector>
#include <tuple> #include <tuple>
#include "VoxelSpace.h" #include "VoxelSpace.h"
#include "lib/djstdlib/core.h"
TEST(VoxelSpaces, BasicPositions) { void test() {
auto space = Voxel::Space{ {
.space=23ul, Space space = {};
.dim_x=3, space.space=23ull;
.dim_y=3, space.dim_x=3;
.dim_z=3, space.dim_y=3;
}; space.dim_z=3;
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 1), true);
EXPECT_EQ(Voxel::filledAt(&space, 1, 0, 0), false);
EXPECT_EQ(Voxel::filledAt(&space, 2, 1, 2), false);
EXPECT_EQ(Voxel::filledAt(&space, 1, 2, 1), false);
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 0), true);
EXPECT_EQ(Voxel::filledAt(&space, 2, 2, 1), false);
space.space = 30ul; Assert(filledAt(&space, 0, 0, 1) == true);
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 1), true); Assert(filledAt(&space, 1, 0, 0) == false);
EXPECT_EQ(Voxel::filledAt(&space, 1, 0, 0), false); Assert(filledAt(&space, 2, 1, 2) == false);
EXPECT_EQ(Voxel::filledAt(&space, 2, 1, 2), false); Assert(filledAt(&space, 1, 2, 1) == false);
EXPECT_EQ(Voxel::filledAt(&space, 1, 2, 1), false); Assert(filledAt(&space, 0, 0, 0) == true);
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 0), false); Assert(filledAt(&space, 2, 2, 1) == false);
EXPECT_EQ(Voxel::filledAt(&space, 2, 2, 1), false);
space.space = 15ul; space.space = 30ull;
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 1), true); Assert(filledAt(&space, 0, 0, 1) == true);
EXPECT_EQ(Voxel::filledAt(&space, 1, 0, 0), false); Assert(filledAt(&space, 1, 0, 0) == false);
EXPECT_EQ(Voxel::filledAt(&space, 2, 1, 2), false); Assert(filledAt(&space, 2, 1, 2) == false);
EXPECT_EQ(Voxel::filledAt(&space, 1, 2, 1), false); Assert(filledAt(&space, 1, 2, 1) == false);
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 0), true); Assert(filledAt(&space, 0, 0, 0) == false);
EXPECT_EQ(Voxel::filledAt(&space, 2, 2, 1), false); Assert(filledAt(&space, 2, 2, 1) == false);
space.space = 23ul; space.space = 15ull;
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 1), true); Assert(filledAt(&space, 0, 0, 1) == true);
EXPECT_EQ(Voxel::filledAt(&space, 1, 0, 0), false); Assert(filledAt(&space, 1, 0, 0) == false);
EXPECT_EQ(Voxel::filledAt(&space, 2, 1, 2), false); Assert(filledAt(&space, 2, 1, 2) == false);
EXPECT_EQ(Voxel::filledAt(&space, 1, 2, 1), false); Assert(filledAt(&space, 1, 2, 1) == false);
EXPECT_EQ(Voxel::filledAt(&space, 0, 0, 0), true); Assert(filledAt(&space, 0, 0, 0) == true);
EXPECT_EQ(Voxel::filledAt(&space, 2, 2, 1), false); Assert(filledAt(&space, 2, 2, 1) == false);
}
TEST(VoxelSpaces, RotatedIndices) { space.space = 23ull;
auto space1 = Voxel::Space{ Assert(filledAt(&space, 0, 0, 1) == true);
.space=172ul, Assert(filledAt(&space, 1, 0, 0) == false);
.dim_x=3, Assert(filledAt(&space, 2, 1, 2) == false);
.dim_y=3, Assert(filledAt(&space, 1, 2, 1) == false);
.dim_z=3, Assert(filledAt(&space, 0, 0, 0) == true);
Assert(filledAt(&space, 2, 2, 1) == false);
}; };
EXPECT_EQ(Voxel::newIndexRotX(&space1, 0, 0, 0), 6); {
EXPECT_EQ(Voxel::newIndexRotX(&space1, 1, 0, 1), 12); Space space1 = {};
space1.space=172ull;
space1.dim_x=3;
space1.dim_y=3;
space1.dim_z=3;
EXPECT_EQ(Voxel::newIndexRotY(&space1, 0, 1, 0), 5); Assert(newIndexRotX(&space1, 0, 0, 0) == 6);
EXPECT_EQ(Voxel::newIndexRotY(&space1, 1, 2, 0), 7); Assert(newIndexRotX(&space1, 1, 0, 1) == 12);
EXPECT_EQ(Voxel::newIndexRotZ(&space1, 1, 0, 2), 23); Assert(newIndexRotY(&space1, 0, 1, 0) == 5);
EXPECT_EQ(Voxel::newIndexRotZ(&space1, 0, 0, 0), 18); Assert(newIndexRotY(&space1, 1, 2, 0) == 7);
}
TEST(VoxelSpaces, UniqueRotations) { Assert(newIndexRotZ(&space1, 1, 0, 2) == 23);
auto space1 = Voxel::Space{ Assert(newIndexRotZ(&space1, 0, 0, 0) == 18);
.space=30ul, }
.dim_x=3,
.dim_y=3, {
.dim_z=3, Arena *arena = arenaAlloc(Megabytes(64));
Space space1 = {};
space1.space=30ull;
space1.dim_x=3;
space1.dim_y=3;
space1.dim_z=3;
list<Space> rotations = getUniqueRotations(arena, &space1);
Space expected_rots[] = {
{ 30ull, 1, 2, 3 },
{ 45ull, 1, 3, 2 },
{ 30ull, 3, 2, 1 },
{ 30ull, 3, 1, 2 },
{ 45ull, 3, 2, 1 },
{ 45ull, 3, 1, 2 },
{ 51ull, 1, 2, 3 },
{ 30ull, 1, 3, 2 },
{ 30ull, 2, 3, 1 },
{ 30ull, 2, 1, 3 },
{ 51ull, 2, 3, 1 },
{ 51ull, 2, 1, 3 },
}; };
auto rotations = Voxel::getUniqueRotations(&space1); Assert(ArrayCount(expected_rots) == rotations.length);
auto expected_rots = std::vector<Voxel::Space>{
{ 30ul, 1, 2, 3 },
{ 45ul, 1, 3, 2 },
{ 30ul, 3, 2, 1 },
{ 30ul, 3, 1, 2 },
{ 45ul, 3, 2, 1 },
{ 45ul, 3, 1, 2 },
{ 51ul, 1, 2, 3 },
{ 30ul, 1, 3, 2 },
{ 30ul, 2, 3, 1 },
{ 30ul, 2, 1, 3 },
{ 51ul, 2, 3, 1 },
{ 51ul, 2, 1, 3 },
};
ASSERT_EQ(expected_rots.size(), rotations.size()); for (int i = 0; i < rotations.length; i++) {
if (i <= ArrayCount(expected_rots)) {
for (int i = 0; i < rotations.size(); i++) { Assert(isMatch(&expected_rots[i], &rotations.data[i]) == true);
if (i <= expected_rots.size()) {
EXPECT_EQ(Voxel::isMatch(&expected_rots.at(i), &rotations.at(i)), true);
} }
} }
}
TEST(VoxelSpaces, AllPermutationsInPrism) { arenaFree(arena);
auto space1 = Voxel::Space{ }
.space=30ul,
.dim_x=3,
.dim_y=3,
.dim_z=3,
};
auto prism_dims = std::array<int, 3>{ 3, 3, 3 }; {
auto perms = Voxel::getAllPermutationsInPrism(&space1, prism_dims.begin()); Arena *arena = arenaAlloc(Megabytes(64));
Space space1 = {};
space1.space=30ul;
space1.dim_x=3;
space1.dim_y=3;
space1.dim_z=3;
int prism_dims[] = { 3, 3, 3 };
list<uint64> perms = getAllPermutationsInPrism(arena, &space1, prism_dims);
auto expected_perms = std::vector<uint64_t>{ auto expected_perms = std::vector<uint64_t>{
30ul, 30ull,
240ul, 240ull,
15360ul, 15360ull,
122880ul, 122880ull,
7864320ul, 7864320ull,
62914560ul, 62914560ull,
153ul, 153ull,
306ul, 306ull,
78336ul, 78336ull,
156672ul, 156672ull,
40108032ul, 40108032ull,
80216064ul, 80216064ull,
266760ul, 266760ull,
533520ul, 533520ull,
1067040ul, 1067040ull,
2134080ul, 2134080ull,
4268160ul, 4268160ull,
8536320ul, 8536320ull,
263682ul, 263682ull,
527364ul, 527364ull,
2109456ul, 2109456ull,
4218912ul, 4218912ull,
16875648ul, 16875648ull,
33751296ul, 33751296ull,
2101761ul, 2101761ull,
4203522ul, 4203522ull,
8407044ul, 8407044ull,
16814088ul, 16814088ull,
33628176ul, 33628176ull,
67256352ul, 67256352ull,
525825ul, 525825ull,
1051650ul, 1051650ull,
4206600ul, 4206600ull,
8413200ul, 8413200ull,
33652800ul, 33652800ull,
67305600ul, 67305600ull,
51ul, 51ull,
408ul, 408ull,
26112ul, 26112ull,
208896ul, 208896ull,
13369344ul, 13369344ull,
106954752ul, 106954752ull,
90ul, 90ull,
180ul, 180ull,
46080ul, 46080ull,
92160ul, 92160ull,
23592960ul, 23592960ull,
47185920ul, 47185920ull,
4680ul, 4680ull,
9360ul, 9360ull,
18720ul, 18720ull,
2396160ul, 2396160ull,
4792320ul, 4792320ull,
9584640ul, 9584640ull,
1542ul, 1542ull,
12336ul, 12336ull,
98688ul, 98688ull,
789504ul, 789504ull,
6316032ul, 6316032ull,
50528256ul, 50528256ull,
36873ul, 36873ull,
73746ul, 73746ull,
147492ul, 147492ull,
18878976ul, 18878976ull,
37757952ul, 37757952ull,
75515904ul, 75515904ull,
3075ul, 3075ull,
24600ul, 24600ull,
196800ul, 196800ull,
1574400ul, 1574400ull,
12595200ul, 12595200ull,
100761600ul, 100761600ull,
}; };
ASSERT_EQ(expected_perms.size(), perms.size()); Assert(expected_perms.size() == perms.length);
for (int i = 0; i < perms.size(); i++) { for (int i = 0; i < perms.length; i++) {
if (i <= expected_perms.size()) { if (i <= expected_perms.size()) {
EXPECT_EQ(expected_perms.at(i), perms.at(i)); Assert(expected_perms.at(i) == perms.data[i]);
} }
} }
}
TEST(VoxelSpaces, RotateXYZ) { arenaFree(arena);
auto space1 = Voxel::Space{ }
.space=30ul,
.dim_x=3,
.dim_y=3,
.dim_z=3,
};
auto space2 = Voxel::Space{ {
.space=30ul, Space space1 = {};
.dim_x=3, space1.space=30ull;
.dim_y=3, space1.dim_x=3;
.dim_z=3, space1.dim_y=3;
}; space1.dim_z=3;
auto space3 = Voxel::Space{ Space space2 = {};
.space=30ul, space2.space=30ull;
.dim_x=3, space2.dim_x=3;
.dim_y=3, space2.dim_y=3;
.dim_z=3, space2.dim_z=3;
};
Voxel::rotate90X(&space1); Space space3 = {};
Voxel::rotate90Y(&space2); space3.space=30ull;
Voxel::rotate90Z(&space3); space3.dim_x=3;
EXPECT_EQ(space1.space, 153ul); space3.dim_y=3;
EXPECT_EQ(space2.space, 1067040ul); space3.dim_z=3;
EXPECT_EQ(space3.space, 1574400ul);
} rotate90X(&space1);
rotate90Y(&space2);
rotate90Z(&space3);
Assert(space1.space == 153ull);
Assert(space2.space == 1067040ull);
Assert(space3.space == 1574400ull);
}
{
Arena *arena = arenaAlloc(Megabytes(64));
TEST(VoxelSpaces, GetAllPositionsInPrism) {
int dims[] = {3, 3, 3}; int dims[] = {3, 3, 3};
auto space1 = Voxel::Space{ Space space1 = {};
.space=30ul, space1.space=30ull;
.dim_x=3, space1.dim_x=3;
.dim_y=3, space1.dim_y=3;
.dim_z=3, space1.dim_z=3;
};
Voxel::cullEmptySpace(&space1); cullEmptySpace(&space1);
uint64_t expected_results1[] = { uint64 expected_results1[] = {
30ul, 30ull,
240ul, 240ull,
15360ul, 15360ull,
122880ul, 122880ull,
7864320ul, 7864320ull,
62914560ul, 62914560ull,
}; };
auto space2 = Voxel::Space{ Space space2 = {};
.space=23ul, space2.space=23ul;
.dim_x=3, space2.dim_x=3;
.dim_y=3, space2.dim_y=3;
.dim_z=3, space2.dim_z=3;
};
Voxel::cullEmptySpace(&space2); cullEmptySpace(&space2);
uint64_t expected_results2[] = { uint64_t expected_results2[] = {
23ul, 23ull,
184ul, 184ull,
11776ul, 11776ull,
94208ul, 94208ull,
6029312ul, 6029312ull,
48234496ul, 48234496ull,
}; };
auto space3 = Voxel::Space{ Space space3 = {};
.space=15ul, space3.space=15ull;
.dim_x=3, space3.dim_x=3;
.dim_y=3, space3.dim_y=3;
.dim_z=3, space3.dim_z=3;
};
Voxel::cullEmptySpace(&space3); cullEmptySpace(&space3);
uint64_t expected_results3[] = { uint64 expected_results3[] = {
15ul, 15ull,
120ul, 120ull,
7680ul, 7680ull,
61440ul, 61440ull,
3932160ul, 3932160ull,
31457280ul, 31457280ull,
}; };
auto positions1 = Voxel::getAllPositionsInPrism(&space1, dims); list<uint64> positions1 = getAllPositionsInPrism(arena, &space1, dims);
auto positions2 = Voxel::getAllPositionsInPrism(&space2, dims); list<uint64> positions2 = getAllPositionsInPrism(arena, &space2, dims);
auto positions3 = Voxel::getAllPositionsInPrism(&space3, dims); list<uint64> positions3 = getAllPositionsInPrism(arena, &space3, dims);
auto mismatches1 = std::vector<std::tuple<int, uint64_t, uint64_t>>(); auto mismatches1 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
auto mismatches2 = std::vector<std::tuple<int, uint64_t, uint64_t>>(); auto mismatches2 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
auto mismatches3 = std::vector<std::tuple<int, uint64_t, uint64_t>>(); auto mismatches3 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
if (positions1[i] != expected_results1[i]) { if (positions1.data[i] != expected_results1[i]) {
mismatches1.push_back({ i, positions1[i], expected_results1[i] }); mismatches1.push_back({ i, positions1.data[i], expected_results1[i] });
} }
if (positions2[i] != expected_results2[i]) { if (positions2.data[i] != expected_results2[i]) {
mismatches2.push_back({ i, positions2[i], expected_results2[i] }); mismatches2.push_back({ i, positions2.data[i], expected_results2[i] });
} }
if (positions3[i] != expected_results3[i]) { if (positions3.data[i] != expected_results3[i]) {
mismatches3.push_back({ i, positions3[i], expected_results3[i] }); mismatches3.push_back({ i, positions3.data[i], expected_results3[i] });
} }
} }
EXPECT_EQ(mismatches1.size(), 0); Assert(mismatches1.size() == 0);
if (mismatches1.size() > 0) { if (mismatches1.size() > 0) {
std::cout << "Index - Actual - Expected" << std::endl; std::cout << "Index - Actual - Expected" << std::endl;
for (auto &mismatch : mismatches1) { for (auto &mismatch : mismatches1) {
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl; std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl;
} }
} }
EXPECT_EQ(mismatches2.size(), 0); Assert(mismatches2.size() == 0);
if (mismatches2.size() > 0) { if (mismatches2.size() > 0) {
std::cout << "Index - Actual - Expected" << std::endl; std::cout << "Index - Actual - Expected" << std::endl;
for (auto &mismatch : mismatches2) { for (auto &mismatch : mismatches2) {
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl; std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl;
} }
} }
EXPECT_EQ(mismatches3.size(), 0); Assert(mismatches3.size() == 0);
if (mismatches3.size() > 0) { if (mismatches3.size() > 0) {
std::cout << "Index - Actual - Expected" << std::endl; std::cout << "Index - Actual - Expected" << std::endl;
for (auto &mismatch : mismatches3) { for (auto &mismatch : mismatches3) {
std::cout << "At " << std::get<0>(mismatch) << ": " << std::get<1>(mismatch) << " != " << std::get<2>(mismatch) << std::endl; std::cout << "At " << std::get<0>(mismatch) << ": " << std::get<1>(mismatch) << " != " << std::get<2>(mismatch) << std::endl;
} }
} }
arenaFree(arena);
}
} }