Author Topic: Select all paperspace pviewports - NOT paperspace itself  (Read 13357 times)

0 Members and 1 Guest are viewing this topic.

mkweaver

  • Bull Frog
  • Posts: 352
Select all paperspace pviewports - NOT paperspace itself
« on: May 28, 2008, 12:47:15 AM »
I have programmed for years with lisp, visual lisp, and vba for years, but am just now getting started using vb.net in autocad (as will be obvious by the code and the question).

I am trying to find the annotation scale of all viewports in the drawing. The code below selects all viewports in the drawing and cycles through them, allowing me to get the properties of each one, however, I'm having a hard time excluding the paperspace viewport.  I thought I could identify it as the viewport with the blockname property = "*Paper_Space", but that didn't work.

Suggestions are appreciated.

Mike
Code: [Select]
  <CommandMethod("SSVP")> _
Public Sub SSVP()
    Dim myDB As DatabaseServices.Database
    Dim myDWG As ApplicationServices.Document
    Dim myEd As EditorInput.Editor
    Dim myPSR As EditorInput.PromptSelectionResult
    Dim mySS As EditorInput.SelectionSet
    Dim mySelectedObject As EditorInput.SelectedObject
    Dim myFilter(0) As DatabaseServices.TypedValue
    Dim iIndex As Integer
    Dim myTransMan As TransactionManager
    Dim myTrans As Transaction
    Dim myViewport As Viewport
    myFilter(0) = New DatabaseServices.TypedValue( _
        DatabaseServices.DxfCode.Start, "VIEWPORT")
    Dim mySF As New EditorInput.SelectionFilter(myFilter)
    Dim myAcadEnt As DatabaseServices.Entity
    myDWG = ApplicationServices.Application.DocumentManager.MdiActiveDocument
    myDB = myDWG.Database
    myEd = myDWG.Editor
    myPSR = myEd.SelectAll(mySF)
    mySS = myPSR.Value
    iIndex = mySS.Count - 1
    myTransMan = myDWG.TransactionManager
    myTrans = myTransMan.StartTransaction
    For iIndex = 0 To mySS.Count - 1
      mySelectedObject = myPSR.Value.Item(iIndex)
      myAcadEnt = mySelectedObject.ObjectId.GetObject(DatabaseServices.OpenMode.ForRead)
      myViewport = mySelectedObject.ObjectId.GetObject(OpenMode.ForRead)
      If myViewport.BlockName = "*Paper_Space" Then
        Debug.Print("Paperspace viewport")
      Else
        Debug.Print(myViewport.AnnotationScale.Scale)
      End If
    Next
    myTrans.Dispose()
    myTransMan.Dispose()
    MsgBox(mySS.Count)
  End Sub

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #1 on: May 28, 2008, 10:44:58 AM »
Wow, that’s a dang good question. I really don’t know how to differentiate between the two.
Suggestions, assume that the first viewport that is owned by each layout is not the one you want.
Put all the viewports that you want to test on specific layer. Here is an example of the former you can test.
sorry it's in C#... Maybe someone else has a better idea.  :mrgreen:

Code: [Select]
#region #Using delarations
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Threading;
using System.Globalization;
using System.Reflection;
using System.Drawing.Imaging;

using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;

//using AcExtensions; mine

using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcEd = Autodesk.AutoCAD.EditorInput;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcWd = Autodesk.AutoCAD.Windows;
#endregion


[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
  public class Commands
  {
    [CommandMethod("doit")]
    public static void doit()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        foreach (AcDb.Viewport vp in doitsub())
        {
          ed.WriteMessage("\n" + vp.AnnotationScale.Scale.ToString());
        }
      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
    }

    public static  IEnumerable<AcDb.Viewport> doitsub()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

      List<AcDb.Viewport> head = new List<AcDb.Viewport>();
      List<AcDb.Viewport> tail = new List<AcDb.Viewport>();

      try
      {
        Database db = HostApplicationServices.WorkingDatabase;
        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
          ObjectId ldid = db.LayoutDictionaryId;
          DBDictionary ld = tr.GetObject(ldid, OpenMode.ForRead, false) as DBDictionary;

          foreach (DBDictionaryEntry de in ld)
          {
            Layout layout = tr.GetObject(de.Value, OpenMode.ForRead, false) as Layout;

            BlockTableRecord bt = tr.GetObject
              (layout.BlockTableRecordId, OpenMode.ForRead, false) as BlockTableRecord;

            foreach (ObjectId eid in bt)
            {
              DBObject dbo = tr.GetObject(eid, OpenMode.ForRead, false);

              if (dbo is AcDb.Viewport)
              {
                AcDb.Viewport vp = dbo as AcDb.Viewport;

                if (vp.BlockName != "*Model_Space")
                  tail.Add(vp);
         
              }
            }
            if (tail.Count != 0)
            {
              tail.RemoveAt(0);
              head.AddRange(tail);
              tail.Clear();
            }
          }
          tr.Commit();
        }
      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
      return head;
    }



« Last Edit: May 30, 2008, 06:52:38 AM by Daniel »

Glenn R

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #2 on: May 28, 2008, 11:19:43 AM »
To see if the current viewport is the paperspace viewport itself (ie in paperspace and not in a viewport):

Code: [Select]

Document doc = acadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

if (db.PaperSpaceVportId != ed.CurrentViewportObjectId)
    // not in paperspace viewport


You can also look up the help on AcDbLayout::getViewportArray and note what it says about the first element.
This is wrapped by the GetViewports() method of the Layout object.

Cheers,
Glenn.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #3 on: May 28, 2008, 11:46:02 AM »
...You can also look up the help on AcDbLayout::getViewportArray and note what it says about the first element.
This is wrapped by the GetViewports() method of the Layout object...

Thanks Glenn  :kewl:
my assumption was right. “The first ID in the list will be the paperspace viewport.”
A version using Layout::GetViewports())

Code: [Select]
[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
  public class Commands
  {
    [CommandMethod("doit")]
    public static void doit()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        foreach (AcDb.Viewport vp in doitsub())
        {
          ed.WriteMessage("\n" + vp.AnnotationScale.Scale.ToString());
        }
      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
    }

    public static IEnumerable<AcDb.Viewport> doitsub()
    {
      Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
      List<AcDb.Viewport> head = new List<AcDb.Viewport>();
      List<AcDb.Viewport> tail = new List<AcDb.Viewport>();
      Database db = HostApplicationServices.WorkingDatabase;
      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        ObjectId ldid = db.LayoutDictionaryId;
        DBDictionary ld = tr.GetObject(ldid, OpenMode.ForRead, false) as DBDictionary;
        foreach (DBDictionaryEntry de in ld)
        {
          Layout layout = tr.GetObject(de.Value, OpenMode.ForRead, false) as Layout;
          foreach (ObjectId eid in layout.GetViewports())
          {
            AcDb.Viewport vp = tr.GetObject(eid, OpenMode.ForRead, false) as AcDb.Viewport;

            if (vp.BlockName != "*Model_Space")
              tail.Add(vp);
           
          }
          if (tail.Count != 0)
          {
            tail.RemoveAt(0);
            head.AddRange(tail);
            tail.Clear();
          }
        }
        tr.Commit();
      }
      return head;
    }
  }
}

Glenn R

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #4 on: May 28, 2008, 11:57:44 AM »
Dan,

There is also a Database::GetViewports(bool)...try that as it would allow you to ditch cycling the layouts and opening each one looking for modelspace...
« Last Edit: May 28, 2008, 12:01:29 PM by Glenn R »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #5 on: May 28, 2008, 12:16:30 PM »
Dan,

There is also a Database::GetViewports(bool)...try that as it would allow you to ditch cycling the layouts and opening each one looking for modelspace...

Ha! Where did that come from  :lol:

new code

Code: [Select]
[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
  public class Commands
  {
    [CommandMethod("doit")]
    public static void doit()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        foreach (AcDb.Viewport vp in doitsub())
        {
          ed.WriteMessage("\n" + vp.AnnotationScale.Scale.ToString());
        }
      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
    }


    public static IEnumerable<AcDb.Viewport> doitsub()
    {
      Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
      List<AcDb.Viewport> head = new List<AcDb.Viewport>();
      Database db = HostApplicationServices.WorkingDatabase;
      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        ObjectIdCollection vpids = db.GetViewports(false);
        foreach (ObjectId vpid in vpids)
        {
          head.Add((AcDb.Viewport)tr.GetObject(vpid, OpenMode.ForRead, false));
        }
        tr.Commit();
      }
      return head;
    }
  }
}

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #6 on: May 28, 2008, 12:22:41 PM »
Mike, any chance we can get you to convert to C#?   :-D

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #7 on: May 28, 2008, 12:47:05 PM »
Maybe a better way... 

Code: [Select]
[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
  public class Commands
  {
    [CommandMethod("doit")]
    public static void doit()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        foreach (AnnotationScale annoScale in doitsub())
        {
          StringBuilder sb = new StringBuilder();
          sb.Append("\n");
          sb.Append("(");
          sb.Append(annoScale.Name);
          sb.Append(" , ");
          sb.Append(annoScale.Scale.ToString());
          sb.Append(")");
          ed.WriteMessage(sb.ToString());
        }
      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
    }


    public static IEnumerable<AnnotationScale> doitsub()
    {
      Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
      List<AnnotationScale> head = new List<AnnotationScale>();
      Database db = HostApplicationServices.WorkingDatabase;
      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        foreach (ObjectId vpid in db.GetViewports(false))
        {
          AcDb.Viewport vp = tr.GetObject(vpid, OpenMode.ForRead, false) as AcDb.Viewport;

          if (vp.AnnotationScale != null)
            head.Add(vp.AnnotationScale);
         
        }
      }
      return head;
    }
  }
}

Glenn R

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #8 on: May 28, 2008, 03:59:28 PM »
Much tighter :)

mkweaver

  • Bull Frog
  • Posts: 352
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #9 on: May 29, 2008, 11:20:51 PM »
First, thanks for all the help.  It is really helpful.

This is what I have now, and it works, as far as it goes.

Code: [Select]
  Public Shared Function doitsub() As IEnumerable(Of Autodesk.AutoCAD.DatabaseServices.Viewport)
    Dim Editor As Autodesk.AutoCAD.EditorInput.Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
    Dim head As New List(Of Autodesk.AutoCAD.DatabaseServices.Viewport)()
    Dim db As Database = HostApplicationServices.WorkingDatabase
    Using tr As Transaction = db.TransactionManager.StartTransaction()
      Dim vpids As ObjectIdCollection = db.GetViewports(False)
      For Each vpid As ObjectId In vpids
        head.Add(DirectCast(tr.GetObject(vpid, OpenMode.ForRead, False), Autodesk.AutoCAD.DatabaseServices.Viewport))
      Next
      tr.Commit()
    End Using
    Return head
  End Function


  <CommandMethod("doit")> _
  Public Shared Sub doit()
    Dim Editor As Autodesk.AutoCAD.EditorInput.Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor

    Try
      For Each vp As Autodesk.AutoCAD.DatabaseServices.Viewport In doitsub()
        Editor.WriteMessage("" & Chr(10) & "" + vp.AnnotationScale.Scale.ToString())
      Next
    Catch ex As SystemException
      Editor.WriteMessage("" & Chr(10) & "" + ex.Message)
      Editor.WriteMessage("" & Chr(10) & "" + ex.StackTrace)
    End Try
  End Sub

Now a couple of questions.  I know that to open an object for read I must wrap the read in a transaction.  So, I see that we've done that in DoitSub, but then when we get to Doit, I don't have to wrap that (the code that gets the viewport properties) in a transaction?  I mean, I can see that I don't - it works, but I would have expected a transaction here:-/
If I now want to modify the annotation scale for the viewport, it looks to me like I must:
  • Start another transaction
  • cycle through the viewports in Head
 
  • re-opening each for write
 
  • make the modification
  • and commit the transaction

Again, thanks for all the examples.  I'm seeing "slight of code" here that I didn't imagine possible.

Testing continues...
« Last Edit: May 29, 2008, 11:35:11 PM by mkweaver »

mkweaver

  • Bull Frog
  • Posts: 352
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #10 on: May 29, 2008, 11:26:01 PM »
Mike, any chance we can get you to convert to C#?   :-D

I spent some time with C and C++ years ago (turbo C 3, I think) and was, shall we say, overwhelmed.  I generated a couple of simple console apps, but didn't ever really get proficient.  Because of this, and the time I have with VB/VBA I assumed that I would come up to speed more quickly with VB.net than I would with C#.

Are there things I could do with C# that I won't be able to do with VB?

mkweaver

  • Bull Frog
  • Posts: 352
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #11 on: May 30, 2008, 12:19:36 AM »
And now another question.

I'm now trying to syncronize the viewport annotation scale with the viewport zoom scale factor.  I have the following code:
Code: [Select]
<CommandMethod("Doit2")> Public Shared Sub Doit2()
    Dim Editor As Autodesk.AutoCAD.EditorInput.Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
    Dim db As Database = HostApplicationServices.WorkingDatabase
    Dim vp As Autodesk.AutoCAD.DatabaseServices.Viewport
    Using tr As Transaction = db.TransactionManager.StartTransaction()
      Try
        For Each vpid As ObjectId In db.GetViewports(False)
          vp = tr.GetObject(vpid, OpenMode.ForWrite, False, True)
          [color=red]vp.AnnotationScale.Scale = vp.CustomScale[/color]
          Editor.WriteMessage("" & Chr(10) & "" + vp.AnnotationScale.Scale.ToString())
        Next
      Catch ex As SystemException
        Editor.WriteMessage("" & Chr(10) & "" + ex.Message)
        Editor.WriteMessage("" & Chr(10) & "" + ex.StackTrace)
      End Try
      tr.commit
    End Using
  End Sub

But it fails, telling me the scale property of the annotationscale is read only.  The documentation (objectarx for acad 2009) says otherwise:
Quote
Autodesk.AutoCAD.DatabaseServices Namespace > Viewport Class > Viewport Properties > Viewport.AnnotationScale Property
Viewport.AnnotationScale Property

C#
public Autodesk.AutoCAD.DatabaseServices.AnnotationScale AnnotationScale;

Visual Basic
Public Property AnnotationScale() As Autodesk.AutoCAD.DatabaseServices.AnnotationScale

Description
Accesses the AnnotationScale associated with the viewport

Conditions
Read / Write


I know that Acad 2009 has a scale syncronize button, but when working with drawings created prior to 2008 (the advent of annotation scaling) the viewport scale factor will be correct while it's annotation scale defaults to 1.  The scale sync button changes the zoom scale factor for the viewport :x Not the desired behavior.

Glenn R

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #12 on: May 30, 2008, 05:00:09 AM »
A suggestion:

In autocad, I generally won't pass around a container of opened objects like you're returning from doitsub.

Instead, pass around an ObjectIdCollection, as this has less overhead and means that you only open objects for read or write when you need them.

mkweaver

  • Bull Frog
  • Posts: 352
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #13 on: May 30, 2008, 07:33:12 AM »
A suggestion:

In autocad, I generally won't pass around a container of opened objects like you're returning from doitsub.

Instead, pass around an ObjectIdCollection, as this has less overhead and means that you only open objects for read or write when you need them.

I hadn't considered that the viewport objects returned by doitsub remained open, I thought committing the transaction would close them.  In this case, then, is there any clean-up that needs to be done with those open objects?

In this case, where I am first reading the scale then modifying it, it sounds like a good idea to use a collection of objectid.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #14 on: May 30, 2008, 12:09:30 PM »
...
If I now want to modify the annotation scale for the viewport, it looks to me like I must:
  • Start another transaction
  • cycle through the viewports in Head
 
  • re-opening each for write
 
  • make the modification
  • and commit the transaction

Again, thanks for all the examples.  I'm seeing "slight of code" here that I didn't imagine possible.

Testing continues...

Exactly,  You could write a class to handle all the methods you need to get/modify the properties.
You could even write a custom struct or class to store your data.
Here are some very quickly thrown together methods that don’t necessarily represent best programming practices, but might give you a few ideas.

Code: [Select]
#region #Using delarations
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Threading;
using System.Globalization;
using System.Reflection;
using System.Drawing.Imaging;

using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;

//using AcExtensions; mine

using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcEd = Autodesk.AutoCAD.EditorInput;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcWd = Autodesk.AutoCAD.Windows;
#endregion

[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
  public class Commands
  {
    [CommandMethod("doitOnce")]
    public static void doitOnce()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        List<AnnotationScale> scalelist = (List<AnnotationScale>)getScaleList();
        AnnotationScale current = scalelist[1];
        Set("Layout1", current);
      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
    }

    [CommandMethod("doitAll")]
    public static void doitAll()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        AnnoDataList annoList = (AnnoDataList)Get();

        List<AnnotationScale> scalelist = (List<AnnotationScale>)getScaleList();
        AnnotationScale current = scalelist[1];

        for (int i = 0; i < annoList.Count; i++)
          ed.WriteMessage("\nold" + annoList[i].ToString());

        for (int i = 0; i < annoList.Count; i++)
          annoList[i].AnnotationScale = current;

        Set(annoList);

        annoList = (AnnoDataList)Get();

        for (int i = 0; i < annoList.Count; i++)
          ed.WriteMessage("\nnew" + annoList[i].ToString());

      }
      catch (SystemException ex)
      {
        ed.WriteMessage("\n" + ex.Message);
        ed.WriteMessage("\n" + ex.StackTrace);
      }
    }

    public static void Set(string LayoutName, AnnotationScale annoScale)
    {
      LayoutManager manager = LayoutManager.Current;
      Database db = HostApplicationServices.WorkingDatabase;
      ObjectId layoutId = manager.GetLayoutId(LayoutName);
      if (layoutId.IsNull)
        return;

      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        AcDb.Layout layout = tr.GetObject(layoutId, OpenMode.ForRead, false) as AcDb.Layout;
        ObjectIdCollection ids = layout.GetViewports();

        if (ids.Count > 0)
        {
          ids.RemoveAt(0);
          for (int i = 0; i < ids.Count; i++)
          {
            AcDb.Viewport vp = tr.GetObject(ids[i], OpenMode.ForWrite, false) as AcDb.Viewport;
            vp.AnnotationScale = annoScale;
          }
        }
        tr.Commit();
      }
    }

    public static void Set(AnnoData annoData)
    {
      Database db = HostApplicationServices.WorkingDatabase;
      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        AcDb.Viewport vp = tr.GetObject(annoData.m_viewPortId, OpenMode.ForWrite, false) as AcDb.Viewport;
        vp.AnnotationScale = annoData.m_AnnotationScale;
        tr.Commit();
      }
    }

    public static void Set(IEnumerable<AnnoData> annoDataList)
    {
      Database db = HostApplicationServices.WorkingDatabase;
      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        foreach (AnnoData data in annoDataList)
        {
          AcDb.Viewport vp = tr.GetObject(data.m_viewPortId, OpenMode.ForWrite, false) as AcDb.Viewport;
          vp.AnnotationScale = data.m_AnnotationScale;
        }
        tr.Commit();
      }
    }

    public static IEnumerable<AnnoData> Get()
    {
      AnnoDataList head = new AnnoDataList();
      AnnoDataList tail = new AnnoDataList();
      Database db = HostApplicationServices.WorkingDatabase;
      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        ObjectId ldid = db.LayoutDictionaryId;
        DBDictionary ld = tr.GetObject(ldid, OpenMode.ForRead, false) as DBDictionary;
        foreach (DBDictionaryEntry de in ld)
        {
          Layout layout = tr.GetObject(de.Value, OpenMode.ForRead, false) as Layout;

          if (layout.LayoutName != "Model")
          {
            foreach (ObjectId eid in layout.GetViewports())
            {
              AcDb.Viewport vp = tr.GetObject(eid, OpenMode.ForRead, false) as AcDb.Viewport;

              if (vp.BlockName != "*Model_Space")
                tail.Add(new AnnoData(layout.LayoutName, vp.ObjectId, vp.AnnotationScale));

            }
            if (tail.Count != 0)
            {
              tail.RemoveAt(0);
              head.AddRange(tail);
              tail.Clear();
            }
          }
        }
        tr.Commit();
      }
      return head;
    }

    //KWB
    static public IEnumerable<AnnotationScale> getScaleList()
    {
      List<AnnotationScale> annolist = new List<AnnotationScale>();

      ObjectContextCollection occ = HostApplicationServices.WorkingDatabase.
        ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");

      foreach (AnnotationScale a in occ)
        annolist.Add(a);

      return annolist;
    }
  }

  //
  public class AnnoDataList : List<AnnoData>
  {
    public AnnoDataList() { }
  }
  public class AnnoData
  {
    internal string m_LayoutName;
    internal ObjectId m_viewPortId;
    internal AnnotationScale m_AnnotationScale;

    public AnnoData(string layout, ObjectId viewPortId, AnnotationScale annotationScale)
    {
      m_LayoutName = layout;
      m_viewPortId = viewPortId;
      m_AnnotationScale = annotationScale;
    }

    public string LayoutName
    {
      get { return this.m_LayoutName; }
      set { this.m_LayoutName = value; }
    }
    public ObjectId ViewPortId
    {
      get { return this.m_viewPortId; }
      set { this.m_viewPortId = value; }
    }
    public AnnotationScale AnnotationScale
    {
      get { return this.m_AnnotationScale; }
      set { this.m_AnnotationScale = value; }
    }

    public override string ToString()
    {
      StringBuilder sb = new StringBuilder();
      sb.Append("(");
      sb.Append(this.m_LayoutName);
      sb.Append(" , ");
      sb.Append(this.m_viewPortId.ToString());
      sb.Append(" , ");
      sb.Append(this.AnnotationScale.Scale.ToString());
      sb.Append(")");
      return sb.ToString();
    }
  }
}




« Last Edit: May 30, 2008, 12:13:01 PM by Daniel »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #15 on: May 30, 2008, 12:21:13 PM »
Mike, any chance we can get you to convert to C#?   :-D

I spent some time with C and C++ years ago (turbo C 3, I think) and was, shall we say, overwhelmed.  I generated a couple of simple console apps, but didn't ever really get proficient.  Because of this, and the time I have with VB/VBA I assumed that I would come up to speed more quickly with VB.net than I would with C#.

Are there things I could do with C# that I won't be able to do with VB?

It’s just my personal attempt to convert .NETers over to a C style language, because I can’t read VB.

Glenn R

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #16 on: May 30, 2008, 12:25:15 PM »
Ditto that.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #17 on: May 30, 2008, 07:24:50 PM »

nice example Daniel.


[< .. >
It’s just my personal attempt to convert .NETers over to a C style language, because I can’t read VB.


 :-D

I can read it, but my therapist has advised me not to.   :angel:
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

pellacad

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #18 on: August 13, 2009, 10:13:05 AM »
I am trying (desperately) to build a collection of viewports from a layout...

Why do I get a "FileNotFoundException was unhandled" alert when I try to execute this code?

I put "Public Shared Function doitsub" and "Public Shared Sub doit" into my form as a function and public sub respectively...and get the previously described File Not Found Error.

This problem is plaguing me, I think I may be at a breakthrough point in my programming if I can get this problem figured out.

 

First, thanks for all the help.  It is really helpful.

This is what I have now, and it works, as far as it goes.

Code: [Select]
  Public Shared Function doitsub() As IEnumerable(Of Autodesk.AutoCAD.DatabaseServices.Viewport)
    Dim Editor As Autodesk.AutoCAD.EditorInput.Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
    Dim head As New List(Of Autodesk.AutoCAD.DatabaseServices.Viewport)()
    Dim db As Database = HostApplicationServices.WorkingDatabase
    Using tr As Transaction = db.TransactionManager.StartTransaction()
      Dim vpids As ObjectIdCollection = db.GetViewports(False)
      For Each vpid As ObjectId In vpids
        head.Add(DirectCast(tr.GetObject(vpid, OpenMode.ForRead, False), Autodesk.AutoCAD.DatabaseServices.Viewport))
      Next
      tr.Commit()
    End Using
    Return head
  End Function


  <CommandMethod("doit")> _
  Public Shared Sub doit()
    Dim Editor As Autodesk.AutoCAD.EditorInput.Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor

    Try
      For Each vp As Autodesk.AutoCAD.DatabaseServices.Viewport In doitsub()
        Editor.WriteMessage("" & Chr(10) & "" + vp.AnnotationScale.Scale.ToString())
      Next
    Catch ex As SystemException
      Editor.WriteMessage("" & Chr(10) & "" + ex.Message)
      Editor.WriteMessage("" & Chr(10) & "" + ex.StackTrace)
    End Try
  End Sub

Now a couple of questions.  I know that to open an object for read I must wrap the read in a transaction.  So, I see that we've done that in DoitSub, but then when we get to Doit, I don't have to wrap that (the code that gets the viewport properties) in a transaction?  I mean, I can see that I don't - it works, but I would have expected a transaction here:-/
If I now want to modify the annotation scale for the viewport, it looks to me like I must:
  • Start another transaction
  • cycle through the viewports in Head
 
  • re-opening each for write
 
  • make the modification
  • and commit the transaction

Again, thanks for all the examples.  I'm seeing "slight of code" here that I didn't imagine possible.

Testing continues...

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #19 on: August 13, 2009, 10:36:37 AM »
I can't see anything in that code that would cause that error
maybe you can post your solution so we can take a look?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #20 on: August 13, 2009, 11:43:32 AM »
Hows my VB  :lol:

Code: [Select]
<CommandMethod("doit")> _
Public Shared Sub doit()
    Dim editor As Editor = Application.DocumentManager.MdiActiveDocument.Editor
    Dim db As Database = HostApplicationServices.WorkingDatabase
    Try
        Using tr As Transaction = db.TransactionManager.StartTransaction
            Dim ldid As ObjectId = db.LayoutDictionaryId
            Dim ld As DBDictionary = TryCast(tr.GetObject(ldid, OpenMode.ForRead, False),DBDictionary)
            Dim de As DBDictionaryEntry
            For Each de In ld
                Dim layout As Layout = TryCast(tr.GetObject(de.Value, OpenMode.ForRead, False),Layout)
                Dim ids As ObjectIdCollection = layout.GetViewports
                If (ids.Count > 0) Then
                    Dim i As Integer
                    For i = 1 To ids.Count - 1
                        Dim vp As Viewport = TryCast(tr.GetObject(ids.Item(i), OpenMode.ForRead, False),Viewport)
                        If (Not vp Is Nothing) Then
                            editor.WriteMessage(ChrW(10) & "Layout {0} , VP#{1} Width = {2}",
                                                         New Object() { layout.LayoutName, i, vp.Width })
                        End If
                    Next i
                End If
            Next
            tr.Commit
        End Using
    Catch ex As Exception
        editor.WriteMessage(ex.StackTrace)
    End Try
End Sub

Glenn R

  • Guest
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #21 on: August 17, 2009, 09:13:56 AM »
I agree with Dan - the FileNotFoundException is being thrown from somewhere else in your code.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #22 on: August 24, 2009, 01:52:34 AM »
Hows my VB  :lol:

Code: [Select]
<CommandMethod("doit")> _
Public Shared Sub doit()
    Dim editor As Editor = Application.DocumentManager.MdiActiveDocument.Editor
    Dim db As Database = HostApplicationServices.WorkingDatabase
// ..>>
<<..//
 End Sub

Dim humour ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Select all paperspace pviewports - NOT paperspace itself
« Reply #23 on: August 24, 2009, 02:25:14 AM »
I've been known to dim on occasion