AbdulElahGwaith's picture
Upload folder using huggingface_hub
985c397 verified
# SPDX-License-Identifier: LGPL-2.1-or-later
# ***************************************************************************
# * Copyright (c) 2009, 2010 Yorik van Havre <yorik@uncreated.net> *
# * Copyright (c) 2009, 2010 Ken Cline <cline@frii.com> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with FreeCAD; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
"""Provides various functions to sort lists of edges."""
## @package sort_edges
# \ingroup draftgeoutils
# \brief Provides various functions to sort lists of edges.
import lazy_loader.lazy_loader as lz
from draftgeoutils.general import geomType
from draftgeoutils.edges import findMidpoint, isLine, invert
# Delay import of module until first use because it is heavy
Part = lz.LazyLoader("Part", globals(), "Part")
## \addtogroup draftgeoutils
# @{
def sortEdges(edges):
"""Sort edges. Deprecated. Use Part.__sortEdges__ instead."""
raise DeprecationWarning("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
def sortEdgesOld(lEdges, aVertex=None):
"""Sort edges. Deprecated. Use Part.__sortEdges__ instead."""
raise DeprecationWarning("Deprecated. Use Part.__sortEdges__ instead")
# There is no reason to limit this to lines only because
# every non-closed edge always has exactly two vertices (wmayer)
# for e in lEdges:
# if not isinstance(e.Curve,Part.LineSegment):
# print("Sortedges cannot treat wired containing curves yet.")
# return lEdges
def lookfor(aVertex, inEdges):
"""Look for a vertex in the list of edges.
Returns count, the position of the instance
the position in the instance and the instance of the Edge.
"""
count = 0
linstances = [] # lists the instances of aVertex
for i in range(len(inEdges)):
for j in range(2):
if aVertex.Point == inEdges[i].Vertexes[j - 1].Point:
instance = inEdges[i]
count += 1
linstances += [i, j - 1, instance]
return [count] + linstances
if len(lEdges) < 2:
if aVertex is None:
return lEdges
else:
result = lookfor(aVertex, lEdges)
if result[0] != 0:
if aVertex.Point == result[3].Vertexes[0].Point:
return lEdges
else:
if geomType(result[3]) == "Line":
return [
Part.LineSegment(aVertex.Point, result[3].Vertexes[0].Point).toShape()
]
elif geomType(result[3]) == "Circle":
mp = findMidpoint(result[3])
return [Part.Arc(aVertex.Point, mp, result[3].Vertexes[0].Point).toShape()]
elif (
geomType(result[3]) == "BSplineCurve"
or geomType(result[3]) == "BezierCurve"
):
if isLine(result[3].Curve):
return [
Part.LineSegment(
aVertex.Point, result[3].Vertexes[0].Point
).toShape()
]
else:
return lEdges
else:
return lEdges
olEdges = [] # ol stands for ordered list
if aVertex is None:
for i in range(len(lEdges) * 2):
if len(lEdges[i / 2].Vertexes) > 1:
result = lookfor(lEdges[i / 2].Vertexes[i % 2], lEdges)
if result[0] == 1: # Have we found an end ?
olEdges = sortEdgesOld(lEdges, result[3].Vertexes[result[2]])
return olEdges
# if the wire is closed there is no end so choose 1st Vertex
# print("closed wire, starting from ",lEdges[0].Vertexes[0].Point)
return sortEdgesOld(lEdges, lEdges[0].Vertexes[0])
else:
# print("looking ",aVertex.Point)
result = lookfor(aVertex, lEdges)
if result[0] != 0:
del lEdges[result[1]]
_next = sortEdgesOld(lEdges, result[3].Vertexes[-((-result[2]) ^ 1)])
# print("result ", result[3].Vertexes[0].Point, " ",
# result[3].Vertexes[1].Point, " compared to ",aVertex.Point)
if aVertex.Point == result[3].Vertexes[0].Point:
# print("keeping")
olEdges += [result[3]] + _next
else:
# print("inverting", result[3].Curve)
if geomType(result[3]) == "Line":
newedge = Part.LineSegment(aVertex.Point, result[3].Vertexes[0].Point).toShape()
olEdges += [newedge] + _next
elif geomType(result[3]) == "Circle":
mp = findMidpoint(result[3])
newedge = Part.Arc(aVertex.Point, mp, result[3].Vertexes[0].Point).toShape()
olEdges += [newedge] + _next
elif geomType(result[3]) == "BSplineCurve" or geomType(result[3]) == "BezierCurve":
if isLine(result[3].Curve):
newedge = Part.LineSegment(
aVertex.Point, result[3].Vertexes[0].Point
).toShape()
olEdges += [newedge] + _next
else:
olEdges += [result[3]] + _next
else:
olEdges += [result[3]] + _next
return olEdges
else:
return []
## @}