Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using Inventor API Objects In External Rules

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
MegaJerk
1338 Views, 7 Replies

Using Inventor API Objects In External Rules

Because I have been doing a lot of work on some heavy duty rules as of late, I decided that maybe it was time to stop using so much copy / paste, and set some often used functions up in my external rules. Our company does this for a few mathematical functions that require a number of Double inputs and spits out the resulting sum (as double), so I figured it wouldn't be so bad to just tack it onto the end of said existing external rule. 

The problem that I run into is that Inventor fails to recognize any of the calls to the Inventor Object Library! 

 

As of right now, I'm not importing anything into the rule, and I know for a fact that the rule is set up as VBOnly (as it's nested inside of a module with no sub main()). Is there something that I need to do, or some way that I need to make a call so that I can use these functions from anywhere in my internal / standard rules? 

 

The code that I would like to get working is as follows... 

 

Public Function GetPartGroup(docAP As Inventor.Document) As String

Dim PartLocation As String
PartLocation = "Nothing"

Dim RefFile As Inventor.FileDescriptor

If docAP.File.ReferencedFileDescriptors.Count > 0 Then
RefFile = docAP.File.ReferencedFileDescriptors.Item(1)

Select Case RefFile.LocationType
Case Inventor.LocationTypeEnum.kLibraryLocation
PartLocation = "Library Part"
Case Inventor.LocationTypeEnum.kWorkspaceLocation
PartLocation = "Local Part"
Case Inventor.LocationTypeEnum.kWorkgroupLocation
PartLocation = "Remote Part"
Case Inventor.LocationTypeEnum.kUnknownLocation
PartLocation = "Unknown Location"
End Select
Return PartLocation
End If

End Function

 

Btw, this will take a document and tell me if it's a library / standard / or some other variant type part. 

 

Thanks for any help. 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
7 REPLIES 7
Message 2 of 8
MegaJerk
in reply to: MegaJerk

Because I made this post right before I left work, I rushed a little and didn’t get the best information possible.

 

I have several external rules that work perfectly using the Inventor API. The thing that I am curious about at the moment is if you can have a function in an external rule that not only access the API but also returns a value to an internal rule.

 

Thanks for any help that you can provide on this subject. 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 3 of 8
MegaJerk
in reply to: MegaJerk

I have started to work my way through this problem but I would love some feedback from Autodesk / Anyone In the Know - on a strange issue that I'm encountering. 

 

First thing first, I have attached two files. One is called CustomFunctions.iLogicVb which is my external rule file, and the other .txt is the rule file that I will be using internally in Inventor. You can use the internal Rule file anywhere as it's not making any environmentally dependent calls. 

 

Basically, if I have a rule file that has a call for AddVbFile "YourFileNameHere.iLogicVB" but do NOT make any calls to the Inventor API (Application) from within that rule, it will not invoke the Inventor application for use inside of the external rule! 

 

This basically means that this fails with errors for any line containing an API call in the external rule ->> : 

 

AddVbFile "CustomFunctions.iLogicVb"

Dim ThisApp As Object
Dim Num1, Num2 As Integer

Num1 = 12
Num2 = 10

If Num1 > Num2 Then
MessageBox.Show("Num1 is larger!")
Else
MessageBox.Show("Num2 is larger!")
End If


'''''''''ThisApp = ThisApplication <-- Totally commented out!

 

 

 

While this succeeds... : 

 

AddVbFile "CustomFunctions.iLogicVb"

Dim ThisApp As Object
Dim Num1, Num2 As Integer

Num1 = 12
Num2 = 10

If Num1 > Num2 Then
MessageBox.Show("Num1 is larger!")
Else
MessageBox.Show("Num2 is larger!")
End If


ThisApp = ThisApplication ' <-- Totally not commented out!'

 

 

The external rule that I am currently using : 

 

' <IsStraightVb>True</IsStraightVb>
Public Module CustomFunctions Public Function ReturnString(OutPut As String) As String If OutPut = "" Then OutPut = "Nothing here" End If Return OutPut End Function Public Function ReturnDouble(OutPut As Double) As Double If OutPut = 0 Then OutPut = 1 End If Return OutPut End Function Public Function GetPartGroup(docAP As Inventor.Document) As String Dim PartLocation As String PartLocation = "Nothing" Dim RefFile As Inventor.FileDescriptor If docAP.File.ReferencedFileDescriptors.Count > 0 Then RefFile = docAP.File.ReferencedFileDescriptors.Item(1) Select Case RefFile.LocationType Case Inventor.LocationTypeEnum.kLibraryLocation PartLocation = "Library Part" Case Inventor.LocationTypeEnum.kWorkspaceLocation PartLocation = "Local Part" Case Inventor.LocationTypeEnum.kWorkgroupLocation PartLocation = "Remote Part" Case Inventor.LocationTypeEnum.kUnknownLocation PartLocation = "Unknown Location" End Select 'MsgBox("test" & PartLocation,vbOKOnly ) Return PartLocation End If End Function End Module

 

Is this intended behavior? Is there a to invoke the Inventor Application from the declaration section of the external rule, or must I make an arbitrary call inside of any internal rule that might want to use a function from my iLogicVb file? 

 

It's strange to me that so long as I invoke it somewhere in my internal rule, it will work, even if it's at the very very very end of the file. Being that I assume iLogic is compiled line by line (like anything else) it makes me curious as to why it would be alright with having the Application assigned to something AFTER the calls to the external rule, rather than before. 

 

I hope that someone can help me with this problem. 

 

Thank you for your time. 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 4 of 8

Hi  MegaJerk,

 

Just giving this a bump. I'm interested in using this strategy also.

 

I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com

Message 5 of 8
MjDeck
in reply to: Curtis_Waguespack

MegaJerk,

You have found the solution.  To provide maximum flexibility in the rule code and to gain a bit of performance, the Inventor API is not referenced unless you explicitly ask for it.  And when you add an external rule with AddVbFile (or an internal one with AddVbRule), the API reference has to be in the main rule.  Often you would use the API in the main rule to get an object to send to the added rule.

 Rules are compiled completely before they are run.  They are run line-by-line, but not interpreted line-by-line.  So a call to the Inventor API anywhere in the main rule will cause the API to be loaded, and it will be available to the added rule..


Mike Deck
Software Developer
Autodesk, Inc.

Message 6 of 8
MegaJerk
in reply to: MjDeck

Alrighty! So for anyone else that has this question, I suppose it could be summarized by saying that: 

 

1: Using an external rule (module / function / StraightVB combo) to return normal VB datatypes (integers, strings, longs, etc. etc.) is fine, no matter what your internal rule is doing, so long as the function arguments are also of the normal VB datatypes. 

 

EX: Internal Rule -

AddVbFile "MathMagic.iLogicVb"

Dim Num1, Num2, Num3 As Integer

Num1 = 12
Num2 = 10 
Num3 = LargestNumber(Num1, Num2)

Msgbox(Num3)

 External Rule (Set to StraightVB Only in options) : 

 

Public Module MathMagic
Public Function LargestNumber(Num1 As Integer, Num2 As Integer) As Integer
     If Num1 >= Num2 Then 
       Return Num1
       Else
       Return Num2
     End If
End Function
End Module 

 Results in a message box that reads : 12 

 

 

2: Using an external rule (same as above) to return normal VB datatypes, but that require Inventor API specific data types, or that use Inventor API specific objects inside of their block, must be initialized first by making a call to the Inventor API inside of the internal rule that you want the values to be returned to. 

 

EX: Internal Rule - 

AddVbFile "MathMagic.iLogicVb"

Dim oDoc As Inventor.Document '<- Inventor API call
Dim oFileName As String

oDoc = ThisApplication.ActiveDocument

oFileName = MyFileName(oDoc)

Msgbox(oFileName)

  External Rule (Set to StraightVB Only in options) :

 

Public Module MathMagic
Public Function MyFileName(SentDoc As Inventor.Document)As String
   Return SentDoc.FullFileName    
End Function
End Module 

 

Results in a message box that reads : "DriveLetter:\Path\FileName.ipt" 

 

3: Mixing and matching your VB datatype functions with Inventor API based functions will result in bad things happening because occasionally you will need to make a call in a rule that doesn't need to access the API to a function that doesn't use the API. At that point you will receive the problems that I did above, and no one wants you to go through all of that. 

EX: Internal Rule -

 

AddVbFile "MathMagic.iLogicVb"

Dim Num1, Num2, Num3 As Integer

Num1 = 12
Num2 = 10 
Num3 = LargestNumber(Num1, Num2)

Msgbox(Num3)

 

External Rule : (Note the mixing of both types of our previous external rules example) 

 

 

Public Module MathMagic
Public Function LargestNumber(Num1 As Integer, Num2 As Integer) As Integer
     If Num1 >= Num2 Then 
       Return Num1
       Else
       Return Num2
     End If
End Function

Public Function MyFileName(SentDoc As Inventor.Document)As String
    Return SentDoc.FullFileName    
End Function

End Module 

 

Results in errors! Because the API was not initialized in the internal rule like it was in Example 2. Even though you don't need it, the external rule does need it despite the fact that you're not even calling on the functions that require it. 


Biggest lesson learned? Keep your fancy pants functions that use the API in a separate file than the your mundane typical functions that you'll be using for regular work. 

Thanks a lot : to Curtis W for the inital help,  and MjDeck who confirmed all things questionable!

 

 



 

 

 

 

 

 

 

 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 7 of 8
rjay75
in reply to: MegaJerk

I see this is still the case. Thanks for this explanation. You just rescued me after two days of trying to figure out why some code would only work in a few rules. Until your explanation it looked complete random as to when it would and wouldn't work.

Message 8 of 8
MegaJerk
in reply to: rjay75

I’m glad that this topic was able to help you sort out your problem. Recently I found myself running into this issue again, and was forced to find some sort of workaround. I’m not certain that it’s the most elegant way of achieving the results that I want, but it does what it should do, so it’s a start.

Feel free to give me any feedback on this method.

Here’s an example of a little External Rule that contains two subs, one of which will access the Inventor Application, and one that does only math. 

 

 

Imports System.Windows.Forms
Imports Inventor

Public Module inventorApp
Public Dim ThisApplication As Object
Sub New ()
Try
ThisApplication = GetObject(, "Inventor.Application")
Catch ex As Exception
MessageBox.Show("Inventor isn't running!?", "Well this is confusing...")
End Try
End Sub
End Module

Public Module myModule
Public Sub testApplicationSub ()
MessageBox.Show(ThisApplication.Documents.Count,"testApplicationSub")
End Sub

Public Function testNumberSub(x As Double, y As Double)
MessageBox.Show(x + y, "testNumberSub")
End Function
End Module


In your main rule, you can call one or the other now without throwing an error because the Application is loaded via the External Rule’s public module.

 

AddVbFile "inventorApp.iLogicVb"

Call testNumberSub(100,0)
'Call testApplicationSub()

 

 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report