如何在 Autodesk Forge 中动态更新 THREE.js PointCloud 覆盖

Posted

技术标签:

【中文标题】如何在 Autodesk Forge 中动态更新 THREE.js PointCloud 覆盖【英文标题】:How to dynamically update THREE.js PointCloud overlay in Autodesk Forge 【发布时间】:2019-12-05 07:58:21 【问题描述】:

我正在为 Autodesk forge 开发一个标记扩展。我希望能够单击一个位置,并将标记动态显示为点云。

下面是扩展的加载函数。我第一次加载点云时它可以工作,但是当我尝试向几何体添加顶点并渲染它时,新点不会出现。但是,光线投射器能够检测到该点。我知道这一点,因为当我第二次单击某个位置时,我收到一条日志,告诉我光线投射器截获了点云(即使该点未在屏幕上呈现)。

ClickableMarkup.prototype.load = function () 
    const self = this;

    /* Initizialize */
    console.log('Start loading clickableMarkup extension');
    this.camera = this.viewer.navigation.getCamera(); // Save camera instance
    console.log(this.camera);
    this.initCameraInfo(); // Populate cameraInfo array
    this.overlayManager.addScene(this.sceneName); // Add scene to overlay manager
    this.scene = this.viewer.impl.overlayScenes[this.sceneName].scene; // Save reference to the scene

    /* Create pointCloud */
    this.geometry = new THREE.Geometry();
    this.cameraInfo.forEach( function(e) 
            // console.log(`   > add $e.position`)
            self.geometry.vertices.push(e.position);
        
    );
    this.geometry.computeBoundingBox();
    // const material = new THREE.PointCloudMaterial(  size: 50, color: 0Xff0000, opacity: 100, sizeAttenuation: true  );
    const texture = THREE.ImageUtils.loadTexture(this.pointCloudTextureURL);
    this.material = new THREE.ShaderMaterial(
        vertexColors: THREE.VertexColors,
        opacity: this.prefs.POINT_CLOUD_OPACITY,
        fragmentShader: this.fragmentShader,
        vertexShader: this.vertexShader,
        depthWrite: true,
        depthTest: true,
        uniforms: 
            size: type: "f", value: self.size,
            tex: type: "t", value: texture
        
    );
    this.points = new THREE.PointCloud( this.geometry, this.material );

    /* Add the pointcloud to the scene */
    this.overlayManager.addMesh(this.points, this.sceneName); /* >>> THIS WORKS  SO IT RENDERS THE POINTCLOUD AT THE BEGINNING OF LAOD <<< */

    /* Set up event listeners */
    document.addEventListener('click', event => 
        event.preventDefault();

        this.setRaycasterIntersects(event); // Fill this.intersects with pointcloud indices that are currently selected

        if (this.intersects.length > 0) 
            console.log('Raycaster hit index: ' + this.hitIndex + JSON.stringify(this.intersects[0]));
            this.setCameraView(this.hitIndex);
         else 
            /*  >>>>  THE PROBLEM IS HERE - IT DOESN'T RENDER THE NEW POINTCLOUD POINTS <<<< */
            const mousePos = this.screenToWorld(event);
            if (mousePos)  // Only add point to scene if the user clicked on the building
                const vertexMousePos = new THREE.Vector3(mousePos.x, mousePos.y, mousePos.z);
                this.geometry.vertices.push(vertexMousePos);
                this.geometry.verticesNeedUpdate = true;
                this.geometry.computeBoundingBox();

                this.points = new THREE.PointCloud(this.geometry, this.material);
                this.overlayManager.addMesh(this.points, this.sceneName);
                this.viewer.impl.invalidate(true); // Render the scene again
            
        

    , false);

    console.log('ClickableMarkup extension is loaded!');
    return true;
;

如何渲染新的点云顶点?

【问题讨论】:

【参考方案1】:

看起来有问题的代码中可能有错字。

this.overlayManager.addMesh(this.points, 'this.sceneName');

应该是

this.overlayManager.addMesh(this.points, this.sceneName);

【讨论】:

我修正了错字,但问题仍然存在 在某处可以找到完整的代码吗?或者,您能否制作一个简单的查看器扩展程序来重现问题并在此处分享? 我在github.com/anjalee-narenthiren/PointcloudBug 上传了一个简单的项目到github。运行 index.html 文件。您必须使用 postman 获取访问密钥并更新 main.js 第 33 行的 accessToken 变量。

以上是关于如何在 Autodesk Forge 中动态更新 THREE.js PointCloud 覆盖的主要内容,如果未能解决你的问题,请参考以下文章

Autodesk Forge 中自定义模型的动态位置

如何在 Autodesk forge 查看器 setTheming 颜色方法中使用十六进制颜色代码?

Autodesk Forge 检索/更新自定义属性

如何在 Forge Viewer 中激活“Autodesk.MemoryLimited”扩展?

Autodesk Forge API - 补丁项输入错误

Autodesk forge 在 Forge Configurator 发明者中自定义转换对象