autodesk-forgeautodesk-viewerautodeskautodesk-model-derivativeautodesk-bim360

Forge Viewer `restoreState` Not Loading Full Building View


I need your support regarding a persistent issue with the Forge Viewer’s restoreState functionality. While restoring isolated or partial views works as expected, attempting to restore the full building view does not reset the model to its full extent - only the camera angle adjusts.

Issue Summary:-

We're using Viewer3D.prototype.restoreState with the following state:

{
  "viewport": {
    "name": "",
    "eye": [97.486, -471.15, 0.263],
    "target": [56.671, -454.526, -11.555],
    "up": [-0.239, 0.097, 0.965],
    "worldUpVector": [0, 0, 1],
    "pivotPoint": [41.235, -480.147, 10.035],
    "distanceToOrbit": 44.507,
    "aspectRatio": 2.157,
    "projection": "perspective",
    "isOrthographic": false,
    "fieldOfView": 53.13
  },
  "cutplanes": []
}

What I Observed:- The camera moves to the saved position but does not reset to show the entire building. We also tried calling viewer.navigation.setRequestHomeView(true) prior to restoring the state, but the issue persists. Actual Image

Expected Outcome:- The restoreState call should restore the camera and render the full model view, as defined in the saved state. Expected Image

Environment:- Forge Viewer: v7 Browser:Latest version of Chrome

Questions & Requests:- Are there any additional properties or configurations required to force a full model view upon restoring state?

Additional information:- While initially loading the full building, the viewer state [this properties/configuration I will use later], I am getting by executing - viewer.getState() - :

{
    "seedURN": "dXJuOmFkc2sud2lwcHJvZDpmcyxxxxxxxxxxxxxxxxxxxxxxxx",
    "objectSet": [
        {
            "id": [],
            "idType": "lmv",
            "isolated": [],
            "hidden": [],
            "explodeScale": 0,
            "explodeOptions": {
                "magnitude": 4,
                "depthDampening": 0
            }
        }
    ],
    "viewport": {
        "name": "",
        "eye": [
            226.09607696533203,
            -317.4277467727661,
            439.23504638671875
        ],
        "target": [
            0,
            -9.5367431640625e-7,
            0
        ],
        "up": [
            -0.43396210192451556,
            0.6092613973392196,
            0.663684747305163
        ],
        "worldUpVector": [
            0,
            0,
            1
        ],
        "pivotPoint": [
            0,
            -9.5367431640625e-7,
            0
        ],
        "distanceToOrbit": 587.2028915198275,
        "aspectRatio": 2.0631911532385465,
        "projection": "orthographic",
        "isOrthographic": true,
        "orthographicHeight": 587.2028915198274
    },
    "autocam": {
        "sceneUpDirection": {
            "x": 0,
            "y": 0,
            "z": 1
        },
        "sceneFrontDirection": {
            "x": 0,
            "y": 1,
            "z": 0
        },
        "cubeFront": {
            "x": 1,
            "y": 0,
            "z": 0
        }
    },
    "renderOptions": {
        "environment": "Sharp Highlights",
        "ambientOcclusion": {
            "enabled": true,
            "radius": 10,
            "intensity": 1
        },
        "toneMap": {
            "method": 1,
            "exposure": -9,
            "lightMultiplier": -1e-20
        },
        "appearance": {
            "ghostHidden": true,
            "ambientShadow": true,
            "antiAliasing": true,
            "progressiveDisplay": true,
            "swapBlackAndWhite": false,
            "displayLines": true,
            "displayPoints": true
        }
    },
    "cutplanes": []
}

Then I am moving to another viewport with other saved configurations mentioned below using viewer.restoreState(obj.VPSettings):

{
  "VPSettings": {
    "viewport": {
      "name": "",
      "eye": [
        -174.93813012139444,
        -51.54313712281373,
        84.62760707425494
      ],
      "target": [
        385.5878058504396,
        78.04956499177632,
        -329.4223514589887
      ],
      "up": [
        0.5691298307152718,
        0.13158190885232712,
        0.811651056213681
      ],
      "worldUpVector": [
        0,
        0,
        1
      ],
      "pivotPoint": [
        27.50610384992521,
        -4.738353215044867,
        -64.91413810081784
      ],
      "distanceToOrbit": 256.0021273640002,
      "aspectRatio": 1.402670813586098,
      "projection": "perspective",
      "isOrthographic": false,
      "fieldOfView": 45
    },
    "cutplanes": [
      [
        0,
        0,
        1,
        16.797346115112305
      ]
    ]
  },
  "modelKeys": [
    "2"
  ],
  "globalOffset": {
    "x": -63.65482444526273,
    "y": 7.325177290169762,
    "z": 351.2549213399469
  }
}

Post that, Again I am trying to reload the full building with initial state viewport settings and tried viewer.navigation.setRequestHomeView(true) but it is not working. Thanks, Sudhir


Solution

  • Update:

    The viewer.navigation.setRequestHomeView(true) is just to move the camera to the home (initial) position. It won't reset the cut planes, so it won't help in this case and don't need to call it.

    Here is a test case to simulate your case

    Initial View and its view state (we call it `viewStateInit`)

    enter image description here

    {
      "seedURN": "dXJuOmF.....Q",
      "objectSet": [
        {
          "id": [],
          "idType": "lmv",
          "isolated": [],
          "hidden": [],
          "explodeScale": 0,
          "explodeOptions": {
            "magnitude": 4,
            "depthDampening": 0
          }
        }
      ],
      "viewport": {
        "name": "",
        "eye": [
          -178.21200942993164,
          -232.16726684570312,
          185.06643099304958
        ],
        "target": [
          0,
          0,
          9.011916795031993e-7
        ],
        "up": [
          0.3254195128849335,
          0.4239431401196343,
          0.8452066934065515
        ],
        "worldUpVector": [
          0,
          0,
          1
        ],
        "pivotPoint": [
          0,
          0,
          9.011916795031993e-7
        ],
        "distanceToOrbit": 346.28130709959277,
        "aspectRatio": 2.0657894736842106,
        "projection": "orthographic",
        "isOrthographic": true,
        "orthographicHeight": 346.2813070995928
      },
      "autocam": {
        "sceneUpDirection": {
          "x": 0,
          "y": 0,
          "z": 1
        },
        "sceneFrontDirection": {
          "x": 0,
          "y": 1,
          "z": 0
        },
        "cubeFront": {
          "x": 1,
          "y": 0,
          "z": 0
        }
      },
      "renderOptions": {
        "environment": "Boardwalk",
        "ambientOcclusion": {
          "enabled": true,
          "radius": 13.123359580052492,
          "intensity": 1
        },
        "toneMap": {
          "method": 1,
          "exposure": -7,
          "lightMultiplier": -1e-20
        },
        "appearance": {
          "ghostHidden": true,
          "ambientShadow": true,
          "antiAliasing": true,
          "progressiveDisplay": true,
          "swapBlackAndWhite": false,
          "displayLines": true,
          "displayPoints": true
        }
      },
      "cutplanes": [],
      "floorGuid": null
    }
    

    Second view and its view state (we call it `viewState1`)

    enter image description here

    {
      "viewport": {
        "name": "",
        "eye": [
          -209.42760355867836,
          -261.2734832428057,
          210.66533315776246
        ],
        "target": [
          0.13088874235086223,
          2.9126006436854937,
          -18.420290877392006
        ],
        "up": [
          0.34922401119950036,
          0.44025953281529284,
          0.827172372463558
        ],
        "worldUpVector": [
          0,
          0,
          1
        ],
        "pivotPoint": [
          0.13088874235086223,
          2.9126006436854652,
          -18.420290877392006
        ],
        "distanceToOrbit": 407.6631842027641,
        "aspectRatio": 2.0657894736842106,
        "projection": "perspective",
        "isOrthographic": false,
        "fieldOfView": 45
      },
      "cutplanes": [
        [
          0,
          0,
          1,
          3.9137442111968994
        ]
      ]
    }
    

    After restore `viewState1`, we want to restore it back to `viewStateInit`. We will see the cut planes are not removed like the following:

    enter image description here

    That is because these cut planes are managed by the Autodesk.Section extension, which cannot be clear by viewer.setCutPlanes() , which viewer also uses it in viewer.restoreState( state ). We can call viewer.impl.getCutPlaneSets() to check if there is any other cut plane sets.

    enter image description here

    In this case, we have one called Autodesk.Viewing.Extension.Section.SectionTool created by the Autodesk.Section extension. To remove that, we can do the below:

    viewer.impl.setCutPlaneSet('Autodesk.Viewing.Extension.Section.SectionTool', null)
    
    //Or 
    // viewer.impl.getCutPlaneSets().forEach(cutPlaneSetId => viewer.impl.setCutPlaneSet(cutPlaneSetId, null))
    
    // Note. this one will clear all cut plane sets from other extensions e.g. Autodesk.AEC.LevelsExtension
    

    enter image description here

    =============== ignore below =========

    If I understand the situation correctly, the expected image appears to have some cut planes applied, and the actual one doesn't.

    From the view state you passed, I can see you have an empty array in `cutplanes` that will clear cut planes. If you want to achieve what expected image does, then remove the empty array of `cutplanes` from the view statue.

    viewer.restoreSate({
      "viewport": {
        "name": "",
        "eye": [97.486, -471.15, 0.263],
        "target": [56.671, -454.526, -11.555],
        "up": [-0.239, 0.097, 0.965],
        "worldUpVector": [0, 0, 1],
        "pivotPoint": [41.235, -480.147, 10.035],
        "distanceToOrbit": 44.507,
        "aspectRatio": 2.157,
        "projection": "perspective",
        "isOrthographic": false,
        "fieldOfView": 53.13
      }
    })
    

    Or tell the viewer to restore the camera state only

    viewer.restoreSate({
      "viewport": {
        "name": "",
        "eye": [97.486, -471.15, 0.263],
        "target": [56.671, -454.526, -11.555],
        "up": [-0.239, 0.097, 0.965],
        "worldUpVector": [0, 0, 1],
        "pivotPoint": [41.235, -480.147, 10.035],
        "distanceToOrbit": 44.507,
        "aspectRatio": 2.157,
        "projection": "perspective",
        "isOrthographic": false,
        "fieldOfView": 53.13
      },
      "cutplanes": []
    }, { viewport: true })
    

    ref: https://aps.autodesk.com/en/docs/viewer/v7/reference/Viewing/Viewer3D/#restorestate-viewerstate-filter-immediate