Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум .:3DCenter.ru:. _ Анимация _ Как быстро удалить из модификатора Skin неиспользуемые кости

Автор: s747s 07/07/2012, 00:21

Доброго времени суток!

Друзья, прошу помощи! Есть скелет Biped, к нему прискинен персонаж, который разбит на отдельные части (руки, ноги, голова, туловище и т.д.). К каждой из таких частей применен уникальный модификатор Skin, и каким-то образом вышло так, что, например, для руки в Skin'е прописаны кости почти всего скелета, включая пальцы на ногах. И такая же картина везде - со всеми отдельными частями тела. Как по-быстрому убрать эти лишние кости, которые только формально числятся, но по факту ни на что не влияют?

Спасибо заранее!

ЗЫ Сцена не моя, досталась по наследству от другого аниматора wink.gif

Автор: Shiva 07/07/2012, 00:56

Скорее всего скин был инстансовый.. т.е. был накинут на все сразу.. а вот кто грохнул инстансовость.. это другой вопрос ))

Автоматом лишние кости никак не удалишь. ручкамис.

Автор: s747s 07/07/2012, 01:05

А как хотя бы получить быстро выделение всех костей, которые используются в Скине? Это часто приходится делать для экспорта персонажей в игровой формат - и приходится вручную каждый раз вот эти все Bip001 Spine, Bip001 R Hand, Bip001 L Hand и т.д. выделять, предварительно выписав их на листик бумаги из перечня в Скине. Можно это автоматизировать как-то?

Автор: Jbond 07/07/2012, 01:22

Так

Код
select $Bip001*

Автор: s747s 07/07/2012, 01:40

Цитата
select $Bip001*
Это выберет вообще все кости Бипеда - так? А мне желательно только те, что в конкретном модификатор Skin задействованы (т.е. например, кости, входящие в состав кисти руки).

Автор: Jbond 07/07/2012, 01:46

Да. Тогда так. Выделить обьект на котором сидит скин - запустить , результат - выделит все кости(и распечатает их в лисенере). Если скин не первый стоит номер подкоректировать $.modifiers[1]

Код
arr= #()
for i =1 to (skinOps.GetNumberBones ($.modifiers[1])) do
(
  temp = skinOps.GetBoneName ($.modifiers[1]) i 1
  format "%\n" temp
  append arr  temp
    
)

clearSelection()
for obj in arr do selectMore (getnodebyname obj)

Автор: s747s 07/07/2012, 02:21

Jbond! Спасибо! То, что нужно - очень удобно! drinks.gif

ЗЫ Может быть, Вы и для удаления ненужных костей из Скина скрипт придумаете? (прошу прощения за наглость blush.gif)

Автор: Jbond 07/07/2012, 11:04

А ненужные это какие? Напишите подробно процесс.

Автор: s747s 07/07/2012, 14:29

Цитата
А ненужные это какие? Напишите подробно процесс.

Вот допустим, есть объект - кисть руки. К ней применен модиф. Скин, и в нем формально задействован почти весь скелет персонажа, включая кости спины, шеи, ног и т.д. Эти кости только числятся в этом списке, но фактически ни на что не влияют и ни в каких деформациях не участвуют. Их можно поудалять вручную, но это долго и неудобно (скелет сложный с множеством костей, самих персонажей тоже много, каждый из них разбит на такие вот части). Поэтому хотелось бы автоматизировать это как-то.

Автор: Jbond 07/07/2012, 16:32

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

Автор: s747s 07/07/2012, 16:37

Боюсь, что самая рутина как раз и состоит в поиске и выделении ненужных костей sad.gif

Автор: Jbond 07/07/2012, 16:56

Все зависит от условия создания скелета.
Кости можно по маске имени выделять. Если у них нормальный naming convention.
Но и выделять их во вьюпорте проблем не должно быть, достаточно вверху на панели включить фильтр на выделение костей.
Оптимально конечно исключить кости если они не оказывают веса на вершины или по какомуто общему для них параметру.Если это конечно будет просто технически.

Автор: s747s 07/07/2012, 17:22

Цитата
Оптимально конечно исключить кости если они не оказывают веса на вершины или по какомуто общему для них параметру.
Вот! Как раз это и нужно. Но я не знаю, можно ли в скриптах до этих параметров как-то добраться.

А по поводу имен костей - они дефолтные бипедовские, и явной связи в именах между мешами и задействованными в них костями нет. Т.е. меш кисти может называться MAN_HeavyArmor021_glove_R, а кости там будут примерно такие: Bip001 Finger01, Bip001 Finger02 и т.д.

Автор: Jbond 07/07/2012, 20:11

Надо погонять на тестовых моделях пару раз проверил вроде работает. Выделить модель, чтобы открыта была панель модификаторов и сам скин модификатор выделен - обязательно.
Push the button -- если кость хоть на одну вершину действует она не удалится.
Если вообще ни на одну то удалятся из списка и распечатается в лисенере, что удалилось.

Код
try(DestroyDialog rltDelUnBones) catch()
global rltDelUnBones
(
    rollout rltDelUnBones "Delete Unused bones"    
    (
        button btnRemoveBones "Remove Bones " width:85 height:60     align:#center
        on     btnRemoveBones pressed do
            (    
                obj =selection[1]
                arrBonesIndex =#()
                arrNames = #()
                if obj != undefined then
                (
                    for m in obj.modifiers where classof m == Skin do
                    (
                        numBones = skinOps.GetNumberBones m     
                        arrBonesIndex = for i =1 to numBones collect i
                        for j =1 to (skinOps.GetNumberVertices m) while arrBonesIndex.count !=0 do
                        (
                            numbBonAff = SkinOps.GetVertexWeightCount m j
                            if numbBonAff >0 then
                            (
                                for k =1 to numbBonAff do
                                (
                                    temp = skinOps.GetVertexWeightBoneID m j k
                                    if  temp >0 then
                                    (
                                        h = findItem arrBonesIndex temp
                                        if h != 0 then deleteItem arrBonesIndex h
                                    )
                                ) --end for

                            ) --end if
                        ) --end for
                        if arrBonesIndex.count > 0 then
                        (            
                            arrNames =     for bon in arrBonesIndex collect skinOps.GetBoneName m bon 1
                            for n in arrNames do
                            (    
                                x= false
                                bonnum = skinOps.GetNumberBones m
                                for h=1 to bonnum while x!=true do
                                (
                                    
                                    if (skinOps.GetBoneName m h 1) == n then
                                    (
                                        skinOps.SelectBone m h
                                        skinOps.removebone m
                                        x = true
                                    )
                                )
                                format "Object Name:% Removed bones:%\n" obj.name n
                            ) --end for  
                        )else (messagebox "All Bones Affects Some Vertex")    
                        
                    ) --end for
                ) --end if    

            ) --end event
    )--end rollout
        
    CreateDialog rltDelUnBones 100 75
)

Автор: s747s 07/07/2012, 21:20

Это просто волшебство! Огромное спасибо! drinks.gif

Автор: SanyaBane 08/09/2017, 20:59

Цитата(Jbond @ 07/07/2012, 20:11) *
Надо погонять на тестовых моделях пару раз проверил вроде работает. Выделить модель, чтобы открыта была панель модификаторов и сам скин модификатор выделен - обязательно.
Push the button -- если кость хоть на одну вершину действует она не удалится.
Если вообще ни на одну то удалятся из списка и распечатается в лисенере, что удалилось.

Текст скрипта


Прошу прощения за некропост, но ОГРОМНОЕ спасибо, вы мне часы работы сэкономили.

Форум Invision Power Board (http://nulled.cc)
© Invision Power Services (http://nulled.cc)