3D 모델을 Python으로 변환하는 방법

3D 모델을 Python으로 변환하는 방법

Aspose.3D FOSS for Python을 사용하여 형식 변환은 두 단계의 과정입니다. Scene 모든 지질학이 메모리에서 일반적인 표현으로 유지되기 때문에, 형식 특정 중간 단계가 필요하지 않습니다. 아래 섹션은 작업 코드와 함께 가장 일반적 인 변환을 보여줍니다.

단계별 가이드

단계 1 : 패키지를 설치합니다.

asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.

시스템 도서관, 컴파일러 또는 추가 실행 시간 의존도 필요하지 않습니다.


단계 2 : 출처 모델을 충전합니다.

사용하기 Scene.from_file() 가장 간단한 경우: 파일 확장에서 형식이 자동으로 발견됩니다 :

from aspose.threed import Scene

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

좌표 시스템 또는 재료 충전을 통제해야 하는 OBJ 파일의 경우, 사용하기 scene.open() 와 함께 ObjLoadOptions:

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)

두 가지 방법은 동일한 접근 방식을 제공합니다. Scene 다음 단계를 위한 저장단계.


단계 3: 충전 된 장면을 검사합니다.

변환을 시작하기 전에, 지질학이 올바르게 충전되었는지 확인할 가치가 있습니다.실종된 파일, 지원되지 않은 FBX 기능 또는 도로 문제와 함께 .mtl 모든 파일은 빈 장면을 생성 할 수 있습니다.

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

단계 4 : 목표 형식으로 저장

전화기 scene.save() 출력 경로와 함께.이 포맷 특정 저장 옵션 개체를 통과 하 고 바이너리 vs ASCII 출력을 제어, 조율 좌석 및 압축.

OBJ에서 STL까지 (비나리)

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에서 GLTF 2.0까지의 옵션

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

스스로 보관된 GLB 바이너리 대신 저장하기 위해서 .gltf + 외부 버퍼, 출력 확장을 변경하여 .glb:

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

3MF까지의 OBJ

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에서 GLTF 2.0까지의 옵션

동일한 패턴은 출처 형식에 관계없이 적용됩니다 :

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

5단계 : 출력 확인하기

저장 후, 출력 파일이 존재하고 0 크기가 없음을 확인합니다.더 자세한 검사를 위해 다시 업로드하고 메시 숫자를 비교하십시오 :

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

일반적인 문제와 해결책

출력 파일이 생성되지만 지질학이 포함되지 않습니다.

소스 파일은 0 메시지로 충전 될 수 있습니다. 스토리지하기 전에 단계 3에서 검사 단위를 추가합니다. 또한 파일 확장이 실제 형식과 일치한다는 것을 확인; Aspose.3D는 확장을 사용하여 파세어를 선택합니다.

GTTF 생산은 텍스트가 부족합니다.

Aspose.3D FOSS는 변환을 통해 지질 및 물질 속성을 수행합니다. OBJ 출처가 외부 이미지 파일을 참조하는 경우 .mtl,이 이미지 파일은 자동으로 동반되지 않습니다. .gltf. 저장 후 수동으로 출력 디렉토리에 텍스트 이미지를 복사합니다.

STL 출력은 내부에서 외부로 보인다 (얼굴 정상이 흐려져 있음)

STL은 휘발성 명령 메타 데이터를 가져오지 않습니다.출력 정상이 반환되는 경우, 설정 StlSaveOptions 옵션이 있는 경우, 또는 충전 중에 코디네이터 시스템을 플리프 : ObjLoadOptions.flip_coordinate_system = True.

ValueError: unsupported format 절약할 때

출력 파일 확장 프로그램을 확인하는 것은 하나입니다. .obj, .stl, .gltf, .glb, .dae, .3mf.확장 프로그램은 Linux에서 사례 민감합니다.

매우 큰 파일은 느린 변환을 일으킨다.

Aspose.3D FOSS는 메모리에서 지메트리를 처리합니다.백만 개의 폴리곤이 있는 파일을 위해서는 충분한 RAM을 보장합니다.현재 스트리밍 작성 API가 없습니다.


자주 묻는 질문 (FAQ)

먼저 디스크에 글을 쓰지 않고 파일을 변환할 수 있습니까?

ᄏᄏᄏᄏ 두 가지 scene.open() 그리고 scene.save() 파일 경로 외에 바이너리 파일 유사 개체를 수락합니다. read() 충전 또는 write() 저축을 위한 :

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는 변환을위한 출처 형식으로 지원되나요?

FBX 토큰화는 부분적으로 실행되지만 파세어가 완성되지 않습니다. FBx 입력은 불완전한 장면을 생성할 수 있습니다. OBJ, STL, glTF, COLLADA 또는 3MF를 신뢰할수있는 출처 형식으로 사용하십시오.

재료는 OBJ-glTF 변환을 생존 할 것입니까?

기본 폰그/람베르트 재료 특성(분해 색상)은 통과하여 수행됩니다. Scene 모델 및 글트를 glTF 재료 블록에.glT F 재질 모델에서 표현할 수 없는 절차적 또는 사용자 지정 징후 매개 변수는 떨어집니다.

여러 파일을 하나의 루프로 변환할 수 있습니까?

예, 각각의 Scene.from_file() 전화는 독립적 인 개체를 생성하므로 경로 목록을 통해 롤이 간단합니다.:

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}")

변환은 장면 히어로키 (부모 / 자녀 노드)를 유지합니까?

예. 노드 나무는 대상 형식이 허용하는 한 보존됩니다. STL과 같은 형태는 단지 노트 구조가없는 평평한 지질을 저장합니다; 이라크는 저장을 빛나게합니다. glTF와 COLLADA와 같은 포맷은 전체 이라는 유지됩니다.

 한국어