无头镀铬中的Autodesk锻造查看器,CONTEXT_LOST_WEBGL

时间:2018-05-17 18:39:53

标签: selenium-chromedriver autodesk-viewer google-chrome-headless

我尝试使用无头Chrome(在Win10上使用v66,使用C#)从锻造autodesk查看器中的3D模型中获取一系列屏幕截图。

我面临的问题是,一旦模型加载,我将相机设置到第一个位置,截取屏幕截图,然后尝试将相机设置到下一个屏幕截图的下一个位置。一旦我尝试了(稍后在初始加载时设置相机位置),webgl上下文就会丢失。

我对WebGL / swiftshaders /等知之甚少,但令我感到沮丧的是,当我在加载后直接定位相机时,它确实有效。 (IE,解决方法是为每个摄像机视图生成一个单独的无头会话,但由于几何体的加载需要20秒或更长时间,这不是首选)

所以,这个:

viewerApp.myCurrentViewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
function () {
    _viewer = viewerApp.myCurrentViewer;
    SetPerspective();
    SetCamera(cams[0].position, cams[0].target);//no probs here
    document.getElementById('MyViewerDiv').classList.add("geometry-loaded");       
 });

工作(相机定位),但是当我稍后执行javascript函数(使用driver.ExecuteScript($"SetCamera({JsonConvert.SerializeObject(target.Value.Position)},{JsonConvert.SerializeObject(target.Value.Target)});");或页面本身超时时),它会输出WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost

当我使用较小的模型时,一切正常。因此,我认为我理解原因是内存/处理消耗太多,但为什么它一直在工作呢?

看着资源监视器,我不相信消费实际上有问题,我的笔记本电脑应该有能力(i7HQ7700,gtx1050,16gbRam)我试图摆弄Chrome的一些GPU和GL标志,但无济于事。我怀疑GPU没有被使用(我发现一些帖子实际上可以用于无头...)另外,伪造查看器输出使用的GPU内存,但这可能只是日志消息:

Starting ChromeDriver 2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb) on port 62676
Only local connections are allowed.
[0517/203535.902:ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context.

DevTools listening on ws://127.0.0.1:12556/devtools/browser/5b66c120-dc64-4211-a207-ac97152ace9a
---some ssl future warnings---
[0517/203540.524:INFO:CONSOLE(2)] "THREE.WebGLRenderer", source: https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js (2)
[0517/203543.074:INFO:CONSOLE(0)] "[.Offscreen-For-WebGL-00000237DECBB270]RENDER WARNING: there is no texture bound to the unit 0", source: http://localhost:8881/Content/Screenshot.html
[0517/203543.074:INFO:CONSOLE(0)] "[.Offscreen-For-WebGL-00000237DECBB270]RENDER WARNING: there is no texture bound to the unit 0", source: http://localhost:8881/Content/Screenshot.html
[0517/203552.280:INFO:CONSOLE(2)] "Total geometry size: 8.434013366699219 MB", source: https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js (2)
[0517/203552.281:INFO:CONSOLE(2)] "Number of meshes: 2909", source: https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js (2)
[0517/203552.281:INFO:CONSOLE(2)] "Num Meshes on GPU: 2908", source: https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js (2)
[0517/203552.281:INFO:CONSOLE(2)] "Net GPU geom memory used: 7494392", source: https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js (2)
[0517/203558.143:INFO:CONSOLE(0)] "WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost", source: http://localhost:8881/Content/Screenshot.html

要完成,运行没有--headless标志的相同程序,工作正常,所以我猜代码本身就可以了。

有没有办法增加允许的资源或其他什么?

(SetCamera的代码)

        function SetCamera(newPos, newTarget) {
        nav = nav || viewerApp.myCurrentViewer.navigation;

        nav.setPosition(newPos);
        nav.setTarget(newTarget);
        nav.orientCameraUp();
    }

编辑:测试用例(目前在测试网站上,因此我们会在某个时候删除)

EDIT2:运行以下代码的结果

的NodeJS:

try {

    const URN = '';
    const Token = '';

    (async () => {
        const puppeteer = require('puppeteer');
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        console.log('browsing');

        await page.goto('https://rogerintelligentcloud.azurewebsites.net/test?urn=' + URN + '&token=' + Token);
        //replace autodeskURN and token to point to your model

        console.log("waiting");
        await page.mainFrame().waitForSelector(
            '.geometry-loaded', {
                timeout: 60000
            });

        await takescreen(page, 'nodetest1');
        await takescreen(page, 'nodetest2');
        await takescreen(page, 'nodetest3');
        await takescreen(page, 'nodetest4');
        await takescreen(page, 'nodetest5');
        await takescreen(page, 'nodetest6');    

        await page.evaluate("Test();");

        await takescreen(page, 'nodetest11');
        await takescreen(page, 'nodetest12');
        await takescreen(page, 'nodetest13');
        await takescreen(page, 'nodetest14');
        await takescreen(page, 'nodetest15');
        await takescreen(page, 'nodetest16');        

        await browser.close();
    })();
} catch (e) {
    console.log(e);
}

async function takescreen(page, name){
    await page.screenshot({
        path: 'c:\\temp\\'+name+'.png'
    });
}

Result of code

1 个答案:

答案 0 :(得分:1)

我没有看到与您的代码段和WebGL模型显示的任何rme_advanced_sample_project.rvt相关错误消息,我唯一能看到的是page.delay is not defined。以下是我的测试代码,您可以通过代码段和Philippe的forge-viewer-headless演示进行修改。如果我错过了什么,请好好指出。感谢〜

import puppeteer from 'puppeteer'
import 'babel-polyfill'
import path from 'path'
import os from 'os';

try {
    const URN = 'YOUR_URN';
    const Token = 'YOUR_TOKEN';

    (async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto(`https://rogerintelligentcloud.azurewebsites.net/test?urn=${ URN }&token=${ Token }`);
    //replace autodeskURN and token to point to your model

        await page.mainFrame().waitForSelector(
            '.geometry-loaded', {
                timeout: 60000
            });

        await delay(3000);

        await page.screenshot({
          path: path.join( os.tmpdir(), 'nodetest.png' )
        })


        await page.evaluate("Test();");
        await page.evaluate("Test();");
        await page.evaluate("Test();");
        await page.evaluate("Test();");

        await delay(3000);

        const targetTxt = await page.evaluate(() => document.querySelector('body > :last-child').innerText );
        console.log( targetTxt );

        const targetLen = await page.evaluate(() => document.querySelectorAll('body > div:not(.box)').length );
        console.log( targetLen );

        await page.screenshot({
          path: path.join( os.tmpdir(), 'nodetest2.png' )
        })

        await browser.close();
    })();

    function delay(timeout) {
        return new Promise((resolve) => {
            setTimeout(resolve, timeout);
        });
    }
}
catch (e) {
    console.log(e);
}

我的测试结果中的快照:

  1. nodetest.png: enter image description here

  2. nodetest2.png: enter image description here

  3. 编辑2:

    使用您的代码进行测试,它在我的机器上运行正常。 enter image description here

    但是在我的环境中正确运行代码有一个变化。我修改了takescreen函数定义:

    function takescreen(page, name){
        return page.screenshot({
            path: 'c:\\temp\\'+name+'.png'
        });
    }