How to use SceneKit to display a colorful point cloud using custom SCNGeometry?

I am currently working on developing OS X software using Swift to display reading point clouds from a PLY file. The file is converted to a PointCloudVertex array, which is defined as follows:

 struct PointCloudVertex { let x: Double, y: Double, z: Double let r: Double, g: Double, b: Double } 

Then I try to build SCNGeometry from an array:

 var vertices = [PointCloudVertex]() for p in points { let v = PointCloudVertex(x: p[0], y: p[1], z: p[2], r: p[3], g: p[4], b: p[5]) vertices.append(v) } let vertexData = NSData(bytes: &vertices, length: sizeof(PointCloudVertex) * points.count) let positionSource = SCNGeometrySource(data: vertexData, semantic: SCNGeometrySourceSemanticVertex, vectorCount: points.count, floatComponents: true, componentsPerVector: 3, bytesPerComponent: sizeof(Double), dataOffset: 0, dataStride: sizeof(PointCloudVertex)) let colorSource = SCNGeometrySource(data: vertexData, semantic: SCNGeometrySourceSemanticColor, vectorCount: points.count, floatComponents: true, componentsPerVector: 3, bytesPerComponent: sizeof(CGFloat), dataOffset: sizeof(Double) * 3, dataStride: sizeof(PointCloudVertex)) let elements = SCNGeometryElement(data: nil, primitiveType: .Point, primitiveCount: points.count, bytesPerIndex: sizeof(Int)) let pointCloud = SCNGeometry(sources: [positionSource, colorSource], elements: [elements]) let pcNode = SCNNode(geometry: pointCloud) self.modelScene.rootNode.addChildNode(pcNode) 

where points is [[Double]] , which stores all the data about the location and color of the data. I am trying to display a point cloud. The positions are correct, but all the dots are black, not the colors that I pass to PointCloudVertex . Moreover, I also tried to use SCNMaterial to associate the color with black geometry. So how can I show a point cloud in a colorful way? I know that SceneKit has some custom rendering API, and I wonder if it will help. It would be helpful if there was some code for this, because I am not so familiar with OpenGL or a metal pattern.

By the way, I also tried using SCNSphere to display a point cloud, it works, but I need to create one SCNSphere for each individual point. My Mac ran out of memory using this method, since I have about 1 million points to display.

The PLY file is in the following format:

 ply format ascii 1.0 comment VCGLIB generated element vertex 684398 property float x property float y property float z property uchar red property uchar green property uchar blue property uchar alpha end_header 7.42808 15.3133 1.45829 55 45 43 255 3.92053 20.8015 -32.8147 156 141 121 255 4.80496 21.0725 -34.3995 160 146 133 255 8.09035 14.6247 33.5683 127 119 101 255 14.66 20.5331 -26.406 70 64 40 255 -0.911526 14.6359 7.66687 157 146 150 255 ... 

In my method of reading PLY files, each row in the main part is converted to [Double] (the last column, which is an alpha value, is discarded). For the red, green, and blue values, I divided them by 255 so that the value is in the range from 0 to 1.

+6
source share

All Articles