
ponimayka1
.pdf
скопированные объекты. Полезно также посмотреть на дерево зависимостей в Нуреrgraph, откуда следует, что скопировалась только связь объекта с деревом истории моделирования.
Я хотел бы сразу отметить, что принципы дублирования Input Graph или Input Connections распространяются не только на объекты, имеющие History, но и на все объекты, просто имеющие входящие связи. Так, например, если объект имеет expression, заставляющий его двигаться определенным образом, то при дублировании по умолчанию этот expression просто «отвалится» от объекта; при дублировании Input Graph будет создан новый expression для копии объекта, а при копировании Input Connections один старый expression будет управлять сразу двумя объектами. (Хотя это может не соответствовать текстовому содержанию самого expression. )
Для взрослых. Это можно легко проверить. Оставьте в сцене один объект, выберите его, в Attribute Editor впишите - в ячейку для translateY - следующий текст:
=noise(time)
и нажмите Enter. Expression готов. Теперь в Duplicate Option Box включите галочку Duplicate Input Connections и скопируйте объект. Оттащите его куда-нибудь неподалеку и посмотрите в Expression Editor, что хотя формула написана для первого объекта, второй объект прекрасно движется в соответствии с нею. Осознать этот парадокс вам поможет Hypergraph, где можно увидеть, что ex pression - это просто вычислитель, имеющий выходы, которые могут быть подсоединены к любому объекту.
Стэк деформаций и история моделирования
Иногда некоторые, более хорошо подкованные индивидуумы, случайно знакомые с понятием «стэк деформаций», начинают воспринимать Construction History тоже как своеобразный стэк моделирования. В принципе это так и есть, за исключением того, что в отличие от деформаций, порядок операций моделирования не может быть произвольно изменен. Посудите сами: если провести лофт через три кривые, а потом пересечь его со сферой, получив замкнутую кривую, го какие операции и в каком порядке здесь можно переставить?! Да, для некоторых операций полигонального моделирования, последовательно передающих данные типа inMesh, outMesh, можно ставить задачу изменения порядка следования нод в дереве зависимостей. Такая задача легко решается (либо при помощи небольшого скрипта, либо ручной переустановкой связей в Нуpergraph), но вряд ли результат перестановки операций, в общем случае, будет предсказуем.
Но давайте разберем этот самый стэк деформаций.
Порядок деформаций. Список операций
Применение деформеров также ведет к появлению History у геометрических объектов, так как деформеры воздействуют непосредственно на форму объекта, и, как следствие, на ноду
121

shape.
Займемся «вивисекцией». Если ваш «ежик» еще «жив» (помните? была выше така» «колючая» фигура), попробуем «поиздеваться» над ним. Если нет, откройте файл starObjectHistory.ma или создайте простой куб.
Выберите объект, навалите на него деформер squash: Deformers=>Create Non Linear=>Squash.
В Channel Box установите factor=3.
Затем снова выберите объект и примените к нему деформер bend: Deformers=>Create Non Linear=>Bend.
В Channel Box установите curvature=2.
Таким образом, мы сначала растянули объект, а затем согнули его. Есть мнение, что если бы сначала объект был согнут, а потом растянут, результат был бы иной. Как поменять порядок деформаций?
Конечно, можно открыть Hypergraph и, проявив паранормальные чудеса смекалки и виртуозное владение мышью, быстро перебросить нужные связи в необходимом порядке. А как быть обычным, «нормальным» людям?
Надо выбрать объект и добраться до плохо описанного в документации окна, в котором есть список всех входящих операций (inputs).
122

Это можно сделать, поставив курсор над объектом и нажав правую кнопку мыши: в
выпавшем меню надо выбрать lnputs=>AU Inputs...
Откроется окно List of input operations for pCube1, в котором представлена вся History объекта в виде списка операций. (Замечу, что Construction History представлена здесь как часть общей History, включающая в себя все операции над формой объекта.) В отличие от Hypergraph, здесь историю следует читать снизу вверх.
Теперь схватите средней кнопкой мыши первый сверху пункт в этом списке - Non Linear(squash1), перетащите его и бросьте на второй пункт: Non Linear(bend1 ).
Порядок следования нод в истории поменялся, а значит поменялся и порядок деформаций -это прекрасно видно на экране.
123

При перетаскивании, порядок следования операций изменяется так: элемент списка вставляется под тот элемент, на который он был «сброшен». (То есть перед ним, если смотреть снизу вверх, с точки зрения History.) Здесь же вы можете заблокировать действие той или иной ноды, изменяя ее атрибут nodeState.
Можете убедиться, что нельзя поменять порядок нод, относящихся к Construction History, то есть к моделированию (об этом уже говорилось раньше).
Если заглянуть в Hypergraph, нажать там главную кнопку и немного подтащить ноды друг к другу, можно выстроить дерево истории в удобочитаемом виде.
Загадочный Tweak
Нода tweak, автоматически появляющаяся при создании деформеров, хранит в себе информацию о ручном редактировании поверхности путем прямого перетаскивания за вершины. Поскольку она, по умолчанию, располагается перед деформерами, перетаскивание вершин на деформированном объекте может вас слегка смутить: ведь вершины будут двигаться, не следуя за манипулятором. (Просто представьте себе, что вслед за вашим смещением вершин к ним мгновенно прикладываются деформации объекта, переставляющие их прямо под вашим курсором.)
Ноду tweak также можно переставить средней кнопкой в списке операций - так, чтобы и она оказалась после деформеров. Вслед за этим вершины будут, конечно, передвигаться корректно, однако при анимации деформеров могут проявиться неожиданные явления.
Путешествия по истории
Вызвать окно со списком исторических связей через меню на правой кнопке мыши путь интуитивно -понятный, но далеко не единственный. Для выбранного объекта на Status Line находятся две кнопки, показывающие все входящие и выходящие операции для выбранного объекта.
124

В Attribute Editor для каждой ноды также существуют две похожие кнопки, позволяющие не только показывать входящие и исходящие связи (через правую кнопку мыши), но и осуществлять в Attribute Editor навигацию вверх и вниз по дереву зависимостей.
Эти кнопки исключительно удобны при работе с деревом материалов и текстур и позволяют быстро перемещаться по связям.
DAG или не DAG? Терминологические дебри
Иногда в интерфейсе и тем более в документации мелькнет аббревиатура DAG. Бывает, встречается сокращение DG. Начинающие диггеры, занявшиеся MAYA, порой думают, что это опечатка. Хотя знание терминологии в этом случае имеет скорее теоретический, чем практический характер, постараюсь прояснить значение этих терминов, а также уместность их употребления. (Кроме того, вы всегда сможете сделать жутко умный вид и со знанием дела ввернуть в дискуссию пару фривольных сентенций, типа «Ну, я-то всегда контролирую свой DAG» или «Ох, еле-еле распутал чужой DG». Попробуйте. Работает...)
Термин DAG (Directed Acyclic Graph) пришел из теории графов и может быть, в принципе, переведен как «направленный непериодический граф». Однако пугаться таких названий не стоит, поскольку DAG -просто «высоколобый» термин для представления иерархии «майской» сцены. Совокупность отношений parent-child для всех объектов в сцене - это и есть DAG. Еще проще можно объяснить понятие DAG визуально: представление сцены в Hypergraph в режиме Scene Hi erarchy - тоже DAG. Запомните навсегда: сам DAG - это не объекты, а представление отношений между объектами!
Слово «направленный» (directed) в данном случае означает, что отношение parent-child имеет направление сверху вниз и однозначно определено. «Непериодический» (acyclic) всего лишь объясняет (для понимающих), что подчиненный объект не может быть родителем своих родителей, то есть направленные отношения parent-child не могут образовывать циклы. Ну и, надеюсь, понятно, что «граф» не имеет никакого отношения к титулованию лиц благородного происхождения, то есть от «графа Толстого» до нашего с вами графа дистанция огромного
125
размера..
Довольно часто встречается термин DAG-object. Совершенно справедливо предположить, что DAG-объект - это просто элемент DAG, то есть любой объект, который может быть «припарентен» к другим DAG-объектам. Очень просто уяснить разницу между DAG и не-DAG объектами, открыв Outliner и включив/выключив галочку Display=>DAG Objects Only. Таким образом, активно используя любимый «метод тыка», можно сказать, что все объекты, которые можно выбрать непосредственно на экране, то есть в панели камеры, являются DAG-объектами. Пытливые умы уже, видимо, сделали вывод, что DAG-объекты всегда имеют transform-ноду, которая позволяет перемещать их в пространстве и группировать с другими объектами. Любая геометрия, источники света, камеры, частицы, локаторы, флюиды, кластеры - все это DAG-объекты. Соответственно, blendshape, или любой материал, или текстура DAG-объектами не являются.
Если быть совсем въедливым, надо упомянуть термин DAG-node, то есть это нода, входящая в состав DAG-объекта. Реально существует всего два типа DAG-нод: это transform-нода и shapeнода, о которых я уже говорил выше. Transform-нода позволяет группировать объекты, и, км правило, она (если это не пустая группа) имеет подчиненные (child) объекты в виде shape-ноды и других transform-нод. Shape-нода никогда не имеет подчиненных объектов, но всегда имеет хотя бы одного transform-родителя. (Отсюда следует еще одно определение DAG-объекта: как постоянной связки transform+shape.)
Благодаря механизму инстансирования, одна shape-нода может иметь несколько; родителей. Именно поэтому DAG называется графом, так как в этом случае он уже перестает иметь структуру иерархического дерева (в котором у потомк всегда один родитель), а становится произвольным графом. Однако в «майской» терминологии уже прижился термин - хотя , строго говоря, некорректный: «дерево зависимостей», или «дерево истории»: под которым понимается, естественно, произвольной формы граф.
Разберем теперь, что такое DG (Dependency Graph). Как следует из названия - это граф зависимостей, представляющий из себя набор нод и связей между ними. DG тоже являета направленным (directed), так как связи между атрибутами нод однозначно направлены. Но, е отличие от DAG, он может быть цикличным, так как пользователь может устанавливать связи между любыми двумя нодами и в любом направлении. Связи в DG уже не являются иерархическими отношениями, а представляют собой просто потоки данных между нодами, соединяющими входные и выходные атрибуты этих нод. Именно DG отображается в Hypergraph в режиме Input And Output Connections.
Отсюда можно сделать вывод: DG-нода - просто элемент DG-графа. DG-ноды можно представлять в виде вычислителей, которые получают данные через входящие атрибуты, затем производят вычисления, и их результат через выходные атрибуты отправляют к другим нодам. Примерами DG-нод являются материалы, текстуры, системное время time1, ноды, отвечающие за Construction History, и пр.
Снова погружаясь в тонкости терминологии, можно сказать, что все DAG-ноды являются,в том числе, и DG-нодами, так как transform и shape тоже могут соединяться с другими нодами при помощи Hypergraph или Connection Editor.
Иногда все DG-ноды, кроме transform и shape, называют Non-DAG Nodes. Но здесь лишь подчеркивается то обстоятельство, что такие ноды нельзя сгруппировать или выбрать, а затем перемещать на экране. Материалы и текстуры - основной пример Non-DAG Nodes. Деформеры, глобальное время time1, expressions, blendshape, defaultRenderGlobals и масса других служебных нод - это все Non-DAG Nodes. Некоторые из них изначально присутствуют в любой сцене, некоторые пользователь создает в явном виде (например, материалы или expressions), но большинство из них возникают как служебные или вспомогательные объекты в процессе выполнения тех или иных операций.
Подытоживая многочисленные формулировки, можно сказать, что DAG это представление сцены с точки зрения иерархии между объектами, a DG - с точки зрения зависимостей между атрибутами объектов.
126
Примечание. |
Понятнее |
всего |
DAG-терминология |
описана |
в |
документации |
в |
|
разделе |
«Для |
взрослых», |
а именно в описании ноды DAG Node. |
Во всех остальных |
||||
разделах |
можно найти |
лишь |
циклические ссылки, |
притом |
скороговоркой, с более |
чем лаконичными разъяснениями.
Циклы в дереве зависимостей и их последствия. Поднимание себя за уши
Если можно соединять атрибуты различных нод Hypergraph в любой последовательности, теоретически возможна ситуация, когда возникают циклы. Другими словами, путешествуя по связям в Hypergraph в направлении стрелок можно вернуться к ноде, с которой начиналось путешествие. Например, если создать три цилиндра, можно без проблем соединить в Connection Editor вращения первого и второго цилиндров (через атрибуты rotate), затем вращения второго «третьего, а затем - третьего и первого. И получится, что все цилиндры управляют друг другом. Попытка повращать любой объект не приведет к успеху, так как атрибуты rotate всех объектов заблокированы связями с другими объектами. Это похоже на попытку поднять самого себя за уши. И хотя MAYA формально позволяет устраивать такие связи, ни к чему хорошему это не приведет, особенно если ваше дерево зависимостей не столь уж примитивно. Наличие циклов может приводить к довольно непредсказуемым и трудно отлавливаемым ошибкам, так как связи между атрибутами продолжают функционировать, но порядок и результат их выполнения неоднозначен. Примером «непреднамеренного» создания циклов может служить попытка «приконстрейнить» родительский объект к одному из своих потомков. В этом случае родитель управляет потомком через иерархию, а потомок управляет родителем через констрейн.
MAYA однако проявляет ангельское терпение, стараясь не «упасть» от таких циклических издевательств и даже сообщает пользователю о наличии циклов в сцене. Поэтому стоит очень внимательно относиться к появлению в Script Editor сообщения типа:
//Warning: Cycle on 'pCube2.rotate' may not evaluate as expected. // (Use 'cycleCheck -e o f f to disable this warning.) //
В случае появления такого приговора следует внимательно пересмотреть связи между объектами и атрибутами, чтобы выявить некорректные зависимости.
Только в одном случае не стоит паниковать при появлении такого сообщения. При использовании динамики твердых тел, после возвращения в первый кадр, MAYA весело сообщает оналичии циклов. Не пугайтесь, так устроена динамика, а точнее, понятие начального положения твердого тела. В этом случае просто не обращайте внимания на сообщение о циклах.
Expression как нода совершенно произвольного назначения. Природа expressions. Входы, выходы и сиротливые expressions
Я уже упоминал о том, что можно рассматривать ноды как простые вычислители принимающие и передающие данные. У каждой ноды собственные правила, по которым она вычисляет выходные данные. Но если вам вдруг понадобится сделать вычисления по собственным формулам, то создавать собственные ноды можно только с помощью специально обученных людей, знающих C++ и умеющих компилировать плагины. В этом случае, на помощь приходят expressions. Те, кто уже знаком с правилами написания expressions, знают, что с их помощью устанавливается связь между атрибутами различных объектов, запрограммированная на языке MEL.
Примечание. Если вы смогли дочитать текст до этого места, автор должен от души поздравить вас: вы обладаете завидным мужеством и у вас
недюжинная |
пытливость ума. |
Правда, дальше, с точки зрения абстрактности |
и технологичности, материал |
будет еще хуже... (Или - лучше? Может, крепче?) |
|
Главное: я |
вас честно об этом |
предупредил. |
127

Давайте посмотрим на expressions как на обычную ноду, которая имеет входы и выходы.
Откройте файл expressionStart.ma.
В нем содержится три объекта и один expression, который удерживает сферу по вертикали посередине между кубами.
В Hypergraph можно увидеть связи между объектами и нодой expression1.
Как следует из диаграммы зависимостей, нода expression1 принимает на вход значения двух атрибутов (pCube1.translateY и pCube2.translateY), вычисляет результат и помещает его на выход (output[0]), который присоединяется к вертикальной координате сферы (nurbsSphere1
128

translateY).
Проделаем следующие действия. Попробуем присоединить выход от expression1 еще к шкому-нибудь объекту.
Создайте полигональный тор.
Выберите его и сферу, а затем в Hypergraph выполните Graph=> Input And Output Connec tions, чтобы увидеть одновременно и тор, и ноду expression1.
Перетащите ноду expression1 на pTorus1 средней кнопкой мыши, удерживая Shift.
Откроется Connection Editor.
Слева, где находится expression1, выберите Output/Output[0], асправа вы делите TranslateY, присоединив, таким образом, выходное значение от expression1 к вертикальному перемещению юра.
Подергав за кубики, убедитесь, что тор двигается вместе со сферой. Теперь откройте
Expression Editor, задайте в нем для удобства Select Filter=>By Expression Name и выберите expression1, чтобы увидеть ег
Парадоксальная вещь! Формула для expression1 не изменилась и не содержит даже упоминаний про pTorus1, однако тор беззастенчиво двигается вместе со сферой.
129

Конечно, если кто-то откроет этот файл в первый раз, его очень сильно озадачит поведеия тора (особенно если еще обратиться к Expression Editor). Недоумение не пройдет до тех пор, пока любопытствующий не откроет Hypergraph и не прочитает эту главу. Однако мы сделали именно то, что хотели, причем вручную, устанавливая связи между объектами. Поэтому MAYA не всегда может адекватно трактовать и отображать наши, в общем-то «хакерские», действия в своем интерфейсе.
Конечно, если добавить в expression1 еще одну строку вида:
pTorus1.translateY=(pCube1.translateY+pCube2.translateY)/2;
то MAYA совершенно законно добавит к ноде expression1 еще один выходной атрибут (output[1]) присоединит его к тору.
Таким образом, в нашем случае (как, впрочем, и в любом другом случае), expression1 работает как простой вычислитель: он принимает данные на входных атрибутах (input[n], их может быть сколько угодно), производит подсчеты и отправляет результат на выходные атрибуты (output[n], и их также может быть сколько угодно).
Проделайте следующий, еще более радикальный эксперимент.
В Hypergraph разыщите expression и аккуратно удалите все его связи с остальным объектами кроме time1.
Теперь откройте Expression Editor и посмотрите на его формулу (для этого может понадобиться нажать кнопку Reload).
130