Параметры и выражения: параметризация функций
core Связать параметр одной ноды с параметром другой через относительную ссылку/выражение так, чтобы зависимость пересчитывалась автоматически
Параметр ноды — это типизированный аргумент функции, как параметр в сигнатуре C-функции: у Transform SOP это tx, ty, tz, rx, ry, rz, sx, sy, sz.
// Аналогия в коде для ноды Transform
transform(
geometry geo, // входные данные (неявный аргумент)
vector3 translate, // параметр Translate
vector3 rotate, // параметр Rotate
vector3 scale // параметр Scale
);
Разница с C в том, что за каждым параметром стоит канал (channel) — ячейка, в которую можно положить не только константу, но и выражение, вычисляемое заново при каждом коке (cook) ноды. Это превращает статичный набор аргументов в узел графа вычислений: значение параметра может зависеть от значений параметров других нод.
Связь делается через ссылку на канал другого узла — функцию ch() (для числового значения) или chs() (для строкового):
// в параметре ty ноды transform2
ch("../transform1/tx") * 0.5
Путь может быть абсолютным (/obj/geo1/transform1/tx), но на практике почти всегда используют относительный: он не ломается при копировании и переименовании сетей. ../ здесь — переход на уровень родительской сети, а transform1/tx — путь до конкретного канала. Это не однократное копирование значения, а живая зависимость: при каждом изменении tx у transform1 Houdini помечает transform2 как «грязный» (требующий пересчёта) и пересчитывает его при следующем запросе геометрии — так же, как формула в ячейке таблицы пересчитывается при изменении данных, на которые она ссылается. В поле параметра можно писать и арифметику: ch("../transform1/tx") * 2 + 1.
graph LR
T1["transform1.tx = 4"] -->|ch expression *0.5| T2["transform2.ty = 2"]Разобранный пример
Задача: сделать так, чтобы объект поднимался по Y ровно на половину того, на сколько его сдвинули по X, без ручной синхронизации двух значений.
Рассуждение: нужен один узел-источник движения (transform1.tx) и один зависимый параметр (transform2.ty). Вручную вписывать число в ty каждый раз при изменении tx — не процедурный подход и первый источник забытых багов. Правильно — прописать в поле ty выражение ch("../transform1/tx") * 0.5. Тогда tx остаётся единственным источником истины, а ty — производной величиной, вычисляемой графом автоматически. Именно так строятся HDA: несколько простых «ручек» управляют сложной внутренней логикой.
Попробуй сейчас
Создай два Transform SOP подряд. У первого задай tx через слайдер (любое значение). У второго в поле ty впиши выражение ch("../transform1/tx") * 0.5. Подвигай tx первого узла и проверь, что ty второго меняется сам, без ручного ввода.
Ожидаемый результат: при любом изменении tx первого узла значение ty второго узла всегда равно половине tx, и это видно как во вьюпорте, так и в самом поле параметра (оно отображается как выражение, а не как константа).
Получилось, если…
Ты можешь объяснить разницу между «вписать число 2 в ty» и «вписать ch(...)*0.5 в ty» в терминах: константа vs зависимость в графе вычислений, пересчитываемая по требованию (pull-based), и вручную написать ch("../node/param") для связи двух параметров.
Вывод
Параметры — это аргументы функции-ноды с каналом вместо простого значения; ch()/относительные пути превращают сеть параметров в граф зависимостей, где изменение одного значения каскадно пересчитывает всё, что от него зависит — без ручной синхронизации.
AI-generated · source-grounded review
🛡 Fact-checked: 2 risky claims verified · 2 removed · confidence: medium · figures: 1
A second opinion has not checked this lesson.
On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Write my course