Render.ru

Instance

Ro

Знаток
Рейтинг
38
#1
Привет, подскажите плиз:
Два инстанс-обьекта, нужно одному поправить текстуру или, например, некоторые вершины немного переместить. Второй, соответственно, не дожен изменяться. Отцепить инстанс от обьекта можно путем Modify - Convert - Instance to Object, а можно ли вернуть назад? Количество вершин, естественно, на обоих остается прежним. Спасиба!
 

fm4

Активный участник
Рейтинг
15
#2
ИМХО, обратно вернуть нельзя, потому что вы уже изменили UV и/или координаты. Как вы думаете, что должно произойти с вашими изменениями?
 

fm4

Активный участник
Рейтинг
15
#3
Кстати, может в вашем случае подойдет Reference?
Если оригинал положить в отдельный файл и втянуть его в сцену через референс, то если мне не изменяет мой склероз, его прокси можно менять локально.

http://download.autodesk.com/us/maya/2009help/files/File_referencing_Modifying_a_file_reference.htm
 

alex_alv

Активный участник
Рейтинг
11
#4
Если например, инстансированный шейп называется pSphereShape1, а сконвертированный в объект инстанс называется pSphere7, то вернуть инстанс обратно в pSphere7 можно через команду
parent -addObject -shape pSphereShape1 pSphere7
а затем в аутлайнере выбрать сконвертированный шейп pSphereShape7 и удалить его.

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

fm4

Активный участник
Рейтинг
15
#5
А что произойдет с изменениями? Пропадут, если я правильно понял?
 

alex_alv

Активный участник
Рейтинг
11
#6
Есть только два варианта:
1) если воспользоваться командой, то пропадут.
2) если написать скрипт, который наоборот переместит измененный шейп в изначальные инстансы, то наоборот, пропадет исходная форма, и изменения проявятся во всех инстансах.
 

alex_alv

Активный участник
Рейтинг
11
#7
Вот этот скрипт.
В первых двух строчках нужно указать имя оригинального шейпа (который будет удален) и имя модифицированного шейпа (который нужно инстансировать вместо оригинального)

string $originalShape="pSphereShape1";
string $modifiedShape="pSphereShape7";


string $transforms[]=`listRelatives -allParents $originalShape`;
string $onetransform;
for($onetransform in $transforms) parent -addObject -shape $modifiedShape $onetransform;
delete $originalShape;
 

fm4

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

Ro

Знаток
Рейтинг
38
#9
fm4, абсолютно верно - все ради придания реализма и небольшой хаотичности. Допустим, в сцене 20 одинаковых крупных обьектов, которые в процессе сцены придется видоизменять, но уже на стадии разработки хотелось бы им придать чуточку реализма и индивидуальности, а каждый раз делать одно и тоже со всеми по отдельности не эргономично. Мы не ищем легких путей : ) Почему же невозможно оставить обьект инстансом, если у него то же самое количество вершин? Ведь в этом случае у обоих обьектов сетки остаются равными, но с поправкой на небольшое изменение координат отдельных вершин. Типа, A1=A2+ (a, b, c), где A1 - координаты определенной точки первого обьекта, A2 - координаты аналогичной точки второго обьекта, ну и a, b и c - смещение точки второго обьекта относительно аналогичной точки первого. Пусть это и может работать тока в "легких" случаях, но все же лучше чем ничего
 

alex_alv

Активный участник
Рейтинг
11
#10
"Почему же невозможно оставить обьект инстансом, если у него то же самое количество вершин?" - странный вопрос.

Инстансы - это по определению одинаковые объекты. Так как инстансы - это один шейп, который имеет несколько родителей-трансформов.
Так что нужно определиться, что хочется сделать - либо инстансы, либо разные объекты.
Если нужны разные объекты по приведенному выше алгоритму, то в чем проблема?
Делается скрипт, который случайным образом распределяет модификацию геометрии; ведь алгоритм уже написан выше аффффтором
Только при этом нельзя требовать от маи построить инстансы. Это будут разные объекты, каждый из которых имеет разный шейп.

В принципе, можно сделать еще интереснее - создать разные объекты, которые по истории связаны с одним и тем же шейпом. Тогда и объекты будут разными и при изменении основного шейпа, от которого они зависят, будут меняться и все остальные.
Но даже в этом случае это не будут инстансы, а будут разные объекты.

Так что нужно сначала поставить задачу, и понять, зачем именно так и только потом приступать к ее решению или к формулированию вопроса.

P.S. Если написанное выше не понятно, попробую написать проще. Если объекты должны быть разными, они точно НЕ будут инстансами. А зачем они должны быть инстансами в такой ситуации? Какое свойство инстансов планируется использовать? Может быть это можно решить другим способом?
 

Ro

Знаток
Рейтинг
38
#11
alex_alv, обьяснение исчерпывает, хотя мона было обойтись ответом "парень, ты не прав, инстанс, это "по определению одинаковые объекты. Так как инстансы - это один шейп, который имеет несколько родителей-трансформов."", а потом написать "создать разные объекты, которые по истории связаны с одним и тем же шейпом." и это было бы шикарно : ) не в инстансе было дело, но в итоге мы кажется друг друга поняли. А как это "которые по истории связаны с одним и тем же шейпом"? Как их связать то?
 

alex_alv

Активный участник
Рейтинг
11
#12
Создаете любой полигональный объект.
Затем дублируете его сколько надо раз (не инстансами, а Ctrl-D).
Затем в конекшн едиторе подключаете атрибут outMesh основного объекта к inMesh всех его копий.
Также это можно сделать не в конекшн едиторе, а командами вроде

connectAttr -f pSphereShape1.outMesh pSphereShape2.inMesh;
connectAttr -f pSphereShape1.outMesh pSphereShape3.inMesh;
connectAttr -f pSphereShape1.outMesh pSphereShape4.inMesh;
...

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

Ro

Знаток
Рейтинг
38
#13
alex_alv, подскажи еще плиз, обьекты обязательно должны быть "нулевыми" (без изменений)? У меня если обьект перемещен\масштабирован\повернут - его копии при выполнении скрипта странным образом трансформируются. Фриз трансформ и делит хистори не помогают
 

alex_alv

Активный участник
Рейтинг
11
#14
От трансформации (если они сделаны трансформ-нодой) ничего не зависит. Все должно работать.
Фриз трансформ - не самая лучая идея (поясню в конце).
Если же у объекта был изменен шейп (Вы таскали вершины), то у всех копий следует обнулить координаты всех вершин, и форма геометрии вернется на место (для обнуления - выделить все вершины копии, затем в ченл боксе ткнуть в CSs (click to show), выделить все цифры, нажать 0 и ентер).

На самом деле, тот способ, который я предложил - он не единственный. Можно, например, использовать различные деформаторы для создания истории объекта (например, бленд шейп).

А про способ подконекчивания outMesh попробую объяснить, что происходит.

Когда Вы создаете например полисферу, создается 3 ноды:


polySphere - это нода, котрая на входе имеет параметры сферы (радиус, колиество разбиений и т. п.), а на выходе, в атрибуте outMesh, выдает шейп сферы (шейп выдается в виде координат вершин, номеров вершин, соединенных ребрами (и мягкость/жесткость этих ребер), номеров ребер, которые используются для построения каждого фэйса и юви-шек каждой вершины в каждом фэйсе).

Нода типа mesh (с названием pSphereShape1).
На вход inMesh этой ноды поступает полигональная геометрия (в нашем случае - полисфера, сгенеренная нодой polySphere).
Причем, на вход inMesh ноды mesh не обязательно должна всегда поступать геомтрия. Если разорвать связь inMesh ноды mesh, то нода mesh просто запомнит внутри себя ту геометрию, которая поступала на этот вход непосредственно перед разрывом связи. С момента разрыва связи, нода mesh будет считать, что на ее вход inMesh продолжает поступать та геометрия, которая сохранена внутри ноды. Если восстановить связь (или подключить ее к другой ноде, например, к polyCube), то нода mesh забудет сохраненную геометрию и начнет работать с новой геометрией, поступающей на ее вход inMesh (т. е. сфера превратится в кубик в этом примере).

У этой ноды mesh три задачи.
1) запомнить в своих атрибутах перемещения всех вершин и юви-шек, которые Вы делали на уровне компонент. Эти изменения запоминаются в виде смещений координат, которые можно посмотреть в ченл-боксе, см. выше. Если все координаты равны нулю, то вершины не изменяются и геометрия сохраняет свой первоначальны вид (который поступает на вход inMesh). Естественно, запоминаются, не трансформации всего объекта, а только трансформации всех вершин. Например, если для вершины 0 в ноде хранятся координаты 1, 0, 0, это означает, что вершина 0 сдвинута (по отношению к геометрии на входе inMesh) по координате x на единицу, и не сдвинута по остальным координатам.

2) Применить сохраненные изменения всех вершин к геометрии, поступающей на вход inMesh (или к геометрии, сохраненной в ноде, если inMesh не подлючен) и сформировать новую геометрию (с тем же количеством вершин) на выходе outMesh.

3) При наличии родителя-трансформа и при установленных атрибутах визуализации, визуализировать геометрию, сгенеренную на выходе outMesh ноды mesh.


Третья нода - нода типа transform, которая указывает, в каком месте пространства, в какой ориенации и масштабе следует визуализировать все шейп-ноды (в данном случае - ноду meh), которые являются ее потомками.

Итак, если потаскаете вершины созданной нами сферы, то все изменения сохранятся в ноде mesh в виде относительных смещений всех вершин (т. е. для каждой вершины сохранится 3 числа - изменение по X, по Y и по Z).

Теперь мы дублируем сферу с помощью Ctrl-D.

Получаем новый объект, но он состоит уже из двух нод - ноды transform и ноды mesh.

С нодой transform все понятно.
А нода mesh не имеет подключения на входе inMesh.
Т. о., она считает, что на ее вход поступает то, что поступало туда последний раз. А именно, выход ноды polySphere, т. е. сфера в неизмененном состоянии.
В самой ноде хранятся трансформации всех вершин, произведенных для первой сферы (т. е. при копировании сферы, изменения, произведенные Вами с ее геометрией, не теряются, а копируются вместе с нодой). Если их все обнулить (как я написал выше), то объект превратится в оригинальную сферу.
Но мы этого пока не делаем, а просто подключаем вход inMesh новой сферы к выходу outMesh первой сферы.

Теперь, вторая нода mesh на входе inMesh получает вместо чистой сферы, которая была сохранена в ноде, сферу, которая модифицирована перетаскиванием вершин.
Но в самой ноде также хранятся изменения вершин.
Результат - к чистой сфере изменения вершин, которые Вы производили, применяются дважды.
Выход - обнулить изменения вершин, сделанные во второй ноде mesh (в копии) , и она станет такой же, как первая сфера.
После этого, Вы можете производить над второй сферой требуемые изменения.

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

Надеюсь, доступно объяснил, как это все работает?

Теперь про фриз трансформ.

Здесь есть неоднозначность.
Если у объекта нет истории, то это работает следующим образом:
1) обнуляются все параметры ноды трансформ. Объек перемещается в начало координат.
2) в ноде mesh вносятся изменения в вершины так, чтобы объект вернулся на место.
Т. е. происходит так, как бужто Вы переместите объект вначало координат целиком, а затем, вернете его на место на уровне компонент (т. е. примените обратную трансформацию, но не к объекту, а ко всем его вершинам). Соответствующие перетаскивания вершин после фриза Вы можете увидеть в ченл-боксе, ткнув на CVs (click to show).

Понятно, что в нашей ситуации, это только усугубит проблему.

Если у объекта есть история, то производится примерно тоже самое, но в историю объекта вставляется дополнительная нода, которая выполняет эту обратную трансформацию вершин.

На счет удаления истории.
При удалении истории первой сферы, просто удаляется все, что подключено к inMesh ноды mesh, т. е. рвется связь на inMesh и нода mesh первой сферы продолжает считать, что на ее вход поступает чистая сфера, к которой применяются изменения, сделанные Вами на уровне компонент, и которые хранятся в ноде mesh.
Т. е. грубо, можно сказать, что при удалении истории она удаляется не вся. Остается нода mesh, которая помнит последнюю стадию изменения геометрии и геометрию перед этими изменениями. Удалить эту часть истории уже нельзя из-за такого алгоритма работы ноды mesh (может быть и можно придумать способ удалить и эту часть истории, но пока не было такой задачи и я не думал на эту тему).
 

alex_alv

Активный участник
Рейтинг
11
#15
Вот пример такого скрипта, который вычитает изменения копии из изменений оригинала.
В первой строке задается имя оригинала, во второй - имя копии.
Количество (и нумерация) вершин должно быть одинаковым.
Скрипт должен работать только один раз (при запуске два раза, изменения оригинала будут вычтены из изменения копии дважды).
Скрипт легко переделать для работы с несколькими выделенными объектами.
Аналогичную историю можно написать и для UV-шек

string $originalShape="pSphereShape1";
string $copyShape="pSphereShape2";

int $vcount[]=`polyEvaluate -v $originalShape`;
int $i;
float $coord1, $coord2;

for($i=0;$i<$vcount[0];$i++)
{
$coord1=`getAttr ($originalShape+".pnts["+$i+"].pntx")`;
$coord2=`getAttr ($copyShape+".pnts["+$i+"].pntx")`;
setAttr ($copyShape+".pnts["+$i+"].pntx") ($coord2-$coord1);

$coord1=`getAttr ($originalShape+".pnts["+$i+"].pnty")`;
$coord2=`getAttr ($copyShape+".pnts["+$i+"].pnty")`;
setAttr ($copyShape+".pnts["+$i+"].pnty") ($coord2-$coord1);

$coord1=`getAttr ($originalShape+".pnts["+$i+"].pntz")`;
$coord2=`getAttr ($copyShape+".pnts["+$i+"].pntz")`;
setAttr ($copyShape+".pnts["+$i+"].pntz") ($coord2-$coord1);

}
 

alex_alv

Активный участник
Рейтинг
11
#16
(хотя для UV скорее всего такой скрипт не потребуется, так как если у объекта есть история, то по-моему, для хранения изменений UV создаютя отдельные ноды, а если истории нет, то изменения сохраняются в геометрии inMesh, но я могу и ошибаться)
 

alex_alv

Активный участник
Рейтинг
11
#17
Однако, если до подключения истории у копий были изменены UV, и эти изменения требуется сохранить, то скорее всего, потребуется подобный скрипт, но он должен будет выполнять обратную операцию и результат сохранять не в ноду типа mesh, а создавать новую ноду типа polyTweakUV и заносить эти изменения в нее.
Причем, работать этот скрипт должен будет до подключения истории, так как иначе, информация об изменениях UV будет утеряна. Более того, подключение истории должно будет производиться не к шейпу копии, а к ее ноде polyTweakUV
 
Сверху