Package entities :: Module NestedRing'
[hide private]
[frames] | no frames]

Source Code for Module entities.NestedRing'

  1  from StringIO import StringIO 
  2  from collections import OrderedDict 
  3  from config import config 
  4  from fabmetheus_utilities import euclidean 
  5  from fabmetheus_utilities.vector3 import Vector3 
  6  from math import pi 
  7  from paths import BoundaryPerimeter, Loop, InfillPath 
  8  from utilities import memory_tracker 
  9  import math 
 10  import sys 
 11  import time 
 12   
 13   
14 -class NestedRing:
15 - def __init__(self, z, runtimeParameters):
16 17 if runtimeParameters.profileMemory: 18 memory_tracker.track_object(self) 19 20 self.runtimeParameters = runtimeParameters 21 self.decimalPlaces = self.runtimeParameters.decimalPlaces 22 self.z = z 23 24 self.perimeter = None 25 self.loops = [] 26 self.infillPaths = [] 27 28 self.innerNestedRings = [] 29 30 # can the following be removed? only used whilst generating the infill? 31 self.infillPathsHolder = [] 32 self.extraLoops = [] 33 self.penultimateFillLoops = [] 34 self.lastFillLoops = None 35 ### 36 37 self.bridgeFeedRateMinute = self.runtimeParameters.bridgeFeedRateMinute 38 self.perimeterFeedRateMinute = self.runtimeParameters.perimeterFeedRateMinute 39 self.extrusionFeedRateMinute = self.runtimeParameters.extrusionFeedRateMinute 40 self.travelFeedRateMinute = self.runtimeParameters.travelFeedRateMinute 41 self.extrusionUnitsRelative = self.runtimeParameters.extrusionUnitsRelative 42 43 self.oozeRate = self.runtimeParameters.oozeRate 44 self.zDistanceRatio = 5.0 45 self.extruderRetractionSpeedMinute = round(60.0 * self.runtimeParameters.extruderRetractionSpeed, self.decimalPlaces) 46 47 self.layerThickness = self.runtimeParameters.layerThickness 48 self.perimeterWidth = self.runtimeParameters.perimeterWidth 49 self.filamentDiameter = self.runtimeParameters.filamentDiameter 50 self.filamentPackingDensity = self.runtimeParameters.filamentPackingDensity 51 self.absolutePositioning = config.getboolean('preface', 'positioning.absolute') 52 self.flowRate = self.runtimeParameters.flowRate 53 self.perimeterFlowRate = self.runtimeParameters.perimeterFlowRate 54 self.bridgeFlowRate = self.runtimeParameters.bridgeFlowRate 55 self.previousPoint = None 56 filamentRadius = 0.5 * self.filamentDiameter 57 filamentPackingArea = pi * filamentRadius * filamentRadius * self.filamentPackingDensity 58 self.flowScaleSixty = 60.0 * ((((self.layerThickness + self.perimeterWidth) / 4) ** 2 * pi) / filamentPackingArea)
59
60 - def __str__(self):
61 output = StringIO() 62 output.write('\n%4s#########################################' % '') 63 output.write('\n%8snestedRing:' % '') 64 65 output.write('\n%10sboundaryPerimeter:\n' % '') 66 output.write(self.perimeter) 67 68 output.write('\n%10sinnerNestedRings:\n' % '') 69 for innerNestedRing in self.innerNestedRings: 70 output.write('%12s%s\n' % ('', innerNestedRing)) 71 72 output.write('\n%10sloops:\n' % '') 73 for loop in self.loops: 74 output.write(loop) 75 76 output.write('\n%10sextraLoops:\n' % '') 77 for extraLoop in self.extraLoops: 78 output.write('%12s%s\n' % ('', extraLoop)) 79 80 output.write('\n%10spenultimateFillLoops:\n' % '') 81 for penultimateFillLoop in self.penultimateFillLoops: 82 output.write('%12s%s\n' % ('', penultimateFillLoop)) 83 84 output.write('\n%10slastFillLoops:\n' % '') 85 if self.lastFillLoops != None: 86 for lastFillLoop in self.lastFillLoops: 87 output.write('%12s%s\n' % ('', lastFillLoop)) 88 89 output.write('\n%10sinfillPaths:\n' % '') 90 for infillPath in self.infillPaths: 91 output.write(infillPath) 92 93 output.write('\n%4s###### end nestedRing ########################' % '') 94 95 return output.getvalue()
96 97
98 - def getDistanceAndDuration(self):
99 '''Returns the amount of time needed to print the ring, and the distance travelled.''' 100 duration = 0.0 101 distance = 0.0 102 103 (perimeterDistance, perimeterDuration) = self.perimeter.getDistanceAndDuration() 104 duration += perimeterDuration 105 distance += perimeterDistance 106 107 for loop in self.loops: 108 (loopDistance, loopDuration) = loop.getDistanceAndDuration() 109 duration += loopDuration 110 distance += loopDistance 111 112 for infillPath in self.infillPaths: 113 (infillPathDistance, infillPathDuration) = infillPath.getDistanceAndDuration() 114 duration += infillPathDuration 115 distance += infillPathDistance 116 117 for nestedRing in self.innerNestedRings: 118 (nestedRingPathDistance, nestedRingPathDuration) = nestedRing.getDistanceAndDuration() 119 duration += nestedRingPathDuration 120 distance += nestedRingPathDistance 121 122 return (distance, duration)
123 124
125 - def getPerimeterPaths(self, pathList):
126 pathList.append(self.perimeter) 127 128 for innerNestedRing in self.innerNestedRings: 129 innerNestedRing.getPerimeterPaths(pathList)
130
131 - def getLoopPaths(self, pathList):
132 for loop in self.loops: 133 pathList.append(loop) 134 135 for innerNestedRing in self.innerNestedRings: 136 innerNestedRing.getLoopPaths(pathList) 137 138
139 - def getInfillPaths(self, pathList):
140 for infillPath in self.infillPaths: 141 pathList.append(infillPath) 142 143 for innerNestedRing in self.innerNestedRings: 144 innerNestedRing.getInfillPaths(pathList) 145 146
147 - def getStartPoint(self):
148 if self.perimeter != None: 149 return self.perimeter.getStartPoint()
150 151
152 - def offset(self, offset):
153 'Moves the nested ring by the offset amount' 154 for innerNestedRing in self.innerNestedRings: 155 innerNestedRing.offset(offset) 156 157 self.perimeter.offset(offset) 158 159 for loop in self.loops: 160 loop.offset(offset) 161 162 for infillPath in self.infillPaths: 163 infillPath.offset(offset)
164 165
166 - def setBoundaryPerimeter(self, boundaryPointsLoop, perimeterLoop=None):
167 self.perimeter = BoundaryPerimeter(self.z, self.runtimeParameters) 168 169 for point in boundaryPointsLoop: 170 self.perimeter.boundaryPoints.append(Vector3(point.real, point.imag, self.z)) 171 172 if len(boundaryPointsLoop) < 2: 173 return 174 175 if perimeterLoop == None: 176 perimeterLoop = boundaryPointsLoop 177 178 if euclidean.isWiddershins(perimeterLoop): 179 self.perimeter.type = 'outer' 180 else: 181 self.perimeter.type = 'inner' 182 path = perimeterLoop + [perimeterLoop[0]] 183 self.perimeter.addPath(path) 184 185
186 - def addInfillGcodeFromThread(self, thread):
187 'Add a thread to the output.' 188 189 infillPath = InfillPath(self.z, self.runtimeParameters) 190 decimalPlaces = self.decimalPlaces 191 if len(thread) > 0: 192 infillPath.startPoint = thread[0] 193 infillPath.points = thread[1 :] 194 else: 195 logger.warning('Zero length vertex positions array which was skipped over, this should never happen.') 196 if len(thread) < 2: 197 logger.warning('Thread of only one point: %s, this should never happen.', thread) 198 return 199 200 self.infillPaths.append(infillPath)
201 202
203 - def getLoopsToBeFilled(self):
204 'Get last fill loops from the outside loop and the loops inside the inside loops.' 205 if self.lastFillLoops == None: 206 return self.getSurroundingBoundaries() 207 return self.lastFillLoops
208 209
210 - def getXYBoundaries(self):
211 '''Converts XYZ boundary points to XY''' 212 xyBoundaries = [] 213 for boundaryPoint in self.perimeter.boundaryPoints: 214 xyBoundaries.append(boundaryPoint.dropAxis()) 215 return xyBoundaries
216 217
218 - def getSurroundingBoundaries(self):
219 'Get the boundary of the surronding loop plus any boundaries of the innerNestedRings.' 220 surroundingBoundaries = [self.getXYBoundaries()] 221 222 for nestedRing in self.innerNestedRings: 223 surroundingBoundaries.append(nestedRing.getXYBoundaries()) 224 225 return surroundingBoundaries
226 227
228 - def getFillLoops(self, penultimateFillLoops):
229 'Get last fill loops from the outside loop and the loops inside the inside loops.' 230 fillLoops = self.getLoopsToBeFilled()[:] 231 surroundingBoundaries = self.getSurroundingBoundaries() 232 withinLoops = [] 233 if penultimateFillLoops == None: 234 penultimateFillLoops = self.penultimateFillLoops 235 236 if penultimateFillLoops != None: 237 for penultimateFillLoop in penultimateFillLoops: 238 if len(penultimateFillLoop) > 2: 239 if euclidean.getIsInFilledRegion(surroundingBoundaries, penultimateFillLoop[0]): 240 withinLoops.append(penultimateFillLoop) 241 242 if not euclidean.getIsInFilledRegionByPaths(self.penultimateFillLoops, fillLoops): 243 fillLoops += self.penultimateFillLoops 244 245 for nestedRing in self.innerNestedRings: 246 fillLoops += euclidean.getFillOfSurroundings(nestedRing.innerNestedRings, penultimateFillLoops) 247 return fillLoops
248
249 - def transferPaths(self, paths):
250 'Transfer paths.' 251 for innerNestedRing in self.innerNestedRings: 252 innerNestedRing.transferPaths(paths) 253 loop = self.getXYBoundaries() 254 for insideIndex in xrange(len(paths) - 1, -1, -1): 255 inside = paths[ insideIndex ] 256 if euclidean.isPathInsideLoop(loop, inside): 257 self.infillPathsHolder.append(inside) 258 del paths[ insideIndex ]
259
260 - def addToThreads(self, extrusionHalfWidth, oldOrderedLocation, threadSequence):
261 'Add to paths from the last location. perimeter>inner >fill>paths or fill> perimeter>inner >paths' 262 self.addPerimeterInner(extrusionHalfWidth, oldOrderedLocation, threadSequence) 263 self.transferInfillPaths(extrusionHalfWidth, oldOrderedLocation, threadSequence)
264
265 - def transferInfillPaths(self, extrusionHalfWidth, oldOrderedLocation, threadSequence):
266 'Transfer the infill paths.' 267 euclidean.transferClosestPaths(oldOrderedLocation, self.infillPathsHolder[:], self)
268
269 - def addPerimeterInner(self, extrusionHalfWidth, oldOrderedLocation, threadSequence):
270 'Add to the perimeter and the inner island.' 271 for loop in self.extraLoops: 272 innerPerimeterLoop = Loop(self.z, self.runtimeParameters) 273 if euclidean.isWiddershins(loop + [loop[0]]): 274 innerPerimeterLoop.type = 'outer' 275 else: 276 innerPerimeterLoop.type = 'inner' 277 innerPerimeterLoop.addPath(loop + [loop[0]]) 278 self.loops.append(innerPerimeterLoop) 279 280 for innerNestedRing in self.innerNestedRings: 281 innerNestedRing.addToThreads(extrusionHalfWidth, oldOrderedLocation, threadSequence)
282