[PYTHON] Folgen Sie der Datenstruktur von Blender und extrahieren Sie die Scheitelpunktkoordinaten aus fbx

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.

Blender-Datenstruktur

Zunächst zu dieser bekannten Figur (Ausgangszustand).

image.png

Die 3D-Ansicht von Blender wird übrigens folgendermaßen verwaltet.

image.png

Im Python-Skript

bpy.context.scene.collection

Hier entspricht es.

image.png

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.

image.png

Das Objekt verbindet das Netz.

image.png

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.

Gilt für fbx

Machen Sie dasselbe für den importierten fbx.

image.png

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()

image.png

Es stellt sich heraus, dass die Eckpunkte der ursprünglichen 3D-Daten genau angeordnet werden können.

Recommended Posts

Folgen Sie der Datenstruktur von Blender und extrahieren Sie die Scheitelpunktkoordinaten aus fbx
Daten aus S3 extrahieren
CSV-Daten extrahieren und berechnen
Extrahieren Sie bestimmte Daten aus komplexem JSON
Persistente Datenstruktur von Grund auf neu erstellt
Extrahieren Sie Pokemon GO Pokemon-Daten und Skill-Daten
Extrahieren und zeichnen Sie die neuesten Bevölkerungsdaten aus den von der Stadt bereitgestellten PDF-Daten
Machen Sie mit Python einen Entscheidungsbaum von 0 und verstehen Sie ihn (4. Datenstruktur)
Python-Datenstruktur und interne Implementierung ~ Liste ~
Struktur und Betrieb der Python-Daten (Python-Lernnotiz ③)