"SelectEvents.OnPreSelect" and "SelectEvents.OnPreSelectMouseMove" come up with different "PreSelectEntity" Object

"SelectEvents.OnPreSelect" and "SelectEvents.OnPreSelectMouseMove" come up with different "PreSelectEntity" Object

arsenii_yavtushenko
Enthusiast Enthusiast
1,117 Views
12 Replies
Message 1 of 13

"SelectEvents.OnPreSelect" and "SelectEvents.OnPreSelectMouseMove" come up with different "PreSelectEntity" Object

arsenii_yavtushenko
Enthusiast
Enthusiast

Hello,

 

Ran into an issue trying to use OnPreSelectMouseMove Event to check if the object being pre-selected is a SketchLine using TypeOf Operator. 

 

Attached below are two very simple codes, identical in all respects except for handler. The code with OnPreSelect Event will correctly return "True" if it is the SketchLine that is being pre-selected, while the code with OnPreSelectMouseMove Event will return "False", even though I am attempting to pre-select the same exact line. 

 

'Using OnPreSelect Event 
    Private Sub oSelectEvents_OnPreSelect(ByRef PreSelectEntity As Object, ByRef DoHighlight As Boolean, ByRef MorePreSelectEntities As Inventor.ObjectCollection, SelectionDevice As Inventor.SelectionDeviceEnum, ModelPosition As Inventor.Point, ViewPosition As Inventor.Point2d, View As Inventor.View) Handles oSelEvents.OnPreSelect
        MsgBox(TypeOf PreSelectEntity Is SketchLine)
    End Sub
'Using OnPreSelectMouseMove Event 
    Private Sub oSelEvents_OnPreSelectMouseMove(PreSelectEntity As Object, ModelPosition As Inventor.Point, ViewPosition As Inventor.Point2d, View As Inventor.View) Handles oSelEvents.OnPreSelectMouseMove
        MsgBox(TypeOf PreSelectEntity Is SketchLine)
    End Sub

 

What's strange is the fact that with OnPreSelect Event, PreSelectEntity is referenced as ByRef, meaning that my function can change it, while with OnPreSelectMouseMove Event, it is referenced as ByVal, and trying to force it otherwise only results in an "Incompatible Signature" error. That and the description on the Help Page for PreSelectEntity Object returned by both events being different makes me wonder if it something that was done this way on purpose, despite me failing to see said purpose. 

 

In my application, I am trying to display the green dot on the line when the user moves a mouse cursor near the Midpoint, such that another object in the same sketch can be constrained to said Midpoint, and since this functionality cannot be accessed through the API, despite being present and working perfectly in Inventor, at least not in the way that I know of, I decided to create it on my own. 

 

Coming back to the issue at hand, in the past I used two events for this function - SelectEvents.OnPreSelect to know when I am over a Line, and MouseEvents.OnMouseMove to know where the Cursor is in respect to the Midpoint of the Line, to know whether it's time to display it or not. This code does work well, but it requires two separate events, and while it's really nothing to be concerned with, it started to seem wasteful ever since I discovered a OnPreSelectMouseMove Event, which makes it possible to merge both events into one, and I just couldn't resist the temptation I guess.. 

 

Which is how I got to the point explained above, the OnPreSelectMouseMove Event seems to be returning some other type of Object compared to the regular OnPreSelect Event, so now when I use the same TypeOf Operator to differentiate between Sketch Entities, it returns "False" regardless of the entity selected, and if I try to force said object to convert to a line using CType Operator, it only returns an exception. 

 

What I am trying to find out is whether PreSelectEntity Object returned by both Events is different on purpose, or whether it's just a bug that is yet to be caught. It could also be that I am doing something wrong entirely, as even though, again, I literally copy/paste the same exact code between Subs and get different results, it could still be a possibility, hence the reason for this post. 

 

If you have any information on the subject, I am all ears!

 

 

P.S. Not to derail this thread, but I also discovered two separate bugs while trying to type out this post. The first one is that if you click on the Code window that is in the post, it remains forever stuck to the cursor at half transparency, for whatever reason, below is a screenshot. 

 

1211.png

 

The second one is that the Window will keep dropping down to the Post Button the moment I type any character in the Post Window if I scroll down past a certain point, the reasons for it are just as unclear to me. 

Accepted solutions (2)
1,118 Views
12 Replies
Replies (12)
Message 2 of 13

WCrihfield
Mentor
Mentor

Hi @arsenii_yavtushenko.  Interesting observation.  My first advise would be to switch from using MsgBox or MessageBox.Show, to using either the iLogic Logger resources or some other similar form of 'logging' the feedback that does not interrupt the code during the events.  When we call a MsgBox or MessageBox.Show in our iLogic rule codes, that usually 'pauses' the code execution until we click OK (or similar) on that message dialog, then allows code execution to resume.  Using a logger will not interrupt code execution, and allows for a more fluid result.  The reason for that first variable being declared and described differently between the two methods is that the SelectEvents.OnPreSelect event allows us to 'change' that entity to another entity [used to enable the built-in' 'Select Other' functionality], thus that variable is 'Read/Write' (input/output).  That event also gives us the ability to specify False for the 'DoHighlight' variable, which will eliminate that entity from pre-selection before it ever happens.  Then its 'MorePreSelectEntities' variable is also Read/Write (input), while the rest of its variables are ReadOnly (output only).  The SelectEvents.OnPreSelectMouseMove first variable is 'ReadOnly', thus it can only be 'ByVal', and does not allow us to change that entity (output only).  And the rest of its variables are the same, so we can not change anything about its functionality, but can only observe it or use it to 'trigger' some other process to start when it happens passes our checks.  As for why both do not recognize the same sketch line, that may be due to both events being used at virtually the same time, but perhaps the 'OnPreSelect' may be catching it first, and not utilizing the 'DoHighlight' variable (setting its value to True, to ensure it gets pre-selected) of the 'OnPreSelect' event.  You could try just observing the one 'OnPreSelectMouseMove' event, without the other event being enabled at all, to see if you then are able to recognize the sketch lines.  And changing the form of feedback may play into that also, but not sure.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 13

arsenii_yavtushenko
Enthusiast
Enthusiast

Thanks for the reply!

 

[EDIT]: Forgot to mention, I am using Visual Studio for this project, not iLogic, if that is relevant at all.

 

The reason I used MsgBox in the code above is just to make it easier to understand, and the result immediately obvious, but yes, I understand that tripping a MsgBox each time the cursor is near a line is far from ideal. In the actual program that I am making, in place of a MsgBox, I have a TypeOf Operator that checks if the selected SketchEntity is, in fact, a SketchLine before proceeding with the rest of the code in a separate routine.

 

While the code below works perfectly well to recognize that it is the SketchLine being pre-selected if I use SelectEvents.OnPreSelect Event...

 

'Using OnPreSelect Event, OnPreSelectMouseMove Event removed.
    Private Sub oSelectEvents_OnPreSelect(ByRef PreSelectEntity As Object, ByRef DoHighlight As Boolean, ByRef MorePreSelectEntities As Inventor.ObjectCollection, SelectionDevice As Inventor.SelectionDeviceEnum, ModelPosition As Inventor.Point, ViewPosition As Inventor.Point2d, View As Inventor.View) Handles oSelectEvents.OnPreSelect
        If TypeOf PreSelectEntity Is SketchLine Then oSketchLine = CType(PreSelectEntity, SketchLine) 'TypeOf returns "True" if the SketchLine is selected, and oSketchLine, declared outside, does return a SketchLine.
    End Sub

 

...if I delete the Event above and try using SelectEvents.OnPreSelectMouseMove Event in its place to do the same thing, it fails to recognize the same Line that is in the same Sketch.

 

'Using OnPreSelectMouseMove Event, OnPreSelect Event removed.
    Private Sub oSelEvents_OnPreSelectMouseMove(PreSelectEntity As Object, ModelPosition As Inventor.Point, ViewPosition As Inventor.Point2d, View As Inventor.View) Handles oSelectEvents.OnPreSelectMouseMove
        If TypeOf PreSelectEntity Is SketchLine Then oSketchLine = CType(PreSelectEntity, SketchLine)'TypeOf returns "False" regardless of what is being selected, and oSketchLine is never used.
    End Sub

 

Those codes are also not designed to be run at the same time, they are two separate scripts to be used in separate instances, they should not be placed at the same time. In my case, I was planning to use OnPreSelectMouseMove Event to fully replace the OnPreSelect Event, as I have to use the latter in combination with MouseEvents.onMouseMove Event, which, while it does work perfectly, is admittedly more clunky than having just one Event handle everything at once, which I assumed was the purpose of the OnPreSelectMouseMove Event in the first place..

 

Reading your reply, I wonder if it was the attempt to make a PreSelectEntity Object Read Only instead of Read/Write is what lead to this strange behavior. I am still not quite sure if OnPreSelectMouseMove Event failing to recognize the SketchLine is a bug or an actual feature that I am missing out on, hence the reason for this thread. Either way though, it does happen on the Autodesk side, so there is little I can do about it.. 

 

Again, thanks for the reply!

0 Likes
Message 4 of 13

lauri_barnhart
Autodesk
Autodesk

Hi @arsenii_yavtushenko,

I wanted to check in and see if you still needed assistance, or if you found a solution to your question already? Let us know if you need further assistance by providing an update or if you have found a solution, please share it with the community so other members who may have the same question could learn from your experience.

All the best,

Lauri | Community Manager


Lauri | Community Manager
0 Likes
Message 5 of 13

WCrihfield
Mentor
Mentor

I meant to get back to this post (at some point), but have been very busy with many other things going on at work lately.  One little detail that came to mind that may (or may not) be helpful in this situation is the SelectEvents.MouseMoveEnabled Property, which I assume should be set to True.  But the Inventor API help page for that Property mentions that is set to True by default, so that may not be a factor, just mentioning it, since it seemed relevant.  It may also be relevant to mention that there are two different sets of Events with similar names and functionalities to be aware of.  There is the set under the Inventor.InteractionEvents, then its child SelectEvents object, where the InteractionEvents must be 'created' then 'started/activated'.  Then there are also some (OnPreSelect, OnSelect, OnUnSelect, OnStopPreSelect) under the Inventor.UserInputEvents, which can be confusing.  Although, there is only one Event named 'OnPreSelectMouseMove', which is under the InteractionEvents.SelectEvents.  The main difference being that one set is only effective during an artificially induced 'Interaction Session', while the other set can be effective all the time.  Although I have used the OnSelect and OnPreSelect events in some of my externally referenced iLogic-based resources recently, I have yet to conduct some local testing with the OnPreSelectMouseMove Event to confirm (or attempt to better understand / explain) the observed behavior.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 13

arsenii_yavtushenko
Enthusiast
Enthusiast

I do apologize for the delay in response, I didn't have access to the project for a few days. 

 

I have tried setting SelectEvents.MouseMoveEnabled to True manually now that you mentioned it, but that had no result at all. 

 

It appears that both MouseMoveEnabled property, as well as the difference in Events that you mentioned, would rather result in no SelectionEvent triggering at all, instead of the Event failing to recognize a certain feature, which is what makes this issue so puzzling, at least to me. In my case, both SelectEvents.OnPreSelect and SelectEvents.OnPreSelectMouseMove appear to be functioning perfectly, the only issue is that the latter fails to distinguish a Sketch Line from any other Object. 

 

The more I look for the information on this topic, the more I wonder if it is indeed an issue with the way PreSelectEntity Object is implemented for both Events, as we have clearly established before that they are not the same for each Event. Seeing how rare either of those features is used in publicly available projects, no wonder nobody, as far as I can tell, had a chance to catch up with it before.. 

 

Again, I do appreciate your help with this!

0 Likes
Message 7 of 13

WCrihfield
Mentor
Mentor

Hi @arsenii_yavtushenko.  I finally got to 'carve out' a chunk of time this morning to do some testing on this topic.  I think I figured it out too.  During my short testing window on a single part document containing some sketch geometry and single extruded solid body, the parameter named 'PreSelectEntity' within the 'OnPreSelectMouseMove' Event 'handler' always directly represented (or Is) an Inventor.ObjectsEnumerator Type Object.  I first tested if it 'Is Nothing', which it always passed.  Then I used the 'TypeName' Function, along with a feedback Log, to write out what Type of object it was.  Once I figured that out, I started testing with TypeOf operator to see if it was an ObjectsEnumerator.  When true, I created that Type of variable and set that as it Value.  Then I checked its Count property, to make sure it was not 'Empty'.  Then I used some more 'Log' entries which were also utilizing the TypeName function to report the Type name of each object in the collection.  In my tests there was always just one object in the collection.  And yes, most of the time it was either SketchLine, SketchArc, or Face Type objects.  Interestingly, I don't think it ever reported an Edge though.  But it may have something to do with the limited geometry in my part, and the fact that I was using a selection filter which was set to 'kSketchCurveLinearFilter'.  But I was not really 'selecting' anything either, just moving my mouse around within Inventor's graphics window while the InteractionEvents session was active, and watching the iLogic Logger window providing live feedback while doing so.  Then copying that entire Log into a new Notepad tab, so I could read down through it all carefully.

I don't know if it matters, but I was using a combination of 3 different resources during my testing.  The whole process started from an 'internal' iLogic rule that was created right within the PartDocument being tested on.  Then that rule was 'referencing' (with AddVbFile) two other external rule files which were set-up with the 'Straight VB Code' option turned on, and represented custom Class blocks of code.  One for managing all the EventHandlers for the DocumentEvents Events, primarily as a back-up, to help eliminate any lingering event handlers when the document closes, just in case.  The other external resource also represented a custom Class, which manages all the EventHandlers for the InteractionEvents and SelectEvents.  Each allow me to start or stop specific 'handlers', and provide a pointer to an 'Action' (Sub Method) for it to run within the event handlers when the events get triggered.  I don't have 100% of the minor bugs ironed out of those external resources, but they worked OK anyways.  I hope this helps.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 13

arsenii_yavtushenko
Enthusiast
Enthusiast

Sorry, I am not particularly versed in iLogic, I moved straight to the vb.net environment, so I may be missing some of the points you mentioned. 

 

I wrote this simple and not-so-pretty code attached below to see if the OnSelectMouseMove Event will behave any different in the iLogic environment, but I got the same result as I have with vb.net add-in, this command still returns False every time I hover over a SketchLine. 

 

Class ThisRule

Dim oBool As Boolean

	Sub Main
		Dim oIE As InteractionEvents = ThisApplication.CommandManager.CreateInteractionEvents
		Dim oSE As SelectEvents = oIE.SelectEvents
		
		oIE.InteractionDisabled = False
		
		With oSE		
			.MouseMoveEnabled = True
			.SingleSelectEnabled = True
			.Enabled = True
		End With
			
		AddHandler oSE.OnSelect, AddressOf oSE_OnSelect
		AddHandler oSE.OnPreSelectMouseMove, AddressOf oSE_OnPreSelectMouseMove
		
        oBool = True
		oIE.Start()
		
	    Do While oBool
			ThisApplication.UserInterfaceManager.DoEvents()
	    Loop
	
	    oIE.Stop()
	
	    oSE.MouseMoveEnabled = False
	    oIE = Nothing
	    oSE = Nothing	
	End Sub
	
	Sub oSE_OnSelect(ByVal JustSelectedEntities As Inventor.ObjectsEnumerator, ByVal SelectionDevice As Inventor.SelectionDeviceEnum, ByVal ModelPosition As Inventor.Point, ByVal ViewPosition As Inventor.Point2d, ByVal View As Inventor.View)
	    oBool = False
	End Sub
	
            'This event still returns "False" into the iLogic Log Window
	Sub oSE_OnPreSelectMouseMove(PreSelectEntity As Object, ModelPosition As Point, ViewPosition As Point2d, View As View) 
		Logger.Info(TypeOf PreSelectEntity Is SketchLine)
	End Sub
End Class

 

If your result was in any way different from mine, I would appreciate it if you can share your version of the iLogic Rule, so I can check if it performs any differently from mine. 

 

Again, thanks a lot for your help!

0 Likes
Message 9 of 13

WCrihfield
Mentor
Mentor

There was nothing particularly unique about my event handler methods or the iLogic environment.  I was just using some different testing techniques.  Within the OnPreSelectMouseMove event handler method, instead of only testing with TypeOf operator comparisons, I first used the TypeName function (see Link below) to figure out exactly which Type of object the PreSelectEntity was, which got written in the 'Logger' entries.  I use that function a lot during the early trial & error testing phases of the iLogic based solutions I develop, to help with object Type identification and prediction, because it will still work even if the variable was never assigned a value, when it will still return the word "Nothing", instead of fail.  In that last example code you just posted, if you replaced this line:

Logger.Info(TypeOf PreSelectEntity Is SketchLine)

...with this line:

Logger.Info("OnPreSelectMouseMove -> PreSelectEntity TypeName = " & TypeName(PreSelectEntity))

Just keep in mind that the iLogic Logger tab must be visible (but not necessarily the active tab) before running the test, so that it will record the Logger feedback while the test is running.  Then after the test, review the Log entries in that window with that starting text to find out what Type of object it was.  But as stated in my previous post, I found out that the 'PreSelectEntity' was always an Inventor.ObjectsEnumerator Type object, which is a type of collection defined within the Inventor API.  Because of this, the PreSelectEntity (an ObjectsEnumerator) itself can never be a SketchLine object, which is why your 'TypeOf' tests are always failing.  But that collection can definitely 'contain' a SketchLine within it, or other types of objects.  And in my testing, that collection only ever contained one object (of varying Types).  I don't know if that will always be the case though.

 https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.information.typename 

Below is the actual block of code I was using for that event handler, but it contains some stuff defined outside of that method, either at Class level or from the routine consuming the Class instance.  In this example the variable named '_GotLogger' is a Boolean that gets set within the 'New' method, indicating if the consumer supplied the 'Optional' iLogic Rule Object named 'Logger' (an iRuleLogger Interface).  Then the variable named '_Logger' represents that iLogic Logger object, if a value was set to it.  The variable named '_OnPreSelectMouseMove_Action' represents a System.Action Type object, which may or may not point to a consumer specified Sub routine with no input parameters that the consumer wants to get called to run within that event handler method, which is why it is within a Try...Catch...End Try statement.

	Private Sub OnPreSelectMouseMove(ByVal PreSelectEntity As Object, _
		ByVal ModelPosition As Inventor.Point, _
		ByVal ViewPosition As Inventor.Point2d, _
		ByVal invView As Inventor.View)
		
		Dim bIsNothing As Boolean = (PreSelectEntity Is Nothing)
		Dim bIsObjectsEnumerator As Boolean = ((Not bIsNothing) AndAlso
			(TypeOf PreSelectEntity Is Inventor.ObjectsEnumerator))
		Dim oObjsEnum As Inventor.ObjectsEnumerator = Nothing
		If bIsObjectsEnumerator Then oObjsEnum = PreSelectEntity
		Dim bIsEmpty As Boolean = (bIsObjectsEnumerator AndAlso (oObjsEnum.Count = 0))
		
		If _GotLogger Then
			Dim sReport As String = "InteractionEvents.SelectEvents.OnPreSelectMouseMove Event Triggered."
			If bIsNothing Then
				sReport &= vbCrLf & "PreSelectEntity Is Nothing."
			ElseIf bIsObjectsEnumerator Then
				sReport &= vbCrLf & "PreSelectEntity Is An Inventor.ObjectsEnumerator."
				If bIsEmpty Then
					sReport &= vbCrLf & "The ObjectsEnumerator was Empty."
				Else
					sReport &= vbCrLf & "The ObjectsEnumerator contained the following:"
					For Each oObj In oObjsEnum
						sReport &= vbCrLf & " - " & TypeName(oObj)
					Next 'oObj
				End If
			Else
				sReport &= vbCrLf & "PreSelectEntity TypeName = " & TypeName(PreSelectEntity)
			End If
			_Logger.Info(vbCrLf & sReport & vbCrLf)
		End If
		
		Try : _OnPreSelectMouseMove_Action : Catch : End Try

	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)

Message 10 of 13

arsenii_yavtushenko
Enthusiast
Enthusiast

Sorry for the delay. 

 

Thanks a lot for your help! I did try the TypeName Function before, but with my lack of experience, I haven't paid that close of an attention to it, and now that you explained it in details, I know that it was rather foolish of me.. 

 

That does explain why it would never differentiate a SketchLine from any other object that is pre-selected, which is a little unfortunate, seeing that this issue can only be on the part of Autodesk, whether intentional or not. 

 

Here's hoping that it will get resolved at some point, but until then, I would have to stick with two separate Events.. 

 

P.S. It is a little strange that Autodesk doesn't provide a direct way to access the Midpoint of a line, like they do with a Coincident Constraint, while I understand that this Midpoint doesn't even exist until it is created, it would still help if they could provide a convenient way of creating it, without having to do it manually. Just an idea.. 😊

 

Thanks again!

0 Likes
Message 11 of 13

WCrihfield
Mentor
Mentor
Accepted solution

It seems like you could still use this one event, because we can still get the SketchLine object from that event handler method, we just have to use a little more code to get it than with the other methods.  See the alternative example of that event handler method blow.  In this example, it 'expects' that the PreSelectEntity will be an Inventor.ObjectsEnumerator, gets that collection, then looks within that collection for the SketchLine object.  The variable for the SketchLine object could be declared outside that method, like at the Class level, then its value gets set within that method.  And when setting the value of that variable within the event handler method, you could also call your other method which 'uses' that SketchLine to extract its 'mid point' (SketchLine.Geometry.MidPoint is a Point2d that can be used), and I assume either use ClientGraphics to show where that location is on that Line, or gets that line's 'parent' sketch, then creates a SketchPoint there, or create a WorkPoint there, or whatever.

Private Sub OnPreSelectMouseMove(ByVal PreSelectEntity As Object, _
	ByVal ModelPosition As Inventor.Point, _
	ByVal ViewPosition As Inventor.Point2d, _
	ByVal invView As Inventor.View)

	If PreSelectEntity Is Nothing Then Return
	Dim oObjsEnum As Inventor.ObjectsEnumerator = Nothing
	If (TypeOf PreSelectEntity Is Inventor.ObjectsEnumerator) Then
		oObjsEnum = CType(PreSelectEntity, Inventor.ObjectsEnumerator)
	End If
	If oObjsEnum Is Nothing OrElse oObjsEnum.Count = 0 Then Return
	'Dim oSketchLine As Inventor.SketchLine = Nothing
	For Each oObj In oObjsEnum
		If (TypeOf oObj Is Inventor.SketchLine) Then
			oSketchLine = CType(oObj, Inventor.SketchLine)
			'Dim oMidPoint As Inventor.Point2d = oSketchLine.Geometry.MidPoint
			'<<< call your other method to run here,
			'which shows the greed dot at its MidPoint'>>>
		End If
	Next 'oObj
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)

Message 12 of 13

WCrihfield
Mentor
Mentor
Accepted solution

I just created an entire working example inside of an iLogic rule that seems to function the way you wanted (from what I understand).  Within this rule I created a custom Class to handle the InteractionEvents,  SelectEvents, and the events of the simple MiniToolbar I included also.  Just added the MiniToolbar to provide an additional way to get back out of the interaction session (besides using the Esc key).  In my testing, I noticed that if I only 'handled' the OnPreSelectMouseMove Event (without OnSelect or OnPreSelect), and did not handle the OnStopPreSelect Event, it would leave the 'mid-point marker' (MPM) on the previously preselected SketchLine while my mouse was away from it, and it would only go away when it was redrawn for the next preselected SketchLine.  So, I had to also include handling the OnStopPreSelect Event, using that to 'hide' the MPM.  The Class does include a block of code for the OnPreSelect Event, but it is currently commented out, along with the Add/Remove Handler lines for it.

The 'regular' part of my iLogic rule (the ThisRule Class & Sub Main...End Sub block at the top) creates an instance of that custom Class using its 'New' method, where it passes in a reference to the active Inventor.Application object.  Then it calls its 'StartInteractionSession' method, which creates everything else needed, then starts the interaction session, then once that session ends, eliminates most of that stuff to clean-up.  When ran, and I preselect any linear sketch lines, it shows an 'X' (the MPM - its shape can be customized) where the midpoint of that line is, then when my mouse moves away from that line, the MPM goes away again, as intended.

See attached text file containing the whole iLogic rule code example that was working good for me in my testing.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 13 of 13

arsenii_yavtushenko
Enthusiast
Enthusiast

I do apologize for the delay once more, but I am back with some great news!

 

I actually got it to work with just the OnPreSelectMouseMove Event, after making the program look through all of the ObjectEnumerator Objects, just like you described in the post earlier, below is an entire code that I came up with for a Visual Studio that I am using, in case if someone runs into this issue at some point, narrated to the best of my abilities..  

 

To use it, create a New Class and simply paste the code below in there.  

 

Option Explicit On
Option Strict On

Imports Inventor

Public Class DisplayPoint
    Private WithEvents oIntEvents As InteractionEvents
    Private WithEvents oSelEvents As SelectEvents

    Private bSelectMidpoint As Boolean
    Private bStillSelecting As Boolean

    Private oGraphNode As GraphicsNode
    Private oGraphCordSet As GraphicsCoordinateSet

    'Function to be Called in the Main Porgram
    Public Function StartSelect(ByVal Filter As SelectionFilterEnum, ByVal Text As String, ByVal Sketch As PlanarSketch) As SketchEntity
        oIntEvents = g_inventorApplication.CommandManager.CreateInteractionEvents
        oSelEvents = oIntEvents.SelectEvents

        oIntEvents.InteractionDisabled = False 'Enable Interactions
        oIntEvents.StatusBarText = Text 'Text shown when Selection is Active

        With oSelEvents
            .Enabled = True
            .ResetSelections()
            .AddSelectionFilter(Filter) 'Filter Objects to be Selected
            .SingleSelectEnabled = True
            .MouseMoveEnabled = True
        End With

        bStillSelecting = True

        Dim oIntGraph As InteractionGraphics = oIntEvents.InteractionGraphics
        Dim oCltGraph As ClientGraphics = oIntGraph.OverlayClientGraphics

        'Create new Overlay Graphics Node, such that the Midpoint can be Displayed over the Line
        If oCltGraph.Count <= 0 Then
            oGraphNode = oCltGraph.AddNode(0)
            oGraphCordSet = oIntGraph.GraphicsDataSets.CreateCoordinateSet(0)
        End If

        'Start the Selection
        oIntEvents.Start()

        'Pause the execution of the Code until the Selection is made
        Do While bStillSelecting
            g_inventorApplication.UserInterfaceManager.DoEvents()
        Loop

        'Store Selected Entities
        Dim oSelectedEnts As ObjectsEnumerator = oSelEvents.SelectedEntities

        'Selection is made, stop the Selection Process
        oIntEvents.Stop()

        'Clean up afterwards
        oSelEvents = Nothing
        oIntEvents = Nothing
        oCltGraph.Delete()

        Try
            'Check if anything at all was Selected
            If oSelectedEnts.Count > 0 Then
                Dim oSelLine As SketchLine

                'Check if it was the Line that got Selected
                If TypeOf oSelectedEnts.Item(1) Is SketchLine Then
                    oSelLine = CType(oSelectedEnts.Item(1), SketchLine)

                    'Check if the Midpoint was Shown when the Selection was made
                    If bSelectMidpoint = True Then

                        'If True, create a Midpoint on the Line that was Selected...
                        Dim oRefPoint As SketchPoint = Sketch.SketchPoints.Add(g_inventorApplication.TransientGeometry.CreatePoint2d(0, 0), False)

                        '...constrain it to said Line...
                        Sketch.GeometricConstraints.AddMidpoint(oRefPoint, oSelLine)

                        '...and return the Point that was just created
                        Return CType(oRefPoint, SketchEntity)
                    Else
                        'If False, return just the Line
                        Return CType(oSelLine, SketchEntity)
                    End If
                Else
                    'If it wasn't the Line, return just the SketchEntity that was Selected
                    Return CType(oSelectedEnts.Item(1), SketchEntity)
                End If
            Else
                Return Nothing
            End If
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

        Return Nothing
    End Function

    'Once the Object is Selected
    Private Sub oSelectEvents_OnSelect(ByVal JustSelectedEntities As Inventor.ObjectsEnumerator, ByVal SelectionDevice As Inventor.SelectionDeviceEnum, ByVal ModelPosition As Inventor.Point, ByVal ViewPosition As Inventor.Point2d, ByVal View As Inventor.View) Handles oSelEvents.OnSelect
        bStillSelecting = False
    End Sub

    'If the Selection Process is Terminated with an Escape Button
    Private Sub oInteractEvents_OnTerminate() Handles oIntEvents.OnTerminate
        bStillSelecting = False
    End Sub

    'Once the User Hovers over the Object
    Private Sub oSelEvents_OnPreSelectMouseMove(PreSelectEntity As Object, ModelPosition As Point, ViewPosition As Point2d, View As Inventor.View) Handles oSelEvents.OnPreSelectMouseMove
        Dim oMidPoint As Point2d = Nothing

        Try
            'Distance between the Midpoint and the Mouse Pointer at which to Show the Point
            'Right now it is set to show up at the same Distance as when the whole Object is being Selected
            Dim oDistance As Double = 0.05

            Dim oObjsEnum As ObjectsEnumerator
            Dim oSketchLine As SketchLine = Nothing

            'The part that made it possible to use OnPreSelectMouseMove Event, courtesy of WCrihfield
            'Check if the Object Selected is ObjectsEnumerator
            If (TypeOf PreSelectEntity Is ObjectsEnumerator) Then
                oObjsEnum = CType(PreSelectEntity, ObjectsEnumerator)

                'If so, look through the ObjectsEnumerator to see if there are any SketchLines in there
                'Find the Line and Exit the Loop right after
                For Each oObj In oObjsEnum
                    If (TypeOf oObj Is SketchLine) Then oSketchLine = CType(oObj, SketchLine) : Exit For
                Next
            Else
                MsgBox("Exited")
                Exit Sub
            End If

            'Check that the Line was Selected
            If Not oSketchLine Is Nothing Then
                oMidPoint = oSketchLine.Geometry.MidPoint

                'Find whether the Cursor is close enough to the Midpoint of the Line to Display the Point over it
                If Math.Abs(oMidPoint.X - ModelPosition.X) <= oDistance AndAlso Math.Abs(oMidPoint.Y - ModelPosition.Y) <= oDistance Then
                    Dim aDouble(3) As Double
                    aDouble(0) = oMidPoint.X
                    aDouble(1) = oMidPoint.Y
                    aDouble(2) = 0

                    'Select where to show the Point
                    oGraphCordSet.PutCoordinates(aDouble)

                    'Create the Point
                    Dim oPointGraph As PointGraphics = oGraphNode.AddPointGraphics

                    oPointGraph.CoordinateSet = oGraphCordSet
                    oPointGraph.PointRenderStyle = PointRenderStyleEnum.kEndPointStyle 'Select the Style of Point to Show
                    oPointGraph.BurnThrough = True 'Pick whether to display it over everything else

                    oGraphNode.Visible = True 'Make sure it's Visible
                    oIntEvents.InteractionGraphics.UpdateOverlayGraphics(g_inventorApplication.ActiveView) 'Update

                    'Set the Flag that the User is about to Select a Midpoint, not the entire Line
                    bSelectMidpoint = True
                    Exit Sub
                End If
            End If

            'If the Mouse Cursor is too far from the Midpoint, stop Displaying it
            Call RemoveDot()
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    'Once the Mouse Cursor is outside of the PreSelect Range
    Private Sub oSelEvents_OnStopPreSelect(ModelPosition As Point, ViewPosition As Point2d, View As Inventor.View) Handles oSelEvents.OnStopPreSelect
        Call RemoveDot()
    End Sub

    'Sub to Delete the Midpoint if it's not being called for
    Private Sub RemoveDot()
        'Delete Graphic Node with the Midpoint in it
        If oGraphNode.Count > 0 Then oGraphNode.Item(1).Delete()

        'Disable Visibility, Update Current View
        oGraphNode.Visible = False
        oIntEvents.InteractionGraphics.UpdateOverlayGraphics(g_inventorApplication.ActiveView)

        'Set the Flag that the User is now selecting the Entire Line, not a Midpoint
        bSelectMidpoint = False
    End Sub
End Class

 

Once the New Class is created, to actually Use it in the Main Program, call it with the code below. 

 

'Create the instance of a Class
Dim oCenterSearch As New DisplayPoint

'Call the Function created in said Class
'The Function comes with 3 Variables - 
'  1). Filter - Selection Filter (what to make Selectable)
'  2). Text - Title that is Displayed when Selection is Active
'  3). Sketch - Sketch in which the Selection is being made, it is there to create Midpoint as needed
Dim oSketchEntity As SketchEntity = oCenterSearch.StartSelect(Filter, Text, Sketch)

 

I'm not exactly convinced that it ended up being simpler, but it doesn't require the use of OnMouseMove Event now, which is exactly what I was after when I created this thread. Everything works exactly as it should, and I now get to know that I can still dig objects out of the ObjectsEnumerator, which I somehow managed to miss completely. 

 

Again, thanks a lot for your assistance, hopefully it will be useful to someone else down the line!