Autodesk-XLSExtension, undefined viewer - autodesk-forge

Im trying to implement the XLS Extension. In the ModelData class, i cannot get objects leaf nodes because the viewer is undefined.
Here is the problematic method:
getAllLeafComponents(callback) {
// from https://learnforge.autodesk.io/#/viewer/extensions/panel?id=enumerate-leaf-nodes
viewer.getObjectTree(function (tree) {
let leaves = [];
tree.enumNodeChildren(tree.getRootId(), function (dbId) {
if (tree.getChildCount(dbId) === 0) {
leaves.push(dbId);
}
}, true);
callback(leaves);
});
}
Im getting Cannot read properties of undefined (reading 'getObjectTree') , meaning viewer is undefined.
However, viewer is working and displaying documents.
I tried to call it by window.viewer and this.viewer to no avail.
Thanks in advance for any help

It looks like it missed two lines. Could you try the revised one below?
// Model data in format for charts
class ModelData {
constructor(viewer) {
this._modelData = {};
this._viewer = viewer;
}
init(callback) {
var _this = this;
var viewer = _this._viewer;
_this.getAllLeafComponents(function (dbIds) {
var count = dbIds.length;
dbIds.forEach(function (dbId) {
viewer.getProperties(dbId, function (props) {
props.properties.forEach(function (prop) {
if (!isNaN(prop.displayValue)) return; // let's not categorize properties that store numbers
// some adjustments for revit:
prop.displayValue = prop.displayValue.replace('Revit ', ''); // remove this Revit prefix
if (prop.displayValue.indexOf('<') == 0) return; // skip categories that start with <
// ok, now let's organize the data into this hash table
if (_this._modelData[prop.displayName] == null) _this._modelData[prop.displayName] = {};
if (_this._modelData[prop.displayName][prop.displayValue] == null) _this._modelData[prop.displayName][prop.displayValue] = [];
_this._modelData[prop.displayName][prop.displayValue].push(dbId);
})
if ((--count) == 0) callback();
});
})
})
}
getAllLeafComponents(callback) {
var _this = this;
var viewer = _this._viewer;
// from https://learnforge.autodesk.io/#/viewer/extensions/panel?id=enumerate-leaf-nodes
viewer.getObjectTree(function (tree) {
var leaves = [];
tree.enumNodeChildren(tree.getRootId(), function (dbId) {
if (tree.getChildCount(dbId) === 0) {
leaves.push(dbId);
}
}, true);
callback(leaves);
});
}
hasProperty(propertyName){
return (this._modelData[propertyName] !== undefined);
}
getLabels(propertyName) {
return Object.keys(this._modelData[propertyName]);
}
getCountInstances(propertyName) {
return Object.keys(this._modelData[propertyName]).map(key => this._modelData[propertyName][key].length);
}
getIds(propertyName, propertyValue) {
return this._modelData[propertyName][propertyValue];
}
}

Related

How to get the selected equipment object id

we have used forge Aggregate Viewer to display the multiple BIM models. But if we click/double click any of the equipment in the Aggregate Forge Viewer the equipment will be zoomed.
but not able to get the selected equipment object id by using the c# code.
Note: If we upload the single file, we are able to get the selected equipment object id in the Forge Viewer.
We used below code, but its not get hitted when we select equipment.
viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, (args) => {
Kindly help us to get the selected equipment object id in Aggregate Forge View while displaying the multiple files.
Kindly share the sample code for our reference.
FITTOVIEW AND SELECTION CHANGE CODE
const Loadedevent = () => {
var objval = document.getElementById('<%=hid_objectid.ClientID%>').value;
if (objval != '') {
var mdlurn = "";
mdlurn = document.getElementById('<%=hid_mdlurn.ClientID%>').value;
const models = viewer.getVisibleModels().find(m => m.getData().urn === mdlurn);
viewer.fitToView([parseInt(objval)], models);
viewer.select([parseInt(objval)], models, Autodesk.Viewing.SelectionType.OVERLAYED);
}
}
SelectionChangeEvent
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
if (args.dbIdArray.length === 1) {
viewer.getProperties(args.dbIdArray[0], function (data) {
if (FromPage == '') {
if (FromSelection == '') {
if (Count === 0) {
var instanceTree = viewer.model.getData().instanceTree;
var parentId = instanceTree.getNodeParentId(args.dbIdArray[0]);
viewer.select([parentId], viewer.model, Autodesk.Viewing.SelectionType.OVERLAYED);
Count = 1;
} else {
itemobject = args.dbIdArray[0];
Count = 0;
}
} else {
FromSelection = '';
itemobject = args.dbIdArray[0];
}
} else {
FromPage = '';
itemobject = args.dbIdArray[0];
}
});
}
});
Edited Code:
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
if (!args.selections || args.selections.length <= 0)
return;
if (args.selections.length == 1 ) {
viewer.getProperties(args.selections[0].dbIdArray[0], function (data) {
if (FromPage == '') {
if (FromSelection == '') {
if (Count === 0) {
var instanceTree = viewer.model.getData().instanceTree;
var parentId = instanceTree.getNodeParentId(args.selections[0].dbIdArray);
viewer.select([parentId], viewer.model, Autodesk.Viewing.SelectionType.OVERLAYED);
Count = 1;
} else {
const dbIds = args.selections[0].dbIdArray;
itemobject = dbIds[0];
Count = 0;
}
} else {
FromSelection = '';
const dbIds = args.selections[0].dbIdArray;
itemobject = dbIds[0];
}
} else {
FromPage = '';
const dbIds = args.selections[0].dbIdArray;
itemobject = dbIds[0];
}
});
}
});
In the multiple models scenario, you must use Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT instead. See https://forge.autodesk.com/blog/multi-model-refresher
/**
* Triggered when objects are selected or deselected.
* Event payload:
* {
* type: 'aggregateSelection',
* target: Viewer3D,
* selections: Array<{
* model: Model,
* nodeArray: Array<number>,
* dbIdArray: Array<number>,
* fragIdsArray: Array<number>
* }>
* }
*/
viewer.addEventListener(
Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT,
(event) => {
// codes for selecting changed
});
To get selected objects, call viewer.getAggregateSelection() instead.
Update
Here are the revised code snippets for you:
FITTOVIEW AND SELECTION CHANGE CODE
const Loadedevent = () => {
let objval = document.getElementById('<%=hid_objectid.ClientID%>').value;
if (objval != '') {
let mdlurn = "";
mdlurn = document.getElementById('<%=hid_mdlurn.ClientID%>').value;
let model = viewer.getVisibleModels().find(m => m.getData().urn === mdlurn); //!<<< find() will return first found item only, so defining the variable in the singular form instead to avoid confusion.
let dbId = parseInt( objval );
viewer.select( [ dbId ] , model, Autodesk.Viewing.SelectionType.OVERLAYED );
// or viewer.setAggregateSelection([ { ids: [ dbId ], model, selectionType: Autodesk.Viewing.SelectionType.OVERLAYED } ]);
viewer.fitToView( [ dbId ], model );
}
}
SelectionChangeEvent
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (event) => {
if (!event.selections || event.selections.length <= 0 || event.selections.length > 1)
return;
let selSet = event.selections[0];
const dbIds = selSet.dbIdArray;
const model = selSet.model;
const dbId = dbIds[0];
model.getProperties(dbId, function(data) {
if (FromPage == '') {
if (FromSelection == '') {
if (Count === 0) {
let instanceTree = model.getInstanceTree();
let parentId = instanceTree.getNodeParentId(dbId);
viewer.select(parentId, model, Autodesk.Viewing.SelectionType.OVERLAYED);
// or viewer.setAggregateSelection([ { ids: [parentId ], model, selectionType: Autodesk.Viewing.SelectionType.OVERLAYED } ])
Count = 1;
} else {
itemobject = dbId;
Count = 0;
}
} else {
FromSelection = '';
itemobject = dbId;
}
} else {
FromPage = '';
itemobject = dbId;
}
});
});

How to properly use html-to-react?

so i am learning about this package html-to-react, and for the most part, i understand it. However, their is a piece of code i just cannot seem to be able to get my head around. The code is:
var React = require('react');
var HtmlToReact = require('html-to-react');
var HtmlToReactParser = require('html-to-react').Parser;
var htmlToReactParser = new HtmlToReactParser();
var htmlInput = '<div><div data-test="foo"><p>Text</p><p>Text</p></div></div>';
var htmlExpected = '<div><div data-test="foo"><h1>Heading</h1></div></div>';
var isValidNode = function () {
return true;
};
var processNodeDefinitions = new HtmlToReact.ProcessNodeDefinitions(React);
// Order matters. Instructions are processed in
// the order they're defined
var processingInstructions = [
{
// This is REQUIRED, it tells the parser
// that we want to insert our React
// component as a child
replaceChildren: true,
shouldProcessNode: function (node) {
return node.attribs && node.attribs['data-test'] === 'foo';
},
processNode: function (node, children, index) {
return React.createElement('h1', {key: index,}, 'Heading');
}
},
{
// Anything else
shouldProcessNode: function (node) {
return true;
},
processNode: processNodeDefinitions.processDefaultNode,
},
];
var reactComponent = htmlToReactParser.parseWithInstructions(
htmlInput, isValidNode, processingInstructions);
var reactHtml = ReactDOMServer.renderToStaticMarkup(
reactComponent);
assert.equal(reactHtml, htmlExpected);
The code i don't understand is the:
shouldProcessNode: function (node) {
return node.attribs && node.attribs['data-test'] === 'foo';
},
Any help would be very appreciated. Thanks

kendoGrid and multiselectbox column initialization using query string parameters

I am implementing a custom solution that will initialize kendoGrid (and its multiselect columns) by applying filters to the grid using query string parameters. I am using Kendo UI v2014.2.903 and multiselectbox user extension.
To achieve this, I have a custom JavaScript function that parses query string parameters into filter object and applies it to kendoGrid's dataSource property using its filter method. Code snippet below:
var preFilterQueryString = getPreFilterQuery(queryString);
if (preFilterQueryString != '') {
kendoGrid.dataSource.filter(parseFilterString(preFilterQueryString));
}
I am initializing multiselectbox as follows:
args.element.kendoMultiSelectBox({
dataSource: getAutoCompleteDataSource(column.field),
valuePrimitive: true,
selectionChanged: function (e) {
//ignored for brevity
}
});
My problem is if I set filters to multiselectbox using above approach, they are not applied correctly to the data set.
For example, if I pass single filter as "Vancouver", correct result set is displayed. Choices in the multiselectbox are "All" and "Vancouver". However, Vancouver choice is not checked in the multiselectbox. Is that by design? Please see image below.
single filter image
If I pass in two filters Vancouver and Warsaw, only the last filter Warsaw is applied to the grid and data set containing only Warsaw is displayed. Again, none of the choices are checked in the multiselectbox.
two filters image
Below is the filter object that is applied to dataSource.filter() method.
kendoGrid's filter object image
Troubleshooting
Below is condensed version (for brevity) of selectionchanged event handler of a multiselectbox column.
if (e.newValue && e.newValue.length) {
var newValue = e.newValue;
console.log('e.newValue: ' + e.newValue);
filter.filters = [];
for (var i = 0, l = newValue.length; i < l; i++) {
filter.filters.push({field: field,operator: 'contains',value: newValue[i]});
}
kendoGrid.dataSource.filter(allFilters);
}
I noticed that when two filters are passed, e.newValue is "Warsaw" instead of an array - "[Vancouver, Warsaw]"
I spent lot of time troubleshooting why only Warsaw is applied to the data set.
Here's what I found out:
_raiseSelectionChanged function is what raises selection changed event. In that function, I noticed that it sets newValue and oldValue event arguments. To set newValue it uses "Value" function. Value function uses the below code to retrieve all the selected list items and return them.
else {
var selecteditems = this._getSelectedListItems();
return $.map(selecteditems, function (item) {
var obj = $(item).children("span").first();
return obj.attr("data-value");
}).join();
}
_getSelectedListItems function uses jQuery filter to fetch all list items that have css class ".selected"
_getSelectedListItems: function () {
return this._getAllValueListItems().filter("." + SELECTED);
},
There's a _select event which seems to be adding ".selected" class to list items. When I put a breakpoint on line 286, it is hitting it only once and that is for Warsaw. I am unable to understand why it is not getting called for Vancouver. I am out of clues and was wondering if anyone has pointers.
debug capture of _select function
Below is kendoMultiSelectBox user extension for your reference:
//MultiSelect - A user extension of KendoUI DropDownList widget.
(function ($) {
// shorten references to variables
var kendo = window.kendo,
ui = kendo.ui,
DropDownList = ui.DropDownList,
keys = kendo.keys,
SELECT = "select",
SELECTIONCHANGED = "selectionChanged",
SELECTED = "k-state-selected",
HIGHLIGHTED = "k-state-active",
CHECKBOX = "custom-multiselect-check-item",
SELECTALLITEM = "custom-multiselect-selectAll-item",
MULTISELECTPOPUP = "custom-multiselect-popup",
EMPTYSELECTION = "custom-multiselect-summary-empty";
var lineTemplate = '<input type="checkbox" name="#= {1} #" value="#= {0} #" class="' + CHECKBOX + '" />' +
'<span data-value="#= {0} #">#= {1} #</span>';
var MultiSelectBox = DropDownList.extend({
init: function (element, options) {
options.template = kendo.template(kendo.format(lineTemplate, options.dataValueField || 'data', options.dataTextField || 'data'));
// base call to widget initialization
DropDownList.fn.init.call(this, element, options);
var button = $('<input type="button" value="OK" style="float: right; padding: 3px; margin: 5px; cursor: pointer;" />');
button.on('click', $.proxy(this.close, this));
var popup = $(this.popup.element);
popup.append(button);
},
options: {
name: "MultiSelectBox",
index: -1,
showSelectAll: true,
preSummaryCount: 1, // number of items to show before summarising
emptySelectionLabel: '', // what to show when no items are selected
selectionChanged: null // provide callback to invoke when selection has changed
},
events: [
SELECTIONCHANGED
],
refresh: function () {
// base call
DropDownList.fn.refresh.call(this);
this._updateSummary();
$(this.popup.element).addClass(MULTISELECTPOPUP);
},
current: function (candidate) {
return this._current;
},
open: function () {
var self = this;
this._removeSelectAllItem();
this._addSelectAllItem();
if ($(this.ul).find('li').length > 6) {
$(this.popup.element).css({ 'padding-bottom': '30px' });
}
else {
$(this.popup.element).css({ 'padding-bottom': '0' });
}
DropDownList.fn.open.call(this);
//hook on to popup event because dropdown close does not
//fire consistently when user clicks on some other elements
//like a dataviz chart graphic
this.popup.one('close', $.proxy(this._onPopupClosed, this));
},
_onPopupClosed: function () {
this._removeSelectAllItem();
this._current = null;
this._raiseSelectionChanged();
},
_raiseSelectionChanged: function () {
var currentValue = this.value();
var currentValues = $.map((currentValue.length > 0 ? currentValue.split(",") : []).sort(), function (item) { return item.toString(); });
var oldValues = $.map((this._oldValue || []).sort(), function (item) { return item ? item.toString() : ''; });
// store for next pass
this._oldValue = $.map(currentValues, function (item) { return item.toString(); });
var changedArgs = { newValue: currentValues, oldValue: oldValues };
if (oldValues) {
var hasChanged = ($(oldValues).not(currentValues).length == 0 && $(currentValues).not(oldValues).length == 0) !== true;
if (hasChanged) {
//if (this.options.selectionChanged)
// this.options.selectionChanged(changedArgs);
this.trigger(SELECTIONCHANGED, changedArgs);
}
}
else if (currentValue.length > 0) {
//if (this.options.selectionChanged)
// this.options.selectionChanged(changedArgs);
this.trigger(SELECTIONCHANGED, changedArgs);
}
},
_addSelectAllItem: function () {
if (!this.options.showSelectAll) return;
var firstListItem = this.ul.children('li:first');
if (firstListItem.length > 0) {
this.selectAllListItem = $('<li tabindex="-1" role="option" unselectable="on" class="k-item ' + SELECTALLITEM + '"></li>').insertBefore(firstListItem);
// fake a data object to use for the template binding below
var selectAllData = {};
selectAllData[this.options.dataValueField || 'data'] = '*';
selectAllData[this.options.dataTextField || 'data'] = 'All';
this.selectAllListItem.html(this.options.template(selectAllData));
this._updateSelectAllItem();
this._makeUnselectable(); // required for IE8
}
},
_removeSelectAllItem: function () {
if (this.selectAllListItem) {
this.selectAllListItem.remove();
}
this.selectAllListItem = null;
},
_focus: function (li) {
if (this.popup.visible() && li && this.trigger(SELECT, { item: li })) {
this.close();
return;
}
this.select(li);
},
_keydown: function (e) {
// currently ignore Home and End keys
// can be added later
if (e.keyCode == kendo.keys.HOME ||
e.keyCode == kendo.keys.END) {
e.preventDefault();
return;
}
DropDownList.fn._keydown.call(this, e);
},
_keypress: function (e) {
// disable existing function
},
_move: function (e) {
var that = this,
key = e.keyCode,
ul = that.ul[0],
down = key === keys.DOWN,
pressed;
if (key === keys.UP || down) {
if (down) {
if (!that.popup.visible()) {
that.toggle(down);
}
if (!that._current) {
that._current = ul.firstChild;
} else {
that._current = ($(that._current)[0].nextSibling || that._current);
}
} else {
//up
// only if anything is highlighted
if (that._current) {
that._current = ($(that._current)[0].previousSibling || ul.firstChild);
}
}
if (that._current) {
that._scroll(that._current);
}
that._highlightCurrent();
e.preventDefault();
pressed = true;
} else {
pressed = DropDownList.fn._move.call(this, e);
}
return pressed;
},
selectAll: function () {
var unselectedItems = this._getUnselectedListItems();
this._selectItems(unselectedItems);
// todo: raise custom event
},
unselectAll: function () {
var selectedItems = this._getSelectedListItems();
this._selectItems(selectedItems); // will invert the selection
// todo: raise custom event
},
_selectItems: function (listItems) {
var that = this;
$.each(listItems, function (i, item) {
var idx = ui.List.inArray(item, that.ul[0]);
that.select(idx); // select OR unselect
});
},
_selectItem: function () {
// method override to prevent default selection of first item, done by normal dropdown
var that = this,
options = that.options,
useOptionIndex,
value;
useOptionIndex = that._isSelect && !that._initial && !options.value && options.index && !that._bound;
if (!useOptionIndex) {
value = that._selectedValue || options.value || that._accessor();
}
if (value) {
that.value(value);
} else if (that._bound === undefined) {
that.select(options.index);
}
},
_select: function (li) {
var that = this,
value,
text,
idx;
li = that._get(li);
if (li && li[0]) {
idx = ui.List.inArray(li[0], that.ul[0]);
if (idx > -1) {
if (li.hasClass(SELECTED)) {
li.removeClass(SELECTED);
that._uncheckItem(li);
if (this.selectAllListItem && li[0] === this.selectAllListItem[0]) {
this.unselectAll();
}
} else {
li.addClass(SELECTED);
that._checkItem(li);
if (this.selectAllListItem && li[0] === this.selectAllListItem[0]) {
this.selectAll();
}
}
if (this._open) {
that._current(li);
that._highlightCurrent();
}
var selecteditems = this._getSelectedListItems();
value = [];
text = [];
$.each(selecteditems, function (indx, item) {
var obj = $(item).children("span").first();
value.push(obj.attr("data-value"));
text.push(obj.text());
});
that._updateSummary(text);
that._updateSelectAllItem();
that._accessor(value, idx);
// todo: raise change event (add support for selectedIndex) if required
that._raiseSelectionChanged();
}
}
},
_getAllValueListItems: function () {
if (this.selectAllListItem) {
return this.ul.children("li").not(this.selectAllListItem[0]);
} else {
return this.ul.children("li");
}
},
_getSelectedListItems: function () {
return this._getAllValueListItems().filter("." + SELECTED);
},
_getUnselectedListItems: function () {
return this._getAllValueListItems().filter(":not(." + SELECTED + ")");
},
_getSelectedItemsText: function () {
var text = [];
var selecteditems = this._getSelectedListItems();
$.each(selecteditems, function (indx, item) {
var obj = $(item).children("span").first();
text.push(obj.text());
});
return text;
},
_updateSelectAllItem: function () {
if (!this.selectAllListItem) return;
// are all items selected?
if (this._getAllValueListItems().length == this._getSelectedListItems().length) {
this._checkItem(this.selectAllListItem);
this.selectAllListItem.addClass(SELECTED);
}
else {
this._uncheckItem(this.selectAllListItem);
this.selectAllListItem.removeClass(SELECTED);
}
},
_updateSummary: function (itemsText) {
if (!itemsText) {
itemsText = this._getSelectedItemsText();
}
if (itemsText.length == 0) {
this._inputWrapper.addClass(EMPTYSELECTION);
this.text(this.options.emptySelectionLabel);
return;
} else {
this._inputWrapper.removeClass(EMPTYSELECTION);
}
if (itemsText.length <= this.options.preSummaryCount) {
this._textAccessor(itemsText.join(", "));
}
else {
this._textAccessor(itemsText.length + ' selected');
}
},
_checkItem: function (itemContainer) {
if (!itemContainer) return;
itemContainer.children("input").prop("checked", true);
},
_uncheckItem: function (itemContainer) {
if (!itemContainer) return;
itemContainer.children("input").removeAttr("checked");
},
_isItemChecked: function (itemContainer) {
return itemContainer.children("input:checked").length > 0;
},
value: function (value) {
if(value != undefined)
console.log("value", value);
var that = this,
idx,
valuesList = [];
if (value !== undefined) {
if (!$.isArray(value)) {
valuesList.push(value);
this._oldValue = valuesList; // to allow for selectionChanged event
}
else {
valuesList = value;
this._oldValue = value; // to allow for selectionChanged event
}
// clear all selections first
$(that.ul[0]).children("li").removeClass(SELECTED);
$("input", that.ul[0]).removeAttr("checked");
$.each(valuesList, function (indx, item) {
var hasValue;
if (item !== null) {
item = item.toString();
}
that._selectedValue = item;
hasValue = value || (that.options.optionLabel && !that.element[0].disabled && value === "");
if (hasValue && that._fetchItems(value)) {
return;
}
idx = that._index(item);
if (idx > -1) {
that.select(
that.options.showSelectAll ? idx + 1 : idx
);
}
});
that._updateSummary();
}
else {
var selecteditems = this._getSelectedListItems();
return $.map(selecteditems, function (item) {
var obj = $(item).children("span").first();
return obj.attr("data-value");
}).join();
}
},
});
ui.plugin(MultiSelectBox);
})(jQuery);
UPDATE
I came across documentation for multiselectbox's select event that clearly states that the select event is not fired when an item is selected programmatically. Is it relevant to what I am trying to do? But why is it firing for one of the filters even though I am setting them programmatically?
enter link description here

Autodesk Forge - Isolating element: amount of transparency of others

When we isolate an element in a 3d view, is there anyway to control the amount of transparency of all the other elements? Say, change to 50% translucent?
Have I missed something obvious?
And can you do the same for 2d views?
I dug out the following code for you, it shows how to set all leaf nodes to 50% opacity by changing their material properties:
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
function getLeafNodes(model, nodeId) {
return new Promise((resolve, reject)=>{
try{
var leafIds = [];
var instanceTree = model.getData().instanceTree
nodeId = nodeId || instanceTree.getRootId()
function _getLeafNodesRec(id){
var childCount = 0;
instanceTree.enumNodeChildren(id,
function(childId) {
_getLeafNodesRec(childId)
++childCount
})
if(childCount == 0){
leafIds.push(id)
}
}
_getLeafNodesRec(nodeId)
return resolve(leafIds)
} catch(ex){
return reject(ex)
}
})
}
function nodeIdToFragIds(model, nodeId) {
var instanceTree = model.getData().instanceTree
var fragIds = []
instanceTree.enumNodeFragments(
nodeId, (fragId) => {
fragIds.push(fragId)
});
return fragIds
}
Autodesk.ADN.Viewing.Extension.Basic = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _this = this;
_this.load = function () {
var fragList = viewer.model.getFragmentList()
getLeafNodes(viewer.model).then((dbIds) => {
dbIds.forEach((dbId) => {
const fragIds = nodeIdToFragIds(
viewer.model, dbId)
fragIds.forEach((fragId) => {
var material = fragList.getMaterial(fragId)
if(material) {
material.opacity = 0.5
material.transparent = true
material.needsUpdate = true
}
})
})
viewer.impl.invalidate(true, true, true)
})
return true;
};
_this.unload = function () {
Autodesk.Viewing.theExtensionManager.unregisterExtension(
"Autodesk.ADN.Viewing.Extension.Basic");
return true;
};
};
Autodesk.ADN.Viewing.Extension.Basic.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.Basic.prototype.constructor =
Autodesk.ADN.Viewing.Extension.Basic;
Autodesk.Viewing.theExtensionManager.registerExtension(
"Autodesk.ADN.Viewing.Extension.Basic",
Autodesk.ADN.Viewing.Extension.Basic);
Some syntax requires ES6 transpiling. You can quickly paste the code there to test it: http://viewer.autodesk.io/node/gallery/#/extension-editor?id=560c6c57611ca14810e1b2bf
This works only for 3D, I'll see what we can do for 2D and update that topic.

Google Api Nearby Places on change of type, layer removed, but advertising stays, how can I remove the complete layer without reloading the page

I have custom code to create a nearby search of places on google map.
Each search type creates a new layer, removed when selecting a different search type, my problem is, even thought he layer is removed, here in Thailand we have "Google partners advertising" show dependant on the search type and this "Layer" doesnt get removed, but added to when creating a new search layer.
This is the code I use to create the search (in part):
Creating a layer (Google):
<div id="map_layers_google">
<input type="checkbox" name="map_google" id="map_google_restaurant" class="box" onclick="Propertywise.Maps.getDataWithinBounds('google_restaurant');" value="google_restaurant">
</div>
getDataWithinBounds: function(layer_name, except_this_area) {
if (!Propertywise.Design.is_ie8_or_less) {
this.layers_on_map[layer_name] = true;
this.getEntitiesWithinBounds(layer_name);
}
getEntitiesWithinBounds: function(entity_name) {
var $this = this;
if (!this.getBounds()) {
setTimeout(function() {
$this.getEntitiesWithinBounds(entity_name);
}, 20);
} else {
var layer_name, category;
var $this_input_el = jQuery("#map_" + entity_name);
jQuery("#map_updating").fadeIn('fast');
if (entity_name.indexOf('google') != -1) {
layer_name = "google";
category = entity_name.replace("google_", "");
} else if (entity_name.indexOf('school') != -1) {
layer_name = "schools";
category = entity_name.replace("schools_", "");
} else if (entity_name.indexOf('events') != -1) {
layer_name = "events";
category = entity_name.replace("events_", "");
} else {
layer_name = "transport";
this.toggleTransitLayer();
}
jQuery("#map_layers_" + layer_name + " input").each(function(index, value) {
var el_id = jQuery(this).attr("id");
var el_entity_name = el_id.replace("map_", "");
Propertywise.Maps.layers_on_map[el_entity_name] = false;
if (jQuery(this).is(":checked") && el_entity_name != entity_name) {
jQuery(this).attr("checked", false);
}
if (jQuery(this).is(":checked") && el_entity_name == entity_name) {
Propertywise.Maps.layers_on_map[entity_name] = true;
}
});
if (jQuery("#map_" + entity_name).is(':checked') || Propertywise.this_page == "school") {
if (layer_name == "google") {
infoWindow = new google.maps.InfoWindow();
Propertywise.Maps.removeMarkers(layer_name);
var request = {
bounds: Propertywise.Maps.map.getBounds(),
types: [category]
};
service = new google.maps.places.PlacesService(Propertywise.Maps.map);
service.radarSearch(request, function(results, status) {
jQuery("#map_updating").fadeOut('fast');
if (status != google.maps.places.PlacesServiceStatus.OK) {
return;
}
for (var i = 0, result; result = results[i]; i++) {
Propertywise.Maps.createMarker(result.geometry.location.lat(), result.geometry.location.lng(), {
place: result,
type: category
});
}
});
}
} else {
this.removeMarkers(layer_name);
jQuery("#map_updating").fadeOut('fast');
}
}
}
And this is the setup and remove each layer:
setUpLayers: function() {
var $this = this;
jQuery.each(this.layers, function(layer_name, value) {
Propertywise.Ajax.requests[layer_name] = [];
$this.layers[layer_name] = [];
});
},
removeMarkers: function(layer_name) {
if (Propertywise.Maps.map) {
var layer = this.layers[layer_name];
for (var i = 0; i < layer.length; i++) {
layer[i].setMap(null);
}
layer = [];
}
}
Here is link to screen shot of the problem.
screenshot
Question is, can anyone help with either changing the above to remove the complete layer(not just marker layer) or advise how to remove the advertising.. I understand this is part of terms of Google to display, but its unprofessional and looks terrible.
Best
Malisa