.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Viewport Layers Set To "Frozen" Are Still Visible

22 REPLIES 22
Reply
Message 1 of 23
mgorecki
2498 Views, 22 Replies

Viewport Layers Set To "Frozen" Are Still Visible

Hello,

I have a sub that gets a page number and a collection of layer ID's to freeze.  The sub will freeze the selected layers in all of the viewports except for the new one.

After running the program, the layers in the specific viewport are still visible, but when you go into Model mode in the viewport and check the layer status, it shows the selected layers are set to Freeze in the viewport. 

If I save the drawing, exit,and re-open it, the layers are now not visible.  I believe I have the "Regen" in the correct spot.

The code is attached.

    ' Freezes the selected layers in all other existing viewport layouts
    Public Sub freezeOtherLayouts(ByVal pageNumber As Integer, ByVal layersToFreezeLayerIds As ObjectIdCollection)
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        Dim detailLayer As String = "DETAIL_" & pageNumber
        Dim vp As Viewport = Nothing
        Dim viewPortFound As Boolean
        Dim vpIDs As ObjectIdCollection = Nothing
        Dim allLayerIDs As New ObjectIdCollection, detailLayerID As New ObjectIdCollection
        Dim freezeVPtrans As Transaction = Nothing

        Try
            freezeVPtrans = db.TransactionManager.StartTransaction()
            Dim myBT As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
            For Each btrID As ObjectId In myBT
                Dim myBTR As BlockTableRecord = btrID.GetObject(OpenMode.ForRead)
                ' If the block table record is a layout
                If myBTR.IsLayout Then
                    viewPortFound = False
                    If Not myBTR.Name = "*Model_Space" Then
                        Dim layOut As Layout = myBTR.LayoutId.GetObject(OpenMode.ForRead)
                        ' If the layout is the new layout
                        If layOut.TabOrder <> pageNumber Then
                            For Each id As ObjectId In myBTR
                                Dim obj As DBObject = id.GetObject(OpenMode.ForWrite)
                                ' If the object is a viewport (there is a model viewport which is found first, we want the second one)
                                If TypeOf obj Is Viewport And viewPortFound = True Then
                                    Dim vpref As Viewport = DirectCast(obj, Viewport)
                                    ' Selected Viewport for write.
                                    vp = freezeVPtrans.GetObject(vpref.ObjectId, OpenMode.ForWrite)
                                    Dim lt As LayerTable = freezeVPtrans.GetObject(db.LayerTableId, OpenMode.ForRead)
                                    ' Freeze the selected layers in the viewports
                                    vp.FreezeLayersInViewport(layersToFreezeLayerIds.GetEnumerator())
                                    lt.Dispose()
                                End If
                                If TypeOf obj Is Viewport Then
                                    viewPortFound = True
                                End If
                            Next
                        End If
                    End If
                End If
            Next
        Catch
            ed.WriteMessage("Error!")
        Finally
            freezeVPtrans.Commit()
            freezeVPtrans.Dispose()
            ed.Regen()
        End Try
    End Sub

 

Thanks,

Mark

22 REPLIES 22
Message 2 of 23
Hallex
in reply to: mgorecki

Try add at the end of code:

 

ed.UpdateTiledViewportsInDatabase()

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 3 of 23
mgorecki
in reply to: Hallex

I added that to the end of my program, but got an Unhandled Exception ({"eNotApplicable"}). 

Message 4 of 23
jeff
in reply to: mgorecki

Are you sure you not trying to set  on ViewPorts associated with Paperspace?

 

 

 

Might try iterating Database.GetViewports() passing in false.

 

Input flag indicating whether to return paperspace viewports associated with layouts 

 

You can also find your answers @ TheSwamp
Message 5 of 23
mgorecki
in reply to: jeff

My viewport is in paperspace on layout P1 (I have Model, P1, and P2 layouts).  In order to see what layers are frozen in that particular viewport, I double picked in the viewport, which put me in Model mode.

Message 6 of 23
mgorecki
in reply to: mgorecki

Hi Jeff,

Can you explain more in regards to "Might try iterating Database.GetViewports() passing in false".  I'm kinda new to VB.Net and I'm still learning.

 

Thanks,

Mark

Message 7 of 23
jeff
in reply to: mgorecki

This might work ok if your trying to not freeze the layers in new viewport and has never been Intialized, but would need to intialize any layouts that have never been.

 

 

        <CommandMethod("FreezeLayers")> _
        Public Sub MyGroupFreezeLayers() ' This method can have any name

            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Using trx As Transaction = db.TransactionManager.StartTransaction

                For Each id As ObjectId In db.GetViewports(False)

                    Dim vp As Viewport = id.GetObject(OpenMode.ForWrite)
                    vp.FreezeLayersInViewport(LayerIds(db).GetEnumerator)

                Next

                trx.Commit()
            End Using

        End Sub


        Private Function LayerIds(ByVal db As Database) As ObjectIdCollection

            Dim layIds As New ObjectIdCollection()
            layIds.Add(db.LayerZero)
            Return layIds

        End Function

 

 

You can also find your answers @ TheSwamp
Message 8 of 23
mgorecki
in reply to: jeff

Hi Jeff,

I tried using your code but it didn't freeze the selected layer or any layers in the existing viewport in the P1 layout.  I'm still trying to understand the whole "db.GetViewports(False)" thing, maybe that's where my problem is.

Message 9 of 23
jeff
in reply to: mgorecki

That example should only freeze entites only on layer 0 and only in viewports that have been intialized.

You can also find your answers @ TheSwamp
Message 10 of 23
mgorecki
in reply to: jeff

How do I initialize a layout?  Is it layout.initialize()  ?

 

I'm ready to post my entire program if it would help.  It's driving me crazy already.

I have only one layout in the drawing.  When the code runs, it adds a new layout to the drawing from a template.  A dialog pops up and asks which layers they want to see in the new layouts viewport.  It also asks which layers they do not want to see in all the other layouts viewports (because a new layer was added and if there are many more layouts it will freeze the selected layers in all the other viewports).  When the program is done running, the new layout looks great.  It shows the layers I want to see, but, the existing layout still looks lthe same.  The layers are all still visible, even though the layer manager says that the layers I told to freeze are frozen.  It's like it's just not finishing up and ending the last part. 

Here's the code that's supposed to freeze all the selected layers in all the other layouts viewports:

    ' Freezes the selected layers in all other existing viewport layouts
    Public Sub freezeOtherLayouts(ByVal pageNumber As Integer, ByVal layersToFreezeLayerIds As ObjectIdCollection)
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        Dim vp As Viewport = Nothing
        Dim viewPortFound As Boolean
        Dim freezeVPtrans As Transaction = db.TransactionManager.StartTransaction()

        Try
            Dim myBT As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
            For Each btrID As ObjectId In myBT
                Dim myBTR As BlockTableRecord = btrID.GetObject(OpenMode.ForRead)
                ' If the block table record is a layout
                If myBTR.IsLayout Then
                    viewPortFound = False
                    If Not myBTR.Name = "*Model_Space" Then
                        Dim layOut As Layout = myBTR.LayoutId.GetObject(OpenMode.ForRead)
                        ' If the layout is not the new layout
                        If layOut.TabOrder <> pageNumber Then
                            For Each id As ObjectId In myBTR
                                Dim obj As DBObject = id.GetObject(OpenMode.ForWrite)
                                ' If the object is a viewport (there is a model viewport which is found first, we want the second one)
                                If TypeOf obj Is Viewport And viewPortFound = True Then
                                    Dim vpref As Viewport = DirectCast(obj, Viewport)
                                    ' Selected Viewport for write.
                                    vp = freezeVPtrans.GetObject(vpref.ObjectId, OpenMode.ForWrite)
                                    Dim lt As LayerTable = freezeVPtrans.GetObject(db.LayerTableId, OpenMode.ForRead)
                                    ' Freeze the selected layers in the viewports
                                    vp.FreezeLayersInViewport(layersToFreezeLayerIds.GetEnumerator())
                                    ed.Regen()
                                    lt.Dispose()
                                End If
                                If TypeOf obj Is Viewport Then
                                    viewPortFound = True
                                End If
                            Next
                        End If
                    End If
                End If
            Next
        Catch
            ed.WriteMessage("Error!")
        Finally
            freezeVPtrans.Commit()
            freezeVPtrans.Dispose()
        End Try
    End Sub

 Help!

Message 11 of 23
mgorecki
in reply to: mgorecki

I changed my code to use GetViewports, so it now looks like this:

    ' Freezes the selected layers in all other existing viewport layouts
    Public Sub freezeOtherLayouts(ByVal pageNumber As Integer, ByVal layersToFreezeLayerIds As ObjectIdCollection)
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        'Dim vp As Viewport = Nothing
        Dim viewPortFound As Boolean
        Dim freezeVPtrans As Transaction = db.TransactionManager.StartTransaction()

        Try
            Dim myBT As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
            For Each btrID As ObjectId In myBT
                Dim myBTR As BlockTableRecord = btrID.GetObject(OpenMode.ForRead)
                ' If the block table record is a layout
                If myBTR.IsLayout Then
                    viewPortFound = False
                    If Not myBTR.Name = "*Model_Space" Then
                        Dim layOut As Layout = myBTR.LayoutId.GetObject(OpenMode.ForRead)
                        ' If the layout is not the new layout
                        If layOut.TabOrder <> pageNumber Then
                            For Each id As ObjectId In db.GetViewports(False)

                                Dim vp As Viewport = id.GetObject(OpenMode.ForWrite)
                                vp.FreezeLayersInViewport(layersToFreezeLayerIds.GetEnumerator)

                            Next
                        End If
                    End If
                End If
            Next
        Catch
            ed.WriteMessage("Error!")
        Finally
            freezeVPtrans.Commit()
            freezeVPtrans.Dispose()
        End Try
    End Sub

 It still leaves the layers visible in the first layout, even though according to the layer manager for that viewport, the layer is frozen.

 

Message 12 of 23
andred
in reply to: mgorecki

Hi,

 

I think I've found a solution. I had exactly the same problem. After many hours of serch and try (very frustrating), I found that I have to activate the layout before freezing the layers. So I add this sub to my function:

 

Public Sub SetCurrentLayoutTab(ByVal LayoutName As String)
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database
        Using doclock As DocumentLock = acDoc.LockDocument
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                Try
                    Dim acLayoutMgr As LayoutManager
                    acLayoutMgr = LayoutManager.Current
                    acLayoutMgr.CurrentLayout = LayoutName
                    acTrans.Commit()
                Catch ex As Autodesk.AutoCAD.Runtime.Exception
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message & vbCr & ex.StackTrace)
                    acTrans.Abort()
                End Try
            End Using
        End Using

    End Sub

 

Also, this is important to do a regen at the end of your function. Here you will find my complete function (sub). It is different from yours, so give it a try and give me some feedbacks.

 

   Public Sub FreezeLayerInOtherViewport(ByVal LayerName As String)

        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database

        Using doclock As DocumentLock = acDoc.LockDocument

            '' Start a transaction
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                Dim blockIDs As ObjectIdCollection = New ObjectIdCollection()
                Dim acLyrTbl As LayerTable
                Dim sLayerNames As String = ""
                Dim CVPort As Viewport

                acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead)
                For Each acObjId As ObjectId In acLyrTbl
                    Dim acLyrTblRec As LayerTableRecord
                    acLyrTblRec = acTrans.GetObject(acObjId, OpenMode.ForRead)
                    If acLyrTblRec.Name.ToUpper = LayerName.ToUpper Then
                        blockIDs.Add(acLyrTblRec.ObjectId)
                        Exit For
                    End If
                Next

                CVPort = DirectCast(acTrans.GetObject(acDoc.Editor.CurrentViewportObjectId, OpenMode.ForRead), Viewport)

                Dim layoutDict As DBDictionary = CType(acTrans.GetObject(acCurDb.LayoutDictionaryId, OpenMode.ForRead), DBDictionary)
                Dim strCurrentLayoutName As String = LayoutManager.Current.CurrentLayout

                For Each entry As DBDictionaryEntry In layoutDict
                    If entry.Key <> "Model" Then
                        Dim lay As Layout = CType(acTrans.GetObject(entry.Value, OpenMode.ForRead), Layout)
                        If lay.LayoutName.ToUpper <> strCurrentLayoutName Then
                            SetCurrentLayoutTab(lay.LayoutName)
                            Dim nCount As Integer = 0
                            For Each vpid As ObjectId In lay.GetViewports
                                nCount = nCount + 1
                                Dim vp As Viewport = CType(acTrans.GetObject(vpid, OpenMode.ForWrite), Viewport)
                                If vp.Handle <> CVPort.Handle Then
                                    If nCount > 1 Then
                                        vp.FreezeLayersInViewport(blockIDs.GetEnumerator)
                                     End If
                                End If
                            Next
                        End If
                    End If
                Next
                acTrans.Commit()
                SetCurrentLayoutTab(strCurrentLayoutName)
                acDoc.Editor.Regen()
            End Using
        End Using

    End Sub

 

Regards,

 

André

 

Message 13 of 23
jeff
in reply to: jeff


@Jeff wrote:

That example should only freeze entites only on layer 0 and only in viewports that have been intialized.


Sorry I was not very clear but thought I put in early reply and guess not but to call Layout.Initialize() for any un-intialized viewports before setting properties.

Going from memory but I believe that will do it.

You can also find your answers @ TheSwamp
Message 14 of 23
mgorecki
in reply to: andred

Hello Andre,

Thank you for your input.  I was able to take some of what you did and integrate it into mine.

    ' Freezes the selected layers in all other existing viewport layouts
    Public Sub freezeOtherLayouts(ByVal pageNumber As Integer, ByVal layersToFreezeLayerIds As ObjectIdCollection)
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        Dim vp As Viewport = Nothing
        Dim viewPortFound As Boolean
        Dim freezeVPtrans As Transaction = Nothing

        Try
            freezeVPtrans = db.TransactionManager.StartTransaction()
            Dim myBT As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
            For Each btrID As ObjectId In myBT
                Dim myBTR As BlockTableRecord = btrID.GetObject(OpenMode.ForRead)
                ' If the block table record is a layout
                If myBTR.IsLayout Then
                    viewPortFound = False
                    If Not myBTR.Name = "*Model_Space" Then
                        Dim layOut As Layout = myBTR.LayoutId.GetObject(OpenMode.ForRead)
                        'Dim initId As ObjectId = Nothing
                        'initId = layOut.Initialize()
                        ' If the layout is not the new layout
                        If layOut.TabOrder <> pageNumber Then
                            SetCurrentLayoutTab(layOut.LayoutName)
                            For Each id As ObjectId In myBTR
                                Dim obj As DBObject = id.GetObject(OpenMode.ForWrite)
                                ' If the object is a viewport (there is a model viewport which is found first, we want the second one)
                                If TypeOf obj Is Viewport And viewPortFound = True Then
                                    Dim vpref As Viewport = DirectCast(obj, Viewport)
                                    ' Selected Viewport for write.
                                    vp = freezeVPtrans.GetObject(vpref.ObjectId, OpenMode.ForWrite)
                                    Dim layerTable As LayerTable = freezeVPtrans.GetObject(db.LayerTableId, OpenMode.ForRead)
                                    ' Freeze the selected layers in the viewports
                                    vp.FreezeLayersInViewport(layersToFreezeLayerIds.GetEnumerator())
                                    'vp.UpdateDisplay()
                                    ed.Regen()
                                    layerTable.Dispose()
                                End If
                                If TypeOf obj Is Viewport Then
                                    viewPortFound = True
                                End If
                            Next
                        End If
                    End If
                End If
            Next
        Catch
            ed.WriteMessage("Error!")
        Finally
            freezeVPtrans.Commit()
            ed.Regen()
            freezeVPtrans.Dispose()
        End Try
    End Sub

    Public Sub SetCurrentLayoutTab(ByVal LayoutName As String)
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database
        Using doclock As DocumentLock = acDoc.LockDocument
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                Try
                    Dim acLayoutMgr As LayoutManager
                    acLayoutMgr = LayoutManager.Current
                    acLayoutMgr.CurrentLayout = LayoutName
                    acTrans.Commit()
                Catch ex As Autodesk.AutoCAD.Runtime.Exception
                    Application.ShowAlertDialog(ex.Message & vbCr & ex.StackTrace)
                    acTrans.Abort()
                End Try
            End Using
        End Using

    End Sub

 

I used your SetCurrentLayoutTab sub, and referenced it inside of the layout loop.  That did the trick and allowed the selected layers to be frozen in the other layout viewports. 

 

Thank you very much!

Mark

Message 15 of 23
andred
in reply to: mgorecki

Hello Mark,

I'm glad to help you, the only annoying thing is you can see layout change, so the screen is flipping but it is very fast on my computer.

 

Regards,

 

André

Message 16 of 23
Dale.Bartlett
in reply to: mgorecki

I have the same problem and despite trolling the forums and trying all the suggestions here, no success. I am generating a series of Layouts, then iterating all Layouts to set current (to initialise), then VP Freezing layers. The layers are correctly frozen in the layer dialog box, but continue to display. Regen/Regenall has no effect. Save, Close and re-Open the drawing and the display is correct. I haven't included code as it is mostly as per this thread. Is there something else? Regards, Dale  




______________
Yes, I'm Satoshi.
Message 17 of 23
Hallex
in reply to: Dale.Bartlett

Dale, I wrote wrong expression in my first post on this thread,

Try add at the end of code instead

 

ed.UpdateTiledViewportsFromDatabase()

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 18 of 23
mgorecki
in reply to: Dale.Bartlett

Hi Dale,

Another thing I found was that AutoCad 2010 is a bit buggy.  Make sure you have the latest service pack.  I downloaded service pack 2 and it fixed the layer visibility issue.  You can tell the service pack you have by going to Help > About.  In the top left mine says version 3 (which in AutoCad land means service pack 2).

Message 19 of 23
Dale.Bartlett
in reply to: mgorecki

Thanks for the replies. I tried ed.UpdateTiledViewportsFromDatabase(); everywhere but it resulted in errors. As it refers to TiledViewports, it seems that it is not applicable to floating viewports, but I am not sure. I am using AutoCAD 2013 SP1 so it is not an old bug. As I say, it is all correct, and re-opens with the correct display, but needs to be refreshed somehow. Regards, Dale




______________
Yes, I'm Satoshi.
Message 20 of 23

Hi

 

Though you have mentioned that code is all most same, I would like to request you to provide non confidential code sample with using which we can reproduce the issue at our end. Also, attach a simple non confidential drawing file against which we can reproduce the issue.



Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost