सीन ग्राफ

A सीन ग्राफ Aspose.3D FOSS for Python का मूलभूत डेटा मॉडल है। प्रत्येक 3D फ़ाइल, चाहे डिस्क से लोड की गई हो या मेमोरी में निर्मित, को एक ट्री के रूप में दर्शाया जाता है Node ऑब्जेक्ट्स जो मूल रूप से स्थित हैं Scene.root_node. प्रत्येक नोड में चाइल्ड नोड्स और एक या अधिक Entity ऑब्जेक्ट्स (मेशेज़, कैमरे, लाइट्स)। सीन ग्राफ को समझने से आपको सीन में प्रत्येक ऑब्जेक्ट की ज्योमेट्री, मैटेरियल्स, और स्पेशियल ट्रांसफ़ॉर्म्स तक सीधा पहुँच मिलती है।.

स्थापना और सेटअप

PyPI से लाइब्रेरी स्थापित करें:

pip install aspose-3d-foss

कोई नेटिव एक्सटेंशन, कंपाइलर, या अतिरिक्त सिस्टम पैकेज आवश्यक नहीं हैं। पूर्ण इंस्टॉलेशन निर्देशों के लिए, देखें इंस्टॉलेशन गाइड.


सारांश: सीन ग्राफ अवधारणाएँ

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.

स्टेप-बाय-स्टेप: प्रोग्रामेटिकली सीन ग्राफ बनाना

स्टेप 1: एक सीन बनाएं

एक नया 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 Entity बनाएं और उसे संलग्न करें

एक 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

फ़ॉर्मेट‑विशिष्ट विकल्पों के लिए, दूसरे आर्ग्यूमेंट के रूप में एक save-options ऑब्जेक्ट पास करें:

from aspose.threed.formats import GltfSaveOptions

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

टिप्स और सर्वोत्तम प्रथाएँ

  • प्रत्येक नोड का नाम रखें. नोड्स को सार्थक नाम देने से ट्रैवर्सल डिबगिंग बहुत आसान हो जाती है और यह सुनिश्चित करता है कि नाम निर्यातित फ़ाइल में संरक्षित रहें.
  • प्रत्येक नोड पर एक मेष. इकाइयों को नोड्स के साथ 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 को कॉल किया गया था)।.
 हिन्दी