Example #1
0
def AddArcOrLines(check_for_arc, new_vertices, might_be_an_arc, arc, arc_found,
                  arc_added):
    if check_for_arc and CheckForArc(new_vertices[-1], might_be_an_arc, arc):
        arc_found = True
    else:
        if arc_found:
            if arc.AlmostALine():
                new_vertices.append(geom.Vertex(arc.e, arc.user_data))
            else:
                new_vertices.append(
                    geom.Vertex(1 if arc.dir else -1, arc.e, arc.c,
                                arc.user_data))

            arc_added = True
            arc_found = False
            back_vt = might_be_an_arc[-1]
            might_be_an_arc = []
            if check_for_arc: might_be_an_arc.append(copy.deepcopy(back_vt))
        else:
            back_vt = might_be_an_arc[-1]
            if check_for_arc: might_be_an_arc.pop_back()
            first = True
            for v in might_be_an_arc:
                if first == False or len(
                        new_vertices) == 0 or new_vertices[-1].p != v.p:
                    new_vertices.append(copy.deepcopy(v))
            might_be_an_arc = []
            if check_for_arc:
                might_be_an_arc.append(copy.deepcopy(back_vt))
Example #2
0
def zigzag(a, stepover, zig_unidirectional):
    if a.NumCurves() == 0:
        return

    global rightward_for_zigs
    global curve_list_for_zigs
    global sin_angle_for_zigs
    global cos_angle_for_zigs
    global sin_minus_angle_for_zigs
    global cos_minus_angle_for_zigs
    global one_over_units

    one_over_units = 1 / geom.get_units()

    a = rotated_area(a)

    b = a.GetBox()

    x0 = b.MinX() - 1.0
    x1 = b.MaxX() + 1.0

    height = b.MaxY() - b.MinY()
    num_steps = int(height / stepover + 1)
    y = b.MinY() + 0.1 * one_over_units
    null_point = geom.Point(0, 0)
    rightward_for_zigs = True
    curve_list_for_zigs = []

    for i in range(0, num_steps):
        y0 = y
        y = y + stepover
        p0 = geom.Point(x0, y0)
        p1 = geom.Point(x0, y)
        p2 = geom.Point(x1, y)
        p3 = geom.Point(x1, y0)
        c = geom.Curve()
        c.Append(geom.Vertex(0, p0, null_point, 0))
        c.Append(geom.Vertex(0, p1, null_point, 0))
        c.Append(geom.Vertex(0, p2, null_point, 1))
        c.Append(geom.Vertex(0, p3, null_point, 0))
        c.Append(geom.Vertex(0, p0, null_point, 1))
        a2 = geom.Area()
        a2.Append(c)
        a2.Intersect(a)
        make_zig(a2, y0, y, zig_unidirectional)
        if zig_unidirectional == False:
            rightward_for_zigs = (rightward_for_zigs == False)

    reorder_zigs()
Example #3
0
 def Append(self, v):
     if isinstance(v, geom.Point):
         self.vertices.append(geom.Vertex(v))
     elif isinstance(v, geom.Vertex):
         self.vertices.append(v)
     else:
         raise ValueError("Vertex argument expected")
Example #4
0
def add_roll_off(curve, roll_off_curve, direction, roll_radius, offset_extra, roll_off):
    if direction == "on": return
    if roll_off == None: return
    if curve.NumVertices() <= 1: return

    last_span = curve.GetLastSpan()
    
    if roll_off == 'auto':
        if roll_radius < 0.0000000001: return
        v = last_span.GetVector(1.0) # get end direction
        if direction == 'right':
            off_v = geom.Point(v.y, -v.x)
        else:
            off_v = geom.Point(-v.y, v.x)

        rollend = last_span.v.p + off_v * roll_radius;
    else:
        rollend =  roll_off  
             
    # add the end of the original kurve
    roll_off_curve.Append(last_span.v.p)
    if rollend == last_span.v.p: return
    rvertex = geom.Vertex(rollend)
    v = last_span.GetVector(1.0) # get end direction
    rvertex.c, rvertex.type = geom.TangentialArc(last_span.v.p, rollend, v)

    # add the roll off arc  
    roll_off_curve.Append(rvertex)
Example #5
0
def add_roll_on(curve, roll_on_curve, direction, roll_radius, offset_extra, roll_on):
    if direction == "on": roll_on = None
    if curve.NumVertices() <= 1: return
    first_span = curve.GetFirstSpan()

    if roll_on == None:
        rollstart = first_span.p
    elif roll_on == 'auto':
        if roll_radius < 0.0000000001:
            rollstart = first_span.p
        v = first_span.GetVector(0.0)
        if direction == 'right':
            off_v = geom.Point(v.y, -v.x)
        else:
            off_v = geom.Point(-v.y, v.x)
        rollstart = first_span.p + off_v * roll_radius
    else:
        rollstart = roll_on       

    rvertex = geom.Vertex(first_span.p)
    
    if first_span.p == rollstart:
        rvertex.type = 0
    else:
        v = first_span.GetVector(0.0) # get start direction
        rvertex.c, rvertex.type = geom.TangentialArc(first_span.p, rollstart, -v)
        rvertex.type = -rvertex.type # because TangentialArc was used in reverse
    # add a start roll on point
    roll_on_curve.Append(rollstart)

    # add the roll on arc
    roll_on_curve.Append(rvertex)
Example #6
0
def make_obround(p0, p1, radius):
    dir = p1 - p0
    d = dir.Length()
    dir.Normalize()
    right = geom.Point(dir.y, -dir.x)
    obround = geom.Area()
    c = geom.Curve()
    vt0 = p0 + right * radius
    vt1 = p1 + right * radius
    vt2 = p1 - right * radius
    vt3 = p0 - right * radius
    c.Append(geom.Vertex(0, vt0, geom.Point(0, 0)))
    c.Append(geom.Vertex(0, vt1, geom.Point(0, 0)))
    c.Append(geom.Vertex(1, vt2, p1))
    c.Append(geom.Vertex(0, vt3, geom.Point(0, 0)))
    c.Append(geom.Vertex(1, vt0, p0))
    obround.Append(c)
    return obround
Example #7
0
 def __init__(self, p, v, start_span=False):
     """ create a Span from a point and a vertex """
     if isinstance(p, geom.Point) == False:
         raise ValueError("Point argument expected")
     self.p = copy.deepcopy(p)
     if isinstance(v, geom.Point):
         self.v = geom.Vertex(p)
     elif isinstance(v, geom.Vertex):
         self.v = copy.deepcopy(v)
     else:
         raise ValueError("Vertex argument expected")
         self.start_span = start_span
Example #8
0
    def calculate_span_cylinders(self, span, color):
        sz = span.p.y * toolpath.coords.voxels_per_mm
        ez = span.v.p.y * toolpath.coords.voxels_per_mm

        z = sz
        while z < ez:
            # make a line at this z
            intersection_line = area.Span(
                area.Point(0, z),
                area.Vertex(0, area.Point(300, z), area.Point(0, 0)), False)
            intersections = span.Intersect(intersection_line)
            if len(intersections):
                radius = intersections[0].x * toolpath.coords.voxels_per_mm
                self.cylinders.append(
                    VoxelCyl(radius, z * toolpath.coords.voxels_per_mm, color))
            z += 1 / toolpath.coords.voxels_per_mm
Example #9
0
 def PointToPerim(self, p):
     best_dist = None
     prev_p = None
     perim = 0.0
     first_span = True
     for vertex in self.vertices:
         if prev_p:
             span = Span(prev_p, vertex, first_span)
             near_point = span.NearestPointToPoint(p)
             first_span = False
             dist = near_point.Dist(p)
             if (best_dist == None or dist < best_dist):
                 best_dist = dist
                 span_to_point(
                     prev_p, geom.Vertex(span.v.type, near_point, span.v.c))
                 perim_at_best_dist = perim + span_to_point.Length()
             perim += span.Length()
         prev_p = vertex.p
     if best_dist == None:
         return None
     return perim_at_best_dist
Example #10
0
def unrotated_vertex(v):
    if v.type:
        return geom.Vertex(v.type, unrotated_point(v.p), unrotated_point(v.c))
    return geom.Vertex(v.type, unrotated_point(v.p), geom.Point(0, 0))
Example #11
0
def make_zig_curve(curve, y0, y, zig_unidirectional):
    if rightward_for_zigs:
        curve.Reverse()

    # find a high point to start looking from
    high_point = None
    for vertex in curve.GetVertices():
        if high_point == None:
            high_point = vertex.p
        elif vertex.p.y > high_point.y:
            # use this as the new high point
            high_point = vertex.p
        elif math.fabs(vertex.p.y - high_point.y) < 0.002 * one_over_units:
            # equal high point
            if rightward_for_zigs:
                # use the furthest left point
                if vertex.p.x < high_point.x:
                    high_point = vertex.p
            else:
                # use the furthest right point
                if vertex.p.x > high_point.x:
                    high_point = vertex.p

    zig = geom.Curve()

    high_point_found = False
    zig_started = False
    zag_found = False

    for i in range(
            0, 2
    ):  # process the curve twice because we don't know where it will start
        prev_p = None
        for vertex in curve.GetVertices():
            if zag_found: break
            if prev_p != None:
                if zig_started:
                    zig.Append(unrotated_vertex(vertex))
                    if math.fabs(vertex.p.y - y) < 0.002 * one_over_units:
                        zag_found = True
                        break
                elif high_point_found:
                    if math.fabs(vertex.p.y - y0) < 0.002 * one_over_units:
                        if zig_started:
                            zig.Append(unrotated_vertex(vertex))
                        elif math.fabs(
                                prev_p.y - y0
                        ) < 0.002 * one_over_units and vertex.type == 0:
                            zig.Append(
                                geom.Vertex(0, unrotated_point(prev_p),
                                            geom.Point(0, 0)))
                            zig.Append(unrotated_vertex(vertex))
                            zig_started = True
                elif vertex.p.x == high_point.x and vertex.p.y == high_point.y:
                    high_point_found = True
            prev_p = vertex.p

    if zig_started:

        if zig_unidirectional == True:
            # remove the last bit of zig
            if math.fabs(zig.LastVertex().p.y - y) < 0.002 * one_over_units:
                vertices = zig.GetVertices()
                while len(vertices) > 0:
                    v = vertices[len(vertices) - 1]
                    if math.fabs(v.p.y - y0) < 0.002 * one_over_units:
                        break
                    else:
                        vertices.pop()
                zig = geom.Curve()
                for v in vertices:
                    zig.Append(v)

        curve_list_for_zigs.append(zig)
Example #12
0
    def _EliminateLoops(self, leftwards_value):
        new_vertices = []
        kinVertex = 0

        spans = self.GetSpans()
        sp0 = geom.Span(geom.Point(0, 0), geom.Point(0, 0))
        sp1 = geom.Span(geom.Point(0, 0), geom.Point(0, 0))

        while (kinVertex < len(self.vertices)):
            clipped = False
            sp0.p = self.vertices[kinVertex].p
            kinVertex += 1

            if kinVertex == 1:
                new_vertices.append(
                    geom.Vertex(sp0.p)
                )  # start point mustn't dissappear for this simple method
            if kinVertex < len(self.vertices):
                ksaveVertex = kinVertex
                sp0.v = self.vertices[kinVertex]
                kinVertex += 1

                ksaveVertex1 = kinVertex
                if kinVertex < len(self.vertices):
                    sp1.p = self.vertices[kinVertex].p
                    kinVertex += 1
                    ksaveVertex2 = kinVertex
                    fwdCount = 0
                    while (kinVertex < len(self.vertices)):
                        sp1.v = self.vertices[kinVertex]
                        kinVertex += 1
                        intersections = sp0.Intersect(sp1)
                        if (len(intersections) > 0) and (sp0.p.Dist(
                                intersections[0]) < geom.tolerance):
                            intersections = []
                        if len(intersections) > 0:
                            if len(intersections) == 2:
                                # choose first intercept on sp0
                                intersections.pop()
                            ksaveVertex = ksaveVertex1
                            clipped = True  # in a clipped section
                            if self._DoesIntersInterfere(
                                    intersection[0], self, leftwards_value):
                                sp0.v.p = intersections[
                                    0]  # ok so truncate this span to the intersection
                                clipped = False  # end of clipped section
                                break
                            # no valid intersection found so carry on
                        sp1.p = sp1.v.p  # next
                        ksaveVertex1 = ksaveVertex2
                        ksaveVertex2 = kinVertex

                        fwdCount += 1
                        if ((kinVertex > len(self.vertices) + 1)
                                or fwdCount > 25) and clipped == False:
                            break

                if clipped:
                    # still in a clipped section - error
                    return False

                print('adding ' + str(sp0.v))
                new_vertices.append(sp0.v)
                kinVertex = ksaveVertex

        # no more spans - seems ok
        self.vertices = new_vertices
        return True
Example #13
0
    def _Offset(self, leftwards_value):
        """ offset the curve using Geoff's method """
        if (math.fabs(leftwards_value) < geom.tolerance) or len(
                self.vertices) < 2:
            return True

        RollDir = l if leftwards_value < 0 else -1

        kOffset = Curve()
        kOffset_started = False

        spans = self.GetSpans()

        bClosed = self.IsClosed()
        nspans = len(spans)
        if bClosed:
            curSpan = spans[-1]
            prevSpanOff = copy.copy(curSpan)
            prevSpanOff.Offset(leftwards_value)
            nspans += 1

        for spannumber in range(0, nspans):
            if spannumber == nspans:
                curSpan = spans[0]  # closed curve - read first span again
            else:
                curSpan = spans[spannumber]

            if curSpan.IsNullSpan() == False:
                intersections = []
                curSpanOff = copy.copy(curSpan)

                curSpanOff.Offset(leftwards_value)

                if kOffset_started == False:
                    kOffset.Append(geom.Vertex(curSpanOff.p))
                    kOffset_started = True

                if spannumber > 0:
                    # see if tangent
                    d = curSpanOff.p.Dist(prevSpanOff.v.p)
                    if (d > geom.tolerance) and (
                            curSpanOff.IsNullSpan()
                            == False) and (prevSpanOff.IsNullSpan() == False):
                        # see if offset spans intersect

                        cp = prevSpanOff.GetVector(1.0) ^ curSpanOff.GetVector(
                            0.0)
                        inters = (cp > 0.0 and leftwards_value > 0) or (
                            cp < 0.0 and leftwards_value < 0)

                        if inters:
                            intersections = prevSpanOff.Intersect(curSpanOff)

                        if len(intersections) == 1:
                            # intersection - modify previous endpoint
                            kOffset.vertices[-1].p = intersections[0]
                        else:
                            # 0 or 2 intersections, add roll around (remove -ve loops in elimination function)
                            kOffset.vertices.append(
                                geom.Vertex(RollDir, curSpanOff.p, curSpan.p))

                if spannumber < len(spans):
                    if kOffset_started == False:
                        kOffset.vertices.append(geom.Vertex(curSpanOff.p))
                        kOffset_started = True
                    kOffset.vertices.append(curSpanOff.v)
                elif len(intersections) == 1:
                    kOffset.vertices[0].p = intersections[0]
            if curSpanOff.IsNullSpan() == False: prevSpanOff = curSpanOff

        if kOffset._EliminateLoops(leftwards_value) == True and bClosed:
            # check for inverted offsets of closed kurves
            if kOffset.IsClosed():
                a = self.GetArea()
                dir = a < 0
                ao = kOffset.GetArea()
                dirOffset = ao < 0

                if dir != dirOffset:
                    return False
                else:
                    # check area change compatible with offset direction - catastrophic failure
                    bigger = (a > 0 and leftward_value > 0) or (
                        a < 0 and leftward_value < 0)
                    if bigger and math.fabs(ao) < math.fabs(a):
                        return False
            else:
                return False  # started closed but now open??

        self.vertices = kOffset.vertices

        return True