I want to show sprites on sheets in Forge Viewer using the same code as for 3D view. This code works perfectly inside 3D views with one or multy-model loaded. But when i open some sheet, sprites are not loaded at all.
I use these events to find elements and add sprites.
viewerInst.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, onGeometryLoaded);
viewerInst.addEventListener(Autodesk.Viewing.MODEL_ADDED_EVENT, onModelAdded);
viewerInst.addEventListener(Autodesk.Viewing.MODEL_UNLOADED_EVENT, onModelUnload);
below is onGeometryLoaded
callback
const onGeometryLoaded = useCallback(
async e => {
const ext = await e.target.loadExtension('Autodesk.DataVisualization');
ext.removeAllViewables();
//remove event listeners to prevent multi event when multy-model loaded
e.target.removeEventListener(Autodesk.DataVisualization.Core.MOUSE_HOVERING, onSpriteHover);
e.target.removeEventListener(Autodesk.DataVisualization.Core.MOUSE_CLICK, onSpriteClick);
//add event listeners to handle sprite click and hover event only once
e.target.addEventListener(Autodesk.DataVisualization.Core.MOUSE_HOVERING, onSpriteHover);
e.target.addEventListener(Autodesk.DataVisualization.Core.MOUSE_CLICK, onSpriteClick);
addSprites(e.target, e.model, prepData.current);
},
[addSprites, handleSearchParams, onSpriteClick, onSpriteHover],
);
below is onModelAdded
callback
const onModelAdded = useCallback(
e => {
//start theme
e.target.setEnvMapBackground(false);
//endtheme
prepData.current = [];
e.target.getAllModels().map(model => {
model.search('Scheduler_3DMarkup', dbIDs => {
dbIDs.map(dbId => {
model.getProperties(dbId, res => {
res.properties.map(el => {
if (el.displayName === 'Scheduler - NF Number') {
const item = needList.find(nf => {
return nf.nf === Number(el.displayValue);
});
prepData.current.push({ dbId, value: item?.status, model: model });
}
});
});
});
});
});
},
[needList],
);
below is onModelUnload
callback
const onModelUnload = useCallback(
async e => {
const ext = await e.target.loadExtension('Autodesk.DataVisualization');
prepData.current = [];
ext.removeAllViewables();
e.target.getAllModels().map(model => {
model.search('Scheduler_3DMarkup', dbIDs => {
dbIDs.map(dbId => {
model.getProperties(dbId, res => {
res.properties.map(el => {
if (el.displayName === 'Scheduler - NF Number') {
const item = needList.find(nf => {
return nf.nf === Number(el.displayValue);
});
prepData.current.push({ dbId, value: item?.status, model: model });
}
});
});
});
});
});
setTimeout(() => {
addSprites(e.target, e.target.model, prepData.current);
}, 100);
},
[addSprites, needList],
);
below addSprite
callback and findViewables
callback for creating sprites
const addSprites = useCallback(
async (viewer, model, dbIDs) => {
const dataVizExtn = await viewer.getExtension('Autodesk.DataVisualization');
const data = await findViewables(model, dbIDs);
dataVizExtn.addViewables(data);
const showViewables = true;
const enableOcclusion = false;
dataVizExtn.showHideViewables(showViewables, enableOcclusion);
viewer.search('');
},
[findViewables],
);
const findViewables = useCallback(async (model, dbIDs) => {
const DataVizCore = Autodesk.DataVisualization.Core;
const viewableType = DataVizCore.ViewableType.SPRITE;
const spriteColor = new THREE.Color(0xffffff);
const style_default = new DataVizCore.ViewableStyle(viewableType, spriteColor, spriteNfDefault);
const style_success = new DataVizCore.ViewableStyle(viewableType, spriteColor, spriteNfSuccess);
const style_warning = new DataVizCore.ViewableStyle(viewableType, spriteColor, spriteNfWarning);
const style_informative = new DataVizCore.ViewableStyle(viewableType, spriteColor, spriteNfInformative);
const style_danger = new DataVizCore.ViewableStyle(viewableType, spriteColor, spriteNfDanger);
const viewableData = new DataVizCore.ViewableData();
viewableData.spriteSize = 40; // Sprites as points of size value pixels
dbIDs.forEach(el => {
el.model.getData().instanceTree.enumNodeFragments(el.dbId, async fragId => {
const frags = el.model.getFragmentList();
let bbox = new THREE.Box3();
frags.getWorldBounds(fragId, bbox);
const center = bbox.getCenter();
const viewable_default = new DataVizCore.SpriteViewable(center, style_default, el.dbId);
const viewable_success = new DataVizCore.SpriteViewable(center, style_success, el.dbId);
const viewable_warning = new DataVizCore.SpriteViewable(center, style_warning, el.dbId);
const viewable_informative = new DataVizCore.SpriteViewable(center, style_informative, el.dbId);
const viewable_danger = new DataVizCore.SpriteViewable(center, style_danger, el.dbId);
if (el.value === 'accepted') {
viewableData.addViewable(viewable_success);
} else if (el.value === 'declined') {
viewableData.addViewable(viewable_danger);
} else if (el.value === 'sent') {
viewableData.addViewable(viewable_informative);
} else if (el.value === 'submitted' || el.value === 'provided') {
viewableData.addViewable(viewable_warning);
} else {
viewableData.addViewable(viewable_default);
}
});
});
await viewableData.finish();
return viewableData;
}, []);
I try to change let bbox = new THREE.Box3();
in find vieweable, try let bbox = new THREE.Box2();
, but it change nothing.
I recheck coordinates that are received in const center = bbox.getCenter();
and there is no z
coordinate (i mean it is 0), but sprites are not shown.
I don't understand the reason why sprites are not shown in sheets.
I had a converstation with Autodesk developer and he provided some articles and aproaches. So i read those articles and update findViewables
function.
we use different methods to find bounds in 2D and 3D views, below is updated part of findViewables
let bbox = new THREE.Box3();
const { role } = model.getDocumentNode().data;
if (role === '2d') {
let boundsCallback = new Autodesk.Viewing.Private.BoundsCallback(bbox);
const mesh = frags.getVizmesh(fragId);
const vbr = new Autodesk.Viewing.Private.VertexBufferReader(mesh.geometry, window.NOP_VIEWER.impl.use2dInstancing);
vbr.enumGeomsForObject(el.dbId, boundsCallback);
}
if (role === '3d') {
frags.getWorldBounds(fragId, bbox);
}
const center = bbox.getCenter();
and now this code works well in 2d and 3d views.