Сплошная проверка документов против дерева. Код не менялся.
docs/rust_vs_cpp.md — числа, снятые с чужого каталога сборки:
- «775 МБ исходников зависимостей» и «10 пакетов в графе C++» получены
на build/, сконфигурированном из другого дерева (его _deps содержит
262 МБ nlohmann_json, который проект не объявляет). На деле девять
объявленных репозиториев дают ~400 МБ исходников;
- пакетов в графе Rust 82, а не 76 (cargo tree по текущему Cargo.lock);
- итог по строкам 2976/494, а не 2962/492: строка «меш» устарела на 17
строк игнорируемого диагностического теста, тесты в модулях — 176;
- «перевес почти весь в Vulkan-слое» — на деле 346 из 542 (64 %), из них
305 на Context и Swapchain; остальное приходится на меш, редактор и
приложение;
- «ни один замер не даёт разницы в порядок величины» неверно:
инкрементальная release — 52.3 против 4.4 с, это 11.9x;
- граней с пятью и более вершинами в plane.obj 119, а не 121;
- из Catch2 перенесены все три случая, и добавлено ещё два, а не
«три перенесены дословно»;
- деструктор Renderer::Impl — 22 строки, а не тридцать;
- путевых зависимостей у порта две: assets/meshes с откатом на текущий
каталог и pipeline_cache.bin рядом с бинарём;
- граф целей CMake ацикличен, цикл существует на уровне исходников —
именно поэтому CMake и молчит.
rust/README.md:
- объявленный rust-version = "1.82" недостижим: залоченные egui,
egui-winit и epaint 0.36.1 требуют 1.95;
- перечни зависимостей крейтов были неполны, приведены целиком;
- build.rs читает ../../../shaders, а не ../../shaders;
- тесты не «чистая математика»: тесты загрузчика читают файлы из
assets/meshes и требуют клон репозитория;
- assets/ порту никто не копирует, он находит корневую копию сам;
- те же поправки про цикл в CMake и про момент ожидания простоя.
README.md:
- панель называется Mesh, а не «Mesh load»;
- пресета clang-cl не существует, компилятор пресеты не фиксируют;
- версии Vulkan SDK и компиляторов сборкой не проверяются;
- Buffer и Image перечислены среди рабочих модулей vk/, хотя ими не
пользуется никто.
docs/theory/solver_2x_sdf/README.md:
- предлагался несуществующий переключатель cfg.collision="bgk" и реестр
операторов get; тот же файл двумя разделами ниже говорит, что оператор
зафиксирован.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Файл описывает всё дерево целиком, а ветки содержат разные его части
(порт на Rust, исследование CFD, базовый C++-редактор). Отслеживаемая
копия при каждом переключении подменялась бы версией своей ветки, тогда
как нужна одна общая. Содержимое на всех ветках было идентично, так что
расхождений открепление не теряет.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9Gcr11JJJyf8NnWsXjDzZ
Было сказано «около сорока строк вызовов» на глаз. Счёт по одним и тем же
модулям (Context и Swapchain целиком, код без пустых и комментариев) даёт
301 строку в C++ против 606 в порте.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Условия, цифры и разбор по коду. Замеры на одной машине подряд: сборка (полная,
тёплая, инкрементальная — в release и debug), размеры бинарей и каталогов, состав
и объём зависимостей, старт до готовности рендерера, процессорное время при 60 Гц,
строки по модулям одинаковыми правилами для обеих версий.
Главные наблюдения:
* инкрементальная release-сборка Rust 52 с против 4.4 с — это цена thin LTO, а не
языка: со сравнимым уровнем оптимизации 5.5 с против 4.4 с;
* FetchContent клонирует 775 МБ истории на каждый каталог сборки и не имеет общего
кэша; 76 крейтов Rust занимают 80 МБ в общем реестре;
* загрузчики .obj сходятся на cow.obj точно и расходятся на plane.obj на 0.13%
треугольников — из-за разной триангуляции многоугольников с n >= 5.
Плюс четыре дефекта C++-версии, найденных при переносе, в том числе строка
«Mesh ready», которую троттлинг категории MeshIO отбрасывает всегда: счётчики после
сварки не печатались никогда.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Та же программа на ash + winit + egui: орбитальная камера, три плоскости сетки,
загрузка .obj, три режима отображения, единый проход динамического рендеринга с
глубинным вложением и submit через synchronization2. Шейдеры общие с C++-версией —
build.rs компилирует их из shaders/ и вшивает SPIR-V в бинарь.
Пять крейтов повторяют карту целей CMake, но инвариант «весь Vulkan в одном месте»
теперь проверяет компилятор: у simv-mesh и simv-editor нет ash в зависимостях.
Расхождения, вынужденные языком, а не вкусом:
* App переехал в исполняемый крейт — в C++ граф целей цикличен (core владеет vk,
vk принимает core::Window&), и держится это лишь на том, что simv_vk видит
заголовки core, не линкуя цель; Cargo такой цикл отвергает;
* состояние сцены возвращается из замыкания интерфейса, а не ставится сеттерами:
замыкание вызывается из метода рендерера, трогать рендерер оттуда нельзя;
* выгрузка меша на видеокарту уехала из середины записи кадра, где C++-версия
зовёт vkDeviceWaitIdle уже после захвата образа цепочки показа.
Vulkan-контекст и цепочка показа написаны руками: замены vk-bootstrap в экосистеме
Rust нет. Обёртки Buffer и Image, лежащие в C++-версии без применения, здесь
задействованы всеми потребителями.
13 тестов, из них три перенесены из Catch2 дословно. cargo clippy -D warnings чист,
слой валидации молчит.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Состояние на момент заведения репозитория.
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>