2389x
001659
2020-10-13

Atualização e ajuste de dados estruturais de vários modelos através da interface COM

Para algumas estruturas, é necessário dimensioná-las em diferentes configurações. A posição de um plataforma de elevação, por exemplo, poderá ter de ser analisada na respetiva posição no solo, no meio e estendida. Uma vez que tais tarefas requerem a criação de vários modelos quase idênticos, a opção de atualizar todos os modelos com apenas um clique do rato representa um alívio considerável.

No texto seguinte, parte -se do princípio de que tem um conhecimento básico da interface COM. Os links levam a artigos sobre noções básicas de programação.

Tarefa

O programa deve ajustar automaticamente todos os dados estruturais, tais como nós, linhas, barras, etc., clicando em um determinado botão. Por exemplo, as coordenadas do nó 1 devem ser transferidas do modelo principal para vários modelos secundários e variantes. No entanto, nem todos os valores devem ser transferidos; apenas aqueles que foram previamente definidos livremente pelo utilizador.

Modelo de exemplo

Como exemplo da função do programa descrito, foi modelada uma plataforma aérea simples. O seguinte modelo é considerado o modelo principal.

Esta plataforma não é parametrizada e está disponível em três tipos: totalmente estendido, no solo e em uma posição central. O tipo totalmente estendido é definido como o modelo principal, o do meio como o tipo 1 e o que está no solo como o tipo 2.

Considerações

Para realizar a tarefa, é necessário um tipo de arquivo de configuração ou uma interface gráfica do usuário para definir quais modelos devem ser comparados entre si.

Para definir as coordenadas livres ou variáveis de um nó, deve ser utilizada a função de comentário do respetivo elemento. O programa procura uma string específica no comentário e, se encontrada, altera ou deixa as coordenadas correspondentes. Além disso, seria útil se novos elementos fossem criados automaticamente em todos os submodelos. Assim, a estrutura deve ser feita de forma a que o utilizador ative o modelo pretendido no RFEM (editado em primeiro plano) e o programa abra os modelos necessários, comparando -os com o modelo principal.

Interface gráfica do utilizador

O seguinte design simples foi selecionado para a interface gráfica do utilizador.

O usuário pode digitar um caminho na caixa de texto ou inseri -lo copiando e colando. Com "Adicionar novo modelo", este pode ser adicionado à lista de modelos a serem ajustados. Utilize o botão "Remover modelo selecionado" para remover um modelo selecionado da lista. O botão "Modificar modelos" inicia o programa.

Fluxo básico do programa

No início, o programa contém apenas os caminhos dos modelos secundários e variantes e necessita primeiro de uma ligação ao RFEM. Se a ligação ao RFEM for estabelecida, deve ser executado um loop nos modelos secundários. Uma vez que o programa também deve criar elementos, a hierarquia deve ser observada. Portanto, os nós são comparados primeiro, depois as linhas, os materiais, as secções e, finalmente, as barras. Os nós representam uma exceção, porque aqui as direções x, y e z devem ser adotadas, se necessário, ou deixadas como estão. Todos os outros elementos são assumidos completamente ou deixados como estão. No entanto, deve ser o mesmo para todos os elementos que são criados novos.

Estrutura básica do programa

O método executado ao clicar no botão "Modificar modelos" tem a seguinte estrutura básica.

private void button_mod_click (objeto remetente, 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();
 }
}

Conforme já descrito, a ligação ao RFEM é estabelecida primeiro através do GetActiveObject ("RFEM5.Application"). Em seguida, é estabelecida uma ligação ao modelo ativo através de GetActiveModel (). Para poder realizar a comparação, os submodelos e os seus dados estruturais são abertos um após o outro num ciclo através das entradas na caixa de listagem (GetModelData ()). Neste momento, todos os dados geométricos estão disponíveis e podem ser comparados.

Se houver um problema (por exemplo, um modelo não pode ser aberto), o erro é detectado pelo bloco try-catch, exibido, e o programa será desbloqueado.

Comparação nodal

A comparação dos nós entre os modelos principal e secundário é o seguinte.

Primeiro, todos os nós do modelo principal são tomados e um loop é iniciado sobre esses nós. Neste ciclo, o sistema tenta primeiro obter os dados do nó com o mesmo número no modelo secundário. Se isso falhar porque o nó não existe, o erro é detectado com outro bloco try-catch e no modelo secundário o nó é criado com os dados do modelo principal.

Se o nó existe, o comentário é lido e desmontado através do separador ";". Se houver menos de três partes, os dados serão retirados do modelo principal. Se houver três partes ou mais, elas serão avaliadas. Um "f" representa um valor fixo que não deve ser substituído. Se não for um "f", o valor é substituído pelo valor do modelo principal.

Um breve exemplo é a string "f ;; f1; kkl" no comentário de um nó. Uma vez desmontadas, resultam as cadeias de caracteres "f", "", "f1" e "kkl". Assim, o valor x é deixado para o nó e os valores y e z são substituídos, uma vez que existe uma string vazia para y e não exatamente "f" mas "f1" para z.

//  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 (exceção ex)
 {
  // if nodes doesn't exist, create it;
  iModData_cpy.PrepareModification();
  iModData_cpy.SetNode(nodes_org[j]);
  iModData_cpy.FinishModification();
 }
 
}

Linhas, materiais e outras comparações

Os outros elementos são ligeiramente diferentes da comparação de nós, mas idênticos entre si.

//  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();
 }
 
}

A diferença da comparação de nós é que o elemento é completamente substituído se nenhum "f" for encontrado no comentário desmontado (desmontado por ";"). Os outros elementos são criados e comparados exatamente da mesma forma. Veja o código -fonte no projeto do Visual Studio em anexo.

Avaliação

O programa é capaz de implementar as alterações desejadas nos modelos secundários. O vídeo para o artigo mostra como funciona. O maior problema atualmente é que as entradas incorretas não são interceptadas, ou apenas ligeiramente interceptadas.

Resumo and Outlook

O programa aqui apresentado é capaz de atualizar modelos secundários com base num modelo principal. As alterações em nós e outros elementos até às barras são transferidas corretamente.

O que falta são rotinas para interceptar entradas incorretas, que ainda podem ser adicionadas. Otimizações adicionais seriam, por exemplo, o fechamento opcional de modelos secundários, o que pode levar a um processamento em segundo plano. Adicionar mais dados estruturais, cargas e combinações também pode ser útil.


Autor

O Eng. Günthel opera na área do apoio técnico para clientes.

Ligações
Downloads