Добавить в корзинуПозвонить
Найти в Дзене
Мария Чухно

Оформление сборок в Revit. Вращение начала сборки с помощью Dynamo

В этой статье рассказала, что такое начало сборки и как его положение влияет на ориентацию видов сборки. Небольшой экскурс для тех, кто не хочет читать предыдущую статью. Начало сборки – это объект, представляющий из себя локальную систему координат. Начало сборки при ее создании всегда ориентировано в направлении глобальных осей, несмотря на то, как ориентированы ее компоненты (в нашем случае железобетонная панель). Чтобы получить виды сборки, параллельные граням панели, а также стандартизировать их создание, чтобы вид впереди всегда показывал наружную грань панели вне зависимости от ее ориентации, начало необходимо повернуть. Вращать начало можно вручную, а можно средствами Dynamo. Здесь мы рассмотрим второй способ. В качестве примера продолжим использовать железобетонную панель. В Revit API начало сборки принадлежит к классу Transform, то есть является трансформацией элемента. Трансформация – это матрица, содержащая в себе данные о координатах элемента и его повороте относительно гл
Оглавление

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

Небольшой экскурс для тех, кто не хочет читать предыдущую статью.

Начало сборки – это объект, представляющий из себя локальную систему координат.

-2

Начало сборки при ее создании всегда ориентировано в направлении глобальных осей, несмотря на то, как ориентированы ее компоненты (в нашем случае железобетонная панель). Чтобы получить виды сборки, параллельные граням панели, а также стандартизировать их создание, чтобы вид впереди всегда показывал наружную грань панели вне зависимости от ее ориентации, начало необходимо повернуть.

Вращать начало можно вручную, а можно средствами Dynamo. Здесь мы рассмотрим второй способ. В качестве примера продолжим использовать железобетонную панель.

Что есть начало

В Revit API начало сборки принадлежит к классу Transform, то есть является трансформацией элемента. Трансформация – это матрица, содержащая в себе данные о координатах элемента и его повороте относительно глобальных осей.

-3

Basis – набор векторов в векторном пространстве.

BasisX, BasisY, BasisZ – векторы единичной длины, определяющие направление осей локальной системы координат. Каждый базисный вектор имеет три координаты, эти координаты определяют конечную точку вектора. Начальной точкой является Origin.

Origin – начало локальной системы координат, по-другому эту матрицу 3х1 называют сдвигом локальной системы координат относительно глобальной. А Basis – поворотом.

Получаем начало сборки

Подготовим небольшой скрипт в Dynamo, который будем наполнять по ходу работы.

-4

В Python Script импортируем необходимые модули, определяем переменные doc и selection с экземпляром текущего документа и входными данными.

-5

В переменную selection мы передаем сборку – это экземпляр класса AssemblyInstance. Начало сборки получаем, используя метод GetTransform этого класса. Свойства Origin, BasisX, BasisY, BasisZ класса Transform вернут положение начала сборки и направление его векторов.

Распечатаем их для наглядности, используя вновь созданную сборку, начало которой размещено по умолчанию.

-6
-7

Попробуем повернуть начало вручную и снова получить свойства трансформации. Как видно, координаты векторов изменились.

-8

Кручу-верчу

Для того, чтобы повернуть начало, нужно воспользоваться методом SetTransform класса AssemblyInstance. Этот метод принимает в качестве аргумента объект трансформации. Значит, мы должны передать в него повернутую трансформацию.

-9

Для создания повернутой трансформации первое, что приходит в голову, это воспользоваться методом CreateRotation класса Transfrom. Метод принимает два аргумента: ось вращения и угол поворота. Поворот всегда происходит против часовой стрелки.

Вращать мы будет относительно оси Z, получим ее из объекта трансформации как transform.BasisZ.

Если бы мы точно знали, на какой угол нужно повернуть трансформацию, то порядок действий был бы такой:

1. Передаем угол в метод CreateRotation. Угол обозначу переменной angle и присвою ему значение 0.785 в радианах (это примерно 45 градусов)

-10

Интуитивно кажется, что эта новая трансформация и есть то, что нам нужно, ведь мы создали вращение вокруг оси Z текущей трансформации и вообще применяем этот метод к текущей трансформации. Но это не так. Если вы попробуете передать переменную rotation в метод SetTransform, то увидите, что начало сборки сместилось во внутреннее проекта. То есть rotation – это трансформация, у которой есть поворот, но нет сдвига. Об этом говорит документация к Revit API:

CreateRotation – это метод, создающий новый повернутый объект трансформации в точке с координатами (0, 0, 0)
CreateRotation – это метод, создающий новый повернутый объект трансформации в точке с координатами (0, 0, 0)

2. Чтобы получить итоговую трансформацию, нужно применить метод Multiply, позволяющий перемножить (объединить) две трансформации, и результат передать в метод SetTransform, не забывая про открытие и закрытие транзакции.

-12

Скрипт работает, начало повернулось на 45 градусов против часовой стрелки.

-13

Если бы мы точно знали, на какой угол нужно повернуть трансформацию, но мы точно не знаем, на какой угол нужно повернуть трансформацию

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

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

-14

Соответственно, главный элемент можно найти, сравнив категории компонентов с категорией именования сборки.

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

-15

В том случае, когда компонентов категории несколько, например, сборка состоит из нескольких стен, в переменную main_member попадет одна из них, в смысле какая-то. Нас такой расклад в принципе устраивает, но, если вы хотите выделить конкретную стену, например, несущий слой, нужно будет добавить отдельный критерий фильтрации.

Главный элемент - загружаемое семейство

Экземпляр загружаемого семейства, который мы получим в переменной main_member – это экземпляр класса FamilyInstance. Его свойство Location вернет положение экземпляра семейства, а свойство Rotation класса Location, в свою очередь, вернет угол поворота, относительно базового положения, определенного в редакторе семейств. Угол всегда будет положительным от 0 до 360 вне зависимости от того, в какую сторону вы вращаете элемент.

-16
-17

Координаты по умолчанию указываются в дюймах, а угол в радианах.

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

Если мы имеем дело со сборкой, начало которой расположено по умолчанию (в направлении глобальных осей), то искомый угол поворота легко получить из угла поворота семейства.

-18

Я добавила pi к углу поворота семейства для того, чтобы довернуть начало еще на 180 градусов, потому что хочу, чтобы вид спереди сборки показывал наружную грань панели, для этого ось Y начала должна смотреть в направлении внутренней грани.

-19

Скрипт работает, однако, такой подход не учитывает сценарий, когда начало уже было повернуто: его могли повернуть вручную, либо сборка была повернута целиком. В таком случае, необходимо получить текущий поворот начала сборки. Его можно найти как угол между базисным вектором начала и тем же вектором глобальной системы координат.

-20

Метод AngleTo класса XYZ всегда возвращает положительное значение угла в диапазоне от 0 до 180 градусов. На этом этапе поиск угла поворота превращается в довольно муторное занятие с подключением тригонометрии, ведь, помимо угла между векторами, нам нужно понять, в каком квадранте находится вектор трансформации.

Метод AngleTo вернет одинаковый результат для разного положения начал
Метод AngleTo вернет одинаковый результат для разного положения начал

К счастью, есть способ, позволяющий вообще не использовать углы и вращение.

Переопределение базисных векторов трансформации

Экземпляры загружаемых семейств, как и сборки, имеют трансформации. Метод GetTransform класса Instance (родительского класса FamilyInstance) вернет объект трансформации экземпляра семейства. Получив базисные векторы трансформации семейства и прировняв к ним соответствующие базисные вектора начала сборки, мы получим поворот начала, не задействуя углы и методы вращения.

-22

Это работает благодаря тому, что базисные векторы задаются точками в локальной системе координат, передав точки из одной системы в другую, мы получим новое направление вектора, origin при этом останется на месте.

Что делать, если главный элемент сборки – стена?

Для стен нельзя получить трансформацию, так как это системное семейство. Положение стены можно определить через свойство Orientation класса Wall. Это свойство возвращает вектор, направленный в сторону наружной поверхности стены. Напомню, что наружная поверхность в Revit обозначена стрелками.

-23

Базисный вектор Y начала сборки должен быть противоположен вектору ориентации стены, а базисный вектор X мы можем получить как векторное произведение между базисным вектором Y и Z.

-24
-25

Вот так можно вращать начало сборки для стандартизации и ускорения оформления чертежей на изделия из загружаемых семейств или стен, не зарываясь в расчете углов. По-моему, получился простой, изящный и надежный способ.

Важно помнить, что поворот начала не влияет на уже созданные виды.

По ссылке приложила скрипт с кодом для двух разных вариантов, работающий для одной сборки.

Скрипт собран в версии Dynamo 2.12 под Revit 2022.1

Полезные ссылки для понимания матрицы трансформации в общем и класса Transform в Revit API:

Матрицы перехода

Матрицы поворота

Трансформации

Класс Transform в Revit API