MultiCAD.NET: подсчет суммарной длины отрезков на чертеже

6863797343d547c9832314d6d8c4b90f.jpgК нам в техподдержку часто приходит вопрос: «Как посчитать суммы длин отрезков (участков трубопровода, элементов электрических схем и т.п.) в чертеже?». Существует масса способов решения этой задачи, в сегодняшней публикации мы рассмотрим реализацию приложения на MultiCAD.NET API, суммирующего длины, которое работает в nanoCAD, AutoCAD и ZWCAD. В качестве примера мы возьмем задачу определения суммарной длины труб в схеме водоснабжения и рассмотрим два варианта выбора элементов для подсчета: пользовательский и по созданному фильтру.

Прежде чем приступить к определению длины отрезка, необходимо определить, что же такое отрезок в MultiCAD.NET. Отрезок является стандартным примитивом наряду с окружностью, текстом, сплайном и др. Для представления отрезка в базе данных чертежа используется класс DBLine из пространства имен всех примитивов Multicad.DatabaseServices.StandardObjects.Объекты DBLine в качестве свойств содержат начальную и конечную точку, но не содержат информации о длине отрезка. Конечно, координат точек отрезка достаточно для вычисления его длины, но удобнее будет использовать его геометрическое представление — объект класса LineSeg3d (доступ к которому обеспечивает свойство DBLine.Line) и его свойство Length для получения длины:

double length = line.Line.Length; Итак, рассмотрим первый вариант приложения, когда пользователю предлагается самостоятельно выбрать отрезки для вычисления итогового значения длины. Для реализации пользовательского выбора объекта будет использоваться метод SelectObjects класса менеджера объектов McObjectManager: public static McObjectId[] SelectObjects (string sPromt); Метод выводит подсказку в консоль и позволяет пользователю самому выбирать объекты, ID выбранных объектов записываются в массив. Затем производится распознавание элементов массива, и для объектов, которые являются отрезками, получаем длину и инкрементируем результат. Общий вид команды, реализующий эту процедуру: 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); } Кроме отрезков прямых на чертежах используются полилинии, которые представляют собой совокупность отрезков и/или дуговых элементов. Получить длину полилинии можно аналогично, использую геометрическое представление примитива — класс Polyline3d через свойство Polyline: double length = polyline.Polyline.Length; На практике, когда чертеж содержит большое число элементов и требуется исключить ошибки пользовательского ввода, объекты могут быть выбраны автоматически, используя фильтр объектов. При создании фильтра указываются необходимые критерии: область выбора объектов (листы, слои, документы, область, и пр.) и типы объектов.Например, для того, чтобы выбрать все линии на конкретном слое используется фильтр с указанием имени слоя: ObjectFilter filter = ObjectFilter.Create (true); filter.AddLayer («Холодная вода»); filter.AddType (typeof (DbLine)); List ids = filter.GetObjects (); Наиболее часто встречающийся на практике пример применения автоматического подсчета суммарной длины линий — формирование отчета по типу труб на схеме водоснабжения.f031d6df0fe94e0f992509794fd90f53.png

В нашем примере схема трубопровода организована таким образом, что трубы каждого типа расположены на отдельных слоях: «Контур 1» и «Контур 2».Следующая команда формирует текстовый отчет с указанием всех типов труб, расположенных на отдельных слоях и их суммарной длины.

[CommandMethod («createReport», CommandFlags.NoCheck | CommandFlags.NoPrefix)] public void createReport () { List 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 (); } } Подсчет суммарной длины и заполнение строк отчета производится в методе getLengthSumByLayer (), код которого представлен ниже: public List getLengthSumByLayer () { List reportStrings = new List(); // Получаем все слои на чертеже List layers = McObjectManager.CurrentStyle.GetLayers (); foreach (string layerName in layers) { ObjectFilter filter = ObjectFilter.Create (true).AddType (typeof (DbLine)).AddType (typeof (DbPolyline)).AddLayer (layerName); List 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; } После выполнения данной команды на чертеж будет добавлен отчет вида:

e76a0a184ffc4420a65d1076159206ba.jpg

Подробную процедуру загрузки MultiCAD.NET приложений вы можете найти в нашей статье Пошаговый обзор: единое MultiCAD.NET приложение в nanoCAD, AutoCAD, ZWCAD

Обсудить статью можно также и на нашем форуме.

© Habrahabr.ru