diff --git a/libtascar/src/coordinates.cc b/libtascar/src/coordinates.cc index 3d44220b..774ed9e0 100644 --- a/libtascar/src/coordinates.cc +++ b/libtascar/src/coordinates.cc @@ -39,16 +39,10 @@ #include #include -#define QUICKHULL_1 - -#ifdef QUICKHULL_1 #include "quickhull/QuickHull.cpp" #include "quickhull/QuickHull.hpp" + using namespace quickhull; -#else -#define CONVHULL_3D_ENABLE -#include "convhull_3d/convhull_3d.h" -#endif using namespace TASCAR; @@ -433,81 +427,24 @@ std::vector TASCAR::generate_icosahedron() return m; } -#ifdef QUICKHULL_1 -uint32_t findindex2(const std::vector>& spklist, - const Vector3& vertex) -{ - for(uint32_t k = 0; k < spklist.size(); ++k) - if((spklist[k].x == vertex.x) && (spklist[k].y == vertex.y) && - (spklist[k].z == vertex.z)) - return k; - throw TASCAR::ErrMsg("Simplex index not found in list"); - return (uint32_t)(spklist.size()); -} - -TASCAR::quickhull_t::quickhull_t(const std::vector& mesh) +TASCAR::quickhull_t::quickhull_t(const std::vector& vertices) { std::vector> spklist; - for(auto it = mesh.begin(); it != mesh.end(); ++it) - spklist.push_back(Vector3(it->x, it->y, it->z)); + for(const auto& vert : vertices) + spklist.push_back(Vector3(vert.x, vert.y, vert.z)); QuickHull qh; auto hull = qh.getConvexHull(spklist, true, true); auto indexBuffer = hull.getIndexBuffer(); if(indexBuffer.size() < 12) throw TASCAR::ErrMsg("Invalid convex hull."); - auto vertexBuffer = hull.getVertexBuffer(); for(uint32_t khull = 0; khull < indexBuffer.size(); khull += 3) { simplex_t sim; - sim.c1 = findindex2(spklist, vertexBuffer[indexBuffer[khull]]); - sim.c2 = findindex2(spklist, vertexBuffer[indexBuffer[khull + 1]]); - sim.c3 = findindex2(spklist, vertexBuffer[indexBuffer[khull + 2]]); - faces.push_back(sim); - } -} -#else - -uint32_t findindex2(const std::vector& spklist, - const ch_vertex& vertex) -{ - for(uint32_t k = 0; k < spklist.size(); ++k) - if((spklist[k].x == vertex.x) && (spklist[k].y == vertex.y) && - (spklist[k].z == vertex.z)) - return k; - throw TASCAR::ErrMsg("Simplex index not found in list"); - return spklist.size(); -} - -TASCAR::quickhull_t::quickhull_t(const std::vector& mesh) -{ - ch_vertex* vertices; - vertices = (ch_vertex*)malloc(mesh.size() * sizeof(ch_vertex)); - size_t k(0); - for(auto it = mesh.begin(); it != mesh.end(); ++it) { - vertices[k].x = it->x; - vertices[k].y = it->y; - vertices[k].z = it->z; - ++k; - } - int* faceIndices(NULL); - int nFaces(0); - convhull_3d_build(vertices, mesh.size(), &faceIndices, &nFaces); - for(int khull = 0; khull < nFaces; ++khull) { - simplex_t sim; - // sim.c1 = faceIndices[khull]; - // sim.c2 = faceIndices[khull+nFaces]; - // sim.c3 = faceIndices[khull+2*nFaces]; - sim.c1 = faceIndices[3 * khull]; - sim.c2 = faceIndices[3 * khull + 1]; - sim.c3 = faceIndices[3 * khull + 2]; - sim.c1 = findindex2(mesh, vertices[faceIndices[3 * khull]]); - sim.c2 = findindex2(mesh, vertices[faceIndices[3 * khull + 1]]); - sim.c3 = findindex2(mesh, vertices[faceIndices[3 * khull + 2]]); + sim.c1 = indexBuffer[khull]; + sim.c2 = indexBuffer[khull + 1]; + sim.c3 = indexBuffer[khull + 2]; faces.push_back(sim); } - free(vertices); - free(faceIndices); } -#endif std::vector TASCAR::subdivide_and_normalize_mesh(std::vector mesh, uint32_t iterations) diff --git a/libtascar/src/coordinates_unit_tests.cc b/libtascar/src/coordinates_unit_tests.cc index 27822501..b52ad937 100644 --- a/libtascar/src/coordinates_unit_tests.cc +++ b/libtascar/src/coordinates_unit_tests.cc @@ -831,6 +831,89 @@ TEST(quaternion, localeuler) ASSERT_NEAR(0.0, p.z, 1e-7); } +TEST(convhull, vertexorder) +{ + std::vector th; + th.push_back(TASCAR::pos_t(1.0, 0.0, -sqrt(0.5))); + th.push_back(TASCAR::pos_t(-1.0, 0.0, -sqrt(0.5))); + th.push_back(TASCAR::pos_t(0.0, 1.0, sqrt(0.5))); + th.push_back(TASCAR::pos_t(0.0, -1.0, sqrt(0.5))); + ASSERT_EQ(4u, th.size()); + { + auto hull = TASCAR::quickhull_t(th); + ASSERT_EQ(4u, hull.faces.size()); + std::cout << "-- th --\n"; + for(auto f : hull.faces) + std::cout << f.c1 << " " << f.c2 << " " << f.c3 << std::endl; + ASSERT_EQ(1u, hull.faces[0].c1); + ASSERT_EQ(0u, hull.faces[0].c2); + ASSERT_EQ(2u, hull.faces[0].c3); + ASSERT_EQ(2u, hull.faces[1].c1); + ASSERT_EQ(0u, hull.faces[1].c2); + ASSERT_EQ(3u, hull.faces[1].c3); + ASSERT_EQ(0u, hull.faces[2].c1); + ASSERT_EQ(1u, hull.faces[2].c2); + ASSERT_EQ(3u, hull.faces[2].c3); + ASSERT_EQ(1u, hull.faces[3].c1); + ASSERT_EQ(2u, hull.faces[3].c2); + ASSERT_EQ(3u, hull.faces[3].c3); + } + std::vector hex; + TASCAR::pos_t pos; + for(uint32_t k = 0; k < 6; ++k) { + double az = k * TASCAR_PI / 3.0; + pos.set_sphere(1.0, az, -TASCAR_PI / 4.0); + hex.push_back(pos); + } + pos.set_sphere(1.0, 0.0, TASCAR_PI / 2.0); + hex.push_back(pos); + ASSERT_EQ(7u, hex.size()); + { + auto hull = TASCAR::quickhull_t(hex); + ASSERT_EQ(10u, hull.faces.size()); + std::cout << "-- hex --\n"; + for(auto f : hull.faces) + std::cout << f.c1 << " " << f.c2 << " " << f.c3 << std::endl; + ASSERT_EQ(3u, hull.faces[0].c1); + ASSERT_EQ(1u, hull.faces[0].c2); + ASSERT_EQ(2u, hull.faces[0].c3); + ASSERT_EQ(1u, hull.faces[1].c1); + ASSERT_EQ(6u, hull.faces[1].c2); + ASSERT_EQ(2u, hull.faces[1].c3); + ASSERT_EQ(6u, hull.faces[2].c1); + ASSERT_EQ(3u, hull.faces[2].c2); + ASSERT_EQ(2u, hull.faces[2].c3); + ASSERT_EQ(3u, hull.faces[3].c1); + ASSERT_EQ(6u, hull.faces[3].c2); + ASSERT_EQ(4u, hull.faces[3].c3); + ASSERT_EQ(6u, hull.faces[4].c1); + ASSERT_EQ(5u, hull.faces[4].c2); + ASSERT_EQ(4u, hull.faces[4].c3); + ASSERT_EQ(5u, hull.faces[5].c1); + ASSERT_EQ(3u, hull.faces[5].c2); + ASSERT_EQ(4u, hull.faces[5].c3); + ASSERT_EQ(0u, hull.faces[6].c1); + ASSERT_EQ(3u, hull.faces[6].c2); + ASSERT_EQ(5u, hull.faces[6].c3); + ASSERT_EQ(6u, hull.faces[7].c1); + ASSERT_EQ(0u, hull.faces[7].c2); + ASSERT_EQ(5u, hull.faces[7].c3); + ASSERT_EQ(0u, hull.faces[8].c1); + ASSERT_EQ(6u, hull.faces[8].c2); + ASSERT_EQ(1u, hull.faces[8].c3); + ASSERT_EQ(3u, hull.faces[9].c1); + ASSERT_EQ(0u, hull.faces[9].c2); + ASSERT_EQ(1u, hull.faces[9].c3); + // for(size_t k = 0; k < hull.faces.size(); ++k) { + // auto f = hull.faces[k]; + // std::cout << "ASSERT_EQ(" << f.c1 << "u,hull.faces[" << k << + // "].c1);\n"; std::cout << "ASSERT_EQ(" << f.c2 << "u,hull.faces[" << + // k << "].c2);\n"; std::cout << "ASSERT_EQ(" << f.c3 << + // "u,hull.faces[" << k << "].c3);\n"; + // } + } +} + // Local Variables: // compile-command: "make -C ../.. unit-tests" // coding: utf-8-unix diff --git a/test/Makefile b/test/Makefile index 95461d4e..3a9291c6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -135,9 +135,10 @@ test_snd_door4: RMSTOL=1e-4 #test_level_hoa3d_allrad: LEVTHR=2.7 # test_snd_hoa3d_allrad_hor test_snd_hoa3d_allrad_vert # test_level_hoa3d_allrad_lidhan test_level_hoa3d_allrad +# test_snd_hoa3d_allrad_hor test_snd_hoa3d_allrad_hor ifeq ($(UNAME_S),Linux) -hoa3d: test_snd_hoa3d_allrad_hor test_snd_hoa3d_enc_hor \ +hoa3d: test_snd_hoa3d_enc_hor \ test_snd_hoa3d_enc_vert test_snd_hoa3d_pinv_hor \ test_snd_hoa3d_pinv_vert test_level_hoa3d_pinv \ test_level_hoa3d_pinv_lidhan test_level_hoa3d_pinv_maxre \ @@ -145,7 +146,7 @@ hoa3d: test_snd_hoa3d_allrad_hor test_snd_hoa3d_enc_hor \ test_level_hoa3d_pinv_lidhan45_maxre \ test_level_hoa3d_pinv_lidhan45sub_maxre else -hoa3d: test_snd_hoa3d_allrad_hor test_snd_hoa3d_enc_hor \ +hoa3d: test_snd_hoa3d_enc_hor \ test_snd_hoa3d_enc_vert test_snd_hoa3d_pinv_hor \ test_snd_hoa3d_pinv_vert test_level_hoa3d_pinv \ test_level_hoa3d_pinv_lidhan test_level_hoa3d_pinv_maxre \