Detecting if a PDF file contains 3D element

Solution 1:

AFAIK, there is no requirement to put any info into its metadata about the fact that 3D elements may be contained in the document.

Some U3D writing software may put some hint about it into the XML metadata though.

Long Answer

You'll have to parse the PDF page tree at least partially in order to find out.

Technically, 3D elements are implemented as annotations. To discover any annotation, you'd have to follow this parsing path:

  1. Read the trailer. It tells you the object number of the /Root indirect object of the document.

  2. Read the cross reference table. It tells you the byte offsets for each indirect object within the document.

  3. Go to the /Root indirect object. Read its /Pages key. This tells you which indirect object represents the root of the document's page tree.

  4. Go to the indirect object which represents the /Pages. Read its /Kids key. This tells you which other indirect objects represent document pages.

  5. Go to each indirect object representing a document page. Look for any (optionally present) /Annots key. If present it will point to other indirect objects representing (possibly all sorts of) annotations.

Now you've found out if the PDF contains annotation(s) or not. If not, stop here. If yes, go on to determine the annotation type(s):

  1. Go to all indirect objects found in the last step. They are of /Type /Annot. See if they are additionally of /Subtype /3D. If yes, you have found a 3D annotation. (Attention, this may still not be a U3D one!)

  2. Within the lastly found indirect object(s) -- the one(s) with the /Subtype /3D key -- look for an additional key of /3DD. It points to this indirect object which contains the actual 3D stream.

  3. Go to the indirect object containing the 3D stream. Its object dictionary should again contain a key:value pair of /Type /3D. Look at its /Subtype key. If it says /U3D you have found what you looked for...

Short Answer

You may be lucky and harvest some low-hanging fruits by using good old grep like this:

$> grep -a U3D cc-7-july09.pdf

  /Subtype /U3D
  /MS /U3D
  /U3DPath [ <135BB3D42FBD85F7C2E178> <056D9A891FB5FDCE8E> ]
  /MS /U3D
  /U3DPath [ <5FFAF35CE3CBD34FAE5360> <4DDFD6048FC6DA05> ]
  /MS /U3D
  /U3DPath [ <2E4E4FD7FEC771038BC5EA> <2A6579CC91BE0B> ]
  /MS /U3D
  /U3DPath [ <6F303AF9850721D5D1FC6C> <7D1B08BEAE4A5A9BEDBB> ]
  /MS /U3D
  /U3DPath [ <F270A04603F0DE08B8AA29> <EE5180016FFBD542> ]
  /MS /U3D
  /U3DPath [ <A1D5848F6841ADA9A3583C> <A3F8A5D45849D392EF> ]
  /MS /U3D
  /U3DPath [ <34B8650D178BBDFF61DC03> <2D8F4C7D3CD980F976> ]
  /MS /U3D
  /U3DPath [ <843CD0339FD1852CCA235B> <9719FB65A990897F> ]

However, this will not work for all 3D PDF documents, especially if the 3D elements are part of an object stream.