def getAroundBetweenPath(self, begin, end): "Get the path around the loops in the way of the original line segment." aroundBetweenPath = [] boundaries = self.getBoundaries() boundarySegments = self.getBoundarySegments(begin, boundaries, end) for boundarySegmentIndex, boundarySegment in enumerate(boundarySegments): segment = boundarySegment.segment if boundarySegmentIndex < len(boundarySegments) - 1 and self.runningJumpSpace > 0.0: segment = boundarySegment.getSegment( boundarySegmentIndex, boundarySegments, self.edgeWidth, self.runningJumpSpace ) aroundBetweenPath += self.getAroundBetweenLineSegment(segment[0], boundaries, segment[1]) if boundarySegmentIndex < len(boundarySegments) - 1: aroundBetweenPath.append(segment[1]) aroundBetweenPath.append(boundarySegments[boundarySegmentIndex + 1].segment[0]) for pointIndex in xrange(len(aroundBetweenPath) - 1, -1, -1): pointBefore = begin beforeIndex = pointIndex - 1 if beforeIndex >= 0: pointBefore = aroundBetweenPath[beforeIndex] pointAfter = end afterIndex = pointIndex + 1 if afterIndex < len(aroundBetweenPath): pointAfter = aroundBetweenPath[afterIndex] if not euclidean.isLineIntersectingLoops(boundaries, pointBefore, pointAfter): del aroundBetweenPath[pointIndex] return aroundBetweenPath
def getAroundBetweenPath(self, begin, end): 'Get the path around the loops in the way of the original line segment.' aroundBetweenPath = [] betweens = self.getBetweens() boundaries = self.getBoundaries() boundarySegments = self.getBoundarySegments(begin, boundaries, end) for boundarySegmentIndex, boundarySegment in enumerate( boundarySegments): segment = boundarySegment.segment if boundarySegmentIndex < len( boundarySegments) - 1 and self.runningJumpSpace > 0.0: segment = boundarySegment.getSegment(boundarySegmentIndex, boundarySegments, self.perimeterWidth, self.runningJumpSpace) aroundBetweenPath += self.getAroundBetweenLineSegment( segment[0], boundaries, segment[1]) if boundarySegmentIndex < len(boundarySegments) - 1: aroundBetweenPath.append(segment[1]) aroundBetweenPath.append( boundarySegments[boundarySegmentIndex + 1].segment[0]) for pointIndex in xrange(len(aroundBetweenPath) - 1, -1, -1): pointBefore = begin beforeIndex = pointIndex - 1 if beforeIndex >= 0: pointBefore = aroundBetweenPath[beforeIndex] pointAfter = end afterIndex = pointIndex + 1 if afterIndex < len(aroundBetweenPath): pointAfter = aroundBetweenPath[afterIndex] if not euclidean.isLineIntersectingLoops(betweens, pointBefore, pointAfter): del aroundBetweenPath[pointIndex] return aroundBetweenPath
def getIsRunningJumpPathAdded( self, betweens, end, lastPoint, nearestEndMinusLastSegment, pathAround, penultimatePoint, runningJumpSpace ): """Add a running jump path if possible, and return if it was added.""" jumpStartPoint = lastPoint - nearestEndMinusLastSegment * runningJumpSpace if euclidean.isLineIntersectingLoops( betweens, penultimatePoint, jumpStartPoint ): return False pathAround[-1] = jumpStartPoint return True
def getLoopsFromCorrectMesh( edges, faces, vertexes, z ): 'Get loops from a carve of a correct mesh.' remainingEdgeTable = getRemainingEdgeTable(edges, vertexes, z) remainingValues = remainingEdgeTable.values() error = False for edge in remainingValues: if len( edge.faceIndexes ) < 2: if not hasattr(edge, 'errorReported'): print('Model error(hole): ' + str(vertexes[edge.vertexIndexes[0]]) + ' ' + str(vertexes[edge.vertexIndexes[1]])) edge.errorReported = True error = True if error: return [] loops = [] while isPathAdded( edges, faces, loops, remainingEdgeTable, vertexes, z ): pass warning = False for idx in xrange(0, len(loops)-1): loop = loops[idx] p0 = loop[-1] for p1 in loop: if euclidean.isLineIntersectingLoops(loops[idx+1:], p0, p1): if not warning: print('Warning, the triangle mesh slice intersects itself in getLoopsFromCorrectMesh in triangle_mesh.') print('Model error(intersect): (%f, %f, %f) (%f, %f, %f)' % (p0.real, p0.imag, z, p1.real, p1.imag, z)) warning = True p0 = p1 if warning: return [] return loops
def getIsAsFarAndNotIntersecting( self, begin, end ): """Determine if the point on the line is at least as far from the loop as the center point.""" if begin == end: print('this should never happen but it does not really matter, begin == end in getIsAsFarAndNotIntersecting in comb.') print(begin) return True return not euclidean.isLineIntersectingLoops( self.getBetweens(), begin, end )
def getIsRunningJumpPathAdded( self, betweens, end, lastPoint, nearestEndMinusLastSegment, pathAround, penultimatePoint, runningJumpSpace ): "Add a running jump path if possible, and return if it was added." jumpStartPoint = lastPoint - nearestEndMinusLastSegment * runningJumpSpace if euclidean.isLineIntersectingLoops( betweens, penultimatePoint, jumpStartPoint ): return False pathAround[-1] = jumpStartPoint return True
def getIsAsFarAndNotIntersecting( self, begin, end ): "Determine if the point on the line is at least as far from the loop as the center point." if begin == end: print('this should never happen but it does not really matter, begin == end in getIsAsFarAndNotIntersecting in comb.') print(begin) return True return not euclidean.isLineIntersectingLoops( self.getBetweens(), begin, end )
def getInsidePointsAlong(self, begin, end, points): "Get the points along the segment if it is required to keep the path inside the widdershin boundaries." segment = end - begin segmentLength = abs(segment) if segmentLength < self.quadrupleEdgeWidth: return [] segmentHalfPerimeter = self.halfEdgeWidth / segmentLength * segment justAfterBegin = begin + segmentHalfPerimeter justBeforeEnd = end - segmentHalfPerimeter widdershins = self.getWiddershins() if not euclidean.isLineIntersectingLoops(widdershins, justAfterBegin, justBeforeEnd): return [] numberOfSteps = 10 stepLength = (segmentLength - self.doubleEdgeWidth) / float(numberOfSteps) for step in xrange(1, numberOfSteps + 1): along = begin + stepLength * step if not euclidean.isLineIntersectingLoops(widdershins, along, justBeforeEnd): return [along] return []
def isIntersectingItself( loop, width ): "Determine if the loop is intersecting itself." outlines = [] for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if euclidean.isLineIntersectingLoops( outlines, pointBegin, pointEnd ): return True addSegmentOutline( False, outlines, pointBegin, pointEnd, width ) return False
def isIntersectingItself(loop, width): "Determine if the loop is intersecting itself." outlines = [] for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if euclidean.isLineIntersectingLoops(outlines, pointBegin, pointEnd): return True addSegmentOutline(False, outlines, pointBegin, pointEnd, width) return False
def getInsidePointsAlong(self, begin, end, points): 'Get the points along the segment if it is required to keep the path inside the widdershin boundaries.' segment = end - begin segmentLength = abs(segment) if segmentLength < self.quadruplePerimeterWidth: return [] segmentHalfPerimeter = self.halfPerimeterWidth / segmentLength * segment justAfterBegin = begin + segmentHalfPerimeter justBeforeEnd = end - segmentHalfPerimeter widdershins = self.getWiddershins() if not euclidean.isLineIntersectingLoops(widdershins, justAfterBegin, justBeforeEnd): return [] numberOfSteps = 10 stepLength = (segmentLength - self.doublePerimeterWidth) / float(numberOfSteps) for step in xrange(1, numberOfSteps + 1): along = begin + stepLength * step if not euclidean.isLineIntersectingLoops(widdershins, along, justBeforeEnd): return [along] return []
def addGcodeFromPerimeterPaths(self, isIntersectingSelf, loop, loopLayer, loopLists, radius): "Add the perimeter paths to the output." segments = [] outlines = [] thickOutlines = [] allLoopLists = loopLists[:] + [thickOutlines] aroundLists = loopLists for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if isIntersectingSelf: if euclidean.isLineIntersectingLoops(outlines, pointBegin, pointEnd): segments += getSegmentsFromLoopListsPoints( allLoopLists, pointBegin, pointEnd) else: segments += getSegmentsFromLoopListsPoints( loopLists, pointBegin, pointEnd) addSegmentOutline(False, outlines, pointBegin, pointEnd, self.overlapRemovalWidth) addSegmentOutline(True, thickOutlines, pointBegin, pointEnd, self.overlapRemovalWidth) else: segments += getSegmentsFromLoopListsPoints( loopLists, pointBegin, pointEnd) perimeterPaths = [] path = [] muchSmallerThanRadius = 0.1 * radius segments = getInteriorSegments(loopLayer.loops, segments) for segment in segments: pointBegin = segment[0].point if not isCloseToLast(perimeterPaths, pointBegin, muchSmallerThanRadius): path = [pointBegin] perimeterPaths.append(path) path.append(segment[1].point) if len(perimeterPaths) > 1: firstPath = perimeterPaths[0] lastPath = perimeterPaths[-1] if abs(lastPath[-1] - firstPath[0]) < 0.1 * muchSmallerThanRadius: connectedBeginning = lastPath[:-1] + firstPath perimeterPaths[0] = connectedBeginning perimeterPaths.remove(lastPath) muchGreaterThanRadius = 6.0 * radius for perimeterPath in perimeterPaths: if euclidean.getPathLength(perimeterPath) > muchGreaterThanRadius: self.distanceFeedRate.addGcodeFromThreadZ( perimeterPath, loopLayer.z)
def addGcodeFromPerimeterPaths( self, nestedRing, isIntersectingSelf, loop, alreadyFilledArounds, halfWidth, boundary ): "Add the perimeter paths to the output." segments = [] outlines = [] thickOutlines = [] allLoopLists = alreadyFilledArounds[:] + [thickOutlines] aroundLists = alreadyFilledArounds for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if isIntersectingSelf: if euclidean.isLineIntersectingLoops(outlines, pointBegin, pointEnd): segments += getSegmentsFromLoopListsPoints(allLoopLists, pointBegin, pointEnd) else: segments += getSegmentsFromLoopListsPoints(alreadyFilledArounds, pointBegin, pointEnd) addSegmentOutline(False, outlines, pointBegin, pointEnd, self.overlapRemovalWidth) addSegmentOutline(True, thickOutlines, pointBegin, pointEnd, self.overlapRemovalWidth) else: segments += getSegmentsFromLoopListsPoints(alreadyFilledArounds, pointBegin, pointEnd) perimeterPaths = [] path = [] muchSmallerThanRadius = 0.1 * halfWidth segments = getInteriorSegments(boundary, segments) for segment in segments: pointBegin = segment[0].point if not isCloseToLast(perimeterPaths, pointBegin, muchSmallerThanRadius): path = [pointBegin] perimeterPaths.append(path) path.append(segment[1].point) if len(perimeterPaths) > 1: firstPath = perimeterPaths[0] lastPath = perimeterPaths[-1] if abs(lastPath[-1] - firstPath[0]) < 0.1 * muchSmallerThanRadius: connectedBeginning = lastPath[:-1] + firstPath perimeterPaths[0] = connectedBeginning perimeterPaths.remove(lastPath) muchGreaterThanRadius = 6.0 * halfWidth for perimeterPath in perimeterPaths: if euclidean.getPathLength(perimeterPath) > muchGreaterThanRadius: nestedRing.perimeter.addPath(perimeterPath)
def addGcodeFromPerimeterPaths(self, isIntersectingSelf, loop, loopLayer, loopLists, radius): "Add the edge paths to the output." segments = [] outlines = [] thickOutlines = [] allLoopLists = loopLists[:] + [thickOutlines] aroundLists = loopLists for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if isIntersectingSelf: if euclidean.isLineIntersectingLoops(outlines, pointBegin, pointEnd): segments += getSegmentsFromLoopListsPoints(allLoopLists, pointBegin, pointEnd) else: segments += getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd) addSegmentOutline(False, outlines, pointBegin, pointEnd, self.overlapRemovalWidth) addSegmentOutline(True, thickOutlines, pointBegin, pointEnd, self.overlapRemovalWidth) else: segments += getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd) edgePaths = [] path = [] muchSmallerThanRadius = 0.1 * radius segments = getInteriorSegments(loopLayer.loops, segments) for segment in segments: pointBegin = segment[0].point if not isCloseToLast(edgePaths, pointBegin, muchSmallerThanRadius): path = [pointBegin] edgePaths.append(path) path.append(segment[1].point) if len(edgePaths) > 1: firstPath = edgePaths[0] lastPath = edgePaths[-1] if abs(lastPath[-1] - firstPath[0]) < 0.1 * muchSmallerThanRadius: connectedBeginning = lastPath[: -1] + firstPath edgePaths[0] = connectedBeginning edgePaths.remove(lastPath) muchGreaterThanRadius = 6.0 * radius for edgePath in edgePaths: if euclidean.getPathLength(edgePath) > muchGreaterThanRadius: self.distanceFeedRate.addGcodeFromThreadZ(edgePath, loopLayer.z)
def getLoopsFromCorrectMesh(edges, faces, vertexes, z): 'Get loops from a carve of a correct mesh.' remainingEdgeTable = getRemainingEdgeTable(edges, vertexes, z) remainingValues = remainingEdgeTable.values() error = False for edge in remainingValues: if len(edge.faceIndexes) < 2: if not hasattr(edge, 'errorReported'): print('Model error(hole): ' + str(vertexes[edge.vertexIndexes[0]]) + ' ' + str(vertexes[edge.vertexIndexes[1]])) edge.errorReported = True error = True if error: return [] loops = [] while isPathAdded(edges, faces, loops, remainingEdgeTable, vertexes, z): pass warning = False for idx in xrange(0, len(loops) - 1): loop = loops[idx] p0 = loop[-1] for p1 in loop: if euclidean.isLineIntersectingLoops(loops[idx + 1:], p0, p1): if not warning: print( 'Warning, the triangle mesh slice intersects itself in getLoopsFromCorrectMesh in triangle_mesh.' ) print('Model error(intersect): (%f, %f, %f) (%f, %f, %f)' % (p0.real, p0.imag, z, p1.real, p1.imag, z)) warning = True p0 = p1 if warning: return [] return loops