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

ios 14中的.ply(多边形)格式文件问题,ios,swift,scenekit,metal,ply-file-format,Ios,Swift,Scenekit,Metal,Ply File Format,我的应用程序在扫描对象后生成ply文件。ios 14更新后,我的3d模型的颜色无法正确加载。此外,我无法在xcode中查看ply文件(在预览中工作正常) 有人知道这个问题的解决方法吗 我厌倦了阅读ply文件内容,并在场景几何体中显示顶点和面,但加载文件所需时间太长 显然,创建mdlAsset()会抛出一些金属警告,并且网格颜色不会正确显示 以下是sceneKit中ios 13和ios 14预览的示例图像 同样的问题,我发现这是一个SceneKit的bug,我有一个解决方案,用C读取.ply文件,

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

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

我厌倦了阅读ply文件内容,并在场景几何体中显示顶点和面,但加载文件所需时间太长

显然,创建mdlAsset()会抛出一些金属警告,并且网格颜色不会正确显示

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


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

  • 首先,我们需要读取.ply文件中的vertexCount和faceCount(我的文件是ASCII格式,所以,)
  • 例如:

        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;
    }
    
    2、将数据读取到阵列: in.c

    在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)
    
    var-vertex:[Float]=Array.init(重复:0,计数:Int(vertexCount)*3)
    var color:[Float]=Array.init(重复:0,计数:Int(vertexCount)*3)
    var face:[Int32]=Array.init(重复:0,计数:Int(faceCount)*3)
    readPlyFile(非女性化指针(变化:url.path)、vertexCount、faceCount和vertex、color和face)
    
    3创建一个自定义的SCN测量:

           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
    
    let positionData=NSData.init(字节:vertex,长度:MemoryLayout.size*vertex.count)
    让vertexSource=SCNGEOmetricySource.init(数据:positionData作为数据,语义:。顶点,向量计数:Int(vertexCount),使用浮动组件:true,componentsPerVector:3,bytesPerComponent:MemoryLayout.size,dataOffset:0,dataStride:MemoryLayout.size*3)
    让colorData=NSData.init(字节:color,长度:MemoryLayout.size*color.count)
    让colorSource=SCNGeometrySource.init(数据:colorData作为数据,语义:。颜色,向量计数:Int(vertexCount),usesFloatComponents:true,ComponentPervector:3,bytesPerComponent:MemoryLayout.size,dataOffset:0,dataStride:MemoryLayout.size*3)
    让indexData=NSData(字节:面,长度:MemoryLayout.size*face.count)
    let element=SCNGEOmetricyElement(数据:作为数据的索引数据,原语类型:SCNGEOmetricyPrimitiveType.triangles,原语计数:Int(faceCount),bytesPerIndex:MemoryLayout.size)
    让gemetry=scngometry.init(源:[vertexSource,colorSource],元素:[element])
    让node=SCNNode.init(几何体:gemetry)
    让场景=SCNScene.init()
    node.geometry?.firstMaterial?.cullMode=.back
    node.geometry?.firstMaterial?.isdoubleblesided=true
    scene.rootNode.addChildNode(节点)
    scnView.scene=场景
    

    成功了!更快

    你能引用这个警告吗?[Metal Compiler warning]警告:编译成功:程序来源:95:26:警告:未使用的函数“reduce_op”静态内联float4 reduce_op(float4 d0,float4 d1)^program_source:581:26:警告:未使用的变量'scn_shadow_sampler_ord_z'静态constexpr sampler scn_shadow_sampler_ord_z=采样器(坐标::标准化,过滤器::线性,mip_过滤器::无,地址::钳制到边缘,比较函数::更大\u相等);签出此线程@SaadTahir是否找到此问题的解决方案?@D.Rothschild我尚未找到此问题的任何解决方案。即使读取PLY文件并制作点云也不是一个可行的解决方案。
     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)
    
           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