You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SceneKit加载.obj模型时如何获取所有子网格名称?

如何用SceneKit+ModelIO获取.obj模型的子网格名称

当然可以通过SceneKit结合ModelIO获取.obj文件里的所有子网格/部件名称!从你贴的代码和控制台输出来看,你其实已经离目标很近了,咱们来理清楚怎么操作:

确认可行性

.obj格式的子网格名称会被ModelIO完整解析并保留,你可以直接从MDLSubmesh对象,或者对应的SCNGeometry、SCNNode上获取这些名称。

从你的代码和输出分析

看你控制台打印的object.childNodes结果,里面的节点已经带有对应的子网格名称了:

object.childNodes==>[<SCNNode: 0x1c41e9300 'default' | geometry=<SCNGeometry: 0x1c5339280 'default' | 6 elements> | no child>, <SCNNode: 0x1c41f5a00 | geometry=<SCNGeometry: 0x1c5339320 'Obj1'> | no child>, ...]

这里的'default'、'Obj1'到'Obj6'就是.obj文件里各个子网格的名称,说明ModelIO已经成功读取到了这些信息。

优化代码直接获取子网格名称

你可以在循环处理子网格的时候,直接从MDLSubmesh的name属性拿到子网格名称,还能把这个名称赋值给对应的SCNGeometry和SCNNode,方便后续操作。修改后的代码如下:

// Here Obj url
let url = URL(string: "https://s3.ap-south-1.amazonaws.com/p9-platform/DAE/barware_s11624.obj")!
let asset = MDLAsset(url: url)
let scene = SCNScene(mdlAsset: asset)
guard let mesh = asset.object(at:0) as? MDLMesh else {
    print("无法获取MDLMesh对象")
    return
}
let vertexBuffer = mesh.vertexBuffers[0]
let descriptor = mesh.vertexDescriptor
let submeshes = mesh.submeshes

for index in 0..<(submeshes?.count ?? 0) {
    guard let submesh0 = submeshes![index] as? MDLSubmesh else { continue }
    // 获取子网格的原始名称,没有的话设置默认名称
    let submeshName = submesh0.name ?? "Unnamed_Submesh_\(index)"
    
    let singleMesh = MDLMesh(vertexBuffer: vertexBuffer, vertexCount: mesh.vertexCount, descriptor: descriptor, submeshes: [submesh0])
    let geometry = SCNGeometry(mdlMesh: singleMesh)
    // 给几何对象设置子网格名称
    geometry.name = submeshName
    
    let node = SCNNode(geometry: geometry)
    // 给节点设置子网格名称,方便后续查找或操作
    node.name = submeshName
    
    scene.rootNode.addChildNode(node)
    // 打印子网格名称,直观查看结果
    print("子网格 \(index) 名称:\(submeshName)")
}

print("scene ===>\(scene.rootNode)")

补充说明

  • 如果你的.obj文件里的子网格本身有自定义命名,ModelIO会直接把这个名称赋值给MDLSubmesh.name;
  • 如果子网格没有命名,submesh0.name会返回nil,这时候可以像代码里那样设置一个默认名称,避免空值问题;
  • 给SCNNode和SCNGeometry设置名称后,后续你可以通过scene.rootNode.childNode(withName: "Obj1", recursively: true)快速找到对应的部件,进行隐藏、修改材质等操作。

内容的提问来源于stack exchange,提问作者Lanover Solutions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:39:18