Search code examples
autodesk-forgeautodesk-viewer

Is it possible to get the name of saved views of nwd models in Forge?


I'm aware that it's possible to get the cameras from saved views in the Navisworks models, but it would be great to get the names as well. When uploading a nwd file to a BIM 360 Document Management project these saved views are shown. Is it possible to do this with the Froge viewer as well? Or is this a Document Manager feaure only? Regards Frode


Solution

  • The saved views in Navisworks files are fetchable with viewpoint names inside the response of the GET:urn/manifest. Here is an example from the Revit house sample model, rac_basic_sample_project.rvt exported as rac_basic_sample_project.nwc, see the folder type folder JSON object:

    enter image description here

    {
        "guid": "dc74c06c-0818-46c3-b9cd-6f9666468d12",
        "type": "view",
        "role": "3d",
        "name": "Default",
        "status": "success",
        "camera": [
            -37.01164245605469,
            -573.8855590820312,
            10.432775497436523,
            -37.01164245605469,
            -101.42298889160156,
            10.432775497436523,
            0,
            -2.220446049250313e-16,
            1,
            1,
            0.785398006439209,
            1,
            0
        ],
        "useAsDefault": true,
        "hasThumbnail": "true",
        "children": [
            {
                "guid": "59d18972-95cb-4845-a116-55a92e3c7ac3",
                "type": "resource",
                "urn": "urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bGt3ZWo3eHBiZ3A2M3g0aGwzMzV5Nm0yNm9ha2dnb2YyMDE3MDUyOHQwMjQ3MzIzODZ6L3JhY19iYXNpY19zYW1wbGVfcHJvamVjdC5ud2M/output/0/0_100.png",
                "role": "thumbnail",
                "mime": "image/png",
                "resolution": [
                    100,
                    100
                ]
            },
            {
                "guid": "14607723-303c-476a-ac39-8f66cac8f4bf",
                "type": "resource",
                "urn": "urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bGt3ZWo3eHBiZ3A2M3g0aGwzMzV5Nm0yNm9ha2dnb2YyMDE3MDUyOHQwMjQ3MzIzODZ6L3JhY19iYXNpY19zYW1wbGVfcHJvamVjdC5ud2M/output/0/0_200.png",
                "role": "thumbnail",
                "mime": "image/png",
                "resolution": [
                    200,
                    200
                ]
            },
            {
                "guid": "d7fd06cb-4ef5-48df-9e27-297343bf107a",
                "type": "resource",
                "urn": "urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bGt3ZWo3eHBiZ3A2M3g0aGwzMzV5Nm0yNm9ha2dnb2YyMDE3MDUyOHQwMjQ3MzIzODZ6L3JhY19iYXNpY19zYW1wbGVfcHJvamVjdC5ud2M/output/0/0_400.png",
                "role": "thumbnail",
                "mime": "image/png",
                "resolution": [
                    400,
                    400
                ]
            }
        ]
    },
    {
        "guid": "cccca659-8638-4e8d-9554-223f7cc4a23b",
        "type": "folder",
        "name": "3D View",
        "role": "viewable",
        "hasThumbnail": "false",
        "status": "success",
        "progress": "0% complete",
        "children": [
            {
                "guid": "3dc842c3-acf9-4921-8d54-ffebf86500d1",
                "type": "view",
                "role": "3d",
                "name": "Kitchen",
                "camera": [
                    -71.70982360839844,
                    -77.9845199584961,
                    4.921259880065918,
                    10.964564323425293,
                    -15.158869743347168,
                    4.921259880065918,
                    4.996003610813204e-16,
                    -4.440892098500626e-16,
                    1,
                    1,
                    0.9272952079772949,
                    1,
                    0
                ],
                "status": "success"
            },
            {
                "guid": "716c2341-af18-4866-9fb7-57a27ff811d3",
                "type": "view",
                "role": "3d",
                "name": "From Yard",
                "camera": [
                    -98.73897552490234,
                    -169.06787109375,
                    0,
                    -42.515201568603516,
                    -44.77614212036133,
                    -1.609189127435573e-14,
                    0,
                    1.1102230246251565e-16,
                    1,
                    1,
                    0.9272952079772949,
                    1,
                    0
                ],
                "status": "success"
            },
            {
                "guid": "1466f07a-5536-4acd-bb51-ee228fb6a41e",
                "type": "view",
                "role": "3d",
                "name": "Living Room",
                "camera": [
                    -31.575815200805664,
                    -51.19736862182617,
                    0.9842519760131836,
                    38.432044982910156,
                    -143.84164428710938,
                    0.9842519760131836,
                    -5.0237591864288333e-14,
                    -3.735900477863652e-14,
                    1,
                    1,
                    0.9272952079772949,
                    1,
                    0
                ],
                "status": "success"
            },
            {
                "guid": "68ffe8dc-9a9c-45a5-aaf5-29221dd38771",
                "type": "view",
                "role": "3d",
                "name": "Approach",
                "camera": [
                    -41.0597038269043,
                    38.65303039550781,
                    32.80839920043945,
                    -49.91415786743164,
                    -107.17664337158203,
                    9.272088050842285,
                    -0.009639321826398373,
                    -0.15875616669654846,
                    0.9872707724571228,
                    1,
                    0.9272952079772949,
                    1,
                    0
                ],
                "status": "success"
            },
            {
                "guid": "4c8b4f68-7010-47eb-a3e3-3aa699e82674",
                "type": "view",
                "role": "3d",
                "name": "Section Perspective",
                "camera": [
                    8.170970916748047,
                    29.014333724975586,
                    5.741469860076904,
                    -82.0259780883789,
                    -107.69042205810547,
                    5.741469860076904,
                    7.771561172376096e-16,
                    2.914335439641036e-16,
                    1,
                    1,
                    0.9272952079772949,
                    1,
                    0
                ],
                "status": "success"
            },
            {
                "guid": "33f941f3-81d1-41c5-82e5-346731d79f34",
                "type": "view",
                "role": "3d",
                "name": "Solar Analysis",
                "camera": [
                    62.19073486328125,
                    -142.4400634765625,
                    161.65139770507812,
                    -32.913902282714844,
                    -97.60645294189453,
                    8.838506698608398,
                    -0.7451809644699097,
                    0.3512883186340332,
                    0.5668349266052246,
                    1,
                    45,
                    273.4084777832031,
                    1
                ],
                "status": "success"
            },
            {
                "guid": "41b33c50-bcdf-4f57-8101-5f8af6ece8eb",
                "type": "view",
                "role": "3d",
                "name": "{3D}",
                "camera": [
                    -104.73332977294922,
                    -202.08343505859375,
                    67.68977355957031,
                    -103.85852813720703,
                    -103.78852081298828,
                    5.5336480140686035,
                    0.004756217356771231,
                    0.5344184637069702,
                    0.8452067375183105,
                    1,
                    45,
                    424.3688049316406,
                    1
                ],
                "status": "success"
            }
        ]
    } 
    

    Now we use the Kitchen view to illustrate the workflow:

    {
        "guid": "3dc842c3-acf9-4921-8d54-ffebf86500d1",
        "type": "view",
        "role": "3d",
        "name": "Kitchen",
        "camera": [
            -71.70982360839844,
            -77.9845199584961,
            4.921259880065918,
            10.964564323425293,
            -15.158869743347168,
            4.921259880065918,
            4.996003610813204e-16,
            -4.440892098500626e-16,
            1,
            1,
            0.9272952079772949,
            1,
            0
        ],
        "status": "success"
    } 
    

    First, let's convert it from original model space into the viewer's:

    const nwVP = JSON.parse( // the above JSON );
    const camera = nwVP.camera;
    const nwVPName = nwVP.name;
    
    const placementWithOffset = viewer.model.getData().placementWithOffset;
    
    const pos = new THREE.Vector3( camera[0], camera[1], camera[2] );
    const target = new THREE.Vector3( camera[3], camera[4], camera[5] );
    const up = new THREE.Vector3( camera[6], camera[7], camera[8] );
    const aspect = camera[9];
    const fov = camera[10] / Math.PI * 180;
    const orthoScale = camera[11];
    const isPerspective = !camera[12];
    
    const offsetPos = pos.applyMatrix4( placementWithOffset );
    const offsetTarget = target.applyMatrix4( placementWithOffset );
    
    const nwSavedViewpoints = [];
    nwSavedViewpoints.push(
        {
            aspect: aspect,
            isPerspective: isPerspective,
            fov: fov,
            position: offsetPos,
            target: offsetTarget,
            up: up,
            orthoScale: orthoScale,
            name: nwVPName
        }
    );
    

    Afterward, switch the viewpoint by

    viewer.impl.setViewFromCamera( nwSavedViewpoints[0] );
    

    Lastly, you may be aware the above converted camera definition will have the almost same value (floating precision issue) as viewer.model.getData().cameras[1]

    enter image description here enter image description here

    Hope it helps!

    Cheers,

    Updates for sectioning mapping

    If your saved viewpoint contains a section plane, the response of GET:urn/manifest would have something like this:

    {
        "guid": "54794b24-d9ef-4a1a-b5aa-8bbf35de2c55",
        "type": "view",
        "role": "3d",
        "name": "Section Test",
        "camera": [
            -264.2721252441406,
            -79.92520141601562,
            148.0021209716797,
            -42.678688049316406,
            -73.8739013671875,
            0.7752543091773987,
            0.5530436635017395,
            0.01510258112102747,
            0.8330153822898865,
            1.4948216676712036,
            0.785398006439209,
            1,
            0
        ],
        "sectionPlane": [
            -0.803684066258349,
            -0.5950562340169588,
            0,
            -92.04215879314862
        ],
        "status": "success"
    } 
    

    The sectionPlane attribute is the target we want. So, the conversion is

    const forge_model_offset = viewer.model.getData().globalOffset;
    
    // assume the param of Navisworks clip plane is available
    //I copied from the response of the GET:urn/manifest
    const navis_clip_plane = { x: -0.803684066258349, y: -0.5950562340169588, z: 0,d:-92.04215879314862 };
    
    //calculate exact distance in Forge Viewer
    const dis_in_forge =( forge_model_offset.x * navis_clip_plane.x  +   
                            forge_model_offset.y * navis_clip_plane.y + 
                            forge_model_offset.z * navis_clip_plane.z) + navis_clip_plane.d;
    
    const cutplanes = [
        new THREE.Vector4( navis_clip_plane.x, navis_clip_plane.y, navis_clip_plane.z, dis_in_forge ) 
    ];
    
    //apply the plane to sectioning
    viewer.setCutPlanes( cutplanes )