< iOS samples

U3DTest - Swift

This example illustrates how to embed U3D content (3 dimensional models) in PDF.

// Copyright (c) 2001-2017 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.

import PDFNet
import Foundation

func Create3DAnnotation(doc: PTPDFDoc, annots: PTObj) {
    // ---------------------------------------------------------------------------------
    // Create a 3D annotation based on U3D content. PDF 1.6 introduces the capability
    // for collections of three-dimensional objects, such as those used by CAD software,
    // to be embedded in PDF files.
    let link_3D: PTObj = doc.createIndirectDict()
    link_3D.putName("Subtype", name: "3D")
    // Annotation location on the page
    let link_3D_rect: PTPDFRect = PTPDFRect(x1: 25, y1: 180, x2: 585, y2: 643)
    link_3D.putRect("Rect", x1: link_3D_rect.getX1(), y1: link_3D_rect.getY1(), x2: link_3D_rect.getX2(), y2: link_3D_rect.getY2())
    // The 3DA entry is an activation dictionary (see Table 9.34 in the PDF Reference Manual)
    // that determines how the state of the annotation and its associated artwork can change.
    let activation_dict_3D: PTObj = link_3D.putDict("3DA")
    // Set the annotation so that it is activated as soon as the page containing the
    // annotation is opened. Other options are: PV (page view) and XA (explicit) activation.
    activation_dict_3D.putName("A", name: "PO")
    // Embed U3D Streams (3D Model/Artwork).
    do {
        let u3d_file = PTMappedFile(filename: Bundle.main.path(forResource: "dice", ofType: "u3d"))
        let u3d_reader = PTFilterReader(filter: u3d_file)
        // To embed 3D stream without compression, you can omit the second parameter in CreateIndirectStream.
        let u3d_data_dict: PTObj = doc.createIndirectStream(u3d_reader, filter_chain: PTFlateEncode(input_filter: PTFilter(), compression_level: -1, buf_sz: 256))
        u3d_data_dict.putName("Subtype", name: "U3D")
        link_3D.put("3DD", obj: u3d_data_dict)
    // Set the initial view of the 3D artwork that should be used when the annotation is activated.
    let view3D_dict: PTObj = link_3D.putDict("3DV")
    do {
        view3D_dict.put("IN", value: "Unnamed")
        view3D_dict.put("XN", value: "Default")
        view3D_dict.putName("MS", name: "M")
        view3D_dict.putNumber("CO", value: 27.5)
        // A 12-element 3D transformation matrix that specifies a position and orientation
        // of the camera in world coordinates.
        let tr3d: PTObj = view3D_dict.putArray("C2W")
    // Create annotation appearance stream, a thumbnail which is used during printing or
    // in PDF processors that do not understand 3D data.
    let ap_dict: PTObj = link_3D.putDict("AP")
    do {
        let builder: PTElementBuilder = PTElementBuilder()
        let writer: PTElementWriter = PTElementWriter()
        writer.writerBegin(with: doc.getSDFDoc(), compress: true)
        let thumb_pathname: String! = Bundle.main.path(forResource: "dice", ofType: "jpg")
        let image = PTImage.create(withFile: doc.getSDFDoc(), filename: thumb_pathname, encoder_hints: PTObj())
        writer.writePlacedElement(builder.createImage(withCornerAndScale: image, x: 0.0, y: 0.0, hscale: link_3D_rect.width(), vscale: link_3D_rect.height()))
        let normal_ap_stream: PTObj = writer.end()
        normal_ap_stream.putName("Subtype", name: "Form")
        normal_ap_stream.putRect("BBox", x1: 0, y1: 0, x2: link_3D_rect.width(), y2: link_3D_rect.height())
        ap_dict.put("N", obj: normal_ap_stream)

func runU3DTest() -> Int {
    return autoreleasepool {
        var ret: Int = 0

        do {
            try PTPDFNet.catchException {
                let doc: PTPDFDoc = PTPDFDoc()
                let rect: PTPDFRect = PTPDFRect()
                rect.set(0, y1: 0, x2: 612, y2: 792)
                let page: PTPage = doc.pageCreate(rect)
                let annots: PTObj = doc.createIndirectArray()
                page.getSDFObj().put("Annots", obj: annots)
                Create3DAnnotation(doc: doc, annots: annots)
                doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("dice_u3d.pdf").path, flags: e_ptlinearized.rawValue)
        } catch let e as NSError {
            ret = 1
        return ret