APS Viewer:境界ボックス

APS Viewer を使ったプログラミング作業をしていると、特定の要素の最小、あるいは最大位置を把握したい場合があります。そのような場面では、デスクトップで利用する CAD のアドイン開発でよく見られる境界ボックス(Bounding Box や Boundary Box)を、同様に取得、利用することが出来ます。

境界ボックスは、要素を囲む最小座標と最大座標を返すのが一般的です。APS Viewer では、現在、画面上でマウス左ボタンを使って選択している要素、またはモデル ブラウザなどで選択した「現在」の要素について、ViewingUtilities.getBoundingBox メソッドが Three.js の THREE.Box3 を返します。

Forge Viewer:オーバーレイとシーン ビルダー でご紹介した方法と、要素の選択時に発生する SELECTION_CHANGED_EVENT イベントを併用すると、Viewer 上に境界ボックスを描画して可視化するようなことも可能です。

     _viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, onSelectedByPick);
    …

    function onSelectedByPick(event) {
        let dbIdArray = event.dbIdArray;
        boundingBox(dbIdArray);
    }
    …
    function boundingBox(dbIdArray) {
        let bbox;
        if (dbIdArray.length > 0) {
            for (i = 0; i < dbIdArray.length; i++) {
                var node = dbIdArray[i];
                bbox = _viewer.utilities.getBoundingBox();
            }

            const min = JSON.parse(JSON.stringify(bbox.min));
            const max = JSON.parse(JSON.stringify(bbox.max));

            const xw = max.x – min.x;
            const yw = max.y – min.y;
            const zh = max.z – min.z;

            if (_viewer.overlays.hasScene('custom-scene')) {
                _viewer.overlays.removeMesh(_scene.mesh, 'custom-scene');
                _viewer.overlays.removeScene('custom-scene');
                _scene.material.dispose();
                _scene.geom.dispose();
                _scene = null;
            }

            _scene = new sceneMember(
                new THREE.BoxGeometry(xw, yw, zh),
                new THREE.MeshBasicMaterial({
                    color: 0x000000,
                    wireframe: true,
                    wireframeLinewidth: 1
                })
            );

            _scene.mesh = new THREE.Mesh(_scene.geom, _scene.material);
            _scene.mesh.position.set(min.x + xw / 2, min.y + yw / 2, min.z + zh / 2);
            if (!_viewer.overlays.hasScene('custom-scene')) {
                _viewer.overlays.addScene('custom-scene');
            }
            _viewer.overlays.addMesh(_scene.mesh, 'custom-scene');
        }
    }

APS Viewer v7 では、モデルブラウザ上の要素選択は要素自身を選択状態にしません。このため、画面上の選択操作時と異なり、SELECTION_CHANGED_EVENT イベントが発生しません。代わりに、モデルブラウザ上で選択した要素は、選択表示(孤立表示、独立表示、ISOLATE 表示)の状態に遷移します。

選択状態になる際には ISOLATE_EVENT イベントが発生するので、このイベントを使うと、モデルブラウザ上の選択を利用することも出来ます。

     _viewer.addEventListener(Autodesk.Viewing.ISOLATE_EVENT, onSelectedByMBrowser);
    …

    function onSelectedByMBrowser(event) {
        let dbIdArray = event.nodeIdArray;
        _viewer.select(dbIdArray); // force to be 'current'
        _viewer.clearSelection();    //
        boundingBox(dbIdArray);
    } 

この方法を使うと、POST job エンドポイントを generateMasterViews advanced オプションを指定して変換した Revit モデルに対して、部屋の境界ボックスを得ることも出来ます。

getBoundingBox メソッドは単一要素だけでなく、ノード全体の境界ボックスも返す点にご注意ください。[Shift] キーを押しながら、画面上で複数の要素を直接選択した場合も同様です。

By Toshiaki Isezaki


Comments

Leave a Reply

Discover more from Autodesk Developer Blog

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

Continue reading