5

I'm getting unexpected results when exporting the contents of a SceneKit scene to a Collada (.dae) file. Here's what I have so far.

I created a simple scene with 5 spheres along the x-axis

var x:CGFloat = 0
for i in 0...4 {
    let sphere = SCNNode(geometry: SCNSphere(radius: 1))
    sphere.name = "sphere\(i+1)"
    sphere.position = SCNVector3(x: x, y: 0, z: 0)
    exportScene.rootNode.addChildNode(sphere)
    x += 2
}

and exported the contents with

let url = URL(fileURLWithPath: pathName)
exportScene.write(to: url, options: nil, delegate: nil) { totalProgress, error, stop in
    print("Export progress: \(totalProgress * 100.0)%")
}

When I load the .dae file into a 3D program (Cheetah 3D), I expect to have 5 identical spheres along the x-axis but instead the following appears. I had similar issues exporting to a .obj file.

enter image description here

The answer in the following says "Keep in mind that DAE doesn't handle all features of SceneKit, though" but the doesn't go into the limitations of the file format.

Easiest method to export a SceneKit scene as a Collada .dae file?

Q: Does anyone know how to export the contents of a SceneKit scene?

tospig
  • 7,762
  • 14
  • 40
  • 79
Epsilon
  • 1,016
  • 1
  • 6
  • 15
  • Can you share the project for download? I'd like to have a look at it, if you allow me. – ZAY Jul 14 '22 at 07:55
  • @ZAY Steps to test the above: 1) create a new SceneKit project, 2) In GameViewController's viewDidLoad function, define `let exportScene = SCNScene()` and then copy/paste the code above, 3) Compile and run – Epsilon Jul 15 '22 at 01:02
  • what did you use as the "pathName" variable? can you qive me a quick example? – ZAY Jul 15 '22 at 15:17
  • @ZAY pathName is the output path name. It needs to have a .dae extension. Example, `let pathName = "/Users/\(NSUserName())/Desktop/test.dae"` – Epsilon Jul 15 '22 at 22:15
  • Please share the .dae file so we can analyse it in the text editor. – de. Jul 16 '22 at 00:47
  • Well, the Problem seems to be really bad. I made a tests using an iPhone and your code. On the iPhone that compiles and displays 5 SCNSpheres side by side. Then, when I save this (found a solution) this happens: MacOS File preview does not show anything (white on white). Then copied it to PC: Blender 3, open the Collada, Blender Crash. Then tested it using Photoshop. Can open file, I see one (ugly shaped) black Sphere. Just one, not five. Then I did an export using Model/IO, the result: One Shere exported with 5 Materials. Sorry, currently I have no solution for you. – ZAY Jul 16 '22 at 22:07
  • @de The .dae file can't be loaded into a text editor because it contains some binary data – Epsilon Jul 18 '22 at 06:40
  • 1
    @ZAY I'm convinced it's a bug – Epsilon Jul 18 '22 at 06:47
  • dae is an xml format - afaik there is no binary version!? – de. Jul 18 '22 at 06:55

1 Answers1

1

macOS app

Looks like the beginning of SceneKit's sunset.

Neither .dae nor .obj formats are properly generated in SceneKit macOS app. Moreover, an .usdz format is not exported at all.

iOS app

In iOS app, only the .usdz format is exported correctly (it kept all nodes' transforms and names of the SCN scene). This .usdz can be opened in Maya. But .dae and .obj files contain only one sphere instead of five.

If you have problems with USDZ's textures in Maya, read this post please.

enter image description here


Note that .usdz is not exported correctly when using for-in loop.

import SceneKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let sceneView = self.view as! SCNView
        sceneView.backgroundColor = .black
        sceneView.scene = SCNScene()
        let url = URL(string: "file:///Users/swift/Desktop/model.usdz")!

        let sphere1 = SCNNode(geometry: SCNSphere(radius: 0.5))
        sphere1.position = SCNVector3(x: -2, y: 0, z: 0)
        sceneView.scene!.rootNode.addChildNode(sphere1)
        
        // ...sphere2, sphere3, sphere4...
        
        let sphere5 = SCNNode(geometry: SCNSphere(radius: 0.5))
        sphere5.position = SCNVector3(x: 2, y: 0, z: 0)
        sceneView.scene!.rootNode.addChildNode(sphere5)
            
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            sceneView.scene?.write(to: url, delegate: nil) { (prgs, _, _) in
                print("Export progress: \(prgs * 100.0)%")
            }
        }
    }
}

P. S.

Tested it on macOS 13.0 Ventura, Xcode 14.1, iOS 16.1 Simulator.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • Surely this must have previously worked, or at least worked better, in earlier versions of iOS? Otherwise there would be mention of it on SO prior to July 2022, and I don't think there is. Currently completely stymied exporting from SceneKit to anything other than USD(Z), any ideas? – Nestor Nov 01 '22 at 20:20
  • Just tested. Works fine with `.usdz`, `.dae` and `.scn` export. – Andy Jazz Nov 01 '22 at 21:22
  • Thanks for checking. SCN and USDZ work, DAE is still affected by the problem you’ve documented here; perhaps your scene wasn’t quite complex enough to trigger it. – Nestor Nov 02 '22 at 20:09
  • I’m testing on 16.1, are you on 16.2? – Nestor Nov 02 '22 at 20:11
  • 16.1 (I wrote that at the end of my post). I haven't tried opening `.dae` in Maya, but from Xcode the file generated visually fine. – Andy Jazz Nov 02 '22 at 20:18
  • Yes I saw that in your post, but the post says .dae only got you one sphere, which is exactly my experience. – Nestor Nov 02 '22 at 22:04