Как получить имя семейства трубы?

Автор Тема: Как получить имя семейства трубы?  (Прочитано 14691 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн DoublefishАвтор темы

  • ADN Club
  • ****
  • Сообщений: 288
  • Карма: 10
  • AutoCAD Civil 3D
Добрый день

подскажите пожалуйста

дано id трубы - как узнать имя семейства этой трубы?

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Как получить имя семейства трубы?
« Ответ #1 : 11-06-2014, 09:03:19 »
С помощью NET API - никак. По крайней мере, так было в версии 2013. Я уже выяснял этот вопрос в ADN.
Вроде пока ничего не изменилось.
Как обходной путь - семейство можно получить с помощью COM API.

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2.  
  3. using Autodesk.Civil.DatabaseServices;
  4.  
  5. using Autodesk.AutoCAD.Interop;
  6. using Autodesk.AECC.Interop.Land;
  7. using Autodesk.AECC.Interop.UiLand;
  8. using Autodesk.AECC.Interop.Pipe;
  9.  
  10. namespace Support
  11. {
  12.     public static class NetworkSupport
  13.     {
  14.         /// <summary>
  15.         /// Получение имени семейства элементов для колодца при помощи COM
  16.         /// </summary>
  17.         /// <param name="structure">Колодец, объект типа Autodesk.Civil.DatabaseServices.Structure</param>
  18.         /// <returns>Строка - имя семейства элементов из каталога для указанного колодца</returns>
  19.         public static string GetStructureFamilyCOM(this Structure structure)
  20.         {
  21.             try
  22.             {
  23.                 IAeccStructure structCOM = (IAeccStructure)structure.AcadObject;
  24.                 IAeccPartFamily partFamCOM = structCOM.PartFamily;
  25.                 return partFamCOM.Name;
  26.             }
  27.             catch
  28.             {
  29.                 Application.ShowAlertDialog(string.Format("Ошибка получения данных о семействе колодца {0}", structure.Name));
  30.                 return null;
  31.             }
  32.         }
  33.     }
  34. }
  35.  
« Последнее редактирование: 11-06-2014, 09:20:53 от Загорулькин Дмитрий »

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Как получить имя семейства трубы?
« Ответ #2 : 11-06-2014, 17:05:19 »
Надеюсь, проблем с подключением COM библиотек и адаптацией кода под трубы (ID труб) нет? :)

Оффлайн DoublefishАвтор темы

  • ADN Club
  • ****
  • Сообщений: 288
  • Карма: 10
  • AutoCAD Civil 3D
Re: Как получить имя семейства трубы?
« Ответ #3 : 16-06-2014, 07:55:51 »
Работает  :)

Оффлайн German

  • ADN Club
  • **
  • Сообщений: 84
  • Карма: 13
Re: Как получить имя семейства трубы?
« Ответ #4 : 24-06-2014, 10:09:08 »
С помощью NET API - никак. По крайней мере, так было в версии 2013. Я уже выяснял этот вопрос в ADN.
Вроде пока ничего не изменилось.
Как обходной путь - семейство можно получить с помощью COM API.
Если я правильно понял, можно и без COM: http://forums.autodesk.com/t5/AutoCAD-Civil-3D-Customization/Finding-out-which-Part-Family-the-pipe-is-from/m-p/3645320#M6716

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как получить имя семейства трубы?
« Ответ #5 : 24-06-2014, 11:35:31 »
Если я правильно понял, можно и без COM: http://forums.autodesk.com/t5/AutoCAD-Civil-3D-Customization/Finding-out-which-Part-Family-the-pipe-is-from/m-p/3645320#M6716
Нет. Ты неправильно понял. Используется всё-равно ActiveX/COM, но благодаря позднему связыванию (Reflection) нет необходимости подключать COM-Interop сборки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн German

  • ADN Club
  • **
  • Сообщений: 84
  • Карма: 13
Re: Как получить имя семейства трубы?
« Ответ #6 : 24-06-2014, 13:42:17 »
Нет. Ты неправильно понял. Используется всё-равно ActiveX/COM, но благодаря позднему связыванию (Reflection) нет необходимости подключать COM-Interop сборки.
Александр, спасибо.
Подскажите, а вот такой метод возможно аналогично "обернуть" или нет: AddFromPolyline ?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как получить имя семейства трубы?
« Ответ #7 : 24-06-2014, 13:59:55 »
Подскажите, а вот такой метод возможно аналогично "обернуть" или нет: AddFromPolyline ?
Теоретически возможно, но я такое не напишу. Так что пользуйся ранним связыванием. :)
P.S.: Вообще-то можно попробовать через dynamic
Кажется он появился в .NET 4.0
« Последнее редактирование: 24-06-2014, 14:57:16 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Как получить имя семейства трубы?
« Ответ #8 : 25-06-2014, 12:30:11 »
А я правильно понимаю, что используя позднее связывание вместо подключения COM библиотек, мы теряем в скорости работы программы?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как получить имя семейства трубы?
« Ответ #9 : 25-06-2014, 12:57:19 »
В принципе да. Но реальные потери зависят от того, насколько это массовая операция, т.е. она выполняется один раз, десять или десять миллионов...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Как получить имя семейства трубы?
« Ответ #10 : 25-06-2014, 13:10:22 »
Ну если речь идет о сетях, то объектов в одном чертеже может быть несколько сотен максимум. Другое дело, что COM свойства и методы приходится использовать с завидной регулярностью... Навскидку, операций может набежать несколько тысяч: получение свойств каждого объекта, плюс какие-то методы, пока не реализованные в NET. Наверное, в этом случае стоит думать о сокращении времени работы отдельных методов? :)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как получить имя семейства трубы?
« Ответ #11 : 25-06-2014, 13:15:26 »
Есть способ, который позволяет ускорить выполнение Reflection - Expression. Пример его использования: http://www.theswamp.org/index.php?topic=44191.msg494532#msg494532
Но насколько будет выигрыш я предугадать не берусь - нужно тестировать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Как получить имя семейства трубы?
« Ответ #12 : 17-01-2017, 17:03:27 »
Как обходной путь - семейство можно получить с помощью COM API.
Вот же засада! Если попытаться получить имя семейства в событиях Database.ObjectOpenedForModify или Database.ObjectModified - возникает исключение, и имя семейства никак не получить. Вот как проверить, изменилось ли у элемента семейство или нет? Самое здравое - это смотреть исходное состояние в Database.ObjectOpenedForModify и сравнивать с состоянием в Database.ObjectModified. Но в этом случае такой подход никак не хочет работать!
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.Civil.DatabaseServices;
  5. using Autodesk.AECC.Interop.Pipe;
  6.  
  7. namespace CivilTest
  8. {
  9.     public class FamilySizeTest
  10.     {
  11.         [CommandMethod("RunComTest", CommandFlags.Modal | CommandFlags.NoBlockEditor)]
  12.         public void Run()
  13.         {
  14.             Document adoc = Application.DocumentManager.MdiActiveDocument;
  15.             Database db = adoc.Database;
  16.            
  17.             db.ObjectOpenedForModify -= Db_ObjectOpMod;
  18.             db.ObjectModified -= Db_ObjectMod;
  19.             db.ObjectOpenedForModify += Db_ObjectOpMod;
  20.             db.ObjectModified += Db_ObjectMod;
  21.         }
  22.  
  23.         [CommandMethod("StopComTest", CommandFlags.Modal | CommandFlags.NoBlockEditor)]
  24.         public void Stop()
  25.         {
  26.             Document adoc = Application.DocumentManager.MdiActiveDocument;
  27.             Database db = adoc.Database;
  28.  
  29.             db.ObjectOpenedForModify -= Db_ObjectOpMod;
  30.             db.ObjectModified -= Db_ObjectMod;
  31.         }
  32.  
  33.         private void Db_ObjectOpMod(object sender, ObjectEventArgs e)
  34.         {
  35.             if (e.DBObject is Part)
  36.             {
  37.                 string famName = GetPartFamilyName(e.DBObject as Part);
  38.                 Application.ShowAlertDialog("Part opened for modify. Part family: " + famName);
  39.             }
  40.         }
  41.  
  42.         private void Db_ObjectMod(object sender, ObjectEventArgs e)
  43.         {
  44.             if (e.DBObject is Part)
  45.             {
  46.                 string famName = GetPartFamilyName(e.DBObject as Part);
  47.                 Application.ShowAlertDialog("Part modified. Part family: " + famName);
  48.             }
  49.         }
  50.  
  51.         string GetPartFamilyName(Part part)
  52.         {
  53.             string ret;      
  54.             try
  55.             {      
  56.                 IAeccPipeNetworkPart partCom = (IAeccPipeNetworkPart)part.AcadObject;
  57.                 IAeccPartFamily partFamilyCom = (IAeccPartFamily)partCom.PartFamily;
  58.                 ret = partFamilyCom.Name;
  59.             }
  60.             catch
  61.             {
  62.                 ret = "*ERROR*";
  63.             }            
  64.             return ret;
  65.         }
  66.     }
  67. }
  68.  

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как получить имя семейства трубы?
« Ответ #13 : 17-01-2017, 17:22:47 »
Интересно, а через DXF добраться до PartFamily нельзя?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Как получить имя семейства трубы?
« Ответ #14 : 17-01-2017, 17:28:12 »
Похоже, что нет  :(.
Я проверил и в ARXDBG и в MGDDBG - у элемента нет никаких ссылок на семейство.
Уже весь мозг себе сломал пытаясь найти выход.