Два skin modifier в один.
- Автор темы firsak
- Дата создания
Писал скрипт для объединения двух объектов с модификатором скин в один.
примечания: кости не должны совпадать по именам, иначе будут глюки.
код:
примечания: кости не должны совпадать по именам, иначе будут глюки.
код:
Код:
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()
)
)--macroscript
Писал скрипт для объединения двух объектов с модификатором скин в один.
примечания: кости не должны совпадать по именам, иначе будут глюки.
примечания: кости не должны совпадать по именам, иначе будут глюки.
Chebu,
Одни и те же кости. Разных костей с одинаковыми именами нет.
Допустим, имеем: 3 объекта. верхняя губа, нижняя губа, голова.
Поставил keyframe на 50-м кадре (открыл рот).
Выделяю губы, жму на кнопку mergeSkinObjects (голову не трогаю), получаю:
У нижней губы исчезают почти все bone weights. Undo.
Теперь уже выделяю все три объекта, жму mergeSkinObjects, результат:
Все объекты - editable poly, с одним модификатором (skin).
Юзаю 3ds max 2008 x64. Куда копать?
Одни и те же кости. Разных костей с одинаковыми именами нет.
Допустим, имеем: 3 объекта. верхняя губа, нижняя губа, голова.
Поставил keyframe на 50-м кадре (открыл рот).
Выделяю губы, жму на кнопку mergeSkinObjects (голову не трогаю), получаю:
У нижней губы исчезают почти все bone weights. Undo.
Теперь уже выделяю все три объекта, жму mergeSkinObjects, результат:
Все объекты - editable poly, с одним модификатором (skin).
Юзаю 3ds max 2008 x64. Куда копать?
firsak, пробуйте:
Код:
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()
)
)--macroscript
Едрён батон.
Работает ведь!
Большое спасибо, Chebu.
Только почему то старый скрипт присосался к Максу, несмотря на то, что я старый *.mcr удалил и заменил на новый. Так и висит под категорией AndreyK. Поэтому сначала запускался старый скрипт. Думал, опять не повезло. Пришлось в доработанном скрипте категорию переименовать в AndreyK2. Странно.
Еще проблема.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся. К примеру, у двух смежных вертексов такие веса:
А если их объединить, то получается бред:
Или:
было
стало
Насколько я понимаю, Max пытается усреднить значения. Но зачем их усреднять, если они идентичные? Все равно, что взять две единицы и попытаться их "усреднить". Идиотизм, короче.
Выход из проблемы нашел в использовании SkinUtilities.
То бишь, сначала соединяю все, что нужно с помощью скрипта от Chebu. Затем юзаю комманду Extract Skin Data To Mesh на полученном объекте. Потом делаю WELD всех вертексов (веса у смежных вертексов портятся). И в конце концов восстанавляваю правильные веса с помощью Import Skin Data From Mesh.
Работает ведь!
Большое спасибо, Chebu.
Только почему то старый скрипт присосался к Максу, несмотря на то, что я старый *.mcr удалил и заменил на новый. Так и висит под категорией AndreyK. Поэтому сначала запускался старый скрипт. Думал, опять не повезло. Пришлось в доработанном скрипте категорию переименовать в AndreyK2. Странно.
Еще проблема.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся. К примеру, у двух смежных вертексов такие веса:
Код:
0,400 Bone01
0,200 Bone02
0,200 Bone03
0,200 Bone04
Код:
0,308 Bone01
0,281 Bone01
0,206 Bone03
0,205 Bone02
Или:
было
Код:
0,700 Bone01
0,300 Bone02
Код:
0,418 Bone01
0,275 Bone01
0,183 Bone02
0,124 Bone02
Выход из проблемы нашел в использовании SkinUtilities.
То бишь, сначала соединяю все, что нужно с помощью скрипта от Chebu. Затем юзаю комманду Extract Skin Data To Mesh на полученном объекте. Потом делаю WELD всех вертексов (веса у смежных вертексов портятся). И в конце концов восстанавляваю правильные веса с помощью Import Skin Data From Mesh.
на здоровье.
теоретически, можно попробовать перед велдом снять в скине галку always deform, а после велда поставить обратно. save-load весов тоже может помочь.
Еще проблема.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся.
Если объединенном с помощью скрипта меше опуститься уровнем ниже и сделать WELD вертексов, а затем вернуться обратно к skin, то веса у соединенных вертексов портятся.
Chebu, только что заметил кое-что еще.
При соединении нескольких объектов, дублируются envelope'ы. Допустим, три объекта, у каждого общая кость bone01. Соединяешь их - получаешь сразу три bone01 в списке модификатора skin. Одна из них нормальная, две остальные с нулевыми influences. Можете сделать, чтобы скрипт автоматом сносил лишние envelope'ы? Или может на что-то нажать можно? Кнопку remove zero weights вижу. Кнопку, типа, remove envelopes with zero influences не вижу.
Постоянно приходится отсоединять/присоединять объекты (ввиду особенности модели). Пустые envelope'ы плодятся в бешенном темпе.
При соединении нескольких объектов, дублируются envelope'ы. Допустим, три объекта, у каждого общая кость bone01. Соединяешь их - получаешь сразу три bone01 в списке модификатора skin. Одна из них нормальная, две остальные с нулевыми influences. Можете сделать, чтобы скрипт автоматом сносил лишние envelope'ы? Или может на что-то нажать можно? Кнопку remove zero weights вижу. Кнопку, типа, remove envelopes with zero influences не вижу.
Постоянно приходится отсоединять/присоединять объекты (ввиду особенности модели). Пустые envelope'ы плодятся в бешенном темпе.
Есть несколько mesh'ев. У каждого свой модификатор skin. Вроде бы простая задача: объединить все объекты в один и сохранить при этом skin и все bone weights. Но у присоединяемых объектов всегда сбрасываются все данные в модификаторе skin. Как быть?
Скачиваете ActorX importer (скрипт для 3DMAX), и ActoX exporter (Плагин для 3D Max)
Устанавливате плагин, он появляется в утилитах.
Експортите сцену со всеми мешами и скинами. В файл формата PSK.
Далее очищаете сцену и импортите этот PSK с помощью скрипта ActorX importer.
Все! Сцена из одного меша. Все скины сохранены. Удачи.
А у меня, вроде, и без утилит получилось.
Weight Tool может скопировать в буфер веса выделенных вершин присоединяемого скина.
Так что, потом можно эту геометрию приаттачить к главной геометрии с главным скином и кости, ему же те добавить.
Отрыть уже этот главный Weight Tool, выделить те же вершины и, - paste.
Энвелопы, правда не сохраняются...наверное, из-за того, что у них свой копипаст.
Weight Tool может скопировать в буфер веса выделенных вершин присоединяемого скина.
Так что, потом можно эту геометрию приаттачить к главной геометрии с главным скином и кости, ему же те добавить.
Отрыть уже этот главный Weight Tool, выделить те же вершины и, - paste.
Энвелопы, правда не сохраняются...наверное, из-за того, что у них свой копипаст.