December 19, 2012

Zooming, panning and orbiting the current AutoCAD view using .NET

I’ve taken a few days off to visit some very old friends who are back in the UK from New Zealand for the festive season, but thought I’d go ahead and share some code I’ve been playing with, even if I can’t actually tell you what it’s for.

I can tell you what it does, of course, but I’m using it in conjunction with some other capabilities that I’m probably not allowed to talk about explicitly. Feel free to speculate at your leisure, I may or may not be able to confirm or deny your suspicions (I need to check on that before being more clear).

The implementation encapsulates the ability to zoom, pan or orbit the current view in AutoCAD. This code is part of a larger proof of concept – and is therefore likely to go through some updates in the very near future – but it seemed likely to be at least of some use as it currently stands.

Here’s the C# code – I won’t show the commands in action, but it should be simple enough to try them out yourself:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.ApplicationServices.Core;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

using System;

namespace CameraTest

{

publicclassCamera

{

// Members

privateDocument _doc = null;

privateViewTableRecord _vtr = null;

privateViewTableRecord _initial = null;

public Camera(Document doc)

{

_doc = doc;

_initial = doc.Editor.GetCurrentView();

_vtr = (ViewTableRecord)_initial.Clone();

}

// Reset to the initial view

publicvoid Reset()

{

_doc.Editor.SetCurrentView(_initial);

_doc.Editor.Regen();

}

// Zoom in or out

publicvoid Zoom(double factor)

{

// Adjust the ViewTableRecord

_vtr.Height *= factor;

_vtr.Width *= factor;

// Set it as the current view

_doc.Editor.SetCurrentView(_vtr);

// Zoom requires a regen for the gizmos to update

_doc.Editor.Regen();

}

// Pan in the specified direction

publicvoid Pan(double leftRight, double upDown)

{

// Adjust the ViewTableRecord

_vtr.CenterPoint =

_vtr.CenterPoint + newVector2d(leftRight, upDown);

// Set it as the current view

_doc.Editor.SetCurrentView(_vtr);

}

// Orbit by angle around axis

publicvoid Orbit(Vector3d axis, double angle)

{

// Adjust the ViewTableRecord

_vtr.ViewDirection =

_vtr.ViewDirection.TransformBy(

Matrix3d.Rotation(angle, axis, Point3d.Origin)

);

// Set it as the current view

_doc.Editor.SetCurrentView(_vtr);

}

}

publicclassCommands

{

[CommandMethod("ZIN")]

publicvoid ZoomIn()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Zoom(0.9);

}

[CommandMethod("ZOUT")]

publicvoid ZoomOut()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Zoom(1.1);

}

[CommandMethod("PLEFT")]

publicvoid PanLeft()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Pan(-1, 0);

}

[CommandMethod("PRIGHT")]

publicvoid PanRight()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Pan(1, 0);

}

[CommandMethod("PUP")]

publicvoid PanUp()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Pan(0, 1);

}

[CommandMethod("PDOWN")]

publicvoid PanDown()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Pan(0, -1);

}

[CommandMethod("OLEFT")]

publicvoid OrbitLeft()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Orbit(Vector3d.ZAxis, Math.PI / 12);

}

[CommandMethod("ORIGHT")]

publicvoid OrbitRight()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Orbit(Vector3d.ZAxis, -Math.PI / 12);

}

[CommandMethod("OUP")]

publicvoid OrbitUp()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Orbit(Vector3d.XAxis, Math.PI / 12);

}

[CommandMethod("ODOWN")]

publicvoid OrbitDown()

{

var cam =

newCamera(Application.DocumentManager.MdiActiveDocument);

cam.Orbit(Vector3d.XAxis, -Math.PI / 12);

}

}

}

With any luck I’ll get the chance to post at least once more before our annual “Week of Rest”, once I'm back home in Switzerland.