2389x
001659
2020-10-13

Actualización de modelos generales y ajuste de datos estructurales utilizando la interfaz COM

En algunas estructuras es necesario que su diseño se realice con diferentes configuraciones. Puede ser que una plataforma elevadora deba analizarse en su posición en el suelo, en la posición media y desplegada. Ya que tales tareas requieren la creación de varios modelos, los cuales son casi idénticos, la actualización de todos los modelos con un solo clic del ratón es una ventaja considerable.

A continuación, se asume que se tiene un conocimiento básico de la interfaz COM. Los enlaces proporcionan artículos sobre conceptos básicos de la programación.

Planteamiento de la tarea

El programa debería ajustar automáticamente cualquier dato estructural como nudos, líneas, barras, etc. al hacer clic en un botón determinado. Por ejemplo, las coordenadas del nudo 1 se deberían transferir desde un modelo principal a varios modelos secundarios y variantes. Sin embargo, no se deberían transferir todos los valores, sino sólo aquellos que el usuario haya definido previamente libremente.

Modelo de ejemplo

Como ejemplo para la función del programa descrita se modeló una plataforma elevadora simple. El siguiente modelo se considera como el modelo principal.

Esta plataforma no está parametrizada y está disponible con tres tipos: completamente desplegada, en el suelo y en una posición media. El tipo completamente desplegada se define como el modelo principal, el del medio como el tipo 1 y el que está en el suelo como el tipo 2.

Consideraciones

Para lograr la tarea, se requiere o bien un tipo de archivo de configuración o una interfaz gráfica de usuario para definir qué modelos se deben comparar entre sí.

Para definir las coordenadas libres o variables de un nudo, se debería usar la función de comentario del elemento respectivo. El programa busca una cadena de caracteres específica en el comentario y, si la encuentra, modifica o deja las coordenadas correspondientes. Además, sería útil que se crearan nuevos elementos automáticamente en todos los submodelos. Por lo tanto, la estructura se debe hacer de tal manera que el usuario active el modelo deseado en RFEM (editado en primer plano) y el programa abra los modelos requeridos, comparándolos con el modelo principal.

Interfaz gráfica de usuario

Se seleccionó el siguiente cálculo simple para la interfaz gráfica de usuario.

El usuario puede escribir una ruta en el cuadro de texto o insertarla copiando y pegando. Con "Add New Model" se puede agregar a la lista de modelos para ajustar. Use el botón "Remove Selected Model" para eliminar un modelo seleccionado en la lista. El botón "Modify Models" inicia el programa.

Desarrollo básico del programa

Al principio, el programa solo tiene las rutas de los modelos secundarios y variantes y primero necesita la conexión con RFEM. Si se establece la conexión con RFEM, entonces se debe ejecutar un bucle sobre los modelos secundarios. Dado que el programa también debería crear elementos, se debe observar la jerarquía. Por lo tanto, primero se comparan los nudos, luego las líneas, los materiales, las secciones y finalmente las barras. Los nudos representan una excepción, porque aquí se deberían adoptar las direcciones x, y, z, si es necesario, o dejarlas como están. Todos los demás elementos se toman completamente o se dejan como están. Sin embargo, debería ser igual para todos los elementos que se creen nuevos.

Estructura básica del programa

El método que se ejecuta al hacer clic en el botón "Modificar modelos" tiene la siguiente estructura básica.

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

Como ya descrito, la conexión con RFEM se establece primero a través de GetActiveObject ("RFEM5.Application"). Luego, se establece una conexión con el modelo activo a través de GetActiveModel(). Para poder realizar la comparación, los submodelos y sus datos estructurales se abren uno tras otro en un bucle a través de los datos de entrada en el cuadro de lista (GetModelData()). En este momento, todos los datos geométricos están disponibles y se pueden comparar.

Si hay algún problema, por ejemplo, no se puede abrir un modelo, el bloque try-catch detecta el error y el programa se desbloqueará.

Comparación de nudos

La comparación de los nudos entre el modelo principal y secundario es la siguiente.

Primero, se toman todos los nudos del modelo principal y se inicia un bucle sobre estos nudos. En este bucle, el sistema primero intenta obtener los datos del nudo con el mismo número en el modelo secundario. Si esto falla porque el nudo no existe, el error se detecta con otro bloque try-catch y en el modelo secundario se crea el nudo con los datos del modelo principal.

Si el nudo existe, el comentario se lee y se desmonta por medio del separador ";". Si hay menos de tres partes, los datos se tomarán del modelo principal. Si hay tres partes o más, se evaluarán. Una "f" representa un valor fijo que no se debe sobrescribir. Si no es una "f", el valor se sobrescribe con el valor del modelo principal.

Un ejemplo corto es la cadena de caracteres "f;;f1;kkl" en el comentario de un nudo. Una vez desmontadas, resultan las cadenas de caracteres "f", "", "f1" y "kkl". Por lo tanto, se deja el valor x para el nudo y se sobrescriben los valores y y z, ya que hay una cadena de caracteres vacía para y y no exactamente "f" sino "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 (Exception ex)
 {
  // if nodes doesn't exist, create it;
  iModData_cpy.PrepareModification();
  iModData_cpy.SetNode(nodes_org[j]);
  iModData_cpy.FinishModification();
 }
 
}

Líneas, materiales y otras comparaciones

Los otros elementos son ligeramente diferentes a la comparación de los nudos e idénticos entre sí.

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

La diferencia con la comparación de nudos es que el elemento se sobrescribe completamente si no se encuentra una "f" en el comentario desensamblado (desensamblado por ";"). Los otros elementos se crean y comparan exactamente de la misma manera. Vea el código fuente en el proyecto de Visual Studio adjunto.

Evaluación

El programa puede implementar los cambios deseados en los modelos secundarios. El funcionamiento se muestra en el vídeo del artículo. El mayor problema es que las entradas de datos incorrectas no se interceptan o solo se interceptan ligeramente.

Resumen y vista general

El programa presentado aquí es capaz de actualizar modelos secundarios basados en un modelo principal. Las modificaciones tanto en los nudos como en las barras se transfieren correctamente.

Lo que falta son rutinas para interceptar entradas incorrectas, las cuales aún podrían agregarse. Otras optimizaciones serían, por ejemplo, el cierre opcional de modelos secundarios, lo que puede conducir a un procesamiento en segundo plano. También puede ser útil agregar más datos estructurales, cargas y combinaciones.


Autor

El Sr. Günthel proporciona soporte técnico para los clientes de Dlubal Software y se ocupa de sus solicitudes.

Enlaces
Descargas