Introduction

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!

Example App

StandardCyborgExample is a bare-bones example app that takes a 3D scan using StandardCyborgFusion and visualizes the result using StandardCyborgUI.

Running StandardCyborgExample

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

    • Select StandardCyborgExample in the project file list
    • Select the StandardCyborgExample target
    • Under the Team menu, choose your development team
  • Add your Standard Cyborg API key

  • Build and run!

Example app, home screen, no scan Example app, scanning Example app, scan preview Example app, home screen, with scan

SDK Overview

The Standard Cyborg SDK provides 3 frameworks:

  • StandardCyborgFusion
    Core 3D reconstruction algorithms live here. Provided as a compiled binary.
  • StandardCyborgUI
    Classes that make it easy for an app to manage TrueDepth camera state, visualize incoming depth frames, and preview scan results
  • StandardCyborgNetworking
    A Swift interface to the Standard Cyborg Platform API, which provides storage and analysis for 3D scans. Scan analysis is performed entirely on the servers.

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].

Integrating 3D scanning into your existing app

Prepare your app and Xcode project

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!

  1. In your project’s root directory, add our repo as a Git submodule

    git submodule add git@github.com:StandardCyborg/StandardCyborgCocoa.git

    Add StandardCyborgUI

  2. With your app’s Xcode project open, drag StandardCyborgUI.xcodeproj from StandardCyborgCocoa in the Finder down into your app’s project
    Add StandardCyborgFusion
  3. Link against the StandardCyborgCocoa and StandardCyborgUI frameworks

    1. Select your app’s Xcodeproj from the project navigator, choose the target for your app, select the Build Phases tab, and disclose Link Binary with Libraries
      Link binary with libraries
    2. Drag StandardCyborgUI.framework from the project navigator into the list under Link Binary with Libraries
    3. Drag StandardCyborgFusion.framework from the Finder into that same list
  4. Copy those frameworks into your app’s built products using a new copy files build phase

    1. Under Build Phases, click +, then choose New Copy Files Phase
      New Copy Files Phase
    2. Expand the newly created phase below
    3. Change the Destination to Frameworks
    4. Drag those two frameworks from the project navigator to the empty list under Copy Files
      Copy Frameworks

Present a ScanningViewController

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.

App scanning preview

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.

Present a PointCloudPreviewViewController

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! App scan preview 1

Customize the PointCloudPreviewViewController

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)
    }

App scan preview 2

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!

Save the scan

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)
    }

Analyze the scan

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.

Interfacing directly with the core scanning algorithms

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.