2380x
001659
2020-10-13

Cross-Model Updating and Adjusting Structural Data Using the COM Interface

It is necessary to design some structures in different configurations. It may be that an aerial work platform must be analyzed in its position on the ground as well as in the middle and in the extended position. Since such tasks require the creation of several models, which are almost identical, updating all the models with just one mouse click is a considerable relief.

In the following text, it is assumed that you have a basic knowledge of the COM interface. The links lead to articles about the basics of programming.

Task

The program should automatically adjust any structural data such as nodes, lines, members, etc. by clicking a certain button. For example, the coordinates of node 1 should be transferred from the main model to various secondary models and variants. However, not all the values should be transferred; only those that were previously defined freely by the user.

Model Example

As an example for the described program's function, a simple aerial work platform was modeled. The following model is considered to be the main model.

This platform is not parameterized and is available with three types: fully extended, on the ground, and in a middle position. The fully extended type is defined as the main model, the middle as type 1, and the one on the ground as type 2.

Considerations

In order to achieve the task, either a kind of configuration file is required, or a graphical user interface to define which models must be compared to each other.

For defining the free or variable coordinates of a node, the comment function of the respective element should be used. The program looks for a specific string in the comment and, if found, modifies or leaves the corresponding coordinates. In addition, it would be useful if new elements were automatically created in all sub-models. Thus, the structure should be made in such a way that the user activates the desired model in RFEM (edited in the foreground) and the program then opens the required models, comparing them to the main model.

Graphical User Interface

The following simple design was selected for the graphical user interface.

The user can type a path in the text box or insert it by copying and pasting. With "Add New Model" it can be added to the list of models to be adjusted. Use the "Remove Selected Model" button to remove a model selected in the list. The "Modify Models" button starts the program then.

Basic Program Flow

At the beginning, the program only has the paths of the secondary models and variants and it needs the connection to RFEM first. If the connection to RFEM is established, a loop should run over the secondary models. Since the program should also create elements, the hierarchy must be observed. Therefore, nodes are compared first, then lines, materials, cross-sections, and finally, members. Nodes represent an exception, because here the directions x, y, and z should be adopted, if necessary, or left as they are. All other elements are either taken over completely or left as they are. However, it should be the same for all elements that new ones are created.

Basic Structure of the Program

The method executed when clicking the "Modify Models" button has the following basic structure.

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

As already described, the connection to RFEM is established first via GetActiveObject ("RFEM5.Application"). Then, a connection to the active model is established via GetActiveModel(). In order to be able to carry out the comparison, the sub-models and their structural data are opened one after the other in a loop via the entries in the list box (GetModelData() ). At this point in time, all the geometric data are available and can be compared.

If there is a problem (for example, a model cannot be opened), the error is caught by the try-catch block, displayed, and the program will be unlocked.

Nodal Comparison

Comparing nodes between the main and secondary models goes as follows.

First, all nodes of the main model are taken and a loop is started over these nodes. In this loop, the system first tries to get the data of the node with the same number in the secondary model. If this fails because the node does not exist, the error is caught with another try-catch block and in the secondary model the node is created with the data from the main model.

If the node exists, the comment is read and disassembled by means of the separator ";". If there are fewer than three parts, then the data will be taken from the main model. If there are three parts or more, they will be evaluated. An "f" stands for a fixed value that should not be overwritten. If it is not an "f", the value is overwritten by the value from the main model.

A brief example is the string "f;;f1;kkl" in a node's comment. Once disassembled, the strings "f", "", "f1", and "kkl" result. Thus, the value x is left for the node and the values y and z are overwritten, since there is an empty string for y and not exactly "f" but "f1" for 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();
 }
 
}

Lines, Materials, and Other Comparisons

The other elements are slightly different from the node comparison but identical among each other.

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

The difference from the node comparison is that the element is completely overwritten if no "f" is found in the disassembled comment (disassembled by ";"). The other elements are created and compared in exactly the same way. See the source code in the attached Visual Studio project.

Evaluation

The program is able to implement the desired changes in the secondary models. The video for the article shows how it works. The biggest problem is currently that incorrect entries are not intercepted, or only slightly intercepted.

Summary and Outlook

The program presented here is able to update secondary models based on a main model. Modifications on nodes and other elements up to members are transferred correctly.

What is missing are routines for intercepting incorrect entries, which could still be added. Further optimizations would be, for example, the optional closing of secondary models, which may lead to processing in the background. Adding further structural data, loads, and combinations can also be useful.


Author

Mr. Günthel provides technical support for our customers.

Links
Downloads