1 Apr 2019

Publicly share models in customized Viewer

When on any of the Autodesk Storage solutions (A360, Fusion Team, etc) then you have the option to share your models publicly by inserting an iframe in your webpage:

Share model in iframe

The problem is that in this case the Viewer cannot be customized.

One solution would be to create your own Viewer instance and server for the login mechanism (see View your models), log in once using your credentials, and then keep the login alive for everyone by using the refresh_token - see About Refresh Token  

One other way would be to take advantage of the existing public sharing mechanism and the login endpoint it provides and add it to your webpage. In this case you do not even need to provide server side login mechanism, just serve from somewhere your html page with the JavaScript code in it. The only thing you need to modify in the below code is the value of embedURLfromA360, which should be set to the URL that is inside the iframe tag highlighted above in yellow

<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta charset="utf-8" />

    <!-- The Viewer CSS -->
    <link
      rel="stylesheet"
      href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css"
      type="text/css"
    />

    <!-- Developer CSS -->
    <style>
      body {
        margin: 0;
      }

      #MyConytainerDiv {
        width: 100%;
        height: 100%;
        position: relative;
      }

      #MyViewerDiv {
        width: 100%;
        height: 100%;
        margin: 0;
      }
    </style>

    <title>Showing Fusion Team Shared models</title>
  </head>

  <body>
    <!-- The Viewer will be instantiated here -->
    <div id="MyConytainerDiv">
      <div id="MyViewerDiv"></div>
    </div>

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

    <!-- Developer JS -->
    <script>
      // this is the iframe URL that shows up when sharing a model embed on a page
      const embedURLfromFusion =
        "https://autodesk3743.autodesk360.com/shares/public/SHabee1QT1a327cf2b7a174096650e4352bf?mode=embed"; // Stirling Engine
      let viewer;

      async function getURN(callback) {
        const ret = await fetch(
          embedURLfromFusion
            .replace("public", "metadata")
            .replace("mode=embed", "")
        );
        const metadata = await ret.json();
        const urn = btoa(metadata.success.body.urn)
          .replace("/", "_")
          .replace("=", "");

        callback(urn);
      }

      async function getToken(callback) {
        const ret = await fetch(
          embedURLfromFusion
            .replace("public", "sign")
            .replace("mode=embed", "oauth2=true"),
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: "{}",
          }
        );
        const oauth = await ret.json();

        callback(oauth.accessToken, oauth.validitySeconds);
      }

      getURN(function (urn) {
        const options = {
          env: "AutodeskProduction",
          getAccessToken: getToken,
        };
        const documentId = "urn:" + urn;
        Autodesk.Viewing.Initializer(options, function onInitialized() {
          Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess);
        });
      });

      /**
       * Autodesk.Viewing.Document.load() success callback.
       * Proceeds with model initialization.
       */
      async function onDocumentLoadSuccess(doc) {
        // A document contains references to 3D and 2D viewables.
        const viewable = doc.getRoot().getDefaultGeometry();

        const viewerDiv = document.getElementById("MyViewerDiv");
        viewer = new Autodesk.Viewing.GuiViewer3D(viewerDiv, {
          extensions: ["Autodesk.DocumentBrowser"],
        });
        viewer.start();

        viewer.loadDocumentNode(doc, viewable);
      }
    </script>
  </body>
</html>

Now I can just serve this html page from anywhere and get this:

Publicly share model

Since in this case we are using our own Viewer instance therefore we can do all the available customizations to it. 😀
E.g. in the above case we are removing some of the toolbar buttons that we do not want the user to see, using the solution shown here: When to remove toolbar buttons   

Related Article