Com carregar models 3D a Java

Com carregar models 3D a Java

Aspose.3D FOSS for Java ofereix una API senzilla per obrir fitxers 3D sense cap dependència nativa. Després de carregar un fitxer en un objecte Scene, podeu recórrer la jerarquia de nodes i llegir les dades de geometria en brut per a cada malla de l’escena.

Guia pas a pas

Pas 1: Afegeix la dependència Maven

Afegeix la dependència Aspose.3D FOSS al teu pom.xml. No es requereixen biblioteques natives addicionals.

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

Pas 2: Importa les classes necessàries

La classe Scene és el contenidor de nivell superior per a totes les dades 3D. Importa-la juntament amb les classes Node, Mesh i qualsevol classe d’opció de càrrega específica del format que necessitis.

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;

Totes les classes públiques es troben al paquet com.aspose.threed.


Pas 3: Carrega un fitxer

Utilitzeu el mètode estàtic Scene.fromFile() per obrir qualsevol format compatible. La biblioteca detecta el format automàticament a partir de l’extensió del fitxer.

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

Alternativament, creeu una instància Scene i invoqueu open(). Això és útil quan voleu passar opcions de càrrega o gestionar errors explícitament:

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

Ambdues aproximacions admeten fitxers OBJ, STL (binari i ASCII), glTF 2.0 / GLB i FBX.


Pas 4: Recórrer els nodes de l’escena

Una escena carregada és un arbre d’objectes Node arrelat a scene.getRootNode(). Utilitzeu getChildNodes() per iterar recursivament i visitar tots els nodes:

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

Cada Node pot portar zero o més objectes Entity (malles, càmeres, llums). Consulteu node.getEntities() per inspeccionar cada entitat adjunta a un node, o utilitzeu node.getEntity() per recuperar l’entitat principal.


Pas 5: Accés a les dades de vèrtex i polígon

Converteix l’entitat d’un node a Mesh i crida getControlPoints() per a les posicions dels vèrtexs i getPolygons() per a les llistes d’índexs de cares:

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() retorna un List<Vector4> on x, y, z porten la posició i w és la coordenada homogènia (normalment 1.0).

mesh.getPolygons() retorna un List<int[]> on cada matriu és el conjunt ordenat d’índexs de punts de control per a una cara.


Pas 6: Aplica les opcions de càrrega específiques del format

Per a un control detallat sobre com s’interpreta un fitxer, passeu una instància de load-options a Scene.fromFile() o scene.open().

Fitxers 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);

Fitxers 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);

Fitxers 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);

Formats d’importació compatibles

FormatExtensióNotes
Wavefront OBJ.objFitxer de material opcional .mtl; habilita amb ObjLoadOptions.setEnableMaterials(true)
STL.stlEls modes ASCII i binari es detecten automàticament
glTF 2.0.gltf, .glbEs donen suport tant les variants GLB binàries com les JSON
Autodesk FBX.fbxEs dóna suport al FBX binari

Problemes comuns i solucions

IOException en carregar — Verifiqueu que la ruta del fitxer és correcta i que el fitxer existeix. Utilitzeu rutes absolutes durant el desenvolupament per eliminar l’ambigüitat del directori de treball.

NullPointerException accedint a l’entitat — No tots els nodes contenen geometria. Sempre protegeix amb node.getEntity() instanceof Mesh abans de fer el casting, o itera node.getEntities() per gestionar nodes amb múltiples objectes adjunts.

Desajust del sistema de coordenades — Si el model carregat apareix invertit o girat, utilitzeu setFlipCoordinateSystem(true) a la classe d’opcions de càrrega corresponent (ObjLoadOptions, GltfLoadOptions o StlLoadOptions).

Escena es carrega però getChildNodes() és buit — Alguns fitxers emmagatzemen geometria sota subescenes en lloc del node arrel. Comproveu scene.getSubScenes() i inspeccioneu el node arrel de cada subescena.


Preguntes freqüents (FAQ)

Quins formats puc carregar?

OBJ, STL (binari i ASCII), glTF 2.0 / GLB i FBX. La detecció del format és automàtica basada en l’extensió del fitxer quan crides Scene.fromFile().

Puc carregar des d’un flux?

Sí. scene.open(InputStream) i Scene.fromStream(InputStream) tots dos accepten un Java InputStream. També podeu passar un FileFormat paràmetre quan el flux no porta una extensió.

És la biblioteca segura per a fils?

Cada instància Scene és independent i no comparteix estat mutable amb altres instàncies.

Com puc llegir el recompte de polígons sense iterar cada cara?

Crida mesh.getPolygonCount() per a un recompte directe d’enters.


Vegeu també

 Català