Updating Tekla elements, which was created from C#

Hello everybody,
I’ve created c# script, which one add weld to the Tekla model. But now, when I modify smf from the input of this component, weld will create again and I have double weld in 1 place.
What can I do with that?
I have just 1 idea, but it isn’t automatic: on the right I delete weld before changing input by the condition and boolean toogle.

private void RunScript(List<object> MainPartIn, List<object> SecPartIn1, List<object> SecPartIn2, ref object A)
  {
    var MainPartList = new List<Beam>();
    Changer(MainPartIn, MainPartList);

    var SecPartList1 = new List<ContourPlate>();
    Changer(SecPartIn1, SecPartList1);

    var SecPartList2 = new List<ContourPlate>();
    Changer(SecPartIn2, SecPartList2);

    var WeldList = new List<Weld>();

    Welder(MainPartList, SecPartList1, WeldList);
    Welder(MainPartList, SecPartList2, WeldList);
    A = WeldList;  
  }

  // <Custom additional code> 
   private void Changer (List<object> listA, List<Beam> listB)
  {
    foreach (var e in listA)    
      listB.Add(e as Tekla.Structures.Model.Beam);    
  }

  private void Changer (List<object> listA, List<ContourPlate> listB)
  {
    foreach (var e in listA)    
      listB.Add(e as Tekla.Structures.Model.ContourPlate);    
  }

  private void Changer (List<object> listA, List<Weld> listB)
  {
    foreach (var e in listA)    
      listB.Add(e as Tekla.Structures.Model.Weld);    
  }

  private void Welder (List<Beam> MainPartList, List<ContourPlate> SecPartList, List<Weld> WeldList)
  {
    for (int i = 0; i < MainPartList.Count;i++)
    {
      var Weld = new Weld();
      Weld.MainObject = MainPartList[i];
      Weld.SecondaryObject = SecPartList[i];
      Weld.ShopWeld = true;
      Weld.AroundWeld = false;
      Weld.Insert();
      WeldList.Add(Weld);
    }
  }

Hi,

This is extremely difficult to do. You’d need to store the GUID of the created weld(s) somewhere (internal property like a private List<GUID> or write them to a file if you need that component to update across multiple sessions) and delete those at the start of the component solution when it’s triggered again.

This is essentially what the Tekla Live Link does… and one of the reasons it can’t handle bolts or welds dynamically is it does for beams or plates.

hm, I think it’s a good way. I will try to do it later, because how I see, it’s indeed hard :slight_smile:
Thank you

I founded a bit better solution with weld. When I working with weld can be created a lot of copy of this, because when update input in C# node, node work again. Thanks for “data recorder” I can delete of all this copy just with 1 click and additional C# node.


Delete weld code:

 private void RunScript(List<object> x, bool y, ref object A)
  {
    var OldWeldList = new List<Weld>();
    Changer(x, OldWeldList);

    if (y)
    {
      foreach (var e in OldWeldList)
      {
        e.Delete();
      }
    }
// <Custom additional code> 
  private void Changer (List<object> listA, List<Beam> listB)
  {
    foreach (var e in listA)
    {
      listB.Add(e as Tekla.Structures.Model.Beam);
    }
  }

  private void Changer (List<object> listA, List<ContourPlate> listB)
  {
    foreach (var e in listA)
    {
      listB.Add(e as Tekla.Structures.Model.ContourPlate);
    }
  }

  private void Changer (List<object> listA, List<Weld> listB)
  {
    foreach (var e in listA)
    {
      listB.Add(e as Tekla.Structures.Model.Weld);
    }
  }
  // </Custom additional code> 
1 Like

Here is one example to create weld in Tekla.
Create weld in Tekla.gh (8.8 KB)

1 Like

Thank you so much for the exemple. This part of code was new for me:

    if (secpa != null)
    {
      if (mainpa != null)
      {
        if (WeldF.Identifier.IsValid())
          WeldF.Modify();
        else       
          WeldF.Insert();        
        Weld = WeldF;
      }
    }
    new Tekla.Structures.Model.Model().CommitChanges();

But at the beginning I’m not understand a bit. Code below have a good work with “second element”, which one have just 1 weld. But if there is 2 and more welds it doesn’t work. And if I use this script again and weld this “second element” with another, then code change first weld and doesn’t make second weld.

    var weldEnum = secpa.GetWelds();
    if (weldEnum.MoveNext())    
      WeldF = weldEnum.Current as Weld;
    else    
      WeldF = new Weld();

What do you think about it? I’ve tried solve it, but in this moment I didn’t it.

Hi @YAHOR
Here is the updated Grasshopper script.

Create multiple welds.gh (14.9 KB)

3 Likes

Thank you for your help :slight_smile:

1 Like

Hello
I returned to your suggestion. I couldn’t safely use @ sajesh_pj solution because I don’t quite understand it :slight_smile:
The implementation of your variant turned out to be not very complicated and it is easy to transfer it between different types of elements. In the example below, I create a weld for a 4-plate beam.

Additional useful example

Also I used this to create steel plates (added chamfer editing).

In the code example, I delete the element, then create a new one, maybe in the future I will make it editable, but at this stage it is simpler.

Code

image

Usefull link:

using System;
using System.Collections;
using System.Collections.Generic;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

using System.Linq;
using System.IO;

//You need to add this files to references in the c# node
using Tekla.Structures;
using Tekla.Structures.Model;
using Tekla.Structures.Geometry3d;



private void RunScript(List<System.Object> BottomBeamIn, List<System.Object> SideBeamIn1, List<System.Object> SideBeamIn2, List<System.Object> TopBeamIn, List<int> Position, int size, ref object WeldOut)
  {
    var Filepath = @"C:\WeldOuterRingGUID.txt";
    var GUIdList = new List<string>();
    var WeldList = new List<Weld>();

    //GUID from file to list in script and clear file
    var sr = new StreamReader(Filepath);
    GUIdList.Add(sr.ReadLine());
    var m = 0;
    while (GUIdList[m] != null)
    {
      GUIdList.Add(sr.ReadLine());
      m++;
    }
    sr.Close();
    File.WriteAllText(Filepath, String.Empty);


    //Choose all WELD
    Model Model = new Model();
    ModelObjectEnumerator Objects = Model.GetModelObjectSelector().
      GetAllObjectsWithType(ModelObject.ModelObjectEnum.WELD); 
// Here just change to another type

    //Comparison all weld to GUID and choose it, save it to weldList
    var counter = 0;
    foreach (Weld obj in Objects)
    {
      for (var i = 0; i < GUIdList.Count - 1;i++)
      {
        bool a = obj.Identifier.GUID.ToString() == GUIdList[i];

        if(obj != null && a)
        {
          WeldList.Add(obj);
          counter += 1;
          break;
        }
      }
      if (counter == (GUIdList.Count - 1))
        break;
    }

    //Delete old weld
    foreach (var obj in WeldList)
    {
      obj.Delete();
    }

    var SideBeamList1 = new List<Beam>();
    Changer(SideBeamIn1, SideBeamList1);

    var SideBeamList2 = new List<Beam>();
    Changer(SideBeamIn2, SideBeamList2);

    var TopBeamList = new List<Beam>();
    Changer(TopBeamIn, TopBeamList);

    var BottomBeamList = new List<Beam>();
    Changer(BottomBeamIn, BottomBeamList);

    Welder(TopBeamList, SideBeamList1, WeldList, Position, false, size);
    Welder(TopBeamList, SideBeamList2, WeldList, Position, true, size);
    Welder(SideBeamList1, BottomBeamList, WeldList, Position, false, size);
    Welder(SideBeamList2, BottomBeamList, WeldList, Position, true, size);

    //GUID to file
    StreamWriter sw = new StreamWriter(Filepath, true);
    foreach (var obj in WeldList)
    {
      sw.WriteLine(obj.Identifier.GUID);
    }
    sw.Close();

    //Update model and send plates out of script
    WeldOut = WeldList;
    new Tekla.Structures.Model.Model().CommitChanges();
  }

  // <Custom additional code> 
  private void Changer (List<object> listA, List<Beam> listB)
  {
    foreach (var e in listA)
      listB.Add(e as Tekla.Structures.Model.Beam);
  }

  private void Changer (List<object> listA, List<ContourPlate> listB)
  {
    foreach (var e in listA)
      listB.Add(e as Tekla.Structures.Model.ContourPlate);
  }

  private void Changer (List<object> listA, List<Weld> listB)
  {
    foreach (var e in listA)
      listB.Add(e as Tekla.Structures.Model.Weld);
  }

  private void Welder (List<Beam> MainPartList, List<Beam> SecPartList, List<Weld> WeldList, List<int>Position, bool mirorPos, int size)
  {
    for (int i = 0; i < MainPartList.Count;i++)
    {
      int posLocal = 0;
      var Weld = new Weld();
      Weld.MainObject = MainPartList[i];
      Weld.SecondaryObject = SecPartList[i];
      Weld.ShopWeld = true;
      Weld.AroundWeld = false;

      if (mirorPos)
      {
        if (Position[i] == 1 || Position[i] == 3)
          posLocal = Position[i] + 1;
        else if (Position[i] == 2 || Position[i] == 4)
          posLocal = Position[i] - 1;
        else posLocal = Position[i];
        Weld.Position = (Weld.WeldPositionEnum) posLocal;
      }
      else
      {
        Weld.Position = (Weld.WeldPositionEnum) Position[i];
      }

      Weld.TypeAbove = BaseWeld.WeldTypeEnum.WELD_TYPE_FILLET;
      Weld.TypeBelow = BaseWeld.WeldTypeEnum.WELD_TYPE_NONE;
      Weld.SizeAbove = size;
      Weld.SizeBelow = 0;

      Weld.Insert();
      WeldList.Add(Weld);
    }
  }

I hope it can help for other people. This forum is so helpful, thanks everybody :wink:

1 Like