Control appearance of named geometry with model states and/or iLogic -- possible?

Control appearance of named geometry with model states and/or iLogic -- possible?

claudio.ibarra
Advocate Advocate
812 Views
8 Replies
Message 1 of 9

Control appearance of named geometry with model states and/or iLogic -- possible?

claudio.ibarra
Advocate
Advocate

The question is pretty much in the title. Let's say you have a simple cylinder, and you want the top face and the outside surface to have a color override in some model states, but not in others. The other faces never have any override. Does it help to name the faces? Can it be done by iLogic looking for a model state change and then setting those faces accordingly? Can it be done in the model state excel table at all? 

 

Difficulty level: Inventor 2023. 

 

Is this an easy non-issue in Inventor 2024 with the finishing feature? 

0 Likes
Accepted solutions (1)
813 Views
8 Replies
Replies (8)
Message 2 of 9

WCrihfield
Mentor
Mentor

Hi @claudio.ibarra.  Colors and Appearances are managed by the DVRs (DesignViewRepresentations), not the ModelStates, but you do still need to be editing either the 'factory' document, or have the MemberEditScope set to all members, if more than just the original ModelState is present, or the change may not be allowed (ModelState members are ReadOnly).  I have not used the new Finish features that many times yet, but yes, that does appear to be a good way to control appearance with a feature, and since it is a Feature, the ModelState would then be involved, primarily to control whether the feature is suppressed or not, and any parameter values involved, but I am honestly not sure about the actual color/appearance itself.  I know that if you just use the finish feature to apply an appearance, the name of that appearance is stored in a 'Finish Parameter', and since parameters are under the control of the ModelStates, it would seem like it could be controlled from the ModelStateTable.

Edit:  The parameters created by a Finish feature appear to be 'greyed out' when viewed from the Parameters dialog box, so I am not sure if their values can be changed independently from editing the feature first.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 9

WCrihfield
Mentor
Mentor

I just did a couple more tests related to this, and in a Part with 2 ModelStates, and 1 FinishFeature.  I am able to change the 'appearance' by changing the FinishFeature.Appearance property's value to a different Asset object.  But even though I can get the parameter associated with that feature by looping through FinishFeature.Parameters (indexed by Integer only), access is denied to change that parameters value.  I even tried to manually enter 'edit mode' of that feature, then open the parameters dialog, just to see if we could change the parameter directly while the feature was in that state, but it will not allow both dialogs open at the same time, and the FinishFeature object does not have an Edit/ExitEdit type methods to enable that process anyways.  So in conclusion, if using a FinishFeature, we can only change the Appearance by editing the FinishFeature, not by changing a parameter value directly.  And while MembeEditScope was set to active member only, and I edited the FinishFeature to a different appearance while different ModelStates were active, those individual ModelStates did not have a different value for that Finish Parameter, and simply switching back and forth between the two ModelStates afterwards did not change their appearance.  I tried the same thing with DVRs...I had two of them (Primary and View1), edited the FinishFeature's appearance differently while the two different DVR's were active, and afterwards, switching between the two DVR's did not change their appearance.  And when opening the ModelStateTable in Excel, those Finish Parameters were not even listed in the table.  So, I believe the long standing route of just using different DVR's, without FinishFeatures, is the way to go here.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 9

claudio.ibarra
Advocate
Advocate

I may have cobbled together a working solution heavily inspired by ("stealing from") this post.

 

This is what I did:

  1. I toggled to factory scope, and added a true/false parameter called "PAINT" (I'm not sure if I needed to change the factory scope or not--- I'm still new to how model states behave with adding/removing parameters).
  2. I went to one member and changed the value to "false", so it would appear in the Excel table.
  3. I set the remainder of the true/false values for every model state.
  4. I added entity names to the surfaces, like "TOP_FACE", "OUTSIDE_DIAMETER"
  5. I added an iLogic rule (based on the above linked post)
    1. 'set this rule to watch this parameter
      oTrigger = PAINT
      
      Dim oDoc As PartDocument 
      oDoc = ThisApplication.ActiveDocument
      
      Dim oEntities As Object 
      oEntities = iLogicVb.Automation.GetNamedEntities(oDoc)
      
      'get the named face
      Dim oFace1 As Face 
      Dim oFace2 As Face
      
      oFace1 = oEntities.FindEntity("TOP_FACE")
      oFace2 = oEntities.FindEntity("OUTSIDE_DIAMETER")
      
      'set the color if paramter is true
      If Parameter("PAINT") = True Then
      	oFace1.Appearance = oDoc.Assets.Item("*Blue")
      	oFace2.Appearance = oDoc.Assets.Item("*Blue")
      Else
      	oFace1.Appearance = oDoc.ActiveAppearance
      	oFace2.Appearance = oDoc.ActiveAppearance
      End If 
  6. I set that rule to the event trigger for any model state change. 

 

It appears to work. Some model states turn blue, and others don't. 

0 Likes
Message 5 of 9

WCrihfield
Mentor
Mentor
Accepted solution

Hi @claudio.ibarra.  I just got back after the holiday weekend.  I am glad to hear that you now have a code solution that is working OK for you.  However, I would like to add a couple more tips about that code that may help make it even better.  Since that code is going to be used as an internal rule (instead of an external rule), then I would suggest that you switch from using the 'ThisApplication.ActiveDocument' phrase, to using the 'ThisDoc.Document' phrase, because that second term was designed specifically for representing the document that the rule is saved within.  That first term just points to whatever document happens to be 'active' (visibly open/editing on your screen) at the moment the rule is ran.  That is OK when you have that part visibly open for editing on your screen at the time, but if an assembly, containing that part, is the 'active' document, and that rule gets triggered to run, it will be trying to act upon the assembly, instead of the part, if the rule is looking at ThisApplication.ActiveDocument.

And if you switch to using the 'ThisDoc.Document' phrase, you might as well also switch from using 'iLogicVb.Automation.GetNamedEntities()', to using 'ThisDoc.NamedEntities', because that phrase is already referring to the same, local document.  It's just a slightly simpler way to do the same thing in situations like this.  I also generally prefer to use the 'TryGetEntity' method, instead of the 'FindEntity' method, just because it is a newer method that will not throw an error if the named entity is not found.  However, when using that, I usually also include an additional line of code that just checks to make sure that the face was actually found, before proceeding.  If this were a longer routine, I might also suggest that you get the two different Asset objects (*Blue & active one) to 2 variables ahead of time, instead of retrieving them both twice (once for each line setting it as a value), but that is just a very minor performance related detail.

I attached a text file containing a slightly edited copy of that last code you posted, which includes the changes I mentioned in my comments above, just in case you may want to review it.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 9

claudio.ibarra
Advocate
Advocate

Thank you so much for the feedback!

 

If I wanted to make this an external rule, would I switch back the This.Document and ThisDoc.NamedEntities?

 

Now that it's working for one part, I wonder if it's possible to sort of "generalize" it and make it into an external rule that looks for specific words in named geometries.

Would it be theoretically possible to make the rule, when run, iterate through ALL named entities in the active part, and act on a keyword in the name? So any surface with "paint" in the name becomes blue, and any surface with "machined" in the name gets another surface, and the rest get the standard surface?

0 Likes
Message 7 of 9

WCrihfield
Mentor
Mentor

Hi @claudio.ibarra.  I'm on my way out for the day, but yes, it would still be OK to use the 'ThisDoc.Document' term in an external rule.  It is a dynamic phrase, and acts differently in different situations (with very little public documentation about how it works differently in those different situations though).  If the external rule is triggered to run by an event on the 'This Document' tab of the Event Triggers dialog, then the 'ThisDoc.Document' phrase should be pointing to that document that the event was fired from.  Otherwise, it would normally point to whichever document was 'active' when the rule first started, when used in an external rule, with no other special circumstances.  I would be tempted to use the 'iLogicVb.Automation.GetNamedEntities()' method though in an external rule, instead of 'ThisDoc.NamedEntities', and use the Document returned by that 'ThisDoc.Document' phrase as input.  Maybe not necessary though.

Yes, you could definitely iterate through all objects within the 'NamedEntities' collection, but it may be a bit odd, because NamedEntities.Entities is a NameValueMap.  You could effectively use 'For Each', but you may be able to use 'For i As Integer = 1 To oMap.Count' type of loop starter.  Obviously the Name would be a String, but the Value is just a generic Object, so you would need to check the Type of each Value to know how to handle it.  Once you know its Type, you can declare a variable of that Type, and set the Value as its value, then work from there within the loop.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 9

claudio.ibarra
Advocate
Advocate

Your explanation of iterating through named entities is a little beyond my ability level to implement, but I can make do with occasionally needing to do this with a few surfaces with the rule living within the part file for now. Thank you!

0 Likes
Message 9 of 9

WCrihfield
Mentor
Mentor

Hi @claudio.ibarra.  Here is an example iLogic rule you can test with and modify as needed for the task you mentioned in the last part of Message 6 above.  You will need to edit the names of the two appearances (lines 16 & 17), to the real names of those appearances.  Also, if there are no local (within the part itself, not just an external library) copies those two special appearances, then local copies will need to be created, either manually, or by adding additional code to the rule to copy them from a specific external library to the part, before you will be able to assign those appearances to faces in the part.

Sub Main
	'make sure this is a Part (not an assembly, drawing, or other)
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then Return
	Dim oPDoc As PartDocument = ThisDoc.Document
	'get the Named Entities (if any)
	Dim oNEs As NamedEntities = iLogicVb.Automation.GetNamedEntities(oPDoc)
	If oNEs Is Nothing OrElse oNEs.Entities.Count = 0 Then
		Logger.Info("No NamedEntities found in this part, so exiting routine.")
		Return
	End If
	Dim oNVM As NameValueMap = oNEs.Entities
	'define the appearances you want to use
	Dim oAppearances As AssetsEnumerator = oPDoc.AppearanceAssets
	Dim oActiveAppearance As Asset = oPDoc.ActiveAppearance
	'<<<< EDIT FOLLOWING APPEARANCE NAMES AS NEEDED >>>>
	Dim oPaintedAppearance As Asset = oAppearances.Item("Painted")
	Dim oMachinedAppearance As Asset = oAppearances.Item("Machined")
	'iterate though the NameValueMap of named entities by Index #
	For i As Integer = 1 To oNVM.Count
		Dim sName As String = oNVM.Name(i) 'the name assigned to the entity
		Dim oEntity As Object = oNVM.Value(sName) 'the named entity
		If TypeOf oEntity Is Face Then 'check Type of entity (could be Face, Edge, or Vertex)
			Dim oFace As Face = oEntity 'make Face Type vairable, and set it as its value
			'check name for keywords, then set appropriate appearance
			If sName.Contains("paint") Then
				oFace.Appearance = oPaintedAppearance
			ElseIf sName.Contains("machined") Then
				oFace.Appearance = oMachinedAppearance
			Else
				oFace.Appearance = oActiveAppearance
			End If
		End If
	Next 'i
	oPDoc.Update2(True)
	'If oPDoc.Dirty Then oPDoc.Save
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes