How can I use setDisplayEdges() for multi-model loading? - autodesk-forge

I would like to turn the BIM edges on for all models. I have set setDisplayEdges(true) during the initialization of the viewer as well as adding isAEC: true to the options in loadModel().
Unfortunately, this does not display the edges.
How do you recommend turning on the edges for multi-model loading?

I'm not sure which model format your road model is, but passing the createWireframe: true option should help turn on the model edges with my research.
viewer.loadDocumentNode(doc, bubble, {createWireframe: true, keepCurrentModels: true})

Related

Check if Model has any default hidden elements in Forge's 3D Viewer

Some background:
I'm using Forge to visualize IFC models. Some of my uploaded models have IfcOpeningElements which seems to be hidden in Forge by default, at least when setting ghosting to false via viewer.setGhosting(false). I'm also having functionality to hide normal elements in the viewer (viewer.hide(dbIds, model)), and to show/hide all elements (model.setAllVisibility(show)).
The problem I'm having is that I want to be able to show/hide the IfcOpeningElements regardless of showing and hiding "normal" elements.
The approach I tried, which is not working very well is to call model.visibilityManager.getHiddenNodes(). The problem with this approach is that, even for models with IfcOpeningElements, getHiddenNodes only returns a non-empty array after ~15 seconds (probably varies with the size of the model). In the meantime, if the user does anything that makes the app call model.setAllVisibility(true), I'm no longer able to detect the original hidden IfcOpeningElements.
Furthermore, when calling getHiddenNodes after an arbitrary waiting period after the model has loaded, I'm not sure if it returns an empty array because the model is not "ready" to detect hidden elements from IfcOpeningElements or if the model simply does not have any IfcOpeningElements.
So, Is there any good way to detect if a model has any "default" hidden elements without having to wait long after the model is loaded? Or perhaps there is a way to call change the visibility of the entire model without changing the visibility of the IfcOpeningElements?
I'm aware of the possibility to listen to the HIDE_EVENT event, but since I'm not sure if it will fire at all (since I'm not sure if the model has any IfcOpeningElements), I cannot block the application from calling model.setAllVisibility(true) which in turn would make getHiddenNodes() return an empty array even if there was hidden elements to begin with.
How about just skipping loading IfcOpeningElements' geometries? To do so, pass skipHiddenFragments: true to the 3rd argument of Viewer3D#loadDocumentNode
viewer.loadDocumentNode(
doc,
viewable,
{
skipHiddenFragments: true
}
);
This approach will skip loading the IfcOpeningElements' meshes, but you can still see their properties while selecting IfcOpeningElements on the model structure panel. On the other hand, you cannot access their bounding boxes and geometries with this approach.
Regarding how to check default hidden elements, try to call this code after all geometries are loaded. The hiddenDbIds are elements hidden by default.
let model = viewer.getAllModels()[0]; //!<< Check the first model just for demo
let fragList = model.getFragmentList();
let hiddenDbIds = Object.keys( fragList.vizflags ).filter(fragId => !fragList.isFragVisible( fragId )).map(fragId => fragList.getDbIds( fragId ) );
// hiddenDbIds.forEach(dbId => viewer.getProperties(dbId, console.log))
Note. The visible flag will also be changed after changing the objects' visibility. So, ensure that run the above before changing the visibilities.

Is it possible to set snap settings?

I'm using the Autodesk Forge viewer v7 using the Edit2D tool. This question is specifically about the snapping functionality. It is currently working but a bit overzealous... It seems to have all of the possible snaps on (endpoint, along line, intersections, centers, etc.). It also seems to snap to layers that I have hidden.
Is there a way to set the snaps that are on and off? Also is there a way to limit the layers that it snaps to? I was looking for possibly a method that will tell me the object(s) it's trying to snap to and the type of snap and let me determine if that's a viable snap point and return true/false or something like that but I couldn't find one. Is there a way to do this?
EDIT
I did find setSnapFilter but it doesn't seem to do anything. I have this implementation in my code:
// #ts-ignore
e.defaultContext.snapper.sheetSnapper.setSnapFilter((e) => {
console.log(e);
return false;
});
However, I never get a console log happening. I have tried this on both the sheet snapper and the layer snapper and I've tried returning both true and false and none of them are ever called or make any difference to the snapping.
Good catch! The context.snapper.sheetSnapper object does have a setSnapFilter method you can override. Unfortunately, this filter is only invoked in the Snapper#onMouseMove method, and the Edit2D extension bypasses this method. That's why overriding the method has no effect. Let me pass this info to the engineering team for consideration.

Forge Viewer poor rendering quality

I'm using the Forge Viewer to display some models converted from IFC (2x3) files.
For some of them, the quality is perfect, but for others the rendering is very poor like the picture bellow.
I've tried to export in SVF, SVF2 and same result.
I've tired different settings to load the model
let config = {
keepCurrentModels: true,
applyScaling: { to: "m" },
applyRefPoint: true,
globalOffset: { x: 0, y: 0, z: 0 }}; //make the view flicker on weird rendered model
None of those settings improved the view except globalOffset who makes the view flicker.
Have you any idea how to fix this ?
This kind of deformation of geometries is typically an indication that the model is very far from the origin. So far that the GPU rendering starts running into floating point precision issues.
Loading the model with globalOffset: new THREE.Vector3(0, 0, 0) should help in this case as it would basically force the viewer not to re-apply the original global offset (which is potentially very large) to all geometry vertices. I'm not sure why the view would flicker after using this option, though, that might be a separate issue.

Autodesk Forge Viewer: how to set object occlusion

I'm playing around with the Autodesk forge viewer and adding custom elements, like it is done in the Autodesk's scene builder example.
I am looking for a possibility to set the "visibility" of one of the new objects - e.g. when moving around the camera, the green cube should remain on it's 3D-position but should not be occluded by any other object (like it is somehow in blue with outline when it is selected). Or maybe even better: if it is covered by another object, it should shine through (with configurable opacity).
Unfortunately after discussing with Engineering it's not yet possible - will continue the conversation to see if we could come up with a workaround for the upcoming releases ...
Like I suggested in the comments try append your geometry to Viewer3DImpl.sceneAfter for the time being (which will be publicly documented and exposed as Viewer3D.sceneAfter in a couple of weeks) or an overlay. Then setting depthTest to false should do what you want...
The choice of sceneAfter or an overlay depends on how you want the objects to be drawn during progressive rendering. sceneAfter is only drawn once at the end of everything else. Overlays are redrawn for each progressive frame...

Triangle edges in CanvasRenderer

I am a newbie regarding three.js and I have a problem with imported geometry (js-file from 3dsmax inclusive all material and textures) and the CanvasRenderer. The CanvasRenderer displays the triangle edges of imported geometry, the WebGLRenderer works well.
Canvas example:
http://der-n.square7.ch/threejs/examples/teapot_canvas.html
WebGL example:
http://der-n.square7.ch/threejs/examples/teapot_webgl.html
In the three.js library I have found the option "overdraw: true" for a material to fix this behaviour but obviously the material+textures are defined by the above mentioned exported 3dsmax js-file.
For the tests I use the "misc_camera_trackball" example with small changes (I have added a JSONLoader, changed some camera and trackball parameters, changed some light colors, added a CanvasRenderer)
Any hints how to solve this?
Thanks for your help.
Best regards
Oggy
In the loader callback, you have all of the loaded materials in an array geometry.materials. You could loop over those materials and set the overdraw property to true for each.
As far as I know, THREE.MeshFaceMaterial is just a pass-through material that indicates "faces have an index that points to a material instance to use from the geometry's materials array", so setting properties for MeshFaceMaterial won't have any effect.