Сообщество программистов Autodesk в СНГ

ADN Club => Civil 3D API => Тема начата: Кирилл Захаров от 01-09-2017, 14:32:30

Название: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 14:32:30
Здравствуйте!

Я пишу программу, которая разбивает объекты Civil 3D. В том случае, если эти объекты разбиваются в обычном AutoCAD (при наличии Object Enabler), то все работает с помощью стандартной функции Explode.
Код - C# [Выбрать]
  1.  DBObjectCollection objs = new DBObjectCollection();
  2. ent.Explode(objs);
  3. foreach (DBObject item in objs)
  4. {
  5.     Entity explEnt = item as Entity;
  6.     ObjectId explId = modelBtr.AppendEntity(explEnt);
  7.     tr.AddNewlyCreatedDBObject(explEnt, true);
  8. }
  9.  
Но, когда я запускаю свою программу в Civil 3D, при разбиении некоторых объектов, в выходную коллекцию objs тянутся лишние объекты. Например, для объектов типа Autodesk.Civil.DatabaseServices.Alignment (ось) тянутся виды продольных профилей, а для объектов Autodesk.Civil.DatabaseServices.SampleLine (ось сечения) - виды поперечных профилей.

Частично я нашел решение - для Alignment можно использовать метод GetPolyline, но как решить эту же проблему для SampleLine я пока не понял. Привожу код тестовой команды (основную суть смотри со строки 40):
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6.  
  7. // This line is not mandatory, but improves loading performances
  8. [assembly: CommandClass(typeof(CivilObjExplodeTest.MyCommands))]
  9.  
  10. namespace CivilObjExplodeTest
  11. {
  12.  
  13.     public class MyCommands
  14.     {
  15.         // Modal Command with localized name
  16.         [CommandMethod("MyGroup", "MyCommand", "MyCommandLocal", CommandFlags.Modal)]
  17.         public void MyCommand() // This method can have any name
  18.         {
  19.  
  20.             Document adoc = Application.DocumentManager.MdiActiveDocument;
  21.             if (adoc == null) return;
  22.  
  23.             Database db = adoc.Database;
  24.  
  25.             Editor ed = adoc.Editor;
  26.  
  27.             PromptEntityOptions peo = new PromptEntityOptions("\nУкажите объекты:");
  28.             PromptEntityResult per = ed.GetEntity(peo);
  29.             if (per.Status == PromptStatus.OK)
  30.             {
  31.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  32.                 {
  33.                     BlockTableRecord modelBtr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
  34.  
  35.  
  36.                     Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
  37.                     Type t = ent.GetType();
  38.                     ed.WriteMessage(t.ToString());
  39.  
  40.  
  41.                     if (t.ToString().Equals("Autodesk.Civil.DatabaseServices.Alignment"))
  42.                     {
  43.                         ObjectId idPoly = (ObjectId)t.GetMethod("GetPolyline").Invoke(ent, null);
  44.  
                        Entity entPoly = tr.GetObject(idPoly, OpenMode.ForRead) as Entity;

                        Entity copy = entPoly.Clone() as Entity;
                        modelBtr.AppendEntity(copy);
                        tr.AddNewlyCreatedDBObject(copy, true);

Код - C# [Выбрать]
  1.                     }
  2.                     else if (t.ToString().Equals("Autodesk.Civil.DatabaseServices.SampleLine"))
  3.                     {
  4.                         //???????
  5.                     }
  6.  
  7.  
  8.                     tr.Commit();
  9.                 }
  10.  
  11.             }
  12.         }
  13.  
  14.     }
  15.  
  16. }
  17.  

Подскажите, пожалуйста, как решить эту проблему для объекта SampleLine и какие еще типы объектов при разбиении могут тянуть за собой что-то лишнее?
Название: Re: Разбиение объектов Civil 3D
Отправлено: Александр Ривилис от 01-09-2017, 14:43:22
Для SampleLine ты можешь получить его вершины при помощи метода SampleLine.Vertices и самостоятельно построить по ним полилинию.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Дмитрий Загорулькин от 01-09-2017, 14:44:47
Но, когда я запускаю свою программу в Civil 3D, при разбиении некоторых объектов, в выходную коллекцию objs тянутся лишние объекты. Например, для объектов типа Autodesk.Civil.DatabaseServices.Alignment (ось) тянутся виды продольных профилей, а для объектов Autodesk.Civil.DatabaseServices.SampleLine (ось сечения) - виды поперечных профилей.
Надо же! Не знал такой особенности. Надо будет проверить.
Alignment - это не ось, а трасса.
Цитировать
Подскажите, пожалуйста, как решить эту проблему для объекта SampleLine
Александр Наумович опередил :)
Цитировать
и какие еще типы объектов при разбиении могут тянуть за собой что-то лишнее?
Чисто теоретически - все графические объекты Civil 3D. Тут только опытным путём можно обнаружить такое.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 14:45:53
Спасибо большое!
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 14:49:22
Надо же! Не знал такой особенности. Надо будет проверить.
В Civil 3D 2016 и 2017 наблюдаю такое.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Дмитрий Загорулькин от 01-09-2017, 14:55:44
При взрыве объекта Civil 3D создаётся анонимный блок. Для трассы и зависимых видов профилей создаётся общий блок или несколько?
Есть какой-то минимальный пример кода?
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 15:10:33
Создается несколько блоков.
Пример кода - просто использовать метод Explode, как у меня в первом сообщении в этой теме.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Дмитрий Загорулькин от 01-09-2017, 15:17:15
Создается несколько блоков.
Скорее всего, в первом - геометрия трассы, в остальных - связанных объектов. Попробуйте первый оставить, остальные удалить.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 15:25:02
Скорее всего, в первом - геометрия трассы, в остальных - связанных объектов. Попробуйте первый оставить, остальные удалить.
Да, об этом я не подумал. Сейчас проверю.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 15:58:20
Вы правы, Дмитрий, спасибо.
Только не первый объект, а последний.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 15:59:27
Думаю все-таки предпочтительнее использовать соответствующие методы Civil. Это должно быть быстрее.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Дмитрий Загорулькин от 01-09-2017, 16:17:31
Только не первый объект, а последний.
Отлично! Буду знать, спасибо :)
Думаю все-таки предпочтительнее использовать соответствующие методы Civil. Это должно быть быстрее.
Да, скорее всего, быстрее будет код работать. Но полилиния, получаемая через Alignment.GetPolyline наследует настройки отображения трассы? Что-то сомневаюсь, учитывая, что у трассы, к примеру, дуговые и прямые участки могут по-разному отображаться. То же самое касается и оси сечения - создаваемой по её вершинам полилинии нужно задать свойства из стиля отображения оси сечения, хотя в этом случае каких-то особых проблем быть не должно. Разумеется, это важно только в случае, когда визуальное отображение должно сохраняться.
Кстати, а метод Alignment.GetPolyline разве не создаёт новую полилинию? Это, по идее, должен быть новый объект и можно использовать его, а не клон.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 16:27:36
Кстати, а метод Alignment.GetPolyline разве не создаёт новую полилинию? Это, по идее, должен быть новый объект и можно использовать его, а не клон.
Точно. Я чего-то не сообразил.

Спасибо за ваши замечания.
Название: Re: Разбиение объектов Civil 3D
Отправлено: Александр Ривилис от 01-09-2017, 16:28:49
Спасибо за ваши замечания.
Про плюсики не забывай!  :)
Название: Re: Разбиение объектов Civil 3D
Отправлено: Кирилл Захаров от 01-09-2017, 16:29:19
Обижаете, Александр)
Я поставил плюсики на все важные сообщения)
Кажется...