Найти тему

Создание развёрток стен с помощью разрезов

Всем привет! Сегодня расскажу, как с помощью Revit API создавать разрезы, параллельные стене, а также смещать их от стены на определённую величину, и раздвигать их границы.

При подготовке статьи я использовал материал из блога Джереми Тэммика:

https://thebuildingcoder.typepad.com/blog/2012/06/create-section-view-parallel-to-wall.html

Создание разреза

Разрезы в Revit API представлены классом ViewSection. Чтобы создать разрез, можно воспользоваться его статическим методом CreateSection. Он принимает документ, тип вида и BoundingBox. Соответственно, задача построения разреза сводится к правильному определению его BoundingBox.

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

var viewTypeId = new FilteredElementCollector(doc)
.OfClass(typeof(ViewFamilyType))
.ToElements()
.Cast<ViewFamilyType>()
.Where(type => type.ViewFamily == ViewFamily.Section)
.FirstOrDefault().Id;

Я беру элементы класса ViewFamilyType — это типы видов, и беру среди них те, которые являются типами разрезов (Section). В данном случае я беру первый элемент, но у себя в приложении вы можете создать ComboBox с выбором нужного типа. Похожий пример я писал в предыдущей статье.

Теперь давайте подробнее рассмотрим класс BoundingBoxXYZ. Это не просто параллелепипед, представленный свой минимальной и максимальной точкой. У него ещё есть свойство Transform, которое управляет его положением в пространстве. Нам надо будет решить задачу по правильному созданию этого самого Transform для разреза.

В своём коде я задал 3 переменные:

var projectionDeprth = 500/304.8;
var offset = 250/304.8;
var sectionOffset = 50/304.8;

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

И далее пройдёмся циклом foreach по всем стенам на активном виде. Тут уже сложно будет выделить отдельные части, поэтому сразу приведу весь фрагмент кода (ссылка на итоговый код будет в конце статьи):

Сначала разберёмся с линией разреза. Для этого на строках 591-593 я получаю её из Location стены, а затем получаю нужные мне параметры:

  • length — половина длины стены. Это расстояние от стартовой точки Transform в обе стороны.
  • lineDifference — вектор от стартовой точки к конечной.
  • middlePoint — центральная точка линии.

Далее разбираемся с границами по высоте. Я решил сделать их соответствующими границе стены, со смещением вверх на sectionOffset, то есть 50 мм. Я получаю переменные maxHeight и minHeight на строках 601-603 с помощью BoundingBox стены.

Далее задаю минимальную и максимальную точки моего BoundingBox на строках 604-605. Если я их так и оставлю, то он создастся в начале координат, поэтому надо трансформировать будущий BoundingBox с помощью Transform.

Для этого нам нужны 3 векторные переменные, которые мы потом назначим на BasisX, BasisY и BasisZ:

  • Нормализованный lineDifference (приведённый к единичной длине) станет BasisX.
  • XYZ.BasisZ (единичный вектор вверх) станет BasisY.
  • А их векторное произведение запишем в BasisZ.

Если честно, я не до конца понимаю, почему всё работает именно так. Поэтому, когда я разбирался с SectionBox фасадов, я определял эти Basis методом подбора. Но с разрезами приведённый код работает. Если разберётесь, в чем дело и как это можно объяснить, чтобы было понятно — пишите в комментарии.

В общем, теперь всё. Записываем все значения в Transform на строках 612-616 и в sectionBox на 618-621, а потом создаём разрез.

Запускаю макрос, и вижу вот такой результат:

-2

Стены обрисовываются во всех направлениях и под любыми углами. Сами разрезы выглядят так:

-3

Как видите, сверху и снизу есть небольшой зазор, потому что я его назначил через sectionOffset. Сдвига вправо-влево нет, если вам он нужен, то добавьте его, модифицировав startPoint и endPoint.

Итоговый код макроса на GitHub Gist

На этом всё. Не забывайте подписываться на мой телеграм-канал о Revit API и ставить лайки на статьи, которые читаете. До новых встреч!

-4