Hi,is it possible to retrofit existing elements (line, line strings etc.) with multilines or replace them with multilines?
RegardsFrank
Hi Frank,
to confirm I understand your question right: You would like to find specific elements and all of them to relace with define multiline? Is such multiline define as style or it should be entered?
Regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Hi Jan,See the answer I gave to Robert Hook.
Frank Schneller said:See the answer I gave to Robert Hook.
Yes, it makes the question and its context clearer :-)
Frank Schneller said:Now I have access to such an element programmatically (element processor)
I do not know your code, but element processor is not the tool to access elements: To access elements, simple enumeration (or scanning, when is rarely necessary) is enough. ElementGraphicsProcessor, when paired with ElementGraphicsOutput, allows to access not elements (they are input for the processor), but their visual representation, depending on defined context. So e.g. simple LineString is element (belonging to specific model, has defined properties and attached data), whereas decompose to "drawn topology", typically represented by CurveVector/CurvePrimitives data structure.
Sometimes the processor must be used when element geometry is accessed (or is one from options at least), but not always.
Frank Schneller said:and would update it with a multiline style from the attached library or convert it to multiline.
I am not sure whether API allows to replace different elements in one call (should be tested), but generally it's about removing existing element and creating new MultilineElement with assigned MultilineStyle.
Although I did not write such code in the past, it sounds quite straightforward.
With regards,
Hi Jan,ok, then a possible solution would be as follows, if I have understood correctly:- You have e.g. a linestring element in the access- read all necessary properties from this element (vertices, level, colour, weight, style etc.)- create a new multiline element with these properties.- Now delete the original line string element.Now the question is how do I create a multiline element in C#?Something like I can do with the following MicroStation KeyIn: active level levelnameactive colour ByLevelactive weight ByLevelactive style ByLevelmlinestyle active stylenameplace mline constrainedRegardsFrank
Frank Schneller said:read all necessary properties from this element (vertices, level, colour, weight, style etc.)
Yes. Some properties are accessible directly from Element, some through ElementPropertyGetter and in some cases, query element to receive CurveVector/CurvePrimitive is necessary.
Frank Schneller said:Now delete the original line string element.
I am not sure whether it's possible to replace one element by another, even when they are different types, or it must be done like you wrote, to delete the old one and to add the new.
Frank Schneller said:Now the question is how do I create a multiline element in C#?
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).
Jan Šlegr said: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.RegardsFrank
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.
Frank Schneller said: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...
Put the above code in a C++ class (e.g. ResourceSynchroniser) that you call each time you start your command.
ResourceSynchroniser
Regards, Jon Summers LA Solutions
Frank Schneller said: when the MultilineStyle is fetched from the active DGN
if I remember correctly, so it is how MicroStation (NET) API works normally.
Frank Schneller said: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? ;-)
Jan Šlegr said: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; } } } }
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.