Author Topic: Multiple modelspace viewports  (Read 3767 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
Multiple modelspace viewports
« on: October 12, 2008, 12:22:26 PM »
There are some things I can't do in vba and this is one of them.
In C# I can't seem to find out how to make the viewport configuration active?
So far with the code below I get 3 vps on the left with the view and ucs I want.
Now I need to make it active.
The views they contain will be next.
Code: [Select]
      [CommandMethod ( "Create4VPorts")]
        public void Create4VPorts()
        {
            String sName = "4Left";           
            Database db=HostApplicationServices.WorkingDatabase;
            Document doc=acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;     

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                ViewportTable vt = (ViewportTable)doc.TransactionManager.GetObject(
                        db.ViewportTableId, OpenMode.ForRead, false) as ViewportTable;
                if (vt.Has(sName)) return;
                vt.UpgradeOpen();
                ViewportTableRecord vp;
                Vector3d viewdir = new Vector3d(1, 1, 1);
 
                for (int i = 0; i <= 3; i++)
                {
                    vp = new ViewportTableRecord();
                    vp.Name = sName;
                    switch (i)
                    {
                        case 0:
                            vp.LowerLeftCorner = new Point2d(0.333, 0);
                            vp.UpperRightCorner = new Point2d(1, 1);
                            vp.SetUcs(OrthographicView.TopView);
                            break;
                        case 1:
                            vp.LowerLeftCorner = new Point2d(0, 0.666);
                            vp.UpperRightCorner = new Point2d(0.333, 1);
                            viewdir = new Vector3d(0, 0, 1);
                            break;
                        case 2:
                            vp.LowerLeftCorner = new Point2d(0, 0.333);
                            vp.UpperRightCorner = new Point2d(0.333, 0.666);
                            viewdir = new Vector3d(1, 0, 0);
                            vp.SetUcs(OrthographicView.RightView);
                            break;
                        case 3:
                            vp.LowerLeftCorner = new Point2d(0, 0);
                            vp.UpperRightCorner = new Point2d(0.333, 0.333);
                            viewdir = new Vector3d(0, 1, 0);
                            vp.SetUcs(OrthographicView.FrontView);
                            break;
                        default:
                            break;

                    }
                    vp.ViewDirection = viewdir;               
                   
                    vt.Add(vp);
                    db.TransactionManager.AddNewlyCreatedDBObject(vp, true);
                }

                //ed.SwitchToModelSpace();
                acadApp.SetSystemVariable("cvport",2);//no go here

                tr.Commit();
                tr.Dispose();

            }
        }
The cad way to make this active is  -vports r 4left

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8805
  • AKA Daniel
Re: Multiple modelspace viewports
« Reply #1 on: October 14, 2008, 10:44:58 AM »
Did you get this worked out? From what I see you are setting up the viewport configuration but not actually adding any Viewport entities to the layout.
I’m not quite sure how to do this though

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Multiple modelspace viewports
« Reply #2 on: October 14, 2008, 10:59:01 AM »
Daniel, no I didn't get it worked out.
This vp configuration is only in modelspace (ViewportTable is only for modelspace),  similar to the cad command vports 4right.
I cant even get sendcommand to work
doc.SendStringToExecute("-vports r 4left ",false, true, true); requires an enter by the user, no matter how I write it, there is a post by Mick where some commands are locked,  perhaps this is one, but they are not locked by vba.
Setting the view centers is probably going to be another difficult part, they usually don't behave


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8805
  • AKA Daniel
Re: Multiple modelspace viewports
« Reply #3 on: October 14, 2008, 12:09:40 PM »
This vp configuration is only in modelspace (ViewportTable is only for modelspace),  similar to the cad command vports 4right.
 


What your code is doing is creating a viewport configutation that can be used in any tab. See pic

You can use SendStringToExecute but is it a kludge?

Code: [Select]
[CommandMethod("Create4VPorts")]
    public void Create4VPorts()
    {
      String sName = "4Left";
      Database db = HostApplicationServices.WorkingDatabase;
      Document doc = acadApp.DocumentManager.MdiActiveDocument;
      Editor ed = doc.Editor;

      using (Transaction tr = doc.TransactionManager.StartTransaction())
      {
        ViewportTable vt = (ViewportTable)doc.TransactionManager.GetObject(
                db.ViewportTableId, OpenMode.ForRead, false) as ViewportTable;
        if (vt.Has(sName)) return;
        vt.UpgradeOpen();
        ViewportTableRecord vp;
        Vector3d viewdir = new Vector3d(1, 1, 1);

        for (int i = 0; i <= 3; i++)
        {
          vp = new ViewportTableRecord();
          vp.Name = sName;
          switch (i)
          {
            case 0:
              vp.LowerLeftCorner = new Point2d(0.333, 0);
              vp.UpperRightCorner = new Point2d(1, 1);
              vp.SetUcs(OrthographicView.TopView);
              break;
            case 1:
              vp.LowerLeftCorner = new Point2d(0, 0.666);
              vp.UpperRightCorner = new Point2d(0.333, 1);
              viewdir = new Vector3d(0, 0, 1);
              break;
            case 2:
              vp.LowerLeftCorner = new Point2d(0, 0.333);
              vp.UpperRightCorner = new Point2d(0.333, 0.666);
              viewdir = new Vector3d(1, 0, 0);
              vp.SetUcs(OrthographicView.RightView);
              break;
            case 3:
              vp.LowerLeftCorner = new Point2d(0, 0);
              vp.UpperRightCorner = new Point2d(0.333, 0.333);
              viewdir = new Vector3d(0, 1, 0);
              vp.SetUcs(OrthographicView.FrontView);
              break;
            default:
              break;

          }
          vp.ViewDirection = viewdir;

          vt.Add(vp);
          db.TransactionManager.AddNewlyCreatedDBObject(vp, true);
        }
        tr.Commit();
      }
      doc.SendStringToExecute("-vports Restore 4left\n", false, true, true); //<<----------------------
    }

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Multiple modelspace viewports
« Reply #4 on: October 14, 2008, 07:53:09 PM »
Cheers Daniel, I had tryed the \n but i must have mucked it up.
I also didn't know you could use this in paperspace, the help says
Code: [Select]
This class is the symbol table for ViewportTableRecords, which represent viewport configurations within AutoCAD when the system variable TILEMODE == 1
Next step, On to starting with a rectangle and trying to have  that centered  in each of the 4 vps

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8805
  • AKA Daniel
Re: Multiple modelspace viewports
« Reply #5 on: October 14, 2008, 08:03:19 PM »
I don’t think it was the \n, but rather the placement of the line of code. I also need to do a little more reading into Viewports


ahlzl

  • Guest
Re: Multiple modelspace viewports
« Reply #6 on: October 14, 2008, 08:27:14 PM »
thank you, Daniel !

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Multiple modelspace viewports
« Reply #7 on: October 27, 2008, 12:07:59 AM »
\n works whereas a space doesn't  because you need to enter rather than spacebar the actual cad command.

I have been pretty confused about these multiple vports. Didn't matter I did I couldn't get a consistant result.
Here are a coulple of findings
1) Each viewport maintains it's own dcs,
the position of the viewport on the screen has no relationship to the dcs and it vport center.
2) Height and width are taken from bottom left corner and if their ratios are incorrect the cenerpoint will be wrong.

Below is getting close but I cannot get the width height relationship for an isoview.
In a new drawing- draw a circle with a diameter of 1.
On zooming extents the properties window reads  height 1.0089 width=1.3637
Now switch to sw isoview and  height=1.0522 width=8.533, the latter doesn't make much sense


Code: [Select]
         [CommandMethod ( "4V")]
        public void Create4VPorts()
        {
            String sName = "4Left";           
            Database db=HostApplicationServices.WorkingDatabase;
            Document doc=acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            acadApp.SetSystemVariable("Tilemode", 1);
            ViewportTableRecord vp;

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                ViewportTable vt =tr.GetObject(
                        db.ViewportTableId, OpenMode.ForRead, false) as ViewportTable;
                if (vt.Has(sName)) goto skip;
                Vector3d viewdir = new Vector3d(-1, -1, 1);
                vp = tr.GetObject(vt["*Active"],
                    OpenMode.ForRead) as ViewportTableRecord;
               
                //dcs
                Matrix3d ucs = ed.CurrentUserCoordinateSystem;
                Point3d viewctr = ((Point3d)acadApp.GetSystemVariable("VIEWCTR")).TransformBy(ucs);
                ViewTableRecord vtr = ed.GetCurrentView();
                Vector3d vd = vtr.ViewDirection.GetNormal();
                Plane pn = new Plane(vtr.Target, vd);
                Matrix3d dcs = Matrix3d.WorldToPlane(pn);
                if (vtr.ViewTwist != 0)
                    dcs = dcs * Matrix3d.Rotation(-vtr.ViewTwist, vtr.ViewDirection, vtr.Target);
                dcs = dcs.Inverse();

                Point3d cenDcs=viewctr.TransformBy(dcs);
                Point2d cen = new Point2d(cenDcs.X, cenDcs.Y);
                double vpHeight = ((double)acadApp.GetSystemVariable("VIEWSIZE"));
                Point2d screensize = (Point2d)acadApp.GetSystemVariable("Screensize");
                double ratio = screensize.X / screensize.Y, widthoverht = 0.0;
                double vpWidth = vpHeight*ratio,Wd=0;
               
                vt.UpgradeOpen();
                for (int i = 0; i <= 3; i++)
                {
                    vp = new ViewportTableRecord();
                    vp.Name = sName;
 
                //bottom  0, 0, -1 //Left  -1, 0, 0 //back 0, 1, 0
                //se  1, -1, 1 //nw  1, 1, 1 //ne  -1, 1, 1
                             
                    switch (i)
                    {
                        case 0:   //Southwest
                            vp.LowerLeftCorner = new Point2d(0.333, 0);
                            vp.UpperRightCorner = new Point2d(1, 1);
                            vp.SetUcs(OrthographicView.TopView);
                           
                            widthoverht = ((vpWidth * 2 / 3) / vpHeight);
                            vp.Height = vpWidth / widthoverht;
                            Wd = vpWidth * 2;
                            break;
                        case 1:  //Topview
                            vp.LowerLeftCorner = new Point2d(0, 0.666);
                            vp.UpperRightCorner = new Point2d(0.333, 1);
                            vp.SetUcs(vp.ViewOrthographic);                 
                            widthoverht = ((vpWidth  / 3) / (vpHeight/3));
                            vp.Height = vpWidth / widthoverht;
                            Wd = vpWidth;
                            viewdir = new Vector3d(0, 0, 1);
                            break;
                        case 2:  //Rightview
                            vp.LowerLeftCorner = new Point2d(0, 0.333);
                            vp.UpperRightCorner = new Point2d(0.333, 0.666);   
                            vp.SetUcs(OrthographicView.RightView);
                            widthoverht = ((vpWidth / 3) / (vpHeight / 3));
                            vp.Height = vpWidth / widthoverht;
                            Wd = vpWidth;
                            viewdir = new Vector3d(1, 0, 0);
                            cen = new Point2d(cenDcs.Y, 0);
                            break;
                        case 3:  //frontview
                            vp.LowerLeftCorner = new Point2d(0, 0);
                            vp.UpperRightCorner = new Point2d(0.333, 0.333); 
                            vp.SetUcs(OrthographicView.FrontView);
                            widthoverht = ((vpWidth / 3) / (vpHeight / 3));
                            vp.Height = vpWidth / widthoverht;
                            Wd = vpWidth;
                            viewdir = new Vector3d(0, -1, 0);
                            cen = new Point2d(cenDcs.X, 0);
                            break;
                        default:
                            break;

                    }       
                    vp.CenterPoint = cen;
                    vp.ViewDirection = viewdir;
                    vp.Width = Wd;
                   
                    vt.Add(vp);
                    db.TransactionManager.AddNewlyCreatedDBObject(vp, true);
                   
                }
               
                tr.Commit();
            }
             skip:
             doc.SendStringToExecute("-vports Restore 4left\n", false, true, true);
        }
« Last Edit: October 27, 2008, 12:11:27 AM by Bryco »

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Multiple modelspace viewports
« Reply #8 on: October 31, 2008, 08:42:06 AM »
Finally, figured out how to set center and width.
If you draw a rectangle in world standard 2d and zoomextents, then run this you will get the same result as using the sw view tool.
(Although cad zooms out a wee bit from true extents)
The use of the Math.PI * 0.25 (45 deg) only works for isoviews but a generic formular could be made.


Code: [Select]
         [CommandMethod("iso")]
         public void CreateIso()
         {
            Database db = HostApplicationServices.WorkingDatabase;
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            acadApp.SetSystemVariable("Tilemode", 1);
            Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            Point3d viewctr = ((Point3d)acadApp.GetSystemVariable("VIEWCTR")).TransformBy(ucs);
            Vector3d viewdir = new Vector3d(-1, -1, 1);//sw
            Matrix3d dcs = WtoDcs();
            Point3d cenDcs = viewctr.TransformBy(dcs);
            double vpHeight = ((double)acadApp.GetSystemVariable("VIEWSIZE"));
            Point2d screensize = (Point2d)acadApp.GetSystemVariable("Screensize");
            double vpWidth = vpHeight * screensize.X / screensize.Y;

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                 ViewportTable vt = tr.GetObject(
                         db.ViewportTableId, OpenMode.ForRead, false) as ViewportTable;               
                 ViewportTableRecord vp = new ViewportTableRecord();
                 vp.Name = "iso";
                 vp.SetUcs(OrthographicView.TopView);
                 double widthoverht = vpWidth  / vpHeight;
                 Extents3d extents = new Extents3d(Point3d.Origin, new Point3d(1, 1, 0));
                 db.UpdateExt(true);
                 extents.Set(db.Extmin, db.Extmax);
                 Point3d min = extents.MinPoint;
                 Point3d max = extents.MaxPoint;
                 Point3d ex = new Point3d(max.X - min.X, min.Y - max.Y, max.Z - min.Z);
                 ex = ex.TransformBy(Matrix3d.Rotation(Math.PI * 0.25, Vector3d.ZAxis, Point3d.Origin));
                 double Wd = ex.X;
                 vp.Height =  Wd / widthoverht;

                 Vector3d vd = new Vector3d(-1, -1, 1);//sw
                 Plane pn = new Plane(Point3d.Origin, viewdir);
                 Point2d cen = viewctr.Convert2d(pn);
                 vp.CenterPoint = cen;
                 vp.ViewDirection = viewdir;
                 vp.Width =  Wd;
                 vt.UpgradeOpen(); 
                 vt.Add(vp);
                 db.TransactionManager.AddNewlyCreatedDBObject(vp, true);
                 tr.Commit();

             }
            doc.SendStringToExecute("-vports Restore iso\n", false, true, true);
            doc.SendStringToExecute("-vports Delete iso\n", false, true, true);
         }