📜 ⬆️ ⬇️

MultiCAD.NET: calculation of the total length of the segments in the drawing



A question often comes to us in tech support: “How to calculate the sum of the lengths of segments (pipeline sections, elements of electrical circuits, etc.) in a drawing?”. There are plenty of ways to solve this problem, in today's publication we will look at the application implementation on the MultiCAD.NET API, the summing length, which works in nanoCAD, AutoCAD and ZWCAD. As an example, we will take the task of determining the total length of pipes in the water supply scheme and consider two options for choosing the elements to be counted: user-defined and according to the created filter.

Determining the sum of user-selected line lengths


Before proceeding to determine the length of the segment, it is necessary to determine what is a segment in MultiCAD.NET. The segment is a standard primitive along with a circle, text, spline, etc. To represent a segment in a drawing database, use the DbLine class from the namespace of all the primitives Multicad.DatabaseServices.StandardObjects .
')
DbLine objects as properties contain a start and end point, but do not contain information about the length of the segment. Of course, the coordinates of the points of the segment are enough to calculate its length, but it will be more convenient to use its geometric representation — an object of the class LineSeg3d (accessed by the DbLine.Line property) and its Length property to get the length:

 double length = line.Line.Length; 

So, we will consider the first version of the application, when the user is asked to independently select segments for calculating the total length value. To implement custom object selection, the SelectObjects method of the SelectObjects object manager class will be used:

 public static McObjectId[] SelectObjects(string sPromt); 

The method displays a tooltip in the console and allows the user to select objects himself, the IDs of the selected objects are written into an array. Then the array elements are recognized, and for objects that are segments, we obtain the length and increment the result. General view of the command that implements this procedure:

 CommandMethod("LineLengthSum", CommandFlags.NoCheck | CommandFlags.NoPrefix)] public void LineLengthSum() { //      McObjectId[] idSelecteds = McObjectManager.SelectObjects("   "); if (idSelecteds.Length == 0) { MessageBox.Show("  "); return; } double lengthSum = 0; foreach (McObjectId currID in idSelecteds) { //    ID McObject currObj = currID.GetObject(); //    if (currObj is DbLine) { lengthSum += (currObj as DbLine).Line.Length; } } MessageBox.Show(lengthSum.ToString(), "   :", MessageBoxButtons.OK, MessageBoxIcon.Information); } 

In addition to the straight line segments in the drawings, polylines are used, which are a combination of segments and / or arc elements. You can get the length of a polyline in the same way, using the geometric representation of the primitive - the Polyline3d class through the Polyline property:

 double length = polyline.Polyline.Length; 

Automatic calculation of the total length of lines


In practice, when a drawing contains a large number of elements and you want to eliminate user input errors, objects can be selected automatically using an object filter. When creating a filter, the necessary criteria are specified: the selection area of ​​the objects (sheets, layers, documents, area, etc.) and the types of objects.
For example, in order to select all the lines on a specific layer, a filter with the name of the layer is used:

 ObjectFilter filter = ObjectFilter.Create(true); filter.AddLayer(" "); filter.AddType(typeof(DbLine)); List<McObjectId> ids = filter.GetObjects(); 

The most common practice in practice is the application of the automatic calculation of the total length of lines - the formation of a report on the type of pipes in the water supply scheme.



In our example, the pipeline scheme is organized in such a way that the pipes of each type are located on separate layers: “Contour 1” and “Contour 2”.
The following command forms a text report with an indication of all types of pipes located on separate layers and their total length.

 [CommandMethod("createReport", CommandFlags.NoCheck | CommandFlags.NoPrefix)] public void createReport() { List<String> reportStrings = getLengthSumByLayer(); if (reportStrings.Count == 0) { MessageBox.Show("      "); return; } //      int indent = 0; //   DbText caption = new DbText(); caption.Text = new TextGeom("   ", new Point3d(0, indent, 0), Vector3d.XAxis, "Standard", 10); caption.DbEntity.AddToCurrentDocument(); foreach (String str in reportStrings) { indent -= 10; DbText reportText = new DbText(); reportText.Text = new TextGeom(str, new Point3d(0, indent, 0), Vector3d.XAxis, "Standard", 6); reportText.DbEntity.AddToCurrentDocument(); } } 

The calculation of the total length and filling in the rows of the report is done in the getLengthSumByLayer() method, the code of which is presented below:

 public List<String> getLengthSumByLayer() { List<String> reportStrings = new List<String>(); //      List<string> layers = McObjectManager.CurrentStyle.GetLayers(); foreach (string layerName in layers) { ObjectFilter filter = ObjectFilter.Create(true).AddType(typeof(DbLine)).AddType(typeof(DbPolyline)).AddLayer(layerName); List<McObjectId> idSelected = filter.GetObjects(); if (idSelected.Count != 0) { double lengthSum = 0; foreach (McObjectId currID in idSelected) { //    ID McObject currObj = currID.GetObject(); //    if (currObj is DbLine) { lengthSum += (currObj as DbLine).Line.Length; } else if (currObj is DbPolyline) { lengthSum += (currObj as DbPolyline).Polyline.Length; } } //         ,      if (lengthSum != 0) { reportStrings.Add(layerName.ToString() + ": " + lengthSum.ToString()); } } } return reportStrings; } 


After this command is executed, a report will be added to the drawing:



A detailed procedure for downloading MultiCAD.NET applications can be found in our article Step-by-step overview: a single MultiCAD.NET application in nanoCAD, AutoCAD, ZWCAD .

You can also discuss the article on our forum .
Translation of the article into English: MultiCAD.NET: Calculating the total length of lines .

Source: https://habr.com/ru/post/246511/


All Articles