Author Topic: Trouble transforming viewport  (Read 4147 times)

0 Members and 1 Guest are viewing this topic.

Bernd

  • Newt
  • Posts: 31
Trouble transforming viewport
« on: March 06, 2018, 10:41:25 AM »
I'm trying to go through all the layouts of a drawing and move their viewports' center because in a previous step all of the modelspace's entities have been moved as well.
This works fine as long as the viewport's coordinate system is wcs which unfortunately isn't always the case.
I tried to use @gile's GeometryExtension Library, but I guess I'm too dumb getting the differences between wcs, ucs, ocs, dcs and psdcs  :no: (further explanations would be very welcome  :idea: )
Here's what I tried so far:
Code - C#: [Select]
  1. [CommandMethod("enumerateLayouts")]
  2. public static void EnumerateLayouts()
  3. {
  4.     using (Transaction trans = _doc.TransactionManager.StartTransaction())
  5.     {
  6.         LayoutManager layoutManager = LayoutManager.Current;
  7.         string currentLayout = layoutManager.CurrentLayout;
  8.  
  9.         try
  10.         {
  11.             using (var layoutDictionary = (DBDictionary)trans.GetObject(_db.LayoutDictionaryId, OpenMode.ForRead))
  12.             {
  13.                 foreach (var layoutEntry in layoutDictionary)
  14.                 {
  15.                     if (layoutEntry.Key == "Model")
  16.                         continue;
  17.  
  18.                     using (var layout = (Layout)trans.GetObject(layoutEntry.Value, OpenMode.ForRead))
  19.                     {
  20.                         layoutManager.CurrentLayout = layout.LayoutName;
  21.  
  22.                         bool isPaperspace = true;
  23.                         foreach (ObjectId viewportId in layout.GetViewports())
  24.                         {
  25.                             // First ID of this list is Paperspace
  26.                             if (isPaperspace)
  27.                             {
  28.                                 isPaperspace = false;
  29.                                 continue;
  30.                             }
  31.  
  32.                             using (var viewport = (Viewport)trans.GetObject(viewportId, OpenMode.ForWrite))
  33.                             {
  34.                                 double xShift = 28999942;
  35.                                 double yShift = -1729;
  36.  
  37.                                 Point3d viewCenter3d = new Point3d(viewport.ViewCenter.X, viewport.ViewCenter.Y, 0);
  38.                                 viewCenter3d = viewCenter3d.Trans(GeometryExtensions.CoordSystem.UCS, GeometryExtensions.CoordSystem.WCS);
  39.                                 viewCenter3d = viewCenter3d.TransformBy(Matrix3d.Displacement(new Vector3d(xShift, yShift, 0)));
  40.                                 viewport.ViewCenter = new Point2d(viewCenter3d.X, viewCenter3d.Y);
  41.                             }
  42.  
  43.                             _editor.Regen();
  44.                         }
  45.                     }
  46.                 }
  47.  
  48.                 trans.Commit();
  49.             }
  50.         }
  51.         catch (System.Exception e)
  52.         {
  53.             _editor.WriteMessage(e.Message);
  54.             trans.Abort();
  55.         }
  56.         finally
  57.         {
  58.             layoutManager.CurrentLayout = currentLayout;
  59.         }
  60.     }
  61. }
  62.  
Result: layouts in wcs are correct, layouts with ucs are unchanged.
I'd really appreciate any help.
Bernd

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Trouble transforming viewport
« Reply #1 on: March 06, 2018, 12:00:25 PM »
Hi,

Assuming all entites have been moved from 0,0 to 28999942,-1729, you have to move the viewports view center with this displacement vector transfromed by the WCS2DCS matrix of the viewport.

Try this (note you should not use per document class fields as _doc or _db in a static method).

Code - C#: [Select]
  1.         [CommandMethod("enumerateLayouts")]
  2.         public static void EnumerateLayouts()
  3.         {
  4.             var doc = AcAp.DocumentManager.MdiActiveDocument;
  5.             var db = doc.Database;
  6.             var ed = doc.Editor;
  7.             using (Transaction trans = doc.TransactionManager.StartTransaction())
  8.             {
  9.                 LayoutManager layoutManager = LayoutManager.Current;
  10.                 string currentLayout = layoutManager.CurrentLayout;
  11.  
  12.                 try
  13.                 {
  14.                     using (var layoutDictionary = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead))
  15.                     {
  16.                         foreach (var layoutEntry in layoutDictionary)
  17.                         {
  18.                             if (layoutEntry.Key == "Model")
  19.                                 continue;
  20.  
  21.                             using (var layout = (Layout)trans.GetObject(layoutEntry.Value, OpenMode.ForRead))
  22.                             {
  23.                                 layoutManager.CurrentLayout = layout.LayoutName;
  24.  
  25.                                 bool isPaperspace = true;
  26.                                 foreach (ObjectId viewportId in layout.GetViewports())
  27.                                 {
  28.                                     // First ID of this list is Paperspace
  29.                                     if (isPaperspace)
  30.                                     {
  31.                                         isPaperspace = false;
  32.                                         continue;
  33.                                     }
  34.  
  35.                                     using (var viewport = (Viewport)trans.GetObject(viewportId, OpenMode.ForWrite))
  36.                                     {
  37.                                         double xShift = 28999942;
  38.                                         double yShift = -1729;
  39.                                         Vector3d disp = new Vector3d(xShift, yShift, 0.0).TransformBy(viewport.WCS2DCS());
  40.                                         viewport.ViewCenter += new Vector2d(disp.X, disp.Y);
  41.                                     }
  42.                                     ed.Regen();
  43.                                 }
  44.                             }
  45.                         }
  46.  
  47.                         trans.Commit();
  48.                     }
  49.                 }
  50.                 catch (System.Exception e)
  51.                 {
  52.                     ed.WriteMessage(e.Message);
  53.                     trans.Abort();
  54.                 }
  55.                 finally
  56.                 {
  57.                     layoutManager.CurrentLayout = currentLayout;
  58.                 }
  59.             }
  60.         }
Speaking English as a French Frog

Bernd

  • Newt
  • Posts: 31
Re: Trouble transforming viewport
« Reply #2 on: March 07, 2018, 03:27:51 AM »
Hi Gilles,

thank you - works as expected (and thanks of course for your library!).
So am I correct that ucs only counts when one is in model space? And the equivalent for paper space is dcs? And what the heck is psdcs for?
I'm really having a hard time understanding Autodesk's documentation on this topic:
Quote
UCS
  User coordinate system (UCS): The working coordinate system. The user specifies a UCS to make drawing tasks easier. All points passed to AutoCAD commands, including those returned from AutoLISP routines and external functions, are points in the current UCS (unless the user precedes them with an * at the Command prompt). If you want your application to send coordinates in the WCS, OCS, or DCS to AutoCAD commands, you must first convert them to the UCS by calling the translating them and then transforming the Point3d or Point 2d object with the TransformBy method that represents the coordinate value.

OCS
  Object coordinate system (also known as Entity coordinate system or ECS): Point values specified by certain methods and properties for the Polyline2d and Polyline objects are expressed in this coordinate system, relative to the object. These points are usually converted into the WCS, current UCS, or current DCS, according to the intended use of the object. Conversely, points in WCS, UCS, or DCS must be translated into an OCS before they are written to the database by means of the same properties.
  When converting coordinates to or from the OCS you must consider the normal of the OCS.

DCS
  Display coordinate system: The coordinate system where objects are transformed before they are displayed. The origin of the DCS is the point stored in the AutoCAD system variable TARGET, and its Z axis is the viewing direction. In other words, a viewport is always a plan view of its DCS. These coordinates can be used to determine where something will be displayed to the user.

PSDCS
  Paper space DCS: This coordinate system can be transformed only to or from the DCS of a Model space viewport. This is essentially a 2D transformation, where the X and Y coordinates are always scaled. Therefore, it can be used to find the scale factor between the two coordinate systems. The PSDCS can be transformed only into a Model space viewport.
« Last Edit: March 07, 2018, 03:50:45 AM by Bernd »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Trouble transforming viewport
« Reply #3 on: March 07, 2018, 04:46:19 AM »
So am I correct that ucs only counts when one is in model space? And the equivalent for paper space is dcs? And what the heck is psdcs for?

It's quite difficult for me to explain this in a better English than the docs does, but I'd give a try.
First, no you can also use UCSs in the paper space to draw in this space, for example adding annotations, inserting a title block, and, of course drawing a viewport.

The DCS is the coordinate system related to the view in a viewport (either a paper space viewport or a model space viewport). The view in the viewport may have been rotated or 3d rotated.

The PSDCS is ONLY used to convert paper space WCS coordinates from or to a paper space viewport view coordinates (DCS).
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Trouble transforming viewport
« Reply #4 on: March 07, 2018, 07:31:20 AM »
Maybe it's more clear with a little example.

Run the DVPB command, select a paper space viewport and you'd see 2 rectangles in model space:
A red rectangle figuring the viewport DCS extents (it always lies on the XY plane and have the WCS origin as center).
A green rectangle figuring the viewport.

Code - C#: [Select]
  1.         [CommandMethod("DVPB", CommandFlags.NoTileMode)]
  2.         public void DrawViewportBoundaryInModelSpace()
  3.         {
  4.             var doc = AcAp.DocumentManager.MdiActiveDocument;
  5.             var db = doc.Database;
  6.             var ed = doc.Editor;
  7.  
  8.             var options = new PromptEntityOptions("\nSelect rectangular viewport: ");
  9.             options.SetRejectMessage("\nSelected object must be a viewport.");
  10.             options.AddAllowedClass(typeof(Viewport), true);
  11.             var result = ed.GetEntity(options);
  12.             if (result.Status != PromptStatus.OK) return;
  13.  
  14.             using (var tr = db.TransactionManager.StartTransaction())
  15.             {
  16.                 var vp = (Viewport)tr.GetObject(result.ObjectId, OpenMode.ForRead);
  17.  
  18.                 var model = (BlockTableRecord)tr.GetObject(
  19.                     SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
  20.  
  21.                 // local methods
  22.                 void DrawLine(Point3d p1, Point3d p2, int colorIndex)
  23.                 {
  24.                     var line = new Line(p1, p2) { ColorIndex = colorIndex };
  25.                     model.AppendEntity(line);
  26.                     tr.AddNewlyCreatedDBObject(line, true);
  27.                 }
  28.                 void DrawVp(Point3d p1, Point3d p2, Point3d p3, Point3d p4, int colorIndex)
  29.                 {
  30.                     DrawLine(p1, p2, colorIndex);
  31.                     DrawLine(p2, p3, colorIndex);
  32.                     DrawLine(p3, p4, colorIndex);
  33.                     DrawLine(p4, p1, colorIndex);
  34.                 }
  35.  
  36.                 // get the viewport vertices in paper space WCS coordinates
  37.                 var extents = vp.GeometricExtents;
  38.                 var pt1 = extents.MinPoint;
  39.                 var pt2 = new Point3d(extents.MaxPoint.X, extents.MinPoint.Y, 0.0);
  40.                 var pt3 = extents.MaxPoint;
  41.                 var pt4 = new Point3d(extents.MinPoint.X, extents.MaxPoint.Y, 0.0);
  42.  
  43.                 // transform the points to the viewport DCS
  44.                 pt1 = pt1.TransformBy(vp.PSDCS2DCS());
  45.                 pt2 = pt2.TransformBy(vp.PSDCS2DCS());
  46.                 pt3 = pt3.TransformBy(vp.PSDCS2DCS());
  47.                 pt4 = pt4.TransformBy(vp.PSDCS2DCS());
  48.                 // draw a red rectangle in model space
  49.                 DrawVp(pt1, pt2, pt3, pt4, 1);
  50.  
  51.                 // transform the points to the WCS
  52.                 pt1 = pt1.TransformBy(vp.DCS2WCS());
  53.                 pt2 = pt2.TransformBy(vp.DCS2WCS());
  54.                 pt3 = pt3.TransformBy(vp.DCS2WCS());
  55.                 pt4 = pt4.TransformBy(vp.DCS2WCS());
  56.                 // draw a green rectangle in model space
  57.                 DrawVp(pt1, pt2, pt3, pt4, 3);
  58.  
  59.                 tr.Commit();
  60.             }
  61.         }
Speaking English as a French Frog

Bernd

  • Newt
  • Posts: 31
Re: Trouble transforming viewport
« Reply #5 on: March 07, 2018, 08:18:32 AM »
Gilles,

thanks for taking the time to fire up an example just to explain an apparently easy topic to folks like me (I hope, I'm not the only one  :embarrassed2: ).
This is really great.

daboho

  • Newt
  • Posts: 40
Re: Trouble transforming viewport
« Reply #6 on: August 15, 2021, 07:28:12 AM »
@gile why show like this in my picture
warning
"viewport does not contain a defenition for WCS2DCS"
see my picture

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Trouble transforming viewport
« Reply #7 on: August 15, 2021, 10:23:19 AM »
@daboho, as said in the first message, you have to reference the GeometryExtensions library which contains the Viewport.DCS2WCS extension method.
Speaking English as a French Frog

daboho

  • Newt
  • Posts: 40
Re: Trouble transforming viewport
« Reply #8 on: August 17, 2021, 04:13:55 PM »
where is i can get reference ?

daboho

  • Newt
  • Posts: 40
Re: Trouble transforming viewport
« Reply #9 on: August 17, 2021, 04:53:37 PM »
@gile i has succses to get geometric exstension but result
i am sorri i am is still newbiew in C# i has run
i want ask first is
 double xShift = 28999942;   this is for coordinat x mean in model space ?
 double yShift = -1729;         this is for coordinat y mean in model space ?
please help

daboho

  • Newt
  • Posts: 40
Re: Trouble transforming viewport
« Reply #10 on: August 19, 2021, 11:15:10 AM »
@gile i has try for any week but stuck for this code
step 1 : i am select borders/rectangle in models space
step 2 : every borders/rectangle will be zoom to all paperspace
the problem while multi select ,all paperspace has same as borders / first selection what is problem for this code
Code: [Select]
  private List<ObjectId> lisFindObjIdOfCircle()
        {
            Document doc = acApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            List<ObjectId> lisObjectIdFound = new List<ObjectId>();

            try
            {
                var option = new PromptSelectionOptions(); option.MessageForAdding = "\nselect Rectangle/Borders Cover Gambar";
                var psr = ed.GetSelection(option, new SelectionFilter(new[] { new TypedValue(0, "LWPOLYLINE,Polyline") }));
             
                SelectionSet acSSet = psr.Value;
                if (psr.Status == PromptStatus.OK)
                {
                   
                    foreach (SelectedObject recID in acSSet)
                    {
                        lisObjectIdFound.Add(recID.ObjectId);
                    }
                }



            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError in getting ObjectId of all circles on the drawing. " +
                                 "Error message is: " + ex.Message);
            }

            return (lisObjectIdFound);
        }

      [CommandMethod("zv", CommandFlags.UsePickSet | CommandFlags.Redraw)]
        public void testview()
        {


            var doc = acApp.DocumentManager.MdiActiveDocument;
            Database db = HostApplicationServices.WorkingDatabase;
            var ed = doc.Editor;
            List<ObjectId> lisCircleObjId = new List<ObjectId>();
            lisCircleObjId = this.lisFindObjIdOfCircle();
         
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                using (var layoutDictionary = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead))
                {
                    using (var mylock = doc.LockDocument())
                    {
                            foreach (var layoutEntry in layoutDictionary)
                            {
                                if (layoutEntry.Key == "Model") continue;

                                using (var layout = (Layout)trans.GetObject(layoutEntry.Value, OpenMode.ForWrite))
                                {

                                    var n = 0;
                                    var extSelObj = new Extents3d();
                                    // ObjectId layoutId = LayoutManager.Current.CreateLayout(layout.LayoutName);             // membuat layout
                                    LayoutManager.Current.CurrentLayout = layout.LayoutName;
                                    Entity entObj = (Entity)trans.GetObject(lisCircleObjId[n], OpenMode.ForRead);
                                    ObjectId idcover = entObj.ObjectId;
                                    extSelObj.AddExtents(entObj.GeometricExtents);
                                    bool isPaperspace = true;
                                    foreach (ObjectId viewportId in layout.GetViewports())
                                    {
                                        if (isPaperspace)
                                        {
                                            isPaperspace = false;
                                            continue;
                                        }
                                        using (var viewport = (Viewport)trans.GetObject(viewportId, OpenMode.ForWrite))
                                        {
                                            if (viewport.Locked == true) viewport.Locked = false;
                                            viewport.On = true;
                                            ed.Command("._MSPACE");
                                            // buat extend dari objectID
                                            var pl = trans.GetObject(entObj.ObjectId, OpenMode.ForRead) as Polyline;
                                            var ext = new Extents3d();
                                            ext = pl.GeometricExtents;
                                            var mn = ext.MinPoint;
                                            var mx = ext.MaxPoint;
                                            dynamic appAcad = acApp.AcadApplication;
                                            //appAcad.ZoomWindow(mn.ToArray(), mx.ToArray());
                                            ObjectId[] newIds = new ObjectId[0];
                                            ed.SetImpliedSelection(newIds);
                                            appAcad.ZoomWindow(extSelObj.MinPoint.ToArray(), extSelObj.MaxPoint.ToArray());
                                            ed.SetImpliedSelection(new ObjectId[] { idcover });
                                            // ed.SetImpliedSelection(new ObjectId[] { myRec });
                                            ed.Command("._PSPACE", "");
                                            doc.Editor.SwitchToPaperSpace();
                                            dynamic acadApp = acApp.AcadApplication;
                                            acadApp.ZoomExtents();
                                            ed.WriteMessage("\n viewlocked : " + viewport.Locked.ToString());
                                            break;

                                        }
                                        n += 1;
                                        ed.Regen();
                                    }
                                }
                            }

                    }
                }

                trans.Commit();
               
            }

        }




« Last Edit: August 19, 2021, 11:46:47 AM by daboho »

daboho

  • Newt
  • Posts: 40
Re: Trouble transforming viewport
« Reply #11 on: August 19, 2021, 11:21:36 AM »
@Gile
in this file  in every paperspae should be what is i wanted