Mixed topology (quad/tri) with ModelIO

青春壹個敷衍的年華 提交于 2019-12-13 17:07:11

问题


I'm importing some simple OBJ assets using ModelIO like so:

let mdlAsset = MDLAsset(url: url, vertexDescriptor: nil, bufferAllocator: nil, preserveTopology: true, error: nil)

... and then adding them to a SceneKit SCN file. But, whenever I have meshes that have both quads/tris (often the case, for example eyeball meshes), the resulting mesh is jumbled:

Incorrect mesh topology

Re-topologizing isn't a good option since I sometimes have low-poly meshes with very specific topology, so I can't just set preserveTopology to false... I need a result with variable topology (i.e. MDLGeometryType.variableTopology).

How do I import these files correctly preserving their original topology?


回答1:


I reported this as a bug at Apple Bug Reporter on 25th of November, bug id: 35687088

Summary: SCNSceneSourceLoadingOptionPreserveOriginalTopology does not actually preserve the original topology. Instead, it converts the geometry to all quads, messing up the 3D model badly. Based on its name it should behave exactly like preserveTopology of Model IO asset loading.

Steps to Reproduce: Load an OBJ file that has both triangles and polygons using SCNSceneSourceLoadingOptionPreserveOriginalTopology and load the same file into an MDLMesh using preserveTopology of ModelIO. Notice how it only works properly for the latter. Even when you create a new SCNGeometry based on the MDLMesh, it will "quadify" the mesh again to contain only quads (while it should support 3-gons and up).

On December 13th I received a reply with a request for sample code and assets, which I supplied 2 days later. I have not received a reply since (hopefully because they are just busy from catching up from the holiday season...).

As I mentioned in my bug report's summary, loading the asset with Model I/O does work properly, but then when you create a SCNNode based on that MDLMesh it ends up messing up the geometry again.

In my case the OBJ files I load have a known format as they are always files also exported with my app (no normals, colors, UV). So what I do is load the information of the MDLMesh (buffers, facetopology etc) manually into arrays, from which I then create a SCNGeometry manually. I don't have a complete separate piece of code of that for you as it is a lot and mixed with a lot of code specific to my app, and it's in Objective C. But to illustrate:

    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));

    ....
    ....
    }

In short, the preserveTopology option in SceneKit isn't working properly. To get from the working version in Model I/O to SceneKit I basically had to write my own converter.



来源:https://stackoverflow.com/questions/48179571/mixed-topology-quad-tri-with-modelio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!