def getGeometryOutputByLoops(derivation, loops): 'Get geometry output by sorted, nested loops.' loops.sort(key=euclidean.getAreaVector3LoopAbsolute, reverse=True) complexLoops = euclidean.getComplexPaths(loops) nestedRings = [] for loopIndex, loop in enumerate(loops): complexLoop = complexLoops[loopIndex] leftPoint = euclidean.getLeftPoint(complexLoop) isInFilledRegion = euclidean.getIsInFilledRegion(complexLoops[: loopIndex] + complexLoops[loopIndex + 1 :], leftPoint) if isInFilledRegion == euclidean.isWiddershins(complexLoop): loop.reverse() nestedRing = euclidean.NestedRing() nestedRing.boundary = complexLoop nestedRing.vector3Loop = loop nestedRings.append(nestedRing) nestedRings = euclidean.getOrderedNestedRings(nestedRings) nestedRings = euclidean.getFlattenedNestedRings(nestedRings) portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary) if len(nestedRings) < 1: return {} if len(nestedRings) == 1: geometryOutput = getGeometryOutputByNestedRing(derivation, nestedRings[0], portionDirections) return solid.getGeometryOutputByManipulation(geometryOutput, derivation.xmlElement) shapes = [] for nestedRing in nestedRings: shapes.append(getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections)) return solid.getGeometryOutputByManipulation({'union' : {'shapes' : shapes}}, derivation.xmlElement)
def getInteriorSegments(loops, segments): 'Get segments inside the loops.' interiorSegments = [] for segment in segments: center = 0.5 * (segment[0].point + segment[1].point) if euclidean.getIsInFilledRegion(loops, center): interiorSegments.append(segment) return interiorSegments
def getOrientedLoops(loops): 'Orient the loops which must be in descending order.' for loopIndex, loop in enumerate(loops): leftPoint = euclidean.getLeftPoint(loop) isInFilledRegion = euclidean.getIsInFilledRegion(loops[: loopIndex] + loops[loopIndex + 1 :], leftPoint) if isInFilledRegion == euclidean.isWiddershins(loop): loop.reverse() return loops
def getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ): "Determine if the inset point is inside the loops." centerMinusBegin = euclidean.getNormalized( pointCenter - pointBegin ) centerMinusBeginWiddershins = complex( - centerMinusBegin.imag, centerMinusBegin.real ) endMinusCenter = euclidean.getNormalized( pointEnd - pointCenter ) endMinusCenterWiddershins = complex( - endMinusCenter.imag, endMinusCenter.real ) widdershinsNormalized = euclidean.getNormalized( centerMinusBeginWiddershins + endMinusCenterWiddershins ) * radius return euclidean.getIsInFilledRegion( loops, pointCenter + widdershinsNormalized ) == inside
def flipDirectLayer(self, rotatedLoopLayer): "Flip the y coordinate of the layer and direct the loops." for loop in rotatedLoopLayer.loops: for pointIndex, point in enumerate(loop): loop[pointIndex] = complex(point.real, -point.imag) triangle_mesh.sortLoopsInOrderOfArea(True, rotatedLoopLayer.loops) for loopIndex, loop in enumerate(rotatedLoopLayer.loops): isInsideLoops = euclidean.getIsInFilledRegion(rotatedLoopLayer.loops[: loopIndex], euclidean.getLeftPoint(loop)) intercircle.directLoop((not isInsideLoops), loop)
def addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, x, y, zigzag): 'Add grid row.' row = [] while x < maximumComplex.real: point = complex(x, y) if euclidean.getIsInFilledRegion(loopsComplex, point): row.append(point) x += diameter.real if zigzag and rowIndex % 2 == 1: row.reverse() gridPath += row
def getIsPointInsideZoneAwayOthers(diameterReciprocal, loopsComplex, point, pixelDictionary): 'Determine if the point is inside the loops zone and and away from the other points.' if not euclidean.getIsInFilledRegion(loopsComplex, point): return False pointOverDiameter = complex(point.real * diameterReciprocal.real, point.imag * diameterReciprocal.imag) squareValues = euclidean.getSquareValuesFromPoint(pixelDictionary, pointOverDiameter) for squareValue in squareValues: if abs(squareValue - pointOverDiameter) < 1.0: return False euclidean.addElementToPixelListFromPoint(pointOverDiameter, pixelDictionary, pointOverDiameter) return True
def getInsetSeparateLoopsFromLoops(inset, loops, thresholdRatio=0.9): 'Get the separate inset loops.' isInset = inset > 0 insetSeparateLoops = [] radius = abs(inset) arounds = getAroundsFromLoops(loops, radius, thresholdRatio) for around in arounds: if isInset == euclidean.getIsInFilledRegion(loops, around[0]): if isInset: around.reverse() insetSeparateLoops.append(around) return insetSeparateLoops
def getExtraFillLoops(loops, radius): 'Get extra loops between inside and outside loops. Extra perimeters' greaterThanRadius = radius / 0.7853 #todo was *1.4 ACT (radius /0.7853) how much the tight spots are covered by the extra loops extraFillLoops = [] centers = intercircle.getCentersFromPoints(intercircle.getPointsFromLoops(loops, greaterThanRadius), greaterThanRadius) for center in centers: inset = intercircle.getSimplifiedInsetFromClockwiseLoop(center, radius) if intercircle.isLargeSameDirection(inset, center, radius): if euclidean.getIsInFilledRegion(loops, euclidean.getLeftPoint(inset)): inset.reverse() extraFillLoops.append(inset) return extraFillLoops
def getDescendingAreaLoops(allPoints, corners, importRadius): 'Get loops which include most of the points.' loops = intercircle.getCentersFromPoints(allPoints, importRadius) descendingAreaLoops = [] sortLoopsInOrderOfArea(True, loops) pointDictionary = {} for loop in loops: if len(loop) > 2 and getOverlapRatio(loop, pointDictionary) < 0.1: intercircle.directLoop(not euclidean.getIsInFilledRegion(descendingAreaLoops, loop[0]), loop) descendingAreaLoops.append(loop) addLoopToPointTable(loop, pointDictionary) descendingAreaLoops = euclidean.getSimplifiedLoops(descendingAreaLoops, importRadius) return getLoopsWithCorners(corners, importRadius, descendingAreaLoops, pointDictionary)
def getInsetSeparateLoopsFromLoops(loops, radius, thresholdRatio=0.9): 'Get the separate inset loops.' if radius == 0.0: return loops isInset = radius > 0 insetSeparateLoops = [] arounds = getAroundsFromLoops(loops, abs(radius), thresholdRatio) for around in arounds: if isInset == euclidean.getIsInFilledRegion(loops, around[0]): if isInset: around.reverse() insetSeparateLoops.append(around) return insetSeparateLoops
def getIsInsetPointInsideLoops(inside, loops, pointBegin, pointCenter, pointEnd, radius): 'Determine if the inset point is inside the loops.' centerMinusBegin = euclidean.getNormalized(pointCenter - pointBegin) centerMinusBeginWiddershins = complex(-centerMinusBegin.imag, centerMinusBegin.real) endMinusCenter = euclidean.getNormalized(pointEnd - pointCenter) endMinusCenterWiddershins = complex(-endMinusCenter.imag, endMinusCenter.real) widdershinsNormalized = euclidean.getNormalized( centerMinusBeginWiddershins + endMinusCenterWiddershins) * radius return euclidean.getIsInFilledRegion(loops, pointCenter + widdershinsNormalized) == inside
def getInsetSeparateLoopsFromLoops(inset, loops, thresholdRatio=0.9): "Get the separate inset loops." isInset = inset > 0 insetSeparateLoops = [] radius = abs(inset) arounds = getAroundsFromLoops(loops, radius, thresholdRatio) for around in arounds: leftPoint = euclidean.getLeftPoint(around) if isInset == euclidean.getIsInFilledRegion(loops, leftPoint): if isInset: around.reverse() insetSeparateLoops.append(around) return insetSeparateLoops
def getInsetSeparateLoopsFromLoops(loops, radius, thresholdRatio=0.9): "Get the separate inset loops." if radius == 0.0: return loops isInset = radius > 0 insetSeparateLoops = [] arounds = getAroundsFromLoops(loops, abs(radius), thresholdRatio) for around in arounds: if isInset == euclidean.getIsInFilledRegion(loops, around[0]): if isInset: around.reverse() insetSeparateLoops.append(around) return insetSeparateLoops
def getDescendingAreaLoops(allPoints, corners, importRadius): 'Get descending area loops which include most of the points.' loops = intercircle.getCentersFromPoints(allPoints, importRadius) descendingAreaLoops = [] sortLoopsInOrderOfArea(True, loops) pointDictionary = {} for loop in loops: if len(loop) > 2 and getOverlapRatio(loop, pointDictionary) < 0.3 and intercircle.getIsLarge(loop, importRadius): intercircle.directLoop(not euclidean.getIsInFilledRegion(descendingAreaLoops, loop[0]), loop) descendingAreaLoops.append(loop) addLoopToPointTable(loop, pointDictionary) descendingAreaLoops = euclidean.getSimplifiedLoops(descendingAreaLoops, importRadius) return getLoopsWithCorners(corners, importRadius, descendingAreaLoops, pointDictionary)
def getExtraFillLoops(loops, radius): 'Get extra loops between inside and outside loops. Extra perimeters' greaterThanRadius = radius / 0.7853 #todo was *1.4 ACT (radius /0.7853) how much the tight spots are covered by the extra loops extraFillLoops = [] centers = intercircle.getCentersFromPoints( intercircle.getPointsFromLoops(loops, greaterThanRadius), greaterThanRadius) for center in centers: inset = intercircle.getSimplifiedInsetFromClockwiseLoop(center, radius) if intercircle.isLargeSameDirection(inset, center, radius): if euclidean.getIsInFilledRegion(loops, euclidean.getLeftPoint(inset)): inset.reverse() extraFillLoops.append(inset) return extraFillLoops
def getLoopsFromMesh( self, z ): "Get loops from a carve of a mesh." originalLoops = [] if self.isCorrectMesh: originalLoops = getLoopsFromCorrectMesh( self.edges, self.faces, self.getTransformedVertexes(), z ) if len( originalLoops ) < 1: originalLoops = getLoopsFromUnprovenMesh( self.edges, self.faces, self.importRadius, self.getTransformedVertexes(), z ) loops = getLoopsInOrderOfArea( compareAreaDescending, euclidean.getSimplifiedLoops( originalLoops, self.importRadius ) ) for loopIndex in xrange( len(loops) ): loop = loops[loopIndex] leftPoint = euclidean.getLeftPoint(loop) isInFilledRegion = euclidean.getIsInFilledRegion( loops[ : loopIndex ] + loops[loopIndex + 1 :], leftPoint ) if isInFilledRegion == euclidean.isWiddershins(loop): loop.reverse() return loops
def getInsetSeparateLoopsFromAroundLoops(loops, radius, radiusAround, thresholdRatio=0.9): 'Get the separate inset loops.' if radius == 0.0: return loops isInset = radius > 0 insetSeparateLoops = [] radius = abs(radius) radiusAround = max(abs(radiusAround), radius) points = getPointsFromLoops(loops, radiusAround, thresholdRatio) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radiusAround) for center in centers: inset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(inset, center, radius): if isInset == euclidean.getIsInFilledRegion(loops, inset[0]): if isInset: inset.reverse() insetSeparateLoops.append(inset) return insetSeparateLoops
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 getInsetSeparateLoopsFromAroundLoops(loops, radius, radiusAround, thresholdRatio=0.9): "Get the separate inset loops." if radius == 0.0: return loops isInset = radius > 0 insetSeparateLoops = [] radius = abs(radius) radiusAround = max(abs(radiusAround), radius) points = getPointsFromLoops(loops, radiusAround, thresholdRatio) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radiusAround) for center in centers: inset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(inset, center, radius): if isInset == euclidean.getIsInFilledRegion(loops, inset[0]): if isInset: inset.reverse() insetSeparateLoops.append(inset) return insetSeparateLoops
def getConnectionIsCloseWithoutOverlap(self, location, path): "Determine if the connection is close enough and does not overlap another thread." if len(path) < 1: return False locationComplex = location.dropAxis(2) segment = locationComplex - path[-1] segmentLength = abs(segment) if segmentLength <= 0.0: return True if segmentLength > self.maximumConnectionDistance: return False segment /= segmentLength distance = self.connectingStepLength segmentEndLength = segmentLength - self.connectingStepLength while distance < segmentEndLength: alongPoint = distance * segment + path[-1] if not euclidean.getIsInFilledRegion(self.boundaryLoops, alongPoint): return False distance += self.connectingStepLength # removedLayerPixelTable = self.layerPixelTable.copy() # if self.oldLocation in self.maskPixelTableTable: # euclidean.removePixelTableFromPixelTable( self.maskPixelTableTable[ self.oldLocation ], removedLayerPixelTable ) # euclidean.addPathToPixelTable( path[ : - 2 ], removedLayerPixelTable, None, self.layerPixelWidth ) segmentTable = {} euclidean.addSegmentToPixelTable(path[-1], locationComplex, segmentTable, 2.0, 2.0, self.layerPixelWidth) # euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, segmentTable, None, self.layerPixelWidth ) # euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, segmentTable, None, self.layerPixelWidth ) # maskPixelTable = {} # if location in self.maskPixelTableTable: # maskPixelTable = self.maskPixelTableTable[ location ] if euclidean.isPixelTableIntersecting(self.layerPixelTable, segmentTable, {}): # if euclidean.isPixelTableIntersecting( removedLayerPixelTable, segmentTable, {} ): return False euclidean.addValueSegmentToPixelTable(path[-1], locationComplex, self.layerPixelTable, None, self.layerPixelWidth) # euclidean.addPixelTableToPixelTable( segmentTable, self.layerPixelTable ) return True
def getFillLoops(self, penultimateFillLoops): 'Get last fill loops from the outside loop and the loops inside the inside loops.' fillLoops = self.getLoopsToBeFilled()[:] surroundingBoundaries = self.getSurroundingBoundaries() withinLoops = [] if penultimateFillLoops == None: penultimateFillLoops = self.penultimateFillLoops if penultimateFillLoops != None: for penultimateFillLoop in penultimateFillLoops: if len(penultimateFillLoop) > 2: if euclidean.getIsInFilledRegion(surroundingBoundaries, penultimateFillLoop[0]): withinLoops.append(penultimateFillLoop) if not euclidean.getIsInFilledRegionByPaths(self.penultimateFillLoops, fillLoops): fillLoops += self.penultimateFillLoops for nestedRing in self.innerNestedRings: fillLoops += euclidean.getFillOfSurroundings(nestedRing.innerNestedRings, penultimateFillLoops) return fillLoops
def getGeometryOutputByLoops(derivation, loops): 'Get geometry output by sorted, nested loops.' loops.sort(key=euclidean.getAreaVector3LoopAbsolute, reverse=True) complexLoops = euclidean.getComplexPaths(loops) nestedRings = [] for loopIndex, loop in enumerate(loops): complexLoop = complexLoops[loopIndex] leftPoint = euclidean.getLeftPoint(complexLoop) isInFilledRegion = euclidean.getIsInFilledRegion( complexLoops[:loopIndex] + complexLoops[loopIndex + 1:], leftPoint) if isInFilledRegion == euclidean.isWiddershins(complexLoop): loop.reverse() nestedRing = euclidean.NestedRing() nestedRing.boundary = complexLoop nestedRing.vector3Loop = loop nestedRings.append(nestedRing) nestedRings = euclidean.getOrderedNestedRings(nestedRings) nestedRings = euclidean.getFlattenedNestedRings(nestedRings) portionDirections = getSpacedPortionDirections( derivation.interpolationDictionary) if len(nestedRings) < 1: return {} if len(nestedRings) == 1: geometryOutput = getGeometryOutputByNestedRing(derivation, nestedRings[0], portionDirections) return solid.getGeometryOutputByManipulation(derivation.elementNode, geometryOutput) shapes = [] for nestedRing in nestedRings: shapes.append( getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections)) return solid.getGeometryOutputByManipulation(derivation.elementNode, {'union': { 'shapes': shapes }})
def getConnectionIsCloseWithoutOverlap( self, location, path ): """Determine if the connection is close enough and does not overlap another thread.""" if len(path) < 1: return False locationComplex = location.dropAxis() segment = locationComplex - path[-1] segmentLength = abs(segment) if segmentLength <= 0.0: return True if segmentLength > self.maximumConnectionDistance: return False segment /= segmentLength distance = self.connectingStepLength segmentEndLength = segmentLength - self.connectingStepLength while distance < segmentEndLength: alongPoint = distance * segment + path[-1] if not euclidean.getIsInFilledRegion( self.boundaryLoops, alongPoint ): return False distance += self.connectingStepLength # removedLayerPixelTable = self.layerPixelTable.copy() # if self.oldLocation in self.maskPixelTableTable: # euclidean.removePixelTableFromPixelTable( self.maskPixelTableTable[ self.oldLocation ], removedLayerPixelTable ) # euclidean.addPathToPixelTable( path[ : - 2 ], removedLayerPixelTable, None, self.layerPixelWidth ) segmentTable = {} euclidean.addSegmentToPixelTable( path[-1], locationComplex, segmentTable, 2.0, 2.0, self.layerPixelWidth ) # euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, segmentTable, None, self.layerPixelWidth ) # euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, segmentTable, None, self.layerPixelWidth ) # maskPixelTable = {} # if location in self.maskPixelTableTable: # maskPixelTable = self.maskPixelTableTable[ location ] if euclidean.isPixelTableIntersecting( self.layerPixelTable, segmentTable, {} ): # if euclidean.isPixelTableIntersecting( removedLayerPixelTable, segmentTable, {} ): return False euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, self.layerPixelTable, None, self.layerPixelWidth ) # euclidean.addPixelTableToPixelTable( segmentTable, self.layerPixelTable ) return True