Skocz do zawartości

Featured Replies

Napisano

Hej, jak w temacie, piszę skrypt, który zapisuje pozycję kości a dokładnie head, tail i rotation_euler.

Męczę się z tym dość długo i niestety nie mogę przebrnąć przez pewien etap.

 

Oto kod który napisałem:

 

def getPosition(a_name):
   bones=bpy.data.armatures[a_name].bones
   bone_struct=[]

   for bone in bones:
       bone_ends=[]
       bpy.context.active_object.data.bones[bone].select=True
       bone_ends.append(bone.name)
       bone_ends.append(bpy.context.active_pose_bone.head)
       bone_ends.append(bpy.context.active_pose_bone.tail)
       bone_ends.append(bpy.context.active_pose_bone.rotation_euler)
       bone_struct.append(bone_ends)
   return(bone_struct)

#zapisywanie animacji do pliku
def saveAnimation(a_name, file_name):
scene=bpy.context.scene
frames=scene.frame_end - scene.frame_start + 1
myFile=open(file_name,"w")
scene.frame_current=0
i=0
j=0

for i in range(scene.frame_start, scene.frame_end + 1):
	myFile.write("Frame: %d;\n" % scene.frame_current)
	scene.frame_current=i
	scene.frame_set(scene.frame_current)

	#korzystam z wczeniej utworzonej funkcji getPosition
	myData=getPosition(a_name)
	for line in myData:
		 myFile.write(str(line))
		 myFile.write("\n")
myFile.close()
return

saveAnimation('Armature', 'animation.txt')

 

W wyniku otrzymuje plik w którym w każdej klatce i przy każdej kości mam wartości obecnie aktywnej kości z klatki 0.

Stosując w konsoli komendę bpy.context.active_pose_bone.head dostaję poprawne wyniki przy zmianie klatki.

Więc sądzę, że kieruje się w dobrym kierunku, ale problem tkwi właśnie z aktywacją kości, której nie potrafie zaimplementować.

 

Wcześniej próbowałem zapisać pozycję nieco inaczej:

def getPosition(a_name):
bones=bpy.data.armatures[a_name].bones
bone_struct=[]
i=0
for bone in bones:
	bone_ends=[]
	bone_ends.append(bone.name)
	bone_ends.append(bones[i].head)
	bone_ends.append(bones[i].tail)
	bone_struct.append(bone_ends)
	i=i+1

return(bone_struct)

 

W wyniku otrzymywałem pozycję każdej kości, ale wyłącznie w pierwszej klatce.

 

Także drodzy koledzy proszę was o pomoc.

  • Odpowiedzi 10
  • Wyświetleń 2,1k
  • Created
  • Ostatniej odpowiedzi

Top Posters In This Topic

Napisano

jak juz pisałem u mnie działa w ten sposób :) żywcem z konsoli pythona

>>> bpy.context.active_bone
[color=#008080]bpy.data.armatures['Armature'].bones["Bone.001"][/color]

>>> bone=bpy.context.active_object.data.bones['Bone']
>>> bpy.context.active_object.data.bones.active=bone
>>> bpy.context.active_bone
[color=#008080]bpy.data.armatures['Armature'].bones["Bone"][/color]

>>> bpy.context.active_pose_bone
[color=#008080]bpy.data.objects['Armature'].pose.bones["Bone"][/color]

>>> bone=bpy.context.active_object.data.bones[1]
>>> bpy.context.active_object.data.bones.active=bone
>>> bpy.context.active_pose_bone
[color=#008080]bpy.data.objects['Armature'].pose.bones["Bone.001"][/color]

active_pose_bone jest read only (tylko do odczytu)

>>> bpy.context.active_pose_bone= bone
[color=#800000]Traceback (most recent call last):
 File "", line 1, in 
AttributeError: bpy_struct: Context property [b]"active_pose_bone" is read-only[/b][/color]

 

ps. może później sie wgryzę w twój kod i spróbuje coś wiecej wykombinować

Edytowane przez szczuro

Napisano

Jest jedna rzecz, o której trzeba pamiętać:

Miałem ten problem przy pisaniu eksportera do After Effects.

 

Jeżeli zmieniasz klatkę za pomocą frame_current = foo to skrypt wprawdzie ustawia klatkę na foo, ale nie updatuje sceny. Jeżeli Twoje kości są animowane, to dla każdej klatki zapisze Ci jej dane z klatki w której byłeś w momencie odpalenia skryptu.

Żeby wszystko się zupdatowało musisz użyć frame_set(foo).

Napisano
  • Autor

Zrobiłem w calości ten skrypt oraz skrypt wczytujący dane. Ale mam kolejny problemik. Działa on wyłącznie w trybie pose mode.

Odpalając go np. trybie object wyskakuje błąd.

 

Tak więc moje pytanie brzmi: jak przy uruchomieniu skryptu sprawdzić czy jest zaznaczony obiekt 'Armatura' i jaki tryb jest obecnie włączony?

Tutaj wiem tylko tyle, że przejście do trybu posemode to posemode_toggle()

Napisano

W założeniu,że masz jeden wybrany obiekt

obj=bpy.context.selected_objects[0]
name=obj.name
print(name)  

 

Jeżeli chodzi o pose mode

if bpy.context.mode != 'POSE':
           bpy.ops.object.posemode_toggle() 

Tak z ciekawości w czym chcesz importować te dane?:)

Napisano
  • Autor

W blenderze.

 

Teraz mam MEGA problem. W swoim projekcie muszę wczytać dane motion capture wykorzystując zmiany pozycji punktów.

Myk polega na tym, że z pozycji trzeba przejść na rotację. Znalazłem coś takiego jak macierze rotacji:

http://pl.wikipedia.org/wiki/Elementarne_macierze_transformacji

http://en.wikipedia.org/wiki/Rotation_matrix

 

Ale nie za bardzo umiem z tego skorzystać, czy miał ktoś z tym już do czynienia i wie jak rozwiązać problem?

Napisano

Macierze i vektory to dalej moja pięta achillesowa, ale podpowiem, że macierze do rotacji (w blenderze) wykorzystują system Quaternion (WXYZ), działa on trochę jak maski pozycji, w zależności od wartości W, X, Y albo Z przyjmuje odpowiednią pozycje i blenduje je między sobą.

 

Musisz poczytać na necie i przeanalizować przykładowe listingi kodu. Sprawdź czy któryś Addon nie robi czegoś z rotacją, na pewno Addon od Motion Capture coś będzie miał.

 

Sam jeszcze tego nie robiłem więc więcej ni pomogę.

Napisano
  • Autor

Już ten Addon przeszukałem, on zczytuje rotację otrzymaną przez program, także w żaden sposób nie obrazuje problemu.

Napisano

Z tego co ja się orientuje Quaterniony to tylko sposób zapisu danych(1 rzeczywista 3 urojone?). W blenderze masz dostęp do rotacja [w,x,y,z,] i dostęp do zwykłych eulera rot x, rot y, rot z. W 3ds max jest identycznie. W maxie jest gotowa funkcja do przeliczania jednych na drugą,w blenderze chyba nie ma tak dobrze...

n-pigeon dobrze mówi szukaj czegoś gotowego... Operacje na macierzach nie są takie łatwe

Napisano

Quaternion i Euler to systemy przedstawiania rotacji, w przypadku Q nie sugerowałbym się oznaczeniami XYZ ma coś wspólnego z XYZ obiektu, ale nie przedstawia o ile stopni jest obrót tylko ile % w końcowej rotacji jest poszczególnych rotacji. Trudno mi to wytłumaczyć, sam to ledwo rozumiem :D Euler jest łatwiejszy do ogarnięcia, ale jest ryzyko utworzenia Gimbal Lock co powoduje czasem błędy przy interpolacji animacji.

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Powiadomienie o plikach cookie

Wykorzystujemy cookies. Przeczytaj więcej Polityka prywatności