Forge Viewer:如何将任意客户点转换为世界点

Posted

技术标签:

【中文标题】Forge Viewer:如何将任意客户点转换为世界点【英文标题】:Forge Viewer: How to convert arbitrary client point to world point 【发布时间】:2019-04-29 21:03:44 【问题描述】:

我现在正在努力解决一些问题。我有一个使用ToolInterface 的扩展实现查看器的页面,以便我可以捕获鼠标事件。我成功获取了鼠标事件,并且可以检索返回的 x、y 坐标。

我想做的是获取该点的世界 (x, y, z) 坐标。我尝试使用Viewer3D.clientToWorld 函数,但无论该点是否超过几何形状,它总是返回null

我也尝试使用ViewingUtilites.getHitPoint 函数来获取世界(x、y、z)坐标,但它也总是返回null。我尝试使用事件返回的 (x, y) 并进行标准化。

所以我的问题是,如何从 Forge 查看器中的客户端 (x, y) 坐标获取世界 (x, y, z) 坐标?

谢谢!

**** 编辑:下面添加的代码

MyViewerTool = function (viewer, options) 

Autodesk.Viewing.Extension.call(this, viewer, options);

var _self = this;
var _viewer = viewer;

// ....
_self.tool = null;

function MyViewerTool(viewer, toolName) 

    function normalizePoint(screenPoint) 
        const viewport = _viewer.navigation.getScreenViewport();
        var n = 
            x: (screenPoint.x - viewport.left) / viewport.width,
            y: (screenPoint.y - viewport.height) / viewport.height
        

        return n;
    

    this.handleSingleClick = function(event, button) 
        console.log(event);
        const normalizedPoint = normalizePoint( x: event.clientX, y: event.clientY );
        const worldPoint = _viewer.utilities.getHitPoint(normalizedPoint.x, normalizedPoint.y);
        console.log(worldPoint);
        return false;
    ;

    // ...

// other code that just does the register/load/etc
// this does load in the viewer as I am able to
// set a breakpoint above and I see what looks like
// valid point data.
// my first try used the clientToWorld(...)
// using the same event data passed in handleSingleClick (above).
//

【问题讨论】:

您可以粘贴您的代码以便我们查看吗?调用 clientToWorld 时是否使用了画布坐标? this.viewer.clientToWorld(event.canvasX, event.canvasY, true) 【参考方案1】:

您可以使用查看器的clientToWorld(x, y, ignoreTransparent) 函数。

一个示例实现:

let canvas = this.viewer.canvas;
let drag = false;

canvas.addEventListener('mousedown', () => drag = false);
canvas.addEventListener('mousemove', () => drag = true);
canvas.addEventListener('mouseup', (evt) =>         
    if (!drag) 
        var hitTest = this.viewer.clientToWorld(evt.offsetX, evt.offsetY, true);
        if (hitTest)                    
            let x = hitTest.point.x;
            let y = hitTest.point.y;
            let z = hitTest.point.z;
        
    
);    

注意 offsetX 和 offsetY 的使用。

【讨论】:

感谢 Johannes,只要我选择几何,offsetXoffsetY 就是缺失的部分。这应该是我现在所需要的。您知道是否有一种方法可以通过在查看器中选择空间点来转换到世界? Utilities.getHitPoint 没用。 试试worldToClient。并注意在官方示例中 canvasX 和 canvasY 优于偏移量。请参阅我之前对您的问题的评论。 感谢@BryanHuang,我之前使用过画布坐标(请参阅原始帖子),但无论是否选择几何图形,它都会返回空值。一旦我切换到偏移,它就起作用了。

以上是关于Forge Viewer:如何将任意客户点转换为世界点的主要内容,如果未能解决你的问题,请参考以下文章

Autodesk Forge Viewer 在本地服务器上存储文件?

如何将 Autodesk 模型衍生 API 元数据中的 objectids 与 Forge Viewer 模型 dbids 匹配?

如何在 Autodesk Forge Viewer 中嵌入 pdf?

如何将 Autodesk Forge Viewer 嵌入移动应用程序?

如何将 BIM360 PushPin Extension 与 Forge Viewer 一起使用?

如何将 XML 从 Naviswork 导出到 Forge Viewer