Exemple #1
0
def circlefrom1Line2Points(edge, p1, p2):
    """circlefrom1Line2Points(edge, Vector, Vector)"""
    p1_p2 = edg(p1, p2)
    s = findIntersection(edge, p1_p2, True, True)
    if not s: return None
    s = s[0]
    v1 = p1.sub(s)
    v2 = p2.sub(s)
    projectedDist = math.sqrt(abs(v1.dot(v2)))
    edgeDir = vec(edge)
    edgeDir.normalize()
    projectedCen1 = Vector.add(s, Vector(edgeDir).multiply(projectedDist))
    projectedCen2 = Vector.add(s, Vector(edgeDir).multiply(-projectedDist))
    perpEdgeDir = edgeDir.cross(Vector(0, 0, 1))
    perpCen1 = Vector.add(projectedCen1, perpEdgeDir)
    perpCen2 = Vector.add(projectedCen2, perpEdgeDir)
    mid = findMidpoint(p1_p2)
    x = DraftVecUtils.crossproduct(vec(p1_p2))
    x.normalize()
    perp_mid = Vector.add(mid, x)
    cen1 = findIntersection(edg(projectedCen1, perpCen1), edg(mid, perp_mid),
                            True, True)
    cen2 = findIntersection(edg(projectedCen2, perpCen2), edg(mid, perp_mid),
                            True, True)
    circles = []
    if cen1:
        radius = DraftVecUtils.dist(projectedCen1, cen1[0])
        circles.append(Part.Circle(cen1[0], NORM, radius))
    if cen2:
        radius = DraftVecUtils.dist(projectedCen2, cen2[0])
        circles.append(Part.Circle(cen2[0], NORM, radius))

    if circles: return circles
    else: return None
Exemple #2
0
def cleanProjection(shape, tessellate=True, seglength=0.05):
    """Return a valid compound of edges, by recreating them.

    This is because the projection algorithm somehow creates wrong shapes.
    They display fine, but on loading the file the shape is invalid.

    Now with tanderson's fix to `ProjectionAlgos`, that isn't the case,
    but this function can be used for tessellating ellipses and splines
    for DXF output-DF.
    """
    oldedges = shape.Edges
    newedges = []
    for e in oldedges:
        try:
            if geomType(e) == "Line":
                newedges.append(e.Curve.toShape())

            elif geomType(e) == "Circle":
                if len(e.Vertexes) > 1:
                    mp = findMidpoint(e)
                    a = Part.Arc(e.Vertexes[0].Point,
                                 mp,
                                 e.Vertexes[-1].Point).toShape()
                    newedges.append(a)
                else:
                    newedges.append(e.Curve.toShape())

            elif geomType(e) == "Ellipse":
                if tessellate:
                    newedges.append(Part.Wire(curvetowire(e, seglength)))
                else:
                    if len(e.Vertexes) > 1:
                        a = Part.Arc(e.Curve,
                                     e.FirstParameter,
                                     e.LastParameter).toShape()
                        newedges.append(a)
                    else:
                        newedges.append(e.Curve.toShape())

            elif (geomType(e) == "BSplineCurve"
                  or geomType(e) == "BezierCurve"):
                if tessellate:
                    newedges.append(Part.Wire(curvetowire(e, seglength)))
                else:
                    if isLine(e.Curve):
                        line = Part.LineSegment(e.Vertexes[0].Point,
                                                e.Vertexes[-1].Point).toShape()
                        newedges.append(line)
                    else:
                        newedges.append(e.Curve.toShape(e.FirstParameter,
                                                        e.LastParameter))
            else:
                newedges.append(e)
        except Part.OCCError:
            print("Debug: error cleaning edge ", e)

    return Part.makeCompound(newedges)
Exemple #3
0
def circleFrom2PointsRadius(p1, p2, radius):
    """Return a list of circles from two points, and one radius.

    The two points must not be equal.

    It calculates up to 2 possible centers.
    """
    if DraftVecUtils.equals(p1, p2):
        return None

    p1_p2 = Part.LineSegment(p1, p2).toShape()
    dist_p1p2 = DraftVecUtils.dist(p1, p1)
    mid = findMidpoint(p1_p2)

    if dist_p1p2 == 2*radius:
        circle = Part.Circle(mid, NORM, radius)
        if circle:
            return [circle]
        else:
            return None

    _dir = vec(p1_p2)
    _dir.normalize()
    perpDir = _dir.cross(App.Vector(0, 0, 1))
    perpDir.normalize()
    dist = math.sqrt(radius**2 - (dist_p1p2 / 2.0)**2)
    cen1 = App.Vector.add(mid, App.Vector(perpDir).multiply(dist))
    cen2 = App.Vector.add(mid, App.Vector(perpDir).multiply(-dist))

    circles = []
    if cen1:
        circles.append(Part.Circle(cen1, NORM, radius))
    if cen2:
        circles.append(Part.Circle(cen2, NORM, radius))

    if circles:
        return circles
    else:
        return None
Exemple #4
0
def circleFrom2PointsRadius(p1, p2, radius):
    """circleFrom2PointsRadiust(Vector, Vector, radius)"""
    if DraftVecUtils.equals(p1, p2): return None

    p1_p2 = Part.LineSegment(p1, p2).toShape()
    dist_p1p2 = DraftVecUtils.dist(p1, p1)
    mid = findMidpoint(p1_p2)
    if dist_p1p2 == 2 * radius:
        circle = Part.Circle(mid, NORM, radius)
        if circle: return [circle]
        else: return None
    dir = vec(p1_p2)
    dir.normalize()
    perpDir = dir.cross(Vector(0, 0, 1))
    perpDir.normalize()
    dist = math.sqrt(radius**2 - (dist_p1p2 / 2.0)**2)
    cen1 = Vector.add(mid, Vector(perpDir).multiply(dist))
    cen2 = Vector.add(mid, Vector(perpDir).multiply(-dist))
    circles = []
    if cen1: circles.append(Part.Circle(cen1, NORM, radius))
    if cen2: circles.append(Part.Circle(cen2, NORM, radius))
    if circles: return circles
    else: return None
Exemple #5
0
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
Exemple #6
0
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 []
Exemple #7
0
def superWire(edgeslist, closed=False):
    """Force a wire between edges that don't have coincident endpoints.

    Forces a wire between edges that don't necessarily
    have coincident endpoints. If closed=True, the wire will always be closed.
    """
    def median(v1, v2):
        vd = v2.sub(v1)
        vd.scale(0.5, 0.5, 0.5)
        return v1.add(vd)

    edges = Part.__sortEdges__(edgeslist)
    print(edges)
    newedges = []

    for i in range(len(edges)):
        curr = edges[i]
        if i == 0:
            if closed:
                prev = edges[-1]
            else:
                prev = None
        else:
            prev = edges[i - 1]

        if i == (len(edges) - 1):
            if closed:
                _next = edges[0]
            else:
                _next = None
        else:
            _next = edges[i + 1]

        print(i, prev, curr, _next)

        if prev:
            if curr.Vertexes[0].Point == prev.Vertexes[-1].Point:
                p1 = curr.Vertexes[0].Point
            else:
                p1 = median(curr.Vertexes[0].Point, prev.Vertexes[-1].Point)
        else:
            p1 = curr.Vertexes[0].Point

        if _next:
            if curr.Vertexes[-1].Point == _next.Vertexes[0].Point:
                p2 = _next.Vertexes[0].Point
            else:
                p2 = median(curr.Vertexes[-1].Point, _next.Vertexes[0].Point)
        else:
            p2 = curr.Vertexes[-1].Point

        if geomType(curr) == "Line":
            print("line", p1, p2)
            newedges.append(Part.LineSegment(p1, p2).toShape())
        elif geomType(curr) == "Circle":
            p3 = findMidpoint(curr)
            print("arc", p1, p3, p2)
            newedges.append(Part.Arc(p1, p3, p2).toShape())
        else:
            print("Cannot superWire edges that are not lines or arcs")
            return None

    print(newedges)
    return Part.Wire(newedges)
Exemple #8
0
def connect(edges, closed=False):
    """Connect the edges in the given list by their intersections."""

    inters_list = []  # List of intersections (with the previous edge).
    for i, curr in enumerate(edges):
        if i > 0:
            prev = edges[i - 1]
        elif closed:
            prev = edges[-1]
        else:
            inters_list.append(None)
            continue

        curr_inters_list = (findIntersection(prev, curr, True, True))
        if len(curr_inters_list) == 0:
            inters_list.append(None)
        elif len(curr_inters_list) == 1:
            inters_list.append(curr_inters_list[0])
        else:
            inters = curr_inters_list[DraftVecUtils.closest(
                curr.Vertexes[0].Point, curr_inters_list)]
            inters_list.append(inters)

    new_edges = []
    for i, curr in enumerate(edges):
        curr_sta = inters_list[i]
        if i < (len(edges) - 1):
            curr_end = inters_list[i + 1]
        elif closed:
            curr_end = inters_list[0]
        else:
            curr_end = None

        if curr_sta is None:
            curr_sta = curr.Vertexes[0].Point
            if i > 0:
                prev = edges[i - 1]
            elif closed:
                prev = edges[-1]
            else:
                prev = None
            if prev is not None:
                prev_end = prev.Vertexes[-1].Point
                new_edges.append(
                    Part.LineSegment(prev_end, curr_sta).toShape())

        if curr_end is None:
            curr_end = curr.Vertexes[-1].Point

        if curr_sta != curr_end:
            if geomType(curr) == "Line":
                new_edges.append(
                    Part.LineSegment(curr_sta, curr_end).toShape())
            elif geomType(curr) == "Circle":
                new_edges.append(
                    Part.Arc(curr_sta, findMidpoint(curr), curr_end).toShape())

    try:
        return Part.Wire(new_edges)
    except Part.OCCError:
        print("DraftGeomUtils.connect: unable to connect edges")
        for edge in new_edges:
            print(edge.Curve, " ", edge.Vertexes[0].Point, " ",
                  edge.Vertexes[-1].Point)
        return None