Forge Viewer には Model Derivative API で SVF 変換したデザインをストリーミング配信を使って表示することが出来ます。通常、表示は変換に使用したシードファイル(CAD 毎に異なる返還前のデザイン ファイル)単位で Basic Viewer や Basic Application などの方法で実装することになります。ただ、ビューア上でコンフィギュレータなど、単一のシードファイルにないモデルを Forge Viewer の同一シーンに表示させたいことがあるかもしれません。
Forge Viewer JavaScript ライブラリでは、そのような用途に Viewer3D.LoadModel メソッドを用意しています。もちろん、この方法で表示させたいモデルも、事前に Model Derivative API で SVF 変換しておく必要があります。
実際の使用では、Autodesk.Viewing.GEOMETRY_LOADED_EVENT イベントを登録、イベントを検出して、カンバス内に Basic Viewer や Basic Application などでメインとなるモデルを表示、ジオメトリのロード完了時に呼び出されるコールバック関数内に LoadModel() を記載する事になります。最初のパラメータには、カンバス上に(2つめ以降に)表示させたいモデルの URN を指定します。この URN 指定では、メインモデルを表示で指定した Base64 エンコードしたシードファイルの URN ではなく、変換済の SVF を示す URN を直接指定します。分かりやすくご紹介するなら、シード ファイルを変換した際に作成されるマニフェストにある SVF を指し示す URN 文字列となります。
ここで Base64 エンコードしたシードファイルの URN を指定してしまうと、Viewer コード実行時に次のエラーが表示されるので分かりやすいはずです。
上記例だと、指定すべき値は "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZnBkLWphcGFuLWF2cGc1ZmdyaDVxYnBvOGhrMTV
sc3p6ZzhkcmZrbnJvdXdtd2QwcDhsbXNlMzJwN29qb3h6NXB6b251dGktN2cvVG93ZXItTm9Cb3VuZG
FyeS5ud2Q" ではなく、"urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZnBkL
WphcGFuLWF2cGc1ZmdyaDVxYnBvOGhrMTVsc3p6ZzhkcmZrbnJvdXdtd2QwcDhsbXNlMzJwN29qb
3h6NXB6b251dGktN2cvQnVpbGRpbmctTm9Cb3VuZGFyeS5ud2Q/output/0/0.svf" となります。
LoadModel() で重要になるのは、各モデルの位置合わせです。一般に、CAD データでは尺度という概念を持ち、用途によっては、更に緯度経度といった位置情報も持ち合わせています。ただし、three.js をベースにする Forge Viewer には、そのような概念はありません。
例えば、Navisworks 内で複数のモデルをインポート、位置合わせしたと仮定します。
この状態で、メインモデル、サブモデル1、サブモデル2単位に個別に NWD ファイルで出力、Model Derivative API で変換して LoadModel() で配置した場合、表示されたモデルが重なってしまったり、モデルの大きさが変わってしまう結果になってしまいます。
Forge Viewer は、ロードするモデルの境界ボックスの中心をカンバス原点に合わせて配置・表示します。つまり、モデル毎に設定される原点が異なるため、上記のように意図しない結果になってしまいます。
ここで必要になるのが、2 つめの options パラメータで指定する Global Offset の値です。Global Offset は、この配置時に、どの程度オフセット(ずらして)配置するかを指定します。前述のように、Navisworks のシーン内で相対位置が決まっている場合には、LoadModel() でメインモデルと同じ Global Offset 値を継承して配置すれば、相対位置を維持したまま表示をおこなうことが可能です。
...
// Intialize Viewer var options = {}; options.env = "AutodeskProduction"; options.accessToken = getToken(); options.document = "urn:" + urn; options.language = "ja"; var viewerElement = document.getElementById('viewer3d'); _viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerElement, {}); // With default UI Autodesk.Viewing.Initializer(options, function () { _viewer.initialize(); _viewer.setTheme("light-theme"); loadDocument(_viewer, options.document); _viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, onViewerGeometryLoaded); }); } function onViewerGeometryLoaded(event) { var urn = "urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZnBkLWphcGFuLWF2cGc1ZmdyaDVxYnBvOGhrMTVsc3p6ZzhkcmZrbnJvdXdtd2QwcDhsbXNlMzJwN29qb3h6NXB6b251dGktN2cvQnVpbGRpbmctTm9Cb3VuZGFyeS5ud2Q/output/0/0.svf"; _viewer.loadModel(urn, { globalOffset: event.model.getData().globalOffset }); urn = "urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZnBkLWphcGFuLWF2cGc1ZmdyaDVxYnBvOGhrMTVsc3p6ZzhkcmZrbnJvdXdtd2QwcDhsbXNlMzJwN29qb3h6NXB6b251dGktN2cvVG93ZXItTm9Cb3VuZGFyeS5ud2Q/output/0/0.svf"; _viewer.loadModel(urn, { globalOffset: event.model.getData().globalOffset }); _viewer.removeEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, onViewerGeometryLoaded); }
...
SVF 変換間に同一シーンで位置合わせをおこなっていない場合には、three.js を併用したマトリックス変換をモデル挿入後に実施し、位置や大きさを変化させる方法もあります。新しい Forge Viewer チュートリアル改訂版 ~ その2 でご紹介している Viewing.Extension.Transform.min.js ファイルで定義された Extension が参考になるかと思います。
同じモデル群に対して位置合わせ等をテストする場合には、コードを修正しても表示に反映されず、期待した結果にならない場合があります。コードの変更による位置等の変化が確実な場面では、前回実行した内容がブラウザ キャッシュに残っていて、適切に反映されない原因になっていることもあります。ブラウザ キャッシュをクリアすると問題が解消することがありますのでお試しください。
なお、英語ブログになってしまいますが、併せて次の記事もご確認いただくこともお勧めします。
Aggregating multiple models in the Viewer
Preparing your viewing application for multi-model workflows
Preparing your viewing application for multi-model workflows - Part 2: Model Loader
By Toshiaki Isezaki
コメント
コメントフィードを購読すればディスカッションを追いかけることができます。