Статьи > Тестирование статей
Части трубопроводной сети (трубы и колодцы) на виде профиля.
(1/1)
Дмитрий Загорулькин:
Оригинал статьи: http://adndevblog.typepad.com/infrastructure/2014/07/pipe-network-parts-on-profile-view.html
На виде профиля, после добавления на него части трубопроводной сети (колодца или трубы), Civil 3D создает новый объект: ProfileViewPart. У этого объекта не много методов, но зато он является объектом базы данных чертежа (с ID и геометрией).
Итак, вопрос: как получить пикетаж и отметку части на виде профиля?
Используя габаритный контейнер части, мы можем получить доступ к координатам XY в модели. Тогда возможно получить среднюю точку (или какую-нибудь другую точку, например с максимальной и минимальной координатой Y). Используя эти координаты XY, мы можем вернуться обратно на вид профиля и запросить пикетаж и отметку для этой точки.
Пример кода ниже демонстрирует эту идею:
--- Код - C# [Выбрать] ---// выбор части сети на виде профиляEditor ed = Application.DocumentManager.MdiActiveDocument.Editor;PromptEntityOptions peo = new PromptEntityOptions( "\nВыберите часть сети на виде профиля: ");peo.SetRejectMessage("\nТолько части сети на виде профиля!");peo.AddAllowedClass(typeof(ProfileViewPart), true);PromptEntityResult per = ed.GetEntity(peo);if (per.Status != PromptStatus.OK) return; Database db = Application.DocumentManager.MdiActiveDocument.Database;using (Transaction trans = db.TransactionManager.StartTransaction()){ // получение части сети, отображенной на виде профиля ProfileViewPart partPV = trans.GetObject(per.ObjectId, OpenMode.ForRead) as ProfileViewPart; Part part = trans.GetObject(partPV.ModelPartId, OpenMode.ForRead) as Part; // может иметься несколько видов профилей, отображающих эту часть... ObjectIdCollection pvIds = part.GetProfileViewsDisplayingMe(); foreach (ObjectId pvId in pvIds) { // получаем среднюю точку этого колодца на виде профиля (зам. пер. – это может быть и труба) // вы можете изменить эти координаты X,Y для максимальных или минимальных значений... Extents3d ext = partPV.GeometricExtents; double x = (ext.MaxPoint.X - ext.MinPoint.X) / 2 + ext.MinPoint.X; double y = (ext.MaxPoint.Y - ext.MinPoint.Y) / 2 + ext.MinPoint.Y; // получение вида профиля ProfileView pv = trans.GetObject(pvId, OpenMode.ForRead) as ProfileView; // и пикетаж с отметкой на виде профиля double station = 0.0; double elevation = 0.0; pv.FindStationAndElevationAtXY(x, y, ref station, ref elevation); ed.WriteMessage( "\n{0} отображается на виде профиля {1} на пикете: {2:0.00} | Отметка: {3:0.00}", part.Name, pv.Name, station, elevation); }}
Александр Ривилис:
Опубликовал на сайте: Части трубопроводной сети (трубы и колодцы) на виде профиля
Дмитрий Загорулькин:
В результате проверки работы кода, обнаружилось, что в алгоритме имеется ошибка. Автор кода учел, что часть может отображаться на нескольких видах профилей. Однако, в этом случае, габаритный контейнер для части на виде профиля будет вычисляться охватыванием всех отображений части на всех видах профилей, т.к. это не несколько разных объектов, а один! Координаты габаритного контейнера получаются несколько иными, чем ожидается, и практического смысла от них мало. Подробно я показал это на видео: https://screencast.autodesk.com/main/details/4fba5135-8cd6-4949-988d-e3e6c239d99c.
В общем-то, использование габаритного контейнера для получения точек части сети на виде профиля – это довольно грубый способ. В конце-концов, это же BIM-продукт! Мы имеем дело с интеллектуальными объектами! Почему бы не получать нужные свойства напрямую? Приведенный ниже код использует как раз такой, цивилизованный подход:
--- Код - C# [Выбрать] ---// выбор части сети на виде профиляEditor ed = Application.DocumentManager.MdiActiveDocument.Editor;PromptEntityOptions peo = new PromptEntityOptions( "\nВыберите часть сети на виде профиля: ");peo.SetRejectMessage("\nТолько части сети на виде профиля!");peo.AddAllowedClass(typeof(ProfileViewPart), true);PromptEntityResult per = ed.GetEntity(peo);if (per.Status != PromptStatus.OK) return; Database db = Application.DocumentManager.MdiActiveDocument.Database;using (Transaction trans = db.TransactionManager.StartTransaction()){ // получение части сети, отображенной на виде профиля ProfileViewPart partPV = trans.GetObject(per.ObjectId, OpenMode.ForRead) as ProfileViewPart; Part part = trans.GetObject(partPV.ModelPartId, OpenMode.ForRead) as Part; // может иметься несколько видов профилей, отображающих эту часть... ObjectIdCollection pvIds = part.GetProfileViewsDisplayingMe(); foreach (ObjectId pvId in pvIds) { // получение вида профиля ProfileView pv = trans.GetObject(pvId, OpenMode.ForRead) as ProfileView; // получение трассы вида профиля Alignment align = trans.GetObject(pv.AlignmentId, OpenMode.ForRead) as Alignment; // если объект - колодец if (part is Structure) { // получение колодца Structure structure = part as Structure; // получение точки вставки колодца в модели Point3d strLoc = structure.Location; // получение пикетажа колодца по трассе вида профиля // как побочные данные, будет получено еще смещение // колодца от трассы вида профиля в плане double station = 0.0, offset = 0.0; align.StationOffset(strLoc.X, strLoc.Y, ref station, ref offset); // вывод сообщения о положении колодца ed.WriteMessage( "\nКолодец '{0}' отображается на виде профиля '{1}' на пикете: {2:0.00}", part.Name, pv.Name, station); // если колодец соединительный - вывод отметки его крышки и дна if (structure.PartType == PartType.StructJunction) { ed.WriteMessage ("\nОтметка крышки колодца: {0:0.00}, дна: {1:0.00}", structure.RimElevation, structure.SumpElevation); } } // если объект - труба else if (part is Pipe) { // получение трубы Pipe pipe = part as Pipe; // ... и ее начальной и конечной точек (на оси трубы) Point3d startPt = pipe.StartPoint, endPt = pipe.EndPoint; // получение пикетажей и смещений начальной и конечной точек double startStation = 0.0, startOffset = 0.0, endStation = 0.0, endOffset = 0.0; align.StationOffset(startPt.X, startPt.Y, ref startStation, ref startOffset); align.StationOffset(endPt.X, endPt.Y, ref endStation, ref endOffset); // вывод значения пикетажей и отметок начальной и конечной точек ed.WriteMessage( "\nТруба '{0}' отображается на виде профиля '{1}'." + "\nНачало - пикет: {2:0.00}, отметка: {3:0.00}" + "\nКонец - пикет: {4:0.00}, отметка: {5:0.00}", part.Name, pv.Name, startStation, startPt.Z, endStation, endPt.Z); } }}
Александр Ривилис:
Отлично! Я исправил статью на сайте согласно с твоими исправлениям и дополнениями.
Навигация
Перейти к полной версии