Всем привет! В прошлый раз разобрал простую тему из Revit API, сегодня статья более сложная и интересная. Научимся создавать части и модифицировать их. Для примера приведу как раз стену, мы разобьём её на части и нарежем наружный слой на отдельные "плитки".
Задача
Необходимо разбить выбранные по определённому признаку стены на части. Выделить в этих частях по имени наружный слой и разделить его на прямоугольники 1000х500 мм.
Решение
Я создал файл на основе встроенного в Autodesk Revit 2023 шаблона (Шаблон строительства) и нарисовал несколько стен двух типов в случайном порядке.
Мы разделим на части все стены, но на прямоугольники разделим только слой "Штукатурка". Почему штукатурка, а не сделать нормальный слой "Плитка"? Потому что я веду блог о программировании под Revit, а не о дизайне. :)
Я разделю все стены на части. Как взять для разделения только некоторые, написано здесь (Collector) и здесь (LINQ).
Код для первоначального разделения на части очень простой. В принципе, такой же простой, как и ручное разделение:
На 47 строке мы проверяем, можно ли разделить элемент, и если да, то делим его на 49 строке.
Теперь попробуем разделить часть (в коде выполнить то, что делает эта кнопка):
Для этого мы выберем все части, у которых в параметре "Материал" указано "Штукатурка".
Подробно о работе с параметрами я пишу здесь.
Далее мы будем делить часть. Код получался довольно сложный, 80 строк, поэтому я приведу его по частям. В конце будет ссылка на код на гитхабе. К сожалению, иначе как картинками сюда я код добавить не могу (с сохранением форматирования).
Итак, что мы делаем:
- Для каждой части создаём массив из одного элемента (строка 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. До новых встреч!