Найти тему

Создание и разделение частей

Оглавление

Всем привет! В прошлый раз разобрал простую тему из Revit API, сегодня статья более сложная и интересная. Научимся создавать части и модифицировать их. Для примера приведу как раз стену, мы разобьём её на части и нарежем наружный слой на отдельные "плитки".

Задача

Необходимо разбить выбранные по определённому признаку стены на части. Выделить в этих частях по имени наружный слой и разделить его на прямоугольники 1000х500 мм.

Решение

Я создал файл на основе встроенного в Autodesk Revit 2023 шаблона (Шаблон строительства) и нарисовал несколько стен двух типов в случайном порядке.

Мы разделим на части все стены, но на прямоугольники разделим только слой "Штукатурка". Почему штукатурка, а не сделать нормальный слой "Плитка"? Потому что я веду блог о программировании под Revit, а не о дизайне. :)

Я разделю все стены на части. Как взять для разделения только некоторые, написано здесь (Collector) и здесь (LINQ).

Код для первоначального разделения на части очень простой. В принципе, такой же простой, как и ручное разделение:

-2

На 47 строке мы проверяем, можно ли разделить элемент, и если да, то делим его на 49 строке.

Теперь попробуем разделить часть (в коде выполнить то, что делает эта кнопка):

-3

Для этого мы выберем все части, у которых в параметре "Материал" указано "Штукатурка".

-4

Подробно о работе с параметрами я пишу здесь.

Далее мы будем делить часть. Код получался довольно сложный, 80 строк, поэтому я приведу его по частям. В конце будет ссылка на код на гитхабе. К сожалению, иначе как картинками сюда я код добавить не могу (с сохранением форматирования).

Ориентируемся на номера строк)
Ориентируемся на номера строк)
-6

Итак, что мы делаем:

  • Для каждой части создаём массив из одного элемента (строка 74), потому что метод DivideParts требует именно ICollection<ElementId>, один Id не катит.
  • Получаем Id основного элемента части и проверяем, что он представляет стену (75-77)
  • Создаём массив из уровня этой стены, он тоже понадобится методу DivideParts.
  • Далее наша задача — создать список разделяющих стену линий. Вот тут основная сложность, по сути, это геометрическая задача, и решать её можно по-разному (так что вы, возможно, найдёте метод попроще)
  • Определяем шаг по вертикали и по горизонтали, определяем длину, высоту и конечные точки стены (строки 79-89). Это наши исходные данные.
  • Определяем переменную horizDiff (94 строка). В таком виде, потому что по сути это вектор, векторная прибавка к стартовой точке.
  • Далее мы сдвигаем наружу стартовую и конечную точку на строках 95-96. Это нужно, потому что при создании частей через API стена делится, только если линии немного выходят за контур стены (почему — я не знаю).
  • Определяем число вертикальных и горизонтальных линий (98-99).
  • Запускаем 2 цикла, в которых создаём сначала вертикальные, потом горизонтальные линии. Для вертикальных линий сдвиг векторных, для горизонтальных просто добавляем координату Z.
  • Затем на строках 116-120 создаём последний аргумент DivideParts — плоскость эскиза деления.
  • И наконец, делим части на 122 строке.

Результат:

Не забудьте включить видимость частей на виде
Не забудьте включить видимость частей на виде

Итоговый код в моём репозитории на GitHub.

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

-8