1

我知道它SceneKit允许您创建某些基本形状,如盒子、球体等。我想知道您是否可以使用场景工具包创建复杂的几何图形。我在这里找到了本教程,它很有帮助。我以格式导出了一些几何BIMServerjson。我想在 SceneKit 中使用它,但我遇到了困难。是否可以在 SceneKit 中执行此操作?下面是我提取的一些几何图形的示例。

{
  "id" : "2O2Fr$t4X7Zf8NOew3FNtn", 
  "type" : "IFCWALLSTANDARDCASE", 
  "geometry" : {
   "metadata" : { "formatVersion" : 3 }, 
    "materials": [],
    "vertices": [  8.8,0.2085,0.0, 3.4479692,0.2085,0.0, 3.4479692,0.2085,2.42, 2.6349692,0.2085,2.42, 2.6349692,0.2085,0.0, 0.0,0.2085,0.0, 0.0,0.2085,3.1, 8.8,0.2085,3.1, 8.383,0.2085,2.52, 8.383,0.2085,0.1, 3.548,0.2085,2.52, 3.548,0.2085,0.1, 8.8,0.2085,0.0, 3.4479692,0.2085,0.0, 3.4479692,-0.2085,0.0, 8.8,-0.2085,0.0, 3.4479692,-0.2085,2.42, 3.4479692,0.2085,2.42, 3.4479692,-0.2085,0.0, 3.4479692,0.2085,0.0, 2.6349692,-0.2085,2.42, 2.6349692,0.2085,2.42, 3.4479692,-0.2085,2.42, 3.4479692,0.2085,2.42, 2.6349692,-0.2085,0.0, 2.6349692,0.2085,0.0, 2.6349692,-0.2085,2.42, 2.6349692,0.2085,2.42, 2.6349692,0.2085,0.0, 0.0,0.2085,0.0, 0.0,-0.2085,0.0, 2.6349692,-0.2085,0.0, 0.0,0.2085,0.0, 0.0,0.2085,3.1, 0.0,-0.2085,0.0, 0.0,-0.2085,3.1, 8.8,0.2085,3.1, 0.0,0.2085,3.1, 0.0,-0.2085,3.1, 8.8,-0.2085,3.1, 8.8,-0.2085,0.0, 8.8,-0.2085,3.1, 8.8,0.2085,0.0, 8.8,0.2085,3.1, 8.383,-0.2085,2.52, 8.383,0.2085,2.52, 8.383,-0.2085,0.1, 8.383,0.2085,0.1, 3.548,-0.2085,2.52, 3.548,0.2085,2.52, 8.383,-0.2085,2.52, 8.383,0.2085,2.52, 8.383,-0.2085,0.1, 8.383,0.2085,0.1, 3.548,-0.2085,0.1, 3.548,0.2085,0.1, 3.548,-0.2085,0.1, 3.548,0.2085,0.1, 3.548,-0.2085,2.52, 3.548,0.2085,2.52, 0.0,-0.2085,0.0, 2.6349692,-0.2085,0.0, 2.6349692,-0.2085,2.42, 3.4479692,-0.2085,2.42, 3.4479692,-0.2085,0.0, 8.8,-0.2085,0.0, 8.8,-0.2085,3.1, 0.0,-0.2085,3.1, 8.383,-0.2085,0.1, 3.548,-0.2085,0.1, 8.383,-0.2085,2.52, 3.548,-0.2085,2.52   ], 
    "normals":  [ 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0    ],
    "colors":   [ ],
    "uvs":    [ ],
    "faces": [  32, 8,7,0,8,7,0, 32, 8,0,9,8,0,9, 32, 7,8,10,7,8,10, 32, 10,2,3,10,2,3, 32, 2,10,11,2,10,11, 32, 11,9,1,11,9,1, 32, 7,10,6,7,10,6, 32, 10,3,6,10,3,6, 32, 3,4,5,3,4,5, 32, 6,3,5,6,3,5, 32, 9,0,1,9,0,1, 32, 11,1,2,11,1,2, 32, 14,12,15,14,12,15, 32, 13,12,14,13,12,14, 32, 18,16,17,18,16,17, 32, 18,17,19,18,17,19, 32, 22,20,21,22,20,21, 32, 22,21,23,22,21,23, 32, 26,24,25,26,24,25, 32, 26,25,27,26,25,27, 32, 29,31,30,29,31,30, 32, 29,28,31,29,28,31, 32, 33,32,34,33,32,34, 32, 35,33,34,35,33,34, 32, 38,39,37,38,39,37, 32, 39,36,37,39,36,37, 32, 41,40,42,41,40,42, 32, 43,41,42,43,41,42, 32, 46,44,45,46,44,45, 32, 46,45,47,46,45,47, 32, 50,48,49,50,48,49, 32, 50,49,51,50,49,51, 32, 55,52,53,55,52,53, 32, 54,52,55,54,52,55, 32, 58,56,57,58,56,57, 32, 58,57,59,58,57,59, 32, 67,60,62,67,60,62, 32, 62,63,71,62,63,71, 32, 67,62,71,67,62,71, 32, 62,60,61,62,60,61, 32, 71,63,69,71,63,69, 32, 67,71,66,67,71,66, 32, 66,71,70,66,71,70, 32, 69,64,68,69,64,68, 32, 70,68,65,70,68,65, 32, 66,70,65,66,70,65, 32, 69,63,64,69,63,64, 32, 68,64,65,68,64,65 ]
     }

  } ,{
  "id" : "2O2Fr$t4X7Zf8NOew3FKGS", 
  "type" : "IFCWALLSTANDARDCASE", 
  "geometry" : {
   "metadata" : { "formatVersion" : 3 }, 
    "materials": [],
    "vertices": [  3.583,0.062,0.0, 3.583,0.062,2.795, 6.661338E-16,0.062,0.0, 6.661338E-16,0.062,2.795, 6.661338E-16,0.062,0.0, 6.661338E-16,0.062,2.795, 6.661338E-16,-0.062,0.0, 6.661338E-16,-0.062,2.795, 6.661338E-16,-0.062,0.0, 6.661338E-16,-0.062,2.795, 3.583,-0.062,0.0, 3.583,-0.062,2.795, 3.583,-0.062,0.0, 3.583,-0.062,2.795, 3.583,0.062,0.0, 3.583,0.062,2.795, 3.583,0.062,0.0, 6.661338E-16,0.062,0.0, 6.661338E-16,-0.062,0.0, 3.583,-0.062,0.0, 3.583,0.062,2.795, 6.661338E-16,0.062,2.795, 6.661338E-16,-0.062,2.795, 3.583,-0.062,2.795   ], 
    "normals":  [ 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0    ],
    "colors":   [ ],
    "uvs":    [ ],
    "faces": [  32, 1,0,2,1,0,2, 32, 3,1,2,3,1,2, 32, 5,4,6,5,4,6, 32, 7,5,6,7,5,6, 32, 9,8,10,9,8,10, 32, 11,9,10,11,9,10, 32, 13,12,14,13,12,14, 32, 15,13,14,15,13,14, 32, 17,19,18,17,19,18, 32, 17,16,19,17,16,19, 32, 22,23,21,22,23,21, 32, 23,20,21,23,20,21 ]
     }
4

2 回答 2

2

我知道有点太晚了,但是如果像我这样的其他人发现这会很酷,以获得更好的答案,对于那些想了解 SceneKit 自定义几何如何工作的人,我看到几何有一些问题,但真的不知道看起来如何,这段代码远非完美,但只是一个起点。

class JSONGeometry: Decodable {
    class Geometry: Decodable {
        var vertices: [CGFloat]
        var normals: [CGFloat]
        var faces: [Int16]

        init(vertices: [CGFloat], normals: [CGFloat], faces: [Int16]) {
            self.vertices = vertices
            self.normals = normals
            self.faces = faces
        }
    }

    static let data: [JSONGeometry] = {
        let json = """
[{
  "id" : "2O2Fr$t4X7Zf8NOew3FNtn",
  "type" : "IFCWALLSTANDARDCASE",
  "geometry" : {
    "metadata" : { "formatVersion" : 3 },
    "materials": [],
    "vertices": [  8.8,0.2085,0.0, 3.4479692,0.2085,0.0, 3.4479692,0.2085,2.42, 2.6349692,0.2085,2.42, 2.6349692,0.2085,0.0, 0.0,0.2085,0.0, 0.0,0.2085,3.1, 8.8,0.2085,3.1, 8.383,0.2085,2.52, 8.383,0.2085,0.1, 3.548,0.2085,2.52, 3.548,0.2085,0.1, 8.8,0.2085,0.0, 3.4479692,0.2085,0.0, 3.4479692,-0.2085,0.0, 8.8,-0.2085,0.0, 3.4479692,-0.2085,2.42, 3.4479692,0.2085,2.42, 3.4479692,-0.2085,0.0, 3.4479692,0.2085,0.0, 2.6349692,-0.2085,2.42, 2.6349692,0.2085,2.42, 3.4479692,-0.2085,2.42, 3.4479692,0.2085,2.42, 2.6349692,-0.2085,0.0, 2.6349692,0.2085,0.0, 2.6349692,-0.2085,2.42, 2.6349692,0.2085,2.42, 2.6349692,0.2085,0.0, 0.0,0.2085,0.0, 0.0,-0.2085,0.0, 2.6349692,-0.2085,0.0, 0.0,0.2085,0.0, 0.0,0.2085,3.1, 0.0,-0.2085,0.0, 0.0,-0.2085,3.1, 8.8,0.2085,3.1, 0.0,0.2085,3.1, 0.0,-0.2085,3.1, 8.8,-0.2085,3.1, 8.8,-0.2085,0.0, 8.8,-0.2085,3.1, 8.8,0.2085,0.0, 8.8,0.2085,3.1, 8.383,-0.2085,2.52, 8.383,0.2085,2.52, 8.383,-0.2085,0.1, 8.383,0.2085,0.1, 3.548,-0.2085,2.52, 3.548,0.2085,2.52, 8.383,-0.2085,2.52, 8.383,0.2085,2.52, 8.383,-0.2085,0.1, 8.383,0.2085,0.1, 3.548,-0.2085,0.1, 3.548,0.2085,0.1, 3.548,-0.2085,0.1, 3.548,0.2085,0.1, 3.548,-0.2085,2.52, 3.548,0.2085,2.52, 0.0,-0.2085,0.0, 2.6349692,-0.2085,0.0, 2.6349692,-0.2085,2.42, 3.4479692,-0.2085,2.42, 3.4479692,-0.2085,0.0, 8.8,-0.2085,0.0, 8.8,-0.2085,3.1, 0.0,-0.2085,3.1, 8.383,-0.2085,0.1, 3.548,-0.2085,0.1, 8.383,-0.2085,2.52, 3.548,-0.2085,2.52   ],
    "normals":  [ 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0    ],
    "colors":   [ ],
    "uvs":    [ ],
    "faces": [  32, 8,7,0,8,7,0, 32, 8,0,9,8,0,9, 32, 7,8,10,7,8,10, 32, 10,2,3,10,2,3, 32, 2,10,11,2,10,11, 32, 11,9,1,11,9,1, 32, 7,10,6,7,10,6, 32, 10,3,6,10,3,6, 32, 3,4,5,3,4,5, 32, 6,3,5,6,3,5, 32, 9,0,1,9,0,1, 32, 11,1,2,11,1,2, 32, 14,12,15,14,12,15, 32, 13,12,14,13,12,14, 32, 18,16,17,18,16,17, 32, 18,17,19,18,17,19, 32, 22,20,21,22,20,21, 32, 22,21,23,22,21,23, 32, 26,24,25,26,24,25, 32, 26,25,27,26,25,27, 32, 29,31,30,29,31,30, 32, 29,28,31,29,28,31, 32, 33,32,34,33,32,34, 32, 35,33,34,35,33,34, 32, 38,39,37,38,39,37, 32, 39,36,37,39,36,37, 32, 41,40,42,41,40,42, 32, 43,41,42,43,41,42, 32, 46,44,45,46,44,45, 32, 46,45,47,46,45,47, 32, 50,48,49,50,48,49, 32, 50,49,51,50,49,51, 32, 55,52,53,55,52,53, 32, 54,52,55,54,52,55, 32, 58,56,57,58,56,57, 32, 58,57,59,58,57,59, 32, 67,60,62,67,60,62, 32, 62,63,71,62,63,71, 32, 67,62,71,67,62,71, 32, 62,60,61,62,60,61, 32, 71,63,69,71,63,69, 32, 67,71,66,67,71,66, 32, 66,71,70,66,71,70, 32, 69,64,68,69,64,68, 32, 70,68,65,70,68,65, 32, 66,70,65,66,70,65, 32, 69,63,64,69,63,64, 32, 68,64,65,68,64,65 ]
     }

} ,{
  "id" : "2O2Fr$t4X7Zf8NOew3FKGS",
  "type" : "IFCWALLSTANDARDCASE",
  "geometry" : {
    "metadata" : { "formatVersion" : 3 },
    "materials": [],
    "vertices": [  3.583,0.062,0.0, 3.583,0.062,2.795, 6.661338E-16,0.062,0.0, 6.661338E-16,0.062,2.795, 6.661338E-16,0.062,0.0, 6.661338E-16,0.062,2.795, 6.661338E-16,-0.062,0.0, 6.661338E-16,-0.062,2.795, 6.661338E-16,-0.062,0.0, 6.661338E-16,-0.062,2.795, 3.583,-0.062,0.0, 3.583,-0.062,2.795, 3.583,-0.062,0.0, 3.583,-0.062,2.795, 3.583,0.062,0.0, 3.583,0.062,2.795, 3.583,0.062,0.0, 6.661338E-16,0.062,0.0, 6.661338E-16,-0.062,0.0, 3.583,-0.062,0.0, 3.583,0.062,2.795, 6.661338E-16,0.062,2.795, 6.661338E-16,-0.062,2.795, 3.583,-0.062,2.795   ],
    "normals":  [ 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, -1.0,-0.0,-0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0    ],
    "colors":   [ ],
    "uvs":    [ ],
    "faces": [  32, 1,0,2,1,0,2, 32, 3,1,2,3,1,2, 32, 5,4,6,5,4,6, 32, 7,5,6,7,5,6, 32, 9,8,10,9,8,10, 32, 11,9,10,11,9,10, 32, 13,12,14,13,12,14, 32, 15,13,14,15,13,14, 32, 17,19,18,17,19,18, 32, 17,16,19,17,16,19, 32, 22,23,21,22,23,21, 32, 23,20,21,23,20,21 ]
  }
}]
"""
        guard let data = json.data(using: .utf8) else { return [] }
        guard let result = try? JSONDecoder().decode([JSONGeometry].self, from: data) else { return [] }
        return result
    }()

    var id: String
    var type: String
    var geometry: Geometry

    var toSCN: SCNGeometry {
        var sources: [SCNGeometrySource] = []

        let vertices = SCNGeometrySource(
            vertices: geometry.vertices.eachSlice(3).map{ SCNVector3($0[0], $0[1], $0[2]) }
        )
        sources.append(vertices)

        if geometry.normals.count > 0 {
            let normals = SCNGeometrySource(
                normals: geometry.normals.eachSlice(3).map{ SCNVector3($0[0], $0[1], $0[2]) }
            )
            sources.append(normals)
        }

        let indices = Data(
            bytes: geometry.faces.map{ Int16($0) },
            count: MemoryLayout<Int16>.size * geometry.faces.count
        )

        let elements = [
            SCNGeometryElement(
                data: indices,
                primitiveType: .triangles,
                primitiveCount: geometry.faces.count / 3,
                bytesPerIndex: MemoryLayout<Int16>.size
            )
        ]

        return SCNGeometry(sources: sources, elements: elements)
    }

    init(id: String, type: String, geometry: Geometry) {
        self.id = id
        self.type = type
        self.geometry = geometry
    }
}

extension Sequence {
    func eachSlice(_ clump:Int) -> [[Self.Element]] {
        return self.reduce(into:[]) { memo, cur in
            if memo.count == 0 {
                return memo.append([cur])
            }
            if memo.last!.count < clump {
                memo.append(memo.removeLast() + [cur])
            } else {
                memo.append([cur])
            }
        }
    }
}

我有一个要点,我将在其中更新与此类似的代码,因为有些人认为我现在不太了解,例如 UV 映射和法线(现在不知道为什么)。

问候

于 2018-02-22T10:04:51.427 回答
0

哎哟! SceneKit 很棒,但是除了它提供的几个原语之外,它不是一个建模器。在专用于 3-D 建模的应用程序中创建模型在各个方面都更加容易和更好。论坛上的很多人都使用 Blender,免费且可随时使用。我使用 Cinema 4D,还有许多其他选项可用。唯一需要的是它们输出 DAE (Collada) 文件。

使用这种应用程序的学习曲线与使用这种低级构建技术很可能会遇到的挫败感相比简直是微不足道。

将 DAE 文件导入 Xcode 后,可以在编辑器窗口中对其进行检查。您可以移动节点,然后重新排列,重命名它们并删除它们。更多内容: 在 Scenekit 中变换和旋转

于 2016-07-23T01:08:02.063 回答