كيفية تحميل نماذج ثلاثية الأبعاد في Java

كيفية تحميل نماذج ثلاثية الأبعاد في Java

Aspose.3D FOSS for Java يوفر واجهة برمجة تطبيقات بسيطة لفتح ملفات ثلاثية الأبعاد دون أي تبعيات أصلية. بعد تحميل ملف إلى كائن Scene يمكنك استعراض تسلسل العقد وقراءة بيانات الهندسة الخام لكل شبكة في المشهد.

دليل خطوة بخطوة

الخطوة 1: إضافة تبعية Maven

أضف تبعية Aspose.3D FOSS إلى pom.xml الخاصة بك. لا توجد مكتبات أصلية إضافية مطلوبة.

<dependency>
  <groupId>com.aspose</groupId>
  <artifactId>aspose-3d-foss</artifactId>
  <version>26.1.0</version>
</dependency>

الخطوة 2: استيراد الفئات المطلوبة

الفئة Scene هي الحاوية العليا لجميع بيانات 3D. استوردها مع Node وMesh وأي فئات خيارات تحميل خاصة بالتنسيق تحتاجها.

import com.aspose.threed.Scene;
import com.aspose.threed.Node;
import com.aspose.threed.Mesh;
import com.aspose.threed.Entity;
import com.aspose.threed.ObjLoadOptions;
import com.aspose.threed.GltfLoadOptions;
import com.aspose.threed.StlLoadOptions;

جميع الفئات العامة موجودة تحت الحزمة com.aspose.threed.


الخطوة 3: تحميل ملف

استخدم الطريقة الساكنة Scene.fromFile() لفتح أي تنسيق مدعوم. المكتبة تكتشف التنسيق تلقائيًا من امتداد الملف.

// Automatic format detection from the file extension
Scene scene = Scene.fromFile("model.obj");

بدلاً من ذلك، أنشئ مثيل Scene واستدعِ open(). هذا مفيد عندما تريد تمرير خيارات التحميل أو معالجة الأخطاء صراحةً:

Scene scene = new Scene();
scene.open("model.obj");

يدعم كلا النهجين ملفات OBJ و STL (الثنائية و ASCII) و glTF 2.0 / GLB و FBX.


الخطوة 4: تجوال عقد المشهد

المشهد المحمَّل هو شجرة من كائنات Node متجذرة في scene.getRootNode(). استخدم getChildNodes() للتكرار بشكل متكرر وزيارة جميع العقد:

import com.aspose.threed.Scene;
import com.aspose.threed.Node;

public class SceneWalker {
    public static void main(String[] args) throws Exception {
        Scene scene = Scene.fromFile("model.obj");
        walkNode(scene.getRootNode(), 0);
    }

    static void walkNode(Node node, int depth) {
        String indent = "  ".repeat(depth);
        System.out.println(indent + "Node: " + node.getName());
        for (Node child : node.getChildNodes()) {
            walkNode(child, depth + 1);
        }
    }
}

يمكن لكل Node أن يحمل صفرًا أو أكثر من كائنات Entity (الشبكات، الكاميرات، الأضواء). تحقق من node.getEntities() لتفحص كل كيان مرتبط بعقدة، أو استخدم node.getEntity() لاسترجاع الكيان الأساسي.


الخطوة 5: الوصول إلى بيانات القمم والمضلعات

حوّل كيان العقدة إلى Mesh واستدعِ getControlPoints() للحصول على مواضع الرؤوس وgetPolygons() لقوائم فهارس الوجوه:

import com.aspose.threed.Scene;
import com.aspose.threed.Node;
import com.aspose.threed.Entity;
import com.aspose.threed.Mesh;

Scene scene = Scene.fromFile("model.obj");

for (Node node : scene.getRootNode().getChildNodes()) {
    Entity entity = node.getEntity();
    if (entity instanceof Mesh) {
        Mesh mesh = (Mesh) entity;
        System.out.printf("Mesh '%s': %d vertices, %d polygons%n",
            node.getName(),
            mesh.getControlPoints().size(),
            mesh.getPolygonCount());

        // First vertex position (Vector4: x, y, z, w)
        if (!mesh.getControlPoints().isEmpty()) {
            var v = mesh.getControlPoints().get(0);
            System.out.printf("  First vertex: (%.4f, %.4f, %.4f)%n", v.x, v.y, v.z);
        }

        // First polygon: array of control-point indices
        if (!mesh.getPolygons().isEmpty()) {
            int[] poly = mesh.getPolygons().get(0);
            System.out.println("  First polygon indices: " + java.util.Arrays.toString(poly));
        }
    }
}

mesh.getControlPoints() تُعيد List<Vector4> حيث x، y، z تحمل الموضع وw هو الإحداثي المتجانس (عادةً 1.0).

mesh.getPolygons() تُعيد List<int[]> حيث أن كل مصفوفة هي مجموعة مرتبة من مؤشرات نقاط التحكم لوجه واحد.


الخطوة 6: تطبيق خيارات التحميل الخاصة بالتنسيق

للحصول على تحكم دقيق في كيفية تفسير الملف، مرّر كائن load-options إلى Scene.fromFile() أو scene.open().

ملفات OBJ — ObjLoadOptions:

import com.aspose.threed.Scene;
import com.aspose.threed.ObjLoadOptions;

ObjLoadOptions options = new ObjLoadOptions();
options.setFlipCoordinateSystem(true);  // Convert right-hand Y-up to Z-up
options.setScale(0.01);                  // Convert centimetres to metres
options.setEnableMaterials(true);        // Load the .mtl material file alongside
options.setNormalizeNormal(true);        // Normalize all normals to unit length

Scene scene = Scene.fromFile("model.obj", options);

ملفات glTF / GLB — GltfLoadOptions:

import com.aspose.threed.Scene;
import com.aspose.threed.GltfLoadOptions;

GltfLoadOptions options = new GltfLoadOptions();
options.setFlipCoordinateSystem(true);  // Flip the coordinate system if needed

Scene scene = Scene.fromFile("model.glb", options);

ملفات STL — StlLoadOptions:

import com.aspose.threed.Scene;
import com.aspose.threed.StlLoadOptions;

StlLoadOptions options = new StlLoadOptions();
options.setFlipCoordinateSystem(true);
options.setRecalculateNormal(true);  // Recompute normals from face geometry

Scene scene = Scene.fromFile("model.stl", options);

تنسيقات الاستيراد المدعومة

الصيغةالامتدادملاحظات
Wavefront OBJ.objملف مادة .mtl اختياري؛ تمكينه باستخدام ObjLoadOptions.setEnableMaterials(true)
STL.stlيتم اكتشاف أوضاع ASCII والثنائية تلقائيًا
glTF 2.0.gltf, .glbيدعم كلا من إصدارات GLB الثنائية وJSON
Autodesk FBX.fbxيدعم FBX الثنائي

المشكلات الشائعة والحلول

IOException عند التحميل — تحقق من أن مسار الملف صحيح وأن الملف موجود. استخدم المسارات المطلقة أثناء التطوير لإزالة الغموض المتعلق بدليل العمل.

NullPointerException accessing entity — ليس كل عقدة تحمل هندسة. احرص دائمًا على الحماية باستخدام node.getEntity() instanceof Mesh قبل التحويل، أو كرّر node.getEntities() للتعامل مع العقد التي تحتوي على عدة كائنات مرفقة.

عدم توافق نظام الإحداثيات — إذا ظهر النموذج المحمَّل مقلوبًا أو مدورًا، استخدم setFlipCoordinateSystem(true) على فئة خيارات التحميل المناسبة (ObjLoadOptions، GltfLoadOptions، أو StlLoadOptions).

المشهد يُحمَّل لكن getChildNodes() فارغ — بعض الملفات تخزن الهندسة تحت المشاهد الفرعية بدلاً من العقدة الجذرية. تحقق من scene.getSubScenes() وتفقد جذر كل مشهد فرعي.


الأسئلة المتكررة (FAQ)

ما هي الصيغ التي يمكنني تحميلها؟

OBJ, STL (ثنائي و ASCII)، glTF 2.0 / GLB، و FBX. يتم الكشف عن التنسيق تلقائيًا بناءً على امتداد الملف عند استدعاء Scene.fromFile().

هل يمكنني التحميل من تدفق؟

نعم. scene.open(InputStream) و Scene.fromStream(InputStream) كلاهما يقبلان Java InputStream. يمكنك أيضًا تمرير معلمة FileFormat عندما لا يحمل التدفق امتدادًا.

هل المكتبة آمنة للمعالجة المتعددة الخيوط؟

كل مثيل Scene مستقل ولا يشارك حالة قابلة للتغيير مع المثيلات الأخرى.

كيف أقرأ عدد المضلعات دون تكرار كل وجه؟

استدعِ mesh.getPolygonCount() للحصول على عدد صحيح مباشر.


انظر أيضًا

 العربية