Description on sortEdges

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
ostapb
Posts: 20
Joined: Thu Sep 08, 2022 1:59 pm

Description on sortEdges

Post by ostapb »

Hello all.

I need to know about function Part.sortEdges(). It seems that I have to use it in some tasks. But I have just basic knowledge. I’ve got info from help(Part.sortEdges) and help(Part.__sortEdges__). Online doc that I’ve found is strange. Maybe I’ve just failed to found needed page. Can anybody help me to find most full description – with details, conditions, limitation etc.?

Of course, I have some specific cases with sortEdges(). Some of them works well, and some don’t. But right now, I don’t want to discuss them here. Maybe later. I want to learn more about what and how does this function do. So, I’ll try to decide whether I can use it for the task or not.

Thank you.
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Description on sortEdges

Post by onekk »

ostapb wrote: Wed May 24, 2023 1:26 pm ...
Not much to tell, it sort edges, there is this discussion thread, with some explanation:

viewtopic.php?p=265695#p265695


See however that:
sorts all input edges and thus returns a list of lists of edges
That is return a "list of list", so if edges are connected they will form a list, and if some edge is not connected they will be returned in a separate list of connected edges:

From what I remember it is useful to obtain as example separate wires from a list of edges, but the explanation will not tell more, you could simply experiment as example with:

Code: Select all

# get the list of edges in a wire
edges_a = wire_a.Edges
# get the list of edges in a different wire
edges_b = wire_b.Edges

edges_mix = []
for a_elem, b_elem in zip(edges_a, edges_b):
    edges_mix.append(a_element)
    edges_mix.append(b_element)


new_edges = Part.sortEdges(edges_mix)
print(new_edges)

Warning, code above is not tested, so take it with some care.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
ostapb
Posts: 20
Joined: Thu Sep 08, 2022 1:59 pm

Re: Description on sortEdges

Post by ostapb »

Thank you.

You say "Not much to tell" about both FreeCAD documentation and OpenCascade documentation? (I hoped that OCC has more detailed docs.)
if edges are connected they will form a list, and if some edge is not connected
Is there any criteria, tolerance or error rate that sortEdges() depends on here? I guess its not just macheps?
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Description on sortEdges

Post by Chris_G »

sortEdges will return lists of edges that are connected within 1e-7 tolerance.
There is PR#9599 that will add the tolerance option, but I think it won't be merged until after the stable 0.21 release.
mconsidine
Posts: 125
Joined: Wed Jan 18, 2023 10:41 pm
Location: Randolph, VT USA

Re: Description on sortEdges

Post by mconsidine »

This actually bit me with the DXF importing, as it turned out the number of edges would get reduced after applying sortEdges in some cases where some segments don't line up well (for whatever reason). So I looked to try a rounding of vertices - which didn't really work either. I look forward to seeing an implementation that might mitigate this issue a bit (and can understand the OP wanting to know more).
mconsidine
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Description on sortEdges

Post by onekk »

mconsidine wrote: Thu May 25, 2023 7:15 pm ...
You could theoretically sort edges and see generated lists, then analyze resultsand regenerate wrong edges using distanceToShape to identify what edge is more near to others, you have to check only remainders (single edges) in lists returned from sort edges and start and ending edges of returned lists.

The point could be to decide what is the wrong value, the remainder or the wire start or end.

Obviously you could have mixed results if edges are not coincident (by design) or you have crossing lines.

As it will be a iteration mechanism probably it could be slow, but probably much faster than doing by hand.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
mconsidine
Posts: 125
Joined: Wed Jan 18, 2023 10:41 pm
Location: Randolph, VT USA

Re: Description on sortEdges

Post by mconsidine »

@onekk: That's brilliant. Thank you for the suggestion. I was wondering if such a function existed and figured it didn't. Plus the idea of going through n^2 comparisons seemed tedious.

But I think you've laid out a way that will work. I'll give it a shot.

Thanks again for the insight.
Regards,
mconsidine
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Description on sortEdges

Post by onekk »

mconsidine wrote: Fri May 26, 2023 10:30 am ...
I model almost exclusively using scripting, so I've been bite by some problems, I use a similar approach to circumvent some intersections than will not be detected by intersect for which I've not found a solution, even common is not solving the problem, traversing edges and use distanceToShape will permit to section wires at intersection with a custom made plane instead of a simple line.

Additional informations supplied, like edge number and parameter of intersection will help you to make a edge list that sortEdge will transform in more manageable things. Sadly the only example I have is for a "paid job" so I can't post it, but if needed next week I could make an example with some code.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
mconsidine
Posts: 125
Joined: Wed Jan 18, 2023 10:41 pm
Location: Randolph, VT USA

Re: Description on sortEdges

Post by mconsidine »

@onekk Yes, I'd be grateful to see anything you could post. In a little while, I'll post an example here of the issue I ran across.
Thanks,
mconsidine
mconsidine
Posts: 125
Joined: Wed Jan 18, 2023 10:41 pm
Location: Randolph, VT USA

Re: Description on sortEdges

Post by mconsidine »

First:

Code: Select all

OS: Linux Mint 21 (X-Cinnamon/cinnamon)
Word size of FreeCAD: 64-bit
Version: 0.21.0.33044 (Git)
Build type: Unknown
Branch: master
Hash: 3fabd940dd3322b247fe2a82f68b754c087f3b34
Python 3.10.6, Qt 5.15.3, Coin 4.0.1, Vtk 9.1.0, OCC 7.7.1
Locale: English/United States (en_US)
Installed mods: 
  * OpenSCAD_Alt_Import 1.0.0
  * ProDarkThemePreferencePack 1.0.0
  * Alternate_OpenSCAD.backup1684871460.3140821 1.0.0 (Disabled)
  * toSketch 1.0.1
  * Alternate_OpenSCAD 1.0.0
  * Render 2023.2.5
  * Manipulator 1.5.0
  * Help 1.0.3
  * POV-Ray-Rendering
  * MeshRemodel 1.8919.0
  * Assembly4 0.50.2
  * freecad.gears 1.0.0
  * CubeMenu
  * fasteners 0.4.56
  * Silk 0.1.3
  * Dracula 0.0.4
  * Curves 0.6.9
  * A2plus 0.4.60n
  * ThreadProfile 1.85.0

If we take as an example the DXF file found in this post:
viewtopic.php?p=683549#p683549

and have Keith Sloan's Alternate OpenSCAD importer add-on, then in the FC python
console we can enter:

Code: Select all

App.newDocument()
import OpenSCADdxf
c,f=OpenSCADdxf.importEZDXFshape("/home/matt/Downloads/DXFtests/forum/SLvl-2D-BodySketch.dxf",retcompound=True,retfaces=True)

Part.show(c)

#or
#
#for aface in f:
#  Part.show(aface)
#
#will show an incomplete import of the DXF outline.

#Collect the edges from an object that is created silently by that routine:
the_edges=OpenSCADdxf.mylayerlist[0]
#the_edges.__len__() # -> 21 edges

#Sort:
sorted_edges=Part.sortEdges(the_edges)
#sorted_edges.__len__() # -> 9 items, but not wall will work as faces
Separate out the ones that will work from those that won't:

Code: Select all

successes=[] # a list for successes
fails=[] # a list for fails

for an_item in sorted_edges:
  try:
    successes+=[Part.Face(Part.Wire(an_item))]
  except:
    fails+=an_item

Part.show(Part.Compound(successes)) #this shows what we initially saw as incomplete

for an_item in fails: #this shows the pieces that needed to be "reattached"
  Part.show(Part.Wire(an_item))
Now, see if we can find the segment closest to the first one in the "fails" list:

Code: Select all

#for the first failed segment, look at distances
for s in successes:
  fails[0].distToShape(s)
But this gives 0.0 as all the distances

I looked at this
help(Part.Shape.distToShape)
but it wasn't clear to me how I could use what comes back to find the closest element of "successes" to work with.

Any thoughts/help would be appreciated.

LATE EDIT: thinking I should look carefully at this post
viewtopic.php?style=5&t=72406

In any case, this is where I ran into confusion with sortEdges. And apologies for hijacking this thread a bit. That was unintended.
mconsidine
Post Reply