Esempio n. 1
0
    def __init__(self, trimOutline, pathWidth, angleDegrees, shiftX=0, shiftY=0,
                 design=None, designType=c.PARTIAL_ROW):
        LineGroup.__init__(self, None)
        self.shiftX = shiftX
        self.shiftY = shiftY
        self.designType = designType
        self.trimOutline = Outline(trimOutline)
        self.angleRad = (angleDegrees/360.0*2*np.pi)
        self.pathWidth = pathWidth
        lowerLeft = Point(self.trimOutline.minX, self.trimOutline.minY)
        upperRight = Point(self.trimOutline.maxX, self.trimOutline.maxY)
        
        self.trimDiagonal = (lowerLeft - upperRight)*1.1       
        self.operations = (self.extendDesign, self.createField,
                           self.centerAndRotateField, self.trimField)
        
        try:
            self.design = design(space = self.pathWidth,
                                 length = self.trimDiagonal,
                                 height = self.trimDiagonal,
                                 ) 
            self.designType = c.FULL_FIELD
        except Exception:
            self.design = LineGroup(design)
        
#        print('\nInfill times:') 
        for i in range(self.designType, c.TRIMMED_FIELD):
            startTime = time.time()
            self.operations[i]();
Esempio n. 2
0
 def extendDesign(self):
     tempDesign = LineGroup(self.design.lines)
     designWidth = self.design.maxX - self.design.minX        
     while(designWidth <= self.trimDiagonal):
         shiftX = self.design[-1].end.x - tempDesign[0].start.x
         shiftY = self.design[-1].end.y - tempDesign[0].start.y
         self.design.addLineGroup(tempDesign.translate(shiftX, shiftY))
         designWidth = self.design.maxX - self.design.minX
Esempio n. 3
0
 def __init__(self, start, end, direction, center, numPoints=c.ARC_NUMPOINTS):
     LG.__init__(self, None)        
     self.start = start
     self.end = end
     self.direction = direction
     self.center = center
     self.numPoints = numPoints        
     self.arcToLines()
Esempio n. 4
0
 def extendDesign(self):
     tempDesign = LineGroup(self.design.lines)
     designWidth = self.design.maxX - self.design.minX
     while (designWidth <= self.trimDiagonal):
         shiftX = self.design[-1].end.x - tempDesign[0].start.x
         shiftY = self.design[-1].end.y - tempDesign[0].start.y
         self.design.addLineGroup(tempDesign.translate(shiftX, shiftY))
         designWidth = self.design.maxX - self.design.minX
Esempio n. 5
0
 def __init__(self,
              start,
              end,
              direction,
              center,
              numPoints=c.ARC_NUMPOINTS):
     LG.__init__(self, None)
     self.start = start
     self.end = end
     self.direction = direction
     self.center = center
     self.numPoints = numPoints
     self.arcToLines()
Esempio n. 6
0
    def __init__(self,
                 trimOutline,
                 pathWidth,
                 angleDegrees,
                 shiftX=0,
                 shiftY=0,
                 design=None,
                 designType=c.PARTIAL_ROW):
        LineGroup.__init__(self, None)
        self.shiftX = shiftX
        self.shiftY = shiftY
        self.designType = designType
        self.trimOutline = Outline(trimOutline)
        self.angleRad = (angleDegrees / 360.0 * 2 * np.pi)
        self.pathWidth = pathWidth
        lowerLeft = Point(self.trimOutline.minX, self.trimOutline.minY)
        upperRight = Point(self.trimOutline.maxX, self.trimOutline.maxY)

        self.trimDiagonal = (lowerLeft - upperRight) * 1.1
        self.operations = (self.extendDesign, self.createField,
                           self.centerAndRotateField, self.trimField)

        try:
            self.design = design(
                space=self.pathWidth,
                length=self.trimDiagonal,
                height=self.trimDiagonal,
            )
            self.designType = c.FULL_FIELD
        except Exception:
            self.design = LineGroup(design)

#        print('\nInfill times:')
        for i in range(self.designType, c.TRIMMED_FIELD):
            startTime = time.time()
            self.operations[i]()
Esempio n. 7
0
 def _straightLines(*,
                    space: float = 0,
                    length: float = 0,
                    height: float = 0) -> LineGroup:
     lines = []
     currHeight = 0
     while currHeight < height:
         lines.append(Line(Point(0, currHeight), Point(length, currHeight)))
         currHeight += space
     group = LineGroup()
     group.lines = lines
     group.minX = 0
     group.minY = 0
     group.maxX = length
     group.maxY = currHeight - space
     return group
Esempio n. 8
0
 def _straightLines(*, space: float=0, length: float=0, height: float=0) -> LineGroup:
     lines = []
     currHeight = 0
     while currHeight < height:
         lines.append(Line(Point(0,currHeight), Point(length,currHeight)))
         currHeight += space
     group = LineGroup()
     group.lines = lines
     group.minX = 0
     group.minY = 0
     group.maxX = length
     group.maxY = currHeight-space
     return group
Esempio n. 9
0
class Infill(LineGroup):
    
   
    
    def __init__(self, trimOutline, pathWidth, angleDegrees, shiftX=0, shiftY=0,
                 design=None, designType=c.PARTIAL_ROW):
        LineGroup.__init__(self, None)
        self.shiftX = shiftX
        self.shiftY = shiftY
        self.designType = designType
        self.trimOutline = Outline(trimOutline)
        self.angleRad = (angleDegrees/360.0*2*np.pi)
        self.pathWidth = pathWidth
        lowerLeft = Point(self.trimOutline.minX, self.trimOutline.minY)
        upperRight = Point(self.trimOutline.maxX, self.trimOutline.maxY)
        
        self.trimDiagonal = (lowerLeft - upperRight)*1.1       
        self.operations = (self.extendDesign, self.createField,
                           self.centerAndRotateField, self.trimField)
        
        try:
            self.design = design(space = self.pathWidth,
                                 length = self.trimDiagonal,
                                 height = self.trimDiagonal,
                                 ) 
            self.designType = c.FULL_FIELD
        except Exception:
            self.design = LineGroup(design)
        
#        print('\nInfill times:') 
        for i in range(self.designType, c.TRIMMED_FIELD):
            startTime = time.time()
            self.operations[i]();
#            print((self.operations[i].__name__ +
#                    ''.ljust(maxLength - len(self.operations[i].__name__)) +
#                    '%.2f sec' %(time.time()-startTime)))
        
    def extendDesign(self):
        tempDesign = LineGroup(self.design.lines)
        designWidth = self.design.maxX - self.design.minX        
        while(designWidth <= self.trimDiagonal):
            shiftX = self.design[-1].end.x - tempDesign[0].start.x
            shiftY = self.design[-1].end.y - tempDesign[0].start.y
            self.design.addLineGroup(tempDesign.translate(shiftX, shiftY))
            designWidth = self.design.maxX - self.design.minX
        
    def createField(self):
        tempDesign = self.design.translate(0, self.pathWidth)
        designHeight = 0 # abs(self.design.maxY - self.design.minY)
        while(designHeight < self.trimDiagonal):
            self.design.addLineGroup(tempDesign)
            tempDesign = tempDesign.translate(0, self.pathWidth)
            designHeight += self.pathWidth
    
    def centerAndRotateField(self):
        designCP = self.design.getMidPoint()
        trimOutlineCP = self.trimOutline.getMidPoint()
        transX = trimOutlineCP.x - designCP.x
        transY = trimOutlineCP.y - designCP.y
        self.design = self.design.transform(mt.combineTransformations(
                        [mt.translateMatrix(transX+self.shiftX, transY+self.shiftY),
                         mt.rotateMatrix(self.angleRad, trimOutlineCP)]))
                         
    def trimField(self):
        trimStarts = self.trimOutline.starts
        trimVectors = self.trimOutline.vectors
        fieldStarts = self.design.starts
        fieldVectors = self.design.vectors
        trimLen = len(self.trimOutline)
        fieldLen = len(self.design)
        Q_Less_P = fieldStarts - trimStarts.reshape(trimLen,1,2)
        denom = np.cross(trimVectors, fieldVectors.reshape(fieldLen,1,2))
        all_t = np.cross(Q_Less_P, trimVectors.reshape(trimLen,1,2)).transpose()/denom
        all_u = np.cross(Q_Less_P, fieldVectors).transpose()/denom
        
        for t, u, line in zip(all_t, all_u, self.design):
            if not self.trimOutline.lineOutsideBoundingBox(line):
                pointSet = set([line.start])
                t = t[(0 <= u) & (u <= 1) & (0 <= t) & (t <= 1)]

                pointSet |= set(Point(line.start.x + line.vector[c.X]*value,
                                    line.start.y+line.vector[c.Y]*value)
                                    for value in t)

                pointSet.add(line.end)
                pointList = sorted(list(pointSet))
                pointVectors = np.array([point.normalVector for point in pointList])
                
                """ Calculation for midPoints from here:
                http://stackoverflow.com/questions/23855976/middle-point-of-each-pair-of-an-numpy-array
                """
                midPoints = (pointVectors[1:] + pointVectors[:-1])/2.0
                for i in range(len(midPoints)):
                    if self.trimOutline.isInside(midPoints[i]):
                        self.append(Line(pointList[i], pointList[i+1]))
Esempio n. 10
0
def organizedLayer(inOutlines, randStart):
    """ Takes in a list of LineGroup objects and returns them as an organized layer.
    
    A dictonary was used to hold the coroutines from linegroup since we
    will want to delete keys, value pairs while iterating throught the dict.
    
    The coroutines yield in a boolean and a Point and then yield back out
    the line which is 'closest' to the point. 'Closest' being in quotes
    because we could use any number of parameters to decide which line is
    closest from Euclidean distance of end points to time since its neighbor
    was printed (for cooling purposes). The yielded in boolean is whether or
    not the previous line was used.
    
    Currently if the LineGroup with the closest line is a outline then the
    entire outline is printed before checking any other LineGroups again.
    
    Parameters
    ----------
    inOutlines - a list of LineGroups that make up the layer
    
    Return
    ------
    A single organized LineGroup 
    """
    layer = LineGroup()

    lineCoros = {
        i: inOutlines[i].nearestLine_Coro(i)
        for i in range(len(inOutlines))
    }

    for coro in lineCoros.values():
        next(coro)
    """
    Find the lower left most point of the boudnding box which encloses
    the layer and use that as the starting point for the sort.
    """
    minX = min(i.minX for i in inOutlines)
    minY = min(i.minY for i in inOutlines)

    if randStart:
        farthestLeftOutline = min(inOutlines, key=lambda x: x.minX)
        startPoint = random.choice(farthestLeftOutline.lines).start


#        maxX = min(i.maxX for i in inOutlines)
#        maxY = min(i.maxY for i in inOutlines)
#
#        line = Line(Point(minX, minY), Point(maxX, maxY))
#
#        angle = 2*math.pi*randStart
#        startX = line.getMidPoint().x + line.length/2*math.cos(angle)
#        startY = line.getMidPoint().y + line.length/2*math.sin(angle)
#
#        startPoint = Point(startX, startY)
    else:
        startPoint = Point(minX, minY)

    lastPoint = startPoint  # The starting point for the sort
    indexOfClosest = -1  # A default value for the inital run
    while True:
        results = []
        for key in list(lineCoros.keys()):
            try:
                results.append(lineCoros[key].send(
                    (c.USED if key == indexOfClosest else c.NOT_USED,
                     lastPoint)))
            except StopIteration:
                """ If we get a StopIteration exception from the coroutine
                that means the LineGroup has no more Lines and we can remove
                it from the dictionary. """
                del lineCoros[key]

        if len(results) == 0: break  # No more items in the dictionary
        result = min(results, key=lambda x: x.distance)
        line = result.line
        indexOfClosest = result.name
        lastPoint = line.end
        layer.append(line)
        if isinstance(inOutlines[indexOfClosest], Outline):
            """ If the closest line was from an Outline then go around the whole
            outline without checking any other LineGroup. Outlines are required
            to be continuous contours (except if the have internal holes) so
            there is no need to check any other LineGroup for a closer line.
            Plus if the outline was being used as a brim to help start a print
            we would not want to stop partially through the brim.
            """
            while True:
                try:
                    line = lineCoros[indexOfClosest].send(
                        (c.USED, lastPoint)).line
                except StopIteration:
                    del lineCoros[indexOfClosest]
                    break
                else:
                    """ A reminder than an else is run if there is no exception. """
                    lastPoint = line.end
                    layer.append(line)
    return layer
Esempio n. 11
0
 def __init__(self, outline=None):
     LineGroup.__init__(self, outline)
     self.outlineFinished = False
Esempio n. 12
0
 def __init__(self, outline=None):
     LineGroup.__init__(self, outline)
     self.outlineFinished = False
Esempio n. 13
0
def noInfill() -> LineGroup:
    return LineGroup()
Esempio n. 14
0
    def _hexagons(*,
                  space: float = 0,
                  length: float = 0,
                  height: float = 0) -> LineGroup:
        baseLine = LineGroup(None)
        baseLine.addLinesFromCoordinateList(
            [[0, 0], [sideLength, 0],
             [
                 sideLength + math.cos(math.pi / 4) * sideLength,
                 math.cos(math.pi / 4) * sideLength
             ],
             [
                 sideLength * 2 + math.cos(math.pi / 4) * sideLength,
                 math.cos(math.pi / 4) * sideLength
             ], [2 * (sideLength + math.cos(math.pi / 4) * sideLength), 0]])
        fullLine = LineGroup(baseLine)

        while fullLine.maxX - fullLine.minX < length:
            baseLine = baseLine.translate(baseLine.maxX - baseLine.minX, 0)
            fullLine.addLineGroup(baseLine)

        mirrorLine = LineGroup(fullLine)
        mirrorLine = mirrorLine.mirror(c.X)
        mirrorLine = mirrorLine.translate(0, -space)
        fullLine.addLineGroup(mirrorLine)
        field = LineGroup(fullLine)

        while field.maxY - field.minY < height:
            fullLine = fullLine.translate(
                0, fullLine.maxY - fullLine.minY + space)
            field.addLineGroup(fullLine)
        return field
Esempio n. 15
0
class Infill(LineGroup):
    def __init__(self,
                 trimOutline,
                 pathWidth,
                 angleDegrees,
                 shiftX=0,
                 shiftY=0,
                 design=None,
                 designType=c.PARTIAL_ROW):
        LineGroup.__init__(self, None)
        self.shiftX = shiftX
        self.shiftY = shiftY
        self.designType = designType
        self.trimOutline = Outline(trimOutline)
        self.angleRad = (angleDegrees / 360.0 * 2 * np.pi)
        self.pathWidth = pathWidth
        lowerLeft = Point(self.trimOutline.minX, self.trimOutline.minY)
        upperRight = Point(self.trimOutline.maxX, self.trimOutline.maxY)

        self.trimDiagonal = (lowerLeft - upperRight) * 1.1
        self.operations = (self.extendDesign, self.createField,
                           self.centerAndRotateField, self.trimField)

        try:
            self.design = design(
                space=self.pathWidth,
                length=self.trimDiagonal,
                height=self.trimDiagonal,
            )
            self.designType = c.FULL_FIELD
        except Exception:
            self.design = LineGroup(design)

#        print('\nInfill times:')
        for i in range(self.designType, c.TRIMMED_FIELD):
            startTime = time.time()
            self.operations[i]()
#            print((self.operations[i].__name__ +
#                    ''.ljust(maxLength - len(self.operations[i].__name__)) +
#                    '%.2f sec' %(time.time()-startTime)))

    def extendDesign(self):
        tempDesign = LineGroup(self.design.lines)
        designWidth = self.design.maxX - self.design.minX
        while (designWidth <= self.trimDiagonal):
            shiftX = self.design[-1].end.x - tempDesign[0].start.x
            shiftY = self.design[-1].end.y - tempDesign[0].start.y
            self.design.addLineGroup(tempDesign.translate(shiftX, shiftY))
            designWidth = self.design.maxX - self.design.minX

    def createField(self):
        tempDesign = self.design.translate(0, self.pathWidth)
        designHeight = 0  # abs(self.design.maxY - self.design.minY)
        while (designHeight < self.trimDiagonal):
            self.design.addLineGroup(tempDesign)
            tempDesign = tempDesign.translate(0, self.pathWidth)
            designHeight += self.pathWidth

    def centerAndRotateField(self):
        designCP = self.design.getMidPoint()
        trimOutlineCP = self.trimOutline.getMidPoint()
        transX = trimOutlineCP.x - designCP.x
        transY = trimOutlineCP.y - designCP.y
        self.design = self.design.transform(
            mt.combineTransformations([
                mt.translateMatrix(transX + self.shiftX, transY + self.shiftY),
                mt.rotateMatrix(self.angleRad, trimOutlineCP)
            ]))

    def trimField(self):
        trimStarts = self.trimOutline.starts
        trimVectors = self.trimOutline.vectors
        fieldStarts = self.design.starts
        fieldVectors = self.design.vectors
        trimLen = len(self.trimOutline)
        fieldLen = len(self.design)
        Q_Less_P = fieldStarts - trimStarts.reshape(trimLen, 1, 2)
        denom = np.cross(trimVectors, fieldVectors.reshape(fieldLen, 1, 2))
        all_t = np.cross(Q_Less_P, trimVectors.reshape(trimLen, 1,
                                                       2)).transpose() / denom
        all_u = np.cross(Q_Less_P, fieldVectors).transpose() / denom

        for t, u, line in zip(all_t, all_u, self.design):
            if not self.trimOutline.lineOutsideBoundingBox(line):
                pointSet = set([line.start])
                t = t[(0 <= u) & (u <= 1) & (0 <= t) & (t <= 1)]

                pointSet |= set(
                    Point(line.start.x +
                          line.vector[c.X] * value, line.start.y +
                          line.vector[c.Y] * value) for value in t)

                pointSet.add(line.end)
                pointList = sorted(list(pointSet))
                pointVectors = np.array(
                    [point.normalVector for point in pointList])
                """ Calculation for midPoints from here:
                http://stackoverflow.com/questions/23855976/middle-point-of-each-pair-of-an-numpy-array
                """
                midPoints = (pointVectors[1:] + pointVectors[:-1]) / 2.0
                for i in range(len(midPoints)):
                    if self.trimOutline.isInside(midPoints[i]):
                        self.append(Line(pointList[i], pointList[i + 1]))
Esempio n. 16
0
 def _hexagons(*, space: float=0, length: float=0, height: float=0) -> LineGroup:
     baseLine = LineGroup(None)
     baseLine.addLinesFromCoordinateList([[0,0], [sideLength, 0],
              [sideLength+math.cos(math.pi/4)*sideLength, math.cos(math.pi/4)*sideLength],
               [sideLength*2+math.cos(math.pi/4)*sideLength, math.cos(math.pi/4)*sideLength],
                [2*(sideLength+math.cos(math.pi/4)*sideLength), 0]])
     fullLine = LineGroup(baseLine)
     
     while fullLine.maxX - fullLine.minX < length:
         baseLine = baseLine.translate(baseLine.maxX - baseLine.minX, 0)
         fullLine.addLineGroup(baseLine)
         
     mirrorLine = LineGroup(fullLine)
     mirrorLine = mirrorLine.mirror(c.X)
     mirrorLine = mirrorLine.translate(0, -space)
     fullLine.addLineGroup(mirrorLine)
     field = LineGroup(fullLine)
     
     while field.maxY - field.minY < height:
         fullLine = fullLine.translate(0, fullLine.maxY-fullLine.minY+space)
         field.addLineGroup(fullLine)
     return field