Camera does a weird snap back when isFitView is set to true

Camera does a weird snap back when isFitView is set to true

tykapl.breuil
Advocate Advocate
740 Views
4 Replies
Message 1 of 5

Camera does a weird snap back when isFitView is set to true

tykapl.breuil
Advocate
Advocate

Hello everyone,

 

For an addin I'm working on, I need to use the isFitView property of the camera object. It works fine on it's own but as soon as I add a change to the camera, the camera does a smooth transition to where it should end up, then snaps back to the position without the fitview. Is this a bug or am I missing something ? In the mean time I simply changed my code to update the camera twice, and it looks and works fine.

 

Sample code :

import adsk.core, adsk.fusion, traceback, adsk.cam

# Affectations usuelles
handlers = []
app: adsk.core.Application = adsk.core.Application.get()
ui = app.userInterface

def run(context):
    try:
        viewport = app.activeViewport
        camera = viewport.camera
        camera.isFitView = True
        camera.viewOrientation = adsk.core.ViewOrientations.IsoTopRightViewOrientation
        viewport.camera = camera
    
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Attached is a gif showing what happens on a model (the model is just a basic cube).

 

0 Likes
Accepted solutions (2)
741 Views
4 Replies
Replies (4)
Message 2 of 5

kandennti
Mentor
Mentor

Hi @tykapl.breuil .

 

I felt that the viewOrientation was not stable.

For now, the only way seems to be to specify the target and upVector directly.

def run(context):
    try:
        viewport: adsk.core.Viewport = app.activeViewport
        camera: adsk.core.Camera = viewport.camera

        eye: adsk.core.Point3D = camera.eye

        targetVec: adsk.core.Vector3D = adsk.core.Vector3D.create(
            -0.5773502691896256, 0.5773502691896256, -0.5773502691896256)
        target: adsk.core.Point3D = eye.copy()
        target.translateBy(targetVec)

        upVec: adsk.core.Vector3D = adsk.core.Vector3D.create(0.0, 0.0, 1.0)

        camera.target = target
        camera.upVector = upVec
        camera.isFitView = True

        viewport.camera = camera
    
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Message 3 of 5

zxynine
Enthusiast
Enthusiast
Accepted solution

Changing the camera does result in some weird effects if you try anything too complex in one go. The key is experimenting with a couple smaller changes and chaining them. You also must keep in mind the  `isSmoothTransition` argument which acts differently depending on the change you make. For example, in combination with changing the upvector or the eye point, the camera will smoothly interpolate to them, and when it is off, the camera will just snap to them.

However,

Using  `isSmoothTransition` with a change in viewport ive noticed only works in special cases. If you set the camera multiple times, you will create an animation of sorts:

 

    des:adsk.fusion.Design= app_.activeProduct
    root = des.rootComponent
    origin = root.originConstructionPoint.geometry
    
    camera_copy:adsk.core.Camera = app_.activeViewport.camera
    camera_copy.isFitView = True
    camera_copy.isSmoothTransition = True
    app_.activeViewport.camera = camera_copy
    
    camera_copy:adsk.core.Camera = app_.activeViewport.camera
    camera_copy.target = origin
    camera_copy.viewOrientation = adsk.core.ViewOrientations.IsoTopRightViewOrientation
    camera_copy.isSmoothTransition = True
    app_.activeViewport.camera = camera_copy

 

That code should mimic the home feature on the view cube as close as I could get it. 

Also note: the  `adsk.doEvents()` function can be used to wait for fusion to catch up to current events.

 

Message 4 of 5

tykapl.breuil
Advocate
Advocate
I had already gone for something close to that, I was just wondering if
there was something better. I have not managed to make adsk.doEvents() do
something however.
0 Likes
Message 5 of 5

tykapl.breuil
Advocate
Advocate
Accepted solution

In the end I found that the issue is with the viewOrientation method that causes problems (and also some lag). I ened up manually setting the viewOrientation for my use case. If any one needs it here is the code I used for the isoTopRight:

viewport = app.activeViewport
camera: adsk.core.Camera = viewport.camera
eye = camera.eye
target = camera.target
eyeVector: adsk.core.Vector3D = adsk.core.Vector3D.create(target.x-eye.x, target.y-eye.y, target.z-eye.z)
directionVector: adsk.core.Vector3D = adsk.core.Vector3D.create(1, -1, 1)
directionVector.scaleBy(eyeVector.length)
target.translateBy(directionVector)
camera.eye = target
camera.upVector = adsk.core.Vector3D.create(-1, 1, 2)
camera.isFitView = True
viewport.camera = camera

 And for the regular orientations :

listViewOrientations = {
    'Back': {'view': 1, 'sign': 1, 'tooltip': 'de l\'', 'name': 'Arrière'},
    'Bottom': {'view': 2, 'sign': -1, 'tooltip': 'du ', 'name': 'Bas'},
    'Left': {'view': 0, 'sign': -1, 'tooltip': 'de la ', 'name': 'Gauche'},
    'Top': {'view': 2, 'sign': 1, 'tooltip': 'du ', 'name': 'Haut'},
    'Right': {'view': 0, 'sign': 1, 'tooltip': 'de la ', 'name': 'Droite'},
    'Front': {'view': 1, 'sign': -1, 'tooltip': 'de l\'', 'name': 'Avant'}
}
viewCoordinate = listViewOrientations[viewId]['view']
viewSign = listViewOrientations[viewId]['sign']
viewport = app.activeViewport
camera = viewport.camera
upVector = camera.upVector
eye = camera.eye
target = camera.target
eyeVector: adsk.core.Vector3D = adsk.core.Vector3D.create(target.x-eye.x, target.y-eye.y, target.z-eye.z)
targetArray = target.asArray()
eyeArray = eye.asArray()
eyeList = [eyeArray[i] for i in range(3)]
otherCoords = [i for i in range(3) if i != viewCoordinate]
baseVectors = [[0 for i in range(3)] for j in range(4)]
for i, coord in enumerate(otherCoords):
    eyeList[coord] = targetArray[coord]
    baseVectors[2*i][coord] = 1
    baseVectors[2*i + 1][coord] = -1
maxCrossProduct = 0
for vector in baseVectors:
    baseVector: adsk.core.Vector3D = adsk.core.Vector3D.create()
    baseVector.setWithArray(vector)
    crossProduct = upVector.dotProduct(baseVector)
    if crossProduct >= maxCrossProduct:
        maxCrossProduct = crossProduct
        camera.upVector = baseVector
eyeList[viewCoordinate] = targetArray[viewCoordinate] + viewSign*eyeVector.length
eye.setWithArray(eyeList)
camera.eye = eye
viewport.camera = camera