March 17, 2013

Bài 7: Khoang chứa (container)

Xin chào,

Trong bài này tôi sẽ trình bày các khái niệm và đặc tính của đối tượng khoang chứa ObjecARX. Chúng ta đã từng đề cập đến trước đó và bây giờ chúng ta sẽ đi sâu vào chi tiết hơn.

Giới thiệu

Mục đích của khoang chưa là lưu trữ và quản lý đối tượng có cùng một kiểu hoặc lớp. Có hai loại khoang là Bảng ký hiệu (Symbol table) và Từ điển (Dictionaries). Mỗi một loại lại có những chức năng đặc biệt được thiết kế để cho phép truy nhập các phương thức đơn giản và hiệu quả hơn.

Bảng ký hiệu

Kiểu khoang chứa này được thiết kế để lưu giữ các bản ghi. Mỗi Bảng ký hiệu lưu giữ bản ghi của nó sử dụng tên mục vào duy nhất. Bằng mục vào này bạn có thể lấy được con trỏ của bản ghi để đọc hoặc ghi thông tin. Khoang chứa cũng có thể nhận thêm các mục vào mới và thậm chí là các mục vào đã được gỡ bỏ (trong trường hợp nó không được đối tượng nào sử dụng nữa).
Để hiểu rõ hơn về mục vào của khoang chứa, bạn cần phải sử dụng một biến lặp tương ứng cho phép bạn lấy các mục vào để truy nhập vào đối tượng. AutoCAD có một vài bảng ký hiệu để lưu giữ lớp, đường nét, kiểu chữ và các đối tượng khác nữa. 

Các khoang chứa hoạt động cùng một cách, có một lớp cơ sở chung cho mỗi Bảng ký hiệu, bản ghi của nó và các biến lặp tương ứng.

Cây phân cấp bảng ký hiệu Symbol Table như sau:

AcDbSymbolTable
AcDbAbstractViewTable
AcDbViewportTable
AcDbViewTable
AcDbBlockTable
AcDbDimStyleTable
AcDbLayerTable
AcDbLinetypeTable
AcDbRegAppTable
AcDbTextStyleTable
AcDbUCSTable
AcDbSymbolTableRecord

AcDbAbstractViewTableRecord
AcDbViewportTableRecord
AcDbViewTableRecord
AcDbBlockTableRecord
AcDbDimStyleTable
Record
AcDbLayerTable
Record
AcDbLinetypeTable
Record
AcDbRegAppTable
AcDbTextStyleTable
AcDbUCSTable
AcDbSymbolTableIterator

AcDbAbstractViewTableIterator
AcDbViewportTableIterator
AcDbViewTableIterator
AcDbBlockTableIterator
AcDbDimStyleTable
Iterator
AcDbLayerTable
Iterator
AcDbLinetypeTable
Iterator
AcDbRegAppTable
Iterator
AcDbTextStyleTable
Iterator
AcDbUCSTable
Iterator
Ví dụ để tạo một layer mới, bạn cần phải:
  • Mở CSDL Database hiện hành;
  • Mở bảng ký hiệu AcDbLayerTable (cho phép Ghi);
  • Tạo một bản ghi mới AcDbLayerTableRecord (sử dụng toán tử new);
  • Định hình cho AcDbLayerTableRecord;
  • Thêm nó vào trong Bảng ký hiệu thích hợp AcDbLayerTable;
  • Đóng bản ghi;
  • Đóng khoang chứa.
void createLayer() {

AcDbLayerTable *pLayerTbl = NULL; acdbHostApplicationServices()->workingDatabase()

->getSymbolTable(pLayerTbl, AcDb::kForWrite);
if (!pLayerTbl->has(_T("MYLAYER"))) {
AcDbLayerTableRecord *pLayerTblRcd = new AcDbLayerTableRecord;
pLayerTblRcd->setName(_T("MYLAYER"));
AcCmColor color;
color.setColorIndex(1); // red
pLayerTblRcd->setColor(color);
pLayerTbl->add(pLayerTblRcd);
pLayerTblRcd->close();
} else acutPrintf("\nLayer already exists");
pLayerTbl->close();


}
Để liệt kê tất cả các lớp tồn tại:
  • Mở CSDL Database hiện hành;
  • Mở bảng AcDbLayerTable (để đọc);
  • Tạo một biến lặp AcDbLayerTableIterator;
  • Lặp lại quá trình với từng mục vào;
  • Lấy tên của các mục vào;
  • Đóng khoang chứa.
void iterateLayers() {

AcDbLayerTable* pLayerTbl = NULL;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLayerTbl, AcDb::kForRead);
AcDbLayerTableIterator* pLayerIterator;
pLayerTbl->newIterator(pLayerIterator);
AcDbLayerTableRecord* pLayerTblRcd;
TCHAR* pLName;
for (; !pLayerIterator->done(); pLayerIterator->step()) {
pLayerIterator->getRecord(pLayerTblRcd, AcDb::kForRead);
pLayerTblRcd->getName(pLName);
pLayerTblRcd->close();
acutPrintf(_T("\nLayer name: %s"),pLName);
acutDelString(pLName);
}
delete pLayerIterator;
pLayerTbl->close();
}

Từ điển Dictionaries

Kiểu khoang chứa này được thiết kế để lưu giữ các đối tượng được dẫn xuất từ AcDbObject. Nó vô cùng hữu ích vì chúng ta cũng cần lưu giữ các đối tượng riêng của mình bên trong nó. Cấu trúc từ điến cũng giống như cấu trúc của cây nơi chúng ta có các điểm nút và các mục vào. Trong cùng một nút, mục vào không thể trùng tên vì chúng phải là duy nhất trong cùng một cấp độ. Có Khóa các mục vàoKhóa mục vào sẽ chỉ ra con trỏ AcDbObject có thể được khôi phục trực tiếp hoặc thông qua biến lặp (AcDbDictionaryIterator).
Để lưu giữ đối tượng, chúng ta cần tạo một mục vào sử dụng phương thức setAt() thông qua con trỏ đối tượng đã được khởi tạo với toán tử new. Khoang chứa AcDbDictionarysẽ trả về mã định danh AcDbObjectId cho từng mục vào.
Khoang chứa này được sử dụng bởi một vài tính năng của AutoCAD như nhóm (group) hoặc nhiều đa tuyến (multiline styles?). Chúng ta khám phá nhiều hơn nữa về Từ điển trong chương Đối tượng riêng.

Tạm biệt!
Link nguồn: Arxdummies

No comments:

Post a Comment

Featured Post

Khóa học AutoLISP cơ bản | Tự học lập trình | AutoLISP that la don gian

Khóa học được cung cấp bởi  Thanh Trí AutoCAD       Thông tin thêm: 👉👉👉

Popular Posts