Hi rom1,
Nice trick.
I tried to go a little further and get this work whatever the current view (i.e. an isometric or orbited view).
The main trick is to transform points from World System Coordinates (WCS) to the view Display Coordinate System (DCS) as shown for
ZoomObjects or in
GeomtryExtensions Editor or Viewport extension methods.
On the other hand, it seems that Database.UpdateExt() is not mandatory. From the tests I did all work fine without calling it.
So, here're some extension methods (yes, I like this feature) used to set a zoom extents in a side Database model space.
/// <summary>
/// Returns the transformation matrix from the ViewportTableRecord DCS to WCS.
/// </summary>
/// <param name="view">The ViewportTableRecord instance this method applies to.</param>
/// <returns>The DCS to WCS transformation matrix.</returns>
public static Matrix3d EyeToWorld(this ViewportTableRecord view)
{
return
Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) *
Matrix3d.Displacement(view.Target - Point3d.Origin) *
Matrix3d.PlaneToWorld(view.ViewDirection);
}
/// <summary>
/// Returns the transformation matrix from the ViewportTableRecord WCS to DCS.
/// </summary>
/// <param name="view">The ViewportTableRecord instance this method applies to.</param>
/// <returns>The WCS to DCS transformation matrix.</returns>
public static Matrix3d WorldToEye(this ViewportTableRecord view)
{
return view.EyeToWorld().Inverse();
}
/// <summary>
/// Sets a zoom extents of the Database model space
/// </summary>
/// <param name="db">The Database instance this method applies to.</param>
public static void ZoomExtents(this Database db)
{
db.TileMode = true;
Point2d scrSize = (Point2d)AcAp.GetSystemVariable("screensize");
double ratio = scrSize.X / scrSize.Y;
using (Transaction tr = db.TransactionManager.StartTransaction())
using (Line line = new Line(db.Extmin, db.Extmax))
{
ViewportTable vpt =
(ViewportTable)tr.GetObject(db.ViewportTableId, OpenMode.ForRead);
ViewportTableRecord vptr =
(ViewportTableRecord)tr.GetObject(vpt["*Active"], OpenMode.ForWrite);
Extents3d ext = line.GeometricExtents;
ext.TransformBy(vptr.WorldToEye());
Point2d pmin = new Point2d(ext.MinPoint.X, ext.MinPoint.Y);
Point2d pmax = new Point2d(ext.MaxPoint.X, ext.MaxPoint.Y);
double height = pmax.Y - pmin.Y;
double width = pmax.X - pmin.X;
if (width / height < ratio)
{
vptr.Height = height;
vptr.Width = height * ratio;
}
else
{
vptr.Width = width;
vptr.Height = width / ratio;
}
vptr.CenterPoint = pmin + (pmax - pmin) / 2.0;
tr.Commit();
}
}
A test command example:
[CommandMethod("zedb")]
public void ZoomExtentsDb()
{
using (Database db = new Database())
{
db.ReadDwgFile(@"F:\Dessin1.dwg", System.IO.FileShare.ReadWrite, false, "");
db.ZoomExtents();
db.SaveAs(@"F:\Dessin1.dwg", DwgVersion.Current);
}
}