Mit Blender habe ich ein Skript erstellt, das nur die Scheitelpunktkoordinaten aus den FBX-Daten extrahiert und anordnet. Daher werde ich es nach der Erklärung einführen.
Zunächst zu dieser bekannten Figur (Ausgangszustand).
Die 3D-Ansicht von Blender wird übrigens folgendermaßen verwaltet.
Im Python-Skript
bpy.context.scene.collection
Hier entspricht es.
Dies ist die GUI.
Am Ursprung befindet sich eine Szene → Sammlung, und die Sammlung enthält Objekte. Ich verstehe den Unterschied zwischen einer Szene und einer Sammlung nicht wirklich. Objekte (sogenannte Cubes, Kameras usw.), die als Daten existieren, werden jedoch durch Verknüpfen in die Sammlung aufgerufen. Dies bedeutet, dass nur verknüpfte Objekte in der Ansicht angezeigt werden und ** Objekte, die unsichtbar sind, aber als Daten existieren **. Auf diese Weise scheinen dieselben Daten verwendet zu werden. Es ist kompliziert für diejenigen, die es bedienen.
Und wie Objekte verfügen auch die dazugehörigen Netze und Materialien über eine Datenliste, die Sie verknüpfen können, um so viel zu verwenden, wie Sie benötigen.
Zum Beispiel hier
bpy.data.objects.new("hoge", bpy.data.meshes.new("fuga"))
Ändert nichts an der scheinbaren Szene,
for i in bpy.data.objects:
print(i)
damit,
Output
<bpy_struct, Object("Camera")>
<bpy_struct, Object("Cube")>
<bpy_struct, Object("hoge")>
<bpy_struct, Object("Light")>
Wird zurückgegeben, sodass Sie sehen können, dass ein mysteriöses Objekt namens "hoge" hinzugefügt wurde. Ebenfalls,
bpy.data.objects['hoge'].to_mesh()
damit,
Output
bpy.data.meshes['fuga']
Sie können sehen, dass dieses Objekt mit einem Netz namens "Fuga" verknüpft ist. Dies sind natürlich nur benannte leere Daten. Wenn Sie also "hoge" jetzt mit der Sammlung verknüpfen, wird nichts mit einem Namen ohne Eckpunkte beschworen.
Schauen Sie sich das Netz genauer an. Die Scheitelpunktinformationen des Netzes werden in der folgenden Form verwaltet.
Das Objekt verbindet das Netz.
Dies ist die GUI.
In den Netzdaten werden auch die Scheitelpunktdaten gespeichert. Wenn Sie also die Scheitelpunktinformationen wünschen, können Sie darauf zugreifen. Nun wollen wir die Würfel anvisieren, die eine richtige Form haben.
bpy.data.objects['Cube'].to_mesh().vertices
Dies ist fast das gleiche wie auf dem obigen Bild.
Output
bpy.data.meshes['Cube'].vertices
Betrachtet man diesen Inhalt,
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>
Die Binärdaten werden ernsthaft zurückgegeben. Da es 8 richtig gibt, scheint es, dass der Würfel keinen Fehler enthält, aber ich möchte, dass Sie den numerischen Wert nach Möglichkeit zurückgeben. Wenn Sie sich die Referenz ansehen, können Sie sehen, dass der Wert mit dem Attribut "co" abgerufen werden kann.
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)>
Jetzt haben wir endlich ein Array von Scheitelpunktkoordinaten.
Machen Sie dasselbe für den importierten fbx.
Im Prinzip sollten Sie die gleiche Form wie oben erhalten, indem Sie die Eckpunkte für alle Netzdaten extrahieren.
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")>
……. Es gibt einen mysteriösen "Würfel". Ja, ** der erste Cube, der beim Starten von Blender vorhanden ist **. Selbst wenn Sie es aus der Szene löschen (um genau zu sein, die Verknüpfung aufheben), verschwinden die darin enthaltenen Daten nicht. Wenn nichts getan wird, wird es bis zur Oberseite des Würfels aufgenommen. Lassen wir es verschwinden.
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")>
Es ist verschwunden. Schreiben Sie anschließend ein Skript, das die Scheitelpunktkoordinaten für alle diese Netzdaten extrahiert.
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)
Da die von "co" erhaltene Zahl vom Typ "Vektor" ist, wird sie zur Erleichterung der Handhabung von "np.array" konvertiert.
Stellen Sie sicher, dass die hier erhaltene Sequenz wirklich die ursprüngliche Form darstellt. Wenn die Eckpunkte die dreidimensionalen Informationen genau enthalten, sollte das einfache Erstellen eines Streudiagramms die ursprüngliche Form darstellen.
Das zuvor erhaltene Array "vts"
np.savetxt(r'Beliebiger Pfad\vts.txt', vts)
Exportieren mit. Zeichnen Sie ein Streudiagramm in einer separaten Python-Datei (da in Blenders integriertem Python keine Matplotlib vorhanden ist ...).
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()
Es stellt sich heraus, dass die Eckpunkte der ursprünglichen 3D-Daten genau angeordnet werden können.
Recommended Posts