How to Join - break lines as single continuous parallel to main lines? Tried that functionality with below keyin's. This functionality was existing in V8i now intension is to implement same in MicroStation Connect edition.
For making parallel lines used InteropUtility.SetCopyParallel(Convert.ToInt32(content), ref message); functionality then break main lines were joined with below keyin but
"choose last; drop curve; selview 1;selview 1;choose none"
"create chain automatic;%d;%d;selview 1"
Please suggest any affective way of implementing both copy parallel along with join if it has break lines as single continuous line.
Manjula Kamarajugadda said:For making parallel lines usedInteropUtility.SetCopyParallel(Convert.ToInt32(content), ref message)choose last; drop curve; selview 1;selview 1;choose none
InteropUtility.SetCopyParallel(Convert.ToInt32(content), ref message)
choose last; drop curve; selview 1;selview 1;choose none
It's not clear whether you want to use
Your tags are also confusing: you mention CONNECT and V8i. Which is it?
You tagged your post with C#. If it is a question about programming, then post to the MicroStation Programming Forum.
Regards, Jon Summers LA Solutions
Hi Jon,
Thanks for your reply.
We have implemented a functionality similar to copy parallel in V8i using MDL. Client has migrated from V8i to Connect Edition. We tried to mimic the same functionality in Connect Edition using C#, but we were not able to achieve the 100% working client is expecting. In Connect Edition we tried to achieve using "InteropUtility.SetCopyParallel(Convert.ToInt32(content), ref message);". By using this we were able to achieve copy parallel but the newly created lines are disconnected so we tried using keyin's in separate click:
Client wanted the functionality to be achieved in same click. This forum link is provided by Bentley Community and request you to forward this ticket to the programming community if possible.
Manjula Kamarajugadda said:This forum link is provided by Bentley Community and request you to forward this ticket to the programming community
I have no idea what you mean by 'this forum link' or 'ticket'. Nor can I respond to your request to 'forward this ticket'. I am not part of Bentley Systems and have no power in Be Communities to forward anything.
Manjula Kamarajugadda said:We have implemented a functionality similar to copy parallel in V8i using MDL. We tried to mimic the same functionality in Connect Edition using C#
Post a code sample of MDL that worked in V8i.
What doesn't work using C# in CONNECT?
Thanks for your reply, We don't have MDL source code
Manjula Kamarajugadda said:We don't have MDL source code
Because you do not share any example, nobody can say if it can be achieved by CE tools only, but I guess when no original code is available, you must develop the tool from scratch (which is not necessarily bad, because CE API is very different and often it's better to rewrite old tools to use full power of CE platform).
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Hi Jan, Sorry for the later reply. We have given few customized tools to a client in V8i, now have migrated those to CE as per client requirement. We were not part when the tools were developed in V8i. Please find the functionality in brief, user selects a landbase feature (line or linstring or arc) in the dgn in the button provided and the requirement is to draw a line in offset (user provided) to the selected landbase feature. user will continuously select lines, when the 2nd landbase feature is selected the newly offset line should also extend and finally it should be a single linestring. We don't have the source code of this. We used keyins move parallel to achieve it in CE but we are not able to connect the offset lines to a single linestring. I think have explained it bit clearly. Thank You.
manjula kamarajugadda said: I think have explained it bit clearly
It's always hard to describe a graphics operation in words alone. But, since we all use MicroStation, why not post a DGN file that illustrates what you want to achieve?
You can attach a DGN file using the Insert=>Insert image/video/file button while editing your post.
Hi Jon, Please find the attached dgn and document for your reference. Please let me know for any other information.MainPlaceQuery.docx25387797 -MAIN.dgn
Hi Jon, Did you get a chance to review the dgn and document. Thanks in advance.
manjula kamarajugadda said:Did you get a chance to review the dgn and document
The explanations and screenshots make it clearer.
The existing app. for V8i performs something similar to Copy Parallel. You believe that the app. is written using MDL but don't have the source code.
The simplest solution would be for your customer to contact the original developer and purchase the source code from them.
You want to write similar functionality for MicroStation CONNECT. Your preferred language is C#. However, the code fragments you have posted use the VBA InterOp and MicroStation key-in commands.
I strongly suggest that you prototype your app. using VBA. That way you can...
Once the VBA prototype is working, you can move it to a C# AddIn, calling your code via InterOp.
Hi Jon, Thanks for the reply. I am trying to achieve it in a different way. I am asking the users to select required landbase features (line, linestring, arc), will collect the coordinates and generate a linestring. I will provide a button in the UI to offset it. I need a small help in arc case, it will have only 3 coordinates and if I try to generate a line string then the shape is not maintained. I need few more points on the arc to maintain the shape, any suggestion how to do it or you can provide sample code.
manjula kamarajugadda said:or you can provide sample code.
What sample code? At first, you must share your code, so it can be discussed and enhanced.
And it is not clear what code you mean: So far, only key-ins were discussed, and this is not the approach that can be used in the discussed case.
manjula kamarajugadda said:I am asking the users to select required landbase features (line, linestring, arc), will collect the coordinates and generate a linestring.
I am not sure I understand the workflow right, but again, you must implement own tool (using whatever API you prefer) to ask a user to select element, identify points and to collect further information.
manjula kamarajugadda said:I am trying to achieve it in a different way.
My feeling from this long discussion is that it is going round in circles: Quite early it was clear the original V8i tool is complex, so it the functionality cannot be achieved using key-ins only. When there is no source code available, the only solution is to write a new tool with the same functionality for MicroStation CE, using one from available API (discussed C# is fine). I do not think any other option exist, until the requirements are simplified to something completely different and much simpler.
Regards,
Hi Jan, Please find the attached code. We were using the Key-In's previously which didn't work for us in the way it was in V8i so trying to generate a line string with the selected elements in the dgn. I am able to collect coordinates of line and linestring, facing problem for arc cases to maintain the shape and requesting some help in the code.
using Bentley.DgnPlatformNET; using Bentley.DgnPlatformNET.Elements; using Bentley.GeometryNET; using Bentley.MstnPlatformNET; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using BM = Bentley.MstnPlatformNET; using BIM = Bentley.Interop.MicroStationDGN; using Bentley.ECObjects.Units; using System.Runtime.InteropServices; namespace ProductionTools { public class PlaceMain : DgnElementSetTool { static BIM.Application app; private List<DPoint3d> pointsCollection; private List<DPoint3d> lastCollection; private string _level = string.Empty; private int _colorindex = 0; private int _linestyle = 0; private int _lineweight = 0; private LevelId _levelId; private int counter = 0; private static List<BIM.Element> elements; private int _offset = 0; private PlaceMain(int colorindex, string level, int linestyle, int lineweight, LevelId lvlId, int offset) : base(0, 0) //Subash Main Place { _level = level; _linestyle = linestyle; _lineweight = lineweight; _colorindex = colorindex; _levelId = lvlId; _offset = offset; pointsCollection = new List<DPoint3d>(); lastCollection = new List<DPoint3d>(); app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; } /// <summary> /// 1. Select Element in OnDataButton. -- Completed /// 2. Add the elements vertices to a collection. -- Completed /// /// if curve drop as line string and get vertices. -- /// /// 3. Mouse right click. -- Completed /// 4. With vertices collection in point2 draw a linestring. -- Completed /// 5. Pick side. /// 6. Offset. /// </summary> /// <param name="ev"></param> /// <returns></returns> protected override bool OnDataButton(DgnButtonEvent ev) { try { HitPath hitPath = DoLocate(ev, true, 1); if (hitPath != null) { Element element = hitPath.GetHeadElement(); if (element != null) { if ((element.ElementType == MSElementType.LineString || element.ElementType == MSElementType.Line || element.ElementType == MSElementType.Arc)) { collectCoordinates(element); } } } } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Enbridge Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } return true; } private void collectCoordinates(Element element) { try { if (element is LineElement flineelement) { CurveVector fcurveVector = CurvePathQuery.ElementToCurveVector(flineelement); DPoint3d startpoint; DPoint3d endpoint; fcurveVector.GetStartEnd(out startpoint, out endpoint); if (pointsCollection.Count == 0) { pointsCollection.Add(startpoint); pointsCollection.Add(endpoint); lastCollection.Add(startpoint); lastCollection.Add(endpoint); counter++; } else { double distance = lastCollection[0].Distance(startpoint); double distance1 = lastCollection[lastCollection.Count - 1].Distance(startpoint); double distance2 = lastCollection[0].Distance(endpoint); double distance3 = lastCollection[lastCollection.Count - 1].Distance(endpoint); if (counter == 1 && distance < distance1 && distance2 < distance3) pointsCollection.Reverse(); checkAndSetLines(startpoint, endpoint, distance, distance1, distance2, distance3); } } else if (element is LineStringElement flinestringelement) { List<DPoint3d> fpoints = new List<DPoint3d>(); CurveVector fcurveVector = CurvePathQuery.ElementToCurveVector(flinestringelement); fcurveVector.GetPrimitive(0).TryGetLineString(fpoints); if (pointsCollection.Count == 0) { foreach (var item in fpoints) { if (!pointsCollection.Contains(item)) { pointsCollection.Add(item); lastCollection.Add(item); } } counter++; } else { double distance = lastCollection[0].Distance(fpoints[0]); double distance1 = lastCollection[lastCollection.Count - 1].Distance(fpoints[0]); double distance2 = lastCollection[0].Distance(fpoints[fpoints.Count - 1]); double distance3 = lastCollection[lastCollection.Count - 1].Distance(fpoints[fpoints.Count - 1]); if (counter == 1 && distance < distance1 && distance2 < distance3) pointsCollection.Reverse(); checkAndSetLines1(fpoints, distance, distance1, distance2, distance3); } } else if (element is ArcElement curveelement) { //SelectionSetManager.AddElement(element, Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModel()); //Session.Instance.Keyin("drop curve equalarclength"); //Session.Instance.Keyin("selview 1"); //Session.Instance.Keyin("selview 1"); //Session.Instance.Keyin("selview 1"); //Bentley.GeometryNET.FacetOptions facetOptions = new FacetOptions(); //facetOptions.ChordTolerance = 35; ////app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; ////app.CadInputQueue.SendKeyin("drop curve equalarclength "); ////app.SetCExpressionValue("advOptions.facetcurve", 5, "SOLIDMODELING"); } } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Enbridge Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } } /// <summary> /// double distance = lastCollection[0].Distance(startpoint); /// double distance1 = lastCollection[lastCollection.Count - 1].Distance(startpoint); /// double distance2 = lastCollection[0].Distance(endpoint); /// double distance3 = lastCollection[lastCollection.Count - 1].Distance(endpoint); /// </summary> /// <param name="startpoint"></param> /// <param name="endpoint"></param> /// <param name="distance"></param> /// <param name="distance1"></param> /// <param name="distance2"></param> /// <param name="distance3"></param> private void checkAndSetLines1(List<DPoint3d> fpoints, double distance, double distance1, double distance2, double distance3) { lastCollection.Clear(); List<double> dblValues = new List<double>(); List<double> dblValues1 = new List<double>(); dblValues.Add(distance); dblValues.Add(distance1); dblValues.Add(distance2); dblValues.Add(distance3); dblValues1.Add(distance); dblValues1.Add(distance1); dblValues1.Add(distance2); dblValues1.Add(distance3); dblValues.Sort(); double dblValue = dblValues[0]; int index = dblValues1.FindIndex(a => a == dblValue); if (index == 2 || index == 3) fpoints.Reverse(); foreach (var item in fpoints) { if (!pointsCollection.Contains(item)) { pointsCollection.Add(item); lastCollection.Add(item); } } counter++; #region Commented //if (distance2 < distance3) //{ // fpoints.Reverse(); // counter++; //} //else //{ // if (distance3 < 1) // { // fpoints.Reverse(); // counter++; // } //} //fpoints.Reverse(); //counter++; //if (counter == 1 && distance2 < distance3) // fpoints.Reverse(); //else //{ // if (distance3 < distance2) // fpoints.Reverse(); // else // { // } //} #endregion Commented } /// <summary> /// double distance = lastCollection[0].Distance(startpoint); /// double distance1 = lastCollection[lastCollection.Count - 1].Distance(startpoint); /// double distance2 = lastCollection[0].Distance(endpoint); /// double distance3 = lastCollection[lastCollection.Count - 1].Distance(endpoint); /// </summary> /// <param name="startpoint"></param> /// <param name="endpoint"></param> /// <param name="distance"></param> /// <param name="distance1"></param> /// <param name="distance2"></param> /// <param name="distance3"></param> private void checkAndSetLines(DPoint3d startpoint, DPoint3d endpoint, double distance, double distance1, double distance2, double distance3) { lastCollection.Clear(); List<double> dblValues = new List<double>(); List<double> dblValues1 = new List<double>(); dblValues.Add(distance); dblValues.Add(distance1); dblValues.Add(distance2); dblValues.Add(distance3); dblValues1.Add(distance); dblValues1.Add(distance1); dblValues1.Add(distance2); dblValues1.Add(distance3); dblValues.Sort(); double dblValue = dblValues[0]; int index = dblValues1.FindIndex(a => a == dblValue); if (index == 2 || index == 3) { if (!pointsCollection.Contains(endpoint)) pointsCollection.Add(endpoint); if (!pointsCollection.Contains(startpoint)) pointsCollection.Add(startpoint); lastCollection.Add(endpoint); lastCollection.Add(startpoint); counter++; } else { if (!pointsCollection.Contains(startpoint)) pointsCollection.Add(startpoint); if (!pointsCollection.Contains(endpoint)) pointsCollection.Add(endpoint); lastCollection.Add(endpoint); lastCollection.Add(startpoint); counter++; } #region Commented //Distance between Last Segment First Vertex to End Point of Current Segment is Less than Last Segment Last Vertex to End Point of Current Segment //if (distance2 < distance3) //{ // if (!pointsCollection.Contains(endpoint)) // pointsCollection.Add(endpoint); // if (!pointsCollection.Contains(startpoint)) // pointsCollection.Add(startpoint); // lastCollection.Add(endpoint); // lastCollection.Add(startpoint); // counter++; //} //else //{ // if (distance3 < 1) // { // if (!pointsCollection.Contains(endpoint)) // pointsCollection.Add(endpoint); // if (!pointsCollection.Contains(startpoint)) // pointsCollection.Add(startpoint); // lastCollection.Add(endpoint); // lastCollection.Add(startpoint); // counter++; // } // else // { // if (!pointsCollection.Contains(startpoint)) // pointsCollection.Add(startpoint); // if (!pointsCollection.Contains(endpoint)) // pointsCollection.Add(endpoint); // lastCollection.Add(endpoint); // lastCollection.Add(startpoint); // counter++; // } //} #endregion Commented } protected override bool OnResetButton(DgnButtonEvent ev) { try { if (pointsCollection.Count != 0) { Create Line String with the selected elements coordinates Element element = createLineString(); } EndDynamics(); ExitTool(); } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Enbridge Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } return true; } private Element createLineString() { double UorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster; DPoint3d[] ptArr = new DPoint3d[pointsCollection.Count]; for (int i = 0; i < pointsCollection.Count; i++) { ptArr[i] = new DPoint3d(pointsCollection[i].X, pointsCollection[i].Y, pointsCollection[1].Z); } LineStringElement ele = new LineStringElement(Session.Instance.GetActiveDgnModel(), null, ptArr); ElementPropertiesGetter elementPropertiesGetter = new ElementPropertiesGetter(ele); ElementPropertiesSetter eps = new ElementPropertiesSetter(); eps.SetColor(Convert.ToUInt32(_colorindex)); eps.SetWeight(Convert.ToUInt32(_lineweight)); eps.SetLinestyle(_linestyle, elementPropertiesGetter.LineStyle); eps.SetLevel(_levelId); eps.Apply(ele); ele.AddToModel(); return ele; } protected override void OnRestartTool() { //throw new NotImplementedException(); } public override StatusInt OnElementModify(Element element) { throw new NotImplementedException(); } public static void startProcess(int colorindex, string level, int linestyle, int lineweight, LevelId lvlId, int offset) { try { BMI.Utilities.ComApp.CommandState.StartPrimitive(new Template_Primitive_Event_Class()); PlaceMain placeMain = new PlaceMain(colorindex, level, linestyle, lineweight, lvlId, offset); placeMain.InstallTool(); } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Enbridge Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } } } }
Hi,
manjula kamarajugadda said:to generate a line string with the selected elements in the dgn
It sounds like something different than is original topic, when complex string was created from offset elements, whereas to create line string requires transformation of elements like arcs to another linear form (line string).
manjula kamarajugadda said:facing problem for arc cases to maintain the shape
I do not understand what do you mean by "for arc cases to maintain the shape". And it's not clear even from the code.
Why you ask for help when you are not willing to describe the problem and expected result completely?
manjula kamarajugadda said:and requesting some help in the code.
Sorry, the code is a mess. Are you serious to send code where a huge amount of lines are "commented garbage"? It doesn't express any respect to other people's time, because every commented line always causes time waste.
Even when I would ignore so many C# clean code best practices violations (with so many, the code is not easily readable), I don't understand what is expected functionality. The original workflow, described in the document, was quite understandable, but the code looks about something different. Maybe it's because the code does everything, so plenty of different functionality is put into one class (what about SOLID?).
Personally, I would recommend to hire a MicroStation developer to implement required functionality. When there is clear and exact specification, It probably requires less time to implement the tool than people spent reading and understanding this discussion.
Now, I think not any other advice can be provided, because you do not describe what your problem is (what is "arc maintain shape"?) and at the same time you share code with plenty of bugs and weird constructions, but with no single compilable line, related to arc (so no arc element functionality can be analyzed).
Hi Jan, Thanks for your reply. The commented code is the other way we tried to achieve the result. We are trying to achieve by some sample examples and suggestions so some commented code is there apologies for the same and there is nothing different with the original topic. I agree that we were not clear in our question and am at least happy that the document is clear. Please see the below points.
1. You understanding of the document is the output or result we are expecting.
2. Facing problem for arc cases to maintain the shape. If I draw a linestring with the arc coordinates then it will not maintain the shape (Please find the attached image - Arc Case Wrong.PNG). Client will not accept like that so wanted to draw a linestring on the arc which should look like the original arc shape (Please find attached image - Arc Case Correct.PNG).
3. I am struggling to maintain the arc shape (please find the attached image -- Arc Case Correct.PNG), seeking some code help for this case. We are planning to collect all the coordinates in the OnDataButton click and generate a line string in the OnResetButton click methods. collectCoordinates method is used to collect the coordinates.
4. startProcess is called in Place button of UI click (Please find the attached image -- Main.png).
5. I can't share the entire code as it client property but will try to clear all your questions.
6. The code is a mess now as we are trying different approaches and will definitely follow SOILD as you suggested.
I have uploaded the code with out any comment now and request you to go through it and help if possible.
Fullscreen 6136.PlaceMain.txt Download using Bentley.DgnPlatformNET; using Bentley.DgnPlatformNET.Elements; using Bentley.GeometryNET; using Bentley.MstnPlatformNET; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using BM = Bentley.MstnPlatformNET; using BIM = Bentley.Interop.MicroStationDGN; using Bentley.ECObjects.Units; using System.Runtime.InteropServices; namespace ProductionTools { public class PlaceMain : DgnElementSetTool { static BIM.Application app; private List<DPoint3d> pointsCollection; private List<DPoint3d> lastCollection; private string _level = string.Empty; private int _colorindex = 0; private int _linestyle = 0; private int _lineweight = 0; private LevelId _levelId; private int counter = 0; private static List<BIM.Element> elements; private int _offset = 0; private PlaceMain(int colorindex, string level, int linestyle, int lineweight, LevelId lvlId, int offset) : base(0, 0) //Subash Main Place { _level = level; _linestyle = linestyle; _lineweight = lineweight; _colorindex = colorindex; _levelId = lvlId; _offset = offset; pointsCollection = new List<DPoint3d>(); lastCollection = new List<DPoint3d>(); app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; } protected override bool OnDataButton(DgnButtonEvent ev) { try { HitPath hitPath = DoLocate(ev, true, 1); if (hitPath != null) { Element element = hitPath.GetHeadElement(); if (element != null) { if ((element.ElementType == MSElementType.LineString || element.ElementType == MSElementType.Line || element.ElementType == MSElementType.Arc)) { collectCoordinates(element); } } } } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } return true; } private void collectCoordinates(Element element) { try { if (element is LineElement flineelement) { CurveVector fcurveVector = CurvePathQuery.ElementToCurveVector(flineelement); DPoint3d startpoint; DPoint3d endpoint; fcurveVector.GetStartEnd(out startpoint, out endpoint); if (pointsCollection.Count == 0) { pointsCollection.Add(startpoint); pointsCollection.Add(endpoint); lastCollection.Add(startpoint); lastCollection.Add(endpoint); counter++; } else { double distance = lastCollection[0].Distance(startpoint); double distance1 = lastCollection[lastCollection.Count - 1].Distance(startpoint); double distance2 = lastCollection[0].Distance(endpoint); double distance3 = lastCollection[lastCollection.Count - 1].Distance(endpoint); if (counter == 1 && distance < distance1 && distance2 < distance3) pointsCollection.Reverse(); checkAndSetLines(startpoint, endpoint, distance, distance1, distance2, distance3); } } else if (element is LineStringElement flinestringelement) { List<DPoint3d> fpoints = new List<DPoint3d>(); CurveVector fcurveVector = CurvePathQuery.ElementToCurveVector(flinestringelement); fcurveVector.GetPrimitive(0).TryGetLineString(fpoints); if (pointsCollection.Count == 0) { foreach (var item in fpoints) { if (!pointsCollection.Contains(item)) { pointsCollection.Add(item); lastCollection.Add(item); } } counter++; } else { double distance = lastCollection[0].Distance(fpoints[0]); double distance1 = lastCollection[lastCollection.Count - 1].Distance(fpoints[0]); double distance2 = lastCollection[0].Distance(fpoints[fpoints.Count - 1]); double distance3 = lastCollection[lastCollection.Count - 1].Distance(fpoints[fpoints.Count - 1]); if (counter == 1 && distance < distance1 && distance2 < distance3) pointsCollection.Reverse(); checkAndSetLines1(fpoints, distance, distance1, distance2, distance3); } } else if (element is ArcElement curveelement) { } } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } } private void checkAndSetLines1(List<DPoint3d> fpoints, double distance, double distance1, double distance2, double distance3) { lastCollection.Clear(); List<double> dblValues = new List<double>(); List<double> dblValues1 = new List<double>(); dblValues.Add(distance); dblValues.Add(distance1); dblValues.Add(distance2); dblValues.Add(distance3); dblValues1.Add(distance); dblValues1.Add(distance1); dblValues1.Add(distance2); dblValues1.Add(distance3); dblValues.Sort(); double dblValue = dblValues[0]; int index = dblValues1.FindIndex(a => a == dblValue); if (index == 2 || index == 3) fpoints.Reverse(); foreach (var item in fpoints) { if (!pointsCollection.Contains(item)) { pointsCollection.Add(item); lastCollection.Add(item); } } counter++; } private void checkAndSetLines(DPoint3d startpoint, DPoint3d endpoint, double distance, double distance1, double distance2, double distance3) { lastCollection.Clear(); List<double> dblValues = new List<double>(); List<double> dblValues1 = new List<double>(); dblValues.Add(distance); dblValues.Add(distance1); dblValues.Add(distance2); dblValues.Add(distance3); dblValues1.Add(distance); dblValues1.Add(distance1); dblValues1.Add(distance2); dblValues1.Add(distance3); dblValues.Sort(); double dblValue = dblValues[0]; int index = dblValues1.FindIndex(a => a == dblValue); if (index == 2 || index == 3) { if (!pointsCollection.Contains(endpoint)) pointsCollection.Add(endpoint); if (!pointsCollection.Contains(startpoint)) pointsCollection.Add(startpoint); lastCollection.Add(endpoint); lastCollection.Add(startpoint); counter++; } else { if (!pointsCollection.Contains(startpoint)) pointsCollection.Add(startpoint); if (!pointsCollection.Contains(endpoint)) pointsCollection.Add(endpoint); lastCollection.Add(endpoint); lastCollection.Add(startpoint); counter++; } } protected override bool OnResetButton(DgnButtonEvent ev) { try { if (pointsCollection.Count != 0) { Create Line String with the selected elements coordinates Element element = createLineString(); } EndDynamics(); ExitTool(); } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } return true; } private Element createLineString() { double UorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster; DPoint3d[] ptArr = new DPoint3d[pointsCollection.Count]; for (int i = 0; i < pointsCollection.Count; i++) { ptArr[i] = new DPoint3d(pointsCollection[i].X, pointsCollection[i].Y, pointsCollection[1].Z); } LineStringElement ele = new LineStringElement(Session.Instance.GetActiveDgnModel(), null, ptArr); ElementPropertiesGetter elementPropertiesGetter = new ElementPropertiesGetter(ele); ElementPropertiesSetter eps = new ElementPropertiesSetter(); eps.SetColor(Convert.ToUInt32(_colorindex)); eps.SetWeight(Convert.ToUInt32(_lineweight)); eps.SetLinestyle(_linestyle, elementPropertiesGetter.LineStyle); eps.SetLevel(_levelId); eps.Apply(ele); ele.AddToModel(); return ele; } protected override void OnRestartTool() { //throw new NotImplementedException(); } public override StatusInt OnElementModify(Element element) { throw new NotImplementedException(); } public static void startProcess(int colorindex, string level, int linestyle, int lineweight, LevelId lvlId, int offset) { try { BMI.Utilities.ComApp.CommandState.StartPrimitive(new Template_Primitive_Event_Class()); PlaceMain placeMain = new PlaceMain(colorindex, level, linestyle, lineweight, lvlId, offset); placeMain.InstallTool(); } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } } } }
using Bentley.DgnPlatformNET; using Bentley.DgnPlatformNET.Elements; using Bentley.GeometryNET; using Bentley.MstnPlatformNET; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using BM = Bentley.MstnPlatformNET; using BIM = Bentley.Interop.MicroStationDGN; using Bentley.ECObjects.Units; using System.Runtime.InteropServices; namespace ProductionTools { public class PlaceMain : DgnElementSetTool { static BIM.Application app; private List<DPoint3d> pointsCollection; private List<DPoint3d> lastCollection; private string _level = string.Empty; private int _colorindex = 0; private int _linestyle = 0; private int _lineweight = 0; private LevelId _levelId; private int counter = 0; private static List<BIM.Element> elements; private int _offset = 0; private PlaceMain(int colorindex, string level, int linestyle, int lineweight, LevelId lvlId, int offset) : base(0, 0) //Subash Main Place { _level = level; _linestyle = linestyle; _lineweight = lineweight; _colorindex = colorindex; _levelId = lvlId; _offset = offset; pointsCollection = new List<DPoint3d>(); lastCollection = new List<DPoint3d>(); app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; } protected override bool OnDataButton(DgnButtonEvent ev) { try { HitPath hitPath = DoLocate(ev, true, 1); if (hitPath != null) { Element element = hitPath.GetHeadElement(); if (element != null) { if ((element.ElementType == MSElementType.LineString || element.ElementType == MSElementType.Line || element.ElementType == MSElementType.Arc)) { collectCoordinates(element); } } } } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } return true; } private void collectCoordinates(Element element) { try { if (element is LineElement flineelement) { CurveVector fcurveVector = CurvePathQuery.ElementToCurveVector(flineelement); DPoint3d startpoint; DPoint3d endpoint; fcurveVector.GetStartEnd(out startpoint, out endpoint); if (pointsCollection.Count == 0) { pointsCollection.Add(startpoint); pointsCollection.Add(endpoint); lastCollection.Add(startpoint); lastCollection.Add(endpoint); counter++; } else { double distance = lastCollection[0].Distance(startpoint); double distance1 = lastCollection[lastCollection.Count - 1].Distance(startpoint); double distance2 = lastCollection[0].Distance(endpoint); double distance3 = lastCollection[lastCollection.Count - 1].Distance(endpoint); if (counter == 1 && distance < distance1 && distance2 < distance3) pointsCollection.Reverse(); checkAndSetLines(startpoint, endpoint, distance, distance1, distance2, distance3); } } else if (element is LineStringElement flinestringelement) { List<DPoint3d> fpoints = new List<DPoint3d>(); CurveVector fcurveVector = CurvePathQuery.ElementToCurveVector(flinestringelement); fcurveVector.GetPrimitive(0).TryGetLineString(fpoints); if (pointsCollection.Count == 0) { foreach (var item in fpoints) { if (!pointsCollection.Contains(item)) { pointsCollection.Add(item); lastCollection.Add(item); } } counter++; } else { double distance = lastCollection[0].Distance(fpoints[0]); double distance1 = lastCollection[lastCollection.Count - 1].Distance(fpoints[0]); double distance2 = lastCollection[0].Distance(fpoints[fpoints.Count - 1]); double distance3 = lastCollection[lastCollection.Count - 1].Distance(fpoints[fpoints.Count - 1]); if (counter == 1 && distance < distance1 && distance2 < distance3) pointsCollection.Reverse(); checkAndSetLines1(fpoints, distance, distance1, distance2, distance3); } } else if (element is ArcElement curveelement) { } } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } } private void checkAndSetLines1(List<DPoint3d> fpoints, double distance, double distance1, double distance2, double distance3) { lastCollection.Clear(); List<double> dblValues = new List<double>(); List<double> dblValues1 = new List<double>(); dblValues.Add(distance); dblValues.Add(distance1); dblValues.Add(distance2); dblValues.Add(distance3); dblValues1.Add(distance); dblValues1.Add(distance1); dblValues1.Add(distance2); dblValues1.Add(distance3); dblValues.Sort(); double dblValue = dblValues[0]; int index = dblValues1.FindIndex(a => a == dblValue); if (index == 2 || index == 3) fpoints.Reverse(); foreach (var item in fpoints) { if (!pointsCollection.Contains(item)) { pointsCollection.Add(item); lastCollection.Add(item); } } counter++; } private void checkAndSetLines(DPoint3d startpoint, DPoint3d endpoint, double distance, double distance1, double distance2, double distance3) { lastCollection.Clear(); List<double> dblValues = new List<double>(); List<double> dblValues1 = new List<double>(); dblValues.Add(distance); dblValues.Add(distance1); dblValues.Add(distance2); dblValues.Add(distance3); dblValues1.Add(distance); dblValues1.Add(distance1); dblValues1.Add(distance2); dblValues1.Add(distance3); dblValues.Sort(); double dblValue = dblValues[0]; int index = dblValues1.FindIndex(a => a == dblValue); if (index == 2 || index == 3) { if (!pointsCollection.Contains(endpoint)) pointsCollection.Add(endpoint); if (!pointsCollection.Contains(startpoint)) pointsCollection.Add(startpoint); lastCollection.Add(endpoint); lastCollection.Add(startpoint); counter++; } else { if (!pointsCollection.Contains(startpoint)) pointsCollection.Add(startpoint); if (!pointsCollection.Contains(endpoint)) pointsCollection.Add(endpoint); lastCollection.Add(endpoint); lastCollection.Add(startpoint); counter++; } } protected override bool OnResetButton(DgnButtonEvent ev) { try { if (pointsCollection.Count != 0) { Create Line String with the selected elements coordinates Element element = createLineString(); } EndDynamics(); ExitTool(); } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } return true; } private Element createLineString() { double UorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster; DPoint3d[] ptArr = new DPoint3d[pointsCollection.Count]; for (int i = 0; i < pointsCollection.Count; i++) { ptArr[i] = new DPoint3d(pointsCollection[i].X, pointsCollection[i].Y, pointsCollection[1].Z); } LineStringElement ele = new LineStringElement(Session.Instance.GetActiveDgnModel(), null, ptArr); ElementPropertiesGetter elementPropertiesGetter = new ElementPropertiesGetter(ele); ElementPropertiesSetter eps = new ElementPropertiesSetter(); eps.SetColor(Convert.ToUInt32(_colorindex)); eps.SetWeight(Convert.ToUInt32(_lineweight)); eps.SetLinestyle(_linestyle, elementPropertiesGetter.LineStyle); eps.SetLevel(_levelId); eps.Apply(ele); ele.AddToModel(); return ele; } protected override void OnRestartTool() { //throw new NotImplementedException(); } public override StatusInt OnElementModify(Element element) { throw new NotImplementedException(); } public static void startProcess(int colorindex, string level, int linestyle, int lineweight, LevelId lvlId, int offset) { try { BMI.Utilities.ComApp.CommandState.StartPrimitive(new Template_Primitive_Event_Class()); PlaceMain placeMain = new PlaceMain(colorindex, level, linestyle, lineweight, lvlId, offset); placeMain.InstallTool(); } catch (Exception ex) { MessageBox.Show(ex.InnerException.ToString(), "Place Main Tool", MessageBoxButton.OK, MessageBoxImage.Error); } } } }
I recommend to split the topic into several new questions (posts), because the discussion is long and diverged from original topic.
manjula kamarajugadda said:2. Facing problem for arc cases to maintain the shape.
The formulation you use is confusing and I think without reading both document and discussion it's hard to understand the context.
In my opinion the right question is "How to linearize arc" and it leads to discussion about implementing Facet Curve functionality. I recommend to check ElementGraphicsProcessor (representing one from core functionality in MicroStation API) with FacetOptions settings,allowing to "facetize" any geometry.
Maybe CurvePrimitive provides similar functionality too.
These classes are explained in different SDK examples and often mentioned in discussions, so there is enough info available. When it is not enough, ask in the new post.
manjula kamarajugadda said:4. startProcess is called in Place button of UI click (Please find the attached image -- Main.png).
The discussion about the code itself and how to implement DgnElementSetTool in the right way would require another separate discussion (and maybe some training).
manjula kamarajugadda said:I need a small help in arc case, it will have only 3 coordinates and if I try to generate a line string then the shape is not maintained. I need few more points on the arc to maintain the shape
As Jan comments, you're adding more and more questions to your original post. That makes it hard to follow your thread.
Post a separate question about the arc conversion problem. The term you are looking for is 'stroke': you stroke a curve to obtain a set of lines that approximate that curve. In V8 MDL there is a function something like mdlElmdscr_stroke(); The CONNECT API provides, as Jan mentioned, the ElementGraphicsProcessor, which has facetizing options.
mdlElmdscr_stroke();
ElementGraphicsProcessor
Ask in a new post.