使用 .obj 文件导出纹理

Rah*_*pta 5 textures swift arkit

我目前正在开发一个关于面部跟踪并将面部导出到 obj 文件的项目。我成功导出它,但无法导出纹理文件。我正在分享导出文件的代码,可能我遗漏了一些东西,请帮助我。当我调用该函数时,newMesh!.generateLightMapTexture它会使代码崩溃并给出以下日志:

Removed 41721 bad triangles
Can't choose for edge creation
Can't choose for edge creation
Can't choose for edge creation
Can't choose for edge creation
Can't choose for edge creation
Can't choose for edge creation
Can't choose for edge creation
Can't choose for edge creation ...
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: unordered_map::at: key not found
Run Code Online (Sandbox Code Playgroud)

下面我分享一下导出的代码:

func exportFile() {
    let geometry = currentFaceAnchor.geometry
    let allocator = MDLMeshBufferDataAllocator()

    let vertices = allocator.newBuffer(with: Data(fromArray: geometry.vertices), type: .vertex)
    let textureCoordinates = allocator.newBuffer(with: Data(fromArray: geometry.textureCoordinates), type: .vertex)
    let triangleIndices = allocator.newBuffer(with: Data(fromArray: geometry.triangleIndices), type: .index)

    let material = MDLMaterial(name: "mat1", scatteringFunction: MDLPhysicallyPlausibleScatteringFunction())
    material.setProperty(MDLMaterialProperty.init(name: "matName", semantic: MDLMaterialSemantic.ambientOcclusion))

    let submesh = MDLSubmesh(indexBuffer: triangleIndices, indexCount: geometry.triangleIndices.count, indexType: .uInt16, geometryType: .triangles, material: material)

    let vertexDescriptor = MDLVertexDescriptor()
    // Attributes
    vertexDescriptor.attributes[0] = MDLVertexAttribute(name: MDLVertexAttributePosition,
                                                        format: .float3,
                                                        offset: 0,
                                                        bufferIndex: 0)
    vertexDescriptor.attributes[1] = MDLVertexAttribute(name: MDLVertexAttributeTextureCoordinate,
                                                        format: .float2,
                                                        offset: 0,
                                                        bufferIndex: 1)
    // Layouts
    vertexDescriptor.layouts[0] = MDLVertexBufferLayout(stride: MemoryLayout<SIMD3<Float>>.stride)
    vertexDescriptor.layouts[1] = MDLVertexBufferLayout(stride: MemoryLayout<SIMD2<Float>>.stride)

    let mdlMesh = MDLMesh(vertexBuffers: [vertices, textureCoordinates], vertexCount: geometry.vertices.count, descriptor: vertexDescriptor, submeshes: [submesh])
    let newMesh = MDLMesh.newSubdividedMesh(mdlMesh, submeshIndex: 0, subdivisionLevels: 2)

    let light = MDLLight.init(scnNode: node)
    light.lightType = .ambient
    newMesh!.generateLightMapVertexColorsWithLights(toConsider: [light], objectsToConsider: [newMesh!], vertexAttributeNamed: MDLVertexAttributeNormal)

   **//Crashing Next Line**

    newMesh!.generateLightMapTexture(withQuality: 1.0, lightsToConsider: [light], objectsToConsider: [newMesh!], vertexAttributeNamed: MDLVertexAttributeNormal, materialPropertyNamed: "matName")

    let asset = MDLAsset(bufferAllocator: allocator)
    asset.add(newMesh!)
    let fileManager = FileManager.default

    let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
    let exportUrl = documentsPath.appendingPathComponent("face.obj")
    do {
        try asset.export(to: exportUrl)
        let fileURLs = try fileManager.contentsOfDirectory(at: documentsPath, includingPropertiesForKeys: nil)

        DispatchQueue.main.async {
            let activityVC = UIActivityViewController(activityItems: fileURLs, applicationActivities: nil)
            self.present(activityVC, animated: true, completion: nil)
        }
    }
    catch {

    }
}
Run Code Online (Sandbox Code Playgroud)

小智 1

也许这就是你所需要的。尝试在崩溃之前添加此行。

newMesh!.addUnwrappedTextureCoordinates(forAttributeNamed: MDLVertexAttributeTextureCoordinate)