Cannot load SVF2 model in Autodesk Forge Viewer - autodesk-forge

I just tried out the SVF2 public beta but couldn't get the model to load in the Viewer. I believe the model was translated successfully since the manifest returned has:
"name": "XXXX_ARC.nwd",
"progress": "complete",
"outputType": "svf2",
"status": "success"
However, when I tried to load the model in Viewer, it would fail on this line:
theViewer.loadModel(svfURL, onItemLoadSuccess, onItemLoadFail);
The svfURL is something like this:
https://cdn.derivative.autodesk.com/modeldata/file/urn:adsk.fluent:fs.file:autodesk-360-translation-storage-prod/*MyURN*/output/otg_files/0/output/0/otg_model.json
And the errors I got from Chrome browser:
403 GET errors. Seems like I don't have privilege to access the model?
Is there some additional setting I need to do?
Additional Info:
I have setup the Viewer environment as follows:
var options = {
env: 'MD20ProdUS',
api: 'D3S',
getAccessToken: getForgeToken
};
var documentId = 'urn:' + urn;
Autodesk.Viewing.Initializer(options, function onInitialized() {
var htmlDiv = document.getElementById('forgeViewer');
var config3d = {
extensions: ['ToolbarExtension', 'HandleSelectionExtension', .....a few extensions ],
loaderExtensions: { svf: "Autodesk.MemoryLimited" }
};
theViewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv, config3d);
var startedCode = theViewer.start();
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
I have also tried removing the config3d when creating the viewer but it still returned the same messages. The code got into onDocumentLoadSuccess but failed at theViewer.loadModel(svfURL, onItemLoadSuccess, onItemLoadFail);, jumping into onItemLoadFail.

Because you mention mainly the viewer not loading the SVF2, I can suspect that maybe you have not specified the correct Viewer environment.
Here is some sample code, and pay attention to the options where you have to set env and API:
var viewer;
var options = {
// These are the SVF2 viewing settings during public beta
env: 'MD20ProdUS', // or MD20ProdEU (for EMEA)
api: 'D3S',
getAccessToken: getForgeToken
};
var documentId = 'urn:' + getUrlParameter('urn');
// Run this when the page is loaded
Autodesk.Viewing.Initializer(options, function onInitialized() {
// Find the element where the 3d viewer will live.
var htmlElement = document.getElementById('MyViewerDiv');
if (htmlElement) {
// Create and start the viewer in that element
viewer = new Autodesk.Viewing.GuiViewer3D(htmlElement);
viewer.start();
// Load the document into the viewer.
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
}
});

I am facing the same problem.
Although the model has been converted to SVF2 format, my cloud credits are being used up .
An excerpt from the manifest:
"name": "7085-33cc-9464.rvt",
"progress": "complete",
"outputType": "svf2",
"status": "success"
No matter with which settings, only the SVF format is loaded in the viewer.
I don't get an error message from the viewer, everything works as before, except that SVF is still loaded and not SVF2.
Viewer init options:
const viewerEnv = await this.initialize({
//env: dbModel.env,
env: "MD20ProdEU",
api: "D3S",
//accessToken: "",
});

Not sure if this has been solved on a separate thread, but the issue was probably that acmSessionId was not set in the options for loadModel() - see https://forge.autodesk.com/blog/403-error-when-trying-view-svf2
function onDocumentLoadSuccess(doc) {
let items = doc.getRoot().search({
'type': 'geometry',
'role': '3d'
}, true)
let url = doc.getViewablePath(items[0])
viewer.loadModel(url, { acmSessionId: doc.getAcmSessionId(url) })
}
The best thing is to just use loadDocumentNode() instead of loadModel()

Related

APS (Forge) Viewer in Sharepoint - Error loading Autodesk Viewer library

I am trying to integrate APS Viewer (formerly Forge Viewer) in a Sharepoint webpart using Sharepoint Framework. There is a post in the blog explaining how to do it: https://aps.autodesk.com/blog/sharepoint-online-integration.
I have adapted the code provided, however, I always end up with this error when loading the Viewer. The error occurs when calling Autodesk.Viewing.Initializer function to initialize the viewer. This call fails because
"ReferenceError: Autodesk is not defined"
yet the library is imported correctly. Anyone knows how can I solve this?
These are the steps we did:
Create a webpart with Sharepoint Framework. No Framework template is selected.
Add custom js script with functions to load the viewer.
Import Autodesk js library for Viewer with SPComponentLoader and load custom js script in render() function of our Sharepoint webpart.
SPComponentLoader.loadScript("https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js");
SPComponentLoader.loadScript("./js/ForgeTree.js");
const viewer: any = require("./ForgeViewer.js");
Call custom function launchViewer from custom js script that calls Autodesk.Viewing.Initializer method. This step fails.
export function launchViewer(urn, viewableId, accessToken) {
console.log('launchViewer')
var options = {
env: 'AutodeskProduction',
getAccessToken: callback => {
callback(accessToken, 3600);
},
// api: 'derivativeV2' + (atob(urn.replace('_', '/')).indexOf('emea') > -1 ? '_EU' : '') // handle OSS US and EU regions
api: 'derivativeV2' + (Buffer.from((urn.replace('_', '/')).indexOf('emea') > -1 ? '_EU' : ''), 'base64') // handle OSS US and EU regions
};
if (viewer === undefined) {
Autodesk.Viewing.Initializer(options, () => {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'), { extensions: [ 'Autodesk.DocumentBrowser'] });
viewer.start();
var documentId = 'urn:' + urn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
})
} else {
var documentId = 'urn:' + urn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
}
}
I think you should simply wait for the SPComponentLoader.loadScript() to finish (use await or then()) as it returns a Promise<TModule>
https://learn.microsoft.com/en-us/javascript/api/sp-loader/spcomponentloader?view=sp-typescript-latest##microsoft-sp-loader-spcomponentloader-loadscript-member(1)
I probably got away with not doing that in my code because the authentication is taking place after that call, which gives extra time for loadScript to finish

Autodesk Forge AggregatedView viewing a "stitched" geometry rather than a smooth one

I have a simple forge app to view 3d models. At first, I initiated the forge viewer with GuiViewer3D class but then wanted to implement AggregatedView instead.
My problem is that AggregatedView shows the model correctly but it shows it as being "stitched" together. Whereas, if I use GuiViewer3D or Viewer3D, the model looks smooth and clean.
I have looked into the globalOffset but in any solution, the globalOffset is the same, and hence should not be the cause here.
This is how the model should look like (GuiViewer3D)
But this is how it looks like instea using AggregatedView
I am not quite sure what the issue here. I am using an .fbx file as the source of 3d model.
This the code of AggregatedView()
var view = new Autodesk.Viewing.AggregatedView();
function launchViewer(urn) {
var options = {
env: 'AutodeskProduction',
getAccessToken: getForgeToken
};
Autodesk.Viewing.Initializer(options, () => {
var htmlDiv = document.getElementById('forgeViewer');
view.init(htmlDiv, options);
var documentId = 'urn:' + urn;
view.unloadAll();
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
}
function onDocumentLoadSuccess(doc) {
var nodes = doc.getRoot().search({ role:'3d', type: 'geometry' });
console.log(nodes);
view.setNodes(nodes[0]);
}
function onDocumentLoadFailure(viewErrorCode, viewErrorMsg) {
console.error('onDocumentLoadFailure() - errorCode:' + viewErrorCode + '\n- errorMessage:' + viewErrorMsg);
}
function getForgeToken(callback) {
fetch('/api/forge/oauth/token').then(res => {
res.json().then(data => {
callback(data.access_token, data.expires_in);
});
});
}
Many thanks in advance!
UPDATE:
After setting the global offset to (0,0,0), the geometry still looks "Stitched" together rather than smooth.
The pivot point is not the global offset. Please use viewer.getAllModels().map( model => model.getGlobalOffset() ) to check that instead. For AggreagateView, you can get the viewer instance via view.viewer;
In addition, AggreagateView loads models in the shared coordinate (applyRefPoint: true), so your model might be far away from the viewer's origin. Could you try this to see if it helps?
const options3d = {
getCustomLoadOptions: (bubble, data) => {
console.log(bubble, data);
return {
applyRefPoint: false //!<<< Disable Share Coordinate
// globalOffset: new THREE.Vector3( 543.0811920166016, 9.154923574611564, -1442.591747316564 ) //!<<< uncomment this to specify your globalOffset, but you need to include `applyRefPoint: false` above together.
// createWireframe: false
};
}
};
view.init(viewerDiv, options3d);

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/

Button for markupCore extension not showing in dockingpanel

I have followed Philippe Leefsma's tutorial on how to implement the markup tool, but without any luck. Link here: http://adndevblog.typepad.com/cloud_and_mobile/2016/02/playing-with-the-new-view-data-markup-api.html
and here: https://developer.api.autodesk.com/viewingservice/v1/viewers/docs/tutorial-feature_markup.html
I get errors that I need to include requireJS, but I don't want to use it. So instead I used this script in my html file:
<script src="https://autodeskviewer.com/viewers/2.2/extensions/MarkupsCore.js">
I don't know if this is the right way to go? I get no errors in the console, but the markup button doesn't show up in the dockingpanel.
This is my code for loading the extension in the viewer:
viewerApp = null;
function initializeViewer(containerId, urn, params) {
function getToken(url) {
return new Promise(function (resolve, reject) {
$.get(url, function (response) {
resolve(response.access_token);
});
});
}
var initOptions = {
documentId: 'urn:' + urn,
env: 'AutodeskProduction',
getAccessToken: function (onGetAccessToken) {
getToken(params.gettokenurl).then(function (val) {
var accessToken = val;
var expireTimeSeconds = 60 * 30;
onGetAccessToken(accessToken, expireTimeSeconds);
});
}
}
function onDocumentLoaded(doc) {
var rootItem = doc.getRootItem();
// Grab all 3D items
var geometryItems3d =
Autodesk.Viewing.Document.getSubItemsWithProperties(
rootItem, { 'type': 'geometry', 'role': '3d' }, true);
// Grab all 2D items
var geometryItems2d =
Autodesk.Viewing.Document.getSubItemsWithProperties(
rootItem, { 'type': 'geometry', 'role': '2d' }, true);
// Pick the first 3D item otherwise first 2D item
var selectedItem = (geometryItems3d.length ?
geometryItems3d[0] :
geometryItems2d[0]);
var domContainer = document.getElementById('viewerContainer');
var config = { extensions: ["Autodesk.Viewing.MarkupsCore"] };
// GUI Version: viewer with controls
var viewer = new Autodesk.Viewing.Private.GuiViewer3D(domContainer, config);
viewer.loadExtension("Autodesk.Viewing.MarkupsCore");
viewer.initialize();
viewer.loadModel(doc.getViewablePath(selectedItem));
var extension = viewer.getExtension("Autodesk.Viewing.MarkupsCore");
viewerApp = viewer;
}
function onEnvInitialized() {
Autodesk.Viewing.Document.load(
initOptions.documentId,
function (doc) {
onDocumentLoaded(doc);
},
function (errCode) {
onLoadError(errCode);
})
}
function onLoadError(errCode) {
console.log('Error loading document: ' + errCode);
}
Autodesk.Viewing.Initializer(
initOptions,
function () {
onEnvInitialized()
})
}
Any help is highly appreciated!
Unfortunately there has been a few changes to the API since I wrote that blog post. The MarkupCore.js is now included in the viewer3D.js source, so you don't need to reference any extra file or use requireJS if you use the latest version of the viewer API.
Keep in mind that this is an API-only feature, so even after loading the markup extension, you won't get any UI out of the box. You have to implemented it yourself, for example create a dialog with buttons that may eventually create markups by calling the API.
Some of the code from my blog post may still be valid and give you an idea about what you need to do.
Hope that helps.