Zooming to a window or entity inside AutoCAD with .NET
This post was inspired by a recent email from Sreekar Devatha, who is just about to leave DevTech India to work in one of our Engineering teams in Singapore (all the best on your new adventure, Sreekar! :-).
It shows how to perform a programmatic zoom in .NET, whether to a window or to an entity. The .NET API in AutoCAD doesn't expose a handy "ZoomWindow" method, but there are a few options open that use officially supported APIs:
- Create a ViewTableRecord and set it as the current view (the classic ObjectARX technique, as described in this DevNote on the ADN site)
- Use the COM API to perform a ZoomWindow
- Call the ZOOM command using one of the techniques in this previous post
The first two change the view very effectively, but don't show the nice view transitions you get with the ZOOM command (hence the 3rd option).
I ended up implementing the following C# code to show each of these techniques, which can be applied to commands that zoom either to a window (ZW) or to an entity (ZE). Just change the functions used from ZoomWin() to ZoomWin2() or ZoomWin3(), as needed:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Interop;
namespace ZoomZoom
{
public class Commands
{
// Zoom to a window specified by the user
[CommandMethod("ZW")]
static public void ZoomWindow()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Get the window coordinates
PromptPointOptions ppo =
new PromptPointOptions(
"\nSpecify first corner:"
);
PromptPointResult ppr =
ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
Point3d min = ppr.Value;
PromptCornerOptions pco =
new PromptCornerOptions(
"\nSpecify opposite corner: ",
ppr.Value
);
ppr = ed.GetCorner(pco);
if (ppr.Status != PromptStatus.OK)
return;
Point3d max = ppr.Value;
// Call out helper function
// [Change this to ZoomWin2 or WoomWin3 to
// use different zoom techniques]
ZoomWin(ed, min, max);
}
// Zoom to the extents of an entity
[CommandMethod("ZE")]
static public void ZoomToEntity()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Get the entity to which we'll zoom
PromptEntityOptions peo =
new PromptEntityOptions(
"\nSelect an entity:"
);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
// Extract its extents
Extents3d ext;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
Entity ent =
(Entity)tr.GetObject(
per.ObjectId,
OpenMode.ForRead
);
ext =
ent.GeometricExtents;
tr.Commit();
}
ext.TransformBy(
ed.CurrentUserCoordinateSystem.Inverse()
);
// Call our helper function
// [Change this to ZoomWin2 or WoomWin3 to
// use different zoom techniques]
ZoomWin(ed, ext.MinPoint, ext.MaxPoint);
}
// Helper functions to zoom using different techniques
// Zoom using a view object
private static void ZoomWin(
Editor ed, Point3d min, Point3d max
)
{
Point2d min2d = new Point2d(min.X, min.Y);
Point2d max2d = new Point2d(max.X, max.Y);
ViewTableRecord view =
new ViewTableRecord();
view.CenterPoint =
min2d + ((max2d - min2d) / 2.0);
view.Height = max2d.Y - min2d.Y;
view.Width = max2d.X - min2d.X;
ed.SetCurrentView(view);
}
// Zoom via COM
private static void ZoomWin2(
Editor ed, Point3d min, Point3d max
)
{
AcadApplication app =
(AcadApplication)Application.AcadApplication;
double[] lower =
new double[3] { min.X, min.Y, min.Z };
double[] upper
= new double[3] { max.X, max.Y, max.Z };
app.ZoomWindow(lower, upper);
}
// Zoom by sending a command
private static void ZoomWin3(
Editor ed, Point3d min, Point3d max
)
{
string lower =
min.ToString().Substring(
1,
min.ToString().Length - 2
);
string upper =
max.ToString().Substring(
1,
max.ToString().Length - 2
);
string cmd =
"_.ZOOM _W " + lower + " " + upper + " ";
// Call the command synchronously using COM
AcadApplication app =
(AcadApplication)Application.AcadApplication;
app.ActiveDocument.SendCommand(cmd);
// Could also use async command calling:
//ed.Document.SendStringToExecute(
// cmd, true, false, true
//);
}
}
}
The code isn't as complete as I'd like: I haven't coded for all the view parameters (which are addressed in the DevNote quoted above in item 1, for those of you who are ADN members and can understand ObjectARX), and haven't tested for handling views not-aligned with the current UCS (etc., etc.). My main purpose was to outline the techniques, rather than to provide an exhaustive solution (and I'm currently on the train back from Geneva airport, having just flown to California and back for 3 days in the San Rafael office, which means any attempt on my side to make this exhaustive might end up exhausting me :-).

Subscribe via RSS
Excellent post! Just fix this in ZoomWin
It says:
view.Width = max2d.X - max2d.Y;
Should be:
view.Width = max2d.X - min2d.X;
Posted by: Hector Cruz | June 06, 2008 at 09:57 PM
Of course - well spotted, Hector! :-)
I've fixed the post.
Kean
Posted by: Kean | June 10, 2008 at 06:39 PM
Hi, it seems you guys are well versed in what ever you do.
Could you help me in a application am trying to develop for my project work in school?
I have developed this application whic calculates for coordinates of ground points on the surface of the earth. I want to represent these points in autocad without actually launching autocad.
What i want to do is to just click a button from vb.net to plot the points and save it as dxf or dwg file which can later be opened with autocad 2002 or 2004.
Or maybe, if you could also help me so that, as the coordinates are calculated in XYZ system, it does the representation in an autocad window on the same form.
thanks.
Posted by: emmaddai owusu | July 24, 2008 at 12:24 PM
You should look into an Autodesk product called RealDWG.
Kean
Posted by: Kean | July 24, 2008 at 01:29 PM
Thanks Kean
If you happen to read comments from old posts, the ZoomWin function should have type Point3d for parameters min and max.
Posted by: Lase | August 12, 2008 at 08:35 PM
Got it - my mistake. I've fixed it.
Kean
Posted by: Kean | August 12, 2008 at 09:46 PM
The ViewTableRecord method works in modelspace when i'm trying to zoom extents (using database.extmin and extmax) but is there a way to do something similar with paperspace? i can't seem to figure out the right way.
Posted by: Tim Catalano | May 01, 2009 at 06:59 PM
I don't know, off the top of my head. Have you tried asking for help on the discussion groups or via ADN, if you're a member?
Kean
Posted by: Kean Walmsley | May 01, 2009 at 09:54 PM