Начальный коммит: Vulkan-редактор SimVulcan + исследование KBC-LBM
Состояние на момент заведения репозитория. C++ приложение (src/, shaders/, tests/) — минимальный редактор 3D-моделей на Vulkan 1.3: орбитальная камера, три опорные сетки через начало координат, загрузка .obj с режимами отображения. Весь Vulkan изолирован в src/vk/. Исследование (docs/) — оригинальные статьи по KBC (docs/origins) и Python-решатель D2Q9 KBC-N1 с AMR 2x и SDF+Bouzidi (docs/theory). В решателе перед коммитом исправлены дефекты, найденные сверкой с первоисточниками: относительный порог знаменателя энтропийного стабилизатора (абсолютный вырождал KBC в LBGK на 77-99% узлов), заворот вход/выход в углах домена, диагностика средней плотности по фиктивным узлам тела, зашитый refine=2. Подробности — docs/theory/solver_2x_sdf/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
add_executable(simv_tests
|
||||
unit/test_mesh.cpp
|
||||
)
|
||||
target_link_libraries(simv_tests PRIVATE
|
||||
Catch2::Catch2WithMain
|
||||
simv_mesh
|
||||
glm::glm
|
||||
)
|
||||
target_include_directories(simv_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
simv_set_warnings(simv_tests)
|
||||
catch_discover_tests(simv_tests)
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "mesh/Mesh.h"
|
||||
#include "mesh/MeshDecimator.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
|
||||
using simv::mesh::Mesh;
|
||||
using Catch::Matchers::WithinAbs;
|
||||
|
||||
TEST_CASE("Mesh::RecalculateBounds finds AABB", "[mesh]") {
|
||||
Mesh m;
|
||||
m.positions = {
|
||||
{-1.0f, -2.0f, -3.0f},
|
||||
{ 4.0f, 5.0f, 6.0f},
|
||||
{ 0.5f, 0.0f, 1.0f},
|
||||
};
|
||||
m.RecalculateBounds();
|
||||
REQUIRE_THAT(m.bboxMin.x, WithinAbs(-1.0f, 1e-6f));
|
||||
REQUIRE_THAT(m.bboxMin.y, WithinAbs(-2.0f, 1e-6f));
|
||||
REQUIRE_THAT(m.bboxMin.z, WithinAbs(-3.0f, 1e-6f));
|
||||
REQUIRE_THAT(m.bboxMax.x, WithinAbs( 4.0f, 1e-6f));
|
||||
REQUIRE_THAT(m.bboxMax.y, WithinAbs( 5.0f, 1e-6f));
|
||||
REQUIRE_THAT(m.bboxMax.z, WithinAbs( 6.0f, 1e-6f));
|
||||
}
|
||||
|
||||
TEST_CASE("WeldVertices collapses near-duplicate vertices", "[mesh][decimator]") {
|
||||
Mesh m;
|
||||
// Two triangles sharing an edge with verts placed within tolerance.
|
||||
m.positions = {
|
||||
{0.0f, 0.0f, 0.0f},
|
||||
{1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f},
|
||||
{0.0001f, 0.0f, 0.0f}, // ≈ #0
|
||||
{1.0001f, 0.0f, 0.0f}, // ≈ #1
|
||||
{1.0f, 1.0f, 0.0f},
|
||||
};
|
||||
m.indices = { 0, 1, 2, 3, 4, 5 };
|
||||
|
||||
simv::mesh::WeldVertices(m, /*tolerance=*/0.01f);
|
||||
|
||||
REQUIRE(m.positions.size() == 4);
|
||||
REQUIRE(m.indices.size() == 6); // both triangles still valid
|
||||
// Bounds should match the "real" hull regardless of welding order.
|
||||
REQUIRE_THAT(m.bboxMax.x, WithinAbs(1.0001f, 1e-3f));
|
||||
}
|
||||
|
||||
TEST_CASE("WeldVertices drops degenerate triangles", "[mesh][decimator]") {
|
||||
Mesh m;
|
||||
// One real triangle + a degenerate one (all three verts within tolerance).
|
||||
m.positions = {
|
||||
{0.0f, 0.0f, 0.0f},
|
||||
{1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f},
|
||||
{2.0f, 2.0f, 0.0f},
|
||||
{2.00005f, 2.0f, 0.0f},
|
||||
{2.0f, 2.00005f, 0.0f},
|
||||
};
|
||||
m.indices = { 0, 1, 2, 3, 4, 5 };
|
||||
|
||||
simv::mesh::WeldVertices(m, /*tolerance=*/0.001f);
|
||||
|
||||
// The degenerate triangle's three verts collapsed to one — that triangle
|
||||
// should be removed entirely.
|
||||
REQUIRE(m.indices.size() == 3);
|
||||
}
|
||||
Reference in New Issue
Block a user