Changing the visibility of layers, in a viewport (VP Freeze)

Hi everyone,

For our project, we need to filter our AutoCAD viewports in terms of the appropriate layer visibility (the “VP Freeze” parameter):

I found some Python code by @mzjensen to change the layer visibility/ freeze parameter for the layers in the modelspace. I was wondering if a similar method could be used to change the visibility parameter per viewport:

The Code/ Topic of mzjensen

Freeze layer by name - dynamo Civil 3D - #10 by mzjensen

# Load the Python Standard and DesignScript Libraries
import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')

# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

def set_layer_on_off(layers,bool):

	if layers is None:
		return None
	if bool is None:
		return None
	
	errorReport = None
	name=[]
	
	global adoc
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:
				for layer in layers:
					lt=t.GetObject(db.LayerTableId,OpenMode.ForWrite)
					try:
						if lt.Has(layer):
							i = t.GetObject(lt[layer], OpenMode.ForWrite)
							i.IsOff=bool
							name.append(i.Name)						
							
					# Error handling
					except:
						import traceback				
				t.Commit()			
	if errorReport == None:
		return name
	else:
		return errorReport
	
OUT = set_layer_on_off(IN[0],IN[1])

Autodesk page about the Viewport Class

PS: This Dynamo script for me is a work in progress so I’ll post updates in this topic when I find some more information/ (parts of the) solution periodically. :slight_smile:

2 Likes

You can’t access the VP Frozen property directly from the layer. There is a function GetViewportOverrides([viewport id]) that returns the color, linetype and so on, and the layer itself has properties that tell if a layer has overrides.

But if you want to see or set the frozen layers you need to access them via the viewport object. More info about that:

3 Likes

Just found this link, which links to another page about ViewPorts which shows a C# approach to thawing or freezing layers in a viewport.

https://help.autodesk.com/view/OARX/2022/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_Viewport_ThawLayersInViewport_IEnumerator
https://help.autodesk.com/view/OARX/2022/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_Viewport_FreezeLayersInViewport_IEnumerator

PS: This is a different page from the ViewPort Class page from my original post.

Also, this code might be of interest (from Read properties of a viewport):

Code
private void VPLOOP()
{
        Document doc = Core.Application.DocumentManager.MdiActiveDocument;
        Autodesk.AutoCAD.GraphicsSystem.Manager gsm = Core.Application.DocumentManager.MdiActiveDocument.GraphicsManager;
        Database db = doc.Database;
        Editor ed = doc.Editor;
        LayoutManager lm = LayoutManager.Current;
 
        int x = 0;
 
        List<string> layers = new List<string>();
 
        foreach (AcadLayer layer in ThisDrawing.Layers) {
                layers.Add(layer.Name);
        }
 
        using (tr == db.TransactionManager.StartTransaction()) {
 
                ObjectId idLay = default(ObjectId);
 
                ObjectId idLayTblRcd = default(ObjectId);
 
                LayerTableRecord lt = default(LayerTableRecord);
 
                Point3d llc = default(Point3d);
                Point3d urc = default(Point3d);
                // Save the name of the current layout
                currentLayout = lm.CurrentLayout;
 
                ObjectId loid = LayoutManager.Current.GetLayoutId(lm.CurrentLayout);
                Layout lo = tr.GetObject(loid, OpenMode.ForRead);
                //For Each de As DBDictionaryEntry In layoutDict
 
                lm.CurrentLayout = currentLayout;
                string layoutName = lo.LayoutName;
 
                if (x == 0 && layoutName != "Model") {
                        //Loop thru layout viewports
                        //Note, the first vp is the layout vp itself
                        ObjectIdCollection vpIdCol = lo.GetViewports();
 
                        //Looping through the collection of viewports
 
                        foreach (ObjectId vpId in vpIdCol) {
                                Viewport vp = vpId.GetObject(OpenMode.ForRead);
 
                                //Make sure we're not checking the overall layout viewport
 
                                if (vp.Number > 1) {
                                        LayerTable ltt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead, false);
 
 
                                        foreach (string lname in layers) {
                                                idLay = ltt(lname);
 
                                                lt = tr.GetObject(idLay, OpenMode.ForRead);
 
 
                                                if (ltt.Has(lname)) {
                                                        idLayTblRcd = ltt.Item(lname);
 
 
                                                } else {
                                                        ed.WriteMessage("Layer: \"" + lname + "\" not available");
 
                                                        VPortX = VPortX + 1;
                                                        break;
 
                                                }
 
 
                                                if (vpId.IsNull()) {
                                                        ed.WriteMessage("No Viewport current.");
                                                        VPortX = VPortX + 1;
                                                        //I would rather just 'Exit Sub' but the transaction needs to be disposed, so we go down to that point in the code.
                                                        goto endusing;
 
                                                }
 
 
                                                if (!vp.IsLayerFrozenInViewport(idLayTblRcd)) {
                                                        LayerTableRecord newLayer = (DatabaseServices.LayerTableRecord)db.TransactionManager.GetObject(idLayTblRcd, DatabaseServices.OpenMode.ForRead);
 
                                                        if (!newLayer.IsFrozen && !newLayer.IsOff) {
                                                                int vpn = vp.Number - 1;
 
                                                                if (!ValidLayers.Contains(newLayer.Name + "," + vpn.ToString())) {
                                                                        ValidLayers.Add(newLayer.Name + "," + vpn.ToString());
                                                                }
                                                        }
                                                }
                                        }
 
                                        //Continuing the loop if the viewport has been erased
                                        if (vp.IsErased) {
                                                continue;
                                        }
 
                                        //This is run if the viewport isn't a rectangle
                                        if (vp.NonRectClipOn) {
                                                //Adding the number of viewports
                                                NumberVPorts = NumberVPorts + 1;
 
                                                ObjectId nonrectoid = vp.NonRectClipEntityId;
                                                Polyline nrvp = tr.GetObject(nonrectoid, OpenMode.ForRead);
                                                Point3dCollection stretchPoints = new Point3dCollection();
 
                                                nrvp.GetStretchPoints(stretchPoints);
 
                                                //Adding up the number of vertices
                                                VPortVertices.Add(stretchPoints.Count + 1);
 
                                                Point2d firstpt = default(Point2d);
                                                for (i = 0; i <= stretchPoints.Count - 1; i++) {
                                                        Point3d newpt = new Point3d(stretchPoints(i).X, stretchPoints(i).Y, stretchPoints(i).Z);
 
                                                        Vector3d newvect = vp.CenterPoint.GetAsVector;
 
                                                        newpt = newpt.Subtract(newvect);
                                                        newpt = newpt.MultiplyBy(1.0 / vp.CustomScale);
 
                                                        Autodesk.AutoCAD.GraphicsSystem.View vpview = new Autodesk.AutoCAD.GraphicsSystem.View();
 
                                                        gsm.SetViewFromViewport(vpview, vp.Number);
                                                        Matrix3d viewmat = vpview.ViewingMatrix.Inverse();
 
                                                        Point3d newpt3d = newpt.TransformBy(viewmat);
                                                        Point2d newpt2d = new Point2d(newpt3d.X, newpt3d.Y);
 
                                                        //Adding each point into the list of coordinates
                                                        VPortCoordinates.Add(newpt2d);
 
                                                        if (i == 0) {
                                                                firstpt = newpt2d;
                                                        }
 
                                                        if (i == stretchPoints.Count - 1) {
                                                                //And adding the first point again, so we can go around in a circle
                                                                VPortCoordinates.Add(firstpt);
                                                        }
                                                }
 
                                        //This is run if it is a rectangle
                                        } else {
                                                llc = vp.Bounds.Value.MinPoint;
                                                urc = vp.Bounds.Value.MaxPoint;
 
                                                llc = llc.Subtract(vp.CenterPoint.GetAsVector);
                                                urc = urc.Subtract(vp.CenterPoint.GetAsVector);
 
                                                llc = llc.MultiplyBy(1.0 / vp.CustomScale);
                                                urc = urc.MultiplyBy(1.0 / vp.CustomScale);
 
                                                Autodesk.AutoCAD.GraphicsSystem.View vpview = new Autodesk.AutoCAD.GraphicsSystem.View();
 
                                                gsm.SetViewFromViewport(vpview, vp.Number);
                                                Matrix3d viewmat = vpview.ViewingMatrix.Inverse();
 
                                                Point3d newllc = llc.TransformBy(viewmat);
                                                Point3d newurc = urc.TransformBy(viewmat);
 
                                                Point2d llc2d = new Point2d(newllc.X, newllc.Y);
                                                Point2d lrc2d = new Point2d(newurc.X, newllc.Y);
                                                Point2d urc2d = new Point2d(newurc.X, newurc.Y);
                                                Point2d ulc2d = new Point2d(newllc.X, newurc.Y);
 
                                                //Adding the vertices and number of viewports
                                                VPortVertices.Add(5);
                                                NumberVPorts = NumberVPorts + 1;
                                                //Adding each coordinate in, and the first again
                                                VPortCoordinates.Add(llc2d);
                                                VPortCoordinates.Add(lrc2d);
                                                VPortCoordinates.Add(urc2d);
                                                VPortCoordinates.Add(ulc2d);
                                                VPortCoordinates.Add(llc2d);
                                        }
                                }
                        }
                }
                x = x + 1;
                //Next
                lm.CurrentLayout = currentLayout;
                endusing:
                //Dispose of the transaction
        }
 
}
 

I just published a new package (‘Arkance Systems Node Library’) where you can find such functionality.

Awesome Anton! Just downloaded the package and I can’t wait to test the nodes! Will keep you posted :smiley:

1 Like

@Anton_Huizinga

Hello Anton, first thank you for work with Dynamo. I can’t seem to find the input node for layers.
Thanks, Daniel.

In the library: ArkanceSystems > AutoCAD > Document > AutoCADLayer. These are real Layer objects, not just layer names as text.

That node does not appear to be present in my list.
I have v7.1 installed.

Look a little bit further in the Document folder, it has subfolders aswel, such as AnnotationScale and AutoCADColor as seen in your screenshot.

1 Like

I see now. Thanks!

1 Like