Создание трубы с помощью метода 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 не является подходящей системой для труб»)
Взглянем на код Джереми:
- ElementId idSystem = pipe.MEPSystem.Id; // invalid
- ElementId idType = pipe.PipeType.Id;
- ElementId idLevel = pipe.LevelId;
- idSysem = ElementId.InvalidElementId; // invalid
- PipingSystem system = PipingSystem.Create(
- doc, pipe.MEPSystem.GetTypeId(), "Tbc" );
- idSystem = system.Id; // invalid
- pipe = Pipe.Create( doc, idSystem,
- idType, idLevel, q0, q1 );
Как можно заметить, вместо типа системы, Джереми пытался передать идентификатор конкретной системы.
Чтоб понять в чем отличие типа системы от системы, давайте создадим несколько труб в пользовательском интерфейсе Revit.
При создании трубы, Revit автоматически помещает ее в какую-либо систему. Если последовательно создать несколько труб или создать трубу, конец которой соединяется с существующей трубой, то Revit объединяет их в одну инженерную систему. В примере выше, система называется «Бытовое горячее водоснабжение 1», а тип этой системы – Бытовое горячее водоснабжение. Очевидно, что в одном проекте может быть несколько систем одного типа:
Так вот, при создании трубу с помощью метода Pipe.Create, необходимо передавать именно тип, а не конкретную систему.
В Revit существуют следующие типы систем для труб:
- Подача жидкости - SupplyHydronic
- Рециркуляция жидкости - ReturnHydronic
- Сантехническая - Sanitary
- Бытовое горячее водоснабжение - DomesticHotWater
- Бытовое холодное водоснабжение - DomesticColdWater
- Водяная система пожаротушения - FireProtectWet
- Газовая система пожаротушения - FireProtectDry
- Дренчерная система пожаротушения - FireProtectPreaction
- Другие системы пожаротушения - FireProtectOther
- Прочее - OtherPipe
- Вентиляционное отверстие - Vent
Давайте рассмотрим пример, как можно создать новую трубу с помощью нового метода.
Проще всего создать новую трубу на основе уже существующей. В этом случае не придется заниматься поисками идентификаторов типа системы, типа трубы и уровня, а взять их из существующей:
- // тип системы.
- // можно определить двумя способами:
- // 1) Взять систему в которой находится существующая труба и
- // выполнить метод GetTypeId() для системы
- // 2) Найти значение параметра
- var pipeSystem = pipe.MEPSystem;
- var pipeSystemTypeId = pipeSystem.GetTypeId();
- var pipingSystemTypeParam =
- pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
- var pipeSystemTypeId2 =
- pipingSystemTypeParam.AsElementId();
- Debug.Assert(pipeSystemTypeId.Equals(pipeSystemTypeId2),
- "Что то не так. Тип системы найденный через систему не соответствуюет типу системы," +
- "полученному через параметр");
- // Тип трубы
- var pipeTypeId = pipe.PipeType.Id;
- // уровень
- var levelId = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsElementId();
Если же в проекте нет ни одной существующей трубы, либо нужно создать трубу конкретного типа, то нужно будет проделать определенные шаги по поиску идентификаторов.
Для примера, создадим трубу на уровне активного вида, с первым попавшимся типоразмером и типом системы «Бытовое горячее водоснабжение».
Отдельно рассмотрим поиск типа системы.
Тип ситсемы в Revit API – это экземпляр класса MEPSystemType. Этот класс также имеет два дочерних класса: MechanicalSystemType и PipingSystemType. Для тип систем для труб используется класс PipingSystemType.
Задача состоит в том, как найти эти типы в проекте.
Так как MEPSystemType является дочерним от класса Element, то для поиска всех объектов типа PipingSystemType можно воспользоваться классом FilteredElementCollector.
- // Найдем все типы систем для труб
- var mepSystemTypes
- = new FilteredElementCollector(doc)
- //.WhereElementIsNotElementType()
- .OfClass(typeof(PipingSystemType))
- .OfType<PipingSystemType>()
- .ToList();
Чтобы выбрать из всех типов подходящий, можно конечно сравнивать наименование, но есть более надежный способ – использовать свойство SystemClassification. «Бытовое горячее водоснабжение». – это DomesticHotWater.
- // Найдем тип Бытовое горячее водоснабжение
- var domesticHotWaterSystemType =
- mepSystemTypes
- .FirstOrDefault(st => st.SystemClassification == MEPSystemClassification.DomesticHotWater);
Для поиска типа также следует воспользоваться FilteredElementCollector.
А вот в качестве уровня можно использовать уровень, к которому привязан активный вид. Для этого нужно получить значение свойства GenLevel активного вида.
Ниже приведен полный код команды для создания трубы с помощью метода Pipe.Create
- [Transaction(TransactionMode.Manual)]
- public class Command : IExternalCommand
- {
- public Result Execute(
- ExternalCommandData commandData,
- ref string message,
- ElementSet elements)
- {
- UIApplication uiapp = commandData.Application;
- UIDocument uidoc = uiapp.ActiveUIDocument;
- Application app = uiapp.Application;
- Document doc = uidoc.Document;
- // Найдем все трубы в проекте.
- FilteredElementCollector col
- = new FilteredElementCollector(doc)
- .WhereElementIsNotElementType()
- .OfClass(typeof(Pipe));
- var pipes = col
- .ToElements()
- .OfType<Pipe>()
- .ToList();
- // Если труба только одна, то создадим трубу на основе уже существующей
- if (pipes.Count == 1)
- {
- var pipe = pipes[0];
- // тип системы.
- // можно определить двумя способами:
- // 1) Взять систему в которой находится существующая труба и
- // выполнить метод GetTypeId() для системы
- // 2) Найти значение параметра
- var pipeSystem = pipe.MEPSystem;
- var pipeSystemTypeId = pipeSystem.GetTypeId();
- var pipingSystemTypeParam =
- pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
- var pipeSystemTypeId2 =
- pipingSystemTypeParam.AsElementId();
- Debug.Assert(pipeSystemTypeId.Equals(pipeSystemTypeId2),
- "Что то не так. Тип системы найденный через систему не соответствуюет типу системы," +
- "полученному через параметр");
- // Тип трубы
- var pipeTypeId = pipe.PipeType.Id;
- // уровень
- var levelId = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsElementId();
- var startPoint = XYZ.Zero;
- var endPoint = new XYZ(90, 0, 0);
- using (var t = new Transaction(doc, "Новая труба"))
- {
- t.Start();
- var newPipe =
- Pipe.Create(doc, pipeSystemTypeId,
- pipeTypeId,
- levelId,
- startPoint,
- endPoint);
- t.Commit();
- }
- }
- else
- {
- // Найдем все типы систем для труб
- var mepSystemTypes
- = new FilteredElementCollector(doc)
- //.WhereElementIsNotElementType()
- .OfClass(typeof(PipingSystemType))
- .OfType<PipingSystemType>()
- .ToList();
- foreach (var pipingSystemType in mepSystemTypes)
- {
- Debug.Print("{0} - {1}", pipingSystemType.Name, pipingSystemType.SystemClassification);
- }
- // Найдем тип Бытовое горячее водоснабжение
- var domesticHotWaterSystemType =
- mepSystemTypes
- .FirstOrDefault(st => st.SystemClassification == MEPSystemClassification.DomesticHotWater);
- if (domesticHotWaterSystemType == null)
- {
- message = "Не найден тип Бытовое горячее водоснабжение";
- return Result.Failed;
- }
- // Ищем типы трубы
- var pipeTypes =
- new FilteredElementCollector(doc)
- .OfClass(typeof(PipeType))
- .OfType<PipeType>()
- .ToList();
- // возьмем первый попавшийся
- var firstPipeType =
- pipeTypes.FirstOrDefault();
- if (firstPipeType == null)
- {
- message = "Не найден тип трубы";
- return Result.Failed;
- }
- var level = uidoc.ActiveView.GenLevel ;
- if (level == null)
- {
- message = "Не могу получить уровень для текущего вида";
- return Result.Failed;
- }
- var startPoint = XYZ.Zero;
- var endPoint = new XYZ(30, 0, 0);
- using (var t = new Transaction(doc, "Создание трубы"))
- {
- t.Start();
- var pipe = Pipe.Create(doc,
- domesticHotWaterSystemType.Id,
- firstPipeType.Id,
- level.Id,
- startPoint,
- endPoint);
- t.Commit();
- }
- }
- return Result.Succeeded;
- }
- }
Автор перевода: Виктор Чекалин
Обсуждение: http://adn-cis.org/forum/index.php?topic=482
Опубликовано 26.01.2014Отредактировано 27.01.2014 в 14:46:51