Autodesk Inventor: Tạo Nút Nhấn Lênh Tùy Chỉnh Không Sử Dụng Template Add-In Và Chạy External Rule Từ Nút Nhấn

Bài viết này hướng dẫn cách viết Add-In của riêng bạn mà không cần sử dụng Template có sẵn của Inventor. Trong hướng dẫn này, chúng ta sẽ thiết lập mọi thứ theo cách thủ công. Hiển thị cho bạn tất cả các cài đặt. Điều đó có ưu điểm là bạn không bị giới hạn ở các cài đặt, phiên bản Inventor/Visual Studio hoặc ngôn ngữ lập trình.

Để không mất thời gian viết lại code VB.NET từ code iLogic. Tôi tận dụng các Rule iLogic đã có sau đó tạo các nút nhấn thêm vào Ribbon Tab để chạy các Rule này. Ở đây tôi sẽ chỉ tập trung vào việc tạo một Add-In. Công bằng mà nói, có lẽ bạn không cần thiết để biến quy tắc iLogic thành một nút của Add-In. Tôi đã tạo cho bạn một tiện ích bổ sung có thể tạo các nút cho quy tắc iLogic và bạn không cần phải viết một dòng mã nào cho nó. Thậm chí còn tiện hơn nếu bạn đang sử dụng Inventor 2023 trở lên, đây là chức năng được tích hợp sẵn.

Vậy tại sao nên tạo Add-Ins? Đây là vài lý do của tôi:

  • Code trở nên lớn và phức tạp đối với quy tắc iLogic
  • Cần hiển thị một cửa sổ trông bắt mắt cho người dùng (Ít nhất là trông đẹp hơn các cửa sổ mà chúng tôi có thể tạo bằng iLogic)
  • Bạn cần Inventor để phản ứng với các sự kiện (ngoài việc người dùng nhấn nút hoặc các sự kiện tích hợp từ iLogic).

Tạo một dự án Visual Studio

Tôi cho rằng bạn đã cài đặt Visual Studio. (Xin lưu ý rằng Visual Code là một IDE lập trình khác của Microsoft nhưng bạn không thể tạo các tiện ích bổ sung bằng nó.) Đây không phải là hướng dẫn về cách cài đặt Visual Studio nhưng có một số mẹo nếu bạn chưa cài đặt. Bạn có thể tải xuống tại đây: https://visualstudio.microsoft.com/downloads/ Đảm bảo bạn cài đặt mọi thứ để tạo các ứng dụng .Net trên máy tính để bàn. Đồng thời bao gồm cả framework .Net 4.7 trở lên.(Tùy thuộc vào phiên bản Inventor của bạn, bạn sẽ cần nó.)

Khởi động Visual Studio và tạo một dự án mới.

Đảm bảo rằng bạn chọn loại dự án với framewor .Net 4.7 trở lên. Ngoài ra, bạn có một số tùy chọn.

Trước hết, bạn có thể chọn ngôn ngữ C# hoặc VB.net. C# là ngôn ngữ .Net được sử dụng phổ biến nhất. Do đó, hầu hết thông tin trên internet đều là về C#. Đó có thể là một lợi thế nếu bạn đang tìm kiếm giải pháp lập trình. Nhưng nếu bạn gặp vấn đề với API của Inventor thì hầu hết các câu trả lời/ví dụ đều được viết bằng VB.net (hoặc VBA rất giống nhau). Trong hướng dẫn này, tôi sẽ tập trung vào VB.net vì bạn có thể tìm thấy nhiều thông tin liên quan hơn.

Lựa chọn thứ hai của bạn là loại công nghệ bạn muốn sử dụng trong các biểu mẫu của bạn. Bạn có các lựa chọn sau: Winforms, WPF hoặc không sử dụng. Winforms là công nghệ cũ nhất nhưng bạn sẽ tìm thấy rất nhiều thông tin về nó. (Nếu bạn tạo/sử dụng các điều khiển tùy chỉnh trong Winforms, bạn có thể gặp vấn đề khi cần ứng dụng của bạn phải là 64 bit. Điều này là ví dụ trong trường hợp bạn cũng bắt đầu làm việc với Vault API). Với các biểu mẫu WPF, bạn có thể làm nhiều hơn (nó linh hoạt hơn) nhưng chúng phức tạp hơn để tạo ra. Nếu bạn không muốn tạo bất kỳ biểu mẫu nào, bạn có thể tạo một “Class Library”. Điều này là cách đơn giản nhất để thiết lập. Trong hướng dẫn này, tôi tạo một thư viện lớp với công nghệ WPF.

Thiết lập Project

Xóa các tệp “app.config”, “MainWindow.xaml” và “Application.xaml” (Điều đó có thể có nghĩa là xóa tất cả các tệp trong trình khám phá giải pháp của bạn)

Đến mục “Project Properties”.

Đặt “Application type” thành “Class Library”.
Ngoài ra, ghi chú “Assembly name” ở đâu đó. Bạn sẽ cần nó sau trong tệp .addin.

Đặt “Build output path”. Có 4 vị trí sau được hỗ trợ. Bạn có thể chọn bất kỳ vị trí nào trong số chúng, phụ thuộc vào nhu cầu của add-in của bạn.

Add-in của bạn dành cho tất cả người dùng, không phụ thuộc vào phiên bản.
Windows 7/8.1/10 – %ALLUSERSPROFILE%\Autodesk\Inventor Addins\

Add-in của bạn dành cho tất cả người dùng, phụ thuộc vào phiên bản.
Windows 7/8.1/10 – %ALLUSERSPROFILE%\Autodesk\Inventor 20xx\Addins\

Add-in của bạn chỉ dành cho người dùng cụ thể, phụ thuộc vào phiên bản.
In Window 7/8.1/10 – %APPDATA%\Autodesk\Inventor 20xx\Addins\

Add-in của bạn chỉ dành cho người dùng cụ thể, không phụ thuộc vào phiên bản.
In Window 7/8.1/10 – %APPDATA%\Autodesk\ApplicationPlugins

Thay đổi start action để chạy Inventor.

Đi tới màn hình “Add reference”.

Duyệt và chọn các tệp sau:

C:\Program Files\Autodesk\Inventor [VERSION]\Bin\Public Assemblies\Autodesk.Inventor.Interop.dll

Các tệp DLL iLogic sau chỉ cần thiết nếu bạn định sử dụng chức năng iLogic.

C:\Program Files\Autodesk\Inventor [VERSION]\Bin\Autodesk.iLogic.Interfaces.dll
C:\Program Files\Autodesk\Inventor [VERSION]\Bin\Autodesk.iLogic.Runtime.dll

Mặc định, thuộc tính “Embedding Interop Types” của tham chiếu Interop của Inventor được đặt thành True. Điều này có thể dẫn đến kết quả không mong muốn. Bạn cần đặt giá trị này thành False.

GUID

Đối với các tệp tiếp theo, bạn sẽ cần một GUID. Đây là một chuỗi nhận dạng được sử dụng bởi Inventor. Nhiều trang web và công cụ có thể tạo nó cho bạn. Tôi thường sử dụng trang web này: https://www.guidgenerator.com/

Addin file

Đối với một tiện ích bổ sung, bạn cần ít nhất 2 tệp. Tệp đầu tiên là tệp .addin. Với tệp này, bạn cho Inventor biết rằng bạn muốn nó tải một Add-In. Thông tin trong tệp này được hiển thị trên màn hình tiện ích bổ sung trong Inventor.

Thêm một tệp mới vào dự án. Tên không quan trọng miễn là phần mở rộng là “.addin”. Thông thường, bạn đặt tên giống như tên của Add-In. Tôi sẽ sử dụng “MyILogicAddin.addin” cho tên này.

Thay đổi các thuộc tính tệp của tệp tiện ích bổ sung. Nó cần được sao chép vào đường dẫn đầu ra khi dự án được biên dịch.

Thêm mã XML sau vào tệp:

<Addin Type="Standard">
	<ClassId>{[GUID here]}</ClassId>
	<ClientId>{[GUID here]}</ClientId>
	<DisplayName>[Name]</DisplayName>
	<Description>[Description]</Description>
	<Assembly>[File name of the dll]</Assembly>	
	<SupportedSoftwareVersionGreaterThan>16..</SupportedSoftwareVersionGreaterThan>
</Addin>

Tệp .addin là một tệp XML. Các tệp XML là các tệp văn bản đơn giản thường được sử dụng để lưu các cài đặt. Tất cả các cài đặt được lưu trong các thẻ lồng nhau. Một thẻ luôn có dạng:

<[TagName] [Properties]>[TagValue]</ [TagName]>

Trong XML, thay thế văn bản giữa các dấu ngoặc vuông (và cũng loại bỏ các dấu ngoặc vuông). Hầu hết các thẻ tự giải thích nhưng các thẻ sau cần chú ý hơn.

Trong các thẻ “ClassId” và “ClientId”, bạn cần đặt GUID mà chúng ta đã tạo trước đó. Đảm bảo bạn loại bỏ các dấu ngoặc vuông nhưng để lại các dấu ngoặc nhọn.

Trong thẻ “Assembly”, đặt tên tệp của Add-In dll của bạn. (Bạn có thể tìm tên trong các thiết lập dự án Visual Studio của bạn. Đừng quên thêm phần mở rộng “.dll”)

Ở đây, tôi đã bỏ qua nhiều thẻ không cần thiết. Để xem danh sách đầy đủ, vui lòng xem tại đây: https://help.autodesk.com/view/INVNTOR/2022/ENU/?guid=GUID-52422162-1784-4E8F-B495-CDB7BE9987AB

Tạo Class StandardAddInServer

Tệp thứ hai mà mỗi Add-In cần là DLL (Dynamic-link library). Đây là tệp chứa mã đã được biên dịch. Trong tệp này, ít nhất phải có một lớp, được gọi là “StandardAddInServer”. Lớp này là điểm vào cho Inventor. Điều này có nghĩa là khi Inventor bắt đầu và đã đọc tệp .addin của bạn, sau đó nó sẽ tải DLL của bạn và bắt đầu tìm kiếm lớp này. Khi nó đã được tìm thấy, nó sẽ bắt đầu gọi các hàm trong lớp này.

Thêm một lớp vào dự án của bạn và đặt tên là “StandardAddInServer”.

Thêm mã sau vào tệp và thay đổi GUID:

Imports System.Runtime.InteropServices
Imports Inventor

' Change the GUID here and use the same as in the addin file!
<GuidAttribute("a7558ed7-8d2d-41bb-9295-4f3c9fe5d902"), ComVisible(True)>
Public Class StandardAddInServer
    Implements Inventor.ApplicationAddInServer

    Private _myButton As MyButton

    ''' <summary>
    '''     Invoked by Autodesk Inventor after creating the AddIn. 
    '''     AddIn should initialize within this call.
    ''' </summary>
    ''' <param name="AddInSiteObject">
    '''     Input argument that specifies the object, which provides 
    '''     access to the Autodesk Inventor Application object.
    ''' </param>
    ''' <param name="FirstTime">
    '''     The FirstTime flag, if True, indicates to the Addin that this is the 
    '''     first time it is being loaded and to take some specific action.
    ''' </param>
    Public Sub Activate(AddInSiteObject As ApplicationAddInSite, FirstTime As Boolean) Implements ApplicationAddInServer.Activate
        Try

            ' initialize the rule class
            _myButton = New MyButton(AddInSiteObject.Application)

        Catch ex As Exception

            ' Show a message if any thing goes wrong.
            MessageBox.Show(ex.Message)

        End Try
    End Sub

    ''' <summary>
    '''     Invoked by Autodesk Inventor to shut down the AddIn. 
    '''     AddIn should complete shutdown within this call.
    ''' </summary>
    Public Sub Deactivate() Implements ApplicationAddInServer.Deactivate

    End Sub

    ''' <summary>
    '''     Invoked by Autodesk Inventor in response to user requesting the execution 
    '''     of an AddIn-supplied command. AddIn must perform the command within this call.
    ''' </summary>
    Public Sub ExecuteCommand(CommandID As Integer) Implements ApplicationAddInServer.ExecuteCommand

    End Sub

    ''' <summary>
    '''     Gets the IUnknown of the object implemented inside the AddIn that supports AddIn-specific API.
    ''' </summary>
    Public ReadOnly Property Automation As Object Implements ApplicationAddInServer.Automation
        Get
            Throw New NotImplementedException()
        End Get
    End Property
End Class

Bạn thấy ở đây 4 hàm (Activate(…), Deactivate(), ExecuteCommand(…), Automation()). Chúng ta chỉ sẽ sử dụng hàm “Activate”. Những hàm khác cần có mặt nhưng không cần thực hiện bất kỳ công việc gì.

Trong hàm “Activate”, chúng tôi khởi tạo lớp Button. Hãy chú ý đến khối try/catch. Theo mặc định, Inventor sẽ không cảnh báo nếu có bất kỳ vấn đề gì xảy ra khi tải Add-In của bạn. Do đó, khối try/catch là cần thiết để bắt bất kỳ ngoại lệ nào mà mã của bạn có thể ném và xử lý ngoại lệ. Ở đây, tôi chỉ hiển thị một hộp thoại thông báo cho người dùng với thông tin cơ bản nhất từ ngoại lệ. (Trong mã sản xuất, bạn có thể xem xét viết tất cả thông tin ngoại lệ vào một nhật ký.) Điều này sẽ giúp bạn khi có điều gì đó không ổn và bạn cần tìm vấn đề. (Và đúng vậy sẽ luôn có điều gì đó không ổn và sau đó bạn cần tất cả thông tin mà bạn có thể lấy được!)

Button class

Lớp Button tạo một nút trong Inventor. Ở đây, chúng tôi cũng viết code được thực thi khi nút được nhấp. Tôi gọi lớp này là “MyButton” nhưng bạn có thể đặt bất cứ tên nào bạn muốn. Chỉ cần đảm bảo bạn sử dụng cùng một tên trong hàm “StandardAddInServer.Activate(…)”

Tạo một lớp “MyButton” và thêm code sau vào:

Imports Inventor
Public Class MyButton
    Private _inventor As Inventor.Application
    Private _settingsButton As ButtonDefinition
    Public Sub New(inventor As Inventor.Application)
        _inventor = inventor

        SetupButtonDefinition()
        AddButtonDefinitionToRibbon()
    End Sub

    Private Sub SetupButtonDefinition()

        Dim conDefs As ControlDefinitions = _inventor.CommandManager.ControlDefinitions
        _settingsButton = conDefs.AddButtonDefinition(
            "MyButton DisplayName",
            "MyButton InternalName",
            CommandTypesEnum.kEditMaskCmdType,
            Guid.NewGuid().ToString(),
            "MyButton DescriptionText",
            "MyButton ToolTipText")
        AddHandler _settingsButton.OnExecute, AddressOf MyButton_OnExecute

    End Sub

    Private Sub AddButtonDefinitionToRibbon()

        Dim ribbon As Ribbon = _inventor.UserInterfaceManager.Ribbons.Item("Assembly")
        Dim ribbonTab As RibbonTab = ribbon.RibbonTabs.Item("id_TabManage")
        Dim ribbonPanel As RibbonPanel = ribbonTab.RibbonPanels.Item("iLogic.RibbonPanel")
        ribbonPanel.CommandControls.AddButton(_settingsButton)

    End Sub

    Private Sub MyButton_OnExecute(Context As NameValueMap)

        Try

            Dim rule As New ThisRule()
            rule.ThisApplication = _inventor
            rule.Main()

        Catch ex As Exception

            MsgBox("Something went wrong while runing rule. Message: " & ex.Message)

        End Try
    End Sub
End Class

Khi lớp Button được khởi tạo, hàm “new” được gọi tự động. Ở đây, chúng ta gọi 2 hàm khác. Bạn có thể đã nhận thấy rằng những hàm đó rất ngắn. Chúng ngắn đến mức tôi có thể đã thêm chúng vào hàm “new”. Một trong những vấn đề khi tạo các chương trình lớn là đọc lại mã sau này. Tạo các hàm nhỏ với tên mô tả tốt giúp việc hiểu mã sau này dễ dàng hơn nhiều. Ngoài ra, điều này tăng cơ hội để bạn có thể sử dụng lại cùng mã cho mục đích khác.

Trong hàm “SetupButtonDefinition”, bạn có thể thay đổi “DisplayName”, “InternalName”, “DescriptionText” và “ToolTipText” của nút mà chúng ta đang tạo. Ở đó, chúng ta cũng xác định hàm nào sẽ được gọi “MyButton_OnExecute”.

Trong hàm “AddButtonDefinitionToRibbon”, chúng ta xác định nơi nút cần phải đặt. Chúng ta bắt đầu bằng cách chọn “Ribbon”. Tôi đã chọn “Ribbon” của “Part” nhưng bạn có thể chọn 1 trong số các tùy chọn sau: ZeroDoc, Part, Assembly, Drawing, Presentation, iFeatures và UnknownDocument. Sau đó, chúng ta cần chỉ định tên nội bộ của “RibbonTab” và “RibbonPanel”. Có quá nhiều tùy chọn để in ở đây nhưng quy tắc illogic sau sẽ in chúng trong nhật ký ilogic.

For Each ribbon As Ribbon In ThisApplication.UserInterfaceManager.Ribbons
    Logger.Info(vbTab & Ribbon.InternalName)
    For Each ribbonTab As RibbonTab In Ribbon.RibbonTabs
        Logger.Info(vbTab & vbTab & RibbonTab.DisplayName & " - " & RibbonTab.InternalName)
        For Each ribbonPanel As RibbonPanel In RibbonTab.RibbonPanels
            Logger.Info(vbTab & vbTab & vbTab & RibbonPanel.DisplayName & " - " & RibbonPanel.InternalName)
        Next
    Next
Next
Dim loggerWindow = ThisApplication.UserInterfaceManager.
	DockableWindows.
	Cast(Of DockableWindow).
	Where(Function(d) d.InternalName.Equals("ilogic.logwindow")).
	First()
loggerWindow.Visible = True

Trong trường hợp của tôi, nút của tôi chỉ hiển thị trong môi trường lắp ráp. Nút nằm trên tab “Manage” trong bảng điều khiển “iLogic”.

Khi được quản lý, hàm “MyButton_OnExecute” được gọi khi nút được nhấp. Ở đây, chúng tôi khởi tạo lớp “ThisRule” thực hiện công việc thực tế.

Abstract rule class

Chúng ta sẽ giả lập iLogic. Điều này có nghĩa là chúng ta cần một số chức năng illogic mặc định trong lớp quy tắc của chúng ta. Nếu bạn bất cứ lúc nào muốn tạo một nút thứ hai thì bạn có lẽ không muốn triển khai cùng một logic hai lần. (Ít nhất là tôi sẽ không thích, có lẽ tôi hơi lười…). Ngoài ra, tôi muốn có thể sao chép mã iLogic gốc vào tiện Add-In của tôi. Do đó, tôi chọn tạo một lớp trừu tượng và kế thừa tất cả các chức năng trong lớp cơ sở trong lớp Rule. Hiện tại, lớp cơ sở này rất nhỏ và chỉ có 2 thuộc tính. Trong hầu hết các trường hợp, việc chỉ cần truy cập vào thuộc tính iLogic “ThisApplication” và “ThisDoc” là đủ.

Tạo một lớp “AbstractRule” và thêm mã sau vào:

Imports Autodesk.iLogic.Interfaces
Imports Autodesk.iLogic.Runtime
Imports Inventor

Public MustInherit Class AbstractRule

    Public Property ThisApplication As Inventor.Application
    Public ReadOnly Property ThisDoc As ICadDoc
        Get
            Return New CadDoc(ThisApplication.ActiveDocument)
        End Get
    End Property

End Class

 Rule class

Đây là lớp sẽ chứa quy tắc iLogic. Trong ví dụ này, tôi sẽ có thể sao chép/dán một quy tắc iLogic từ Inventor vào lớp này. (Hãy nhớ rằng chúng ta chưa triển khai tất cả các chức năng/thuộc tính iLogic. Mã của bạn có thể không hoạt động nếu bạn sao chép một trong các quy tắc của mình. Trong trường hợp đó, bạn cần triển khai các hàm của mình để giả lập các chức năng iLogic)

Tạo một lớp “ThisRule” và thêm mã sau vào:

Imports Inventor

Public Class ThisRule
    Inherits AbstractRule


    Public Sub Main()

        ' Your iLogic code goes here.

    End Sub

End Class

Chú ý dòng 4, đây là nơi chúng tôi cho biết trình biên dịch kế thừa lớp cơ sở. Trong các quy tắc phức tạp hơn, bạn sẽ có nhiều hàm hơn hoặc thậm chí là một lớp hoàn chỉnh. Sau đó, bạn có thể cần thêm mã bên ngoài của hàm chính.

Để kết thúc hướng dẫn này với một Add-In hoạt động/hoạt động, chúng tôi sẽ thay thế mã lớp bằng quy tắc “ThisRule”. Lớp “ThisRule” sẽ như sau.

Imports Inventor

Public Class ThisRule
    Inherits AbstractRule

    Private searchText As String
    Private iLogicAddinGuid As String = "{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}"
    Private iLogicAddin As ApplicationAddIn = Nothing
    Private iLogicAutomation = Nothing
    Private outputFile As String = "c:\TEMP\seachedRules.txt"

    Sub Main()
        If (IO.File.Exists(outputFile)) Then
            IO.File.Delete(outputFile)
        End If
        searchText = InputBox("Text to search for", "Search")

        iLogicAddin = ThisApplication.ApplicationAddIns.ItemById(
            "{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}")
        iLogicAutomation = iLogicAddin.Automation
        Dim doc As AssemblyDocument = ThisDoc.Document

        searchDoc(doc)
        For Each refDoc As Document In doc.AllReferencedDocuments
            searchDoc(refDoc)
        Next

        Process.Start("notepad.exe", outputFile)
    End Sub

    Private Sub searchDoc(doc As Document)
        Dim rules = iLogicAutomation.Rules(doc)
        If (rules Is Nothing) Then Return
        For Each rule In rules
            Dim strReader As IO.StringReader = New IO.StringReader(rule.Text)
            Dim i As Integer = 1

            Do While (True)
                Dim line As String
                line = strReader.ReadLine()
                If line Is Nothing Then Exit Do
                If (line.ToUpper().Contains(searchText.ToUpper())) Then
                    Dim nl = System.Environment.NewLine
                    IO.File.AppendAllText(outputFile,
                        "Doc name : " & doc.DisplayName & nl &
                        "Rule name: " & rule.Name & nl &
                        "line " & i & "  : " & line.Trim() & nl & nl)
                End If
                i = i + 1
            Loop
        Next
    End Sub
End Class

Bây giờ nhấn “Run” (hoặc nhấn F5) trong Visual Studio và thử Add-In của bạn!

Tham khảo: http://www.hjalte.nl

Bình luận

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *