Сегодня рассмотрим создание размеров с помощью Revit API. Это, с одной стороны, довольно простая тема: создать размеры сами по себе не очень сложно. Но с другой стороны, возможных сценариев автоматизации этого процесса очень много, и, как правило, "просто поставить размеры" не особо хватает.
Для данной статьи я воспользуюсь средой для создания макросов SharpDevelop, про которую я писал в самой первой статье блога. Макросы — довольно удобная штука для быстрой проверки всяких гипотез или набросков кода, но в данном случае я решил использовать их просто для разнообразия.
Исходные данные
Стена, в ней 2 двери. Нужно образмерить габариты стены и дверей:
Для создания размеров используем метод NewDimension. Он принимает на вход вид, линию и массив из Reference:
Разберёмся пошагово. С видом всё понятно: это просто document.ActiveView. А откуда взять линию?
Очевидно, что ось стены для размеров нам не подойдёт. В своей реализации вы можете сделать, как посчитаете нужным: например, сделать смещение на 10 мм перпендикулярно ей. Я же просто попрошу пользователя ввести 2 точки, а затем сделаю линию, приведя координату Y второй точки к первой.
Да, решение работает только вдоль одной оси, но его легко распространить и на 2 оси, воспользовавшись if-else, сравнивая разницу между координатами X и Y.
Получение ReferenceArray
Reference — это такой интересный объект, который является ссылкой на геометрический элемент. Это может быть элемент целиком, его грань, ребро или точка на ребре. Типы Reference можно посмотреть в этом перечислении.
Обычно у элемента (грани, ребра) есть свойство Reference, откуда его и можно получить. Мы так и поступим: возьмём геометрию стены, возьмём оттуда все рёбра, длина которых будет равна толщине стены, и оттуда возьмём те, что нам нужны:
Вот примерно такой маршрут по RevitLookup до нужных нам ребёр. Я возьму только те, у которых ElementReferenceType == REFERENCE_TYPE_CUT_EDGE. Если честно, я не понял, в чём разница с просто LINEAR, но данная схема работает, а если взять все, то будет дублирование.
Кстати, вы уже обновили Revit Lookup до нового интерфейса? На момент выхода статьи наиболее актуальная версия лежит здесь.
Код для получения ReferenceArray будет такой:
Поясню некоторые нюансы:
- В Options обязательно ставим ComputeReferences == true.
- GeometryElement возвращаемый методом get_Geometry — это перечисление GeometryObject. Solid — это класс-наследник GeometryObject. Именно поэтому я получаю Solid именно так.
- Числа double нельзя сравнивать непосредственно из-за их высокой точности, поэтому я сравниваю модуль из разности с произвольной малой погрешностью типа 10-6 (можете взять -9 или -12, разницы особо не будет)
- Остальное вроде бы очевидно из кода, но если у вас есть вопросы, пишите их в комментарии.
Создание размера
Получив все исходные данные, создаём размер, не забывая про транзакции.
В конце: блок catch для отладки при исключениях.
Запускаем макрос и получаем результат:
Итоговый код метода, создающего стены, я поместил на GitHub Gist. Нужно создать макрос и скопировать в него данный метод, а затем скомпилировать всё и запустить.
Мой телеграм-канал: заходите, подписывайтесь, делитесь идеями. До новых встреч!