En utilisant Blender, j'ai créé un script qui extrait uniquement les coordonnées des sommets des données FBX et les arrange, je vais donc l'introduire après explication.
Tout d'abord, à propos de cette figure familière (état initial).
À propos, la vue 3D de Blender est gérée de la manière suivante.
Dans le script Python
bpy.context.scene.collection
C'est là que ça correspond.
Ceci est l'interface graphique.
Il y a une scène → collection à l'origine, et il y a des objets dans la collection. Je ne comprends pas vraiment la différence entre une scène et une collection. Cependant, les objets (dits cubes, caméras, etc.) qui existent sous forme de données sont appelés dans la collection en les liant. Cela signifie que seuls les objets liés apparaîtront dans la vue, et les ** objets invisibles mais existant en tant que données **. En faisant cela, il semble que les mêmes données soient utilisées. C'est compliqué pour ceux qui l'exploitent.
Et comme les objets, les maillages et les matériaux qui les accompagnent ont également une liste de données que vous pouvez lier pour utiliser autant que vous en avez besoin.
Par exemple, ici
bpy.data.objects.new("hoge", bpy.data.meshes.new("fuga"))
Ne change rien à la scène apparente,
for i in bpy.data.objects:
print(i)
alors,
Output
<bpy_struct, Object("Camera")>
<bpy_struct, Object("Cube")>
<bpy_struct, Object("hoge")>
<bpy_struct, Object("Light")>
Est retourné, donc vous pouvez voir qu'un objet mystérieux appelé hoge
a été ajouté. Aussi,
bpy.data.objects['hoge'].to_mesh()
alors,
Output
bpy.data.meshes['fuga']
Vous pouvez voir que cet objet est lié à un maillage appelé fuga
. Bien sûr, il ne s'agit que de données vides nommées, donc si vous liez hoge
à la collection maintenant, il n'appellera rien avec un nom qui n'a pas de sommets.
Regardez de plus près le maillage. Les informations sur les sommets du maillage sont gérées sous la forme suivante.
L'objet lie le maillage.
Ceci est l'interface graphique.
Les données de maillage stockent également les données de sommet, donc si vous voulez les informations de sommet, vous y accéderez. Ciblons maintenant les cubes qui ont une forme appropriée.
bpy.data.objects['Cube'].to_mesh().vertices
C'est presque le même que l'image ci-dessus.
Output
bpy.data.meshes['Cube'].vertices
En regardant ce contenu,
for i in bpy.data.meshes['Cube'].vertices:
print(i)
Output
<bpy_struct, MeshVertex at 0x0000024A9FA28038>
<bpy_struct, MeshVertex at 0x0000024A9FA2804C>
<bpy_struct, MeshVertex at 0x0000024A9FA28060>
<bpy_struct, MeshVertex at 0x0000024A9FA28074>
<bpy_struct, MeshVertex at 0x0000024A9FA28088>
<bpy_struct, MeshVertex at 0x0000024A9FA2809C>
<bpy_struct, MeshVertex at 0x0000024A9FA280B0>
<bpy_struct, MeshVertex at 0x0000024A9FA280C4>
Les données binaires sont renvoyées sérieusement. Puisqu'il y en a 8 correctement, il semble qu'il n'y ait pas d'erreur dans le cube, mais j'aimerais que vous retourniez la valeur numérique si possible. Si vous regardez la Référence, vous pouvez voir que la valeur peut être obtenue avec l'attribut co
.
for i in bpy.data.meshes['Cube'].vertices:
print(i.co)
Output
<Vector (1.0000, 1.0000, 1.0000)>
<Vector (1.0000, 1.0000, -1.0000)>
<Vector (1.0000, -1.0000, 1.0000)>
<Vector (1.0000, -1.0000, -1.0000)>
<Vector (-1.0000, 1.0000, 1.0000)>
<Vector (-1.0000, 1.0000, -1.0000)>
<Vector (-1.0000, -1.0000, 1.0000)>
<Vector (-1.0000, -1.0000, -1.0000)>
Maintenant, nous avons enfin un tableau de coordonnées de sommets.
Faites de même pour le fbx importé.
En principe, vous devriez obtenir la même forme que ci-dessus en extrayant les sommets de toutes les données de maillage.
for i in bpy.data.meshes:
print(i)
Output
<bpy_struct, Mesh("Cube")>
<bpy_struct, Mesh("Mesh")>
<bpy_struct, Mesh("Mesh.001")>
<bpy_struct, Mesh("Mesh.002")>
<bpy_struct, Mesh("Mesh.003")>
<bpy_struct, Mesh("Mesh.004")>
<bpy_struct, Mesh("Mesh.005")>
<bpy_struct, Mesh("Mesh.006")>
<bpy_struct, Mesh("Mesh.007")>
……. Il y a un mystérieux «Cube». Oui, ** le premier cube qui existe lorsque vous lancez Blender **. Même si vous le supprimez de la scène (dissocier pour être exact), les données à l'intérieur ne disparaîtront pas. Si rien n'est fait, il remontera en haut du cube. Faisons disparaître.
bpy.data.meshes.remove(bpy.data.meshes['Cube'])
for i in bpy.data.meshes:
print(i)
Output
<bpy_struct, Mesh("Mesh")>
<bpy_struct, Mesh("Mesh.001")>
<bpy_struct, Mesh("Mesh.002")>
<bpy_struct, Mesh("Mesh.003")>
<bpy_struct, Mesh("Mesh.004")>
<bpy_struct, Mesh("Mesh.005")>
<bpy_struct, Mesh("Mesh.006")>
<bpy_struct, Mesh("Mesh.007")>
Il a disparu. Après cela, écrivez un script qui extrait les coordonnées des sommets de toutes ces données de maillage.
import bpy
import numpy as np
vts = []
for m in bpy.data.meshes:
for v in m.vertices:
vts.append(v.co)
vts = np.array(vts)
Puisque le nombre obtenu par «co» est de type «Vector», il est converti par «np.array» pour une facilité de manipulation.
Vérifiez que la séquence obtenue ici représente bien la forme d'origine. Si les sommets contiennent les informations tridimensionnelles avec précision, un diagramme de dispersion doit montrer la forme d'origine.
Le tableau vts
obtenu plus tôt
np.savetxt(r'Chemin arbitraire\vts.txt', vts)
Exporter avec. Dessinez un diagramme de dispersion dans un fichier Python séparé (car le Python intégré de Blender n'a pas matplotlib ...).
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
data = np.loadtxt('vts.txt')
X = data[:,0]
Y = data[:,1]
Z = data[:,2]
fig = plt.figure()
ax = Axes3D(fig)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.plot(X,Y,Z,marker="o",linestyle='None',ms=0.2)
plt.show()
Il s'avère que les sommets des données 3D d'origine peuvent être arrangés avec précision.
Recommended Posts