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

15/01/2014

Создание наклонного сегмента между двумя трубами

Недавно я рассказывал о своем небольшим проекте по вычислению наклонного сегмента между двумя трубами.

Сразу же возникает очевидный вопрос: «отлично. Но только как же теперь вставить реальный сегмент трубы, вместо того, чтобы просто отобразить линию, отображающую результат расчета сегмента?».

Фактически эта задача сводится к двум подзадачам:

  • Создать сегмент трубы
  • Соединить все три трубы вместе

Как я говорил ранее, например в статье Перемещение соединений воздуховодов, существует два подхода к решению этих задач:

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

Я хочу реализовать оба варианта.

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

Первый метод. Создание двух труб

В Revit API есть два метода для создания труб:

  • Новый статический метод Pipe.Create
  • Старый метод Document.Create.NewPipe

Проблемы при использовании Pipe.Create

Очевидно, что я пытался вначале использовать новый метод.

Статический метод Pipe.Create принимает в качестве аргументов 6 параметров:

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

Я попробовал взять требуемые значения параметров из одной существующей трубы и вызвать метод создания трубы с помощью вот такого кода:

Код - C#: [Выделить]
  1.   ElementId idSystem = pipe.MEPSystem.Id;
  2.   ElementId idType = pipe.PipeType.Id;
  3.   ElementId idLevel = pipe.LevelId;
  4.  
  5.   pipe = Pipe.Create( doc, idSystem,
  6.     idType, idLevel, q0, q1 );

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

Я поигрался с различными значениями параметра, пытаясь подобрать корректный идентификатор типа системы, пробовал ElementId.InvalidElementId и пробовал использовать идентификатор новой системы, но, к сожалению, все впустую. Победить ошибку так и не получилось.

Как только я найду рабочее решение этой проблемы, я непременно дам вам знать.

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

Так как новый метод для создания трубы мне использовать так и не удалось, то придется воспользоваться старым проверенным методом NewPipe, определенным в классе Autodesk.Revit.Creation.Document.

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

В метод NewPipe достаточно передать только координаты начала и окончания трубы, а также типоразмер.

Я воспользовался классом FilteredElementCollector для поиска стандартного типа трубы просто сравнивая наименование со словом «Стандартная». Но я уверен что есть способ, который позволит найти стандартный тип трубы вне зависимости от языка интерфейса.

Также я предварительно взял значение диаметра существующих труб, и затем задал тот же самый диаметр для новой трубы. Для поиска параметра я воспользовался встроенным параметром RBS_PIPE_DIAMETER_PARAM.

В результате код выглядит вот так:

Код - C#: [Выделить]
  1.   BuiltInParameter bip
  2.     = BuiltInParameter.RBS_PIPE_DIAMETER_PARAM;
  3.  
  4.   double diameter = pipe
  5.     .get_Parameter( bip ) // "Diameter"
  6.     .AsDouble();
  7.  
  8.   PipeType pipe_type_standard
  9.     = new FilteredElementCollector( doc )
  10.       .OfClass( typeof( PipeType ) )
  11.       .Cast<PipeType>()
  12.       .Where<PipeType>( e
  13.         => e.Name.Equals( "Стандартная" ) )
  14.       .FirstOrDefault<PipeType>();
  15.  
  16.   Debug.Assert(
  17.     pipe_type_standard.Id.IntegerValue.Equals(
  18.       pipe.PipeType.Id.IntegerValue ),
  19.     "ожидалось, что все трубы в простом проекте имеют один и тот же типоразмер " );
  20.  
  21.   pipe = doc.Create.NewPipe( q0, q1,
  22.     pipe_type_standard );
  23.  
  24.   pipe.get_Parameter( bip )
  25.     .Set( diameter );

Вот скриншот исходного проекта с двумя трубами перед выполнением команды

 

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

 

Обратите внимание, что я пока не делал каких-либо попыток соединить все три трубы. Сделаю это чуть позже.

Как я обещал, я также попробую все же воспользоваться методом Pipe.Create.

Код, который я написал выше, доступен в примерах The Building Coder на GitHub в команде под названием CmdRollingOffset. Версия команды, которая обсуждалась в статье, находится в release 2014.0.106.2

В команду я добавил три булевых переменных, для выбора различных вариантов команды, обсуждаемых в последних двух темах:

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

Код - C#: [Выделить]
  1.   /// <summary>
  2.   /// Команда может разместить просто линию
  3.   /// представляющую собой результат расчета наклонного сегмента
  4.   /// или вставить трубу с соответствующими фитингами
  5.   /// </summary>
  6.   static bool _place_model_line = false;
  7.  
  8.   /// <summary>
  9.   /// Выбор метода создания трубы с помощью Pipe.Create
  10.   /// или Document.Create.NewPipe.
  11.   /// </summary>
  12.   static bool _use_static_pipe_create = false;

Надеюсь эта информация будет для вас полезна.

Источник: http://thebuildingcoder.typepad.com/blog/2014/01/creating-a-rolling-offset-pipe-between-two-pipes.html

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

Опубликовано 15.01.2014
Отредактировано 15.01.2014 в 20:08:23