Hur man laddar 3D-modeller i Java

Hur man laddar 3D-modeller i Java

Aspose.3D FOSS för Java ger en enkel API för att öppna 3D-filer utan några inhemska beroende. Scene objekt du kan gå knuthierarkin och läsa rågeometriska data för varje mesh i scenen.

Steg för steg guide

Steg 1: Lägg till Maven beroende

Lägg till Aspose.3D FOSS beroende på din pom.xml.Inga ytterligare inhemska bibliotek krävs.

<dependency>
  <groupId>org.aspose</groupId>
  <artifactId>aspose-3d-foss</artifactId>
  <version>26.5.0</version>
</dependency>

Steg 2: Importera de nödvändiga klasserna

Den Scene klass är den högsta nivån container för alla 3D-data. importera det tillsammans med Node, Mesh, och alla format-specifika laddningsalternativ klasser du behöver.

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;

Alla offentliga klasser lever under com.aspose.threed förpackning .


Steg 3: Ladda upp en fil

Använd statisk Scene.fromFile() Metoden för att öppna något stöds format. biblioteket upptäcker formatet automatiskt från filändelsen.

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

Alternativt, skapa en Scene Instans och kallelse open().Detta är användbart när du vill passera laddningsalternativ eller hantera fel uttryckligen:

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

Båda metoderna stöder OBJ, STL (binär och ASCII), glTF 2.0 / GLB och FBX-filer.


Steg 4: Övergång Scene Nodes

En laddad scen är ett träd av Node föremål som är rötta i scene.getRootNode().Användning getChildNodes() att itera återkommande och besöka alla noder:

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

Varje Node kan bära noll eller mer Entity objekt (mässa, kameror, ljus) Kontrollera node.getEntities() att inspektera varje enhet som är ansluten till ett nod eller använda den node.getEntity() att återfå den primära enheten.


Steg 5: Tillgång till Vertex och Polygon Data

Hämta en node entitet till Mesh och ringer getControlPoints() för vertexpositioner och getPolygons() För ansiktsindex listor:

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() Återkommer A List<Vector4> Var är x, y, z Ta den position och w Det är den homogena koordinaten (vanligtvis 1.0).

mesh.getPolygons() Återkommer A List<int[]> där varje array är den beställda uppsättningen kontrollpunktsindex för ett ansikte.


Steg 6: Tillämpa format-specifika laddningsalternativ

För fingrined kontroll över hur en fil tolkas, gå till ett laddningsalternativ inställning till Scene.fromFile() eller scene.open().

OBJ filer - 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);

GTTF / GLB filer - 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 filer - 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);

Stödda importformat

FormateraUtvidgningenNoter
OBJ.objWavefront OBJ; valfritt .mtl material filer; möjlig med ObjLoadOptions.setEnableMaterials(true)
STL.stlASCII och binära lägen är självdetekterade
GTTF.gltf, .glbglTF 2.0; binära GLB och JSON varianter stöds båda
FBX.fbxBinär FBX stöds

Vanliga problem och fixar

IOException på last — Kontrollera filvägen är korrekt och filen finns. Använd absoluta vägar under utveckling för att eliminera arbet-direktivet ambiguitet.

NullPointerException Tillgångsinstitut – Inte varje nod bär geometri. alltid vakna med node.getEntity() instanceof Mesh före kastning eller iterate node.getEntities() för att hantera noder med flera anslutna objekt.

Systemförsvaret missmatch Om den laddade modellen visas flätad eller roterad, använd setFlipCoordinateSystem(true) i den lämpliga last-alternativklassen (ObjLoadOptions, GltfLoadOptions,eller StlLoadOptions).

Scenen är laddad men getChildNodes() är tomt — Vissa filer lagrar geometri under subscener istället för rötknappen. scene.getSubScenes() och inspektera varje sub-scenen rötknot.


Ofta ställda frågor (FAQ)

Vilka format kan jag ladda?

OBJ, STL (binär och ASCII), glTF 2.0 / GLB, och FBX. Formatdetektion är automatiskt baserat på filutvidgningen när du ringer Scene.fromFile().

Kan jag ladda från en ström?

Ja ja . scene.open(InputStream) och Scene.fromStream(InputStream) Båda accepterar Java InputStream.Du kan också passera en FileFormat parameter när strömmen inte bär en förlängning.

Är biblioteket trådsäker?

Varje Scene instans är oberoende och delar inte mutabel status med andra instanser.

Hur läser jag polygon räkningar utan att itera varje ansikte?

Ringa till mesh.getPolygonCount() för en direkt helhetskonto.


Se även

 Svenska