Jak zainstalować modele 3D w Pythonie
Aspose.3D FOSS dla Pythona zapewnia prostą API do otwarcia plików 3D bez żadnych zależności. po załadowaniu pliku w Scene Obiekt, można przejść hierarchii węzłów i przeczytać surowe dane geometryczne dla każdego z nich na scenie.
Przewodnik krok po kroku
Krok 1: Instalacja pakietu
Instaluj Aspose.3D FOSS z PyPI. Nie wymagane są dodatkowe biblioteki systemowe.
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.
Wspierane wersje Pythona: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Krok 2: Wprowadzenie klasy scenicznej
i The Scene Klasy są najwyższym pojemnikiem dla wszystkich danych 3D. Importować je wraz z dowolnymi klasami opcji obciążenia potrzebne.
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptionsWszystkie klasy publiczne żyją pod aspose.threed lub jego podpakowania (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).
Krok 3: Pobierz plik
Użyj statycznego Scene.from_file() metoda otwierania dowolnego obsługiwanego formatu. biblioteka automatycznie wykrywa format z rozszerzenia pliku.
##Automatic format detection
scene = Scene.from_file("model.obj")Alternatywnie, tworzyć A Scene Instancja i wezwanie open();Przydatne, gdy chcesz przejść opcje ładowania lub wyraźnie radzić sobie z błędami:
scene = Scene()
scene.open("model.obj")Oba metody obsługują pliki OBJ, STL (binary i ASCII), glTF 2.0 / GLB, COLLADA (DAE) i 3MF.
Krok 4: Przechodź przez scenę
„Przemocny sceną jest drzewo Node Obiekty z korzeniami w scene.root_node.Iterate recursively, aby znaleźć wszystkie węzły:
from aspose.threed import Scene, Node
scene = Scene.from_file("model.obj")
def walk(node: Node, depth: int = 0) -> None:
indent = " " * depth
print(f"{indent}Node: {node.name!r}")
for child in node.child_nodes:
walk(child, depth + 1)
walk(scene.root_node)Każdy z nich Node Można przewozić zero lub więcej. Entity obiekty (meczety, kamery, światła) sprawdź node.entities Zobacz co jest przywiązane.
Krok 5: Dostęp do danych Vertex i Polygon
Wprowadź podmiot węzła do Mesh i przeczytaj jego punkty kontrolne (pozycje odwrotne) i poligony (listy indeksów twarzy):
from aspose.threed import Scene
from aspose.threed.entities import Mesh
scene = Scene.from_file("model.obj")
for node in scene.root_node.child_nodes:
for entity in node.entities:
if isinstance(entity, Mesh):
mesh: Mesh = entity
print(f"Mesh '{node.name}': "
f"{len(mesh.control_points)} vertices, "
f"{len(mesh.polygons)} polygons")
# First vertex position
if mesh.control_points:
v = mesh.control_points[0]
print(f" First vertex: ({v.x:.4f}, {v.y:.4f}, {v.z:.4f})")
# First polygon face (list of control-point indices)
if mesh.polygons:
print(f" First polygon: {mesh.polygons[0]}")mesh.control_points Jest to lista Vector4 przedmioty ; x, y, z Wziąć pozycję i w Jest to koordynacja homogenna (zazwyczaj 1.0).
mesh.polygons jest listą list z całości, w których każda lista wewnętrzna jest zamówionym zestawem indeksów punktów kontrolnych dla jednej twarzy.
Krok 6: Wprowadź opcje ładowania specyficzne dla formatu
Aby uzyskać kontrolę nad tym, jak jest interpretowany plik OBJ, przejdź do ObjLoadOptions Przykładem jest scene.open():
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.flip_coordinate_system = True # Convert right-hand Y-up to Z-up
options.scale = 0.01 # Convert centimetres to metres
options.enable_materials = True # Load .mtl material file
options.normalize_normal = True # Normalize all normals to unit length
scene = Scene()
scene.open("model.obj", options)W przypadku plików STL, równowartość klasy jest StlLoadOptions.W przypadku GST, użyj GltfLoadOptions.Zobacz The Referencje API Dla pełnej listy.
Wspólne problemy i rozwiązania
FileNotFoundError podczas rozmowy Scene.from_file()
Droga musi być absolutna lub poprawna w stosunku do dyrektora roboczego w czasie pracy. pathlib.Path Aby stworzyć wiarygodne drogi:
from pathlib import Path
from aspose.threed import Scene
path = Path(__file__).parent / "assets" / "model.obj"
scene = Scene.from_file(str(path))mesh.polygons jest puste po pobraniu pliku STL
Archiwum STL przechowują trójkąt jako surowe strony, a nie indeksowane łodygi. po ładowaniu poligony są syntetyzowane z tych stron. polygons Wygląda pusty, sprawdź len(mesh.control_points);Jeśli liczba jest wieloma z 3 geometry są przechowywane w nieindeksowanej formie, a każda kolejna trójkątność pionów tworzy jeden trojuł.
System koordynacyjny nie jest zgodny (model pojawia się z rotacją lub lustrem)
Różne narzędzia używają różnych konwencji (Y-up vs Z-Up, lewą ręką vs prawą). ObjLoadOptions.flip_coordinate_system = True lub zastosowanie rotacji do korzeniowego węzła Transform po ładowaniu.
AttributeError: 'NoneType' object has no attribute 'polygons'
Lista podmiotów w przyciskach może zawierać podmioty nieprzyłączone (kamera, światła). isinstance(entity, Mesh) Przed castingem.
Często zadawane pytania (FAQ)
Jakie formaty 3D można pobrać?
OBJ (Wavefront), STL (binary i ASCII), glTF 2.0 / GLB, COLLADA (DAE) i 3MF. Tokenizacja plików FBX jest częściowo obsługiwana, ale pełna parsing nie jest jeszcze kompletna.
Czy ładowanie pliku OBJ również ładuje .mtl Materiał ?
Tak, kiedy ObjLoadOptions.enable_materials = True Biblioteka poszukuje w tym celu .mtl w tym samym katalogu, jak i w .obj Artykuły - jeśli .mtl brakuje, geometria jest nadal obciążona i wyda się ostrzeżenie.
Czy mogę pobrać plik z prądu bytu zamiast ścieżki?
Tak i tak. scene.open() akceptuje dowolny obiekt podobny do pliku z A .read() metoda oprócz paska ścieżki pliku. przejść otwarty strumień binarny (np., io.BytesIOi bezpośrednio. Scene.from_file() Akceptuje tylko strzałkę ścieżki pliku.
Jak uzyskać normę powierzchniową?
Po wyładowaniu sprawdź mesh.get_element(VertexElementType.NORMAL).To powraca do A VertexElementNormal Które data Lista zawiera jeden wektor na odniesienie, mapowany według: mapping_mode i reference_mode.
from aspose.threed.entities import Mesh, VertexElementType
normals = mesh.get_element(VertexElementType.NORMAL)
if normals:
print(normals.data[0]) # First normal vectorCzy biblioteka jest bezpieczna do ładowania wielu plików równocześnie?
Każdy z nich Scene Obiekt jest niezależny. Pobierz oddzielne pliki do odrębnych Scene Przykłady z oddzielnych filarów są bezpieczne, o ile nie udostępniasz jednego Scene Przez wiązki bez zamknięcia zewnętrznego.