TIN-поверхности, чертежи, трассы и сети в 3D — на Android, desktop и в браузере. Kotlin Multiplatform, рендер Filament, свой потоковый разборщик DXF и LandXML.
Скачать: Android APK · Windows · macOS (Apple Silicon) · Linux (deb) · все выпуски
Замеры 24.10.2026, MacBook Pro M3 Pro.
| Читатель | Язык | Скорость чтения, МБ/с |
TIN 20,9 МБ, мс |
Открыто | Поддержано типов |
|---|---|---|---|---|---|
| KoTIN | Kotlin | 464 | 42 | 341/341 | 34/34 |
| dxf-viewer | JS | 100 | 190 | 317/341 | 16/34 |
| dxf-parser | JS | 97 | 196 | 321/341 | 16/34 |
| dxflib | C++ | 93 | 217 | 327/341 | 18/34 |
| netDxf | C# | 78 | 362 | 275/341 | 25/34 |
| libdxfrw | C++ | 63 | 318 | 332/341 | 34/34 |
| ACadSharp | C# | 26 | 477 | 336/341 | 31/34 |
| ezdxf | Python | 6,0 | 2 821 | 337/341 | 33/34 |
KoTIN читает в 4,6 раза быстрее ближайшего и открывает все файлы. Скорость: 6 синтетических DXF на 70 МБ (TIN, горизонтали, съёмка, план); открываемость: 341 тестовый DXF открытых проектов: R12–R2018, бинарные, битые.
Какие типы объектов читают
🟢 читает · 🟡 частично · 🔴 нет · ⚪ проверить не удалось. По исходникам, октябрь 2026. В подсчёт идут типы, которые дают изображение, 🟡 тоже; без типов, которым нужны внешние файлы (растр, подложки, шрифты SHX).
Библиотеки — разбирают в модель
| Тип | KoTIN | libdxfrw | ezdxf | ACadSharp | netDxf | dxflib | dxf-parser | dxf-viewer |
|---|---|---|---|---|---|---|---|---|
| LINE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| XLINE / RAY | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 |
| POINT | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| CIRCLE / ARC | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| ELLIPSE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| SPLINE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| LWPOLYLINE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| POLYLINE 2D/3D | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| POLYLINE polyface, mesh | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | ⚪ | 🟢 | 🟢 |
| 3DFACE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| SOLID / TRACE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟡 | 🟡 |
| TEXT | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| MTEXT | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| ATTRIB / ATTDEF | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟡 | 🟡 | 🟡 |
| INSERT (+ MINSERT) | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| HATCH | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🟢 |
| MPOLYGON | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 | 🔴 |
| DIMENSION | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| ARC_DIMENSION, LARGE_RADIAL | 🟢 | 🟢 | 🟢 | 🟡 | 🟡 | 🔴 | 🔴 | 🔴 |
| LEADER | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 |
| MULTILEADER (MLEADER) | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🟢 | 🔴 |
| TOLERANCE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| MLINE | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| ACAD_TABLE | 🟢 | 🟢 | 🟡 | 🟢 | 🟡 | 🔴 | 🔴 | 🔴 |
| MESH (SubD) | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| HELIX | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 | 🔴 |
| WIPEOUT | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| OLE2FRAME | 🟡 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 |
| 3DSOLID, REGION, BODY | 🟡 | 🟡 | 🟢 | 🟡 | 🔴 | 🔴 | 🔴 | 🔴 |
| SURFACE (все виды) | 🟡 | 🟢 | 🟡 | 🟡 | 🔴 | 🔴 | 🔴 | 🔴 |
| ACAD_PROXY_ENTITY | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 |
| Неизвестная, с графикой прокси | 🟢 | 🟡 | 🟡 | 🟡 | 🔴 | 🔴 | 🔴 | 🔴 |
| VIEWPORT (листы) | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| ARCALIGNEDTEXT, RTEXT | 🟡 | 🟢 | 🔴 | 🔴 | 🔴 | 🟡 | 🔴 | 🔴 |
| Формат файла | ||||||||
| Бинарный DXF | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| R12 и старше | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🟢 | ⚪ | ⚪ |
Кодировка из $DWGCODEPAGE |
🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🟡 |
| Читатель | Язык | Скорость чтения, МБ/с |
TIN 6,0 МБ, мс |
Открыто | Эталон | Поддержано разделов |
|---|---|---|---|---|---|---|
| KoTIN | Kotlin | 208 | 14 | 95/95 | 108/108 | 10/10 |
| npm landxml | JS | 166 | 47 | 49/95 | 69/108 | 1/10 |
| CivilCraft | JS | 83 | 79 | 95/95 | 90/108 | 6/10 |
| mac999/landxml_parser | Python | 36 | 80 | 95/95 | 37/108 | 1/10 |
| LandXML2glTF | C++ | 10 | 670 | 69/95 | 31/108 | 5/10 |
KoTIN читает быстрее всех, и только у него всё совпало с эталоном. 95 файлов: образцы landxml.org и тесты KoTIN; эталон — 71 поверхность и 37 файлов с трассами, разобранные через lxml.
Какие разделы читают
| Раздел LandXML | KoTIN | CivilCraft | mac999/ landxml_parser |
npm landxml | LandXML2glTF |
|---|---|---|---|---|---|
| Surfaces (TIN, grid) | 🟢 | 🟡 только TIN | 🔴 | 🟡 только TIN | 🟢 |
| Alignments | 🟢 спирали, профили, поперечники | 🟡 без спиралей | 🟢 | 🔴 | 🟡 ломаные |
| CgPoints | 🟢 | 🟢 | 🔴 | 🔴 | 🟢 |
| Parcels | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 |
| PlanFeatures | 🟢 | 🟢 | 🔴 | 🔴 | 🟢 |
| PipeNetworks | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 |
| Survey | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 |
| Monuments | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 |
| Roadways | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 |
| CoordinateSystem | 🟡 показывает, не пересчитывает | 🟢 | 🔴 | 🔴 | 🟢 |
Открыть файл
≡ → «Открыть файл» или кнопка на пустом экране. Android: из файлового менеджера «Открыть с помощью» → KoTIN. Web: ссылка ?file=путь/к/файлу.dxf.
Камера «Орбита»
Переключатель «Орбита | Карта» — справа внизу. Палец вращает, два пальца сдвигают, щипок — зум. Мышь: ЛКМ вращает, ПКМ сдвигает, колесо — зум.
Камера «Карта»: сдвиг и зум
Палец или ЛКМ сдвигает (с инерцией), щипок или колесо — зум к курсору.
Камера «Карта»: поворот и наклон
Два пальца поворачивают, движение двумя пальцами вверх-вниз наклоняет. Мышь: ПКМ поворачивает, Shift+ЛКМ вверх-вниз наклоняет.
Вернуть вид
Если чертёж ушёл за край экрана, указатель «Чертёж · N м» ведёт к нему. В меню ≡ — «Вид чертежа» (сохранённый в файле) и «Исходный вид».
Слои
Клик по слою скрывает или показывает его; «Все» / «Ни одного» — для всех сразу. Цвет квадратика — цвет слоя в сцене.
Выбор объекта
Удерживайте нажатие на объекте — откроется карточка со свойствами. «Рядом ещё объекты» ‹ › перебирает соседей, × снимает выбор.
Оси X и Y
В «Настройках»: «X — восток, Y — север» или «X — север, Y — восток» (как в геодезии).
Что показывать
Поверхность, каркас, чертёж, подписи, точки; «Скрывать за поверхностью», «Чертёж в плоскость (без отметок)»; масштаб по высоте 1×–10× в «Настройках».
Подписи
Когда подписей много, они прореживаются по масштабу: чем дальше камера, тем их меньше; приблизьте — появятся все. Включается само или в меню «Прореживать подписи по масштабу».
Установка и сборка — desktop, Android, web, тесты
Нужен JDK 24 (toolchain демона — gradle/gradle-daemon-jvm.properties).
./gradlew :app:run --args="путь/к/файлу.dxf" # desktop (JDK 22+, FFM-биндинги Filament)
./gradlew :androidApp:installDebug # Android
./gradlew :app:wasmJsBrowserDistribution # web → app/build/dist/wasmJs/productionExecutable
./gradlew :app:jvmTest # тесты- Android: файл — кнопкой в приложении или из файлового менеджера «Открыть с помощью» → KoTIN.
- Web: папку сборки раздать любым статическим сервером; файл по ссылке —
index.html?file=dxf/X.dxfили#dxf/X.dxf. Симлинки на свои данные в папку сборки не класть: Gradle при пересборке удалит файлы по ссылке.
Запуск тестов и тестовые файлы
./gradlew :app:jvmTest # все тесты
./gradlew :app:jvmTest --tests '*DxfHatchTest*' # один класс
LANDXML_BIG=1 ./gradlew :app:jvmTest --tests '*LandXmlLoadTest*' # нагрузочные: крупный TIN, PntList на 100 МБНагрузочные тесты без LANDXML_BIG=1 пропускаются; LANDXML_JFR=1 дополнительно пишет профиль JFR.
Тестовые файлы лежат в репозитории (app/src/jvmTest/resources) и собираются генераторами из scripts/:
python3 -m venv .venv && .venv/bin/pip install ezdxf
.venv/bin/python scripts/gen_test_dxf.py # DXF → app/src/jvmTest/resources/dxf/tasks
python3 scripts/gen_test_landxml.py # LandXML → app/src/jvmTest/resources/landxml/syntheticГенераторы детерминированы: пересоздание файлов не даёт изменений в git.