WLXCAD — WLX-плагин просмотра DWG / DXF для Total Commander

В этом репозитории реализован CAD-просмотрщик только для чтения в виде нативного WLX-плагина, работающего внутри процесса Total Commander (F3 / Ctrl+Q). Это НЕ CAD-редактор.
Что реализовано в исходном коде
- Экспортируемые функции WLX:
ListLoad,ListLoadW,ListCloseWindow,ListGetDetectString; поддержка путей Windows в Unicode; отдельное окно и документ для каждого экземпляра просмотрщика. - Неблокирующая загрузка файлов, возможность отмены обработки результатов загрузки, отсутствие обращения к интерфейсу из рабочего потока, вывод сообщений об ошибках непосредственно в окне просмотра.
- Сглаживание средствами Direct2D, вывод текста через DirectWrite с резервным шрифтом TrueType (
Segoe UI), тёмный и светлый фон. - Вписывание чертежа в окно; масштабирование относительно курсора; перемещение чертежа перетаскиванием левой или средней кнопкой мыши; изменение размеров окна без повторной загрузки; необязательная сетка с динамическим шагом и индикатор осей XY.
- Список слоёв на основе ListView с флажками, изменение видимости без повторной загрузки файла; выбор пространства (модель / объекты, непосредственно расположенные на листе).
- Собственный парсер ASCII DXF, поддерживающий записи групп формата R12 и более поздних версий, а также объекты DXF:
LINE,LWPOLYLINE, классическиеPOLYLINE/VERTEX,ARC,CIRCLE,ELLIPSE,POINT,TEXT,MTEXT,INSERT,BLOCK,SOLID,TRACE,HATCH(упрощённо),SPLINE, атрибуты в виде текста там, где это применимо, и базовые ссылки на блокиDIMENSION. - Координаты CAD в формате двойной точности (
double); смещение начала координат перед рендерингом с использованиемfloat; цвета слоёв, TrueColor, приближённая палитра ACI, простые типы и приблизительная толщина линий. - Ограничение глубины рекурсии до 32 уровней и обнаружение циклов при вложенных вставках блоков. Отсечение объектов вне области просмотра для объектов, не относящихся к блокам. Геометрические сплайны аппроксимируются B-сплайнами с учётом узлового вектора.
- Рабочий путь загрузки DWG на основе GNU LibreDWG, включаемый параметром
WLXCAD_WITH_LIBREDWG=ON. DWG декодируется и преобразуется в DXF внутри процесса DLL, после чего импортируется в общую CAD-модель. Плагин не запускаетdwg2dxf.exeили какие-либо внешние CAD-приложения.
Известные ограничения и незавершённые требования для выпуска
- Готовые
.wlx/.wlx64не включены: в среде разработки отсутствуют Windows SDK, MSVC и Total Commander; компиляцию для Windows, проверку ABI и загрузки DLL, а также тестирование работы необходимо выполнить в Windows. Переносимые тесты парсера и геометрии на C++17 проходят в Linux. - По умолчанию собирается версия только для DXF. При попытке открыть DWG без сборки с LibreDWG просмотрщик отображает поясняющее сообщение об ошибке, а не имитирует чтение файла. Для поддержки DWG нужна сборка с совместимым Windows SDK LibreDWG (подробнее ниже). Поддерживаемые версии DWG зависят от выбранного выпуска LibreDWG и должны проверяться на реальных файлах.
- Двоичный DXF не реализован. Не поддерживаются внешние чертежи XREF, пользовательские и proxy-объекты, трёхмерные тела, геометрия SHX-шрифтов, растровые изображения, полноценные образцы штриховки HATCH с границами из рёбер и сплайнов, а также видовые экраны модели через объекты VIEWPORT на листах.
- Поддержка встроенного форматирования MTEXT частичная; используется только 2D-проекция XY; сплайны и дуги с
bulgeразбиваются на отрезки, а не отрисовываются как аналитические кривые с бесконечным разрешением. Поворот и растяжение текста внутри вложенных блоков отображаются приближённо. - Для больших файлов применяется отсечение отдельных объектов вне области просмотра, однако пространственный индекс и постоянный кэш геометрии Direct2D пока отсутствуют. Производительность на 100–500 тысячах объектов в Windows не измерялась.
- Сторонний CAD-декодер, работающий внутри процесса Total Commander, по-прежнему может привести к аварийному завершению основного приложения при нарушении доступа к памяти в нативном коде. Обработка исключений C++ не обеспечивает полной защиты от повреждённых DWG-файлов; гарантированная изоляция потребовала бы вынести декодер в отдельный процесс, что изменило бы архитектуру.
- Изменение видимости слоёв в режиме только для чтения может переопределять исходное состояние отключённых или замороженных слоёв, но не меняет сам файл.
Сборка (Windows / Visual Studio 2022)
Установите CMake 3.20 или новее, Visual Studio 2022 с компонентом «Разработка классических приложений на C++» (Desktop development with C++) и актуальный Windows SDK. Для сборки только с поддержкой DXF:
cmake --preset vs2022-x64
cmake --build --preset vs2022-x64-release
cmake --preset vs2022-x86
cmake --build --preset vs2022-x86-release
Ожидаемые выходные файлы:
build/vs2022-x64/Release/wlxcad.wlx64build/vs2022-x86/Release/wlxcad.wlx
CMakeLists.txt также копирует pluginst.inf и документацию в Release/package. Необходимо проверить экспортируемые функции DLL командой dumpbin /exports, затем проверить работу F3 и Ctrl+Q в вашей установленной версии Total Commander. Автоматические тесты не заменяют проверку в Windows.
Включение поддержки DWG (LibreDWG)
GNU LibreDWG распространяется по лицензии GPLv3 или более поздней версии. Используйте библиотеку, собранную для нужной архитектуры и совместимую с применяемыми версиями Visual C++ и CRT. Готовая DLL или библиотека импорта, собранная MinGW, может оказаться несовместимой с проектом Visual Studio на этапе линковки. В документации LibreDWG описана сборка с помощью MSVC/CMake.
Необходим SDK, содержащий dwg.h, bits.h, out_dxf.h, библиотеку импорта или статическую библиотеку и, в случае динамической сборки, соответствующие DLL и зависимости:
cmake --preset vs2022-x64 `
-DWLXCAD_WITH_LIBREDWG=ON `
-DLIBREDWG_ROOT="C:/sdk/libredwg/x64"
cmake --build --preset vs2022-x64-release
Для Win32 повторите сборку с соответствующим SDK x86. Параметр CMake требует наличия SDK на этапе конфигурации — он намеренно не реализован как заглушка. Если структура каталогов SDK отличается, явно задайте LIBREDWG_INCLUDE_DIR, LIBREDWG_BITS_INCLUDE_DIR, LIBREDWG_DXF_INCLUDE_DIR, LIBREDWG_CONFIG_INCLUDE_DIR и LIBREDWG_LIBRARY. Важно: LibreDWG генерирует config.h в каталоге CMake-сборки соответствующей архитектуры (build/libredwg-x64/src/config.h или build/libredwg-x86/src/config.h), а не в каталоге исходников. Переменная LIBREDWG_CONFIG_INCLUDE_DIR должна указывать на содержащий этот файл каталог src той же архитектуры, что и .lib. CMake проверяет SIZEOF_SIZE_T, чтобы предотвратить смешивание заголовков x86 и x64.
Функция LibreDWG dwg_read_file() принимает имя файла через API с аргументом char*: плагин создаёт копию DWG в %TEMP%, используя Unicode-безопасные функции Windows, затем пытается передать LibreDWG путь в кодировке ANSI или короткое имя 8.3 и выполняет преобразование через dwg_write_dxf(). Если путь временного каталога Windows не представим в системной ANSI-кодировке (ACP), а короткие имена 8.3 недоступны, импорт DWG может завершиться с понятным сообщением об ошибке. Это ограничение не затрагивает обработку путей к DXF встроенным парсером.
При статической линковке могут потребоваться дополнительные статические библиотеки, от которых зависит LibreDWG, в зависимости от её параметров сборки. При динамической линковке размещайте DLL зависимостей соответствующей архитектуры рядом с нужной библиотекой WLX. Не помещайте DLL для x86 и x64 с одинаковыми именами в один каталог. Скрипт упаковки проверяет зависимости DLL с помощью dumpbin, когда эта утилита доступна. В режиме -WithLibreDwg он требует dumpbin.exe и отклоняет неподдерживаемые динамические зависимости SDK и среды выполнения: для общего ZIP с версиями x86 и x64 связывайте LibreDWG и её зависимости статически.
Официальные ресурсы LibreDWG: https://www.gnu.org/software/libredwg/ и https://github.com/LibreDWG/libredwg. Соблюдайте лицензионные условия исходного проекта, указывайте авторство и включайте соответствующие исходные тексты и файлы лицензий при распространении двоичных сборок. Исходный код самого WLXCAD распространяется по GPL-3.0-or-later для совместимости с этим необязательным модулем.
Сборка и упаковка релиза одной командой (Windows)
Расположенный в корне проекта скрипт package.ps1 использует тот же процесс упаковки, что и WLX3D: настройка x64 → сборка Release → тесты → настройка x86 → сборка Release → тесты → подготовка файлов → создание ZIP. Используются существующие CMake-пресеты vs2022-x64, vs2022-x64-release, vs2022-x86 и vs2022-x86-release.
В PowerShell из каталога проекта:
.\package.ps1
Команда создаёт архив dist/wlxcad.zip и распакованный каталог dist/wlxcad/. Архив содержит wlxcad.wlx64, wlxcad.wlx, pluginst.inf, readme.txt, license.txt и BUILDINFO.txt. По умолчанию формируется релиз только с поддержкой DXF. При открытии DWG будет выводиться ошибка модуля LibreDWG, пока поддержка DWG не будет включена явно.
Другие примеры:
# Полная повторная конфигурация и пересборка обеих архитектур
.\package.ps1 -Clean
# Повторная упаковка уже собранных Release-файлов (с проверкой сохранённой настройки DWG)
.\package.ps1 -SkipBuild
# Сборка и упаковка с поддержкой DWG и отдельными SDK x64/x86
.\package.ps1 -Clean -WithLibreDwg
# Отключение тестов парсера или изменение имени ZIP-архива
.\package.ps1 -SkipTests -OutputName wlxcad-dev.zip
Для автоматического режима DWG (-WithLibreDwg) требуются Git, CMake, инструменты C++ Visual Studio 2022 и dumpbin.exe (используйте Developer PowerShell для Visual Studio). Скрипт запускает CMake библиотеки LibreDWG из каталога её исходников, чтобы определение версии по .version случайно не обращалось к постороннему Git-репозиторию WLXCAD (fatal: Not a valid object name HEAD). При первом запуске он клонирует ветку master исходного репозитория LibreDWG в third_party/libredwg вместе с Git-подмодулями (включая jsmn/jsmn.h), настраивает статическую сборку MSVC в build/libredwg-x64 и build/libredwg-x86, затем связывает полученные библиотеки с соответствующими DLL плагина. Если существующий локальный репозиторий был создан старой версией скрипта без подмодулей, скрипт обнаружит отсутствие jsmn/jsmn.h и автоматически выполнит git submodule update --init --recursive. Для ручного исправления используйте git -C .\third_party\libredwg submodule update --init --recursive. Скачанные исходники сохраняются локально и автоматически не обновляются; для повторной загрузки удалите third_party/libredwg либо укажите -LibreDwgRef <branch-or-tag> при первоначальном клонировании. Доступ к сети требуется только при первом скачивании. Этот процесс не был проверен в Windows в среде разработки проекта; при изменениях в исходном LibreDWG могут потребоваться доработки. Для режима DWG ожидаются подходящие статические зависимости LibreDWG обеих архитектур. Поскольку обе версии плагина устанавливаются в один каталог Total Commander, скрипт не объединяет несовместимые DLL x86/x64 с одинаковыми именами. Для проверки зависимостей через dumpbin запускайте скрипт из Developer PowerShell для Visual Studio. Ошибки сборки и тестов, отсутствие WLX-файлов и несоответствие сохранённых параметров DWG останавливают создание ZIP.
Если LibreDWG уже успешно собрана, но старая версия package.ps1 завершалась ошибкой The property 'Root' cannot be found on this object, замените скрипт упаковки и повторите запуск без -Clean: ./package.ps1 -WithLibreDwg. Существующие файлы в build/libredwg-x64 и build/libredwg-x86 будут повторно использованы при инкрементальной сборке CMake; скачивать исходники заново не нужно. Исправленный скрипт показывает диагностический вывод конфигурации и сборки на экране, не добавляя его по ошибке к результатам функций PowerShell. Он также отдельно передаёт каталог сгенерированного файла config.h LibreDWG для каждой архитектуры, устраняя ошибку MSVC fatal error C1083: Cannot open include file: 'config.h' в LibreDwgBridge.c. Если LibreDWG для x64 и x86 уже скомпилирована, достаточно заменить package.ps1 и CMakeLists.txt, затем повторить ./package.ps1 -WithLibreDwg без -Clean.
Для обратной совместимости также предусмотрен скрипт-обёртка docs/package.ps1, перенаправляющий вызов основному скрипту в корне проекта. Каталоги сборки и релиза (build/ и dist/) исключены из отслеживания Git.
Установка в Total Commander
Откройте dist/wlxcad.zip в Total Commander, чтобы запустить стандартный установщик WLX-плагинов, либо выберите «Конфигурация → Настройка → Плагины → Lister» и укажите wlxcad.wlx / wlxcad.wlx64. Строка распознавания файлов (DetectString): EXT="DWG" | EXT="DXF".
Перед публикацией необходимо проверить экспортируемые функции обеих DLL и фактическую работу F3 / Ctrl+Q в Windows. Эта версия исходников была собрана и проверена для переносимого DXF-кода в Linux, но не загружалась в Total Commander.
Управление
| Действие / клавиша | Результат |
|---|---|
| F3 / Ctrl+Q | Открыть файл в стандартном Lister / Quick View |
| Колесо мыши | Масштабирование относительно курсора |
| Перетаскивание левой / средней кнопкой мыши | Перемещение чертежа (Pan) |
| Двойной щелчок / F / Home / 0 | Вписать чертёж в окно (Zoom Extents) |
+ / - |
Увеличить / уменьшить масштаб |
L |
Показать / скрыть боковую панель слоёв |
G |
Включить / выключить сетку |
| Esc | Запросить закрытие просмотрщика через Total Commander |
| Выпадающий список Layout | Переключить отображение на объекты листа, если они есть |
| Кнопка Light | Переключить светлый / тёмный фон |
Тесты
Тесты DXF-парсера выполняются в Linux и Windows независимо от Total Commander:
cmake --preset linux-tests
cmake --build --preset linux-tests
ctest --preset linux-tests --output-on-failure
Проверяются: версия и единицы измерения ASCII DXF, слои, видимость, вложенные блоки, преобразования INSERT, дуги с bulge, эллипсы, сплайны с узловым вектором, текст, большие мировые координаты, смещение начала координат камеры и повреждённые файлы. samples/example.dxf — воспроизводимый тестовый чертёж, создаваемый скриптом samples/create_sample.py.
Структура проекта
src/plugin/ Экспорт WLX-функций / граница загрузчика
src/viewer/ Win32-окно и элементы управления, асинхронное управление жизненным циклом
src/cad/ Кроссплатформенная CAD-модель и DXF-парсер, модуль DWG
src/renderer/ Direct2D-рендерер, камера и геометрия
src/util/ Необязательное диагностическое логирование
samples/ Пример DXF и генератор
tests/ Переносимые тесты парсера и геометрии
package.ps1 Сборка x64/x86, запуск тестов, упаковка dist/wlxcad.zip
docs/package.ps1 Обёртка для обратной совместимости
Для включения отладочного журнала укажите -DWLXCAD_ENABLE_LOGGING=ON; журнал сохраняется в %TEMP%\wlxcad.log. Перед распространением готовых бинарных файлов для Windows могут потребоваться дополнительные исправления, связанные с SDK или ABI.
Клавиша Escape
При нажатии Esc внутри области чертежа клавиша теперь передаётся содержащему её окну Lister / Quick View в Total Commander, чтобы основное приложение закрыло просмотрщик штатным способом. Это безопаснее, чем напрямую уничтожать окно плагина.