布局和视口

布局和视口是CAD出图的重要手段之一,其中视口可以映射到模型空间的任一范围,进而在布局空间灵活组织图形成果。
本文针对布局创建及切换、视口创建封装若干接口。

切换布局

借助Database的TileMode属性来切换到模型空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public static void SwitchLayout(this Document doc, string layoutName)
{
if (string.IsNullOrWhiteSpace(layoutName) || ObjectId.Null == doc.Database.GetLayoutIdByName(layoutName))
return;
using (var docLock = doc.LockDocument())
LayoutManager.Current.CurrentLayout = layoutName;
}

public static void SwitchToModel()
{
var doc = DwgOperators.ThisDocument;
using (var docLock = doc.LockDocument())
doc.Database.TileMode = true;
}

//----------------------------------------------------------------------
private static ObjectId GetLayoutIdByName(this Database db, string layoutName)
{
ObjectId resId = ObjectId.Null;

if (string.IsNullOrWhiteSpace(layoutName))
return resId;

using (Transaction transaction = db.TransactionManager.StartTransaction())
{
BlockTable blockTable = transaction.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
foreach (ObjectId id in blockTable)
{
BlockTableRecord btr = transaction.GetObject(id, OpenMode.ForRead) as BlockTableRecord;
if (btr.IsLayout)
{
Layout layout = transaction.GetObject(btr.LayoutId, OpenMode.ForRead) as Layout;
if (layout.LayoutName == layoutName)
{
resId = id;
break;
}
}
}
transaction.Commit();
}
return resId;
}

创建布局

为了使新布局生效,调用SwitchLayout()切换一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static ObjectId CreateLayout(this Document doc, string layoutName)
{
ObjectId resId = ObjectId.Null;
if (doc == null || string.IsNullOrWhiteSpace(layoutName))
return resId;
var db = doc.Database;
if (db.GetLayoutIdByName(layoutName) != ObjectId.Null)
return resId;
using (var docLock = doc.LockDocument())
{
using (Transaction transaction = doc.TransactionManager.StartTransaction())
{
DBDictionary layouts = transaction.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary;
resId = LayoutManager.Current.CreateLayout(layoutName);
transaction.Commit();
}
}
doc.Database.SwitchLayout(layoutName);
return resId;
}

创建视口

创建从任一矩形创建视口的函数,此函数的开发着实花费了不少精力,感叹一下!

  • CreateViewportIntoPaperspace():创建模型空间中任一矩形的视口(很实用)
  • SetViewportLockedLayers():设置某一视口中的图层状态
  • AddUCS():添加用户坐标系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
public static ObjectId CreateViewportIntoPaperspace(this Database db,string layoutName, Point3d leftBottomPoint, double width, double height,double rotation, Point3d viewportLeftBottomPoint, double? viewportWidth = null,double? viewportHeight = null, double scale = 1.0)
{
ObjectId resId = ObjectId.Null;

if (string.IsNullOrWhiteSpace(layoutName))
return resId;

using (Transaction transaction = db.TransactionManager.StartTransaction())
{
Viewport vport = new Viewport();

double vWidth, vHeight;
if (viewportWidth == null)
vWidth = width;
else
vWidth = viewportWidth.Value;
if (viewportHeight == null)
vHeight = height;
else
vHeight = viewportHeight.Value;
vport.CenterPoint = new Point3d(viewportLeftBottomPoint.X + 0.5 * vWidth, viewportLeftBottomPoint.Y + 0.5 * vHeight, 0);
vport.Width = vWidth;
vport.Height = vHeight;

var point = CoorTransform(leftBottomPoint, rotation, new Point3d(0.5 * width, 0.5 * height, 0));
vport.ViewTarget = point;

var ucsId = db.AddUCS($"ucs-{Guid.NewGuid().ToString()}", leftBottomPoint,
new Vector3d(Math.Cos(rotation), Math.Sin(rotation), 0),
new Vector3d(Math.Cos(rotation + 0.5 * Math.PI), Math.Sin(rotation + 0.5 * Math.PI), 0));
vport.SetUcs(ucsId);

vport.TwistAngle = Math.PI * 2 - rotation;
vport.ViewDirection = new Vector3d(0, 0, 1);
vport.CustomScale = scale;
resId = db.AddEntity(vport, layoutName);
db.SwitchLayout(layoutName);
vport.On = true;

transaction.Commit();
}
return resId;
}

public static void SetViewportLockedLayers(this Document doc, ObjectId id, List<string> frozenLayerNames)
{
if (doc == null || id == ObjectId.Null) return;
if (frozenLayerNames == null || frozenLayerNames.Count == 0) return;
var db = doc.Database;
using (Transaction transaction = db.TransactionManager.StartTransaction())
{
Viewport vp = transaction.GetObject(id, OpenMode.ForWrite) as Viewport;
if (vp != null)
{
LayerTable lt = transaction.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
List<ObjectId> layerIds = new List<ObjectId>();
foreach (var name in frozenLayerNames)
if (lt.Has(name))
layerIds.Add(lt[name]);
vp.FreezeLayersInViewport(layerIds.GetEnumerator());
}
transaction.Commit();
}
}

//----------------------------------------------------------------------
private static ObjectId AddUCS(this Database db, string ucsName, Point3d origin, Vector3d xAxis, Vector3d yAxis)
{
ObjectId resId = ObjectId.Null;

if (string.IsNullOrWhiteSpace(ucsName))
return resId;

using (Transaction transaction = db.TransactionManager.StartTransaction())
{
UcsTable ucsTable = transaction.GetObject(db.UcsTableId, OpenMode.ForWrite) as UcsTable;
if (!ucsTable.Has(ucsName))
{
UcsTableRecord ucsTableRecord = new UcsTableRecord();
ucsTableRecord.Name = ucsName;
ucsTableRecord.Origin = origin;
ucsTableRecord.XAxis = xAxis;
ucsTableRecord.YAxis = yAxis;

resId = ucsTable.Add(ucsTableRecord);
transaction.AddNewlyCreatedDBObject(ucsTableRecord, true);
ucsTable.DowngradeOpen();
}
else
resId = ucsTable[ucsName];
transaction.Commit();
}
return resId;
}

private static Point3d CoorTransform(Point3d deltaDist, double rotation, Point3d p1)
{
double dist1 = Math.Sqrt(p1.X * p1.X + p1.Y * p1.Y);
double rotation1 = Arctan(p1.Y, p1.X);
double totalRotation = rotation1 + rotation;
Point3d resPoint = new Point3d(deltaDist.X + dist1 * Math.Cos(totalRotation), deltaDist.Y + dist1 * Math.Sin(totalRotation), 0);
return resPoint;
}

评论