Взаимодействие с CAD в Lazarus IDE
Продолжая тему работы с 3D-моделями в Lazarus IDE, стоит отдельно рассказать о взаимодействии с CAD-системами. Здесь интерес представляет как построение 2D-графики на чертеже, так и создание или редактирование 3D-моделей.
Исторически сложилось так, что я больше всего, как инженер-конструктор, работал с КОМПС-3D, и много проектов делал именно в нем. Я начал работать в КОМПАС еще в 2003 году, когда делал в нем чертежи для курсовых проектов. Переход с версии 5.11 на версию 6 произвел на меня большое впечатление, и с тех пор я вижу, как с каждым обновлением, улучшается работа и расширяется функциональность системы. Наверное, можно сказать, что сегодня КОМПАС-3D — это не просто система, а полноценная платформа с множеством специализированных приложений и решений, предоставляющая широкие возможности как для конструкторов машиностроительного направления, так и для проектировщиков в строительной сфере.
Возможности автоматизации
КОМПАС-3D предлагает инструменты не только для инженеров, работающих в системе, но и для разработчиков ПО, позволяя тем самым расширять возможности, путем создания решений для конкретных задач. Программисты могут создавать специализированные модули, которые интегрируются в систему. Например, модули вроде «Валы и механические передачи» или «Механика: пружины» упрощают проектирование типовых узлов. А такие модули, как «APM FEM» и «Kompas-Flow», позволяют взаимодействовать с 3D-моделью и выполнять CAE-расчёты непосредственно в интерфейсе КОМПАС-3D.

Для автоматизации рутинных задач в КОМПАС-3D доступна библиотека КОМПАС-Макро. Библиотека записывает макросы в процессе работы пользователя с документами КОМПАС. Выполняемые команды посредством языка программирования Python фиксируются в файле. После записи, макросы можно отредактировать и добавить на панель в виде команды.
Взаимодействовать с КОМПАС-3D возможно не только с помощью создания модулей, но и из кода отдельного приложения. В своё время, работая инженером-конструктором, я разрабатывал приложения, которые автоматизировали расчёты и создавали эскизы на чертеже, или выполняли пакетную обработку документов КОМПАС, для получения информации из углового штампа чертежа и данных из спецификации.

Сейчас же я чаще работаю над задачами, связанными с интеграцией PLM и CAD, где требуется получать или наоборот сформировать определённую информацию внутри 3D-модели. Собственно, поэтому в статье я хочу представить практические рекомендации по одному из вариантов работы с 3D-моделями.
SDK и справочные материалы
Когда нужно проверить гипотезу или создать прототип реализации какой-либо функции, я использую Lazarus IDE в связке с библиотеками, входящими в состав SDK КОМПАС-3D. Подробная справка по API включена в SDK (для этого нужно активировать соответствующую опцию при установке). Также справку можно найти на официальном сайте АСКОН в разделе Руководство пользователя KOMPAS-Invisible (API КОМПАС-3D).
Кроме того, иногда полезными оказываются статьи в блоге компании на Харбре — АСКОН — Разработчик инженерного ПО и ИТ-интегратор. Например, я иногда обращаюсь к статьям из цикла публикаций — Работа с API КОМПАС-3D → Урок 1 → Основы, написанные Сергеем Норсеевым, автором книги «Разработка приложений под КОМПАС в Delphi». В этой книге подробно раскрывается большинство вопросов работы с API.
В сложных и непонятных для меня случаях я иду на форум АСКОН, в раздел Программирование приложений. Чаще всего получается так, что тема уже кем-то исследована и имеется описанное решение.
Подключение модулей в проектах Lazarus IDE
Поскольку в набор SDK входят и модули именно для Delphi, чтобы подключить их в проект, созданный в Lazarus IDE, необходимо добавить директиву компилятора {$mode delphi} в файлы модулей. Это предотвратит появление ошибки, возникающей из-за совпадения имен переменных с уже объявленными типами.
При подключении модулей SDK в проект можно использовать только необходимые, а не весь набор. Чаще всего выбор модулей зависит от версии API, с которой планируется работать.
Особенности версий API
Стоит отметить, что у КОМПАС-3D существует несколько версий API. Есть API.5 и API.7, который не является последовательной версией пятерки, а еще есть KsAPI. Все эти версии являются скорее взаимодополняющими инструментами. API.5 остаётся основой для большинства задач автоматизации, тогда как API.7 (и его наследник KsAPI) расширяет возможности, обеспечивая кроссплатформенность и современные подходы к разработке.
API.5 ориентирован на базовые операции: создание документов (чертежей, фрагментов, спецификаций), управление компонентами сборки и выполнение стандартных 3D-операций (выдавливание, вращение и т.д.).
API.7 дополняет API.5, и предоставляет доступ к более специализированным функциям, таким как работа с параметрическими переменными, событиями интерфейса, а также расширенными настройками системы (например, привязки, форматы листов).
KsAPI — это новый кроссплатформенный программный интерфейс (API), разрабатываемый для работы как в операционной системе Windows, так и в Linux, что особенно актуально в свете портирования КОМПАС-3D на платформу Linux. Про KsAPI есть статья на Хабре -Будущее КОМПАС API на Linux
Вариант работы с 3D-моделями
Принципиально, с помощью кода можно выполнять построение 2D-графики или формирование 3D-моделей, используя базовые операции. Примером такого подхода может служить Программа построения зубчатых колес по ГОСТ 591–69 присланная на Конкурс асов 3D-моделирования в номинацию Приложения для Компас-3D.
Однако в обычной практике создание сложных трёхмерных моделей с использованием кода может быть неудобным и трудоёмким. Даже если модель вариативна, её проще построить с помощью инструментов 3D-моделирования, заложив различные варианты с помощью параметризации. Затем можно вынести ключевые параметры в переменные и сделать их внешними (т.е. изменяемыми через API). Управляя внешними переменными из приложения, можно быстро получать новую 3D-модель нужной конфигурации.
Например, описанный выше подход используется в приложении «IOSO», реализующем технологию многомерной нелинейной оптимизации.

В процессе работы, для каждой итерации, путем изменения 3D-модели через переменные, получается новая конфигурация, которая далее передается на расчёт. После этого система оценивает результаты, корректирует исходные данные и повторно изменяет 3D-модель. Этот процесс продолжается до достижения оптимального решения или достижения лимита по циклам итерации.
Стоит отметить, что переменные могут использоваться не только для определения параметров построения геометрии и управления включением или выключением операций, но и для нанесения значений на тексты с помощью ссылок. Это может применяться как для вставки текста в технические требования, так и для размерных надписей.
Дополнительные пользовательские данные
Помимо передачи данных внутрь 3D-модели в виде переменных или свойств, иногда возникает задача хранения дополнительной информации. Например, это могут быть данные, которые не должны быть доступны пользователю, или данные большого объема, для которых переменные или свойства не подходят. В таких случаях удобно использовать пользовательское хранилище, которое позволяет управлять дополнительными данными.
Пользовательские хранилища — это механизм, позволяющий сохранять произвольные данные в файлах КОМПАС-3D. Эти данные могут включать метаинформацию, настройки, параметры или любые другие сведения, необходимые для работы взаимодействующего с 3D-моделью приложения. Хранилища могут быть как глобальными (привязанными ко всему документу), так и локальными (привязанными к конкретным объектам модели).
Хранилища
В КОМПАС-3D для работы с хранилищами используется интерфейс IUserDataStoragesMng. Пользовательские хранилища организованы в виде Коллекций, где внутри каждого хранилища находятся объекты по форме «ключ-значение». Ключ — это строка, которая идентифицирует данные, а значение — это произвольные данные, которые могут быть представлены в виде строки, числа, массива байт или другого типа.

program CAD_UserStorrage;
{$codePage UTF-8}
uses ComObj, Variants, ActiveX, ksTLB, ksApi7, ksConstTLB;
var
KompasApi7: IApplication;
Document3D: IKompasDocument3D;
StoragesMng: IUserDataStoragesMng;
Storages:IUserDataStorages;
Storage:IUserDataStorage;
userData,stName: OleVariant;
comment:widestring;
p:integer;
begin
// Подключение к КОМПАС API 7
KompasApi7:=nil;
if not Assigned(KompasApi7) then
try
// Попытка подключения к запущенному экземпляру
KompasApi7 := GetActiveOleObject('Kompas.Application.7') as IApplication;
except
try
// Попытка создания нового экземпляра
KompasApi7 := CreateOleObject('Kompas.Application.7') as IApplication;
except
Writeln('Не удалось подключиться к Ole объекту');
end;
end;
KompasApi7.Visible:=true;
Document3D := KompasApi7.Documents.Add(ksDocumentPart,true) as IKompasDocument3D;
StoragesMng := Document3D.UserDataStoragesMng;
// Новую коллекцию хранилищ, привязываем к документу, указываем (nil)
Storages:=StoragesMng.Add(nil);
// Внутри коллекции создаем новое хранилище
Storage:=Storages.Add('ST');
// Запись данных в хранилище
TVariantArg(userData).vt:= VT_UINT;
userData:=120398123;
// '' - без пароля, userData - данные, 'unit' - ключ
Storage.AddObject('',userData,'unit');
TVariantArg(userData).vt:= VT_BSTR;
TVariantArg(userData).bstrVal:=StringToOleStr('String line');
Storage.AddObject('',userData,'string');
TVariantArg(userData).vt:= VT_R8;
userData:=12.8;
Storage.AddObject('',userData,'min');
TVariantArg(userData).vt:= VT_R8;
userData:=1209.68;
Storage.AddObject('',userData,'max');
// Чтение данных
TVariantArg(stName).vt:= VT_BSTR;
TVariantArg(stName).bstrVal:=StringToOleStr('ST');
Storage:=Storages.Item[stName];
Writeln('Получено хранилище: '+Storage.Name['']);
TVariantArg(stName).vt:= VT_BSTR;
TVariantArg(stName).bstrVal:=StringToOleStr('unit');
comment:=Storage.GetObject(stName,userData,p);
Writeln('Запись: '+comment+' = '+VarToStr(userData));
TVariantArg(stName).vt:= VT_BSTR;
TVariantArg(stName).bstrVal:=StringToOleStr('string');
comment:=Storage.GetObject(stName,userData,p);
Writeln('Запись: '+comment+' = '+VarToStr(userData));
TVariantArg(stName).bstrVal:=StringToOleStr('min');
comment:=Storage.GetObject(stName,userData,p);
Writeln('Запись: '+comment+' = '+VarToStr(userData));
readln;
// Удаление коллекции
TVariantArg(stName).vt:= VT_BSTR;
TVariantArg(stName).bstrVal:=StringToOleStr('ST');
if Storages.Delete('',stName) then
Writeln('Хранилище удалено')
else
Writeln('Удалить хранилище не удалось');
readln;
end.
Есть еще одна особенность хранилищ, которые создаются с привязкой к объекту, например к свойству. При редактировании свойства в интерфейсе КОМПАС-3D данные из хранилища будут удалены.
Заключение
Использование переменных и пользовательских хранилищ позволяет организовать один из способов работы с 3D-моделями, при котором может быть сформирована нужная конфигурация геометрии, и сохранены внутри файла КОМПАС специфические данные проекта. В разрабатываемом приложении может быть организована функция открытия проекта из файла КОМПАС, где данные будут читаться из пользовательского хранилища документа. Для защиты данных пользовательские хранилища могут быть защищены паролем.
Хотя в статье рассматривался вариант использования Lazarus IDE, стоит отметить, что API КОМПАС-3D доступен и для других языков программирования, таких как C#, C++ и Python.