Getting to MeshAnchor.MeshClassification from MeshAnchor?

I am working with MeshAnchors, and I am having troubles getting to the classification of the triangles/faces.

This post references the MeshAnchor.Geometry, and that struct does have a property named "classifications", but it is of type GeometrySource. I cannot find any classification information in GeometrySource. Am I missing something there?

I think I am looking for something of type MeshAnchor.MeshClassification, but I cannot find any structs with this as a property.

Accepted Reply

You are on the right track. Here are two extensions which should get you the mesh classification of a single face in the mesh (I haven't tested it!):

extension GeometrySource {
    subscript(_ index: Int32) -> CUnsignedChar {
        precondition(format == .uchar, "This subscript operator can only be used on GeometrySource instances with format .uchar")
        return buffer.contents().advanced(by: offset + (stride * Int(index))).assumingMemoryBound(to: CUnsignedChar.self).pointee
    }
}

extension MeshAnchor {
    public func classificationOf(face index: Int32) -> MeshAnchor.MeshClassification? {
        guard let classifications = self.geometry.classifications else { return nil }
        let classification = classifications[index]
        return MeshAnchor.MeshClassification(rawValue: Int(classification)) ?? nil
    }
}
  • Thanks! I took a slightly less efficient approach (mainly, so I could understand all the nested data structures), and I could get the results I wanted. For example, I applied occlusion material to .seat (which includes couches) or .floor), so I could get my couch/chairs or floor to appear through the virtual content in mixed reality mode.

Add a Comment

Replies

I made some progress.

When creating the SceneReconstructionProvider, specify the classifications mode.

let sceneReconstruction = SceneReconstructionProvider(modes: [.classification])

Then the MeshAnchor.Geometry's classification property is set, and here are some example values

count: 11342
description: GeometrySource(count: 11342, format: MTLVertexFormat(rawValue: 45))
format: 45
componentsPerVector: 1
offset: 0
stride: 1

So I am guessing the buffer contains a sequence values that map to the MeshAnchor.MeshClassification raw values. (Now I just need to figure out which MTLVertexFormat case has a raw value of 45 :-)

Edit: uchar is type 45. So, the buffer contains a sequence of unsigned bytes.

You are on the right track. Here are two extensions which should get you the mesh classification of a single face in the mesh (I haven't tested it!):

extension GeometrySource {
    subscript(_ index: Int32) -> CUnsignedChar {
        precondition(format == .uchar, "This subscript operator can only be used on GeometrySource instances with format .uchar")
        return buffer.contents().advanced(by: offset + (stride * Int(index))).assumingMemoryBound(to: CUnsignedChar.self).pointee
    }
}

extension MeshAnchor {
    public func classificationOf(face index: Int32) -> MeshAnchor.MeshClassification? {
        guard let classifications = self.geometry.classifications else { return nil }
        let classification = classifications[index]
        return MeshAnchor.MeshClassification(rawValue: Int(classification)) ?? nil
    }
}
  • Thanks! I took a slightly less efficient approach (mainly, so I could understand all the nested data structures), and I could get the results I wanted. For example, I applied occlusion material to .seat (which includes couches) or .floor), so I could get my couch/chairs or floor to appear through the virtual content in mixed reality mode.

Add a Comment