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

30/12/2014

Ошибка при создании арматурных стержней из кривых

Ошибка при создании арматурных стержней из кривых

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

Код - C#: [Выделить]
  1. public static Rebar CreateFromCurves(
  2.     Document doc, RebarStyle style, RebarBarType barType,
  3.     RebarHookType startHook, RebarHookType endHook, Element host,
  4.     XYZ norm, IList<Curve> curves,
  5.     RebarHookOrientation startHookOrient,
  6.     RebarHookOrientation endHookOrient,
  7.     bool useExistingShapeIfPossible, bool createNewShape);

Давайте подробнее разберем аргументы norm и curves:

  • norm . Type: XYZ. Нормаль к плоскости, на которой лежит арматура.
  • curves. Type: IList<Curve>. Массив кривых, который определяет фигуру арматуры. Кривые должны принадлежать плоскости, определяемую нормалью и исходной точкой. Отгибы и отводы не должны включаться в этот массив.

Файл справки RevitAPI.chm говорит нам о том, что поверхность и кривые должны быть перпендикулярны нормали.

Клиент хочет создать два арматурных стрежня. Поверхность и кривые действительно перпендикулярны, и первый стержень создается без проблем. А вот создание второго стержня падает с ошибкой InvalidOperationException: Невозможно создать фигуру арматурного стержня с заданными кривыми (Unable to create a RebarShape based on the given curves).

Код - C#: [Выделить]
  1. RebarBarType bartype = new FilteredElementCollector(RevitDoc)
  2.     .OfClass(typeof(RebarBarType))
  3.     .FirstOrDefault(t => t.Name == "8 HPB300") as RebarBarType;
  4. Curve
  5. curve = Line.CreateBound(
  6.     new XYZ(5.656152019023, 43.5912980314625, -10.0065608637852),
  7.     new XYZ(5.65615201724766, 43.5912980188303, 7.70997373826235));
  8. curves.Add(curve);
  9. curve = Line.CreateBound(
  10.     new XYZ(5.65615201724766, 43.5912980188303, 7.70997373826235),
  11.     new XYZ(5.65615201724766, 45.2478392340832, 7.70997373826235));
  12. curves.Add(curve);
  13. curve = Line.CreateBound(
  14.     new XYZ(5.65615201724766, 45.2478392340832, 7.70997373826235),
  15.     new XYZ(5.656152019023, 45.2478392467154, -10.0065608637852));
  16. curves.Add(curve);
  17.  
  18. // Первый стержень создается без проблем!
  19. Rebar.CreateFromCurves(RevitDoc, RebarStyle.Standard, bartype, null,
  20.     null, ele, nml, curves, RebarHookOrientation.Left,
  21.     RebarHookOrientation.Left, false, true);
  22.  
  23. // Проблемный арматурный стержень
  24. List<Curve> curves2 = new List<Curve>();
  25. curve = Line.CreateBound(
  26.     new XYZ(6.22700217574493, 43.5110702844365, -10.0065608637852),
  27.     new XYZ(6.22700217219427, 43.5110702591722, 7.70997373826235));
  28. curves2.Add(curve);
  29. curve = Line.CreateBound(
  30.     new XYZ(6.22700217219427, 43.5110702591722, 7.70997373826235),
  31.     new XYZ(6.22700217219427, 45.1676114744251, 7.70997373826235));
  32. curves2.Add(curve);
  33. curve = Line.CreateBound(
  34.     new XYZ(6.22700217219427, 45.1676114744251, 7.70997373826235),
  35.     new XYZ(6.22700217574493, 45.1676114996894, -10.0065608637852));
  36. curves2.Add(curve);
  37. //InvalidOperationException – выбрасывается исключение
  38. //  => Unable to create a RebarShape based on the given curves
  39. Rebar.CreateFromCurves(RevitDoc, RebarStyle.Standard, bartype, null,
  40.     null, ele, nml, curves2, RebarHookOrientation.Left,
  41.     RebarHookOrientation.Left, false, true);

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

Мой коллега Grzegorz говорит:

Алгоритм создания фигуры достаточно сложен. В основном проблема может возникнуть для фигур, которые определены сегментами, располагающимися под прямым углом. Они должны быть определены очень точно (различные цифры на 7 или 8 месте после запятой, могут вызвать исключение). Наилучшим решением будет округление всех координат до 6 цифры после запятой.

Я изменил код таким образом, и проблема исчезла:

Код - C#: [Выделить]
  1. curve = Line.CreateBound(
  2.     XYZ(6.22700217574493, 43.5110702844365, -10.0065608637852),
  3.     XYZ(6.22700217219427, 43.5110702591722, 7.70997373826235));
  4. curves2.Add(curve);
  5. curve = Line.CreateBound(
  6.     XYZ(6.22700217219427, 43.5110702591722, 7.70997373826235),
  7.     XYZ(6.22700217219427, 45.1676114744251, 7.70997373826235));
  8. curves2.Add(curve);
  9. curve = Line.CreateBound(
  10.     XYZ(6.22700217219427, 45.1676114744251, 7.70997373826235),
  11.     XYZ(6.22700217574493, 45.1676114996894, -10.0065608637852));
  12. curves2.Add(curve);
  13.  
  14. ....
  15.  
  16. private XYZ XYZ(double x, double y, double z)
  17. {
  18.     return new XYZ(
  19.         Math.Round(x, 6), Math.Round(y, 6), Math.Round(z, 6));
  20. }

Источник: http://adndevblog.typepad.com/aec/2014/12/revitapi-rebarcreatefromcurves-throws-unable-to-create-a-rebarshape-based-on-the-given-curves.html

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

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