iOS显示STL文件(3D效果)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS显示STL文件(3D效果)相关的知识,希望对你有一定的参考价值。
参考技术A 由于项目需要,因此需要在项目中集成STL文件3D显示效果,最早解决方案是STL文件转DAE文件,使用SceneKit直接加载并显示出来,但是多了个步骤总是感觉很麻烦,后来想到使用OpenGL用来显示STL文件,而OpenGL那晦涩难懂的语法实在是浪费太多时间,所以写了个简单的项目(基于ScentKit)用来集成STL的文件显示。首先对于STL文件的内容请参考 STL文件解析 ,STL文件分为两种编码格式,一种为ASCII,一种为二进制,具体区别请自行查看。
这里以SceneKit为例,首先创建一个类继承自SCNView:
实现方法:
首先实现初始化方法:
使用传递的路径初始化场景:
这里场景的光照原来一直是自己打的,后来发现自己打的光怎么样都不好看,所以使用了默认的光源。
在这里加载STL文件(顺便区分STL文件的编码方式)
加载二进制的STL文件:
加载ASCII编码的STL文件:
好了,那么既然解析方法和显示方法都已经创建完毕,那么接下来显示STL文件就简单很多了:
最终效果如图所示:
在 macOS 的 SceneKit 中无法显示 stl 文件
【中文标题】在 macOS 的 SceneKit 中无法显示 stl 文件【英文标题】:Trouble displaying stl file in SceneKit with macOS 【发布时间】:2019-12-14 18:48:43 【问题描述】:我有一个二进制 stl 文件,它可以在 ios scenekit 中显示,但不能在具有相同代码的 macOS 中显示。当我加载文件时,有时应用程序崩溃,有时它显示错误的东西
macOS 10.14.6
- (SCNNode *)loadBinarySTLWithData:(NSData *)data
NSMutableData *vertices = [NSMutableData data];
NSMutableData *normals = [NSMutableData data];
NSMutableData *elements = [NSMutableData data];
if (data.length % 50 != 0)
return nil;
NSInteger allCount = data.length/50;
for (int i = 0; i < allCount; i ++)
for (int j = 1; j <= 3; j ++)
[normals appendData:[data subdataWithRange:NSMakeRange(i * 50, 12)]];
[vertices appendData:[data subdataWithRange:NSMakeRange(i * 50 + j*12, 12)]];
int element[3] = (int)i * 3,(int)i*3 + 1,(int)i*3 + 2;
[elements appendBytes:&element[0] length:sizeof(element)];
SCNGeometrySource *verticesSource = [SCNGeometrySource geometrySourceWithData:vertices semantic:SCNGeometrySourceSemanticVertex vectorCount:allCount*3 floatComponents:YES componentsPerVector:3 bytesPerComponent:sizeof(float) dataOffset:0 dataStride:sizeof(SCNVector3)];
SCNGeometrySource *normalsSource = [SCNGeometrySource geometrySourceWithData:normals semantic:SCNGeometrySourceSemanticNormal vectorCount:allCount*3 floatComponents:YES componentsPerVector:3 bytesPerComponent:sizeof(float) dataOffset:0 dataStride:sizeof(SCNVector3)];
SCNGeometryElement *geoMetryElement = [SCNGeometryElement geometryElementWithData:elements primitiveType:SCNGeometryPrimitiveTypeTriangles primitiveCount:allCount bytesPerIndex:sizeof(int)];
SCNGeometry *geometry = [SCNGeometry geometryWithSources:@[verticesSource,normalsSource] elements:@[geoMetryElement]];
geometry.firstMaterial.diffuse.contents = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
geometry.firstMaterial.doubleSided = YES;
SCNNode *node = [SCNNode nodeWithGeometry:geometry];
return node;
【问题讨论】:
【参考方案1】:SCNVector3
在 iOS 和 macOS 上有不同的声明:
// iOS
typedef struct SCNVector3
float x, y, z;
SCNVector3;
// macOS
typedef struct SCNVector3
CGFloat x, y, z;
SCNVector3;
当为 64 位编译时,CGFloat
是 double
。
这意味着sizeof(SCNVector3)
不是 macOS 上的正确步幅。你应该改用3 * sizeof(float)
。
【讨论】:
以上是关于iOS显示STL文件(3D效果)的主要内容,如果未能解决你的问题,请参考以下文章
## 利用MPU6050 + OLED屏显示cube3D矩形效果
在 SceneKit/modelIO 中测量 3D-Obj 文件上两点之间的距离并显示它们