Есть несколько mesh'ев. У каждого свой модификатор skin. Вроде бы простая задача: объединить все объекты в один и сохранить при этом skin и все bone weights. Но у присоединяемых объектов всегда сбрасываются все данные в модификаторе skin. Как быть?
ChebuПисал скрипт для объединения двух объектов с модификатором скин в один.
примечания: кости не должны совпадать по именам, иначе будут глюки.
О. Практически оно. Спасибо, работает! Но блин, у меня как раз объекты с одинаковыми костями... У вертексов с одинаковыми костями веса пропадают. Реально ли доработать скрипт?
Едрён батон.
Работает ведь!
Большое спасибо, Chebu.
Только почему то старый скрипт присосался к Максу, несмотря на то, что я старый *.mcr удалил и заменил на новый. Так и висит под категорией AndreyK. Поэтому сначала запускался старый скрипт. Думал, опять не повезло. Пришлось в доработанном скрипте категорию переименовать в AndreyK2. Странно.
Еще проблема.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся. К примеру, у двух смежных вертексов такие веса:
Насколько я понимаю, Max пытается усреднить значения. Но зачем их усреднять, если они идентичные? Все равно, что взять две единицы и попытаться их "усреднить". Идиотизм, короче.
Выход из проблемы нашел в использовании SkinUtilities.
То бишь, сначала соединяю все, что нужно с помощью скрипта от Chebu. Затем юзаю комманду Extract Skin Data To Mesh на полученном объекте. Потом делаю WELD всех вертексов (веса у смежных вертексов портятся). И в конце концов восстанавляваю правильные веса с помощью Import Skin Data From Mesh.
Еще проблема.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся.
теоретически, можно попробовать перед велдом снять в скине галку always deform, а после велда поставить обратно. save-load весов тоже может помочь.
Chebu, только что заметил кое-что еще.
При соединении нескольких объектов, дублируются envelope'ы. Допустим, три объекта, у каждого общая кость bone01. Соединяешь их - получаешь сразу три bone01 в списке модификатора skin. Одна из них нормальная, две остальные с нулевыми influences. Можете сделать, чтобы скрипт автоматом сносил лишние envelope'ы? Или может на что-то нажать можно? Кнопку remove zero weights вижу. Кнопку, типа, remove envelopes with zero influences не вижу. 🙁
Постоянно приходится отсоединять/присоединять объекты (ввиду особенности модели). Пустые envelope'ы плодятся в бешенном темпе.
Chebufirsak, поправлю в понедельник, когда до рабочего компьютера доберусь.
Нет ли каких-нибудь сподвижек в шлифовании скрипта? 🙂 В принципе, и так уже хорош (не знаю, что бы я без него делал), но все же один баг присутствует (дублируются envelopes с разных объектов).
firsakЕсть несколько mesh'ев. У каждого свой модификатор skin. Вроде бы простая задача: объединить все объекты в один и сохранить при этом skin и все bone weights. Но у присоединяемых объектов всегда сбрасываются все данные в модификаторе skin. Как быть?
Есть немного странный способ, но работает на 100%
Скачиваете ActorX importer (скрипт для 3DMAX), и ActoX exporter (Плагин для 3D Max)
Устанавливате плагин, он появляется в утилитах.
Експортите сцену со всеми мешами и скинами. В файл формата PSK.
Далее очищаете сцену и импортите этот PSK с помощью скрипта ActorX importer.
Все! Сцена из одного меша. Все скины сохранены. Удачи.
А у меня, вроде, и без утилит получилось.
Weight Tool может скопировать в буфер веса выделенных вершин присоединяемого скина.
Так что, потом можно эту геометрию приаттачить к главной геометрии с главным скином и кости, ему же те добавить.
Отрыть уже этот главный Weight Tool, выделить те же вершины и, - paste.
Энвелопы, правда не сохраняются...наверное, из-за того, что у них свой копипаст.
А можно поподробнее о ActorX importer? А то у меня не получается импортить, вываливается окно с ошибкой. Skin Utilities хорош для объединения двух мешей, но он не всегда корректно переносит веса.
Доступ к резюме доступен только по пакетному доступу HR менеджерам зарегистрированных компаний. Узнать о вариантах корпоративных пакетов можно по ссылке.
firsak
Vertalet
firsak
Chebu
примечания: кости не должны совпадать по именам, иначе будут глюки.
код:
macroscript mergeSkinObjects category:"AndreyK" ( fn fnMergeSkinObjects objectsList refFrame = ( ObjSkinVertices = #() bonesList = #() struct sSkinVertex (bonesCount,bonesID,bonesWeight) --1 setCommandPanelTaskMode #modify bonesOffset = 0 for obj in objectsList do ( select obj skinMod = undefined for i=1 to obj.modifiers.count do ( if (classof obj.modifiers[i] == Skin) do skinMod = obj.modifiers[i] ) if(skinMod != undefined) then ( --modPanel.setCurrentObject skinMod vertices_count = skinOps.GetNumberVertices skinMod for i = 1 to vertices_count do ( newSkinVertex = sSkinVertex 0 #() #() newSkinVertex.bonesCount = skinOps.getVertexWeightCount skinMod i for j = 1 to newSkinVertex.bonesCount do ( Append newSkinVertex.bonesID ((skinOps.getVertexWeightBoneID skinMod i j)+bonesOffset) Append newSkinVertex.bonesWeight ( skinOps.getVertexWeight skinMod i j ) ) append ObjSkinVertices newSkinVertex ) bones_count = skinOps.GetNumberBones skinMod bonesOffset += bones_count for i = 1 to bones_count do ( appendifunique bonesList (skinOps.GetBoneName skinMod i 0) ) )-- if(skinMod != undefined) else deleteItem objectsList (findItem objectsList obj) )--for obj in objectsList --2 at time refFrame ( skinobj = box prefix:"skinobj_" convertto skinobj editable_poly polyop.deleteVerts skinobj #{1..8} for newElement in objectsList do ( polyop.attach skinobj newElement ) --3 skinMod = skin() addModifier skinobj skinMod skinMod.bone_limit = 4 --todo - find maximum bone_limit in all objects skinMod.weightAllVertices = false select skinobj setCommandPanelTaskMode #modify --modPanel.setCurrentObject skinMod for BoneName in BonesList do ( skinOps.addbone skinMod (GetNodeByName(BoneName)) 1 ) skinOps.Invalidate skinMod 0 skinOps.SelectBone skinMod 1 --4 vertices_count = skinOps.GetNumberVertices skinMod for i = 1 to vertices_count do ( skinOps.SetVertexWeights skinMod i ObjSkinVertices[i].bonesID[1] 1 skinOps.SetVertexWeights skinMod i ObjSkinVertices[i].bonesID ObjSkinVertices[i].bonesWeight ) )--at time refFrame )--fn fnMergeSkinObjects on execute do ( objectsList = selection as array if(objectsList.count>0) do try ( fnMergeSkinObjects objectsList 0 ) catch() ) )--macroscriptfirsak
Chebu
firsak
Одни и те же кости. Разных костей с одинаковыми именами нет.
Допустим, имеем: 3 объекта. верхняя губа, нижняя губа, голова.
Поставил keyframe на 50-м кадре (открыл рот).
Выделяю губы, жму на кнопку mergeSkinObjects (голову не трогаю), получаю:
У нижней губы исчезают почти все bone weights. Undo.
Теперь уже выделяю все три объекта, жму mergeSkinObjects, результат:
Все объекты - editable poly, с одним модификатором (skin).
Юзаю 3ds max 2008 x64. Куда копать?
Chebu
ок, понял, допилю.
Chebu
macroscript mergeSkinObjects category:"AndreyK" ( fn fnMergeSkinObjects objectsList refFrame = ( ObjSkinVertices = #() bonesList = #() struct sSkinVertex (bonesCount,bonesID,bonesWeight) --1 setCommandPanelTaskMode #modify bonesOffset = 0 for obj in objectsList do ( select obj skinMod = undefined for i=1 to obj.modifiers.count do ( if (classof obj.modifiers[i] == Skin) do skinMod = obj.modifiers[i] ) if(skinMod != undefined) then ( --modPanel.setCurrentObject skinMod vertices_count = skinOps.GetNumberVertices skinMod for i = 1 to vertices_count do ( newSkinVertex = sSkinVertex 0 #() #() newSkinVertex.bonesCount = skinOps.getVertexWeightCount skinMod i for j = 1 to newSkinVertex.bonesCount do ( Append newSkinVertex.bonesID ((skinOps.getVertexWeightBoneID skinMod i j)+bonesOffset) Append newSkinVertex.bonesWeight ( skinOps.getVertexWeight skinMod i j ) ) append ObjSkinVertices newSkinVertex ) bones_count = skinOps.GetNumberBones skinMod bonesOffset += bones_count for i = 1 to bones_count do ( append bonesList (skinOps.GetBoneName skinMod i 0) ) )-- if(skinMod != undefined) else deleteItem objectsList (findItem objectsList obj) )--for obj in objectsList --2 at time refFrame ( skinobj = box prefix:"skinobj_" convertto skinobj editable_poly polyop.deleteVerts skinobj #{1..8} for newElement in objectsList do ( polyop.attach skinobj newElement ) --3 skinMod = skin() addModifier skinobj skinMod skinMod.bone_limit = 4 --todo - find maximum bone_limit in all objects skinMod.weightAllVertices = false select skinobj setCommandPanelTaskMode #modify --modPanel.setCurrentObject skinMod for BoneName in BonesList do ( skinOps.addbone skinMod (GetNodeByName(BoneName)) 1 ) skinOps.Invalidate skinMod 0 skinOps.SelectBone skinMod 1 --4 vertices_count = skinOps.GetNumberVertices skinMod for i = 1 to vertices_count do ( skinOps.SetVertexWeights skinMod i ObjSkinVertices[i].bonesID[1] 1 skinOps.SetVertexWeights skinMod i ObjSkinVertices[i].bonesID ObjSkinVertices[i].bonesWeight ) )--at time refFrame )--fn fnMergeSkinObjects on execute do ( objectsList = for obj in selection where (superclassof obj ==GeometryClass) collect obj if(objectsList.count>0) do try ( fnMergeSkinObjects objectsList 0 ) catch() ) )--macroscriptfirsak
Работает ведь!
Большое спасибо, Chebu.
Только почему то старый скрипт присосался к Максу, несмотря на то, что я старый *.mcr удалил и заменил на новый. Так и висит под категорией AndreyK. Поэтому сначала запускался старый скрипт. Думал, опять не повезло. Пришлось в доработанном скрипте категорию переименовать в AndreyK2. Странно.
Еще проблема.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся. К примеру, у двух смежных вертексов такие веса:
А если их объединить, то получается бред:
Или:
было
стало
Насколько я понимаю, Max пытается усреднить значения. Но зачем их усреднять, если они идентичные? Все равно, что взять две единицы и попытаться их "усреднить". Идиотизм, короче.
Выход из проблемы нашел в использовании SkinUtilities.
То бишь, сначала соединяю все, что нужно с помощью скрипта от Chebu. Затем юзаю комманду Extract Skin Data To Mesh на полученном объекте. Потом делаю WELD всех вертексов (веса у смежных вертексов портятся). И в конце концов восстанавляваю правильные веса с помощью Import Skin Data From Mesh.
Chebu
теоретически, можно попробовать перед велдом снять в скине галку always deform, а после велда поставить обратно. save-load весов тоже может помочь.
firsak
При соединении нескольких объектов, дублируются envelope'ы. Допустим, три объекта, у каждого общая кость bone01. Соединяешь их - получаешь сразу три bone01 в списке модификатора skin. Одна из них нормальная, две остальные с нулевыми influences. Можете сделать, чтобы скрипт автоматом сносил лишние envelope'ы? Или может на что-то нажать можно? Кнопку remove zero weights вижу. Кнопку, типа, remove envelopes with zero influences не вижу. 🙁
Постоянно приходится отсоединять/присоединять объекты (ввиду особенности модели). Пустые envelope'ы плодятся в бешенном темпе.
Chebu
firsak
Chebu
3dlub
Скачиваете ActorX importer (скрипт для 3DMAX), и ActoX exporter (Плагин для 3D Max)
Устанавливате плагин, он появляется в утилитах.
Експортите сцену со всеми мешами и скинами. В файл формата PSK.
Далее очищаете сцену и импортите этот PSK с помощью скрипта ActorX importer.
Все! Сцена из одного меша. Все скины сохранены. Удачи.
Flashpavel
INCUS
Weight Tool может скопировать в буфер веса выделенных вершин присоединяемого скина.
Так что, потом можно эту геометрию приаттачить к главной геометрии с главным скином и кости, ему же те добавить.
Отрыть уже этот главный Weight Tool, выделить те же вершины и, - paste.
Энвелопы, правда не сохраняются...наверное, из-за того, что у них свой копипаст.
Евгения Ремезова