Python'da 3D Modelleri Nasıl Dönüştürülür

Python'da 3D Modelleri Nasıl Dönüştürülür

Aspose.3D FOSS for Python ile format dönüştürme iki adımlı bir süreçtir: bir Scene nesnesine yükleme, ardından istenen çıktı formatına kaydetme. Tüm geometri ortak bir bellek içi temsilde tutulduğundan, format‑spesifik ara adımlara ihtiyaç yoktur. Aşağıdaki bölümler, çalışan kodlarla en yaygın dönüşümleri gösterir.

Adım Adım Kılavuz

Adım 1: Paketi Yükleyin

pip install aspose-3d-foss

Sistem kütüphaneleri, derleyiciler veya ek çalışma zamanı bağımlılıkları gerekmez.


Adım 2: Kaynak Modeli Yükle

En basit durum için Scene.from_file() kullanın: format dosya uzantısından otomatik olarak algılanır:

from aspose.threed import Scene

scene = Scene.from_file("model.obj")

Koordinat sistemi veya malzeme yüklemesi üzerinde kontrol gerektiğinde OBJ dosyaları için scene.open() ile ObjLoadOptions kullanın:

from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions

options = ObjLoadOptions()
options.flip_coordinate_system = True  # Convert to Z-up if needed
options.enable_materials = True        # Load the accompanying .mtl file
options.normalize_normal = True

scene = Scene()
scene.open("model.obj", options)

Her iki yaklaşım da sonraki kaydetme adımı için aynı Scene nesnesini üretir.


Adım 3: Yüklenen Sahneyi İncele

Bir dönüşüme başlamadan önce, geometrinin doğru yüklendiğini kontrol etmek faydalıdır. Eksik bir dosya, desteklenmeyen bir FBX özelliği veya bir .mtl dosyasındaki yol sorunu, boş bir sahne oluşturabilir.

from aspose.threed import Scene
from aspose.threed.entities import Mesh

scene = Scene.from_file("model.obj")

mesh_count = 0
total_vertices = 0

def count_meshes(node) -> None:
    global mesh_count, total_vertices
    for entity in node.entities:
        if isinstance(entity, Mesh):
            mesh_count += 1
            total_vertices += len(entity.control_points)
    for child in node.child_nodes:
        count_meshes(child)

count_meshes(scene.root_node)
print(f"Loaded {mesh_count} mesh(es), {total_vertices} total vertices")

if mesh_count == 0:
    raise ValueError("Scene contains no geometry: check the source file path and format")

Adım 4: Hedef Formata Kaydet

Çıktı yolu ile scene.save() çağırın. İkili ve ASCII çıktısı, koordinat eksenleri ve sıkıştırma kontrolü için format‑özel kaydetme seçenekleri nesnesi geçirin.

OBJ’den STL’ye (ikili)

from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions

scene = Scene.from_file("model.obj")

save_opts = StlSaveOptions()
##StlSaveOptions defaults to binary output, which is more compact.

scene.save("model.stl", save_opts)
print("Saved model.stl")

OBJ’den glTF 2.0’a

from aspose.threed import Scene
from aspose.threed.formats import GltfSaveOptions

scene = Scene.from_file("model.obj")

save_opts = GltfSaveOptions()

scene.save("model.gltf", save_opts)
print("Saved model.gltf")

Kendi içinde barındıran bir GLB ikili dosyası olarak kaydetmek için, .gltf + harici tamponlar yerine, çıktı uzantısını .glb olarak değiştirin:

scene.save("model.glb", save_opts)

OBJ’den 3MF’ye

from aspose.threed import Scene
from aspose.threed.formats import ThreeMfSaveOptions

scene = Scene.from_file("model.obj")

save_opts = ThreeMfSaveOptions()

scene.save("model.3mf", save_opts)
print("Saved model.3mf")

STL’den glTF 2.0’e

Aynı desen, kaynak formatına bakılmaksızın geçerlidir:

from aspose.threed import Scene
from aspose.threed.formats import GltfSaveOptions

scene = Scene.from_file("input.stl")
scene.save("output.gltf", GltfSaveOptions())
print("Saved output.gltf")

Adım 5: Çıktıyı Doğrula

Kaydetme işleminden sonra, çıktı dosyasının mevcut olduğunu ve sıfırdan farklı bir boyuta sahip olduğunu doğrulayın. Daha kapsamlı bir kontrol için, dosyayı yeniden yükleyin ve ağ sayısını karşılaştırın:

import os
from aspose.threed import Scene
from aspose.threed.entities import Mesh

output_path = "model.stl"

##Basic file-system check
size = os.path.getsize(output_path)
print(f"Output file size: {size} bytes")
if size == 0:
    raise RuntimeError("Output file is empty: save may have failed silently")

##Round-trip verification: reload and count geometry
def _iter_nodes(node):
    yield node
    for child in node.child_nodes:
        yield from _iter_nodes(child)

reloaded = Scene.from_file(output_path)
mesh_count = sum(
    1
    for node in _iter_nodes(reloaded.root_node)
    for entity in node.entities
    if isinstance(entity, Mesh)
)
print(f"Round-trip check: {mesh_count} mesh(es) in output")

Yaygın Sorunlar ve Çözümler

Çıktı dosyası oluşturuldu ancak içinde geometri yok

Kaynak dosya sıfır ağ ile yüklenmiş olabilir. Kaydetmeden önce Adım 3’teki denetleme adımını ekleyin. Ayrıca dosya uzantısının gerçek formatla eşleştiğinden emin olun; Aspose.3D, ayrıştırıcıyı seçmek için uzantıyı kullanır.

glTF çıktısında dokular eksik

Aspose.3D FOSS dönüşüm sırasında geometri ve malzeme özelliklerini taşır. Kaynak OBJ .mtl içinde harici görüntü dosyalarına referans veriyorsa, bu görüntü dosyaları .gltf ile otomatik olarak kopyalanmaz. Kaydetmeden sonra doku görüntülerini çıktı dizinine manuel olarak kopyalayın.

STL çıktısı içe dönük görünüyor (yüz normalleri ters çevrildi)

STL, winding-order meta verisini taşımaz. Çıktı normalleri ters ise, mevcutsa StlSaveOptions seçeneklerini ayarlayın veya yükleme sırasında koordinat sistemini ters çevirin: ObjLoadOptions.flip_coordinate_system = True.

ValueError: unsupported format kaydederken

Çıktı dosya uzantısının .obj, .stl, .gltf, .glb, .dae, .3mf‘den biri olduğundan emin olun. Uzantılar Linux’ta büyük/küçük harfe duyarlıdır.

Çok büyük dosyalar yavaş dönüşüme neden olur

Aspose.3D FOSS geometrileri bellekte işler. Milyonlarca poligon içeren dosyalar için yeterli RAM sağladığınızdan emin olun. Şu anda streaming-write API bulunmamaktadır.


Sıkça Sorulan Sorular (SSS)

Dosyayı önce diske yazmadan dönüştürebilir miyim?

Evet. Hem scene.open() hem de scene.save() dosya yollarının yanı sıra ikili dosya benzeri nesneleri kabul eder. Yükleme için read() uygulayan, kaydetme için ise write() uygulayan herhangi bir nesneyi geçirin:

import io
from aspose.threed import Scene

# Load from an in-memory buffer
data = open('model.obj', 'rb').read()
scene = Scene()
scene.open(io.BytesIO(data))

# Save to an in-memory buffer
buf = io.BytesIO()
scene.save(buf)

FBX, dönüşüm için bir kaynak formatı olarak destekleniyor mu?

FBX tokenizasyonu kısmen uygulanmıştır, ancak ayrıştırıcı tam değildir. FBX girişi eksik sahneler üretebilir. Güvenilir kaynak formatları olarak OBJ, STL, glTF, COLLADA veya 3MF kullanın.

OBJ-to-glTF dönüşümünde materyaller hayatta kalacak mı?

Temel Phong/Lambert malzeme özellikleri (dağılma rengi) Scene modeli aracılığıyla taşınır ve glTF malzeme bloğuna yazılır. glTF malzeme modelinde ifade edilemeyen prosedürel veya özel gölgelendirici parametreleri atılır.

Bir döngüde birden fazla dosyayı dönüştürebilir miyim?

Evet. Her Scene.from_file() çağrısı bağımsız bir nesne oluşturur, bu yüzden bir yol listesi üzerinde döngü oluşturmak basittir:

from pathlib import Path
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions

source_dir = Path("input")
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)

opts = StlSaveOptions()
for obj_file in source_dir.glob("*.obj"):
    scene = Scene.from_file(str(obj_file))
    out_path = output_dir / obj_file.with_suffix(".stl").name
    scene.save(str(out_path), opts)
    print(f"Converted {obj_file.name} -> {out_path.name}")

Dönüştürme sahne hiyerarşisini (ebeveyn/çocuk düğümler) korur mu?

Evet. Düğüm ağacı, hedef formatın izin verdiği ölçüde korunur. STL gibi formatlar yalnızca düğüm yapısı olmadan düz geometri depolar; hiyerarşi kaydetme sırasında düzleştirilir. glTF ve COLLADA gibi formatlar tam hiyerarşiyi korur.

 Türkçe