Civil 3D. Получение данных о семействе и типоразмере части трубопроводной сети.

Автор Тема: Civil 3D. Получение данных о семействе и типоразмере части трубопроводной сети.  (Прочитано 1281 раз)

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

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

  • ADN
  • *
  • Сообщений: 1612
  • Карма: 372
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Иногда нужно получить данные о семействе и типоразмере трубы или колодца, которые уже присутствуют на чертеже. Например - чтобы создать такую же часть в другом месте сети. Метод создания трубы или колодца в сети требует указания ObjectId для семейства и типоразмера (из справки):
Network.AddStructure Method (ObjectId, ObjectId, Point3d, Double, ObjectId, Boolean):
Код - C# [Выбрать]
  1. public void AddStructure(
  2.         ObjectId structureFamilyId,
  3.         ObjectId structureSizeId,
  4.         Point3d location,
  5.         double rotation,
  6.         ref ObjectId newStructureId,
  7.         bool applyRules
  8. )
Network.AddLinePipe Method:
Код - C# [Выбрать]
  1. public void AddLinePipe(
  2.         ObjectId pipeFamilyId,
  3.         ObjectId pipeSizeId,
  4.         LineSegment3d line,
  5.         ref ObjectId newPipeId,
  6.         bool applyRules
  7. )
Однако в NET API Civil 3D 2013-2016 нет таких свойств у части, как FamilyId и PartSizeId. Более того, если название типоразмера мы еще можем получить из свойства PartSizeName, то о семействе части в NET API вообще нет никаких данных! Поэтому, это один из тех нередких случаев, когда мы вынуждены использовать COM API. Решение этой задачи в виде кода представлено ниже:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Получение данных о семействе и типоразмере части сети
  3. /// </summary>
  4. /// <param name="part">Часть сети - труба или колодец</param>
  5. /// <param name="familyId">Выходной параметр - Id семейства части</param>
  6. /// <param name="familyName">Выходной параметр - название семейства части</param>
  7. /// <param name="sizeId">Выходной параметр - Id типоразмера части</param>
  8. /// <param name="sizeName">Выходной параметр - название типоразмера части</param>
  9. public static void GetPartFamilyAndSize
  10.     (this Part part,
  11.     out ObjectId familyId,
  12.     out string familyName,
  13.     out ObjectId sizeId,
  14.     out string sizeName)
  15. {
  16.     familyId = ObjectId.Null;
  17.     sizeId = ObjectId.Null;
  18.  
  19.     // Получаем COM-объект для части
  20.     dynamic partCOM = part.AcadObject;
  21.  
  22.     // Получаем из свойств COM-объекта названия семейства          
  23.     familyName = partCOM.PartFamily.Name;
  24.  
  25.     // Получаем название типоразмера из свойства COM-объекта
  26.     sizeName = partCOM.PartSizeName;
  27.  
  28.     // Можно получить название типоразмера из свойства NET-объекта
  29.     // sizeName = part.PartSizeName;
  30.  
  31.     // Запускаем эмуляцию транзакции
  32.     using (OpenCloseTransaction ocTr = part.Database.TransactionManager.StartOpenCloseTransaction())
  33.     {
  34.         // Получаем сеть части
  35.         Network net = ocTr.GetObject(part.NetworkId, OpenMode.ForRead) as Network;
  36.         // ... и ее список элементов
  37.         PartsList partsList = ocTr.GetObject(net.PartsListId, OpenMode.ForRead) as PartsList;
  38.         // Проходим по коллекции семейств домена части в списке элементов
  39.         foreach (ObjectId curFamilyId in partsList.GetPartFamilyIdsByDomain(part.Domain))
  40.         {
  41.             // Получаем семейство элементов
  42.             PartFamily partFam = ocTr.GetObject(curFamilyId, OpenMode.ForRead) as PartFamily;
  43.             // Если название семейства совпадает с названием семейства части
  44.             if (partFam.Name.Equals(familyName))
  45.             {
  46.                 // Сохраняем его идентификатор в переменной
  47.                 familyId = curFamilyId;
  48.                 // Проходим по типоразмерам элементов в семействе
  49.                 for (int i = 0; i < partFam.PartSizeCount; i++)
  50.                 {
  51.                     ObjectId famSizeId = partFam[i];
  52.                     // Получаем объект описания типоразмера
  53.                     PartSize partSize = ocTr.GetObject(famSizeId, OpenMode.ForRead) as PartSize;
  54.                     // Если его название совпадает с названием типоразмера части
  55.                     if (partSize.Name.Equals(sizeName))
  56.                     {
  57.                         // Сохраняем его идентификатор в переменной
  58.                         sizeId = famSizeId;
  59.                         // Мы нашли нужный типоразмер - прерываем
  60.                         // цикл прохода по типоразмерам семейства
  61.                         break;
  62.                     }
  63.                 }
  64.                 // Мы нашли нужное семейство - перываем
  65.                 // цикл прохода по семействам в списке
  66.                 break;
  67.             }
  68.         }
  69.         ocTr.Commit();
  70.     }
  71. }
  72.  

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

  • Administrator
  • *****
  • Сообщений: 8165
  • Карма: 978
  • Рыцарь ObjectARX
  • Skype: rivilis
Отлично! Я позволил себе немного подправить терминологию, чтобы она совпадала с официальной от Autodesk и опубликовал статью на нашем сайте: Получение данных о семействе и типоразмере элемента трубопроводной сети
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение