ویژگی‌ها و عملکردها

Aspose.3D FOSS برای Python یک API کامل گراف صحنه برای خواندن، ساخت و نوشتن محتوای سه‌بعدی در چندین فرمت استاندارد صنعتی فراهم می‌کند. این صفحه هر بخش اصلی ویژگی را با مثال‌های کد Python کارآمد که از API واقعی کتابخانه استفاده می‌کنند، مستند می‌کند.

نصب و راه‌اندازی

کتابخانه را از PyPI با یک فرمان واحد نصب کنید:

pip install aspose-3d-foss

هیچ بسته سیستمی اضافی، افزونه بومی یا ابزار زنجیره کامپایلر مورد نیاز نیست. کتابخانه کاملاً Python است و از Python 3.7 تا 3.12 بر روی ویندوز، macOS و لینوکس پشتیبانی می‌کند.

برای تأیید نصب:

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 برای Python فرمت‌های زیر را می‌خواند و می‌نویسد:

قالبپسوندخواندننوشتننکات
Wavefront OBJ.objبلهبله.mtl بارگذاری مواد پشتیبانی می‌شود
STL (دودویی).stlبلهبلهدورگردی تأیید شد (39 آزمون)
STL (ASCII).stlبلهبلهدورگردی تأیید شد
glTF 2.0.gltfبلهبلهگراف کامل صحنه حفظ شد
GLB (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 (mesh, camera, or light) به‌علاوه یک 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}")

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)}")

دسترسی به عناصر رئوس

عناصر رئوس داده‌های مربوط به هر رئوس یا هر چندضلعی را حمل می‌کنند. رایج‌ترین این عناصر شامل نرمال‌ها، مختصات UV، رنگ‌های رئوس و گروه‌های صاف‌سازی هستند:

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 (نورپردازی Specular). هر دو به‌صورت خودکار از فایل‌های .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 ماژول تمام انواع ریاضیات هندسی مورد نیاز برای ساخت و بررسی صحنه را فراهم می‌کند.

کلاسهدف
Vector22D floating-point vector (UV coordinates)
Vector33D double-precision vector (positions, normals)
Vector44D double-precision vector (homogeneous coordinates)
FVector33D single-precision vector (compact storage)
Quaternionنمایش چرخش بدون قفل گیمبال
Matrix44×4 transformation matrix
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گراف صحنه و مواد به‌صورت خودکار حفظ می‌شوند

نمونه‌های استفاده

مثال ۱: تبدیل فرمت 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")

مثال ۲: بسته‌بندی دسته‌ای 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)}")

مثال ۳: بازرسی گراف صحنه و گزارش خروجی

گراف صحنه یک فایل 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 بلوک‌ها هنگام پردازش فایل‌های غیرقابل اعتماد یا کاربر‑محور. نام فایل را در پیام‌های استثنا گزارش دهید تا اشکال‌زدایی در خطوط لولهٔ دسته‌ای ساده‌تر شود.

مشکلات رایج

مشکلدلیلراه‌حل
Mesh پس از بارگذاری به صورت معکوس ظاهر می‌شودعدم تطابق جهت‌گیری سیستم مختصاتتغییر وضعیت ObjLoadOptions.flip_coordinate_system
نرمال‌ها طول صفر دارندفایل منبع نرمال‌های نرمال‌نشده داردتنظیم ObjLoadOptions.normalize_normal = True
متریال‌ها از OBJ بارگذاری نشدندenable_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 پشتیبانی می‌شوند؟? Python 3.7، 3.8، 3.9، 3.10، 3.11 و 3.12 همگی پشتیبانی می‌شوند. این کتابخانه کاملاً Python است و هیچ افزونه بومی ندارد، بنابراین بر روی هر پلتفرمی که CPython اجرا می‌شود کار می‌کند.

آیا این کتابخانه وابستگی‌های خارجی دارد؟? خیر. Aspose.3D FOSS برای Python فقط از کتابخانه استاندارد Python استفاده می‌کند. این به‌صورت یک فرمان واحد نصب می‌شود pip install aspose-3d-foss دستور بدون مراحل پیگیری دیگر.

آیا FBX پشتیبانی می‌شود؟? توکن‌ساز FBX پیاده‌سازی شده و می‌تواند جریان توکن باینری FBX را تجزیه کند، اما سازنده گراف صحنه بر پایه توکن‌ساز دارای باگ‌های شناخته‌شده است و برای استفاده در تولید آماده نیست. برای استفاده قابل اعتماد در تولید، از OBJ، STL، glTF، COLLADA یا 3MF استفاده کنید.

آیا می‌توانم Aspose.3D FOSS را در یک محصول تجاری استفاده کنم؟? بله. این کتابخانه تحت مجوز MIT منتشر شده است که اجازه استفاده در نرم‌افزارهای مالکیتی و تجاری را بدون پرداخت حق امتیاز می‌دهد، به شرطی که اطلاعیه مجوز گنجانده شود.

چگونه می‌توانم یک باگ را گزارش دهم یا درخواست یک فرمت کنم؟? یک issue در مخزن باز کنید. شامل یک فایل بازتولید کنندهٔ حداقل و نسخهٔ Python، سیستم‌عامل و نسخهٔ کتابخانه از pip show aspose-3d-foss.


خلاصه مرجع API

کلاس‌های اصلی

  • Scene: محفظهٔ سطح بالای یک صحنهٔ سه‌بعدی. نقطهٔ ورودی برای open(), from_file(),، و save().
  • Node: گرهٔ درختی در گراف صحنه. حامل entity, transform, global_transform, material, child_nodes,، و name.
  • Entity: کلاس پایه برای اشیائی که به گره‌ها متصل می‌شوند (Mesh, Camera, Light).
  • Transform: موقعیت، چرخش (Quaternion) و مقیاس در فضای محلی برای یک گره.
  • 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: ماتریس تبدیل ۴×۴.
  • BoundingBox: جعبه محدود‌کننده محوری‌تراز شده با minimum : و maximum : گوشه‌ها.

انیمیشن

  • AnimationClip: محفظه نام‌گذاری‌شده برای مجموعه‌ای از کانال‌های انیمیشن و فریم‌های کلیدی آن‌ها.
  • AnimationNode: داده‌های انیمیشن برای هر گره درون یک کلیپ.
  • KeyFrame: یک فریم کلیدی تک با زمان و مقدار.
  • KeyframeSequence: دنبالهٔ مرتب فریم‌های کلیدی برای یک ویژگی انیمیشنی تک.

گزینه‌های بارگذاری / ذخیره‌سازی

  • ObjLoadOptions: تنظیمات بارگذاری مخصوص OBJ: enable_materials, flip_coordinate_system, normalize_normal, scale.
  • StlSaveOptions: تنظیمات ذخیره‌سازی مخصوص STL (حالت باینری در مقابل ASCII).

دوربین‌ها و نورها

  • Camera: موجودیت دوربین با تنظیمات پروجکشن، قابل اتصال به یک Node.
  • Light: موجودیت منبع نور، قابل اتصال به یک Node.
 فارسی