| name | acad-layouts-viewports |
| description | Paper space layouts, viewport creation, properties, layer overrides, plot settings |
AutoCAD Layouts and Viewports
Use this skill when creating or managing paper space layouts, inserting and configuring viewports, switching between model space and paper space, setting viewport properties (scale, center, locked, layer overrides), or configuring plot settings on layouts.
Model Space vs Paper Space
AutoCAD drawings contain one model space and one or more paper space layouts. Each layout is backed by a BlockTableRecord.
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
BlockTableRecord paperSpace = (BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.PaperSpace], OpenMode.ForRead);
BlockTableRecord currentSpace = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
tr.Commit();
}
BlockTableRecord.ModelSpace is the string constant "*Model_Space"
BlockTableRecord.PaperSpace is the string constant "*Paper_Space"
- Additional paper space layouts use
"*Paper_Space0", "*Paper_Space1", etc.
Layout Access
LayoutManager
LayoutManager layoutMgr = LayoutManager.Current;
string currentName = layoutMgr.CurrentLayout;
int count = layoutMgr.LayoutCount;
layoutMgr.CurrentLayout = "Layout1";
Enumerating Layouts via LayoutDictionary
using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary layoutDict = (DBDictionary)tr.GetObject(
db.LayoutDictionaryId, OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
Layout layout = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
ed.WriteMessage($"\n{layout.LayoutName} (Tab order: {layout.TabOrder})");
}
tr.Commit();
}
Getting a Layout by Name
DBDictionary layoutDict = (DBDictionary)tr.GetObject(
db.LayoutDictionaryId, OpenMode.ForRead);
if (layoutDict.Contains("Sheet 1"))
{
Layout layout = (Layout)tr.GetObject(
layoutDict.GetAt("Sheet 1"), OpenMode.ForRead);
ObjectId blockId = layout.BlockTableRecordId;
}
Creating Layouts
Create a New Layout
LayoutManager layoutMgr = LayoutManager.Current;
ObjectId newLayoutId = layoutMgr.CreateLayout("My New Sheet");
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Layout newLayout = (Layout)tr.GetObject(newLayoutId, OpenMode.ForWrite);
newLayout.TabOrder = layoutMgr.LayoutCount;
tr.Commit();
}
Copy an Existing Layout
LayoutManager layoutMgr = LayoutManager.Current;
layoutMgr.CopyLayout("Layout1", "Layout1 - Copy");
Delete a Layout
LayoutManager layoutMgr = LayoutManager.Current;
layoutMgr.DeleteLayout("Sheet to Remove");
Rename a Layout
LayoutManager layoutMgr = LayoutManager.Current;
layoutMgr.RenameLayout("OldName", "NewName");
Viewport Creation
Creating a Viewport in Paper Space
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
Layout layout = (Layout)tr.GetObject(
layoutMgr.GetLayoutId("Sheet 1"), OpenMode.ForRead);
BlockTableRecord paperBtr = (BlockTableRecord)tr.GetObject(
layout.BlockTableRecordId, OpenMode.ForWrite);
Viewport vp = new Viewport();
vp.CenterPoint = new Point3d(5.5, 4.25, 0);
vp.Width = 8.0;
vp.Height = 5.0;
paperBtr.AppendEntity(vp);
tr.AddNewlyCreatedDBObject(vp, true);
vp.ViewTarget = new Point3d(1000, 2000, 0);
vp.ViewCenter = new Point2d(1000, 2000);
vp.ViewHeight = 250.0;
vp.CustomScale = 1.0 / 50.0;
vp.On = true;
vp.Locked = true;
tr.Commit();
}
Overall Viewport (Layout Default)
Every paper space layout has an overall viewport (the paper boundary) with Number = 1. It is created automatically and should not be deleted.
ObjectIdCollection vpIds = layout.GetViewports();
foreach (ObjectId vpId in vpIds)
{
Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForRead);
if (vp.Number == 1)
{
continue;
}
}
Standard Scale Types
vp.StandardScale = StandardScaleType.ScaleToFit;
vp.StandardScale = StandardScaleType.CustomScale;
Viewport Configuration
Setting Viewport Scale and Center
Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);
vp.ViewCenter = new Point2d(5000, 3000);
vp.ViewTarget = new Point3d(5000, 3000, 0);
vp.CustomScale = 1.0 / 240.0;
vp.ViewHeight = vp.Height / vp.CustomScale;
Non-Rectangular (Clipped) Viewports
Circle clipBoundary = new Circle(new Point3d(5, 4, 0), Vector3d.ZAxis, 3.0);
paperBtr.AppendEntity(clipBoundary);
tr.AddNewlyCreatedDBObject(clipBoundary, true);
vp.NonRectClipEntityId = clipBoundary.ObjectId;
vp.NonRectClipOn = true;
Viewport Layer Property Overrides
Viewport-specific layer overrides control per-viewport layer visibility, color, linetype, lineweight, transparency, and plot style without affecting other viewports or model space.
VP Freeze (Per-Viewport Layer Visibility)
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);
LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
ObjectIdCollection freezeIds = new ObjectIdCollection();
freezeIds.Add(lt["C-TOPO-CONTOUR"]);
freezeIds.Add(lt["C-ROAD-CENTERLINE"]);
vp.FreezeLayersInViewport(freezeIds.GetEnumerator());
ObjectIdCollection thawIds = new ObjectIdCollection();
thawIds.Add(lt["C-TOPO-CONTOUR"]);
vp.ThawLayersInViewport(thawIds.GetEnumerator());
tr.Commit();
}
Checking VP Frozen State
LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
bool isFrozenInVp = layer.IsVpFrozen(vpId);
VP Color, Linetype, Lineweight, Transparency Overrides
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);
LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
ObjectId layerId = lt["C-ROAD-CURB"];
vp.SetLayerPropertyOverrides(layerId,
new LayerPropertyOverrides
{
Color = Color.FromColorIndex(ColorMethod.ByAci, 1),
Linetype = db.ContinuousLinetype,
LineWeight = LineWeight.LineWeight050,
Transparency = new Transparency(30),
IsOverriddenColor = true,
IsOverriddenLinetype = true,
IsOverriddenLineWeight = true,
IsOverriddenTransparency = true
});
vp.RemoveLayerPropertyOverrides(layerId);
tr.Commit();
}
Default Viewport Visibility for New Viewports
LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForWrite);
layer.ViewportVisibilityDefault = false;
Switching Layouts Programmatically
LayoutManager layoutMgr = LayoutManager.Current;
layoutMgr.CurrentLayout = "Sheet 1";
layoutMgr.CurrentLayout = "Model";
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
ed.SwitchToModelSpace();
ed.SwitchToPaperSpace();
Activating a Specific Viewport
ed.CurrentViewportObjectId = vpId;
Plot Settings on Layouts
Every Layout inherits from PlotSettings. Use PlotSettingsValidator to configure plot parameters.
Configuring Plot Settings
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Layout layout = (Layout)tr.GetObject(layoutId, OpenMode.ForWrite);
PlotSettingsValidator psv = PlotSettingsValidator.Current;
psv.RefreshLists(layout);
psv.SetPlotConfigurationName(layout, "DWG To PDF.pc3", null);
psv.RefreshLists(layout);
StringCollection mediaNames = psv.GetCanonicalMediaNameList(layout);
foreach (string media in mediaNames)
{
string localName = psv.GetLocaleMediaName(layout, media);
if (localName.Contains("22") && localName.Contains("34"))
{
psv.SetCanonicalMediaName(layout, media);
break;
}
}
psv.SetPlotType(layout, Autodesk.AutoCAD.DatabaseServices.PlotType.Layout);
psv.SetUseStandardScale(layout, true);
psv.SetStdScaleType(layout, StdScaleType.StdScale1To1);
psv.SetUseStandardScale(layout, false);
psv.SetCustomPrintScale(layout, new CustomScale(1.0, 1.0));
psv.SetPlotCentered(layout, true);
psv.SetCurrentStyleSheet(layout, "monochrome.ctb");
psv.SetPlotRotation(layout, PlotRotation.Degrees000);
tr.Commit();
}
Page Setups (Named PlotSettings)
DBDictionary plotSettingsDict = (DBDictionary)tr.GetObject(
db.PlotSettingsDictionaryId, OpenMode.ForRead);
foreach (DBDictionaryEntry entry in plotSettingsDict)
{
PlotSettings ps = (PlotSettings)tr.GetObject(entry.Value, OpenMode.ForRead);
ed.WriteMessage($"\nPage setup: {ps.PlotSettingsName}");
}
layout.CopyFrom(pageSetupPlotSettings);
Layout Events
LayoutManager layoutMgr = LayoutManager.Current;
layoutMgr.LayoutSwitched += (sender, e) =>
{
ed.WriteMessage($"\nSwitched to layout: {e.LayoutName}");
};
layoutMgr.LayoutRenamed += (sender, e) =>
{
ed.WriteMessage($"\nLayout renamed: {e.OldName} -> {e.NewName}");
};
layoutMgr.LayoutRemoved += (sender, e) =>
{
ed.WriteMessage($"\nLayout removed: {e.LayoutName}");
};
layoutMgr.LayoutCreated += (sender, e) =>
{
ed.WriteMessage($"\nLayout created: {e.LayoutName}");
};
layoutMgr.LayoutsReordered += (sender, e) =>
{
ed.WriteMessage("\nLayout tabs reordered.");
};
Gotchas
- The Model tab is a layout too (
Layout.ModelType == true) and is always present in the layout dictionary -- do not delete it
- Every paper space layout auto-creates an overall viewport (
Number == 1) representing the paper boundary -- do not erase it
Viewport.On = true must be set explicitly after creation or the viewport appears blank
Viewport.CustomScale is paper/model ratio: 1/50.0 means 1 paper unit = 50 model units
ViewHeight and CustomScale are linked -- setting one recalculates the other; set CustomScale last if you need a precise scale
PlotSettingsValidator methods modify the Layout object directly -- the Layout must be opened ForWrite before calling them
psv.RefreshLists() must be called after SetPlotConfigurationName() before querying paper sizes -- otherwise the media list is stale
LayoutManager.CurrentLayout setter throws if the layout name does not exist
FreezeLayersInViewport() and ThawLayersInViewport() take an IEnumerator of ObjectIds, not an ObjectIdCollection directly -- call .GetEnumerator() on the collection
- Layer
"0" cannot be VP-frozen
- Viewport layer overrides only take effect when the viewport is on and the layout is active
CopyLayout copies all entities including viewports and their configurations
DeleteLayout cannot remove the last remaining paper space layout
Layout.TabOrder is 0-based with 0 reserved for Model -- paper space layouts start at 1
- Setting
Locked = true on a viewport prevents user zoom/pan but code can still modify ViewCenter and ViewHeight
Related Skills
acad-layers — viewport layer property overrides extend base layer properties per-viewport
acad-blocks — each layout is backed by a BlockTableRecord; layout entities live in paper space BTRs
acad-plot-publish — batch plotting and publishing across multiple layouts
acad-editor-input — switching layouts and activating viewports programmatically via Editor