Иерархические сборки.
При отображении сложной или анимированной сцены необъходимо работать с большим количеством связанных интерактивных объектов, перемещающихся друг относительно друга по определённым законам.
Для облегчения реализации такого поведения в zencad представлена библиотека zencad.assemble и её основное средство zencad.assemble.unit.
Сборочный юнит (zencad.assemble.unit).
Сборочный юнит - это объект, имеющий собственную локальную систему координат, относительно которой позиционируются связанные с этим юнитом интерактивные объекты и другие юниты. Юниты могут создавать структуру дерева, отсчитывая своё положение относительно положения юнита-предка (unit.parent). Если юнит не имеет предка, его положение отсчитывается от глобальной системы координат.
Юнит содержит два объекта координатного преобразования - location и global_location.
- location - задаёт положение юнита относительно положения юнита предка. location может быть обновлён или непосредственно, или с помощью метода relocate.
- globallocation - это положение юнита относительно глобальной системы координат. globallocation используется при отрисовке объекта. globallocation строится на основе дерева unit.location и может быть обновлён с помощью метода locationupdate, relocate и, с помощью других операций.
Добавление объекта.
Создаёт и связывает с юнитом интерактивный объект на основе переданного геометрического объекта obj.
Если в качестве параметра передан интерактивный объект, юнит берёт его под управление. (Примечание: юнит управляет расположением интерактивного объекта).
Сигнатура:
u.add(obj, color=None)
Пример:
m = box(10)
i = box(10).right(20)
u.add(m)
u.add(i)
Добавление юнита-потомка.
Устанавливает объект u предком для объекта child. Теперь положение объектов в юните child (и его потомках) будет расчитываться с учётом положения объекта u.
Сигнатура:
u.link(child)
Пример:
from zencad.assemble import unit
u = unit()
child = unit()
u.link(child)
Обновить глобальное расположение.
Обновить глобальное расположение объекта согласно данным о его текущем положении и объекту глобального положения предка. view - если объект отображен, перерисовать его, исходя из нового положения. deep - применить рекурсивно всех потомков объекта.
Сигнатура:
u.location_update(deep=True, view=True)
Изменить локальное положение.
Изменить текущее положение на объект location и применить процедуру location_update с опциями deep, view.
Сигнатура:
u.relocate(location, deep=False, view=True)
Отобразить на сцене.
Сигнатура:
u.bind_to_scene(scene)
Добавить юнит и его потомков в сцену scene. Для обычного скрипта достаточно display(u): привязку к сцене выполняет система отображения. Цвет задаётся при добавлении геометрии через u.add(obj, color=...).
Пример сборки
Обе детали находятся в системе координат base. Перемещение родителя переносит их вместе, сохраняя взаимное положение:
from zencad import *
from zencad.assemble import unit
base = unit()
base.add(box(20, 10, 3), color=blue)
post = unit(parent=base, location=translate(10, 5, 3))
post.add(cylinder(2, 12), color=yellow)
base.relocate(translate(30, 0, 0), deep=True)
assert tuple(post.global_location.translation()) == (40, 5, 3)
display(base)
show()