Is there a way to quickly select all edges associated with a face?

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
Post Reply
UpcycleElectronics
Posts: 3
Joined: Wed Jun 16, 2021 8:25 pm

Is there a way to quickly select all edges associated with a face?

Post by UpcycleElectronics »

Is there a way to quickly select all edges associated with a face?
For instance, if I have someone else's mesh (thingiverse STL), converted to a solid (Part WB), and am unlucky enough that the file has a bajillion chamfers, and I want to remove features using the Draft WB to downgrade the solid to faces and the Defeaturing WB/toolbar to remove and reconstruct faces. Inevitably, I'll need to modify a few faces that have like 100 edges. I really wish I had a way to select all the edges of a face from the face. Something like "<ALT>+left-click" to select edges from a face. Is there something like this available? I've encountered this a couple of times in recent weeks.
-Jake
chrisb
Veteran
Posts: 54313
Joined: Tue Mar 17, 2015 9:14 am

Re: Is there a way to quickly select all edges associated with a face?

Post by chrisb »

No direct answer to your question, but I see it again and again that people invest much time in order to convert STLs to FreeCAD objects. And the final result is at its best a poorly tesselated object.

I recommend to head for a finally good model by converting the stl to a shape and use that as reference for a new - real - FreeCAD model.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: Is there a way to quickly select all edges associated with a face?

Post by heda »

if nothing else one can always resort to scripting...

Code: Select all

# one face selected
s, = Gui.Selection.getSelectionEx()
obj = s.Object
face, = s.SubObjects
Gui.Selection.clearSelection()
hits = list()
for fe in face.Edges:
    for i, edge in enumerate(obj.Shape.Edges, start=1):
        if fe.isEqual(edge):
            hits.append('Edge{}'.format(i))
        edge.reverse()
        if fe.isEqual(edge):
            hits.append('Edge{}'.format(i))

Gui.Selection.addSelection(obj, hits)
UpcycleElectronics
Posts: 3
Joined: Wed Jun 16, 2021 8:25 pm

Re: Is there a way to quickly select all edges associated with a face?

Post by UpcycleElectronics »

chrisb wrote: Wed Jun 16, 2021 9:38 pm No direct answer to your question, but I see it again and again that people invest much time in order to convert STLs to FreeCAD objects. And the final result is at its best a poorly tesselated object.

I recommend to head for a finally good model by converting the stl to a shape and use that as reference for a new - real - FreeCAD model.
It took me awhile to figure out when it is better to rebuild versus modify. I still get it wrong most times. Watching Mark Ganson's youtube stuff helped me see the relationship between wires faces and solids https://www.youtube.com/c/mwganson. My resulting prints have come out useful.
heda wrote: Wed Jun 16, 2021 11:07 pm if nothing else one can always resort to scripting...
You are a god and a gentleman! That works perfectly. Now I just need it in a pretty button. CTRL+V certainly works well for me now. THANKS!!!
-Jake
chrisb
Veteran
Posts: 54313
Joined: Tue Mar 17, 2015 9:14 am

Re: Is there a way to quickly select all edges associated with a face?

Post by chrisb »

You can configure your own buttons for your own macros, see Customize Toolbars.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
mario52
Veteran
Posts: 4701
Joined: Wed May 16, 2012 2:13 pm

Re: Is there a way to quickly select all edges associated with a face?

Post by mario52 »

Hi

you work with many STL file , maybe this macro can also help you

(I made this macro for another user but I think I misunderstood his need)

select your object and click the face interesting for convert in a Shape face

you have options create point, triangle, triangle face, color

EDIT 17/06/2021 11h21 modify the code adding line option

Code: Select all

#Mesh_Face_to_Shape_Face
#https://forum.freecadweb.org/posting.php?mode=reply&f=3&t=59475#preview
#original macro https://wiki.freecadweb.org/Code_snippets#Get_the_normal_vector_of_a_surface_from_a_STL_file
#Mario52
#15/06/2021; 17/06/2021
#

from pivy import coin
import warnings
warnings.simplefilter("ignore")
import Draft

#### Config ####
global point   ; point    = 0   # if 1 create points
global triangle; triangle = 0   # if 1 create triangle (1 by default)
global faces   ; faces    = 1   # if 1 create face     (1 by default)
global couleur ; couleur  = 1   # if 1 create face colored (1 by default)
#### Config ####

global meth

global v, c
v=Gui.activeDocument().activeView()
class ViewObserver:
    def logPosition(self, info):
        global v, c
        global meth

        try:
            down = (info["Key"])
            if down == "ESCAPE":
                v.removeEventCallback("SoEvent",c)      # remove ViewObserver SoEvent
                Gui.ActiveDocument.ActiveView.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), meth)  # remove SoMouseButtonEvent
                FreeCAD.Console.PrintMessage("Quit Mesh_Face_to_Shape_Face" + "\n")
        except Exception:
            None

o = ViewObserver()
c = v.addEventCallback("SoEvent",o.logPosition)
##v.removeEventCallback("SoEvent",c)      # remove ViewObserver SoEvent

def makeTriangle(cb):
    import Draft
    global point
    global triangle
    global couleur

    pp = cb.getPickedPoint()
    try:
        if pp: # and (pp != None):
            objs = FreeCADGui.Selection.getSelection()
            if hasattr(objs[0], "Mesh"):      # upgrade with wmayer thanks #http://forum.freecadweb.org/viewtopic.php?f=13&t=22331
                index = coin.cast(pp.getDetail(), "SoFaceDetail").getFaceIndex()
                #print("Mesh")
                s = objs[0].Mesh
                coordPoints = s.Facets[index].Points
                if point == 1:
                    Draft.makePoint(coordPoints[0][0], coordPoints[0][1], coordPoints[0][2])
                    Draft.makePoint(coordPoints[1][0], coordPoints[1][1], coordPoints[1][2])
                    Draft.makePoint(coordPoints[2][0], coordPoints[2][1], coordPoints[2][2])
                if triangle == 1:
                    points = [FreeCAD.Vector(coordPoints[0][0], coordPoints[0][1], coordPoints[0][2]), 
                              FreeCAD.Vector(coordPoints[1][0], coordPoints[1][1], coordPoints[1][2]), 
                              FreeCAD.Vector(coordPoints[2][0], coordPoints[2][1], coordPoints[2][2])]
                    line = Draft.makeWire(points,  closed=True, face=False, support=None)
                    FreeCAD.ActiveDocument.getObject(line.Name).Label = "Triangle_" + str(index)
                    if couleur == 1:
                        FreeCADGui.ActiveDocument.getObject(line.Name).LineColor = (0.8000,0.0000,0.0000)
                    Draft.autogroup(line)
                if faces == 1:
                    points = [FreeCAD.Vector(coordPoints[0][0], coordPoints[0][1], coordPoints[0][2]), 
                              FreeCAD.Vector(coordPoints[1][0], coordPoints[1][1], coordPoints[1][2]), 
                              FreeCAD.Vector(coordPoints[2][0], coordPoints[2][1], coordPoints[2][2])]
                    line = Draft.makeWire(points,  closed=True, face=True, support=None)
                    FreeCAD.ActiveDocument.getObject(line.Name).Label = "Face_" + str(index)
                    if couleur == 1:
                        FreeCADGui.ActiveDocument.getObject(line.Name).ShapeColor = (0.8000,0.0000,0.0000)
                    Draft.autogroup(line)

                FreeCAD.ActiveDocument.recompute()
            else:
                FreeCAD.Console.PrintMessage("Select Mesh object" + "\n")
    except Exception:
        None

meth=Gui.ActiveDocument.ActiveView.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), makeTriangle)
##Gui.ActiveDocument.ActiveView.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), meth)
FreeCAD.Console.PrintMessage("\n" + "Type ESCAPE for quit Mesh_Face_to_Shape_Face" + "\n\n")


MeshFace_To_ShapeFace.gif
MeshFace_To_ShapeFace.gif (580.5 KiB) Viewed 1910 times
mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: Is there a way to quickly select all edges associated with a face?

Post by heda »

UpcycleElectronics wrote: Thu Jun 17, 2021 12:54 am That works
nino problema

@mario52 - nice - actually so nice that it really should be part of mesh wb imho (dropdown toolbar icon for the different choices?)

since faster is better, did the obvious code mods that should do a bit on speed,
on the smaller test case used - it did close to 30%

Code: Select all

# one face selected
s, = Gui.Selection.getSelectionEx()
obj = s.Object
face, = s.SubObjects
Gui.Selection.clearSelection()
hits = list()
Edge = 'Edge{}'.format
objEdges = tuple(obj.Shape.Edges)
for fe in face.Edges:
    feisEqual = fe.isEqual
    for i, edge in enumerate(objEdges, start=1):
        if feisEqual(edge):
            hits.append(Edge(i))
            break
        edge.reverse()
        if feisEqual(edge):
            hits.append(Edge(i))
            break

Gui.Selection.addSelection(obj, hits)
Post Reply