Skip to content

Instantly share code, notes, and snippets.

@warrenm
Created June 12, 2018 06:31
Show Gist options
  • Save warrenm/f4f1c7f7e71bd88fc3d3df95b60d5f04 to your computer and use it in GitHub Desktop.
Save warrenm/f4f1c7f7e71bd88fc3d3df95b60d5f04 to your computer and use it in GitHub Desktop.
Generating thumbnail images of 3D model files for use with AR QuickLook
import Foundation
import SceneKit
class ARQLThumbnailGenerator {
private let device = MTLCreateSystemDefaultDevice()!
/// Create a thumbnail image of the asset with the specified URL at the specified
/// animation time. Supports loading of .scn, .usd, .usdz, .obj, and .abc files,
/// and other formats supported by ModelIO.
/// - Parameters:
/// - url: The file URL of the asset.
/// - size: The size (in points) at which to render the asset.
/// - time: The animation time to which the asset should be advanced before snapshotting.
func thumbnail(for url: URL, size: CGSize, time: TimeInterval = 0) -> UIImage? {
let renderer = SCNRenderer(device: device, options: [:])
renderer.autoenablesDefaultLighting = true
if (url.pathExtension == "scn") {
let scene = try? SCNScene(url: url, options: nil)
renderer.scene = scene
} else {
let asset = MDLAsset(url: url)
let scene = SCNScene(mdlAsset: asset)
renderer.scene = scene
}
let image = renderer.snapshot(atTime: time, with: size, antialiasingMode: .multisampling4X)
return image
}
}
@mostafakram
Copy link

First of all thanks for sharing, great gist 🤘

But I think you should add import SceneKit.ModelIO, because without it compiler error says: "Argument labels '(mdlAsset:)' do not match any available overloads"

@hellensoloviy
Copy link

Awesome gist :)

@Kanunnikoff
Copy link

Thank you very much!

@clarkezone
Copy link

I like this, one issue is that it doesn’t seem to be loading textures correctly for me.. I see a “flat what” mesh. I’m using Apple’s test files so it’s not an issue with the models

@michaelqxx
Copy link

Very useful. Call asset.loadTextures() to show the textures.

@mo75
Copy link

mo75 commented Oct 3, 2019

This sounds exactly like what I need, but I’ve never used swift. I have 100+ usdz files on my site (Squatties.com) that I’m trying to thumbnail from. Can anyone explain how I’d run this on my machine, and ideally batch the process by pointing it a folder on my desktop. I’d be very very grateful. I copied the code into a swift playground in the hope I’d get somewhere but I essentially don’t understand how to pass the function the parameters.

@michaelqxx
Copy link

I use a bash script to curl a php script on my server to list my directory of models, then for each model I wget the file, call "swift $PLAYGROUND $file, then scp the thumbnail back to my server. A playground is actually a directory and the swift file to call from a terminal lives in there usually as "Contents.swift". Right click on the playground and "show package contents". You can access arguments in swift with "CommandLine.arguments". You could also do everything in the playground and not use bash, but I was in a hurry and curl / wget / scp seemed easy enough.

@AMJ-7
Copy link

AMJ-7 commented Jun 11, 2021

is .reality supported?!

@warrenm
Copy link
Author

warrenm commented Jun 11, 2021

I don't believe so. The supported formats are a subset of the constants listed here.

@AMJ-7
Copy link

AMJ-7 commented Jun 28, 2021

I got this issue while using in cellForItemAt
[SceneKit] Error: Failed to load <C3DImage 0x28016c200 src:file:///private/var/mobile/Containers/Data/Application/19E310AE-1945-417C-B09D-D215DF530BD5/Documents/fender_stratocaster.usdz [0.000000x0.000000]>

@EuRabelo
Copy link

love you for this code :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment