更新时间:2023-01-06 13:06:47
Based on the suggestion of Zhong Wu in another post, here is the final solution to select element which is under or inside another element. I created an Autodesk Forge viewer extension to use it easily.
///////////////////////////////////////////////////////////////////////////////
// InnerSelection viewer extension
// by Khoa Ho, December 2016
//
///////////////////////////////////////////////////////////////////////////////
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
Autodesk.ADN.Viewing.Extension.InnerSelection = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _self = this;
var _container = viewer.canvas.parentElement;
var _renderer = viewer.impl.renderer();
var _instanceTree = viewer.model.getData().instanceTree;
var _fragmentList = viewer.model.getFragmentList();
var _eventSelectionChanged = false;
var _viewport;
var _outerDbId;
_self.load = function () {
_container.addEventListener('mousedown',
onMouseDown);
viewer.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
onItemSelected);
console.log('Autodesk.ADN.Viewing.Extension.InnerSelection loaded');
return true;
};
_self.unload = function () {
_container.removeEventListener('mousedown',
onMouseDown);
viewer.removeEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
onItemSelected);
console.log('Autodesk.ADN.Viewing.Extension.InnerSelection unloaded');
return true;
};
function onMouseDown(e) {
var viewport = viewer.impl.clientToViewport(e.canvasX, e.canvasY);
_viewport = viewport; // Keep this viewport to use in onItemSelected()
var dbId = _renderer.idAtPixel(viewport.x, viewport.y);
if (_outerDbId == dbId) {
_outerDbId = -1;
// Deselect everything
viewer.select();
} else {
_outerDbId = dbId;
// Hide outer element temporarily to allow picking its behind element
viewer.hideById(dbId);
_eventSelectionChanged = true;
}
viewer.impl.sceneUpdated(true);
}
function onItemSelected(e) {
if (_eventSelectionChanged) {
// Prevent self looping on selection
_eventSelectionChanged = false;
// Show outer element back
viewer.show(_outerDbId);
// Get inner element Id after the outer element
// was just hidden on mouse down event
var innerDbId = _renderer.idAtPixel(_viewport.x, _viewport.y);
if (innerDbId > -1) {
// Select the inner element when it is found
viewer.select(innerDbId);
console.debug("Selected inner Id: " + innerDbId);
} else if (_outerDbId > -1) {
// Select the outer element if the inner element is not found
viewer.select(_outerDbId);
console.debug("Selected outer Id: " + _outerDbId);
}
}
}
};
Autodesk.ADN.Viewing.Extension.InnerSelection.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.InnerSelection.prototype.constructor =
Autodesk.ADN.Viewing.Extension.InnerSelection;
Autodesk.Viewing.theExtensionManager.registerExtension(
'Autodesk.ADN.Viewing.Extension.InnerSelection',
Autodesk.ADN.Viewing.Extension.InnerSelection);