ios 14 中的 .ply(多边形)格式文件问题

Ali*_*man 5 ios scenekit swift metal ply-file-format

我的应用程序在扫描对象后生成 ply 文件。ios 14 更新后,我的 3d 模型的颜色无法正确加载。另外我无法在 xcode 中查看 ply 文件(在预览中工作正常)。

有人知道这个问题的解决方法吗?

我厌倦了阅读层文件内容并在场景几何图形中显示顶点和面,但加载文件需要很长时间。

显然,创建 mdlAsset() 会引发一些 Metal 警告,并且网格颜色无法正确显示。

以下是sceneKit 中ios 13 和14 预览的示例图像。

ios 13和ios 14 ply文件预览在scenekit中的比较

小智 3

same problem,i found it is a SceneKit's bug, i had a solution that read .ply file with C, and creat a SCNGeometry instance with data, main code:

  1. first we need read vertexCount and faceCount in .ply file (my file is ASCII format,so, )
    bool readFaceAndVertexCount(char* filePath, int *vertexCount, int *faceCount);
Run Code Online (Sandbox Code Playgroud)

example:

    bool readFaceAndVertexCount(char* filePath, int *vertexCount, int *faceCount) {
    
    char data[100];
    FILE *fp;
    if((fp = fopen(filePath,"r")) == NULL)
    {
        printf("error!");
        return false;
    }
    
    while (!feof(fp))
        
    {
        fgets(data,1024,fp);  
        unsigned long i = strlen(data);
        data[i - 1] = '\0';
        
        if (strstr(data, "element vertex") != NULL) {
            char *res = strtok(data," ");
            while (res != NULL) {
                res = strtok(NULL, " ");
                if (res != NULL) {
                    *vertexCount = atoi(res);
                }
            }
        }
        
        if (strstr(data, "element face") != NULL) {
            char *res = strtok(data," ");
            while (res != NULL) {
                res = strtok(NULL, " ");
                if (res != NULL) {
                    *faceCount = atoi(res);
                }
            }
        }
        
        
        if (*faceCount > 0 && *vertexCount > 0) {
            break;
        }
    }
    
    fclose(fp);
    return  true;
}
Run Code Online (Sandbox Code Playgroud)

2, read data to array: in .c

// you need to implement with your files
bool readPlyFile(char* filePath, const int vertexCount, int faceCount, float *vertex, float *color, int *elment)
Run Code Online (Sandbox Code Playgroud)

in .swift:

 var vertex: [Float] = Array.init(repeating: 0, count: Int(vertexCount) * 3)
        
 var color: [Float] = Array.init(repeating: 0, count: Int(vertexCount) * 3)
        
 var face: [Int32] = Array.init(repeating: 0, count: Int(faceCount) * 3)
        
 readPlyFile(UnsafeMutablePointer<Int8>(mutating: url.path),vertexCount,faceCount,&vertex,&color,&face)
Run Code Online (Sandbox Code Playgroud)

3 creat a custom SCNGeometry:

       let positionData = NSData.init(bytes: vertex, length: MemoryLayout<Float>.size * vertex.count)
        
        let vertexSource = SCNGeometrySource.init(data: positionData as Data, semantic: .vertex, vectorCount: Int(vertexCount), usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<Float>.size * 3)
        
        let colorData = NSData.init(bytes: color, length: MemoryLayout<Float>.size * color.count)
        
        let colorSource = SCNGeometrySource.init(data: colorData as Data, semantic: .color, vectorCount: Int(vertexCount), usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<Float>.size * 3)
        
        
        let indexData = NSData(bytes: face, length: MemoryLayout<Int32>.size * face.count)
        
        let element = SCNGeometryElement(data: indexData as Data, primitiveType: SCNGeometryPrimitiveType.triangles, primitiveCount: Int(faceCount), bytesPerIndex: MemoryLayout<Int32>.size)
        
        let gemetry = SCNGeometry.init(sources: [vertexSource,colorSource], elements: [element])
        
        let node = SCNNode.init(geometry: gemetry)
        
        let scene = SCNScene.init()
       
        node.geometry?.firstMaterial?.cullMode = .back
        node.geometry?.firstMaterial?.isDoubleSided = true
        
        scene.rootNode.addChildNode(node)
        scnView.scene = scene
Run Code Online (Sandbox Code Playgroud)

it work! and faster!