如何在Java上加载3D模型

如何在Java上加载3D模型

Aspose.3D FOSS for Java 提供一个简单的 API,以便在没有任何原生依赖的情况下打开 3D 文件。 Scene 对象可以走路节点的序列,并阅读原始地质数据每个场景中的分支。.

步骤指南

步骤1:添加Maven依赖性

将 Aspose.3D FOSS 的依赖添加到您的位置 pom.xml.没有额外的本地图书馆需要。.

<dependency>
  <groupId>org.aspose</groupId>
  <artifactId>aspose-3d-foss</artifactId>
  <version>26.5.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:访问 Vertex 和 Polygon 数据

点击一个节点的实体到 Mesh 和呼叫 getControlPoints() 对于 vertex 位置和 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() 返回 A List<Vector4> 哪里 x, y, z 保持位置和 w 是同一坐标(通常为 1.0 )。.

mesh.getPolygons() 返回 A List<int[]> 每个序列是指对一个面孔的控制点指标订单。.


步骤6:应用格式特定的加载选项

要对文件的解释进行精细控制,请输入一个负载选项例子到 Scene.fromFile()scene.open().

文件 - 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);

文件 - 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);

支持的进口格式

格式化延伸笔记
OBJ.obj波前OBJ;可选 .mtl 文件;可用于 ObjLoadOptions.setEnableMaterials(true)
STL.stlASCII 和二进制模式是自动检测的
格拉特F.gltf, .glbglTF 2.0;二进制GLB和JSON变量都支持
FBX.fbx双重 FBX 支持

常见问题和解决方案

IOException 负载上 检查文件路径是正确的,并且文件存在。在开发过程中使用绝对路线来消除工作导体不一致性。.

NullPointerException 接入实体 不是每個節點都帶有地質,總是守護。 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() 直接整数的。.


看也

 中文