Python में 3D दृश्य ग्राफ कैसे पार करें
Aspose.3D FOSS में दृश्य ग्राफ एक पेड़ है Node वस्तुओं में जड़ें scene.root_node.प्रत्येक 3D फ़ाइल, चाहे OBJ, glTF, STL, COLLADA या 3MF से लोड हो, एक ही पेड़ संरचना का उत्पादन करती है. इसे पार करने के तरीके को जानने से आपको भूमेट्री की जांच करनी पड़ती है, बहुआयामी गिनती कर सकती है और प्रकार-प्रकार में वस्तुओं को फिल्टर कर सकते हैं, और एक जटिल दृश्य के विशिष्ट हिस्सों को संसाधित कर सकता है।.
कदम-दर-चरण गाइड
चरण 1: स्थापना और आयात
PIPI से Aspose.3D FOSS स्थापित करें:
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.
आपको आवश्यक कक्षाओं का आयात करना होगा:
from aspose.threed import Scene
from aspose.threed.entities import Meshसभी सार्वजनिक वर्गों के नीचे रहते हैं aspose.threed या इसके उप-पैकेज (aspose.threed.entities, aspose.threed.utilities).
चरण 2: एक फ़ाइल से एक दृश्य लोड करें
स्टैटिक का उपयोग करें Scene.from_file() किसी भी समर्थित प्रारूप को खोलने का तरीका. फ़ाइल एक्सटेंशन से प्रारंभिक रूप स्वचालित रूप से पता चलता है:
scene = Scene.from_file("model.gltf")आप स्पष्ट लोड विकल्पों के साथ भी खोल सकते हैं:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True
scene = Scene()
scene.open("model.obj", options)लोड करने के बाद, scene.root_node सभी आयातित नोड्स इस नॉड के बच्चे या वंशज हैं।.
चरण 3: एक पुनरावृत्ति यात्रा कार्य लिखें
सबसे सरल पारगमन प्रत्येक नोड को गहराई से प्रथम क्रम में देखता है:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def traverse(node, depth=0):
prefix = " " * depth
entity_name = type(node.entity).__name__ if node.entity else "-"
print(f"{prefix}[{entity_name}] {node.name}")
for child in node.child_nodes:
traverse(child, depth + 1)
scene = Scene.from_file("model.gltf")
traverse(scene.root_node)उदाहरण के लिए:
[-]
[-] Armature
[Mesh] Body
[Mesh] Eyes
[-] Ground
[Mesh] Plane<button class=“hextra-code-copy-btn hx-group/copybtn hx-transition-all active:hx-opacity-50 hx-bg-primary-700/5 hx-border hx-border-black/5 hx-text-gray-600 hover:hx-text-gray-900 hx-rounded-md hx-p-1.5 dark:hx-bg-primary-300/10 dark:hx-border-white/10 dark:hx-text-gray-400 dark:hover:hx-text-gray-50” title=“Copy code”
<div class="copy-icon group-[.copied]/copybtn:hx-hidden hx-pointer-events-none hx-h-4 hx-w-4"></div>
<div class="success-icon hx-hidden group-[.copied]/copybtn:hx-block hx-pointer-events-none hx-h-4 hx-w-4"></div>
नोट : रूट नोड में एक खाली नाम है (
""(पहली पंक्ति दिखाती है)[-]नाम के बिना नहीं।.
node.child_nodes बच्चों को इनपुट आदेश में वापस लाता है (उदाहरण के लिए, जिस आदेश से आयातक या उपयोगकर्ता उन्हें जोड़ते हैं)।.
चरण 4: प्रत्येक नोड पर एक्सेस इकाई संपत्तियों
उपयोग करें node.entity पहली इकाई को एक नोड से जोड़ा जाना, या node.entities सभी को इटेरेट करने के लिए. प्रारूप-विशिष्ट गुणों तक पहुंचने से पहले प्रकार की जांच करें:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def print_entity_details(node, depth=0):
indent = " " * depth
for entity in node.entities:
if isinstance(entity, Mesh):
mesh = entity
print(f"{indent}Mesh '{node.name}':")
print(f"{indent} vertices : {len(mesh.control_points)}")
print(f"{indent} polygons : {mesh.polygon_count}")
print(f"{indent} cast_shadows : {mesh.cast_shadows}")
print(f"{indent} receive_shadows: {mesh.receive_shadows}")
for child in node.child_nodes:
print_entity_details(child, depth + 1)
scene = Scene.from_file("model.gltf")
print_entity_details(scene.root_node)node.transform.translation, node.transform.rotation,और node.transform.scaling स्थानीय-स्पेस परिवर्तन के लिए।. node.global_transform अंतरिक्ष के परिणामों का मूल्यांकन (जैसा कि global_transform.scale अंतरिक्ष के लिए).
चरण 5: एंटीइट प्रकार के अनुसार नोड्स फ़िल्टर करें
केवल विशिष्ट प्रकार के एंटीवायरस पर काम करने के लिए, एक isinstance गार्ड के अंदर:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def find_mesh_nodes(node, results=None):
if results is None:
results = []
for entity in node.entities:
if isinstance(entity, Mesh):
results.append(node)
break # One match per node is enough
for child in node.child_nodes:
find_mesh_nodes(child, results)
return results
scene = Scene.from_file("model.gltf")
mesh_nodes = find_mesh_nodes(scene.root_node)
print(f"Found {len(mesh_nodes)} mesh node(s)")
for n in mesh_nodes:
print(f" {n.name}")यह पैटर्न बड़े पैमाने पर संचालन के लिए उपयोगी है: प्रत्येक मशीन नोड में एक ट्रांसफार्मर लागू करना, सामग्री को प्रतिस्थापित करना या उप-पौधे निर्यात करना।.
चरण 6: सभी मेश और प्रिंट वर्टेक्स गिनती इकट्ठा करें
एक ही पास में मस्च आंकड़ों को जोड़ें:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def collect_meshes(node, results=None):
if results is None:
results = []
if isinstance(node.entity, Mesh):
results.append((node.name, node.entity))
for child in node.child_nodes:
collect_meshes(child, results)
return results
scene = Scene.from_file("model.gltf")
meshes = collect_meshes(scene.root_node)
print(f"Total meshes: {len(meshes)}")
total_verts = 0
total_polys = 0
for name, mesh in meshes:
verts = len(mesh.control_points)
polys = mesh.polygon_count
total_verts += verts
total_polys += polys
print(f" {name}: {verts} vertices, {polys} polygons")
print(f"Scene totals: {total_verts} vertices, {total_polys} polygons")सामान्य मुद्दे
| मुद्दे | संकल्प |
|---|---|
AttributeError: 'NoneType' object has no attribute 'polygons' | गार्ड के साथ if node.entity is not None या isinstance(node.entity, Mesh) मस्जिद संपत्ति तक पहुंचने से पहले. नोड्स बिना वस्तुओं वापस None. |
| यात्रा जल्दी बंद हो जाती है। | सुनिश्चित करें कि पुनरावृत्ति में प्रवेश किया जाए। node.child_nodes.अगर आप केवल इथेरेट करते हैं scene.root_node.child_nodes (आप सभी के लिए नहीं हैं) आप सभी को याद करते हैं।. |
| मिलने वाले परिणामों से गायब हो गए मेश | सुनिश्चित करें कि फ़ाइल प्रारूप हीराकी बनाए रखता है. OBJ सभी भूमध्यसागरी को एक नोड स्तर में फ्लैट करता है . गहरे आयरक्चर के लिए glTF या COLLADA का उपयोग करें. |
node.entity केवल पहली इकाई वापस आती है। | उपयोग करें node.entities (पूर्ण सूची) जब एक नोड कई वस्तुओं को ले जाता है।. node.entity एक छोटी सी बात है कि node.entities[0] जब entities वह अनैच्छिक है।. |
collect_meshes वापस 0 परिणाम एक लोड STL के लिए | STL फ़ाइलें आमतौर पर एक फ्लैट नोड बनाती हैं जिसमें सीधे नीचे एक मश वस्तु होती है। root_node.चेक करें root_node.child_nodes[0].entity सीधे।. |
| नोड नाम खाली तार हैं | कुछ प्रारूप (बिनरी STL, कुछ OBJ फ़ाइल) वस्तु नामों को संग्रहीत नहीं करते हैं. नोड्स खाली हो जाएंगे name तारों; पहचान के लिए संकेतक का उपयोग करें।. |
अक्सर पूछे जाने वाले प्रश्न
एक दृश्य ग्राफ कितना गहरा हो सकता है?
कोई कठिन सीमा नहीं है. Python की डिफ़ॉल्ट रिकर्सी सीमा (1000 फ्रेम) रीक्सेस क्रॉसल फ़ंक्शन पर लागू होती है . बहुत गहरी दार्शनिकताओं के लिए, रैक को एक स्पष्ट स्टैक्स में परिवर्तित करें:
from collections import deque
from aspose.threed import Scene
scene = Scene.from_file("deep.gltf")
queue = deque([(scene.root_node, 0)])
while queue:
node, depth = queue.popleft()
print(" " * depth + node.name)
for child in node.child_nodes:
queue.append((child, depth + 1))क्या मैं पेड़ को पार करते समय बदल सकता हूं?
न तो कणों को जोड़ें या हटा दें। child_nodes इसे इटेर करते समय. एक पहले पास में परिवर्तित करने के लिए कोडों को इकट्ठा करें, फिर दूसरे पास पर परिवर्तन लागू करें.
नाम के अनुसार एक विशिष्ट नोड कैसे पाएं?
उपयोग करें node.get_child(name) एक नाम के अनुसार एक सीधा बच्चा खोजने के लिए. गहरी खोज के लिये, एक नामांकन फ़िल्टर के साथ पेड़ से गुजरना:
def find_by_name(root, name):
if root.name == name:
return root
for child in root.child_nodes:
result = find_by_name(child, name)
if result:
return result
return None
target = find_by_name(scene.root_node, "Wheel_FL")क्या है node.entity हमेशा एक मशीन वापस आते हैं?
एक नोड किसी भी प्रकार के इकाई को पकड़ सकता है: Mesh, Camera, Light,हमेशा के लिए, या किसी भी व्यक्ति को नियंत्रित करें. हम हमसे संपर्क करें isinstance(node.entity, Mesh) मस्जिद विशेष गुणों का उपयोग करने से पहले।.
मैं एक नोड की विश्व-स्पेस स्थिति कैसे प्राप्त करता हूं?
पढ़ाई node.global_transform.translation.यह विश्व अंतरिक्ष में मूल्यांकन की स्थिति है, सभी पूर्वजों के परिवर्तनों को ध्यान में रखते हुए। node.transform.translation नोड को पुनर्स्थापित करें।.
क्या मैं एक दृश्य में कुल पॉलीगोन की गिनती कर सकता हूं बिना किसी क्रॉसाल लिखने के?
सीधे एपीआई के माध्यम से नहीं; कोई नहीं है scene.total_polygon_count संपत्ति का उपयोग करें collect_meshes और सारा mesh.polygon_count परिणामों के अनुसार, चरण 6 में दिखाया गया है।.