我正在使用ModelIO导入一些简单的OBJ资产,如下所示:
let mdlAsset = MDLAsset(url: url, vertexDescriptor: nil, bufferAllocator: nil, preserveTopology: true, error: nil)..。然后将它们添加到SceneKit SCN文件中。但是,每当我有两个四边形/三角形的网格(通常是这种情况,例如眼球网格),结果网格是混乱的:
重新拓扑化不是一个好的选择,因为我有时会有非常特定拓扑的低多边形网格,所以我不能只是将preserveTopology设置为false……我需要一个具有可变拓扑结构(即MDLGeometryType.variableTopology)的结果。
如何正确导入这些文件并保留其原始拓扑?
发布于 2018-01-10 21:14:14
11月25日,我在Apple bug Reporter上报告了这是一个错误,错误id: 35687088
摘要:实际上并不保留原始拓扑。相反,它将几何体转换为所有四边形,严重扰乱了3D模型。根据其名称,它的行为应该与模型IO资产加载的preserveTopology完全相同。
再现步骤:使用加载同时具有三角形和多边形的OBJ文件,并使用ModelIO的preserveTopology将相同的文件加载到MDLMesh中。请注意,它只适用于后者。即使在基于MDLMesh创建新的SCNGeometry时,它也会再次使网格“四边形”,使其仅包含四边形(虽然它应该支持3边形或更高)。
12月13日,我收到了一个回复,要求提供示例代码和资产,这是我在两天后提供的。从那以后,我还没有收到回复(希望是因为他们只是忙于从假日季节赶过来…)。
正如我在bug报告的摘要中提到的,使用模型I/O加载资源确实可以正常工作,但是当您基于该MDLMesh创建SCNNode时,它会再次弄乱几何体。
在我的例子中,我加载的OBJ文件有一种已知的格式,因为它们总是与我的应用程序一起导出的文件(没有法线,颜色,UV)。因此,我所做的是手动将MDLMesh的信息(缓冲区、面拓扑等)加载到数组中,然后从数组中手动创建一个SCNGeometry。我没有为你提供一个完整的单独的代码片段,因为它很多,并且混合了很多特定于我的应用程序的代码,它在Objective C中。
NSError *scnsrcError;
MDLAsset *asset = [[MDLAsset alloc] initWithURL:objURL vertexDescriptor:nil bufferAllocator:nil preserveTopology:YES error:&scnsrcError];
NSLog(@"%@", scnsrcError.localizedDescription);
MDLMesh * newMesh = (MDLMesh *)[asset objectAtIndex:0];
for (MDLSubmesh *faces in newMesh.submeshes) {
//MDLSubmesh *faces = newMesh.submeshes.firstObject;
MDLMeshBufferData *topo = faces.topology.faceTopology;
MDLMeshBufferData *vertIx = faces.indexBuffer;
MDLMeshBufferData *verts = newMesh.vertexBuffers.firstObject;
int faceCount = (int)faces.topology.faceCount;
int8_t *faceIndexValues = malloc(faceCount * sizeof(int8_t));
memcpy(faceIndexValues, topo.data.bytes, faceCount * sizeof(int8_t));
int32_t *vertIndexValues = malloc(faces.indexCount * sizeof(int32_t));
memcpy(vertIndexValues, vertIx.data.bytes, faces.indexCount * sizeof(int32_t));
SCNVector3 *vertValues = malloc(newMesh.vertexCount * sizeof(SCNVector3));
memcpy(vertValues, verts.data.bytes, newMesh.vertexCount * sizeof(SCNVector3));
....
....
}简而言之,SceneKit中的preserveTopology选项不能正常工作。为了从模型I/O中的工作版本转换到SceneKit,我基本上必须编写我自己的转换器。
https://stackoverflow.com/questions/48179571
复制相似问题