Экспорт текстуры с файлом .obj - PullRequest
4 голосов
/ 16 июня 2020

В настоящее время я работаю над проектом по отслеживанию лица и экспорту лица в файл 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 {

    }
}
...