كيفية تحميل النماذج 3D في Python
Aspose.3D FOSS for Python يوفر API بسيط لفتح ملفات 3D دون أي إدمانات أصلية. Scene الكائن، يمكنك المشي في الهرم العقدي وقراءة البيانات الجغرافية الخام لكل مساحة في المشهد.
خطوة بخطوة دليل
الخطوة 1: قم بتثبيت الحزمة
تثبيت Aspose.3D FOSS من PyPI. لا تتطلب مكتبات نظام إضافية.
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.
الإصدارات التي تدعمها Python: 3.7، 3.8، 39.9، 3.0، 3.11.
الخطوة 2: استيراد فئة المشهد
وَالْمُتَّقِينَ 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 الملفات.
الخطوة 4: عبور نواة المشهد
المشهد المزدحم هو شجرة من 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: الوصول إلى Vertex و Polygon Data
إدخال كيان النود إلى 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.لـ GST ، استخدم GltfLoadOptions.انظروا إلى إشارة 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);إذا كان العد متعدد من 3 يتم تخزين الهندسة في شكل غير مؤشر وكل ثلاثية متتالية من الأركان تشكل مثلث واحد.
نظام المنسق غير متوافق (يظهر النموذج مستديرًا أو مرآة)
أدوات مختلفة تستخدم موافقات مختلف (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 (binary و ASCII) و glTF 2.0 / GLB ، COLLADA (DAE) وال 3MF. يتم دعم توكينات ملف FBX جزئياً ولكن لا يزال التقطيع الكامل غير كامل.
هل تحميل ملف OBJ أيضا تحميل .mtl المواد ؟?
نعم، عندما ObjLoadOptions.enable_materials = True (الإيجابية) يبحث المكتبة عن .mtl في نفس الدليل الذي يكتب به .obj الملفات، إذا كان .mtl لا يزال الهندسة محملة، ويتم إصدار تحذير.
هل يمكنني تحميل ملف من تدفق بايت بدلاً من مسار؟?
نعم . scene.open() يُقبل أي مادة مثل الملف مع .read() طريقة بالإضافة إلى شريط مسار الملفات.مرسلة مفتوحة تدفق ثنائي (على سبيل المثال،., io.BytesIO) مباشرة . Scene.from_file() فقط تقبل شريط مسار الملف.
كيف يمكنني الحصول على سطح طبيعي؟?
بعد التحميل، تحقق من mesh.get_element(VertexElementType.NORMAL).هذا يعود إلى A 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هل مكتبة الأقراص آمنة لتحميل ملفات متعددة في وقت واحد؟?
كل واحد منهم Scene موضوع مستقل. تحميل ملفات منفصلة إلى منفصلا Scene الحالات من الأسلاك منفصلة آمنة طالما أنك لا تشارك واحد Scene من خلال الأسلاك دون قفل خارجي.