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: 

Script to level the camera

3 REPLIES 3
Reply
Message 1 of 4
michael
348 Views, 3 Replies

Script to level the camera

I use the following when making screen shots to straighten up the view, making vertical lines plumb (in ortho mode). Even in perspective mode it helps improve consistency between shots of different parts of the model.

 

There are some potential edge cases (e.g. upVector perpendicular to y-axis), but for my intended use I don't expect to be operating anywhere near them. If there's a way in the UI that I missed to accomplish the same thing I'd love to know about it 🙂

 

Cheers,

 

Michael

 

#Description- LevelCamera.py

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

def decomposeVector(a, b):
    
    aParallelB = b.copy()
    aParallelB.scaleBy(a.dotProduct(b) / b.dotProduct(b))
    
    aPerpendicularB = a.copy()
    aPerpendicularB.subtract(aParallelB)
    
    return [aParallelB, aPerpendicularB]
    
def verticalizeView():
    ui = None
    app = adsk.core.Application.get()
    ui  = app.userInterface

    cam = app.activeViewport.camera
    
    yAxisVector = adsk.core.Vector3D.create(0.0, 1.0, 0.0)
    upVector = cam.upVector
    # construct vector pointing from camera to target
    eyeVector = adsk.core.Vector3D.create(cam.target.x - cam.eye.x, cam.target.y - cam.eye.y, cam.target.z - cam.eye.z)

    # Whenever view is level, Y-axis, upVector, and eyeVector will be coplanar.
    # To roll the camera to make it level, project the upVector to the plane
    # formed by Y-axis + eyeVector then rescale to get new upVector

    # make sure the request makes sense   
    if yAxisVector.isParallelTo(eyeVector):
        # NOTE: above should really check instead to see if angle
        # between Y axis and eyeVector is closer than some arbitrary amount to 0 or pi
        ui.messageBox('Camera is pointing straight up or down')
    else:
        # get vector perpendicular to both yAxis + eyeVector
        orthoVector = yAxisVector.crossProduct(eyeVector)
        # isolate the portion of camera upVector that would remain once we project onto 
        # vertically oriented plane containing eyeVector
        upParallel, upPerpendicular = decomposeVector(upVector, orthoVector)
        # stretch remainder back to unit length (don't know if Fusion cares)
        upPerpendicular.scaleBy(1/upPerpendicular.length)
        cam.upVector = upPerpendicular
        rotation = round(upVector.angleTo(upPerpendicular) * 360 / 6.283,1)
        app.activeViewport.camera = cam
        ui.messageBox('Done. Camera rotated by ' + str(rotation) + ' degree(s)')

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        verticalizeView()

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

3 REPLIES 3
Message 2 of 4
ekinsb
in reply to: michael

I don't know of a built-in command in Fusion do this.  I believe this will accomplish the same thing in your case though.

 

def verticalizeView():
    app = adsk.core.Application.get()
    ui = app.userInterface

    view = app.activeViewport
    cam = view.camera
    
    yAxisVector = adsk.core.Vector3D.create(0.0, 1.0, 0.0)

    # make sure the request makes sense   
    if yAxisVector.isParallelTo(eyeVector):
        ui.messageBox('Camera is pointing straight up or down')
    else:
        cam.upVector = yAxisVector
        view = cam

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 3 of 4
michael
in reply to: ekinsb

Hmm, I tried your code and I didn't see any effect (but also did not get any exception either). It would indeed be much simpler if I could just set the upVector that way without worrying about maintaining perpendicularity with camera->target vector

 

I did figure out though that if I set Orbit to Constrained in UI before maneuvering for my screen shot that it eliminates need for my script 🙂

 

Michael

 

Message 4 of 4
michael
in reply to: michael

 

PS: I pasted in the eyeVector line before trying to run:

 

eyeVector = adsk.core.Vector3D.create(cam.target.x - cam.eye.x, cam.target.y - cam.eye.y, cam.target.z - cam.eye.z)

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