Альтернативный экспорт модели из DAZ Studio в 3Ds Max по средствам скриптов и модуля Morph-O-Matic

Всем привет. Предлагаю вашему вниманию новый урок по переносу анимированной модели из DAZ Studio в 3D Max с использованием морфов. Для начала в общих чертах о том что это такое и для чего. В своем предыдущем уроке я рассказал о переносе модели через формат FBX. У данного метода есть свои преимущества и недостатки. Плюс в том что во первых все очень просто а во вторых мы получаем непосредственно анимированную в максе модель со скином, костями и фулбоди морфами ( здесь сразу поясню, поскольку этот урок по скриптам он не для новичков по этому пояснять что такое морф и другие вещи по которым и так достаточно информации а так-же азы работы с программами я не буду). Теперь о недостатках. Дело в том что в дазе дополнительно работает специальный аппарат поправляющий геометрию модели при ее анимации. К сожалению этот аппарат через fbx не переносится а без него анимация особенно в экстремальных позах мягко говоря не очень а грубо говоря гуано. В данном уроке я перенесу модель через морфы, цели для которых мы будем вытаскивать из даза и забрасывать их в макс. В итоге получим сетку в максе анимированную морфом и полностью соответствующую дазовской но строить анимацию нужно будет через DAZ. В целом некий аналог PoserFusion только без него. Если вы заинтересовались то продолжим.

И так по-скольку самая сложная часть урока это скрипты то он в основном будет посвящен им. Но не пугайтесь те кто со скриптами вообще незнаком они будут весьма простые и их написание я постараюсь попроще разжевать. Один скрипт для DAZ Studio на языке DazScript 2 и один для макса на Max Script соответственно. Из софта в уроке будет использоваться DAZ Studio 4.5 Pro, 3ds Max 2013 а так-же модуль Morph-O-Matic (по сути тот-же Morpher только лучше). Он входит в состав набора Di-O-Matic Pro (весьма интересная для максового аниматора вещь). Где взять думаю сами знаете. Начинаем с даза. Открываем его и загружаем Genesis или любую дазовскую модель. Выбираем ее заходим в параметры и выставляем разрешение сетки Base если оно не стоит. Минимальное разрешение а значит быстрее работа с моделью, экспорт/импорт и меньше файлы. Далее нужно зайти в меню File/Export задать путь имя файла и тип obj и выбрать сохранить. Вылезут опции экспорта где нужно снять галочку Write Surfaces. Материалы нам в данном случае не нужны т. к. речь не о них а это поможет сократить время экспорта. Применяем и сохраняем файл. Для чего мы это делаем. Мы будем писать скрипт для так называемого тихого экспорта, который не запрашивает опции экспорта а берет существующие. По этому мы их заранее и прописываем. Далее можно создать анимацию и приступать ко скрипту. Процесс построения анимации модели я пропущу по-скольку урок о другом. Скажу только что для титульного видео я воспользовался модулем aniMate2. Работа с ним стандартна (позы и ключи) и сложностей не вызывает. Можно взять и готовые пресеты. Итак будем считать что анимация модели у вас имеется и переходим к скриптам.


 

 

Первым по счету у нас идет DAZScript но перед тем как приступить непосредственно к написанию скриптов я расскажу о базовых принципах которые для этого использую. Во-первых скрипт это мини программа написанная для другой программы (даз студио и макс в данном случае), которая и выполняется там через встроенный редактор (интертритатор) скриптов. Т.е. выполнение команд скрипта суть действия самой программы. По-этому прогер пишущий скрипт должен знать работу самой программы то-есть понимать какие действия к чему приводят. Во вторых для написания скрипта нужно знать так называемый синтаксис языка на котором вы его пишите. Ну это собственно что и как писать. Для получения этой информации необходимо воспользоваться официальной справкой программы по скриптам, благо таковая имеется у каждой серьезной скриптуемой программы. Есть она и у макса с дазом. О максе позже а у даза чтобы в нее попасть нужно открыть редактор скриптов, меню Window\Tabs\Script IDE. В нем жмем Help и ждем открытия страницы (и-нет должен быть подключен). Открывшаяся страница представляет собой центр документации даза. Здесь сразу поясню одну тему. Последняя DAZ Studio скриптуется на новом языке DAZScript2. Документация по нему еще полностью не готова, о чем они пишут на странице в зеленом фоне. Там же указано где взять мануал к предыдущему DAZ Script. Он нам вполне подходит по-этому кликаем here и далее качаем DAZ Script API. Это и есть архив с нашей справкой. И в третьих по-скольку скрипт это алгоритм то-есть последовательность действий, приводящих к определенному результату, пишущий скрипт должен уметь или знать как эту последовательность составить. Для этого необходимы базовые (как минимум) знания о принципах построения скриптов, базовые (как минимум) знания математики и умение мыслить логически. В данном уроке я затрагиваю лишь часть этих знаний но на конкретном примере. С них собственно и начнем.

И MaxScript и DazScript относятся к так называемым интерпретируемым языкам. Это значит что они пишутся специально подготовленными командами, которые программа затем переводит в нужный ей код. Это сделано для удобства написания. По сути скрипт есть текстовый файл с определенной информацией и писать его можно в любом текстовом редакторе но выполнять только в редакторе скриптов проги для которой он пишется. В нем-же (редакторе скриптов) можно и писать, что обычно еще удобнее так-как в нем существуют помогающие темы (о них позже). Сам скрипт делится на две зоны. Зона ввода команд скрипта и зона комментариев. Их разница исходит от их определения. Любой символ написанный в зоне команд имеет значение (пробелы не учитываются) в то время как в зоне комментов вы можете писать все что угодно, хоть иероглифы. Программа все это тупо пропускает. Эта зона отделяется специальными символами и пишется для себя или для любого читающего скрипт, и целесообразнее там и писать комментарии к командам скрипта. В DAZ Script отделение комментариев осуществляется или двойной косой чертой ( // ). Это используется когда пометка составляет одну целую строку скрипта и ставится в начале строки. Все что следует за этим символом и до конца строки является комментарием. Или применяются одинарные косые, ставящиеся в начале и конце пометки. Это используется когда комментарий вставляется в строку или является многострочным. Так-же хочу пояснить смежный момент написания. Дело в том что в скрипте существуют так называемые строковые величины. Они тоже отделяются спец. символами (кавычками) и в них тоже можно писать что угодно (если позволит совместимость шрифтов) но это не комментарии и они определяются к выполнению скриптом и это надо понимать. В основном скриптование это математика и логика и многие правила оттуда и перешли (математические и логические операции) но есть и принципиальные различия. Одно из главных это знак равно ( = ). В скрипте он означает не равенство а присвоение (то что справа от знака присваивается тому что слева) То-есть в скрипте выражение n = n + 1 (невозможное в математике) означает что после его выполнения n станет больше на единицу. Это тоже надо четко понимать. Еще одно важное отличие от математики это переменные. В скрипте это более широкое понятие. Для того чтобы задать переменную в скрипте достаточно написать ее имя. Имя должно начинаться с латинской буквы, содержать латинские - же буквы и цифры и быть отличным от написания команд скрипта. После задания переменной ей можно присвоить ( знак равно ) значение. Оно может быть любым от константы до строковой величины или объекта сцены. Строка var n = "String" создаст переменную n и присвоит ей строковое значение String. var это команда задания переменной. Вы это можете проверить скопировав и вставив строку в Script IDE и после нажав Execute (выполнить). Буква n вбитая строкой ниже после выполнения вернет в графе Result наше строковое значение. Если переменная создана но не назначена то ей автоматом присваивается значение undefined. Для разнообразия можно поиграться с созданием и присвоением значений переменным, что-бы лучше понять как это работает.

Другая важная часть скрипта это функции. В DAZ Script чтобы создать функцию нужно вбить команду function. Далее нужно поставить имя функции. Здесь правила такие-же как и у имени переменных. После вы можете присвоить этому имени стандартную функцию или организовать собственную. Следует пояснить что строка создания функции не является строкой выполнения функции. Выполнятся функция будет при ее вызове (вбивании ее имени). В скриптах данного урока функции использоваться не будут и на этом с ними я закончу дабы излишне не усложнять его и не перегружать вам мозг. Следующая важная и интересная часть скриптов это множества и массивы (в дазе они обзываются словарями но я их буду называть как в максе - массивами). С множеством все понятно. Это простой набор чего бы-то не было. Массив штука более сложная и чаще используемая. Массив это пронумерованное множество, каждый элемент которого обладает собственным номером (индексом ) по которому к нему (элементу массива) может быть осуществлен моментальный доступ. Чтобы лучше это понять массив можно представить как шкаф с ящиками, у каждого из которых есть свой номер. В ящиках может лежать все что угодно, так и элементы массива могут быть любыми (константы, переменные, объекты сцены, аргументы команд и т.д.). Массиву также создается собственное имя. Если имя массива - A то выражение A[n] означает энный элемент массива А. Массивы так -же в скриптах урока не используются и с ними я на этом закончу. Следующая и самая важная на мой взгляд часть скрипта это собственно сами команды скрипта. С двумя из них для DAZ Script мы знакомы ( var и function). Каждая команда имеет собственное имя. При его верном написании в редакторе оно подсвечивается цветным шрифтом. Если этого не произошло то команда вбита неверно и строка вызовет ошибку при выполнении. Это и есть один из помощников, упомянутых мной ранее. Имя команды может стоять как в начале строки так и после определенного символа (точки например). После имени идет список параметров команды (так называемых аргументов). Он может быть пуст. Тогда команда выполнится с параметрами по умолчанию. Например команда Box() в максе создаст ящик по умолчанию в центре координат. Но если мы поставим координаты в скобки то ящик создастся в нужном месте. Нужно учитывать что многие команды требуют наличие строгого определенного количества строго определенных аргументов, и их нехватка или лишние то-же вызовут ошибку. Основой наших скриптов будет команда цикла For. Это одна из самых распространенных команд. Подробнее о ней я расскажу в ходе описания самих скриптов, перед которым скажу о еще одном немаловажном аспекте. Если мы посмотрим на рис 6 то увидим серую зону внизу. Это зона сообщений скрипт-редактора .Здесь указывается время выполнения скрипта, результат если таковой имеется, а так-же строка и вид ошибки если она произошла в ходе выполнения. Это ценная информация для отладки скрипта и на нее нужно обращать внимание.

Теперь приступаем к самому процессу написания скрипта для DAZ Studio. Напомню мы имеем анимированную модель. Нам нужно выполнить экспорт модели в obj формат в каждом энном кадре. Как бы мы это делали в ручную? Мы бы двигали таймслайдер, делали экспорт, снова двигали снова экспорт и т. д. Даже для пятисекундной анимации замумукаешся но именно на этих действиях построен алгоритм нашего скрипта, который будет выполнять их автоматом. Для этого мы и применим команду цикла for. Что-же собственно делает эта команда. Она повторяет заданное количество раз все действия находящиеся в зоне цикла. Действий у нас будет два, сдвиг слайдера времени и экспорт. Вот собственно и вся не хитрая схема, в ходе дальнейшего разбора вы ее поймете глубже. По-скольку алгоритм мы придумали переходим к его реализации (написанию скрипта). Я выложу его сразу весь а потом буду разбирать по строкам.

// DAZ Studio version 4.5.1.56 filetype DAZ Script
var t = 0
var oExportMgr = App.getExportMgr()
var oExporter = oExportMgr.findExporterByClassName( "DzObjExporter" )
var oSettings = new DzFileIOSettings()
oSettings.setIntValue( "RunSilent", 1 )
for( var i = 0; i < 3; i += 1 ){
Scene.setFrame(t)
oExporter.writeFile( "E:\\content\\obj\\" + "Genesis" + String(i) + ".obj" , oSettings )
t = t + 5
}

Вот собственно и весь скрипт. Для выполнения его нужно скопировать в скрипт-редактор даза и подставить свои аргументы. А теперь начнем разбор полетов. Первая строка как видно из начального символа - // это комментарий. Второй строкой мы создаем переменную t и присваиваем ей значение ноль. Эта переменная будет определять положение слайдера времени и мы задаем ее начальное значение. Оно должно соответствовать началу анимации т. к. в этом кадре будет осуществлен первый экспорт. В третьей строке мы создаем новую переменную oExportMgr и присваиваем ей команду получения модуля экспорта из даза App.getExportMgr(). Ну тут думаю смысл понятен - чтобы работать с экспортом нужно его в скрипте определить. Но вытаскивания одного менеджера экспорта не достаточно. Нужно еще определить вид экспорта (obj) и параметры чем и занимаются следующие строки. Четвертая строка создает переменную oExporter и присваивает ей команду получения экспортера obj из нашего модуля экспорта findExporterByClassName . Данная команда пишется через точку после самого модуля. Аргументом для нее служит строковое значение "DzObjExporter" собственно и определяющее класс экспорта. Пятая строка создает переменную oSettings и присваивает ей команду получения так называемого объекта установок даза DzFileIOSettings(). Команда new служит для создания нового экземпляра установок. Из самих установок экспорта у нас в данном случае только одна - запуск тихого режима (это режим который сделает все автоматом по заданным параметрам ничего более не запрашивая). Его осуществляет команда setIntValue, которая пишется в следующей строке через точку после нашего объекта установок. Аргументами для нее являются строковое значение "RunSilent" и единица, говорящая о включении данного режима. Можно сказать все необходимые параметры мы определили и далее следует сам цикл т.е. седьмая строка это его команда for. Данная команда выполнит все что находится в фигурных скобках под ней (зона цикла) столько раз сколько заложено границами цикла, которые создаются при помощи так называемой переменной цикла. Аргументом для команды For и служит данная переменная i, по которой он и будет проходить. Мы задаем ее первое значение (начало цикла) i = 0, через точку с запятой задаем конец цикла i < 3 (т.е. 2) а так же шаг цикла i += 1 (или i = i +1). Данное выражение указывает что i на каждом шаге цикла будет прибавляться на единицу. В целом эти значения говорят что цикл будет проводиться три круга . На первом i = 0, на втором i = 1 и на третьем i = 2. (Здесь поясню, я взял границы цикла от 0 до 2 для примера. Вам конечную границу нужно будет установить исходя из длины вашей анимации и шага экспорта). Далее следует сама область цикла заключенная в фигурные скобки. В ней мы с начала прописываем команду установки таймслайдера Scene.setFrame. Аргументом для нее служит переменная t, которая на первом шаге цикла у нас равна нулю. После следует строка команды экспорта oExporter.writeFile. У нее два аргумента. Первый это строковое значение с путем для создания файла. Путь указывается полный, вместе с именем и расширением. Здесь у нас идет определенная хитрость. Дело в том что мы должны придать файлу, создаваемому на каждом шаге цикла индивидуальное имя чтобы они не накладывались. По этому к имени мы будем приплюсовывать переменную цикла i, которая на каждом шаге своя. Для этого мы сделаем составное строковое выражение. Первая часть это путь до имени, заканчивающийся косой чертой ( косая черта в строковом выражении создается двойной косой). Вы должны понимать что путь у вас будет свой. Далее через плюс идет строка имени файла. У меня это "Genesis" у вас может быть свое. Далее так же через плюс команда String. Данная команда создает строку из своего аргумента, а аргументом для нее ставим переменную цикла i. И последним идет строка с расширением после точки ".obj". Данное сочетание в совокупности и оформит наш путь. Вторым аргументом для команды writeFile служат установки экспорта т.е. переменная oSettings. Предпоследней строкой идет выражение наращивающее переменную t -- Ћt = t + 5Л. После ее исполнения t будет увеличиваться на нужную нам величину (пять кадров в моем случае) и соответственно команда Scene.setFrame(t) на следующем шаге цикла передвинет временной слайдер на эту-же величину а последующая строка сделает там экспорт (для этого и нужен был цикл).И последней строкой идет фигурная скобка, закрывающая зону цикла. Надеюсь я доходчиво объяснил и вы во всем разобрались. Вам остается только подставить свои значения а именно начальное значение пер. t (соотв. началу анимации), лимитируещее значение переменной цикла i (то которое у меня тройка). Его вы посчитаете исходя из требуемого кол-ва файлов ( длина анимации деленная на шаг), сам шаг таймслайдера (который у меня пятерка) и ваш путь. И еще перед выполнением скрипта если в сцене много объектов то для экспорта нужных остальные можно просто скрыть, закрыв ихний глаз в меню Scene. Если все правильно то после выполнения скрипт начнет тихий экспорт файлов с текущими настройками даза. Если в скрипте ошибка то редактор выдаст сообщение о ней. Посмотрите на него, подумайте и устраните ошибку и если у вас это получилось то можно идти дальше. Что касается DAZ Script то для его более подробного изучения рекомендую все ту-же справку. На странице офф. справки находится много примеров с разбором и много другой полезной инфы (правда все на инглиш).

Итак, результатом работы нашего скрипта должен стать пронумерованный набор obj файлов. Если это получилось то можно идти далее то-есть наконец переходить к максу. Для начала кратко о последовательности действий а она в принципе не хитра. Мы импортируем модель из даза через obj в исходной т-позе. Наложим на нее модификатор Morph-O-Matic (уже скриптом) загрузим наши obj формы анимированной модели и пропишем их как цели для морфа. Вот собственно и все. Для начала установите модуль Di-O-Matic если у вас его еще нет. Из него мы возьмем модификатор Morph-O-Matic, улучшенная версия морфера в которой к примеру неограниченное число морфов. Далее вам нужно экспортировать из ДАЗа и импортировать в МАКС нашу модель в исходной позе через OBJ формат. Как это сделать думаю уже знаете да это в принципе и не сложно. Дополнительно отмечу лишь что геометрия исходной формы должна быть аналогична геометрии целей по числу вершин и полигонов, иначе ничего не получиться. Другими словами если в начале урока вы брали голую модель без одежды и прибамбасов то она так и должна остаться без них. Для них можно будет сделать другой перенос по аналогии. Также приведу свои настройки в меню импорта. Далее выбираем появившуюся в видовых окнах модель и приступаем к написанию скрипта.

Для этого в максе есть два инструмента (не считая справки по скриптам) Это MaxScriptEditor в котором собственно пишется и исполняется скрипт и MaxScriptListener в котором отображаются результаты выполнения (или не выполнения ) скрипта а так-же его ошибки, если скрипт не прошел, что очень помогает в работе. Чем хорош MaxScriptEditor. В нем правильно написанные команды подсвечиваются разными цветами, что тоже помогает в написании. Теперь привожу сам скрипт и далее его разбор.





modPanel.addModToSelection (Morph_O_Matic())
a =modPanel.getCurrentObject()


for i = 1 to 6 do
(
importFile ("E:\content\obj" +"\\" +"Genesis" + i as string +".obj" ) #noPrompt
obj = getCurrentSelection()
obj. name = "Genesis"
m = i + 1
MOM_MC_InsertTarget a [1] m $Genesis
delete obj
)

Текст можно сразу скопировать в MaxScriptEditor и увидите как он раскрасится. Теперь по порядку начиная с первой строки в редакторе. Символ в ее начале Ћ--Л говорит что это комментарий. Вторая строка. Ее синяя часть это команда, накладывающая на выделенный объект модификатор. Ее первая часть (та что до точки) modPanel Вызывает стек модификаторов вторая (после точки) addModToSelection добавляет модиф. на выделенный обьект. (сразу поясню если ничего не выбрано то команда выдаст ошибку). Зеленая часть это аргумент команды. В данном случае он пишется в кавычках. Здесь конкретнее название нашего мод-ра Morph_O_Matic(). Дополнительные кавычки в конце аргумента означают настройки мод-ра по умолчанию. Третьей строкой мы создаем переменную а (имена переменных не подсвечиваются) и присваеваем ей наш модификатор командой modPanel.getCurrentObject() Вторая часть которой говорит что будет взят текущий (он же последне-созданный) модификатор. Теперь напечатав в скрипте ЋаЛ мы обратимся к нему. Шестой строкой мы создаем цикл командой for i = 1 to 6 do, что можно перевести как - для каждой i от 1 до 6 нужно сделать ( а что сделать пишется в теле цикла) i это переменная цикла 1 и 6 начало и конец цикла( эти цифры взяты для примера, у вас они должны соответствовать начальному и конечному номеру экспортируемых obj файлов.). Далее следует область цикла, которая начинается и заканчивается скобкой. После скобки следует команда импорта. Ее аргументы это путь для импорта в скобках. Его написание аналогично дазовскому с некоторыми поправками. Символ "\\" означает что в путь добавится только одна косая черта. Выражение i as string добавит в имя файла цифру, которая соответствует переменной i на данном шаге цикла. Второй аргумент - выражение #noPrompt оэначает что будет произведен тихий импорт без запроса, с имеющимися на данный момент настройками в меню импорта. Девятая строка создает переменную с именем obj которой присваивается текущий выделенный объект командой getCurrentSelection(), а этим объектом и будет как раз последняя импортированная геометрия. Десятая строка придает этому объекту имя. Ну тут думаю все понятно. Дело в том, что импортируемуму объекту будет присвоено имя по умолчанию, а нам надо его переименовать для последуещего обращения к нему. При выполнении данной команды меняется имя объекта на то что написано в кавычках, что сразу отображается на панели инструментов. Следующая строка создает переменную m, используемую для последующей строки. Эта переменная будет на единицу больше чем переменная цикла i ( за чем об этом далее). Двенадцатая строка создает цель для нашего модификатора Morph-O-Matic по средствам команды MOM_MC_InsertTarget. Аргументами для нее служат во первых сам мод-тор, то-есть наша переменная а. Далее идет цифра один в квадратных скобках, говорящая что будет выбран первый канал для цели (надеюсь вы понимаете о чем речь). После следует переменная m, которая на первом шаге цикла будет равна двум. Она означает что будет создана вторая цель для первого канала (первой по умолчанию служит сам оригинальный объект). Последним аргументом идет сам объект для цели. Символ $ перед именем означает что будет взят объект сцены с именем следующим за ним. Предпоследняя строка удаляет импортированный объект. Цель создана, мод-тор сделал запись в своем реестре и он больше не нужен, чтоб не загрезънять сцену. Последняя строка закрывает цикл ( не забывайте об этом при создании сложных циклов). Следующий шаг цикла импортирует следующий файл и создаст третью цель по этому файлу и так пока он(цикл) не пройдет то-есть не кончится переменная цикла i. Вот собственно и все. Результатом выполнения скрипта (если вы все сделали правильно) будет создание канала мод-ра Morph-O-Matic с целями из всех созданных в Дазе файлов. Анимация веса канала приведет к анимации модели аналогичной Дазовской. Нужно учитывать что созданный объект - это полноценная максовая геометрия со всеми вытекающими (можно накладывать одежду, работать с физикой и тп.) Но есть и минусы - к объекту нельзя применить кости для анимации т.к. он уже анимирован морфом.
На последок скажу что скрипты приведенные мною это рабочие примеры для изучения языка. Поняв (надеюсь) как они работают вы можете модифицировать их по своему желанию. Изменить команды или аргументы. Для ознакомления с коими можно воспользоватся офф. справкой, которая является самым полноценным документом. У макса так она ваще супер. При написании скрипта важна не только конечная цель, хотя она конечно на первом месте но и путь достижения этой цели. Он должен быть как можно более кратким (оптимизироапнным) чтобы машина не захлебнулась в расчетах. По этому перед написанием скрипта надо продумать его структуру а в процессе написания размышлять над улучшением. Но это уже после изучения основ. Если возникнут вопросы к уроку пишите с комментариях - постораюсь ответить. Желаю успехов. 

194 0 850 3
5
2014-03-05
неужели ЭТИМ еще кто то пользуется?
2014-03-06
Skif, вы шо) Экспортить голых девушек бесценно :D! Ну по правде и правда, зачем это?
2014-04-03
"по средствам скриптов"... и запятые в русском языке никто не отменял... Как же задолбала тотальная безграмотность!
2018-12-13
Лучше вообще ничего не делать чем такое мутить да еще с какими то непонятными скриптами.
2021-10-08
Все, кто комментил до сих пор, по всей видимости, великие цифровые художники, которым нефиг делать слепить любого перса для каждого конкретного случая. А я вот простой моушн-дизайнер, и давно искал способ экспортировать анимацию из DAZ в Синему. Теперь все отлично работает и огромный решпект автору!
RENDER.RU