Bug report when setting Face Name

Bug report when setting Face Name

They_Call_Me_Jake
Advocate Advocate
1,089 Views
9 Replies
Message 1 of 10

Bug report when setting Face Name

They_Call_Me_Jake
Advocate
Advocate

InvApp is a normal Marshall reference that works for everything else in my .dll. 

 

        Dim thisDoc As PartDocument = InvApp.ActiveDocument
        Dim oPartCompDef As PartComponentDefinition = thisDoc.ComponentDefinition

        Dim frontFace As Face = thisDoc.SelectSet.Item(1)

        Const iLogicAddinGuid As String = "{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}"
        Dim addin As ApplicationAddIn = InvApp.ApplicationAddIns.ItemById(iLogicAddinGuid)
        Dim iLogicAuto As Object = addin.Automation
        Dim namedEntities As Object = iLogicAuto.GetNamedEntities(oPartCompDef.Document)

        namedEntities.SetName(frontFace, "FrontFace")

 

Intermittently, an exception will throw on .SetName (ArgumentException): Controls created on one thread cannot be parented to a control on a different thread error.

 

This exception only happens if there are no existing named faces in the part. The exception appears to be related to creating the "Geometry" tab under the iLogic tab.

 

This bug is INTERMITTENT and I have no idea what causes it to stop happening. I have tried restarting the computer, starting in brand new parts in inventor, etc. I was seeing the bug happen reliably, and then suddenly it stopped happening with the exact same code. There is no multithreading in my application, although I had 
Imports System.Threading at the top of my code, it has been grayed out the whole time and as such is not being used for anything.

0 Likes
1,090 Views
9 Replies
Replies (9)
Message 2 of 10

Stakin
Collaborator
Collaborator

the code can run here,Is the problem with your Inventor App?Or your System setting?

0 Likes
Message 3 of 10

JelteDeJong
Mentor
Mentor

I can reproduce the problem. It seems that it's not possible to create the first named entity. Not sure how this is supposed to work. But it's possible to create named entities without calling the iLogic addin. Something becomes a named entity as soon as you put the correct attribute on it and add it to the list. that list is an attribute of the document. Below you will find an iLogic rule that will do this. But there is 1 small problem. The geometry tab will not show or get updated until you reopen the part.

JelteDeJong_0-1633620417177.png

 

Sub Main()
    Dim InvApp = ThisApplication
    Dim thisDoc As PartDocument = InvApp.ActiveDocument
    Dim oPartCompDef As PartComponentDefinition = thisDoc.ComponentDefinition

    Dim frontFace As Face = thisDoc.SelectSet.Item(1)
    addNameToFace(thisDoc, frontFace, "FrontFace1")

End Sub

Private Sub addNameToFace(doc As PartDocument, face As Face, name As String)

    Dim attSetName As String = "iLogicEntityNameSet"
    Dim attName As String = "iLogicEntityName"

    Dim att As Attribute = getAttribute(face, attSetName, attName)
    att.Value = name

    Dim attSetNameDoc = "iLogicEntityNameSet"
    Dim attNameDoc = "iLogicEntityNamesOrdered"
    Dim attDoc As Attribute = getAttribute(doc, attSetNameDoc, attNameDoc)

    If (attDoc.Value.contains(name) = False) Then

        Dim atts As AttributesEnumerator = doc.AttributeManager.FindAttributes(attSetName, attName)

        Dim entities As String = ""
        For Each itemAtt As Attribute In atts
            entities = entities & itemAtt.Value & Constants.vbTab
        Next
        attDoc.Value = entities
    End If
End Sub

Public Function getAttribute(objectWithAttributes As Object, attSetName As String, attName As String) As Attribute
    Dim attSet As AttributeSet

    If (objectWithAttributes.AttributeSets.NameIsUsed(attSetName)) Then
        attSet = objectWithAttributes.AttributeSets.Item(attSetName)
    Else
        attSet = objectWithAttributes.AttributeSets.Add(attSetName)
    End If

    Dim att As Attribute
    If attSet.NameIsUsed(attName) Then
        att = attSet.Item(attName)
    Else
        att = attSet.Add(attName, ValueTypeEnum.kStringType, "")
    End If
    Return att
End Function

 

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 4 of 10

Stakin
Collaborator
Collaborator

Your code can't run properly,

No error,No result. it seems no run it ever.

0 Likes
Message 5 of 10

JelteDeJong
Mentor
Mentor

Did you reopen the document after you run the rule? Only then the change will be visible. I created a new rule that will do everything for you. (including closing and reopening the file. I also found a bug that, in my previous rule)  Anyway, it works for me.

 

Sub Main()
    Dim doc As PartDocument = ThisDoc.Document

    Dim face As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Select a face")
    Dim name As String = InputBox("Give a name", "Name", "Face ")

    addNameToFace(doc, face, name)

    Dim fileName = doc.FullFileName
    doc.Save()
    doc.Close()
    ThisApplication.Documents.Open(fileName)

End Sub

Private Sub addNameToFace(doc As PartDocument, face As Face, name As String)

    Dim attSetName As String = "iLogicEntityNameSet"
    Dim attName As String = "iLogicEntityName"
    Dim att As Attribute = getAttribute(face, attSetName, attName)
    att.Value = name

    Dim refKey() As Byte = New Byte() {}
    face.CreatedByFeature.GetReferenceKey(refKey)
    Dim refKeyString = doc.ReferenceKeyManager.KeyToString(refKey)

    Dim attFeatureName As String = "iLogicEntityNameFeatureName"
    Dim attFeature As Attribute = getAttribute(face, attSetName, attFeatureName)
    attFeature.Value = refKeyString


    Dim attSetNameDoc = "iLogicEntityNameSet"
    Dim attNameDoc = "iLogicEntityNamesOrdered"
    Dim attDoc As Attribute = getAttribute(doc, attSetNameDoc, attNameDoc)

    If (attDoc.Value.contains(name) = False) Then

        Dim atts As AttributesEnumerator = doc.AttributeManager.FindAttributes(attSetName, attName)

        Dim entities As String = ""
        For Each itemAtt As Attribute In atts
            entities = entities & itemAtt.Value & Constants.vbTab
        Next
        attDoc.Value = entities
    End If
End Sub

Public Function getAttribute(objectWithAttributes As Object, attSetName As String, attName As String) As Attribute
    Dim attSet As AttributeSet

    If (objectWithAttributes.AttributeSets.NameIsUsed(attSetName)) Then
        attSet = objectWithAttributes.AttributeSets.Item(attSetName)
    Else
        attSet = objectWithAttributes.AttributeSets.Add(attSetName)
    End If

    Dim att As Attribute
    If attSet.NameIsUsed(attName) Then
        att = attSet.Item(attName)
    Else
        att = attSet.Add(attName, ValueTypeEnum.kStringType, "")
    End If
    Return att
End Function

 

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 6 of 10

Stakin
Collaborator
Collaborator

wonderful,thank you very much

 

0 Likes
Message 7 of 10

Cadkunde.nl
Collaborator
Collaborator

I just happen to work on this problem now and want to suggest that instead of saving, closing and reopening.

 

You could also create a temporary rule, run it, then delete it:

Shared Sub CreateRule(strTag As String, oDoc As PartDocument, iLogicAuto As Object)
Dim RuleName As String = "Cadkunde_TemporaryRule"

Dim RuleText As String = "Dim thisDoc As PartDocument = ThisApplication.ActiveDocument" & vbLf &
"Dim oPartCompDef As PartComponentDefinition = thisDoc.ComponentDefinition" & vbLf &
"Dim frontFace As Face = thisDoc.SelectSet.Item(1)" & vbLf &
"Const iLogicAddinGuid As String = ""{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}""" & vbLf &
"Dim addin As ApplicationAddIn = Thisapplication.ApplicationAddIns.ItemById(iLogicAddinGuid)" & vbLf &
"Dim iLogicAuto As Object = addin.Automation" & vbLf &
"Dim namedEntities As Object = iLogicAuto.GetNamedEntities(oPartCompDef.Document)" & vbLf &
"namedEntities.SetName(frontFace, ""FrontFace"")"

Dim rule As Object = iLogicAuto.GetRule(oDoc, RuleName)
If rule IsNot Nothing Then
iLogicAuto.DeleteRule(oDoc, RuleName)
End If
iLogicAuto.Addrule(oDoc, RuleName, RuleText)
iLogicAuto.RunRule(oDoc, RuleName)
iLogicAuto.DeleteRule(oDoc, RuleName)
End Sub

0 Likes
Message 8 of 10

WCrihfield
Mentor
Mentor

Hi @Cadkunde.nl.  I have another idea for you to try that may be even simpler/easier to do.  Have you tried simply turning the visibility of the iLogic DockableWindow off, then back on again?  We have to do that little trick when deleting iLogic Forms from an Inventor drawing, to see the results in the iLogic tab, without closing/re-opening the file.  I picked that little 'blink' tip up from Curtis Waguespack in another forum topic months ago.  Its 'InternalName' is "ilogic.treeeditor".

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 10

Cadkunde.nl
Collaborator
Collaborator

Well I tried that path. Use Jelte his code and added the dockable window tip

It looks perfect at first, but then when you try to delete an entity created with this, ilogic gives an error

 

 

Shared Sub AddTag(strTag As String)
Dim addIn As ApplicationAddIn = Globals.oApp.ApplicationAddIns.ItemById("{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}")
Dim iLogicObject As Object = addIn.Automation
Dim oDoc As PartDocument = Globals.oApp.ActiveDocument
If oDoc.IsModifiable = True Then
Dim oSel As Inventor.SelectSet = oDoc.SelectSet

Dim FaceList As New List(Of Face)
For Each oFace As Object In oSel
FaceList.Add(oFace)
Next

For i = 0 To FaceList.Count - 1
addNameToFace(oDoc, FaceList.Item(i), strTag & i)
'CreateRule(strTag, i, FaceList, oDoc, iLogicObject)
Next

Dim oMan As UserInterfaceManager = Globals.oApp.UserInterfaceManager
For Each oWin As DockableWindow In oMan.DockableWindows
If oWin.InternalName = "ilogic.treeeditor" Then
oWin.Visible = False
oWin.Visible = True
End If
Next
End If

End Sub

Shared Sub addNameToFace(doc As PartDocument, face As Face, name As String)

Dim attSetName As String = "iLogicEntityNameSet"
Dim attName As String = "iLogicEntityName"

Dim att As Attribute = getAttribute(face, attSetName, attName)
att.Value = name

Dim attSetNameDoc = "iLogicEntityNameSet"
Dim attNameDoc = "iLogicEntityNamesOrdered"
Dim attDoc As Attribute = getAttribute(doc, attSetNameDoc, attNameDoc)

If (attDoc.Value.contains(name) = False) Then

Dim atts As AttributesEnumerator = doc.AttributeManager.FindAttributes(attSetName, attName)

Dim entities As String = ""
For Each itemAtt As Attribute In atts
entities = entities & itemAtt.Value & Constants.vbTab
Next
attDoc.Value = entities
End If
End Sub

Shared Function getAttribute(objectWithAttributes As Object, attSetName As String, attName As String) As Attribute
Dim attSet As AttributeSet

If (objectWithAttributes.AttributeSets.NameIsUsed(attSetName)) Then
attSet = objectWithAttributes.AttributeSets.Item(attSetName)
Else
attSet = objectWithAttributes.AttributeSets.Add(attSetName)
End If

Dim att As Attribute
If attSet.NameIsUsed(attName) Then
att = attSet.Item(attName)
Else
att = attSet.Add(attName, ValueTypeEnum.kStringType, "")
End If
Return att
End Function

0 Likes
Message 10 of 10

Cadkunde.nl
Collaborator
Collaborator

Hmmz, I think I will pursuit client graphics and add own attributes, hoped for some quick and easy method with ilogic.
But its giving more frustration than help

0 Likes