如何在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 | .stl | ASCII 和二进制模式是自动检测的 |
| 格拉特F | .gltf, .glb | glTF 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() 直接整数的。.