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

{

  public class Camera

  {

    // Members

 

    private Document _doc = null;

    private ViewTableRecord _vtr = null;

    private ViewTableRecord _initial = null;

 

    public Camera(Document doc)

    {

      _doc = doc;

      _initial = doc.Editor.GetCurrentView();

      _vtr = (ViewTableRecord)_initial.Clone();

    }

 

    // Reset to the initial view

 

    public void Reset()

    {

      _doc.Editor.SetCurrentView(_initial);

      _doc.Editor.Regen();

    }

 

    // Zoom in or out

 

    public void 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

 

    public void Pan(double leftRight, double upDown)

    {

      // Adjust the ViewTableRecord

 

      _vtr.CenterPoint =

        _vtr.CenterPoint + new Vector2d(leftRight, upDown);

 

      // Set it as the current view

 

      _doc.Editor.SetCurrentView(_vtr);

    }

 

    // Orbit by angle around axis

 

    public void 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);

    }

  }

 

  public class Commands

  {

    [CommandMethod("ZIN")]

    public void ZoomIn()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

      cam.Zoom(0.9);

    }

 

    [CommandMethod("ZOUT")]

    public void ZoomOut()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

      cam.Zoom(1.1);

    }

 

    [CommandMethod("PLEFT")]

    public void PanLeft()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

      cam.Pan(-1, 0);

    }

 

    [CommandMethod("PRIGHT")]

    public void PanRight()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

      cam.Pan(1, 0);

    }

 

    [CommandMethod("PUP")]

    public void PanUp()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

      cam.Pan(0, 1);

    }

 

    [CommandMethod("PDOWN")]

    public void PanDown()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

      cam.Pan(0, -1);

    }

 

    [CommandMethod("OLEFT")]

    public void OrbitLeft()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

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

    }

 

    [CommandMethod("ORIGHT")]

    public void OrbitRight()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

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

    }

 

    [CommandMethod("OUP")]

    public void OrbitUp()

    {

      var cam =

        new Camera(Application.DocumentManager.MdiActiveDocument);

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

    }

 

    [CommandMethod("ODOWN")]

    public void OrbitDown()

    {

      var cam =

        new Camera(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.

8 responses to “Zooming, panning and orbiting the current AutoCAD view using .NET”

  1. Very nice and clean examples. There are some additional samples in the .NET Developer's Guide that show how to emulate many of the features of the ZOOM command.

    docs.autodesk.com/AC...

  2. Woot! Doom is finally coming to the AutoCAD platform :-).

  3. Hi Kean,

    Happy new year!

    Is it possible to create image by giving camera location, target and a projection matrix parameter(like FOV, aspect ration, far/near plane distance) through .Net API?

    Many thanks,
    ali

  4. Currently, in our project, we convert autocad model by FBX convertor and load it again by separate graphic library(directx or openGL) to get a customize view(image) from a point. So, I was just wondering if that's possible to create this custom image within autocad since the model is already rendered?

  5. Hi ali,

    Happy New Year!

    You could certainly do something like that. This post may be of some help for capturing the image:

    keanw.com/2007/04/taking_a_snapsh.html

    Setting up the view should also be possible via a ViewTableRecord - as shown in this post.

    Regards,

    Kean

  6. You can certainly do this, yes.

    Kean

  7. btanner_fireplan Avatar
    btanner_fireplan

    Hello Kean. This post is a little older, but I thought I might pose a related query if you don't mind.
    I'm unfortunately not an AutoCAD guy, I'm a developer trying to help my AutoCAD guys ๐Ÿ™‚
    I'm also a Java/Mac guy, not a C#/Windows guy, but I'm learning.

    My team has 3 viewports in each of their paperspace layouts. This is all in 2D. The main one will have an arbitrary rotation, and the other 2 need to match it.

    I can grab all the viewports programatically, and I think there should be some easy way to grab the rotation of the main viewport and simply apply it to the other 2. I tried just getting/setting the the TwistAngles, and that seems like an interesting direction, but the rotation isn't around the center of the viewport so it messes things up.

    Any chance this is a super easy 2 line solution? If not, any chance you would like to write it for me and I'll pay you? I'm learning all this AutoCAD development stuff so help my team, but really I need like 4 features written for them and they should be good to go ๐Ÿ™‚

    Sorry to bug you via comments on your website - let me know if you are interested ๐Ÿ™‚

    1. Hello,

      Can you email me (my address is on my About page) a drawing showing a typical set of viewports?

      I can imagine writing a blog post that transfers view information between a selected viewport and the others in paperspace... that should be of general enough interest to justify the time.

      Regards,

      Kean

Leave a Reply to Kean Walmsley Cancel reply

Your email address will not be published. Required fields are marked *