Author Topic: Viewport Layers Set To "Frozen" Are Still Visible  (Read 5336 times)

0 Members and 1 Guest are viewing this topic.

MGorecki

  • Guest
Viewport Layers Set To "Frozen" Are Still Visible
« on: July 11, 2012, 07:00:10 PM »
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:

Code: (vbnet) [Select]
    ' 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

I just don't understand why the layers I selected to freeze (in layersToFreezeLayerIds) is still visible when the layer manager for the viewport shows them frozen.

Thanks,
« Last Edit: July 12, 2012, 10:35:46 AM by MGorecki »

TheMaster

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #1 on: July 11, 2012, 07:04:49 PM »
Is the existing layout with the newly-frozen layers being regenerated?

trembre

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #2 on: July 11, 2012, 09:12:40 PM »
 I wrote a batch "unfreezer" for viewport frozen layers years ago in VBA.  I don't know whether the same rules would apply, but the only way I could find to affect the state of layers frozen/thawed by viewport was by directly modifying the viewports relevant XData.  I'd have to dig out the code to get the specifics, but for the code to work I had to copy the original viewport, delete it from the drawing, delete the appropriate XData records from the copy, then re-create it. 

 Whether you'd have to be so clunky in .NET (or even VBA - all I know is it worked!), I wouldn't know, but the lack of any viewport XData modification stands out to me as a possible issue.

MexicanCustard

  • Swamp Rat
  • Posts: 684
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #3 on: July 12, 2012, 07:25:53 AM »
instead of ed.Regen() try vp.UpdateDisplay()
Revit 2018, AMEP 2018 64bit Win 10

MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #4 on: July 12, 2012, 10:30:48 AM »
Hi Bullfrog, I have the "ed.Regen()" in the code after it freezes the layers in the viewport.

MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #5 on: July 12, 2012, 10:34:37 AM »
Hello Mexican Custard, I tried that just now, but it doesn't make a difference.  Thanks though.

Delegate

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #6 on: July 12, 2012, 12:06:22 PM »
I did not have any problem getting the freezelayersinviewport to work and did not need vp.updatedisplay or ed.regen.

Try this code and see if it works on your computer - basically it freezes all layers in all viewports apart from the layout viewport. Then maybe we can see if the problem is elsewhere.

Code: (CSharp) [Select]
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in1.MyCommands))]

namespace AutoCAD_CSharp_plug_in1
{

   
    public class MyCommands
    {
       
        [CommandMethod("MyGroup", "MyCommand", "MyCommandLocal", CommandFlags.Modal)]
        public void MyCommand() // This method can have any name
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            ObjectIdCollection ids = new ObjectIdCollection();
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                LayerTable acLyrTbl;
                acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,OpenMode.ForRead) as LayerTable;
                foreach (ObjectId item in acLyrTbl)
                {
                    ids.Add(item);
                }

                BlockTableRecord btr = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord;
                RXClass VPClass = RXObject.GetClass(typeof(Viewport));
                foreach (ObjectId item in btr)
                {
                    if (item.ObjectClass == VPClass)
                    {
                        Viewport vp = acTrans.GetObject(item, OpenMode.ForWrite) as Viewport;
                        if (vp.Number != 1)
                        {
                            vp.FreezeLayersInViewport(ids.GetEnumerator());
                        }                 
                    }
                }               
                acTrans.Commit();
            }

        }       

    }

}



MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #7 on: July 12, 2012, 01:43:22 PM »
Hi Delegate,
Thank you for the code to try.  It did freeze all the layers in the new layout, but it did not change the layer visibility in the first layout viewport.
Could something be wrong with the first layout?  Maybe with the viewport itself?  I heard about viewports needing to be activated (though I'm not sure how to do that) before they can be changed.

Thanks,
Mark

Delegate

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #8 on: July 12, 2012, 03:30:11 PM »
Hi

Sorry this maybe as written. I should have said I've got the blocktablerecord from the CurrentSpaceID  so will only work on the active layout unless you've changed it to loop through the layouts.

MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #9 on: July 12, 2012, 04:19:59 PM »
I'm new to a lot of the VB.Net stuff, you'll have to explain:
RXClass VPClass = RXObject.GetClass(typeof(Viewport));

What is this and what does it do?  How can I use it?

Thanks,
Mark

MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #10 on: July 12, 2012, 04:30:06 PM »
Ok I changed the code so that affects all layouts:
Code: (vbnet) [Select]
    Public Sub FreezeAllInVPs()
        ' This method can have any name
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database
        Dim ids As New ObjectIdCollection()
        Dim viewPortFound As Boolean, pageNumber As Integer = 2

        Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
            Dim acLyrTbl As LayerTable
            acLyrTbl = TryCast(acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead), LayerTable)
            For Each item As ObjectId In acLyrTbl
                ids.Add(item)
            Next

            'Dim btr As BlockTableRecord = TryCast(acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForRead), BlockTableRecord)
            Dim myBT As BlockTable = acCurDb.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
                            Dim VPClass As RXClass = RXObject.GetClass(GetType(Viewport))
                            For Each item As ObjectId In myBTR
                                If item.ObjectClass = VPClass And viewPortFound = True Then
                                    Dim vp As Viewport = TryCast(acTrans.GetObject(item, OpenMode.ForWrite), Viewport)
                                    If vp.Number <> 1 Then
                                        vp.FreezeLayersInViewport(ids.GetEnumerator())
                                    End If
                                End If
                                If item.ObjectClass = VPClass Then
                                    viewPortFound = True
                                End If
                            Next
                            acTrans.Commit()
                        End If
                    End If
                End If
            Next
        End Using
    End Sub

In the new layout I had selected 2 layers to remain visible.  They were still visible, but when you double pick in the viewport and check the layer manager it shows that all layers have been frozen.
In the original layout, all layers were visible, but when I double picked in the viewport and checked the layer manager, it also showed that all layers were frozen.

Delegate

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #11 on: July 12, 2012, 05:03:00 PM »
I'm new to a lot of the VB.Net stuff, you'll have to explain:
RXClass VPClass = RXObject.GetClass(typeof(Viewport));

What is this and what does it do?  How can I use it?

Thanks,
Mark

Its just another way of checking the type - could be circle, polyline etc.  Your method typeof means you have to cast to object before checking though won't make much difference unless large amount of items involved.

You can delete the viewportfound parts now. The vp.number <> 1 takes care of that. Sure someone will correct that if wrong.

Move the acTrans.commit to be above the End Using statement - your commiting before finishing.

If still not working maybe look at the calling code where you create the new layout - is it fully commited to database before your operations on layers and viewports? Throw in a ed.regen and vp.updatedisplay just to double check that to.

MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #12 on: July 12, 2012, 05:12:14 PM »
I removed the viewportFound parts, and now all layers get frozen in paperspace (can't see the title block or anything in ps) but the viewport layers are still visible.

Delegate

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #13 on: July 12, 2012, 05:31:17 PM »
Oh dear read this and ignore what i Sad  :ugly:

http://forums.autodesk.com/t5/NET/Layouts-and-Viewports/td-p/3128748

Also some info about activating layouts .

MGorecki

  • Guest
Re: Viewport Layers Set To "Frozen" Are Still Visible
« Reply #14 on: July 16, 2012, 05:48:24 PM »
Ok, I can't believe it was so simple.  In a previous sub, I forgot to close a transaction (smacking head).  All fixed now, but thank you all for your helpful support.