.ply多边形格式文件在iOS 14中的问题

问题描述

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

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

我厌倦了读取层文件的内容并以场景几何图形显示顶点和面,但是加载文件花费的时间太长。

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

这是来自SceneKit中的ios 13和14预览的示例图像。

comparison of ios 13 and ios 14 ply file preview in scenekit

解决方法

同样的问题,我发现这是一个SceneKit的错误,我有一个解决方案,可以使用C读取.ply文件,并使用数据创建SCNGeometry实例,主要代码:

  1. 首先,我们需要读取.ply文件中的vertexCount和faceCount(我的文件是ASCII格式,所以,)
    bool readFaceAndVertexCount(char* filePath,int *vertexCount,int *faceCount);

示例:

    bool readFaceAndVertexCount(char* filePath,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," ");
                if (res != NULL) {
                    *faceCount = atoi(res);
                }
            }
        }
        
        
        if (*faceCount > 0 && *vertexCount > 0) {
            break;
        }
    }
    
    fclose(fp);
    return  true;
}

2,将数据读取到数组: 在.c

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

在.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)

3创建自定义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,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

工作!更快!

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...