Jak načíst 3D modely v Javě

Jak načíst 3D modely v Javě

Aspose.3D FOSS for Java poskytuje jednoduché API pro otevírání 3D souborů bez jakýchkoli nativních závislostí. Po načtení souboru do objektu Scene můžete procházet hierarchii uzlů a číst surová geometrická data pro každý mesh ve scéně.

Průvodce krok za krokem

Krok 1: Přidejte Maven závislost

Přidejte závislost Aspose.3D FOSS do svého pom.xml. Nejsou vyžadovány žádné další nativní knihovny.

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

Krok 2: Naimportujte požadované třídy

Třída Scene je kontejner nejvyšší úrovně pro všechna 3D data. Importujte ji spolu s Node, Mesh a případnými třídami možností načítání specifickými pro formát, které potřebujete.

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;

Všechny veřejné třídy jsou umístěny v balíčku com.aspose.threed.


Krok 3: Načíst soubor

Použijte statickou metodu Scene.fromFile() k otevření libovolného podporovaného formátu. Knihovna automaticky detekuje formát z přípony souboru.

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

Alternativně vytvořte instanci Scene a zavolejte open(). To je užitečné, když chcete předat možnosti načítání nebo explicitně zpracovat chyby:

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

Oba přístupy podporují soubory OBJ, STL (binární i ASCII), glTF 2.0 / GLB a FBX.


Krok 4: Procházet uzly scény

Načtená scéna je strom objektů Node kořeněných v scene.getRootNode(). Použijte getChildNodes() k rekurzivnímu procházení a návštěvě všech uzlů:

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

Každý Node může nést nula nebo více Entity objektů (meshe, kamery, světla). Zkontrolujte node.getEntities() pro prohlédnutí každé entity připojené k uzlu, nebo použijte node.getEntity() k získání primární entity.


Krok 5: Přístup k datům vrcholů a polygonů

Přetypujte entitu uzlu na Mesh a zavolejte getControlPoints() pro pozice vrcholů a getPolygons() pro seznamy indexů ploch:

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() vrací List<Vector4>, kde x, y, z nesou pozici a w je homogenní souřadnice (obvykle 1.0).

mesh.getPolygons() vrací List<int[]>, kde každé pole je uspořádaná množina indexů řídicích bodů pro jednu plochu.


Krok 6: Použít specifické možnosti načítání formátu

Pro jemnozrnou kontrolu nad tím, jak je soubor interpretován, předávejte instanci load-options do Scene.fromFile() nebo scene.open().

OBJ soubory — 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 soubory — 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 soubory — 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);

Podporované formáty importu

FormátPříponaPoznámky
Wavefront OBJ.objVolitelný soubor materiálu .mtl; povolit pomocí ObjLoadOptions.setEnableMaterials(true)
STL.stlRežimy ASCII a binární jsou automaticky rozpoznány
glTF 2.0.gltf, .glbPodporovány jak binární GLB, tak JSON varianty
Autodesk FBX.fbxBinární FBX podporován

Běžné problémy a opravy

IOException on load — Ověřte, že cesta k souboru je správná a soubor existuje. Používejte během vývoje absolutní cesty, aby se odstranila nejednoznačnost pracovního adresáře.

NullPointerException přístup k entitě — Ne každý uzel obsahuje geometrii. Vždy se chraňte pomocí node.getEntity() instanceof Mesh před přetypováním, nebo iterujte node.getEntities() pro zpracování uzlů s více připojenými objekty.

Neshoda souřadnicových systémů — Pokud se načtený model jeví jako převrácený nebo otočený, použijte setFlipCoordinateSystem(true) na příslušné třídy load-options (ObjLoadOptions, GltfLoadOptions nebo StlLoadOptions).

Scéna se načte, ale getChildNodes() je prázdná — Některé soubory ukládají geometrii pod podscénami místo kořenového uzlu. Zkontrolujte scene.getSubScenes() a prozkoumejte kořenový uzel každé podscény.


Často kladené otázky (FAQ)

Které formáty mohu načíst?

OBJ, STL (binární a ASCII), glTF 2.0 / GLB a FBX. Detekce formátu je automatická na základě přípony souboru, když zavoláte Scene.fromFile().

Mohu načíst ze streamu?

Ano. scene.open(InputStream) a Scene.fromStream(InputStream) oba přijímají Java InputStream. Můžete také předat parametr FileFormat, když proud neobsahuje rozšíření.

Je knihovna bezpečná pro vlákna?

Každá instance Scene je nezávislá a nesdílí měnitelný stav s ostatními instancemi.

Jak načíst počty polygonů bez iterace každé plochy?

Zavolejte mesh.getPolygonCount() pro přímý celočíselný počet.


Viz také

 Čeština