From 632b72e7cdcc34e519be1cda568e144dd9f285ec Mon Sep 17 00:00:00 2001 From: vocx-fc Date: Fri, 22 May 2020 00:33:32 -0500 Subject: [PATCH] Draft: move functions to draftgeoutils.intersections --- src/Mod/Draft/CMakeLists.txt | 1 + src/Mod/Draft/DraftGeomUtils.py | 312 +-------------- src/Mod/Draft/draftgeoutils/intersections.py | 386 +++++++++++++++++++ 3 files changed, 391 insertions(+), 308 deletions(-) create mode 100644 src/Mod/Draft/draftgeoutils/intersections.py diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index d63addbdb5..7f15d94891 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -32,6 +32,7 @@ SET (Draft_geoutils draftgeoutils/__init__.py draftgeoutils/general.py draftgeoutils/edges.py + draftgeoutils/intersections.py ) SET(Draft_tests diff --git a/src/Mod/Draft/DraftGeomUtils.py b/src/Mod/Draft/DraftGeomUtils.py index 4cec069637..4640fa773c 100644 --- a/src/Mod/Draft/DraftGeomUtils.py +++ b/src/Mod/Draft/DraftGeomUtils.py @@ -101,253 +101,11 @@ from draftgeoutils.general import isValidPath from draftgeoutils.edges import findEdge -def findIntersection(edge1, edge2, - infinite1=False, infinite2=False, - ex1=False, ex2=False, - dts=True, findAll=False): - """findIntersection(edge1,edge2,infinite1=False,infinite2=False,dts=True): - returns a list containing the intersection point(s) of 2 edges. - You can also feed 4 points instead of edge1 and edge2. If dts is used, - Shape.distToShape() is used, which can be buggy""" - - def getLineIntersections(pt1, pt2, pt3, pt4, infinite1, infinite2): - if pt1: - # first check if we don't already have coincident endpoints - if (pt1 in [pt3,pt4]): - return [pt1] - elif (pt2 in [pt3,pt4]): - return [pt2] - norm1 = pt2.sub(pt1).cross(pt3.sub(pt1)) - norm2 = pt2.sub(pt4).cross(pt3.sub(pt4)) - if not DraftVecUtils.isNull(norm1): - try: - norm1.normalize() - except: - return [] - if not DraftVecUtils.isNull(norm2): - try: - norm2.normalize() - except: - return [] - if DraftVecUtils.isNull(norm1.cross(norm2)): - vec1 = pt2.sub(pt1) - vec2 = pt4.sub(pt3) - if DraftVecUtils.isNull(vec1) or DraftVecUtils.isNull(vec2): - return [] # One of the line has zero-length - try: - vec1.normalize() - vec2.normalize() - except: - return [] - norm3 = vec1.cross(vec2) - if not DraftVecUtils.isNull(norm3) and (norm3.x+norm3.y+norm3.z != 0): - k = ((pt3.z-pt1.z)*(vec2.x-vec2.y)+(pt3.y-pt1.y)*(vec2.z-vec2.x)+ \ - (pt3.x-pt1.x)*(vec2.y-vec2.z))/(norm3.x+norm3.y+norm3.z) - vec1.scale(k,k,k) - intp = pt1.add(vec1) - - if infinite1 == False and not isPtOnEdge(intp,edge1) : - return [] - - if infinite2 == False and not isPtOnEdge(intp,edge2) : - return [] - - return [intp] - else : - return [] # Lines have same direction - else : - return [] # Lines aren't on same plane - - # First, check bound boxes - if isinstance(edge1,Part.Edge) and isinstance(edge2,Part.Edge) \ - and (not infinite1) and (not infinite2): - if not edge1.BoundBox.intersect(edge2.BoundBox): - return [] # bound boxes don't intersect - - # First, try to use distToShape if possible - if dts and isinstance(edge1,Part.Edge) and isinstance(edge2,Part.Edge) \ - and (not infinite1) and (not infinite2): - dist, pts, geom = edge1.distToShape(edge2) - sol = [] - if round(dist,precision()) == 0: - for p in pts: - if not p in sol: - sol.append(p[0]) - return sol - - pt1 = None - - if isinstance(edge1,FreeCAD.Vector) and isinstance(edge2,FreeCAD.Vector): - # we got points directly - pt1 = edge1 - pt2 = edge2 - pt3 = infinite1 - pt4 = infinite2 - infinite1 = ex1 - infinite2 = ex2 - return getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2) - - elif (geomType(edge1) == "Line") and (geomType(edge2) == "Line") : - # we have 2 straight lines - pt1, pt2, pt3, pt4 = [edge1.Vertexes[0].Point, - edge1.Vertexes[1].Point, - edge2.Vertexes[0].Point, - edge2.Vertexes[1].Point] - return getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2) - - elif (geomType(edge1) == "Circle") and (geomType(edge2) == "Line") \ - or (geomType(edge1) == "Line") and (geomType(edge2) == "Circle") : - - # deals with an arc or circle and a line - - edges = [edge1,edge2] - for edge in edges : - if geomType(edge) == "Line": - line = edge - else : - arc = edge - - dirVec = vec(line) ; dirVec.normalize() - pt1 = line.Vertexes[0].Point - pt2 = line.Vertexes[1].Point - pt3 = arc.Vertexes[0].Point - pt4 = arc.Vertexes[-1].Point - center = arc.Curve.Center - - int = [] - # first check for coincident endpoints - if DraftVecUtils.equals(pt1,pt3) or DraftVecUtils.equals(pt1,pt4): - if findAll: - int.append(pt1) - else: - return [pt1] - elif (pt2 in [pt3,pt4]): - if findAll: - int.append(pt2) - else: - return [pt2] - - if DraftVecUtils.isNull(pt1.sub(center).cross(pt2.sub(center)).cross(arc.Curve.Axis)) : - # Line and Arc are on same plane - - dOnLine = center.sub(pt1).dot(dirVec) - onLine = Vector(dirVec) - onLine.scale(dOnLine,dOnLine,dOnLine) - toLine = pt1.sub(center).add(onLine) - - if toLine.Length < arc.Curve.Radius : - dOnLine = (arc.Curve.Radius**2 - toLine.Length**2)**(0.5) - onLine = Vector(dirVec) - onLine.scale(dOnLine,dOnLine,dOnLine) - int += [center.add(toLine).add(onLine)] - onLine = Vector(dirVec) - onLine.scale(-dOnLine,-dOnLine,-dOnLine) - int += [center.add(toLine).add(onLine)] - elif round(toLine.Length-arc.Curve.Radius,precision()) == 0 : - int = [center.add(toLine)] - else : - return [] - - else : - # Line isn't on Arc's plane - if dirVec.dot(arc.Curve.Axis) != 0 : - toPlane = Vector(arc.Curve.Axis) ; toPlane.normalize() - d = pt1.dot(toPlane) - if not d: - return [] - dToPlane = center.sub(pt1).dot(toPlane) - toPlane = Vector(pt1) - toPlane.scale(dToPlane/d,dToPlane/d,dToPlane/d) - ptOnPlane = toPlane.add(pt1) - if round(ptOnPlane.sub(center).Length - arc.Curve.Radius,precision()) == 0 : - int = [ptOnPlane] - else : - return [] - else : - return [] - - if infinite1 == False : - for i in range(len(int)-1,-1,-1) : - if not isPtOnEdge(int[i],edge1) : - del int[i] - if infinite2 == False : - for i in range(len(int)-1,-1,-1) : - if not isPtOnEdge(int[i],edge2) : - del int[i] - return int - - elif (geomType(edge1) == "Circle") and (geomType(edge2) == "Circle") : - # deals with 2 arcs or circles - cent1, cent2 = edge1.Curve.Center, edge2.Curve.Center - rad1 , rad2 = edge1.Curve.Radius, edge2.Curve.Radius - axis1, axis2 = edge1.Curve.Axis , edge2.Curve.Axis - c2c = cent2.sub(cent1) - - if cent1.sub(cent2).Length == 0: - # circles are concentric - return [] - - if DraftVecUtils.isNull(axis1.cross(axis2)) : - if round(c2c.dot(axis1),precision()) == 0 : - # circles are on same plane - dc2c = c2c.Length ; - if not DraftVecUtils.isNull(c2c): c2c.normalize() - if round(rad1+rad2-dc2c,precision()) < 0 \ - or round(rad1-dc2c-rad2,precision()) > 0 or round(rad2-dc2c-rad1,precision()) > 0 : - return [] - else : - norm = c2c.cross(axis1) - if not DraftVecUtils.isNull(norm): norm.normalize() - if DraftVecUtils.isNull(norm): x = 0 - else: x = (dc2c**2 + rad1**2 - rad2**2)/(2*dc2c) - y = abs(rad1**2 - x**2)**(0.5) - c2c.scale(x,x,x) - if round(y,precision()) != 0 : - norm.scale(y,y,y) - int = [cent1.add(c2c).add(norm)] - int += [cent1.add(c2c).sub(norm)] - else : - int = [cent1.add(c2c)] - else : - return [] # circles are on parallel planes - else : - # circles aren't on same plane - axis1.normalize() ; axis2.normalize() - U = axis1.cross(axis2) - V = axis1.cross(U) - dToPlane = c2c.dot(axis2) - d = V.add(cent1).dot(axis2) - V.scale(dToPlane/d,dToPlane/d,dToPlane/d) - PtOn2Planes = V.add(cent1) - planeIntersectionVector = U.add(PtOn2Planes) - intTemp = findIntersection(planeIntersectionVector,edge1,True,True) - int = [] - for pt in intTemp : - if round(pt.sub(cent2).Length-rad2,precision()) == 0 : - int += [pt] - - if infinite1 == False : - for i in range(len(int)-1,-1,-1) : - if not isPtOnEdge(int[i],edge1) : - del int[i] - if infinite2 == False : - for i in range(len(int)-1,-1,-1) : - if not isPtOnEdge(int[i],edge2) : - del int[i] - - return int - else: - print("DraftGeomUtils: Unsupported curve type: (" + str(edge1.Curve) + ", " + str(edge2.Curve) + ")") - return [] +from draftgeoutils.intersections import findIntersection -def wiresIntersect(wire1, wire2): - """wiresIntersect(wire1,wire2): returns True if some of the edges of the wires are intersecting otherwise False""" - for e1 in wire1.Edges: - for e2 in wire2.Edges: - if findIntersection(e1,e2,dts=False): - return True - return False +from draftgeoutils.intersections import wiresIntersect + def pocket2d(shape, offset): @@ -1251,71 +1009,9 @@ def offsetWire(wire, dvec, bind=False, occ=False, else: return nedges -def connect(edges, closed=False): - """Connect the edges in the given list by their intersections.""" - nedges = [] - v2 = None - for i in range(len(edges)): - curr = edges[i] - #print("debug: DraftGeomUtils.connect edge ",i," : ",curr.Vertexes[0].Point,curr.Vertexes[-1].Point) - if i > 0: - prev = edges[i-1] - else: - if closed: - prev = edges[-1] - else: - prev = None - if i < (len(edges)-1): - next = edges[i+1] - else: - if closed: next = edges[0] - else: - next = None - if prev: - #print("debug: DraftGeomUtils.connect prev : ",prev.Vertexes[0].Point,prev.Vertexes[-1].Point) +from draftgeoutils.intersections import connect - # If the edge pairs has intersection - # ... and if there is prev v2 (prev v2 was calculated intersection), do not calculate again, just use it as current v1 - avoid chance of slight difference in result - # And, if edge pairs has no intersection (parallel edges, line - arc do no intersect, etc.), so just just current edge endpoints as v1 - # ... and connect these 2 non-intersecting edges - - # seem have chance that 2 parallel edges offset same width, result in 2 colinear edges - Wall / DraftGeomUtils seem make them 1 edge and thus 1 vertical plane - i = findIntersection(curr,prev,True,True) - if i: - if v2: - v1 = v2 - else: - v1 = i[DraftVecUtils.closest(curr.Vertexes[0].Point,i)] - else: - v1 = curr.Vertexes[0].Point - - nedges.append(Part.LineSegment(v2,v1).toShape()) - - else: - v1 = curr.Vertexes[0].Point - if next: - #print("debug: DraftGeomUtils.connect next : ",next.Vertexes[0].Point,next.Vertexes[-1].Point) - i = findIntersection(curr,next,True,True) - if i: - v2 = i[DraftVecUtils.closest(curr.Vertexes[-1].Point,i)] - else: - v2 = curr.Vertexes[-1].Point - else: - v2 = curr.Vertexes[-1].Point - if geomType(curr) == "Line": - if v1 != v2: - nedges.append(Part.LineSegment(v1,v2).toShape()) - elif geomType(curr) == "Circle": - if v1 != v2: - nedges.append(Part.Arc(v1,findMidpoint(curr),v2).toShape()) - try: - return Part.Wire(nedges) - except: - print("DraftGeomUtils.connect: unable to connect edges") - for e in nedges: - print(e.Curve, " ",e.Vertexes[0].Point, " ", e.Vertexes[-1].Point) - return None def findDistance(point, edge, strict=False): """ diff --git a/src/Mod/Draft/draftgeoutils/intersections.py b/src/Mod/Draft/draftgeoutils/intersections.py new file mode 100644 index 0000000000..fcb258718a --- /dev/null +++ b/src/Mod/Draft/draftgeoutils/intersections.py @@ -0,0 +1,386 @@ +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * * +# * 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 basic functions for calculating intersections of shapes.""" +## @package intersections +# \ingroup DRAFTGEOUTILS +# \brief Provides basic functions for calculating intersections of shapes. + +import lazy_loader.lazy_loader as lz + +import FreeCAD +import DraftVecUtils + +from draftgeoutils.general import precision, vec, geomType, isPtOnEdge +from draftgeoutils.edges import findMidpoint + +# Delay import of module until first use because it is heavy +Part = lz.LazyLoader("Part", globals(), "Part") + + +def findIntersection(edge1, edge2, + infinite1=False, infinite2=False, + ex1=False, ex2=False, + dts=True, findAll=False): + """Return a list containing the intersection points of 2 edges. + + You can also feed 4 points instead of `edge1` and `edge2`. + If `dts` is used, `Shape.distToShape()` is used, which can be buggy. + """ + + def getLineIntersections(pt1, pt2, pt3, pt4, infinite1, infinite2): + if pt1: + # first check if we don't already have coincident endpoints + if pt1 in [pt3, pt4]: + return [pt1] + elif (pt2 in [pt3, pt4]): + return [pt2] + norm1 = pt2.sub(pt1).cross(pt3.sub(pt1)) + norm2 = pt2.sub(pt4).cross(pt3.sub(pt4)) + + if not DraftVecUtils.isNull(norm1): + try: + norm1.normalize() + except Part.OCCError: + return [] + + if not DraftVecUtils.isNull(norm2): + try: + norm2.normalize() + except Part.OCCError: + return [] + + if DraftVecUtils.isNull(norm1.cross(norm2)): + vec1 = pt2.sub(pt1) + vec2 = pt4.sub(pt3) + if DraftVecUtils.isNull(vec1) or DraftVecUtils.isNull(vec2): + return [] # One of the lines has zero-length + try: + vec1.normalize() + vec2.normalize() + except Part.OCCError: + return [] + norm3 = vec1.cross(vec2) + denom = norm3.x + norm3.y + norm3.z + if not DraftVecUtils.isNull(norm3) and denom != 0: + k = ((pt3.z - pt1.z) * (vec2.x - vec2.y) + + (pt3.y - pt1.y) * (vec2.z - vec2.x) + + (pt3.x - pt1.x) * (vec2.y - vec2.z))/denom + vec1.scale(k, k, k) + intp = pt1.add(vec1) + + if infinite1 is False and not isPtOnEdge(intp, edge1): + return [] + + if infinite2 is False and not isPtOnEdge(intp, edge2): + return [] + + return [intp] + else: + return [] # Lines have same direction + else: + return [] # Lines aren't on same plane + + # First, check bound boxes + if (isinstance(edge1, Part.Edge) and isinstance(edge2, Part.Edge) + and (not infinite1) and (not infinite2)): + if not edge1.BoundBox.intersect(edge2.BoundBox): + return [] # bound boxes don't intersect + + # First, try to use distToShape if possible + if (dts and isinstance(edge1, Part.Edge) and isinstance(edge2, Part.Edge) + and (not infinite1) and (not infinite2)): + dist, pts, geom = edge1.distToShape(edge2) + sol = [] + if round(dist, precision()) == 0: + for p in pts: + if p not in sol: + sol.append(p[0]) + return sol + + pt1 = None + + if isinstance(edge1, FreeCAD.Vector) and isinstance(edge2, FreeCAD.Vector): + # we got points directly + pt1 = edge1 + pt2 = edge2 + pt3 = infinite1 + pt4 = infinite2 + infinite1 = ex1 + infinite2 = ex2 + return getLineIntersections(pt1, pt2, pt3, pt4, infinite1, infinite2) + + elif (geomType(edge1) == "Line") and (geomType(edge2) == "Line"): + # we have 2 straight lines + pt1, pt2, pt3, pt4 = [edge1.Vertexes[0].Point, + edge1.Vertexes[1].Point, + edge2.Vertexes[0].Point, + edge2.Vertexes[1].Point] + return getLineIntersections(pt1, pt2, pt3, pt4, infinite1, infinite2) + + elif ((geomType(edge1) == "Circle") and (geomType(edge2) == "Line") + or (geomType(edge1) == "Line") and (geomType(edge2) == "Circle")): + + # deals with an arc or circle and a line + edges = [edge1, edge2] + for edge in edges: + if geomType(edge) == "Line": + line = edge + else: + arc = edge + + dirVec = vec(line) + dirVec.normalize() + pt1 = line.Vertexes[0].Point + pt2 = line.Vertexes[1].Point + pt3 = arc.Vertexes[0].Point + pt4 = arc.Vertexes[-1].Point + center = arc.Curve.Center + + int = [] + # first check for coincident endpoints + if DraftVecUtils.equals(pt1, pt3) or DraftVecUtils.equals(pt1, pt4): + if findAll: + int.append(pt1) + else: + return [pt1] + elif pt2 in [pt3, pt4]: + if findAll: + int.append(pt2) + else: + return [pt2] + + if DraftVecUtils.isNull(pt1.sub(center).cross(pt2.sub(center)).cross(arc.Curve.Axis)): + # Line and Arc are on same plane + + dOnLine = center.sub(pt1).dot(dirVec) + onLine = FreeCAD.Vector(dirVec) + onLine.scale(dOnLine, dOnLine, dOnLine) + toLine = pt1.sub(center).add(onLine) + + if toLine.Length < arc.Curve.Radius: + dOnLine = (arc.Curve.Radius**2 - toLine.Length**2)**(0.5) + onLine = FreeCAD.Vector(dirVec) + onLine.scale(dOnLine, dOnLine, dOnLine) + int += [center.add(toLine).add(onLine)] + onLine = FreeCAD.Vector(dirVec) + onLine.scale(-dOnLine, -dOnLine, -dOnLine) + int += [center.add(toLine).add(onLine)] + elif round(toLine.Length - arc.Curve.Radius, precision()) == 0: + int = [center.add(toLine)] + else: + return [] + + else: + # Line isn't on Arc's plane + if dirVec.dot(arc.Curve.Axis) != 0: + toPlane = FreeCAD.Vector(arc.Curve.Axis) + toPlane.normalize() + d = pt1.dot(toPlane) + if not d: + return [] + dToPlane = center.sub(pt1).dot(toPlane) + toPlane = FreeCAD.Vector(pt1) + toPlane.scale(dToPlane/d, dToPlane/d, dToPlane/d) + ptOnPlane = toPlane.add(pt1) + if round(ptOnPlane.sub(center).Length - arc.Curve.Radius, + precision()) == 0: + int = [ptOnPlane] + else: + return [] + else: + return [] + + if infinite1 is False: + for i in range(len(int) - 1, -1, -1): + if not isPtOnEdge(int[i], edge1): + del int[i] + if infinite2 is False: + for i in range(len(int) - 1, -1, -1): + if not isPtOnEdge(int[i], edge2): + del int[i] + return int + + elif (geomType(edge1) == "Circle") and (geomType(edge2) == "Circle"): + # deals with 2 arcs or circles + cent1, cent2 = edge1.Curve.Center, edge2.Curve.Center + rad1, rad2 = edge1.Curve.Radius, edge2.Curve.Radius + axis1, axis2 = edge1.Curve.Axis, edge2.Curve.Axis + c2c = cent2.sub(cent1) + + if cent1.sub(cent2).Length == 0: + # circles are concentric + return [] + + if DraftVecUtils.isNull(axis1.cross(axis2)): + if round(c2c.dot(axis1), precision()) == 0: + # circles are on same plane + dc2c = c2c.Length + if not DraftVecUtils.isNull(c2c): + c2c.normalize() + if (round(rad1 + rad2 - dc2c, precision()) < 0 + or round(rad1 - dc2c - rad2, precision()) > 0 + or round(rad2 - dc2c - rad1, precision()) > 0): + return [] + else: + norm = c2c.cross(axis1) + if not DraftVecUtils.isNull(norm): + norm.normalize() + if DraftVecUtils.isNull(norm): + x = 0 + else: + x = (dc2c**2 + rad1**2 - rad2**2) / (2*dc2c) + y = abs(rad1**2 - x**2)**(0.5) + c2c.scale(x, x, x) + if round(y, precision()) != 0: + norm.scale(y, y, y) + int = [cent1.add(c2c).add(norm)] + int += [cent1.add(c2c).sub(norm)] + else: + int = [cent1.add(c2c)] + else: + return [] # circles are on parallel planes + else: + # circles aren't on same plane + axis1.normalize() + axis2.normalize() + U = axis1.cross(axis2) + V = axis1.cross(U) + dToPlane = c2c.dot(axis2) + d = V.add(cent1).dot(axis2) + V.scale(dToPlane/d, dToPlane/d, dToPlane/d) + PtOn2Planes = V.add(cent1) + planeIntersectionVector = U.add(PtOn2Planes) + intTemp = findIntersection(planeIntersectionVector, + edge1, True, True) + int = [] + for pt in intTemp: + if round(pt.sub(cent2).Length-rad2, precision()) == 0: + int += [pt] + + if infinite1 is False: + for i in range(len(int) - 1, -1, -1): + if not isPtOnEdge(int[i], edge1): + del int[i] + if infinite2 is False: + for i in range(len(int) - 1, -1, -1): + if not isPtOnEdge(int[i], edge2): + del int[i] + + return int + else: + print("DraftGeomUtils: Unsupported curve type: " + "(" + str(edge1.Curve) + ", " + str(edge2.Curve) + ")") + return [] + + +def wiresIntersect(wire1, wire2): + """Return True if some of the edges of the wires are intersecting. + + Otherwise return `False`. + """ + for e1 in wire1.Edges: + for e2 in wire2.Edges: + if findIntersection(e1, e2, dts=False): + return True + return False + + +def connect(edges, closed=False): + """Connect the edges in the given list by their intersections.""" + nedges = [] + v2 = None + + for i in range(len(edges)): + curr = edges[i] + # print("debug: DraftGeomUtils.connect edge ", i, " : ", + # curr.Vertexes[0].Point, curr.Vertexes[-1].Point) + if i > 0: + prev = edges[i-1] + else: + if closed: + prev = edges[-1] + else: + prev = None + if i < (len(edges)-1): + _next = edges[i+1] + else: + if closed: + _next = edges[0] + else: + _next = None + if prev: + # print("debug: DraftGeomUtils.connect prev : ", + # prev.Vertexes[0].Point, prev.Vertexes[-1].Point) + + # If the edge pairs has intersection and if there is prev v2 + # (prev v2 was calculated intersection), do not calculate + # again, just use it as current v1 - avoid chance of slight + # difference in result. And, if edge pairs + # has no intersection (parallel edges, line + # - arc do no intersect, etc.), so just just current + # edge endpoints as v1 and connect these 2 non-intersecting + # edges + + # Seem have chance that 2 parallel edges offset same width, + # result in 2 colinear edges - Wall / DraftGeomUtils + # seem make them 1 edge and thus 1 vertical plane + i = findIntersection(curr, prev, True, True) + if i: + if v2: + v1 = v2 + else: + v1 = i[DraftVecUtils.closest(curr.Vertexes[0].Point, i)] + else: + v1 = curr.Vertexes[0].Point + nedges.append(Part.LineSegment(v2, v1).toShape()) + else: + v1 = curr.Vertexes[0].Point + + if _next: + # print("debug: DraftGeomUtils.connect _next : ", + # _next.Vertexes[0].Point, _next.Vertexes[-1].Point) + i = findIntersection(curr, _next, True, True) + if i: + v2 = i[DraftVecUtils.closest(curr.Vertexes[-1].Point, i)] + else: + v2 = curr.Vertexes[-1].Point + else: + v2 = curr.Vertexes[-1].Point + if geomType(curr) == "Line": + if v1 != v2: + nedges.append(Part.LineSegment(v1, v2).toShape()) + elif geomType(curr) == "Circle": + if v1 != v2: + nedges.append(Part.Arc(v1, + findMidpoint(curr), + v2).toShape()) + try: + return Part.Wire(nedges) + except: + print("DraftGeomUtils.connect: unable to connect edges") + for e in nedges: + print(e.Curve, " ", + e.Vertexes[0].Point, " ", + e.Vertexes[-1].Point) + return None