如何解决.ply多边形格式文件在iOS 14中的问题
我的应用程序在扫描对象后生成层文件。 ios 14更新后,我的3d模型的颜色无法正确加载。另外,我无法在xcode中查看层文件(在预览中工作正常)。
我厌倦了读取层文件的内容并以场景几何图形显示顶点和面,但是加载文件花费的时间太长。
显然创建mdlAsset()会引发一些Metal警告,并且网格颜色不能正确显示。
这是来自SceneKit中的ios 13和14预览的示例图像。
解决方法
同样的问题,我发现这是一个SceneKit的错误,我有一个解决方案,可以使用C读取.ply文件,并使用数据创建SCNGeometry实例,主要代码:
- 首先,我们需要读取.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
工作!更快!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。