Jump to content

Collecting ViewPorts in a Drawing Using VB.NET


PellaCAD

Recommended Posts

Is it possible to build a collection of viewports (just regular old viewports) that are used in each layout of a drawing?

 

Does anyone know how to do this?

 

Is this rocket science??? (Sorry to sound frustrated, but I've been working on this non-stop for days now...)

Link to comment
Share on other sites

  • Replies 26
  • Created
  • Last Reply

Top Posters In This Topic

  • SEANT

    15

  • PellaCAD

    10

  • Lee Mac

    2

Top Posters In This Topic

Posted Images

Here’s a fairly basic sample routine to collect viewports associated with a particular Layout.

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.ApplicationServices

Public Class SampleCommands


   <CommandMethod("LVP")> _
   Public Sub LayoutVPs()
       Dim doc As Document = Application.DocumentManager.MdiActiveDocument
       Dim db As Database = doc.Database
       Dim ed As Editor = doc.Editor
       Dim layId As ObjectId
       Dim lo As Layout
       Dim loName As String

       Using trans As Transaction = db.TransactionManager.StartTransaction()
           Dim laydic As DBDictionary = DirectCast(trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead, False), DBDictionary)
           For Each dentry As DictionaryEntry In laydic

               layId = DirectCast(dentry.Value, ObjectId)
               lo = DirectCast(trans.GetObject(layId, OpenMode.ForRead), Layout)
               loName = lo.LayoutName
               If loName <> "Model" Then
                   ed.WriteMessage(vbLf & "Layout " & loName & " has " & CollectVieports(lo, doc).Count & " viewports.")
               End If
           Next
       End Using

   End Sub

   Function CollectVieports(ByRef lo As Layout, ByRef doc As Document) As ObjectIdCollection

       Dim db As Database = doc.Database
       Dim Btr As BlockTableRecord
       Dim vp As Viewport
       Dim oidcol As ObjectIdCollection = New ObjectIdCollection()
       Dim notpvp As Boolean 'don't include the general layout vp
       Using trans As Transaction = db.TransactionManager.StartTransaction()
           Btr = DirectCast(trans.GetObject(lo.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord)
           For Each oid As ObjectId In Btr
               vp = TryCast(trans.GetObject(oid, OpenMode.ForRead), Viewport)
               If Not vp Is Nothing Then
                   If notpvp Then oidcol.Add(oid)
                   notpvp = True
               End If

           Next
       End Using
       Return oidcol
   End Function

End Class

Link to comment
Share on other sites

I suspect that will be true for just about any other programming language.

 

VB tends to be even more verbose than others due to a mindset towards readability, (maybe even designed to be comprehensible for non programmers). I suppose one of the advantages of that would be a reduced need for in code commenting.

 

 

Of course, everything printed in the post above does not need to be explicitly typed. The VS IDE has a lot of features that do the typing for you (or me, as the case may be).

 

Also, the sample has a few additional steps not required for what it posts to the command line, but probably useful for more practical tasks.

Link to comment
Share on other sites

First, thank you for your help! (I've really been floundering on this issue...)

 

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

 

I put "Public Sub LayoutVPs" and "Function CollectVieports" into my form as a public sub and function respectively...

 

I added the "Imports" statements to the top of my form as well...

 

What file is this routine looking for, that it can not find???

 

Perplexed...

Link to comment
Share on other sites

The routine isn’t looking for any file except the active document in this line of code:

 

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

 

 

As a routine designed for the AutoCAD command line, however, it may be lacking some parameters required for use with a userform.

 

When you step through your composited code, which line generates the error?

Link to comment
Share on other sites

Hi Seant,

 

I have LayoutVPs on a button click...the program bombs out right there at the LayoutVPs call.

 

What's the recommended method to use this viewport collection process?

 

OK...I just commented out everything except the "Dim db As Database = objAcad.ActiveDocument.Database" line...still bombs out.

I think it does not like the "As Database"...how can I define that definition in an absolute way?

 

Pete

Link to comment
Share on other sites

As mentioned previously, the routine was intended to work from the command line. I’ve attached the project files to test if you so desire. Either debug from VS and NETLOAD from “. . . . CountlayoutsVPs\CountlayoutsVPs\bin\Debug” or run the compiled version from “. . . . CountlayoutsVPs\CountlayoutsVPs\bin\Release”. With either, the command LVP should start the routine in AutoCAD.

 

I couldn’t say with any certainty why it is bombing out unless I saw how the form’s Click Events were set.

CountlayoutsVPs.zip

Link to comment
Share on other sites

It might be useful if I'd share some of my system info with you...(sorry about that)...

 

Visual Studio 2005 Professional Edition.

AutoCAD 2008

 

I'm compiling to an exe and running outside of AutoCAD, the program starts externally and cranks up AutoCAD if it finds it's not running.

 

The code I use to start the layout collector is:

********************************************************************************

PrivateSub bnOK4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bnOK4.Click

 

LayoutVPs()

 

EndSub

********************************************************************************

I had to change these lines:

 

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim db As Database = doc.Database

 

to

 

Dim doc As AcadDocument

Dim db As AcadDatabase = objAcad.ActiveDocument.Database

 

 

I'm trying to find an equivalent for:

 

Dim ed As Editor = doc.Editor

 

I'm loading up the CountLayoutsVP2.zip file you sent earlier...I'll report back in a few minutes.

 

___

 

BINGO! Once I changed from ACAD 2009 to ACAD 2008 and did the NETLOAD thing...she started working.

 

Your code is the closest to a solution that I've found in over 15 months of working on this problem...

 

It's time to covert your NETLOAD code over to my EXE code. I sure could use your help if you had a few minutes...

 

Pete (A king-sized THANK YOU!)

Link to comment
Share on other sites

You're going to need something like:

 

 

    Private Sub bnOK4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim sampcomm As SampleCommands = New SampleCommands()
       sampcomm.LayoutVPs()
   End Sub

 

Where SampleCommands is the name of the Public Class where the sub is located.

Link to comment
Share on other sites

The project I posted previously is VS 2008. I’m not sure if it is backward compatible.

 

If you’re accessing AutoCAD from an outside executable, there are probably a few more housekeeping tasks required in addition to the tweak I posted above. Many of us programmers here would appreciate some tips with that process, and would benefit greatly if you post the entire procedure once its sorted out.

Link to comment
Share on other sites

I don't mind lending a hand but have to admit it is tricky with an incomplete picture.

 

Can you post everything you're working with at this point? If so, I'll have some time tonight to take a look at it.

Link to comment
Share on other sites

Hey Seant,

 

I'd be more than happy to share this program with you.

 

Give me just a minute...I'll have it ready for you.

 

CADTutor says the file is too large (1MB)...send me an email, I'll reply with the attachment.

 

OK...ready to post...I chopped it into 4 zip files...put all the files into a single folder.

 

Put the last set of files into a sub-folder called My Project...

 

Here they come...

 

Pete (my home email is CADDude at PellaCAD dot com)

Link to comment
Share on other sites

Seant,

 

Per your request for assistance with an external exe accessing AutoCAD...I'd be happy to share my expertise in that arena.

 

I do a boatload of AutoCAD-Excel linking as well...

 

It looks like you work inside AutoCAD (via NETLOAD)...I could use some help getting your viewport counting subs and functions brought over into my universe.

 

Talk to you tomorrow,

 

Pete

Link to comment
Share on other sites

You’ve definitely got a lot going on in there.

 

Hopefully the form in question could be paired down to just the essential components to test the Executable/AutoCAD interaction.

Link to comment
Share on other sites

I believe this issue has already been resolved but figured I post an example anyway, even if only to give the thread some additional value to future searches.

 

The attached is an example of a standalone .NET exe processing a DWG file via Interop. The routine selects/opens a drawing file to list layouts and VP quantities.

 

The files are opened with ObjectDBX so are not present in the AutoCAD drawing editor, though AutoCAD does need to be open.

 

As always with example routines, test on non consequential files.

 

 

Edit: Fixed bug in attachment

GetAcadVPs_rev1.zip

Link to comment
Share on other sites

Good morning Seant...

 

I made some good progress using the ListLayoutVPs and CollectViewPorts subs...I added a debug.print to get the program to list the PViewPort ObjectID and the containing layout name. (It really works flawlessly!)

 

eg

PViewport objectID "2122446976" resides on layout E(04)

PViewport objectID "2113999800" resides on layout E(05)

PViewport objectID "2114773808" resides on layout E(06)

PViewport objectID "2114776744" resides on layout E(07)

PViewport objectID "2125253152" resides on layout E(08)

The program seems to only collect the Primary ViewPort on each layout tab...

 

The task now, is to go through each layout tab and collect the simple ViewPorts.

 

Do we look inside each PViewPort? Or is accessing simple ViewPorts accomplished in some other manner??

 

Thanks again Seant for helping me break through what had become a rather significant log jam.

 

If we can get this last piece unscrambled, I think I am on my way.

 

Pete

Link to comment
Share on other sites

. . . . .

 

The program seems to only collect the Primary ViewPort on each layout tab...

 

The task now, is to go through each layout tab and collect the simple ViewPorts.

 

. . . . .

 

Pete

 

The routine is only returning the Main Layout ViewPort and none of the floating Viewports? :o

 

That’s odd. I set the code up to include all viewports except the layouts main VP. And everything appears to be working as it should on my end. See attachment.

 

I did just notice that I forgot to zero the “widest” variable within the layouts For Each loop (I’ll post a correction shortly). Is a repeated value for widest the reason it appears to exclude the floating viewports?

VP.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...