def getInsetLoopsFromLoop(loop, radius, thresholdRatio=0.9,outsetInnerMagic=1.0): 'Get the inset loops, which might overlap.' if radius == 0.0: return [loop] # figureout cw or ccw sum = 0; for index,v in enumerate(loop): sum+=(loop[(index+1)%len(loop)].imag-v.imag)*(loop[(index+1)%len(loop)].real+v.real) isInner = sum<0 innerMagic = 1.0 if isInner: innerMagic = outsetInnerMagic; #if isInner: # arounds = getAroundsFromLoop(loop, radius, thresholdRatio) #else: # arounds = getAroundsFromLoop(loop, radius, thresholdRatio) isInset = radius > 0 insetLoops = [] isLoopWiddershins = euclidean.isWiddershins(loop) arounds = getAroundsFromLoop(loop, radius, thresholdRatio,innerMagic) for around in arounds: leftPoint = euclidean.getLeftPoint(around) shouldBeWithin = (isInset == isLoopWiddershins) if euclidean.isPointInsideLoop(loop, leftPoint) == shouldBeWithin: if isLoopWiddershins != euclidean.isWiddershins(around): around.reverse() insetLoops.append(around) return insetLoops
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 getIsIntersectingWithinList(loop, loopList): "Determine if the loop is intersecting or is within the loop list." leftPoint = euclidean.getLeftPoint(loop) for otherLoop in loopList: if euclidean.getNumberOfIntersectionsToLeft(otherLoop, leftPoint) % 2 == 1: return True return euclidean.isLoopIntersectingLoops(loop, loopList)
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 flipDirectLayer(self, loopLayer): "Flip the y coordinate of the layer and direct the loops." for loop in loopLayer.loops: for pointIndex, point in enumerate(loop): loop[pointIndex] = complex(point.real, -point.imag) triangle_mesh.sortLoopsInOrderOfArea(True, loopLayer.loops) for loopIndex, loop in enumerate(loopLayer.loops): isInsideLoops = euclidean.getIsInFilledRegion(loopLayer.loops[: loopIndex], euclidean.getLeftPoint(loop)) intercircle.directLoop((not isInsideLoops), loop)
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 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 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.isInFilledRegion(loops, leftPoint): if isInset: around.reverse() insetSeparateLoops.append(around) return insetSeparateLoops
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.isInFilledRegion( loops, leftPoint ): if isInset: around.reverse() insetSeparateLoops.append( around ) return insetSeparateLoops
def getInsetLoopsFromLoop(inset, loop, thresholdRatio=0.9): "Get the inset loops, which might overlap." isInset = inset > 0 insetLoops = [] isLoopWiddershins = euclidean.isWiddershins(loop) arounds = getAroundsFromLoop(loop, inset, thresholdRatio) for around in arounds: leftPoint = euclidean.getLeftPoint(around) shouldBeWithin = (isInset == isLoopWiddershins) if euclidean.isPointInsideLoop(loop, leftPoint) == shouldBeWithin: if isLoopWiddershins != euclidean.isWiddershins(around): around.reverse() insetLoops.append(around) return insetLoops
def getInsetLoopsFromLoop(loop, radius, thresholdRatio=0.9): 'Get the inset loops, which might overlap.' isInset = radius > 0 insetLoops = [] isLoopWiddershins = euclidean.isWiddershins(loop) arounds = getAroundsFromLoop(loop, radius, thresholdRatio) for around in arounds: leftPoint = euclidean.getLeftPoint(around) shouldBeWithin = (isInset == isLoopWiddershins) if euclidean.isPointInsideLoop(loop, leftPoint) == shouldBeWithin: if isLoopWiddershins != euclidean.isWiddershins(around): around.reverse() insetLoops.append(around) return insetLoops
def getLoopsFromMesh( self, z ): "Get loops from a carve of a mesh." originalLoops = [] if self.isCorrectMesh: originalLoops = getLoopsFromCorrectMesh( self.edges, self.faces, self.getVertices(), z ) if len( originalLoops ) < 1: originalLoops = getLoopsFromUnprovenMesh( self.edges, self.faces, self.importRadius, self.getVertices(), z ) loops = getLoopsInOrderOfArea( compareAreaDescending, euclidean.getSimplifiedLoops( originalLoops, self.importRadius ) ) for loopIndex in xrange( len( loops ) ): loop = loops[ loopIndex ] leftPoint = euclidean.getLeftPoint( loop ) isInFilledRegion = euclidean.isInFilledRegion( loops[ : loopIndex ] + loops[ loopIndex + 1 : ], leftPoint ) if isInFilledRegion == euclidean.isWiddershins( loop ): loop.reverse() return loops
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 addWiden( self, rotatedBoundaryLayer ): "Add widen to the layer." loops = triangle_mesh.getLoopsInOrderOfArea( triangle_mesh.compareAreaAscending, rotatedBoundaryLayer.loops ) widdershinsLoops = [] clockwiseInsetLoops = [] for loopIndex in xrange( len( loops ) ): loop = loops[ loopIndex ] if euclidean.isWiddershins( loop ): otherLoops = loops[ : loopIndex ] + loops[ loopIndex + 1 : ] leftPoint = euclidean.getLeftPoint( loop ) if euclidean.isPointInsideLoops( otherLoops, leftPoint ): self.distanceFeedRate.addGcodeFromLoop( loop, rotatedBoundaryLayer.z ) else: widdershinsLoops.append( loop ) else: clockwiseInsetLoops += intercircle.getInsetLoopsFromLoop( self.doublePerimeterWidth, loop ) self.distanceFeedRate.addGcodeFromLoop( loop, rotatedBoundaryLayer.z ) for widdershinsLoop in widdershinsLoops: outsetLoop = intercircle.getLargestInsetLoopFromLoop( widdershinsLoop, - self.doublePerimeterWidth ) widenedLoop = getWidenedLoop( widdershinsLoop, clockwiseInsetLoops, outsetLoop, self.perimeterWidth, self.tinyRadius ) self.distanceFeedRate.addGcodeFromLoop( widenedLoop, rotatedBoundaryLayer.z )
def addWiden( self, rotatedBoundaryLayer ): "Add widen to the layer." loops = trianglemesh.getLoopsInOrderOfArea( trianglemesh.compareAreaAscending, rotatedBoundaryLayer.loops ) widdershinsLoops = [] clockwiseInsetLoops = [] for loopIndex in xrange( len(loops) ): loop = loops[loopIndex] if euclidean.isWiddershins(loop): otherLoops = loops[ : loopIndex ] + loops[loopIndex + 1 :] leftPoint = euclidean.getLeftPoint(loop) if getIsPointInsideALoop( otherLoops, leftPoint ): self.distanceFeedRate.addGcodeFromLoop( loop, rotatedBoundaryLayer.z ) else: widdershinsLoops.append(loop) else: clockwiseInsetLoops += intercircle.getInsetLoopsFromLoop( self.doublePerimeterWidth, loop ) self.distanceFeedRate.addGcodeFromLoop( loop, rotatedBoundaryLayer.z ) for widdershinsLoop in widdershinsLoops: outsetLoop = intercircle.getLargestInsetLoopFromLoop( widdershinsLoop, - self.doublePerimeterWidth ) widenedLoop = getWidenedLoop( widdershinsLoop, clockwiseInsetLoops, outsetLoop, self.perimeterWidth ) self.distanceFeedRate.addGcodeFromLoop( widenedLoop, rotatedBoundaryLayer.z )
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 addWiden(self, loopLayer): 'Add widen to the layer.' triangle_mesh.sortLoopsInOrderOfArea(False, loopLayer.loops) widdershinsLoops = [] clockwiseInsetLoops = [] for loopIndex in xrange(len(loopLayer.loops)): loop = loopLayer.loops[loopIndex] if euclidean.isWiddershins(loop): otherLoops = loopLayer.loops[: loopIndex] + loopLayer.loops[loopIndex + 1 :] leftPoint = euclidean.getLeftPoint(loop) if getIsPointInsideALoop(otherLoops, leftPoint): self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z) else: widdershinsLoops.append(loop) else: # clockwiseInsetLoop = intercircle.getLargestInsetLoopFromLoop(loop, self.widenEdgeWidth) # clockwiseInsetLoop.reverse() # clockwiseInsetLoops.append(clockwiseInsetLoop) clockwiseInsetLoops += intercircle.getInsetLoopsFromLoop(loop, self.widenEdgeWidth) self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z) for widdershinsLoop in widdershinsLoops: outsetLoop = intercircle.getLargestInsetLoopFromLoop(widdershinsLoop, -self.widenEdgeWidth) for widenedLoop in getWidenedLoops(widdershinsLoop, clockwiseInsetLoops, outsetLoop, self.lessThanHalfEdgeWidth): self.distanceFeedRate.addGcodeFromLoop(widenedLoop, loopLayer.z)
def addWiden(self, rotatedLoopLayer): 'Add widen to the layer.' triangle_mesh.sortLoopsInOrderOfArea(False, rotatedLoopLayer.loops) widdershinsLoops = [] clockwiseInsetLoops = [] for loopIndex in xrange(len(rotatedLoopLayer.loops)): loop = rotatedLoopLayer.loops[loopIndex] if euclidean.isWiddershins(loop): otherLoops = rotatedLoopLayer.loops[: loopIndex] + rotatedLoopLayer.loops[loopIndex + 1 :] leftPoint = euclidean.getLeftPoint(loop) if getIsPointInsideALoop(otherLoops, leftPoint): self.distanceFeedRate.addGcodeFromLoop(loop, rotatedLoopLayer.z) else: widdershinsLoops.append(loop) else: # clockwiseInsetLoop = intercircle.getLargestInsetLoopFromLoop(loop, self.doublePerimeterWidth) # clockwiseInsetLoop.reverse() # clockwiseInsetLoops.append(clockwiseInsetLoop) clockwiseInsetLoops += intercircle.getInsetLoopsFromLoop(loop, self.doublePerimeterWidth) self.distanceFeedRate.addGcodeFromLoop(loop, rotatedLoopLayer.z) for widdershinsLoop in widdershinsLoops: outsetLoop = intercircle.getLargestInsetLoopFromLoop(widdershinsLoop, -self.doublePerimeterWidth) widenedLoop = getWidenedLoop(widdershinsLoop, clockwiseInsetLoops, outsetLoop, self.perimeterWidth) self.distanceFeedRate.addGcodeFromLoop(widenedLoop, rotatedLoopLayer.z)
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) rotatedLoopLayer.loops = trianglemesh.getLoopsInOrderOfArea(trianglemesh.compareAreaDescending, rotatedLoopLayer.loops) for loopIndex, loop in enumerate(rotatedLoopLayer.loops): isInsideLoops = euclidean.isPointInsideLoopsZone(rotatedLoopLayer.loops[: loopIndex], euclidean.getLeftPoint(loop)) booleansolid.directLoop((not isInsideLoops), loop)