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);
// Model space block table record
BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
// Paper space block table record (the first/default paper space)
BlockTableRecord paperSpace = (BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.PaperSpace], OpenMode.ForRead);
// Current space (model or paper depending on active tab)
BlockTableRecord currentSpace = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
tr.Commit();
}
BlockTableRecord.ModelSpaceis the string constant"*Model_Space"BlockTableRecord.PaperSpaceis the string constant"*Paper_Space"- Additional paper space layouts use
"*Paper_Space0","*Paper_Space1", etc.
Layout Access
LayoutManager
LayoutManager layoutMgr = LayoutManager.Current;
// Get the current layout name
string currentName = layoutMgr.CurrentLayout;
// Get layout count (includes "Model" tab)
int count = layoutMgr.LayoutCount;
// Switch to a layout by name
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;
// CreateLayout returns the ObjectId of the new layout
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; // place at end
tr.Commit();
}
Copy an Existing Layout
LayoutManager layoutMgr = LayoutManager.Current;
// CopyLayout copies the source layout including all entities and settings
layoutMgr.CopyLayout("Layout1", "Layout1 - Copy");
Delete a Layout
LayoutManager layoutMgr = LayoutManager.Current;
// Cannot delete the Model tab or the last paper space layout
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); // center in paper space units
vp.Width = 8.0; // width in paper space units
vp.Height = 5.0; // height in paper space units
paperBtr.AppendEntity(vp);
tr.AddNewlyCreatedDBObject(vp, true);
// Set the view target (model space coordinates to display)
vp.ViewTarget = new Point3d(1000, 2000, 0);
vp.ViewCenter = new Point2d(1000, 2000);
vp.ViewHeight = 250.0; // controls zoom level (model space units visible)
// Set custom scale (e.g., 1:50)
vp.CustomScale = 1.0 / 50.0;
// Turn the viewport on
vp.On = true;
// Lock the viewport to prevent accidental zoom/pan
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.
// Find the overall viewport
ObjectIdCollection vpIds = layout.GetViewports();
foreach (ObjectId vpId in vpIds)
{
Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForRead);
if (vp.Number == 1)
{
// This is the overall (paper space boundary) viewport
continue;
}
// Process user-created viewports
}
Standard Scale Types
vp.StandardScale = StandardScaleType.ScaleToFit;
vp.StandardScale = StandardScaleType.CustomScale;
// Other values: Scale1To1, Scale1To2, Scale1To4, Scale1To5, Scale1To8,
// Scale1To10, Scale1To16, Scale1To20, Scale1To30, Scale1To40, Scale1To50,
// Scale1To100, Scale2To1, Scale4To1, Scale8To1, Scale10To1, Scale100To1
Viewport Configuration
Setting Viewport Scale and Center
Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);
// Center the view on model space coordinates
vp.ViewCenter = new Point2d(5000, 3000);
vp.ViewTarget = new Point3d(5000, 3000, 0);
// Set scale: CustomScale = paper_units / model_units
// For 1" = 20' scale (1:240 when base unit is inches):
vp.CustomScale = 1.0 / 240.0;
// Or use ViewHeight to control zoom (model space units visible vertically)
// ViewHeight = viewport_paper_height / custom_scale
vp.ViewHeight = vp.Height / vp.CustomScale;
Non-Rectangular (Clipped) Viewports
// Create a clipping boundary (circle, polyline, etc.)
Circle clipBoundary = new Circle(new Point3d(5, 4, 0), Vector3d.ZAxis, 3.0);
paperBtr.AppendEntity(clipBoundary);
tr.AddNewlyCreatedDBObject(clipBoundary, true);
// Assign the clip boundary to the viewport
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);
// Freeze layers in this viewport
ObjectIdCollection freezeIds = new ObjectIdCollection();
freezeIds.Add(lt["C-TOPO-CONTOUR"]);
freezeIds.Add(lt["C-ROAD-CENTERLINE"]);
vp.FreezeLayersInViewport(freezeIds.GetEnumerator());
// Thaw layers in this viewport
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);
// Check if a layer is frozen in a specific viewport
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"];
// Set viewport-specific color override
vp.SetLayerPropertyOverrides(layerId,
new LayerPropertyOverrides
{
Color = Color.FromColorIndex(ColorMethod.ByAci, 1), // red in this VP
Linetype = db.ContinuousLinetype,
LineWeight = LineWeight.LineWeight050,
Transparency = new Transparency(30),
IsOverriddenColor = true,
IsOverriddenLinetype = true,
IsOverriddenLineWeight = true,
IsOverriddenTransparency = true
});
// Remove overrides for a layer
vp.RemoveLayerPropertyOverrides(layerId);
tr.Commit();
}
Default Viewport Visibility for New Viewports
LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForWrite);
// When false, new viewports will have this layer frozen by default
layer.ViewportVisibilityDefault = false;
Switching Layouts Programmatically
// Switch active layout tab
LayoutManager layoutMgr = LayoutManager.Current;
layoutMgr.CurrentLayout = "Sheet 1";
// Switch to model space
layoutMgr.CurrentLayout = "Model";
// Set active viewport in paper space (MSPACE/PSPACE equivalent)
// Use Editor.SwitchToModelSpace / SwitchToPaperSpace for interactive switching
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Switch to model space within the current paper space layout
ed.SwitchToModelSpace();
// Switch back to paper space
ed.SwitchToPaperSpace();
Activating a Specific Viewport
// Set the active viewport by viewport number
// MdiActiveDocument.Editor.CurrentViewportObjectId targets a specific VP
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;
// Refresh the list of available devices
psv.RefreshLists(layout);
// Set the plot device (printer/plotter)
psv.SetPlotConfigurationName(layout, "DWG To PDF.pc3", null);
// Refresh after device change to get available paper sizes
psv.RefreshLists(layout);
// Set the paper size
StringCollection mediaNames = psv.GetCanonicalMediaNameList(layout);
// Find desired paper size (e.g., "ANSI_D_(22.00_x_34.00_Inches)")
foreach (string media in mediaNames)
{
string localName = psv.GetLocaleMediaName(layout, media);
if (localName.Contains("22") && localName.Contains("34"))
{
psv.SetCanonicalMediaName(layout, media);
break;
}
}
// Set plot area
psv.SetPlotType(layout, Autodesk.AutoCAD.DatabaseServices.PlotType.Layout);
// Other PlotType values: Display, Extents, Limits, View, Window
// Set plot scale
psv.SetUseStandardScale(layout, true);
psv.SetStdScaleType(layout, StdScaleType.StdScale1To1);
// Or set a custom scale
psv.SetUseStandardScale(layout, false);
psv.SetCustomPrintScale(layout, new CustomScale(1.0, 1.0));
// Plot offset (center the plot)
psv.SetPlotCentered(layout, true);
// Or set manual offset
// psv.SetPlotOrigin(layout, new Point2d(0.5, 0.25));
// Plot style table
psv.SetCurrentStyleSheet(layout, "monochrome.ctb");
// Plot rotation
psv.SetPlotRotation(layout, PlotRotation.Degrees000);
tr.Commit();
}
Page Setups (Named PlotSettings)
// Access the plot settings dictionary for named page setups
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}");
}
// Apply a named page setup to a layout
layout.CopyFrom(pageSetupPlotSettings);
Layout Events
LayoutManager layoutMgr = LayoutManager.Current;
// Fires when the current layout tab changes
layoutMgr.LayoutSwitched += (sender, e) =>
{
ed.WriteMessage($"\nSwitched to layout: {e.LayoutName}");
};
// Fires when a layout is about to be renamed
layoutMgr.LayoutRenamed += (sender, e) =>
{
ed.WriteMessage($"\nLayout renamed: {e.OldName} -> {e.NewName}");
};
// Fires when a layout is about to be removed
layoutMgr.LayoutRemoved += (sender, e) =>
{
ed.WriteMessage($"\nLayout removed: {e.LayoutName}");
};
// Fires when a layout is created or copied
layoutMgr.LayoutCreated += (sender, e) =>
{
ed.WriteMessage($"\nLayout created: {e.LayoutName}");
};
// Fires when tab order changes
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 = truemust be set explicitly after creation or the viewport appears blankViewport.CustomScaleis paper/model ratio:1/50.0means 1 paper unit = 50 model unitsViewHeightandCustomScaleare linked -- setting one recalculates the other; setCustomScalelast if you need a precise scalePlotSettingsValidatormethods modify the Layout object directly -- the Layout must be openedForWritebefore calling thempsv.RefreshLists()must be called afterSetPlotConfigurationName()before querying paper sizes -- otherwise the media list is staleLayoutManager.CurrentLayoutsetter throws if the layout name does not existFreezeLayersInViewport()andThawLayersInViewport()take anIEnumeratorof ObjectIds, not anObjectIdCollectiondirectly -- 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
CopyLayoutcopies all entities including viewports and their configurationsDeleteLayoutcannot remove the last remaining paper space layoutLayout.TabOrderis 0-based with 0 reserved for Model -- paper space layouts start at 1- Setting
Locked = trueon a viewport prevents user zoom/pan but code can still modifyViewCenterandViewHeight
Related Skills
acad-layers— viewport layer property overrides extend base layer properties per-viewportacad-blocks— each layout is backed by a BlockTableRecord; layout entities live in paper space BTRsacad-plot-publish— batch plotting and publishing across multiple layoutsacad-editor-input— switching layouts and activating viewports programmatically via Editor