solved: selecting the wrong element

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
mfasano
Posts: 122
Joined: Wed Apr 11, 2018 12:31 pm

solved: selecting the wrong element

Post by mfasano »

Hello;
I am running version 17 on a Mac running MacOs v. 10.12.6

I am trying to select particular elements to a part (faces and edges), with a mouse click. I seem to be getting the previous element I selected. I want the one that shows up in the selection panel when I click on it.

the first item I select after starting the macro I get this error.
<type 'exceptions.IndexError'>
Traceback (most recent call last):
File "/Users/fasa02/Documents/freecad/FreeCad_macros/test_macro.FCMacro", line 18, in subselect
element_ = SubElement[0].SubElementNames[0] # name of 1 element selected
IndexError: list index out of range
after making the next selection I get the first one I selected, and only the previous one with every other selection



Code: Select all

import Part, FreeCAD, PartGui, FreeCADGui
from FreeCAD import Base, Console


#App.newDocument()

 
#This class logs any mouse button events. As the registered callback function fires twice for 'down' and
#'up' events we need a boolean flag to handle this.


class ViewObserver:
   def subselect(self, info):
       DOWN = (info["State"] == "DOWN")
       
       if (DOWN):
#           try:
               SubElement = FreeCADGui.Selection.getSelectionEx()                    # sub element name with getSelectionEx()
               element_ = SubElement[0].SubElementNames[0]                           # name of 1 element selected
               App.Console.PrintMessage("elementSelec   : "+str(element_)+"\n\n")     
#               actview.removeEventCallback("SoMouseButtonEvent",c)  
#           except:
#               App.Console.PrintMessage("Oups"+"\n\n")     


actview=Gui.activeDocument().activeView() 


o = ViewObserver()
c = actview.addEventCallback("SoMouseButtonEvent",o.subselect) 

#  actview.removeEventCallback("SoMouseButtonEvent",c) 
Also, How do I stop a macro from running. if I make a change to a macro, save it, then run it again, it seems both versions are running. The only way I have found to end the old one is close the part, reopen it and then run the macro.

Thanks,
Last edited by mfasano on Tue Nov 27, 2018 3:07 pm, edited 1 time in total.
TheMarkster
Veteran
Posts: 5513
Joined: Thu Apr 05, 2018 1:53 am

Re: selecting the wrong element

Post by TheMarkster »

You get the previous element because it's still the current selection. (FreeCAD hasn't had time yet to make the object you just clicked the current selection.) Use getPreselection() instead of getSelectionEx() if you just want to know which object was clicked.

To avoid exceptions you can check that you have something to work with before trying to access it:

Code: Select all

       if (DOWN):
               pre = FreeCADGui.Selection.getPreselection()
               if pre:
                   if len(pre.SubElementNames)!= 0:
                       FreeCAD.Console.PrintMessage(pre.ObjectName+","+pre.SubElementNames[0]+"\n")
If you need that object to be the current selection you can manually make it the current selection.

Code: Select all

FreeCADGui.Selection.addSelection(pre.Object,pre.SubElementNames[0])
(But I haven't tested this very extensively.)

After the macro finishes the observer is still installed and is still getting called and is still doing its thing. You just need to provide some means of removing the observer, such as by detecting AltDown (if that works on MacOS) or whatever.

Code: Select all

       if info["AltDown"]:
           actview.removeEventCallback("SoMouseButtonEvent",c)
           FreeCAD.Console.PrintMessage("Observer removed. \n\n")
           return

You can get some additional information about the objects currently under the cursor position:

Code: Select all

                   v = FreeCADGui.ActiveDocument.ActiveView
                   cp = v.getCursorPos()
                   i = v.getObjectInfo(cp)
User avatar
mfasano
Posts: 122
Joined: Wed Apr 11, 2018 12:31 pm

Re: selecting the wrong element

Post by mfasano »

getPreselection() works perfectly.

Thanks Markster
Post Reply