0

I am trying to display a point on model displayed in the Autodesk forge viewer. However I am unable to figure out how to transform the point.

The answer Aligning Coordinate Systems in Autodesk Forge Viewer doesn't work for me because viewer.model.getData() doesn't have a globalOffset property.

I have uploaded some example code along with the original dwg file here https://github.com/umarmohammed/forgeviewerdemo

nodd13
  • 158
  • 1
  • 7

1 Answers1

1

Sorry, I haven't received any responses from our engineering team. There seems not to have another way to obtain viewportId of current 2d view, and might have floating precision issue here, this is the issue I mentioned above. I will keep asking for them. So, here is the way I found to do point transformation from DWG coordinate system to the Viewers'.

  1. Obtain current viewport id via VertexBufferReader, but you have to specify a 2d item(dbId) in the loaded view to read viewportId from it.

    var viewportId = null;
    function GeometryCallback(viewer) {
        this.viewer = viewer;
    }
    
    GeometryCallback.prototype.onLineSegment = function(x1, y1, x2, y2, vpId) {
        viewportId = vpId;
    }
    
    var fragId = 0;
    var m = viewer.impl.getRenderProxy(viewer.model, fragId);
    var vbr = new Autodesk.Viewing.Private.VertexBufferReader(m.geometry, viewer.impl.use2dInstancing);
    vbr.enumGeomsForObject(dbId, new GeometryCallback());
    
  2. Project DWG point back to Viewer coordinate system.

    var vpXform = viewer.model.getPageToModelTransform(viewportId).clone();
    var invVpXform = new WGS.LmvMatrix4(true);
    
    invVpXform.getInverse(vpXform, true);
    
    var ptInCadX = ...;
    var ptInCadY = ...;
    var verticesInViewer = new THREE.Vector3().set(ptInCadX, ptInCadY, 0).applyMatrix4(invVpXform);
    

Hope it helps.

Eason Kang
  • 6,155
  • 1
  • 7
  • 24
  • I'm unsure how to get the dbId and fragId. In my example would the correct dbId be `viewer.model.getData().instanceTree.nodeAccess.rootId`? How do I get the fragId from the dbId? – nodd13 Jun 08 '18 at 13:57
  • Select an item on the 2D view of the Viewer, and call `viewer.getSelection()` to get `dbId`. Afterward, `var it = viewer.model.getData().instanceTree; it.enumNodeFragments( dbId, function( fragId ) { console.log( fragId ) })` – Eason Kang Jun 09 '18 at 06:49
  • There is another way to obatin the instancTree, `viewer.getObjectTree(function( it ) { console.log( it ) }, functio( code, msg ) { console.error( code, msg ) })` – Eason Kang Jun 09 '18 at 06:51
  • getting the dbId and fragId inside the `Autodesk.Viewing.SELECTION_CHANGED_EVENT` handler works perfectly. However I need to perform the transformation when model is loaded. The way I did this was to call `viewer.select(dbId, Autodesk.Viewing.SelectionMode.REGULAR)` inside the `Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT`. I have updated the code on my github repository to demonstrate this. However this is a very convoluted way of doing this. Is there a simpler way to do the transformation when the model is loaded? Preferably one that doesn't involve selecting an item first. – nodd13 Jun 13 '18 at 11:16
  • 1
    If you want to transform the model while loaded, you can try to pass this option to `Viewer3D#loadModel`: `const modelOpts = { placementTransform: new THREE.Matrix4().makeTranslation( x1, y1, z1 ), globalOffset: { x: 0, y: 0, z: 0 } }; ` – Eason Kang Jun 13 '18 at 11:21