الميزات والوظائف

الميزات والوظائف

توفر Aspose.3D FOSS for Python واجهة برمجة تطبيقات كاملة للرسم البياني للمشهد لقراءة وإنشاء وكتابة محتوى ثلاثي الأبعاد بعدة تنسيقات معيارية في الصناعة. توثّق هذه الصفحة كل مجال ميزات رئيسي مع أمثلة شفرة بايثون تعمل تستخدم واجهة برمجة التطبيقات الفعلية للمكتبة.

التثبيت والإعداد

قم بتثبيت المكتبة من PyPI بأمر واحد:

pip install aspose-3d-foss

لا توجد حزم نظام إضافية أو امتدادات أصلية أو سلاسل أدوات المترجم مطلوبة. المكتبة هي بايثون صافية وتدعم بايثون 3.7 حتى 3.12 على ويندوز، ماك أو إس، ولينكس.

للتحقق من التثبيت:

from aspose.threed import Scene

scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")

الميزات والوظائف

دعم الصيغ

تقرأ وتكتب Aspose.3D FOSS for Python الصيغ التالية:

FormatExtensionقراءةكتابةملاحظات
Wavefront OBJ.objنعمنعمدعم تحميل مواد .mtl
STL (binary).stlنعمنعمتم التحقق من الجولة الكاملة (39 اختبارًا)
STL (ASCII).stlنعمنعمتم التحقق من الجولة الكاملة
glTF 2.0.gltfنعمنعمتم الحفاظ على مخطط المشهد الكامل
GLB (binary glTF).glbنعمنعمحاوية ثنائية بملف واحد
COLLADA.daeنعمنعمهيكلية المشهد والمواد
3MF.3mfنعمنعمتنسيق التصنيع الإضافي
FBX.fbxجزئيلامحلل الرموز يعمل؛ المحلل يحتوي على أخطاء معروفة

تحميل OBJ مع الخيارات

ObjLoadOptions يتحكم في طريقة تحليل ملفات OBJ:

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

options = ObjLoadOptions()
options.enable_materials = True        # Load accompanying .mtl file
options.flip_coordinate_system = False # Preserve original handedness
options.normalize_normal = True        # Normalize vertex normals to unit length
options.scale = 1.0                    # Apply a uniform scale factor at load time

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

print(f"Loaded {len(scene.root_node.child_nodes)} top-level nodes")

حفظ إلى STL

StlSaveOptions يتحكم في الإخراج الثنائي مقابل ASCII وإعدادات أخرى خاصة بـ STL:

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

scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)

مخطط المشهد

جميع المحتوى ثلاثي الأبعاد مُنظم كشجرة من كائنات Node. جذر الشجرة هو scene.root_node. يمكن لكل عقدة أن تحتوي على عقد فرعية وتحمل Entity (شبكة، كاميرا، أو إضاءة) بالإضافة إلى Transform.

التنقل في تسلسل المشهد الهرمي

from aspose.threed import Scene

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

def traverse(node, depth=0):
    indent = "  " * depth
    entity_type = type(node.entity).__name__ if node.entity else "none"
    print(f"{indent}{node.name} [{entity_type}]")
    for child in node.child_nodes:
        traverse(child, depth + 1)

traverse(scene.root_node)

إنشاء مشهد برمجياً

from aspose.threed import Scene, Node, Entity
from aspose.threed.entities import Mesh
from aspose.threed.utilities import Vector3

scene = Scene()
root = scene.root_node

##Create a child node and position it
child = root.create_child_node("my_object")
child.transform.translation = Vector3(1.0, 0.0, 0.0)
child.transform.scaling = Vector3(2.0, 2.0, 2.0)

scene.save("constructed.glb")

فحص GlobalTransform

GlobalTransform يعطي تحويل الفضاء العالمي لعقدة بعد تجميع جميع تحويلات الأسلاف:

from aspose.threed import Scene

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

for node in scene.root_node.child_nodes:
    gt = node.global_transform
    print(f"Node: {node.name}")
    print(f"  World translation: {gt.translation}")
    print(f"  World scale: {gt.scale}")

Mesh API

تُتيح كيان Mesh الوصول إلى بيانات الهندسة بما في ذلك نقاط التحكم (الرؤوس)، المضلعات، وعناصر الرؤوس للاتجاهات العادية، إحداثيات UV، والألوان.

قراءة هندسة الشبكة

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

options = ObjLoadOptions()
options.enable_materials = True
options.flip_coordinate_system = False

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

for node in scene.root_node.child_nodes:
    if node.entity is None:
        continue
    mesh = node.entity
    print(f"Mesh: {node.name}")
    print(f"  Vertices: {len(mesh.control_points)}")
    print(f"  Polygons: {len(mesh.polygons)}")

الوصول إلى عناصر الرأس

تحمل عناصر الرؤوس بيانات لكل رأس أو لكل مضلع. أكثر العناصر شيوعًا هي normals، UV coordinates، vertex colors، و smoothing groups:

from aspose.threed import Scene
from aspose.threed.entities import VertexElementNormal, VertexElementUV

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

for node in scene.root_node.child_nodes:
    if node.entity is None:
        continue
    mesh = node.entity

    # Iterate vertex elements to find normals and UVs
    for element in mesh.vertex_elements:
        if isinstance(element, VertexElementNormal):
            print(f"  Normals count: {len(element.data)}")
        elif isinstance(element, VertexElementUV):
            print(f"  UV count: {len(element.data)}")

نظام المواد

يدعم Aspose.3D FOSS نوعين من المواد: LambertMaterial (تظليل انتشاري) و PhongMaterial (تظليل انعكاسي). يتم تحميل كلاهما تلقائيًا من ملفات .mtl عند استخدام ObjLoadOptions مع enable_materials = True.

مواد القراءة من OBJ

from aspose.threed import Scene
from aspose.threed.shading import LambertMaterial, PhongMaterial
from aspose.threed.formats import ObjLoadOptions

options = ObjLoadOptions()
options.enable_materials = True

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

for node in scene.root_node.child_nodes:
    mat = node.material
    if mat is None:
        continue
    print(f"Node: {node.name}")
    if isinstance(mat, PhongMaterial):
        print(f"  Type: Phong")
        print(f"  Diffuse: {mat.diffuse_color}")
        print(f"  Specular: {mat.specular_color}")
    elif isinstance(mat, LambertMaterial):
        print(f"  Type: Lambert")
        print(f"  Diffuse: {mat.diffuse_color}")

تعيين مادة برمجيًا

from aspose.threed import Scene, Node
from aspose.threed.shading import PhongMaterial
from aspose.threed.utilities import Vector3

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

material = PhongMaterial()
material.diffuse_color = Vector3(0.8, 0.2, 0.2)   # Red diffuse
material.specular_color = Vector3(1.0, 1.0, 1.0)  # White specular

##Apply to the first mesh node
for node in scene.root_node.child_nodes:
    if node.entity is not None:
        node.material = material
        break

scene.save("recolored.glb")

أدوات الرياضيات

توفر وحدة aspose.threed.utilities جميع أنواع الرياضيات الهندسية اللازمة لإنشاء المشهد وفحصه.

الفئةالغرض
Vector2متجه عائم ثنائي الأبعاد (إحداثيات UV)
Vector3متجه ثلاثي الأبعاد بدقة مزدوجة (المواقع، المتجهات العمودية)
Vector4متجه رباعي الأبعاد بدقة مزدوجة (إحداثيات متجانسة)
FVector3متجه ثلاثي الأبعاد بدقة مفردة (تخزين مدمج)
Quaternionتمثيل الدوران بدون قفل الجيمبال
Matrix4مصفوفة تحويل 4×4
BoundingBoxصندوق احتواء محاذى للمحاور مع زوايا الحد الأدنى/الأقصى

العمل مع التحويلات

from aspose.threed.utilities import Vector3, Quaternion, Matrix4
import math

##Build a rotation quaternion from axis-angle
axis = Vector3(0.0, 1.0, 0.0)          # Y-axis
angle_rad = math.radians(45.0)
q = Quaternion.from_angle_axis(angle_rad, axis)

print(f"Quaternion: x={q.x:.4f} y={q.y:.4f} z={q.z:.4f} w={q.w:.4f}")

##Convert to rotation matrix
mat = q.to_matrix()
print(f"Rotation matrix row 0: {mat[0, 0]:.4f} {mat[0, 1]:.4f} {mat[0, 2]:.4f}")

حساب صندوق الحدود

from aspose.threed import Scene

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

# NOTE: mesh.get_bounding_box() is a stub — it always returns an empty BoundingBox()
# regardless of geometry. Compute bounds manually from control_points:
for node in scene.root_node.child_nodes:
    if node.entity is None:
        continue
    mesh = node.entity
    pts = mesh.control_points  # returns a copy of the vertex list
    if not pts:
        continue
    xs = [p.x for p in pts]
    ys = [p.y for p in pts]
    zs = [p.z for p in pts]
    print(f"Mesh: {node.name}")
    print(f"  Min: ({min(xs):.3f}, {min(ys):.3f}, {min(zs):.3f})")
    print(f"  Max: ({max(xs):.3f}, {max(ys):.3f}, {max(zs):.3f})")

الرسوم المتحركة

توفر Aspose.3D FOSS نموذجًا للرسوم المتحركة يعتمد على AnimationClip، AnimationNode، KeyFrame، وKeyframeSequence. يمكن الوصول إلى بيانات الرسوم المتحركة المخزنة في الملفات التي تم تحميلها (glTF، COLLADA) من خلال هذه الكائنات.

قراءة مقاطع الرسوم المتحركة

from aspose.threed import Scene

scene = Scene.from_file("animated.glb")

for clip in scene.animation_clips:
    print(f"Clip: {clip.name}  ({clip.start:.2f}s – {clip.stop:.2f}s)")
    for anim_node in clip.animations:
        print(f"  Animation node: {anim_node.name}")
        for sub in anim_node.sub_animations:
            print(f"    Sub-animation: {sub.name}")
        for bp in anim_node.bind_points:
            print(f"    Bind point: {bp.name}")

خيارات التحميل والحفظ

كل تنسيق مدعوم له فئة خيارات مقابلة تتحكم في سلوك التحليل والتسلسل.

الفئةالصيغةالخصائص الرئيسية
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLالوضع الثنائي مقابل وضع ASCII
(glTF يستخدم الإعدادات الافتراضية)glTF / GLBمخطط المشهد والمواد محفوظان تلقائيًا

أمثلة الاستخدام

مثال 1: تحويل تنسيق OBJ إلى STL

تحويل ملف OBJ (مع المواد) إلى STL ثنائي، مع طباعة إحصائيات الشبكة على طول العملية:

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

##Load OBJ with material support
load_opts = ObjLoadOptions()
load_opts.enable_materials = True
load_opts.flip_coordinate_system = False
load_opts.normalize_normal = True

scene = Scene()
scene.open("input.obj", load_opts)

##Report what was loaded
total_vertices = 0
total_polygons = 0
for node in scene.root_node.child_nodes:
    if node.entity is not None:
        mesh = node.entity
        total_vertices += len(mesh.control_points)
        total_polygons += len(mesh.polygons)
        print(f"  {node.name}: {len(mesh.control_points)} vertices, {len(mesh.polygons)} polygons")

print(f"Total: {total_vertices} vertices, {total_polygons} polygons")

##Save as STL
save_opts = StlSaveOptions()
scene.save("output.stl", save_opts)
print("Saved output.stl")

مثال 2: تجميع دفعة glTF إلى GLB

إعادة حفظ دليل يحتوي على ملفات glTF + القوام منفصلة كملفات ثنائية GLB ذاتية الاحتواء:

import os
from aspose.threed import Scene

input_dir = "gltf_files"
output_dir = "glb_files"
os.makedirs(output_dir, exist_ok=True)

for filename in os.listdir(input_dir):
    if not filename.endswith(".gltf"):
        continue
    src = os.path.join(input_dir, filename)
    dst = os.path.join(output_dir, filename.replace(".gltf", ".glb"))
    scene = Scene.from_file(src)
    scene.save(dst)
    print(f"Packed {filename} -> {os.path.basename(dst)}")

مثال 3: فحص مخطط المشهد وتقرير التصدير

تجول في مخطط مشهد ملف COLLADA، اجمع إحصائيات لكل شبكة، واطبع تقريرًا منظمًا:

from aspose.threed import Scene

scene = Scene.from_file("assembly.dae")

report = []

def collect(node, path=""):
    full_path = f"{path}/{node.name}" if node.name else path
    if node.entity is not None:
        mesh = node.entity
        gt = node.global_transform
        report.append({
            "path": full_path,
            "vertices": len(mesh.control_points),
            "polygons": len(mesh.polygons),
            "world_x": gt.translation.x,
            "world_y": gt.translation.y,
            "world_z": gt.translation.z,
        })
    for child in node.child_nodes:
        collect(child, full_path)

collect(scene.root_node)

print(f"{'Path':<40} {'Verts':>6} {'Polys':>6} {'X':>8} {'Y':>8} {'Z':>8}")
print("-" * 78)
for entry in report:
    print(
        f"{entry['path']:<40} "
        f"{entry['vertices']:>6} "
        f"{entry['polygons']:>6} "
        f"{entry['world_x']:>8.3f} "
        f"{entry['world_y']:>8.3f} "
        f"{entry['world_z']:>8.3f}"
    )

نصائح وأفضل الممارسات

اختيار التنسيق

  • glTF 2.0 / GLB هو تنسيق التبادل الموصى به للمشاهد التي تشمل المواد، الرسوم المتحركة، والهياكل المعقدة. يفضَّل GLB (ثنائي) على glTF (نص + ملفات خارجية) من أجل القابلية للنقل.
  • STL هو الاختيار الصحيح عندما يكون المستهلك اللاحق مقطعًا، أداة CAD، أو أي أداة تحتاج فقط إلى الهندسة. لا يحمل STL بيانات مادة أو رسوم متحركة.
  • OBJ مدعوم على نطاق واسع وخيار جيد عندما يجب تبادل بيانات المادة مع أدوات أقدم. احرص دائمًا على إبقاء ملف .mtl بجانب ملف .obj.

أنظمة الإحداثيات

  • تستخدم التطبيقات المختلفة اتفاقيات مختلفة للاتجاه. اضبط ObjLoadOptions.flip_coordinate_system = True عند استيراد ملفات OBJ من الأدوات التي تستخدم نظام إحداثيات يميني إذا كان خط أنابيبك يتوقع إحداثيات يسارية، والعكس بالعكس.
  • تحقق من اتفاقية المحاور للعنصر المصدر قبل تطبيق أي انعكاس. يؤدي الانعكاس مرتين إلى تكوين هندسة غير صحيحة.

التطبيع

  • دائمًا قم بتعيين ObjLoadOptions.normalize_normal = True عندما يتوقع خط الأنابيب اللاحق وحدات النورمال (على سبيل المثال، عند تمرير النورمال إلى شادر أو إجراء حسابات إضاءة باستخدام حاصل الضرب النقطي). النورمال غير المعيّنة من ملفات OBJ غير المتكوّنة بشكل صحيح تسبب تشوهات الإضاءة.

الأداء

  • حمّل الملفات مرة واحدة وحوّل مخطط المشهد الموجود في الذاكرة بدلاً من إعادة التحميل من القرص لكل تنسيق إخراج. استدعاء Scene.from_file() واحد يليه عدة استدعاءات scene.save() يكون أكثر كفاءة من التحميل المتكرر.
  • عند معالجة دفعات كبيرة، أنشئ نسخة واحدة من ObjLoadOptions أو StlSaveOptions وأعد استخدامها عبر جميع الملفات بدلاً من إنشاء كائن خيارات جديد لكل ملف.

معالجة الأخطاء

  • غلف استدعاءات scene.open() و scene.save() في كتل try/except عند معالجة الملفات غير الموثوقة أو التي يقدمها المستخدم. أبلغ عن اسم الملف في رسائل الاستثناء لتبسيط تصحيح الأخطاء في خطوط الأنابيب الدفعية.

مشكلات شائعة

المشكلةالسببالحل
تظهر الشبكة معكوسة بعد التحميلعدم توافق اتجاه نظام الإحداثياتبدّل ObjLoadOptions.flip_coordinate_system
العموديات ذات طول صفرملف المصدر يحتوي على عموديات غير مُعَدةعيّن ObjLoadOptions.normalize_normal = True
لم يتم تحميل المواد من OBJenable_materials هو False (الافتراضي)عيّن ObjLoadOptions.enable_materials = True
يتم تحميل المشهد لكن جميع العقد فارغةالملف يستخدم تنسيق FBXمحلل FBX قيد التطوير؛ استخدم OBJ أو STL أو glTF بدلاً من ذلك
النموذج صغير جدًا أو كبير جدًاملف المصدر يستخدم وحدات غير متريةطبق ObjLoadOptions.scale لتحويله إلى وحدتك المستهدفة
AttributeError على mesh.polygonsكيان العقدة ليس شبكةاحمِ باستخدام if node.entity is not None قبل الوصول إلى خصائص الكيان
تم رفض ملف GLB من قبل العارضتم حفظه بامتداد .gltfاستخدم امتداد .glb عند استدعاء scene.save() لتفعيل الحاوية الثنائية

الأسئلة المتكررة

ما إصدارات بايثون المدعومة؟
Python 3.7، 3.8، 3.9، 3.10، 3.11، و 3.12 كلها مدعومة. المكتبة مكتوبة بلغة بايثون خالصة دون أي امتداد أصلي، لذا تعمل على أي منصة تشغل CPython.

هل تحتوي المكتبة على أي تبعيات خارجية؟ لا. Aspose.3D FOSS for Python يستخدم فقط مكتبة Python القياسية. يتم تثبيتها بأمر واحد pip install aspose-3d-foss دون خطوات متابعة.

هل يتم دعم FBX؟
تم تنفيذ محلل FBX ويمكنه تحليل تدفق الرموز الثنائية لـ FBX، لكن مُنشئ مخطط المشهد فوق المحلل يحتوي على أخطاء معروفة وليس جاهزًا للإنتاج. استخدم OBJ أو STL أو glTF أو COLLADA أو 3MF للاستخدام الإنتاجي الموثوق.

هل يمكنني استخدام Aspose.3D FOSS في منتج تجاري؟ نعم. تم إصدار المكتبة تحت رخصة MIT، التي تسمح بالاستخدام في البرمجيات المملوكة والتجارية دون دفع رسوم ملكية، بشرط تضمين إشعار الرخصة.

كيف يمكنني الإبلاغ عن خطأ أو طلب تنسيق؟
افتح مشكلة في المستودع. قم بتضمين ملف تكرار بسيط وإصدار بايثون، نظام التشغيل، وإصدار المكتبة من pip show aspose-3d-foss.


ملخص مرجع API

الفئات الأساسية

  • Scene: حاوية المستوى الأعلى لمشهد ثلاثي الأبعاد. نقطة الدخول لـ open()، from_file()، وsave().
  • Node: عقدة شجرة في رسم المشهد. تحمل entity، transform، global_transform، material، child_nodes، وname.
  • Entity: الفئة الأساسية للكائنات المرفقة بالعقد (شبكة، كاميرا، إضاءة).
  • Transform: الموضع، الدوران (كواتيرنيون)، والقياس في الفضاء المحلي لعقدة.
  • GlobalTransform: تحويل الفضاء العالمي للقراءة فقط يتم حسابه بتجميع جميع تحويلات الأسلاف.

الهندسة

  • Mesh: شبكة مضلعات مع control_points (قائمة الرؤوس) و polygons.
  • VertexElementNormal: متجهات العمودي لكل رأس أو لكل مضلع.
  • VertexElementUV: إحداثيات القوام UV لكل رأس.
  • VertexElementVertexColor: بيانات اللون لكل رأس.
  • VertexElementSmoothingGroup: تعيينات مجموعة التنعيم للمضلعات.

المواد

  • LambertMaterial: نموذج التظليل المنتشر مع diffuse_color و emissive_color.
  • PhongMaterial: نموذج التظليل اللامع يضيف specular_color و shininess.

أدوات الرياضيات (aspose.threed.utilities)

  • Vector2: متجه ثنائي الأبعاد.
  • Vector3: متجه ثلاثي الأبعاد بدقة مزدوجة.
  • Vector4: متجه رباعي الأبعاد بدقة مزدوجة.
  • FVector3: متجه ثلاثي الأبعاد بدقة مفردة.
  • Quaternion: رباعي دوران مع from_angle_axis() وto_matrix().
  • Matrix4: مصفوفة تحويل 4×4.
  • BoundingBox: صندوق احتواء محاذى للمحاور مع زوايا minimum وmaximum.

الرسوم المتحركة

  • AnimationClip: حاوية مسماة لمجموعة من قنوات الرسوم المتحركة وإطاراتها المفتاحية.
  • AnimationNode: بيانات الرسوم المتحركة لكل عقدة داخل المقطع.
  • KeyFrame: إطار مفتاح واحد مع الوقت والقيمة.
  • KeyframeSequence: تسلسل مرتب من إطارات المفاتيح لخاصية متحركة واحدة.

خيارات التحميل / الحفظ

  • ObjLoadOptions: إعدادات التحميل الخاصة بـ OBJ: enable_materials، flip_coordinate_system، normalize_normal، scale.
  • StlSaveOptions: إعدادات الحفظ الخاصة بـ STL (الوضع الثنائي مقابل وضع ASCII).

الكاميرات والإضاءة

  • Camera: كيان الكاميرا مع إعدادات الإسقاط، قابل للإرفاق إلى Node.
  • Light: كيان مصدر الضوء، قابل للإرفاق إلى Node.
 العربية