def getInfillDictionary(arounds, aroundWidth, infillInset, infillWidth, pixelTable, rotatedLoops, testLoops=None): 'Get combined fill loops which include most of the points.' slightlyGreaterThanInfillInset = intercircle.globalIntercircleMultiplier * infillInset allPoints = intercircle.getPointsFromLoops(rotatedLoops, infillInset, 0.7) centers = intercircle.getCentersFromPoints(allPoints, slightlyGreaterThanInfillInset) infillDictionary = {} for center in centers: insetCenter = intercircle.getSimplifiedInsetFromClockwiseLoop( center, infillInset) insetPoint = insetCenter[0] if len(insetCenter) > 2 and intercircle.getIsLarge( insetCenter, infillInset) and euclidean.getIsInFilledRegion( rotatedLoops, insetPoint): around = euclidean.getSimplifiedLoop(center, infillInset) euclidean.addLoopToPixelTable(around, pixelTable, aroundWidth) arounds.append(around) insetLoop = intercircle.getSimplifiedInsetFromClockwiseLoop( center, infillInset) euclidean.addXIntersectionsFromLoopForTable( insetLoop, infillDictionary, infillWidth) if testLoops != None: testLoops.append(insetLoop) return infillDictionary
def addTailoredLoopPath(self, line): "Add a clipped loop path." if self.clipLength > 0.0: removeTable = {} euclidean.addLoopToPixelTable(self.loopPath.path, removeTable, self.layerPixelWidth) euclidean.removePixelTableFromPixelTable(removeTable, self.layerPixelTable) self.loopPath.path = euclidean.getClippedLoopPath( self.clipLength, self.loopPath.path) self.loopPath.path = euclidean.getSimplifiedPath( self.loopPath.path, self.perimeterWidth) euclidean.addLoopToPixelTable(self.loopPath.path, self.layerPixelTable, self.layerPixelWidth) if self.oldWiddershins == None: self.addGcodeFromThreadZ(self.loopPath.path, self.loopPath.z) else: if self.oldWiddershins != euclidean.isWiddershins( self.loopPath.path): self.loopPath.path.reverse() # self.addGcodeFromThreadZ( self.loopPath.path, self.loopPath.z ) for point in self.loopPath.path: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, point, self.loopPath.z) if self.getNextThreadIsACloseLoop( self.loopPath.path) and self.maximumConnectionDistance > 0.0: self.oldWiddershins = euclidean.isWiddershins(self.loopPath.path) else: self.oldWiddershins = None self.distanceFeedRate.addLine(line) self.loopPath = None
def addTailoredLoopPath(self, line): "Add a clipped loop path." if self.clipLength > 0.0: removeTable = {} euclidean.addLoopToPixelTable(self.loopPath.path, removeTable, self.layerPixelWidth) euclidean.removePixelTableFromPixelTable(removeTable, self.layerPixelTable) self.loopPath.path = euclidean.getClippedSimplifiedLoopPath( self.clipLength, self.loopPath.path, self.perimeterWidth ) euclidean.addLoopToPixelTable(self.loopPath.path, self.layerPixelTable, self.layerPixelWidth) if self.oldWiddershins is None: self.addGcodeFromThreadZ(self.loopPath.path, self.loopPath.z) else: if self.oldWiddershins != euclidean.isWiddershins(self.loopPath.path): self.loopPath.path.reverse() for point in self.loopPath.path: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, point, self.loopPath.z) if self.getNextThreadIsACloseLoop(self.loopPath.path): self.oldConnectionPoint = self.loopPath.path[-1] self.oldWiddershins = euclidean.isWiddershins(self.loopPath.path) else: self.oldConnectionPoint = None self.oldWiddershins = None self.distanceFeedRate.addLine(line) self.loopPath = None
def addSupportLayer(self, endpoints, layer): 'Add support layer before the object layer.' # TODO refactor to parent object - avoid duplication for line in self.supportStartLines: layer.preSupportGcodeCommands.append(line) aroundPixelTable = {} aroundWidth = 0.25 * self.interfaceStep boundaryLoops = self.boundaryLayers[layer.index] halfSupportOutset = 0.5 * self.supportOutset aroundBoundaryLoops = intercircle.getAroundsFromLoops( boundaryLoops, halfSupportOutset) for aroundBoundaryLoop in aroundBoundaryLoops: euclidean.addLoopToPixelTable(aroundBoundaryLoop, aroundPixelTable, aroundWidth) paths = euclidean.getPathsFromEndpoints(endpoints, 1.5 * self.interfaceStep, aroundPixelTable, aroundWidth) feedRateMinuteMultiplied = self.supportFeedRate * 60 supportFlowRateMultiplied = self.supportFlowRateRatio * self.supportFeedRate for path in paths: supportPath = SupportPath(self.slicedModel.runtimeParameters) supportPath.addPath(path) layer.supportPaths.append(supportPath) layer.postSupportGcodeCommands.extend(self.supportEndLines)
def getInfillDictionary(arounds, aroundWidth, infillInset, infillWidth, pixelTable, rotatedLoops, testLoops=None): 'Get combined fill loops which include most of the points.' slightlyGreaterThanInfillInset = intercircle.globalIntercircleMultiplier * infillInset allPoints = intercircle.getPointsFromLoops(rotatedLoops, infillInset, 0.7) centers = intercircle.getCentersFromPoints(allPoints, slightlyGreaterThanInfillInset) infillDictionary = {} for center in centers: insetCenter = intercircle.getSimplifiedInsetFromClockwiseLoop(center, infillInset) insetPoint = insetCenter[0] if len(insetCenter) > 2 and intercircle.getIsLarge(insetCenter, infillInset) and euclidean.getIsInFilledRegion(rotatedLoops, insetPoint): around = euclidean.getSimplifiedLoop(center, infillInset) euclidean.addLoopToPixelTable(around, pixelTable, aroundWidth) arounds.append(around) insetLoop = intercircle.getSimplifiedInsetFromClockwiseLoop(center, infillInset) euclidean.addXIntersectionsFromLoopForTable(insetLoop, infillDictionary, infillWidth) if testLoops != None: testLoops.append(insetLoop) return infillDictionary
def setLayerPixelTable(self): "Set the layer pixel table." self.layerCount.printProgressIncrement('clip') boundaryLoop = None extruderActive = False self.lastInactiveLocation = None self.layerPixelTable = {} oldLocation = self.oldLocation for afterIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[afterIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( oldLocation, splitLine) if extruderActive and oldLocation != None: self.addSegmentToPixelTables(location.dropAxis(), oldLocation.dropAxis()) if extruderActive: if self.lastInactiveLocation != None: self.addSegmentToPixelTables( self.lastInactiveLocation.dropAxis(), location.dropAxis()) self.lastInactiveLocation = None else: self.lastInactiveLocation = location oldLocation = location elif firstWord == 'M101': extruderActive = True elif firstWord == 'M103': extruderActive = False elif firstWord == '(</boundaryPerimeter>)': euclidean.addLoopToPixelTable(boundaryLoop, self.layerPixelTable, self.layerPixelWidth) boundaryLoop = None elif firstWord == '(<boundaryPoint>': if boundaryLoop == None: boundaryLoop = [] location = gcodec.getLocationFromSplitLine(None, splitLine) boundaryLoop.append(location.dropAxis()) elif firstWord == '(</layer>)': return
def setLayerPixelTable(self): "Set the layer pixel table." self.layerCount.printProgressIncrement('clip') boundaryLoop = None extruderActive = False self.lastInactiveLocation = None self.layerPixelTable = {} oldLocation = self.oldLocation for afterIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(oldLocation, splitLine) if extruderActive and oldLocation != None: self.addSegmentToPixelTables(location.dropAxis(), oldLocation.dropAxis()) if extruderActive: if self.lastInactiveLocation != None: self.addSegmentToPixelTables(self.lastInactiveLocation.dropAxis(), location.dropAxis()) self.lastInactiveLocation = None else: self.lastInactiveLocation = location oldLocation = location elif firstWord == 'M101': extruderActive = True elif firstWord == 'M103': extruderActive = False elif firstWord == '(</boundaryPerimeter>)': euclidean.addLoopToPixelTable(boundaryLoop, self.layerPixelTable, self.layerPixelWidth) boundaryLoop = None elif firstWord == '(<boundaryPoint>': if boundaryLoop == None: boundaryLoop = [] location = gcodec.getLocationFromSplitLine(None, splitLine) boundaryLoop.append(location.dropAxis()) elif firstWord == '(</layer>)': return
def addSupportLayer(self, endpoints, layer): 'Add support layer before the object layer.' # TODO refactor to parent object - avoid duplication for line in self.supportStartLines: layer.preSupportGcodeCommands.append(line) aroundPixelTable = {} aroundWidth = 0.25 * self.interfaceStep boundaryLoops = self.boundaryLayers[layer.index] halfSupportOutset = 0.5 * self.supportOutset aroundBoundaryLoops = intercircle.getAroundsFromLoops(boundaryLoops, halfSupportOutset) for aroundBoundaryLoop in aroundBoundaryLoops: euclidean.addLoopToPixelTable(aroundBoundaryLoop, aroundPixelTable, aroundWidth) paths = euclidean.getPathsFromEndpoints(endpoints, 1.5 * self.interfaceStep, aroundPixelTable, aroundWidth) feedRateMinuteMultiplied = self.supportFeedRate * 60 supportFlowRateMultiplied = self.supportFlowRateRatio * self.supportFeedRate for path in paths: supportPath = SupportPath(self.slicedModel.runtimeParameters) supportPath.addPath(path) layer.supportPaths.append(supportPath) layer.postSupportGcodeCommands.extend(self.supportEndLines)
def fill(self, layer): 'Add fill to the carve layer.' layerIndex = layer.index alreadyFilledArounds = [] pixelTable = {} arounds = [] betweenWidth = self.extrusionWidth / 1.7594801994 # this really sucks I cant find hwe#(self.repository.infillWidthOverThickness.value * self.extrusionWidth *(0.7853))/1.5 #- 0.0866#todo todo TODO *0.5 is the distance between the outer loops.. self.layerExtrusionWidth = self.infillWidth # spacing between fill lines layerFillInset = self.infillWidth # the distance between perimeter incl loops and the fill pattern layerRotation = self.getLayerRotation(layerIndex, layer) reverseRotation = complex(layerRotation.real, -layerRotation.imag) surroundingCarves = [] layerRemainder = layerIndex % self.diaphragmPeriod extraShells = self.extraShellsSparseLayer if layerRemainder >= self.diaphragmThickness and layer.bridgeRotation == None: for surroundingIndex in xrange(1, self.solidSurfaceThickness + 1): self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves) self.addRotatedCarve(layerIndex, surroundingIndex, reverseRotation, surroundingCarves) if len(surroundingCarves) < self.doubleSolidSurfaceThickness: extraShells = self.extraShellsAlternatingSolidLayer if self.previousExtraShells != self.extraShellsBase: extraShells = self.extraShellsBase if layer.bridgeRotation != None: extraShells = 0 betweenWidth *= self.bridgeWidthMultiplier#/0.7853 #todo check what is better with or without the normalizer self.layerExtrusionWidth *= self.bridgeWidthMultiplier layerFillInset *= self.bridgeWidthMultiplier aroundInset = 0.25 * self.layerExtrusionWidth aroundWidth = 0.25 * self.layerExtrusionWidth self.previousExtraShells = extraShells gridPointInsetX = 0.5 * layerFillInset doubleExtrusionWidth = 2.0 * self.layerExtrusionWidth endpoints = [] infillPaths = [] layerInfillSolidity = self.infillSolidity self.isDoubleJunction = True self.isJunctionWide = True rotatedLoops = [] nestedRings = layer.nestedRings createFillForSurroundings(nestedRings, betweenWidth, False) for extraShellIndex in xrange(extraShells): createFillForSurroundings(nestedRings, self.layerExtrusionWidth, True) fillLoops = euclidean.getFillOfSurroundings(nestedRings, None) slightlyGreaterThanFill = 1.001 * layerFillInset #todo was 1.01 ACT 0.95 How much the parallel fill is filled for loop in fillLoops: alreadyFilledLoop = [] alreadyFilledArounds.append(alreadyFilledLoop) planeRotatedPerimeter = euclidean.getPointsRoundZAxis(reverseRotation, loop) rotatedLoops.append(planeRotatedPerimeter) centers = intercircle.getCentersFromLoop(planeRotatedPerimeter, slightlyGreaterThanFill) euclidean.addLoopToPixelTable(planeRotatedPerimeter, pixelTable, aroundWidth) for center in centers: alreadyFilledInset = intercircle.getSimplifiedInsetFromClockwiseLoop(center, layerFillInset) if intercircle.isLargeSameDirection(alreadyFilledInset, center, layerFillInset): alreadyFilledLoop.append(alreadyFilledInset) around = intercircle.getSimplifiedInsetFromClockwiseLoop(center, aroundInset) if euclidean.isPathInsideLoop(planeRotatedPerimeter, around) == euclidean.isWiddershins(planeRotatedPerimeter): around.reverse() arounds.append(around) euclidean.addLoopToPixelTable(around, pixelTable, aroundWidth) if len(arounds) < 1: self.addThreadsBridgeLayer(layerIndex, nestedRings, layer) return back = euclidean.getBackOfLoops(arounds) front = euclidean.getFrontOfLoops(arounds) front = math.ceil(front / self.layerExtrusionWidth) * self.layerExtrusionWidth fillWidth = back - front numberOfLines = int(math.ceil(fillWidth / self.layerExtrusionWidth)) self.frontOverWidth = 0.0 self.horizontalSegmentLists = euclidean.getHorizontalSegmentListsFromLoopLists(alreadyFilledArounds, front, numberOfLines, rotatedLoops, self.layerExtrusionWidth) self.surroundingXIntersectionLists = [] self.yList = [] removedEndpoints = [] if len(surroundingCarves) >= self.doubleSolidSurfaceThickness: xIntersectionIndexLists = [] self.frontOverWidth = euclidean.getFrontOverWidthAddXListYList(front, surroundingCarves, numberOfLines, xIntersectionIndexLists, self.layerExtrusionWidth, self.yList) for fillLine in xrange(len(self.horizontalSegmentLists)): xIntersectionIndexList = xIntersectionIndexLists[fillLine] surroundingXIntersections = euclidean.getIntersectionOfXIntersectionIndexes(self.doubleSolidSurfaceThickness, xIntersectionIndexList) self.surroundingXIntersectionLists.append(surroundingXIntersections) addSparseEndpoints(doubleExtrusionWidth, endpoints, fillLine, self.horizontalSegmentLists, layerInfillSolidity, removedEndpoints, self.solidSurfaceThickness, surroundingXIntersections) else: for fillLine in xrange(len(self.horizontalSegmentLists)): addSparseEndpoints(doubleExtrusionWidth, endpoints, fillLine, self.horizontalSegmentLists, layerInfillSolidity, removedEndpoints, self.solidSurfaceThickness, None) paths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.layerExtrusionWidth, pixelTable, aroundWidth) oldRemovedEndpointLength = len(removedEndpoints) + 1 while oldRemovedEndpointLength - len(removedEndpoints) > 0: oldRemovedEndpointLength = len(removedEndpoints) removeEndpoints(pixelTable, self.layerExtrusionWidth, paths, removedEndpoints, aroundWidth) paths = euclidean.getConnectedPaths(paths, pixelTable, aroundWidth) for path in paths: addPathToInfillPaths(self.layerExtrusionWidth, infillPaths, path, layerRotation) for nestedRing in nestedRings: nestedRing.transferPaths(infillPaths) self.addThreadsBridgeLayer(layerIndex, nestedRings, layer)
def fill(self, layer): 'Add fill to the carve layer.' layerIndex = layer.index alreadyFilledArounds = [] pixelTable = {} arounds = [] betweenWidth = self.extrusionWidth / 1.7594801994 # this really sucks I cant find hwe#(self.repository.infillWidthOverThickness.value * self.extrusionWidth *(0.7853))/1.5 #- 0.0866#todo todo TODO *0.5 is the distance between the outer loops.. self.layerExtrusionWidth = self.infillWidth # spacing between fill lines layerFillInset = self.infillWidth # the distance between perimeter incl loops and the fill pattern layerRotation = self.getLayerRotation(layerIndex, layer) reverseRotation = complex(layerRotation.real, -layerRotation.imag) surroundingCarves = [] layerRemainder = layerIndex % self.diaphragmPeriod extraShells = self.extraShellsSparseLayer if layerRemainder >= self.diaphragmThickness and layer.bridgeRotation == None: for surroundingIndex in xrange(1, self.solidSurfaceThickness + 1): self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves) self.addRotatedCarve(layerIndex, surroundingIndex, reverseRotation, surroundingCarves) if len(surroundingCarves) < self.doubleSolidSurfaceThickness: extraShells = self.extraShellsAlternatingSolidLayer if self.previousExtraShells != self.extraShellsBase: extraShells = self.extraShellsBase if layer.bridgeRotation != None: extraShells = 0 betweenWidth *= self.bridgeWidthMultiplier #/0.7853 #todo check what is better with or without the normalizer self.layerExtrusionWidth *= self.bridgeWidthMultiplier layerFillInset *= self.bridgeWidthMultiplier aroundInset = 0.25 * self.layerExtrusionWidth aroundWidth = 0.25 * self.layerExtrusionWidth self.previousExtraShells = extraShells gridPointInsetX = 0.5 * layerFillInset doubleExtrusionWidth = 2.0 * self.layerExtrusionWidth endpoints = [] infillPaths = [] layerInfillSolidity = self.infillSolidity self.isDoubleJunction = True self.isJunctionWide = True rotatedLoops = [] nestedRings = layer.nestedRings createFillForSurroundings(nestedRings, betweenWidth, False) for extraShellIndex in xrange(extraShells): createFillForSurroundings(nestedRings, self.layerExtrusionWidth, True) fillLoops = euclidean.getFillOfSurroundings(nestedRings, None) slightlyGreaterThanFill = 1.001 * layerFillInset #todo was 1.01 ACT 0.95 How much the parallel fill is filled for loop in fillLoops: alreadyFilledLoop = [] alreadyFilledArounds.append(alreadyFilledLoop) planeRotatedPerimeter = euclidean.getPointsRoundZAxis( reverseRotation, loop) rotatedLoops.append(planeRotatedPerimeter) centers = intercircle.getCentersFromLoop(planeRotatedPerimeter, slightlyGreaterThanFill) euclidean.addLoopToPixelTable(planeRotatedPerimeter, pixelTable, aroundWidth) for center in centers: alreadyFilledInset = intercircle.getSimplifiedInsetFromClockwiseLoop( center, layerFillInset) if intercircle.isLargeSameDirection(alreadyFilledInset, center, layerFillInset): alreadyFilledLoop.append(alreadyFilledInset) around = intercircle.getSimplifiedInsetFromClockwiseLoop( center, aroundInset) if euclidean.isPathInsideLoop( planeRotatedPerimeter, around) == euclidean.isWiddershins( planeRotatedPerimeter): around.reverse() arounds.append(around) euclidean.addLoopToPixelTable(around, pixelTable, aroundWidth) if len(arounds) < 1: self.addThreadsBridgeLayer(layerIndex, nestedRings, layer) return back = euclidean.getBackOfLoops(arounds) front = euclidean.getFrontOfLoops(arounds) front = math.ceil( front / self.layerExtrusionWidth) * self.layerExtrusionWidth fillWidth = back - front numberOfLines = int(math.ceil(fillWidth / self.layerExtrusionWidth)) self.frontOverWidth = 0.0 self.horizontalSegmentLists = euclidean.getHorizontalSegmentListsFromLoopLists( alreadyFilledArounds, front, numberOfLines, rotatedLoops, self.layerExtrusionWidth) self.surroundingXIntersectionLists = [] self.yList = [] removedEndpoints = [] if len(surroundingCarves) >= self.doubleSolidSurfaceThickness: xIntersectionIndexLists = [] self.frontOverWidth = euclidean.getFrontOverWidthAddXListYList( front, surroundingCarves, numberOfLines, xIntersectionIndexLists, self.layerExtrusionWidth, self.yList) for fillLine in xrange(len(self.horizontalSegmentLists)): xIntersectionIndexList = xIntersectionIndexLists[fillLine] surroundingXIntersections = euclidean.getIntersectionOfXIntersectionIndexes( self.doubleSolidSurfaceThickness, xIntersectionIndexList) self.surroundingXIntersectionLists.append( surroundingXIntersections) addSparseEndpoints(doubleExtrusionWidth, endpoints, fillLine, self.horizontalSegmentLists, layerInfillSolidity, removedEndpoints, self.solidSurfaceThickness, surroundingXIntersections) else: for fillLine in xrange(len(self.horizontalSegmentLists)): addSparseEndpoints(doubleExtrusionWidth, endpoints, fillLine, self.horizontalSegmentLists, layerInfillSolidity, removedEndpoints, self.solidSurfaceThickness, None) paths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.layerExtrusionWidth, pixelTable, aroundWidth) oldRemovedEndpointLength = len(removedEndpoints) + 1 while oldRemovedEndpointLength - len(removedEndpoints) > 0: oldRemovedEndpointLength = len(removedEndpoints) removeEndpoints(pixelTable, self.layerExtrusionWidth, paths, removedEndpoints, aroundWidth) paths = euclidean.getConnectedPaths(paths, pixelTable, aroundWidth) for path in paths: addPathToInfillPaths(self.layerExtrusionWidth, infillPaths, path, layerRotation) for nestedRing in nestedRings: nestedRing.transferPaths(infillPaths) self.addThreadsBridgeLayer(layerIndex, nestedRings, layer)