README.md

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.wlx64
  • build/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, чтобы основное приложение закрыло просмотрщик штатным способом. Это безопаснее, чем напрямую уничтожать окно плагина.

Описание
WLXCAD — DWG / DXF Lister Plugin for Total Commander
Релизы
2026-10-10
последний
Конвейеры
0 успешных
0 с ошибкой
Разработчики