UpPetto

This is a real course generated by UpPetto — unedited.

AI-generated. Two models wrote it, a third checked every risky claim against sources, a fourth re-checked.

Create my own course

Создание атрибутов, условия и фильтрация по индексам

core Написать VEX-код, который создаёт атрибут @mask по условию на положение точки и удаляет/изменяет точки по их индексу или атрибуту

Атрибут, созданный в VEX, — это не локальная переменная: если объявить его с префиксом @, он записывается в геометрию и виден всем нодам ниже по графу. Это превращает VEX в источник управляющих сигналов: посчитали условие один раз в Wrangle — дальше Group, Blast, Delete, Color или Switch читают этот атрибут по имени, без пересчёта логики. Сначала генерируем данные, затем управляем формой — базовый процедурный принцип Houdini.

Создание атрибутов

Объявление — это одновременно создание и первое присваивание; тип задаётся явно (типом переменной или префиксом):

float @mask = 0;      // то же, что f@mask = 0;
i@team_id  = 2;       // int-атрибут
v@force    = {0, 9.8, 0};   // векторный атрибут

Если атрибут с таким именем уже есть на входной геометрии, VEX пишет в него; если нет — создаёт новый на этой ноде. Проверять результат удобно в Geometry Spreadsheet — это главный инструмент отладки данных.

Условия и фильтрация

Синтаксис if/else не отличается от C:

if (@P.y > 0) {
    f@mask = 1;
    @Cd = {1, 0, 0};
} else {
    f@mask = 0;
    @Cd = {0, 0, 1};
}

Дальше в ноде Blast в поле Group можно написать @mask=1 — и удалить именно эту часть геометрии. Логика (VEX) и действие (Blast) разделены, сеть остаётся гибкой.

Индексные переменные

  • @ptnum — индекс текущей точки (0…@numpt-1) при обходе по точкам;
  • @primnum — индекс текущего примитива;
  • @elemnum — индекс текущего элемента в выбранном режиме обхода (по точкам совпадает с @ptnum);
  • @numpt / @numprim — общее число точек / примитивов (значение уже известно, считать не нужно).
// окрасить каждую вторую точку
if (@ptnum % 2 == 0) @Cd = {1, 1, 0};

Удаление геометрии

Удаление делается функцией, а не присваиванием — «удалить точку через @P = null» в VEX не существует:

removepoint(geoself(), @ptnum);   // или removepoint(0, @ptnum);

Первый аргумент — дескриптор геометрии: geoself() (ссылка на текущую геометрию, аналог this) или литерал 0, означающий то же самое.

graph LR
    A[Attribute Wrangle: создаёт @mask по условию] --> B[Blast / Delete: читает @mask]
    B --> C[Color / Material: читает @mask]
    A -.->|атрибут = управляющий сигнал| C
Атрибут, созданный в VEX, становится сигналом для нод ниже по графу

Разобранный пример

Задача: на сетке точек оставить только те, что попадают в шахматный паттерн по индексу, остальные удалить — частый приём прореживания перед инстансингом.

// Attribute Wrangle, Run Over: Points
int col = @ptnum % 10;       // сетка 10 точек по ширине
int row = @ptnum / 10;
int @mask = (col + row) % 2; // 0 или 1 — шахматная маска

if (@mask == 0) {
    removepoint(geoself(), @ptnum);
}

Разбор: % и / работают как целочисленные операции C. Маску сначала создаём как обычный атрибут — это полезно даже при последующем удалении: до удаления по @mask можно построить группу или подсветить точки цветом для отладки. Удаление всегда идёт последним шагом, когда решение уже принято.

Попробуй сейчас

На Grid (или Scatter) добавьте Attribute Wrangle. Создайте int @mask, равный 1, если @P.x > 0, иначе 0. Не удаляя точки, сначала проверьте маску: @Cd = @mask ? vector(1,0,0) : vector(0,0,1) — увидите две половины сетки разного цвета и новый столбец mask в Geometry Spreadsheet. Затем замените вывод цвета на removepoint(geoself(), @ptnum) для случая @mask == 0.

Ожидаемый результат: на первом шаге сетка окрашена в два цвета по половинам; на втором остаётся только половина точек — та, где @mask == 1.

Получилось, если…

Вы это поняли, если можете объяснить: почему полезно сначала создать атрибут-маску и только потом удалять точки, а не удалять сразу внутри if? (Ответ: маска остаётся видимой и переиспользуемой другими нодами — например, Blast с группой @mask=1; удаление же необратимо для геометрии.)

Вывод

Атрибут с @ — одновременно переменная VEX и данные, видимые всей сети ниже по графу. @ptnum/@primnum/@elemnum/@numpt дают позицию элемента без ручного счётчика. Удаление — отдельная функция (removepoint(geoself()|0, @ptnum)), а не побочный эффект присваивания; часто гибче отдать удаление ноде Blast по маске.

AI-generated · source-grounded review

🛡 Fact-checked: 4 risky claims verified · 1 removed · confidence: high · figures: 1
[verified] Атрибут, созданный в VEX, виден нодам ниже по графу и может управлять ими (Blast с группой @mask=1)
База знаний: атрибуты передаются по цепочке нод и управляют трансформациями, цветом, инстансингом, материалами
[removed] @ptnum доступен всегда, независимо от Run Over
Не подтверждено; для примитивного обхода корректны @primnum/@elemnum
[verified] removepoint(geoself(), @ptnum) и removepoint(0, @ptnum) эквивалентны: 0 — дескриптор текущей геометрии
Согласуется с описанной в базе фильтрацией точек по условиям в VEX; обе формы указывают на текущую геометрию ноды
[verified] @numpt/@numprim содержат общее число точек/примитивов
База знаний упоминает индексные переменные (@ptnum, @elemnum) и агрегирование данных по элементам геометрии
[verified] Figure (mermaid, урок 2): Wrangle создаёт @mask → Blast/Delete читает → Color/Material читает; атрибут как управляющий сигнал
Направление потока и роль атрибута как управляющих данных соответствуют базе знаний об атрибутах, проходящих по цепочке нод
[removed] Удалено утверждение, что @ptnum доступен всегда, независимо от режима Run Over (в режиме обхода по примитивам корректен @primnum/@elemnum; универсальная доступность @ptnum базой знаний не подтверждена)

A second opinion has not checked this lesson.

Key concepts: создание атрибутов if/else в VEX @ptnum/@elemnum/@numpt removepoint
Tell me more 🔒 Didn't understand — explain simply 🔒 Show examples 🔒 Sources 🔒

On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Write my course

Check yourself

1. Что происходит, когда вы пишете `f@mask = 0;` в Attribute Wrangle?
2. Что проверяет выражение `@ptnum % 10 == 0` в Attribute Wrangle, работающем по точкам?
3. Как правильно удалить текущую точку по условию в VEX?
On your own course, these are marked as you answer