2313x
001659
13.10.2020

Aktualizace a úprava údajů o konstrukci napříč modely přes rozhraní COM

V našem následujícím příspěvku budeme předpokládat již základní znalosti práce s rozhraním COM. Odkazy na články, které se zabývají základy programování, připojujeme níže.

Vytyčení úkolu

Program by měl po kliknutí na tlačítko automaticky upravit v různých modelech údaje o konstrukci, jako jsou uzly, linie, pruty a další. Z hlavního modelu by se například měly převzít souřadnice uzlu 1 do různých vedlejších modelů a variant. Nelze ovšem přitom převzít veškeré hodnoty, ale jen hodnoty, které byly dříve uživatelem zadány jako volné.

Příklad

Jako příklad pro funkci programu jsme vytvořili model jednoduché zvedací plošiny. Následující model budeme považovat za hlavní model.

Zvedací plošina není zadána parametricky a je k dispozici ve třech variantách: vysunutá do maximální výšky, u země a ve střední poloze. Plošinu v maximální výšce označíme za hlavní model, prostřední polohu za variantu 1 a polohu u země za variantu 2.

Prvotní úvaha

K dosažení tohoto úkolu je zapotřebí buď určitý konfigurační soubor nebo grafické rozhraní, ve kterém se stanoví, které modely se mají porovnávat.

Pro zadání volných nebo proměnných souřadnic uzlu se použije komentář příslušného prvku. Program by měl v komentáři vyhledávat konkrétní řetězec a pokud ho nalezne, změní anebo ponechá příslušné souřadnice. Kromě toho by se ve všech submodelech měly rovněž automaticky vytvářet nové prvky. Uživatel by tak aktivoval požadovaný model v programu RFEM (upravoval ho v popředí) a program by následně otevřel požadované modely a porovnal je s tímto hlavním modelem.

Grafické rozhraní

Pro grafické rozhraní jsme zvolili následující jednoduché řešení.

Uživatel může vložit nebo zadat pomocí funkce Kopírovat & Vložit cestu do textového pole. Pomocí "Add New Model" ho lze připojit na seznam porovnávaných modelů. Pomocí tlačítka "Remove Selected Model" lze model vybraný v seznamu odstranit. Tlačítkem "Modify Models" se pak spustí příslušný program.

Základní běh programu

Program má zpočátku pouze cesty k vedlejším modelům a variantám a vyžaduje nejdříve napojení na program RFEM. Po navázání spojení s programem RFEM se má jako další krok spustit smyčka přes vedlejší modely. Protože program má také vytvářet prvky, je třeba dbát na hierarchii. Proto se nejdříve porovnávají uzly, poté linie, materiály, průřezy a nakonec pruty. Výjimku tvoří uzly, protože v tomto případě se mají podle potřeby převzít anebo ponechat směry x, y a z. Všechny ostatní prvky se buď zcela přenesou anebo ponechají. U všech prvků je ovšem stejné vytváření nových prvků.

Základní struktura programu

Metoda, která se spustí po kliknutí na tlačítko "Modify Models", má následující základní strukturu.

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

Jak jsme již zmínili, nejdříve se naváže spojení s programem RFEM přes GetActiveObject("RFEM5.Application"). Poté se ustaví spojení s aktivním modelem přes GetActiveModel(). Aby bylo možné provést srovnání, otevřou se nyní postupně ve smyčce položky v seznamu se submodely a jejich konstrukčními údaji (GetModelData() ). Nyní máme k dispozici všechny geometrické údaje a lze je porovnat.

Pokud se například vyskytne problém, například některý model nelze otevřít, chyba se zachytí přes try-catch block, zobrazí se a program pokračuje.

Porovnání uzlů

Porovnání uzlů mezi hlavním a vedlejším modelem probíhá následovně.

Nejdříve se vyvolají všechny uzly hlavního modelu a spustí se nad nimi smyčka. V této smyčce se nejdříve zkouší vyvolat údaje uzlu se stejným číslem ve vedlejším modelu. Pokud se to nepodaří, protože uzel neexistuje, zachytí se chyba dalším try-cath blokem a místo toho se vytvoří ve vedlejším modelu uzel s údaji z hlavního modelu.

Pokud uzel existuje, načte se komentář a rozloží se pomocí oddělovače ";". Pokud přitom vzniknou méně než 3 části, převezmou se údaje z hlavního modelu. Pokud jsou části tři anebo více, vyhodnotí se. "f" představuje pevnou hodnotu, kterou nelze přepsat. V případě, že „f“ chybí, hodnota se přepíše hodnotou z hlavního modelu.

Krátkým příkladem je řetězec "f;;f1;kkl" v komentáři k uzlu. Po rozložení dostaneme řetězce "f", "", "f1" a "kkl". U uzlu se tedy ponechává hodnota x a hodnoty y a z se přepíšou, protože pro y je zde prázdný řetězec a pro z tu není přesně „f“, ale „f1“.

//  compare/change nodes
Dlubal.RFEM5.Node[] nodes_org = iModData_org.GetNodes();
pro (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();
 }
 
}

Linie, materiály a ostatní srovnání

U ostatních prvků, pro které je již postup stejný, se průběh mírně liší od porovnávání uzlů.

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

Rozdíl oproti porovnávání uzlů spočívá v tom, že se prvek zcela přepíše, pokud se v rozloženém komentáři (pomocí ";") nenachází žádné "f". Ostatní prvky se vytvářejí a porovnávají naprosto stejně. Podívat se můžete na zdrojový kód v přiloženém Visual Studio projektu.

Vyhodnocení

Program je schopen provést požadované změny ve vedlejších modelech. Tuto funkcionalitu programu ukazujeme ve videu k tomuto příspěvku. Největším problém aktuálně spočívá v tom, že se chyby v zadání neodchytávají vůbec nebo málo.

Shrnutí a výhled

Ukázaný program umožňuje aktualizovat vedlejší modely na základě hlavního modelu. Řádně se přenášejí změny od uzlů až po pruty.

Co chybí, jsou rutiny pro zachytávání chybných zadání, které by ještě bylo možné doplnit. Další optimalizací by bylo například volitelné zavření vedlejších modelů, což může vést ke zpracování na pozadí. Jako užitečné se může jevit také doplnění dalších údajů o konstrukci, zatížení a kombinací.


Autor

Ing. Günthel zajišťuje technickou podporu zákazníkům.

Odkazy
Stahování