def getLargestCenterOutsetLoopFromLoop(loop, radius, thresholdRatio=0.9): 'Get the largest circle outset loop from the loop.' if radius == 0.0: return loop radius = abs(radius) points = getPointsFromLoop(loop, radius, thresholdRatio) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radius) largestCenterOutset = None largestOutsetArea = -987654321.0 for center in centers: outset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(outset, center, radius): if euclidean.isPathInsideLoop( loop, outset) != euclidean.isWiddershins(loop): centerOutset = CenterOutset(center, outset) outsetArea = abs(euclidean.getAreaLoop(outset)) if outsetArea > largestOutsetArea: largestOutsetArea = outsetArea largestCenterOutset = centerOutset if largestCenterOutset == None: return None largestCenterOutset.center = euclidean.getSimplifiedLoop( largestCenterOutset.center, radius) return largestCenterOutset
def transferPaths(self, paths): 'Transfer paths.' for innerNestedRing in self.innerNestedRings: innerNestedRing.transferPaths(paths) loop = self.getXYBoundaries() for insideIndex in xrange(len(paths) - 1, -1, -1): inside = paths[ insideIndex ] if euclidean.isPathInsideLoop(loop, inside): self.infillPathsHolder.append(inside) del paths[ insideIndex ]
def getBridgeLoops( layerThickness, loop ): "Get the inset bridge loops from the loop." halfWidth = 1.5 * layerThickness slightlyGreaterThanHalfWidth = 1.1 * halfWidth extrudateLoops = [] centers = intercircle.getCentersFromLoop( loop, slightlyGreaterThanHalfWidth ) for center in centers: extrudateLoop = intercircle.getSimplifiedInsetFromClockwiseLoop( center, halfWidth ) if intercircle.isLargeSameDirection( extrudateLoop, center, halfWidth ): if euclidean.isPathInsideLoop( loop, extrudateLoop ) == euclidean.isWiddershins( loop ): extrudateLoop.reverse() extrudateLoops.append( extrudateLoop ) return extrudateLoops
def getBridgeLoops( layerThickness, loop ): 'Get the inset bridge loops from the loop.' halfWidth = 1.5 * layerThickness slightlyGreaterThanHalfWidth = 1.1 * halfWidth extrudateLoops = [] centers = intercircle.getCentersFromLoop( loop, slightlyGreaterThanHalfWidth ) for center in centers: extrudateLoop = intercircle.getSimplifiedInsetFromClockwiseLoop( center, halfWidth ) if intercircle.isLargeSameDirection( extrudateLoop, center, halfWidth ): if euclidean.isPathInsideLoop( loop, extrudateLoop ) == euclidean.isWiddershins(loop): extrudateLoop.reverse() extrudateLoops.append( extrudateLoop ) return extrudateLoops
def getLargestCenterOutsetLoopFromLoop(loop, radius, thresholdRatio=0.9): 'Get the largest circle outset loop from the loop.' radius = abs(radius) points = getPointsFromLoop(loop, radius, thresholdRatio) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radius) largestCenterOutset = None largestOutsetArea = -987654321.0 for center in centers: outset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(outset, center, radius): if euclidean.isPathInsideLoop(loop, outset) != euclidean.isWiddershins(loop): centerOutset = CenterOutset(center, outset) outsetArea = abs(euclidean.getAreaLoop(outset)) if outsetArea > largestOutsetArea: largestOutsetArea = outsetArea largestCenterOutset = centerOutset if largestCenterOutset == None: return None largestCenterOutset.center = euclidean.getSimplifiedLoop(largestCenterOutset.center, radius) return largestCenterOutset
def getLargestCenterOutsetLoopFromLoop( loop, radius, thresholdRatio = 0.9 ): "Get the largest circle outset loop from the loop." radius = abs(radius) slightlyGreaterThanRadius = 1.01 * radius points = getPointsFromLoop( loop, slightlyGreaterThanRadius, thresholdRatio ) centers = getCentersFromPoints( points, radius ) largestCenterOutset = None largestOutsetArea = - 999999999.0 for center in centers: outset = getSimplifiedInsetFromClockwiseLoop( center, radius ) if isLargeSameDirection( outset, center, radius ): if euclidean.isPathInsideLoop( loop, outset ) != euclidean.isWiddershins(loop): centerOutset = CenterOutset( center, outset ) outsetArea = abs( euclidean.getPolygonArea( outset ) ) if outsetArea > largestOutsetArea: outsetArea = largestOutsetArea largestCenterOutset = centerOutset if largestCenterOutset == None: return None largestCenterOutset.center = euclidean.getSimplifiedLoop( largestCenterOutset.center, radius ) return largestCenterOutset
def getIsIntersectingWithinLoop(loop, otherLoop, outsetLoop): "Determine if the loop is intersecting or is within the other loop." if euclidean.isLoopIntersectingLoop(loop, otherLoop): return True return euclidean.isPathInsideLoop( otherLoop, loop) != euclidean.isPathInsideLoop(otherLoop, outsetLoop)
def getIsIntersectingWithinLoop( loop, otherLoop, outsetLoop ): "Determine if the loop is intersecting or is within the other loop." if euclidean.isLoopIntersectingLoop( loop, otherLoop ): return True return euclidean.isPathInsideLoop( otherLoop, loop ) != euclidean.isPathInsideLoop( otherLoop, outsetLoop )
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)