def getRemainingLoopAddFace(faces, remainingLoop): "Get the remaining loop and add face." for indexedVertexIndex, indexedVertex in enumerate(remainingLoop): nextIndex = (indexedVertexIndex + 1) % len(remainingLoop) previousIndex = (indexedVertexIndex + len(remainingLoop) - 1) % len(remainingLoop) nextVertex = remainingLoop[nextIndex] previousVertex = remainingLoop[previousIndex] remainingPath = euclidean.getAroundLoop( (indexedVertexIndex + 2) % len(remainingLoop), previousIndex, remainingLoop) if len(remainingLoop) < 4 or getIsPathEntirelyOutsideTriangle( previousVertex, indexedVertex, nextVertex, remainingPath): faceConvex = face.Face() faceConvex.index = len(faces) faceConvex.vertexIndexes.append(indexedVertex.index) faceConvex.vertexIndexes.append(nextVertex.index) faceConvex.vertexIndexes.append(previousVertex.index) faces.append(faceConvex) return euclidean.getAroundLoop(nextIndex, indexedVertexIndex, remainingLoop) print( 'Warning, could not decompose polygon in getRemainingLoopAddFace in trianglemesh for:' ) print(remainingLoop) return []
def getPathBetween(self, betweenFirst, betweenSecond, isLeavingPerimeter, loopFirst): "Add a path between the perimeter and the fill." loopFirst = intercircle.getLargestInsetLoopFromLoopNoMatterWhat( loopFirst, self.combInset) nearestFirstDistanceIndex = euclidean.getNearestDistanceIndex( betweenFirst, loopFirst) nearestSecondDistanceIndex = euclidean.getNearestDistanceIndex( betweenSecond, loopFirst) firstBeginIndex = (nearestFirstDistanceIndex.index + 1) % len(loopFirst) secondBeginIndex = (nearestSecondDistanceIndex.index + 1) % len(loopFirst) nearestFirst = euclidean.getNearestPointOnSegment( loopFirst[nearestFirstDistanceIndex.index], loopFirst[firstBeginIndex], betweenFirst) nearestSecond = euclidean.getNearestPointOnSegment( loopFirst[nearestSecondDistanceIndex.index], loopFirst[secondBeginIndex], betweenSecond) clockwisePath = [nearestFirst] widdershinsPath = [nearestFirst] loopBeforeLeaving = euclidean.getAroundLoop(firstBeginIndex, firstBeginIndex, loopFirst) if nearestFirstDistanceIndex.index == nearestSecondDistanceIndex.index: if euclidean.getPathLength( widdershinsPath) < self.minimumDepartureDistance: widdershinsPath = [nearestFirst] + loopBeforeLeaving reversedLoop = loopBeforeLeaving[:] reversedLoop.reverse() clockwisePath = [nearestFirst] + reversedLoop else: widdershinsLoop = euclidean.getAroundLoop(firstBeginIndex, secondBeginIndex, loopFirst) widdershinsPath += widdershinsLoop clockwiseLoop = euclidean.getAroundLoop(secondBeginIndex, firstBeginIndex, loopFirst) clockwiseLoop.reverse() clockwisePath += clockwiseLoop clockwisePath.append(nearestSecond) widdershinsPath.append(nearestSecond) if euclidean.getPathLength(widdershinsPath) > euclidean.getPathLength( clockwisePath): loopBeforeLeaving.reverse() widdershinsPath = clockwisePath if isLeavingPerimeter: totalDistance = euclidean.getPathLength(widdershinsPath) loopLength = euclidean.getPolygonLength(loopBeforeLeaving) while totalDistance < self.minimumDepartureDistance: widdershinsPath = [nearestFirst ] + loopBeforeLeaving + widdershinsPath[1:] totalDistance += loopLength return widdershinsPath
def getPathsByIntersectedLoop(begin, end, loop): "Get both paths along the loop from the point closest to the begin to the point closest to the end." closestBeginDistanceIndex = euclidean.getClosestDistanceIndexToLine(begin, loop) closestEndDistanceIndex = euclidean.getClosestDistanceIndexToLine(end, loop) beginIndex = (closestBeginDistanceIndex.index + 1) % len(loop) endIndex = (closestEndDistanceIndex.index + 1) % len(loop) closestBegin = euclidean.getClosestPointOnSegment(loop[closestBeginDistanceIndex.index], loop[beginIndex], begin) closestEnd = euclidean.getClosestPointOnSegment(loop[closestEndDistanceIndex.index], loop[endIndex], end) clockwisePath = [closestBegin] widdershinsPath = [closestBegin] if closestBeginDistanceIndex.index != closestEndDistanceIndex.index: widdershinsPath += euclidean.getAroundLoop(beginIndex, endIndex, loop) clockwisePath += euclidean.getAroundLoop(endIndex, beginIndex, loop)[::-1] clockwisePath.append(closestEnd) widdershinsPath.append(closestEnd) return [clockwisePath, widdershinsPath]
def getIntersectLoop(self): "Get intersection loop." beginIndex = self.closestXIntersectionIndex.index + len( self.alongAway.loop) + 1 endIndex = self.alongAway.pointIndex + len(self.alongAway.loop) + 1 return euclidean.getAroundLoop(beginIndex, endIndex, self.alongAway.loop)
def alterClockwiseSupportedPath( alongAway, xmlElement ): "Get clockwise path with overhangs carved out." alongAway.bottomPoints = [] alongAway.overhangSpan = xmlElement.getCascadeFloat( 0.0, 'overhang.span') maximumY = - 987654321.0 minimumYPointIndex = 0 for pointIndex in xrange( len( alongAway.loop ) ): point = alongAway.loop[pointIndex] if point.y < alongAway.loop[ minimumYPointIndex ].y: minimumYPointIndex = pointIndex maximumY = max( maximumY, point.y ) alongAway.maximumYPlus = 2.0 * ( maximumY - alongAway.loop[ minimumYPointIndex ].y ) alongAway.loop = euclidean.getAroundLoop( minimumYPointIndex, minimumYPointIndex, alongAway.loop ) overhangClockwise = OverhangClockwise( alongAway ) alongAway.unsupportedPointIndexes = [] oldUnsupportedPointIndexesLength = - 987654321.0 while len( alongAway.unsupportedPointIndexes ) > oldUnsupportedPointIndexesLength: oldUnsupportedPointIndexesLength = len( alongAway.unsupportedPointIndexes ) addUnsupportedPointIndexes( alongAway ) for pointIndex in alongAway.unsupportedPointIndexes: point = alongAway.loop[pointIndex] point.y -= alongAway.maximumYPlus alongAway.unsupportedPointIndexes.sort() alongAway.unsupportedPointIndexLists = [] oldUnsupportedPointIndex = - 987654321.0 unsupportedPointIndexList = None for unsupportedPointIndex in alongAway.unsupportedPointIndexes: if unsupportedPointIndex > oldUnsupportedPointIndex + 1: unsupportedPointIndexList = [] alongAway.unsupportedPointIndexLists.append( unsupportedPointIndexList ) oldUnsupportedPointIndex = unsupportedPointIndex unsupportedPointIndexList.append( unsupportedPointIndex ) alongAway.unsupportedPointIndexLists.reverse() for unsupportedPointIndexList in alongAway.unsupportedPointIndexLists: overhangClockwise.alterLoop( unsupportedPointIndexList )
def getJitteredLoop( jitterDistance, jitterLoop ): 'Get a jittered loop path.' loopLength = euclidean.getLoopLength( jitterLoop ) lastLength = 0.0 pointIndex = 0 totalLength = 0.0 jitterPosition = ( jitterDistance + 256.0 * loopLength ) % loopLength while totalLength < jitterPosition and pointIndex < len( jitterLoop ): firstPoint = jitterLoop[pointIndex] secondPoint = jitterLoop[ (pointIndex + 1) % len( jitterLoop ) ] pointIndex += 1 lastLength = totalLength totalLength += abs(firstPoint - secondPoint) remainingLength = jitterPosition - lastLength pointIndex = pointIndex % len( jitterLoop ) ultimateJitteredPoint = jitterLoop[pointIndex] penultimateJitteredPointIndex = ( pointIndex + len( jitterLoop ) - 1 ) % len( jitterLoop ) penultimateJitteredPoint = jitterLoop[ penultimateJitteredPointIndex ] segment = ultimateJitteredPoint - penultimateJitteredPoint segmentLength = abs(segment) originalOffsetLoop = euclidean.getAroundLoop( pointIndex, pointIndex, jitterLoop ) if segmentLength <= 0.0: return originalOffsetLoop newUltimatePoint = penultimateJitteredPoint + segment * remainingLength / segmentLength return [newUltimatePoint] + originalOffsetLoop
def getJitteredLoop(jitterDistance, jitterLoop): 'Get a jittered loop path.' loopLength = euclidean.getLoopLength(jitterLoop) lastLength = 0.0 pointIndex = 0 totalLength = 0.0 jitterPosition = (jitterDistance + 256.0 * loopLength) % loopLength while totalLength < jitterPosition and pointIndex < len(jitterLoop): firstPoint = jitterLoop[pointIndex] secondPoint = jitterLoop[(pointIndex + 1) % len(jitterLoop)] pointIndex += 1 lastLength = totalLength totalLength += abs(firstPoint - secondPoint) remainingLength = jitterPosition - lastLength pointIndex = pointIndex % len(jitterLoop) ultimateJitteredPoint = jitterLoop[pointIndex] penultimateJitteredPointIndex = (pointIndex + len(jitterLoop) - 1) % len(jitterLoop) penultimateJitteredPoint = jitterLoop[penultimateJitteredPointIndex] segment = ultimateJitteredPoint - penultimateJitteredPoint segmentLength = abs(segment) originalOffsetLoop = euclidean.getAroundLoop(pointIndex, pointIndex, jitterLoop) if segmentLength <= 0.0: return originalOffsetLoop newUltimatePoint = penultimateJitteredPoint + segment * remainingLength / segmentLength return [newUltimatePoint] + originalOffsetLoop
def getPathsByIntersectedLoop( begin, end, loop ): "Get both paths along the loop from the point nearest to the begin to the point nearest to the end." nearestBeginDistanceIndex = euclidean.getNearestDistanceIndex( begin, loop ) nearestEndDistanceIndex = euclidean.getNearestDistanceIndex( end, loop ) beginIndex = ( nearestBeginDistanceIndex.index + 1 ) % len(loop) endIndex = ( nearestEndDistanceIndex.index + 1 ) % len(loop) nearestBegin = euclidean.getNearestPointOnSegment( loop[ nearestBeginDistanceIndex.index ], loop[ beginIndex ], begin ) nearestEnd = euclidean.getNearestPointOnSegment( loop[ nearestEndDistanceIndex.index ], loop[ endIndex ], end ) clockwisePath = [ nearestBegin ] widdershinsPath = [ nearestBegin ] if nearestBeginDistanceIndex.index != nearestEndDistanceIndex.index: widdershinsPath += euclidean.getAroundLoop( beginIndex, endIndex, loop ) clockwisePath += euclidean.getAroundLoop( endIndex, beginIndex, loop )[: : -1] clockwisePath.append( nearestEnd ) widdershinsPath.append( nearestEnd ) return [ clockwisePath, widdershinsPath ]
def getRemainingLoopAddFace(faces, remainingLoop): 'Get the remaining loop and add face.' for indexedVertexIndex, indexedVertex in enumerate(remainingLoop): nextIndex = (indexedVertexIndex + 1) % len(remainingLoop) previousIndex = (indexedVertexIndex + len(remainingLoop) - 1) % len(remainingLoop) nextVertex = remainingLoop[nextIndex] previousVertex = remainingLoop[previousIndex] remainingPath = euclidean.getAroundLoop((indexedVertexIndex + 2) % len(remainingLoop), previousIndex, remainingLoop) if len(remainingLoop) < 4 or getIsPathEntirelyOutsideTriangle(previousVertex, indexedVertex, nextVertex, remainingPath): faceConvex = face.Face() faceConvex.index = len(faces) faceConvex.vertexIndexes.append(indexedVertex.index) faceConvex.vertexIndexes.append(nextVertex.index) faceConvex.vertexIndexes.append(previousVertex.index) faces.append(faceConvex) return euclidean.getAroundLoop(nextIndex, indexedVertexIndex, remainingLoop) print('Warning, could not decompose polygon in getRemainingLoopAddFace in trianglemesh for:') print(remainingLoop) return []
def getPathsByIntersectedLoop(begin, end, loop): 'Get both paths along the loop from the point closest to the begin to the point closest to the end.' closestBeginDistanceIndex = euclidean.getClosestDistanceIndexToLine( begin, loop) closestEndDistanceIndex = euclidean.getClosestDistanceIndexToLine( end, loop) beginIndex = (closestBeginDistanceIndex.index + 1) % len(loop) endIndex = (closestEndDistanceIndex.index + 1) % len(loop) closestBegin = euclidean.getClosestPointOnSegment( loop[closestBeginDistanceIndex.index], loop[beginIndex], begin) closestEnd = euclidean.getClosestPointOnSegment( loop[closestEndDistanceIndex.index], loop[endIndex], end) clockwisePath = [closestBegin] widdershinsPath = [closestBegin] if closestBeginDistanceIndex.index != closestEndDistanceIndex.index: widdershinsPath += euclidean.getAroundLoop(beginIndex, endIndex, loop) clockwisePath += euclidean.getAroundLoop(endIndex, beginIndex, loop)[::-1] clockwisePath.append(closestEnd) widdershinsPath.append(closestEnd) return [clockwisePath, widdershinsPath]
def getPathBetween(self, betweenFirst, betweenSecond, isLeavingPerimeter, loopFirst): "Add a path between the perimeter and the fill." loopFirst = intercircle.getLargestInsetLoopFromLoopNoMatterWhat(loopFirst, self.combInset) nearestFirstDistanceIndex = euclidean.getNearestDistanceIndex(betweenFirst, loopFirst) nearestSecondDistanceIndex = euclidean.getNearestDistanceIndex(betweenSecond, loopFirst) firstBeginIndex = (nearestFirstDistanceIndex.index + 1) % len(loopFirst) secondBeginIndex = (nearestSecondDistanceIndex.index + 1) % len(loopFirst) nearestFirst = euclidean.getNearestPointOnSegment( loopFirst[nearestFirstDistanceIndex.index], loopFirst[firstBeginIndex], betweenFirst ) nearestSecond = euclidean.getNearestPointOnSegment( loopFirst[nearestSecondDistanceIndex.index], loopFirst[secondBeginIndex], betweenSecond ) clockwisePath = [nearestFirst] widdershinsPath = [nearestFirst] loopBeforeLeaving = euclidean.getAroundLoop(firstBeginIndex, firstBeginIndex, loopFirst) if nearestFirstDistanceIndex.index == nearestSecondDistanceIndex.index: if euclidean.getPathLength(widdershinsPath) < self.minimumDepartureDistance: widdershinsPath = [nearestFirst] + loopBeforeLeaving reversedLoop = loopBeforeLeaving[:] reversedLoop.reverse() clockwisePath = [nearestFirst] + reversedLoop else: widdershinsLoop = euclidean.getAroundLoop(firstBeginIndex, secondBeginIndex, loopFirst) widdershinsPath += widdershinsLoop clockwiseLoop = euclidean.getAroundLoop(secondBeginIndex, firstBeginIndex, loopFirst) clockwiseLoop.reverse() clockwisePath += clockwiseLoop clockwisePath.append(nearestSecond) widdershinsPath.append(nearestSecond) if euclidean.getPathLength(widdershinsPath) > euclidean.getPathLength(clockwisePath): loopBeforeLeaving.reverse() widdershinsPath = clockwisePath if isLeavingPerimeter: totalDistance = euclidean.getPathLength(widdershinsPath) loopLength = euclidean.getPolygonLength(loopBeforeLeaving) while totalDistance < self.minimumDepartureDistance: widdershinsPath = [nearestFirst] + loopBeforeLeaving + widdershinsPath[1:] totalDistance += loopLength return widdershinsPath
def getBottomLoop(self, closestBottomIndex, insertedPoint): "Get loop around bottom." endIndex = self.alongAway.pointIndex + len(self.alongAway.loop) + 1 return euclidean.getAroundLoop(closestBottomIndex, endIndex, self.alongAway.loop)
def getIntersectLoop(self): "Get intersection loop." beginIndex = self.closestXIntersectionIndex.index + len( self.alongAway.loop ) + 1 endIndex = self.alongAway.pointIndex + len( self.alongAway.loop ) + 1 return euclidean.getAroundLoop( beginIndex, endIndex, self.alongAway.loop )
def getBottomLoop( self, closestBottomIndex, insertedPoint ): "Get loop around bottom." endIndex = self.alongAway.pointIndex + len( self.alongAway.loop ) + 1 return euclidean.getAroundLoop( closestBottomIndex, endIndex, self.alongAway.loop )