iLogic – Occurrence Selection Filter In Drawings

Guest Post by Jhoel Forshav

When developing iLogic rules, it’s quite common that you’ll need to prompt the user to pick something from the model window. For example, it could be a face, a component occurrence, a model edge etc. For most of the different types of selections your code might require, there’s a corresponding selection filter to use as an argument in the function CommandManager.Pick(Filter As SelectionFilterEnum, PromptText As String).

One filter however, that I tend to see questions about from time to time on the Inventor Customization Forum is the one to pick a component occurrence represented on a drawing sheet.

In short, there is no selection filter for this. There is however ways to reach the component occurrence by entities that you can pick by iLogic code on the sheet – DrawingCurveSegment.

We cannot use CommandManager.Pick in this case, but there are other ways to reach the same result.

The iLogic code below is an example I wrote to use the DrawingCurveSegment-filter, access the ComponentOccurrence it represents and through that every other DrawingCurveSegment in the same view that represents the same ComponentOccurence. Using the SelectEvents object and its event handlers, we can then have the application highlight every DrawingCurveSegment that represents the same ComponentOccurrence as the one we’re hovering above during the SelectEvent, making it appear as if we’re actually using a ComponentOccurrence-filter.

The property DoHighlight in the OnPreselect-event doesn’t just control whether the preselected collection of entities should be highlighted, it also controls whether it should be selectable. Therefore we can make only DrawingCurveSegments that represents a model edge selectable.

The path from a DrawingCurveSegment to the ComponentOccurrence will looks like this:

DrawingCurveSegment.Parent(=DrawingCurve).ModelGeometry(=Edge).Parent(=SurfaceBodyProxy).Parent(=ComponentOccurrence).

If this path fails to return an object of type ComponentOccurrence we’ll know that the DrawingCurveSegment doesn’t represent a ComponentOccurrence, so a simple Try-Catch statement will be an effective way to determine if DoHighlight should be true or false in our OnPreselect sub.

Click me for HD version

Here is the iLogic code:

Sub Main
	'iLogic Code by Jhoel Forshav - originally posted at https://clintbrown.co.uk/ilogic-occurrence-selection-filter-in-drawings/
	Dim oSelect As New SelectClass
	Dim oOcc As ComponentOccurrence = oSelect.SelectOccurrence(ThisApplication)
	oSelect = Nothing
	If IsNothing(oOcc) Then Exit Sub
	MessageBox.Show("You have picked: " & oOcc.Name, "Pick part", MessageBoxButtons.OK, _
	MessageBoxIcon.Information)
End Sub


Class SelectClass

	Private WithEvents oInteractEvents As InteractionEvents
	Private WithEvents oSelectEvents As SelectEvents
	Private bTooltipEnabled As Boolean
	Private ThisApplication As Inventor.Application
	Private SelectedOcc As ComponentOccurrence
	Private stillSelecting As Boolean = True

	Public Function SelectOccurrence(oApp As Inventor.Application)
		ThisApplication = oApp
		oInteractEvents = ThisApplication.CommandManager.CreateInteractionEvents
		oInteractEvents.InteractionDisabled = False
		oSelectEvents = oInteractEvents.SelectEvents
		oSelectEvents.AddSelectionFilter(SelectionFilterEnum.kDrawingCurveSegmentFilter)
		oSelectEvents.WindowSelectEnabled = False
		bTooltipEnabled = ThisApplication.GeneralOptions.ShowCommandPromptTooltips
		ThisApplication.GeneralOptions.ShowCommandPromptTooltips = True
		oInteractEvents.StatusBarText = "Pick part occurrence."
		oInteractEvents.Start()
		AppActivate(ThisApplication.Caption)
		While stillSelecting
			ThisApplication.UserInterfaceManager.DoEvents()
		End While
		Return SelectedOcc
	End Function

	Private Sub oInteractEvents_OnTerminate() Handles oInteractEvents.OnTerminate
		ThisApplication.GeneralOptions.ShowCommandPromptTooltips = bTooltipEnabled
		oSelectEvents = Nothing
		oInteractEvents = Nothing
		stillSelecting = False
	End Sub

	Private Sub oSelectEvents_OnPreselect(ByRef PreSelectEntity As Object, ByRef DoHighlight As Boolean, _
		ByRef MorePreSelectEntities As ObjectCollection, ByVal SelectionDevice As SelectionDeviceEnum, _
		ByVal ModelPosition As Point, ByVal ViewPosition As Inventor.Point2d, _
		ByVal View As Inventor.View) Handles oSelectEvents.OnPreselect
		Try
			Dim oCurves As DrawingCurvesEnumerator = DirectCast(PreSelectEntity, DrawingCurveSegment) _
			.Parent.Parent.DrawingCurves(DirectCast(PreSelectEntity, DrawingCurveSegment) _
			.Parent.ModelGeometry.Parent.Parent)
			Dim oCol As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
			For Each oCurve As DrawingCurve In oCurves
				For Each oSeg As DrawingCurveSegment In oCurve.Segments
					If oSeg IsNot PreSelectEntity Then oCol.Add(oSeg)
				Next
			Next
			MorePreSelectEntities = oCol
			DoHighlight = True
		Catch
			DoHighlight = False
		End Try

	End Sub

	Private Sub oSelectEvents_OnSelect(ByVal JustSelectedEntities As ObjectsEnumerator, _
		ByVal SelectionDevice As SelectionDeviceEnum, ByVal ModelPosition As Point, _
		ByVal ViewPosition As Point2d, ByVal View As Inventor.View) Handles oSelectEvents.OnSelect
		SelectedOcc = DirectCast(JustSelectedEntities.Item(1), DrawingCurveSegment) _
		.Parent.ModelGeometry.Parent.Parent
		ThisApplication.CommandManager.StopActiveCommand
	End Sub

End Class

About the Author:

Jhoel Forshav has a Bachelor of Science degree in Mechanical Engineering and a of Master of Science degree in Engineering – Design and Product Development.

He graduated from Linköping University in 2016 and works for a Swedish company that creates industrial steel products. Jhoel’s role at the company is best explained as that of the CAD-expert, automating processes through Addins, iLogic rules and standalone applications for Inventor. Jhoel oversees the CAD procedures and helps manage the Vault.

Jhoel is very active on the Inventor Customization forum and has been an Autodesk Expert Elite member since September 2020.

Autodesk Forums | LinkedIn | Blog