how to use the .impl methods in forge viewer V7* - autodesk-forge

I have been using following .impl methods in V6*
viewerApp.getCurrentViewer().impl.invalidate
viewerApp.getCurrentViewer().impl.matman()._materials
How to proceed with V7*
Thank you
EDIT :
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2',
getAccessToken: function(onTokenReady) {
var token = accessToken;
var timeInSeconds = 3600;
onTokenReady(token, timeInSeconds);
}
};
var documentId = "urn:" + urn;
Autodesk.Viewing.Initializer(options, function() {
var htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
var startedCode = viewer.start();
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
...
Then I'm using impl methods as below ..
var mats = viewer.impl.matman()._materials;
But I still get the error
Cannot read property 'impl' of null
not sure why but may be my global viewer variable is null , any idea why this is happening or what have i done wrong.

Anything under the impl is typically considered internal implementation, and as such should not be relied on in production code. With that said, the impl property is still available, and if needed, you can use it in Forge Viewer version 7.* like so:
const viewer = new Autodesk.Viewing.GuiViewer3D(...);
viewer.impl.invalidate();
viewer.impl.matman();

Related

Autodesk Forge Viewer Api Cannot load markups inside screenshot

Good day,
I am using the latest Autodesk forge viewer and I am trying to take a screenshot that also renders my markups. Right now my code takes a screenshot without any markups. Below is my viewer code. I am loading markups Core and markups Gui extensions. Notice the "takeSnapshot(viewer)" function inside onDocumentLoadSuccess(viewerDocument). The function is defined right before the initializer function.
function takeSnapshot(target){
$('#snipViewer').click( () => {
target.getScreenShot(1600, 920, (blobURL) => {
let snip = blobURL;
$('#sniplink').attr("href", snip);
$('#sniplink').html('Not Empty');
$('#sniplink').css({"background-image": `url(${blobURL})`});
});
});
}
//Autodesk Viewer Code
instance.data.showViewer = function showViewer(viewerAccessToken, viewerUrn){
localStorage.setItem("viewerAccessTokentoken", viewerAccessToken);
localStorage.setItem("viewerUrn", viewerUrn);
var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2',
getAccessToken: function(onTokenReady) {
var token = viewerAccessToken;
var timeInSeconds = 3600;
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function() {
let htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
let startedCode = viewer.start();
viewer.setTheme("light-theme");
viewer.loadExtension("Autodesk.CustomDocumentBrowser").then(() => {
viewer.loadExtension("Autodesk.Viewing.MarkupsCore");
viewer.loadExtension("Autodesk.Viewing.MarkupsGui");
});
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
$("#loadingStatus").html("Failed to create a Viewer: WebGL not supported.");
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = `urn:` + viewerUrn;
var derivativeId = `urn:` + instance.derivativeUrn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
takeSnapshot(viewer);
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
$("#loadingStatus").html("Failed fetching Forge manifest.");
}
}
I have already read this article: https://forge.autodesk.com/blog/screenshot-markups
I have tried doing this method but the instructions are very unclear for me. <div style="width:49vw; height:100vh;display:inline-block;"><canvas id="snapshot" style="position:absolute;"></canvas><button onclick="snaphot();" style="position:absolute;">Snapshot!</button></div>
What is the canvas element here for? Am I supposed to renderToCanvas() when I load the markups extension inside the initialize function or in my screenshot function? Is there some way I can implement the renderToCanvas() without changing too much of what I already am using here? I am not an expert with the viewer API so please if you could help me it would be very much appreciated, I am a beginner please don't skip many steps.
Thank you very much!
Here's a bit more simplified logic for generating screenshots with markups in Forge Viewer, with a bit more explanation on why it needs to be done this way below:
function getViewerScreenshot(viewer) {
return new Promise(function (resolve, reject) {
const screenshot = new Image();
screenshot.onload = () => resolve(screenshot);
screenshot.onerror = err => reject(err);
viewer.getScreenShot(viewer.container.clientWidth, viewer.container.clientHeight, function (blobURL) {
screenshot.src = blobURL;
});
});
}
function addMarkupsToScreenshot(viewer, screenshot) {
return new Promise(function (resolve, reject) {
const markupCoreExt = viewer.getExtension('Autodesk.Viewing.MarkupsCore');
const canvas = document.createElement('canvas');
canvas.width = viewer.container.clientWidth;
canvas.height = viewer.container.clientHeight;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(screenshot, 0, 0, canvas.width, canvas.height);
markupCoreExt.renderToCanvas(context, function () {
resolve(canvas);
});
});
}
const screenshot = await getViewerScreenshot(viewer);
const canvas = await addMarkupsToScreenshot(viewer, screenshot);
const link = document.createElement('a');
link.href = canvas.toDataURL();
link.download = 'screenshot.png';
link.click();
Basically, the markups extension can only render its markups (and not the underlying 2D/3D scene) into an existing <canvas> element. That's why this is a multi-step process:
You render the underlying 2D/3D scene using viewer.getScreenShot, getting a blob URL that contains the screenshot image data
You create a new <canvas> element
You insert the screenshot into the canvas (in this case we create a new Image instance and render it into the canvas using context.drawImage)
You call the extension's renderToCanvas that will render the markups in the canvas on top of the screenshot image

Forge Viewer: Properties Window

The Properties window does not populate any properties even though the 2D view has properties info for the selected room
Here is the function that loads the model. what am I missing?
function loadModel() {
var initialViewable = viewables[indexViewable];
var svfUrl = lmvDoc.getViewablePath(initialViewable);
var modelOptions = {
sharedPropertyDbPath: lmvDoc.getFullPath(lmvDoc.getRoot().findPropertyDbPath())
};
viewer.loadModel(svfUrl, modelOptions, onLoadModelSuccess, onLoadModelError);
}
One line missing in your code, please try the following instead:
var sharedDbPath = initialViewable.findPropertyDbPath();
sharedDbPath = lmvDoc.getFullPath( sharedDbPath );
var modelOptions = {
sharedPropertyDbPath: sharedDbPath
};
However, you should not need to specify the sharedPropertyDbPath manually now. You can take advantage of the Viewer3D#loadDocumentNode to load the model directly. It will automatically determine the path for you. (started from v7 viewer)
const initialViewable = viewables[0];
viewer.loadDocumentNode( lmvDoc, initialViewable, loadOptions )
.then( onLoadModelSuccess )
.catch( onLoadModelError );

Set Autodesk Forge Viewer to Infinity Pool environment

Im trying to set the Infinity pool environment on the viewer but it doesn't change, it still has the initial grey background, any ideas? I'm trying to set the light preset in the ondocumentLoadSuccess Callback
var viewer;
function launchViewer(urn, accessToken, expires) {
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2', // for models uploaded to EMEA change this option to 'derivativeV2_EU'
getAccessToken: function (onTokenReady) {
var token = accessToken;
var timeInSeconds = expires; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function () {
var htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.Viewer3D(htmlDiv);
var startedCode = viewer.start();
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = 'urn:' + urn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
}
function onDocumentLoadSuccess(viewerDocument) {
viewer.setLightPreset(7);
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
In some cases the model you are loading into the viewer may be trying to set its own environment. Try calling the viewer.setLightPreset method after the model is loaded.

Error in viewing files in Autodesk forge viewer - error calling doc.getRootItem()

When viewing files in Autodesk forge viewer, getting the following errors,
Cannot read property ‘setEndpoint’ of undefined. Screenshot
doc.getRootItem is not a function. Screenshot
And will be able to view after empty cache and hard reload (Ctrl + Shift +R) the page. Sometimes the same errors will persist even after hard reload and clearing browser cache.
Code for the second error.
var options = {
env: 'AutodeskProduction',
accessToken: getAccessToken() //Method to get access token- no errors here
};
var documentId = 'urn:' + urn;
Autodesk.Viewing.Initializer(options, function onInitialized() {
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
//Autodesk.Viewing.Document.load - success function.
function onDocumentLoadSuccess(doc) {
setTimeout(function() {
debugger;
}, 5000);
//Error is thrown in the line below.
var viewables = Autodesk.Viewing.Document.getSubItemsWithProperties(doc.getRootItem(), {
'type': 'geometry'
}, true); //throws error on calling doc.getRootItem()
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
// Choose any of the avialble viewables
var initialViewable = viewables[0];
var svfUrl = doc.getViewablePath(initialViewable);
var modelOptions = {
sharedPropertyDbPath: doc.getPropertyDbPath()
};
var viewerDiv = document.getElementById('divViewer');
viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv);
viewer.start(svfUrl, modelOptions, onLoadModelSuccess, onLoadModelError);
}
You must have unwitting upgraded to Viewer V7 with which getRootItem and several other functions have been deprecated - see here for its release notes and migration guide.
Stick with V6 with <script src="https://developer-stg.api.autodesk.com/modelderivative/v2/viewers/viewer3D.js?v=6.6"></script> - if you don't specify a version by default the latest stable version would be served which is now V7.0.

Autodesk forge viewer pdf error

I am struggling to view a pdf in the forge viewer. All other drawings .rvt .dwg .dxf .nwd are showing without any issue.
Initially I received a error
Cannot read property 'loadFromZip' of undefined
Have managed to evade this by adding "loadOptions" into the modeloptions I send through to the viewer. But now I get a error 6 back from the viewer which is a server error. Please if someone could advise what to do.
loadModel() {
var initialViewable = viewables[indexViewable];
var svfUrl = lmvDoc.getViewablePath(initialViewable);
var modelOptions = {
sharedPropertyDbPath: lmvDoc.getPropertyDbPath(),
loadOptions: {}
};
viewer.loadModel(
svfUrl,
modelOptions,
this.onLoadModelSuccess,
this.onLoadModelError
);
}
Thanks in advance
You have to use ViewingApplication rather than Viewer3D or GuiViewer3D to initialize your viewer to view PDF files since there are some additional configuration values for PDF set up by the ViewingApplication automatically.
Also refer to:
Forge Viewer fails to dispaly PDF's
=== Example for passing configs to Viewer instance via ViewingApplication ===
//--- Method 1:
var viewerConfigs = {
extensions: ['MyAwesomeExtension'],
extOpts: {
MyAwesomeExtension: {
buttonColor: 'red'
}
}
};
var viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, viewerConfigs);
// In the constructor of the MyAwesomeExtension
class MyAwesomeExtension extends Autodesk.Viewing.Extension {
constructor( viewer, options ) {
super( viewer, options );
// your options here
const opts = options.extOpts.MyAwesomeExtension;
}
}
//--- Method 2:
// After model was loadded,
var viewer = viewerApp.getCurrentViewer();
var extOpts = {
opt1: true
};
viewer.loadExtension( 'Autodesk.ADN.MyExtension', extOpts );
For more details, please refer:
https://developer.autodesk.com/en/docs/viewer/v2/tutorials/extensions/
https://developer.autodesk.com/en/docs/viewer/v2/tutorials/basic-application/