2

I have some questions to the Viewer v7 and I cannot find any answers in the tutorials an API-References.

What I want to do: I want to upload PDFs to Forge using Forge Datamanagment API and then open it via the Viewer

What I have managed to do so far: I managed to upload PDF files to Forge and translate it to SVF.

However, so far, when I want to open the PDF using the Viewer I just get a blank page. I have followed this tutorial and additionally I added the extension Autodesk.PDF. So this is what my code looks like:

Autodesk.Viewing.Initializer(options, () => {
   this.viewer = new Autodesk.Viewing.GuiViewer3D(this.viewerDiv);
   this.viewer.loadExtension("Autodesk.PDF").then(() => {
        const startedCode = this.viewer.start();
        if (startedCode > 0) {
            console.error('Failed to create a Viewer: WebGL not supported.');
            return;
        }
        Autodesk.Viewing.Document.load(urn, (doc) => this.onDocumentLoadSuccess(doc), (err) => this.onDocumentLoadFailure(err));
   });
});

onDocumentLoadSuccess(doc) {
   var defaultModel = doc.getRoot().getDefaultGeometry();
   this.viewer.loadDocumentNode(doc, defaultModel);
}

onDocumentLoadFailure(viewerErrorCode) {
   this.handleError('Error loading document', viewerErrorCode);
}

For IFC files this works fine but not for PDF files.

I have seen some tutorials using the loadModel function, which takes as input an URL, to open PDF files without even translating them.

So here are my questions:

  • Do I even need to translate my PDF files to open it in the Viewer?
  • Why does the Viewer work for IFC Files but not for PDF files although the translation to SVF succeeds?
  • Can I use the loadModel function also with an URN (so the base64 endcoded objectId)?

Thanks in advance

Andreas
  • 309
  • 1
  • 8

1 Answers1

2

Q1: Do I even need to translate my PDF files to open it in the Viewer?

A1: Yes! According to Forge Viewer's Term of Usage, the Autodesk Forge viewer can only be used to view files generated by Autodesk Forge services

/*!
 * LMV v7.6.1
 * 
 * Copyright 2019 Autodesk, Inc.
 * All rights reserved.
 * 
 * This computer source code and related instructions and comments are the
 * unpublished confidential and proprietary information of Autodesk, Inc.
 * and are protected under Federal copyright and state trade secret law.
 * They may not be disclosed to, copied or used by any third party without
 * the prior written consent of Autodesk, Inc.
 * 
 * Autodesk Forge Viewer Usage Limitations:
 * 
 * The Autodesk Forge viewer can only be used to view files generated by
 * Autodesk Forge services. The Autodesk Forge Viewer JavaScript must be
 * delivered from an Autodesk hosted URL.
 */

Q2: Why does the Viewer work for IFC Files but not for PDF files although the translation to SVF succeeds?

A2: Please provide the error message from the GET:urn/manifest

Q3: Can I use the loadModel function also with an URN (so the base64 endcoded objectId)?

A3: Yes, if I understand it correctly. Here is the code snippet, and the screencast: https://knowledge.autodesk.com/community/screencast/de6b2d2a-c6b3-4747-8664-bd79cf417765

<!DOCTYPE html>
<html>
  <head>
    <title>PDF Viewer</title>
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta charset="utf-8">

    <!-- The Viewer CSS -->
    <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.6.*/style.min.css" type="text/css">
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      /* Create two unequal columns that floats next to each other */
      .column {
        float: left;
        height: 100vh;
      }

      .left {
        width: 10%;
      }

      .right {
        width: 90%;
      }

      /* Clear floats after the columns */
      .row:after {
        content: "";
        position: relative;
        display: inline-block;
        clear: both;
      }

      #pdf-pages-wrapper {
        position: relative;
        width: 100%;
        height: 100%;
        overflow-y: scroll;
      }

      #pdf-pages-wrapper ul {
        padding-left: 20px;
      }

      #pdf-pages-wrapper a {
        color: black;
        text-decoration: none;
      }

      #pdf-pages-wrapper a.active {
        font-weight: bold;
        color: blue;
        text-decoration: underline;
      }

      #viewer {
        position: relative;
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div class="row">
      <div class="column left">
        <div id="pdf-pages-wrapper"></div>
      </div>
      <div class="column right">
          <div id="viewer"></div>
      </div>
    </div>

    <!-- The Viewer JS -->
    <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.6.*/viewer3D.js"></script>

    <!-- Developer JS -->
    <script>
      class PdfData {
          constructor( document ) {
            this.doc = document;
            this.pages = [];
          }

          parse() {
            const filter = {
              type:'geometry',
              role: '2d'
            };

            const doc = this.doc;
            const rootItem = doc.getRoot();
            const viewables = rootItem.search( filter );

            if( viewables.length === 0 ) {
              console.error( 'Document contains no viewables.' );
              return false;
            }

            const pages = viewables.map( v => {
              const files = v.search( { role: 'pdf-page' } );
              const file = files[0];

              if( !file ) return;
              const urn = file.data.urn;

              return {
                guid: v.guid(),
                raw: v,
                name: v.name(),
                urn,
                url: function() {
                  return Autodesk.Viewing.endpoint.getItemApi() + urn;
                }
              };
            });

            this.pages = pages;

            if( !pages || pages.length <= 0 )
              return false;

            return true;
          }
        }

        let viewer;
        const options = {
            env: 'AutodeskProduction',
            accessToken: 'YourAccessToken'
        };

        const documentId = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXQvRTE1MDEyX1RVRl9aMzkwTS1QUk9fR0FNSU5HX1dpLUZpX1VNX1YyX1dFQi5wZGY';
        Autodesk.Viewing.Initializer(options, function() {
          Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
        });

        function onDocumentLoadSuccess( doc ) {
          buildPdfPageList( doc );

          const container = document.getElementById( 'viewer' );
          viewer = new Autodesk.Viewing.GuiViewer3D( container );
          viewer.start();

          viewer.loadExtension( 'Autodesk.PDF' ).then( () => {
            const event = new Event( 'click' );
            const page = document.querySelector( '#pdf-pages-wrapper a' );
            page.dispatchEvent( event );
          });
        }

        function onDocumentLoadFailure(viewerErrorCode) {
          console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
        }

        function onLoadModelSuccess(model) {
          console.log( 'onLoadModelSuccess()!' );
          console.log( 'Validate model loaded: ' + ( viewer.model === model ) );
          console.log( model );
        }

        function onLoadModelError( viewerErrorCode ) {
            console.error( 'onLoadModelError() - errorCode:' + viewerErrorCode);
        }

        function buildPdfPageList( doc ) {
          const pdf = new PdfData( doc );
          pdf.parse();
          const pageWrapperContainer = document.getElementById( 'pdf-pages-wrapper' );
          const pagesContainer = document.createElement( 'ul' );
          pageWrapperContainer.appendChild( pagesContainer );

          for( let i=0; i < pdf.pages.length; i++ ){
            const page = pdf.pages[i];
            console.log( page );
            const pageHolder = document.createElement( 'li' );
            pagesContainer.appendChild( pageHolder );

            const pageItem = document.createElement( 'a' );
            pageHolder.appendChild( pageItem );

            pageItem.href = '#';
            pageItem.innerText = page.name;
            pageItem.addEventListener( 'click', ( e ) => {
              e.preventDefault();
              e.stopPropagation();

              document.querySelectorAll( '#pdf-pages-wrapper a' ).forEach( e => e.classList.remove( 'active' ) );
              e.target.classList.add( 'active' );

              viewer.tearDown();
              const url = page.url();

              console.log( page, url );
              viewer.loadModel( url, {page: 1}, onLoadModelSuccess, onLoadModelError );
            });
          }
        }
    </script>
  </body>
</html>
Eason Kang
  • 6,155
  • 1
  • 7
  • 24
  • Hi Eason! Thanks for your reply. I do not get an error on GET:urn/manifest. The upload and translating works fine. When I use your code, I get an empty page and the following warning in the browser's console: Warning: Invalid stream: "FormatError: Bad FCHECK in flate stream: 120, 194" – Andreas Dec 16 '19 at 14:03
  • Hi Andreas, could you consider providing a none-confidential reproducible case that contains a minimum complete yet runnable code project and the PDF file for our investigations to email forge[DOT]help[AT]autodesk[DOT]com? – Eason Kang Dec 17 '19 at 04:04
  • Hi. It turned out, that we had another problem with the upload. Somehow the files get corrupted but the translation seem to have no problem with the files. However, now it works fine. Thanks for your help. Since your answer is perfectly correct for the original question, I will mark it as accepted. Cheers – Andreas Dec 17 '19 at 09:18