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

20/09/2015

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

Иногда нужно получить данные о семействе и типоразмере трубы или колодца, которые уже присутствуют на чертеже. Например - чтобы создать такой же элемент в другом месте сети. Метод создания трубы или колодца в сети требует указания 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. )

Однако в Civil 3D .NET API 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. }

Автор: Дмитрий Загорулькин

Обсуждение: http://adn-cis.org/forum/index.php?topic=3032

Опубликовано 20.09.2015