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
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`)
{
"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`)
{
"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:
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.
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
=============== 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 })