def getOverhangDirection(belowOutsetLoops, segmentBegin, segmentEnd): "Add to span direction from the endpoint segments which overhang the layer below." segment = segmentEnd - segmentBegin normalizedSegment = euclidean.getNormalized( complex(segment.real, segment.imag)) segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) segmentBegin = segmentYMirror * segmentBegin segmentEnd = segmentYMirror * segmentEnd solidXIntersectionList = [] y = segmentBegin.imag solidXIntersectionList.append( euclidean.XIntersectionIndex(-1.0, segmentBegin.real)) solidXIntersectionList.append( euclidean.XIntersectionIndex(-1.0, segmentEnd.real)) for belowLoopIndex in xrange(len(belowOutsetLoops)): belowLoop = belowOutsetLoops[belowLoopIndex] rotatedOutset = euclidean.getPointsRoundZAxis(segmentYMirror, belowLoop) euclidean.addXIntersectionIndexesFromLoopY(rotatedOutset, belowLoopIndex, solidXIntersectionList, y) overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y) overhangDirection = complex() for overhangingSegment in overhangingSegments: overhangDirection += getDoubledRoundZ(overhangingSegment, normalizedSegment) return overhangDirection
def getDistance(self): "Get distance between point and nearest intersection or bottom point along line." self.pointMinusBottomY = self.alongAway.point.y - self.alongAway.minimumY self.diagonalDistance = self.pointMinusBottomY * self.diagonalRatio if self.alongAway.pointIndex == None: return self.getDistanceToBottom() rotatedLoop = euclidean.getPointsRoundZAxis( self.intersectionYMirror, euclidean.getComplexPath( self.alongAway.loop ) ) rotatedPointComplex = rotatedLoop[ self.alongAway.pointIndex ] beginX = rotatedPointComplex.real endX = beginX + self.diagonalDistance + self.diagonalDistance xIntersectionIndexList = [] for pointIndex in self.alongAway.awayIndexes: beginComplex = rotatedLoop[ pointIndex ] endComplex = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] xIntersection = euclidean.getXIntersectionIfExists( beginComplex, endComplex, rotatedPointComplex.imag ) if xIntersection != None: if xIntersection >= beginX and xIntersection < endX: xIntersectionIndexList.append( euclidean.XIntersectionIndex( pointIndex, xIntersection ) ) self.closestXDistance = 987654321.0 self.closestXIntersectionIndex = None for xIntersectionIndex in xIntersectionIndexList: xDistance = abs( xIntersectionIndex.x - beginX ) if xDistance < self.closestXDistance: self.closestXIntersectionIndex = xIntersectionIndex self.closestXDistance = xDistance if self.closestXIntersectionIndex != None: return self.closestXDistance return self.getDistanceToBottom()
def addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Add intersections of the loop with the x segment.' rotatedLoop = euclidean.getPointsRoundZAxis( segmentYMirror, loop ) for pointIndex in xrange( len( rotatedLoop ) ): pointFirst = rotatedLoop[ pointIndex ] pointSecond = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] addLineXSegmentIntersection( lineLoopsIntersections, segmentFirstX, segmentSecondX, pointFirst, pointSecond, y )
def addPathToInfillPaths(infillWidth, infillPaths, path, rotationPlaneAngle): 'Add simplified path to fill.' simplifiedPath = euclidean.getSimplifiedPath(path, infillWidth) if len(simplifiedPath) < 2: return planeRotated = euclidean.getPointsRoundZAxis(rotationPlaneAngle, simplifiedPath) infillPaths.append(planeRotated)
def getSegmentsFromLoopListsPoints( loopLists, pointBegin, pointEnd ): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength == 0.0: return [] normalizedSegment /= normalizedSegmentLength segmentYMirror = complex( normalizedSegment.real, - normalizedSegment.imag ) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd rotatedLoopLists = [] for loopList in loopLists: rotatedLoopList = [] rotatedLoopLists.append( rotatedLoopList ) for loop in loopList: rotatedLoop = euclidean.getPointsRoundZAxis( segmentYMirror, loop ) rotatedLoopList.append( rotatedLoop ) xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointBeginRotated.real ) ) xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointEndRotated.real ) ) euclidean.addXIntersectionIndexesFromLoopListsY( rotatedLoopLists, xIntersectionIndexList, pointBeginRotated.imag ) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag ) for segment in segments: for endpoint in segment: endpoint.point *= normalizedSegment return segments
def getSegmentsFromPoints(loops, pointBegin, pointEnd): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs(normalizedSegment) if normalizedSegmentLength == 0.0: return [] normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex(-1, pointBeginRotated.real)) xIntersectionIndexList.append( euclidean.XIntersectionIndex(-1, pointEndRotated.real)) for loopIndex in xrange(len(loops)): rotatedLoop = euclidean.getPointsRoundZAxis(segmentYMirror, loops[loopIndex]) euclidean.addXIntersectionIndexesFromLoopY(rotatedLoop, loopIndex, xIntersectionIndexList, pointBeginRotated.imag) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag) for segment in segments: for endpoint in segment: endpoint.point *= normalizedSegment return segments
def addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y ): "Add intersections of the loop with the x segment." rotatedLoop = euclidean.getPointsRoundZAxis( segmentYMirror, loop ) for pointIndex in xrange( len( rotatedLoop ) ): pointFirst = rotatedLoop[ pointIndex ] pointSecond = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] addLineXSegmentIntersection( lineLoopsIntersections, segmentFirstX, segmentSecondX, pointFirst, pointSecond, y )
def getPathsBetween(self, begin, end): "Insert paths between the perimeter and the fill." aroundBetweenPath = [] points = [begin] lineX = [] switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, -segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag boundaries = self.getBoundaries() for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[boundaryIndex] boundaryRotated = euclidean.getPointsRoundZAxis( segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) lineX.append(xIntersection) points.append(end) lineXIndex = 0 # pathBetweenAdded = False while lineXIndex < len(lineX) - 1: lineXFirst = lineX[lineXIndex] lineXSecond = lineX[lineXIndex + 1] loopFirst = boundaries[lineXFirst.index] if lineXSecond.index == lineXFirst.index: pathBetween = self.getPathBetween( loopFirst, points[lineXIndex:lineXIndex + 4]) pathBetween = self.getSimplifiedAroundPath( points[lineXIndex], points[lineXIndex + 3], loopFirst, pathBetween) aroundBetweenPath += pathBetween lineXIndex += 2 else: lineXIndex += 1 # isLeavingPerimeter = False # if lineXSecond.index != lineXFirst.index: # isLeavingPerimeter = True # pathBetween = self.getPathBetween( points[ lineXIndex + 1 ], points[ lineXIndex + 2 ], isLeavingPerimeter, loopFirst ) # if isLeavingPerimeter: # pathBetweenAdded = True # else: # pathBetween = self.getSimplifiedAroundPath( points[ lineXIndex ], points[ lineXIndex + 3 ], loopFirst, pathBetween ) # pathBetweenAdded = True # aroundBetweenPath += pathBetween # lineXIndex += 2 return aroundBetweenPath
def addSegmentOutline(isThick, outlines, pointBegin, pointEnd, width): "Add a diamond or hexagonal outline for a line segment." width = abs(width) exclusionWidth = 0.6 * width slope = 0.2 if isThick: slope = 3.0 exclusionWidth = 0.8 * width segment = pointEnd - pointBegin segmentLength = abs(segment) if segmentLength == 0.0: return normalizedSegment = segment / segmentLength outline = [] segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd along = 0.05 alongLength = along * segmentLength if alongLength > 0.1 * exclusionWidth: along *= 0.1 * exclusionWidth / alongLength alongEnd = 1.0 - along remainingToHalf = 0.5 - along alongToWidth = exclusionWidth / slope / segmentLength pointBeginIntermediate = euclidean.getIntermediateLocation( along, pointBeginRotated, pointEndRotated) pointEndIntermediate = euclidean.getIntermediateLocation( alongEnd, pointBeginRotated, pointEndRotated) outline.append(pointBeginIntermediate) verticalWidth = complex(0.0, exclusionWidth) if alongToWidth > 0.9 * remainingToHalf: verticalWidth = complex(0.0, slope * remainingToHalf * segmentLength) middle = (pointBeginIntermediate + pointEndIntermediate) * 0.5 middleDown = middle - verticalWidth middleUp = middle + verticalWidth outline.append(middleUp) outline.append(pointEndIntermediate) outline.append(middleDown) else: alongOutsideBegin = along + alongToWidth alongOutsideEnd = alongEnd - alongToWidth outsideBeginCenter = euclidean.getIntermediateLocation( alongOutsideBegin, pointBeginRotated, pointEndRotated) outsideBeginCenterDown = outsideBeginCenter - verticalWidth outsideBeginCenterUp = outsideBeginCenter + verticalWidth outsideEndCenter = euclidean.getIntermediateLocation( alongOutsideEnd, pointBeginRotated, pointEndRotated) outsideEndCenterDown = outsideEndCenter - verticalWidth outsideEndCenterUp = outsideEndCenter + verticalWidth outline.append(outsideBeginCenterUp) outline.append(outsideEndCenterUp) outline.append(pointEndIntermediate) outline.append(outsideEndCenterDown) outline.append(outsideBeginCenterDown) outlines.append(euclidean.getPointsRoundZAxis(normalizedSegment, outline))
def addSegmentOutline( isThick, outlines, pointBegin, pointEnd, width ): "Add a diamond or hexagonal outline for a line segment." width = abs( width ) exclusionWidth = 0.6 * width slope = 0.2 if isThick: slope = 3.0 exclusionWidth = 0.8 * width segment = pointEnd - pointBegin segmentLength = abs( segment ) if segmentLength == 0.0: return normalizedSegment = segment / segmentLength outline = [] segmentYMirror = complex( normalizedSegment.real, - normalizedSegment.imag ) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd along = 0.05 alongLength = along * segmentLength if alongLength > 0.1 * exclusionWidth: along *= 0.1 * exclusionWidth / alongLength alongEnd = 1.0 - along remainingToHalf = 0.5 - along alongToWidth = exclusionWidth / slope / segmentLength pointBeginIntermediate = euclidean.getIntermediateLocation( along, pointBeginRotated, pointEndRotated ) pointEndIntermediate = euclidean.getIntermediateLocation( alongEnd, pointBeginRotated, pointEndRotated ) outline.append( pointBeginIntermediate ) verticalWidth = complex( 0.0, exclusionWidth ) if alongToWidth > 0.9 * remainingToHalf: verticalWidth = complex( 0.0, slope * remainingToHalf * segmentLength ) middle = ( pointBeginIntermediate + pointEndIntermediate ) * 0.5 middleDown = middle - verticalWidth middleUp = middle + verticalWidth outline.append( middleUp ) outline.append( pointEndIntermediate ) outline.append( middleDown ) else: alongOutsideBegin = along + alongToWidth alongOutsideEnd = alongEnd - alongToWidth outsideBeginCenter = euclidean.getIntermediateLocation( alongOutsideBegin, pointBeginRotated, pointEndRotated ) outsideBeginCenterDown = outsideBeginCenter - verticalWidth outsideBeginCenterUp = outsideBeginCenter + verticalWidth outsideEndCenter = euclidean.getIntermediateLocation( alongOutsideEnd, pointBeginRotated, pointEndRotated ) outsideEndCenterDown = outsideEndCenter - verticalWidth outsideEndCenterUp = outsideEndCenter + verticalWidth outline.append( outsideBeginCenterUp ) outline.append( outsideEndCenterUp ) outline.append( pointEndIntermediate ) outline.append( outsideEndCenterDown ) outline.append( outsideBeginCenterDown ) outlines.append( euclidean.getPointsRoundZAxis( normalizedSegment, outline ) )
def getPathsBetween(self, begin, end): """Insert paths between the perimeter and the fill.""" aroundBetweenPath = [] points = [begin] lineX = [] switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, - segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag boundaries = self.getBoundaries() for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[ boundaryIndex ] boundaryRotated = euclidean.getPointsRoundZAxis(segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) lineX.append(xIntersection) points.append(end) lineXIndex = 0 # pathBetweenAdded = False while lineXIndex < len(lineX) - 1: lineXFirst = lineX[lineXIndex] lineXSecond = lineX[lineXIndex + 1] loopFirst = boundaries[lineXFirst.index] if lineXSecond.index == lineXFirst.index: pathBetween = self.getPathBetween(loopFirst, points[lineXIndex : lineXIndex + 4]) pathBetween = self.getSimplifiedAroundPath(points[lineXIndex], points[lineXIndex + 3], loopFirst, pathBetween) aroundBetweenPath += pathBetween lineXIndex += 2 else: lineXIndex += 1 # isLeavingPerimeter = False # if lineXSecond.index != lineXFirst.index: # isLeavingPerimeter = True # pathBetween = self.getPathBetween( points[ lineXIndex + 1 ], points[ lineXIndex + 2 ], isLeavingPerimeter, loopFirst ) # if isLeavingPerimeter: # pathBetweenAdded = True # else: # pathBetween = self.getSimplifiedAroundPath( points[ lineXIndex ], points[ lineXIndex + 3 ], loopFirst, pathBetween ) # pathBetweenAdded = True # aroundBetweenPath += pathBetween # lineXIndex += 2 return aroundBetweenPath
def addRotatedCarve(self, currentLayer, layerDelta, reverseRotation, surroundingCarves): 'Add a rotated carve to the surrounding carves.' layerIndex = currentLayer + layerDelta if layerIndex < 0 or layerIndex >= len(self.slicedModel.layers): return layer = self.slicedModel.layers[layerIndex] nestedRings = layer.nestedRings rotatedCarve = [] for nestedRing in nestedRings: planeRotatedLoop = euclidean.getPointsRoundZAxis(reverseRotation, nestedRing.getXYBoundaries()) rotatedCarve.append(planeRotatedLoop) outsetRadius = float(abs(layerDelta)) * self.extrusionWidth #todo investigate was float(abs(layerDelta)) * self.layerThickness rotatedCarve = intercircle.getInsetSeparateLoopsFromLoops(-outsetRadius, rotatedCarve) surroundingCarves.append(rotatedCarve)
def getOverhangDirection( belowOutsetLoops, segmentBegin, segmentEnd ): "Add to span direction from the endpoint segments which overhang the layer below." segment = segmentEnd - segmentBegin normalizedSegment = euclidean.getNormalized( complex( segment.real, segment.imag ) ) segmentYMirror = complex( normalizedSegment.real, - normalizedSegment.imag ) segmentBegin = segmentYMirror * segmentBegin segmentEnd = segmentYMirror * segmentEnd solidXIntersectionList = [] y = segmentBegin.imag solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentBegin.real ) ) solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentEnd.real ) ) for belowLoopIndex in xrange( len( belowOutsetLoops ) ): belowLoop = belowOutsetLoops[ belowLoopIndex ] rotatedOutset = euclidean.getPointsRoundZAxis( segmentYMirror, belowLoop ) euclidean.addXIntersectionIndexesFromLoopY( rotatedOutset, belowLoopIndex, solidXIntersectionList, y ) overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y ) overhangDirection = complex() for overhangingSegment in overhangingSegments: overhangDirection += getDoubledRoundZ( overhangingSegment, normalizedSegment ) return overhangDirection
def addRotatedCarve(self, currentLayer, layerDelta, reverseRotation, surroundingCarves): 'Add a rotated carve to the surrounding carves.' layerIndex = currentLayer + layerDelta if layerIndex < 0 or layerIndex >= len(self.slicedModel.layers): return layer = self.slicedModel.layers[layerIndex] nestedRings = layer.nestedRings rotatedCarve = [] for nestedRing in nestedRings: planeRotatedLoop = euclidean.getPointsRoundZAxis( reverseRotation, nestedRing.getXYBoundaries()) rotatedCarve.append(planeRotatedLoop) outsetRadius = float( abs(layerDelta) ) * self.extrusionWidth #todo investigate was float(abs(layerDelta)) * self.layerThickness rotatedCarve = intercircle.getInsetSeparateLoopsFromLoops( -outsetRadius, rotatedCarve) surroundingCarves.append(rotatedCarve)
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)