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

21/01/2014

Явное создание отводов при создании наклонного сегмента трубопровода

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

В завершении рассмотрим создание и вставку соответствующих фитингов.

Я долго мучился с этой задачей, пока я наконец не получил то что хотел.

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

После того как я реализовал все эти шаги, и готовил пост к публикации, Тате (Tate) оставил очень подходящий и полезный комментарий в предыдущем посте.  

С помощью всего лишь одного метода Document.NewElbowFitting можно создать, разместить и соединить фитинги друг с другом автоматически.

Большое спасибо, Tate!

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

Геометрия наклонного сегмента

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

 

Точки p0 и p1 являются крайними точками исходных труб, который находятся на максимальном расстоянии друг от друга.

Точка pm является серединой между p0 и p1. Она также используется для определения середины наклонного сегмента трубопровода.

Точки q0 и q1 являются началом и окончанием наклонного сегмента трубопровода. Мы использовали эти точки для размещения линии модели и для вставки трубы без отводов.

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

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

Размещение фитингов для соединения наклонного сегмента

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

Расчет наклонного сегмента по-прежнему остается неизменным.

Новая версия выглядит довольно объемной:

Код - C#: [Выделить]
  1.                     // Найдем подходящий отвод
  2.  
  3.                     FamilySymbol symbol
  4.                       = new FilteredElementCollector(doc)
  5.                           .OfClass(typeof(FamilySymbol))
  6.                           .OfCategory(BuiltInCategory.OST_PipeFitting)
  7.                           .Cast<FamilySymbol>()
  8.                           .FirstOrDefault(e =>
  9.                               e.Family.Name.Equals("M_Отвод - Типовой",
  10.                               StringComparison.InvariantCultureIgnoreCase));
  11.  
  12.                     // Установим угол фитинга равным 45 градусов
  13.  
  14.                     FamilyInstance fitting0 = doc.Create
  15.                       .NewFamilyInstance(q0, symbol,
  16.                         StructuralType.NonStructural);
  17.  
  18.                     fitting0.get_Parameter("Угол").Set(
  19.                       45.0 * Math.PI / 180.0);
  20.  
  21.                     //fitting0.get_Parameter( bipDiameter ) // параметра Диаметр нет
  22.                     //  .Set( diameter );
  23.  
  24.                     fitting0.get_Parameter("Номинальный радиус")
  25.                       .Set(0.5 * diameter);
  26.  
  27.                     Line axis = Line.CreateBound(p0, q0);
  28.                     angle = z.AngleTo(XYZ.BasisZ);
  29.  
  30.                     ElementTransformUtils.RotateElement(
  31.                       doc, fitting0.Id, axis, Math.PI - angle);
  32.  
  33.                     Connector con0 = Util.GetConnectorClosestTo(
  34.                       Util.GetConnectorManager(fitting0).Connectors, p0);
  35.  
  36.                     // Уменьшим или увеличим существующую трубу
  37.  
  38.                     (pipes[0].Location as LocationCurve).Curve
  39.                       = Line.CreateBound(p0, con0.Origin);
  40.  
  41.                     // Соединим трубу с фитингом
  42.  
  43.                     Util.Connect(con0.Origin, pipe, fitting0);
  44.  
  45.                     // Установим угол наклона для другого фитинга
  46.  
  47.                     FamilyInstance fitting1 = doc.Create
  48.                       .NewFamilyInstance(q1, symbol,
  49.                         StructuralType.NonStructural);
  50.  
  51.                     fitting1.get_Parameter("Угол").Set(
  52.                       45.0 * Math.PI / 180.0);
  53.  
  54.                     fitting1.get_Parameter("Номинальный радиус")
  55.                       .Set(0.5 * diameter);
  56.  
  57.                     axis = Line.CreateBound(
  58.                       q1, q1 + XYZ.BasisZ);
  59.  
  60.                     ElementTransformUtils.RotateElement(
  61.                       doc, fitting1.Id, axis, Math.PI);
  62.  
  63.                     axis = Line.CreateBound(q1, p1);
  64.  
  65.                     ElementTransformUtils.RotateElement(
  66.                       doc, fitting1.Id, axis, Math.PI - angle);
  67.  
  68.                     Connector con1 = Util.GetConnectorClosestTo(
  69.                       Util.GetConnectorManager(fitting1).Connectors, p1);
  70.  
  71.                     (pipes[1].Location as LocationCurve).Curve
  72.                       = Line.CreateBound(con1.Origin, p1);
  73.  
  74.                     Util.Connect(con1.Origin, fitting1, pipes[1]);
  75.  
  76.                     con0 = Util.GetConnectorClosestTo(
  77.                        Util.GetConnectorManager(fitting0).Connectors, pm);
  78.  
  79.                     con1 = Util.GetConnectorClosestTo(
  80.                       Util.GetConnectorManager(fitting1).Connectors, pm);
  81.  
  82.                     // Если мы соединим фитинги друг с другом
  83.                     // то это не создаст автоматически трубу между ними
  84.                    
  85.                     //con0.ConnectTo( con1 );
  86.  
  87.                     // Создадим наклоный сегмент
  88.  
  89.                     pipe = doc.Create.NewPipe(con0.Origin,
  90.                       con1.Origin, pipe_type_standard);
  91.  
  92.                     pipe.get_Parameter(bipDiameter)
  93.                       .Set(diameter);
  94.  
  95.                     // Соединим наклонный сегмент с фитингами
  96.  
  97.  
  98.                     Util.Connect(con0.Origin, fitting0, pipe);
  99.                     Util.Connect(con1.Origin, pipe, fitting1);

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

Результат

Послу запуска команды, моя тестовая модель стала выглядеть вот так:

 

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

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

Источник: http://thebuildingcoder.typepad.com/blog/2014/01/explicitly-placing-rolling-offset-pipe-elbow-fittings.html

 

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

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