ios 14 中的 .ply(多边形)格式文件问题
Posted
技术标签:
【中文标题】ios 14 中的 .ply(多边形)格式文件问题【英文标题】:.ply (polygon) format file issue in ios 14 【发布时间】:2021-01-13 22:10:15 【问题描述】:我的应用在扫描对象后生成 ply 文件。 ios 14 更新后,我的 3d 模型的颜色无法正确加载。我也无法在 xcode 中查看 ply 文件(在预览中工作正常)。
有人知道这个问题的解决方法吗?
我厌倦了阅读 ply 文件内容并在场景几何体中显示顶点和面,但加载文件需要很长时间。
显然创建 mdlAsset() 会引发一些金属警告,并且网格颜色无法正确显示。
这是来自 ios 13 和 14 在 sceneKit 中预览的示例图像。
【问题讨论】:
你能引用警告吗? [Metal Compiler Warning] 警告:编译成功:program_source:95:26:警告:未使用函数'reduce_op'静态内联float4 reduce_op(float4 d0,float4 d1)^ program_source:581:26:警告:未使用的变量 '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); 签出这个帖子developer.apple.com/forums/thread/659856 @SaadTahir 你找到解决这个问题的方法了吗? @D.Rothschild 我还没有找到任何解决这个问题的方法。即使读取 PLY 文件 abd 制作点云也不是可行的解决方案。 【参考方案1】:同样的问题,我发现这是一个 SceneKit 的错误,我有一个解决方案,用 C 读取 .ply 文件,并使用数据创建一个 SCNGeometry 实例,主要代码:
-
首先我们需要读取 .ply 文件中的 vertexCount 和 faceCount(我的文件是 ASCII 格式,所以,)
bool readFaceAndVertexCount(char* filePath, int *vertexCount, int *faceCount);
示例:
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、读取数据到数组: 在.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, 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
它工作!更快!
【讨论】:
以上是关于ios 14 中的 .ply(多边形)格式文件问题的主要内容,如果未能解决你的问题,请参考以下文章