Parameter manipulation - best practice?

Parameter manipulation - best practice?

llorden4
Collaborator Collaborator
483 Views
6 Replies
Message 1 of 7

Parameter manipulation - best practice?

llorden4
Collaborator
Collaborator

I'm looking for your experience with modifying parameters, best practices for results.

 

Looking at this sample iLogic code...

Rise = 1 in
'or
Parameter("Rise") = 1 in

 

I like using the line 1 example as the Parameter name will have a blue text color when there's a matching Parameter found, a great way to make sure I didn't do a typo when typing out the line.

 

However, iLogic steers me to using the line 3 example.  I'm not sure if this performes better while the parameter is being utilized within the iLogic rule, but the Parameter name is treated as a string here and there's no color reaction to indicate to me whether or not I've successfully typed the variable name correctly until the rule runs and comes across that particular line.

 

Your personal thoughts on a best practice and why?

Autodesk Inventor Certified Professional
Accepted solutions (1)
484 Views
6 Replies
Replies (6)
Message 2 of 7

WCrihfield
Mentor
Mentor

Hi @llorden4.  This is a good, and interesting topic.  For me, which one I would prefer to use usually depends on where and how I am planning on using them.  Obviously we can only use the line 1 example within an 'internal' iLogic rule, while the example on line 3 can be used in either an internal or external iLogic rule.  So, the Line 3 example is more flexible, if your internal rule may later need to be converted into an external rule.  They do both act differently though, and knowing how they act differently is key to their proper use, and knowing when to use them for best results.

 

The primary 2 advantages to using the example on line 1, is:  1)  The compactness of the code (just the name of the parameter (if the parameter's name is short) 2)  The automatic triggering of the rule to run when the value of that one specific parameter changes.

The first advantage mentioned, only an advantage if the name of the parameter is not very long.  I guess you could count the parameter name turning blue, in recognition an advantage, but I never really saw it that way myself.  The second advantage is only an advantage if you 'really' wanted the rule to be triggered every time 'every' parameter name being used within that rule changes.  We do have a setting to turn that triggering off, but for the whole rule, not just for specific parameter names.  

 

One thing that both have in common is the ability to directly Get/Set the value in 'document units', instead of in 'database units'.  However, this so called advantage can also be confusing, because we are talking about 'document units' not actually the parameter's own units.  For example, if your document units were Inches, but this parameter was set to some other units, such as feet, yards, miles, millimeters, etcetera, then units conversions would still be needed, because the parameter's true value, in its own units is neither document units nor database units.  At this point we practically have to create our own custom Functions to get/set a parameter's value in the parameter's own units, when they are different than both the document units and database units.

 

One think to always keep in mind when working with the Line 1 example codes, is that you will need to use the:

RuleParametersOutput

This is apparently the name of a Sub routine that has been defined within the 'ThisRule' Partial Class that gets created automatically for us in the background within our iLogic rules.  This is apparently needed at intervals within any longer codes using those blue, unquoted parameter names, in order to push any changed values to the model, because otherwise this action will not happen until after the rule has finished.  In some longer rule cases, this 'update' needs to happen before the end of the rule, because other calculations are being done with those 'changes' in mind, but those changes have not taken place yet, unless you have used that Sub to push those changes to the model.

 

On the other hand, when using the Line 3 example codes, we have the IParamDynamic object (represented by the 'Parameter' iLogic Rule Object), and all its Properties, such as UpdateAfterChange.  We can set this to True near the beginning of our rule, then when any iLogic snippet code starting with 'Parameter' is used to change a parameter value anywhere in that rule, after that point, it will cause the model to update, which is nice (if the update does not take a long time to process).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 7

WCrihfield
Mentor
Mentor

Another difference between those two ways of accessing a parameter's value has to do with document reference.  When using the blue, unquoted parameter names within an internal iLogic rule, you can know with great confidence that those are being directly referenced from the document in which the internal iLogic rule they are being used within, is itself saved within.  (If the rule is saved within a document, then those blue, unquoted parameters are linked to the document that the rule is saved within.)

 

On the other hand, when using:

Parameter("MyParamName")

How confident are you about which document that is 'pointing to' or 'pulling the value from' or 'focused on'?  Since this line of code can be used in either an internal or external rule, will it 'always' be pointing to the same document, in both cases?  What are the rules or design intent that dictate which document this line of code will be focused on in all the different scenarios you can come up with, such as when the rule gets ran remotely by an event or RunRule type of code?  All good points to consider, and something that I have been asking for 'official', publicly available documentation for the past several years.

 

Sure it does give us an extended variation: 

IParamDynamic.Value Property (Object, String) 

Where it allows us to specify the 'name' of either an assembly component, or a document, with the optional first argument called "componentOrDocName", but then it does not really explain what this means in good enough detail either.  When working with an assembly component, that is simple enough, because it just uses ComponentOccurrence.Name property value.  But what about when you have a component with the same exact name in two completely different sub assemblies, or one is in the top level, while one is in a sub assembly...which one will it point to, and which one will get ignored?  When you want to work with a referenced document, it does not tell us this, but that document must be within the 'Document.AllReferencedDocuments' collection of the document that this line of code would have normally targeted (the 'local' or 'active' document).  It also tells us to use the Document's 'Name' property, which we both know does not seem to exist (unless it is 'hidden' & private).  What we do have is DisplayName, FullDocumentNameFullFileName, & InternalName.  So which is it?  Well, we have learned on our own that DisplayName 'sometimes' works.  But that is a Read/Write property, sometimes including file extension, sometimes not, with no good explanation when/why.  That's a lot of unknown, undocumented details in my opinion, so I use Parameter() snippets fairly sparingly, when I know that document reference is not going to be an issue, even if they get ran remotely.

I do still use both of then quite a bit, but am just more careful with them than I used to be, due to all the stuff I have seen in the forums over the years, and due to a few of my own odd situations I had to figure out.

 

Since for years now I have tried to minimize 'local' / internal iLogic rules/forms, in favor of external iLogic rules & global iLogic Forms, one interesting way I still take advantage of the blue, unquoted parameter names for is to simply trigger a super simple internal iLogic rule to run, where that internal iLogic rule only has 2 lines of code, and is only used to run an external iLogic rule to run when that specific parameter's value changes.  Within this simple internal iLogic rule is something like the following:

oTrigger = Profile_Height
iLogicVb.Automation.RunExternalRule(ThisDoc.Document, "Manage Profile_Height Changes")

or maybe like this, if I know the 'target' rule is using the RuleArguments tool to look for 'input' data:

oTrigger = Profile_Height
Dim oArgs As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
oArgs.Add("Document", ThisDoc.Document)
iLogicVb.Automation.RunExternalRuleWithArguments(ThisDoc.Document, _
"Manage Profile_Height Changes", oArgs)

This way, if the value of that parameter changes, it will trigger this super simplistic internal iLgoic rule to run, which will only run my external iLogic rule to run, and the external rule is using the 'ThisDoc' term, instead of ThisApplication.ActiveDocument, so that it will be working with the same document that the 'RunRule' code meant for it to be working with, and contains all the 'real' code for dealing with this change.  And is most likely using either Inventor API route of accessing the Parameter object, or is taking advantage of the StandardObjectFactory Class and its Create Method to get an IStandardObjectProvider Interface that will remain focused on the Document object that I supplied as 'input' into the Create method.  Then I can use the iLogic snippets with more security about which Document they will remain focused on.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 7

llorden4
Collaborator
Collaborator

Interesting, I've been avoiding the external rule route just to avoid dealing with those very undocumented issues you outlined.  I guess I need to delve into that realm to better understand why you prefer it.

Autodesk Inventor Certified Professional
0 Likes
Message 5 of 7

WCrihfield
Mentor
Mentor

Everyone has their reasons for doing things the way they do, but my main reason for wanting to keep as much of my code 'external' is because I want to only have to edit it once, in one place, and be done with it.  We do not have Vault yet, have a very large storage area full of CAD / Engineering related data, all under one main 'project' area.  We do have some types of things that are pretty common, but just different enough to keep them in 'normal'/'general' file system area, rather than Content Center or iPart folders, because we want to maintain full control over each individual file, and keep them in our standard file system layout.  And since I have been into iLogic / Inventor API for several years now, and have many hundreds of unique rules & forms, if I had to edit them within individual Inventor files, I would never get done with it.  I can edit one external rule, instead of having to edit potentially hundreds of Inventor files with internal iLogic rules in them that are 'mostly' identical, or very similar.  And if I want to change a form, I can change the one global one, instead of tens or hundreds of internal ones.

So, not necessarily just due to Parameter related issues.

However, since making that move to external rules, and figuring some of this stuff out, I have grown to rely more and more on the Inventor API code way of doing most things, instead of the iLogic shortcut snippets ways.  There is just more inherent security in seemingly better documentation, in-line document object references, and actual objects.  Where most iLogic tools generally just ask for names (String) of documents or objects, the Inventor API generally asks for the actual objects themselves, which eliminates confusion/uncertainty.

I know for sure which document I am reading/writing from/to in this Inventor API code:

Dim oADoc As AssemblyDocument = ThisApplication.Documents.Open("C:\Temp\MyAssembly.iam", False)
oADoc.ComponentDefinition.Parameters.UserParameters.Item("Height").Expression = "26 in"

...even though it may take a little more code to get there. 😉

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 7

llorden4
Collaborator
Collaborator

I have the exact same environment, no vault but have taken the opposite route with internal codes to maintain status with projects that have been completed.  If I used external rules then a part made a specific way "x" years ago might be updated to a new standard with an external and maintained rule to where the part may no longer turnout the same if accidentaly refreshed.   Like you said, we each have our reasons and I can better understand your choices.  Thanks for sharing that insight.

 

I welcome other viewpoints, for anyone else so inclined to share.

Autodesk Inventor Certified Professional
Message 7 of 7

llorden4
Collaborator
Collaborator
Accepted solution

Having a bit more experience behind me now, I thought I'd revisit this to share some lessons learned.  I'll start by sharing that my coding experience is still very much internal with the file being utilized, so this shared experience will only apply (with certainty) to local programming only.

 

I found there really is no difference on performance between the line 1 or line 3 example I originally posted; both work equally as well.

HOWEVER...

You are limited to only one edit, any additional edits to the same parameter within that rule will cause "all" changes to be lost.

For example:  If a Parameter named "Rise" had a current value of 2 and the rule was:

Rise = 1

Then the parameter would correctly update with the new value of 1. 

 

In the example below, if the current value was 4.5 and this rule was run:

If Rise > 4 Then Rise = 5
If Rise < 6 Then Rise = 5

Then the parameter would keep it's original value of 4.5 and the code to change the value to 5 would simply be lost. 

 

 

To overcome this, the best practice becomes to convert these to a Variable, manage the Variable while within the rule, and when completed store that variable value to the Parameter.   For example:

Dim oRise As Double = Rise
If oRise > 4 Then oRise = 5
If oRise < 6 Then oRise = 5
Rise = oRise 'can also use Parameter("Rise") = oRise

The result here would successfully change the Parameters value to 5.

 

 

Understanding this workflow has driven my routines to now first load all the parameters I work with to Variables within the rule and update the Parameters on exit, this way I don't accidentally create a condition where an update might be voided as code gets created, updated, or expanded to over time.

 

Managing unit values is another topic I won't get into here, but there's another big lesson to be learned there for anyone starting their learning journey.  I hope someone else finds this topic useful.

Autodesk Inventor Certified Professional
0 Likes