How to set light theme on viewer? - autodesk-forge

I have this sample code, to initialize viewer:
<div id="viewer"></div>
<script>
var app;
var options = {
env: 'AutodeskProduction',
accessToken: 'mytoken'
};
var urn = 'myUrn';
Autodesk.Viewing.Initializer(options, function() {
app = new Autodesk.Viewing.ViewingApplication('viewer');
app.registerViewer(app.k3D, Autodesk.Viewing.Private.GuiViewer3D);
function onDocumentLoadSuccess() {
const viewables = app.bubble.search({ 'type': 'geometry' });
app.selectItem(viewables[0].data);
}
function onDocumentLoadFailure() {}
app.loadDocument('urn:' + urn, onDocumentLoadSuccess, onDocumentLoadFailure);
});
</script>
I want to use light theme but I'm not sure how to do that.
How to set light theme to viewer, please?
Thank you

You can add during inside the Initializer
Autodesk.Viewing.Initializer(options, function onInitialized() {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('MyViewerDiv'));
viewer.setTheme("light-theme");
viewer.start();
loadDocument(....)
});

Are you looking for the following API? Just call this method after your viewer is initialized.
/**
* Sets the current UI theme of the viewer.
* Supported values are "light-theme" and "dark-theme", which is the default.
*
* #param {string} name - Name of the theme, it will be added to the viewer's container class list.
*
* #alias Autodesk.Viewing.Viewer3D#setTheme
*/
Viewer3D.prototype.setTheme = function (name) {
};
Modified your code as follow and added one line of code in onItemLoadSuccess() as follow.
viewerApp.myCurrentViewer.setTheme("light-theme");
<script>
var viewerApp;
var options = {
env: 'AutodeskProduction',
getAccessToken: function(onGetAccessToken) {
//
// TODO: Replace static access token string below with call to fetch new token from your backend
// Both values are provided by Forge's Authentication (OAuth) API.
//
// Example Forge's Authentication (OAuth) API return value:
// {
// "access_token": "<YOUR_APPLICATION_TOKEN>",
// "token_type": "Bearer",
// "expires_in": 86400
// }
//
var accessToken = 'mytoken';
var expireTimeSeconds = 60 * 30;
onGetAccessToken(accessToken, expireTimeSeconds);
}
};
let config3d = {
};
var documentId = 'urn:myurn';
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config3d);
viewerApp.loadDocument(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
function onDocumentLoadSuccess(doc) {
// We could still make use of Document.getSubItemsWithProperties()
// However, when using a ViewingApplication, we have access to the **bubble** attribute,
// which references the root node of a graph that wraps each object from the Manifest JSON.
var viewables = viewerApp.bubble.search({'type':'geometry'});
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
// Choose any of the avialble viewables
viewerApp.selectItem(viewables[0].data, onItemLoadSuccess, onItemLoadFail);
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
function onItemLoadSuccess(viewer, item) {
console.log('onItemLoadSuccess()!');
viewerApp.myCurrentViewer.setTheme("light-theme");
}
function onItemLoadFail(errorCode) {
console.error('onItemLoadFail() - errorCode:' + errorCode);
}
</script>

Related

Object selection in forge viewer

I have created the sample application for forge viewer.
I am able to view the Revit and navisworks files in forge viewer.
I want to select an item from the viewer by passing inputs to viewer.bubble.search method.
I am using the same coding from the url:
https://forge.autodesk.com/en/docs/viewer/v7/reference/Viewing/BubbleNode/
I am using the below code. Please help.
var viewer;
var urn1;
var accestoken1;
var jsdata;
function uploadfile(file) {
document.getElementById('<%=UploadBtn.ClientID%>').click();
}
function showModel(urn) {
var options = {
env: 'AutodeskProduction',
getAccessToken: getForgeToken
};
Autodesk.Viewing.Initializer(options, () => {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'), { extensions: ['Autodesk.DocumentBrowser'] });
viewer.start();
var documentId = 'urn:' + urn;
urn1 = urn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
// viewer.fitToView([270005], viewer.model);
// viewer.select([270005]);
});
}
function myFunction1() {
setTimeout(function () {
myFunction2();
}, 500);
}
function onDocumentLoadSuccess(doc) {
var viewables = viewer.bubble.search({ type: 'geometry', role: '3d', name: 'DOMW PIPE' });
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
function getForgeToken(callback) {
fetch('/api/forge/oauth/token').then(res => {
res.json().then(data => {
callback(data.access_token, data.expires_in);
accestoken1 = data.access_token;
});
});
}
with thanks and regards.
Castro Nelson
If you'd like to make it possible to choose which of the 2D or 3D views (that the Model Derivative service extracted from your original design) to load in the viewer, consider using the built-in viewer extension called Autodesk.DocumentBrowser. The extension will add a new UI to the viewer that can be used to switch between the different 2D/3D views quite easily.
You can experiment with the extension on https://forge-extensions.autodesk.io:

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.

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.

How to add Google Drive Picker in Google web app

what I'm trying to do is to show the Google Picker in my Google Web app. I already tried many ways to accomplish that, but nothing works.
At the moment my code looks like this:
WebApp.html
<!-- rest of the code -->
<button type="button" id="pick">Pick File</button>
</div>
<script>
function initPicker() {
var picker = new FilePicker({
apiKey: "####################",
clientId: "##########-##########################",
buttonEl: document.getElementById('pick'),
onSelect: function(file) {
alert('Selected ' + file.title);
} // onSelect
}); // var picker
} // function initPicker()
</script>
<!-- rest of the code -->
WebAppJS.html
/* rest of the code */
var FilePicker = window.FilePicker = function(options) {
this.apiKey = options.apiKey;
this.clientId = options.clientId;
this.buttonEl = options.buttonEl;
this.onSelect = options.onSelect;
this.buttonEl.addEventListener('click', this.open.bind(this));
this.buttonEl.disabled = true;
gapi.client.setApiKey(this.apiKey);
gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this));
google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) });
}
FilePicker.prototype = {
open: function() {
var token = gapi.auth.getToken();
if (token) {
this._showPicker();
} else {
this._doAuth(false, function() { this._showPicker(); }.bind(this));
}
},
_showPicker: function() {
var accessToken = gapi.auth.getToken().access_token;
this.picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.DOCUMENTS).
setAppId(this.clientId).
setOAuthToken(accessToken).
setCallback(this._pickerCallback.bind(this)).
build().
setVisible(true);
},
_pickerCallback: function(data) {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var file = data[google.picker.Response.DOCUMENTS][0],
id = file[google.picker.Document.ID],
request = gapi.client.drive.files.get({ fileId: id });
request.execute(this._fileGetCallback.bind(this));
}
},
_fileGetCallback: function(file) {
if (this.onSelect) {
this.onSelect(file);
}
},
_pickerApiLoaded: function() {
this.buttonEl.disabled = false;
},
_driveApiLoaded: function() {
this._doAuth(true);
},
_doAuth: function(immediate1, callback) {
gapi.auth.authorize({
client_id: this.clientId + '.apps.googleusercontent.com',
scope: 'https://www.googleapis.com/auth/drive.readonly',
immediate: immediate1
}, callback);
}
}; // FilePicker.prototype
/* rest of the code */
For now, what this code does is showing kind of a popup, but empty. Code is based on Daniel15's code.
What I already tried is:
relocating chunks of code, to server-side and client-side,
using htmlOutput, htmlTemplate - non of those works,
many other things, that i can't exactly remember.
What I would like to get is answer to the question: Why this code doesn't show Google Picker.
Thanks in advance.
Try adding a call origin and developer key
_showPicker: function() {
var accessToken = gapi.auth.getToken().access_token;
this.picker = new google.picker.PickerBuilder()
.addView(google.picker.ViewId.DOCUMENTS)
.setAppId(this.clientId)
.setOAuthToken(accessToken)
.setCallback(this._pickerCallback.bind(this))
.setOrigin('https://script.google.com') //
.setDeveloperKey(BROWSERKEYCREATEDINAPICONSOLE) //
.build()
.setVisible(true);
},

How to free up memory when saving images inside IndexDB

I have a no of images on page and trying to save it inside IndexDb if it does not exist.
All seems to be working fine and images load up instantly if it exist but looks like browser memory is leaking. It's give some jerk and hang sometime. I m not sure how this can be handle, I have written a directive that looks like this
(function () {
'use strict';
// TODO: replace app with your module name
angular.module('app').directive('imageLocal', imageLocal);
imageLocal.$inject = ['$timeout', '$window', 'config', 'indexDb'];
function imageLocal($timeout, $window, config, indexDb) {
// Usage:
//
// Creates:
//
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
var imageId = attrs.imageLocal;
// Open a transaction to the database
var transaction;
$timeout(function () {
transaction = indexDb.db.transaction(["mystore"], "readwrite");
getImage();
}, 500);
function getImage() {
transaction.objectStore('mystore').get(imageId)
.onsuccess = function (event) {
var imgFile = event.target.result;
if (imgFile == undefined) {
saveToDb(imgFile);
return false;
}
showImage(imgFile);
}
}
function showImage(imgFile) {
console.log('getting');
// Get window.URL object
var url = $window.URL || $window.webkitURL;
// Create and revoke ObjectURL
var imageUrl = url.createObjectURL(imgFile);
element.css({
'background-image': 'url("' + imageUrl + '")',
'background-size': 'cover'
});
}
function saveToDb() {
// Create XHR
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", config.remoteServiceName + '/image/' + imageId, true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
// Blob as response
blob = xhr.response;
console.log("Blob:" + blob);
// Put the received blob into IndexedDB
putInDb(blob);
}
}, false);
// Send XHR
xhr.send();
function putInDb(blob) {
// Open a transaction to the database
transaction = indexDb.db.transaction(["mystore"], "readwrite");
// Put the blob into the database
var request = transaction.objectStore("mystore").add(blob, imageId);
getImage();
request.onsuccess = function (event) {
console.log('saved');
}
};
}
}
}
})();