Thanks for the study
This post start with a view to understand the detailed algorithm of Part.getSortedCluser() and Part.sortEdges() in the first place.
Thanks for the study
Code: Select all
edge.reverse()
Anyway, what are you expecting with the edge.reverse() ? That thread in fact contained study and experiment of the effect of that method.edwilliams16 wrote: ↑Sun Feb 05, 2023 11:58 pm I tried to write Part.__sortEdges__ in python, but got stuck on reversing an edge. It turns outjust changes the Orientation flag. It doesn't create a new edge with the vertices swapped, which the C++ does. I couldn't find a method to do that. (Of course, there might be some hack like creating a BSpline and reversing the parametrization, or case by case with lines, arcs etc.)Code: Select all
edge.reverse()
viewtopic.php?t=31850&start=10 If that was resolved here, I didn't understand it.
If you mean [1, 2, 3, 4, 5, 6] -> [[1, 2, 3, 4], [5], [6]], it stops adding edges to the segment after [1] -> [1,2] -> [1, 2, 3] ->[1, 2, 3, 4] because it tests for closure after each edge is added.
To write Part.__sortEdges__ one needs a function that actually creates an edge with the vertices exchanged. edge.reverse() doesn't do that. It creates a pointer to the same TShape with the Orientation flag reversed. Part.__sortEdges__ creates new edges with the vertices swapped when required.Anyway, what are you expecting with the edge.reverse() ? That thread in fact contained study and experiment of the effect of that method.edwilliams16 wrote: ↑Sun Feb 05, 2023 11:58 pm I tried to write Part.__sortEdges__ in python, but got stuck on reversing an edge. It turns outjust changes the Orientation flag. It doesn't create a new edge with the vertices swapped, which the C++ does. I couldn't find a method to do that. (Of course, there might be some hack like creating a BSpline and reversing the parametrization, or case by case with lines, arcs etc.)Code: Select all
edge.reverse()
viewtopic.php?t=31850&start=10 If that was resolved here, I didn't understand it.
Code: Select all
import FreeCAD
import Part
V3d = FreeCAD.Vector
pt1 = V3d(0,0,0)
pt2 = V3d(20,0,0)
pt3 = V3d(20,10,0)
pt4 = V3d(0,10,0)
ln1 = Part.LineSegment(pt1, pt2).toShape()
ln2 = Part.LineSegment(pt2, pt3).toShape()
ln3 = Part.LineSegment(pt3, pt4).toShape()
ln4 = Part.LineSegment(pt4, pt1).toShape()
ln5 = Part.LineSegment(pt1, pt3).toShape()
ln6 = Part.LineSegment(pt4, pt2).toShape()
edges = [ln1, ln2, ln3, ln4, ln5, ln6]
def sortEdges(edges):
"""Sort edges. Deprecated. Use Part.__sortEdges__ instead."""
if len(edges) < 2:
return edges
# Build a dictionary of edges according to their end points.
# Each entry is a set of edges that starts, or ends, at the
# given vertex hash.
sdict = dict()
edict = dict()
nedges = []
for e in edges:
if hasattr(e, "Length"):
if e.Length != 0:
sdict.setdefault(e.Vertexes[0].hashCode(), []).append(e)
edict.setdefault(e.Vertexes[-1].hashCode(), []).append(e)
nedges.append(e)
if not nedges:
print("DraftGeomUtils.sortEdges: zero-length edges")
return edges
# Find the start of the path. The start is the vertex that appears
# in the sdict dictionary but not in the edict dictionary, and has
# only one edge ending there.
startedge = None
for v, se in sdict.items():
if v not in edict and len(se) == 1:
startedge = se
break
# The above may not find a start vertex; if the start edge is reversed,
# the start vertex will appear in edict (and not sdict).
if not startedge:
for v, se in edict.items():
if v not in sdict and len(se) == 1:
startedge = se
break
# If we still have no start vertex, it was a closed path. If so, start
# with the first edge in the supplied list
if not startedge:
startedge = nedges[0]
v = startedge.Vertexes[0].hashCode()
# Now build the return list by walking the edges starting at the start
# vertex we found. We're done when we've visited each edge, so the
# end check is simply the count of input elements (that works for closed
# as well as open paths).
ret = list()
# store the hash code of the last edge, to avoid picking the same edge back
eh = None
for _ in range(len(nedges)):
try:
eset = sdict[v]
e = eset.pop()
if not eset:
del sdict[v]
if e.hashCode() == eh:
raise KeyError
v = e.Vertexes[-1].hashCode()
eh = e.hashCode()
except KeyError:
try:
eset = edict[v]
e = eset.pop()
if not eset:
del edict[v]
if e.hashCode() == eh:
raise KeyError
v = e.Vertexes[0].hashCode()
eh = e.hashCode()
e = invert(e)
except KeyError:
print("DraftGeomUtils.sortEdges failed - running old version")
# return sortEdgesOld(edges)
ret.append(e)
return ret
sort_edges = sortEdges(edges)
print(sort_edges)
The key point in this code is invert(edge), which points toonekk wrote: ↑Mon Feb 06, 2023 6:27 pm This code could be a
https://github.com/FreeCAD/FreeCAD/blob ... t_edges.py
Maybe trying to reuse some of this code even deprecated, could be a strating point, that eventually could be made in C++ by someone.
Regards
Carlo D.
edwilliams16 wrote: ↑Mon Feb 06, 2023 6:39 pm The key point in this code is invert(edge), which points to
...
where one finds it goes case-by-case of edge Curves, but can't handle either Beziers or BSplines. I imagine that is why it was deprecated in favor of Part.__sortEdges__ which does.