Navigation
The quickest way to take the 3D scanning SDK for a spin is to build and run the example app: StandardCyborgExample.
After testing that out, we’ll give a brief overview of the Standard Cyborg APIs, then run through how to integrate 3D scanning into your existing app.
Want to dive into the API reference? Head over to the README.
Need to clarify any 3D scanning jargon? Check out the glossary
Further questions? Take a look in the FAQ, or feel free to ask us directly!
StandardCyborgExample is a bare-bones example app that takes a 3D scan using StandardCyborgFusion and visualizes the result using StandardCyborgUI.
NOTE: This app doesn’t build for the iOS Simulator due to lack of support for Metal.
Clone the StandardCyborgCocoa repository
git clone git@github.com:StandardCyborg/StandardCyborgCocoa.git
Open the Xcode project at
open StandardCyborgCocoa/StandardCyborgExample/StandardCyborgExample.xcodeproj
Change the development team to your own
StandardCyborgExample
in the project file listStandardCyborgExample
targetAdd your Standard Cyborg API key
Info.plist
SC_API_KEY
with your API key generated at https://platform.standardcyborg.com
The Standard Cyborg SDK provides 3 frameworks:
The 3D reconstruction algorithms exist entirely within StandardCyborgFusion.framework
. But if your app doesn’t already have a pipeline set up for streaming and rendering 3D depth frames from the camera, it’s often fastest to leverage the some or all of the classes within StandardCyborgUI
to build a typical scanning experience.
A typical pipeline is [take scan] > [preview scan] > [save scan].
First, make sure you set a camera usage description and your Standard Cyborg API key in your app’s Info.plist
:
<key>NSCameraUsageDescription</key>
<string>MyAppName uses the front-facing camera for 3D scanning</string>
<key>SC_API_KEY</key>
<string>ABCDEF1234567890</string>
Second, add the Standard Cyborg frameworks to your Xcode project or workspace via your method of choice.
NOTE: CocoaPods support is coming soon! The following uses a git submodule to manually integrate with our repository. Feel free to use the dependency management method of your choice!
In your project’s root directory, add our repo as a Git submodule
git submodule add git@github.com:StandardCyborg/StandardCyborgCocoa.git
StandardCyborgUI.xcodeproj
from StandardCyborgCocoa
in the Finder down into your app’s project
Link against the StandardCyborgCocoa and StandardCyborgUI frameworks
StandardCyborgUI.framework
from the project navigator into the list under Link Binary with LibrariesStandardCyborgFusion.framework
from the Finder into that same listCopy those frameworks into your app’s built products using a new copy files build phase
When the user and app are ready to begin scanning, present a ScanningViewController.
import StandardCyborgFusion
import StandardCyborgUI
class MyViewController: UIViewController, ScanningViewControllerDelegate {
@IBAction func presentScanningVC() {
present(ScanningViewController(delegate: self), animated: true)
}
// MARK: - ScanningViewControllerDelegate
func scanningViewControllerDidCancel(_ controller: ScanningViewController) {
// We'll implement this in a minute
}
func scanningViewController(_ controller: ScanningViewController, didScan pointCloud: SCPointCloud) {
// We'll implement this in a minute
}
If the app hasn’t requested camera access yet, the camera permission dialog will be presented first.
With camera permission granted, you’ll now be in the depth preview mode, ready to start scanning! The user can start and stop scanning by tapping the shutter button, just like recording a video.
Once a scan completes successfully, ScanningViewController will notify your view controller, its delegate, that it finished building an SCPointCloud!
Next up, let’s visualize that scan.
Once scanning finishes, or if the user taps the cancel button, ScanningViewController
notifies its delegate. It’s the delegate’s responsibility to present a preview of the scan result, so let’s implement that now using PointCloudPreviewViewController
. Going back to MyViewController…
class MyViewController: UIViewController, ScanningViewControllerDelegate {
@IBAction func presentScanningVC() {
present(ScanningViewController(delegate: self), animated: true)
}
// MARK: - ScanningViewControllerDelegate
func scanningViewControllerDidCancel(_ controller: ScanningViewController) {
dismiss(animated: true)
}
func scanningViewController(_ controller: ScanningViewController, didScan pointCloud: SCPointCloud) {
let previewVC = PointCloudPreviewViewController(pointCloud: pointCloud)
controller.present(previewVC, animated: false)
}
After a successful scan, the user will now see the point cloud!
But wait, how can the user do something useful when the scan looks good? We can customize the scan preview UI and know when its buttons are tapped by talking to its leftButton
and rightButton
.
class MyViewController: UIViewController, ScanningViewControllerDelegate {
@IBAction func presentScanningVC() {
present(ScanningViewController(delegate: self), animated: false)
}
// MARK: - ScanningViewControllerDelegate
func scanningViewControllerDidCancel(_ controller: ScanningViewController) {
dismiss(animated: false)
}
func scanningViewController(_ controller: ScanningViewController, didScan pointCloud: SCPointCloud) {
let previewVC = PointCloudPreviewViewController(pointCloud: pointCloud)
previewVC.leftButton.setTitle("Rescan", for: UIControl.State.normal)
previewVC.leftButton.addTarget(self, action: #selector(previewRescanTapped(_:)), for: UIControl.Event.touchUpInside)
previewVC.rightButton.setTitle("Save", for: UIControl.State.normal)
previewVC.rightButton.addTarget(self, action: #selector(previewSaveTapped(_:)), for: UIControl.Event.touchUpInside)
controller.present(previewVC, animated: false)
}
@objc private func previewRescanTapped(_ sender: UIButton) {
presentedViewController?.dismiss(animated: false)
}
@objc private func previewSaveTapped(_ sender: UIButton) {
// Do your thing with the scan here!
presentedViewController?.dismiss(animated: false)
}
If you want to further customize this scan preview UI, feel free to embed this view controller in your own, subclass it, or write your own!
File management is left completely up to you, but StandardCyborgFusion
provides convenient methods for serializing and unserializing an SCPointCloud to/from disk using the PLY format. Let’s save that scan to the user’s documents directory!
@objc private func previewSaveTapped(_ sender: UIButton) {
if let previewVC = presentedViewController as? PointCloudPreviewViewController,
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
{
let plyURL = documentsURL.appendingPathComponent("Scan.ply")
let thumbnailURL = documentsURL.appendingPathComponent("Scan.jpeg")
previewVC.pointCloud.writeToPLY(atPath: plyURL.path)
if let thumbnail = thumbnail,
let jpegData = thumbnail.jpegData(compressionQuality: 0.8)
{
try? jpegData.write(to: scanThumbnailURL)
}
}
presentedViewController?.dismiss(animated: true)
}
Coming soon!
Scan analysis is performed on the Standard Cyborg servers. Classes within StandardCyborgNetworking
provide a convenient interface to upload a scanned point cloud for analysis, then digest the analysis results. It is also possible to implement this yourself by using the Standard Cyborg Platform API.
To provide the fullest level of customization for your app, you can skip the StandardCyborgUI classes and interface directly with the core scanning algorithms in StandardCyborgFusion.framework
. The API documentation for SCReconstructionManager details how to do this.