نحوه بارگذاری مدلهای سهبعدی در Python
Aspose.3D FOSS برای Python یک API ساده برای باز کردن فایلهای 3D بدون هیچ وابستگی بومی فراهم میکند. پس از بارگذاری یک فایل به یک Scene شیء، میتوانید سلسلهمراتبی گرهها را پیمایش کنید و دادههای هندسی خام هر مش در صحنه را بخوانید.
راهنمای گام به گام
گام ۱: نصب بسته
نصب Aspose.3D FOSS از PyPI. هیچ کتابخانه سیستمی اضافی مورد نیاز نیست.
pip install aspose-3d-fossنسخههای پشتیبانیشده Python: 3.7، 3.8، 3.9، 3.10، 3.11، 3.12.
گام ۲: وارد کردن کلاس Scene
کلاس Scene کلاس، محفظه سطح بالای تمام دادههای 3D است. آن را به همراه هر کلاس گزینهبارگذاری که نیاز دارید وارد کنید.
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptionsتمام کلاسهای عمومی زیر aspose.threed یا زیرپکیجهای آن (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).
گام ۳: بارگذاری یک فایل
از متد استاتیک Scene.from_file() برای باز کردن هر فرمت پشتیبانیشده استفاده کنید. کتابخانه فرمت را بهصورت خودکار از پسوند فایل تشخیص میدهد.
##Automatic format detection
scene = Scene.from_file("model.obj")بهجای آن، یک Scene نمونه ایجاد کنید و فراخوانی کنید open(); مفید است وقتی میخواهید گزینههای بارگذاری را پاس کنید یا خطاها را بهصورت صریح مدیریت کنید:
scene = Scene()
scene.open("model.obj")هر دو روش از فایلهای OBJ، STL (دودویی و ASCII)، glTF 2.0 / GLB، COLLADA (DAE) و 3MF پشتیبانی میکنند.
گام ۴: پیمایش گرههای Scene
یک صحنه بارگذاریشده یک درخت از Node اشیائی که ریشه در scene.root_node. بهصورت بازگشتی تکرار کنید تا تمام گرهها را پیدا کنید:
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)هر Node میتواند صفر یا بیشتر داشته باشد Entity اشیاء (مشها، دوربینها، نورها). بررسی کنید node.entities تا ببینید چه چیزی پیوست شده است.
مرحلهٔ 5: دسترسی به دادههای راس و چندضلعی
موجودیت یک گره را به Mesh و نقاط کنترل آن (موقعیتهای راس) و چندضلعیها (فهرستهای ایندکس سطح) را بخوانید:
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 یک لیست از Vector4 اشیاء؛; x, y, z موقعیت و w مختصات همگن است (معمولاً 1.0).
mesh.polygons یک لیست از لیستهای اعداد صحیح است که در آن هر لیست داخلی مجموعهٔ مرتبشدهای از شاخصهای نقاط کنترل برای یک فیس است.
مرحلهٔ 6: اعمال گزینههای بارگذاری مخصوص فرمت
برای کنترل دقیق بر نحوهٔ تفسیر یک فایل OBJ، یک ObjLoadOptions نمونه را به 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)برای فایلهای STL، کلاس معادل است StlLoadOptions. برای glTF، از GltfLoadOptions. ببینید the مرجع API برای یک فهرست کامل.
مشکلات رایج و راهحلها
خطای FileNotFoundError هنگام فراخوانی Scene.from_file()
مسیر باید مطلق باشد یا نسبت به دایرکتوری کاری در زمان اجرا بهدرستی نسبی باشد. از pathlib.Path برای ساخت مسیرهای قابل اعتماد:
from pathlib import Path
from aspose.threed import Scene
path = Path(__file__).parent / "assets" / "model.obj"
scene = Scene.from_file(str(path))mesh.polygons پس از بارگذاری یک فایل STL خالی است
فایلهای STL مثلثها را بهصورت فیستهای خام ذخیره میکنند، نه یک مش ایندکسشده. پس از بارگذاری، چندضلعیها از آن فیستها ترکیب میشوند. اگر polygons خالی بهنظر میرسد، بررسی کنید len(mesh.control_points); اگر تعداد مضربی از ۳ باشد، هندسه بهصورت بدون ایندکس ذخیره میشود و هر سهگانه متوالی رئوس یک مثلث را تشکیل میدهد.
عدم تطابق سیستم مختصات (مدل بهنظر میرسد چرخیده یا آینهای باشد)
ابزارهای مختلف از قراردادهای متفاوتی استفاده میکنند (Y‑up در مقابل Z‑up، دست چپ در مقابل دست راست). تنظیم کنید ObjLoadOptions.flip_coordinate_system = True یا یک چرخش به ریشه گرهٔ Transform پس از بارگذاری.
AttributeError: 'NoneType' object has no attribute 'polygons'
فهرست موجودیتهای یک گره ممکن است شامل موجودیتهای غیر مش (دوربینها، نورها) باشد. همیشه با isinstance(entity, Mesh) قبل از تبدیل.
سوالات متداول (FAQ)
کدام فرمتهای 3D را میتوانم بارگذاری کنم؟?
OBJ (Wavefront)، STL (دودویی و متنی)، glTF 2.0 / GLB، COLLADA (DAE) و 3MF. توکنیزاسیون فایل FBX بهصورت جزئی پشتیبانی میشود اما تجزیه کامل هنوز تکمیل نشده است.
آیا بارگذاری یک فایل OBJ همچنین .mtl ماتریال؟?
بله، وقتی ObjLoadOptions.enable_materials = True (پیشفرض). کتابخانه به دنبال .mtl فایل در همان دایرکتوری که .obj فایل. اگر the .mtl وجود ندارد، هندسه همچنان بارگذاری میشود و یک هشدار صادر میگردد.
آیا میتوانم بهجای مسیر، فایلی را از یک جریان بایت بارگذاری کنم؟?
بله. scene.open() هر شیء شبیهفایلی را که دارای یک .read() متد علاوه بر یک رشته مسیر فایل میپذیرد. یک جریان باینری باز (به عنوان مثال،., io.BytesIO) بهصورت مستقیم. Scene.from_file() فقط یک رشته مسیر فایل را میپذیرد.
چگونه میتوانم نرمالهای سطح را دریافت کنم؟?
پس از بارگذاری، بررسی کنید mesh.get_element(VertexElementType.NORMAL). این یک VertexElementNormal که data فهرست شامل یک بردار نرمال برای هر مرجع است که بر اساس mapping_mode و reference_mode.
from aspose.threed.entities import Mesh, VertexElementType
normals = mesh.get_element(VertexElementType.NORMAL)
if normals:
print(normals.data[0]) # First normal vectorآیا کتابخانه برای بارگذاری همزمان چندین فایل thread‑safe است؟?
هر Scene شیء مستقل است. بارگذاری فایلهای جداگانه بهصورت جداگانه Scene نمونهها از رشتههای جداگانه ایمن هستند بهشرط اینکه یک Scene در میان رشتهها بدون قفلگذاری خارجی.