תכונות ופונקציונליות
Aspose.3D FOSS עבור Python מספק API מלא של גרף סצנה לקריאה, בנייה וכתיבה של תוכן תלת‑ממדי במגוון פורמטים תקניים בתעשייה. דף זה מתעד כל תחום תכונה מרכזי עם דוגמאות קוד Python עובדות המשתמשות ב‑API האמיתי של הספרייה.
התקנה והגדרה
התקן את הספרייה מ‑PyPI עם פקודה אחת:
pip install aspose-3d-fossאין צורך בחבילות מערכת נוספות, הרחבות מקומיות, או שרשראות כלי קומפיילר. הספרייה היא Python טהורה ותומכת ב‑Python 3.7 עד 3.12 ב‑Windows, macOS ו‑Linux.
כדי לאמת את ההתקנה:
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 | חלקי | לא | ה‑Tokenizer פועל; ל‑parser יש באגים ידועים |
טעינת 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}")Mesh API
ה Mesh הישות מספקת גישה לנתוני גאומטריה כולל נקודות בקרה (קודקודים), פוליגונים, ואלמנטים של קודקוד עבור נורמליות, UVs וצבעים.
קריאת גאומטריית Mesh
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 (הצללה משקפת). שניהם נטענים אוטומטית מקבצי .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 | 2D floating-point vector (UV coordinates) |
Vector3 | 3D double-precision vector (positions, normals) |
Vector4 | 4D double-precision vector (homogeneous coordinates) |
FVector3 | 3D single-precision vector (compact storage) |
Quaternion | ייצוג סיבוב ללא נעילת גימבל |
Matrix4 | 4×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}")אפשרויות טעינה ושמירה
לכל פורמט נתמך יש מחלקת אפשרויות תואמת שמבקרת את התנהגות הפענוח והסיריאליזציה.
| מחלקה | פורמט | מאפיינים מרכזיים |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | מצב פלט בינארי מול 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 |
| חומרים לא נטענו מ‑OBJ | enable_materials הוא False (ברירת מחדל) | הגדר ObjLoadOptions.enable_materials = True |
| הסצנה נטענת אך כל הצמתים ריקים | הקובץ משתמש בפורמט FBX | ה‑parser של FBX בתהליך; השתמש ב‑OBJ, STL, או glTF במקום |
| המודל קטן או גדול מאוד | קובץ המקור משתמש ביחידות לא‑מטריות | החל ObjLoadOptions.scale להמיר ליחידת היעד שלך |
AttributeError מופעל mesh.polygons | הישות Node אינה Mesh | הגן עם 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. היא מותקנת כ‑single pip install aspose-3d-foss פקודה ללא שלבים נוספים.
האם FBX נתמך? הטוקניזר של FBX מיושם ויכול לנתח את זרם הטוקנים הבינארי של FBX, אך בונה גרף הסצנה שמעל הטוקניזר מכיל באגים ידועים ואינו מוכן לייצור. השתמשו ב‑OBJ, STL, glTF, COLLADA, או 3MF לשימוש אמין בייצור.
האם אני יכול להשתמש ב‑Aspose.3D FOSS במוצר מסחרי? כן. הספרייה משוחררת תחת רישיון MIT, המאפשר שימוש בתוכנות קנייניות ומסחריות ללא תשלומי תמלוגים, בתנאי שהודעת הרישיון נכללת.
איך לדווח על באג או לבקש פורמט? פתח בעיה במאגר. כלול קובץ מינימלי לשחזור ואת גרסת 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: טרנספורמציה במרחב עולמי לקריאה בלבד המחושבת על‑ידי צבירת כל הטרנספורמציות של האבות.
Geometry
Mesh: Polygon mesh עםcontrol_points(רשימת קודקודים) וpolygons.VertexElementNormal: וקטורי נורמל לכל קודקוד או לכל פוליגון.VertexElementUV: קואורדינטות מרקם UV לכל קודקוד.VertexElementVertexColor: נתוני צבע לכל קודקוד.VertexElementSmoothingGroup: הקצאות קבוצות החלקה של פוליגונים.
חומרים
LambertMaterial: מודל הצללה Diffuse עם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.