כיצד לבנות רשת תלת‑ממדית עם Aspose.3D בפייתון

כיצד לבנות רשת תלת‑ממדית עם Aspose.3D בפייתון

Aspose.3D FOSS for Python מאפשר לך לבנות גאומטריה תלת‑ממדית לחלוטין בקוד: אין צורך בכלי מודלינג חיצוני. אתה יוצר Mesh, ממלא אותו במיקומי קודקודים (control_points) והגדרות פנים (polygons), מצרף תכונות קודקוד אופציונליות כגון נורמליות, ואז שומר את הסצנה לכל פורמט נתמך.

מדריך שלב אחר שלב

שלב 1: התקנת החבילה

התקן את Aspose.3D FOSS מ‑PyPI. אין צורך בהרחבות מקומיות או בשרשרת כלי קומפיילר.

pip install aspose-3d-foss

אמת את ההתקנה:

from aspose.threed import Scene
print("Aspose.3D FOSS ready")

גרסאות Python נתמכות: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


שלב 2: צור סצנה וצומת

כל רשת חייבת להיות בתוך גרף סצנה. צור Scene והוסף Node בעל שם כדי לאחסן את הרשת:

from aspose.threed import Scene

scene = Scene()
node = scene.root_node.create_child_node("triangle")

שם הצומת נשמר בקובץ המיוצא והוא שימושי לאיתור באגים ולשחזור מאוחר יותר באמצעות node.get_child("triangle").


שלב 3: צור Mesh Object

צור מופע של Mesh עם שם תיאורי אופציונלי:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

הרשת ריקה בתחילה: אין קודקודים, אין פוליגונים. אתה ממלא אותה בשלבים הבאים.


שלב 4: הוסף נקודות שליטה (קודקודים)

נקודות הבקרה הן מיקומי הקודקודים. כל קודקוד נשמר כ‑Vector4(x, y, z, w) כאשר w=1 מצביע על נקודה במרחב תלת‑ממדי:

from aspose.threed.utilities import Vector4

##Vertex 0: origin
# Note: control_points returns a copy of the internal vertex list.
# Appending to the returned copy discards the vertex silently.
# Use _control_points to mutate the backing list directly.
# This is a known library limitation — a public add_control_point() API is not yet available.
mesh._control_points.append(Vector4(0.0, 0.0, 0.0, 1.0))

##Vertex 1: 1 unit along X
mesh._control_points.append(Vector4(1.0, 0.0, 0.0, 1.0))

##Vertex 2: apex
mesh._control_points.append(Vector4(0.5, 1.0, 0.0, 1.0))

print(f"Vertices added: {len(mesh.control_points)}")

Important: mesh.control_points מחזירה העתק של רשימת הקודקודים הפנימית (ה‑getter מבצע list(self._control_points)). קריאה ל‑mesh.control_points.append(v) מוסיפה להעתק, ולא למשטח, ולכן הקודקוד נזרק בשקט. תמיד השתמשו ב‑mesh._control_points.append(v) כדי להוסיף קודקודים. גישה למצב פרטי דרך _control_points היא פתרון עקיף ידוע; הממשק עשוי להשתנות בגרסה עתידית של הספרייה.


שלב 5: צור משטחי פוליגון

הגדר את טופולוגיית הפנים באמצעות אינדקסי קודקוד. העבר אינדקסי קודקוד לcreate_polygon(). שלושה אינדקסים מייצרים משולש; ארבעה מייצרים מרובע:

##Triangle: connect vertices 0 → 1 → 2
mesh.create_polygon(0, 1, 2)

print(f"Polygon count: {mesh.polygon_count}")

לרשת מרובעת היית מעביר ארבעה אינדקסים: mesh.create_polygon(0, 1, 2, 3).

האינדקסים חייבים להיות מיקומים תקינים בcontrol_points (מבוססי‑אפס, בטווח). סדר הסיבוב הוא נגד כיוון השעון לנורמליים הפונים החוצה.


שלב 6: הוסף נורמות קודקוד

נורמות הקודקוד נשמרות כVertexElement המצורפת לרשת. השתמשו בmesh.create_element() עם VertexElementType.NORMAL, MappingMode.CONTROL_POINT, וReferenceMode.DIRECT:

from aspose.threed.entities import VertexElementType, MappingMode, ReferenceMode, VertexElementNormal
from aspose.threed.utilities import Vector4, FVector4

##Create the normal element (returns VertexElementNormal, a VertexElementFVector subclass)
normals: VertexElementNormal = mesh.create_element(
    VertexElementType.NORMAL,
    MappingMode.CONTROL_POINT,
    ReferenceMode.DIRECT
)

##One normal per vertex: all pointing out of the XY plane (0, 0, 1)
normals.set_data([
    FVector4(0, 0, 1, 0),   # vertex 0
    FVector4(0, 0, 1, 0),   # vertex 1
    FVector4(0, 0, 1, 0),   # vertex 2
])

print("Normal layer attached.")

MappingMode.CONTROL_POINT מתאר נורמל אחד לכל קודקוד. ReferenceMode.DIRECT מתאר שהנתונים של הנורמל נקראים באותו סדר כמו נקודות הבקרה (אין חוצץ אינדקס נוסף).

וקטורי נורמל משתמשים בFVector4(x, y, z, w) עם w=0 כדי לציין כיוון במקום מיקום. FVector4 הוא וקטור צף חד‑דיוק; נתוני תכונת קודקוד בVertexElementFVector תתי‑מחלקות משתמשים בסוג זה.


שלב 7: צרף את הרשת לצומת ושמור

הוסף את ה‑mesh לצומת, ואז שמור את הסצנה:

node.add_entity(mesh)

scene.save("triangle.gltf")
print("Saved triangle.gltf")

הסקריפט המלא שעובד (כל השלבים משולבים):

from aspose.threed import Scene
from aspose.threed.entities import Mesh, VertexElementType, MappingMode, ReferenceMode, VertexElementNormal
from aspose.threed.utilities import Vector3, Vector4, FVector4

scene = Scene()
node = scene.root_node.create_child_node("triangle")

mesh = Mesh("triangle")

##Add 3 vertices (x, y, z, w)
# Use _control_points to mutate the backing list directly (control_points returns a copy)
mesh._control_points.append(Vector4(0.0, 0.0, 0.0, 1.0))
mesh._control_points.append(Vector4(1.0, 0.0, 0.0, 1.0))
mesh._control_points.append(Vector4(0.5, 1.0, 0.0, 1.0))

##Create a triangle polygon
mesh.create_polygon(0, 1, 2)

##Add normals (create_element returns VertexElementNormal, a VertexElementFVector subclass)
normals: VertexElementNormal = mesh.create_element(VertexElementType.NORMAL, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT)
normals.set_data([
    FVector4(0, 0, 1, 0),
    FVector4(0, 0, 1, 0),
    FVector4(0, 0, 1, 0),
])

node.add_entity(mesh)
scene.save("triangle.gltf")

בעיות נפוצות

IssueResolution
IndexError ב create_polygonודא שכל האינדקסים נמצאים בתוך range(len(mesh.control_points)). האינדקסים הם מבוססי‑0.
ייצוא רשת עם אפס קודקודיםmesh.control_points.append(...) מסיר קודקודים בשקט מכיוון שהמאפיין מחזיר עותק. השתמש ב‑mesh._control_points.append(...) במקום.
ספירת הנורמליות אינה תואמת לספירת הקודקודיםבעת שימוש ב‑MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, על normals.data להכיל בדיוק len(control_points) ערכים.
הרשת חסרה בקובץ השמוראשר ש‑node.add_entity(mesh) קרא לפני scene.save(). רשת שלא מחוברת לאף צומת אינה מיוצאת.
סדר רוטציה שגוי (הפאה נראית בלתי נראית)סדר קודקודים נגד כיוון השעון מייצר נורמלית הפונה החוצה. הפוך את סדר האינדקסים ב‑create_polygon כדי להפוך זאת.
polygon_count מחזיר 0polygon_count קורא את אותה רשימה כמו polygons. אם create_polygon לא קרא, הרשימה ריקה.
הנורמליות נראות שגויות במציגודא שכל וקטורי הנורמליות הם באורך יחידה. חשב עם n / abs(n) או העבר ערכים מנורמלים מראש.

שאלות נפוצות

מה ההבדל בין Vector3 ו-Vector4 עבור נקודות בקרה?

control_points מאחסן Vector4 אובייקטים. הרכיב w הוא הקואורדינטה ההומוגנית: השתמש ב-w=1 למיקומי קודקודים וב-w=0 לווקטורי כיוון כגון נורמליות. Vector3 משמש לשינויים (תרגום, קנה מידה) אך לא לאחסון גאומטריה.

האם אני יכול לבנות רשת עם קוואדים במקום משולשים?

כן. קרא mesh.create_polygon(0, 1, 2, 3) עם ארבע אינדקסים כדי להגדיר קוואד. כמה יעדי שמירה (STL, 3MF) דורשים משולשים ויבצעו טריאנגולציה של קוואדים אוטומטית. glTF ו‑COLLADA משמרים קוואדים.

איך מוסיפים קואורדינטות UV?

השתמש בmesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) כדי ליצור VertexElementUV לערוץ הדיפוז, ולאחר מכן למלא את רשימת data שלו עם ערכי Vector4. קואורדינטות UV משתמשות בx ובy; z וw הן בדרך כלל 0. הארגומנט הראשון חייב להיות קבוע TextureMapping (למשל, TextureMapping.DIFFUSE) שמזהה לאיזה משבצת מרקם שייכת שכבת ה‑UV.

האם ה‑mesh צריך נורמליים כדי לייצא כראוי?

לא. נורמליות הן אופציונליות. אם מושמטות, רוב הצופים מחשבים נורמליות לכל פנים מהסדר של הפוליגון. הוספת נורמליות מפורשות לכל קודקוד מייצרת הצללה חלקה יותר.

האם אני יכול להוסיף רשתות מרובות לצומת אחד?

כן. קרא node.add_entity(mesh) מספר פעמים. כל קריאה מוסיפה ישות חדשה לnode.entities. חלק מהפורמטים עשויים לשטח מספר ישויות לישות אחת ביצוא.

איך לשלוש רשת עם סוגי פוליגונים מעורבים?

הפעל mesh.triangulate() כדי להמיר את כל הקוודרים וה‑N‑גונים למשולשים במקום. זה שימושי לפני שמירת הקבצים לפורמטים שתומכים רק במשולשים.

 עברית