Sample Kotlin code for using Apryse SDK to embed U3D content (3 dimensional models) in PDF files. Learn more about our Android SDK.
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6package com.pdftron.android.pdfnetsdksamples.samples
7
8import com.pdftron.android.pdfnetsdksamples.OutputListener
9import com.pdftron.android.pdfnetsdksamples.PDFNetSample
10import com.pdftron.android.pdfnetsdksamples.R
11import com.pdftron.android.pdfnetsdksamples.util.Utils
12import com.pdftron.common.PDFNetException
13import com.pdftron.filters.FilterReader
14import com.pdftron.filters.FlateEncode
15import com.pdftron.filters.MappedFile
16import com.pdftron.pdf.*
17import com.pdftron.sdf.Obj
18import com.pdftron.sdf.SDFDoc
19import java.util.*
20
21class U3DTest : PDFNetSample() {
22 init {
23 setTitle(R.string.sample_u3d_title)
24 setDescription(R.string.sample_u3d_description)
25 }
26
27 override fun run(outputListener: OutputListener?) {
28 super.run(outputListener)
29 mOutputListener = outputListener
30 mFileList.clear()
31 printHeader(outputListener!!)
32 try {
33
34 PDFDoc().use { doc ->
35 val page = doc.pageCreate()
36 doc.pagePushBack(page)
37 val annots = doc.createIndirectArray()
38 page.sdfObj.put("Annots", annots)
39
40 Create3DAnnotation(doc, annots)
41 doc.save(Utils.createExternalFile("dice_u3d.pdf", mFileList).absolutePath, SDFDoc.SaveMode.LINEARIZED, null)
42 mOutputListener!!.println("Done")
43 }
44 } catch (e: Exception) {
45 mOutputListener!!.printError(e.stackTrace)
46 }
47
48 for (file in mFileList) {
49 addToFileList(file)
50 }
51 printFooter(outputListener)
52 }
53
54 companion object {
55
56 private var mOutputListener: OutputListener? = null
57
58 private val mFileList = ArrayList<String>()
59
60 @Throws(PDFNetException::class)
61 internal fun Create3DAnnotation(doc: PDFDoc, annots: Obj) {
62 // ---------------------------------------------------------------------------------
63 // Create a 3D annotation based on U3D content. PDF 1.6 introduces the capability
64 // for collections of three-dimensional objects, such as those used by CAD software,
65 // to be embedded in PDF files.
66 val link_3D = doc.createIndirectDict()
67 link_3D.putName("Subtype", "3D")
68
69 // Annotation location on the page
70 val link_3D_rect = Rect(25.0, 180.0, 585.0, 643.0)
71 link_3D.putRect("Rect", link_3D_rect.x1, link_3D_rect.y1,
72 link_3D_rect.x2, link_3D_rect.y2)
73 annots.pushBack(link_3D)
74
75 // The 3DA entry is an activation dictionary (see Table 9.34 in the PDF Reference Manual)
76 // that determines how the state of the annotation and its associated artwork can change.
77 val activation_dict_3D = link_3D.putDict("3DA")
78
79 // Set the annotation so that it is activated as soon as the page containing the
80 // annotation is opened. Other options are: PV (page view) and XA (explicit) activation.
81 activation_dict_3D.putName("A", "PO")
82
83 // Embed U3D Streams (3D Model/Artwork).
84 run {
85 val u3d_file = MappedFile(Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "dice.u3d")!!.absolutePath)
86 val u3d_reader = FilterReader(u3d_file)
87
88 // To embed 3D stream without compression, you can omit the second parameter in CreateIndirectStream.
89 val u3d_data_dict = doc.createIndirectStream(u3d_reader, FlateEncode(null))
90 u3d_data_dict.putName("Subtype", "U3D")
91 link_3D.put("3DD", u3d_data_dict)
92 }
93
94 // Set the initial view of the 3D artwork that should be used when the annotation is activated.
95 val view3D_dict = link_3D.putDict("3DV")
96 run {
97 view3D_dict.putString("IN", "Unnamed")
98 view3D_dict.putString("XN", "Default")
99 view3D_dict.putName("MS", "M")
100 view3D_dict.putNumber("CO", 27.5)
101
102 // A 12-element 3D transformation matrix that specifies a position and orientation
103 // of the camera in world coordinates.
104 val tr3d = view3D_dict.putArray("C2W")
105 tr3d.pushBackNumber(1.0)
106 tr3d.pushBackNumber(0.0)
107 tr3d.pushBackNumber(0.0)
108 tr3d.pushBackNumber(0.0)
109 tr3d.pushBackNumber(0.0)
110 tr3d.pushBackNumber(-1.0)
111 tr3d.pushBackNumber(0.0)
112 tr3d.pushBackNumber(1.0)
113 tr3d.pushBackNumber(0.0)
114 tr3d.pushBackNumber(0.0)
115 tr3d.pushBackNumber(-27.5)
116 tr3d.pushBackNumber(0.0)
117
118 }
119
120 // Create annotation appearance stream, a thumbnail which is used during printing or
121 // in PDF processors that do not understand 3D data.
122 val ap_dict = link_3D.putDict("AP")
123 run {
124 val builder = ElementBuilder()
125 val writer = ElementWriter()
126 writer.begin(doc)
127
128 val thumb_pathname = Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "dice.jpg")!!.absolutePath
129 val image = Image.create(doc, thumb_pathname)
130 writer.writePlacedElement(builder.createImage(image, 0.0, 0.0, link_3D_rect.width, link_3D_rect.height))
131
132 val normal_ap_stream = writer.end()
133 normal_ap_stream.putName("Subtype", "Form")
134 normal_ap_stream.putRect("BBox", 0.0, 0.0, link_3D_rect.width, link_3D_rect.height)
135 ap_dict.put("N", normal_ap_stream)
136 }
137 }
138 }
139
140}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6package com.pdftron.android.pdfnetsdksamples.samples;
7
8import com.pdftron.android.pdfnetsdksamples.OutputListener;
9import com.pdftron.android.pdfnetsdksamples.PDFNetSample;
10import com.pdftron.android.pdfnetsdksamples.R;
11import com.pdftron.android.pdfnetsdksamples.util.Utils;
12import com.pdftron.common.PDFNetException;
13import com.pdftron.filters.FilterReader;
14import com.pdftron.filters.FlateEncode;
15import com.pdftron.filters.MappedFile;
16import com.pdftron.pdf.ElementBuilder;
17import com.pdftron.pdf.ElementWriter;
18import com.pdftron.pdf.Image;
19import com.pdftron.pdf.PDFDoc;
20import com.pdftron.pdf.Page;
21import com.pdftron.pdf.Rect;
22import com.pdftron.sdf.Obj;
23import com.pdftron.sdf.SDFDoc;
24
25import java.util.ArrayList;
26
27public class U3DTest extends PDFNetSample {
28
29 private static OutputListener mOutputListener;
30
31 private static ArrayList<String> mFileList = new ArrayList<>();
32
33 public U3DTest() {
34 setTitle(R.string.sample_u3d_title);
35 setDescription(R.string.sample_u3d_description);
36 }
37
38 @Override
39 public void run(OutputListener outputListener) {
40 super.run(outputListener);
41 mOutputListener = outputListener;
42 mFileList.clear();
43 printHeader(outputListener);
44 try (PDFDoc doc = new PDFDoc()) {
45 Page page = doc.pageCreate();
46 doc.pagePushBack(page);
47 Obj annots = doc.createIndirectArray();
48 page.getSDFObj().put("Annots", annots);
49
50 Create3DAnnotation(doc, annots);
51 doc.save(Utils.createExternalFile("dice_u3d.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.LINEARIZED, null);
52 mOutputListener.println("Done");
53 } catch (Exception e) {
54 mOutputListener.printError(e.getStackTrace());
55 }
56
57 for (String file : mFileList) {
58 addToFileList(file);
59 }
60 printFooter(outputListener);
61 }
62
63 static void Create3DAnnotation(PDFDoc doc, Obj annots) throws PDFNetException {
64 // ---------------------------------------------------------------------------------
65 // Create a 3D annotation based on U3D content. PDF 1.6 introduces the capability
66 // for collections of three-dimensional objects, such as those used by CAD software,
67 // to be embedded in PDF files.
68 Obj link_3D = doc.createIndirectDict();
69 link_3D.putName("Subtype", "3D");
70
71 // Annotation location on the page
72 Rect link_3D_rect = new Rect(25, 180, 585, 643);
73 link_3D.putRect("Rect", link_3D_rect.getX1(), link_3D_rect.getY1(),
74 link_3D_rect.getX2(), link_3D_rect.getY2());
75 annots.pushBack(link_3D);
76
77 // The 3DA entry is an activation dictionary (see Table 9.34 in the PDF Reference Manual)
78 // that determines how the state of the annotation and its associated artwork can change.
79 Obj activation_dict_3D = link_3D.putDict("3DA");
80
81 // Set the annotation so that it is activated as soon as the page containing the
82 // annotation is opened. Other options are: PV (page view) and XA (explicit) activation.
83 activation_dict_3D.putName("A", "PO");
84
85 // Embed U3D Streams (3D Model/Artwork).
86 {
87 MappedFile u3d_file = new MappedFile(Utils.getAssetTempFile(INPUT_PATH + "dice.u3d").getAbsolutePath());
88 FilterReader u3d_reader = new FilterReader(u3d_file);
89
90 // To embed 3D stream without compression, you can omit the second parameter in CreateIndirectStream.
91 Obj u3d_data_dict = doc.createIndirectStream(u3d_reader, new FlateEncode(null));
92 u3d_data_dict.putName("Subtype", "U3D");
93 link_3D.put("3DD", u3d_data_dict);
94 }
95
96 // Set the initial view of the 3D artwork that should be used when the annotation is activated.
97 Obj view3D_dict = link_3D.putDict("3DV");
98 {
99 view3D_dict.putString("IN", "Unnamed");
100 view3D_dict.putString("XN", "Default");
101 view3D_dict.putName("MS", "M");
102 view3D_dict.putNumber("CO", 27.5);
103
104 // A 12-element 3D transformation matrix that specifies a position and orientation
105 // of the camera in world coordinates.
106 Obj tr3d = view3D_dict.putArray("C2W");
107 tr3d.pushBackNumber(1);
108 tr3d.pushBackNumber(0);
109 tr3d.pushBackNumber(0);
110 tr3d.pushBackNumber(0);
111 tr3d.pushBackNumber(0);
112 tr3d.pushBackNumber(-1);
113 tr3d.pushBackNumber(0);
114 tr3d.pushBackNumber(1);
115 tr3d.pushBackNumber(0);
116 tr3d.pushBackNumber(0);
117 tr3d.pushBackNumber(-27.5);
118 tr3d.pushBackNumber(0);
119
120 }
121
122 // Create annotation appearance stream, a thumbnail which is used during printing or
123 // in PDF processors that do not understand 3D data.
124 Obj ap_dict = link_3D.putDict("AP");
125 {
126 ElementBuilder builder = new ElementBuilder();
127 ElementWriter writer = new ElementWriter();
128 writer.begin(doc);
129
130 String thumb_pathname = Utils.getAssetTempFile(INPUT_PATH + "dice.jpg").getAbsolutePath();
131 Image image = Image.create(doc, thumb_pathname);
132 writer.writePlacedElement(builder.createImage(image, 0.0, 0.0, link_3D_rect.getWidth(), link_3D_rect.getHeight()));
133
134 Obj normal_ap_stream = writer.end();
135 normal_ap_stream.putName("Subtype", "Form");
136 normal_ap_stream.putRect("BBox", 0, 0, link_3D_rect.getWidth(), link_3D_rect.getHeight());
137 ap_dict.put("N", normal_ap_stream);
138 }
139 }
140
141}
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales