[CONNECT Update 17 C#] Add multiline to element

Hi,
is it possible to retrofit existing elements (line, line strings etc.) with multilines or replace them with multilines?

Regards
Frank

Parents Reply Children
  • I wrote it in my previous answer: There is MultilineElement with dedicated method to create the new element. Be aware that multiline is always created based on style (even when it can be "unnamed"), so when the style is not in dgnlib, I guess you must to create it upfront (or to pass the existing active style).

    Hi Jan,
    with the following test code I can unfortunately only draw an invisible multiline element.

        using BD = Bentley.DgnPlatformNET;
        using BDE = Bentley.DgnPlatformNET.Elements;
        using BG = Bentley.GeometryNET;
        using BIM = Bentley.Interop.MicroStationDGN;
        using BM = Bentley.MstnPlatformNET;
        using BMI = Bentley.MstnPlatformNET.InteropServices;
    
        BD.DgnModel dgnModel = BM.Session.Instance.GetActiveDgnModel();
        BG.DPoint3d[] dPoint3ds = new BG.DPoint3d[3];
        
        dPoint3ds[0].X = 0;
        dPoint3ds[0].Y = 0;
        dPoint3ds[1].X = 100000;
        dPoint3ds[1].Y = 100000;
        dPoint3ds[2].X = 200000;
        dPoint3ds[2].Y = 0;
        
        BG.DVector3d dVector3d = default;
        
        BD.DgnFile multilineLib = null;
        
        string multilineFileName = @"c:\LVG\MicroStationCONNECT\WorkSpaces\Kartographie\WorkSets\dtk50_utm\Standards\Dgnlib\DTK50_EbenenML.dgnlib";
        
        BM.DgnLibIterator dgnLibIterator = new BM.DgnLibIterator(BM.DgnLibSelector.ElementStyles);
        foreach (BD.DgnFile lib in dgnLibIterator)
        {
            Debug.WriteLine("DgnLib: " + lib.GetFileName());
        
            if (lib.GetFileName().ToLower() == multilineFileName.ToLower().Replace("\\", @"\"))
            {
                if (File.Exists(multilineFileName))
                {
                    Debug.WriteLine("Multiline-DgnLib: " + lib.GetFileName());
                    multilineLib = lib;
                }
            }
        }
        
        BD.MultilineStyle multilineStyle = BD.MultilineStyle.GetByName("3170_0", multilineLib);
        
        using (BDE.Element element = BDE.MultilineElement.CreateMultilineElement(
                   dgnModel,
                   null,
                   multilineStyle,
                   1,
                   dVector3d,
                   dPoint3ds))
        {
            element.AddToModel();
        
            BIM.Application msApp = BMI.Utilities.ComApp;
            BIM.Element bimElement = msApp.ActiveModelReference.GetElementByID(element.ElementId);
            BIM.Level level = msApp.ActiveSettings.Level;
            BIM.LineStyle lineStyle = msApp.ActiveSettings.LineStyle;
            bimElement.LineStyle = lineStyle;
            bimElement.Level = level;
            bimElement.Color = msApp.ActiveSettings.Color;
            bimElement.LineWeight = msApp.ActiveSettings.LineWeight;
            bimElement.Rewrite();
        }


    However, if you move the cursor over the point in question, a multiline element is displayed!


    However, the style properties do not contain '3170_0', which is the name of a multiline definition.


    The variable 'multilineLib' really contains the multiline style '3170_0'. I have checked this. If this were not true, there would be an uncaught runtime error.

    This is what '3170_0' looks like when drawn by hand with MicroStation.


    It looks like I'm doing something wrong here or something is still missing.

    Regards
    Frank


  • Addendum:
    The BDE.MultilineElement.CreateMultilineElement only works as hoped when the MultilineStyle is fetched from the active DGN. However, this only works if the respective MultilineElement has already been drawn once by hand with the respective style in this DGN.
    Apparently, BDE.MultilineElement.CreateMultilineElement has a problem when a DGNLIB is used as a source for MultilineStyles.

  • The BDE.MultilineElement.CreateMultilineElement only works as hoped when the MultilineStyle is fetched from the active DGN

    Resources — line styles, text styles, level definitions — are often stored in a read-only DGNLib (Design Library).  A MicroStation built-in command will copy the resource from the DGNLib to the active DGN file on demand.  Your code must do the same before attempting to use a resource...

    1. Check whether a resource exists in the active DGN file
    2. If the resource does not exist, search visibile DGNLibs
      1. If the resource is found, copy it to the active DGN file
      2. If the resource is not found, issue a helpful warning to your user

    Put the above code in a C++ class (e.g. ResourceSynchroniser) that you call each time you start your command.

     
    Regards, Jon Summers
    LA Solutions

  • Hi Frank,

    when the MultilineStyle is fetched from the active DGN

    if I remember correctly, so it is how MicroStation (NET) API works normally.

    Apparently, BDE.MultilineElement.CreateMultilineElement has a problem when a DGNLIB is used as a source for MultilineStyles.

    In such case you must check whether the style is already in DGN file or not.

    I think in the past I had to do the same with text styles (or was is another style? ;-)

    With regards,

      Jan

  • Hi Frank,

    In such case you must check whether the style is already in DGN file or not.

    I found my older code. I have no idea whether it's the simplest way, but it works at least for text styles, so I guessit can be used for multiline styles too :-)

    DgnTextStyle styleInActiveFile = DgnTextStyle.GetByName(name, Session.Instance.GetActiveDgnFile());
    
    if (null == styleInActiveFile)
    {
        DgnLibIterator iterator = new DgnLibIterator(DgnLibSelector.ElementStyles);
    
        foreach (DgnFile lib in iterator)
        {
            TextStyleCollection textStyles = lib.GetTextStyles();
    
            foreach (DgnTextStyle textStyle in textStyles)
            {
                if (0 == string.CompareOrdinal(name, textStyle.Name))
                {
                    textStyle.Add(Session.Instance.GetActiveDgnFile());
                    styleInActiveFile = DgnTextStyle.GetByName(name, Session.Instance.GetActiveDgnFile());
    
                    break;
                }
            }
        }
    }

    Regards,

      Jan

    Answer Verified By: Frank Schneller 

  • Hi Jan,
    You have helped me once again with this tip.
    It is the same with multilines as with text styles.

    Thanks.

    Regards
    Frank