Merge branch 'master' of ssh://git.code.sf.net/p/free-cad/code

This commit is contained in:
wmayer 2015-01-12 01:44:13 +01:00
commit c9a70c7f03

View File

@ -655,85 +655,73 @@ def isLine(bsp):
return False return False
return True return True
def sortEdgesNew(edges): def sortEdges(edges):
"""Sort edges in path order, i.e., such that the end point of edge N """Sort edges in path order, i.e., such that the end point of edge N
equals the start point of edge N+1. equals the start point of edge N+1.
""" """
# Build a dictionary of edges according to their end points.
def vpoint(vertex): # Each entry is a set of edges that starts, or ends, at the
"""Turn a vertex into a triple of its point coordinates. This is # given vertex hash.
so we can put it into a dictionary; vertexes hash on their identity
and compare equal on object identity rather than coordinates.
And vertex.Point compares on value, but is mutable so it doesn't
have a hash value.
"""
p = vertex.Point
return (p.x, p.y, p.z)
# Build a dictionary of vertexes according to their end points.
# Each entry is a set of vertexes that starts, or ends, at the
# given vertex position.
sdict = dict() sdict = dict()
edict = dict() edict = dict()
nedges = []
for e in edges: for e in edges:
v1, v2 = e.Vertexes if e.Length != 0:
v1 = vpoint(v1) sdict.setdefault( e.Vertexes[0].hashCode(), [] ).append(e)
v2 = vpoint(v2) edict.setdefault( e.Vertexes[-1].hashCode(),[] ).append(e)
try: nedges.append(e)
sdict[v1].add(e)
except KeyError:
sdict[v1] = set()
sdict[v1].add(e)
try:
edict[v2].add(e)
except KeyError:
edict[v2] = set()
edict[v2].add(e)
# Find the start of the path. The start is the vertex that appears # 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 # in the sdict dictionary but not in the edict dictionary, and has
# only one edge ending there. # only one edge ending there.
startedge = None startedge = None
for v, se in sdict.items(): for v, se in sdict.items():
if v not in edict and len (se) == 1: if v not in edict and len(se) == 1:
startedge = se startedge = se
break break
# The above may not find a start vertex; if the start edge is reversed, # The above may not find a start vertex; if the start edge is reversed,
# the start vertex will appear in edict (and not sdict). # the start vertex will appear in edict (and not sdict).
if not startedge: if not startedge:
for v, se in edict.xitems(): for v, se in edict.items():
if v not in sdict and len (se) == 1: if v not in sdict and len(se) == 1:
startedge = se startedge = se
break break
# If we still have no start vertex, it was a closed path. If so, start # If we still have no start vertex, it was a closed path. If so, start
# with the first edge in the supplied list # with the first edge in the supplied list
if not startedge: if not startedge:
startedge = edges[0] startedge = nedges[0]
v = vpoint (startedge.Vertexes[0]) v = startedge.Vertexes[0].hashCode()
# Now build the return list by walking the edges starting at the start # 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 # 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 # end check is simply the count of input elements (that works for closed
# as well as open paths). # as well as open paths).
ret = list() ret = list()
for i in range(len(edges)): # store the hash code of the last edge, to avoid picking the same edge back
eh = None
for i in range(len(nedges)):
try: try:
eset = sdict[v] eset = sdict[v]
e = eset.pop() e = eset.pop()
if not eset: if not eset:
del sdict[v] del sdict[v]
v = e.Vertexes[1] if e.hashCode() == eh:
raise KeyError
v = e.Vertexes[-1].hashCode()
eh = e.hashCode()
except KeyError: except KeyError:
try: try:
eset = edict[v] eset = edict[v]
e = eset.pop() e = eset.pop()
if not eset: if not eset:
del edict[v] del edict[v]
v = e.Vertexes[0] if e.hashCode() == eh:
e.reverse() raise KeyError
v = e.Vertexes[0].hashCode()
eh = e.hashCode()
e = invert(e)
except KeyError: except KeyError:
print("DraftGeomUtils.sortEdges failed") print("DraftGeomUtils.sortEdges failed - running old version:")
return sortEdgesOld(edges) return sortEdgesOld(edges)
ret.append(e) ret.append(e)
v = vpoint(v)
# All done. # All done.
return ret return ret
@ -827,6 +815,20 @@ def sortEdgesOld(lEdges, aVertex=None):
return [] return []
def invert(edge):
'''invert(edge): returns an inverted copy of this edge'''
if geomType(edge) == "Line":
return Part.Line(edge.Vertexes[-1].Point,edge.Vertexes[0].Point).toShape()
elif geomType(edge) == "Circle":
mp = findMidpoint(edge)
return Part.Arc(edge.Vertexes[-1].Point,mp,edge.Vertexes[0].Point).toShape()
elif geomType(edge) in ["BSplineCurve","BezierCurve"]:
if isLine(edge.Curve):
return Part.Line(edge.Vertexes[-1].Point,edge.Vertexes[0].Point).toShape()
print "DraftGeomUtils.invert: unable to invert ",edge.Curve
return edge
def flattenWire(wire): def flattenWire(wire):
'''flattenWire(wire): forces a wire to get completely flat '''flattenWire(wire): forces a wire to get completely flat
along its normal.''' along its normal.'''
@ -844,11 +846,6 @@ def flattenWire(wire):
w = Part.makePolygon(verts) w = Part.makePolygon(verts)
return w return w
def sortEdges(edges):
"define here which version to use"
#return sortEdgesNew(edges)
return sortEdgesOld(edges)
def findWires(edgeslist): def findWires(edgeslist):
'''finds connected wires in the given list of edges''' '''finds connected wires in the given list of edges'''
@ -1231,7 +1228,9 @@ def connect(edges,closed=False):
try: try:
return Part.Wire(nedges) return Part.Wire(nedges)
except: except:
print("DraftGeomUtils.connect: unable to connect edges:",nedges) print("DraftGeomUtils.connect: unable to connect edges")
for e in nedges:
print e.Curve, " ",e.Vertexes[0].Point, " ", e.Vertexes[-1].Point
return None return None
def findDistance(point,edge,strict=False): def findDistance(point,edge,strict=False):
@ -1417,6 +1416,9 @@ def getTangent(edge,frompoint=None):
def bind(w1,w2): def bind(w1,w2):
'''bind(wire1,wire2): binds 2 wires by their endpoints and '''bind(wire1,wire2): binds 2 wires by their endpoints and
returns a face''' returns a face'''
if (not w1) or (not w2):
print("DraftGeomUtils: unable to bind wires")
return None
if w1.isClosed() and w2.isClosed(): if w1.isClosed() and w2.isClosed():
d1 = w1.BoundBox.DiagonalLength d1 = w1.BoundBox.DiagonalLength
d2 = w2.BoundBox.DiagonalLength d2 = w2.BoundBox.DiagonalLength