Hello,
I have an iLogic rule to calculate the area of multiple selected faces.
The user should select all faces needed and after that press ESC and the calculation is done. When CTRL is pressed during the pick, already selected faces should get unselected. During that, all faces that are selected are highlighted.
The Problem is, if all selected faces get selected again, without pressing CTRL, the hightlightset is not highlightet anymore. The selectset and the highlightset are still containing all previous selected faces and the calculation of the area is working. Only the highlighting itself is not working.
I'm clueless, what might be the issue.
Thanks for your help .
'Definition
Dim oApp As Inventor.Application = ThisApplication
Dim oDoc As PartDocument = ThisApplication.ActiveDocument
Dim oStartFace,oFace As Inventor.Face '= Nothing
Dim AreaCache As Double = 0
Dim FaceCol As New Collection
FaceCol.Clear
Dim oHSet As HighlightSet = oDoc.CreateHighlightSet()
oHSet.Clear
'if done, start again
TheStart:
On Error GoTo ENDE
While True
Dim i As Double
Dim k As Integer
k = 1
Dim bNEW As Boolean
bNEW = True
Dim oStartFaceIN, oFaceIN As String
oStartFace = ThisApplication.CommandManager.Pick(Inventor.SelectionFilterEnum.kPartFaceFilter, "Fläche anwählen + ""Esc"" bestätigen.")
' If nothing gets selected then we're done
If IsNothing(oStartFace) Then Exit While
''Läuft nicht
If System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then
If FaceCol.Count>0 Then
For i = 1 To FaceCol.Count
oFaceIN = FaceCol.Item(i).InternalName
oStartFaceIN = oStartFace.InternalName
If InStr(oFaceIN, oStartFaceIN) = 1 Then
bNEW = False
Exit For
End If
k = k + 1
Next i
End If
If bNEW = False
FaceCol.Remove(k)
oHSet.Remove(k)
ThisApplication.ActiveView.Update
End If
Else
If FaceCol.Count>0 Then
For i = 1 To FaceCol.Count
oFaceIN = FaceCol.Item(i).InternalName
oStartFaceIN = oStartFace.InternalName
If InStr(oFaceIN, oStartFaceIN) = 1 Then
bNEW = False
Exit For
End If
k = k + 1
Next i
End If
If bNEW = True Then
FaceCol.Add(oStartFace)
oHSet.AddItem(oStartFace)
End If
End If
''Läuft nicht
oStartFace = Nothing
End While
For Each oFace In FaceCol
AreaCache = AreaCache + oFace.Evaluator.Area
Next
If AreaCache = 0 Then
GoTo ENDE
End If
AreaCache = Math.Round(AreaCache*100,1)
MessageBox.Show(AreaCache & "mm²")
oHSet.Clear
FaceCol.Clear
AreaCache = 0
'if done, go to the start
GoTo TheStart
Return
ENDE:
Solved! Go to Solution.
Solved by Michael.RostZ454J. Go to Solution.
Solved by robbeRtek. Go to Solution.
Hi @Michael.RostZ454J. Interesting code. I can tell when testing it that after I have selected all faces, then select them again without using Ctrl key, they do appear to loose their highlight color, but when continuing to select any of them again, I can see that highlight color 'blink', then remain the default color (not the highlight color). Seems like a visual glitch to me, but may be a bug of some sort. Might be worth reporting to the folks at Autodesk, but seems like a rather minor bug, since the selection has been maintained. The real test would be to only use the HighlightSet, and not the 'Collection', then when needed, get the objects you want to test from the HighlightSet, just to see if they are still in there. Not very efficient, but its just for testing purposes at this point, to see of those faces are still in the HighlightSet or only in the Collection. They will want to know that if you plan on reporting it. Nice touch using the ModifierKeys to help with the removal of unwanted faces while selecting.
Wesley Crihfield
(Not an Autodesk Employee)
While testing further, I got rid of the Collection object and just used the HighlightSet for everything. It does keep the objects even when they are selected twice without using the Ctrl key, and are no longer showing the highlight color. That could definitely lead to unexpected results.
Wesley Crihfield
(Not an Autodesk Employee)
Hello @WCrihfield,
I found a thread with a similar task. The solution there shows the same strange behavior.
"Measure - Area of multiple faces at once"
I haven't found a solution yet. As a workaround, I emptied the highlight set and then filled it again.
However, that is not a solution. Only selected areas are then highlighted, but it looks like a light show.
We had similar problems with hightlight sets a couple of time ago,
we don't use it anymore, instead we use color override from face.
I guess through the pick command, when selecting an 2time, 'the color overwrite from the face that is attached from highlight set is reset/clear '
(the .pick has some hidden functions : like its return always an proxy if you use it on assembly environment))
here's an small snippet from our code : (in your case, after the command you want the face back in de original collor -- > store value first or use Face.AppearanceSourceType Property to set the override to bodyappearance.
Dim docAsset As Assets
docAsset = partDoc1.Assets
Dim oAppearanceGreen As Asset
oAppearanceGreen = docAsset.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", "AppearencesGreen", "New AppearenceGreen")
Dim generic_color_green As ColorAssetValue
generic_color_green = oAppearanceGreen.Item("generic_diffuse")
generic_color_green.Value = oTG.CreateColor(0, 128, 0) ' Groen
Dim oAppearanceYellow As Asset
oAppearanceYellow = docAsset.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", "AppearencesYellow", "New AppearenceYellow")
Dim generic_color_yellow As ColorAssetValue
generic_color_yellow = oAppearanceGreen.Item("generic_diffuse")
generic_color_yellow.Value = oTG.CreateColor(255, 255, 0) ' Geel
Dim ptx1 As Point = bf.PointOnFace
Dim ptx2 As Point = oppositface.PointOnFace
If ptx1.Y < ptx2.Y Then
bf.Appearance = oAppearanceGreen
oppositface.Appearance = oAppearanceYellow
Else
bf.Appearance = oAppearanceYellow
oppositface.Appearance = oAppearanceGreen
End If
Hello @robbeRtek,
I gave it a try and changed the code. The only problem is that not every overwrite is allowed to be reset to default. We also have colored areas that have to stay that way.
I tried to replace the highlight set with another collection in which the colors are stored. The part with the selection and deselection with CTRL works so far. However, inventor always stops when the areas are to be set to their original color while calculating the area. But that also seems to be a bug. If I display a message box beforehand, everything goes through as desired.
Edit: If I separate the calculation of the area and the recoloring and put the output of the calculation results in between, the problem is gone. However, this can only be implemented for individual parts and so the original problem remains because the highlight set would be the way to go for an assembly.
'Definition
Dim oApp As Inventor.Application = ThisApplication
Dim oDoc As PartDocument = ThisApplication.ActiveDocument
Dim oCompDef As ComponentDefinition
oCompDef = oDoc.ComponentDefinition
Dim oStartFace,oFace As Inventor.Face '= Nothing
Dim AreaCache As Double = 0
Dim FaceCol As New Collection
FaceCol.Clear
Dim ColorCol As New Collection
ColorCol.Clear
Dim oHSet As HighlightSet = oDoc.CreateHighlightSet()
oHSet.Clear
' Definition der transienten Geometrie
Dim oTransObj As TransientObjects
oTransObj = oApp.TransientObjects
Dim docAsset As Assets
docAsset = oDoc.Assets
Dim oAssetLib As AssetLibrary
oAssetLib = oApp.AssetLibraries.Item("Autodesk Darstellungs-Bibliothek") 'Autodesk Appearance Library
Dim oColor As String
oColor = "Markierung"
' Get an asset In the library
Dim oHighlightColor As Asset
Try 'Copy the asset locally.
oHighlightColor = docAsset.Item(oColor)
Catch 'or just use it if it's already local
oHighlightColor = docAsset.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", oColor, oColor)
Dim generic_highlight_color As ColorAssetValue
generic_highlight_color = oHighlightColor.Item("generic_diffuse")
generic_highlight_color.Value = oHSet.Color
End Try
'wenn fertig, starte von vorn
TheStart:
While True
Dim k As Integer
k = 1
Dim bNEW As Boolean
bNEW = True
oStartFace = oApp.CommandManager.Pick(Inventor.SelectionFilterEnum.kPartFaceFilter, "Fläche anwählen + ""Esc"" bestätigen.")
' If nothing gets selected then we're done
If oStartFace Is Nothing Then Exit While
'wenn STRG gedrückt wird, sollen bereits selektierte Flächen wieder abgewählt werden
If System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then 'STRG wird gedrückt beim Selektieren
If FaceCol.Count>0 Then
For k = 1 To FaceCol.Count
oFace= FaceCol.Item(k)
If oFace.InternalName = oStartFace.InternalName Then
bNEW = False
Exit For
End If
Next
End If
If bNEW = False
FaceCol.Remove(k)
oFace.Appearance = ColorCol.Item(k)
ColorCol.Remove(k)
'oHSet.Remove(oFace)
oApp.ActiveView.Update
End If
Else 'STRG wird nicht gedrückt beim selektieren
If FaceCol.Count>0 Then
For k = 1 To FaceCol.Count
oFace= FaceCol.Item(k)
If oFace.InternalName = oStartFace.InternalName Then
bNEW = False
Exit For
End If
Next
End If
If bNEW = True Then
FaceCol.Add(oStartFace)
ColorCol.Add(oStartFace.Appearance)
oStartFace.Appearance = oHighlightColor
'oHSet.AddItem(oStartFace)
oApp.ActiveView.Update
End If
End If
oStartFace = Nothing
End While
MessageBox.Show("random message")
'Berechenen der Flächeninhalte der Selektion
Dim i As Integer
If FaceCol.Count > 0 Then
For i = 1 To FaceCol.Count
oFace = FaceCol.Item(i)
AreaCache = AreaCache + oFace.Evaluator.Area
oFace.Appearance = ColorCol.Item(i)
oApp.ActiveView.Update
Next
End If
If AreaCache = 0 Then Return
'Ausgabe Flächeninhalt
AreaCache = Math.Round(AreaCache*100,1)
MessageBox.Show(AreaCache & "mm²")
'oCompDef.ClearAppearanceOverrides() 'Alle farbig veränderten Flächen werden auf Standard gesetzt
oHSet.Clear
FaceCol.Clear
ColorCol.Clear
AreaCache = 0
'if done, go to the start
GoTo TheStart
hello,
if the user select an second time a face, (or thirt)
What output do you want?
1) the face stay highlight, and in the area calculation, use 2x the area from that face?
2) nothing, the area calculation, use 1x the area from each face that is seleceted, the highlight stays?
Regards
Nr. 2)
If the user selects a face a second (or more) time, I count that as an accident. The already selected and highlighted face should stay highlighted and in the collection for the area calculation.
If the user wants to deselect a face, he should press CTRL during the pick. Then the face should be removed from the collection (and the area of these face should not be counted during calculation) and the highlighting should disappear.
If the user presses ESC, the area of all highlighted faces should be calculated and after the output of the calculated area, all highlighting should disappear and the selection process should start from the beginning.
here is a working rule,
Thanks to accept solution :
Sub main Dim _inv As Inventor.Application = ThisApplication Dim PartDoc As PartDocument = ThisDoc.Document Dim oTG As TransientObjects = _inv.TransientObjects Dim oDocAssets As Assets = PartDoc.Assets Dim oAppearanceHighlightRed As Asset = GetOrCreateAsset(oDocAssets, "New HighlightRed") Dim ColorHighlightRed As ColorAssetValue = oAppearanceHighlightRed.Item("generic_diffuse") ColorHighlightRed.Value = oTG.CreateColor(255, 0, 0) ' red Dim oStartFace As Face Dim FaceList As New List(Of Face) While True oStartFace = _inv.CommandManager.Pick(Inventor.SelectionFilterEnum.kPartFaceFilter, "Fläche anwählen + ""Esc"" bestätigen.") ' If nothing gets selected then we're done If oStartFace Is Nothing Then Exit While If FaceList.Count = 0 Then FaceList.Add(oStartFace) 'if crtl is pressed and listCount =0, we see crtl press as user fault, dont look oStartFace.Appearance = oAppearanceHighlightRed ElseIf Not FaceList.Contains(oStartFace) Then If Not System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then FaceList.Add(oStartFace) oStartFace.Appearance = oAppearanceHighlightRed End If Else 'contains If System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then FaceList.Remove(oStartFace) oStartFace.AppearanceSourceType = AppearanceSourceTypeEnum.kBodyAppearance End If End If End While If FaceList.Count =0 Then Exit Sub 'Area calculation Dim AreaCache As Double = 0 For Each oFace As Face In FaceList AreaCache = AreaCache + oFace.Evaluator.Area Next If Not AreaCache = o Then AreaCache = Math.Round(AreaCache*100,1) MsgBox("Area : " & AreaCache & "mm²") End If 'reset highligt For Each oFace As Face In FaceList oFace.AppearanceSourceType = AppearanceSourceTypeEnum.kBodyAppearance 'other options to reset easy : kComponentOccurrenceAppearance,kDefaultAppearance,kFeatureAppearance,kMaterialAppearance,kPartAppearance Next End Sub Function GetOrCreateAsset(ByVal assets As Assets, ByVal assetName As String) As Asset Try Return assets.Item(assetName) Catch ex As Exception ' Het asset bestaat nog niet, dus maken we er een aan Return assets.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", "HighlightRed", assetName) End Try End Function
Here i've the code with highlightset : the core issue :
'oHSet.Remove(StartFace)
If you add it again, it don't Highlight,....
so the solution is to clear it first, and make the 'new' set again.
oHSet.Clear For Each _face As Face In FaceList oHSet.AddItem(_face) Next
here is full code, 2 options , with color override or with highlight
Sub main Dim _inv As Inventor.Application = ThisApplication Dim PartDoc As PartDocument = ThisDoc.Document Dim oHSet As HighlightSet = PartDoc.CreateHighlightSet() oHSet.Clear ' Dim oTG As TransientObjects = _inv.TransientObjects ' Dim oDocAssets As Assets = PartDoc.Assets ' Dim oAppearanceHighlightRed As Asset = GetOrCreateAsset(oDocAssets, "New HighlightRed") ' Dim ColorHighlightRed As ColorAssetValue = oAppearanceHighlightRed.Item("generic_diffuse") ' ColorHighlightRed.Value = oTG.CreateColor(255, 0, 0) ' red Dim oStartFace As Face Dim FaceList As New List(Of Face) While True oStartFace = _inv.CommandManager.Pick(Inventor.SelectionFilterEnum.kPartFaceFilter, "Fläche anwählen + ""Esc"" bestätigen.") ' If nothing gets selected then we're done If oStartFace Is Nothing Then Exit While If FaceList.Count = 0 Then FaceList.Add(oStartFace) 'if crtl is pressed and listCount =0, we see crtl press as user fault, dont look 'oStartFace.Appearance = oAppearanceHighlightRed oHSet.AddItem(oStartFace) ElseIf Not FaceList.Contains(oStartFace) Then If Not System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then FaceList.Add(oStartFace) oHSet.AddItem(oStartFace) 'oStartFace.Appearance = oAppearanceHighlightRed End If Else 'contains If System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then FaceList.Remove(oStartFace) 'oStartFace.AppearanceSourceType = AppearanceSourceTypeEnum.kBodyAppearance 'oHSet.Remove(StartFace) same behavior off your code oHSet.Clear For Each _face As Face In FaceList oHSet.AddItem(_face) Next End If End If End While If FaceList.Count = 0 Then Exit Sub 'Area calculation Dim AreaCache As Double = 0 For Each oFace As Face In FaceList AreaCache = AreaCache + oFace.Evaluator.Area Next If Not AreaCache = o Then AreaCache = Math.Round(AreaCache * 100, 1) MsgBox("Area : " & AreaCache & "mm²") End If oHSet.clear 'reset highligt ' For Each oFace As Face In FaceList ' oFace.AppearanceSourceType = AppearanceSourceTypeEnum.kBodyAppearance ' 'other options to reset easy : kComponentOccurrenceAppearance,kDefaultAppearance,kFeatureAppearance,kMaterialAppearance,kPartAppearance ' Next End Sub 'Function GetOrCreateAsset(ByVal assets As Assets, ByVal assetName As String) As Asset ' Try ' Return assets.Item(assetName) ' Catch ex As Exception ' ' Het asset bestaat nog niet, dus maken we er een aan ' Return assets.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", "HighlightRed", assetName) ' End Try 'End Function
Your first option works like my try after you mentioned to highlight the faces via coloring and not with the highlightset. (with the little "Edit")
In your second option something must be missing. Cause it shows the same strange behavior of the highlightset that is mentioned in my start post. I also tried to clear an rebuild the whole highlightset. But if there are many faces selected, they will all highlight one after another which looks also very strange.
But I found an workaround.
Now every time an already highlighted face is selected (without pressing CTRL), it is removed from the highlightset and will be immediately added back.
This is not the most elegant solution, but it works (at least for me).
I also got rid of the collection cause everything can be done with the highlightset. (thanks to @WCrihfield for this idea). Besides this I also replaced the messagebox for the output with an inputbox as used in the other thread. This gives you the option for "copy and past" for the result.
Thanks for your help and effort. 👍
My solution via highlightset:
'Definition
Dim oApp As Inventor.Application = ThisApplication
Dim oDoc As Document = oApp.ActiveDocument
Dim oStartFace,oFace As Inventor.Face '= Nothing
Dim AreaCache As Double = 0
Dim oHSet As HighlightSet = oDoc.CreateHighlightSet()
oHSet.Clear
'if done, start again
TheStart:
On Error GoTo ENDE
While True
Dim k As Integer
k = 1
Dim bNEW As Boolean
bNEW = True
oStartFace = oApp.CommandManager.Pick(Inventor.SelectionFilterEnum.kPartFaceFilter, "Fläche anwählen + ""Esc"" bestätigen.")
' If nothing gets selected then we're done
If IsNothing(oStartFace) Then Exit While
If System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then
If oHSet.Count>0 Then
For Each oFace In oHSet
If oFace.InternalName = oStartFace.InternalName And oFace.TransientKey = oStartFace.TransientKey Then
bNEW = False
Exit For
End If
k = k + 1
Next
End If
If bNEW = False
oHSet.Remove(k)
oApp.ActiveView.Update
End If
Else
If oHSet.Count>0 Then
For Each oFace In oHSet
If oFace.InternalName = oStartFace.InternalName And oFace.TransientKey = oStartFace.TransientKey Then
bNEW = False
Exit For
End If
k = k + 1
Next
End If
If bNEW = True Then
oHSet.AddItem(oStartFace)
Else If bNEW = False Then
oHSet.Remove(k)
oHSet.AddItem(oStartFace)
End If
End If
''Läuft nicht
oStartFace = Nothing
End While
'For Each oFace In FaceCol
For Each oFace In oHSet
AreaCache = AreaCache + oFace.Evaluator.Area
Next
If AreaCache = 0 Then Return
AreaCache = Math.Round(AreaCache*100,1)
Dim Auswahl As String
'MessageBox.Show(AreaCache & "mm²")
Auswahl = InputBox("Oberfläche:", "Oberflaeche_berechnen_Multiselect", AreaCache & "mm²")
'MessageBox.Show (Auswahl)
oHSet.Clear
AreaCache = 0
If Auswahl = "" Then Exit Sub
'if done, go to the start
GoTo TheStart
Return
ENDE:
My Solution with changing the color:
'Definition
Dim oApp As Inventor.Application = ThisApplication
Dim oDoc As Document = oApp.ActiveDocument
Dim oEdDoc As Document = oApp.ActiveEditDocument
Dim oCompDef As ComponentDefinition
oCompDef = oDoc.ComponentDefinition
Dim oStartFace,oFace As Inventor.Face '= Nothing
Dim AreaCache As Double = 0
Dim FaceCol As New Collection
FaceCol.Clear
Dim ColorCol As New Collection
ColorCol.Clear
Dim oHSet As HighlightSet = oDoc.CreateHighlightSet()
oHSet.Clear
' Definition der transienten Geometrie
Dim oTransObj As TransientObjects
oTransObj = oApp.TransientObjects
Dim docAsset As Assets
docAsset = oDoc.Assets
Dim oAssetLib As AssetLibrary
oAssetLib = oApp.AssetLibraries.Item("Autodesk Darstellungs-Bibliothek") 'Autodesk Appearance Library
Dim oColor As String
oColor = "Markierung"
' Get an asset In the library
Dim oHighlightColor As Asset
Try 'Copy the asset locally.
oHighlightColor = docAsset.Item(oColor)
Catch 'or just use it if it's already local
oHighlightColor = docAsset.Add(AssetTypeEnum.kAssetTypeAppearance, "Generic", oColor, oColor)
Dim generic_highlight_color As ColorAssetValue
generic_highlight_color = oHighlightColor.Item("generic_diffuse")
generic_highlight_color.Value = oHSet.Color
End Try
'wenn fertig, starte von vorn
TheStart:
While True
Dim k As Integer
k = 1
Dim bNEW As Boolean
bNEW = True
oStartFace = oApp.CommandManager.Pick(Inventor.SelectionFilterEnum.kPartFaceFilter, "Fläche anwählen + ""Esc"" bestätigen.")
' If nothing gets selected then we're done
If oStartFace Is Nothing Then Exit While
'wenn STRG gedrückt wird, sollen bereits selektierte Flächen wieder abgewählt werden
If System.Windows.Forms.Control.ModifierKeys = System.Windows.Forms.Keys.Control Then 'STRG wird gedrückt beim Selektieren
If FaceCol.Count>0 Then
For k = 1 To FaceCol.Count
oFace= FaceCol.Item(k)
If oFace.InternalName = oStartFace.InternalName And oFace.TransientKey = oStartFace.TransientKey Then
bNEW = False
Exit For
End If
Next
End If
If bNEW = False
FaceCol.Remove(k)
oFace.Appearance = ColorCol.Item(k)
ColorCol.Remove(k)
'oHSet.Remove(oFace)
oApp.ActiveView.Update
End If
Else 'STRG wird nicht gedrückt beim selektieren
If FaceCol.Count>0 Then
For k = 1 To FaceCol.Count
oFace= FaceCol.Item(k)
If oFace.InternalName = oStartFace.InternalName And oFace.TransientKey = oStartFace.TransientKey Then
bNEW = False
Exit For
End If
Next
End If
If bNEW = True Then
FaceCol.Add(oStartFace)
ColorCol.Add(oStartFace.Appearance)
oStartFace.Appearance = oHighlightColor
'oHSet.AddItem(oStartFace)
oApp.ActiveView.Update
End If
End If
oStartFace = Nothing
End While
'Berechenen der Flächeninhalte der Selektion
Dim i As Integer
If FaceCol.Count > 0 Then
For i = 1 To FaceCol.Count
oFace = FaceCol.Item(i)
AreaCache = AreaCache + oFace.Evaluator.Area
Next
End If
If AreaCache = 0 Then Return
'Ausgabe Flächeninhalt
AreaCache = Math.Round(AreaCache * 100, 1)
InputBox("Oberfläche:", "Oberflaeche_berechnen_Multiselect", AreaCache & "mm²")
'MessageBox.Show(AreaCache & "mm²")
For i = 1 To FaceCol.Count
oFace = FaceCol.Item(i)
oFace.Appearance = ColorCol.Item(i)
oApp.ActiveView.Update
Next
'oCompDef.ClearAppearanceOverrides() 'Alle farbig veränderten Flächen werden auf Standard gesetzt
oHSet.Clear
FaceCol.Clear
ColorCol.Clear
AreaCache = 0
'End If
'if done, go to the start
GoTo TheStart
Can't find what you're looking for? Ask the community or share your knowledge.