Cài đặt AddinManager, sử dụng class FilteredElementCollector để truy xuất đến các element trong Revit

Sharing is caring!

Mỗi khi viết addin cho Revit, điều khiến tui bực bội nhất là cứ phải tắt rồi lại mở lải Revit để cho ổng cập nhật lại cái file dll vừa mới rebuild của tui. Sửa code 10 lần là phải tắt rồi mở lại Revit 10 lần như vậy, nó ức chế lắm các bạn. May mắn thay, những lập trình viên của Revit đã tạo ra một cái addin có tên là AddinManager tạm gọi là addin của addin để quản lý các cái addin khác trong quá trình debug, sửa chữa code. Vậy ta tìm thấy cái AddinManager này ở đâu? Xin thưa là, họ nhét nó vào trong cái Revit SDK đó mấy bạn.

Vậy hôm nay, tui sẽ chỉ các bạn cách cài đặt cái AddinManager này và tiện thể viết một cái addin để giới thiệu cho các bạn cái class FilteredElementCollector.

1. Cài AddinManager:

Đầu tiên, các bạn vào trang web của Revit để download cái SDK về. Link nó đây: Revit SDK 2016 . Xong, các bạn cứ chọn thư mục nào đó rồi install (thực chất là nó giải nén ra thôi). Sau khi cài xong, các bạn sẽ có thư mục giống như vầy:

Các bạn thấy cái thư mục Add-in Manager không? Thấy thì click vào, mở nó ra thì các bạn sẽ thấy các file dll và file addin như vầy:

Tiếp theo, copy 3 file AddInManager.dllAutodesk.AddInManager.addinAutodesk.AddInManager-Automatic.addin vào thư mục C:\ProgramData\Autodesk\Revit\Addins\2016. Vẫn chưa chạy được đâu, các bạn phải edit lại cái đường dẫn file .dll trong 2 file .addin đó nữa thì nó mới hiểu.

Tắt Revit (nếu đang mở) trước khi copy 3 file trên

Mở 2 cái file Autodesk.AddInManager.addinAutodesk.AddInManager-Automatic.addin trong thư mục C:\ProgramData\Autodesk\Revit\Addins\2016, các bạn thấy nội dung như sau:

Autodesk.AddInManager.addin

Autodesk.AddInManager-Automatic.addin

Các bạn chỉ cần xóa mấy cái đoạn text [TARGETDIR] đi là xong, lý do là cái file AddinManager.dll nó nằm cùng thư mục với 2 file .addin này rồi.

Để kiểm tra, các bạn chạy Revit, xong kiểm tra cái mục External Tools trong cái tab Add-ins, các bạn sẽ thấy nó được load lên như vầy:

Vậy là xong phần cài đặt AddinManager ha, dễ òm Whistling  .Cách sử dụng như thế nào thì lát nữa chạy addin demo tui sẽ nói tiếp. Giờ qua phần viết Addin mới nào Who-s-the-man .

2. Sử dụng class FilteredElementCollector:

Khi các bạn mở một file revit lên thì thánh thần ơi, một đống element trong đó luôn nào là Wall, Door, Rebar, Beam, Floor……, mỗi loại có vài chục element, vậy thì làm sao cái addin mình nó biết là phải tương tác với cái element hay một nhóm các element nào bây giờ? Dễ òm, dùng cái class FilteredElementCollector này chứ đâu, Revit nó cung cấp cho mình mà  Happy-Grin

Class FilteredElementCollector này nó cung cấp cho mình một số cách để lọc các element như sau:

  • Filter các element gì đó trên toàn bộ document.
  • Filter các element gì đó trong một View cụ thể.
  • Filter các element gì đó trong một tập các element có sẵn (thông thường là danh sách các ElementId).

Vậy thì tui sẽ viết demo cho từng kiểu cho dễ ha.

Để xem chi tiết API của từng class, các bạn mở cái file RevitAPI.chm trong thư mục cài cái Revit SDK như hướng dẫn phần 1

2.1. Filter các element trên toàn bộ document:

Chạy Revit, mở cái file Structural Sample Project lên, xong tui tự hỏi, làm sao biết trong file này có bao nhiêu cái dầm(Beam) và mỗi cái dầm này có Id là bao nhiêu, thôi khỏi hỏi, viết cái addin cho nó tự đếm:

Giải thích code nha:

Để filter trên toàn bộ document, các bạn phải tạo đối tượng FilteredElementCollector với tham số là cái document hiện hành (là biến doc đó các bạn). tiếp, ta phải cho nó một số điều kiện để nó lọc thông qua các hàm sau:

hàm này sẽ chỉ lấy các element không phải là ElementType, bởi vì Beam là một FamilyInstance chứ không phải là ElementType.

hàm ofCategory() này sẽ filter theo những BuiltInCategory của Revit, cụ thể là Beam thì thuộc category là BuiltInCategory.OST_StructuralFraming

Để chắn chắn, tui dùng hàm OfClass() để lọc các element phải là FamilyInstance class, (do Beam là FamilyInstance).

Túm lại là diễn giải bằng ngôn ngữ tự nhiên thì như sau: lọc các element không phải là ElementType mà phải là Familyinstance và thuộc category là BuiltInCategory.OST_StructuralFraming

Thứ tự gọi hàm không ảnh hưởng đến kết quả, càng nhiều điều kiện thì kết quả lọc sẽ nhỏ lại

Lúc này là ta đã có một tập các Element là FamilyInstance rồi, duyệt qua từng element, lấy ra cái Id tương ứng của nó, đồng thời tăng biến total lên 1.

Sau khi kết thúc vòng lặp foreach, thêm cái dòng text total vào cuối chuổi, sau đó dùng TaskDialog để show kết quả.

Code xong, build ra file DLL thôi (cách build project thì các bạn xem lại bài nhập môn). Sau khi build thành công, các bạn chạy Revit, chon tab Add-ins, click External Tools, click Add-in Manager (Manual Mode):

Do tui để [Transaction(TransactionMode.Manual)] ngay trên đầu class nên khi chọn Add-in Manager phải chọn là Manual Mode.

Click nút Load, rồi chọn đến thư mục [FilteredElementDemoProject_DIR]\bin\Debug, chọn file FilterElementDemo.dll, thì nó sẽ được load lên như vầy:

Các bạn thấy, trong cái file DLL nó sẽ có cái class FilterDocumentCommand. Click nó rồi chọn nút Run hoặc là double click vào nó luôn cũng được, các bạn sẽ thấy kết quả được show ra (do dài quá, nên tui chỉ chụp màn hình ở khúc cuối để thấy được Total):

Để thử như tui nói là khi rebuild mà không cần tắt rồi mở lại Revit, các bạn comment cái dòng code Append số Id, sau đó rebuild, rồi mở Add-in Manager như lúc nảy, rồi double click cái FilterDocumentCommand thì sẽ thấy kết quả chỉ show ra Total of Beam thôi:

2.2. Filter các element trong một View:

Cũng cái file Structural Sample Project, tui click vào cái Structural Plans – level 1 như hình:

Lại tự hỏi, thế level 1 này có bao nhiêu thanh rebar? Xem code nha:

Cũng trong cái file Command.cs, tui tạo một class mới tên là FilterInViewCommand (nhớ là class phải nằm trong namespace nha mí bạn).

Trong C#, một file .cs có thể chứa nhiều class

để filter trong một View nào đó, các bạn phải lấy được các ActiveView nha, mình mở view nào thì cái đó chính là ActiveView.

Sau đó, truyền cái Id của ActiveView này vào constructor của class FilteredElementCollector

Filter rebar bằng class Rebar, do đó ta sử dụng hàm OfClass().

Phải using using Autodesk.Revit.DB.Structure; mới sửa dụng được class Rebar

Thay vì phải dùng vòng lặp foreach để đếm element thì FilteredElementCollector có sẳn hàm ToElements() để ta chuyển ra cái List<Element>, rồi lấy thuộc tính Count của list này, khỏi phải đếm như lúc nảy.

Tạo chuổi kết quả gồm tên view hiện tại và số lượng rebar trong view đó.

Xong, build lại code. Lúc này do tui thêm một command mới, do đó tui phải load lại cái file DLL vào Addin Manager cho nó cập nhật lại. Các bạn chọn cái DLL hiện tại trong Addin Manager, click nút Remove, xong click nút Load rồi chọn lại cái DLL vừa mới rebuild là nó sẽ cập nhật lại thành 2 cái command:

Double click cái command FilterInViewCommand đi mấy bạn, kết quả là:

2.3. Filter element trong một tập các element được chọn:

Bây giờ cũng trong View này, cũng filter rebar, nhưng mà là tui dùng chuột, chọn đại một đống element, rồi filter rebar trong cái đống đó, lại xem code nha:

Lại tạo class mới là FilterInSetOfElementsCommand, vậy các bạn nhớ lát phải update cái file DLL trong Addin Manager nha.

Chú này xuất hiện nảy giờ, mà giờ mới dùng đây, class Selection này dùng để lấy các element mà các bạn dùng chuột quét chọn hay pick từng element.

Do tui sẽ quét chọn đại mà, nên tui sẽ có được một tập các element, không biết là bao nhiêu, nhưng thằng Selection này nó sẽ trả về một List<ElementId> các element đã được chọn bằng hàm GetElementIds(). Sau đó ta truyền cái list này vào constructor của class FilteredElementCollector.

Mấy cái khác thì như cũ. Rebuild code, các bạn update lại file DLL cho Addin Manager:

Xong, các bạn tắt cái Addin Manager đi để trở lại cái view hiện tại, sau đó các bạn dùng chuột quét chọn, chổ nào cũng được, miễn là chọn được element:

Chọn element xong, các bạn mở Addin Manager lên và chạy command FilterInSetOfElementsCommand, kết quả sẽ là:

Tired , mệt quá. Qua bài này, các bạn đã hiểu cách dùng Addin Manager cũng như class FilteredElementCollector, class này dùng nhiều lắm, nên các bạn thử làm cho quen. Hẹn ở các bạn ở các bài sau.  THANK-YOU

Sharing is caring!

Nhập môn Revit Add-in với C#
Cài đặt Visual Studio 2017 Community

Vincent Le

Tui là Lê Minh Đạt, tên tiếng anh là Vincent(do thích nhân vật Vincent Valentine, ai từng là fan của trò Final Fantasy VII thì sẽ biết nhân vật này, hehe). Đang tập tành làm một blogger viết về mảng lập trình, mong muốn được chia sẻ những gì đã học được, tích góp được trong 10 năm đi làm thợ code.

shares