找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1984|回复: 0

[分享] How to Get Current View Size

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-6-23 22:27:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
How to Get Current View Size

Sometimes one could run into question that you are sure you knew the answer and had dealt with it before, but just could not get it off your head right away.

A few days ago when I update an existing CAD application, I was asked to select certain entities visible in current view, be them in modelspace layout or paperspace layout, or in a active viewport of paperspace layout. I thought, "OK, I can get the size of current view and then select everything in a window that is the size of the current view (or slightly smaller than the view size). Then I went on searching Object Browser in Visual Studio for View, Viewport, ViewTableRecord, ViewportTableRecord... to see how I can easily get the size of current view in AutoCAD.

Well, it turned out that it would be unnecessarily complicated if I tried to use these classes for this task and luckily I recalled in my old VBA code I used AutoCAD system variables for similar work: VIEWSIZE and VIEWCTR.

System variable VIEWCTR provides a Point3d value as current view's centre point, while VIEWSIZE is the height of current view, measured in drawing unit. The problem left is how to know the width of current view? Again, another system variable SCREENSIZE comes to rescue: it provides the current viewport's size, but in PIXELs. Here what the unit of the size from SCREENSIZE is does not matter, we can use the ratio of width-height to calculate the current view's width in drawing unit from its height, like this:

view_width=view_height * (screen_width/screen_height)

The other thing to be careful is that the view's centre from VIEWCTR is in UCS coordinate.

Here is the code to get current view's size and its extents:

    1 using Autodesk.AutoCAD.ApplicationServices;
    2 using Autodesk.AutoCAD.DatabaseServices;
    3 using Autodesk.AutoCAD.Geometry;
    4
    5 namespace GetViewSize
    6 {
    7     public class ViewUtil
    8     {
    9         private Document _dwg;
   10
   11         public ViewUtil(Document dwg)
   12         {
   13             _dwg = dwg;
   14         }
   15
   16         public Point2d GetCurrentViewSize()
   17         {
   18             //Get current view height
   19             double h = (double)Application.GetSystemVariable("VIEWSIZE");
   20
   21             //Get current view width,
   22             //by calculate current view's width-height ratio
   23             Point2d screen = (Point2d)Application.GetSystemVariable("SCREENSIZE");
   24             double w = h * (screen.X / screen.Y);
   25
   26             return new Point2d(w, h);
   27         }
   28
   29         public Extents2d GetCurrentViewBound(
   30             double shrinkScale=1.0, bool drawBoundBox=false)
   31         {
   32             //Get current view size
   33             Point2d vSize = GetCurrentViewSize();
   34
   35             double w = vSize.X * shrinkScale;
   36             double h = vSize.Y * shrinkScale;
   37
   38
   39             //Get current view's centre.
   40             //Note, the centre point from VIEWCTR is in UCS and
   41             //need to be transformed back to World CS
   42             Point3d cent = ((Point3d)Application.GetSystemVariable("VIEWCTR")).
   43                 TransformBy(_dwg.Editor.CurrentUserCoordinateSystem);
   44
   45             Point2d minPoint = new Point2d(cent.X - w / 2.0, cent.Y - h / 2.0);
   46             Point2d maxPoint = new Point2d(cent.X + w / 2.0, cent.Y + h / 2.0);
   47
   48             if (drawBoundBox)
   49             {
   50                 DrawBoundBox(minPoint, maxPoint);
   51             }
   52
   53             return new Extents2d(minPoint, maxPoint);
   54         }
   55
   56         private void DrawBoundBox(Point2d minPoint, Point2d maxPoint)
   57         {
   58             using (Transaction tran = _dwg.TransactionManager.StartTransaction())
   59             {
   60                 //Get current space
   61                 BlockTableRecord space = (BlockTableRecord)tran.GetObject(
   62                     _dwg.Database.CurrentSpaceId, OpenMode.ForWrite);
   63
   64                 //Create a polyline as bounding box
   65                 Polyline pl = new Polyline(4);
   66
   67                 pl.AddVertexAt(0, minPoint, 0.0, 0.0, 0.0);
   68                 pl.AddVertexAt(1, new Point2d(minPoint.X, maxPoint.Y), 0.0, 0.0, 0.0);
   69                 pl.AddVertexAt(2, maxPoint, 0.0, 0.0, 0.0);
   70                 pl.AddVertexAt(3, new Point2d(maxPoint.X, minPoint.Y), 0.0, 0.0, 0.0);
   71                 pl.Closed = true;
   72
   73                 pl.SetDatabaseDefaults(_dwg.Database);
   74
   75                 space.AppendEntity(pl);
   76                 tran.AddNewlyCreatedDBObject(pl, true);
   77
   78                 tran.Commit();
   79             }
   80         }
   81     }
   82 }


In the GetCurrentViewBound() method, the optional argument "shrinkScale" is used for getting a slight smaller bound than the view is (or slightly larger, if it is greater than 1.0). The second optional argument is mostly for debugging purpose: if set to "true", a polyline would be drawn as the bounding box of the current view.

Here is the command class to run the code:

    1 using Autodesk.AutoCAD.ApplicationServices;
    2 using Autodesk.AutoCAD.EditorInput;
    3 using Autodesk.AutoCAD.Geometry;
    4 using Autodesk.AutoCAD.Runtime;
    5
    6 [assembly: CommandClass(typeof(GetViewSize.MyCommands))]
    7
    8 namespace GetViewSize
    9 {
   10     public class MyCommands
   11     {
   12         [CommandMethod("GetViewSize")]
   13         public static void RunMyCommand()
   14         {
   15             Document dwg = Application.DocumentManager.MdiActiveDocument;
   16             Editor ed = dwg.Editor;
   17
   18             ViewUtil util = new ViewUtil(dwg);
   19
   20             try
   21             {
   22                 //Get current view size
   23                 Point2d vSize = util.GetCurrentViewSize();
   24                 ed.WriteMessage("\nCurrent view size: " +
   25                     "H={0} W={1}", vSize.Y, vSize.X);
   26
   27                 //Draw a bound box of current view, which
   28                 //is slightly smaller than current view
   29                 util.GetCurrentViewBound(0.95, true);
   30
   31                 //Draw a bound box of current view, which
   32                 //is exactly the same size as current view
   33                 util.GetCurrentViewBound(1.0, true);
   34             }
   35             catch (System.Exception ex)
   36             {
   37                 ed.WriteMessage("\nError: {0}", ex.ToString());
   38             }
   39
   40             Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
   41         }
   42     }
   43 }

The code can be used to get current view's size. When in tiled multi-viewport modelspace, the view is the view in active viewport. When in paperspace layout, if there is no paperspace viewport active (after command "PS"), the view is the view of paperspace, while if there is a paperspace viewport active (after command "MS"), the view is the modelspace view seeing through the paperspace viewport.

Well, with paperspace viewport, one can use the size of the viewport and transform to size in modelspace in order to get the model view size seeing through the paperspace viewport. If the paperspace viewport has non-rectangular border, then the simple approach to get a rectangular view size shown in this article would be problematic (when the purpose is to selecting all entities visible in the view/viewport.



论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-5 22:55 , Processed in 0.189749 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表