使用.obj文件导出纹理

时间:2020-06-16 11:26:36

标签: swift textures 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

下面我分享了导出代码:

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 {

    }
}

1 个答案:

答案 0 :(得分:1)

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

newMesh!.addUnwrappedTextureCoordinates(forAttributeNamed: MDLVertexAttributeTextureCoordinate)

相关问题