Visual Studio Node.js プロジェクトでの Forge SDK の利用

Visual Studio からの Web アプリのデプロイ では Visual Studio で作成したスケルトン プロジェクトを使って、「空の Azure Node.js Web アプリケーション」テンプレートが生成した簡単な Web アプリを Azure にデプロイする手順をご案内しました。

今回は、同じ手順で作成したプロジェクトに、Forge Node.js クイックスタート ~ その1 や  Forge SDK を使用した 3-legged OAuth Access Token 取得 で使った  Forge Node.js SDK を組み込み、Basic Application  相当のコードを Web アプリに実装してデプロイします。なお、表示する 3D モデルは、あらかじめ変換済の URN があることを前提とします。


  1. Visual Studio からの Web アプリのデプロイ でご案内した手順で「空の Azure Node.js Web アプリケーション」テンプレートを使ったスケルトン プロジェクトを作成します。ここでは、プロジェクト名を NodejsWebApp3 とします。
  2. スケルトン プロジェクトに Forge Node.js SDK パッケージを追加します。[ソリューション エクスプローラ] 上の npm を見つけてマウスの右ボタンでクリックしたら、[新しい npm パッケージをインストールする(N)…] を選択してください。
  3. [新しい npm パッケージのインストール] ダイアログが表示されたら、左上の検索ボックスに Autodesk Forge を入力して(①)、リストアップされてくる中から「forge-apis x.x.x Autodesk Inc. を見つけて選択し(②)、 [パッケージのインストール(I)] ボタンをクリックします(③)。
  4. [ソリューション エクスプローラ] 上の npm 下に「forge-apis@x.x.x」が追加されたのを確認したら、[新しい npm パッケージのインストール] ダイアログを閉じてください。
'use strict';
var http = require('http');
var ForgeSDK = require('forge-apis');
var port = process.env.PORT || <<YOUR PORT NUMBER>>;

var CLIENT_ID = '<<YOUR CLIENT ID>>',
    CLIENT_SECRET = '<<YOOUE CLIENT SECRET>>',
    ENCODED_URN = '<<YOUR BASE64 ENCODED URN>>';

http.createServer(function (req, res) {
    var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLeggedV2(CLIENT_ID, CLIENT_SECRET, ['viewables:read'], true);
    oAuth2TwoLegged.authenticate().then(function (credentials) {
        console.log("**** Got Credentials", credentials);
        var token = credentials["access_token"];
        var data = [
            '<head>',
            '  <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />',
            '  <meta charset="utf-8">',
            '',
            '  <!-- The Viewer CSS -->',
            '  <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/style.min.css" type="text/css">',
            '',
            '  <!-- Developer CSS -->',
            '  <style>',
            '    body {',
            '      margin: 0;',
            '    }',
            '    #MyViewerDiv {',
            '      width: 100%;',
            '      height: 100%;',
            '      margin: 0;',
            '      background-color: #F0F8FF;',
            '    }',
            '  </style>',
            '</head>',
            '<body>',
            '',
            '  <!-- The Viewer will be instantiated here -->',
            '  <div id="MyViewerDiv"></div>',
            '',
            '  <!-- The Viewer JS -->',
            '  <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/viewer3D.min.js"></script>',
            '',
            '  <!-- Developer JS -->',
            '  <script>',
            "    var token = '" + token + "';",
            "    var urn = '" + ENCODED_URN + "';",
            '',
            '    var viewerApp;',
            '    var _viewer;',
            '    var options = {',
            "      env: 'AutodeskProduction',",
            '      getAccessToken: function(onGetAccessToken) {',
            '        //',
            '        // TODO: Replace static access token string below with call to fetch new token from your backend',
            "        // Both values are provided by Forge's Authentication (OAuth) API.",
            '        //',
            "        // Example Forge's Authentication (OAuth) API return value:",
            '        // {',
            '        // "access_token": "<YOUR_APPLICATION_TOKEN>",',
            '        // "token_type": "Bearer",',
            '        // "expires_in": 86400',
            '        // }',
            '        //',
            '        var accessToken = token;',
            '        var expireTimeSeconds = 60 * 30;',
            '        onGetAccessToken(accessToken, expireTimeSeconds);',
            '      }',
            '',
            '    };',
            '',
            "    var documentId = 'urn:' + urn;",
            '    Autodesk.Viewing.Initializer(options, function onInitialized(){',
            '      var avp = Autodesk.Viewing.Private;',
            '      avp.logger.setLevel( avp.LogLevels.Debug );',
            '      var config3d = {',
            "        extensions: ['Autodesk.Viewing.Collaboration']",
            '      };',
            "      viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');",
            '      viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config3d);',
            '      viewerApp.loadDocument(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);',
            '    });',
            '',
            '    function onDocumentLoadSuccess(doc) {',
            '',
            '      // We could still make use of Document.getSubItemsWithProperties()',
            '      // However, when using a ViewingApplication, we have access to the **bubble** attribute,',
            '      // which references the root node of a graph that wraps each object from the Manifest JSON.',
            "      var viewables = viewerApp.bubble.search({'type':'geometry'});",
            '      if (viewables.length === 0) {',
            "        console.error('Document contains no viewables.');",
            '        return;',
            '      }',
            '',
            '      // Choose any of the avialble viewables',
            '      viewerApp.selectItem(viewables[1].data, onItemLoadSuccess, onItemLoadFail);',
            '    }',
            '',
            '    function onDocumentLoadFailure(viewerErrorCode) {',
            "      console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);",
            '    }',
            '',
            '    function onItemLoadSuccess(viewer, item) {',
            "      console.log('onItemLoadSuccess()!');",
            '      console.log(viewer);',
            '      console.log(item);',
            '',
            '      // Congratulations! The viewer is now ready to be used.',
            "      console.log('Viewers are equal: ' + (viewer === viewerApp.getCurrentViewer()));",
            '      _viewer = viewer',
            "      viewer.search('LDK 202', onSearchResult);",
            '    }',
            '',
            '    function onItemLoadFail(errorCode) {',
            "      console.error('onItemLoadFail() - errorCode:' + errorCode);",
            '    }',
            '',
            'function onSearchResult(idArray) {',
            //            '    _viewer.isolate(idArray);',
            //            '    _viewer.clearSelection();',
            //            '    _viewer.select(idArray, Autodesk.Viewing.SelectionMode.OVERLAYED);',
            '    var col = new THREE.Vector4(0, 0, 1, 0.3);',
            '    _viewer.show(idArray[0]);',
            '    _viewer.setThemingColor(idArray[0], col);',
            '}',
            '',
            '',
            '  </script>',
            '</body>'
        ].join('\n');
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write(data);
        res.end();
    }, function (err) {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write('ERROR: ' + err.errorCode);
        res.end();
        console.error('\x1b[31m Error:', err, '\x1b[0m');
    });

}).listen(port);
  1. server.js を修正したプロジェクト(NodejsWebApp3 プロジェクト)の実行をテストしてみます。[デバッグ(D)] メニューから [▶ デバッグッグの開始(S)] を選択して、Web ブラウザが起動後に server.js で指定した URN を持つ 3D モデルが表示されることを確認してください。
  2. プロジェクトのローカルでの実行が正常なら、Visual Studio からの Web アプリのデプロイ で の手順に沿って Azure へのデプロイをおこないます。ここでは、[App Service の作成] ダイアログで、Visual Studio が自動設定したアプリ名を書き換え、NodejsWebApp3-app に書き換えることにします。リソース グループも NodejsWebApp3-app 名で新規作成することにします。
  3. [発行] ダイアログでは、各項目を既定値のまま [発行(P)] ボタンをクリックします。
  4. 発行が正常に完了すると、Azure 上の URL(ここでは https://nodejswebapp3-app.azurewebsites.net/)で指定した 3D モデルを表示されるはずです。

    もちろん、WebGL 対応の Web ブラウザさえあれば、デプロイされた Web アプリはデバイスを問わず参照出来るはずです。

今回の例では、Node.js で構築した Web サーバー実装で Forge Node.js SDK を使った Authentication(Forge Web アプリ認証)を経て Access Token を取得し、クライアントからのWeb サーバー リクエスト(URL 入力)に対するレスポンスとして、Basic_Application の内容となる HTML と内包する JavaScript コードを返す(表示させる)コードを作成してみました。

An illustration showing various web browsers and devices on the left, connected to a cloud server labeled 'RESTful API' and 'FORGE'. Below, a screenshot of the Autodesk Forge portal is displayed with the title 'Test app'.

この他にも、多様な Web サーバーを実装することが出来るはずです。

By Toshiaki Isezaki

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading