مشاهدة Graph

أ أ المشهد الرسمي هو نموذج البيانات الأساسية لـ Aspose.3D FOSS for Python. كل ملف 3D، سواء تم تحميلها من القرص أو تم بناءه في الذاكرة، يتم تمثيلها كشجرة من Node الأجسام التي تُدخل في Scene.root_node.يمكن لكل عقدة أن تحمل عقدات الطفل وواحدة أو أكثر. Entity الكائنات (المؤتمرات، الكاميرات والأضواء).فهم الرسم البياني للمشهد يمنحك الوصول المباشر إلى الهندسة والملفات والتحولات الفضائية لكل كائن في المشهد.

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

قم بتثبيت المكتبة من PyPI:

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

لا تتطلب التمديدات أو المجموعات أو حزم النظام الإضافية.للمبادئ التوجيهية الكاملة، انظر: دليل التثبيت.


الموضوع: مشاهدة فيلم Scene Graph Concepts

يلي الرسم البياني للمشهد في Aspose.3D FOSS سلسلة بسيطة من التخزين:

Scene
└── root_node  (Node)
    ├── child_node_A  (Node)
    │   ├── entity: Mesh
    │   └── transform: translation, rotation, scale
    ├── child_node_B  (Node)
    │   └── child_node_C  (Node)
    │       └── entity: Mesh
    └── ...
الموضوعدور
Sceneالحاوية العليا - حوض root_node, asset_info, animation_clips,و ، و sub_scenes.
Node- اسم العقدة: لديه أحد الوالدين، صفر أو أكثر من الأطفال، الصفر أم أكثر الكيانات، ومكانية Transform.
Entityالجيومتر أو الكائن المسرحي المرفق إلى عقدة.أنواع الكيانات الشائعة: Mesh, Camera, Light.
Transformموقع الفضاء المحلي، والدورات، والمقياس لنوود.نتائج الفضائيات العالمية يتم قراءتها من global_transform.

خطوة بخطوة: بناء الرسم البياني المشهد برمجة

الخطوة الأولى: إنشاء مشهد

و جديد Scene يبدأ دائماً بالخروج من الفراغ. root_node:

from aspose.threed import Scene

scene = Scene()
print(scene.root_node.name)   # "" (empty string — root node has no name by default)
print(len(scene.root_node.child_nodes))  # 0

Scene هو نقطة الدخول لكل شيء: تحميل الملفات، وتخزين المجلدات, إنشاء مقاطع الرسوم المتحركة, والوصول إلى شجرة العقد.


الخطوة 2: إنشاء أشرطة الأطفال

استخدام create_child_node(name) إضافة أسماء العقد إلى الشجرة:

from aspose.threed import Scene

scene = Scene()

parent = scene.root_node.create_child_node("parent")
child  = parent.create_child_node("child")

print(parent.name)                          # "parent"
print(child.parent_node.name)               # "parent"
print(len(scene.root_node.child_nodes))     # 1

بدلاً من ذلك، قم بإنشاء نظام ثابت. Node و يضيفها صراحة:

from aspose.threed import Scene, Node

scene = Scene()
node = Node("standalone")
scene.root_node.add_child_node(node)

كلا النهجين يحققان نفس النتيجة. create_child_node أكثر صرامة للبناء داخل الخط.


الخطوة 3: إنشاء كيان Mesh وربطه

أ أ Mesh أضف تعليق حول (control_points(وأما في الدنيا فهي تُعرف على التفكير)polygonsإنشاء واحد ، إضافة الهندسة الجيولوجية ، ثم ضعه إلى عقدة:

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

scene = Scene()
parent = scene.root_node.create_child_node("parent")
child  = parent.create_child_node("child")

##Create a quad mesh (four vertices, one polygon)
# Note: control_points returns a copy of the internal list; append to
# _control_points directly to actually add vertices. This is a known
# library limitation — a public add_control_point() API is not yet available.
mesh = Mesh("cube")
mesh._control_points.append(Vector4(0, 0, 0, 1))
mesh._control_points.append(Vector4(1, 0, 0, 1))
mesh._control_points.append(Vector4(1, 1, 0, 1))
mesh._control_points.append(Vector4(0, 1, 0, 1))
mesh.create_polygon(0, 1, 2, 3)

child.add_entity(mesh)

print(f"Mesh name:      {mesh.name}")
print(f"Vertex count:   {len(mesh.control_points)}")
print(f"Polygon count:  {mesh.polygon_count}")

Vector4(x, y, z, w) يقدم اتساقًا متجانسًّا.استخدام w=1 من أجل مواقف نقطة منتظمة.

create_polygon(*indices) يقبل المؤشرات العمودية ويسجل وجهًا واحدًّا في قائمة البوليغونات.تجاوز ثلاثة مؤشرات لثلاثة أجزاء، وأربعة لربع.


الخطوة 4: إعداد تحويلات النود

كل عقدة لديها Transform التي تسيطر على موقفها، والتوجه، وحجمها في الفضاء المحلي:

from aspose.threed.utilities import Vector3, Quaternion

##Translate the node 2 units along the X axis
child.transform.translation = Vector3(2.0, 0.0, 0.0)

##Scale the node to half its natural size
child.transform.scaling = Vector3(0.5, 0.5, 0.5)

##Rotate 45 degrees around the Y axis using Euler angles
child.transform.euler_angles = Vector3(0.0, 45.0, 0.0)

التحولات متراكمة: موقع الفضاء العالمي في عقدة الطفل هو تكوين تحولها الخاص مع جميع التحويلات الأجداد. node.global_transform (مستحيل و لا يقرأ إلا ).


الخطوة 5: اجتياز المسرحية الرسوم المتكررة

تسير على الشجرة بأكملها من خلال التراجع عن طريق node.child_nodes:

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)

نموذج الخروج للمشهد الذي تم بناؤه أعلاه (اسم عقدة الجذر هو سلك فارغ):

 [None]
  parent [None]
    child [Mesh]

للمشاهد مع العديد من الكيانات لكل عقدة، إيترايت node.entities بدلاً من node.entity:

def traverse_full(node, depth=0):
    indent = "  " * depth
    entity_names = [type(e).__name__ for e in node.entities] or ["None"]
    print(f"{indent}{node.name} [{', '.join(entity_names)}]")
    for child in node.child_nodes:
        traverse_full(child, depth + 1)

traverse_full(scene.root_node)

الخطوة 6: حفظ المشهد

قم بتوجيه مسار الملف إلى scene.save().تنزيل النموذج من ملحق الملف:

scene.save("scene.gltf")   # JSON glTF 2.0
scene.save("scene.glb")    # Binary GLB container
scene.save("scene.obj")    # Wavefront OBJ
scene.save("scene.stl")    # STL

بالنسبة للخيارات المحددة للنموذج، قم بتقديم كائن خيارات التخزين كحجة ثانية:

from aspose.threed.formats import GltfSaveOptions

opts = GltfSaveOptions()
scene.save("scene.gltf", opts)

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

  • اسم كل عقدة. إعطاء العقد أسماء ذات مغزى يجعل التفريغ عبرات أسهل بكثير ويضمن أن الأسماء يتم الحفاظ عليها في الملف المستورد.
  • 1 ملعقة لكل عقدة. الحفاظ على الكيانات 1:1 مع العقد يسهل التحولات والتصادم الأسئلة.
  • استخدام create_child_node عن طريق اليد المرفقة. يضع الإشارة الأصلية تلقائيًا ويكون أقل عرضة للخطأ.
  • قراءة global_transform بعد أن تم بناء الهرم. إن النتيجة الفضائية العالمية مستقرة فقط بمجرد أن يتم وضع جميع التحولات الأجدية.
  • لا تتحول الشجرة أثناء التجول. إضافة أو إزالة عقدة الطفل أثناء التآكل child_nodes سوف تنتج سلوك غير متوقع. جمع العقدة أولا، ثم تعديل.
  • استخدام نقاط التحكم Vector4,لا ، لا Vector3. دائماً اجتاز w=1 - الموقف العادي للفيرتكس.; w=0 يمثل اتجاه فيكتور (وليس نقطة).
  • mesh.control_points إرجاع نسخة. وَالْمُتَّقِينَ control_points عودة الممتلكات list(self._control_points) - يرفع إلى القائمة التي تم إرجاعها لا يتغير المزيج. mesh._control_points هذا هو الحد المكتبي المعروف؛ API المتغيرات العامة لا يوجد بعد.

القضايا المشتركة

مسألةالقرار
AttributeError: 'NoneType' object has no attribute 'polygons'الحراسة مع if node.entity is not None قبل الوصول إلى ممتلكات الكيان.مصدر بدون كيانات لديه entity = None.
يظهر الماس في الأصل على الرغم من الإعدادات translationtransform.translation إذا كان النقطة الأم نفسها لديها تحويل غير الهوية ، فقد تختلف موقف العالم. global_transform.
طفل يفتقر بعد scene.save() / تحميلبعض تنسيقات (OBJ) تلمع الهرم.استخدم glTF أو COLLADA للحفاظ على شجرة العقد الكاملة.
polygon_count 0 بعد mesh.create_polygon(...)تأكد من أن المؤشرات الورقية قد انتقلت إلى create_polygon في المدى القصير (0 إلى len(control_points) - 1).
Node.get_child(name) العودة Noneاسم الحالة حساسة.تأكيد سلك الاسم الدقيق المستخدم في وقت إنشاء.
زيارات العقد في ترتيب غير متوقعchild_nodes إعادة الأطفال في أمر الإدراج (الطلب) add_child_node / create_child_node وَلَمْ يُدْرِكْهُ ) .
 العربية