2315x
001659
2020-10-13

Обновление и согласование данных о конструкции в моделях через интерфейс COM

В нашей статье мы будем исходить из наличия базовых знаний об интерфейсе COM. Ссылки на статьи с основами программирования вы найдете ниже.

Постановка задачи

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

Модель примера

В качестве примера для функции программы была создана модель простой подъемной платформы. Следующую модель будем считать основной моделью.

Подъемная платформа не задана параметрически и имеется в трех вариантах: поднятая на максимальную высоту, на земле и в среднем положении. Платформу с максимальным подъемом обозначим как основную модель, среднее положение как вариант 1 и положение на земле как вариант 2.

Предварительные соображения

Для решения данной задачи нам потребуется либо файл конфигурации, либо графический интерфейс, в котором определяется, какие модели нужно привести в соответствие.

Для ввода свободных или переменных координат узла применяется комментарий соответствующего элемента. Программа должна выполнить поиск конкретной символьной строки в комментарии и, в случае ее нахождения, изменить или оставить без изменений соответствующие координаты. Кроме того, имеет смысл автоматическое создание новых элементов во всех второстепенных моделях. Таким образом, конфигурация должна соответствовать тому, что пользователь активирует в RFEM требуемую модель (редактирует на переднем плане), а затем программа откроет требуемые модели и сравнит их с основной моделью.

Графический интерфейс

Для графического интерфейса был выбран следующий простой вариант.

Пользователь может ввести или вставить с помощью функции «копировать и вставить» путь доступа в текстовое поле. С помощью «Add New Model» можно добавить ее в список сравниваемых моделей. Для удаления выбранной модели из списка применяется кнопка «Remove Selected Model». Кнопка «Modify Models» запускает программу.

Основные функции программы

Изначально программа имеет в распоряжении только путь к вторичным моделям и вариантам и требует вначале соединения с программой RFEM. После установления соединения с программой RFEM будет необходимо запустить цикл по вторичным моделям. Поскольку программа также должна создавать элементы, необходимо учитывать их иерархию. Поэтому сначала сравниваются узлы, а затем линии, материалы, сечения и, наконец, стержни. Исключением являются узлы, так как в данном случае следует по необходимости перенести или оставить направления x, y и z. Все остальные элементы будут либо перенесены полностью, либо оставлены без изменений. Для всех элементов должно быть одинаково создание новых элементов.

Основная структура программы

Метод, выполняемый при нажатии кнопки «Modify Models», имеет следующую основную конфигурацию.

private void button_mod_click(object sender, EventArgs e)
{
 // RFEM
 //##############################
 Dlubal.RFEM5.IModel3 iModel_org = null;
 Dlubal.RFEM5.IApplication iApp = null;
 try
 { 
  // get interface to application and open model
  iApp = Marshal.GetActiveObject("RFEM5.Application") as Dlubal.RFEM5.IApplication;
  iApp.LockLicense();
  iModel_org = iApp.GetActiveModel() as Dlubal.RFEM5.IModel3;
  
  // loop over found models
  Dlubal.RFEM5.IModel iModel_cpy = null;
  
  for (int i = 0; i < listBox_models.Items.Count; ++i)
  {
   // open model
   iModel_cpy = iApp.OpenModel(listBox_models.Items[i].ToString());
   
   // get structural data
   Dlubal.RFEM5.IModelData2 iModData_org
    = iModel_org.GetModelData() as Dlubal.RFEM5.IModelData2;
   Dlubal.RFEM5.IModelData2 iModData_cpy
    = iModel_cpy.GetModelData() as Dlubal.RFEM5.IModelData2;
   
   //  compare/change nodes
   //  compare/change lines
   //  compare/change materials
   //  compare/change cross sections
   //  compare/change members
  }
  
 }
 catch (Exception ex)
 {
  MessageBox.Show(ex.Message, ex.Source);
 }
 finally
 {
  if (iApp != null)
  {
   iApp.UnlockLicense();
   
   // Releases COM object - not needed anymore
   // Marshal.ReleaseComObject(iApp);
   iApp = null;
  }
  
  iModel_org = null;
  
  // Cleans Garbage Collector for releasing all COM interfaces and objects.
  System.GC.Collect();
  System.GC.WaitForPendingFinalizers();
 }
}

Как описано выше, сначала выполняется соединение с программой RFEM через GetActiveObject("RFEM5.Application"). Затем посредством GetActiveModel() создается соединение с активной моделью. Для того, чтобы можно было выполнить сравнение, второстепенные модели и их конструктивные данные (GetModelData() ) будут последовательно открываться в цикле по записям в поле списка. С этого момента у нас имеются все геометрические данные для сравнения.

Если возникнет какая-либо проблема, например, невозможно открыть модель, то ошибка распознается через try-catch-Block, отобразится, а программа продолжит работу.

Сравнение узлов

Сравнение узлов основной и второстепенной модели выполняется следующим образом.

Сначала выбираются все узлы основной модели и запускается цикл по этим узлам. В данном цикле сначала программа пытается получить данные узла с тем же номером во второстепенной модели. Если этого не произойдет из-за отсутствия узла, то ошибка фиксируется с помощью следующего try-catch-Block, а вместо этого во вторичной модели создается узел с данными из основной модели.

Если узел найден, то считывается комментарий и разделяется с помощью разделителя «;». Если при этом образуется менее трех частей, то данные считываются из основной модели. Если образуются три или более частей, то выполняется их оценка. Буква «f» означает фиксированное значение, которое нельзя заменять. Если «f» отсутствует, то значение будет заменено значением из основной модели.

В качестве небольшого примера можно привести строку «f;;f1;kkl» в комментарии к узлу. При разложении получаются строки «f», «», «f1» и «kkl». Таким образом, для узла останется неизменным значение x, а значения y и z будут заменены, так как для y присутствует пустая строка и для z не знак «f», а «f1».

//  compare/change nodes
Dlubal.RFEM5.Node[] nodes_org = iModData_org.GetNodes();
for(int j=0; j < nodes_org.Length; ++j)
{
 try
 {
  Dlubal.RFEM5.INode iNode = iModData_cpy.GetNode(nodes_org[j].No, Dlubal.RFEM5.ItemAt.AtNo);
  Dlubal.RFEM5.Node node = new Dlubal.RFEM5.Node();
  node = iNode.GetData();
  
  // check, if there are fixed components
  List<string> defs = (node.Comment).Split(';').ToList<string>();
  
  if (defs.Count >= 3)
  {
   if (defs[0] != "f")
    node.X = nodes_org[j].X;
   
   if (defs[1] != "f")
    node.Y = nodes_org[j].Y;
    
   if (defs[2] != "f")
    node.Z = nodes_org[j].Z;
  }
  else
  {
   node.X = nodes_org[j].X;
   node.Y = nodes_org[j].Y;
   node.Z = nodes_org[j].Z;
  }
  
  // set node
  iModData_cpy.PrepareModification();
  iNode.SetData(node);
  iModData_cpy.FinishModification();
  
 }
 catch (Exception ex)
 {
  // if nodes doesn't exist, create it;
  iModData_cpy.PrepareModification();
  iModData_cpy.SetNode(nodes_org[j]);
  iModData_cpy.FinishModification();
 }
 
}

Линии, материалы и остальные сравнения

Для остальных элементов процесс сравнения одинаков и немного отличается от сравнения узлов.

//  compare/change lines
Dlubal.RFEM5.Line[] lines_org = iModData_org.GetLines();
for (int j = 0; j < lines_org.Length; ++j)
{
 try
 {
  Dlubal.RFEM5.ILine iLine = iModData_cpy.GetLine(lines_org[j].No, Dlubal.RFEM5.ItemAt.AtNo);
  Dlubal.RFEM5.Line line = new Dlubal.RFEM5.Line();
  line = iLine.GetData();
  
  // check, if the line is fixed
  List<string> defs = (line.Comment).Split(';').ToList<string>();
  
  if (defs[0] != "f")
  {
   line = lines_org[j];
  }
  
  // set line
  iModData_cpy.PrepareModification();
  iLine.SetData(line);
  iModData_cpy.FinishModification();
  
 }
 catch (Exception ex)
 {
  // if nodes doesn't exist, create it;
  iModData_cpy.PrepareModification();
  iModData_cpy.SetLine(lines_org[j]);
  iModData_cpy.FinishModification();
 }
 
}

Отличие от сравнения узлов заключается в том, что элемент полностью заменяется, если в разложенном комментарии (разделенном с помощью «;») не найдено «f». Остальные элементы создаются и сравниваются точно таким же образом. Исходный код вы найдете в прилагаемом проекте Visual Studio.

Анализ

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

Заключение и перспективы применения

Представленная программа позволяет обновить второстепенные модели на основе основной модели. Изменения передаются должным образом, начиная от узлов и заканчивая стержнями.

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


Автор

Г-н Гюнтель осуществляет техническую поддержку пользователей Dlubal Software.

Ссылки
Скачивания