Несмотря на тотальную «мобилизацию» среднестатистического пользователя, большинство инженеров продолжают работать на стационарных ПК. Крупных инженерных программ, в первую очередь САПР, для мобильных ОС крайне мало. Несколько лет назад у компании АСКОН появилось бесплатное приложение КОМПАС:24 для просмотра документов КОМПАС-3D (деталей, сборок, чертежей, спецификаций и др.) на Android-устройствах.
Модель «КАМАЗ Будущего», автор Дмитрий Котляр.
О том, как было реализовано портирование большого Windows-приложения на Android, рассказывает один из разработчиков КОМПАС:24 Александр Полуэктов.
Исходные условия
Специфика формата файлов КОМПАС-3D такова, что отсутствует описание внутренней структуры документа и невозможно прочитать файл, не имея исходников основного продукта (хотя попытки предпринимались как собственными силами, так и сторонними разработчиками).
Данные сериализуются в бинарном виде, каждый класс делает это самостоятельно с учетом версии файла. КОМПАС-3D с пятой версии разрабатывался только под Windows, но пользователи давно просили реализовать хотя бы просмотр файлов из других ОС. Было принято решение о создании отдельного продукта КОМПАС:24 для Android на основе имеющегося кода КОМПАС-3D.
Проект очень крупный – несколько миллионов строк на C++. Раз есть C++, можно использовать NDK, а не писать всё заново. Несколько сократило объем работы то, что часть системы (геометрическое ядро) уже была независима от GUI и адаптирована для Linux-систем.
Тестовое приложение ядра C3D для Linux
Сложности, подводные камни и решения
Изначально задача состояла в том, чтобы прочитать 3D-модели из файлов и отрисовать их, т. е. достать тела, насчитать триангуляцию и вывалить в OpenGL. В реальности оказалось, что в файле сохраняются не результирующие тела, а только история построения. Потребовалось организовать чтение всех имеющихся объектов, включая объекты чертежа/фрагмента, которые используются в эскизе. Добавив работы, это позволило организовать открытие не только деталей/сборок, но и чертежей/фрагментов. Оказалось, что изменения модели, выполненные в сборке, требуют перестроения включенных деталей с передачей данных через запись в память, аналогично хранению на диске. Кроме чтения файла пришлось реализовать еще и механизм записи.
Большое количество исходных текстов, несомненно, надо структурировать. Дабы не изобретать велосипед, проект был разбит на модули, аналогично исходным. Были исключены модули, отвечающие за пользовательский интерфейс и процессы построения. Сначала возникла сложность с нежелающим линковаться математическим ядром. Проблема появилась из-за слишком длинной командной строки, передаваемой линковщику. Для разрешения ситуации без крупных переделок проекта пришлось вывести сборку ядра на виртуальную машину с Linux. К счастью, в очередной версии Android NDK проблема была исправлена, и сейчас такие сложности отсутствуют.
Не являлась существенной проблемой, но требовала крепких нервов отладка. Внесение изменений в одну строчку требует на сборку и перезапуск проекта от трех (в лучшем случае) до 40 минут.
Отображение чертежа
Работа с файловой системой, реестром и пользовательским интерфейсом была вынесена в отдельные модули. Это позволило значительно ограничить места сплошного переписывания. Здесь сложностей добавили строки. В зависимости от версии файла строка может оказаться либо 1-байтной windows-1251, либо 2-байтной wchar_t. Для Android NDK родная кодировка utf-8 и допустимо использование 4-байтного wchar_t. А ещё строки сравниваются на больше/меньше и с них насчитываются хэши. Единственный способ борьбы с этим зоопарком – длительная отладка и пристальный взгляд в код.
Значительно увеличило время разработки большое количество legacy-кода. Проект — реально старый. Встречается код, написанный 15 лет назад под Visual Studio 6 / Borland C++ Builder. С учётом того, как спокойно компилятор от Microsoft относится к нарушению стандарта C++ (а иногда даже поощряет), пришлось часто переписывать платформонезависимые, на первый взгляд, фрагменты кода.
О специфике сериализации я уже упоминал в начале. Данные сериализуются в бинарном виде, и каждый класс делает это самостоятельно с учетом версии файла. Сериализуются встроенные типы windows, в т.ч. VARIANT. Сериализуются хэши строк, которые потом сравниваются со строками (помним про кодировки).
Результаты разработки
Разработка первой версии КОМПАС:24 заняла около полугода. В новых релизах появляется поддержка свежих версий файлов КОМПАС-3D и небольшие доработки.
В проект включено более 2000 cpp-файлов из КОМПАС-3D и около 20 файлов, характерных только для КОМПАС:24. В коде около 4000 участков с различной реализацией для КОМПАС-3D и КОМПАС:24.
Достигнута возможность открывать любую модель, сборку или чертеж, на которые хватит оперативной памяти мобильного устройства. На практике открываются не все файлы, но это вопрос исправления отдельных багов.
Получен код, который относительно легко поддерживать для всех платформ. Существуют экспериментальные сборки КОМПАС:24 для Linux и Windows.
Применение динамического сечения к модели турбомуфты
В процессе разработки подтверждена возможность существования КОМПАС-3D для Android. При открытии сборок происходит полное перестроение. Мобильные приложения сделали огромный скачок от простых игр и записных книжек до серьёзных проектов. К тому же по производительности современные телефоны обогнали ПК десятилетней давности, а размеры и разрешения планшетов позволяют размещать на экране достаточное количество информации.
КОМПАС:24 стал полигоном для проверки решений, часть из которых была впоследствии перенесена в КОМПАС-3D. К примеры, в КОМПАС:24 впервые появились динамическое сечение 3D-моделей, быстрая отрисовка с кэшированием триангуляции и быстрое открытие сборок из кэша без перестроения.
Александр Полуэктов, ведущий программист
Автор: kompas_3d