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

26/01/2014

Создание трубы с помощью метода Pipe.Create

В статье создание наклонного сегмента между двумя трубами Джереми столкнулся с проблемой создания трубы с помощью метода Pipe.Create.

Статический метод Pipe.Create появился в Revit API 2014 на замену методу Document.Create.NewPipe.

Метод принимает следующие параметры:

  • document. Проект, в котором нужно создать трубу.
  • systemTypeId. Идентификатор типа системы.
  • pipeTypeId. Идентификатор типа трубы.
  • levelId. Идентификатор уровня, на котором нужно создать трубу.
  • firstPoint. Координаты начала трубы
  • secondPoint. Координаты окончания трубы.

Как описывает Джереми, какое бы значение параметра systemTypeId он не передавал, всегда возникает ошибка: "The systemTypeId is not valid piping system type. Parameter name: systemTypeId" («Параметр systemTypeId не является подходящей системой для труб»)

Взглянем на код Джереми:

Код - C#: [Выделить]
  1.             ElementId idSystem = pipe.MEPSystem.Id; // invalid
  2.             ElementId idType = pipe.PipeType.Id;
  3.             ElementId idLevel = pipe.LevelId;
  4.             idSysem = ElementId.InvalidElementId; // invalid
  5.             PipingSystem system = PipingSystem.Create(
  6.               doc, pipe.MEPSystem.GetTypeId(), "Tbc" );
  7.             idSystem = system.Id; // invalid
  8.             pipe = Pipe.Create( doc, idSystem,
  9.               idType, idLevel, q0, q1 );

Как можно заметить, вместо типа системы, Джереми пытался передать идентификатор конкретной системы.

Чтоб понять в чем отличие типа системы от системы, давайте создадим несколько труб в пользовательском интерфейсе Revit.

 

При создании трубы, Revit автоматически помещает ее в какую-либо систему. Если последовательно создать несколько труб или создать трубу, конец которой соединяется с существующей трубой, то Revit объединяет их в одну инженерную систему. В примере выше, система называется «Бытовое горячее водоснабжение 1», а тип этой системы – Бытовое горячее водоснабжение. Очевидно, что в одном проекте может быть несколько систем одного типа:

 

Так вот, при создании трубу с помощью метода Pipe.Create, необходимо передавать именно тип, а не конкретную систему.

В Revit существуют следующие типы систем для труб:

  • Подача жидкости - SupplyHydronic
  • Рециркуляция жидкости - ReturnHydronic
  • Сантехническая - Sanitary
  • Бытовое горячее водоснабжение - DomesticHotWater
  • Бытовое холодное водоснабжение - DomesticColdWater
  • Водяная система пожаротушения - FireProtectWet
  • Газовая система пожаротушения - FireProtectDry
  • Дренчерная система пожаротушения - FireProtectPreaction
  • Другие системы пожаротушения - FireProtectOther
  • Прочее - OtherPipe
  • Вентиляционное отверстие - Vent

Давайте рассмотрим пример, как можно создать новую трубу с помощью нового метода.

Проще всего создать новую трубу на основе уже существующей. В этом случае не придется заниматься поисками идентификаторов типа системы, типа трубы и уровня, а взять их из существующей:

Код - C#: [Выделить]
  1.                 // тип системы.
  2.                 // можно определить двумя способами:
  3.                 // 1) Взять систему в которой находится существующая труба и
  4.                 // выполнить метод GetTypeId() для системы
  5.                 // 2) Найти значение параметра
  6.  
  7.                 var pipeSystem = pipe.MEPSystem;
  8.                 var pipeSystemTypeId = pipeSystem.GetTypeId();
  9.  
  10.                 var pipingSystemTypeParam =
  11.                     pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
  12.                 var pipeSystemTypeId2 =
  13.                     pipingSystemTypeParam.AsElementId();
  14.  
  15.                 Debug.Assert(pipeSystemTypeId.Equals(pipeSystemTypeId2),
  16.                     "Что то не так. Тип системы найденный через систему не соответствуюет типу системы," +
  17.                     "полученному через параметр");
  18.  
  19.                 // Тип трубы
  20.                 var pipeTypeId = pipe.PipeType.Id;
  21.  
  22.                 // уровень
  23.                 var levelId = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsElementId();

Если же в проекте нет ни одной существующей трубы, либо нужно создать трубу конкретного типа, то нужно будет проделать определенные шаги по поиску идентификаторов.

Для примера, создадим трубу на уровне активного вида, с первым попавшимся типоразмером и типом системы «Бытовое горячее водоснабжение».

Отдельно рассмотрим поиск типа системы.

Тип ситсемы в Revit API – это экземпляр класса MEPSystemType. Этот класс также имеет два дочерних класса: MechanicalSystemType и PipingSystemType. Для тип систем для труб используется класс PipingSystemType.

Задача состоит в том, как найти эти типы в проекте.

Так как MEPSystemType является дочерним от класса Element, то для поиска всех объектов типа PipingSystemType можно воспользоваться классом FilteredElementCollector.

Код - C#: [Выделить]
  1.                 // Найдем все типы систем для труб
  2.                 var mepSystemTypes
  3.                   = new FilteredElementCollector(doc)
  4.                     //.WhereElementIsNotElementType()               
  5.                     .OfClass(typeof(PipingSystemType))
  6.                     .OfType<PipingSystemType>()
  7.                     .ToList();

Чтобы выбрать из всех типов подходящий, можно конечно сравнивать наименование, но есть более надежный способ – использовать свойство SystemClassification. «Бытовое горячее водоснабжение». – это DomesticHotWater.

Код - C#: [Выделить]
  1.                 // Найдем тип Бытовое горячее водоснабжение
  2.                 var domesticHotWaterSystemType =
  3.                     mepSystemTypes
  4.                         .FirstOrDefault(st => st.SystemClassification == MEPSystemClassification.DomesticHotWater);

Для поиска типа также следует воспользоваться FilteredElementCollector.

А вот в качестве уровня можно использовать уровень, к которому привязан активный вид. Для этого нужно получить значение свойства GenLevel активного вида.

Ниже приведен полный код команды для создания трубы с помощью метода Pipe.Create

Код - C#: [Выделить]
  1.     [Transaction(TransactionMode.Manual)]
  2.     public class Command : IExternalCommand
  3.     {
  4.         public Result Execute(
  5.           ExternalCommandData commandData,
  6.           ref string message,
  7.           ElementSet elements)
  8.         {
  9.             UIApplication uiapp = commandData.Application;
  10.             UIDocument uidoc = uiapp.ActiveUIDocument;
  11.             Application app = uiapp.Application;
  12.             Document doc = uidoc.Document;
  13.  
  14.             // Найдем все трубы в проекте.
  15.  
  16.             FilteredElementCollector col
  17.               = new FilteredElementCollector(doc)
  18.                 .WhereElementIsNotElementType()               
  19.                 .OfClass(typeof(Pipe));
  20.  
  21.             var pipes = col
  22.                 .ToElements()
  23.                 .OfType<Pipe>()
  24.                 .ToList();
  25.  
  26.             // Если труба только одна, то создадим трубу на основе уже существующей
  27.             if (pipes.Count == 1)
  28.             {
  29.                 var pipe = pipes[0];
  30.  
  31.                 // тип системы.
  32.                 // можно определить двумя способами:
  33.                 // 1) Взять систему в которой находится существующая труба и
  34.                 // выполнить метод GetTypeId() для системы
  35.                 // 2) Найти значение параметра
  36.  
  37.                 var pipeSystem = pipe.MEPSystem;
  38.                 var pipeSystemTypeId = pipeSystem.GetTypeId();
  39.  
  40.                 var pipingSystemTypeParam =
  41.                     pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
  42.                 var pipeSystemTypeId2 =
  43.                     pipingSystemTypeParam.AsElementId();
  44.  
  45.                 Debug.Assert(pipeSystemTypeId.Equals(pipeSystemTypeId2),
  46.                     "Что то не так. Тип системы найденный через систему не соответствуюет типу системы," +
  47.                     "полученному через параметр");
  48.  
  49.                 // Тип трубы
  50.                 var pipeTypeId = pipe.PipeType.Id;
  51.  
  52.                 // уровень
  53.                 var levelId = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsElementId();
  54.  
  55.                 var startPoint = XYZ.Zero;
  56.  
  57.                 var endPoint = new XYZ(90, 0, 0);
  58.  
  59.                 using (var t = new Transaction(doc, "Новая труба"))
  60.                 {
  61.                     t.Start();
  62.  
  63.                     var newPipe =
  64.                         Pipe.Create(doc, pipeSystemTypeId,
  65.                             pipeTypeId,
  66.                             levelId,
  67.                             startPoint,
  68.                             endPoint);
  69.  
  70.                     t.Commit();
  71.                 }
  72.             }
  73.             else
  74.             {
  75.                 // Найдем все типы систем для труб
  76.                 var mepSystemTypes
  77.                   = new FilteredElementCollector(doc)
  78.                     //.WhereElementIsNotElementType()               
  79.                     .OfClass(typeof(PipingSystemType))
  80.                     .OfType<PipingSystemType>()
  81.                     .ToList();
  82.  
  83.                 foreach (var pipingSystemType in mepSystemTypes)
  84.                 {
  85.                     Debug.Print("{0} - {1}", pipingSystemType.Name, pipingSystemType.SystemClassification);
  86.                 }
  87.  
  88.                 // Найдем тип Бытовое горячее водоснабжение
  89.                 var domesticHotWaterSystemType =
  90.                     mepSystemTypes
  91.                         .FirstOrDefault(st => st.SystemClassification == MEPSystemClassification.DomesticHotWater);
  92.  
  93.                 if (domesticHotWaterSystemType == null)
  94.                 {
  95.                     message = "Не найден тип Бытовое горячее водоснабжение";
  96.                     return Result.Failed;
  97.                 }
  98.  
  99.                 // Ищем типы трубы
  100.                 var pipeTypes =
  101.                     new FilteredElementCollector(doc)
  102.                         .OfClass(typeof(PipeType))
  103.                         .OfType<PipeType>()
  104.                         .ToList();
  105.  
  106.                 // возьмем первый попавшийся
  107.                 var firstPipeType =
  108.                     pipeTypes.FirstOrDefault();
  109.  
  110.                 if (firstPipeType == null)
  111.                 {
  112.                     message = "Не найден тип трубы";
  113.                     return Result.Failed;
  114.                 }
  115.   
  116.                 var level = uidoc.ActiveView.GenLevel ;
  117.  
  118.                 if (level == null)
  119.                 {
  120.                     message = "Не могу получить уровень для текущего вида";
  121.                     return Result.Failed;
  122.                 }
  123.                 var startPoint = XYZ.Zero;
  124.  
  125.                 var endPoint = new XYZ(30, 0, 0);
  126.  
  127.                 using (var t = new Transaction(doc, "Создание трубы"))
  128.                 {
  129.                     t.Start();
  130.                     var pipe = Pipe.Create(doc,
  131.                         domesticHotWaterSystemType.Id,
  132.                         firstPipeType.Id,
  133.                         level.Id,
  134.                         startPoint,
  135.                         endPoint);
  136.  
  137.                     t.Commit();
  138.                 }
  139.             }           
  140.             return Result.Succeeded;
  141.         }
  142.     }

Автор: Виктор Чекалин
Автор перевода: Виктор Чекалин

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

Опубликовано 26.01.2014
Отредактировано 27.01.2014 в 14:46:51