Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
tykapl.breuil
169 Views, 4 Replies

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

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).

 

4 REPLIES 4
Message 2 of 5
kandennti
in reply to: tykapl.breuil

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
in reply to: tykapl.breuil

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
in reply to: zxynine

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.
Message 5 of 5

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

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report