.ply (polygon) format file issue in ios 14
Asked Answered
C

1

7

My app generates ply files after scanning objects. After ios 14 update the color of my 3d models does not load correctly. Also I am unable to view ply files in xcode (works fine in preview).

Anyone know the workaround to this problem?

I tired reading ply file content and display vertices and faces in scene geometry but it takes too long to load a file.

Apparently creating mdlAsset() throws some Metal warning and the mesh color does not show up properly.

Here are the sample images from ios 13 and 14 preview in sceneKit.

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

Chukker answered 28/9, 2020 at 10:19 Comment(5)
Can you quote the warning?Getraer
[Metal Compiler Warning] Warning: Compilation succeeded with: program_source:95:26: warning: unused function 'reduce_op' static inline float4 reduce_op(float4 d0, float4 d1) ^ program_source:581:26: warning: unused variable 'scn_shadow_sampler_ord_z' static constexpr sampler scn_shadow_sampler_ord_z = sampler(coord::normalized, filter::linear, mip_filter::none, address::clamp_to_edge, compare_func::greater_equal);Chukker
Checkout this thread developer.apple.com/forums/thread/659856Getraer
@SaadTahir did you find a solution to this problem?Uneducated
@D.Rothschild I have not find any solution to this problem yet. Even reading the PLY file abd making a pointcloud is not a feasible solution.Chukker
B
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);

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;
}

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)

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)

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

it work! and faster!

Breault answered 25/11, 2020 at 7:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.