В современных условиях для любого предприятия важно сокращение сроков проектирования новых изделий. Один из путей такого сокращения – это автоматизация процессов проектирования. Среди проектируемых изделий можно выделить стандартную тару. С помощью этой тары (комплектов ящиков) могут быть упакованы, например, комплексы радиоэлектронной аппаратуры. Задача проектирования таких комплектов ящиков в отдельных случаях может быть достаточно формализована и представлять собой монотонную работу.



Следует отметить, что задачами автоматизации проектирования тары занимался ряд ученых, разработчиков и организаций (см. например [1, 2, 3]). Однако не существует широко известных инструментов, предназначенных для решения узкоспециализированной задачи: проектирования ящиков типа VI по ГОСТ 5959-80 (см. рисунок выше) на основе API SolidWorks. Поэтому представляют интерес способы такого решения.

Автор статьи, работая конструктором и имея некоторые навыки разработки приложений VBA, как раз и столкнулся с необходимостью проектировать комплекты ящиков. И это подтолкнуло его к идее разработать для этого программу.

Первоначально для автоматизации проектирования был написан макрос VBA (ознакомиться с результатами разработки можно в соответствующей публикации [4]). Однако за рамками публикации остались отдельные моменты, представляющие скорее не научный, а практический интерес для разработчиков, использующих API SolidWorks. Тем, кто приступает к программированию с использованием API, зачастую много времени приходится затрачивать на поиск методов решен��я типовых задач, причем иногда на англоязычных ресурсах.

Отметим также, что написанный макрос VBA был не лишен ряда недостатков, таких как ручное обновление таблицы параметров, длительное время выполнения операций перестроения 3D-модели, мелькание перед пользователем картинок перестраивающейся модели и некоторых других. Эти недостатки не являлись критичными для основной функциональности, однако увеличивали время проектирования изделия и делали приложение менее эстетичным для восприятия.

Это послужило основанием для рассмотрения в статье следующих вопросов.

  1. Разработка приложения, которое лишено вышеуказанных недостатков.
  2. Средства API, используемые для решения некоторых типовых задач.

Приложение, упомянутое выше, было написано на языке программирования C++/CLI (и я не испугаюсь этих слов). Выбор такого языка для решения задачи основывался на ряде причин, выходящих за рамки данной статьи. В качестве альтернативы можно использовать, например, язык программирования C#. Названия объектов, методов и свойств API SolidWorks для VBA, C# и С++/CLI одни и те же, поэтому для переноса программного кода в другой язык программирования требуется знать лишь некоторые особенности синтаксиса.

Для разработки такого приложения автору пришлось получить начальное представление о программировании на языке С++.

Внешний вид стартовой формы приложения представлен на рисунке.



Демонстрацию процесса проектирования тары с помощью программы можно увидеть на видео.


Структурная схема программного продукта, приведенная в публикации [4], претерпела некоторые изменения в основном в части архитектуры приложения. Методика построения 3D-модели, схема обмена данными и применения ряда инструментов SolidWorks осталась та же. Измененная структурная схема представлена на рисунке.



Следует отметить, что минимизация времени редактирования шаблонов сборочных чертежей после их перестроения под ящик с пользовательскими размерами была достигнута за счет особого подхода к построению эскизов, лежащих в основе местных разрезов на чертеже. На геометрические объекты эскизов накладывались привязки к геометрии ящика, на эскизы наносились размеры, которые в дальнейшем скрывались.

Теперь перейдем к описанию решения некоторых типовых задач.

1. Получение доступа к объекту типа SldWorks^


Предполагается, что разработчиком в Visual Studio 2019 создан пустой проект CLR и начата работа над приложением Windows Form (см., например [5]). Также предполагается, что разработчик получил начальное представление о программировании на С++ (или, например, на С# или VB, если идти другими путями).

Кроме файла исходного кода, запускающего стартовую форму, добавлен заголовочный файл и основной файл исходного кода. В последних двух файлах после директив препроцессора #include указываются пространства имен SolidWorks:

using namespace SolidWorks::Interop::sldworks;
using namespace SolidWorks::Interop::swcommands;
using namespace SolidWorks::Interop::swconst;

В окне обозревателя решений Visual Studio 2019 в разделе «Ссылки» необходимо добавить ссылки на файлы dll SolidWorks, предназначенные для работы с API (см. рисунок).



Данные файлы находятся в папке C:\Program Files\SolidWorks Corp\SolidWorks\api\redist\

Одним из способов получения доступа к объекту типа SldWorks^ является использование следующего программного кода:

SldWorks^ swApp = nullptr; //Объект типа SldWorks^
        
//Массив запущенных процессов SolidWorks
array<Process^>^ localByName = Process::GetProcessesByName("SLDWORKS");
		

//Проверяем, запущен ли хоть один процесс SW
if (localByName->Length > 0)
{
MessageBoxA(0, "Запущено одно или несколько приложений SolidWorks. Закройте их и повторите попытку.", "Ошибка!", MB_ICONSTOP | MB_OK);
     return -1;
}
swApp = (SldWorks^) Activator::CreateInstance(Type::GetTypeFromProgID("SldWorks.Application.21"));

Отметим, что в нашем случае для корректной работы приложения необходимо запускать определенную версию SolidWorks, для чего выполняются дополнительные проверки. Аргумент «SldWorks.Application.21» означает, что необходимо запустить SolidWorks 2013. Цифры в конце аргумента возрастают на единицу с увеличением года версии программы на один.

2. Задача копирования файлов шаблонов 3D-модели сборки ящика


Как упоминалось в публикации [4], каждой конфигурации конструкции ящика поставлен в соответствие свой комплект файлов шаблонов. Необходимо скопировать файлы шаблонов так, чтобы исходные файлы остались неизменными, а сборочный чертеж проектируемого ящика ссылался на модель, скопированную в папку, указанную пользователем. Решение этой задачи иллюстрируется фрагментом программного кода, представленным ниже.

//Предполагается здесь и в других примерах кода, что уже получен доступ к приложению //SolidWorks (переменная swApp типа SldWorks^), что показано в фрагменте кода к задаче 1 

IModelDoc2^ swModel;
int longstatus;
bool boolstatus;

//Открываем файл 3D-модели ящика и чертеж в папке с шаблонами
swApp->OpenDoc6(gcnew System::String(str_Drawing_input_path.c_str()), 3, 0, "", swErrors, swWarnings);
//str_Drawing_input_path – путь хранения шаблона чертежа, тип переменной string
swApp->OpenDoc6(gcnew System::String(str_Box_input_path.c_str()), 2, 0, "", swErrors, swWarnings);
//str_Box_input_path – путь хранения шаблона 3D-модели сборки, тип переменной string
swApp->ActivateDoc2("Ящик", false, longstatus);
swModel = (IModelDoc2^)swApp->ActiveDoc;

//Сохраняем сборку в папку, указанную пользователем. Ссылки на модель в чертеже при этом меняются
longstatus = swModel->SaveAs3(gcnew System::String(str_Box_output_path.c_str()), 0, 1);
//str_Box_output_path – путь для сохранения файла сборки в папку пользователя, тип переменной string
swModel = (IModelDoc2^)swApp->ActiveDoc;
swApp->ActivateDoc2("Ящик - Лист1", false, longstatus);
swModel = (IModelDoc2^)swApp->ActiveDoc;
		
//Сохраняем шаблон чертежа
boolstatus = swModel->Save3(1, swErrors, swWarnings);

//Закрываем шаблон чертежа
swApp->CloseDoc("Ящик - Лист1");

//Копируем шаблон чертежа в папку пользователя
File::Copy(gcnew System::String(str_Drawing_input_path.c_str()), gcnew System::String(str_Drawing_output_path.c_str()), true);
//str_Drawing_output_path - путь для сохранения файла сборки в папку пользователя, тип переменной string
		
//Открываем шаблон чертежа
swModel = swApp->OpenDoc6(gcnew System::String(str_Drawing_input_path.c_str()), 3, 0, "", swErrors, swWarnings);

//Сохраняем сборку в предыдущее место. Ссылки на модель в чертеже опять меняются
swApp->ActivateDoc2(gcnew System::String(Box_parametres.str_Box_designation.c_str()) + " - Ящик.SLDASM", false, longstatus);
swModel = (IModelDoc2^)swApp->ActiveDoc;
longstatus = swModel->SaveAs3(gcnew System::String(str_Box_input_path.c_str()), 0, 1);
		
//Закроем шаблон файла сборки ящика
swApp->CloseDoc("Ящик.SLDASM");
swModel = (IModelDoc2^)swApp->ActiveDoc;
swApp->ActivateDoc2("Ящик - Лист1", false, longstatus);
swModel = (IModelDoc2^)swApp->ActiveDoc;
		
//Снова сохраняем шаблон чертежа
boolstatus = swModel->Save3(1, swErrors, swWarnings);
		
//Закрываем шаблон чертежа
swApp->CloseDoc("Ящик - Лист1");

3. Задача записи в файл 3D-модели сборки пользовательских свойств


Решение этой задачей иллюстрируется программным кодом соответствующей функции:

	//Функция добавления свойств к файлу модели
int SetActiveConfigProperty(IModelDoc2^ Model, string PropertyName, string PropertyValue, int PropertyType)
{
		ConfigurationManager^ swConfMgr;               
		ModelDocExtension^ swModelDocExt;
		CustomPropertyManager^ swCustProp;
		System::String^ ConfigName;
		System::String^ resolvedPropertyValue;
		int int_Result_code;
		
		swConfMgr = Model->ConfigurationManager;
		ConfigName = swConfMgr->ActiveConfiguration->Name;

		swModelDocExt = Model->Extension;
		swCustProp = swModelDocExt->CustomPropertyManager[ConfigName];
		
		//Для корректной работы удаляем свойство, если оно существует
		int_Result_code = swCustProp->Delete(gcnew System::String(PropertyName.c_str()));
		//Проверяем тип добавляемого свойства: 1 - текст, 2 - число
		if (PropertyType == 1)
			int_Result_code = swCustProp->Add2(gcnew System::String(PropertyName.c_str()), 30, gcnew System::String(PropertyValue.c_str()));
		else if (PropertyType == 2)
			int_Result_code = swCustProp->Add2(gcnew System::String(PropertyName.c_str()), 5, gcnew System::String(PropertyValue.c_str()));
		
		return int_Result_code;
}

4. Задача автоматического перестроения таблицы параметров без участия конструктора


Предварительно в файле 3D-модели сборки сохранены пользовательские свойства, которые должны обновиться в таблице параметров. Решение этой задачи в макросе, предназначенном для других целей, рассмотрено на ресурсе [6]. Приведем фрагмент кода, отвечающий за данную функциональность:

DesignTable^ DesTbl;
bool bool_Result;
ModelDoc2^ swDoc;

//Получаем доступ к таблице параметров
swDoc = (ModelDoc2^)swApp->ActiveDoc;
DesTbl = (DesignTable^)swDoc->GetDesignTable();
bool_Result = DesTbl->Attach();

//Обновляем таблицу параметров и отключаемся от нее
bool_Result = DesTbl->UpdateTable(2, true);
DesTbl->Detach();

5. Задачи ускорения работы макроса


Эти задачи могут быть решены путем использования ряда методов API [7]. В нашей работе было использовано два из них: скрытие приложения от пользователя и отключение регенерации экрана. Отключение регенерации экрана осуществлялось не на всех этапах, а лишь на этапе автоматического обновления таблицы параметров. Поэтому решаемая задача иллюстрирует не количественный, а качественный выигрыш в скорости. Обращаем внимание, что для отключения видимости приложения нужно изменять не одно свойство приложения, а целых три [8]:

Frame^ pFrame;

swApp->UserControl = false;
swApp->Visible = false;
pFrame = (Frame^)swApp->Frame();
pFrame->KeepInvisible = true;

Фрагмент кода, отключающий регенерацию экрана:

IModelDoc2^ swModel;
ModelView^ modView;

swModel = (IModelDoc2^)swApp->ActiveDoc;
modView = (ModelView^)swModel->ActiveView;
modView->EnableGraphicsUpdate = false;

Как показали замеры времени, взаимодействие с API SolidWorks макроса VBA (с учетом ручного обновления таблицы параметров) и приложения C++/CLI при проектировании одного и того же ящика занимает приблизит��льно 160 и 65 секунд соответственно. Это подтверждает ожидаемое сокращение времени работы макроса. Примерно такая же картина наблюдается при сравнении двух версий приложений на C++/CLI.

В заключение отметим, что в статье были рассмотрены средства API, которые были использованы при решении ряда типовых задач взаимодействия с SolidWorks. Усовершенствованное приложение позволяет получить комплект конструкторской документации на ящик приблизительно за 5-7 минут по сравнению с 10-15 минутами для макроса VBA (без учета сохранения документации в PDM/PLM системе).

Библиографический список


  1. Инженерная компания Глосис [Электронный ресурс] .– URL: glosys.ru/index.php/projects/item/161-sistema-avtomatizirovannogo-proektirovaniya-yaschichnoy-taryi.html .– (дата обращения 12.01.2022).
  2. Полянсков Ю. В., Павлов П. Ю., Блюменштейн А. А., Мешихин А. А. Автоматизированное проектирование тары для транспортировки панелей гражданского самолета // Известия Самарского научного центра Российской академии наук .–2019 .– т. 21 .– №4.
  3. Ястребов Д. В., Згуральская Е. Н., Егорычев Д. В. Автоматизированное проектирование тары для транспортировки узлов и панелей авиационных изделий // Известия Самарского научного центра Российской академии наук .– 2021 .– т. 23 .– №1.
  4. Серков Е. А. Автоматизация проектирования тары для комплексов радиоэлектронной аппаратуры // Изв. вузов. Приборостроение .– 2020 .– т. 63 .– №6 .– с. 548-554.
  5. YouTube. Создание оконного приложения С++/Visual studio 2019/Windows Form. [Электронный ресурс] .– URL: www.youtube.com/watch?v=QbMVxkzTi54 .– (дата обращения 09.11.2021).
  6. SolidWorks. Forums. [Электронный ресурс] .– Режим доступа: для авториз. пользователей .– URL: forum.solidworks.com/thread/114067 .– (дата обращения 07.11.2021).
  7. CAD booster. SolidWorks automation. How to improve SOLIDWORKS macro speed 10x [Электронный ресурс] .– URL: cadbooster.com/improve-solidworks-macro-speed-10x/#disable-updating-feature-tree .– (дата обращения 07.11.2021).
  8. SolidWorks. Forums. [Электронный ресурс] .– Режим доступа: для авториз. пользователей .– URL: forum.solidworks.com/thread/106420 .– (дата обращения 07.11.2021).