Switch between representations

Switch between representations

sebastien.forman
Advocate Advocate
1,369 Views
14 Replies
Message 1 of 15

Switch between representations

sebastien.forman
Advocate
Advocate

Hi all,

 

I would like to make a short cut for switch between representation, just select assembly or part in view, tap on short cut, and next representation is coming.

 

I have find the code for making a representation with the name directly.

But i i don't know how i  can find the next representation name.

Public Sub changeRepresentation()

'    Dim oDef As AssemblyComponentDefinition
'    Set oDef = ThisApplication.ActiveDocument.ComponentDefinition
'    Dim copyDesign As DesignViewRepresentations
'    Set copyDesign = oDef.RepresentationsManager.DesignViewRepresentations()
'
'    Dim doc As AssemblyDocument
'    Set doc = ThisApplication.ActiveDocument
'    Dim rm As RepresentationsManager
'    Set rm = doc.ComponentDefinition.RepresentationsManager
'    Dim prs As PositionalRepresentations
'    Set prs = rm.PositionalRepresentations
'
'     Dim index As Integer
'    For index = 1 To prs.Count
'        If rm.ActivePositionalRepresentation Is prs(index) _
'            Then Exit For
'    Next
'
'    If index < copyDesign.Count Then
'    index = index + 1
'    Else
'    index = 0
'    End If
'
    Dim oDoc As Document
    Set oDoc = ThisApplication.ActiveDocument
    Dim oObj As Object
    Set oObj = oDoc.SelectSet.Item(1) 'item selected in view.

    Call oObj.SetDesignViewRepresentation("Par défaut", , True) 'put name of representation here
    'Call oObj.SetLevelOfDetailRepresentation("ilogic")
    'Debug.Print oObj.ActiveDesignViewRepresentation
    'Debug.Print oObj.ActiveLevelOfDetailRepresentation

End Sub

The comment part is a  code who find the name of representations of the main assembly, but not selected assembly...

 

 

Thank you for your help

 

Sébastien Forman

0 Likes
1,370 Views
14 Replies
Replies (14)
Message 2 of 15

sebastien.forman
Advocate
Advocate

hi, 

finally i found a working code.

Just need to select an object in view and launch this script, it will take the next Representation.

Here it is:

Public Sub changeRepresentation()
Dim doc As AssemblyDocument
Set doc = ThisApplication.ActiveDocument
Dim oAsmCompDef As ComponentDefinition
Set oAsmCompDef = doc.ComponentDefinition
Dim oCompOcc As Inventor.ComponentOccurrence
Dim sSet As selectset
Set sSet = ThisApplication.ActiveDocument.selectset

For Each oCompOcc In sSet
    If oCompOcc.visible = True Then
        On Error Resume Next
            Dim oDesignVR As DesignViewRepresentations
            Set oDesignVR = oCompOcc.Definition.RepresentationsManager.DesignViewRepresentations
            Dim iNumberOfRep As Integer
            iNumberOfRep = oDesignVR.Count
            Dim oActiveRep As DesignViewRepresentation
            Set oActiveRep = oCompOcc.Definition.RepresentationsManager.ActiveDesignViewRepresentation
            Dim i As Integer
            For i = 1 To iNumberOfRep
                If oDesignVR(i).name = oActiveRep.name Then
                    If i = iNumberOfRep Then
                        i = 1
                    Else
                        i = i + 1
                    End If
                    Call oDesignVR(i).Activate
                    Call oCompOcc.SetDesignViewRepresentation(oDesignVR(i).name, , False)
                    i = iNumberOfRep
                End If
            Next
    End If
Next
End Sub

 

 

0 Likes
Message 3 of 15

sebastien.forman
Advocate
Advocate

in fact, there is a strange behavior, the RepresentationManager does not have the good value of the ActiveDesignViewRepresentation.
Is this a mishandling on my part, or an API bug?

Try to select 3 iam with "3 internal representations" and execute the script. The code does not work.

If I only select an iam with "3 internal representations" the code works.

Public Sub RepresentationSwitchNext()
Dim doc As AssemblyDocument
Set doc = ThisApplication.ActiveDocument
Dim oAsmCompDef As ComponentDefinition
Set oAsmCompDef = doc.ComponentDefinition
Dim oCompOcc As Inventor.ComponentOccurrence
Dim sSet As selectset
Set sSet = ThisApplication.ActiveDocument.selectset

Dim oCol As ObjectCollection
Set oCol = ThisApplication.TransientObjects.CreateObjectCollection
For Each oCompOcc In sSet
    Call oCol.Add(oCompOcc)
Next
For Each oCompOcc In oCol
    On Error Resume Next
    If oCompOcc.visible = True Then
            Dim oDesignVR As DesignViewRepresentations
            Set oDesignVR = oCompOcc.Definition.RepresentationsManager.DesignViewRepresentations
            Dim iNumberOfRep As Integer
            iNumberOfRep = oDesignVR.Count
            Dim oActiveRep As DesignViewRepresentation
            Set oActiveRep = oCompOcc.Definition.RepresentationsManager.ActiveDesignViewRepresentation
            Dim i As Integer
            For i = 1 To iNumberOfRep
                If oDesignVR(i).name = oActiveRep.name Then
                    If i = iNumberOfRep Then
                        i = 1
                    Else
                        i = i + 1
                    End If
                    Call oDesignVR(i).Activate
                    Call oCompOcc.SetDesignViewRepresentation(oDesignVR(i).name, , False)
                    i = iNumberOfRep
                End If
            Next
    End If
Next
Call ThisApplication.ActiveDocument.selectset.SelectMultiple(oCol)
End Sub

https://autode.sk/38rLPv0

0 Likes
Message 4 of 15

JelteDeJong
Mentor
Mentor

try this iLogic rule

Dim doc As AssemblyDocument = ThisDoc.Document
Dim repManager As RepresentationsManager = doc.ComponentDefinition.RepresentationsManager

Dim newRep = repManager.DesignViewRepresentations.Item(1)
Dim selectNext As Boolean = False
For Each rep As DesignViewRepresentation In repManager.DesignViewRepresentations
    If selectNext Then
        newRep = rep
        Exit For
    End If
    If (repManager.ActiveDesignViewRepresentation.Name.Equals(rep.Name)) Then
        selectNext = True
    End If
Next
newRep.Activate()

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 5 of 15

DRoam
Mentor
Mentor

Nice code, @JelteDeJong, very efficient. I think the OP wanted to change the View Rep for the selected occurrence in an assembly, not the active document. Could you modify your code to do this?

 

You'll need to account for if the occurrence isn't currently Associative to a View Rep. My guess is this is what was giving @sebastien.forman issues with his code.

Message 6 of 15

JelteDeJong
Mentor
Mentor

i missed the part that TS wanted to switch a occurence. That is also more dificult then it should be. As @sebastien.forman wrote the ComponentOccurrence.ActiveDesignViewRepresentation does not always returns the correct name (or better it does not give a name. The help say this:

 

"Property that returns the name of the active Design View Representation for an assembly occurrence. This property returns a null string in the case where a design view representation was set for the occurrence non-associatively (i.e. with the 'Associative' flag turned off)."

 

Therefor the ComponentOccurrence.ActiveDesignViewRepresentation does return the correct name when the Design View Representation is Associative'.But in the other case there is a problem. I was hoping to work around this issue.  (By turning the associativity on. Read the name and turning it on again.) But it turns out that the property "ComponentOccurrence.IsAssociativeToDesignViewRepresentation" can only be set to "False". If you set it to true Inventor will throw an exception :-S

 

I could not find a way to get the name when the Associative' flag is turned Off....

There for the following code will only work if the Associative' flag is turned On.

 

Dim occ As ComponentOccurrence = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select an assembly occurence.")
Dim currentRepName As String = ""
If (occ.IsAssociativeToDesignViewRepresentation = True) Then
    currentRepName = occ.ActiveDesignViewRepresentation
Else
    MsgBox("This only works if the occurence is associative to DesignViewRepresentation")
    Return
    'Try 
    '    occ.IsAssociativeToDesignViewRepresentation = True
    '    currentRepName = occ.ActiveDesignViewRepresentation
    '    occ.IsAssociativeToDesignViewRepresentation = False
    'Catch ex As Exception
    '    currentRepName = "Master"
    'End Try
End If

Dim doc As Document = occ.Definition.Document
Dim repManager As RepresentationsManager = doc.ComponentDefinition.RepresentationsManager

Dim newRepName = repManager.DesignViewRepresentations.Item(2).Name
Dim selectNext As Boolean = False
For Each rep As DesignViewRepresentation In repManager.DesignViewRepresentations
    If selectNext Then
        newRepName = rep.Name
        Exit For
    End If
    If (currentRepName.Equals(rep.Name)) Then
        selectNext = True
    End If
Next

occ.SetDesignViewRepresentation(newRepName,, True)

 

I left the work around as comment in the code for others to try.

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

0 Likes
Message 7 of 15

sebastien.forman
Advocate
Advocate

Hi @JelteDeJong , hi @DRoam ,

 

Thank you for your help, search and your code.

 

Same issues than me, it seem than without "associative" option, doesn't stock last choice of representation. In this condition, It's strange and funny to see that my code can work notwithstanding... 

 

But only with one selected object.

 

I have a parallel question, what is for you the advantage of using ilogic rules, in the sense that the IDE does not allow my knowledge
-debug step by step
- see the values in real time.
-Have detailed help on the code (F1)
-Used "Watches".

Ilogic IDE is just for coloring of code no?
You understand that I prefer IDE MVBA :-).

 

Have a nice day.

 

Sébastien

 

 

 

 

0 Likes
Message 8 of 15

DRoam
Mentor
Mentor

The reason "ActiveDesignViewRepresentation" returns the null string when "Associative" is turned off, is that when Associative is turned off, there IS no Active design view representation. Even if one was set before, that is only a transient operation that is true at that particular moment in time.

 

If I set an occurrence to the "Default" view rep, but don't check Associative, that occurrence takes on the current state of Default. But because Associative wasn't checked, it would be mistaken to assume, at any later point in time, that the occurrence is still in the same state as the "Default" view rep. The occurrence may have changed, or Default may have changed, or both. Without "Associative" checked, Inventor just can't know if the occurrence is still in the same state as "Default" or not (or any other View Rep the occurrence has). So when asked what the Active design rep for a non-associative occurrence is, Inventor just says, "As far as I know, there isn't one."

 

(EDIT: The same is also true when going through the GUI, actually. If you right-click an occurrence and set it to the "Default" view rep, but don't check Associative, and say OK, then re-open its "Representations...", you'll see that even the GUI doesn't know or remember that you set it to Default -- it will instead say Master.)

 

This is also why you can't just set the "IsAssociative" property to True -- because Inventor doesn't know which View Rep to set it associative to. It doesn't know what the last-applied View Rep was.

 

One change that could be made to Inventor to make this work better for us, would be to remember the last View Rep that the occurrence was set to, even if it wasn't associative. This could be stored in a separate property, perhaps called "LastAppliedViewRepresentation". Inventor could use that information to allow us to set "IsAssociative" to True directly. Or we could use it to do something else -- in this case, we could use that information to determine the next view rep and activate it. There's an existing idea for this, but it's relating to Drawing Views rather than Assembly Occurrences. But the underlying issue is exactly the same. So you may consider voting for it here: API improvement: Reassociate a Drawing View with its Design View Representation.

 

In the meantime...

 

The best you can do right now is make an educated guess, using logic that makes sense for your models, as to which View Rep was most recently used for a given occurrence. Or, you can just arbitrarily choose one (like the first one).

 

In the case of @sebastien.forman's application, if he comes across an occurrence whose "IsAssociativeToDesignViewRepresentation" property is False, he can just arbritarily choose to set it to the first View Rep the occurrence has, rather than setting it to the "next" one.

 

Unfortunately, that's the best solution we have right now.

0 Likes
Message 9 of 15

sebastien.forman
Advocate
Advocate

Hello @DRoam,

 

I agree with you.

 

Just one think seem to be different of your explication.

 

Why this code work for a non associative item?

 

Public Sub RepresentationSwitchNext()
Dim doc As AssemblyDocument
Set doc = ThisApplication.ActiveDocument
Dim oAsmCompDef As ComponentDefinition
Set oAsmCompDef = doc.ComponentDefinition
Dim oCompOcc As Inventor.ComponentOccurrence
Dim sSet As selectset
Set sSet = ThisApplication.ActiveDocument.selectset

Dim oCol As ObjectCollection
Set oCol = ThisApplication.TransientObjects.CreateObjectCollection
For Each oCompOcc In sSet
    Call oCol.Add(oCompOcc)
Next
For Each oCompOcc In oCol
    On Error Resume Next
    If oCompOcc.visible = True Then
            Dim oDesignVR As DesignViewRepresentations
            Set oDesignVR = oCompOcc.Definition.RepresentationsManager.DesignViewRepresentations
            Dim iNumberOfRep As Integer
            iNumberOfRep = oDesignVR.Count
            Dim oActiveRep As DesignViewRepresentation
            Set oActiveRep = oCompOcc.Definition.RepresentationsManager.ActiveDesignViewRepresentation
            Dim i As Integer
            For i = 1 To iNumberOfRep
                If oDesignVR(i).name = oActiveRep.name Then
                    If i = iNumberOfRep Then
                        i = 1
                    Else
                        i = i + 1
                    End If
                    Call oDesignVR(i).Activate
                    Call oCompOcc.SetDesignViewRepresentation(oDesignVR(i).name, , False)
                    i = iNumberOfRep
                End If
            Next
    End If
Next
Call ThisApplication.ActiveDocument.selectset.SelectMultiple(oCol)
End Sub

 

The solution of a new variable "LastAppliedViewRepresentation" is a good idea, maybe i will put a new variable in iproperty like this:

Capture.PNG

Pending a plausible API change

0 Likes
Message 10 of 15

DRoam
Mentor
Mentor

Hi @sebastien.forman, this code is doing something really interesting. It's not using the occurrence's active View Rep (oCompOcc.ActiveDesignViewRepresentation) to determine which one to activate next; it's using the occurrence's document's active View Rep (oCompOcc.Definition.RepresentationsManager.ActiveDesignViewRepresentation). It actually activating the next sequential View Rep from the one that's currently active within the occurrence's document. And it activate this View Rep for both the occurrence (Call oCompOcc.SetDesignViewRepresentation()) and the occurrence's document (Call oDesignVR(i).Activate).

 

Basically what it's doing is ignoring the active View Rep for the occurrence altogether, and just assuming the document's active View Rep (the one you would see if you right-clicked the occurrence and hit "Open") is the current View Rep for the occurrence (which may not be true). This circumvents the ComponentOccurrence.ActiveDesignViewRepresentation and ignores it altogether, thereby circumventing the null string issue.

 

On one hand, this is a bad idea, for two reasons: 1) It ignores the actual active View Rep for the occurrence (if it's set associative to one); and 2) If there are X occurrences of a given document, the code will step through them sequentially and each occurrence will have a different View Rep.

 

On the other hand, though, this is actually a really good idea as a way to decide which View Rep to activate and associate if one isn't currently.

 

What I would do is modify that code to have the following logic: If the occurrence "IsAssociativeToDesignViewRepresentation", then activate the next sequential View Rep for it; however, if it's NOT associative, activate the same View Rep that's currently active in the occurrence's document.

 

Unfortunately, this isn't as simple as it sounds, because you'll have to handle the fact that the Master view rep cannot be set associatively. For Assemblies, you probably want to just skip the Master view rep altogether, because it's usually just garbage. But for parts, you probably want to use it. You'll also need to take into account if an assembly ONLY has the Master view rep and no others. And you'll also need to handle the situation where the active View Rep for a part's document is "Master", in which case you'll want to active and associate to the next View Rep, if there is one. There just a bunch of little corner cases that you'll need to account for, unfortunately.

 

The following code should get you started in that process. It's in iLogic rather than VBA. This may not exactly match you intent, but hopefully it gets you closer.

 

Dim doc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oAsmCompDef As AssemblyComponentDefinition = doc.ComponentDefinition

' Get select set.
Dim sSet As SelectSet = ThisApplication.ActiveDocument.selectset

' Save select set to object collection so it can be re-selected after code completion.
Dim oCol As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
For Each oCompOcc In sSet
    oCol.Add(oCompOcc)
Next

' Iterate through selected occurrences.
For Each obj As Object In oCol
	If TypeOf obj Is ComponentOccurrence Then
	    Dim oCompOcc As ComponentOccurrence = obj
		
	    If oCompOcc.Visible = True Then
			If oCompOcc.IsAssociativeToDesignViewRepresentation Then
				' Activate the next sequential View Rep.
				Dim occActiveVR As String = oCompOcc.ActiveDesignViewRepresentation
				
				Dim docVRs As DesignViewRepresentations = oCompOcc.Definition.RepresentationsManager.DesignViewRepresentations
				
				Dim i As Integer
				
				For i = 1 To docVRs.Count
	                If docVRs(i).Name = occActiveVR Then
						' Determine which view rep to activate next.
	                    If i = docVRs.Count Then
							' If a Part, go back to 1 ("Master"). If an assembly, skip Master (unless there are no others).
							If oCompOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
								i = 1
							ElseIf oCompOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
								If docVRs.Count >= 2 Then
									i = 2
								Else
									i = 1
								End If
							End If
	                    Else
	                        i += 1
	                    End If
						
						' Determine whether to set Associative.
						Dim assoc As Boolean
						If i = 1 Then
							assoc = False ' ("Master" cannot be set associatively).
						Else
							assoc = True
						End If
						
						' Activate View Rep.
	                    oCompOcc.SetDesignViewRepresentation(docVRs(i).Name, , assoc)
						
	                    Exit For
	                End If
				Next
			Else
				' Activate an arbitrarily-chosen View Rep. In this case, choose the document's active View Rep.
				' NOTE: Need to fix this to handle if the document is a Part, in which case activate the next View Rep after Master, if it exists.
				Dim docActiveVR As String = oCompOcc.Definition.RepresentationsManager.ActiveDesignViewRepresentation.Name
				
				oCompOcc.SetDesignViewRepresentation(docActiveVR, , True)
			End If
	    End If
	End If
	
Next

ThisApplication.ActiveDocument.selectset.SelectMultiple(oCol)

 

 

Message 11 of 15

DRoam
Mentor
Mentor

Also, just a quick response to your iLogic vs. VBA question: iLogic is essentially a wrapper on top of the VB.NET language. VB.NET is a much more modern and feature-rich language than VBA (which is basically VB6). This answer on StackExchange lists several of the differences. A couple of the big differences for me are dynamic Lists and Try/Catch, which VBA does not have. VB.NET is also just friendlier to write in, as you don't have to use "Set" and "Call", and you can define a variable on the same line as you declare it.

 

While the iLogic IDE leaves a lot to be desired as (particularly relating to debugging), it is getting better. I would not choose to sacrifice the capabilities of VB.NET for the debugging in VBA. I've learned to get by using Message boxes and the new Logger.Debug feature of iLogic when I need to debug.

Message 12 of 15

sebastien.forman
Advocate
Advocate

Hi @DRoam , thank you for your perfect analyse and information.

 

I will test you code and improve it as soon as possible. That seem to be a good approach.

 

 Have a nice day.

 

Sébastien.

0 Likes
Message 13 of 15

sebastien.forman
Advocate
Advocate

About comparaison with VB6 and VB.net, i understand your position about it. VB net seem to be really powerful.

 

I understand too that with this VB.net compiled langage, it's difficult to make step by step debugging feature easily.

 

It is all the more unfortunate by the fact that I use the object explorer in memory to design my code ...

 

Maybe add-ins with visual studio will be a good solution for having power full environement of development.

 

0 Likes
Message 14 of 15

JelteDeJong
Mentor
Mentor

the iLogic ide is not user friendly if you are used to vba or visual studio. There for i have a visual studio project that let me write iLogic code in visual studio (and run it in visual studio). Then when the code is finished i copy past the code to ilogic browser and im done. (i need to note that not all commands are supported.) That project can be found on GitHub.

 

If you have Inventor 2019 or beter then its also possible to debug iLoic rules directly from visual studio. I did not try it my self. have a look at this article

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 15 of 15

sebastien.forman
Advocate
Advocate

Interesting, thank you.

I will read that.

0 Likes