Forge Node.js クイックスタート ~ その2

<本記事は2019年12月10日に Forge SDK 更新にあわせて一部改定しています。>

Forge Node.js クイックスタート ~ その1 ではhttps://forge.autodesk.com/en/docs/quickstarts/v1/nodejs/ に記載されている Forge Node.js SDK のサンプル(Quickstart) の内容に沿って、GitHub に記載されている Forge SDK をローカルコンピュータにコピーして、サンプルの実装を完了させる手順をご紹介しました。

実装した dmSample.js のメインルーチンでは、Access Token を取得して Bucket を作成、指定したデザイン ファイルをアップロードした後にそのファイルを削除しまうので、ここでは、アップロードしたデザインファイルを Model Derivative API で変換して、Forge Viewer に表示する部分を追記していきます。


  1. アップロードしたデザイン ファイルを Forge Viewer で表示するには、Model Derivative API を使用する必要があります。Forge SDK にも Model Derivative API をラップしているので、Node.js で機能を利用出来るように変数代入します。前回 GitHub リポジトリからクローンした  forge-api-nodejs-clientsamples フォルダから  dmSample.js ファイルを見つけて Adobe Brackets で開きます。
  2. dmSample.js 内で BucketsApi と objectsApi をインスタンス化して変数に代入している箇所を見つけて、下記の青字部分を追記してください。 new ForgeSDK.ObjectsApi() の後に , (カンマ)を挿入する点に注意してください。
var fs = require('fs');
var ForgeSDK = require('./../src/index');

// TODO - insert your CLIENT_ID and CLIENT_SECRET
var FORGE_CLIENT_ID = '0FbkV1SHBrTuIdIT51KECv45uUuJvsHN',
    FORGE_CLIENT_SECRET = 'J8JsGASgIXszdrIu';

// TODO - Choose a bucket key - a unique name to assign to a bucket. It must be globally unique across all applications and
// regions, otherwise the call will fail. Possible values: -_.a-z0-9 (between 3-128 characters in
// length). Note that you cannot change a bucket key.
var BUCKET_KEY = 'forge_sample_' + CLIENT_ID.toLowerCase();

// TODO - Choose a filename - a key for the uploaded object
var FILE_NAME = 'Chair.f3d';

// TODO - specify the full filename and path
var FILE_PATH = 'C:/Users/isezakt/Desktop/Chair.f3d';
var bucketsApi = new ForgeSDK.BucketsApi(), // Buckets Client
    objectsApi = new ForgeSDK.ObjectsApi(), // Objects Client
    derivativesApi = new ForgeSDK.DerivativesApi(); // Derivatives Client

// Initialize the 2-legged oauth2 client
var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(
    FORGE_CLIENT_ID, CLIENT_SECRET,
    ['data:write', 'data:read', 'bucket:read', 'bucket:update', 'bucket:create'],
    true
);
  1. dmSample.js 内にアップロードしたデザイン ファイルのドキュメント ID(objectId)を Base64 でエンコードする base64encode() 関数を getBuckets() 関数の後に追記します。
/** * Get the buckets owned by an application. 
 * Uses the oAuth2TwoLegged object that you retrieved previously. */
var getBuckets = function () {
    console.log("**** Getting all buckets");
    return bucketsApi.getBuckets({}, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials());
};

function base64encode(str) {
    return new Buffer(str).toString('base64');
}
  1. 次に dmSample.js 内に 変換を指示する translate endpoint を呼び出す translateFile() 関数を base64encode() 関数の後に追記します。
var translateFile = function (encodedURN) {
    console.log("**** Translating file derivative")
        ; var postJob = {
            input: {
                urn: encodedURN
            },
            output: {
                formats:
                    [
                        {
                            type: "svf",
                            views: ["2d", "3d"]
                        }
                    ]
            }
        };
    return new Promise(function (resolve, reject) {
        derivativesApi.translate(postJob, {}, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials()).then(
            function (res) {
                resolve(res);
            },
            function (err) {
                reject(err);
            })
    });
};
  1. 同様に、dmSample.js 内に 変換状態をチェックする getManifest endpoint を呼び出す manifestFile() 関数を translateFile() 関数の後に追記します。
var manifestFile = function (encodedURN) {
    console.log("**** Getting File Manifest Status");
    return new Promise(function (resolve, reject) {
        derivativesApi.getManifest(encodedURN, {}, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials()).then(
            function (res) {
                if (res.body.progress != "complete") {
                    console.log("The status of your file is " + res.body.status);
                    console.log(" Please wait while we finish Translating your file");
                } else {
                    console.log("****" + res.body.status);
                    console.log("****" + res.body.progress);
                    resolve(res);
                }
            }, function (err) {
                reject(err);
            }
        )
    });
}
  1. dmSample.js の最後にあるメインルーチンに変換処理と変換終了を検出するマニフェストの取得する青字部分の処理を追記します。もともと記述されている deleteFile() の呼び出しは削除します。
/** * Create an access token and run the API calls. */
oAuth2TwoLegged.authenticate().then(function (credentials) {
    console.log("**** Got Credentials", credentials);
    createBucketIfNotExist(BUCKET_KEY).then(
        function (createBucketRes) {
            console.log("**** Create bucket if not exist response:", createBucketRes.body);
            getBuckets().then(function (getBucketsRes) {
                console.log("**** Get all buckets response:");
                var bucketsArray = getBucketsRes.body.items;
                bucketsArray.map(function (currentBucket) {
                    console.log(currentBucket.bucketKey);
                })
            }, function (err) {
                console.error(err);
            });
            uploadFile(BUCKET_KEY, FILE_PATH, FILE_NAME).then(function (uploadRes) {
                console.log("**** Upload file response:", uploadRes.body);
                deleteFile(BUCKET_KEY, FILE_NAME).then(function (deleteRes) {
                    console.log("**** Delete file response status code:", deleteRes.statusCode);
                }, defaultHandleError);

                var objectId = uploadRes.body.objectId;
                console.log("objectId:", objectId);
                var urn = base64encode(objectId);
                console.log("urn:", urn);
                translateFile(urn).then(function (translateRes) {
                    manifestFile(urn).then(function () {
                        console.log("**** Your File is ready for viewing");
                    }, defaultHandleError)
                }, defaultHandleError);
            }, defaultHandleError);
        }, defaultHandleError);
}, defaultHandleError);
  1. Node.js command prompt 上で samples ディレクトリに移動して、node dmSample.js と入力して処理を実行します。コード中の console.log() で指定した情報が表示されるはずなので、この中に Access Token とエンコードされた URN(ドキュメント ID)が含まれることを確認してください。
  2. 次の HTML ファイルをダウンロード、解凍して、accessToken パラメータに Access Token を、urn パラメータに SVF ファイル変換が終了したデザイン ファイルの URN を与えてみてください。
  • Viewer.htmの後に ? でパラメータを接続して、パラメータ間は & で統合します。例えば、Access Token が eyJhbGciOiJIUzI1NiIsImtpZCI6Imp3dF9zeW1tZXRyaWNfa2V5In0.eyJjbGllbnRfaWQiOiJWMlpQcmNaR242eWVqTXRSNzZHM2lMR2pxRng、ドキュメント ID(URN)が dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZnBkLWphcGFuLXNhbXBsZS1idWNrZXQvQmlrZSUyMGZyYW1lLmYzZA== の場合、C:Forge-Workshop フォルダにダウンロード済みの Viewer.htm で表示するには、次のような指定で表示するドキュメントを引き渡すことが出来ます。

file:///C:/Forge-Workshop/viewer.htm?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6Imp3dF9zeW1tZXRyaWNfa2V5In0.eyJjbGllbnRfaWQiOiJWMlpQcmNaR242eWVqTXRSNzZHM2lMR2pxRng&urn=dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZnBkLWphcGFuLXNhbXBsZS1idWNrZXQvQmlrZSUyMGZyYW1lLmYzZA==

A 3D model of a chair with a yellow seat and backrest, supported by a silver metal frame.
  • URL パラメータとして Access Token を渡した場合、Web ブラウザが持つ CORS(Cross-Origin Resource Sharing)  を抑止するセキュリティ上の制限によって、表示が出来ない場合があります(ブラウザ依存)。Google Chrome の場合には、No ‘Access-Control-Allow-Origin’ header is present on the requested resource. 等のエラーが発生してしまいますので、Chrome の起動ショートカットにパラメータ、–disable-web-security –user-data-dir、または、–allow-file-access-from-files –allow-file-access –allow-cross-origin-auth-prompt を指定することで、このセキュリティ機能を無効化して開発時のテストをおこなうことが出来ます。もちろん、一般利用時には、この設定での Chrome 起動はお勧めしません。ご注意ください。

Screenshot of Google Chrome properties window showing CORS settings with command line options to disable web security.

ここまでの実装で、アップロードしたデザインファイルを変換して Forge Viewer に表示することが出来るはずです。このコードを拡張することで、実際の運用で利用する処理を実装してみてください。現実には dmSample.js と連携する HTML ファイルを定義して、ボタンなどを配置し、ユーザ アクションをトリガに処理をすすめるのが一般的と思います。

Viewer 表示の自動化を書いたブログ記事も 付録 として記載していますので、必要に応じてご確認ください。

By Toshiaki Isezaki 

Discover more from Autodesk Developer Blog

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

Continue reading