Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export Texture with .obj file

I am currently working on a project on face tracking and exporting the face in obj file. I am successful in exporting it but not able to export the texture files. I am sharing the code for exporting the file , may be I am missing something please help me. When ever I am calling the function newMesh!.generateLightMapTexture it is crashing the code and giving following log:

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

Below I am sharing the code for exporting:

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 {

    }
}
like image 444
Rahul Dasgupta Avatar asked Nov 06 '22 07:11

Rahul Dasgupta


1 Answers

Maybe this is what you needed. Try adding this line before where it crashed.

newMesh!.addUnwrappedTextureCoordinates(forAttributeNamed: MDLVertexAttributeTextureCoordinate)

like image 118
Zeyu Wang Avatar answered Nov 16 '22 12:11

Zeyu Wang