Trong quá trình triển khai bản vẽ hạ tầng bằng Civil 3D, việc bố trí nhãn hố ga (Structure Label) sao cho đồng đều và dễ đọc là một công việc khá mất thời gian. Đặc biệt khi số lượng structure lớn, việc chỉnh thủ công từng nhãn dễ gây sai lệch và thiếu nhất quán.
Bài viết này giới thiệu một đoạn code C# giúp đồng bộ vị trí nhãn structure dựa trên một nhãn mẫu, từ đó giúp chuẩn hóa trình bày bản vẽ một cách nhanh chóng.
Mục tiêu của công cụ
- Chọn một nhãn structure làm chuẩn
- Lấy thông tin vị trí offset của nhãn này
- Áp dụng lại offset đó cho nhiều nhãn khác
- Giúp các nhãn được căn chỉnh đồng đều
Quy trình sử dụng
Khi chạy lệnh PN_MAStrucLabel, người dùng thực hiện:
- Bước 1 - Chọn một structure label làm mẫu
- Bước 2 - Chọn các structure label cần đồng bộ
- Bước 3 - Hệ thống tự động cập nhật vị trí các nhãn
Nguyên lý hoạt động
1. Lấy nhãn mẫu
Chương trình yêu cầu chọn một đối tượng thuộc loại StructureLabel.
Sau đó lấy thông tin:
DraggedOffset- khoảng lệch của nhãn so với vị trí neo
Đây chính là dữ liệu chuẩn để áp dụng cho các nhãn khác.
2. Lọc danh sách nhãn cần xử lý
Sử dụng SelectionFilter với DXF:
AECC_STRUCTURE_LABEL
Điều này đảm bảo chỉ chọn đúng các nhãn structure.
3. Cập nhật vị trí nhãn
Với mỗi nhãn được chọn:
- Tính toán lại vị trí bằng
Matrix3d.Displacement - Gán lại
LabelLocation - Gán lại
DraggedOffset
Nhờ đó, tất cả nhãn sẽ có cùng cách hiển thị như nhãn mẫu.
Đoạn code minh họa
[CommandMethod("PN_MAStrucLabel")]
[Obsolete]
public void JigStructurelabel()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
CivilDocument civil = CivilApplication.ActiveDocument;
try
{
using (DocumentLock aclock = doc.LockDocument())
{
using (Transaction _tr = db.TransactionManager.StartTransaction())
using (_tr)
{
PromptEntityOptions _ent = new PromptEntityOptions("\nSelect structure label typical:");
_ent.SetRejectMessage("Must be SurfaceElevationLabel");
_ent.AddAllowedClass(typeof(StructureLabel), true);
PromptEntityResult _ents = ed.GetEntity(_ent);
if (_ents.Status != PromptStatus.OK)
return;
ObjectId _EDS = _ents.ObjectId;
StructureLabel _struc = _tr.GetObject(_EDS, OpenMode.ForWrite) as StructureLabel;
var _local = _struc.DraggedOffset;
TypedValue[] _tv = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "AECC_STRUCTURE_LABEL") };
SelectionFilter _ts = new SelectionFilter(_tv);
PromptSelectionOptions _op = new PromptSelectionOptions();
_op.MessageForAdding = "Select Structure label to typical:";
PromptSelectionResult _ops = ed.GetSelection(_op, _ts);
if (_ops.Status != PromptStatus.OK)
return;
ObjectId[] _IDS = _ops.Value.GetObjectIds();
foreach (ObjectId _id in _IDS)
{
StructureLabel _strucs = _tr.GetObject(_id, OpenMode.ForWrite) as StructureLabel;
_strucs.LabelLocation = _strucs.AnchorInfo.Location.TransformBy(Matrix3d.Displacement(_local));
_strucs.DraggedOffset = _local;
_strucs.UpgradeOpen();
}
_tr.Commit();
}
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\nError: " + ex.Message);
}
}
Một số lưu ý
- Luôn sử dụng
Transactionkhi thao tác với database - Dùng
DocumentLockđể tránh xung đột khi chỉnh sửa bản vẽ - Kiểm tra đối tượng trước khi cast sang
StructureLabel - Thuộc tính
[Obsolete]cho thấy có thể cần refactor lại trong tương lai
Khi nào nên sử dụng
- Cần chuẩn hóa bản vẽ trước khi nộp hồ sơ
- Làm việc với nhiều structure trong cùng một khu vực
- Muốn tiết kiệm thời gian chỉnh sửa thủ công
Kết luận
Đây là một ví dụ đơn giản nhưng rất hiệu quả về việc ứng dụng API của Civil 3D để tự động hóa công việc. Chỉ với một nhãn mẫu, bạn có thể nhanh chóng đồng bộ hàng loạt nhãn khác, đảm bảo tính nhất quán và nâng cao chất lượng bản vẽ.
Bạn có thể mở rộng thêm:
- Đồng bộ theo nhiều kiểu label style
- Áp dụng cho profile view
- Xây dựng giao diện chọn mẫu