Message 1 of 4
Script to level the camera
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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()))
