Author Topic: zoomextents issues  (Read 1502 times)

0 Members and 1 Guest are viewing this topic.

BrianM

  • Mosquito
  • Posts: 15
zoomextents issues
« on: December 04, 2012, 12:04:56 pm »
I have some issues when trying to perform a zoomextents. I've tried a couple methods. The first method, involves using COM Interop, which is posted below.
Code - vb.net: [Select]
  1. Dim comApp As Autodesk.AutoCAD.Interop.AcadApplication
  2.            comApp = GetObject(, "AutoCAD.Application")
  3.            comApp.ZoomExtents()

The second method I used is true .NET, which is posted here:

Code - vb.net: [Select]
  1. Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  2.  
  3.        Dim db As Database = HostApplicationServices.WorkingDatabase
  4.  
  5.        Dim doc As Document = Application.DocumentManager.MdiActiveDocument()
  6.  
  7.            Using docLoc As DocumentLock = doc.LockDocument
  8.                db.UpdateExt(True)
  9.  
  10.        Dim ViewTableRecord As New ViewTableRecord
  11.  
  12.        Dim MaxPoint As Point3d = db.Extmax
  13.  
  14.        Dim MinPoint As Point3d = db.Extmin
  15.  
  16.        Dim MaxPoint2D As Point2d = New Point2d(MaxPoint.X, MaxPoint.Y)
  17.  
  18.        Dim MinPoint2D As Point2d = New Point2d(MinPoint.X, MinPoint.Y)
  19.  
  20.                ViewTableRecord.CenterPoint = MinPoint2D + (MaxPoint2D - MinPoint2D) * 0.5
  21.  
  22.                ViewTableRecord.Height = MaxPoint2D.Y - MinPoint2D.Y
  23.  
  24.                ViewTableRecord.Width = MaxPoint2D.X - MinPoint2D.X
  25.  
  26.                ed.SetCurrentView(ViewTableRecord)
  27.            End Using

These two pieces of code give me the exact same results. However, they are not the same as doing a zoom extents manually at the command line.
I need to programmatically get the same results as I do with a manual zoom extents.
I'm creating a bitmap file from items selected in a drawing. The size of the active window determines the size of the bmp. My code resizes the current window, does a zoomextents, then saves the drawing objects as a bmp file. If I do this manually, it turns out correct. However, doing the zoomextents programmatically doesn't work. It's close, but some of the drawing objects end up slightly outside of the active window, as though it didn't do a full zoom extents.

Any idea what's creating this issue?

Thanks

Brian

BrianM

  • Mosquito
  • Posts: 15
Re: zoomextents issues
« Reply #1 on: December 04, 2012, 12:34:19 pm »
I just tried this:

SendStringToExecute("Zoom e ", False, False, False)

and also the com version sendcommand.

Both of these zoom properly, but they don't perform the zoom until after the program is completed. I need it to perform a zoom in the middle of my program.

BlackBox

  • Gator
  • Posts: 2643
Re: zoomextents issues
« Reply #2 on: December 04, 2012, 12:58:01 pm »
Kean describes three different methods of accomplishing this using ViewTableRecord, COM, and Command (see the helper functions) in this article:

Zooming to a window or entity inside AutoCAD with .NET
"Potential has a shelf life." - Margaret Atwood

BillZndl

  • Bull Frog
  • Posts: 217
  • will code for food
Re: zoomextents issues
« Reply #3 on: December 04, 2012, 01:09:45 pm »
I've used this with good success:
(C#)
Code: [Select]
using System;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsSystem;
using Autodesk.AutoCAD.Internal;

public static void ZoomToExtents()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = doc.Editor;       

            using (DocumentLock docloc = doc.LockDocument())
            {
                using (Transaction trans = doc.TransactionManager.StartTransaction())
                {
                 
                 Point3d min = (Point3d)Application.GetSystemVariable("EXTMIN");
                 Point3d max = (Point3d)Application.GetSystemVariable("EXTMAX");
               
                 int CvId = Convert.ToInt32((Application.GetSystemVariable("CVPORT")));
                 using (Manager gm = doc.GraphicsManager)
                 using (View vw = gm.GetGsView(CvId, true))
                  {
                    vw.ZoomExtents(min, max);
                    vw.Zoom(0.95); //optional
                    gm.SetViewportFromView(CvId, vw, true, true, false);
                  }

                trans.Commit();

                }
            }
        }
« Last Edit: December 04, 2012, 01:12:58 pm by BillZndl »
AutoCAD:
It works or dies trying.

Jeff H

  • King Gator
  • Posts: 4451
Re: zoomextents issues
« Reply #4 on: December 04, 2012, 01:49:04 pm »
Shhh!!!!!
 
Do not tell or show anyone this is but, uses COM and at least does not tie you down to year and can be reused
 
Code - C#: [Select]
  1.  
  2.         public static void ZoomExtents(this Document doc)
  3.        {
  4.            dynamic acadapp = Application.AcadApplication;
  5.            acadapp.ZoomExtents();
  6.        }
  7.  
  8.  

BillZndl

  • Bull Frog
  • Posts: 217
  • will code for food
Re: zoomextents issues
« Reply #5 on: December 04, 2012, 02:32:22 pm »
Shhh!!!!!
 
Do not tell or show anyone this is but, uses COM and at least does not tie you down to year and can be reused
 
Code - C#: [Select]
  1.  
  2.         public static void ZoomExtents(this Document doc)
  3.        {
  4.            dynamic acadapp = Application.AcadApplication;
  5.            acadapp.ZoomExtents();
  6.        }
  7.  
  8.  

:) I should add: I haven't really kept up with things. Thanks Jeff!
AutoCAD:
It works or dies trying.

Jeff H

  • King Gator
  • Posts: 4451
Re: zoomextents issues
« Reply #6 on: December 04, 2012, 03:34:03 pm »
Shhh!!!!!
 
Do not tell or show anyone this is but, uses COM and at least does not tie you down to year and can be reused
 
Code - C#: [Select]
  1.  
  2.         public static void ZoomExtents(this Document doc)
  3.        {
  4.            dynamic acadapp = Application.AcadApplication;
  5.            acadapp.ZoomExtents();
  6.        }
  7.  
  8.  

 :) I should add: I haven't really kept up with things. Thanks Jeff!
Not so much here but there are interop COM haters out there that do not like any COM but with dynamics your not tied to release and i should throw in a SendStringToExecute() example.
 
Not doing bunch of loops or intensive crap I think it is great.
 
But for saving a doc here is a example by TT http://www.theswamp.org/index.php?topic=42016.msg471429#msg471429
 
But you can download the Active docs http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=1911627# and look through to idea of somethings especially for setting preferences and options.
 
I just code it in a class with interop assemblies referenced then cut and paste and replace needed Types with dynamic(there really is not a dynamic type) but dynamic keyword.
The only reason I do that is because of spelling and no intellisense with "duck typing"
 
 
 

BillZndl

  • Bull Frog
  • Posts: 217
  • will code for food
Re: zoomextents issues
« Reply #7 on: December 05, 2012, 03:32:56 pm »
I see now why I did my zoom extents that way in my previous post.
I originally placed the following method in a button click so I could zoom up to a part (AutoCAD Group) that is selected in my listview:
Code: [Select]
private static void ZoomToPart(ObjectId GID, Transaction trans, Document doc)
        {                   
            using (trans)
            {
                Group EntGrpDic = (Group)trans.GetObject(GID, OpenMode.ForRead);
               
                ObjectId[] Eids = EntGrpDic.GetAllEntityIds();

                Extents3d exts =
                    Eids.Select(id => ((Entity)trans.GetObject(id, OpenMode.ForRead)).GeometricExtents).Aggregate(
                    (e1, e2) => { e1.AddExtents(e2); return e1; });         
               
                Point3d min = exts.MinPoint;
                Point3d max = exts.MaxPoint;               
                                               
                int CvId = Convert.ToInt32((Application.GetSystemVariable("CVPORT")));
                using (Manager gm = doc.GraphicsManager)
                using (View vw = gm.GetGsView(CvId, true))
                {                   
                    vw.ZoomExtents(min, max);
                    vw.Zoom(0.95);
                    gm.SetViewportFromView(CvId, vw, true, true, false);
                }

                trans.Commit();
            }       
        }

After I accomplished that task, it seemed like a good idea to be able to return to the zoom extents of the document,
so I simply copied the method and substituted the extmin and extmax system varibles to zoom to the previous drawing extents.
Guess I could have made it easier on myself after all.... :)

AutoCAD:
It works or dies trying.

gile

  • Water Moccasin
  • Posts: 1699
  • Marseille, France
Re: zoomextents issues
« Reply #8 on: December 05, 2012, 05:02:31 pm »
Hi,

Here're some extension methods to make a zoom extents in the current viewport.
This will work whatever the current view (even 3d orbited views)

Code - C#: [Select]
  1.    static class ZoomExtensions
  2.    {
  3.        // Returns the transformation matrix from the ViewTableRecord DCS to WCS
  4.        public static Matrix3d EyeToWorld(this ViewTableRecord view)
  5.        {
  6.            return
  7.                Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) *
  8.                Matrix3d.Displacement(view.Target - Point3d.Origin) *
  9.                Matrix3d.PlaneToWorld(view.ViewDirection);
  10.        }
  11.  
  12.        // Returns the transformation matrix from WCS to the ViewTableRecord DCS
  13.        public static Matrix3d WorldToEye(this ViewTableRecord view)
  14.        {
  15.            return view.EyeToWorld().Inverse();
  16.        }
  17.  
  18.        // Process a zoom according to the extents3d in the current viewport
  19.        public static void Zoom(this Editor ed, Extents3d ext)
  20.        {
  21.            using (ViewTableRecord view = ed.GetCurrentView())
  22.            {
  23.                ext.TransformBy(view.WorldToEye());
  24.                view.Width = ext.MaxPoint.X - ext.MinPoint.X;
  25.                view.Height = ext.MaxPoint.Y - ext.MinPoint.Y;
  26.                view.CenterPoint = new Point2d(
  27.                    (ext.MaxPoint.X + ext.MinPoint.X) / 2.0,
  28.                    (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0);
  29.                ed.SetCurrentView(view);
  30.            }
  31.        }
  32.  
  33.        // Process a zoom extents in the current viewport
  34.        public static void ZoomExtents(this Editor ed)
  35.        {
  36.            Database db = ed.Document.Database;
  37.            Extents3d ext = (short)AcAp.GetSystemVariable("cvport") == 1 ?
  38.                new Extents3d(db.Pextmin, db.Pextmax) :
  39.                new Extents3d(db.Extmin, db.Extmax);
  40.            ed.Zoom(ext);
  41.        }
  42.    }
Speaking English as a French Frog

BrianM

  • Mosquito
  • Posts: 15
Re: zoomextents issues
« Reply #9 on: December 05, 2012, 09:30:35 pm »
Thank you for the suggestions. So far, I haven't found a fix for my problem. I've posted a piece of code that is part of an image creation command that I am working on. The same issue occurs with any zoom extents code. In the example below, I just use com, for simplicity.
Draw a few objects on your screen, then run the code. In 2013, the window changes to the proper size, but it will not do a zoom extents. It's close, but the edges of the objects are still off the screen. If I run it a second time, it will do a proper zoom extents.
Any ideas what may be causing this?

Code - vb.net: [Select]
  1. <CommandMethod("CreateImage")> _
  2.        Public Sub Main()
  3.  
  4.            Dim doc As Document = Application.DocumentManager.MdiActiveDocument()
  5.            Dim ed As Editor = doc.Editor
  6.            Dim docWindow As Window = doc.Window
  7.            Dim db As Database = doc.Database
  8.            docWindow.WindowState = Window.State.Normal
  9.            Dim newSize As System.Drawing.Size = New System.Drawing.Size(950, 573) 'was 608
  10.            docWindow.SetSize(newSize)
  11.  
  12.  
  13.            'use com to perform a zoom extents
  14.            Dim comAcad As Object = Application.AcadApplication
  15.            comAcad.ZoomExtents()
  16.  
  17.        End Sub

Jeff H

  • King Gator
  • Posts: 4451
Re: zoomextents issues
« Reply #10 on: December 05, 2012, 11:07:42 pm »
Do not know for sure because like most things you have spend time testing just to see if it works instead of having some documentation that would explain the fundamentals so you could figure out quickly but with have you tried
Database.UpdateExt()

TJK44

  • Newt
  • Posts: 182
Re: zoomextents issues
« Reply #11 on: December 06, 2012, 10:25:12 am »
Brian, try this. I believe I got this from a post Gile had made awhile back.

Code: [Select]
    Public Shared Sub ZoomExtents(ByVal ed As Editor, ByVal db As Database, ByVal doc As Document)
        Using view As ViewTableRecord = ed.GetCurrentView()
            Using doclock As DocumentLock = doc.LockDocument
                Dim extents As New Extents3d(db.Extmin, db.Extmax)
                Dim WCS2DCS As Matrix3d = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) * Matrix3d.Displacement(view.Target - Point3d.Origin) * Matrix3d.PlaneToWorld(view.ViewDirection)
                extents.TransformBy(WCS2DCS.Inverse())
                Dim center As New Point2d((extents.MinPoint.X + extents.MaxPoint.X) / 2.0, (extents.MinPoint.Y + extents.MaxPoint.Y) / 2.0)
                view.Height = (extents.MaxPoint.Y - extents.MinPoint.Y)
                view.Width = (extents.MaxPoint.X - extents.MinPoint.X)
                view.CenterPoint = center
                ed.SetCurrentView(view)
                db.UpdateExt(True)
            End Using
        End Using
    End Sub

BrianM

  • Mosquito
  • Posts: 15
Re: zoomextents issues
« Reply #12 on: December 09, 2012, 07:54:32 am »
I've had a chance to play with this a bit more.
All of the zoom extents code that has been suggested, along with the code that I originally tried works fine if I run it by itself. The zoom extents only works improperly when the window resize code is run before it.
I'm still experimenting with the code to resize the window. I've tried everything I can think of so far, but still get the same results.

Brian

BrianM

  • Mosquito
  • Posts: 15
Re: zoomextents issues
« Reply #13 on: February 16, 2013, 12:45:38 pm »
I took a break from this to work on some other projects. I've been playing with some other code to try to get this to work, but still no luck.

Here's the code I currently have:

Code: [Select]
<CommandMethod("CreateImage")> _
        Public Sub Main()

            Dim doc As Document = Application.DocumentManager.MdiActiveDocument()

            Dim ed As Editor = doc.Editor
            Dim docWindow As Window = doc.Window
            Dim db As Database = doc.Database

            docWindow.WindowState = Window.State.Normal
            Dim newSize As System.Drawing.Size = New System.Drawing.Size(950, 573) 'was 608
            docWindow.SetSize(newSize)


            Using docLoc As DocumentLock = doc.LockDocument
                db.UpdateExt(True)

                Dim ViewTableRecord As New ViewTableRecord

                Dim MaxPoint As Point3d = db.Extmax

                Dim MinPoint As Point3d = db.Extmin

                Dim MaxPoint2D As Point2d = New Point2d(MaxPoint.X, MaxPoint.Y)

                Dim MinPoint2D As Point2d = New Point2d(MinPoint.X, MinPoint.Y)

                ViewTableRecord.CenterPoint = MinPoint2D + (MaxPoint2D - MinPoint2D) * 0.5

                ViewTableRecord.Height = MaxPoint2D.Y - MinPoint2D.Y

                ViewTableRecord.Width = MaxPoint2D.X - MinPoint2D.X

                ed.SetCurrentView(ViewTableRecord)
            End Using

           
        End Sub

And here's an image of the resulting window resize and zoom with the above code. I have tried all of the suggested zoom extents code suggested in the other posts, along with numerous other ideas that I had, but I get exactly the same results.
If I run this code once, then hit Enter to repeat the command, then it zooms properly. It acts like the database isn't updated when the code is run the first time, but I've tried a database.UpdateExt, with the same results. Any help / suggestions would be greatly appreciated.


IDabble

  • Mosquito
  • Posts: 15
Re: zoomextents issues
« Reply #14 on: February 16, 2013, 05:31:27 pm »
You might try something I took from the AutoCAD .NET Developer's Guide
http://docs.autodesk.com/ACD/2011/ENU/filesMDG/WS1a9193826455f5ff2566ffd511ff6f8c7ca-4363.htm
It's got a main zoom function and you can call it in various ways.
For ZoomExtents, notice the last argument is a zoom factor leaving a little room around the extents.

edit:  I just had to test this and come back, because I was sure it had worked for me.  It's golden.   :kewl:

Code: [Select]
/// <summary> manipulates the Zoom method to emulate the traditional Zoom Extents command </summary>
public static void ZoomExtents()
{
    Application.ShowAlertDialog("Begin Command"); // for testing
    // call Zoom method with undefined MinPt & MaxPt, origin as the center point, and a non-zero veiwport scale factor
    Zoom(new Point3d(), new Point3d(), Point3d.Origin, 1.02);
    Application.ShowAlertDialog("End Command"); // for testing
}

Code: [Select]
/// <summary> this method is used as the base method for all variations of the traditional Zoom command </summary>
/// <param name="p3dMin"> the preferred lower left corner of the view, if known </param>
/// <param name="p3dMax"> the preferred upper right corner of the view, if known </param>
/// <param name="p3dCenter"> the view center point, if known </param>
/// <param name="dblFactor"> the final scale factor of the view </param>
public static void Zoom(Point3d p3dMin, Point3d p3dMax, Point3d p3dCenter, double dblFactor)
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    int intCurVport = Convert.ToInt32(Application.GetSystemVariable("CVPORT"));
    // get the extents of the current space; no points or only a center point is provided; check to see if ModelSpace is current
    if (db.TileMode)
        if ( p3dMin.Equals(new Point3d()) && p3dMax.Equals(new Point3d()) ) // if all are true
        {
            p3dMin = db.Extmin;
            p3dMax = db.Extmax;
        }
    else
        // check to see if PaperSpace is current
        if (intCurVport == 1)
            // get the extents of PaperSpace
            if ( p3dMin.Equals(new Point3d()) && p3dMax.Equals(new Point3d()) ) // if all are true
            {
                p3dMin = db.Pextmin;
                p3dMax = db.Pextmax;
            }
        else
            // get the extents of Model space
            if ( p3dMin.Equals(new Point3d()) && p3dMax.Equals(new Point3d()) ) // if all are true
            {
                p3dMin = db.Extmin;
                p3dMax = db.Extmax;
            }
    // start a transaction
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        // get the current view
        using (ViewTableRecord vtr = doc.Editor.GetCurrentView())
        {
            Extents3d ext3d;
            // translate world coordinate system (WCS) to display coordinate system (DCS)
            Matrix3d mat3dWcsToDcs;
            mat3dWcsToDcs = Matrix3d.PlaneToWorld(vtr.ViewDirection);
            mat3dWcsToDcs = Matrix3d.Displacement(vtr.Target - Point3d.Origin) * mat3dWcsToDcs;
            mat3dWcsToDcs = Matrix3d.Rotation(-vtr.ViewTwist, vtr.ViewDirection, vtr.Target) * mat3dWcsToDcs;
            // if a center point is specified, define the min and max point of the extents for Center and Scale modes
            if (p3dCenter.DistanceTo(Point3d.Origin) != 0)
            {
                p3dMin = new Point3d(p3dCenter.X - (vtr.Width / 2), p3dCenter.Y - (vtr.Height / 2), 0);
                p3dMax = new Point3d((vtr.Width / 2) + p3dCenter.X, (vtr.Height / 2) + p3dCenter.Y, 0);
            }
            ext3d = new Extents3d(p3dMin, p3dMax);
            // calculate the ratio between the width and height of the current view
            double dblViewRatio;
            dblViewRatio = (vtr.Width / vtr.Height);
            // tranform the extents of the view
            mat3dWcsToDcs = mat3dWcsToDcs.Inverse();
            ext3d.TransformBy(mat3dWcsToDcs);
            double dblWidth;
            double dblHeight;
            Point2d p2dNewCentPt;
            // check to see if a center point was provided (Center and Scale modes)
            if (p3dCenter.DistanceTo(Point3d.Origin) != 0)
            {
                dblWidth = vtr.Width;
                dblHeight = vtr.Height;
                if (dblFactor == 0)
                    p3dCenter = p3dCenter.TransformBy(mat3dWcsToDcs);
                p2dNewCentPt = new Point2d(p3dCenter.X, p3dCenter.Y);
            }
            else // working in Window, Extents and Limits mode
            {
                // calculate the new width and height of the current view
                dblWidth = ext3d.MaxPoint.X - ext3d.MinPoint.X;
                dblHeight = ext3d.MaxPoint.Y - ext3d.MinPoint.Y;
                // get the center of the view
                p2dNewCentPt = new Point2d(((ext3d.MaxPoint.X + ext3d.MinPoint.X) * 0.5), ((ext3d.MaxPoint.Y + ext3d.MinPoint.Y) * 0.5));
            }
            // check to see if the new width fits in current window
            if (dblWidth > (dblHeight * dblViewRatio))
                dblHeight = dblWidth / dblViewRatio;
            // resize and scale the view
            if (dblFactor != 0)
            {
                vtr.Height = dblHeight * dblFactor;
                vtr.Width = dblWidth * dblFactor;
            }
            // set the center of the view
            vtr.CenterPoint = p2dNewCentPt;
            // set the current view
            doc.Editor.SetCurrentView(vtr);
        }
        // commit the changes
        trans.Commit();
    }
}
« Last Edit: February 26, 2013, 08:44:20 pm by IDabble »