How to improve Forge Viewer performance in local environment - autodesk-forge

I am trying to load a local model, and I am using the following load option:
option = {
"env": "Local",
"document": "0/0.svf",
"useADP": false,
"useConsolidation": true,
"consolidationMemoryLimit": 104857600,
"createWireframe": true,
"bvhOptions": {
"frags_per_leaf_node": 512,
"max_polys_per_node": 100000
},
"isAEC": true,
"disablePrecomputedNodeBoxes": true
}
var viewer = new Autodesk.Viewing.Private.GuiViewer3D(myViewerDiv, optionObject);
Autodesk.Viewing.Initializer(options, function () {
viewer.start(options.document, options);
Viewing the model in local environment is significantly slower (lower FPS, less responsive) when compared to "AutodeskProduction" environment using the same setup. Is there any additional settings that can further improve the performance? Thanks.

I'd say among these options a fined-tuned combination of useConsolidation and consolidationMemoryLimit probably did the trick for you - see here for details:
const initializerOptions = {
useConsolidation: true,
consolidationMemoryLimit: 150 * 1024 * 1024
}
However the balancing act here is when you have large numbers of BVH (as can be noticed in the BVHoptions) that might neutralize the performance gain so you'd want to play up to those factors.

Related

next-pwa runtimecaching does not produce strategies

I start using next-pwa and the basic setup worked like a charm. Now it want to play with the runtime caching option, which does not work for me:
My next.config.js includes the standard cache entries plus a custom one that should use the strategy StaleWhileRevalidate for each request going to /api/todoitem:
const withPWA = require("next-pwa");
const defaultRuntimeCaching = require("next-pwa/cache");
module.exports = withPWA({
reactStrictMode: true,
pwa: {
dest: "public",
disable: false, // disable PWA
register: true,
skipWaiting: true,
runtimeCaching: [
{
urlPattern: /\/api\/todoitem/,
method: "GET",
handler: "StaleWhileRevalidate",
options: {
cacheName: "todoApp-api",
expiration: {
maxEntries: 64,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
...defaultRuntimeCaching,
],
},
});
Restart npm run dev fire up the browser -> fetch GET /api/todoitem -> and console.log tells me
workbox Network request for '/api/todoitem' returned a response with status '200'.
workbox Using NetworkOnly to respond to '/api/todoitem'
I tried a number of combinations of regexes, including defaultRuntimeCaching before or after my runtimeCache entry to no avail.
Any hints to get custom runtimeCache rules working would be greatly appreciated.
next.js 12.0.7
next-pwa 5.4.4
node.js v14.18.2
After some research I found:
In development mode, next-pwa creates a service worker that disables caching. It even tells me so on the console ;-):
[PWA] Build in development mode, cache and precache
are mostly disabled. This means offline support is
disabled, but you can continue developing other
functions in service worker.
When building the app via next build it creates a service worker that uses my custom rules and when starting the app next start the rules seem to work.
A bit hard to debug, so I tried to set mode: "production" on my developer machine but then for some reason the service worker gets rebuilt at every other request which brings the app to a grinding halt.

How to record http requests with Google Chrome extension and persist them

I want to create a Chrome extension, that records HTTP requests (to a pre-defined host) and persists them as a list in local storage so when I call a particular website again the list will be extended.
I want to go with Manifest v3 to make the extension "ready for the future". I created a background script to trigger the request that currently puts all the details into local storage like that (currently this is redundant for demonstration purposes, I also tried it seperated):
chrome.webRequest.onBeforeRequest.addListener(details => {
var urls = [];
chrome.storage.local.get(['data'], function(data){
urls = data.urls;
});
chrome.scripting.executeScript(
{
target: {tabId: details.tabId},
func: recordClick,
args: [details, urls]
},
() => {
urls.push(details);
console.log(urls.length);
chrome.storage.local.set({urls: urls});
});
}, {
urls: ['<all_urls>']
});
There's another function called recordClick() that does the same as in the callback:
function recordClick(details, urls) {
urls.push(details.url);
chrome.storage.local.set({urls: urls});
}
I tried several ways on where to load and save the result but none of them work. When I load the previous urls within the onBeforeRequest trigger, urls is not global and not known within the callback. When I put it outside the trigger definition, it's not reading the storage in realtime. I also tried to load the urls in a content script, loaded at "Document start". I tried to load the urls in the backend script at the top, and so on.
Seems like I have a timing problem: The trigger always loads an empty list or the variable is not global. I'm not able to extend the list. No matter where I put the storage functions.
Is my plan feasable at all? What am I'm doing wrong?
thanks!
Since chrome.storage.local.get is asynchronous, you should move chrome.scripting.executeScript into the callback of it.
onComplete may be suitable for your purpose, instead of onBeforeRequest.
chrome.webRequest.onBeforeRequest.addListener(details => {
chrome.storage.local.get('urls', function(data){
let urls = [];
if( data.urls ) {
urls = data.urls;
}
urls.push(details);
chrome.storage.local.set({urls: urls}, function() {
console.log('Value is set to ');
console.log(urls);
});
chrome.scripting.executeScript( {
target: {tabId: details.tabId},
func: function(details, urls){ console.log("executed script") },
args: [details, urls]
},
() => {
console.log("injected")
});
});
},
{ urls: ['<all_urls>'] }
);

Autodesk Viewer memory leak

I have some big memory issues in an angular/typescript app using the forge viewer (v6.6.1). This has also been discussed before: Severe memory leaks in the Autodesk Forge viewer on devices
Whenever we close the component or route to an other page we destroy the current created viewer. For this I use the function viewer.finish(); However it seems that it doesn't release any GPU memory. This is most notable when using models that contain textures. The problem is that after a few times opening this in our app it will crash as to much gpu memory is used.
To see the memory usage buildup I used chrome://tracing/ (using the record category memory-infra).
Here are some screenshots where you can see the memory buildup.
Initial initialisation of the page
after returning to this page after closing it
after returning to this page after closing it a third time
As you can see the memory under textures builds up quite fast. And this is just a light model that we use. With some models is build up in steps of over 250MB.
Here is the part of component code that does the work. I also provided a link to a minimal angular project on github that you can run. When you start the app you can use the toggle button to create / destroy the component and trigger the issue.
public viewer;
public options;
public url = 'MODEL-YOUR-URL-HERE';
#ViewChild('viewer')
public viewerContainer: any;
constructor() { }
ngOnInit() {
this.options = {
env: 'Local',
useADP: false,
language: 'en',
};
Autodesk.Viewing.Initializer(this.options, () => {
this.onEnvInitialized();
});
}
public onEnvInitialized() {
this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(this.viewerContainer.nativeElement, {});
this.viewer.initialize();
this.viewer.loadModel( decodeURI(this.url), {}, () => { }, (aErrorCode) => { } );
}
ngOnDestroy() {
this.viewer.finish();
this.viewer = null;
}
https://github.com/zedero/forge-angular-memory-issue
Engineering's final recommendations are to wait for Viewer v7.0 which is set to release for general access in a few weeks time with multiple bug fixes & improvements on memory management.
In the meantime see if you have any event listeners/custom extensions that might be holding on to references to nodes etc - remove/unload these and see if that helps.

chrome.storage.sync.set won't update the storage anymore

I am using chrome.storage.sync for some of my chrome extensions, great tool!
But I have an issue now, after updating the storage like 10 times. It blocks and does not update anymore... No error or anything so I do not know where the problem is.
FYI: I still have space in the storage.
The code:
Storage.get_all = function(callback) {
STORAGE_SYNC.get('key', function(items) {
callback(items.gifs_v2);
});
};
Storage.post = function(id, item, callback) {
var THIS = this;
THIS.get_all(function(items) {
if(items) {
items[id] = item;
STORAGE_SYNC.set({'key': items}, callback);
} else {
THIS.post_all({}, function() {
THIS.post(id, item, callback);
});
}
})
};
There are several quotas published in the official documentation. Look it up. You probably run out of one of them. Remember that sync also goes into google's sync servers so abusing them will block you for a while. If you dont need to sync among devices use the regular local storage instead of sync.

In Google Chrome, what is the extension api for changing the UserAgent and Device Metrics?

In Google Chrome, when viewing the developer tools, in the bottom right there is a Gear Icon that opens an additional Settings popup. One of the pages in the Settings popup is Overrides that contains User Agent and Device Metrics settings. I am trying to find the extensions API that is able to set those values programatically. Does such an API exist?
I've looked the main apis, and the experimental apis , but can't seem to find anything.
The sample for devtools.panels in the code samples doesn't seem to indicate how to 'explore' the existing devpanels either.
Specifically I'm trying to build simple extension available from a context menu in a Browser Action. It would act like a user-agent switcher, offering choices from the same list in the Settings popup, and automatically sets the Device Metrics to the values of the selected Agent. e.g. 640x960 for IPhone 4.
Any leads on how to programatically access the Settings popup
Some of the advanced features offered by the Developer tools can be accessed through the chrome.debugger API (add the debugger permission to the manifest file).
The User agent can be changed using the Network.setUserAgentOverride command:
// Assume: tabId is the ID of the tab whose UA you want to change
// It can be obtained via several APIs, including but not limited to
// chrome.tabs, chrome.pageAction, chrome.browserAction, ...
// 1. Attach the debugger
var protocolVersion = '1.0';
chrome.debugger.attach({
tabId: tabId
}, protocolVersion, function() {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
return;
}
// 2. Debugger attached, now prepare for modifying the UA
chrome.debugger.sendCommand({
tabId: tabId
}, "Network.enable", {}, function(response) {
// Possible response: response.id / response.error
// 3. Change the User Agent string!
chrome.debugger.sendCommand({
tabId: tabId
}, "Network.setUserAgentOverride", {
userAgent: 'Whatever you want'
}, function(response) {
// Possible response: response.id / response.error
// 4. Now detach the debugger (this restores the UA string).
chrome.debugger.detach({tabId: tabId});
});
});
});
The official documentation for the supported protocols and commands can be found here. As of writing, there's no documentation for changing the Device metrics. However, after digging in Chromium's source code, I discovered a file which defined all currently known commands:
chromium/src/out/Debug/obj/gen/webcore/InspectorBackendDispatcher.cpp
When I look through the list of definitions, I find Page.setDeviceMetricsOverride. This phrase seems to match our expectations, so let's search further, to find out how to use it:
Chromium code search: "Page.setDeviceMetricsOverride"
This yields "chromium/src/out/Release/obj/gen/devtools/DevTools.js" (thousands of lines). Somewhere, there's a line defining (beautified):
InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{
"name": "width",
"type": "number",
"optional": false
}, {
"name": "height",
"type": "number",
"optional": false
}, {
"name": "fontScaleFactor",
"type": "number",
"optional": false
}, {
"name": "fitWindow",
"type": "boolean",
"optional": false
}], []);
How to read this? Well, use your imagination:
chrome.debugger.sendCommand({
tabId: tabId
}, "Page.setDeviceMetricsOverride",{
width: 1000,
height: 1000,
fontScaleFactor: 1,
fitWindow: false
}, function(response) {
// ...
});
I've tested this in Chrome 25 using protocol version 1.0, and it works: The tab being debugged is resized. Yay!